基于vivado开发xilinx系列FPGA的冷知识
第二篇来聊聊FPGA的硬件调试。
理论上来说,ISE中自带的chipscope也是可以用的,只是很多时候第三方开发板用10pin的JTAG连不上这个,所以还是老老实实用自带的ila(Integrated Logic Analyzer)工具吧。
关于ila的使用相关操作直接百度应该都能找到,只是普遍讲的比较乱,其实就两种常用的操作。
一、直接调用IP核
第一种方式是最常用的,也是我最推荐的,优点是直观形象、移植方便、不容易出错,缺点是只能添加同一个verilog文件内的信号(说不定也可以跨文件?关键是我不会)
在IP里表中搜索ila可以找到这个ip核:
至于这个system ila也不用担心选错了,反正是用不了的。
接下来是对ila进行配置,大部分保持默认。
按照项目需求,选好probe数量、采样数、高级触发功能就行了。
关于comparator的数量有什么用我也不懂,默认设置下用了这么久好像也没什么不对。
接下来就是生成ip核,在veo文件里找到例化代码复制过去用就完事了,给个例子吧:
-
ila_0 ila_inst (
-
.clk(clk), // input wire clk
-
.probe0(probe0), // input wire [0:0] probe0
-
.probe1(probe1) // input wire [31:0] probe1
-
);
二、使用set up debug功能在xdc文件中添加
重点来讲讲这种方式吧。这种方式的优缺点都十分明显,一定要慎重。
其实你百度到的一般都是这么用的(他们才不会告诉你这些坑),但是我面试时未来的领导告诉我最好少用这个,其实我大概也明白为什么。
该方法的最大优势是可以配合mark debug这个功能实现对任意位置任意信号的抓取。可问题是,这种方式经常处于不可控的状态,所谓“不可控”有这么几层意思:
1、该方式直接修改的是xdc,很多人(懒得学呗)压根不知道你加了这堆东西;
2、综合时会优化掉不少纯连线使用的中间变量,这导致你在该功能下找信号时经常会很迷惑;
3、总会有一些莫名其妙的操作导致xdc在另一个界面修改,你加了半天最后发现压根没写进xdc;
4、稍微一点点设计的变化就会让你添加的某些信号消失,从而在跑opt implementation时报错,你最好是每次先综合完再点set up debug确认一下。
说了这么多劝退的原因,为什么我依然使用这种方式呢,主要还是方便。
set up debug功能就在open synthesized design里,首先必须跑完综合流程,再打开综合。
接下来在sources窗口的旁边会出现netlist窗口(没有的话就在标题栏的window选项里)
如图,我添加了顶层文件为AD1_wrapper,里面包含了一个名为AD1_i的模块,我想观察其中DDC模块的I路输出,依次点开找到这个引脚,右键mark debug即可,当然也可以直接选下面的assign to debug port(不推荐)。
点开每个模块后nets中包含所有的引脚信号,inst包含所有的子模块,同样可以点开继续寻找更底层的子模块信号,只要你程序写的足够有条理应该不难找,这里我再次推荐block design这种开发方式(使用方法详见另一个专栏),这会让本流程无比好找。
如果你依然觉得这样找起来太麻烦,那我还可以教你一种写代码时直接标记的方式:
(*mark_debug = "true"*)
大小写都可以,写在任何你想要观测的信号前,比如:
-
(*mark_debug = "true"*) wire rst_n;
-
(*mark_debug = "true"*) reg [15:0] cnt;
-
(*mark_debug = "true"*) output dataout;
道理是相通的,netlist标记是写在了xdc里,这种是写在了verilog里,本质是一样的。
只进行了mark是没有意义的,接下来必须点击set up debug并直至finish。
就一直无脑next直至这个窗口,检查一下刚才mark的信号都在不在,有没有缺失clock domain的,这个是ila的工作时钟,一般选用全局工作时钟。
如果你发现某些信号没有时钟,最好检查一下是不是因为全程序都没有操作导致直接接地或者拉高了,这样是不是你要的结果;某些异步的信号的确天生没有时钟源,这时依然选择全局工作时钟,记住,这不是信号的时钟源,是ila的工作时钟!
把这几个选项按需求选后,点next直到finish,之后一定记得按ctrl+s保存,最后重新generate bitstream,完事。