2014-02-27 91 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的序列。