同步FIFO的verilog实现(2)——高位扩展法

一、前言

        在之前的文章中,我们介绍了同步FIFO的verilog的一种实现方法:计数法。其核心在于:在同步FIFO中,我们可以很容易的使用计数来判断FIFO中还剩下多少可读的数据,从而可以判断空、满。

        关于计数法实现同步FIFO的详细内容,请参考:同步FIFO的verilog实现(1)——计数法

二、高位扩展法原理

        我们知道对于FIFO的设计来说,其核心在于设计读写指针,并且生成可靠的空、满信号。

        当读/写地址指针在复位操作期间被置为零时,或者当读指针在从FIFO中读取了最后一个字之后追上了写指针,此时读指针和写指针相等代表着FIFO为空状态。而当写指针再次追上读指针时,此时读指针和写指针相等代表着FIFO为写满。也就是说当读写指针相等时,FIFO要么为空,要么为满。
   因此我们可以将地址位扩展一位,用最高位来判断空满,其余低位还是正常用于读写地址索引。当写指针递增超过FIFO的最大地址时,写指针的MSB位将置为1,同时将其余低位设置回零。读指针也是如此。如果读指针和写指针的MSB不同,则意味着写指针比读指针多绕了一次,表示FIFO写满。如果两个指针的MSB相同,则表示两个指针的回绕次数相同,表示FIFO读空。如下图所示:

        当最高位不同,且其他位相同,则表示读指针或者写指针多跑了一圈,这显然不可能发生,情况只能是写指针多跑了一圈,与就意味着FIFO被写满了。
        当最高位相同,且其他位相同,则表示读指针追到了写指针或者写指针追到了读指针,而显然不会让写指针追读指针(这种情况只能是写指针超过读指针一圈),所以可能出现的情况只能是读指针追到了写指针,也就意味着FIFO被读空了。

三、同步FIFO的verilog实现

        理解了原理,我们就能很快设计出相应的verilog代码:

//------------------------<高位扩展法设计同步FIFO>----------------------------
module sync_fifo1#(  
//-----------------------------<参数定义>---------------------------------parameter FIFO_WIDTH = 16,                          //FIFO宽度parameter FIFO_DEPTH = 16                           //FIFO深度
)(
//-----------------------------<接口定义>---------------------------------input clk,                                          //时钟信号input rst,                                          //复位信号input [FIFO_WIDTH-1:0] din,                         //FIFO输入数据(写数据)input rd_en,                                        //读使能信号 input wr_en,                                        //写使能信号output reg [FIFO_WIDTH-1:0] dout,                   //FIFO输出数据(读数据) output empty,                                       //FIFO空标志 output full                                         //FIFO满标志 
); //-----------------------------<reg定义>---------------------------------reg [FIFO_WIDTH-1:0] fifo_buffer[FIFO_DEPTH-1:0];	//用二维数组实现RAM	reg [$clog2(FIFO_DEPTH):0] wr_addr;			     	//写地址(写指针),位宽要多出一位reg [$clog2(FIFO_DEPTH):0] rd_addr;			    	//读地址(读指针),位宽要多出一位//-----------------------------<wire定义>---------------------------------     wire [$clog2(FIFO_DEPTH) - 1 : 0]	wr_addr_true;	//真实写地址指针wire [$clog2(FIFO_DEPTH) - 1 : 0]	rd_addr_true;   //真实读地址指针wire								wr_addr_msb;	//写地址指针地址最高位wire								rd_addr_msb;	//读地址指针地址最高位assign {wr_addr_msb,wr_addr_true} = wr_addr;		//将最高位与其他位拼接assign {rd_addr_msb,rd_addr_true} = rd_addr;		//将最高位与其他位拼接       //-----------------------------<读操作>-----------------------------------
always@(posedge clk or posedge rst)begin if(rst)rd_addr <= 0;else if(rd_en && !empty)begin                       //读使能有效且FIFO非空rd_addr	<=	rd_addr + 1'd1;                     //读指针递增dout	<=	fifo_buffer[rd_addr_true];               //fifo读出数据endelse beginrd_addr	<=	rd_addr;                            dout	<=	dout;end
end//-----------------------------<写操作>-----------------------------------
always@(posedge clk or posedge rst)begin if(rst)wr_addr <= 0;else if(wr_en && !full)begin                       //写使能有效且FIFO非满wr_addr	<=	wr_addr + 1'd1;                    //读指针递增fifo_buffer[wr_addr_true] <= din;              //数据写入fifoendelse beginwr_addr	<=	wr_addr;                            end
end//-----------------------------<通过地址扩展位更新空/满信号>-----------------------------------
assign	empty = ( wr_addr == rd_addr ) ? 1'b1 : 1'b0;                                              //当所有位相等时,读指针追到了写指针,FIFO被读空
assign	full  = ((wr_addr_msb != rd_addr_msb ) && ( wr_addr_true == rd_addr_true )) ? 1'b1 : 1'b0; //当最高位不同但是其他位相等时,写指针超过读指针一圈,FIFO被写满endmodule

四、测试代码

        给出如下的测试代码:

`timescale 1ns/1ns
//-----------------------------<高位扩展法同步FIFO测试>---------------------------------
module tb_sync_fifo1();parameter WIDTH	= 8;parameter DEPTH	= 8;reg                 clk         ;reg                 rst         ;reg  [WIDTH-1:0]	din    		;reg 				wr_en  		;reg 				rd_en  		;wire [WIDTH-1:0]	dout		;wire 				full        ;wire 				empty       ;//-----------------------------<测试模块例化>---------------------------------
sync_fifo1 #(.FIFO_WIDTH	(WIDTH),		 //FIFO宽度.FIFO_DEPTH (DEPTH)          //FIFO深度
)
sync_fifo_u1(.clk		(clk		),.rst		(rst		),.din     	(din 	    ),.rd_en		(rd_en		),.wr_en		(wr_en		),.dout    	(dout	    ),	.empty		(empty		),	.full		(full		)	
);//-----------------------------<模块测试>---------------------------------
initial beginclk = 1'b0;							//初始时钟为0rst <= 1'b0;						//初始复位din <= 'd0;		wr_en <= 1'b0;		rd_en <= 1'b0;
#10rst <= 1'b1;
#10 rst <= 1'b0;repeat(10)#10 beginwr_en <= 1'b1;rd_en <= 1'b0;din <= $random;                   //生成8位的随机数endrepeat(10)#10 beginwr_en <= 1'b0;rd_en <= 1'b1;end
$finish;
end//------------------------------<设置时钟>----------------------------------------
always #5 clk = ~clk;			endmodule

五、结果

 

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

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

相关文章

【数据库】MySQL基础知识全解

系列综述&#xff1a; &#x1f49e;目的&#xff1a;本系列是个人整理为了秋招面试的&#xff0c;整理期间苛求每个知识点&#xff0c;平衡理解简易度与深入程度。 &#x1f970;来源&#xff1a;材料主要源于拓跋阿秀、小林coding等大佬博客进行的&#xff0c;每个知识点的修…

企业架构LNMP学习笔记30

1、upstream 中server的关键字&#xff1a;语法&#xff1a; upstream中的分发之后的几个关键字&#xff1a; 1&#xff09;backup 备 其他的没有backup标识的都不可用了&#xff0c;才分发到backup&#xff1b; 2&#xff09;down 此条配置&#xff0c;不会被分发到。 syst…

OmniGraffle Pro for Mac 中文正式版(附注册码) 苹果电脑 思维导图软件

OmniGraffle Pro是OmniGraffle的高级版本&#xff0c;它提供了更多的功能和工具&#xff0c;可以帮助用户创建更为复杂和高级的图表和流程图。OmniGraffle Pro支持自定义形状、图形、线条和箭头等&#xff0c;可以让用户创建出更加精细的图表。此外&#xff0c;OmniGraffle Pro…

字符编码(idea)

File----------settings-------------Editor------------File Encodings

详细解析如何用“双指针“解题(面试必备,小白一看就会系类)

一、前言 大家在平时的训练和交流中肯定多少都会听过或者见过用"双指针"去快速的解题&#xff0c;那么大家有没有想过&#xff0c;为什么要用"双指针"呢&#xff1f;这里的"双指针"和我们平时了解的指针一样吗&#xff1f; 其实&#xff0c;这里…

永辉上半年净利润扭亏为盈,是“科技重启”的功劳吗?

你有多久没逛超市了&#xff1f;你记忆中的超市是怎样的&#xff1f;现在逛超市的原因又是什么&#xff1f; 其实&#xff0c;对于很多年轻人来说&#xff0c;现在的“快递点”就是“新时代超市”。而传统“超市”“大卖场”被新型超市、电商抢走不少人流量后&#xff0c;逐渐…

个人主页网站动态星空背景源码(带后台版本)

动态星空背景个人主页网站源码是一种用于创建个人主页的开源项目。它具有一个令人印象深刻的动态星空背景&#xff0c;为用户提供了一个独特而吸引人的网页设计。此源码还包含一个后台版本&#xff0c;使用户能够轻松管理和更新他们的个人主页内容。 通过该源码&#xff0c;用…

亿发软件:智慧门店商超系统,2023新零售POS数字运营一体化管理

2023年9月6日&#xff0c;山东济宁一家超市因为酸奶价格标签错误而引发了广泛关注。标签原本显示几十个人为9.9元&#xff0c;但特价销售价却标为10元。这一小小的错误却在社交媒体上引发了轩然大波&#xff0c;让超市一度处于舆论的风口浪尖。超市工作人员回应&#xff0c;表示…

华为云云耀云服务器L实例评测 | 华为云云耀云服务器L实例使用教学

文章目录 前言一、登录华为云二、创建云服务器L实例三、登录云服务器L实例四、使用云服务器L实例后记 前言 华为云是中国领先的云计算服务提供商之一&#xff0c;旗下的云耀云服务器是一种高性能、高可靠性、灵活可扩展的云服务器。 下面&#xff0c;我将为大家介绍华为云云耀云…

【算法】希尔 (Shell) 排序 详解

希尔排序 详解 希尔排序代码实现 排序&#xff1a; 排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 稳定性&#xff1a; 假定在待排序的记录序列中&#xff0c;存在多个具有相同的关键字的记录&#x…

MySQL学习问题记录

文章目录 MySQL学习问题记录1、查询记录自动根据id排序&#xff1f; MySQL学习问题记录 1、查询记录自动根据id排序&#xff1f; step1&#xff1a;建表 表项信息&#xff1a; 写入数据顺序id为10 2 7 1。查寻时返回记录顺序为1 2 7 10&#xff1f; 更新一条数据后仍然按照…

【AIGC专题】Stable Diffusion 从入门到企业级实战0403

一、前言 本章是《Stable Diffusion 从入门到企业级实战》系列的第四部分能力进阶篇《Stable Diffusion ControlNet v1.1 图像精准控制》第03节&#xff0c; 利用Stable Diffusion ControlNet Canny模型精准控制图像生成。本部分内容&#xff0c;位于整个Stable Diffusion生态…

PyTorch深度学习实战(15)——迁移学习

PyTorch深度学习实战&#xff08;15&#xff09;——迁移学习 0. 前言1. 迁移学习1.1 迁移学习基本概念1.2 迁移学习的重要性1.3 ImageNet1.4 迁移学习流程 2. VGG16 架构3. 使用预训练 VGG16 模型实现猫狗分类小结系列链接 0. 前言 迁移学习( Transfer Learning )是一种利用从…

时序预测 | MATLAB实现ICEEMDAN-iMPA-BiLSTM时间序列预测

时序预测 | MATLAB实现ICEEMDAN-iMPA-BiLSTM时间序列预测 目录 时序预测 | MATLAB实现ICEEMDAN-iMPA-BiLSTM时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 ICEEMDAN-iMPA-BiLSTM功率/风速预测 基于改进的自适应经验模态分解改进海洋捕食者算法双向长短期记忆…

C语言深入理解指针(非常详细)(五)

目录 回调函数qsort使用举例qsort函数的模拟实现sizeof和strlen的对比sizeofstrlensizeof和strlen的对比一道关于sizeof的题 回调函数 回调函数就是一个通过函数指针调用的函数 如果你把函数的指针&#xff08;地址&#xff09;作为参数传递给另一个函数&#xff0c;当这个指…

Python小知识 - Python装饰器

Python装饰器 在Python中&#xff0c;装饰器是一个特殊的函数&#xff0c;可以将其他函数包装在装饰器函数中&#xff0c;并且将被包装的函数作为参数传递给装饰器函数。 使用装饰器的好处是可以自动在被包装的函数前后执行一些额外的代码&#xff0c;比如在函数执行前后打印日…

ClickHouse的Join算法

ClickHouse的Join算法 ClickHouse是一款开源的列式分析型数据库&#xff08;OLAP&#xff09;&#xff0c;专为需要超低延迟分析查询大量数据的场景而生。为了实现分析应用可能达到的最佳性能&#xff0c;分析型数据库&#xff08;OLAP&#xff09;通常将表组合在一起形成一个…

电脑文件批量重命名:高效操作技巧

随着时间的推移&#xff0c;我们积累的文件和文件夹数量越来越多&#xff0c;需要对它们进行合理的命名和管理&#xff0c;以便更方便地查找和利用。而文件批量重命名功能可以帮助我们更高效地管理文件夹。下面介绍五种方式&#xff0c;帮助你更好地利用文件批量重命名工具&…

ADASAPA场景设计分享

相信大家都对于ADAS与APA这两个车机功能都不陌生&#xff0c;对其场景设计过程可能并不是很清楚。今天小怿就跟大家分享一下自己的设计心得。 首先&#xff0c;我们来看一下ADAS和APA的定义&#xff0c;以便我们更好地了解其功能和应用场景。 ADAS定义 ADAS的全称叫Advanced …

Nosql数据库服务之redis

Nosql数据库服务之redis 一图详解DB的分支产品 Nosql数据库介绍 是一种非关系型数据库服务&#xff0c;它能解决常规数据库的并发能力&#xff0c;比如传统的数据库的IO与性能的瓶颈&#xff0c;同样它是关系型数据库的一个补充&#xff0c;有着比较好的高效率与高性能。 专…