0

描述:

我正在尝试为检测 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;
4

2 回答 2

2

这些是您示例中的 FSM 代码和测试平台代码的一些问题,但主要问题是要测试 FSM,您需要应用一系列输入值并检查输出。您不能只在 1 和 0 之间切换输入信号。所以,这里有一些建议:

  • 首先,您必须决定是需要检测任何输入序列的通用 FSM,还是只检测单个序列的 FSM(您的代码显示第二个选项)
  • 您需要在测试中考虑时间维度。你的是一个时钟电路,这意味着每次测试都需要几个时钟周期。
  • 为了测试每个可能的输入序列,我建议您创建一个以参数为参数的过程:
    • FSM 的 4 个输入值序列(可能是 std_logic_vector)
    • 您希望看到的 4 个输出值的序列
    • (可选)您期望 FSM 将经历的 4 个状态的序列

您的程序可能如下所示:

    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;

应该管用。

于 2014-03-01T12:14:23.187 回答
1

在返回并正确检测到两个s 的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

于 2014-03-01T12:18:46.737 回答