用FPGA做项目的时候,大部分时间都花在调试上了,调试除了板子实际跑看结果和用VIVADO的仿真功能外,还可以用XILINX 自带的ILA功能来进行调试,本文就简单演示下 XILINX的 ILA 功能。
本文在 vivado2018.3版本上 演示, 其他版本请自行研究
备注 此文针对1.1及以上版本硬件,如果是v1.0的硬件请看对应的工程
ILA的工作方式,相当于在芯片内部放了一个小型的逻辑分析仪,并且用这个逻辑分析仪的探针去抓取芯片内部不同的信号,并将信号的波形采集上传并最终显示出来,根据这些波形,我们可以判断各种模块工作是否符合预期,或者哪里的信号与设计的不相符合,从而达到调试的目的。
工作的过程中ILA自动将用户的信号暂存到BRAM中,然后通过JTAG读取到PC端进行波形的显示。
ILA的工作方式和仿真有点相近,但是ILA抓到的波形是代码编译综合下载到FPGA后真实运行的结果,而仿真则是理想情况下输出的结果,两者在程序较复杂的时候,或者时序约束没做好的情况下会有出入,所以当程序工作不符合预期又找不到方向的时候,可以用ILA来抓取关键信号的波形看看,因为ILA是真实跑的过程中抓的波形,所以结果更有说服力。
1.ILA模块的添加
本文用一个计数器的简单工程来演示下 ILA功能模块的使用。
本文在 vivado2018.3版本上 演示, 其他版本请自行研究
1.1 创建工程:(本文仅对ILA的部分进行介绍,对工程创建过程不熟悉的可以看工程一)http://www.hellofpga.com/index.php/2022/10/04/01/
1.2 代码:这里我们代码上做一个简单的功能,FPGA芯片内部计数器time_count每满100次计数(0-99)result寄存器翻转一次(从1变成0,或者从0变成1) ,并且用ILA模块侦测芯片内部的这两个信号,计数器变量(time_count) 和结果的寄存器(result) 程序和工程一很像,但是为了演示,所以缩短了计数器的时间
`timescale 1ns / 1ps module ILA_TEST( input clk ); parameter T1MS = 7'd99; //50M晶振时钟 reg [7:0]time_count;//时钟计数器 reg result; always@(posedge clk) if(time_count>=T1MS)begin time_count<=26'd0; result<=~result; end else time_count<=time_count+1'b1; endmodule
1.3 调用ILA模块
在vivado软件中,打开IP核目录(IP Catalog),搜索ILA,如下图所示
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-76.png)
1.4 在弹出的ILA配置界面里 修改参数(因为我们要采集2个信号即两个探针,所以探针数量改成2,由于我们的计数从0-99计数,所以1024的深度足够采样好几个周期了,所以这里采样深度不变)
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-77.png)
1.5对探针的位宽进行修改,因为我们的time_count是7位的 ,而result变量是1个bit的,所以这里修改成7和1,然后点选OK ,然后再在弹出的窗口选择generate生成ILA模块(需要一点时间)
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-78-1024x440.png)
1.6 记住 下图所示的模块名,和 信号组成
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-79.png)
1.7 在我们之前写的代码里加入ILA模块的例化代码(例化就是生成一个实体)
ila_0 u_0( .clk(CLK), .probe0(time_count), .probe1(result) ) ;
完整代码如下:
`timescale 1ns / 1ps module ILA_TEST( input CLK ); parameter T1MS = 7'd99; //50M晶振时钟 reg [7:0]time_count;//时钟计数器 reg result; always@(posedge CLK) if(time_count>=T1MS)begin time_count<=26'd0; result<=~result; end else time_count<=time_count+1'b1; ila_0 u_0( .clk(CLK), .probe0(time_count), .probe1(result) ) ; endmodule
增加约束文件:
set_property IOSTANDARD LVCMOS33 [get_ports CLK] set_property PACKAGE_PIN K17 [get_ports CLK]
之后点选run 和 generate bitstream进行综合 布线,和生成二进制文件
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-81.png)
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-80.png)
2. 下载代码
2.1 接通好JTAG 和主板,并且将主板供上电源, 点选 open target 来连接目标板子
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-82.png)
2.2接通成功后会出现下面这个图
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-83.png)
2.3 右键选择芯片型号,并点program device进行FPGA的代码下载(这些操作都和正常FPGA工程一致)
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-84.png)
点选Program 下载
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-85.png)
3 ILA调试
3.1 执行完之前的下载操作后,系统如果运行没问题会自动弹出一个ila调试窗口, 入下图所示 点选箭头(Run trigger for this ILA core)开始采样
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-86-1024x492.png)
3.2 之后我们就会读取到1024个(深度)时钟的探针逻辑波形数据
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-87-1024x330.png)
3.3通过ctrl+鼠标滚轮我们可以放大缩小看波形细节
3.4系统默认是 16进制数据显示的,通过右键波形选择 Radix –>Unsigned Decimal(无符号的,也可以选signed这个有符号的),可以查看 10进制的数值
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-88.png)
3.5通过波形我们可以看到 系统每计数到99,result 改变一次状态
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-89.png)
并且result呈周期性的 变化状态
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-90.png)
3.6 也可以,点选Waveform Style –> Analog 来显示数值对应的模拟波形(如正弦波三角波等)
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-91.png)
这里因为count是从0-99 再到0,所以外形看上去有点类似三角波 如下图所示
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-92.png)
以下是完整工程:
以上是 ILA功能的简单调用和介绍,当然ILA的功能远不止我介绍的这些,还包括触发功能等,如目标值达到某些特定的值才触发波形采样,这些功能需要各位自行去挖掘了,不作展开