VIVADO FIFO (同步和异步) IP 核详细使用配置步骤

news2025/1/17 11:47:11

VIVADO FIFO (同步和异步) IP 核详细使用配置步骤

目录

前言

一、同步FIFO的使用

1、配置

2、仿真

二、异步FIFO的使用

1、配置

2、仿真


前言

        在系统设计中,利用FIFO(first in first out)进行数据处理是再普遍不过的应用了,使用FIFO实现不同域时钟的数据同步,总线位宽调整,数据缓存等。本文以xilinx vivado中的FIFO IP 核为例,详细介绍其配置步骤,并给出详细的仿真,本文包含同步和异步(不同时钟)FIFO的详细使用步骤。


提示:以下是本篇文章正文内容,转载请附上原文链接

一、同步FIFO的使用

1、配置

         在IP Catalog 界面搜索FIFO并双击FIFO Generator开始配置IP 核。对IP核命名,不妨取test_synchronous_fifo(同步FIFO的测试)。

首先,配置Basic界面:

Interface Type 保持默认即可,一般不选AXI接口。

FIFO Implementation 选用什么资源生成FIFO,这里选择 Common Clock Block RAM,即用块RAM资源生成一个同步FIFO。

该界面下面显示的是在选定方式生成的FIFO具有的特点。

然后,配置Native Ports界面:

Read Mode 默认选Standard FIFO,First FIFO Fall Through 会在没有读的时候就在读端口放置第一个数据,如手册中的下图所示,只要写入一个数据 D1 后,在rd_en为低电平的时候,dout就会变成D1且valid一直拉高。大家可以根据自己的需求选择对应的读模式。

Data Port Parameters 用来配置读写的深度和数据位宽,这里示例配置4bit宽度,16的深度。

!!!要留意一下配置的深度和实际的深度,手册中提及了选择不同实现方式(Basic 界面)实际深度与配置的深度是有差异的,实际深度才是可以使用的深度。

ECC,Output... 是IP核纠错,输出端加寄存器的功能,在配置时其实不用管,不用勾选任何东西。

Initialization 勾选复位,类型选择同步复位,Full Flags Reset Value 是复位时满标志的默认电平,Dout Reset Value 是复位时默认的读端口输出。

再然后,配置Status Flags界面:

Optional Flags中的Almost Full Flag是快要写满标志,即再写一个数据就满了的提示, Almost Empty Flag是快要读空标志,即再读一个数据就空了的提示。

Write Acknowledge 是写数据的标志,如果勾选高电平有效,则其拉高表示数据被写入。

Overflow 是溢出标志,如果满了,继续写数据是写不了的,溢出了。

valid Flag 读数据时输出数据有效的标志。

Underflow Flag 下溢标志,如果选择高电平有效,也就是读空了继续读该标志就会拉高。

Programmable Flags 是自定义一个数据写多少个就算满的标志信号和数据还剩多少个就算空的标志信号,可以在IP核界面配置固定的值,也可以引入两个输入端口由程序编程设置。需要用到该功能的可自行配置。

此处,按下图配置届时仿真可观察这些信号。

最后,配置Data Counts界面:

可以勾选Data Count,指示FIFO中还有多少个数据。由于此时是同步FIFO,所以只有一个Data Count。

至此,同步 FIFO 配置完成,下面进行仿真。

2、仿真

        创建一个名为 tb_synchronous_fifo 的 testbench 文件,测试以上配置的FIFO。

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2025/01/15 11:36:36
// Design Name: 
// Module Name: tb_synchronous_fifo
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//

module tb_synchronous_fifo();

parameter  PERIOD   = 2;

reg clk=1;
reg rst_n=0;
reg [3 : 0] din=0;
reg wr_en=0;
reg rd_en=0;

wire [3 : 0] dout;
wire full;
wire almost_full;
wire wr_ack;
wire overflow;
wire empty;
wire almost_empty;
wire valid;
wire underflow;
wire [3 : 0] data_count;

initial
begin
    forever #(PERIOD/2)  clk=~clk;
end

initial
begin
    #(PERIOD*5) rst_n  =  1;
end

reg [4:0] cnt;
always @(posedge clk or negedge rst_n)
begin
    if(!rst_n)
        begin
            wr_en<=0;
            cnt<=0;
        end
    else if(cnt<16)
        begin
            cnt<=cnt+1;
            wr_en<=1;
            din<=din+1;
        end
    else
        begin
            wr_en<=0;
        end
end

always @(posedge clk or negedge rst_n)
begin
    if(!rst_n)
        begin
            rd_en<=0;
        end
    else if(cnt==16)
        begin
            rd_en<=1;
        end
end

test_synchronous_fifo u_test_synchronous_fifo (
  .clk(clk),                    // input wire clk 
  .srst(!rst_n),                // input wire srst ip核本身是高电平复位
  .din(din),                    // input wire [3 : 0] din
  .wr_en(wr_en),                // input wire wr_en
  .rd_en(rd_en),                // input wire rd_en
  .dout(dout),                  // output wire [3 : 0] dout
  .full(full),                  // output wire full
  .almost_full(almost_full),    // output wire almost_full
  .wr_ack(wr_ack),              // output wire wr_ack
  .overflow(overflow),          // output wire overflow
  .empty(empty),                // output wire empty
  .almost_empty(almost_empty),  // output wire almost_empty
  .valid(valid),                // output wire valid
  .underflow(underflow),        // output wire underflow
  .data_count(data_count)       // output wire [3 : 0] data_count
);

endmodule

        从以上结果可以看出写入16个数据,读出16个数据,谁先写入就先被读出。大家可自行观察其他信号的变化是否和自己理解的一致。

        上面配置FIFO的深度只有16,如果写入数据个数大于16,数据能写进去吗?答案是写不进去,并不是我们理解的满了再进就会将最开始进的挤出去。VIVADO FIFO IP就是这样这样设置的,没有办法改变,那么如果某些场景下需要这种满了再进就会将最开始进的挤出去的这种功能,光调用IP还无法实现。

        例如,将上面代码中的 else if(cnt<16)  和 else if(cnt==16) 两句代码中的16改成20再仿真,结果如下,分析结果可以得出,满了继续写不会将最开始写的挤出去,而是直接忽视掉再写的数据。

二、异步FIFO的使用

1、配置

        在IP Catalog 界面搜索FIFO并双击FIFO Generator开始配置IP 核。对IP核命名,不妨取test_asynchronous_fifo(异步FIFO的测试)。

首先,配置Basic界面:

Interface Type 保持默认即可,一般不选AXI接口。

FIFO Implementation 选用什么资源生成FIFO,这里选择 Independent Clocks Block RAM,即用块RAM资源生成一个异步FIFO。

相比于同步FIFO,多了synchronization Stages的配置,这个相当于写时钟域里面的数据经过多少个时钟周期同步到读时钟区域,可以理解成延时打拍同步。

该界面下面显示的是在选定方式生成的FIFO具有的特点。

然后,配置Native Ports界面:

Read Mode 同步FIFO配置有介绍,此处默认选Standard FIFO。

Data Port Parameters 用来配置读写的深度和数据位宽,这里示例配置4bit宽度,16的深度。

!!!要留意一下配置的深度和实际的深度,手册中提及了选择不同实现方式(Basic 界面)实际深度与配置的深度是有差异的,实际深度才是可以使用的深度。异步FIFO此时实际可使用的深度就比我们配置的少了一个。

ECC,Output... 是IP核自己纠错,输出端加寄存器的功能,在配置时其实不用管,不用勾选任何东西。

Initialization 勾选复位,Reset Type 固定了只能异步复位,是相对于整个IP而言。Full Flags Reset Value 是复位后满标志的默认电平,Dout Reset Value 是复位后默认的读端口输出。

相比于同步FIFO,多了Enable Reset Synchronization,该选项是读写时钟域分开来看时,在各自的时钟域里面使用同步复位。Enable Safety Circuit 手册说是一个保护电路,默认勾选即可,不用过多纠结。

Full Flags Reset Value 是复位时满标志默认电平,Dout Reset Value 是复位时默认读端口输出。

再然后,配置Status Flags界面:

同步FIFO配置界面已一 一说明。此处,按下图配置届时仿真可观察这些信号。

最后,配置Data Counts界面:

Data Count,指示FIFO中还有多少个数据。由于此时是异步FIFO,所以读写各有一个Data Count。

至此,异步 FIFO 配置完成,下面进行仿真。

2、仿真

        创建一个名为 tb_asynchronous_fifo 的 testbench 文件,测试以上配置的异步FIFO。

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2025/01/15 12:20:08
// Design Name: 
// Module Name: tb_asynchronous_fifo
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//

module tb_asynchronous_fifo();

parameter  PERIOD   = 2;

reg rst_n=0;
reg wr_clk=1;
reg rd_clk=1;
reg [3 : 0] din=0;
reg wr_en=0;
reg rd_en=0;

wire [3 : 0] dout;
wire full;
wire almost_full;
wire wr_ack;
wire overflow;
wire empty;
wire almost_empty;
wire valid;
wire underflow;
wire [3 : 0] rd_data_count;
wire [3 : 0] wr_data_count;
wire wr_rst_busy;
wire rd_rst_busy;

initial
begin
    forever #(PERIOD/2)  wr_clk=~wr_clk;
end

initial
begin
    forever #(PERIOD)    rd_clk=~rd_clk;
end

initial
begin
    #(PERIOD*5) rst_n  =  1;
end

reg flag=0;

initial
begin
    #(PERIOD*28) flag  =  1;
    #(PERIOD)    flag  =  0;
end

reg [4:0] cnt;
always @(posedge wr_clk or negedge rst_n)
begin
    if(!rst_n)
        begin
            wr_en<=0;
            cnt<=0;
        end
    else if(flag)
        begin
            cnt<=cnt+1;
            wr_en<=1;
            din<=din+1;
        end
    else if(1<=cnt&&cnt<16)
        begin
            cnt<=cnt+1;
            wr_en<=1;
            din<=din+1;
        end
    else
        begin
            wr_en<=0;
        end
end

always @(posedge rd_clk or negedge rst_n)
begin
    if(!rst_n)
        begin
            rd_en<=0;
        end
    else if(cnt==16)
        begin
            rd_en<=1;
        end
end

test_asynchronous_fifo u_test_asynchronous_fifo (
  .rst(!rst_n),                   // input wire rst
  .wr_clk(wr_clk),                // input wire wr_clk
  .rd_clk(rd_clk),                // input wire rd_clk
  .din(din),                      // input wire [3 : 0] din
  .wr_en(wr_en),                  // input wire wr_en
  .rd_en(rd_en),                  // input wire rd_en
  .dout(dout),                    // output wire [3 : 0] dout
  .full(full),                    // output wire full
  .almost_full(almost_full),      // output wire almost_full
  .wr_ack(wr_ack),                // output wire wr_ack
  .overflow(overflow),            // output wire overflow
  .empty(empty),                  // output wire empty
  .almost_empty(almost_empty),    // output wire almost_empty
  .valid(valid),                  // output wire valid
  .underflow(underflow),          // output wire underflow
  .rd_data_count(rd_data_count),  // output wire [3 : 0] rd_data_count
  .wr_data_count(wr_data_count),  // output wire [3 : 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
);

endmodule

观察上面的仿真结果,第一,复位时满信号为1,与我们IP配置界面相吻合;第二,因为本身实际容量只有15个数据,我们写16个数据,溢出了一个,图中overflow拉高了一个电平,与同步FIFO一样,写满了就写不进去了;第三,图中两条黄色线之间相差4个读时钟周期,就是我们前面配置提到的延迟打拍保证时钟区域同步,那明明前面配置的是2,为什么这里为4呢?这是因为下图中的数字2造成的,2+2=4。

接下来将IP配置界面的同步拍数改为3,那么仿真图中两条黄色线之间则会有5个读时钟周期,以保证数据同步到读时钟域,如下面仿真图所示。

至此,本文结束。

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

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

相关文章

一、1-2 5G-A通感融合基站产品及开通

1、通感融合定义和场景&#xff08;阅读&#xff09; 1.1通感融合定义 1.2通感融合应用场景 2、通感融合架构和原理&#xff08;较难&#xff0c;理解即可&#xff09; 2.1 感知方式 2.2 通感融合架构 SF&#xff08;Sensing Function&#xff09;&#xff1a;核心网感知控制…

某政务行业基于 SeaTunnel 探索数据集成平台的架构实践

分享嘉宾&#xff1a;某政务公司大数据技术经理 孟小鹏 编辑整理&#xff1a;白鲸开源 曾辉 导读&#xff1a;本篇文章将从数据集成的基础概念入手&#xff0c;解析数据割裂给企业带来的挑战&#xff0c;阐述数据集成的重要性&#xff0c;并对常见的集成场景与工具进行阐述&…

【MySQL】使用C语言链接

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;MySQL 目录 一&#xff1a;&#x1f525; MySQL connect &#x1f98b; Connector / C 使用&#x1f98b; mysql 接口介绍&#x1f98b; 完整代码样例 二&#xff1a;&#x1f525; 共勉 一&#…

《Java核心技术II》并行流

并行流 从集合中获取并行流&#xff1a;Stream paralleWords words.parallelStream(); parallel方法将任意顺序流转换为并行流&#xff1a;Stream paralleWords Stream.of(wordArray).parallel(); 以下是不好的示范&#xff0c;假设对字符串的所有短单词计数&#xff1a; …

【Rust自学】13.2. 闭包 Pt.2:闭包的类型推断和标注

13.2.0. 写在正文之前 Rust语言在设计过程中收到了很多语言的启发&#xff0c;而函数式编程对Rust产生了非常显著的影响。函数式编程通常包括通过将函数作为值传递给参数、从其他函数返回它们、将它们分配给变量以供以后执行等等。 在本章中&#xff0c;我们会讨论 Rust 的一…

ETW HOOK[InfinityHook]技术解析

文章目录 概述分析过程参考资料 概述 ETW是操作系统为了对系统调用、异常等信息做了一个日志操作&#xff0c;本质就是在进行调用这些中断、异常、系统调用时会走向这个代码函数区域日志保存的功能。而ETW HOOK就是在驱动层微软的PatchGuard并未对其做到很好的检测&#xff0c…

码编译安装httpd 2.4,测试

下载链接&#xff1a;https://dlcdn.apache.org/httpd/httpd-2.4.62.tar.gz [rootopenEuler-1 ~]# yum install gcc gcc-c make -y [rootopenEuler-1 ~]# ll /root total 9648 -rw-------. 1 root root 920 Jan 10 17:15 anaconda-ks.cfg -rw-r--r-- 1 root root 9872432…

步入响应式编程篇(一)

响应式编程 为什么要有响应式编程&#xff1f;响应式编程的用法Flow api的用法处理器 为什么要有响应式编程&#xff1f; 传统编码&#xff0c;操作流程常见的是命令式编程范式&#xff0c;如对于一个请求或操作来说&#xff0c;都是串行执行&#xff0c;直到异常或执行结束&a…

C++—18、C++ 中如何写类

一、类的功能阐述 今天我们将用目前学到的类的基础知识从头开始编写一个类。只编写一个基本的Log类&#xff0c;来演示到目前为止我们学过的一些基本特性。随着接下来的学习你会看到从一个类的基本版本到一个更高级版本的过程和区别。高级版本可以做同样的事情&#xff0c;但可…

SW - 查看装配图中的零件的全路径名称

文章目录 SW - 查看装配图中的零件的全路径名称概述笔记END SW - 查看装配图中的零件的全路径名称 概述 装配图中&#xff0c;如果本机有多个不同版本的同名零件(e.g. v1/p1零件, v2/p1零件)&#xff0c;在装配图中想确认是哪个版本的零件。 如果编辑错了文件&#xff0c;或者…

【开源分享】nlohmann C++ JSON解析库

文章目录 1. Nlohmann JSON 库介绍2. 编译和使用2.1 获取库2.2 包含头文件2.3 使用示例2.4 编译 3. 优势4. 缺点5. 总结参考 1. Nlohmann JSON 库介绍 Nlohmann JSON 是一个用于 C 的现代 JSON 库&#xff0c;由 Niels Lohmann 开发。它以易用性和高性能著称&#xff0c;支持 …

神经网络基础-正则化方法

文章目录 1. 什么是正则化2. 正则化方法2.1 Dropout正则化2.2 批量归一化(BN层) 学习目标&#xff1a; 知道正则化的作用掌握随机失活 DropOut 策略知道 BN 层的作用 1. 什么是正则化 在设计机器学习算法时希望在新样本上的泛化能力强。许多机器学习算法都采用相关的策略来减小…

【C++】面试题整理(未完待续)

【C】面试题整理 文章目录 一、概述二、C基础2.1 - 指针在 32 位和 64 位系统中的长度2.2 - 数组和指针2.3 - 结构体对齐补齐2.4 - 头文件包含2.5 - 堆和栈的区别2.6 - 宏函数比较两个数值的大小2.7 - 冒泡排序2.8 - 菱形继承的内存布局2.9 - 继承重写2.10 - 如何禁止类在栈上分…

ASP.NET Core - 依赖注入(四)

ASP.NET Core - 依赖注入&#xff08;四&#xff09; 4. ASP.NET Core默认服务5. 依赖注入配置变形 4. ASP.NET Core默认服务 之前讲了中间件&#xff0c;实际上一个中间件要正常进行工作&#xff0c;通常需要许多的服务配合进行&#xff0c;而中间件中的服务自然也是通过 Ioc…

w~Transformer~合集11

我自己的原文哦~ https://blog.51cto.com/whaosoft/12472192 #LightSeq 最高加速9倍&#xff01;字节跳动开源8比特混合精度Transformer引擎,近年来&#xff0c;Transformer 已经成为了 NLP 和 CV 等领域的主流模型&#xff0c;但庞大的模型参数限制了它的高效训练和推理。…

海云安开发者安全智能助手D10荣膺 “ AI标杆产品 ” 称号,首席科学家齐大伟博士入选2024年度 “ 十大杰出青年 ”

2024年12月27日&#xff0c;粤港澳大湾区AI领袖峰会在深圳成功举办&#xff0c;大会表彰了在人工智能技术创新、应用实践和产业发展等方面取得优异成绩的企业和个人&#xff0c;深圳海云安网络安全技术有限公司开发者安全智能助手D10荣膺“AI标杆产品”称号。同时&#xff0c;公…

Autodl转发端口,在本地机器上运行Autodl服务器中的ipynb文件

通过 SSH 隧道将远程端口转发到本地机器 输入服务器示例的SSH指令和密码&#xff0c;将远程的6006端口代理到本地 在服务器终端&#xff0c;激活conda虚拟环境 conda activate posecnnexport PYOPENGL_PLATFORMegljupyter notebook --no-browser --port6006 --allow-root从…

网站建设公司哪家好?我的避坑指南

公司刚成立那个时候&#xff0c;第一步就是想着抓紧做一个官网&#xff0c;因为一个好的网站可以通过互联网源源不断的带来客流&#xff0c;所以小公司业务最重要&#xff0c;我就赶紧在网上开始找公司。 网站是的大活&#xff0c;对于我这种什么都不会的&#xff0c;当然只能…

浅谈云计算15 | 存储可靠性技术(RAID)

存储可靠性技术 一、存储可靠性需求1.1 数据完整性1.2 数据可用性1.3 故障容错性 二、传统RAID技术剖析2.1 RAID 02.2 RAID 12.3 RAID 52.4 RAID 62.5 RAID 10 三、RAID 2.0技术3.1 RAID 2.0技术原理3.1.1 两层虚拟化管理模式3.1.2 数据分布与重构 3.2 RAID 2.0技术优势3.2.1 自…

qml RadialGradient详解

1、概述 RadialGradient是QML中用于创建径向渐变效果的一种类型。它允许您定义从中心向外辐射的颜色渐变&#xff0c;可以应用于各种QML可视组件上&#xff0c;如Rectangle、Image等&#xff0c;以创建出丰富的视觉效果。 2、重要属性 angle&#xff1a;定义渐变围绕其中心点…