当前位置:网站首页>异步FIFO基本原理(基于Verilog的简单实现)
异步FIFO基本原理(基于Verilog的简单实现)
2022-07-28 16:23:00 【别再出error了】
参考文献:
[1]彭莉, 秦建业, 付宇卓. 异步FIFO的设计与验证[J]. 计算机工程与应用, 2005, 41(3):4.
[2]魏芳, 刘志军, 马克杰. 基于Verilog HDL的异步FIFO设计与实现[J]. 电子技术应用, 2006, 32(7):4.

FIFO简介:一种跨时钟域传输信号的方法,读写操作由不同的时钟产生,对空或满的判断是跨时钟域的。
背景:
现代的IC芯片包含丰富的触发器,不同电路的时钟驱动源存在频率和相位的差异,因而需要对跨不同时钟域进行异步信号传输。
异步FIFO法是跨越异步时钟边界传输数据的一种常用方法!
首先需要简单复习一下亚稳态,亚稳态问题是异步数据传输的主要问题。
首先需要明确建立时间(Setup Time)和保持时间(Hold Time)的概念:我们知道,针对一个使用上升沿触发的触发器来说,在上升沿到来之前,为了获得稳定的输出,触发器的输入数据需要稳定一段时间,而需要稳定的最小时间就是建立时间;而在上升沿到来之后,需要保持一段时间,需要保持时间的最小值就是保持时间。(针对建立时间和保持时间以及亚稳态的概念,触发器具体变化过程之后有时间再整理一下)
原理如图:

如果无法保证上述条件,触发器将会工作在一个不确定的状态,就成为亚稳态。
传统异步FIFO结构与设计
异步FIFO的FIFO是“First in,first out.”的缩写,即先进先出,常使用在产生数据的接口部分用于存储、缓存数据。异步FIFO是一种不同时钟域之间传递数据的常用方法,而时钟周期和相位完全独立,在异步FIFO设计中的两个最大难题是——避免亚稳态问题和空满信号的产生。
异步FIFO结构:
双端口存储器(Dual Port RAM)、写地址(wptr)产生逻辑、读地址(rptr)产生逻辑及空满标志(wfull、rempty)产生逻辑。
读写时钟是不同的时钟域,而通常空满信号是在写地址和读地址的相互比较下得出的。

设计方案:
如图2就是一种常见的设计方案,而在实际设计中有一些方法可以尽量减少亚稳态。
(1)格雷码
对读写地址采用格雷码。同步多个异步信号出现亚稳态的概率远远大于同步一个异步信号的概率。由于格雷码每次只变化一位,采用格雷码可以有效的减少亚稳态的产生。

(2)两级同步电路
采用触发器来同步异步输入信号,如图4,将a时钟域的数据adata,用两级寄存器同步,a2bdata是属于b时钟域的。这种方法可以将出现亚稳态的概率减低很多。但需要注意输入信号的时延问题。

异步FIFO设计改进
在传统设计中,空满信号是由读写地址先两级同步后再比较产生,每一位都需要两级同步。若设计需要读写地址为4位的寄存器(wptr[3:0],rptr[3:0]),则需要4X2X2=16个寄存器。若先比较读写地址产生空满信号,后同步空满信号的方法。则需要2X2=4个寄存器,极大地减少了设计面积。
空满标志产生逻辑(关键!):
产生原则:写满不溢出,读空不多读。无论在什么时刻都不能出现读写地址同时对一个存储器地址操作。空满标志满足:
空标志:(|写地址-读地址|<=预定值)&&(写地址超前读地址)-- 写
满标志:(|写地址-读地址|<=预定值)&&(读地址超前写地址)-- 读
若采用减法会需要一个很大的组合逻辑,一般只采用相等不相等的比较逻辑,避免使用减法器,再需要一个控制信号来区分当读写地址相等时是空还是满。
首先通过比较得到两个异步空/满标志信号(aempty/afull),送入读写模块进行同步,输出rempty/wfull的空/满信号。(rempty意味着空,不能读操作;wfull,满,不写)
在参考文献【1】中,空满信号标志由首位确定;在参考文献【2】的方法中,空满标志由首位和direction(判断是方向)决定(常用,例题所用方法)。
方法【2】如图:

以16X16异步FIFO为例,写地址wptr[4:0],读地址rptr[4:0],低三位为真正读写位,最高位区分空满。若读写地址完全相等表明读地址追上了写地址,则FIFO为空;若最高位相反但其余位相同,表明写地址领先读地址一个周期,FIFO为满。(两个地址完全相等,为空;首位相反其余相等,为满)
以写地址为例:
parameter n =4;
reg[n:0] wbin,wbnext; //写地址
reg[n:0] wptr,wgnext;
always @(posedge wclk or negedge wrst_n)
if(!wrst_n)begin //异步低电平置零
wbin<=0;
wptr[n-1:0]<=0;
end
else begin
wbin<=wbnext;
wptr[n-1:0]<=wgnext[n-1:0];
end
always @(wbin[n]) //当wbin首位发生改变时,对wptr赋值一次
wptr[n]=wbin[n];
assgin wbnext = !full? wbin+winc:wbin; //写地址格雷码加法器,不为满时加
assign wgnext[n-1:0] = (wbnext[n-1:0]>>1)^wbnext[n-1:0];
将空标志aempty_n同步到读时钟域控制异步FIFO读操作,满标志afull_n同步到读时钟域异步FIFO写操作。代码如下:
wire aempty_n = ~(wptr==rptr);
//按文中的意思,读写地址完全相同时取0,此时为空,所以aempty_n应该时低电平有效,为写状态
wire afull_n = ~((wptr[n]!==rptr[n])&&(rptr[n-1]==wptr[n-1]:0))
// 首位不同且其余位相同时,full_n取0,为满,读状态。
//读操作,按文章意思应该是将空信号到同步读操作
always @(posedge rclk or negedge rrst_n or negedge aempty_n)
if(!rrst_n)
{rempty,rempty2}<=2'b11; //空,不可读,清除数据
else if(!aempty_n)
{rempty,rempty2}<=2'b11;// 空,不可读
else
{rempty,rempty2}<={rempty2,~rempty_n};
//写操作
always @(posedge rclk or negedge wrst_n or negedge afull_n)
if(!wrst_n)
{wfull,wfull2}<=2'b00; //异步置零,清除数据,wfull为0时,不满,可以写
else if(!afull_n) //afull_n有效时,为满,写地址为满,不能再继续写入
{wfull,wfull2}<=2'b11;
else
{wfull,wfull2}<={wfull2,~afull_n}; //不满时。继续写入
//这一段代码还不是太理解,主要是两个always模块不理解,之后再好好看看
改进方案分析与总结
(1)空满信号标志无毛刺:由于格雷码,使得rptr[n-1:0]==wptr[n-1:0]是一个稳定的信号。
(2)同步电路不会造成FIFO溢出:
afull_n是因为写地址追上了读地址并领先了一个周期,此时“满”,不能再写数据,否则会造成写溢出。当读地址增加时,读走了一个数据,afull_n跳变为1,无效。可见,afull_n由1到0是由wclk写时钟同步的,由0到1是读时钟rclk同步的。afull_n只影响FIFO的写入,所以同步到写时钟域。
而当afull_n变高无效时,表明FIFO非满,可以进行写操作,且与读操作同步。但写信号无法及时采到(因为 {wfull,wfull2}<={wfull2,~afull_n};,wfull取到0时才能写,会延后至少两个周期),FIFO的写要至少晚两个周期。
空信号类似,也不会出现读溢出。
//后续再找一道例题看看。
好好学习天天向上!

边栏推荐
- 线性代数及矩阵论(七)
- valarray数值库学习
- Unity shader procedural texture
- Round 1A 2022 - Code jam 2022 c.weightlifting (interval DP)
- Ugui learning notes (IV) ugui event system overview and Usage Summary
- Mysql database addition, deletion, modification and query (detailed explanation of basic operation commands)
- influxdb2的使用
- Classroom attendance system based on QT design (using RDS for MySQL cloud database)
- Microservice Architecture - service registry and service gateway (6.8) (Reprint)
- Use of influxdb2
猜你喜欢

Goweb开发之Beego框架实战:第一节 Beego框架介绍

总数据量超万亿行,玉溪卷烟厂通过正确选择时序数据库轻松应对

Mysql database addition, deletion, modification and query (detailed explanation of basic operation commands)

Analysis of browser decoding process

Goweb开发之Beego框架实战:第四节 数据库配置及连接

The practice of the beego framework for goweb development: Section V project construction and user registration

Goweb开发之Beego框架实战:第四节 数据库配置及连接

MySQL数据库增删改查(基础操作命令详解)

Jupyter notebook win installation record

微服务架构-服务注册中心和服务网关(6.8) (转载)
随机推荐
Codeforces round 770 (Div. 2) F. Fibonacci additions (construction + difference)
UNIQUE VISION Programming Contest 2022(AtCoder Beginner Contest 248)G. GCD cost on the tree
Round 1C 2022 - Code jam 2022 b.square (Mathematics, thinking)
Learn about service discovery in kubernetes
侦察机与预警机的区别
The practice of beego framework developed by goweb: Section 4 database configuration and connection
Some notes on how unity objects move
Use of influxdb2
Deep understanding of deepsea and salt deployment tools – storage6
How to protect image security during construction
Android Development - set cache
Rsync service deployment and parameter details
《Kubernetes》你需要掌握的 Service 和 Ingress
Iris framework practice of goweb development: project summary and review
Reduce cycle complexity
Unity shader depth of field effect
全链路灰度在数据库上我们是怎么做的?
The 16th program design competition of Dalian University of Technology (Problem Solver)
高速电路中电容的选型和应用——详解
Goweb开发之Beego框架实战:第四节 数据库配置及连接