FPGA工程的debug
在通过仿真规避了rtl代码设计阶段的问题后,我们编译的bit具备了上板卡调试的条件。以时钟章节的工程为例,在上板后可以直观的看到led灯的闪烁来进行功能是否正常的判断,但如果想要检测一些中间的过程信号,例如cnt寄存器的具体值,那么就需要在工程中添加ila IP抓取信号进行检测判断。
ila IP的添加
在FPGA改成中有多种方式可以抓取待debug的信号,可以在综合工具栏下通过set up debug选择对应的信号线进行添加。但这种方法在如今做block design的开发年代并不推荐,下面重点介绍通过添加ila IP的方式来抓取信号。

IP catalog下找到 ila ip

IP 配置页参数介绍

**Component Name (ila_0):**设置IP核实例名,生成后该名称将作为顶层模块名。
**Monitor Type:**选择ILA监控的信号类型。
**Native:**监控普通用户逻辑信号,也是最常用的模式。
**AXI:**专用于监控 AXI总线 的通道信号(如地址、数据、控制信号),并能按通道类型(读/写)进行分组显示,极大方便AXI协议调试。
**Number of Probes:**需监控的信号组(探针)数量。每个探针可包含多位信号。ILA可支持最多1024个探针,但图形界面仅支持配置前64个。
**Sample Data Depth:**采样深度,决定ILA一次触发能捕获的数据点数量。例如设为1024,则触发后ILA会连续采集1024个时钟周期的信号值。深度越大,捕获的波形越长,但也更消耗BRAM资源。
**Same Number of Comparators for All Probe Ports:**启用后,所有探针使用相同数量的比较器,便于统一配置触发条件。
**Number of Comparators:**每个探针配备的比较器数量。比较器用于设置触发条件(例如在特定数据值上触发)。数量越多,触发的逻辑组合可以更复杂,但也更消耗资源。
**Trigger Out Port:**勾选后为ILA提供一个触发输出端口。当内部触发条件满足时,该端口输出一个脉冲,可用于级联其他ILA或触发外部仪器,包含一路触发输出及一路后级的ACK信号输入。
**Trigger In Port:**勾选后为ILA提供一个触发输入端口,允许外部信号强制触发ILA开始捕获数据,包含一路触发输入及一路输出给上一级的ACK信号。
**Input Pipe Stages:**在信号进入ILA采样逻辑前添加的流水线寄存器级数。增加级数有助于改善时序收敛(降低路径延迟),但同时也会增加观察到信号的延迟。
现在以检测时钟工程中的lock 信号以及cnt寄存器值信号为例,对ila做一下配置;
共检测两组信号,因此probes设置为2;

lock信号位宽为1,cnt寄存器位宽为26,对应的抓取位宽配置为1和26;

设置完成后ooc生成IP,参考模块调用示例,顶层代码添加以下内容。
ila_0 ila_cnt (
.clk(clk0), // input wire clk
.probe0(pll_lock), // input wire [0:0] probe0
.probe1(cnt) // input wire [25:0] probe1
);
Verilog作为硬件语言,代码并不是自上而下顺序执行,而是并行运作,因此这段ila代码添加的位置并不是那么重要,当然还是需要放在调用的这几个信号的定义语句之后,对于未作明确reg、wire类型定义的信号,会默认按照wire类型定义。
ila ip的正常工作需要时钟参考,因此对于一些外部时钟,供给一个ila ip后如果发现ila报错无法工作那就可以判断时钟源出了问题*
上板调试
Program device,会在下载bit的时候将编译好的ltx文件也下载进板卡。
下载完成后就可以看到ila窗口了,在窗口下可以看到在工程中配置抓取的两组信号pll_lock以及cnt寄存器。目前这里是没有任何数据的(类似示波器的wait for trig状态)

通过点击红框所示位置可以进行一次debug抓取,类似运行示波器的auto,这里可以看到时钟一直保持在锁定状态,cnt寄存器支持进行累加计数。

上面只展示了ila对FPGA芯片内部数字信号的抓取记录和展示的能力,实际在进行工程debug时并不是这样使用的,想要实际定位问题,需要在trigger setup下设置抓取条件,类似在使用示波器抓取波形时,需要接入合适的触发信号并调节合适的触发电平,当这个触发条件满足时,ila才会抓取对应的数字信号时序信息。
所以更多的时候能不能有效的定位问题取决于工程师是否能够分析得出哪些是有效的信号,并思考得出合适的抓取条件,这样才能精准抓到想要观察的异常状况,进而定位解决。
ila 的 Trigger Setup
添加信号,并通过合适的 与/或 等于/不等于 条件来定义特定的触发条件

例如现在想在cnt计数为100时进行一次数据采集,将trig进行上图配置

点击运行后,可以观察到在一段等待时间后,采数被触发并在窗口中展示了对应的时序波形。其中红色的T标识了满足触发条件的时刻。
Trigger mode Setting配置

Capture mode: ALWAYS
这是ILA的采集策略。ALWAYS 表示 ILA 始终在采样并填充存储空间。当存储空间填满后,新数据会覆盖旧数据,直到触发条件满足的那一刻,然后停止捕获并保留触发点周围的数据。
另一种模式是 TRIGGER,表示ILA只在触发条件满足后才开始捕获数据。
Number of windows: 1 - 1024
该参数定义了ILA将存储空间划分为多少个窗口(Segment)。每个窗口可以独立地保存一次触发事件的捕获数据。这允许你多次触发并保存多段数据,而不是只保存一次触发事件。结合触发位置,可以灵活地观察触发前后的数据变化。
例如,如果你将其设置为 4,则ILA会依次捕获4次触发事件的数据,并在工具窗口中显示为4个独立的波形窗口。
Window data depth: 1024 1 - 1024
每个窗口的采样深度。它决定了一次触发事件下,ILA捕获多少个连续时钟周期的数据样本。
注意:这个值的最大值由之前IP配置时设定的采样深度决定。例如,你之前设定了 Sample Data Depth: 4096,那么这里最大也只能填 4096。
Trigger position in window: 512 0 - 1023
这个值指定了触发点位于窗口内的位置(以样本数计)。它决定了你能在波形上观察到触发点前和触发点后各多少数据。
若设为窗口中间值(如 512/1024),则波形上触发点左右两侧的数据量大致相等。
若设为 0,则触发点位于窗口最左侧,只能观察到触发后的数据。
若设为最大值(如 1023),则触发点位于窗口最右侧,能够观察到触发前的大量数据,便于分析触发前状态。建议在调试时通常将其设为窗口深度的一半,以便同时观察触发前后的信号变化。但如果想定位问题的"前因",可以适当增大这个值。