开发者

Sharing (including?) generics in VHDL between files?

Assume I have this simple core with generics as genertest.vhd:

--------------------------------------------------------------------------
library IEEE;
  use IEEE.STD_LOGIC_1164.ALL;
  -- use IEEE.STD_LOGIC_ARITH.ALL;
  -- use IEEE.STD_LOGIC_UNSIGNED.ALL;
  use IEEE.NUMERIC_STD.ALL;


ENTITY genertest IS
  GENERIC(
    numbits : natural := 8
  );
  PORT
  (
    clk   :  IN STD_LOGIC;
    d_OUT : OUT STD_LOGIC_VECTOR(numbits-1 downto 0);
    d_IN  :  IN STD_LOGIC_VECTOR(numbits-1 downto 0)
  );
END genertest;


ARCHITECTURE structure OF genertest IS
BEGIN

  main_proc: PROCESS(clk)
  BEGIN
    IF rising_edge(clk) THEN -- posedge
      d_OUT <= not(d_IN);
    END IF;
  END PROCESS main_proc;

END structure;

... and I want to test it with following test workbench, genertest_twb.vhd:

----------------------------------------------------------------------------------

library IEEE;
  use IEEE.STD_LOGIC_1164.ALL;
  -- use IEEE.STD_LOGIC_ARITH.ALL;
  -- use IEEE.STD_LOGIC_UNSIGNED.ALL;
  use IEEE.NUMERIC_STD.ALL;

ENTITY genertest_twb IS
END genertest_twb;

ARCHITECTURE testbench_arch OF genertest_twb IS

  COMPONENT genertest
    PORT(
      clk   :  IN STD_LOGIC;
      d_OUT : OUT STD_LOGIC_VECTOR(numbits-1 downto 0);
      d_IN  :  IN STD_LOGIC_VECTOR(numbits-1 downto 0)
    );
  END COMPONENT;

  SIGNAL wtCLK : std_logic := '0';
  SIGNAL wCntReg : STD_LOGIC_VECTOR(numbits-1 DOWNTO 0) := (others => 'Z');
  SIGNAL tmp_cnt : natural := 0 ;

  -- clock parameters
  constant PERIODN : natural := 20; -- can be real := 20.0;
  constant PERIOD : time := PERIODN * 1 ns;
  constant DUTY_CYCLE : real := 0.5;
  constant OFFSET : time := 100 ns;

BEGIN

  UUT : genertest -- VHDL
  PORT MAP(
    clk => wtCLK,
    d_IN => wCntReg,
    d_OUT => OPEN
  );

  -- clock process for generating CLK
  -- (here, left as unnamed)
  PROCESS
  BEGIN

    WAIT for OFFSET;

    CLOCK_LOOP : LOOP
      wtCLK <= '0';
      -- tmp_na - natural problems with bit width?
      -- wCntReg <= std_logic_vector(to_unsigned(natural'pos(tmp_na), wCntReg'length));
      WAIT FOR (PERIOD - (PERIOD * DUTY_CYCLE));
      wtCLK <= '1';
      WAIT FOR (PERIOD * DUTY_CYCLE);
    END LOOP CLOCK_LOOP;
  END PROCESS;


  count_proc: PROCESS(wtCLK)
  BEGIN
    IF rising_edge(wtCLK) THEN -- posedge
      tmp_cnt <= tmp_cnt + 1;
      wCntReg <= std_logic_vector(to_unsigned(natural'pos(tmp_cnt), wCntReg'length));
    END IF;
  END PROCESS count_proc;


END testbench_arch;

Now, I would assume that by referencing the genertest component, the workbench would automatically know about the numbits generic, but unfortunately, that is not the case; behavioral simulation of the above workbench in ISE WebPack fails with:

ERROR:HDLCompiler:69 - "/genertest_tbw.vhd" Line 17: <numbits> is not declared.
ERROR:HDLCompiler:69 - "/genertest_tbw.vhd" Line 18: <numbits> is not declared.
ERROR:HDLCompiler:69 - "/genertest_tbw.vhd" Line 23: <numbits> is not declared.

By adding the generic part in the genertest_tbw.vhd here:

  COMPONENT genertest
    GENERIC(
      numbits : natural := 8
    );
    PORT(
      ...

... will fix generics references local to the component - unfortunately, the reference to the generic in the SIGNAL wCntReg declaration will still fail.

Finally, adding the generic part in the generte开发者_StackOverflow社区st_tbw.vhd here:

ENTITY genertest_twb IS
  GENERIC(
    numbits : natural := 8
  );
END genertest_twb;

... makes the generic available to the entire workbench file.

However, that still means I have to manually copy/paste numbits : natural := 8 sentence in the workbench file as well; which means it will figure two places, and I'd have to change both if I want to change the generic value :(

So my question is - is there a way to share / include generics, such that they are written/defined in only one file - and other files can refer to these particular values?

Thanks in advance for any answers,

Cheers!


You're missing the point of generics. You don't pass the generic values up through the hierarchy, you pass them down.

Define numbits in your testbench (perhaps as something a bit more meaningful, like RAM_WIDTH), and use it to instantiate genertest with the appropriate number of bits. The default value defined for numbits in your genertest entity is used for code that does not explicitly define the generic value (either for readability, or perhaps to maintain backwards compatibility for a function that used to always take 8 bits, but now is configurable to any width).

So in your testbench, you want something like:

constant RAM_WIDTH : integer := 8;
...
UUT : genertest 
  GENERIC MAP (
    numbits => RAM_WIDTH
  );
  PORT MAP
  (
    clk   => wtCLK,
...


If you want "shared constants" you need a package with some constants in it.

Then use those constants to map onto the generics of the items you instantiate.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜