2014-02-27 177 views
0

說明:VHDL狀態機測試平臺

我試圖生成檢測110或(2)1和(1)0。我已經寫的任意組合5狀態時序狀態機試驗檯碼。見下文。我在測試臺上遇到了問題,這是錯誤的。我想測試所有可能的序列以及輸入序列組合。

請給我一個很好的測試臺的例子,以達到我需要的粉碎機。

VHDL代碼:

library IEEE; 
use IEEE.STD_LOGIC_1164.all; 

entity state is 
port(clk, x : in std_logic; 
     z : out std_logic 
    ); 
end entity; 

architecture behavioral of state is 
type state_type is (s0,s1,s2,s3,s4); 
signal state,next_s: state_type; 

------------------------------------------------------------------------------ 

begin 
process (state,x) 
begin 
if clk='1' and clk'event then 

case state is 
when s0 => 
    if(x ='0') then 
    z <= '0'; 
    next_s <= s4; 
    else 
    z <= '0'; 
    next_s <= s1; 
    end if; 

when s1 => --when current state is "s1" 
    if(x ='0') then 
    z <= '0'; 
    next_s <= s3; 
    else 
    z <= '0'; 
    next_s <= s2; 
    end if; 

when s2 => --when current state is "s2" 
    if(x ='0') then 
    z <= '1'; 
    next_s <= s0; 
    else 
    z <= '0'; 
    next_s <= s0; 
    end if; 

when s3 => --when current state is "s3" 
    if(x ='0') then 
    z <= '0'; 
    next_s <= s0; 
    else 
    z <= '1'; 
    next_s <= s0; 
    end if; 

when s4 => --when current state is s4 
    if (x = '0') then 
    z <= '0'; 
    next_s <= s0; 
    else 
    z <= '0'; 
    next_s <= s3; 
    end if; 
end case; 
end if; 

end process; 
end behavioral; 

試驗檯代碼:

library ieee; 
use ieee.std_logic_1164.all; 

-- Add your library and packages declaration here ... 

entity state_tb is 
end state_tb; 

architecture TB_ARCHITECTURE of state_tb is 
-- Component declaration of the tested unit 
component state 
port(
    clk : in STD_LOGIC; 
    x : in STD_LOGIC; 
    z : out STD_LOGIC); 
end component; 

-- Stimulus signals - signals mapped to the input and inout ports of tested entity 
signal clk : STD_LOGIC; 
signal x : STD_LOGIC; 
-- Observed signals - signals mapped to the output ports of tested entity 
signal z : STD_LOGIC; 

-- Add your code here ... 

begin 

-- Unit Under Test port map 
UUT : state 
    port map (
     clk => clk, 
     x => x, 
     z => z 
    ); 

-- CLOCK STIMULI 
CLOCK: process 
begin 
CLK <= not clk after 20 ns; 
wait for 40 ns; 
end process; 

-- X input STIMULI 
X_Stimuli: process 
begin 
X <= not x after 40 ns; 
wait for 80 ns; 
end process; 

end TB_ARCHITECTURE; 

configuration TESTBENCH_FOR_state of state_tb is 
for TB_ARCHITECTURE 
    for UUT : state 
     use entity work.state(behavioral); 
    end for; 
end for; 
end TESTBENCH_FOR_state; 
+1

結核病以何種方式出錯?當你解決這個問題時會發生什麼? –

+0

我相信我的刺激是錯誤的,因爲當我繪製我的波形我沒有得到(2)1和(1)0的所有可能的組合。你會有一個更好的刺激的建議?我不確定你的意思是解決這個問題嗎? – user2444074

回答

2

這些都是一些問題,無論是FSM代碼,並在你的榜樣測試平臺的代碼,但主要問題是測試您不需要應用輸入值的序列並檢查輸出。你不能只是切換在1和0之間所以你的輸入信號,這裏的一些建議:

  • 首先,你必須決定是否要一個通用FSM檢測任何輸入序列,或 FSM檢測只有一個序列(您的代碼顯示第二個選項)
  • 您需要考慮測試中的時間維度。你的是一個時鐘電路,這意味着每個測試都需要幾個時鐘週期。
  • 測試所有可能的輸入序列,我建議你創建一個需要作爲參數的過程:
    • 的4個輸入值序列的FSM(可能是一個std_logic_vector)
    • 的4個輸出值序列你希望看到
    • (可選)4的序列指出你所期望的FSM會經過

你的程序可能看起來像:

procedure test_sequence(
     input_sequence: std_logic_vector; 
     expected_output_sequence: std_logic_vector 
    ) is begin 
     for i in input_sequence'range loop 
      x <= input_sequence(i); 
      wait until rising_edge(clk); 
      assert z = expected_output_sequence(i); 
     end loop; 
    end; 

然後,在你的主要測試過程中,你可以測試一個序列有:

test_sequence(
    input_sequence => "110", 
    expected_output_sequence => "001" 
); 

其他一些建議:

  • 您應該添加一個復位信號,以使測試更加簡單,並防止模擬和合成之間的不匹配
  • 您的情況不需要配置,您可以將其從代碼中刪除
  • 您的FSM的代碼是不完整的,因爲你永遠不更新當前的狀態
  • 在像您使用的是一個測試平臺,您需要初始化用作輸入到DUT(x和CLK)

的信號請注意,上述過程需要位於流程的聲明區域內。例如:

main_test_process: process is 

    procedure test_sequence(
     input_sequence: std_logic_vector; 
     expected_output_sequence: std_logic_vector 
    ) is begin 
     for i in input_sequence'range loop 
      x <= input_sequence(i); 
      wait until rising_edge(clk); 
      assert z = expected_output_sequence(i); 
     end loop; 
    end; 

begin 

    test_sequence(input_sequence => "000", expected_output_sequence => "000"); 
    test_sequence(input_sequence => "001", expected_output_sequence => "000"); 
    -- (add any other input sequences here...) 
    test_sequence(input_sequence => "110", expected_output_sequence => "001"); 

    std.env.finish; 

end process; 

應該工作。

1

在返回s0之前,您的狀態機有2或3個步驟的以下可能的週期,並正確檢測到兩個1的順序。

Case (x1,x2,x3) States (z1,z2,z3) 
    0 0,0,0  4,0,... 0,0,... (starts again at s0)    
    1 0,0,1  4,0,... 0,0,... (starts again at s0)    
    2 0,1,0  4,3,0 0,0,0  (covered by your TB)   
    3 0,1,1  4,3,0 0,0,1    
    4 1,0,0  1,3,0 0,0,0    
    5 1,0,1  1,3,0 0,0,1  (covered by your TB)   
    6 1,1,0  1,2,0 0,0,1    
    7 1,1,1  1,2,0 0,0,0    

當我看到你創建你的刺激如下

  __ __ __ __ __ 
clk __| |__| |__| |__| |__| |__... 
      _____  _____  _____ 
x  _____|  |_____|  |_____|  |... 

即因爲在x = 1的每一部分中,您只有一個上升時鐘,因此您只能用0101010 ...模式測試順序,您的狀態機將在上面標記的兩條路徑之一上進行測試。這意味着其他6個可能的路徑永遠不會在您的測試平臺中執行。

由於此狀態機的路徑數量有限且數量有限,因此我建議您進行詳盡的測試,您將基本上循環上述8種可能的情況;這可以使用3位計數器輕鬆實現。所以,你會在形式

reset 
test-case 0 (sequence 0,0,0) 
reset 
test-case 1 (and so on) 

這將要求您重置添加到實體state創建序列。或者,您可以修改您的狀態機,使其保持在s0的零輸入;那麼您可以隨時重置0,0,0的序列。