为什么这段代码在 vhdl 模拟中什么都没有?(测试平台和设计)
Why isnt this code in vhdl simulating anything?(testbench and design)
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity D_flip_flop is
port (
D : in STD_LOGIC;
Q : inout STD_LOGIC;
Q_tonos : out STD_LOGIC;
CLK : in STD_LOGIC;
RST : in STD_LOGIC
);
end D_flip_flop;
architecture Behavioral of D_flip_flop is
begin
process_flip_flip: process
begin
wait until CLK'EVENT AND CLK = '1';
if(RST='1') then
Q <= '0';
else
Q <= D;
end if;
Q_tonos <= not Q;
end process process_flip_flip;
end Behavioral;
-------------------------
--testbench
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY test_flip_flop IS
END test_flip_flop;
ARCHITECTURE tb OF test_flip_flop IS
COMPONENT D_flip_flop
PORT(
D : IN std_logic;
Q : INout std_logic;
Q_tonos : OUT std_logic;
CLK : IN std_logic;
RST : IN std_logic
);
END COMPONENT;
signal D : std_logic ;
signal CLK : std_logic ;
signal RST : std_logic ;
signal Q : std_logic;
signal Q_tonos : std_logic;
constant CLK_period : time := 10 ns;
signal stopClk : boolean;
BEGIN
-- Instantiate the Unit Under Test (UUT)
dut: D_flip_flop PORT MAP (
D => D,
Q => Q,
Q_tonos => Q_tonos,
CLK => CLK,
RST => RST
);
CLK_process :process
begin
while not stopClk loop
CLK <= '0';
wait for CLK_period/2;
CLK <= '1';
wait for CLK_period/2;
end loop;
wait;
end process CLK_process;
-- Stimulus process
stim_proc: process
begin
-- insert stimulus here
D <= '0';
RST <= '1';
wait for 100 ns;
D <= '0';
RST <= '0';
wait for 100 ns;
D <= '1';
RST <= '0';
wait for 100 ns;
D <= '1';
RST <= '0';
wait for 100 ns;
wait;
end process;
END;
我认为您的测试台中缺少一行:
D <= '1';
RST <= '0';
wait for 100 ns;
stopClk <= TRUE; -- add this line
wait;
end process;
END;
http://www.edaplayground.com/x/56Mm
这样,当测试完成后,时钟stopClk
信号关闭时钟发生器,模拟结束。它完成是因为它达到了一种叫做 event starvation 的状态。每次执行包含信号分配的代码行时,都会将一个事件添加到模拟器 事件队列 (其 "to do list")。如果您创建了一种没有此类行继续执行的情况,则事件队列将变为空。这是事件饥饿。模拟器检测到这一点并且模拟停止。 (你想想,它还能做什么?)
如果没有这条额外的线,模拟将永远运行,因为时钟生成过程永远执行信号分配,所以事件队列永远不会为空。
不是真正的答案,但是:考虑使用 if rising_edge(CLK) 或者 if CLK='1' and CLK'event 而不是 等到 。并不是所有的合成工具都支持这种代码,而且在专业领域很少见到它 ;)
p.s。 stopClk 信号未被驱动(或者是它?)你的 TB 时钟是通过它启用的,但我想它仍然是 'u'整个模拟。除非强制模拟。
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity D_flip_flop is
port (
D : in STD_LOGIC;
Q : inout STD_LOGIC;
Q_tonos : out STD_LOGIC;
CLK : in STD_LOGIC;
RST : in STD_LOGIC
);
end D_flip_flop;
architecture Behavioral of D_flip_flop is
begin
process_flip_flip: process
begin
wait until CLK'EVENT AND CLK = '1';
if(RST='1') then
Q <= '0';
else
Q <= D;
end if;
Q_tonos <= not Q;
end process process_flip_flip;
end Behavioral;
-------------------------
--testbench
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY test_flip_flop IS
END test_flip_flop;
ARCHITECTURE tb OF test_flip_flop IS
COMPONENT D_flip_flop
PORT(
D : IN std_logic;
Q : INout std_logic;
Q_tonos : OUT std_logic;
CLK : IN std_logic;
RST : IN std_logic
);
END COMPONENT;
signal D : std_logic ;
signal CLK : std_logic ;
signal RST : std_logic ;
signal Q : std_logic;
signal Q_tonos : std_logic;
constant CLK_period : time := 10 ns;
signal stopClk : boolean;
BEGIN
-- Instantiate the Unit Under Test (UUT)
dut: D_flip_flop PORT MAP (
D => D,
Q => Q,
Q_tonos => Q_tonos,
CLK => CLK,
RST => RST
);
CLK_process :process
begin
while not stopClk loop
CLK <= '0';
wait for CLK_period/2;
CLK <= '1';
wait for CLK_period/2;
end loop;
wait;
end process CLK_process;
-- Stimulus process
stim_proc: process
begin
-- insert stimulus here
D <= '0';
RST <= '1';
wait for 100 ns;
D <= '0';
RST <= '0';
wait for 100 ns;
D <= '1';
RST <= '0';
wait for 100 ns;
D <= '1';
RST <= '0';
wait for 100 ns;
wait;
end process;
END;
我认为您的测试台中缺少一行:
D <= '1';
RST <= '0';
wait for 100 ns;
stopClk <= TRUE; -- add this line
wait;
end process;
END;
http://www.edaplayground.com/x/56Mm
这样,当测试完成后,时钟stopClk
信号关闭时钟发生器,模拟结束。它完成是因为它达到了一种叫做 event starvation 的状态。每次执行包含信号分配的代码行时,都会将一个事件添加到模拟器 事件队列 (其 "to do list")。如果您创建了一种没有此类行继续执行的情况,则事件队列将变为空。这是事件饥饿。模拟器检测到这一点并且模拟停止。 (你想想,它还能做什么?)
如果没有这条额外的线,模拟将永远运行,因为时钟生成过程永远执行信号分配,所以事件队列永远不会为空。
不是真正的答案,但是:考虑使用 if rising_edge(CLK) 或者 if CLK='1' and CLK'event 而不是 等到 。并不是所有的合成工具都支持这种代码,而且在专业领域很少见到它 ;)
p.s。 stopClk 信号未被驱动(或者是它?)你的 TB 时钟是通过它启用的,但我想它仍然是 'u'整个模拟。除非强制模拟。