一、基本介绍
1.1前言
ILA是vivado中独特的IP核,在调试过程中能加速我们debug,本次我们来学习ILA,以助于后续我们开发复杂大型项目基本发现和解决问题的能力。
本次项目会用led闪烁的代码进行讲解,如何使用ILA,先附上我的源代码
`timescale 1ns / 1ps
module flash_led(
input sclk,
input s_rst_n,
output reg [3:0] led);
reg [25:0] cnt;
always@(posedge sclk or negedge s_rst_n) begin
if(s_rst_n==1'b0)
cnt<='d0;
else if (cnt=='d49_999_999)
cnt<='d0;
else
cnt<=cnt+1;
end
always@(posedge sclk or negedge s_rst_n) begin
if(s_rst_n==1'b0)
led<=4'b0000;
else if (cnt=='d49_999_999)
led<=~led;
else
led<=led;
end
endmodule
1.2介绍
我们所熟知的ILA,其实他需要两个IP核,ILA和VIO
ILA:监控逻辑内部信号和端口信号
VIO:实时监控和驱动逻辑内部信号和端口信号
本次先介绍ILA
1.3ILA的添加方式
ILA有三种添加方法:
1、HDL方式:生成一个ILA的ip核,然后在verilog代码中对ip核进行例化,将探针和内部信号进行连接,我们就能观测信号了。
优点:想观察什么信号,直接连接(直接在代码中例化和修改)
缺点:需要修改设计
2、Hierarchy/schematic法:
前者是通过添加信号列表做调试,后者是原理图方式,这两种方式都需要对代码进行综合之后去添加
优点:不用修改源设计,直接在列表添加待测信号
缺点:综合会对程序进行优化,可能导致我们无法在列表中找到需要调试的信号(可以通过添加属性去解决)
3、IP Integrator
在IP寄存器中添加需要调试的信号
二、具体调用
1、调用ILA的ip核
按照箭头数量对应第几步,照着操作即可,system ILA我们不用管他,这不是调试用的

2、配置ILA
我们可以双击ILA,此时会弹出一个IP核的配置页面,首先我们需要明确我们要观测的信号数量,本次实验需要观测s_rst_n,led,cnt也就是3个信号,然后我们也需要明确一下他们的位数,然后开始配置。


3、综合选项
这里有弹出一个综合选项,一个是global,一个是ooc模式,我们选取默认的ooc模式
提一下ooc和global模式的区别:
ooc模式:创建ILA的ip核会被综合一次,后续综合整个工程的这个ILA不会被再次综合,会节约一些时间
global模式:每次编译综合的时候,ILA这个ip核就会被综合一次,会很消耗时间
选取完之后跑一次编译,跑到implehension(大概这个地方,不用在意单词是否正确)

4、例化ILA
按照图示步骤,双击ila_0.veo,得到例化模板

例化模板:
ila_0 your_instance_name (
.clk(clk), // input wire clk
.probe0(probe0), // input wire [0:0] probe0
.probe1(probe1), // input wire [3:0] probe1
.probe2(probe2) // input wire [25:0] probe2
);
将这个代码粘贴到我们的源文件中,对应我们之前配置ILA的部分,了解每个信号应该连到那里,例化模块名字想好,稍微修改一下:
`timescale 1ns / 1ps
module flash_led(
input sclk,
input s_rst_n,
output reg [3:0] led);
reg [25:0] cnt;
always@(posedge sclk or negedge s_rst_n) begin
if(s_rst_n==1'b0)
cnt<='d0;
else if (cnt=='d49_999_999)
cnt<='d0;
else
cnt<=cnt+1;
end
always@(posedge sclk or negedge s_rst_n) begin
if(s_rst_n==1'b0)
led<=4'b0000;
else if (cnt=='d49_999_999)
led<=~led;
else
led<=led;
end
ila_0 ila_0_inst (
.clk(sclk), // input wire clk
.probe0(s_rst_n), // input wire [0:0] probe0
.probe1(led), // input wire [3:0] probe1
.probe2(cnt) // input wire [25:0] probe2
);
endmodule
三、遇到问题
首先,我手上的板子是没焊接PL端晶振的,我一开始认为这个是我板子没PL端晶振导致的,后面换用PS端晶振,也没成功,我以为这个文章就可能写不出来了。按照步骤走我编译的时候没找到探针,一个探针都没有。然后我去查信息,看到似乎这个ILA对于采样有要求,于是折腾了JTAG采样速率,后面也是失败,然后就再查,查出来时钟有要求(我猜需要PL端晶振才行)
后续是我买了个新板子,然后后面编译完,我看了下他结合约束完成的情况,然后发现有个警告

询问了下deep老师,然后我才发现,我的约束文件写错了。
大家需要仔细检查一下自己的约束文件,时钟的配置不是一般引脚那样就行
create_clock -period 20.000 -name sclk [get_ports sclk]
如果你发现你的约束文件没有加上这个,那么系统大概率是分辨不出来你这个引脚是时钟引脚的,他只会认为你这个引脚是普通引脚,导致后续观察不到波形
四、ILA的使用
1、界面介绍
加号代表添加观测信号,减号代表删除选中的信号
然后是连续触发,播放键就是再往后提取一些信号(满足要求后上传)
然后是立即触发,直接上传当前FPGA的信号

这个是修改为无符号十进制数的方法:

2、设置触发条件
我们这次实验需要找到对应cnt计数跳转到0的位置
我们可以看到trigger setup(设置触发条件)这里,点击add probes

将cnt触发时的值设置为0即可,然后点击播放键进行触发一次


可以发现,我们触发的位置是在中间,如果我们不喜欢这样,可以通过点击settings然后往下滑动,找到trigger position这里自行修改(没啥用,感觉doge)

3、如何删除ILAip
在使用完我们的IP核,确认好我们已经完成了任务要求之后,我们可以通过删除ip核来节省我们的FPGA资源(过河拆桥中)
鼠标右键我们的ip核,然后选择remove,然后记得勾选also delete the project local file