2017-02-08 155 views
0

當測試簡單的計數器實現時,GHDL仿真不會退出仿真。我的意圖是使用由主進程更改的共享變量來停止兩個併發進程。但主要過程並未停止時鐘進程。用等待語句停止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

在最近的ghdl版本中,您可以結合使用[--assert-level = ](http://ghdl.readthedocs.io/en/latest/Simulation_and_runtime.html?highlight=severity)和--ieee- asserts = 阻止來自標準包的警告,以允許在斷言語句中暫停SEVERITY_LEVEL HALT。您也可以將延遲從「等待50納秒; clk <=不是clk;如果simend = true,則等待;結束if;'進程語句自然循環。 – user1155120

+0

我建議避免時鐘殺手的開銷,而是使用@scary_jeff建議的std.env.stop。 –

回答

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之後,共享變量必須是受保護的類型。您可以看到,除非您設置編譯VHDL-93的選項,否則會在EDA Playground上發出警告。編譯VHDL-93會阻止您使用stop(或finish)過程。

1

的另一種方式,如果你有一個兼容VHDL2008模擬器是結束仿真:

use std.env.stop; 

然後你可以通過調用stop結束模擬:

stop; 

這在我看來,比等待時鐘轉換不足以導致仿真器迭代限制達到更優雅。

+0

在最近的ghdl中,這意味着使用'--std = 08'標誌進行編譯和詳細說明。 –

1

我同意@scary_jeff,std.env.stop在這裏是一個很好的答案。如果我只是調用它在一個地方,我的選擇是離開過包參考,並叫它:

std.env.stop; 

在你堅持使用舊的模擬器時,您可以使用

report "Just Kidding. Test Done." severity failure ; 

OTOH如果您需要協調結束多個進程之間的模擬併爲模擬運行添加監視計時器,則可以考慮使用Osvvm.TbUtilPkg.WaitForBarrier過程。它的使用方式如下所示。第一次調用WaitForBarrier(TestDone,5 ms)將在TestDone沒有發生的情況下在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庫。下載中還有一個完整的用戶指南。