系列文章目录

一、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) beginif(!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;
endendmodule

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) beginif(!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) beginif(!rst_n)wr_data <= 8'd0;else if(wr_req)wr_data <= wr_data + 1'b1;elsewr_data <= 8'd0;
endendmodule    

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 beginsys_clk = 1'b0;sys_rst_n = 1'b0;#(T+1)sys_rst_n = 1'b1;
endalways #(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 才拉低。

通常情况下,向FIFO 中写数据时,当写使能(wr_req)为高,下一个写时钟的上升沿,数据就可以写入FIFO。但是需要特别注意的是,从FIFO 中读取数据时,当读使能为高,读时钟(rd_req)的第二个周期之后才有有效数据输出。

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

  1. 吴恩达《机器学习》学习笔记十二——机器学习系统

    吴恩达<机器学习>学习笔记十二--机器学习系统 一.设计机器学习系统的思想 1.快速实现+绘制学习曲线--寻找重点优化的方向 2.误差分析 3.数值估计 二.偏斜类问题(类别不均衡) 三. ...

  2. ROS学习笔记十二:使用roswtf

    ROS学习笔记十二:使用roswtf 在使用ROS过程中,roswtf工具可以为我们提供ROS系统是否正常工作的检查作用. 注意:在进行下列操作之前,请确保roscore没有运行. 检查ROS是否安装 ...

  3. Python语言入门这一篇就够了-学习笔记(十二万字)

    Python语言入门这一篇就够了-学习笔记(十二万字) 友情提示:先关注收藏,再查看,12万字保姆级 Python语言从入门到精通教程. 文章目录 Python语言入门这一篇就够了-学习笔记(十二万字 ...

  4. Polyworks脚本开发学习笔记(十二)-输出和读取文本文件

    Polyworks脚本开发学习笔记(十二)-输出和读取文本文件 Polyworks作为一个测量工具,将测量的数据方便的导出到文本文件则是一项必须的功能.在DATA_FILE这个命令下提供了很多子命令用 ...

  5. OpenCV学习笔记(十二)——图像分割与提取

    在图像处理的过程中,经常需要从图像中将前景对象作为目标图像分割或者提取出来.例如,在视频监控中,观测到的是固定背景下的视频内容,而我们对背景本身并无兴趣,感兴趣的是背景中出现的车辆.行人或者其他对象. ...

  6. PCL学习笔记(二):PCL官方教程学习

    PCL学习笔记(二):PCL官方教程学习 PCD文件制作 Features 表面法线提取 Keypoints 提取NARF关键点 KdTree Range Image How to create a ...

  7. 【现代机器人学】学习笔记十二:轮式移动机器人

    目录 轮式机器人类型 全向轮式机器人 建模 单个全向轮是怎么运动的 多个全向轮是如何带动底盘运动的 运动规划和反馈控制 非完整约束轮式移动机器人 建模 独轮车 差速驱动机器人 车型机器人 非完整移动机 ...

  8. 【theano-windows】学习笔记十二——卷积神经网络

    前言 按照进度, 学习theano中的卷积操作 国际惯例, 来一波参考网址 Convolutional Neural Networks (LeNet) 卷积神经网络如何应用在彩色图像上? 卷积小知识 ...

  9. (C/C++学习笔记) 十二. 指针

    十二. 指针 ● 基本概念 变量的地址就是指针,存放指针的变量就是指针变量(因而又叫作地址变量 address variable); 这个地址编号本身就是一个无符号的整数,在32位系统下为4字节(8位 ...

最新文章

  1. 在阿里当PM都需要做什么?
  2. 独家 | 手把手教你用R语言做回归后的残差分析(附代码)
  3. 说一说MVC的CompressActionFilterAttrubute(五)
  4. html如何超链接到servlet
  5. 计算机视觉的基石-滤波
  6. 信号传递的时机与顺序
  7. html运用以及工具
  8. 王垠:怎样尊重一个程序员?
  9. java panel frame_Java 版 (精华区)--Frame和Panel的区别【转载】
  10. jupyter notebook 设置默认目录
  11. 基于物理渲染的基础理论
  12. linux下添加新硬盘的方法
  13. php文本框限制字节,js限制文本框输入长度两种限制方式(长度、字节数)_基础知识...
  14. LeetCode简单题目(#53 #58 #66 #67 #69 #70 #83 #88)-8道
  15. (转载)python-hwdata
  16. web前端面试题(必背面试题)
  17. 求边界点 -- Python
  18. 浙江学计算机怎么选课,新高考下浙江孩子应怎么选课(专业人士建议)
  19. c语言拍皮球100,童话故事——拍皮球
  20. xgboost 怎么读_你真的会读书了吗?五本书让你会读书,读好书,好读书!

热门文章

  1. x265代码阅读:码率控制(一)
  2. windows编写linux脚本,适用于 Windows 和 Linux 的脚本编写工具包
  3. linux 对函数的未定义的引用,对libncurses中函数的未定义引用
  4. Appium: Could not proxy command to the remote server. Original error: socket hang up
  5. 5, 10,15,20-四(4-甲氧羰基苯基)卟啉(TPPCOOMe)/5-(对亮氨酸丁氧苯基 )-10 ,15 ,20-三苯基卟啉锌配合物(Zn[Leu-TPP]齐岳定制
  6. 数字字符串位数不足左边补零
  7. JAVA 日期推算---算法
  8. 停不下来!程序员在GitHub上开源了一个自制表情包项目
  9. 小程序进阶-emoji表情
  10. 国际短信平台短信路由搭建后台软件定制-移讯云短信系统