我一直试图写一个模拟拨动式触发器一段时间了。我在这里找不到代码有什么问题,但出于某种原因,当我模拟它时,输出会在时钟的下降沿而不是上升沿进行切换。是否有我错过的错误?
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity TFF is
Port (EN, T, CLK : in std_logic;
Q : out std_logic);
end TFF;
architecture Behavioral of TFF is
signal temp_q : std_logic := '0';
begin
proc1 : process (EN, T, CLK)
begin
if EN = '1' then
if rising_edge(CLK) then
if T = '1' then temp_q <= (not temp_q);
else temp_q <= temp_q; end if;
end if;
else Q <= temp_q; end if;
Q <= temp_q;
end process proc1;
end Behavioral;
答案 0 :(得分:2)
它在下降沿切换,因为在rising_edge中它使用temp_q
的旧值(记住,分配给信号不是一次完成,它是调度的,并且在过程结束时完成),并且因为你有rising_edge()
之外的作业,如果它是在下降边缘完成的。
如果您不在rising_edge()
以外的任何内容。每次时钟边沿发生变化时,此过程都会启动,因此也会在下降沿发生。除灵敏度列表中的CLK外,您也不需要任何其他内容。分配给Q
也不必在过程中完成 - 它可以同时完成。您还可以将temp_q <= temp_q;
移动到流程正文的开头,以便始终对其进行调度,如果T = '0'
,它将被反转。最后,您应首先检查rising_edge,然后检查时钟启用。
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity TFF is
Port (EN, T, CLK : in std_logic;
Q : out std_logic);
end TFF;
architecture Behavioral of TFF is
signal temp_q : std_logic := '0';
begin
Q <= temp_q;
proc1 : process (CLK)
begin
if rising_edge(CLK) then
if EN = '1' then
temp_q <= temp_q;
if T = '1' then
temp_q <= not temp_q;
end if;
end if;
end if;
end process proc1;
end Behavioral;
答案 1 :(得分:0)
每当调用进程时,您都会分配Q <= temp_q
,这意味着敏感列表中的一个信号会发生变化。这意味着您分别在时钟的上升沿分配temp_q <= not(temp_q)
或temp_q <= temp_q
,然后在下降沿将该值分配给Q,因为这是下次运行该过程时的情况。当它被异步合成时,事物看起来会更奇怪。
我不是百分百肯定你想要达到的目标。如果您想要完整的同步设计,那么if rising_edge(CLK)
应该是最重要的IF语句。此外,灵敏度列表中不需要T信号,因为此信号的变化不会直接影响任何输出信号。