同步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
五、结果
相关文章:

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

数据结构与算法面试
1、链表反转 需要三个指针,一个pre指针指向反转的前一个节点,cur指向要反转的节点,然后设置有一个temp指针指向需要反转的下一个节点,用来使得cur指针移动,因为我们反转之后,无法使用next指针访问到后一个节…...

android studio cmake生成.a文件(静态库)及调用(c c++)静态库.a
第一步生成静态库.a文件: cmake 语法如何生成静态库,就不介绍了,比较简单,我下文列出的参考资料里面有详细介绍。 add_library(${CMAKE_PROJECT_NAME} STATICsrc/CalculStatic.cpp)这一步有坑,我刚开始的时候,也花了不少时间,死活都没有生成.a静态库文件。但是我多方查…...

本地部署体验LISA模型(LISA≈图像分割基础模型SAM+多模态大语言模型LLaVA)
GitHub地址:https://github.com/dvlab-research/LISA 该项目论文paper reading:https://blog.csdn.net/Transfattyacids/article/details/132254770 在GitHub上下载源文件,进入下载的文件夹,打开该地址下的命令控制台,…...

SpotBugs代码检查:instanceof总是返回true(BC_VACUOUS_INSTANCEOF)
https://spotbugs.readthedocs.io/en/latest/bugDescriptions.html#bc-instanceof-will-always-return-true-bc-vacuous-instanceof 使用instanceof判断的时候,总是返回true,除非被检测的结果是null。遇到这种告警,可能是写代码的人理解错误…...
Redis的Java客户端:Jedis入门
Jedis的优点在于方法名称和Redis命令基本一致,不过存在线程安全问题,在多线程操作时需要引入线程池。 一、引入依赖 <!--jedis--> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifa…...

【完整代码】2023数学建模国赛C题代码--蔬菜类商品的自动定价与补货决策
C 题 蔬菜类商品的自动定价与补货决策 在生鲜商超中,一般蔬菜类商品的保鲜期都比较短,且品相随销售时间的增加而变差, 大部分品种如当日未售出,隔日就无法再售。因此,商超通常会根据各商品的历史销售和需 求情况每天进…...

idea:java: Compilation failed: internal java compiler error
java: Compilation failed: internal java compiler error错误 检查下面2个即可:...

普罗米修斯(Prometheus)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、普罗米修斯(Prometheus)是什么?1.下载Prometheus工具(切记和操作系统版本对应)2.解压命令3.修改prom…...
JAVA面试题2012年版本
1、已知a10,b15,在不用第三方变量的情况下,将a、b的值调换? 2、Session容易丢值,cookie不安全,用什么可以代替它们? 3、简述多态的特征及意义 4、冒泡排序 5、已知int array[]{3,7,5,12,20};实现从大到小排序并返回数组输出…...
IED设备模型
IED设备模型 IED设备模型是指对工业电子设备进行详细描述和建模的模型。它的核心是通过设备的特性和功能来建立相应的数学模型,以便进行仿真、测试和优化等操作。 建立IED设备模型需要遵循以下步骤: 设备描述:首先需要详细描述设备的功能、特性、参数等信息,以便建立相应…...

HTTP代理如何设置
HTTP代理是一种非常重要的网络工具,它可以帮助我们在访问互联网时提高访问速度,保护用户隐私等等。在使用HTTP代理时,需要先进行设置。下面就来介绍一下HTTP代理如何设置。 一、了解HTTP代理 在开始设置HTTP代理之前,我们需要先了…...
【设计模式】单例设计模式
目录 1、前言 2、基本语法 2.1、懒汉式单例 2.2、饿汉式单例 2.3、双重检验锁单例模式 2.4、静态内部类单例模式 2.5、枚举单例模式 2.6、ThreadLocal单例模式 2.7、注册单例模式 3、使用场景 4、使用示例 5、常见问题 5、总结 1、前言 单例模式是一种设计模式&…...

SpingBoot整合Sa-Token框架(1)
一、文档参考:框架介绍 (sa-token.cc) 框架生态——开源项目 (sa-token.cc) 二、与SpingBoot整合 1、创建项目 在 IDE 中新建一个 SpringBoot 项目,例如:sa-token-demo-springboot(不会的同学请自行百度或者参考:Sp…...

软件测试技术题目大全【含答案】
请看下面 你的测试职业发展是什么? 测试经验越多,测试能力越高。所以我的职业发展是需要时间积累的,一步步向着高级测试工程师奔去。而且我也有初步的职业规划,前3年积累测试经验,按如何做好测试工程师的要点去要求自己&#x…...

C#__线程的优先级和状态控制
线程的优先级: 一个CPU同一时刻只能做一件事情,哪个线程优先级高哪个先运行,优先级相同看调度算法。 在Thread类中的Priority属性(Highest,Above,Normal,BelowNormal,Lowest)可以影响线程的优先级 关于…...
103.36.167.X在服务器删除、复制文件的时候会出现卡的情况,是什么原因?
服务器硬盘在删除文件或复制文件时出现卡顿情况可能有多种原因。以下是一些常见的问题和解决方法: 硬盘性能低下:如果服务器硬盘的读写速度较慢,可能会导致卡顿现象。解决方法可以是升级到更高性能的硬盘或者使用RAID技术提升硬盘读写速度。 …...
Vim 插件应用篇 vim-plug:简洁高效的Vim插件管理工具
用插件管理插件 Vim-plug介绍 Vim-plug 是一个Vim插件管理器,利用异步并行可以快速地安装、更新和卸载插件。它的安装和配置都非常简单,而且在操作过程中会给出很多易读的反馈信息,是一个自由、开源、速度非常快的、并行地安装或更新插件&a…...
springboot 请求https的私有证书验证
一、方案描述 我这里采用RestTemplate的方式调用https请求,请求第三方接口获取数据,证书由第三方私自签发的证书,我们构建的是一个springboot的API项目。 1.pom文件引入jar <dependencies><dependency><groupId>org.spr…...

YOLO的基本原理详解
YOLO介绍 YOLO是一种新的目标检测方法。以前的目标检测方法通过重新利用分类器来执行检测。与先前的方案不同,将目标检测看作回归问题从空间上定位边界框(bounding box)并预测该框的类别概率。使用单个神经网络,在一次评估中直接…...

19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
Web中间件--tomcat学习
Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...

脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)
一、OpenBCI_GUI 项目概述 (一)项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台,其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言,首次接触 OpenBCI 设备时,往…...
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么?它的作用是什么? Spring框架的核心容器是IoC(控制反转)容器。它的主要作用是管理对…...

【多线程初阶】单例模式 指令重排序问题
文章目录 1.单例模式1)饿汉模式2)懒汉模式①.单线程版本②.多线程版本 2.分析单例模式里的线程安全问题1)饿汉模式2)懒汉模式懒汉模式是如何出现线程安全问题的 3.解决问题进一步优化加锁导致的执行效率优化预防内存可见性问题 4.解决指令重排序问题 1.单例模式 单例模式确保某…...

21-Oracle 23 ai-Automatic SQL Plan Management(SPM)
小伙伴们,有没有迁移数据库完毕后或是突然某一天在同一个实例上同样的SQL, 性能不一样了、业务反馈卡顿、业务超时等各种匪夷所思的现状。 于是SPM定位开始,OCM考试中SPM必考。 其他的AWR、ASH、SQLHC、SQLT、SQL profile等换作下一个话题…...