2013-04-12 210 views
3

我在网上找到了下面这段代码,同时寻找好的FIFO设计。从链接SVN Code FIFO -Author Clifford E. Cummings。我做了一些研究,但我无法弄清楚为什么设计中有三个指针?我可以读取代码,但是我错过了什么?异步FIFO设计

module sync_r2w #(parameter ADDRSIZE = 4) 
(output reg [ADDRSIZE:0] wq2_rptr, 
input [ADDRSIZE:0] rptr, 
input wclk, wrst_n); 
reg [ADDRSIZE:0] wq1_rptr; 
always @(posedge wclk or negedge wrst_n) 
if (!wrst_n) {wq2_rptr,wq1_rptr} <= 0; 
else {wq2_rptr,wq1_rptr} <= {wq1_rptr,rptr}; 
endmodule 


module sync_w2r #(parameter ADDRSIZE = 4) 
(output reg [ADDRSIZE:0] rq2_wptr, 
input [ADDRSIZE:0] wptr, 
input rclk, rrst_n); 
reg [ADDRSIZE:0] rq1_wptr; 
always @(posedge rclk or negedge rrst_n) 
if (!rrst_n) {rq2_wptr,rq1_wptr} <= 0; 
else {rq2_wptr,rq1_wptr} <= {rq1_wptr,wptr}; 
endmodule 

回答

9

你在这里看到的是所谓的双等级同步器。如你所说,这是一个异步FIFO。这意味着FIFO的读取和写入侧不在同一时钟域。

正如您所知,触发器需要设置和保持时序要求才能正常工作。当您将信号从一个时钟域驱动到另一个时钟域时,在一般情况下无法保证这一要求。

当你违反这些要求时,FF进入所谓的'亚稳定'状态,其中有一段时间不确定,然后(或多或少)随机地进入1或0.他们这样做(和这是很重要的),而不是一个时钟周期。

这就是为什么在这里两层触发器。第一个有一个趋向亚稳定的机会,但应该及时解决,被第二组触发器干净地捕获。

这是它自己的是不足以跨时钟域传递一个多位值(地址指针)。如果不止一个位同时发生变化,那么您不能确定转换在另一侧是否干净。所以在这些情况下你会经常看到的是FIFO指针将通过灰色编码。这意味着计数器的每个增量一次最多改变一个位。

例如而不是00-> 01-> 10-> 11-> 00 ...它将是00-> 01-> 11-> 10-> 00 ...

时钟域交叉是一个深刻而微妙的主题。即使有经验的设计师也经常在没有仔细考虑的情况下将其搞乱

顺便说一句普通的Verilog仿真不会显示我刚才在零延迟模拟中所描述的内容。您需要使用实时时序模型进行带注释的SDF模拟。