参考博客
可以先看一下参考博客,讲的还算很详细。
链接: (原創) 如何使用SignalTap II觀察reg與wire值? (SOC) (Verilog) (Quartus II) (SignalTap II).
我的理解
参考博客中讲到,为了防止Quartus工具优化我们定义的wire和reg信号,可以在其定义前加约束,例如wire信号如下约束:
(* keep *)wire a;
或者
wire a/*synthesis keep*/;
reg信号如下约束:
(* noprune *)reg a;
或者
reg a/*synthesis noprune*/;
或者在模块后面添加约束防止整个模块被优化,在此就不列举了,具体见参考博客。
笔者使用的方法
通常,我们在SignalTap中添加信号都是要搜索相应的信号名,比如我需要监测如下一些信号
// register and wire definition
reg rd_req;
reg wr_req;
reg [22:0] rd_addr;
reg [22:0] wr_addr;
wire rd_data_vld;
wire wr_data_rdy;
wire [63:0] rd_data;
wire [63:0] wr_data;
wire rd_ack;
wire wr_ack;
根据参考博客的做法就是在上述信号前都加上相应的约束,但是在SignalTap添加信号的时候,需要手动搜索这些信号或者挨个寻找添加。在这里我使用的便捷方法就是,重新定义一组相应的寄存器(当然这会增加FPGA寄存器资源的使用)。
如下
//debug
(* noprune *)reg ila_rd_req;
(* noprune *)reg ila_wr_req;
(* noprune *)reg [22:0] ila_rd_addr;
(* noprune *)reg [22:0] ila_wr_addr;
(* noprune *)reg ila_rd_data_vld;
(* noprune *)reg ila_wr_data_rdy;
(* noprune *)reg [63:0] ila_rd_data;
(* noprune *)reg [63:0] ila_wr_data;
(* noprune *)reg ila_rd_ack;
(* noprune *)reg ila_wr_ack;
信号的同步操作时钟为afi_clk,异步高电平复位信号为afi_reset,如下
always@(posedge afi_clk or posedge afi_reset)
if(afi_reset)begin
ila_rd_req <= 0;
ila_wr_req <= 0;
ila_rd_addr <= 0;
ila_wr_addr <= 0;
ila_rd_data_vld <= 0;
ila_wr_data_rdy <= 0;
ila_rd_data <= 0;
ila_wr_data <= 0;
ila_rd_ack <= 0;
ila_wr_ack <= 0;
end
else begin
ila_rd_req <= rd_req;
ila_wr_req <= wr_req;
ila_rd_addr <= rd_addr;
ila_wr_addr <= wr_addr;
ila_rd_data_vld <= rd_data_vld;
ila_wr_data_rdy <= wr_data_rdy;
ila_rd_data <= rd_data;
ila_wr_data <= wr_data;
ila_rd_ack <= rd_ack;
ila_wr_ack <= wr_ack;
end
在需要监测的信号前都加上"ila_",这样我在SignalTap中搜索* ila_ *即可快速添加这些信号。
如下(有些信号是我实际做工程的时候添加的,在本博客中未列举)
这样我们需要检测的信号就可以快速被添加进来。
不足之处
该方法操作便利的同时,不足就在于每次添加新的检测信号时,就需要再定义一个相应的寄存器,并添加进always块里面。麻烦就麻烦在需要重新定义新寄存器并重新赋值上面吧~
后面有想法学习一下python,用一段python小程序自动生成一个模板,应该会便捷很多,哈哈哈~