Verilog基础之十四、FIFO实现

news2024/9/21 4:34:14

目录

一、FIFO

1.1 定义

1.2 实现方式

1.3 实现原理  

二、代码实现

三、仿真结果

3.1 复位阶段

3.2 写入阶段

3.3 读取阶段

3.4 同时读写或不读不写

四、参考资料


一、FIFO

1.1 定义

    FIFO(First in First out)为先进先出队列,具有存储功能,可用于不同时钟域间传输数据以及不同的数据宽度进行数据匹配。如其名称,数据传输为单向,从一侧进入,再从另一侧出来,出来的顺序和进入的顺序相同。

1.2 实现方式

    FIFO可由多种不同的实现方式,可以用块状RAM,分布式RAM来实现,也可直接使用IP核,当数据较小时,建议使用分布式RAM实现,数据较大时,用块状RAM实现。

1.3 实现原理  

    FIFO组成包含存储单元,写时钟,读时钟,满标志,空标志,读写控制信号,当读时钟和写时钟都是同一个时钟时,则为同步FIFO,否则为异步FIFO。

    a.首先,在复位操作后,在写时钟控制下,如果状态非满状态,数据可写入到FIFO中。每写一次数据,写指针加一,写满后将不允许再写入;

    b.当FIFO中数据非空时,在读时钟的控制下,数据可从FIFO中读出。每读一次数据,读时钟加一,位于下一个读取的位置,在空状态下,将不能继续读数据;

    无论是同步FIFO还是异步FIFO,都是以双口RAM为基础来实现。

二、代码实现

    ​代码为书籍《FPGA应用技术及实践》中5.3.3 FIFO设计中的代码,相比原代码中,对read/write为00时,对count的值变化进行了修改,修改为count<=count更合理,设计为实现4X16的同步FIFO

module FIFO_V(rst,clk,data_in,data_out,read,write,empty,full );
input rst,clk;
input [15:0] data_in;
output reg [15:0] data_out;
input read,write;
output empty,full;
parameter depth=2,max_count=2'b11;
reg empty,full;
reg [depth-1:0] tail;
reg [depth-1:0] head;
reg [depth-1:0] count;
reg [15:0] fifomem [0:max_count];
//读空判断
always@(posedge clk)
begin
    if(rst==1)
    begin
        data_out<=16'h0000;
    end
    else if(read==1'b1&&empty==1'b0)
    begin
        data_out<=fifomem[tail];
    end
end
//写满判断
always@(posedge clk)
begin
    if(rst==1'b0&&write==1'b1&&full==1'b0)
    fifomem[head]<=data_in;
end
//写操作
always@(posedge clk)
begin
    if(rst==1)
        head<=2'b00;
        else
    begin
        if(write==1'b1&&full==1'b0)
        head<=head+1;
    end
end
//读操作
always@(posedge clk)
begin
    if(rst==1)
    begin
        tail<=2'b00;
    end
    else if(read==1'b1&&empty==1'b0)
    begin
        tail<=tail+1;
    end
end
//读写操作下的计数
always@(posedge clk)
begin
    if(rst==1)
    begin
        count<=2'b00;
    end
    else 
    begin
        case({read,write})
            2'b00:count<=count;
            2'b01:if(count!=max_count) count<=count+1;
            2'b10:if(count!=2'b00) count<=count-1;
            2'b11:count<=count;
         endcase
    end
end
//队列空状态判断
always@(posedge clk)
begin
    if(count==2'b00)
        empty<=1'b1;
    else
        empty<=1'b0;
end
//队列满状态判断
always@(posedge clk)
begin
    if(count==max_count)
        full<=1'b1;
    else
        full<=1'b0;
end
endmodule

测试代码 

对于read和write信号,尽量避免在时钟上升沿时进行状态变化,如此处write翻转在201ns,read翻转在#252,即避免了和时钟的上升沿同步,也避免了和write翻转的同步

`timescale 1ns / 1ps
module FIFO_tb( );
reg clk,rst,write,read;
reg [15:0] data_in;
wire [15:0] data_out;
wire empty,full;
FIFO_V FIFO_test (.clk(clk),.rst(rst),.data_in(data_in),.write(write),.read(read),.empty(empty),.full(full),.data_out(data_out));
//初始状态赋值
initial
begin
clk=0;
rst=1;
data_in=16'h1111;
#51 rst=0;
end
//写操作
initial
begin
write=1;
#201 write=1;
#30 write=0;
#200 write=1;
#85 write=0;
//#10 write=1;
//#60 write=0;
end
//读操作
initial
begin
read=0;
#252 read=1;
#200 read=0;
#100 read=1;
end
//输入信号与时钟信号生成
always #20 data_in=data_in+16'h1111;
always #10 clk=~clk;
endmodule

三、仿真结果

3.1 复位阶段

    在起始的50ns内,复位信号rst(红色标注)为1时,进行复位操作,如黄色定位线所示,输出data_out为0,empty和full标志为0;

 

3.2 写入阶段

    在110.1ns时开始写入,时间点不是110ns而是多了0.1ns是由于modelsim默认的开始时刻是0.1ns开始;因为count原先一直处于初始化状态2'b00,在此时因为写入进行了empty的逻辑判断,因为empty为0;

    在clk信号中1、2、3、4上升沿位置,即为写入4个值:6666,7777,8888,9999,写完后刚好写满,因此full标志位在170.1ns处变为1,表示已写满无法再写入。

 

3.3 读取阶段

    在270.1ns时,read/write的值为1/0开始从FIFO中进行数据读取,在clk信号的1,2,3,4读取了4个数值,根据data_out可知为6666,7777,8888,9999。读出顺序与写入顺序一致,即先入先出。

3.4 同时读写或不读不写

    在450ns时,read/write都为1,读写同时进行,并且empty为1,可知不进行读操作,count的逻辑。但因full为0,可以进行写入,此时进行写入,在4个clk周期写满,因此在530.1ns时full标志位为1

 

    在530ns和550ns时,read/write都为0,此时不读也不写入,因此输出状态不变,一直为9999,

 

四、参考资料

书籍《FPGA应用技术及实践》中5.3.3 FIFO设计章节

    

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

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

相关文章

一篇带你彻底搞懂线程池

目录 一、自定义线程池 1、产生背景 2、堵塞队列 3、线程池 4、拒绝策略 二、ThreadPoolExecuor 1、线程池状态 2、构造方法 3、newFixedThreadPool 4、newCachedThreadPool 5、newSingleThreadExecutor 6、提交任务 7、关闭线程池 三、异步模式之工作线程 1、定…

C-数据的储存(上)

文章目录 前言&#x1f31f;一、数据类型详细介绍&#x1f30f;1.内置类型&#x1f4ab;&#xff08;1&#xff09;.整形家族&#x1f4ab;&#xff08;2&#xff09;.浮点数家族&#x1f30f;2.构造类型&#xff08;也称自定义类型&#xff09;&#x1f30f;3.指针类型&#x…

OpenCV 入门教程:Haar特征分类器

OpenCV 入门教程&#xff1a; Haar 特征分类器 导语一、Haar特征分类器原理二、Haar特征分类器步骤三、示例应用总结 导语 Haar 特征分类器是图像处理中常用的目标检测算法&#xff0c;用于识别图像中的特定目标。该算法基于 Haar-like 特征模板&#xff0c;通过训练分类器来实…

ArcGIS PRO基础教程(一)

操作要求 1.面积为50-80亩 2.不能选在有耕地、园地内 3.坡度小于15度,高程在以下1930 4.距离水源地在300米以内 已知数据 1.等高线图 CONTOUR 2.土地利用图 parcel 3.水系图 water 操作步骤 创建工程,模板选地图就可以了(注:在arcgis pro中创建工程可以看作在arcg…

大火的ChatGPT与表格插件结合会有哪些意想不到的效果?

大火的ChatGPT与表格插件结合会有哪些意想不到的效果&#xff1f; 摘要&#xff1a;本文由葡萄城技术团队于CSDN原创并首发。转载请注明出处&#xff1a;葡萄城官网&#xff0c;葡萄城为开发者提供专业的开发工具、解决方案和服务&#xff0c;赋能开发者。 ChatGPT已经火了好…

前端全集Ⅰ---- HTML/CSS/JavaScript

一 介绍web开发 Web&#xff1a;全球广域网&#xff0c;也称万维网&#xff0c;能够通过浏览器访问的网站 Web网站的工作流程&#xff1a;&#xff08;前后端分离模式&#xff09; 网页有哪些组成&#xff1f; 文字、图片、视频、音频、超链接 前端代码通过浏览器的解析和渲…

3-exercises

解&#xff1a; &#xff08;1&#xff09;Create a tensor a from list(range(9)). Predict and then check the size, offset, and stride. 创建列表a 将其转化为张量 a.size&#xff1a;The size (or shape, in NumPy parlance) is a tuple indicating how many elements a…

脚本引流是什么?其实很好理解,就是利用软件脚本来引流,这种软件我们通常叫引流脚本

脚本引流是什么&#xff1f;其实很好理解&#xff0c;就是利用脚本来引流&#xff0c;这种软件我们通常叫引流脚本&#xff0c;引流脚本的研发就是结合了以往的那些加人软件&#xff0c;从中吸取了长处并且升级了功能&#xff0c;而且通过不断的测试改进&#xff0c;在今年的7月…

C# PaddleInference OCR文字识别(只识别)

说明 C# PaddleInference OCR文字识别&#xff08;只识别&#xff09;&#xff0c;没有文字区域检测、文字方向判断 测试图片是文字区域检测裁剪出来、处理过的图片 完整的OCR识别查看 C# PaddleInference OCR识别 学习研究Demo_天天代码码天天的博客-CSDN博客 效果 项目 …

-1在内存中的存储及打印问题。

首先先看看代码&#xff1a; #include"stdio.h" int main() { char a -1; signed char b -1; unsigned char c -1; printf("a%d b%d c%d", a, b, c); return 0; } 代码很简单&#xff0c;问打印结果是什么&#xff1f; 下面我…

Java 比对两张图片的差异

1.基本介绍 Github上的“https://github.com/akullpp/awesome-java”页整理了非常多的各类Java组件的实现&#xff0c;前面一篇从它的图片处理篇找到了《image-comparison》进行了动手实践&#xff0c;关于图片处理的二维码组件《ZXing》本站曾有实践&#xff1b;关于图片识别…

CUDA+CUDNN+torch+torchvision安装

弄了好久&#xff0c;终于弄好了&#xff01;&#xff01;&#xff01; 原因&#xff1a;其实之前我是已经配置好pytorch的相关环境的了。但是这段时间&#xff0c;在跑GNN相关论文中的代码时&#xff0c;发现代码中的某个函数要求torch必须得是1.8 而我之前安装的是torch1.1…

leetcode-209.长度最小的子数组

leetcode-209.长度最小的子数组 文章目录 leetcode-209.长度最小的子数组题目描述代码提交(快慢指针-滑动窗口) 题目描述 代码提交(快慢指针-滑动窗口) 代码 class Solution {public:int minSubArrayLen(int target, vector<int> &nums) {int slow 0;int fast 0;i…

Spring中事务传播机制的理解与简单试用

目录 一&#xff0c;前言 二&#xff0c;Spring框架中的事务传播行为 三&#xff0c;事务的传播行为测试 Propagation.REQUIRED Propagation.SUPPORTS Propagation.MANDATORY Propagation.REQUIRES_NEW Propagation.NOT_SUPPORTED Propagation.NEVER Propagation.NES…

c++11 标准模板(STL)(std::basic_istream)(三)

定义于头文件 <istream> template< class CharT, class Traits std::char_traits<CharT> > class basic_istream : virtual public std::basic_ios<CharT, Traits> 类模板 basic_istream 提供字符流上的高层输入支持。受支持操作包含带格式的…

从零配置 linux 开发环境

文章目录 目的效果图配置本地 Windows 主机好用工具WSLSSH 连接远程 Linux 开发机配置本机字体【in-prog】配置 vscode 远程连接 配置远程 Linux 主机zsh & oh-my-zsh配置 github 的 SSHneovimvundleinit.vim 文件 vim-plug.lua 文件 tmuxclangcpplint 目的 记录下我的开发…

Go语言开发者的Apache Arrow使用指南:高级数据结构

经过对前面两篇文章《Arrow数据类型》[1]和《Arrow Go实现的内存管理》[2]的学习&#xff0c;我们知道了各种Arrow array type以及它们在内存中的layout&#xff0c;我们了解了Go arrow实现在内存管理上的一些机制和使用原则。 Arrow的array type只是一个定长的、同类型的值序列…

[SWPUCTF 2021 新生赛]jicao

点进去后是一段php代码 <?php highlight_file(index.php); include("flag.php"); $id$_POST[id]; $jsonjson_decode($_GET[json],true); if ($id"wllmNB"&&$json[x]"wllm") {echo $flag;} ?> 包含了flag.php文件&#xff0c;设定…

数据结构关键路径问题:下面是一个有10个活动的AOE图,时间余量最大的活动是()

关键路径问题 名人说&#xff1a;莫听穿林打叶声&#xff0c;何妨吟啸且徐行。—— 苏轼《定风波莫听穿林打叶声》 本篇笔记整理&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 关键路径问题〇、概念说明1、AOE网2、关键路…

4-软件错误(BUG)

目录 1.什么是bug? 2.如何描述一个bug? ①发现问题的版本 ②问题出现的环境 ③错误重现的步骤 ④预期行为的描述 ⑤错误行为的描述 ⑥其他 ⑦不要把多个bug放到一起 PS&#xff1a;案例1 PS&#xff1a;案例2 3.如何定义bug的级别&#xff1f; ①Blocker&#x…