超详细FPGA新手小白入门点亮LED灯

Vivado软件的基本操作(以控制LED灯闪烁为例)

其实之前早已用过Vivado进行FPGA的开发学习,但由于每次都是浅尝辄止地学了一些时间,加上Vivado软件和FPGA开发流程的复杂性,长时间不用就会遗忘。因此今天还是简单地写个笔记记录一下Vivado软件的一些基本操作,实现一个“hello world工程”:控制LED灯的闪烁。

实验基于的版本是Vivado17.4,FPGA芯片是Xilinx的XC7Z100-2FFG900。

创建Vivado工程

(1)双击Vivado快捷方式启动Vivado。

image-20230301094254836

(2)点击Create Project创建一个新工程。

image-20230301094414293

(3)在弹出的建立新工程的向导中点击Next。

image-20230301094518524

(4)在弹出的对话框中输入工程名和工程存放的目录,之后点击Next。

需要注意工程路径“Project location”不能有中文空格,路径名称也不能太长。由于默认勾选了“Create project subdirectory”选项,Vivado会在所选工程目录下自动创建一个与工程名同名的文件夹,用于存放工程内的各钟文件。 Vivado会自动管理工程文件夹内的各种工程文件,并创建相应的子目录。

image-20230301094912469

(5)在工程类型中选择RTL Project,之后点击Next。

  • “RTL Project”是指按照正常设计流程所选择的类型,这也是常用的一种类型,“ RTL Project”下的 Do not specify sources at this time”用于设置是否在创建工程向导的过程中添加设计文件,如果勾选后,则不创建或者添加设计文件;
  • “Post synthesis Project”在导入第三方工具所产生的综合后网表时才选择;
  • “I/O Planning Project”一般用于在开始RTL设计之前,创建一个用于早期IO规划和器件开发的空工程;
  • “Imported Project” 用于从 ISE、 XST或 Synopsys Synplify导入现有的工程源文件;
  • “Example Project”是指创建一个 Vivado提供的工程模板 。

image-20230301095323117

(6)这里添加源文件界面直接点击Next,选择在创建完工程之后再创建和添加源文件。以及Target language选择Verilog(默认),但也可以使用VHDL,支持多语言混合编程。

image-20230301095756397

(7)添加约束文件界面直接点击Next,即在创建完工程之后创建添加约束文件。

image-20230301095919744

(8)接下来选择器件型号,这里根据大家自己的具体芯片型号去相应选择即可。选择完成后点击Next。

image-20230301100153893

具体的ZYNQ命名规则如下图所示:

image-20230301100411942

(9)进入工程概览界面,这个页面将之前几个步骤中的设置全部列了出来,供用户检查。确认无误后点击Finish完成工程的创建。

image-20230301100632109

Vivado主界面介绍

image-20230301101121623

(1)Flow Navigator:提供对命令和工具的访问,包含从输入到生成比特流的整个过程。

(2)数据窗口区域:默认情况下,这个区域显示与设计源文件和数据相关的信息,如:

  • Sources窗口:显示层次结构(Hierarchy)、IP源文件(IP Sources)、库(Libraries)和编译顺序(Compile Order)的视图。
  • Netlist窗口:提供分析后的(elaborated)或综合后的(synthesisized)逻辑设计的分层视图。

(3)Properties窗口:显示有关所选逻辑对象或器件资源的信息。

(4)工作空间(Workspace):工作区显示了具有图形界面的窗口和需要更多屏幕空间的窗口,包括:

  • 用于显示和编辑基于文本的文件和报告的Text Editor。
  • 原理图(Schematic)窗口。
  • 器件(Device)窗口。
  • 封装(Package)窗口。

(5)结果区域窗口:在Vivado中所运行命令的状态和结果,显示在结果窗口区域内,这是一组子窗口的集合。子窗口的集合。在运行命令、生成消息、创建日志文件和报表文件时,相关信息将显示在此区域。默认情
况下,此区域包括以下窗口:

  • Tcl Console:允许输入Tcl命令,并查看以前的命令和输出的历史记录。
  • Messages:显示当前设计的所有信息,包括”Error”、” Critical Warning”、“Warning”等。
  • Log:显示由综合、实现和仿真运行创建的日志文件。
  • Reports:提供对整个设计流程中的活动运行所生成的报告的快速访问。
  • Design Runs:管理当前工程的运行。

(6)主工具栏:提供了对Vivado中最常用命令的单击访问。

(7)主菜单:提供对Vivado命令的访问。常用的命令会一直显示(例如, File > Project > Open),而其他命令只在设计活动时显示 (例如,Reports > ReportDRC)。

(8)窗口布局(Layout)选择器:提供预定义的窗口布局,以方便设计过程中的各种任务。布局选择器能够轻松地更改窗口布局,也可以使用菜单栏中的 “Layout”菜单来更改窗口布局。

创建Verilog输入文件

(1)点击左侧的Add Sources或者右侧的“+“号。

image-20230301105324075

(2)选择Add or create design sources,之后点击Next。

image-20230301105442719

(3)选择Create file。

image-20230301105606830

(4)自己输入文件名,点击“OK”。

image-20230301105713830

(5)点击Finish,会出现如下窗口。

此窗口用于设置源文件的模块名称和端口列表,Vivado会根据在此窗口中的设置,自动地在HDL源文
件中写入相应的verilog语句。我们手动输入代码,所以这里不作任何设置,直接点击 OK即可。

image-20230301105823485

(6)在弹出的对话框中选择“Yes”。

image-20230301105959163

(7)此时“Sources”窗口中就出现了我们刚刚创建的源文件,如下图所示。

image-20230301110120583

(8)这时可直接双击打开这个.v文件进行Verilog代码的编写。由于Vivado自带的编辑器不是很好用,所以我这里配置了将vscode代替默认的编辑器(网上有详细教程,可以自己查一下,包括也可以替换成vim、notepad++等)。

这里定义了一个 32 位的寄存器timer, 用于循环计数 0~199999999(1 秒钟), 计数到 199999999(1秒)的时候, 寄存器 timer 变为0,并翻转四个LED。这样原来LED是灭的话,就会点亮,如果原来LED为亮的话,就会熄灭。由于输入时钟为 200MHz 的差分时钟,因此需要添加IBUFDS原语连接差分信号。

编写好代码后切记保存

`timescale 1ns / 1ps

module led_twinkle(
    // 差分时钟输入
    input                sys_clk_p,
    input                sys_clk_n,
    input                rst_n,
    output reg  [3:0]    led
    );
    
    reg  [31:0]    timer_cnt;
    wire  sys_clk;

    IBUFDS # (
        .DIFF_TERM("FALSE"),
        .IBUF_LOW_PWR("TRUE"),
        .IOSTANDAND("DEFAULT")
    ) IBUFDS_inst (
        .O(sys_clk),
        .I(sys_clk_p),
        .IB(sys_clk_n)
    );

    always @ (posedge sys_clk or negedge rst_n) begin
        if (!rst_n) begin
            led <= 4'd0;
            timer_cnt <= 32'd0;
        end
        else if (timer_cnt >= 32'd199_999_999) begin
             led <= ~led;
             timer_cnt <= 32'd0;
        end
        else begin
            led <= led;
            timer_cnt <= timer_cnt + 32'd1;
        end
    end
    
endmodule

功能仿真

在设计输入之后,设计综合前进行RTL级仿真,称为综合前仿真,也称为前仿真或功能仿真。前仿真也就是纯粹的功能仿真,主旨在于验证电路的功能是否符合设计要求,其特点是不考虑电路门延迟与线延迟。功能仿真需要的文件:

  • 设计HDL源代码。
  • 测试激励代码(TestBench):根据设计要求输入/输出的激励程序,由于不需要进行综合,书写具有很大的灵活性。
  • 仿真模型/库:根据设计内调用的器件供应商提供的模块而定,如:FIFO、ADD_SUB等。在使用Vivado Simulator时,仿真器所需的仿真模型/库是预编译好并集成在 Vivado中的,因此不需要进行额外的预编译操作,直接加载HDL设计和TestBench即可执行仿真。

(1)首先创建一个TestBench,点击左侧的Add Sources或者右侧的“+“号。

image-20230301133522230

(2)在弹出的窗口中选择“ Add or Create Simulation Sources”,之后点击Next,如下图所示。

image-20230301133609733

(3)在接下来的页面中点击Create File。

image-20230301133730091

(4)在弹出的窗口中输入TestBench的文件名,TestBench源文件名称的后缀“tb”可以用来向用户示意该源文件是一个 TestBench源文件,仅用于仿真,并不能用于设计的综合和实现。

image-20230301133928501

(5)点击OK后点击Finish。

image-20230301134011827

(6)在弹出的自定义模块窗口中直接点击OK即可结束TestBench源文件的创建。

image-20230301134126121

(7)编写.v文件代码。

代码第一行的timescale是Verilog语法中的不可综合语法,用于定义仿真的时间表示仿真的单位时间为1ns,精度为1ps,这是Xilinx官方推荐的仿真单位时间和精度。

`timescale 1ns / 1ps

module led_twinkle_tb;

    reg            sys_clk_p;
    wire           sys_clk_n;
    reg            rst_n;
    wire  [3:0]    led;

    led_twinkle u_led_twinkle (
        .sys_clk_p(sys_clk_p),
        .sys_clk_n(sys_clk_n),
        .rst_n(rst_n),
        .led(led)
    );

    initial begin
        sys_clk_p = 0;
        rst_n = 0;
        #1000;
        rst_n = 1;
    end

    always #2.5 sys_clk_p = ~sys_clk_p;

    assign sys_clk_n = ~sys_clk_p;

endmodule

(8)在“Flow Navigator“窗口中点击“Run Simulation”并选择 “Run Behavioral Simulation”。

image-20230301141120966

(9)之后就进入了仿真界面。

image-20230301142735768

①Scope窗口:Scope(范围)是HDL设计的层次划分。在Scope窗口中,可以看到设计层次结构。当选择了一个Scope层次结构中的作用域时,该作用域内的所有 HDL对象,包括reg、wire等都会出现在“Objects”窗口中。可以在 “Objects”窗口中选择HDL对象,并将它们添加到波形查看器中。

②Object窗口:“Objects”窗口会显示在Scopes”窗口中选择的范围内的所有HDL仿真对象。例如,在Scope窗口中选择顶层模块“led_twinkle”,在“Objects”窗口中就会自动显示出led_twinkle模块中所有的对象。如下图所示:

image-20230301142152130

③波形窗口:用于显示所要观察信号的波形。若要向波形窗口添加单个HDL对象或多个HDL对象,可以在“Objects”窗口中,右键单击一个或多个对象,然后从下拉菜单中选择“Add to Wave Window”选项。例如,可以把 “led_twinkle”模块 下的“timer_ cnt”计数器添加到波形窗口中。

image-20230301142356848

④仿真工具栏:仿真工具栏包含运行各个仿真动作的命令按钮。从左至右依次是:

  • Restart:将仿真时间重置为零,此时波形窗口中原有的波形都会被清除。下次执行仿真时,会从0时刻重新开始。

  • Run all:运行仿真,直到其完成所有事件或遇到 HDL语句中的 s t o p 或 stop或 stopfinish命令为止。注意,如果没有在 TestBench语句中加入 s t o p 或 stop或 stopfinish命令,当点击Run all命令时,仿真器会无休止地一直仿真下去,除非用户点击仿真工具栏中的“ Break”按钮来手动地结束仿真。但是这里有个地方需要注意,如果此时需要仿真的设计比较复杂,则仿真器在运行仿真时会耗费电脑大量的CPU和内存资源,此时有可能会造成电脑卡顿甚至死机的情况。所以,如果设计比较复杂,且没有在 TestBench语句中加入 s t o p 或 stop或 stopfinish命令,最好不要轻易点击 Run all命令。

  • Run For:运行特定的一段时间。紧随在后面的两个文本框用于设定仿真时长的数值大小和时间单位。

  • Step:按步运行仿真,每一步仿真一个HDL语句。

  • Break:暂停当前仿真。

  • Relaunch :重新编译仿真源并重新启动仿真。

  • 源代码进行修改。在修改完 HDL源代码后,如果需要修改HDL代码,可以点击Relaunch按钮来重新加载UUT设计和 TestBench,以重新对修改后的HDL源代码进行仿真。此时就不需要再关闭并重新打开仿真器了。

在刚打开仿真器时,仿真器会首先将TestBench中的信号加入到波形窗口中 ,并执行一段时长的仿真。仿真的时长由Settings设置窗口中的参数值指定,如下图所示:

image-20230301143154594

可以看到,仿真器启动后默认立即执行的仿真时长是1000ns。由于我们是在默认立即执行仿真结束之后,才加入了“timer_cnt”计数器信号,所以新加入的”timer_cnt“信号并没有波形。此时我们需要将仿真时刻重置为0,重新开始仿真。点击Restart按钮,波形窗口中的当前仿真时刻点(黄色标尺)就会回归到0ns,且原先的所有波形都被清除,如下图所示:

image-20230301143642061

点击仿真工具栏中的Run For按钮,默认仿真时长是10us,此时就可以看到波形窗口中就出现了波形。

image-20230301143901667

分析与综合

(1)点击“Flow Navigator”窗口中的“Open Elaborated Design”按钮。此时,Vivado会编译RTL源文件并进行全面的语法检查,并在Messages窗口中给出相应的“Error”和“Warning”。

image-20230301144413001

(2)打开分析后 Elaborated的设计后Vivado会生成顶层原理图视图,并在默认view layout中显示设计,如下图所示:

image-20230301144713800

(3)将打开的分析后的设计关闭,再点击“Flow Navigator”窗口中的“Run Synthesis”按钮进行综合。

image-20230301145046179

image-20230301145113139

(4)在弹出的窗口中点击"OK"。

image-20230301145204904

(5)综合完成后弹出如下窗口,直接关闭即可。

image-20230301145349219

约束输入

(1)首先需要创建一个用于存储约束语句的约束文件。点击“Sources”窗口中的 “+”号,在弹出的窗口选择“ Add or create constraints”,如下图所示,点击“Next”:

image-20230301145537998

(2)点击“Create File”。

image-20230301145649475

(3)在弹出的对话框中输入约束文件的名称“led_twinkle”,然后点击 OK。

image-20230301145747061

(4)点击“Finish”即可。

image-20230301145824354

Vivado的约束文件是以“.xdc”为文件后缀的ASCII文本文件,其中存储的是一条条的xdc约束命令。

image-20230301145914854

点开此文件,输入如下内容:

set_property PACKAGE_PIN AJ16 [get_ports {led[0]}]
set_property PACKAGE_PIN AK16 [get_ports {led[1]}]
set_property PACKAGE_PIN AE16 [get_ports {led[2]}]
set_property PACKAGE_PIN AE15 [get_ports {led[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[3]}]
set_property PACKAGE_PIN AF18 [get_ports rst_n]
set_property IOSTANDARD LVCMOS33 [get_ports rst_n]
set_property PACKAGE_PIN F9 [get_ports sys_clk_p]
set_property IOSTANDARD DIFF_SSTL15 [get_ports sys_clk_p]

create_clock -period 5.000 -name sys_clk_p -waveform {0.000 2.500} [get_ports sys_clk_p]

普通 IO 口只需约束引脚号和电压,管脚约束如下:

set_property PACKAGE_PIN “引脚编号” [get_ports “端口名称”]

电平信号的约束如下:

set_property IOSTANDARD “电平标准” [get_ports “端口名称”]

这里需要注意文字的大小写,端口名称是数组的话用{ }括起来,端口名称必须和源代码中的名字一致,且端口名字不能和关键字一样。

电平标准中“LVCMOS33”后面的数字指FPGA的BANK 电压,LED所在BANK电压为3.3伏,所以电平标准为“LVCMOS33”。Vivado 默认要求为所有 IO 分配正确的电平标准和管脚编号。

对于xdc文件,每一个约束命令单独占用一行,命令的结尾没有如verilog中的分号一样的语句结束符号。每一条注释也单独占用一行。命令的第一个关键字代表该命令的名称,其后的所有字段都是该命令的参数列表。

设计实现

(1)约束输入完毕之后,就可以开始实现设计了。点击“Flow Navigator”窗口中的”Run Implementation”按钮。

image-20230301150644493

(2)在弹出的界面选择OK。

image-20230301150728672

可以看到实现正在进行。

image-20230301150904820

(3)直接关闭实现完成后的提示窗口。

image-20230301151303830

再次查看“Design Runs”窗口中的实现结果,发现时序要求都已满足,即没有报红,说明设计成功地在FPGA中完成了实现。

image-20230301151400283

下载比特流

(1)生成用于下载到器件中的比特流文件,点击“Flow Navigator”窗口中的“Generate Bitstream”按钮。

image-20230301151545593

(2)在弹出的窗口中直接点击OK。

image-20230301151654528

此时可以看到“Design Runs”窗口中显示正在生成比特流:

image-20230301151815779

(3)生成完成后,直接关闭提示窗口。

image-20230301151939560

(4)开始下载比特流,点击“Flow Navigator”窗口中的“Open Hardware Manager”按钮。

image-20230301152044652

(5)将开发板上电并接好JTAG接口,点击Open target中的Auto Connect(或Hardware中的此按钮)。

image-20230301152522179

出现如下界面就表示 Vivado就已经和下载器连接成功了:

image-20230301162540483

(6)右击xc7z100_1,在弹出的菜单中点击Program Device。

image-20230301162811612

(7)在弹出的对话框中直接点Program即可。
image-20230301162853680

下载成功后,可以观察到板子上的LED灯在不停地闪烁。

image-20230301163020705

总结

至此使用Vivado开发FPGA实现一个简单的LED闪烁的流程就走完了,可以看到还是比较复杂的。之后还有Vivado中在线逻辑分析仪的使用、固化文件的生成等,就另起文章记录了。

参考

达芬奇之FPGA开发指南 V1.2

cource_s1_ALINX_ZYNQ(AX7Z100)开发平台FPGA教程V1.07

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值