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. 乘风破浪:LeetCode真题_018_4Sum

    乘风破浪:LeetCode真题_018_4Sum 一.前言 前面我们已经练习过了三个数相加的集合运算,现在变成了四个数,其实道理是一样的.三个数的时候可以转成两个数的加法,最后来解决,而四个数的可以转 ...

  2. 沉淀,再出发:Django的简单使用

    沉淀,再出发:Django的简单使用 一.前言     在学习了python的基础语法之后,其实大家都很怀疑python的使用场景,其实python在很多场合都有很强的适应性,就比如说web开发之中使 ...

  3. December 07th 2016 Week 50th Wednesday

    Life is a flower, and love is the honey of the flower. 人生是花儿,而爱情就是花的蜜. My life is not as beautiful a ...

  4. December 06th 2016 Week 50th Tuesday

    Behind every beautiful thing, there is some kind of pain. 美丽背后,必有努力. No pains, no gains. But it seem ...

  5. codeforces 812E Sagheer and Apple Tree(思维、nim博弈)

    codeforces 812E Sagheer and Apple Tree 题意 一棵带点权有根树,保证所有叶子节点到根的距离同奇偶. 每次可以选择一个点,把它的点权删除x,它的某个儿子的点权增加x ...

  6. 缓存MEMCACHE php调用

    在项目中,涉及大访问量时,合理的使用缓存能减轻数据库的压力,同时提升用户体验.即在非实时性的需求的前提下,一小段时间内(若干秒),用于显示的数据从缓存中获取的,而不用直接读取数据库,能有效的减少数据库 ...

  7. Android Volley源码分析及扩展

    转载请标明出处: http://www.cnblogs.com/why168888/p/6681232.html 本文出自:[Edwin博客园] Volley 介绍 Android系统中主要提供了两种 ...

  8. ERROR: Repository not found. ////Git, but is not registered in the Settings.

    1.ERROR: Repository not found. 这个问题是因为在你推送的github账户中,并没有这个Repository. 解决方法: 1)检查自己的github中的Repositor ...

  9. 使用loader打包静态文件-样式2

    这篇我们了解下css-loader常用的配置项,要配置的话,use里面就不再是一个字符串了 // 打包模块不知道该怎么办,就去模块配置里面该怎么办 module: { // 规则 rules: [{ ...

  10. browserify文件后函数调用报is not defined的原因

    举个例子: a.js ; module.exports.a = a; b.js var result = require('./a'); var getA =() => { console.lo ...