在FPGA工程中经常会因为debug手段有限无法捕捉到错误状态,ila的basic使用能够满足大部分捕捉要求,在不能满足捕捉条件时,编写中间逻辑也可以触发异常状态。vivado提供了 ILA Advanced Trigger,通过编写触发状态机达到触发条件。今天写了简单的debug程序,跑了下 ILA Advanced Trigger,没有太多惊喜,可能小程序,体验不出其特殊价值,期待后面复杂工程的检验。
程序是一个计数器,在循环计数,通过设置VIO来产生触发条件。代码段如下:
//计数器循环计数 reg[31:0] timer_cnt; always@(posedge sys_clk) timer_cnt <= (timer_cnt >= 32'd49_999_999) ? 0 : timer_cnt + 32'd1; //产生trigger信号
wire vio_in;//默认初值是0 reg vio_1r; reg vio_2r; reg vio_rise;
always@(posedge sys_clk) begin vio_1r <= vio_in; vio_2r <= vio_1r; vio_rise <= ~vio_2r & vio_1r; end
//例化VIO核 vio_0 vio( .clk(sys_clk), .probe_out0(vio_in) ); //例化ILA核 ila_0 ila( .clk(sys_clk), .probe0(timer_cnt), .probe1(vio_in), .probe2(vio_rise), );
1、首先例化ILA核
2、下到板子中,trigger界面可勾选BASIC_ONLY、ADVANCED_ONLY,在勾选ADVANCED_ONLY时,如下图:
3、在advanced trigger下需要编写trigger状态机,该状态机形式简单,保存后缀名为*.tsm。设计的捕捉条件时首先检测到vio信号上升沿后,进入触发timer_cnt状态,在timer_cnt == 32'h00000100时进行触发。具体如下:
#ILA FSM STATE state wait_for_vio_rise: if (vio_rise == 1'b1) then goto wait_for_timer_cnt; else goto wait_for_vio_rise; endif
state wait_for_timer_cnt: if (timer_cnt == 32'h00000100) then trigger; else goto wait_for_timer_cnt; endif 下载板子中如图:按VIO按钮,触发在timer_cnt == 32'h00000100处。使用FSM状态触发,同时可以触发ILA端口的信号,这样触发条件更严格,有利于异常现象的排查。
这样看来是挺简单的,希望能起到四两拨千斤的效果。
详细的设置可参考ug936-vivado-tutorial-programming-debugging最后一章节。