描述:
我正在尝试为5状态顺序状态机生成测试平台,该状态机检测110或(2)1和(1)0的任意组合。我已经编写了代码。见下文。我在测试台上遇到了问题。我想测试所有可能的序列以及非序列的输入组合。
请给我一个好的测试台的例子,以达到我对mealy机器的需求。
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;
答案 0 :(得分:2)
这些是您的示例中的FSM代码和测试平台代码的一些问题,但主要问题是要测试FSM,您需要应用输入值的序列并检查输出。你不能只在1到0之间切换输入信号。所以,这里有一些建议:
您的程序可能如下:
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"
);
其他一些建议:
请注意,上述过程需要位于进程的声明区域内。类似的东西:
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 :(得分:1)
在返回s0
并正确检测到两个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个可能的pathes永远不会在您的测试平台中执行。
由于这个状态机的路径数量很少且数量有限,我建议进行详尽的测试,在此基本上可以循环使用上面列出的8种可能的情况;这可以通过3位计数器轻松实现。所以你要以
的形式创建一个序列reset
test-case 0 (sequence 0,0,0)
reset
test-case 1 (and so on)
这将要求您向实体state
添加重置。或者,您可以修改状态机以保留在s0
中,输入为零;那么您可以随时使用0,0,0
序列进行重置。