异步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深度(简单来说就是需要存多少个数据) ...
随机推荐
- 【转】搭建Java版WebService
原文地址:http://www.cnblogs.com/jasoncc/archive/2011/12/22/2296052.html Hi,大家好! 今天主要和大家分享,如何搭建一个Web服务,做A ...
- 面向对象方法的重载(overloading)和覆盖(overriding)。
在有些JAVA书籍中将overriding称为重载,overloading称为过载. Overloading在一个类中可以定义多个同名方法,各个方法的参数表一定不同.但修饰词可能相同,返回值也可能 ...
- 三、主流区块链技术特点及Hyperledger Fabric V1.0版本特点
一.Hyperledger fabric V1.0 架构 1.逻辑架构: 2.区块链网络 3.运行时架构 二.架构总结 1.架构要点 分拆Peer的功能,将Blockchain的数据维护和共识服务进行 ...
- vmware-hostd.exe 占用443端口导致Apache无法正常启动?
问题: [Apache] Problem detected!16:23:19 [Apache] Port 443 in use by ""D:\vmware\VMware W ...
- 缓存技术PK:选择Memcached还是Redis?
缓存技术PK:选择Memcached还是Redis? memcached完全剖析----------------->高质量文章 memcached的最佳实践方案 数据缓存系统-memcached ...
- 修改torndb库为依赖pymysql,使其适应python3,一个更简单的操作数据库的类。
1.python的MySQLdb和pymysql是两个基本数据库操作包,MySQLdb安装很麻烦,要有c++相关环境,python3也安装不了. python3一般安装pymysql,此包与MySQL ...
- IntelliJ IDEA 激活 及 License Server 安装使用 Window篇
IDEA版本: IntelliJ IDEA 2017.2Build #IU-172.3317.76, built on July 15, 2017Licensed to Administrator J ...
- BackgroundWorker学习笔记
1 简介 BackgroundWorker 类允许您在单独的专用线程上运行操作. 耗时的操作(如下载和数据库事务)在长时间运行时可能会导致用户界面 (UI) 似乎处于停止响应状态. 如果您需要能进行响 ...
- Nginx-设定允许的ip和要拒绝的ip
作用范围和配置的顺序有关系,先配置的优先级高,会覆盖和后一个配置重合的部分, 可以添加多个allow和多个deny: 1)这个配置127.0.0.1可以通过访问. allow 127.0.0.1; d ...
- 为C函数自动添加跟踪语句
目录 为C函数自动添加跟踪语句 声明 一. 问题提出 二. 代码实现 2.1 函数匹配测试 2.2 插入跟踪语句 三. 效果验证 为C函数自动添加跟踪语句 标签: Python 正则表达式 声明 本文 ...