FPGA FIFO——IP核

news2024/11/27 8:49:27

文章目录

  • 前言
  • 一、FIFO
    • 1、区别
    • 2、分类
  • 二、单时钟&多时钟FIFO框图
  • 三、FIFO IP 核配置
  • 四、源码
    • 1、fifo_wr(写模块)
    • 2、fifo_rd(读模块)
    • 3、ip_fifo(顶层文件)
  • 五、仿真
    • 1、仿真文件
    • 2、波形分析
  • 六、SignalTap II在线验证
  • 七、总结
  • 八、参考资料


前言

环境:
1、Quartus18.0
2、vscode
3、板子型号:原子哥开拓者2(EP4CE10F17C8)
要求:
实现当 FIFO 为空时就开始向 FIFO 中写入数据,直到 FIFO 写满为止;当 FIFO 为满时则开始从 FIFO 中读出数据,直到 FIFO 读空为止的功能。


一、FIFO

FIFO 的英文全称是 First In First Out,即先进先出。FPGA 使用的 FIFO 一般指的是对数据的存储具有先进先出特性的一个缓存器,常被用于数据的缓存或者高速异步数据的交互,也即所谓的跨时钟域信号传递

1、区别

与RAM、ROM的相比,FIFO没有外部读写地址线,采用的是顺序写入、顺序读出数据的方式,缺点就是不能像RAM、ROM那样由地址线决定读取或写入的地址。

2、分类

  • 单时钟 FIFO:

单时钟 FIFO 具有一个独立的时钟端口 clock,因此所有的输入输出信号都同步于 clock 信号。

  • 作用:
    单时钟 FIFO 常用于同步时钟的数据缓存
  • 双时钟 FIFO:

从输出数据的位宽的角度分为普通双时钟和混合宽度双时钟。
在双时钟FIFO 结构中,写端口和读端口分别有独立的时钟,所有与写相关的信号都是同步于写时钟 wrclk,所有与读相关的信号都是同步于读时钟 rdclk。

  • 作用:
    双时钟 FIFO 常用于跨时钟域的数据信号的传递,例如时钟域 A 下的数据 data1 传递给异步时钟域 B,当 data1 为连续变化信号时,如果直接传递给时钟域 B 则可能会导致收非所送的情况,即在采集过程中会出现包括亚稳态问题在内的一系列问题,使用双时钟 FIFO 能够将不同时钟域中的数据同步到所需的时钟域中。

二、单时钟&多时钟FIFO框图

  • 模块框图:
    在这里插入图片描述
  • 端口框图:
    在这里插入图片描述
  • 参数描述:

FIFO 的宽度:FIFO 一次读写操作的数据位 N;
FIFO 的深度:FIFO 可以存储多少个宽度为 N 位的数据。
空标志:对于双时钟 FIFO 又分为读空标志 rdempty 和写空标志 wrempty。FIFO 已空或将要空时由FIFO 的状态电路送出的一个信号,以阻止 FIFO 的读操作继续从FIFO 中读出数据而造成无效数据的读出。
满标志:对于双时钟 FIFO 又分为读满标志 rdfull 和写满标志 wrfull。FIFO 已满或将要写满时由 FIFO的状态电路送出的一个信号,以阻止 FIFO 的写操作继续向 FIFO 中写数据而造成溢出。
读时钟:读 FIFO 时所遵循的时钟,在每个时钟的上升沿触发。
写时钟:写 FIFO 时所遵循的时钟,在每个时钟的上升沿触发。

三、FIFO IP 核配置

  • 查找FIFO IP:
    在这里插入图片描述
  • 双击过后:
    在这里插入图片描述

选择路径、语言。

  • 选择位宽、深度、时钟:
    在这里插入图片描述
  • 选择中等优化:
    在这里插入图片描述

1、最低延迟,但要求同步时钟: 此选项使用一个同步阶段,没有亚稳态保护,适用于同步时钟。它是最小尺寸,提供良好的 Fmax。
2、异步时钟时的最小设置: 这个选项使用两个同步阶段,具有良好的亚稳态保护。它是中等尺寸,提供良好的 Fmax。
3、异步时钟时最好的亚稳态保护,最好的Fmax,不同步: 这个选项使用三个或更多的同步阶段,具有最好的亚稳态保护。它是最大尺寸,给出了最好的 Fmax。

我们一般会根据工程需求以及资源来选择合适的优化。

  • 选择输出控制信号:
    在这里插入图片描述

这里我们选择读空、读满、读侧数据量和写空、写满信号、写侧数据量

  • 选择输出模式和存储器类型:
    在这里插入图片描述

输出模式:
1、正常模式:FIFO 将端口 rdreq 看做正常的读请求并在该端口信号为高电平进行读操作。
2、前显模式:FIFO 将端口 rdreq 看做读确认信号,将 rdreq 信号置为高电平时将输出 FIFO 中的下一个数据字(如果存在)。

  • 上溢检测与下溢检测:
    在这里插入图片描述

这里的上下溢检测默认是打开的,如果不需要的话可以进行勾选来禁止,以此来节省资源,提高FIFO性能。

  • 添加仿真库(默认存在):
    在这里插入图片描述
  • 勾选inst文件:
    在这里插入图片描述
  • 点击finish后点击YES添加到工程:
    在这里插入图片描述
  • 添加成功效果:
    在这里插入图片描述

四、源码

1、fifo_wr(写模块)

module fifo_wr(
    input               clk     ,
    input               rst_n   ,
    input               wrempty ,//写空信号
    input               wrfull  ,//写满信号

    output reg [7:0]    data    ,//写数据
    output reg          wrreq    //写请求
);
reg [1:0] flow_cnt;//状态计数器
/***************
写 fifo 模块主要完成向 fifo 中写入数据的功能,当 fifo 为空时,向 fifo 中写入数据;
当 fifo 写满之后,停止写入数据,然后重新判断 fifo 是否为空。
***************/
//写数据
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)begin
        wrreq <= 1'b0;
        data  <= 8'd0;
        flow_cnt <= 2'd0;
    end
    else begin
        case(flow_cnt)
        2'd0: begin
            if(wrempty) begin//写空间为空,写请求使能,进入下一个状态
                wrreq <= 1'b1;
                flow_cnt <= flow_cnt + 1'b1;
            end
            else
                flow_cnt <= flow_cnt;//其实最多就计到1,其余状态不变,在写满后置0
        end
        2'd1: begin
            if(wrfull) begin
                wrreq <= 1'b0;
                data  <= 8'd0;
                flow_cnt <= 2'd0;
            end
            else begin
                wrreq <= 1'b1;//保持写请求为有效状态
                data  <= data + 1'd1;//写数据加1
            end
        end
        default: flow_cnt <= 2'd0;
        endcase
    end
end
endmodule

2、fifo_rd(读模块)

module fifo_rd(
    input           clk         ,
    input           rst_n       ,
    input [7:0]     data        ,
    input           rdfull      ,
    input           rdempty     ,

    output reg rdreq
);

reg [7:0] data_fifo;//读取的数据
reg [1:0] flow_cnt;//状态计数器
/***************
读 fifo 模块主要完成向 fifo 中读出数据的功能,当 fifo 数据为满的状态时,
开始向 fifo 中读出数据;当 fifo 读空之后,停止读数据,然后重新判断 fifo 是否为满的状态。
***************/
//读取数据
always @(posedge clk or negedge rst_n)begin
    if(!rst_n) begin
        rdreq <= 1'b0;
        data_fifo <= 8'd0;
    end
    else begin
        case(flow_cnt)
            2'd0: begin
                if(rdfull) begin//与写不同,读是满的时候才使能
                    rdreq <= 1'b1;
                    flow_cnt <= flow_cnt + 1'b1;
                end
                else
                    flow_cnt <= flow_cnt;
            end
            2'd1: begin
                if(rdempty) begin
                    rdreq <= 1'b0;
                    data_fifo <= 8'd0;
                    flow_cnt  <= 2'd0;
                end
                else begin
                    rdreq <= 1'b1;
                    data_fifo <= data;
                end
            end
            default: flow_cnt <= 2'd0;
        endcase
    end
end
endmodule

3、ip_fifo(顶层文件)

module ip_fifo(
    input sys_clk ,
    input sys_rst_n
);
//写数据
wire wrreq ;
wire [7:0] data ;
wire wrempty ;
wire wrfull ;
wire wrusedw;//写侧FIFO中的数据量
//读数据
wire rdreq ;
wire [7:0] q ;//FIFO读出的数据
wire rdempty ;
wire rdfull ;
wire rdusedw;//读侧FIFO中的数据量
//fifo IP核
fifo fifo_inst(
    .wrclk ( sys_clk ), // 写时钟
    .wrreq ( wrreq ), // 写请求
    .data ( data ), // 写入 FIFO 的数据
    .wrempty ( wrempty ), // 写空信号
    .wrfull ( wrfull ), // 写满信号
    .wrusedw ( wrusedw ), // 写侧数据量

    .rdclk ( sys_clk ), // 读时钟
    .rdreq ( rdreq ), // 读请求
    .q ( q ), // 从 FIFO 输出的数据
    .rdempty ( rdempty ), // 读空信号
    .rdfull ( rdfull ), // 读满信号
    .rdusedw ( rdusedw ) // 读侧数据量
);
//写模块
fifo_wr fifo_wr_inst(
    .clk       (sys_clk),
    .rst_n     (sys_rst_n),
    .wrempty   (wrempty),//写空信号
    .wrfull    (wrfull),//写满信号

    .data      (data),//写数据
    .wrreq     (wrreq) //写请求
);
//读模块
fifo_rd fifo_rd_inst(
    .clk         (sys_clk),
    .rst_n       (sys_rst_n),
    .data        (q),
    .rdfull      (rdfull),
    .rdempty     (rdempty),

    .rdreq       (rdreq)
);
endmodule

五、仿真

1、仿真文件

`timescale 1ns/1ns
module ip_fifo_tb();

parameter T = 20;

reg sys_clk;
reg sys_rst_n;

initial begin
    sys_clk <= 1'b0;
    sys_rst_n <= 1'b0;
    #(T + 1)
    sys_rst_n <= 1'b1;
    #(3000*4)
    $stop;
end

always #(T) sys_clk = ~sys_clk;

ip_fifo ip_fifo_inst(
    .sys_clk     (sys_clk),
    .sys_rst_n   (sys_rst_n)
 );
endmodule

2、波形分析

  • 说明:

这里为了我们理解,使用的是同步FIFO,即读写使用的都是系统时钟。意味着读和写操作不能同时进行。只有在写操作完成后,才能进行读操作。

当有数据写入FIFO时,写操作将会阻塞,直到有读操作将数据读取走。同样地,当FIFO已满时,写操作也会阻塞,直到有读操作将数据读取走腾出空间。这确保了数据的顺序性:先进先出。

在这里插入图片描述
在这里插入图片描述

  • 波形分析:

在波形写满过后,且经过三个时钟周期后,读满信号 rdfull 才有效,并且在读请求信号rereq 拉高后的第 3 个时钟周期写满信号 wrfull 才拉低。写完才进行的读,且是从0开始读的,符合先进先出。


六、SignalTap II在线验证

  • 读状态:
    在这里插入图片描述
  • 分析:

在写满过后,写使能置0,无法进行写入,隔三个时钟周期读满信号有效,读使能有效,从0开始读出数据,我们开始写入也是从0开始的,符合先进先出。

  • 写状态:
    在这里插入图片描述
  • 分析:

在读空三个周期过后,写使能有效,开始从0进行写入操作。因为这里使用的是同一时钟,所以在写的时候会堵塞,写满后才能读取。

七、总结

写到这一篇IP核的系列文章就结束了,还有许多的IP核等待我们的学习,只是这几个是比较常用的先进行一个学习。与RAM不同,FIFO是先进先出,不能随意对某一个地址进行读写,只能按照顺序读写。

八、参考资料

以上资料均来自正点原子的教学视频或开拓者2开发教程:原子官方

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

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

相关文章

python与深度学习(六):CNN和手写数字识别二

目录 1. 说明2. 手写数字识别的CNN模型测试2.1 导入相关库2.2 加载数据和模型2.3 设置保存图片的路径2.4 加载图片2.5 图片预处理2.6 对图片进行预测2.7 显示图片 3. 完整代码和显示结果4. 多张图片进行测试的完整代码以及结果 1. 说明 本篇文章是对上篇文章训练的模型进行测试…

5.5.tensorRT基础(2)-封装插件过程,并实现更容易的插件开发

目录 前言1. 插件封装2. 补充知识总结 前言 杜老师推出的 tensorRT从零起步高性能部署 课程&#xff0c;之前有看过一遍&#xff0c;但是没有做笔记&#xff0c;很多东西也忘了。这次重新撸一遍&#xff0c;顺便记记笔记。 本次课程学习 tensorRT 基础-封装插件过程&#xff0c…

5G的发展过程

目录 1.什么是5G 2.5G与4G的区别 3.5G的应用领域 4.5G给人类带来的福利 5.5G未来的发展趋势 1.什么是5G 5G技术是第五代移动通信技术&#xff0c;它是对之前的2G、3G和4G技术的升级和革新。5G技术具有更高的数据传输速度、更低的延迟和更大的网络容量&#xff0c;为人们提供…

Qt简单实现密码器控件

本文实例为大家分享了Qt自定义一个密码器控件的简单实现代码&#xff0c;供大家参考&#xff0c;具体内容如下 实现构思&#xff1a; 密码器的功能可以看成是计算器和登陆界面的组合&#xff0c;所以在实现功能的过程中借鉴了大神的计算器的实现代码和登陆界面实现的代码。 …

20230720在ubuntu22.04系统下载+解密+合并ts切片的步骤(STEP-BY-STEP版本)

20230720在ubuntu22.04系统下载解密合并ts切片的步骤&#xff08;STEP-BY-STEP版本&#xff09; 2023/7/20 23:06 https://app1ce7glfm1187.h5.xiaoeknow.com/v2/course/alive/l_64af6130e4b03e4b54da1681?type2&app_idapp1cE7gLFM1187&pro_idterm_645c69388953e_Nhew…

人类机器人编程的心理机制(一)

\qquad 本文中的人类机器人编程(Human Robot Programming)意指“基于创伤的脑控(trauma-based mind control, T.B.M.C)”或“基于创伤的编程(trauma-based programming)”&#xff0c;文中用英文缩写“T.B.M.C”指代。T.B.M.C的操纵主体是施加编程的个人或机构&#xff0c;文中…

个人博客系统(三)

在个人博客系统(二)中介绍了注册页面和登录页面,这两个页面比较简单,最重要的一个问题是验证码的实现,具体详情可见:http://t.csdn.cn/EyVjz​​​​​​ 接下来,本博客主要介绍的是添加博客页面和修改博客页面。 1 添加博客页面 该页面如图所示: 首先判断文章标题是…

AcWing算法提高课笔记

目录 Level2 1.动态规划——从集合角度考虑DP问题 1.1 数字三角形模型 1.1.1摘花生 1.1.2最低通行费 1.1.3方格取数 1.1.4传纸条 1.2 最长上升子序列模型 1.2.1怪盗基德的滑翔翼 1.2.2登山 1.2.3合唱队形 1.2.4好友城市 1.2.5最大上升子序列和 1.2.6拦截导弹 1.2…

MySQL下载与安装

MySQL下载与安装 一、下载 地址&#xff1a;https://dev.mysql.com/downloads/mysql/ 当前最新是8.0版本&#xff0c;我选择上一个最新的mysql-5.7.24-winx64.zip 二、安装 MySQL安装文件分两种 .msi和.zip &#xff0c;.msi需要安装 zip格式是自己解压&#xff0c;解压缩之后…

Openlayers实战:extent介绍及实际应用

Openlayers中,extent是重要的属性,它主要目的是圈定边界。setExtent方法可以设定边界的值;fit()方法可以适配狂口的位置。 效果图 源代码 /* * @Author: 大剑师兰特(xiaozhuanlan),还是大剑师兰特(CSDN) * @此源代码版权归大剑师兰特所有,可供学习或商业项目中借鉴,…

关于Idea/DataGrip下载的插件在那个文件夹

不止Idea和DataGrip&#xff0c;只要是JET BRAINS家的产品都实用。 路径&#xff1a;C:\Users\windows登录账户\AppData\Roaming\JetBrains\DataGrip2021.3\plugins 如果要找其他软件的插件&#xff0c;就在JetBrains目录下找到相对应的软件&#xff0c;点进去后就是插件。 针…

瑞吉外卖开发笔记 七(Linux)

为什么要学Linux ? 企业用人要求个人发展要求 学习后能干什么&#xff1f; Linux简介 不同应用领域的主流操作系统 桌面操作系统 Windows &#xff08;用户数量最多)Mac OS&#xff08;操作体验好&#xff0c;办公人士首选)Linux&#xff08;用户数量少) 服务器操作系统 UN…

Python Flask构建微信小程序订餐系统 (十一)

🔥 已经删除的会员不允许进行编辑昵称 🔥 🔥 已经删除的会员要隐藏掉会员信息的编辑按钮 🔥 🔥 创建商品表 food 🔥 CREATE TABLE `food` (`id` int(11) unsigned NOT NULL AUTO_INCREMENT,`cat_id` int(11) NOT NULL DEFAULT 0 COMMENT 分类id,`name` varchar…

springboot集成logback按日志级别按天保存

演示结果 集成logback后项目启动控制台不会有日志输出 生成的日志文件路径windows上是默认D盘,linux上可自定义 代码实现 pom.xml <dependency><groupId>ch.qos.logback</groupId>

[DASCTF 2023 0X401七月暑期挑战赛] crypto

密码只有3道题&#xff0c;最后一道被卡了&#xff0c;赛后在师傅一点点提示下完成。 ezRSA 题目很短&#xff0c;分两个RSA一个用小写表示一个用大写表示&#xff0c;小写n用大写加密&#xff0c;大写的给出了P和Q>>16的提示。 from Crypto.Util.number import * from…

EMC学习笔记(十九)EMC常用元件简单介绍

EMC常用元件简单介绍 1.共模电感2.磁珠3.滤波电容器 1.共模电感 由于 EMC 所面临解决问题大多是共模干扰&#xff0c;因此共模电感也是我们常用的有力元件之一&#xff01;这里就给大家简单介绍一下共模电感的原理以及使用情况。 共模电感是一个以铁氧体为磁芯的共模干扰抑制…

C语言每日一题:3.错误的集合

题目链接&#xff1a;点击 思路一 1.1.排序遍历拿到我们重复的数值的同时去遍历数组一遍,求和重复的数字只加入一遍,和设置为sum1&#xff1b; 2.求没有消失的和&#xff0c;等差数列求和公式(1n)*n/2&#xff0c;定义为sum2&#xff1b; 3.sum2-sum1就是消失的数值。 这个方法…

【git】零基础学习git(持续更新中)

文章目录 前言git安装LinuxWindows git配置创建版本库将文件添加到版本库一次添加一个文件一次添加多个文件 查看git状态查看修改的差异查看历史记录当前版本 回退回退到上一个版本回退到某个版本如果关闭当前窗口如果关闭了当前窗口 工作区与版本库关系查看工作区和版本库里面…

记录一下trackformer的安装过程

项目地址 1、创建python环境&#xff0c;并激活 conda create -n TF python3.8 -y conda activate TF2、进入trackformer中&#xff0c;并且运行setup.py cd Desktop/MOT/trackformer/ python setup.py install3、下载pytorch pytorch官方安装法 # CUDA 11.1 pip install …

虚拟机ip地址总是改变的完美解决

在连接虚拟机进行操作时&#xff0c;第一次成功连接到虚拟机&#xff0c;但是关闭虚拟机后&#xff0c;第二天发现怎么都连接不上该虚拟机了&#xff0c;结果查询虚拟机的ip地址发现ip地址发生了改变&#xff0c;那么怎么才能让虚拟机的ip地址固定不变呢&#xff1f; 具体操作…