在测试简单的计数器实现时,VHDL仿真不会退出仿真。我的目的是使用主进程更改的共享变量来停止两个并发进程。但主要过程并不是停止时钟过程。
我的计数器实现是:
entity dff is
port(
direction, reset, clk, load : in std_logic;
din : in std_logic_vector(3 downto 0);
dout : out std_logic_vector(3 downto 0));
end dff;
architecture behav of dff is
signal temp : std_logic_vector(3 downto 0);
begin
process(clk, reset)
begin
if (reset='1') then
temp <= "0000";
elsif rising_edge(clk) then
if (load='1') then
temp <= din;
else
if (direction='0') then
temp <= std_logic_vector(unsigned(temp) + 1);
else
temp <= std_logic_vector(unsigned(temp) - 1);
end if;
end if;
end if;
dout <= temp;
end process;
end behav;
我的测试台:
architecture behav of test_tb is
component dff port(
direction, reset, clk, load : in std_logic;
din : in std_logic_vector(3 downto 0);
dout : out std_logic_vector(3 downto 0));
end component;
signal direction, reset, clk, load : std_logic := '1';
signal din, dout : std_logic_vector(3 downto 0) := x"7";
shared variable simend : boolean := false;
begin
clkk : process
begin
if simend=false then
clk <= not clk after 50 ns;
else
wait;
end if;
end process clkk;
uut : dff port map(
direction, reset, clk, load, din, dout);
stim : process
begin
reset <= '0';
wait for 1 us;
load <= '0';
wait for 2 us;
direction <= '0';
wait for 2 us;
load <= '1';
wait for 1 us;
reset <= '1';
wait for 0.5 us;
simend := true;
wait;
end process stim;
end behav;
答案 0 :(得分:1)
如果您有符合VHDL2008标准的模拟器,则结束模拟的另一种方法是:
use std.env.stop;
然后,您可以通过调用stop
来结束模拟:
stop;
在我看来,这比等待时钟转换不足导致模拟器迭代限制更加优雅。
答案 1 :(得分:1)
我同意@scary_jeff,std.env.stop在这里是一个很好的答案。如果我只是在一个地方调用它,我的首选是取消包参考,然后调用它:
std.env.stop;
如果您遇到旧模拟器,可以使用
report "Just Kidding. Test Done." severity failure ;
OTOH如果您需要协调结束多个进程之间的模拟并为您的模拟运行添加看门狗定时器,您可以考虑过程Osvvm.TbUtilPkg.WaitForBarrier。它的使用如下所示。如果TestDone在此之前没有发生,那么第一次调用WaitForBarrier(TestDone,5 ms)将在5 ms内唤醒,并在此时停止模拟。
signal TestDone : integer_barrier := 1 ;
ControlProc : process
begin
-- initialize test
SetAlertLogName("Uart1_Rx") ;
. . .
WaitForBarrier(TestDone, 5 ms) ; -- control process uses timeout
AlertIf(now >= 5 ms, "Test finished due to Time Out") ;
ReportAlerts ;
std.env.stop ;
end process ControlProc ;
CpuProc : process
begin
InitDut(. . . )_;
Toggle(CpuReady) ;
-- run numerous Cpu test transactions
. . .
WaitForBarrier(TestDone) ;
wait ;
end process CpuProc ;
UartTxProc : process
Begin
WaitForToggle(CpuReady) ;
-- run numerous Uart Transmit test transactions
. . .
WaitForBarrier(TestDone) ;
wait ;
end process UartTxProc ;
. . .
您可以在osvvm.org和github上找到OSVVM库。下载中还提供了完整的用户指南。
答案 2 :(得分:0)
我会更像这样编码你的时钟发生器:
clkk : process
begin
while simend=false loop
clk <= not clk;
wait for 50 ns;
end loop;
wait;
end process clkk;
可以在不执行clkk
语句的情况下执行wait
进程。 (行clk <= not clk after 50 ns
不会等待或阻止 - <=
是非阻塞分配。)因此,您有一个永不停止的无限循环。你可以通过运行模拟时间永远不会前进的this example on EDA Playground来看到这一点,因为EDA Playground的最大运行时间为1分钟,1分钟后超时。
另外,我建议不要为simend
使用共享变量。相反,为什么不使用信号呢?您的代码在VHDL-2000之后甚至不可兼容,因为在VHDL-2000之后,共享变量必须是受保护类型。您可以看到在EDA Playground上生成警告,除非您设置了编译VHDL-93的选项。编译VHDL-93会阻止您使用stop
(或finish
)程序。