我必须使用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;
但是模拟没有显示任何结果。我不是很擅长测试平台,我真的想了解它们的工作原理,特别是时钟生成和波向量的插入!也许我可以更好地解释我的怀疑,但如果有人能给我看一个初学者的测试平台示例,那将是非常有帮助的!
由于
答案 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;
希望这会对你有所帮助。 问候。 麦克