赞
踩
编写好实现指定功能的Verilog模块后,需要对其进行仿真来验证模块的正确性,这需要用到EDA开发工具的仿真器,我们选择Xilinx公司的Vivado自带的仿真工具进行仿真。
在前面的章节已经学习了为Verilog模块编写基本的测试模块,即testbench的基本步骤和方法。本文不再赘述,直接罗列代码如下。
//用组合逻辑实现与calc_v2()函数相同的功能
module calc_wire(
input wire [31:0] a,
input wire [31:0] b,
input wire [31:0] c,
output wire [31:0] sum
);
wire [31:0] tmp;
assign tmp = (a+b) - c * 8;
assign sum = tmp;
endmodule
//用时序逻辑实现与calc_v2()函数相同的功能,计算表达式((a+b) - c * 8)的值 module calc_reg( input clk, input wire [31:0] a, input wire [31:0] b, input wire [31:0] c, output reg [31:0] sum ); //声明一个位宽32bit的reg型变量tmp reg [31:0] tmp; //alway块用于对reg型变量赋值tmp always @(posedge clk) tmp <= (a + b) - c * 8; //又一个alway块用于对reg型变量赋值sum always @(posedge clk) begin sum <= tmp; end endmodule
之前博文针对单个Verilog模块calc_reg和calc_wire分别编写了两个testbench,这是为了让大家了解组合逻辑和时序逻辑的区别。实际上,对一个模块而言,一般来说既包含组合逻辑,也会包含时序逻辑,对应的testbench也不会刻意在模块级区分组合逻辑或时序逻辑。下面,我们编写一个对calc_wire和calc_reg两个模块进行综合比对测试的模块,这样可以更好地理解组合逻辑和时序逻辑的区别。
//时间单位:1ns, 时间精度:1ps `timescale 1ns/1ps module calc_testbench(); //1. 时序逻辑需要至少一个时钟信号 // 因此,testbench必须生成一个虚拟的时钟信号 reg clk; initial begin clk = 0; forever begin #50; //50ns, 一个时钟周期为50ns*2 = 100ns clk = ~clk; end end //2. 给出待测模块需要的输入参数 reg [31:0] aa; reg [31:0] bb; reg [31:0] cc; initial begin aa = 30; bb = 40; cc = 2; #10; //wait for 10ns, less than one clk period bb = 90; #5; cc = 5; #55; aa = 20; #206; aa = 100; bb = 10; cc = 20; end //3. 调用待测试函数calc_reg,并将结果保存到整数dd中 // 将信号aa,bb,cc的值分别传递给模块的输入参数a,b,c // 并将模块运算结果通过sum_0提取出来 // 时序逻辑需要时钟信号clk也由外部输入 wire [31:0] sum_0; calc_reg dut_0( .clk(clk), //时序逻辑必须输入时钟信号 .a(aa), .b(bb), .c(cc), .sum(sum_0) ); //4. 用相同的输入数据例化组合逻辑模块calc_wire // 将信号aa,bb,cc的值分别传递给模块的输入参数a,b,c // 并将模块运算结果通过sum提取出来 wire [31:0] sum_1; calc_wire dut_1( .a(aa), .b(bb), .c(cc), .sum(sum_1) ); //5. 显示函数计算的结果用于比对和验证 initial begin #3000; $display("reg: (%d + %d) - %d * 8 = %d",aa,bb,cc,sum_0); $display("wire: (%d +%d) - %d * 8 = %d",aa,bb,cc,sum_1); $finish; end endmodule
打开Vivado,新建一个名为simulation_demo
的项目
(1)点击菜单【File】–【Project】–【New】新建工程
(2)在弹出界面点击【Next】
(3)修改项目名称和存放位置
Project Name: simulation_demo
Project Location: 选择某个容易找到的位置(/home/dayao/tmp
)
勾选Create project subdirectory
(4)点击【Next】勾选RTL Project
(5)点击【Next】直到选择Parts也就是FPGA芯片型号的界面。
(6)选择一款FPGA芯片,比如Artix-7系列芯片xc7a100tfgg484-2
(7)点击【Next】,直到【Finish】
为新项目添加可综合设计模块(Design module
)
(1)复制上面calc_wire()
和calc_reg()
模块的源码分别保存为文件calc_wire.v
和calc_reg.v
,将文件保存到项目所在文件夹下,比如文件夹/home/dayao/tmp/simulation_demo/
下。
(2)将文件calc_wire.v
和calc_reg.v
添加到Vivado工程, 注意添加文件时选择Add or Create design sources
,因为这两个文件是生成实际硬件模块的可综合设计模块。
添加仿真模块(Simulation module
)
(1) 上面calc_testbench()
模块源码的内容为calc_testbench.v
,同样放在文件夹/home/dayao/tmp/simulation_demo/
下。
(2) 将文件calc_testbench.v
添加到Vivado工程, 注意添加文件时注意选择Add or Create simulation sources
,因为这个文件是仿真文件,并不会生成实际的硬件模块。
完成上面的步骤后,应该在Vivado的源码管理界面看到如下结构
现在可以使用Vivado自带仿真器进行数据仿真了。
点击Vivado的【Flow Navigator】–【SIMULATION】-【Run Simulation】–【Run Behavioral Simulation】启动Vivado仿真界面,开始编译仿真模块并显示仿真结果,如果没有错误,应该出现下面的仿真结果界面。
注意:上面的波形图中,数据都是以十进制的形式表示的,Vivado默认的数据格式是十六进制,有时不方便观察。在仿真界面可以二进制、八进制、十进制和十六进制等多种形式表现。方法如下:
(1) 选中需要修改进制的信号(可以多选)点击右键弹出下拉菜单如下图所示;
(2) 下拉菜单中选择【Radix】–
Binary : 二进制
Hexadecimal: 十六进制
Octal: 八进制
ASCII: 字符
Unsigned Decimal: 无符号十进制数
Signed Decimal: 有符合十进制数
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。