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

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

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 3918|回复: 11

[求助] 异步fifo程序问题 求大神指导

[复制链接]
发表于 2011-11-28 10:27:01 | 显示全部楼层 |阅读模式

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

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

x
为什么要同步wptr、rptr? 就是20-27行的程序则怎么解释?



  1. module fifo1(rdata, wfull, rempty, wdata, winc, wclk, wrst_n,rinc, rclk, rrst_n);
  2. parameter DSIZE = 8; parameter ASIZE = 4;
  3. output [DSIZE-1:0] rdata;
  4. output wfull;
  5. output rempty;
  6. input [DSIZE-1:0] wdata;
  7. input winc, wclk, wrst_n;
  8. input rinc, rclk, rrst_n;
  9. reg wfull,rempty;
  10. reg [ASIZE:0] wptr, rptr, wq2_rptr, rq2_wptr, wq1_rptr,rq1_wptr;
  11. reg [ASIZE:0] rbin, wbin;
  12. reg [DSIZE-1:0] mem[0:(1<<ASIZE)-1]; //定义存储器宽度为8,深度为16
  13. wire [ASIZE-1:0] waddr, raddr; //读写地址
  14. wire [ASIZE:0] rgraynext, rbinnext,wgraynext,wbinnext; //读写的格雷码与二进制码
  15. wire rempty_val,wfull_val;
  16. //-----------------双口RAM存储器--------------------
  17. assign rdata=mem[raddr];
  18. always@(posedge wclk)
  19. if (winc && !wfull) mem[waddr] <= wdata;
  20. //-------------同步rptr 指针-------------------------
  21. always @(posedge wclk or negedge wrst_n)
  22. if (!wrst_n) {wq2_rptr,wq1_rptr} <= 0;
  23. else {wq2_rptr,wq1_rptr} <= {wq1_rptr,rptr}; //这里采用了位拼接操作符
  24. //-------------同步wptr指针---------------------------
  25. always @(posedge rclk or negedge rrst_n)
  26. if (!rrst_n) {rq2_wptr,rq1_wptr} <= 0;
  27. else {rq2_wptr,rq1_wptr} <= {rq1_wptr,wptr}; //
  28. //-------------rempty产生与raddr产生-------------------
  29. always @(posedge rclk or negedge rrst_n) // GRAYSTYLE2 pointer
  30. begin
  31. if (!rrst_n) {rbin, rptr} <= 0;
  32. else {rbin, rptr} <= {rbinnext, rgraynext};
  33. end
  34. // Memory read-address pointer (okay to use binary to address memory)
  35. assign raddr = rbin[ASIZE-1:0];
  36. assign rbinnext = rbin + (rinc & ~rempty);
  37. assign rgraynext = (rbinnext>>1) ^ rbinnext; //产生读格雷码
  38. // FIFO empty when the next rptr == synchronized wptr or on reset
  39. assign rempty_val = (rgraynext == rq2_wptr);
  40. always @(posedge rclk or negedge rrst_n)
  41. begin
  42. if (!rrst_n) rempty <= 1'b1;
  43. else rempty <= rempty_val;
  44. end
  45. //---------------wfull产生与waddr产生------------------------------
  46. always @(posedge wclk or negedge wrst_n) // GRAYSTYLE2 pointer
  47. if (!wrst_n) {wbin, wptr} <= 0;
  48. else {wbin, wptr} <= {wbinnext, wgraynext};
  49. // Memory write-address pointer (okay to use binary to address memory)
  50. assign waddr = wbin[ASIZE-1:0];
  51. assign wbinnext = wbin + (winc & ~wfull);
  52. assign wgraynext = (wbinnext>>1) ^ wbinnext; //产生写格雷码
  53. assign wfull_val = (wgraynext=={~wq2_rptr[ASIZE:ASIZE-1], wq2_rptr[ASIZE-2:0]}); //:ASIZE-1]
  54. always @(posedge wclk or negedge wrst_n)
  55. if (!wrst_n) wfull <= 1'b0;
  56. else wfull <= wfull_val;
  57. endmodule





复制代码
发表于 2011-11-28 13:05:14 | 显示全部楼层
你这个是异步FIFO...wclk和rclk频率又不同....
异步时钟域的信号同步常规做法啊,打两拍....避免亚稳态的传播..
基础知识....
发表于 2011-11-28 15:33:51 | 显示全部楼层
同步到当前时钟域,否则做比较的时候可能异常,亚稳态之类。
 楼主| 发表于 2011-11-28 15:47:03 | 显示全部楼层
回复 3# jackertja


    能给详细说说吗,我是菜鸟,不是很理解
 楼主| 发表于 2011-11-28 15:49:52 | 显示全部楼层
回复 2# jack888518


    我看的有关异步fifo里面都提到过这个亚稳态的问题,不说是用格雷码来消除吗?难道不是吗?那几句代码为什么采用了非阻塞赋值?能给详细解答一下吗?
发表于 2011-11-28 16:04:26 | 显示全部楼层
本帖最后由 jackertja 于 2011-11-28 16:10 编辑

回复 4# lixuecheng


    写端要判断fifo是否full,要将写地址和读地址做比较,如果直接用读时钟下的读地址信号,有可能在写时钟上升沿时读地址正在跳变,比较器的结果也在跳变造成full信号的建立/保持时间不够,产生亚稳态。
将读地址同步到写时钟域下,就保证了后面比较结果的建立/保持时间。
---
但 在用写时钟采用读地址时,也可能因为建立/保持时间不够而造成亚稳态,得到错误的值,因此要先将读地址转换成格雷码,这样即使采错,也只是前一个地址的值,可以通过其他逻辑来防止写溢出。

--
写地址同步到读时钟的原因相同。
发表于 2011-11-28 22:31:57 | 显示全部楼层



这个回答差不多了...楼主你问说的格雷码避免亚稳态这种情况只针对连续变化的多位异步输入信号(比如地址信号,001->010->011.....)等等,通过格雷码,各地址线之间保证一个时钟周期只会有一个bit变化,就算产生了亚稳态,也只有一个亚稳态信号,再通过其他逻辑手段处理下,对不敏感电路,还是可以使用的。
发表于 2011-11-28 22:34:15 | 显示全部楼层


回复  jack888518


    我看的有关异步fifo里面都提到过这个亚稳态的问题,不说是用格雷码来消除吗?难 ...
lixuecheng 发表于 2011-11-28 15:49




   用非阻塞赋值就是一种逻辑处理,加两个寄存器“等”两个clk,你没发现两边的连接符所包含的信号正好是Z字型赋值的么....
 楼主| 发表于 2011-12-1 10:52:11 | 显示全部楼层
回复 8# jack888518


    {wq2_rptr,wq1_rptr} <= {wq1_rptr,rptr};
   这句可不可以等效于wq2_rptr<=wq1_rptr;wq1_rptr<=rptr;为什么是两个周期呢?
发表于 2011-12-1 13:52:36 | 显示全部楼层


你这个是异步FIFO...wclk和rclk频率又不同....
异步时钟域的信号同步常规做法啊,打两拍....避免亚稳态的传 ...
jack888518 发表于 2011-11-28 13:05



五个字符。

写错删除。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

×

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

GMT+8, 2024-5-13 02:53 , Processed in 0.038619 second(s), 7 queries , Gzip On, Redis On.

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