Совместное использование (в том числе?) Обобщений в VHDL между файлами? - PullRequest
3 голосов
/ 15 июля 2011

Предположим, у меня есть это простое ядро ​​с обобщениями как 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;

... и я хочу проверить это с помощью следующего тестового рабочего места, 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;

Теперь я хотел бы предположить, что, ссылаясь на компонент genertest, рабочая среда автоматически узнает об универсальном numbits, но, к сожалению, это не так; поведенческое моделирование вышеупомянутого рабочего места в ISE WebPack завершается неудачно с:

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.

Добавив общую часть в genertest_tbw.vhd здесь:

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

... исправит ссылки на универсальные элементы, локальные для компонента - к сожалению, ссылка на универсальные элементы в объявлении SIGNAL wCntReg по-прежнему не будет работать.

Наконец, добавление общей детали в genertest_tbw.vhd здесь:

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

... делает универсальный доступным для всего файла рабочей среды.

Однако это по-прежнему означает, что я должен вручную скопировать / вставить numbits : natural := 8 предложение в файле рабочей среды; это означает, что он будет отображать два места, и мне придется изменить оба, если я хочу изменить общее значение: (

Так что мой вопрос - есть ли способ поделиться / включить дженерики, чтобы они были записаны / определены только в одном файле - и другие файлы могут ссылаться на эти конкретные значения?

Заранее спасибо за любые ответы,
Ура!

Ответы [ 2 ]

8 голосов
/ 15 июля 2011

Вам не хватает дженериков.Вы не передаете общие значения вверх по иерархии, вы передаете их вниз.

Определите числа в вашей тестовой среде (возможно, как что-то более значимое, например, RAM_WIDTH), и используйте его для создания экземпляра gentest с помощьюсоответствующее количество бит.Значение по умолчанию, определенное для числовых значений в вашей обобщенной сущности, используется для кода, который явно не определяет обобщенное значение (либо для удобочитаемости, либо, возможно, для обеспечения обратной совместимости для функции, которая всегда принимала 8 бит, но теперь настраивается для любогоширина).

Итак, в вашем тестовом стенде вы хотите что-то вроде:

constant RAM_WIDTH : integer := 8;
...
UUT : genertest 
  GENERIC MAP (
    numbits => RAM_WIDTH
  );
  PORT MAP
  (
    clk   => wtCLK,
...
3 голосов
/ 15 июля 2011

Если вам нужны «общие константы», вам нужен package с некоторыми константами в нем.

Затем используйте эти константы для сопоставления с типами предметов, которые вы создаете.

...