一周掌握 FPGA VHDL Day 6

2020-12-30 14:57:03 浏览数 (1)

大侠好,欢迎来到FPGA技术江湖,江湖偌大,相见即是缘分。大侠可以关注FPGA技术江湖,在“闯荡江湖”、"行侠仗义"栏里获取其他感兴趣的资源,或者一起煮酒言欢。

今天给大侠带来的是一周掌握 FPGA VHDL Day 6,今天开启第六天,带来VHDL仿真。下面咱们废话就不多说了,一起来看看吧。每日十分钟,坚持下去,量变成质变。

VHDL语言

六、VHDL仿真

仿真(Simulation,也称模拟),不接触具体的硬件系统利用计算机对电路设计的逻辑行为和运行功能进行模拟检测,较大规模的VHDL系统设计的最后完成必须经历多层次的仿真测试过程,包括针对系统的VHDL行为仿真、分模块的时序仿真和硬件仿真,直至最后系统级的硬件仿真测试。

6.1 仿真激励信号的产生

代码语言:javascript复制
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写一个波形信号发生器

代码语言:javascript复制
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仿真测试模块

代码语言:javascript复制
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的仿真输出波形:

  • 利用仿真器的波形设置命令施加激励信号
代码语言:javascript复制
force命令的格式如下:
force <信号名> <值> [<时间>][, <值> <时间> …] [-repeat <周期>]
代码语言:javascript复制
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的结构体进行仿真:

① 初始化仿真过程后,在命令行中输入命令:

代码语言:javascript复制
force a 10 0, 5 200, 8 400
force b 3 0, 4 100, 6 300

SIGGEN的仿真输出波形:

② 执行RUN命令。

6.2 VHDL测试基准(Test Bench)

8位计数器源程序:

代码语言:javascript复制
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):

代码语言:javascript复制
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 综合。

END

后续会持续更新,带来Vivado、 ISE、Quartus II 、candence等安装相关设计教程,学习资源、项目资源、好文推荐等,希望大侠持续关注。

大侠们,江湖偌大,继续闯荡,愿一切安好,有缘再见!

0 人点赞