FPGA知识基础之--FIFO ip核的使用以及实例化clocking wizard ip产生一个异步FIFO,附RTL和仿真代码

news2024/9/21 16:35:14

目录

  • 一、FIFO简介
    • 1.定义
    • 2.特点
    • 3.分类
    • 4.FIFO在FPGA中的应用
  • 二、实验任务
  • 三、FIFO IP核
    • 1.接口
    • 2.写时序
    • 3.读时序
      • 1.Standara
      • 2 .FWFT
  • 四、vivado设置
  • 五、程序设计
    • 1.模块
    • 2.时序
    • 3.异步信号传输
    • 4.RTL代码
  • 五、仿真
    • 1.Testbench代码
    • 2.波形


一、FIFO简介

1.定义

FIFO是一种先进先出的数据缓存队列,主要特点是数据顺序写入,再按照同样的顺序输出数据,即先进去的数据先被取出来。

2.特点

  • 无需外部读写地址线:FIFO的使用非常简单,因为它不需要外部读写地址线,数据会自动按照先进先出的顺序进行存取。
  • 数据顺序性:FIFO保证了数据的顺序性,即先写入的数据会先被读取出来。
  • 缓存作用:FIFO可以作为数据缓存,当数据源和数据接收端的速度不一致时,FIFO可以起到缓冲数据的作用,避免数据丢失或溢出。

3.分类

根据FIFO输入时钟的区别,可以分为同步FIFO和异步FIFO:

同步FIFO:只有一个独立的时钟端口clock,所有的输入输出信号都同步于clock信号。
异步FIFO:有两个时钟,写端口和读端口分别有独立的时钟,所有写相关的信号都属于写时钟,所有与读相关的信号都属于读时钟。

4.FIFO在FPGA中的应用

FIFO在FPGA开发中的应用非常广泛,主要包括以下几个方面:

  • 数据传输同步:在数据传输过程中,由于不同的设备或处理器的时钟频率可能不同,因此需要进行同步处理。FIFO作为一种缓冲元件,可以将异步数据进行存储,并在同步时按照先进先出的顺序输出,确保数据的正确传输。
  • 网络协议转换:在计算机网络中,不同的协议可能具有不同的数据包格式和传输速率。使用FIFO可以将一种协议的数据包转换为另一种协议的数据包,实现协议转换。
  • 数据压缩与信号处理:在处理大量数据时,FIFO可以用于存储待压缩的数据,并控制数据的压缩顺序。在信号处理中,FIFO可以用于缓存信号数据,并对数据进行预处理和后处理。
  • 并行数据处理:在并行数据处理中,多个处理器或线程同时对数据进行处理。FIFO可以用于协调不同处理器之间的数据传输,并确保数据的顺序和完整性。

二、实验任务

生成一个异步FIFO,当FIFO为空时,向FIFO写入数据,直到将FIFO写满后停止写操作,当FIFO为满时,从FIFO中读数据,直到FIFO被读空后停止读操作。将FIFO的深度和宽度分别设置为256和8进行读写测试

三、FIFO IP核

笔者参考了xlinx的pg_057参考文档,针对于本博客需要的知识来向读者进行分享,详细说明请参考xlinx提供的官方文档。

1.接口

在这里插入图片描述
xlinx提供的IP核有如下接口,笔者标注了每个接口信号的基本功能

2.写时序

在这里插入图片描述

3.读时序

需要注意的是,在FIFO中读有两种模式,Standard模式和**First-Word Fall-Through(FWFT)**模式,关于这两种模式的区分,xlinx文档已经给出了很详尽的解释

在这里插入图片描述
笔者将通过时序图来向大家简单介绍一下这两种模式的区分

1.Standara

在这里插入图片描述

2 .FWFT

在这里插入图片描述
学习完上诉知识后,我们来正式开始今天的实验任务,设计一个异步FIFO

四、vivado设置

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
其余保持默认即可

五、程序设计

1.模块

顶层模块
在这里插入图片描述
写模块
在这里插入图片描述
读模块
在这里插入图片描述

关于各个模块的接口,建议读者首先根据自身的任务要求,其次可参考vivado ip核中的例化模板,可知道ip核的输入输出端口,即可做好模块的划分
在这里插入图片描述

2.时序

写模块时序
在这里插入图片描述
读模块时序
在这里插入图片描述

3.异步信号传输

  • 对于单bit信号,我们一般采用打拍的方法,通过打两拍来将异步的信号变为同步,例如在本任务中,full信号是写模块输出的,其时钟和读模块时钟不一致,因此需要对full进行打两拍,来使得full信号与读模块时序一致,同理empty信号也是一样
  • 对于多bit信号,我们则用FIFO来进行信号的传输,哈哈哈哈哈,突然感觉知识产生了闭环对吧,挺有意思

4.RTL代码

写模块

module fifo_wr (
input                    wr_clk,  //写时钟
input                    rst_n,   //复位信号  
input                    wr_rst_busy, //写忙信号  
input                    almost_full,   //满前一个  
input                    empty,     //空信号
input                    wr_data_count, //计数信号


output  reg              wr_en, //使能信号
output  reg [7:0]        wr_data   //写数据
);

//打拍
reg     empty_d0;
reg     empty_d1;

//打两拍,使得异步单比特信号变成同步
always @(posedge wr_clk or negedge rst_n) begin
    if(!rst_n) begin
        empty_d0   <= 1'b0;        
        empty_d1   <= 1'b0;        
    end
    else begin
        empty_d0   <= empty;
        empty_d1   <= empty_d0;
    end
end

//使能信号赋值
always @(posedge wr_clk or negedge rst_n) begin
    if(!rst_n) 
       wr_en <= 1'b0;
    else if(!wr_rst_busy) begin
        if(empty_d1)
           wr_en <= 1'b1;
        else if(almost_full)
           wr_en <= 1'b0;
        
    end
    else
       wr_en <= 1'b0;
end  

//写数据
always @(posedge wr_clk or negedge rst_n) begin
    if(!rst_n)
        wr_data <= 8'd0;
    else if(wr_en == 1 && wr_data < 8'd254)
        wr_data <= wr_data + 8'd1;
    else 
        wr_data <= 8'd0;

end

    
endmodule

读模块

module fifo_rd(
input                    rd_clk,
input                    rst_n,
input                    full,
input                    rd_rst_busy,
input                    almost_empty,
input        [7:0]       rd_data,

output   reg             rd_en


);

reg         full_d0;
reg         full_d1;

//打拍
always @(posedge rd_clk or negedge rst_n) begin
    if(!rst_n) begin
        full_d0   <= 1'b0;        
        full_d1   <= 1'b0;        
    end
    else begin
        full_d0   <= full;
        full_d1   <= full_d0;
    end
end


//对rd_en进行赋值,FIFO写满之后开始读,读空之后停止读
always @(posedge rd_clk or negedge rst_n) begin
    if(!rst_n) 
        rd_en <= 1'b0;
    else if(!rd_rst_busy) begin
        if(full_d1)
           rd_en <= 1'b1;
        else if(almost_empty)
           rd_en <= 1'b0;
        
    end
    else
        rd_en <= 1'b0;
end



endmodule

顶层模块

module ip_fifo(
input       sys_clk,
input       sys_rst_n
);


wire         clk_50m       ;  // 50M时钟
wire         clk_100m      ;  // 100M时钟
wire         locked        ;  // 时钟锁定信号
wire         rst_n         ;  // 复位,低有效
wire         wr_rst_busy   ;  // 写复位忙信号
wire         rd_rst_busy   ;  // 读复位忙信号
wire         wr_en    ;  // FIFO写使能信号
wire         rd_en    ;  // FIFO读使能信号
wire  [7:0]  wr_data  ;  // 写入到FIFO的数据
wire  [7:0]  rd_data  ;  // 从FIFO读出的数据
wire         almost_full   ;  // FIFO将满信号
wire         almost_empty  ;  // FIFO将空信号
wire         full          ;  // FIFO满信号
wire         empty         ;  // FIFO空信号
wire  [7:0]  wr_data_count ;  // FIFO写时钟域的数据计数
wire  [7:0]  rd_data_count ;  // FIFO读时钟域的数据计数



assign rst_n = sys_rst_n & locked;


clk_wiz_0 u_clk_wiz_0
(
.clk_out1   (clk_50m), 
.clk_out2   (clk_100m), 

.locked     (locked),  
.clk_in1    (sys_clk) 
);


//例化写FIFO模块
fifo_wr     u_fifo_wr(
.wr_clk                       (clk_50m),// 写时钟
.rst_n                        (rst_n), // 复位信号
.wr_rst_busy                  (wr_rst_busy),// 写复位忙信号
.almost_full                  (almost_full ),
.empty                        (empty),
.wr_data_count                (wr_data_count ),
.wr_en                        (wr_en),
.wr_data                      (wr_data)
);

//例化读FIFO模块
fifo_rd  u_fifo_rd(
.rd_clk                       (clk_100m),
.rst_n                        (rst_n),
.full                         (full),
.rd_rst_busy                  (rd_rst_busy),
.almost_empty                  (almost_empty),
.rd_data                      (rd_data),
.rd_en                        (rd_en)
);

//例化FIFO IP核
fifo_generator_0  u_fifo_generator_0(
.rst                                 (~rst_n),   //比较奇怪                   
.wr_clk                              (clk_50m),   //写时钟            
.rd_clk                              (clk_100m),  //读时钟          
.din                                 (wr_data),                      
.wr_en                               (wr_en),                  
.rd_en                               (rd_en),                  
.dout                                (rd_data),                    
.full                                (full),                    
.almost_full                         (almost_full),      
.empty                               (empty),                  
.almost_empty                        (almost_empty),    
.rd_data_count                       (rd_data_count),  
.wr_data_count                       (wr_data_count),  
.wr_rst_busy                         (wr_rst_busy),      
.rd_rst_busy                         (rd_rst_busy)      
);                       





endmodule

FIFO ip核和 clocking wizard ip核在顶层模块中调用即可
需要注意的是:我们会发现,这个顶层模块也太难写了,第一眼看完全无从下手,这里笔者认为,根据顶层模块框图来对各个模块进行例化即可不那么模糊,至于前面变量的调用,缺啥补啥就可以了,都是wire线网类型,对各个变量进行提前说明即可,这是笔者的一些小技巧。

五、仿真

1.Testbench代码

`timescale	1ns/1ns //仿真的单位/仿真的精度s
module tb_ip_fifo();

parameter CLK_PERIOD = 20;

reg 		sys_clk;  //周期20ns
reg 		sys_rst_n; 


initial begin
	sys_clk <= 1'b0;
	sys_rst_n <=1'b0;
	#200 
	sys_rst_n <= 1'b1;
end

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


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

因为顶层模块只有两个激励,所以仿真测试代码还是很好写的

2.波形

笔者是利用vivado和modelsim来进行联合仿真
写模块
在这里插入图片描述

在这里插入图片描述
读模块
在这里插入图片描述
仿真验证正确


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

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

相关文章

电能表在企业能源管理中的作用

电能表在企业能源管理中扮演着至关重要的角色&#xff0c;它不仅是能源计量的基础工具&#xff0c;更是企业实现高效能源管理、降低能源成本、提高竞争力的关键所在。 一、精确计量与实时监测 电能表作为能源计量的基础工具&#xff0c;其首要作用是实现电能的精确计量。相比…

PostgreSQL 练习 ---- psql 新增连接参数

目标 添加一个连接参数&#xff0c;默认为 false 。当 psql 连接时&#xff0c;若该连接参数非 “true” 时&#xff0c;用户 “u1“ 对表对象无操作权限&#xff0c;包括自己拥有的表。 连接机制简介 连接过程如下所述&#xff1a; 客户端初始化一个空连接&#xff0c;设置…

如何高效记录并整理编程学习笔记?

一&#xff1a;简介 在编程学习的过程中&#xff0c;建立一个高效的笔记记录和整理方法确实非常重要。下面是一些方法和建议&#xff0c;帮助你打造自己的编程学习“知识宝库”。 1&#xff09;. 选择合适的工具 选择一个适合自己的笔记工具非常重要。可以考虑以下几种&#…

SB3045LFCT-ASEMI无人机专用SB3045LFCT

编辑&#xff1a;ll SB3045LFCT-ASEMI无人机专用SB3045LFCT 型号&#xff1a;SB3045LFCT 品牌&#xff1a;ASEMI 封装&#xff1a;TO-220F 批号&#xff1a;最新 最大平均正向电流&#xff08;IF&#xff09;&#xff1a;30A 最大循环峰值反向电压&#xff08;VRRM&…

大模型系列8-Latex

大模型系列8-Latex 背景Latex符号符号加帽子、横线和波浪线求和连乘希腊字母等于约等于积分微分公式对齐算法矩阵 背景 目前正通过论文、博客、视频、文档等各种形式学习各种大模型知识。为了更好的记录&#xff0c;写了一些大模型的博客&#xff0c;不专业&#xff0c;只备忘…

Openlayers6 图形绘制和修改功能(结合React)

Openlayers常用的API了解的差不多了&#xff0c;就开始进入实战了&#xff0c;首先从绘制基本的图形开始&#xff0c;这里主要介绍一下绘制圆形、矩形和多边形。 通过使用openlayers的ol.interaction.Draw和ol.interaction.Modify模块实现地图上绘制圆形、矩形、多边形并修改编…

2024.8.12(LVS)

一、LVS 1、描述以及工作原理 1. 什么是LVS linux virtural server的简称,也就是linxu虚拟机服务器,这是一个由章文嵩博士发起的开源项目,官网是http://www.linuxvirtualserver.org,现在lvs已经是linux内核标准的一部分,使用lvs可以达到的技术目标是:通过linux达到负载均衡技…

mysql注入-字符编码技巧

一、环境搭建 创建数据表 CREATE TABLE mysql_Bian_Man (id int(10) unsigned NOT NULL AUTO_INCREMENT,username varchar(255) COLLATE latin1_general_ci NOT NULL,password varchar(255) COLLATE latin1_general_ci NOT NULL,PRIMARY KEY (id) ) ENGINEMyISAM AUTO_INCREME…

Python办公自动化:使用`xlutils` 修改Excel文档

在日常办公自动化中&#xff0c;除了读取Excel文件&#xff0c;我们还经常需要对文件进行修改或更新。在Python中&#xff0c;除了xlrd&#xff0c;还可以使用xlutils库来实现对Excel文件的修改操作。本文将继续以“巴黎奥运会奖牌榜.xlsx”文件为例&#xff0c;讲解如何使用xl…

OpenCV + CUDA + cuDNN模块编译

简介 在追求高端性能与资源优化并重的应用场景中&#xff0c;如边缘计算设备或资源受限的开发板上运行YOLO等复杂深度学习模型&#xff0c;采用C结合OpenCV与GPU加速技术相较于传统的Python环境展现出显著优势。这种策略不仅极大地提升了执行效率&#xff0c;还显著降低了运行时…

陶晶池串口屏数据存储区概述与使用

陶晶池串口屏的数据存储区大小&#xff1a;x系列是2k字节的&#xff0c;其他系列是1k字节的&#xff0c;超出了就会从头覆盖最先的字节 你可以在主动解析模式下调用u[x]来访问数据存储区内第x-1字节是什么&#xff0c;也可以读取usize看看记录大小 它的原理是&#xff0c;每接收…

axios 封装避免重复请求(两种)

目录 前言 Demo 第一种实现方法 第二种方法&#xff08;axios版本0.22.0以上&#xff09; 前言 在当今的前端开发领域&#xff0c;数据交互是不可或缺的一环。Axios 作为一款基于 Promise 的 HTTP 客户端&#xff0c;因其简洁的 API 和丰富的配置选项&#xff0c;深受广大…

R语言的下载和安装

R是一种强大的编程语言和环境&#xff0c;主要用于统计计算和数据分析。自从R诞生以来&#xff0c;它在统计学家和数据科学家中迅速普及。然而&#xff0c;R本身只是一个命令行工具&#xff0c;对于大多数用户来说&#xff0c;单独使用R可能会有些困难或者不方便。RStudio作为一…

科技云报道:“大模型+机器人”,具身智能将开启“智械时代”

科技云报道原创。 从15世纪达芬奇绘制出世界上第一份人形机器人手稿&#xff0c;到如今波士顿动力、本田、特斯拉、Figure AI等企业相继推出了人形机器人产品&#xff0c;机器人新物种持续衍生&#xff0c;人形机器人产业已经从萌芽概念阶段进入产业化落地前期。 近日&#x…

Golang面试题四(并发编程)

目录 1.Go常见的并发模型 2.哪些方法安全读写共享变量 3.如何排查数据竞争问题 ​4.Go有哪些同步原语 1. Mutex (互斥锁) 2. RWMutex (读写互斥锁) 3. Atomic 3.1.使用场景 3.2.整型操作 3.3.指针操作 3.4.使用示例 4. Channel 使用场景 使用示例 5. sync.WaitGr…

Java同城生鲜配送物流配送到店独立骑手端系统小程序源码

&#x1f69a;【一键解锁新鲜生活&#xff01;同城生鲜配送系统全揭秘】&#x1f966;&#x1f680; &#x1f50d; 源码揭秘&#xff1a;打造高效生鲜配送的秘密武器 &#x1f527; 想要在家就能享受超市般的生鲜盛宴吗&#xff1f;揭秘同款城生鲜配送系统的源码&#xff0c…

信号与线性系统实验一:LTI连续系统时域响应测试与分析

文章目录 一、实验目的二、实验内容与原理&#xff08;简单列了一下提纲&#xff09;第一部分&#xff1a;连续系统时域响应MATLAB仿真分析第二部分&#xff1a;连续系统时域响应Multisim电路仿真分析 三、实验器材四、实验步骤第一部分&#xff1a;连续系统时域响应MATLAB仿真…

vulnhub系列:sp eric

vulnhub系列&#xff1a;sp eric 靶机下载 一、信息收集 nmap扫描存活&#xff0c;根据mac地址寻找IP nmap 192.168.23.0/24nmap扫描端口&#xff0c;开放端口&#xff1a;22、80 nmap 192.168.23.189 -p- -A -sV -Pndirb 扫描目录&#xff0c;.git 源码&#xff0c;admin…

【python】PyQt5中单行文本输入控件QLineEdit的详细解析与应用实战

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

使用Python打造简易Web服务器

目录 准备工作 创建Web服务器 示例代码 运行服务器 结论 在开发过程中&#xff0c;了解Web服务器的工作原理是非常有用的。Python作为一个功能强大的编程语言&#xff0c;提供了http.server模块&#xff0c;让我们能够快速地搭建一个简易的Web服务器。本文将指导你如何使用…