异步FIFO

news/2025/11/5 17:46:32/文章来源:https://www.cnblogs.com/Holybanban/p/19194312

目录
  • 一、原理介绍
    • 1.1 ram读写
  • 二、异步FIFO代码
    • 2.1 代码
    • 2.2 仿真代码
  • 声明

一、原理介绍

这里我就不多写原理了(Doreen大佬写的很好),主要记录一下自己学习异步FIFO过程中的理解。

1.1 ram读写

看“声明”中的帖子时,发现同步FIFO和异步FIFO在读写ram时有一个明显的区别。即同步FIFO读写ram需要外部输入的读写信号以及空满信号联合判断能否读写,而异步FIFO是通过外部输入的读写信号以及空满信号联合对读写指针的自增进行限制,从而达到控制是否读写的目的。

由于空满标志的判断需要将读写指针同步到对方的时钟域下,要打两拍,所以说空满标志的判断是不及时的。例如FIFO深度1024,写入1024个数据后,开始读出数据。当读出一个数据后,就应该可以继续写入了,但由于读地址有两拍的滞后性,此时出现“假满”,还不能写数据,不过这种情况不是不可接受的,只是FIFO的效率降低一点罢了。“假空”也是类似的。

二、异步FIFO代码

2.1 代码

`timescale 1ns/1ps
module AsyncFIFO #(parameter DATA_WIDTH = 8,parameter FIFO_DEPTH = 16
)(input  wire                     wr_clk_i    ,input  wire                     rd_clk_i    ,input  wire                     wr_rstn_i   ,input  wire                     rd_rstn_i   ,input  wire                     rd_en_i     ,input  wire                     wr_en_i     ,input  wire [DATA_WIDTH-1:0]    wr_data_i   ,output wire [DATA_WIDTH-1:0]    rd_data_o   ,output wire                     fifo_full_o ,output wire                     fifo_empty_o
);
localparam DEPTH = $clog2(FIFO_DEPTH);reg  [DEPTH:0] wr_ptr_d1;
reg  [DEPTH:0] rd_ptr_d1;
reg  [DEPTH:0] wr_ptr_gray_sync1;
reg  [DEPTH:0] wr_ptr_gray_sync2;
reg  [DEPTH:0] rd_ptr_gray_sync1;
reg  [DEPTH:0] rd_ptr_gray_sync2;
reg            fifo_empty_d1;wire [DEPTH:0] wr_ptr_gray = (wr_ptr_d1 >> 1) ^ wr_ptr_d1;
wire [DEPTH:0] rd_ptr_gray = (rd_ptr_d1 >> 1) ^ rd_ptr_d1;
wire           fifo_empty  = (rd_ptr_gray == wr_ptr_gray_sync2) ? 1'b1 : 1'b0; 
wire           wr_able     =  wr_en_i && !fifo_full_o;
wire           rd_able     =  rd_en_i && !fifo_empty;
wire [DEPTH:0] wr_ptr      = (wr_able) ? wr_ptr_d1 + 1'b1 : wr_ptr_d1;
wire [DEPTH:0] rd_ptr      = (rd_able) ? rd_ptr_d1 + 1'b1 : rd_ptr_d1;reg  [DATA_WIDTH-1:0] ram [0:FIFO_DEPTH-1];
reg  [DATA_WIDTH-1:0] rd_data;wire [DEPTH-1:0] wr_addr = wr_ptr_d1[DEPTH-1:0]; 
wire [DEPTH-1:0] rd_addr = rd_ptr_d1[DEPTH-1:0]; always @(posedge wr_clk_i)                      if(wr_able)    ram[wr_addr]      <= wr_data_i;
always @(posedge rd_clk_i or negedge rd_rstn_i) if(!rd_rstn_i) rd_data           <= 'd0; else if(rd_able) rd_data <= ram[rd_addr];always @(posedge wr_clk_i or negedge wr_rstn_i) if(!wr_rstn_i) wr_ptr_d1         <= 'd0; else wr_ptr_d1           <= wr_ptr;
always @(posedge rd_clk_i or negedge rd_rstn_i) if(!rd_rstn_i) rd_ptr_d1         <= 'd0; else rd_ptr_d1           <= rd_ptr;
always @(posedge wr_clk_i or negedge wr_rstn_i) if(!wr_rstn_i) rd_ptr_gray_sync1 <= 'd0; else rd_ptr_gray_sync1   <= rd_ptr_gray;
always @(posedge rd_clk_i or negedge rd_rstn_i) if(!rd_rstn_i) wr_ptr_gray_sync1 <= 'd0; else wr_ptr_gray_sync1   <= wr_ptr_gray;
always @(posedge rd_clk_i or negedge rd_rstn_i) if(!rd_rstn_i) fifo_empty_d1     <= 'd0; else fifo_empty_d1       <= fifo_empty;always @(posedge wr_clk_i or negedge wr_rstn_i) if(!wr_rstn_i) rd_ptr_gray_sync2 <= 'd0; else rd_ptr_gray_sync2   <= rd_ptr_gray_sync1;
always @(posedge rd_clk_i or negedge rd_rstn_i) if(!rd_rstn_i) wr_ptr_gray_sync2 <= 'd0; else wr_ptr_gray_sync2   <= wr_ptr_gray_sync1;assign rd_data_o    = rd_data;
assign fifo_full_o  = (wr_ptr_gray == {~rd_ptr_gray_sync2[DEPTH:DEPTH-1], rd_ptr_gray_sync2[DEPTH-2:0]}) ? 1'b1 : 1'b0;
assign fifo_empty_o = fifo_empty_d1;endmodule

设计的整体思路都是模仿Doreen的方法。

最初写代码的时候,fifo_empty_o没有像上面的代码一样延一个时钟周期,仿真时一直拉高rd_en_i时能正常读出ram的最后一个值,但是在读出最后一个值的同时fifo_empty_o就拉高了,我是认为这里有点奇怪,但是觉得既然能正常读出,应该没有多大的问题。

但是后来我想到,如果fifo输出了fifo_empty_o给读取电路,读取电路就应该立即拉低rd_en_i,而不是像上面说的恒拉高rd_en_i,此时就会出现漏读,像这样,

image

左边的蓝色框正常写入8个数据,wr_en_i有1ps的延时,所以最左侧的上升沿没有跟写时钟上升沿对齐。红框中是读出数据,rd_en_i同样有1ps的延时,只读出了前7个数据,所以fifo_empty_o应该要延一个时钟周期

延一个时钟周期的图如下,

image

可见红框中正常读出了8个数,只是数字8没有截出来。

然后考虑到万一读电路保持rd_en_i恒为高,能不能正常工作,

image

这里rd_en_i就是恒拉高,在读出8的下一个时钟上升沿,fifo_empty_o才拉高,我认为这样才是正确的,而且rd_en_i恒拉高没有产生任何影响。

下面是从还没有写入数据就开始读,

image

在还没有写入数据的时候是读不出数据的,并且由于指针同步造成的假空,导致fifo_empty_o频繁翻转,但是读数据是正常读出了8个数。

上面是慢到快,经过验证,快到慢、非整数倍时钟都一样能正常工作。

针对fifo_empty_o是否需要延迟这一个时钟周期,或者本来就应该是这样(我最初的写法有问题),欢迎指正。

2.2 仿真代码

`timescale 1ns/1ps
module AsyncFIFO_tb();
localparam              DATA_WIDTH = 8;
localparam              FIFO_DEPTH = 8;
reg                     wr_clk_i;
reg                     rd_clk_i;
reg                     wr_rstn_i;
reg                     rd_rstn_i;
reg                     rd_en_i;
reg                     wr_en_i;
reg  [DATA_WIDTH-1:0]   wr_data_i;
wire [DATA_WIDTH-1:0]   rd_data_o;
wire                    fifo_full_o;
wire                    fifo_empty_o;AsyncFIFO #(.DATA_WIDTH(DATA_WIDTH),.FIFO_DEPTH(FIFO_DEPTH)
)myFIFO(.wr_clk_i       (wr_clk_i),.rd_clk_i       (rd_clk_i),.wr_rstn_i      (wr_rstn_i),.rd_rstn_i      (rd_rstn_i),.rd_en_i        (rd_en_i),.wr_en_i        (wr_en_i),.wr_data_i      (wr_data_i),.rd_data_o      (rd_data_o),.fifo_full_o    (fifo_full_o),.fifo_empty_o   (fifo_empty_o)
);
initial begin$fsdbDumpfile("test.fsdb");$fsdbDumpvars(0, AsyncFIFO_tb);
endalways #20 wr_clk_i = ~wr_clk_i;
always #10 rd_clk_i = ~rd_clk_i;initial beginwr_clk_i = 0;rd_clk_i = 0;wr_rstn_i = 1;rd_rstn_i = 1;wr_en_i = 0;rd_en_i = 0;wr_data_i = 0;#10;wr_rstn_i = 0;rd_rstn_i = 0;#10;wr_rstn_i = 1;rd_rstn_i = 1;repeat(10) @(posedge wr_clk_i);@(posedge rd_clk_i) #1 rd_en_i = 1;repeat(10) @(posedge wr_clk_i);@(posedge wr_clk_i) #1 wr_en_i = 1; wr_data_i = 1;@(posedge wr_clk_i) #1 wr_data_i = 2;@(posedge wr_clk_i) #1 wr_data_i = 3;@(posedge wr_clk_i) #1 wr_data_i = 4;@(posedge wr_clk_i) #1 wr_data_i = 5;@(posedge wr_clk_i) #1 wr_data_i = 6;@(posedge wr_clk_i) #1 wr_data_i = 7;@(posedge wr_clk_i) #1 wr_data_i = 8;@(posedge wr_clk_i) #1 wr_en_i = 0;//@(posedge rd_clk_i) #1 rd_en_i = 1;//repeat(9) @(posedge rd_clk_i);//rd_en_i = 0;//repeat(10) @(posedge rd_clk_i);repeat(100) @(posedge wr_clk_i);$finish;
endendmodule

声明

本文的第一节和第二节参考自<掰开揉碎讲 FIFO(同步FIFO和异步FIFO) - Doreen的FPGA自留地 - 博客园>
https://www.cnblogs.com/DoreenLiu/p/17348480.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/957022.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025 洗车设备厂家最新推荐排行榜:全自动 / 自助设备企业实力测评与权威选购指南

引言 当前洗车行业 “洗车难、洗车贵” 问题突出,传统设备耗能耗水高、清洁效果参差不齐,市场品牌繁杂导致采购方选型困难。为此,行业协会联合专业测评机构发布最新推荐榜单,测评依据《洗车设备行业服务能力白皮书…

视频编码标准发展史

视频编码标准发展史 重回 AI 战场!H.266/VVC 的时代才刚刚开始

2025 年安全触边厂家最新推荐榜:聚焦品质服务商,结合权威测评与市场口碑的全面选购指南防爆灵敏安全触边/无人车安全触边公司推荐

引言 安全触边作为工业生产中保障人员与设备安全的关键防护设备,其品质与性能直接影响生产作业的安全性与稳定性。当前市场上安全触边品牌数量众多,产品质量差异显著,给企业选购带来极大困扰。为帮助企业精准筛选优…

096_尚硅谷_多重循环应用案例

096_尚硅谷_多重循环应用案例1.多重循环控制 2.统计3个班成绩情况,每个班有5名同学,求出各个班的平均分和所有班级的平均分 3.统计3个班成绩情况,每个班有5名同学,求出各个班的平均分和所有班级的平均分_分析实现思…

2025 年减震气囊厂家最新推荐榜权威发布:39 项专利企业领衔,驾驶室 / 卡车底盘 / 空气弹簧气囊甄选指南

引言 随着汽车工业与工业设备领域快速发展,减震气囊作为保障运行平稳、提升驾乘舒适度的核心部件,市场需求持续攀升。但市场产品质量参差不齐、新兴领域适配性不足等问题突出,采购方亟需权威参考依据。为此,行业协…

2025 年 11 月列管冷凝器,列管式冷凝器,不锈钢冷凝器厂家最新推荐,聚焦资质、案例、售后的五家企业深度解读!

引言 在工业生产领域,列管冷凝器、列管式冷凝器及不锈钢冷凝器作为关键换热设备,其性能优劣直接影响企业生产效率与安全。为给企业采购提供权威参考,行业协会近期开展专项测评,通过对近百家厂家的资质认证、产品性…

2025 年安全地毯源头厂家最新推荐排行榜:聚焦 IP65 防护与 30ms 快速响应,权威测评实力企业全解析防滑安全地毯/机械防护安全地毯/橡胶安全地毯公司推荐

引言 在工业生产领域,安全防护是企业运营的核心议题,安全地毯作为关键区域防护设备,其性能与响应速度直接影响作业安全。为筛选优质产品,行业协会联合专业测评机构开展专项测评,覆盖防护等级、响应速度、环境适应…

2025年矿用本安型低速图像处理摄像仪厂家权威推荐榜单:矿用本安型显示屏/本安型海思3403主板/本安型海思3519D主板源头厂家精选

在矿山智能化与安全生产要求不断提升的背景下,矿用本安型低速图像处理摄像仪作为井下安全监测的核心设备,其防爆性能、图像处理能力及环境适应性直接关系到矿山安全生产水平。根据矿山智能化建设数据,我国已有超100…

【转载】(修改版本)浮点数的表现形式

【转载】(修改版本)浮点数的表现形式引自: https://blog.csdn.net/lxl1307/article/details/142518676(2)浮点数存的过程 IEEE754规定: 对于32位的浮点数,最高的1位存储符号位S,接着的8位存储指数E,剩下的23位…

2025 年 11 月高性价比学习机推荐:松鼠 AI S20 深度测评与选购指南

孩子网课需求常态化、家长辅导精力有限、不同学科知识点衔接难 —— 这些现实痛点,让 “能精准诊断、能个性化推练、能实时答疑” 的智能学习机,成为现代家庭的教育刚需。2025 年 “双减” 政策与数字化教育融合持续…

2025 年 11 月搅拌反应釜,树脂反应釜,高速反应釜,远红外反应釜厂家最新推荐,聚焦资质、案例、售后的五家机构深度解读!

引言 在化工、医药、新能源等领域的生产流程中,搅拌反应釜、树脂反应釜、高速反应釜、远红外反应釜作为关键设备,其性能与质量直接关系到生产效率与产品品质。为帮助企业精准筛选优质设备供应商,行业协会联合专业测…

什么是未来的好产业

什么是未来的好产业往后看5年,10年,什么是未来的好行业,好产业? 都说股票不要天天盯盘,最好不看,选择一个好行业,有成长的qy,跟随qy一起发展。 但是看上市公司的gp,5年,10年在原地的也不少,如何预测5年,10…

国家育儿补贴怎么领?领多少?AiPy 计算器帮你一键查询(附计算器生成教程)

最近,国家育儿补贴政策正式公布,这无疑给众多育儿家庭带来了实实在在的福利。然而,政策公布后,不少家长却陷入了新的困惑:补贴到底能领多少?具体的领取条件是什么?这些问题成了大家关注的焦点。 中国育儿补贴背…

安川机器人管材焊接智能节气仪

在工业焊接领域,气体消耗成本是生产运营的重要组成部分。安川机器人管材焊接智能节气仪(WGFACS)的出现,为企业实现节能降耗提供了有效途径,显著提升了安川焊接机器人节气的效率与精准度。 工作原理 WGFACS节气装…

Day12背景属性---拆封写法与复合写法

1.背景图<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0&q…

2025年增加等效弯曲韧性指数纤维定制厂家权威推荐榜单:增韧纤维/高分子聚乙烯纤维/高延性混凝土纤维源头厂家精选

在建筑材料与复合材料领域,增韧纤维作为提升混凝土等效弯曲韧性指数的关键材料,其性能直接影响工程结构的抗裂性能与耐久性。根据行业统计,2025年国内工程纤维市场规模预计突破80亿元,其中增韧纤维年增长率达15%,…

【LVGL】内存分配管理(与 sct 文件配合管理)

引言 LVGL 内存管理,可选默认 lvgl 管理方式,也可选自定义管理方式。 LVGL 内存消耗 这里说的内存管理,就是指“LVGL 要管理的内存”。 这个内存池不能分配的过大,过大则图形缓冲区或其他被分配的位置就可能不足;…

焊接效率翻倍!焊台工具的性价比黑马!正点原子T300智能焊台160W 大功率 + 四芯兼容!

焊接效率翻倍!焊台工具的性价比黑马!正点原子T300智能焊台160W 大功率 + 四芯兼容! 电子工程师的工作台前,永远缺一台「趁手」的焊台:功率不足焊不动大焊点,换芯麻烦适配性差,温控不准烧穿 PCB 板 — 这些痛点,…

实现 json path 来评估函数式解析器的损耗

目的 之前就考虑评估过 函数式解析器 在dotnet这些面向对象语言上有着一些损耗,虽然表意性很强,与ABNF范式结合使用,维护性大大提升 不过由于性能考虑(以及之前认为也或许没有太多机会实现解析器),就没打算继续深…

2025年无线充电方案厂家新排行榜,稳定无线充电方案公司推荐

2025年智慧科技产业高速迭代,无线充电方案及机器人无线充电方案、稳定无线充电方案等细分领域技术,已成为智能家居、智慧出行、智慧物流、智能制造等场景的核心基础设施,其传输效率、安全稳定性、场景适配性直接决定…