特权同学

不可无视异步清除信号

0
阅读(42020)

接着上次AV图像显示,当时的现象是图像时不时的错位显示(视觉上就是瞬间错位的显示闪烁)。让特权同学很是纳闷了两天有余,顺着整个数据流的方向从输入的芯片时钟VCLK找起,到内部的帧解码,再到跨时钟交换数据的FIFO,最后怀疑SDRAM的读写时序方面。并且不断的重新查看verilog源码、仿真查看关键信号、时序分析也是力求准确,甚至最后只能动用Signal Tap II来,并且在工程内部做一些简单的标志位来定位可疑的地方。

两天下来都有些筋疲力尽,实在有些找不着北,使用Signal Tap II每次重新定位问题都得重新编译下载,动辄三五分钟甚至更长时间的编译都可以去泡上一杯茶了。后来把问题最终定位在了数据交换的DCFIFO上,原本把问题定位在FIFO的满和空上,但是调试纠错了很久都没有发现这里有什么不是的地方。因此,猜想由于两边的时钟是异步的,会不会在读写的时候出问题了呢,由于之前对FIFO的结构,尤其是DCFIFO本身没有太多研究,也只是简单的调用IP核,花了些时间研究FIFO,但是还真没弄明白怎么回事。

后来调试中对每一个组合逻辑输出部分都先打一拍再输出看看问题是否解决,忽然想到两个FIFO的清除信号虽然都是寄存器直接输出的,好像蛮干净的,但尤其那个完全不相干时钟的FIFO,它的清除信号该做一点同步工作。也只是简单的打了一怕,再编译下载,好像图像不再有错误帧显示了,原本每三五秒就闪烁一次,这回足足盯着看了3分钟没有问题。反复验证,确实这么一个简单的代码更改解决了问题。

         这个问题确是出在异步清除信号上,但不是FIFO的异步清除信号,也和FIFO无关。而是一个和FIFO共用的清除信号,但是他影响的是一个地址计数器,直接导致问题的出现。这个清除信号是下面的st_blk,其实它不出现在敏感表里触发,也算是同步处理的异步清除信号。这个异步清除信号是外部输入VCLK时钟,他的27MHz和这里用于清除地址的100MHz时钟毫不相关,理论上直接拿来用确实不合适,但是想到它清零sys_wrabr寄存器和sys_wrabr的计数使能条件neg_sdwrack触发相遇的可能性基本为零。但是结果却是问题出在了这里。说实话,特权同学甚至现在也没有完全搞明白这个未经过处理的异步清除信号为何能够带来这样大的危害。

always @(posedge clk_100m or negedge rst_n)

         if(!rst_n) sys_wrabr <= 13'd0;

         else if(!st_blk) sys_wrabr <= 13'd0;         //一屏结束后重新复位地址

         else if(neg_sdwrack) sys_wrabr <= sys_wrabr+1'b1;     //一页写入完成后,地址递增256

 

         对于这样的教训,还是应该记住一点:异步清除信号最好同步后再用,就像之前特权同学重视异步复位的同步释放那样。最后,特权同学也不得不认真的给这里清除信号做一个异步清除信号的同步释放处理。

 

reg st_blkr1,st_blkr2;      //bank清零寄存器,用于异步复位同步释放处理

        

always @(posedge clk_100m or negedge st_blk)

         if(!st_blk) st_blkr1 <= 1'b0;

         else st_blkr1 <= 1'b1;

        

always @(posedge clk_100m or negedge st_blk)

         if(!st_blk) st_blkr2 <= 1'b0;

         else st_blkr2 <= st_blkr1;