今天给大侠带来的是一周掌握 FPGA VHDL Day 6,今天开启第六天,带来VHDL仿真。下面咱们废话就不多说了,一起来看看吧。每日十分钟,坚持下去,量变成质变。
VHDL语言
六、VHDL仿真
仿真(Simulation,也称模拟),不接触具体的硬件系统利用计算机对电路设计的逻辑行为和运行功能进行模拟检测,较大规模的VHDL系统设计的最后完成必须经历多层次的仿真测试过程,包括针对系统的VHDL行为仿真、分模块的时序仿真和硬件仿真,直至最后系统级的硬件仿真测试。
6.1 仿真激励信号的产生
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY ADDER4 IS
PORT ( a, b : IN INTEGER RANGE 0 TO 15;
c : OUT INTEGER RANGE 0 TO 15 );
END ADDER4;
ARCHITECTURE one OF ADDER4 IS
BEGIN
c <= a + b;
END one;
方法一:
① 用VHDL写一个波形信号发生器
ENTITY SIGGEN IS
PORT ( sig1 : OUT INTEGER RANGE 0 TO 15;
sig2 : OUT INTEGER RANGE 0 TO 15 );
END;
ARCHITECTURE Sim OF SIGGEN IS
BEGIN
sig1 <= 10, 5 AFTER 200 ns, 8 AFTER 400 ns;
sig2 <= 3, 4 AFTER 100 ns, 6 AFTER 300 ns;
END;
SIGGEN的仿真输出波形:
② 将波形信号发生器与ADDER4组装为一个VHDL仿真测试模块
ENTITY BENCH IS
END;
ARCHITECTURE one OF BENCH IS
COMPONENT ADDER4
PORT ( a, b : integer range 0 to 15;
c : OUT INTEGER RANGE 0 TO 15 );
END COMPONENT;
COMPONENT SIGGEN
PORT ( sig1 : OUT INTEGER RANGE 0 TO 15;
sig2 : OUT INTEGER RANGE 0 TO 15 );
END COMPONENT;
SIGNAL a, b, c : INTEGER RANGE 0 TO 15;
BEGIN
U1 : ADDER4 PORT MAP (a, b, c);
U2 : SIGGEN PORT MAP (sig1=>a, sig2=>b);
END;
SIGGEN的仿真输出波形:
利用仿真器的波形设置命令施加激励信号
force命令的格式如下:
force <信号名> <值> [<时间>][, <值> <时间> …] [-repeat <周期>]
force a 0 (强制信号的当前值为0)
force b 0 0, 1 10 (强制信号b在时刻0的值为0,在时刻10的值为1)
force clk 0 0, 1 15 –repeat 20 (clk为周期信号,周期为20)
对ADDER4的结构体进行仿真:
① 初始化仿真过程后,在命令行中输入命令:
force a 10 0, 5 200, 8 400
force b 3 0, 4 100, 6 300
SIGGEN的仿真输出波形:
② 执行RUN命令。
6.2 VHDL测试基准(Test Bench)
8位计数器源程序:
Library IEEE;
use IEEE.std_logic_1164.all;
entity counter8 is
port (CLK, CE, LOAD, DIR, RESET: in STD_LOGIC;
DIN: in INTEGER range 0 to 255;
COUNT: out INTEGER range 0 to 255 );
end counter8;
architecture counter8_arch of counter8 is
begin
process (CLK, RESET)
variable COUNTER: INTEGER range 0 to 255;
begin
if RESET='1' then COUNTER := 0;
elsif CLK='1' and CLK'event then
if LOAD='1' then COUNTER := DIN;
Else
if CE='1' then
if DIR='1' then
if COUNTER =255 then COUNTER := 0;
else COUNTER := COUNTER + 1;
end if;
else
if COUNTER =0 then COUNTER := 255;
else COUNTER := COUNTER-1;
end if;
end if;
end if;
end if;
end if;
COUNT <= COUNTER;
end process;
end counter8_arch;
测试基准文件(Test Bench):
Entity testbench is end testbench;
Architecture testbench_arch of testbench is
File RESULTS: TEXT open WRITE_MODE is "results.txt";
Component counter8
port ( CLK: in STD_LOGIC;
RESET: in STD_LOGIC;
CE, LOAD, DIR: in STD_LOGIC;
DIN: in INTEGER range 0 to 255;
COUNT: out INTEGER range 0 to 255 );
end component;
shared variable end_sim : BOOLEAN := false;
signal CLK, RESET, CE, LOAD, DIR: STD_LOGIC;
signal DIN: INTEGER range 0 to 255;
signal COUNT: INTEGER range 0 to 255;
procedure WRITE_RESULTS (
CLK,CE,LOAD,LOAD,RESET : STD_LOGIC;
DIN,COUNT : INTEGER ) is
Variable V_OUT : LINE;
Begin
write(V_OUT, now, right, 16, ps); -- 输入时间
write(V_OUT, CLK, right, 2);
write(V_OUT, RESET, right, 2);
write(V_OUT, CE, right, 2);
write(V_OUT, LOAD, right, 2);
write(V_OUT, DIR, right, 2);
write(V_OUT, DIN, right, 257);
--write outputs
write(V_OUT, COUNT, right, 257);
writeline(RESULTS,V_OUT);
end WRITE_RESULTS;
begin
UUT: COUNTER8
port map (CLK => CLK,RESET => RESET,
CE => CE, LOAD => LOAD,
DIR => DIR, DIN => DIN,
COUNT => COUNT );
CLK_IN: process
Begin
if end_sim = false then CLK <= '0';
Wait for 15 ns;
CLk <='1';
Wait for 15 ns;
Else
Wait;
end if;
end process;
STIMULUS: process
Begin
RESET <= '1';
CE <= ‘1’; --计数使能
DIR <= ‘1’; -- 加法计数
DIN <= 250; -- 输入数据 LOAD <= ‘0’; --禁止加载输入的数据 wait for 15 ns;
RESET <= '0';
wait for 1 us;
CE <= ‘0’; --禁止计数脉冲信号进入 wait for 200 ns;
CE <= '1';
wait for 200 ns;
DIR <= '0';
wait for 500 ns;
LOAD <= '1';
wait for 60 ns;
LOAD <= '0';
wait for 500 ns;
DIN <= 60;
DIR <= '1';
LOAD <= '1';
wait for 60 ns;
LOAD <= '0';
wait for 1 us;
CE <= '0';
wait for 500 ns;
CE <= '1';
wait for 500 ns;
end_sim :=true;
wait;
end process;
WRITE_TO_FILE: WRITE_RESULTS(CLK,RESET,CE,LOAD,DIR,DIN,COUNT);
End testbench_arch;
8位计数器测试基准仿真部分波形图:
Day 6 就到这里,Day 7 将带来最后一篇,带来 VHDL 综合。