使用wait语句停止VHDL仿真

时间:2017-02-08 05:41:53

标签: vhdl

在测试简单的计数器实现时,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;

3 个答案:

答案 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)程序。