异步fifo的Verilog实现
一、分析

2.将一个二进制的计数值从一个时钟域同步到另一个时钟域的时候很容易出现问题,因为采用二进制计数器时所有位都可能同时变化,在同一个时钟沿同步多个信号的变化会产生亚稳态问题。而使用格雷码只有一位变化,因此在两个时钟域间同步多个位不会产生问题。所以需要一个二进制到gray码的转换电路,将地址值转换为相应的gray码,然后将该gray码同步到另一个时钟域进行对比,作为空满状态的检测。
那么,多位二进制码如何转化为格雷码?
换一种描述方法:
verilog代码实现就一句:assign gray_code = (bin_code>>1) ^ bin_code;
使用gray码解决了一个问题,但同时也带来另一个问题,即在格雷码域如何判断空与满。
这里直接给出结论:
判断读空时:需要读时钟域的格雷码rgray_next和被同步到读时钟域的写指针rd2_wp每一位完全相同;
判断写满时:需要写时钟域的格雷码wgray_next和被同步到写时钟域的读指针wr2_rp高两位不相同,其余各位完全相同;
二、Verilog实现
module fifo
#(
parameter WSIZE = ;
parameter DSIZE = ;
)
(
input wr_clk,
input rst,
input wr_en,
input [WSIZE- : ]din,
input rd_clk,
input rd_en,
output [WSIZE- : ]dout,
output reg rempty,
output reg wfull
); //定义变量
reg [WSIZE- :] mem [DSIZE- : ];
reg [WSIZE- : ] waddr,raddr;
reg [WSIZE : ] wbin,rbin,wbin_next,rbin_next;
reg [WSIZE : ] wgray_next,rgray_next;
reg [WSIZE : ] wp,rp;
reg [WSIZE : ] wr1_rp,wr2_rp,rd1_wp,rd2_wp;
wire rempty_val,wfull_val; //输出数据
assign dout = mem[raddr]; //输入数据
always@(posedge wr_clk)
if(wr_en && !wfull)
mem[waddr] <= din; //1.产生存储实体的读地址raddr; 2.将普通二进制转化为格雷码,并赋给读指针rp
always@(posedge rd_clk or negedge rst_n)
if(!rst_n)
{rbin,rp} <= ;
else
{rbin,rp} <= {rbin_next,rgray_next}; assign raddr = rbin[WSIZE- : ];
assign rbin_next = rbin + (rd_en & ~rempty);
assign rgray_next = rbin_next ^ (rbin_next >> ); //1.产生存储实体的写地址waddr; 2.将普通二进制转化为格雷码,并赋给写指针wp
always@(posedge wr_clk or negedge rst_n)
if(!rst_n)
{wbin,wp} <= ;
else
{wbin,wp} <= {wbin_next,wgray_next}; assign waddr = wbin[WSIZE- : ];
assign wbin_next = wbin + (wr_en & ~wfull);
assign wgray_next = wbin_next ^ (wbin_next >> ); //将读指针rp同步到写时钟域
always@(posedge wr_clk or negedge rst_n)
if(!rst_n)
{wr2_rp,wr1_rp} <= ;
else
{wr2_rp,wr1_rp} <= {wr1_rp,rp}; //将写指针wp同步到读时钟域
always@(posedge rd_clk or negedge rst_n)
if(!rst_n)
{rd2_wp,rd1_wp} <= ;
else
{rd2_wp,rd1_wp} <= {rd1_wp,wp}; //产生读空信号rempty
assign rempty_val = (rd2_wp == rgray_next);
always@(posedge rd_clk or negedge rst_n)
if(rst_n)
rempty <= 'b1;
else
rempty <= rempty_val; //产生写满信号wfull
assign wfull_val = ((~(wr2_rp[WSIZE : WSIZE-]),wr2_rp[WSIZE- : ]) == wgray_next);
always@(posedge wr_clk or negedge rst_n)
if(!rst_n)
wfull <= 'b0;
else
wfull <= wfull_val; endmodule
异步fifo的Verilog实现的更多相关文章
- 异步FIFO总结+Verilog实现
异步FIFO简介 异步FIFO(First In First Out)可以很好解决多比特数据跨时钟域的数据传输与同步问题.异步FIFO的作用就像一个蓄水池,用于调节上下游水量. FIFO FIFO是一 ...
- 异步FIFO的verilog实现与简单验证(调试成功)
最近在写一个异步FIFO的时候,从网上找了许多资料,文章都写的相当不错,只是附在后面的代码都多多少少有些小错误. 于是自己写了一个调试成功的代码,放上来供大家参考. 非原创 原理参考下面: 原文 ht ...
- 异步FIFO及verilog原码
这几天看了Clifford E. Cummings的两篇大作<Simulation and Synthesis Techniques for Asynchronous FIFO Design&g ...
- 同步fifo与异步fifo
参考以下帖子: https://blog.csdn.net/hengzo/article/details/49683707 https://blog.csdn.net/Times_poem/artic ...
- 怎么用Verilog语言描述同步FIFO和异步FIFO
感谢 知乎龚大佬 打杂大佬 网上几个nice的博客(忘了是哪个了....) 前言 虽然FIFO都有IP可以使用,但理解原理还是自己写一个来得透彻. 什么是FIFO? Fist in first out ...
- Verilog设计异步FIFO
转自http://ninghechuan.com 异步FIFO有两个异步时钟,一个端口写入数据,一个端口读出数据.通常被用于数据的跨时钟域的传输. 同步FIFO的设计.一个时钟控制一个计数器,计数器增 ...
- 异步fifo的设计
本文首先对异步 FIFO 设计的重点难点进行分析 最后给出详细代码 一.FIFO简单讲解 FIFO的本质是RAM, 先进先出 重要参数:fifo深度(简单来说就是需要存多少个数据) ...
- 基于FPGA的异步FIFO设计
今天要介绍的异步FIFO,可以有不同的读写时钟,即不同的时钟域.由于异步FIFO没有外部地址端口,因此内部采用读写指针并顺序读写,即先写进FIFO的数据先读取(简称先进先出).这里的读写指针是异步的, ...
- 异步fifo的设计(FPGA)
本文首先对异步 FIFO 设计的重点难点进行分析 最后给出详细代码 一.FIFO简单讲解 FIFO的本质是RAM, 先进先出 重要参数:fifo深度(简单来说就是需要存多少个数据) ...
随机推荐
- Linux报“ '/usr/bin' is not included in the PATH environment variable”解决方法
https://www.cnblogs.com/alvinwei1024/p/4811993.html https://blog.csdn.net/drbinzhao/article/details/ ...
- file_name[:-4]
file_name: chair_0001.off file_name[:-4] : chair_0001
- [CNN] Tool - Deep Visualization
From: http://www.infoq.com/cn/news/2016/12/depth-neural-network-fake-photos 当时大部分的DNN在识别图像中对象的过程中主要依 ...
- mysql按月查询
SELECT DATE_FORMAT(GenerateTime, '%m') as month, SUM(GenerateCount) AS count FROM identitycodetask ' ...
- JAVA WEB -- request
request request.getContextPath() 返回站点的根目录 request.getRealpath("/")得到的是实际的物理路径,也就是你的项目所在服务 ...
- 深入探讨WPF的ListView控件
接上一篇博客初步探讨WPF的ListView控件(涉及模板.查找子控件) 我们继续探讨ListView的用法 一.实现排序功能 需求是这样的:假如我们把学生的分数放入ListView,当我 ...
- 通信原理之TCP/IP基本概念 (二)
本来想写写,但发现有人写的很好了,不造轮子了! 直接转了 一.为什么会有TCP/IP协议 在世界上各地,各种各样的电脑运行着各自不同的操作系统为大家服务,这些电脑在表达同一种信息的时候所使用的方法是 ...
- iOS - 切换rootViewController时,销毁之前的控制器
一.iOS在切换根控制器时,如何销毁之前的控制器?(切换rootViewController时注意的内存泄漏) 首先.在iOS的ARC机制下,任何对象,当没有其他对象对他进行强引用时,都会被自动释放. ...
- 一款Redis客户端,可以作为Redis Desktop manager的有效补充或替代
一.由来 对于redis客户端,我和大多数人一样,都是用Redis Desktop Manager. 但我发现个问题,我的版本是0.9.1.771. 我这个版本有个问题,就是如果value太长的话,不 ...
- 排查java进程cpu占用高的问题
一.思路 分两步,主要是找出占用cpu高的进程,再找出该进程内到底是哪个线程占用cpu高. 二.找出占用cpu高的进程 参考: https://blog.csdn.net/hfhwfw/article ...