数字ic设计技巧:添加debug信号
数字ic设计技巧:添加debug信号
文章目录
- 数字ic设计技巧:添加debug信号
- 1. 握手方式读取数据的debug信号o_wait_read
- 2. FIFO的空满信号
- 3. 输入错误
- 4. 多状态机的debug信号
- 5. 使用FIFO记录log
在数字ic设计的过程中,我们常常通过添加一些debug信号来调试代码,以便快速定位问题;比如我们用一个芯片读取很多设备的数据进行处理,有个设备一直没返回数据,导致芯片一直在等待这个数据,卡住了,这时候就需要有个芯片引脚(debug信号),让我们能知道是哪个设备的问题;
1. 握手方式读取数据的debug信号o_wait_read
我们向一个设备发送req请求信号,该设备接收到请求信号后,将准备好的dat数据和ack有效信号一起发送给我们;我们在ack有效时候接收数据,完成握手;代码如下所示:
output req;
input ack;
input [3: 0] dat;
always@(posedge click or negedge rstn)
if(!rstn)
req <= 1‘d0;
else if(clr | (req & ack))
req <= 1’b0; //握手成功,接收到数据后不再请求
else if(req_vld)
req <= 1’b1; //拉起请求
always@(posedge clk or negedge rstn)
if(!rstn)
dat_rec <= ‘d0;
else if(req&ack)
dat_rec<= dat; //req和ack均为1时,接收数据
但现在有个问题,如果我们输出req之后,对应的模块一直没有返回ack数据,怎么办?这时我们需要设计一个最大等待时间MAX_DELAY_TIME,超过这个时间,就发送一个脉冲告诉芯片的控制模块这儿卡住了,然后由控制模块再根据具体需要来决定怎么处理(一般是清零,重新运行)
reg [12 : 0] delay_cnt;
always@(posedge click or negedge rstn)
if(!rstn)
delay_cnt <= 0;
else if(clr | req&ack)
delay_cnt <= 0;//清零或正常握手
else if(req)
delay_cnt <= delay_cnt+1; //有req为1,但ack为0
assign o_wait_read = delay_cnt == MAX_DELAY_TIME;
2. FIFO的空满信号
数字ic设计中经常会用到FIFO,如果FIFO为空时,我们却发起了读请求;或者FIFO为满时,我们发起了写请求;这肯定是会导致丢失数据,有一定风险,需要我们认真检查,因此这两种情况都应该在调试中用$display打印出来;
always@(posedge clk)
if(full & write) //对一个满状态的FIFO进行写操作
$diplay(‘write FIFO error’)
always@(posedge clk)
if(empty & read) //对一个空状态的FIFO进行读操作
$diplay(‘read FIFO error’)
3. 输入错误
比如我们根据算法分析,认为输入信号a的数值必定是小于b的,但是芯片中的模块接收到了一个a > b的信号,这时应该返回一个error信号,而不是直接进行正常的运算;
always@(posedge clk or negedge rstn)
if(!rstn)
error = 0;
else if(clr)
error = 0;
else if(a > b & dat_vld) //a>b且该数据有效
error = 1;
4. 多状态机的debug信号
在多个状态机中,有时会将状态机外接出去。这样将来芯片实际运行时,如果卡住,或者出其他问题,我们就能很快知道他卡在哪个状态了;
5. 使用FIFO记录log
在网上看到一种方法,用一个FIFO储存芯片运行的关键结点的log信息,如果出错,就通过芯片预留的端口将该log信息读取出来,从而达到快速定位问题的效果。