FPGA学习笔记(十二)IP核之FIFO的学习总结

news2025/4/29 5:52:27

系列文章目录

一、FPGA学习笔记(一)入门背景、软件及时钟约束

二、FPGA学习笔记(二)Verilog语法初步学习(语法篇1)

三、FPGA学习笔记(三) 流水灯入门FPGA设计流程

四、FPGA学习笔记(四)通过数码管学习顶层模块和例化的编写

五、FPGA学习笔记(五)Testbench(测试平台)文件编写进行Modelsim仿真

六、FPGA学习笔记(六)Modelsim单独仿真和Quartus联合仿真

七、FPGA学习笔记(七)verilog的深入学习之任务与函数(语法篇3)

八、FPGA学习笔记(八)同步/异步信号的打拍分析及处理

九、FPGA学习笔记(九)SPI学习总结及stm32的HAL库下SPI配置

十、FPGA学习笔记(十)IP核之PLL锁相环的学习总结

十一、FPGA学习笔记(十一)IP核之RAM的学习总结

文章目录

  • 系列文章目录
  • FIFO简介
  • FIFO的程序设计
    • FIFO IP核创建
    • FIFO读程序
    • FIFO写程序
    • FIFO顶层模块
    • modelsim的FIFO仿真文件
    • 结果


参考正点原子开拓者FPGA开发指南

FIFO简介

FIFO( First In First Out):先进先出
常用在数据缓存或者跨时钟域的信号传递(高速异步数据的交互)

类比前面学习的ROM,只是没有地址线,采取顺序写入数据,顺序读出数据的方式。

  • FIFO分类:
    SCFIFO(single clock FIFO):单时钟FIFO。
    DCFIFO(double clock FIFO):双时钟FIFO。
    DCFIFO_MIXED_WIDTHS:混合宽度双时钟FIFO。
    同步FIFO:读时钟和写时钟的频率相同(单时钟)
    异步FIFO:读时钟和写时钟的频率不同(双时钟)。
    在这里插入图片描述
    双时钟将clock分为wrclk和rdclk

  • 常见FIFO参数:
    FIFO宽度(N):一次读写操作的N位数据
    FIFO深度(M):存储M个宽度为N位的数据
    将空标志:almost_empty(FIFO即将被清空)
    空标志:empty。FIFO 已空时送出的一个信号,阻止读操作继续从 FIFO中读出数据而造成无效数据的读出。
    将满标志:almost_full。FIFO 即将被写满。
    满标志:full。FIFO 已满或将要写满时的一个信号,阻止写操作继续向 FIFO 中写数据而造成溢出。
    读时钟:读 FIFO 时所遵循的时钟,在每个时钟的上升沿触发。
    写时钟:写 FIFO 时所遵循的时钟,在每个时钟的上升沿触发。
    wrreq/rdreq:请求(request)

  • 应用实例:
    跨时钟域:存储器A和B的时钟不一样,传递数据的时候可以用FIFO作为两者的衔接。
    带宽不同步:两个存储器的数据宽度不一样(比如一个8位,一个12位),传递数据的时候可以用FIFO作为两者的衔接。

FIFO的程序设计

需要四个模块:FIFO模块、写测试模块、读测试模块、顶层模块

FIFO IP核创建

quartus18下(quartus13还是在那个MegaWizard Plug In Manager里面)
在这里插入图片描述
指定好路径和IP核的名字:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
上图选择我们想要的优化:

  • Lowest latency but requires synchronized clocks(最低延迟,但要求同步时钟): 此选项使用一个同步阶段,没有亚稳态保护,适用于同步时钟。它是最小尺寸,提供良好的 Fmax 。
  • TYPE_Cmal setting for unsynchronized clocks (异步时钟时的最小设置):这个选项使用两个同步阶段,具有良好的亚稳态保护。它是中等尺寸,提供良好的 Fmax 。
  • Best metastability protection, best fmax and unsynchronized clocks
    (异步时钟时最好的亚稳态保护,最好的 Fmax ,不同步):这个选项使用三个或更多的同步阶段,具有最好的亚稳态保护。它是最大尺寸,给出了最好的 Fmax 。

在这里插入图片描述
在这里插入图片描述
正常模式: 将 rdreq 看做读请求,在该端口信号为高电平进行读操作。(一般选正常模式)

前显模式: 将 rdreq 看做读确认,rdreq 信号置为高电平时,输出 FIFO 中的下一个数据字(如果存在)。(将会使设计性能下降)(应该意思就是超前读了一个数据字)
在这里插入图片描述
是否禁止上溢检测和下溢检测的保护电路。

上溢检测保护电路主要是用于在FIFO 满时,禁止 wrreq 端口
下溢检测保护电路主要是用于在 FIFO 空时,禁止 rdreq 端口

“Implement FIFO storage with logic cells only, even if the device contains memory blocks ?(选项使用逻辑单元实现 FIFO 存储器,即使器件拥有存储块)
选择使用存储块实现FIFO
在这里插入图片描述
仿真FIFO IP 核,需要用到“ altera_mf ”仿真库。

想要将此 FIFO IP 核用在其他的 EDA 工具上,可以通过选择“ Generate netlist ”来生成 IP_syn.v 文件,用于其他的 EDA 工具中。
在这里插入图片描述
FIFO_IP_inst.v选上后,可以打开,里面有直接例化好的(我感觉没啥用,选不选都无所谓)

FIFO读程序

//****************************************Copyright (c)***********************************//
// File name:           fifo_rd
// Last modified Date:  2021/4/7 9:30:00
// Last Version:        V1.1
// Descriptions:        FIFO读模块
// Created by:          正点原子
//****************************************************************************************//

module fifo_rd(
    input              clk,      //时钟信号
    input              rst_n,    //复位信号
    
    //fifo的读端口
    input              rd_full,  //读侧满信号
    input              rd_empty, //读侧空信号
    output             rd_req,   //读请求信号
    input   [7:0]      rd_data   //读出FIFO的数据
    );

//reg define
reg     rd_req_t;   

//*****************************************************
//**                    main code
//*****************************************************

//防止fifo读空后继续读出数据
assign  rd_req = rd_req_t & (~rd_empty);  

//rd_req_t信号赋值    
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        rd_req_t <= 1'b0;
    else if(rd_full)  
        rd_req_t <= 1'b1;
    else if(rd_empty)
        rd_req_t <= 1'b0;
end

endmodule 

FIFO写程序

//****************************************Copyright (c)***********************************//
// File name:           fifo_wr
// Last modified Date:  2021/4/7 9:30:00
// Last Version:        V1.1
// Descriptions:        FIFO写模块
// Created by:          正点原子
//****************************************************************************************//

module fifo_wr(
    input              clk,      //时钟信号
    input              rst_n,    //复位信号
                                 
    //fifo的写端口               
    input              wr_full,  //写侧满信号
    input              wr_empty, //写侧空信号
    output             wr_req,   //写请求信号
    output  reg [7:0]  wr_data   //写入FIFO的数据
    );

//reg define    
reg     wr_req_t;   

//*****************************************************
//**                    main code
//*****************************************************

//防止fifo写满后继续写入数据
assign  wr_req = wr_req_t & (~wr_full);  

//wr_req_t信号赋值    
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        wr_req_t <= 1'b0;
    else if(wr_empty)  
        wr_req_t <= 1'b1;
    else if(wr_full)
        wr_req_t <= 1'b0;
end

//写数据信号赋值 
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        wr_data <= 8'd0;
    else if(wr_req)
        wr_data <= wr_data + 1'b1;
    else
        wr_data <= 8'd0;
end

endmodule    
    

FIFO顶层模块

//****************************************Copyright (c)***********************************//
//Copyright(C) 正点原子 2018-2028
// File name:           ip_fifo
// Last modified Date:  2021/4/7 9:30:00
// Last Version:        V1.1
// Descriptions:        IP核之FIFO实验
//****************************************************************************************//

module ip_fifo(
    input    sys_clk    ,      //时钟信号
    input    sys_rst_n         //复位信号
    );

//wire define
wire                clk_50m ;  //50Mhz时钟  
wire                clk_25m ;  //25Mhz时钟   
wire                locked  ;  //时钟稳定信号

wire                rst_n   ;  //复位信号   

wire     [7:0]      rd_usedw;  //读侧FIFO中的数据量
wire     [7:0]      wr_usedw;  //写侧FIFO中的数据量

wire                wr_full ;  //写侧满信号
wire                wr_empty;  //写侧空信号
wire                wr_req  ;  //写请求信号
wire     [7:0]      wr_data ;  //写入FIFO的数据

wire                rd_full ;  //读侧满信号
wire                rd_empty;  //读侧空信号
wire                rd_req  ;  //读请求信号
wire     [7:0]      rd_data ;  //读出FIFO的数据

//*****************************************************
//**                    main code
//*****************************************************

//待时钟输出稳定后,再拉高rst_n信号
assign rst_n = sys_rst_n & locked;

//例化锁相环模块    
pll_clk	u_pll_clk (
    .areset (~sys_rst_n ),
    .inclk0 (sys_clk ),
    .c0     (clk_50m ),
    .c1     (clk_25m ),
    .locked (locked )
    );    

//例化FIFO写模块
fifo_wr u_fifo_wr(
    .clk        (clk_50m),  
    .rst_n      (rst_n),

    .wr_full    (wr_full ),
    .wr_empty   (wr_empty),
    .wr_req     (wr_req  ),
    .wr_data    (wr_data )
    );

//例化异步FIFO模块    
async_fifo	u_async_fifo (
    .aclr       (~rst_n ),
    .data       (wr_data ),
    .rdclk      (clk_25m ),
    .rdreq      (rd_req ),
    .wrclk      (clk_50m ),
    .wrreq      (wr_req ),
    .q          (rd_data ),
    .rdempty    (rd_empty ),
    .rdfull     (rd_full ),
    .rdusedw    (rd_usedw ),
    .wrempty    (wr_empty ),
    .wrfull     (wr_full ),
    .wrusedw    (wr_usedw )
    );

//例化FIFO读模块
fifo_rd u_fifo_rd(
    .clk         (clk_25m),
    .rst_n       (rst_n),

    .rd_full     (rd_full ),
    .rd_empty    (rd_empty),
    .rd_req      (rd_req  ),
    .rd_data     (rd_data )
    );
  
endmodule    

modelsim的FIFO仿真文件

`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;
end

always #(T/2) sys_clk = ~sys_clk; 

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

这个仿真库也要添加进去,在quartus的安装路径下:quartus/eda/sim_lib/altera_mf .v
在这里插入图片描述

结果

代码结构是当FIFO写满使开始读取,当全部读完的时候再开始写。

同一个时钟的读切换写:
在这里插入图片描述
FIFO数据全部读完的时候,读空信号 rdempty 先拉高,过两个时钟周期后写空信号 wrempty 才拉高,这是由FIFO 内部结构决定的,并且在写请求信号 wrempty 拉低后的第 3 个时钟周期 读空信号 rdempty 才拉低。

上面是读时钟和写时钟使用的是一个clock,下图是写始终50Mhz,读时钟25Mhz:
在这里插入图片描述
FIFO数据全部读完的时候,读空信号 rdempty 先拉高,过两个时钟周期后写空信号 wrempty 才拉高,这是由FIFO 内部结构决定的,并且在wrempty 拉低后的第 4 个时钟周期 读空信号 rdempty 才拉低。

同一个时钟的写切换读:
在这里插入图片描述
在写满信号 wrfull 拉高 2 个时钟周期后,读满信号 rdfull 才有效,并且rdfull拉低后的第3个时钟周期写满信号 wrfull 才拉低。

上面是读时钟和写时钟使用的是一个clock,下图是写始终50Mhz,读时钟25Mhz
在这里插入图片描述
因为时钟不一样,在写满信号 wrfull 拉高 2 .5个时钟(读时钟)周期后,读满信号 rdfull 才有效,并且在rdfull拉低后的第3个时钟(写时钟)周期写满信号 wrfull 才拉低。

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

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

相关文章

机器人/人工智能/就业形势2023

机器人/人工智能/就业形势2022https://blog.csdn.net/ZhangRelay/article/details/124441772机器人人工智能课程需求和就业趋势-2022-https://blog.csdn.net/ZhangRelay/article/details/127087308如上已成往事。2023年如何呢&#xff1f;之前文章都过于简洁&#xff0c;很多朋…

浅谈 MySQL 的 Undo log 日志

undo log 存储在类型为 FIL_PAGE_UNDO_LOG 页中。 可以从系统表空间中分配空间&#xff0c;也可以从 undo tablespace 中分配空间。 FIL_PAGE_UNDO_LOG 类型页主要分为四部分&#xff1a; File Header&#xff0c;所有页都有的结构Undo Page Header TRX_UNDO_PAGE_TYPE&#x…

十一、docker相关问题解决方案

&#x1f33b;&#x1f33b;一、创建tomcat失败报348 问题二、端口监听问题&#xff0c;没安装命令三、非正常关闭电脑导致虚拟机无法启动一、创建tomcat失败报348 问题 创建失败问题&#xff1a; docker: Error response from daemon: OCI runtime create failed: container…

通用vue组件化搜索组件页面

一、组件化封装 1.首先创建一个form文件夹&#xff0c;将搜索框组件的内容全部写在这个里面&#xff0c;然后再在需要的页面直接引入相应的组件即可 2.首先先在goods.vue文件里面写对应的文本数组formItems&#xff0c;将所定义的类型IFormItem引用进去&#xff0c;这个里面写…

coresight(五) rom table

五、 rom table 在一个soc中&#xff0c;有多个coresight组件&#xff0c;但是软件怎么去识别这些coresight组件&#xff0c;去获取这些coresight组件的信息了&#xff1f;这个时候&#xff0c;就需要靠coresight组件中&#xff0c;一个重要的组件&#xff0c;这个组件就是rom …

CMD有哪些有趣的命令?

程序员宝藏库&#xff1a;https://gitee.com/sharetech_lee/CS-Books-Store 用惯Linux和macOS的同学都会对各种各样强大的命令印象深刻&#xff0c;然而再转向Windows时就开始不屑一顾&#xff0c;认为Windows上没有Linux上那些超级便捷好用的命令。 其实&#xff0c;Windows下…

ROS安装及rosdep update问题解决

ROS安装&#xff1a; 参考链接&#xff1a;详细介绍如何在ubuntu20.04中安装ROS系统&#xff0c;以及安装过程中出现的常见错误的解决方法&#xff0c;填坑&#xff01;&#xff01;&#xff01;_慕羽★的博客-CSDN博客_ubuntu20.04安装ros rosdep update问题解决&#xff1a…

Linux Shell 脚本编程基础

Shell是一个命令解释器,它解释由用户输入的命令并且把它们送到内核,不仅如此,Shell有自己的编程语言用于对命令的编辑,它允许用户编写由shell命令组成的程序.Shel编程语言具有普通编程语言的很多特点,比如它也有循环结构和分支控制结构等,用这种编程语言编写的Shell程序与其他应…

Selenium用法详解【窗口表单切换】【JAVA爬虫】

简介本文主要讲解java 代码利用Selenium如何实现控制浏览器进行窗口切换和页面内的不同表单之间的切换操作。切换操作窗口切换在 selenium 操作页面的时候&#xff0c;可能会因为点击某个链接而跳转到一个新的页面&#xff08;打开了一个新标签页&#xff09;&#xff0c;这时候…

电子词典流程图

简易流程&#xff1a; 详细介绍 服务端&#xff08;TCP并发&#xff09; 一.分支线程负责处理客户端发送的信息 1.登陆与注册信息 登陆&#xff08;l&#xff09;;注册&#xff08;e&#xff09; (1)登陆根据接收的用户名&#xff0c;密码在用户注册表中遍历是否符合&#xff…

ORB-SLAM2 --- ORBmatcher::SearchBySim3函数

目录 1.函数作用 2.函数流程 3.函数解析 3.1 准备工作&#xff1a;内参&#xff0c;计算Sim3的逆 3.2 记录已经匹配的特征点 3.3 通过Sim变换&#xff0c;寻找 pKF1 中特征点和 pKF2 中的新的匹配 3.4 通过Sim变换&#xff0c;寻找 pKF2 中特征点和 pKF1 中的新的匹…

Jenkins远程SSH部署SpringBoot项目

1.前置环境 前置环境配置&#xff1a;jdk、maven、git 2.在Jenkins配置git凭据 请查看往期文章&#xff1a; https://blog.csdn.net/RookiexiaoMu_a/article/details/122655272?spm1001.2014.3001.5501 3.安装Publish over SSH插件 4.配置SSH Servers 安装完Publish over…

C++蓝桥杯贪心算法

目录 &#x1f33c;一&#xff0c;1812: [NewOJ Week 5] 排列变换 &#x1f33c;二&#xff0c;1827: [NewOJ Week 8] 升降数字 &#x1f33c;三&#xff0c;剑指offer 10-II 青蛙跳台阶问题 &#x1f33c;四&#xff0c;P1223 排队接水 &#x1f33c;五&#xff0c;P5650…

npm常用命令

目录1. 构建项目2. 安装包3. 查看安装目录4. 卸载包5. 更新包6. 查看已安装的包7. 使用国内npm镜像源8. 使用yarn1. 构建项目 npm init # 全部使用默认配置 npm init --yes2. 安装包 # 全局安装 npm install 包名 -g # 本地安装 npm install 包名 # 一次安装多个 npm install…

ROS移动机器人开发——硬件引脚

我们使用的32开发板为冰达机器人官方的开发板&#xff0c;类型为STM32RCT6。32章节的目的为&#xff0c;将官方所给源码转化为 官方标准库函数来进行使用 —————————————— 需求提出&#xff1a; 电源 1. 3.3V-200ma供电 2. 输入 9-12.6V 5A 控制&#xff1a…

(十三)JAVA基础语法

目录 前言: 一、包 二、权限修饰符 三、final关键字 四、常量 五、枚举 六、抽象类 七、抽象类:模板方法模式 八、接口 前言: ①包: 在编写Java程序时&#xff0c;随着程序架构越来越大&#xff0c;类的个数也越来越多&#xff0c;这时就会发现管理程序中维护类名称也…

利用OpenCV的函数calcHist()计算出图像的直方图数据后绘制图像的直方图

利用OpenCV的函数calcHist()计算出图像的直方图数据后绘制图像的直方图 在上一篇博文 https://www.hhai.cc/thread-200-1-1.html 中已经对OpenCV的直方图计算函数calcHist()进行了详细介绍。 这篇博文介绍如何用直方图数据绘制直方图。 OpenCV是没有统计图绘制的相关函数的&a…

Verilog语法笔记(夏宇闻第三版)-循环语句

目录 forever语句: repeat语句: while语句: for语句: 在Verilog HDL中存在着四种类型的循环语句&#xff0c;用来控制执行语句的执行次数。 1) forever 连续的执行语句。 2) repeat 连续执行一条语句 n 次。 3) while 执行一条语句直到某个条件不满足。如果一开始条件即…

数据异动分析方法论

注&#xff1a;本文首发于公众号&#xff1a;书剑双修&#xff0c;欢迎关注。 数据异动分析是一类典型的数据分析问题&#xff0c;也是分析师日常工作中会频繁遇到的问题。很多的数据分析面试过程中&#xff0c;都会对这个方面进行考察&#xff0c;以此来判断分析师思考问题的全…

使用IIS服务器搭建一个网站

1、什么是IISIIS全称为Internet Information Services&#xff0c;是一种Web服务组件。通过在自己电脑上安装好IIS服务&#xff0c;就可以把你自己的电脑当作一个网站的服务器。2、搭建一个IIS2.1、开启windows的IIS服务Step1、控制面板——程序——程序和功能——启用或关闭wi…