#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 недопустимо. Едва ли больше усилий, чем вообще не возобновлять выполнение. (Процессы возобновляются в том же операторе ожидания, выполнение которого они приостановили.)