как использовать список чувствительности в нескольких зависимых процессах

#vhdl #fpga

#vhdl #fpga

Вопрос:

Я пишу код для простого арифметического уравнения d = 1 (k * o). В моем коде есть три процесса.третий процесс зависит от второго, а второй зависит от первого.Я не могу сохранить список чувствительности правильным. Вывод не определен.

 library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity dcalc is
    Port ( k : in  STD_LOGIC_VECTOR (7 downto 0);
           o : in  STD_LOGIC_VECTOR (7 downto 0);
           e : in  STD_LOGIC_VECTOR (7 downto 0);
           d : out  STD_LOGIC_VECTOR (7 downto 0);
              clk: in  STD_LOGIC);
end dcalc;

architecture Behavioral of dcalc is
COMPONENT divd
    PORT(
         d1 : IN  std_logic_vector(7 downto 0);
         e : IN  std_logic_vector(7 downto 0);
         remi : OUT  std_logic_vector(7 downto 0);
         clk : IN  std_logic
        );
    END COMPONENT;
signal  endp1,d2,k1,o1,e1,d3: unsigned (7 downto 0);
--signal d3:std_logic_vector(7 downto 0);
begin

--process 1
process(k,o,e)
begin
if(clk'event and clk='1') then
k1<=unsigned(k);
o1<=unsigned(o);
e1<=unsigned(e);
endp1<=x"01";
end if;
end process; 

--process 2
process(endp1)
begin
if(clk'event and clk='1') then
d2<=1 (k1*o1);
end if;
end process;

--process 3
process(d2)
begin
if(clk'event and clk='1') then
d<=std_logic_vector(d2);
end if;
end process;

end Behavioral;
  

В первом процессе выполняется преобразование. Когда процесс 1 завершен, d2 должен быть вычислен в процессе 2. когда d2 вычисляется в процессе 2, d должен быть обновлен в процессе 3. вот мой тестовый код:

 LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;

ENTITY ccalctb IS
END ccalctb;

ARCHITECTURE behavior OF ccalctb IS 

    -- Component Declaration for the Unit Under Test (UUT)

    COMPONENT dcalc
    PORT(
         k : IN  std_logic_vector(7 downto 0);
         o : IN  std_logic_vector(7 downto 0);
         e : IN  std_logic_vector(7 downto 0);
         d : OUT  std_logic_vector(7 downto 0);
         clk : IN  std_logic
        );
    END COMPONENT;


   --Inputs
   signal k : std_logic_vector(7 downto 0) := (others => '0');
   signal o : std_logic_vector(7 downto 0) := (others => '0');
   signal e : std_logic_vector(7 downto 0) := (others => '0');
   signal clk : std_logic := '0';

    --Outputs
   signal d : std_logic_vector(7 downto 0);

   -- Clock period definitions
   constant clk_period : time := 10 ns;

BEGIN

    -- Instantiate the Unit Under Test (UUT)
   uut: dcalc PORT MAP (
          k => k,
          o => o,
          e => e,
          d => d,
          clk => clk
        );

   -- Clock process definitions
   clk_process :process
   begin
        clk <= '0';
        wait for clk_period/2;
        clk <= '1';
        wait for clk_period/2;
   end process;


   -- Stimulus process
   stim_proc: process
   begin        
      -- hold reset state for 100 ns.
      wait for 100 ns;  
k<=x"07";
o<=x"08";
e<=x"07";
      wait for clk_period*10;

      -- insert stimulus here 

      wait;
   end process;

END;
  

Пожалуйста, помогите.
Вот результат моделирования после изменения всего списка чувствительности процесса только на clk:

введите описание изображения здесь

Ответ №1:

В синхронном (синхронизированном) процессе список чувствительности должен содержать только часы (и, возможно, асинхронный сброс):

 process(clk)
begin
  if RISING_EDGE(clk) then
    k1<=unsigned(k);
    o1<=unsigned(o);
    e1<=unsigned(e);
    endp1<=x"01";
  end if;
end process;
  

В вашем исходном списке чувствительности изменения на входах общего триггера (или регистра, который является вектором общих триггеров) вызвали выполнение процесса, но, как мы знаем, результат не меняется немедленно, он ожидает тактового фронта. А затем, когда наступил тактовый фронт, clk его не было в списке чувствительности, поэтому симуляция проигнорировала его. В результате ваши выходные данные никогда не обновляются при моделировании.

(Напротив, синтез, как правило, игнорирует ваш список чувствительности и просто помещает логический элемент, настроенный как подлинный общий триггер, который будет правильно обновляться на фронте синхронизации)

Комментарии:

1. Я изменил список чувствительности только на clk. Но все равно выходные данные остаются неопределенными. Не могли бы вы помочь с двумя другими списками чувствительности процесса?

2. @soulz: все они являются синхронными процессами. Таким образом, все они имеют один и тот же список чувствительности, clk . Показывает ли ваш симулятор значение промежуточных сигналов? После внесения изменений в первый процесс вы должны начать видеть, что k1 , o1 , e1 изменяется, даже если конечный результат этого не делает.

3. Я изменил весь список чувствительности процесса на clk. Да, он показывает промежуточные сигналы. Тем не менее выходные данные остаются неопределенными. k1, o1, e1 остаются неопределенными.

4. » В синхронном (синхронизированном) процессе список чувствительности должен быть только тактовым (и, возможно, асинхронным сбросом) …» Это семантически неправильный английский. Список чувствительности может содержать любой сигнал, вычисленный в выражении в процессе (включая clk ). Поскольку все остальные вычисления выполняются в операторе if в последовательных операторах, управляемых вычислением условия (выражения) clk , они здесь не нужны. Здесь они законны. См. Инструкцию IEEE Sttd 1076-2008 11.3 Process и инструкцию 10.2 Wait.

5. Идея сокращения списков чувствительности (в отличие от списка, созданного с зарезервированным словом all ) заключается в снижении затрат на обработку при моделировании. Достаточно интересно, что это повлечет за собой только оценку условия оператора if и повторное выполнение неявного оператора wait, оценивающего список чувствительности, когда условие оператора if недопустимо. Едва ли больше усилий, чем вообще не возобновлять выполнение. (Процессы возобновляются в том же операторе ожидания, выполнение которого они приостановили.)