FPGA原理与结构——FIFO IP核的使用与测试

news2025/1/23 13:54:42

一、前言

        本文介绍FIFO Generator v13.2 IP核的具体使用与例化,在学习一个IP核的使用之前,首先需要对于IP核的具体参数和原理有一个基本的了解,具体可以参考:

FPGA原理与结构——FIFO IP核原理学习https://blog.csdn.net/apple_53311083/article/details/132378996?spm=1001.2014.3001.5501

二、FIFO IP核定制

1、FIFO IP核

step1 打开vivado工程,点击左侧栏中的IP Catalog

c1987bb2bcf249be8d0ca5f847744a0c.jpeg

step2 在搜索栏搜索FIFO,找到FIFO Generator核

99ad759bbe6a4661b465b48f57064dc5.jpeg

2、IP核定制 

step3 Basic 界面定制

f0f81c6c86c54f9ca5078d8b1ee0dfbf.jpeg

①Component Name :自定义FIFO的名称 

②Interface Type :接口类型,我们知道FIFO可以支持Native接口和AXI接口,其中AXI接口包括AXI3,AXI4,AXI Stream类型,这里我们选择Native。

    Fifo Implementation :用于选择我们想要实现的是同步 FIFO 还是异步 FIFO 以及使用哪
种资源实现 FIFO,这里我们选择“Independent Clocks Block RAM”,即使用块 RAM 来实现的异步 FIFO。
 
    Synchronization Stages :同步级数,这里保持默认为2,如果有更高的频率要求,可以提升。
 
③FIFO Implementation Options :不同资源类型实现FIFO所能支持的功能列表,大家根据表格自行观察连接即可。


step4 Native Ports 界面设计

5cb4107a8efc498ead60d87e7a8d816a.jpeg

①Read Mode :用于设置读 FIFO 时的读模式,可选的有标准模式和前显模式,一般没有特殊需求的前提下,我们推荐标准模式。这里我们选择默认的“Standard FIFO”。
 
②Data Port Parameters :用于设置读写端口的数据总线的宽度以及 FIFO 的深度,写宽度“Write Width”我们设置为 8 位,写深度“Write Depth”我们设置为 256,注意此时 FIFO IP 核所能实现的实际深度却是 255;虽然读宽度“Read Width”能够设置成和 写宽度不一样的位宽,且此时读深度“Read Depth”会根据上面三个参数被动地自动设置成相应的值;但是我们还是将读宽度“Read Width”设置成和写宽度“Write Width”一样的位宽,这也是在实际应用中最常用的情况。
 
③ ECC模式:在本次的FIFO测试中不使用
 
④ Initiazation :用于设置FIFO的复位等相关内容,默认同步复位,安全复位,full在复位时保持高电平有效。
 

step5 Status Flags 界面定制

a0527277fa314254b78eb21c51ed18b7.jpeg

“Status Flags”界面,这个界面用于设置用户自定义接口或者用于设定专用的输入口。
 
① Optional Flags : 可选信号,在这里可以勾选将空和将满信号,这里我们都勾上。
 
② Handshaking Options :握手信号,这里我们使用不到,就不勾选了。
 
③ Programmable Flags : 可编程阈值,这里我们也不做选择。
 

step6 Data Counts

3abd803c1c1948d9906d08033aab49fe.jpeg

        Data Counts界面用于设置 FIFO 内数据计数的输出信号,此信号表示当前在 FIFO 内存在多少个有效数据。为了更加方便地观察读/写过程,这里我们把读/写端口的数据计数都打开,且计数值总线的位宽设置为满位宽,即 8 位。
 

step7 Summary 5615d074617449bcaa49ddc8e40c1ce3.jpeg

         IP核定制的最后一面永远是Summary界面,帮助我们进行一个回顾和检查。

三、IP核测试

        首先设计了写FIFO模块和读FIFO模块:

3.1 写fifo模块

//-------------------------------------<写fifo模块>--------------------------------
module fifo_wr(
//-------------------<信号输入>-----------------------
    input clk,               //系统时钟
    input rst,                   //复位信号
    input almost_empty,          //FIFO将空信号
    input almost_full ,          //FIFO将满信号

//-------------------<信号输出>----------------------- 
    output reg fifo_wr_en,         //FIFO写使能
    output reg [7:0] fifo_wr_data  //写入FIFO的数据
);

//reg define
reg  [1:0]  state            ;  //动作状态
reg  		almost_empty_d0  ;  //almost_empty 延迟一拍
reg  		almost_empty_syn ;  //almost_empty 延迟两拍
reg  [3:0]  dly_cnt          ;  //延迟计数器

//因为 almost_empty 信号是属于FIFO读时钟域的
//所以要将其同步到写时钟域中
always@( posedge clk ) begin
	if( rst ) begin
		almost_empty_d0  <= 1'b0 ;
		almost_empty_syn <= 1'b0 ;
	end
	else begin
		almost_empty_d0  <= almost_empty ;
		almost_empty_syn <= almost_empty_d0 ;
	end
end

//向FIFO中写入数据
always @(posedge clk ) begin
    if(rst) begin
        fifo_wr_en   <= 1'b0;
        fifo_wr_data <= 8'd0;
        state        <= 2'd0;
		dly_cnt      <= 4'd0;
    end
    else begin
        case(state)
            2'd0: begin 
                if(almost_empty_syn) begin  //如果检测到FIFO将被读空
                    state <= 2'd1;          //就进入延时状态
                end 
                else
                    state <= state;
            end 
			2'd1: begin
                if(dly_cnt == 4'd10) begin  //延时10拍
											//原因是FIFO IP核内部状态信号的更新存在延时
											//延迟10拍以等待状态信号更新完毕                   
                    dly_cnt    <= 4'd0;
					state      <= 2'd2;     //开始写操作
					fifo_wr_en <= 1'b1;     //打开写使能
				end
				else
					dly_cnt <= dly_cnt + 4'd1;
            end             
			2'd2: begin
                if(almost_full) begin      //等待FIFO将被写满
                    fifo_wr_en   <= 1'b0;  //关闭写使能
                    fifo_wr_data <= 8'd0;
                    state        <= 2'd0;  //回到第一个状态
                end
                else begin                 //如果FIFO没有被写满
                    fifo_wr_en   <= 1'b1;  //则持续打开写使能
                    fifo_wr_data <= fifo_wr_data + 1'd1;  //且写数据值持续累加
                end
            end 
			default : state <= 2'd0;
        endcase
    end
end

endmodule

3.2 读FIFO模块

//-------------------------------------<读fifo模块>--------------------------------
module fifo_rd(
//-------------------<信号输入>-----------------------
    input               clk ,        // 时钟信号
    input               rst ,      // 复位信号
    input        [7:0]  fifo_dout ,  // 从FIFO读出的数据
    input               almost_full ,// FIFO将满信号
    input               almost_empty,// FIFO将空信号

//-------------------<信号输出>----------------------- 
    output  reg         fifo_rd_en   // FIFO读使能
);

//reg define
reg  [1:0]  state           ;  // 动作状态
reg         almost_full_d0  ;  // fifo_full 延迟一拍
reg  		almost_full_syn ;  // fifo_full 延迟两拍
reg  [3:0]  dly_cnt         ;  // 延迟计数器

//因为 fifo_full 信号是属于FIFO写时钟域的
//所以要将其同步到读时钟域中
always@( posedge clk ) begin
	if( rst ) begin
		almost_full_d0  <= 1'b0 ;
		almost_full_syn <= 1'b0 ;
	end
	else begin
		almost_full_d0  <= almost_full ;
		almost_full_syn <= almost_full_d0 ;
	end
end

//读出FIFO的数据
always @(posedge clk ) begin
    if(rst) begin
        fifo_rd_en <= 1'b0;
		state      <= 2'd0;
		dly_cnt    <= 4'd0;
    end
    else begin
        case(state)
            2'd0: begin
                if(almost_full_syn)      //如果检测到FIFO将被写满
                    state <= 2'd1;       //就进入延时状态
                else
                    state <= state;
            end 
			2'd1: begin
                if(dly_cnt == 4'd10) begin  //延时10拍
											//原因是FIFO IP核内部状态信号的更新存在延时
											//延迟10拍以等待状态信号更新完毕
                    dly_cnt <= 4'd0;
					state   <= 2'd2;        //开始读操作
				end
				else
					dly_cnt <= dly_cnt + 4'd1;
            end
		    2'd2: begin
                if(almost_empty) begin     //等待FIFO将被读空
                    fifo_rd_en <= 1'b0;    //关闭读使能
                    state      <= 2'd0;    //回到第一个状态
                end
                else                       //如果FIFO没有被读空
                    fifo_rd_en <= 1'b1;    //则持续打开读使能
            end 
			default : state <= 2'd0;
        endcase
    end
end

endmodule

3.3 顶层模块

module fifo_top(
//-------------------<信号输入>-----------------------
    input sys_clk,               //系统时钟
    input rst                    //复位信号
);

    wire [7:0] din;             //fifo的输入数据(写入的数据)
    wire wr_en;                 //写使能
    wire rd_en;                 //读使能
    wire [7:0] dout;            //fifo的输出数据(读出的数据)
    wire full;                  //fifo满信号
    wire almost_full;           //fifo将满标志
    wire empty;                 //fifo空标志
    wire almost_empty;          //fifo将空标志
    wire [7:0]rd_data_count;    //fifo写时钟域的数据计数
    wire [7:0]wr_data_count;    //fifo读时钟域的数据计数
    wire wr_rst_busy;
    wire rd_data_count;              
    
//-------------------<IP核例化>-----------------------
fifo_exp1 fifo1 (
  .rst            (rst),                       // input wire rst
  .wr_clk         (sys_clk),                   // input wire wr_clk
  .rd_clk         (sys_clk),                   // input wire rd_clk
  .din            (din),                       // input wire [7 : 0] din
  .wr_en          (wr_en),                     // input wire wr_en
  .rd_en          (rd_en),                     // input wire rd_en
  .dout           (dout),                      // output wire [7 : 0] dout
  .full           (full),                      // output wire full
  .almost_full    (almost_full),               // output wire almost_full
  .empty          (empty),                     // output wire empty
  .almost_empty   (almost_empty),              // output wire almost_empty
  .rd_data_count  (rd_data_count),             // output wire [7 : 0] rd_data_count
  .wr_data_count  (wr_data_count),             // output wire [7 : 0] wr_data_count
  .wr_rst_busy    (wr_rst_busy),               // output wire wr_rst_busy
  .rd_rst_busy    (rd_rst_busy)                // output wire rd_rst_busy
);

//例化写FIFO模块
fifo_wr  fifo_wr_u1(
    .clk            ( sys_clk    ),   // 写时钟
    .rst            ( rst  ),   // 复位信号

    .fifo_wr_en     ( wr_en )  , // fifo写请求
    .fifo_wr_data   ( din    ) , // 写入FIFO的数据
    .almost_empty   ( almost_empty ), // fifo空信号
    .almost_full    ( almost_full  )  // fifo满信号
);

//例化读FIFO模块
fifo_rd  fifo_rd_u1(
    .clk          ( sys_clk    ),      // 读时钟
    .rst          ( rst  ),      // 复位信号

    .fifo_rd_en   ( rd_en ),      // fifo读请求
    .fifo_dout    ( dout  ),      // 从FIFO输出的数据
    .almost_empty ( almost_empty ),    // fifo空信号
    .almost_full  ( almost_full  )     // fifo满信号
);

endmodule

3.4 测试模块

`timescale 1ns / 1ps

module tb_ip_fifo( );
    // Inputs
    reg sys_clk;
    reg rst;
    
    // Instantiate the Unit Under Test (UUT)
    fifo_top  tb1_fifo_top (
        .sys_clk         (sys_clk), 
        .rst             (rst)
    );
    
    //Genarate the clk
    parameter PERIOD = 20;

    always begin
        sys_clk = 1'b0;
        #(PERIOD/2) sys_clk = 1'b1;
        #(PERIOD/2);
    end   
   
    initial begin
        // Initialize Inputs
        rst = 1;
        // Wait 100 ns for global reset to finish
        #100  ;
        rst = 0;
        // Add stimulus here
        
    end

endmodule

3.4 测试结果

4e6a307bdfe14cad9d529680c41836ab.jpeg

        通过看到FIFO如我们预期的写入和读出数据,读出的数据满足先入先出的原则。

四、总结 

        本文总结了FIFO IP核的使用方法,给出了各个配置参数的具体含义及配置方式,并对相关的设计进行了测试。

 

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

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

相关文章

GEE14:提取每年的GPP最大值

获取GPP最大值 1. 数据介绍2. JavaScript代码 最近学习了关于获取每年GPP最大值的DOY&#xff08;day of year&#xff09;的方法&#xff1a; 1. 数据介绍 MOD17A2H v006&#xff1a; The MOD17A2H Version 6 Gross Primary Productivity (GPP) product is a cumulative 8-d…

soundtouch库的编译与使用

源码下载 https://gitlab.com/soundtouch/soundtouch/-/archive/2.1.2/soundtouch-2.1.2.tar.bz2 SDK配置 使用vs逐个打开source下指定的三个项目文件&#xff0c;修改SDK&#xff0c;因为可能库中使用的是8.0&#xff0c;你使用的10.0 编译 打开vs&#xff0c;打开终端&am…

图像处理简介

目录 基本术语 1 .图像(image) 1.1 像素(Pixel) 1.2 颜色深度&#xff08;Color Depth&#xff09; 1.3 分辨率&#xff08;Resolution&#xff09; 1.4 像素宽高比&#xff08;Pixel Aspect Ratio&#xff09; 1.5 帧率(FPS) 1.6 码率&#xff08;BR&#xff09; 1. …

基于Stable Diffusion的AIGC服饰穿搭实践

本文主要介绍了基于Stable Diffusion技术的虚拟穿搭试衣的研究探索工作。文章展示了使用LoRA、ControlNet、Inpainting、SAM等工具的方法和处理流程&#xff0c;并陈述了部分目前的实践结果。通过阅读这篇文章&#xff0c;读者可以了解到如何运用Stable Diffusion进行实际操作&…

ScreenToGif-动图制作软件实用操作

ScreenToGif官网&#xff1a;ScreenToGif ⭕第一步&#xff1a;启动页面 ⭕第二步&#xff1a;选项 &#x1f95d;录像机-捕获频率选择手动-播放延迟1000ms(可以任意) ⭕第三步&#xff1a;录像机开始录屏 &#x1f95d;我们调整录屏的大小后&#xff0c;打开画图&#xff0c…

HK1 RBOX X4,Vontar X4,S905 X4 刷 ATV

准备工作 需要HK1 RBOX X4一个&#xff08;内存版本不限 通刷&#xff09;&#xff0c;机顶盒电源&#xff0c;USB双公线一条&#xff08;可以使用两个usb数据线剪开后相同颜色对接使用&#xff0c;最好使用电烙铁焊接一下更稳定&#xff09;&#xff0c;安装 INTEL CPU 运行 w…

Empowering Long-tail Item Recommendation through Cross Decoupling Network (CDN)

Empowering Long-tail Item Recommendation through Cross Decoupling Network (CDN) 来源&#xff1a; KDD’2023Google Research 文章目录 Empowering Long-tail Item Recommendation through Cross Decoupling Network (CDN)长尾问题分析CDNItem Memorization and General…

【算法】leetcode 105 从前序与中序遍历序列构造二叉树

题目 输入某二叉树的前序遍历和中序遍历的结果&#xff0c;请构建该二叉树并返回其根节点。 假设输入的前序遍历和中序遍历的结果中都不含重复的数字。 示例 1: Input: preorder [3,9,20,15,7], inorder [9,3,15,20,7] Output: [3,9,20,null,null,15,7]示例 2: Input: pr…

可控生成之GLIGEN原理

🤗关注公众号 funNLPer 快乐白嫖🤗 论文:GLIGEN: Open-Set Grounded Text-to-Image Generation 代码:gligen/GLIGEN 项目地址:GLIGEN demo地址:gligen demo 文章目录 1. 动机2. 模型结构及原理2.1 输入处理2.1.1 Caption Tokens2.1.2 Grounding Tokens2.2 Gated Sel…

应急三维电子沙盘数字孪生系统

一、简介应急三维电子沙盘数字孪生系统是一种基于虚拟现实技术和数字孪生技术的应急管理工具。它通过将真实世界的地理环境与虚拟世界的模拟环境相结合&#xff0c;实现了对应急场景的模拟、分析和决策支持。该系统主要由三维电子沙盘和数字孪生模型两部分组成。三维电子沙盘是…

ROS-5.自定义topic消息格式

自定义topic消息格式 1. 定义消息1.1. 定义msg文件1.2. 在package.xml中添加功能包依赖1.3. 在CMakeList.txt添加编译选项1.4. 编译 2.定义发布者和订阅者2.1 定义发布者2.2. 定义订阅者2.3. 修改CMakeList.txt2.4 编译 3. 使用消息3.1 启动ros主程序3.2. 启动发布者3.3 启动订…

处理时延降低24倍,联通云粒数据引擎优化实践

*作者&#xff1a;郑扬勇&#xff0c;云粒星河数据中台产品负责人 云粒智慧科技有限公司成立于 2018 年 6 月&#xff0c;是中国联通集团混改以来成立的首家合资公司&#xff0c;是中国智慧城市数智化建设者。一直以来&#xff0c;云粒智慧以数字化、智能化、集约化产品为核心&…

[杂谈]-2023年实现M2M的技术有哪些?

2023年实现M2M的技术有哪些&#xff1f; 文章目录 2023年实现M2M的技术有哪些&#xff1f;1、寻找连接2、M2M与IoT3、流行的 M2M 协议 在当今的数字世界中&#xff0c;机器对机器 (M2M) 正在迅速成为标准。 M2M 包括使联网设备能够交换数据或信息的任何技术。 它可以是有线或无…

关于已经安装了TorchCRF,导入时却提示“ModuleNotFoundError: No module named ‘torchcrf‘”的解决办法

应用python时&#xff0c;想导入torchcrf库 from torchcrf import CRF 但系统提示&#xff1a;ModuleNotFoundError: No module named torchcrf 在命令提示符里输入“pip list”检查已安装库&#xff0c;发现torchcrf已经安装 搞了半天&#xff0c;发现是大小写的问题&#x…

2023.9 - java - 浅拷贝

与 js的浅拷贝不同&#xff1a; 在 JavaScript 中&#xff0c; Object.assign() 或 spread 运算符等方法可以实现浅拷贝&#xff0c;但只针对对象的第一层属性进行复制。如果一个对象只包含基本数据类型的属性&#xff0c;那么对浅拷贝出来的对象进行修改不会影响原始对象&…

Spring IOC的理解

总&#xff1a; 控制反转&#xff08;IOC&#xff09;&#xff1a;理论思想&#xff0c;传统java开发模式&#xff0c;对象是由使用者来进行管理&#xff0c;有了spring后&#xff0c;可以交给spring来帮我们进行管理。依赖注入&#xff08;DI&#xff09;&#xff1a;把对应的…

React笔记(四)类组件(2)

一、类组件的props属性 组件中的数据&#xff0c;除了组件内部的状态使用state之外&#xff0c;状态也可以来自组件的外部&#xff0c;外部的状态使用类组件实例上另外一个属性来表示props 1、基本的使用 在components下创建UserInfo组件 import React, { Component } from…

OpenCV基本操(IO操作,读取、显示、保存)

图像的IO操作&#xff0c;读取和保存方法 1.1 API cv.imread()参数&#xff1a; 要读取的图像 读取图像的方式&#xff1a; cv.IMREAD*COLOR:以彩色模式加载图像&#xff0c;任何图像的图像的透明度都将被忽略。这是默认参数 标志&#xff1a; 1 cv.IMREAD*GRAYSCALE :以…

【进阶之路】pytest自动化测试框架从0-1精通实战

前言 1、运行方式 命令行模式&#xff1a; pytest -s login.py主函数模式&#xff1a; if __name__ __main__:pytest.main(["-s", "login.py"])pytest.ini运行&#xff1a; 在 pytest.ini 文件中配置 pytest 的运行参数。 注意点&#xff1a; 位置&…

车载监管模块项目需求分析报告

目录 1 文档说明.......................................................................................... 4 2 参考文件.......................................................................................... 4 3 概述.......................................…