跳转至

Vivado 使用入门

第六章 Vivado使用入门

计算机组成原理的实验使用的是Vivado的开发环境2019.2版本。Vivado开发环境非常庞大,只需要安装最基础的WebPack免费版本即可。免费版本包含了生成实验板所需要的比特流bit文件的生成工具。

需要注意的是Vivado不支持中文目录,务必不要安装到中文目录下使用,也不要将Vivado的项目放到中文目录下面,否则会综合不过。实验平台后台的自动测试工具只支持Vivado 2019.2的版本,不支持旧的版本,也不支持新的版本,请仅使用2019.2的版本实验。

创建项目

注意,这里的创建项目的工作是给同学们演示一个正常的Vivado项目的流程。实际上在实验样例代码中已经包含了一个专门针对实验环境的顶层项目thinpad_top。后面的第九章有关于顶层项目的详细讨论和介绍。实验只需要依赖顶层项目工作即可。这里是Vivado使用入门,让大家熟悉一下环境,以及开发的各个流程。真正的实验需要复制顶层项目,针对不同的实验在顶层项目中增加源代码。

首次进入Vivado的界面:

创建新的一个项目:

输入项目名称:

选择项目的性质:

选择型号芯片xc7a100tfgg676-2L型号芯片,这个芯片是实验平台上的FPGA芯片:

项目情况简介:

创建完成空白的项目:

编写代码

添加源文件:

创建新的文件:

输入clock为创建文件的名称:

创建完文件,点击finish:

设置模块的输入输出:

添加完成,并且可以查看源代码:

在源代码部分输入以下源代码,这是一段计数器的代码:

module clock(
    input wire clock,
    input wire rst,
    output reg[6:0] seg1,
    output reg[6:0] seg2
    );

    reg[3:0] cnt_L = 4'b0000;
    reg[3:0] cnt_H = 4'b0000;
    reg[25:0] cnt = 26'b00000000000000000000000000;
    reg clk_out;
    reg[3:0] tmp_H = 4'b0000;
    reg[3:0] tmp_L = 4'b0000;

    always @ (posedge clock) begin
        cnt <= cnt + 1;
        if(cnt ==  26'b00_0000_0000_0000_0000_0000_0000)
            clk_out <= 0;
        if(cnt == 26'b10_1111_1010_1111_0000_1000_0000)   //计数50000000次,1秒钟
            begin
                cnt <= 26'b00_0000_0000_0000_0000_0000_0000;
                clk_out <= 1;
            end
    end

    always @(posedge clk_out or posedge rst) begin  //将秒数转换成输出的格式
        if(rst == 1)
            begin
                tmp_H = 4'b0000;
                tmp_L = 4'b0000;
            end
        else
            begin
                tmp_L = cnt_L + 1;
                if(tmp_L > 4'b1001)
                begin
                    tmp_L = 4'b0000;
                    tmp_H = cnt_H + 1;
                    if (tmp_H > 4'b1001)
                        tmp_H = 4'b0000;
                end
            end
        cnt_L = tmp_L;
        cnt_H = tmp_H;
    end

    always @(cnt_L) begin //将秒表的个位数输出到数码管
        case(cnt_L)
            4'b0000: seg1 = 7'b0111111;
            4'b0001: seg1 = 7'b0000110;
            4'b0010: seg1 = 7'b1011011;
            4'b0011: seg1 = 7'b1001111;
            4'b0100: seg1 = 7'b1100110;
            4'b0101: seg1 = 7'b1101101;
            4'b0110: seg1 = 7'b1111101;
            4'b0111: seg1 = 7'b0000111;
            4'b1000: seg1 = 7'b1111111;
            4'b1001: seg1 = 7'b1101111;
            default: seg1 = 7'b0000000;
        endcase
    end

    always @(cnt_H) begin //将秒表的十位数输出到数码管
        case(cnt_H)
            4'b0000: seg2 = 7'b0111111;
            4'b0001: seg2 = 7'b0000110;
            4'b0010: seg2 = 7'b1011011;
            4'b0011: seg2 = 7'b1001111;
            4'b0100: seg2 = 7'b1100110;
            4'b0101: seg2 = 7'b1101101;
            4'b0110: seg2 = 7'b1111101;
            4'b0111: seg2 = 7'b0000111;
            4'b1000: seg2 = 7'b1111111;
            4'b1001: seg2 = 7'b1101111;
            default: seg2 = 7'b0000000;
        endcase
    end
endmodule

输入代码之后的情况:

上述的代码就是一个秒表计数器的代码。这个秒表计数器会在每秒计数一次,99秒后回到0开始重新计数。系统的输入为外部时钟的输入,系统的输出为两个七段数码管。由于外部的时钟频率非常高,在代码中依据1秒的时间要求进行延迟。

代码综合

写完代码之后,将经过综合,实现,生成比特流的过程,最终生成可以加载到FPGA上面能用的比特流文件。下面是各个流程的含义。

综合:Verilog语言翻译为门电路的表示,使用LUT,FF(flip-flop,寄存器)方式来完成门电路的构成等。

实现:考虑连线,各个元器件的放置,连线优化等。

生成bitstream:生成最终的可以使用的比特流文件,可以被加载到FPGA上使用。

下面是代码经过综合,实现和生成比特流的各个过程。实际工作中,可以直接点击generate bitstream选项来直接生成比特流。Vivado软件会自动调用上面的三个过程。

选择综合选项:

开始综合:

综合进行中:

综合完成:

增加仿真代码与前仿真

右键点击simulation sources,可以增加仿真的代码:

通过上述的向导工具,创建一个test.v的测试文件。(创建过程和上述创建clock.v的过程类似,可以先不用指定输入输出,只需要创建出文件即可。)

将test.v中的源代码修改如下:

`timescale 1ns / 1ps
module test();
    reg clock;
    reg rst;
    wire[6:0] seg1, seg2;

    initial begin
        clock = 0;
        rst = 1;
        #100;
        rst = 0;
        forever #10 clock = ~clock;
    end

    clock test_clock(
        .clock(clock),
        .rst(rst),
        .seg1(seg1),
        .seg2(seg2)
    );
endmodule

上述代码的主要工作是为模块加入输入信号,创建了一个50MHz的时钟并加入了一个复位信号。实际的硬件电路也需要这样的两个信号作为输入。

可以开始仿真(右边是仿真信号的情况):

左边的Run Simulation那里可以启动仿真。

上面的菜单上有控制仿真开始和结束的按钮。

上面的仿真都是行为仿真,也称为前仿真,这种仿真没有将信号延时加入,离实际的硬件还有一定的差距。功能仿真可以用来验证设计的功能,但不能用来检查严格的时序,而时序仿真(后仿真)则是将延时加入,更接近实际硬件运行。前仿真比较快,后仿真更费时间。在开发的过程中,可以先利用前仿真来查找功能上的错误,再用后仿真调时序。

在Vivado中,进行行为仿真的时候,直接点击行为仿真就可以直接反映修改后的代码仿真情况。但是,如果需要综合后仿真,或者实现后仿真,则需要进行综合或者实现后才有正确的仿真结果。这一点需要注意,即在进行后仿真的时候需要先进行综合和实现。

添加约束

添加约束的意思是将已经完成的模块与板子上的输入输出管脚对应起来,这样生成的最后的比特流文件才能够在板子上真正执行。

开始定义约束,按下define target按钮:

创建约束文件:

编辑clock.xdc文件:

将下面的约束内容写入到clock.xdc中:

# Clock
set_property -dict {PACKAGE_PIN D18 IOSTANDARD LVCMOS33} [get_ports clock]; #50MHz main clock in
set_property -dict {PACKAGE_PIN F22 IOSTANDARD LVCMOS33} [get_ports rst]; #BTN6

# DPY0
set_property IOSTANDARD LVCMOS33 [get_ports seg1[*]]
set_property PACKAGE_PIN F15 [get_ports {seg1[2]}]
set_property PACKAGE_PIN H15 [get_ports {seg1[3]}]
set_property PACKAGE_PIN G15 [get_ports {seg1[4]}]
set_property PACKAGE_PIN H16 [get_ports {seg1[1]}]
set_property PACKAGE_PIN H14 [get_ports {seg1[0]}]
set_property PACKAGE_PIN G19 [get_ports {seg1[5]}]
set_property PACKAGE_PIN J8 [get_ports {seg1[6]}]

# DPY2
set_property IOSTANDARD LVCMOS33 [get_ports seg2[*]]
set_property PACKAGE_PIN G8 [get_ports {seg2[2]}]
set_property PACKAGE_PIN G7 [get_ports {seg2[3]}]
set_property PACKAGE_PIN G6 [get_ports {seg2[4]}]
set_property PACKAGE_PIN D6 [get_ports {seg2[1]}]
set_property PACKAGE_PIN E5 [get_ports {seg2[0]}]
set_property PACKAGE_PIN F4 [get_ports {seg2[5]}]
set_property PACKAGE_PIN G5 [get_ports {seg2[6]}]

set_property CFGBVS VCCO [current_design]
set_property CONFIG_VOLTAGE 3.3 [current_design]

其中"set_property PACKAGE_PIN"命令表示设置管脚约束,这类约束是与电路板连线相关的。实验平台上有各种外围电路连接到FPGA不同的管脚上,进行实验的时候需要选择Verilog中不同的信号与FPGA哪些管脚进行绑定。

完整的管脚绑定关系可以参考thinpad_top的项目模板。

最后两条命令"set_property CFGBVS"和"set_property CONFIG_VOLTAGE"设置了FPGA配置电路的供电方式,它们由电路板硬件设计得出,在各个实验中不需要更改。

运行实现并生成比特流bit文件

运行实现,并生成比特流(bitstream)bit文件:

左边是实现,中间是选择生成bit文件,bit文件为最终可以装载到FPGA中的文件。

成功生成bit文件:

Vivado可以随时查看工作状态的提示:

在Vivado的右上角可以看到当前Vivado后台综合,实现,生成bitstream的进度情况。

登录在线实验平台,上传bit文件:

上传并开始,就可以看到计数器程序:

每一个开发板都会把特定的FPGA管脚与特定的片外元器件相连接在一起,因此约束文件反映的是开发板的硬件实现情况。组成原理开发板的硬件连接情况是固定的,教学小组也直接提供了匹配硬件平台连接情况的约束文件,这个文件被包含在thinpad_top的项目文件中。在实验中,程序可以基于thinpad_top的项目文件开始编写,项目里面已经有了所有的约束,但是要注意约束和程序中的变量名对应。建议可以直接用thinpad_top的项目文件中的变量名作为程序的输入输出的变量名。


最后更新: 2021年10月25日