用于反应计时器设计VHDL的Testbench

时间:2018-04-14 16:03:39

标签: vhdl modelsim test-bench

我必须使用modelsim测试这个组件:

    COMPONENT part5 
PORT ( CLOCK_50,KEY0,KEY3 : IN STD_LOGIC;
       SW: IN STD_LOGIC_VECTOR (7 DOWNTO 0);
       HEX3,HEX2,HEX1,HEX0: OUT STD_LOGIC_VECTOR (6 DOWNTO 0);
       LEDR : OUT STD_LOGIC_VECTOR (1 DOWNTO 0)
      );
END COMPONENT;

它将在altera DE2上实现。 在KEY0进入逻辑电平1后,它应该与时钟(CLOCK_50)一起工作,计数时钟周期,直到它到达SW上插入的数字(7 DOWNTO 0),此时它将打开红色LED:LEDR。从LEDR打开时,四个十六进制显示(HEX0,HEX1,HEX2和HEX3)开始以1 ms的间隔计数。我必须尽快按下按钮KEY3(在DE2板上),直到达到SW(7 DOWNTO 0)中显示的值:红灯熄灭并显示停止计数。

我试过这个:

LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;` 

ENTITY tb_part5 IS 
END ENTITY;

ARCHITECTURE beha OF tb_part5 IS

COMPONENT part5 
PORT ( CLOCK_50,KEY0,KEY3 : IN STD_LOGIC;
       SW: IN STD_LOGIC_VECTOR (7 DOWNTO 0);
       HEX3,HEX2,HEX1,HEX0: OUT STD_LOGIC_VECTOR (6 DOWNTO 0);
       LEDR : OUT STD_LOGIC_VECTOR (1 DOWNTO 0)
      );
END COMPONENT;

SIGNAL clk,key,rst: STD_LOGIC:='0';--inputs
SIGNAL switch: STD_LOGIC_VECTOR (7 DOWNTO 0); 
SIGNAL led,led1: STD_LOGIC;--outputs
SIGNAL dec0,dec1,dec2,dec3 : STD_LOGIC_VECTOR (6 DOWNTO 0);

BEGIN
switch<="00001010";

PROCESS --clock
BEGIN
clk<='1' AFTER 10 ns ;
clk<='0' AFTER 20 ns ;
END PROCESS;

PROCESS --reset
BEGIN
rst<='0';
WAIT FOR 20 ns;
rst<='1';
WAIT;
END PROCESS;

PROCESS
BEGIN
IF led='1' THEN 
   key<= '1';
   WAIT FOR 20 ns;
   key<='0';
   WAIT FOR 20 ns;
ELSE 
   key<='0';
END IF;
END PROCESS;



DUT : part5 PORT MAP (CLOCK_50=>clk, KEY0=>rst,KEY3=>key,SW=>switch,HEX3=>dec3,HEX2=>dec2,HEX1=>dec1,HEX0=>dec0,LEDR(0)=>led,LEDR(1)=>led1);
END beha;

但是模拟没有显示任何结果。我不是很擅长测试平台,我真的想了解它们的工作原理,特别是时钟生成和波向量的插入!也许我可以更好地解释我的怀疑,但如果有人能给我看一个初学者的测试平台示例,那将是非常有帮助的!

由于

1 个答案:

答案 0 :(得分:1)

测试平台的初学者架构非常简单。您只需5个进程即可测试很多组件(包括clk和重置过程)。当您创建测试平台时,通常会为您的被测设计(DUT)生成至少一个时钟和一个复位。对于这些过程,您可以保留以下内容,这应该适用于所有单时钟设计(无论重置是同步还是异步都无关紧要)。然后,您将创建一个刺激过程。此过程将允许您为DUT生成数据(您将影响连接到DUT的信号)。此过程可以定义模拟的结束。如果要测试没有修改信号的序列(DUT输入),可以设置一些信号并等待100000 ns。

生成刺激后,您可以启动模拟并手动验证您的DUT输出,但这不是最好的方法(可能在您的情况下,但不是在更大的设计中)。控制输出完整性的最简单方法是生成引用。此参考是您的设计的预期反应。例如:如果你想实现一个等待100个时钟周期的设计。您将创建输出的参考信号,但您不必使用可以合成的VHDL。您可以访问所有VHDL功能(等待,等待,等等......)。

最后,您将拥有最后一个进程,即检查程序。这个将比较dut输出和参考,以定义您的设计中是否存在某些错误。

不要忘记在所有过程中放置​​一个等待语句(取决于每个例子的end_sim_s),以便在模拟外翻时停止模拟

这是一个空的测试台结构:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity tb_part5 is
    port (
     -- no IO for test bench
    );
end entity;

architecture beha of tb_part5 is

    ---------------
    -- Constants --
    ---------------
    constant CLOCK_PERIOD : time := 10 ns;  -- e.g.

    ------------------------
    -- Test bench signals --
    ------------------------
    signal clk_sti   : std_logic := '0';
    signal rst_sti   : std_logic := '1'; -- !!! activ high !!!
    -- end of sim flag
    signal end_sim_s : boolean   := false;

begin

    ----------------------
    -- Clock generation --
    ----------------------
    process
    begin
        clk_sti <= '1';
        wait for CLOCK_PERIOD/2;
        clk_sti <= '0';
        wait for CLOCK_PERIOD/2;
        if end_sim_s = true then
            wait;                       -- end of simulation
        end if;
    end process;

    --------------------
    -- Reset sequence --
    --------------------
    process
    begin
        rst <= '1';
        wait for 2*CLOCK_PERIOD;
        rst <= '0';
        wait;
    end process;

    ----------------------
    -- Stimulus process --
    ----------------------
    process
    begin
        -- default values for DUT inputs

        -- wait end of reset sequence
        wait until (rst_sti = '0');

        -- do something

        -- end of simulation
        end_sim_s <= true;
        wait;
    end process;

    -----------------------
    -- Reference process --
    -----------------------

    -------------------
    -- Check process --
    -------------------

    -----------------------
    -- DUT instanciation --
    -----------------------

end beha;

对于您的测试平台,我建议您使用以下架构。但是你必须意识到你的测试台没有验证任何东西。

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity tb_part5 is
port (
    -- no IO in test bench
    );
end entity;

architecture beha of tb_part5 is

    ---------------
    -- Constants --
    ---------------
    constant CLOCK_PERIOD : time := 10 ns;  -- e.g.

    -----------------------
    -- Internals signals --
    -----------------------
    signal clk, key, rst          : std_logic := '0';  --inputs
    signal switch                 : std_logic_vector (7 downto 0);
    signal led, led1              : std_logic;         --outputs
    signal dec0, dec1, dec2, dec3 : std_logic_vector (6 downto 0);

    -- test bench signals
    signal end_sim_s : boolean := false;


begin

    switch <= "00001010";

    ----------------------
    -- Clock generation --
    ----------------------
    process
    begin
        clk <= '0';
        wait for CLOCK_PERIOD/2;
        clk <= '1';
        wait for CLOCK_PERIOD/2;
        if end_sim_s = true then
            wait;                       -- end of simulation
        end if;
    end process;

    --------------------
    -- Reset sequence --
    --------------------
    process
    begin
    -- TIPS : if you want to be more efficient you should us a norm to
    -- define your signal. A reset signal activ low can be called nRst for
    -- exemple. Maybe actually you have an activ low reset but maybe not.
    -- This exemple show a reset activ low sequence
        rst <= '0';
        wait for 2*CLOCK_PERIOD;
        rst <= '1';
        wait;
    end process;

    ---------------------
    -- Your TEST bench --
    ---------------------
    -- this part do the same thing that you were asking.    
    process
    begin
        -- the if statement in the previous version is not a good thing to do.
        -- in fact, you want your process to wait until an event.

        -- initial state (default value)
        key <= '0';

        -- wait until the end of reset sequence (just in case)
        wait until (rst = '1');         -- e.g.

        -- wait until DUT assert led
        wait until (led = '1');         -- e.g.

        -- start your sequence
        key <= '1';
        wait for 20 ns;
        key <= '0';
        wait for 20 ns;

        -- here you have 2 choices. let the process iterate a second time or just
        -- end the simulation at this moment
        -- stop here
        -- notify the others process the end of simulation
        end_sim_s <= true;
        -- block process
        wait;
    end process;

    -----------------------
    -- DUT instanciation --
    -----------------------
    DUT : part5 port map (
        CLOCK_50 => clk,
        KEY0     => rst,
        KEY3     => key,
        SW       => switch,
        HEX3     => dec3,
        HEX2     => dec2,
        HEX1     => dec1,
        HEX0     => dec0,
        LEDR(0)  => led,
        LEDR(1)  => led1
        );

end beha;

希望这会对你有所帮助。 问候。 麦克