在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 4506|回复: 10

[求助] 请教关于异步FIFO设计的问题

[复制链接]
发表于 2015-3-26 22:19:24 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
本帖最后由 IC.Michael 于 2015-3-26 22:21 编辑

Clifford E. Cummings有一篇文章【Simulation and Synthesis Techniques for Synchronous FIFO Design】提到一个FIFO设计,该设计只能用于测试不能用于综合。其中有些代码不太理解,请教一下大家。代码如下:



  1. `timescale 1ns/1ns
  2. module beh_fifo(rdata, rempty, wdata, wfull,
  3.                 rinc,rclk,rrst_n, winc,wclk,wrst_n);
  4.                
  5.   parameter DSIZE = 8;
  6.   parameter ASIZE = 4;
  7.   
  8.   output [DSIZE-1:0] rdata;
  9.   output wfull;
  10.   output rempty;
  11.   
  12.   input [DSIZE-1:0] wdata;
  13.   input winc, wclk, wrst_n;
  14.   input rinc, rclk, rrst_n;
  15.   
  16.   reg [ASIZE:0] wptr, wrptr1, wrptr2, wrptr3;
  17.   reg [ASIZE:0] rptr, rwptr1, rwptr2, rwptr3;
  18.   
  19.   parameter MEMDEPTH = 1<<ASIZE;
  20.   
  21.   reg [DSIZE-1:0] ex_mem [0:MEMDEPTH-1];
  22.   
  23.   always @(posedge wclk or negedge wrst_n)
  24.     begin
  25.       if (!wrst_n)
  26.         wptr <= 0;
  27.       else if (winc && !wfull)
  28.         begin
  29.           ex_mem[wptr[ASIZE-1:0]] <= wdata;
  30.           wptr <= wptr+1;
  31.         end
  32.     end
  33.    
  34.   always @(posedge wclk or negedge wrst_n)
  35.     begin
  36.       if (!wrst_n)
  37.         {wrptr3,wrptr2,wrptr1} <= 0;
  38.       else
  39.         {wrptr3,wrptr2,wrptr1} <= {wrptr2,wrptr1,rptr};
  40.     end
  41.    
  42.   always @(posedge rclk or negedge rrst_n)
  43.     begin
  44.       if (!rrst_n)
  45.         rptr <= 0;
  46.       else if (rinc && !rempty)
  47.         rptr <= rptr+1;
  48.     end
  49.    
  50.   always @(posedge rclk or negedge rrst_n)
  51.     begin
  52.       if (!rrst_n)
  53.         {rwptr3,rwptr2,rwptr1} <= 0;
  54.       else
  55.         {rwptr3,rwptr2,rwptr1} <= {rwptr2,rwptr1,wptr};
  56.     end
  57.    
  58.   assign rdata = ex_mem[rptr[ASIZE-1:0]];
  59.   assign rempty = (rptr == rwptr3);
  60.   assign wfull = ((wptr[ASIZE-1:0] == wrptr3[ASIZE-1:0]) &&
  61.                   (wptr[ASIZE] != wrptr3[ASIZE]));

  62. endmodule


复制代码



代码中关于reg [ASIZE:0] wptr, wrptr1, wrptr2, wrptr3; reg [ASIZE:0] rptr, rwptr1, rwptr2, rwptr3;这两组寄存器中
wrptr1, wrptr2, wrptr3以及rwptr1, rwptr2, rwptr3的作用不甚清楚,第二个以及第四个always块,还望请教一下大家。
发表于 2015-3-27 09:46:53 | 显示全部楼层
it looks the 2nd always block would like to synchronize rptr from rclk domain to wclk domain; and the 4th always block would like to synchronize wprt from wclk domain to rclk domain.
But I'm wondering if it is right here.
Basically, the multi-bit bus should be converted to other format to make sure only one bit is changing at any clock edge before feed it to synchronizer. In async fifo, gray code is used.
Another interesting issue is that if the fifo depth is not the power of 2, for example, there are only 13 entries. what should we do to handle the waddr/raddr synchronization.
 楼主| 发表于 2015-3-27 13:18:41 | 显示全部楼层
回复 2# fly_haopp


谢谢你的回复。我不明白的是:比如第四个always块中 {rwptr3,rwptr2,rwptr1} <= {rwptr2,rwptr1,wptr};
但是在判断空标志时用到了assign rempty = (rptr == rwptr3);
这里我不太理解,为何之前是通过左移四位补上wptr,在判断空时比较rptr和rwptr呢?
发表于 2015-3-27 23:06:01 | 显示全部楼层
跨时钟打了3排,同步到读时钟域,然后比较读写指针;RAM使用读写指针的低三位做地址;
 楼主| 发表于 2015-3-30 11:07:34 | 显示全部楼层
回复 4# qmdong


   谢谢您的回复!打三排是什么意思?还有这样会不会造成比较的时候的读写指针并不都是最新的读写指针呢?因为{wrptr3,wrptr2,wrptr1} <= {wrptr2,wrptr1,rptr};比如这个操作,需要等待三个时钟,rptr的值才会传给wrptr?另一点,它这里取这么移位比较的意义在哪里呢?为何不直接在写时钟时采样读指针,然后比较即可呢?
发表于 2015-3-30 15:06:51 | 显示全部楼层
假设rptr==rwptr3,实际上wptr可能不等于rwptr3,也就是判断为空的时候,其实有可能写入了数据,也就是不一定是空的。如果直接用rptr==wptr判断空满,因为是异步时钟,可能判断的过程中出现了读或者写的操作,这样可能会出错。用延迟后的读写指针比较,这样虽然可能空满判断不准确,这就是浪费了一些fifo空间,但是不至于出现错误。
 楼主| 发表于 2015-3-30 15:41:36 | 显示全部楼层
回复 6# ganshizhang

谢谢你的回答!但是我还是有一点疑问想要请教你!

   

读写

读写
比如进行三个操作,分别为复位、只写、只读。相应寄存器状态如图所示。但是在读完之后,rptr不等于rwptr3,因此判断非空,则继续读数据,而实际上此时fifo里面已经无有效数据了。这该如何解释呢?
发表于 2015-4-1 10:39:32 | 显示全部楼层
注意一下rptr读操作的条件,rinc&&!rempty
在你进行第一个写操作的时候,rwptr3需要进行三拍rclk延迟后,才能同步成1,也就是写完三拍过后,rempty才能变成0,也就是在前三拍不能进行读操作
 楼主| 发表于 2015-4-1 11:07:24 | 显示全部楼层
回复 8# ganshizhang


   多谢你的指点,现在明白了,谢谢!
发表于 2018-2-3 01:20:32 | 显示全部楼层
回复 8# ganshizhang


   Thank you for the reply, learn a lot
About the code could not be synthesized, how do you tell if it could not?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /2 下一条


小黑屋| 手机版| 关于我们| 联系我们| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-12-27 06:57 , Processed in 0.034501 second(s), 9 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表