module fifo1 #(parameter DSIZE = ,
parameter ASIZE = ) //用格雷码的局限性:循环计数深度必须是2的n次幂,否则就失去了每次只变化一位的特性
(wclk,wrstn,wdata,wfull,winc,rclk,rrstn,rdata,rempty,rinc);
input wclk,wrstn,winc;
input [DSIZE - :] wdata;
output wfull; input rclk,rrstn,rinc;
output [DSIZE - :] rdata;
output rempty; reg wfull,rempty; //空满输出
reg [ASIZE:] rbin,wbin; //读写二进制地址
reg [ASIZE:] wptr,rq1_wptr,rq2_wptr, //读写指针打两拍CDC同步
rptr,wq1_rptr,wq2_rptr;
wire [ASIZE:] rbinnext,wbinnext, //读写指针递增
rgraynext,wgraynext; //读写指针递增对应的格雷码
wire [ASIZE - :] waddr,raddr; //实际读写mem的地址 reg [DSIZE - :] mem [:(<<ASIZE) - ]; //左移一位表示乘2 //---------------------双口RAM存储器 数据读写-----------------------------
assign rdata = mem[raddr]; //读
always@(posedge wclk) begin //写
if(winc && !wfull) begin
mem[waddr] <= wdata;
end
end //---------------------将读指针CDC到写时钟域------------------------------
always@(posedge wclk or negedge wrstn) begin
if(!wrstn) begin
wq2_rptr <= 'd0;
wq1_rptr <= 'd0;
end
else begin
wq1_rptr <= rptr;
wq2_rptr <= wq1_rptr;
end
end //---------------------将写指针CDC到读时钟--------------------------------
always@(posedge rclk or negedge rrstn) begin
if(!rrstn) begin
rq2_wptr <= 'd0;
rq1_wptr <= 'd0;
end
else begin
rq1_wptr <= wptr;
rq2_wptr <= rq1_wptr;
end
end //读相关指针的产生
always@(posedge rclk or negedge rrstn) begin
if(!rrstn) begin
rptr <= 'd0;
rbin <= 'd0;
end
else begin
rptr <= rgraynext;
rbin <= rbinnext;
end
end
//写相关的指针
always@(posedge wclk or negedge wrstn) begin
if(!wrstn) begin
wbin <= 'd0;
wptr <= 'd0;
end
else begin
wbin <= wbinnext;
wptr <= wgraynext;
end
end //addr截取与格雷码化指针
assign raddr = rbin[ASIZE - :]; //mem的读地址
assign rbinnext = rbin + (rinc & ~rempty); //mem的下一个读地址
assign rgraynext = (rbinnext>>) ^ rbinnext; //mem的读地址对应的格雷码 assign waddr = wbin[ASIZE - :];
assign wbinnext = wbin + (winc & !wfull);
assign wgraynext = (wbinnext>>) ^ wbinnext; //---------------------rempty产生------------------------------
//FIFO empty when the next rptr == synchronized wptr or on the reset
always@(posedge rclk or negedge rrstn) begin
if(!rclk) begin
rempty <= 'b1;
else begin
rempty <= (rgraynext == rq2_wptr);
end
end //---------------------wfull产生------------------------------
//FIFO full when CDC过来的格雷码(采样值)的最高位+次高位和bin转换过来的格雷码(理论值)均不同,剩下低位都相同
always@(posedge wclk or negedge wrstn) begin
if(!wrstn) begin
wfull <= ;
end
else begin
wfull <= (wgraynext == {~wq2_rptr[ASIZE,ASIZE-],wq2_rptr[ASIZE-:]});
end
end endmodule
/*Clifford E. Cummings的文章中提到的STYLE #1,构造一个指针宽度为N+1,深度为2^N字节的FIFO(为便方比较将格雷码指
针转换为二进制指针)。当指针的二进制码中最高位不一致而其它N位都 相等时,FIFO为满(在Clifford E. Cummings的文章中以
格雷码表示是前两位均不相同,而后两位LSB相同为满,这与换成二进制表示的MSB不同其他相同为满是一样的)。当指针完全相等时,
FIFO为空。
这种方法思路非常明了,为了比较不同时钟产生的指针,需要把不同时钟域的信号同步到本时钟域中来,而使用Gray码的目的就是使这个
异步同步化的过程发生亚稳态的机率最小。
*/

很好的讲解:

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

学习笔记二:异步FIFO的更多相关文章

  1. AJax 学习笔记二(onreadystatechange的作用)

    AJax 学习笔记二(onreadystatechange的作用) 当发送一个请求后,客户端无法确定什么时候会完成这个请求,所以需要用事件机制来捕获请求的状态XMLHttpRequest对象提供了on ...

  2. JMX学习笔记(二)-Notification

    Notification通知,也可理解为消息,有通知,必然有发送通知的广播,JMX这里采用了一种订阅的方式,类似于观察者模式,注册一个观察者到广播里,当有通知时,广播通过调用观察者,逐一通知. 这里写 ...

  3. 微信小程序学习笔记二 数据绑定 + 事件绑定

    微信小程序学习笔记二 1. 小程序特点概述 没有DOM 组件化开发: 具备特定功能效果的代码集合 体积小, 单个压缩包体积不能大于2M, 否则无法上线 小程序的四个重要的文件 *js *.wxml - ...

  4. WPF的Binding学习笔记(二)

    原文: http://www.cnblogs.com/pasoraku/archive/2012/10/25/2738428.htmlWPF的Binding学习笔记(二) 上次学了点点Binding的 ...

  5. [Firefly引擎][学习笔记二][已完结]卡牌游戏开发模型的设计

    源地址:http://bbs.9miao.com/thread-44603-1-1.html 在此补充一下Socket的验证机制:socket登陆验证.会采用session会话超时的机制做心跳接口验证 ...

  6. java之jvm学习笔记二(类装载器的体系结构)

    java的class只在需要的时候才内转载入内存,并由java虚拟机的执行引擎来执行,而执行引擎从总的来说主要的执行方式分为四种, 第一种,一次性解释代码,也就是当字节码转载到内存后,每次需要都会重新 ...

  7. Java IO学习笔记二

    Java IO学习笔记二 流的概念 在程序中所有的数据都是以流的方式进行传输或保存的,程序需要数据的时候要使用输入流读取数据,而当程序需要将一些数据保存起来的时候,就要使用输出流完成. 程序中的输入输 ...

  8. 《SQL必知必会》学习笔记二)

    <SQL必知必会>学习笔记(二) 咱们接着上一篇的内容继续.这一篇主要回顾子查询,联合查询,复制表这三类内容. 上一部分基本上都是简单的Select查询,即从单个数据库表中检索数据的单条语 ...

  9. NumPy学习笔记 二

    NumPy学习笔记 二 <NumPy学习笔记>系列将记录学习NumPy过程中的动手笔记,前期的参考书是<Python数据分析基础教程 NumPy学习指南>第二版.<数学分 ...

  10. Learning ROS for Robotics Programming Second Edition学习笔记(二) indigo tools

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...

随机推荐

  1. iOS 技能分类:

    1.语言与系统: 2.架构与机制: 3.性能:cpu.gpu.io.缓存.内存:性能监测工具: 4.知名开源库:

  2. 【node.js】Buffer(缓冲区)

    Node.js中,定义了一个 Buffer 类,该类用来创建一个专门存放二进制数据的缓存区. 创建 Buffer 类 Node Buffer 类可以通过多种方式来创建. 1.创建长度为 10 字节的 ...

  3. Presentation 常用的承接句——技术分享、学术报告串联全场不尴尬

    前言 现在即使是搞技术,做科研的,也需要在不同的场合,用ppt来做分享,做汇报,做总结. 如果国际会议,研讨会,或者在外企,国外工作,英文的presentation就更加必不可少.英语的提升需要大家从 ...

  4. [Python 网络编程] TCP、简单socket模拟ssh (一)

    OSI七层模型(Open System Interconnection,开放式系统互联) 应用层 网络进程访问应用层: 为应用程序进程(例如:电子邮件.文件传输和终端仿真)提供网络服务: 提供用户身份 ...

  5. C# - 静态类和静态构造函数

    一个类只能有一个静态构造函数,该构造函数不能有访问修饰符,不能带任何参数,不能直接调用,只能在: 1 创建包含静态构造函数的类实例时 2 访问包含静态构造函数的静态成员时 会先调用静态构造函数,无论创 ...

  6. linux使用秘钥登录(禁用root密码登录)

    目的:为了巩固线上外网服务器的安全,避免黑客攻击植入木马,初步决定禁用root密码登录(安全强度低),统一使用秘钥登录(4096位长度,安全性较高) 具体操作如下: 一.生成ssh秘钥: ssh-ke ...

  7. 【zigbee】【蓝牙】射频信号放大器兼容AT2401C

    现在科技产品的不断进步,智能家居方面慢慢对信号和距离方面的要求渐渐增加.深圳市动能世纪科技有限公司不断的满足客户需求,推出了一款射频信号放大器AT2401C满足客户距离信号等等的需求.并全方位技术支持 ...

  8. Linux 启动进程结束进程通用代码

    linux启动springboot项目 start.sh #!/bin/sh rm -f tpid nohup java -jar restDate--SNAPSHOT.jar --spring.pr ...

  9. cocos2d-x开发:服务端基础库封装

    元旦前面几天都在忙着面试,随后的几天也就一直在做服务端基础库开发方面的工作.对于服务端开发,是很久之前的事情了.那时候我还在大学读书,一直都是在倒腾服务端开发方面的东西,毕业后参加公司工作就是一直从事 ...

  10. LeetCode35.搜索插入位置 JavaScript

    给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引.如果目标值不存在于数组中,返回它将会被按顺序插入的位置. 你可以假设数组中无重复元素. 示例 1: 输入: [1,3,5,6], 5 输 ...