当前位置:   article > 正文

【0基础学会Verilog】004. 学会使用Vivado自带仿真器

vivado自带仿真

编写好实现指定功能的Verilog模块后,需要对其进行仿真来验证模块的正确性,这需要用到EDA开发工具的仿真器,我们选择Xilinx公司的Vivado自带的仿真工具进行仿真。


1. 编写仿真模块

在前面的章节已经学习了为Verilog模块编写基本的测试模块,即testbench的基本步骤和方法。本文不再赘述,直接罗列代码如下。

  • 组合逻辑版calc()模块
//用组合逻辑实现与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

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 时序逻辑版calc()模块

//用时序逻辑实现与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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 综合测试模块

之前博文针对单个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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78

2. 建立Vivado工程并添加Verilog文件

  • 打开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.vcalc_reg.v,将文件保存到项目所在文件夹下,比如文件夹/home/dayao/tmp/simulation_demo/下。
    (2)将文件calc_wire.vcalc_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的源码管理界面看到如下结构
在这里插入图片描述


3. 使用Vivado自带仿真器仿真

现在可以使用Vivado自带仿真器进行数据仿真了。

点击Vivado的【Flow Navigator】–【SIMULATION】-【Run Simulation】–【Run Behavioral Simulation】启动Vivado仿真界面,开始编译仿真模块并显示仿真结果,如果没有错误,应该出现下面的仿真结果界面。
在这里插入图片描述
注意:上面的波形图中,数据都是以十进制的形式表示的,Vivado默认的数据格式是十六进制,有时不方便观察。在仿真界面可以二进制、八进制、十进制和十六进制等多种形式表现。方法如下:

(1) 选中需要修改进制的信号(可以多选)点击右键弹出下拉菜单如下图所示;
(2) 下拉菜单中选择【Radix】–

在这里插入图片描述

Binary : 二进制
Hexadecimal: 十六进制
Octal: 八进制
ASCII: 字符
Unsigned Decimal: 无符号十进制数
Signed Decimal: 有符合十进制数


4. 扩展练习

  1. 编写一个计数器模块(couter),该计数器从0开始计数,计数到255时返回0,再次开始计数。
  2. 为这个**计数器模块(couter)**编写testbench,验证模块的功能是否正确。
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/431480
推荐阅读
相关标签
  

闽ICP备14008679号