学习笔记二:异步FIFO
1 module fifo1 #(parameter DSIZE = 8, 2 parameter ASIZE = 4) //用格雷码的局限性:循环计数深度必须是2的n次幂,否则就失去了每次只变化一位的特性 3 (wclk,wrstn,wdata,wfull,winc,rclk,rrstn,rdata,rempty,rinc); 4 input wclk,wrstn,winc; 5 input [DSIZE - 1:0] wdata; 6 output wfull; 7 8 input rclk,rrstn,rinc; 9 output [DSIZE - 1:0] rdata; 10 output rempty; 11 12 reg wfull,rempty; //空满输出 13 reg [ASIZE:0] rbin,wbin; //读写二进制地址 14 reg [ASIZE:0] wptr,rq1_wptr,rq2_wptr, //读写指针打两拍CDC同步 15 rptr,wq1_rptr,wq2_rptr; 16 wire [ASIZE:0] rbinnext,wbinnext, //读写指针递增 17 rgraynext,wgraynext; //读写指针递增对应的格雷码 18 wire [ASIZE - 1:0] waddr,raddr; //实际读写mem的地址 19 20 reg [DSIZE - 1:0] mem [0:(1<<ASIZE) - 1]; //左移一位表示乘2 21 22 23 //---------------------双口RAM存储器 数据读写----------------------------- 24 assign rdata = mem[raddr]; //读 25 always@(posedge wclk) begin //写 26 if(winc && !wfull) begin 27 mem[waddr] <= wdata; 28 end 29 end 30 31 //---------------------将读指针CDC到写时钟域------------------------------ 32 always@(posedge wclk or negedge wrstn) begin 33 if(!wrstn) begin 34 wq2_rptr <= 5'd0; 35 wq1_rptr <= 5'd0; 36 end 37 else begin 38 wq1_rptr <= rptr; 39 wq2_rptr <= wq1_rptr; 40 end 41 end 42 43 //---------------------将写指针CDC到读时钟-------------------------------- 44 always@(posedge rclk or negedge rrstn) begin 45 if(!rrstn) begin 46 rq2_wptr <= 5'd0; 47 rq1_wptr <= 5'd0; 48 end 49 else begin 50 rq1_wptr <= wptr; 51 rq2_wptr <= rq1_wptr; 52 end 53 end 54 55 56 //读相关指针的产生 57 always@(posedge rclk or negedge rrstn) begin 58 if(!rrstn) begin 59 rptr <= 5'd0; 60 rbin <= 5'd0; 61 end 62 else begin 63 rptr <= rgraynext; 64 rbin <= rbinnext; 65 end 66 end 67 //写相关的指针 68 always@(posedge wclk or negedge wrstn) begin 69 if(!wrstn) begin 70 wbin <= 5'd0; 71 wptr <= 5'd0; 72 end 73 else begin 74 wbin <= wbinnext; 75 wptr <= wgraynext; 76 end 77 end 78 79 //addr截取与格雷码化指针 80 assign raddr = rbin[ASIZE - 1:0]; //mem的读地址 81 assign rbinnext = rbin + (rinc & ~rempty); //mem的下一个读地址 82 assign rgraynext = (rbinnext>>1) ^ rbinnext; //mem的读地址对应的格雷码 83 84 assign waddr = wbin[ASIZE - 1:0]; 85 assign wbinnext = wbin + (winc & !wfull); 86 assign wgraynext = (wbinnext>>1) ^ wbinnext; 87 88 //---------------------rempty产生------------------------------ 89 //FIFO empty when the next rptr == synchronized wptr or on the reset 90 always@(posedge rclk or negedge rrstn) begin 91 if(!rclk) begin 92 rempty <= 1'b1; 93 else begin 94 rempty <= (rgraynext == rq2_wptr); 95 end 96 end 97 98 //---------------------wfull产生------------------------------ 99 //FIFO full when CDC过来的格雷码(采样值)的最高位+次高位和bin转换过来的格雷码(理论值)均不同,剩下低位都相同 100 always@(posedge wclk or negedge wrstn) begin 101 if(!wrstn) begin 102 wfull <= 0; 103 end 104 else begin 105 wfull <= (wgraynext == {~wq2_rptr[ASIZE,ASIZE-1],wq2_rptr[ASIZE-2:0]}); 106 end 107 end 108 109 endmodule 110 /*Clifford E. Cummings的文章中提到的STYLE #1,构造一个指针宽度为N+1,深度为2^N字节的FIFO(为便方比较将格雷码指 111 针转换为二进制指针)。当指针的二进制码中最高位不一致而其它N位都 相等时,FIFO为满(在Clifford E. Cummings的文章中以 112 格雷码表示是前两位均不相同,而后两位LSB相同为满,这与换成二进制表示的MSB不同其他相同为满是一样的)。当指针完全相等时, 113 FIFO为空。 114 这种方法思路非常明了,为了比较不同时钟产生的指针,需要把不同时钟域的信号同步到本时钟域中来,而使用Gray码的目的就是使这个 115 异步同步化的过程发生亚稳态的机率最小。 116 */
很好的讲解:
https://www.cnblogs.com/aslmer/p/6114216.html#4067080
https://blog.csdn.net/wyj_2016/article/details/78469272
https://blog.csdn.net/IamSarah/article/details/76085635
https://blog.csdn.net/IamSarah/article/details/76093802
https://blog.csdn.net/tnaig/article/details/81503259
转载于:https://www.cnblogs.com/ucas-ime/p/10254811.html
学习笔记二:异步FIFO相关推荐
- IC学习笔记3——异步FIFO
IC学习笔记3--异步FIFO 异步FIFO的工作内容与同步FIFO类似,但是异步FIFO的控制并不像同步FIFO那么简单,因为异步FIFO工作在不同的时钟域,这将会带来一些问题,比如空满检测?是否还 ...
- 深度强化学习笔记(二)——Q-learning学习与二维寻路demo实现
深度强化学习笔记(二)--Q-learning学习与二维寻路demo实现 文章目录 深度强化学习笔记(二)--Q-learning学习与二维寻路demo实现 前言 理论 什么是Q-Learning 算 ...
- SwiftUI学习笔记之异步数据请求
SwiftUI学习笔记之异步数据请求 方法一 方法描述: 结合使用 ObservableObject @Published @ObservedObject ObservableObject 定义自己的 ...
- Netty学习笔记二网络编程
Netty学习笔记二 二. 网络编程 1. 阻塞模式 阻塞主要表现为: 连接时阻塞 读取数据时阻塞 缺点: 阻塞单线程在没有连接时会阻塞等待连接的到达,连接到了以后,要进行读取数据,如果没有数据,还要 ...
- qml学习笔记(二):可视化元素基类Item详解(上半场anchors等等)
原博主博客地址:http://blog.csdn.net/qq21497936 本文章博客地址:http://blog.csdn.net/qq21497936/article/details/7851 ...
- [转载]dorado学习笔记(二)
原文地址:dorado学习笔记(二)作者:傻掛 ·isFirst, isLast在什么情况下使用?在遍历dataset的时候会用到 ·dorado执行的顺序,首先由jsp发送请求,调用相关的ViewM ...
- PyTorch学习笔记(二)——回归
PyTorch学习笔记(二)--回归 本文主要是用PyTorch来实现一个简单的回归任务. 编辑器:spyder 1.引入相应的包及生成伪数据 import torch import torch.nn ...
- tensorflow学习笔记二——建立一个简单的神经网络拟合二次函数
tensorflow学习笔记二--建立一个简单的神经网络 2016-09-23 16:04 2973人阅读 评论(2) 收藏 举报 分类: tensorflow(4) 目录(?)[+] 本笔记目的 ...
- Scapy学习笔记二
Scapy学习笔记二 Scapy Sniffer的用法: http://blog.csdn.net/qwertyupoiuytr/article/details/54670489 Scapy Snif ...
- Ethernet/IP 学习笔记二
Ethernet/IP 学习笔记二 原文链接:http://wiki.mbalib.com/wiki/Ethernet/IP 1.通信模式 不同于源/目的通信模式,EtherNet/IP 采用生产/消 ...
最新文章
- for 循环迭代变量
- 山寨SaaS--管理软件夜未眠(五)
- I/O设备的编址方式(统一编址,独立编址)
- dhcp服务器没有响应怎么解决,dhcp服务器没有响应
- 腾讯专利仅次谷歌;​苹果或将 iPhone 订单转给和硕;​Uber 接受比特币支付 | 极客头条...
- mysql计算经纬度亮点之间的距离
- Go基础-变量的定义
- 四种超实用的超级记忆法-数字定桩法,借助语句定桩法,标题定桩法,记忆宫殿法
- ov5640摄像头使用心得
- 雅猴的脚印——2019年下半年
- pandas面板(Panel)
- 【Verilog基础】数字电路-逻辑式化简公式(附吸收律推导过程)
- Class-Balanced Loss Based on Effective Number of Samples - 1 - 论文学习
- 工业循环水浅层砂过滤器(励进浅层介质过滤器)介绍及现场案例图
- 内存动态分配与释放,malloc和new区别
- Codeforces——791A Bear and Big Brother
- Johnson法则简要证明
- 用CNN实现全景图像语义分割!
- 08001-命名通道提供程序:无法打开与SQL Server的连接[53] 08001-命名管道提供程序:无法打开与SQL Server的连接[1326] 数据库连接不上提示08001
- 《学术小白的学习之路 07》自然语言处理之 LDA主题模型 01
热门文章
- 每日一题(16)—— 声明和定义的区别
- vk_down 每次下翻丙行 c++_笔记本接口不够用?不妨试试这款Type-C拓展坞,给你7个接口用...
- 最新车载导航端口检测工具_高德地图这个功能 把微信都没做好的车载社交解决了?...
- python复制sheet_python excel sheet复制
- 一张倾斜图片进行矫正 c++_专业性文章:10分钟矫正骨盆前倾
- oracle 锁表如何解决_Java高并发解决什么方式
- CoderHub接口文档
- Chapter3-2_Speech Separation(TasNet)
- LeetCode 1689. 十-二进制数的最少数目(脑筋急转弯)
- LeetCode 1244. 力扣排行榜(map+multiset)