Search code examples
vhdlxilinx

Connecting ports by name in VHDL, UCF-style


I have a VHDL entity defined like this:

entity RealEntity is
  port(
    CLK_50MHZ: in std_logic;
    LED : out std_logic_vector(3 downto 0)
    );
end RealEntity;

If I also have UCF entries for LED<0>..LED<3> and CLK_50MHZ, then I can compile this entity directly.

However, I don't actually have a 50 MHz clock on my board, so I have to use a clock manager chip. I'm using Xilinx tools for this which has a wizard to add a DCM core, and then I wrap it in another VHDL entity for easy use:

entity dcm is
  port(
    CLK_32MHZ: in std_logic;
    CLK_50MHZ: out std_logic
    );
end dcm;

where CLK_32MHZ is something that actually exists in my UCF.

To connect these two, I am currently using a third entity to be used as my toplevel one:

entity main is
  port(
    CLK_32MHZ : in  std_logic;
    LED       : out std_logic_vector(3 downto 0)
    );
end main;

architecture arch of main is
  signal CLK_50MHZ : std_logic;

  component dcm
    port(
      CLK_32MHZ : in  std_logic;
      CLK_50MHZ : out std_logic
      );
  end component;

  component RealEntity
    port(CLK_50MHZ : in  std_logic;
         LED       : out std_logic_vector(3 downto 0)
         );
  end component;

begin
  inst_dcm : dcm
    port map(
      CLK_32MHZ => CLK_32MHZ,
      CLK_50MHZ => CLK_50MHZ
      );

  inst_RealEntity : RealEntity
    port map(
      CLK_50MHZ => CLK_50MHZ,
      LED       => LED
      );

end arch;

As you can see, this third entity is 100% boilerplate. My question is, is it possible to avoid writing this main entity, and instead just use RealEntity and dcm directly, and connect the two CLK_50MHZ ports by virtue of them sharing their name, basically emulating CLK_50MHZ being present in my UCF file?


Solution

  • Somehow you have to tell the tools how to wire up your DCM and your real entity. Your "boilerplate" top-level entity is what achieves that. You can't do it in the UCF file as it doesn't allow you to create connections, just attach various attributes to the connections that you have made.

    So your problem then becomes one of what tools exist to enable you to "wire things up" as efficiently as possible. Brian has enumerated some options for you there...

    You can reduce your boilerplate by using direct instantiation. Remove your component declarations and then do:

    inst_RealEntity : entity work.RealEntity
        port map(
          CLK_50MHZ => CLK_50MHZ,
          LED       => LED
          );