【ZYNQ】从入门到秃头03 Vivado软件的硬件调试

文章目录

硬件调试简介

在整个FPGA设计中,硬件调试与验证会花费超过40%的时间
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
传统的FPGA板级调试是由外接的逻辑分析仪连接到 FPGA的控制管脚,然后将内部信号引出至引脚IO上,进行板级调试。 这种 方法 的 缺点 是 首先 我们需要一个 逻辑分析仪, 而逻辑分析仪 一般价格 都比较昂贵, 且对于 需要 测试 几十个引脚的时候, 选择使用外接的逻辑分析仪就比较繁琐了。在线逻辑分析仪克服了以上 所有的缺点 ,其借用了传统逻辑分析仪的理念以及大部分的功能,并利用 FPGA中的逻辑资源,将这些功能植入到 FPGA的设计当中。一般地,在线逻辑分析仪的应用原理框图如下图所示:调试FPGA设计是一个不断迭代的过程
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试

【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
传统的FPGA板子调试:逻辑分析仪

Xilinx硬件调试解决方案

  • Vivado工具集成了逻辑分析仪,用于替换外部的逻辑分析仪
  • 添加ILA核和VIO核实现硬件调试
  • 通过JTAG接口和PC连接
    【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
    其中,待测设计(Design Under Test DUT)就是用户逻辑,它和片内的在线逻辑分析仪都位于 FPGA中。在线逻辑分析仪通过一个或多个探针( Probe)来采集希望观察的信号,然后通过片内的 JTAG硬核组件,来将捕获到的数据传送给下载器,进而上传到 Vivado IDE以供用户查看。 Vivado IDE也能够按照上述数据路径,反向地向 FPGA中的在线逻辑分析仪传送一些控制信息。由此可见,在线逻辑分析仪不需要将待测信号引出至 I/O上,也不需要电路板走线或者探测点,当然更不需要外部的逻辑分析仪的花费,在Vivado中就可以将在线逻辑分析仪添加到设计中。但是,在线 逻辑分析仪会占用一定数量的内部逻辑资源,如块 RAM、查找表、触发器等等。

ILA

ILA(Integrated Logic Analyzer )监控逻辑内部信号和端口信号

ILA相当于一个探针,把关键位置的信号引出来,传到PC端进行观察,并且可以存储一段信息

在Vivado中,在线逻辑分析仪的功能被称为“ 集成逻辑分析器( Integrated Logic AnalyzerILA))”,它以 IP核的形式来加入到用户设计中。 Vivado提供了三种具有不同集成层次的插入 ILA方法,以满足不同 Vivado用户群的不同需求:

第一种方法是直接在HDL代码中例化一个 ILA IP核,也被称为“ HDL实例化调试探针流程”,这是集成层次最高的方法。 ILA IP核可以在 IP Catalog IP目录)中找到,并 对其进行配置,以符合所需的调试需求。这是最直接的方法,但其灵活性也较差。在调试工作完毕之后,还需要在 HDL源代码中删除ILA IP核,然后重新综合并实现,以生成最终的比特流。

第二种方法是在综合后的网表中,分别标记要进行调试观察的各个信号,然后通过一个简单的“Setup Debug”向导来设置各个探针和 ILA IP核的工作参数,然后工具会根据用户设置的参数,自动地生成各个ILA IP核。这个方法也被称为“网表插入调试探针流程”。在此流程中,用户不需要修改 HDL源代码,并且能够单独控制每个 ILA IP核以及每 个探针,这样就提供了很大的灵活性。用户设置的调试信息会以Tcl XDC调试命令的形式保存到 XDC约束文件中,在实现阶段, Vivado会读取这些 XDC调试命令,并在布局布线时加入这些 ILA IP核。在调试工作完毕之后,用户就可以在综合后的网表中删除 ILA IP核,或者在 XDC文件中删除调试命令,然后再对设计进行实现,以生成最终的比特流。

第三种方法是手动地在XDC约束文件中书写对应的 Tcl XDC调试命令,在实现阶段工具会自动读取这些命令,并在布局布线时加入这些 ILA IP核。在调试工作完毕之后,用户还需要在 XDC约束文件中删除这些命令,然后实现最终的设计。这种方法集成层次最低,一般不会使用这种方法。

VIO

VIO(Virtual Input/Output )实时监控和驱动逻辑内部信号和端口信号

VIO实现PC给出指令,驱动模块运行

HDL实例化调试探针流程

“HDL实例化调试探针流程”需要在 HDL源代码中实例化 ILA IP核。我们点击 Flow Navigator窗口中的“ IP Catalog”按钮,如下图所示
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
这时“IP Catalog”窗口就被打开了,如下图所示
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
我们在搜索栏中输入“ILA”,这时 Vivado会自动根据关键词搜索出相应的结果,我们双击“ ILA Integrated Logic Analyzer))”,如下图所示
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
接下来会弹出“ILA IP”核的配置页面,如下图所示
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
界面中需要输入监控的端口数量以及位宽,所以要提前规划好,回到代码中
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
这里选择监控 sys_rst_n,led,cnt,加起来是 1 + 2 + 26 = 29 位
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
采样深度越大,消耗资源越多,缓冲的数据越多,观察到的信号也就越长

然后在换页界面,设置好需要检测位置的位宽

1

2

26
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试

在这里,我们简要介绍一下Vivado的 OOC Out-of-Context)综合的概念。对于顶层设计 Vivado使用自顶向下的全局( Global)综合方式,将顶层之下的所有逻辑模块都进行综合,但是设置为 OOC方式的模块除外,它们独立于顶层设计而单独综合。 通常,在整个设计周期中,顶层设计会被多次修改并综合。但有些子模块在创建完毕之后不会因为顶层设计的修改而被修改,如 IP,它们被设置为 OOC综合方式。OOC模 块只会在综合 顶层 之前被综合一次,这样在顶层的设计迭代过程中, OOC模块就不必跟随顶层模块,而一次次的产生相同结果的多余综合了 。所以, OOC流程减少了设计 的 周期,并消除了设计迭代,使您可以保存和重用综合结果。

这时可以在“Source”窗口中看到已经出现了 ILA IP核,如下图所示:

【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
由于我们还没有把它例化到顶层的HDL代码中,所以在层次结构上它与顶层并排。下面我们将其 例化到顶层的HDL代码中。在 “Source”窗口中的 “IP Sources”选项卡中双击 ILA IP核的例化模板文本文件,找到例化模板的内容,如下图所示:
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
将图中的红色方框中的模板代码复制并粘贴到led_twinkle.v顶层 HDL代码中,并将 ILA的时钟和探针信号连接到顶层设计中,例化 ILA IP核的代码如下:

ila_0 your_instance_name (
	.clk(clk), // input wire clk


	.probe0(probe0), // input wire [0:0]  probe0  
	.probe1(probe1), // input wire [1:0]  probe1 
	.probe2(probe2) // input wire [25:0]  probe2
);

我们将ILA的时钟连接到了顶层时钟 sys_clk信号上, probe0探针连接到了 sys_rst_n probe1探针连接到了 led probe2探针连接到了 cnt。代码修改完成后如下图所示:
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
保存源文件之后就可以直接综合并实现设计,最后生成比特流。

至此,我们就成功地使用HDL实例化调试探针流程” 将 ILA IP核添加到了设计中。 接下来就可以将比特流下载到 FPGA中,并对信号进行在线观察。

Hardware Manager中观察调试信号

重新生成比特流

之后我们打开Hardware Manager,连接到开发板,并下载比特流,如下图所示
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
在弹出的窗口中,Vivado会自动识别比特 流文件和具有调试探针信息的 .ltx文件,如下图所示:
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
.ltx文件存储了调试探针的信息,用来传递给 Vivado IDE,它是从我们的设计中被提取出来的 。

通常,调试探测文件是在实现过程中自动创建的,并位于和比特流文件相同的目录下。若实现后的设计中包含了 ILA IP核,则在下载比特流时, Vivado会自动识别出 .ltx文件。

这里我们不必太多地关注此文件,只要按照 Vivado自动的设定来下载设计即可。我们直接点击“Program”,此时 Vivado会自动打开 ILA的调试窗口,如下图所示:
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
如果Waveform窗口中显示的信号不全,可以点击“ Waveform – hw_ila_1”窗口中的加号,来将所有的探针信号添加到波形窗口中(如果默认已经显示所有待观察的信号,不用重复添加),如下图所示:
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
我们直接点击触发采集信号的按钮,可以观察到此时信号的波形,如图所示:
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
采集到信号后,可以点击上图中的放大和缩小的图标,来对波形数据进行放大和缩小。波形默认以十六进制显示的,可以右击cnt计数器,选择“ Radix Unsigned Decimal”,即可切换到无符号的十进制显示,如下图所示:
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
下面开始触发条件的设置,在这里简要介绍一个触发的概念。

前面我们介绍过, ILA会将所采集到的探针数据存放在 RAM中,然后通过 JTAG和下载器上传到 Vivado。那么触发就是决定 ILA会在什么时候将 RAM中的探针值数据上传到 Vivado,当 ILA检测到 触发条件得到满足时,就会把 RAM中的探针值数据上载到 Vivado,然后 Vivado将探针数据的波形显示出来。

我们在“Trigger Setup”窗口中添加触发条件,点击 “+”号,将 cnt信号添加进来,如下图所示:
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
之前我们在HDL代码中设置为了 cnt计数器每计数到 25’d25_000_000和 25’d50_000_000时就改变两
个 led的状态,为了方便 led翻转状态的查看,我们可以将 触发条件设置为“ cnt等于十进制数25_000_000”,即,当 ILA检测到 cnt计数器的值等于 25’d25_000_000时,就会将 RAM中的数据上传到Vivado 如下图所示:【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
然后我们就可以开始进行触发动作了。在波形窗口中有4个触发动作,如下图所示:

【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
从左至右依次是:(1)自动触发开关、 2)开始触发、 3)立即触发、 4)停止触发。下面对他
们分别进行介绍:

(1)自动触发开关,它和“开始触发”按钮联合在一起使用。若打开了此选项,则在 ILA开始运行触发(即点击了“开始触发”按钮)后,会不断地对触发条件进行检测,每次触发条件被满足时(即 cnt计数到了 25_000_000),都会将 RAM中存储的所有的探针值数据上传到 Vivado Vivado上显示的波形也会随之不断更新,直到用户点击了“停止触发”按钮。若没有点击此选项,则在 ILA开始运行触发(即点击了“开始触发”按钮)后,在检测到触发条件得到满足并完成了上传数据之后,就会停止触发,等待用
户下一步的指令。

(2)开始触发,它和“自动触发开关”按钮联合在一起使用。点击之后 ILA就会开始进行触发操作。

(3)立即触发,立即将当前 ILA RAM中的数据上传到 Vivado,而不管触发条件是否得到满足。

(4)停止触发,停止当前正 在进行的触发活动。

我们这里直接点击“开始触发”按钮,而不打开“自动触发”开关。然后由于cnt计数器每隔 500ms就会计数到 25_000_000,所以我们几乎马上就可以看到波形窗口中出现了波形,如下图所示
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
将波形放大之后就可以看到counter的具体值,如下图所示:
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
此时就可以看到,在当cnt计数到 25_000_000时, led的状态就会发生跳变。读者也可以尝试再次点击“开始触发”按钮或打开“自动触发”按钮,来观察波形。

如果调试工作完毕之后,可以在 led_twinkle.v源代码中删除对 ILA IP核的例化,或者通过添加“和“ “*/”注释掉这段代码,如下图所示

【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
然后重新综合并实现,以生成最终的比特流。

网表插入调试探针流程

添加“Make Debug”属性

网表插入调试探针流程需要在综合后的网表中,将要进行调试观察的各个信号标记“ mark_debug”属性,然后通过“ Setup Debug”向导来设置 ILA IP核的参数,最后工具会根据参数来自动创建 ILA IP核。

可以在综合之后的网表中手动选择网络并点击“mark_debug”按钮;也可以在综合之前在 HDL代码中为想要观察的 reg或 wire信号添加“ Mark Debug”综合属性,例如

(* mark_debug = “true” *)reg [25:0] cnt ;

其中

(* mark_debug = “true” *)

必须紧挨在变量声明的前面。这样,在综合完成之后并打开综合后的设计时, cnt信号就自动被标记了“ Mark Debug”属性。此外,被添加了 (* mark_debug = “true” )属性的reg或 wire信号不会被工具优化掉。这里我们选择第二个方法,即在HDL代码中添加 ( mark_debug = “true” *)综合属性,如下图所示:

【ZYNQ】从入门到秃头03 Vivado软件的硬件调试

Run Synthesis

添加“Make Debug”属性之后,点击 Run Synthesis”进行综合
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试

综合完之后我们点击 Flow Navigator”窗口中的 Open Synthesized Design”按钮,如下图所示

【ZYNQ】从入门到秃头03 Vivado软件的硬件调试

在综合后设计的窗口布局选择器中,我们选择Debug”窗口布局,如下图所示
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试

“ Netlist”子窗口、 Schematic”子窗口以及 Debug”子窗口

此时,Vivado打开了“ Netlist”子窗口、 Schematic”子窗口以及 Debug”子窗口。

其中Netlist”子窗口和 Schematic”子窗口都可以用于标记要进行观察的信号 Debug”子窗口用于显示并设置 ILA IP核的各个参数。如下图所示:
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
在“Debug”子窗口中,又包含两个选项卡 Debug Cores”和 Debug Nets”。

这两个选项卡都用于显示所有的已标记为“ Mark_Debug”的信号。

不同之处在于 Debug Cores”选项卡 是一个更加以 ILA IP核为中心的视图,所有 已标记为“ Mark_Debug”的信号并且已经被分配到 ILA探针的信号都会被显示在各个 ILA IP核的视图树下,已标记为“ Mark_Debug”的信号但是还没有被分配到 ILA探针的信号被显示在“ Unassigned Debug Nets”下 当然也可以在其中查看和设置 ILA IP核的 各种属性和参数。

Debug Nets”选项卡仅显示已标记为 Mark_Debug”的信号,但不显示 ILA IP核, 所有 已标记为Mark_Debug”的信号并且已经被分配到 ILA探针的信号都会被显示在“ Assigned Debug Nets”下,已标记为“ Mark_Debug”的信号但是还没有被分配到 ILA探针的信号被显示在“Unassigned Debug Nets”下。

(1)在综合后的网表中手动为信号添加 mark_debug属性

如果未在HDL代码中书写 (* mark_debug = “true” *)综合属性,则需要首先标记要进行观察的信号。在综合后的网表中,信号的名称可能会发生一定的变化,以 led信号为例,在“ Netlist”子窗口中的 Nets目录下,找到“ led_OBUF[0]”网络,右击该网络(此时右边的 Schematic”子窗口也会自动地高亮选择此网络,因为“ Netlist”子窗口中的对象和 Schematic”子窗口中的对象,两者之间是 交叉选择的),在弹出的菜单中心选择“ Mark Debug”命令,如下图所示
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
也可以在“Schematic”子窗口中选择网络,然后右键选择 Mark Debug”命令,如下图所示
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
此时在“Debug”子窗口的 Debug Nets”选项卡的 Unassigned Debug Nets”目录下就会出现我们刚刚标记的“ led_OBUF[0]”网络。,如下图所示
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试

(2 )HDL代码中已经具有 mark_debug属性的信号

在HDL代码中已经添加了“ Mark Debug”综合属性的信号会被自动出现在 Debug Nets”选项卡的Unassigned Debug Nets”目录下,如下图所示为网络标记了“Mark Debug”之后,我们就可以进行 ILA IP核的配置了。点击“ Debug”子窗口中的Setup Debug”按钮,如下图所示
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试

“Setup Debug”向导

弹出“Setup Debug”向导,我们直接点击 Next”按钮,如下图所示
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
接下来的页面是选择用于采样待测信号的时钟域,Vivado会自动识别出各个待测信号所属的时钟域并将其自动设定为其采样时钟,本次添加的三个信号属于系统时钟( sys_clk)的时钟域 Vivado也已经自动将 “sys_clk_IBUF”时钟设置为了这两个信号的采样时钟,如下图所示:
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
当然,用户也可以手动指定各个用于采样待测信号的时钟域,右击待测信号,选择“Select Clock Domain”,弹出 Select Clock Domain”窗口,如 图所示:

【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
在“Select Clock Domain”窗口中就可以选择用于采样待测信号的时钟了。 Setup Debug”向导会为每个采样时钟生成一个单独的 ILA IP核,由于本例程中只有一个时钟,所以这里最后只会生成一个 ILA IP核。

设置完采样时钟后,我们点击next,接下来的页面用于设置 ILA IP核的全局设置,如下图所示:
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
其中“Sample of data depth”用于设置采样深度 Input pipe stages”用于设置待测信号和其采样时钟之间的同步级数。如果在上一个设置时钟域页面中,存在与其采样时钟之间是异步的待测信号,则为了避免亚稳态,此数值最好不要低于 2。由于本例中的两个待测信号的其采样时钟是同步的,所以可以设置为0。

我们点击next,就进入了最后的概览页面,确认无误后直接点击 Finish”按钮即可,如下图所示

【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
在“Debug”子窗口中的 Debug Cores”选项卡中,可以看到 Vivado已经添加了 ILA IP核,并且Unassigned Debug Nets”目录下已经没有未被分配的信号了,如下图所示
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
网表中被标记为Mark Debug的信号也变为了虚线,以表示其完成了 ILA IP核的分配

XDC约束文件

前面我们提到过,在“网表插入调试探针流程 ”中, 用户设置的调试信息最终会以 Tcl XDC调试命令的形式保存到 XDC约束文件中。

在实现阶段, Vivado会从 XDC约束文件中读取这些 XDC调试命令,并在布局布线时加入这些 ILA IP核。

此时,我们所做出的所有的更改和设置,都还只是停留在电脑内存中,我们需要将其保存在硬盘的 XDC约束文件 中,以供 Vivado在实现阶段读取。点击工具栏中的保存按钮

在出现的消息框中直接点击OK,如下图所示
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
如果弹出“Save Constraints”对话框,询问用户将约束保存在哪个 XDC约束文件中,本例的工程中只有一个 XDC约束文件,选择“ Select an existing file”,位于 led_twinkle.xdc文件下,然后点击“ OK”按钮即可(有时候也有可能没有弹出这个对话框)。

此时,我们打开led_twinkle.xdc文件,就会看到在用户约束的下面, Vivado自动写入了用于 debug的约束命令,如下图所示:
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
在实现阶段,Vivado会读取这些约束,并按照这些命令的参数来自动地加入 ILA IP核。

至此,我们就成功地使用“网表插入调试探针流程 ”将 ILA IP核添加到了设计中。

接下来就可以实现设计并生成比特流,最后将比特流下载到 FPGA中,以对信号进行在线观察。

对信号在线观察的方法请参考“Hardware Manager中观察调试信号”一节,操作方法和“ HDL 实例化调试探针”的观察波形信号一样,没有任何区别。
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试

如果调试工作完毕之后,可以删除 led_twinkle.v源代码信号中的“ Make Debug”属性和删除 XDC文件中的包含调试信息的 Tcl文件,然后重新综合并实现,以生成最终的比特流。 至此,在线逻辑分析仪的使用介绍完毕。

在 Vivado中进行功能仿真

在进行功能仿真之前,我们先看一下典型的FPGA设计流程,流程图如下:
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
从上图可以看到,在设计输入之后、设计综合之前进行RTL级仿真,称为综合前仿真,也称为前仿真或功能仿真。

前仿真也就是纯粹的功能仿真,主旨在于验证电路的功能是否符合设计要求,其特点是不考虑电路门延迟与线延迟。

在完成一个设计的代码编写工作之后,可以直接对 代码进行仿真,检测源代码是否符合功能要求。

这时,仿真的对象为 HDL代码,可以比较直观的观察波形的变化,在设计的最初阶段发现问题,节省大量的精力。

在布局布线后进行的仿真称为布局布线后仿真,也称为后仿真或时序仿真。时序仿真真实地反映了逻辑的时延与功能,综合考虑电路的路径延迟与门延迟的影响,验证电路能否在一定时序条件下满足设计构想的过程,是否存在时序违规。

Vivado设计套件内部集成了仿真器 Vivado Simulator 能够在设计流程的不同阶段运行设计的功能仿真和时序仿真,结果可以在 Vivado IDE集 成的波形查看器中显示。 Vivado还支持与诸如 ModelSim、Verilog Compiler Simulator (VCS)、 Questa Advanced Simulator等第三方仿真器的联合仿真。

功能仿真需要的文件:

1.设计 HDL源代码,也被称为 UUT Unit Under Test)):可以是 VHDL语言或 Verilog语言,既可以是设计的顶层模块,也可以是设计的下层子模块。

2.测试激励代码,也被称为 TestBench:根据 UUT顶层 输入 /输出接口的设计要求,来产生 顶层 输入接口的测试激励并监 视 顶层 输出接口。由于不需要进行综合,书写具有很大的灵活性。

TestBench和 UUT之间 的关系如下图所示:
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
3.仿真模型 /库:根据设计内调用的器件供应商提供的模块而定,如: FIFO、 ADD_SUB等。在使用Vivado Simulator时,仿真器所需的仿真模型 /库是预编译好并集成在 Vivado中的,因此不需要进行额外的预编译操作,直接加载 HDL设计和 TestBench即可执行仿真。

接下来我们开始在Vivado IDE中进行仿真,首先需要创建一个 TestBench。

我们点击“ Sources”窗口中的“ “+”号 Add Sources命令),在弹出的窗口中选择“ Add or Create Simulation Sources”
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
点击“NEXT”按钮,在接下来的页面中点击 Create File”,如下图所示
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
TestBench源文件名称的前缀“ tb_”可以用来向用户示意:该源文件是一个 TestBench源文件,仅用于仿真,并不能用于设计的综合和实现。

建议大家按照这种规范来创建 TestBench,以免设计源文件和仿真源文件相混淆

接下来直接点击“Finish”按钮,在弹出的自动定义模块窗口中我们直接点击“OK”按钮即可,结束 TestBench源文件端口的定义,如下图所示:
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
紧接着会弹出一个模块定义的确认按钮,点击“YES”按钮即可

此时我们就可以在 Source窗口→ Simulation Sources→sim_1 下找到 tb_led_twinkle.v文件,这个文件就是刚刚创建 的 TestBench文件,双击打开后发现其模块内部只定义了模块名,如下图所示:
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
我们删除tb_led_twinkle.v文件中默认的代码,然后替换成 LED灯闪烁的 TestBench(激励)代码,代码如下:

`timescale 1ns / 1ps

module tb_led_twinkle();
//输入
reg sys_clk;
reg sys_rst_n; 
//输出
wire [1:0] led; 
//信号初始化
initial begin
	sys_clk = 1'b0;
	sys_rst_n = 1'b0;
	#200
	sys_rst_n = 1'b1;
end
//生成时钟 
always #10 sys_clk = ~sys_clk;
//例化待测设计 
led_twinkle u_led_twinkle(
	.sys_clk (sys_clk),
	.sys_rst_n (sys_rst_n),
	.led (led)
	);

endmodule

编写完成后,单击保存按钮来保存TestBench。

为了让读者能够更好的理解,这里我们就简单介绍一下TestBench源代码。

仿真代码首先要规定时间单位和精度,我们建议大家最好在 Testbench里面统一规定时间单位,不要在工程代码里定义,因为不同的模块如果时间单位不同可能会为仿真带来一些问题。

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

代码的第 3行就是 TestBench的模块名定义

代码的第 5行至第 10行是我们的数据类型定义 , 第 12~18行是信号的初始化

代码的第 20-21行用于生成时钟信号

代码的第 23-28行是对被测模块led_twinkle)的例化。

在开始仿真之前,有一点需要注意,我们在Vivado软件中实现的功能是 LED闪烁效果,它的间隔时间是 500ms,如果我们想要仿真这个功能,那么我们仿真软件运行时间最低就是 500ms。这 500ms在我们看来是很短的,而对仿真软件来说是很漫长的,毕竟我们的仿真时间单位可是 1ns。为了便于我们仿真,这里我们需要稍微改动一下“ led_twinkle.v”文件的代码,将计时器 cnt的最大计时值设为 10,如下图所
示:
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
在“Flow Navigator 窗口中点击 “Run Simulation”并选择 “Run Behavioral Simulation”,如下图所示
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
之后我们就进入了仿真界面,如下图所示:
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
下面分别介绍仿真界面中的各个子窗口:

(1 )Scope窗口。

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

(2 )Object窗口。

“ Objects”窗口会显示在 Scopes”窗口中选择的范围内的所有 HDL仿真对象。例如,我们在 Scope窗口中选择“ u_led_twinkle”,在 Objects”窗口中就会自动显示出 led_twinkle模块中所有的对象。
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
可以看出,在led_twinkle顶层模块中除了顶层端口 sys_clk、 sys_rst_n、 led之外,还包括在内部定义的计数器 cnt。

(3)波形窗口。

用于显示所要观察信号的波形。若要向波形 窗口添加单个 HDL对象或多个 HDL对象,在 “Objects”窗口中,右键单击一个或多个对象,然后从下拉菜单中选择 “Add to Wave Window”选项。

例如,我们把“u_led_twinkle”模块 下的“ cnt”计数器添加到波形窗口中 如 下图所示
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试添加到波形窗口中的“ cnt”计数器 如下图所示
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试

一般地,每当我们进行一次仿真时,都会把当前波形的配置信息保存下来,包括波形窗口中具有哪些信号等等,以便在下一次打开仿真器进行仿真时,继续使用上一次仿真的配置 信息。我们点击波形窗口中的保存按钮。

(4 )仿真工具栏。

仿真工具栏包含运行各个仿真动作的命令按钮,如下图所示:
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
介绍完各个窗口和命令按钮的使用后,下面我们开始进行仿真。

在刚打开仿真器时,仿真器会将TestBench中的信号加入到波形窗口中 ,并执行一段时长的仿真,仿真的时长由 Settings设置窗口中的参数值指定,如下图所示:
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
可以看到,仿真器启动后默认立即执行的仿真时长是1000ns。 由于我们是在 默认立即执行仿真结束之后,才 加入了 cnt”计数器信号,所以新加入的 cnt信号并没有波形。此时我们需要将仿真时刻重置为0,重新开始仿真。点击 Restart按钮,波形窗口中的当前仿真时刻点(黄色标尺)就会回归到 0ns,且原先的 所有波形都被清除,如下图所示:
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
此时点击仿真工具栏中的 Run For按钮,默认仿真时长是 10us,如下图所示
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试

cnt信号默认显示为 16进制,为了方便观察,我们将其设置为 10进制。对 cnt信号右键,在弹出的菜单中依次选择 “Radix”——“Unsigned Decimal”

可以看出,cnt每计数到 4和 10,两个 led的电平状态就切换一次。证明我们的 HDL设计达到了我们想要的功能。

在仿真结束后,可以在Flow Navigator窗体中找到 SIMULATION,鼠标右击 SIMULATION,选择Close Simulation来关闭仿真的界面,如下图所示:
【ZYNQ】从入门到秃头03 Vivado软件的硬件调试
紧接着会弹出一个关闭仿真的确认窗口,点击“OK”按钮即可。

上一篇:一生都要Debug,我们最需要掌握哪些硬技能?


下一篇:1-1-Qt的安装