基于Vivado的FIFO-IP核-强化篇

FIFO-IP核的配置

下面操作是以异步FIFO为例,且读模式为首字先出模式FWFT。

配置界面1

1、模块命名

首先给FIFO模块起名,要做到见名知意。

2、接口类型

接口类型,选择不同的接口类型,那么FIFO的信号线是不同的,也就是说接口类型不同,信号线的功能也不一样,我们的读写操作所使用的信号线不同。我们默认选择Native本地接口。

3、FIFO类型

FIFO类型选取,有同步FIFO和异步FIFO。

Block RAM称为块RAM、嵌入式RAM,它是一个电路,专门用于存储数据的。其电路是在FPGA内部,一块BRAM大小为36Kbit,由两个小的RAM(18Kbit)组成。在FPGA内部资源里有很多BRM资源。它是按块使用的,比如我们位宽是64bit,深度为65536,那么就要消耗64*65535 / (36*1024) ≈ 113.8,需要114个BRAM。那如果消耗了113.1个,那么还是消耗114个BRAM。

总结:(1)FPGA越贵,BRAM资源越多

(2)BRAM的数量,需要根据我们选择芯片信号,去查看手册得知。

(3)每一个BRAM的容量大小为36Kbit,每一块BRAM是由两个小的RAM(18Kbit)组成。

(4)有时候使用存储类的IP核,可能消耗的是BRAM资源,主要看我们选择是BRAM还是DRAM。

(5)消耗BRAM计算公式:位宽*深度 bit / 36Kbit,若存在小数,则结果要+1。

Distributed RAM称为分布式RAM,它消耗的只能是FPGA内部的CLB(可配置逻辑块)中的SLILCM中的LUT(查找表)资源, 可在UG474手册中12页查到。SLILCM的资源要少于SLILCL,在FPGA中比较分散。

FIFO/ROM/RAM-IP核如何选择RAM类型:

BRAM:尽量选择这个,数据量大、较为重要的数据、时钟频率高。是因为它是一个电路专门用于存储数据,适用于时钟频率快的情况。

DRAM:数据量小、不太重要的数据、时钟频率低。是因为它消耗的只能是FPGA内部的CLB(可配置逻辑块)中的SLILCM中的LUT(查找表)资源,而SLILCM的资源在FPGA中比较分散,在读写数据时这个时延相对来说比较大,适用于时钟频率慢的情况。

Bulitin FIFO:在FPGA内部是一个专门的电路,适用于高速的数据缓存的情况。

这里选择异步FIFO的BRAM类型。

配置界面2

1、读模式选择

设置读模式,分别是标准FIFO和首字先出模式。

标准FIFO:读使能rden和读数据之间会有一拍的延迟,也就是1个时钟的潜伏期(1 Clock Latency)

首字先出模式(FWFT) :读使能rden和读数据之间无延迟,也就是0个潜伏期(0 Clock Latency)

2、数据端口的参数

然后再设置读写位宽,以及深度。

异步FIFO可以解决的问题:(1)数据位宽不匹配问题(跨位宽),FIFO作为数据缓存器(同步FIFO也可以),但是需要注意的是读位宽最大只能是写位宽的8倍。(2)跨时域问题

3、输出寄存器

读使能rden和读数据之间的Clock Latency有三种情况:

0拍:FWFT,用在读使能rden和读数据间的时序是对齐的。

1拍:Standard,正常情况下都使用这个。

2拍:Standard + Output Registers,当时钟频率>=200Mhz或者我们的工程所用资源超过了FPGA芯片内部资源的70%,推荐使用2拍延迟

4、复位引脚

FIFO的复位信号rst高电平有效,在复位时rst信号高电平持续时间需要长一些,而且复位结束以后还需要等一会时间。如下图所示:来自PG057手册P128。在这段时间内读写数据都是无效的,也就是说在复位操作这段时间内不可以读写数据。

配置界面3

prog_full和prog_empty可作为反馈机制引脚,控制往FIFO里写数据模块,FIFO快满时不能写,FIFO读空时快点写。

配置界面4

假设写数据位宽位8bit,读数据位宽16bit。

写用量信号wr_data_count:代表FIFO中有多少个8bit数据。

读用量信号rd_data_count:代表FIFO中有多少个16bit数据。

配置界面5

最后检查一下配置是否正确,然后点击OK,即完成FIFO-IP核的配置。

仿真代码

复制代码
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2023/05/17 09:16:36
// Design Name: 
// Module Name: FWFT_FIFO_TB
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module FWFT_FIFO_TB(

    );
	
	
	reg fifo_clk;
	reg [15:0] fifo_wrdata;
	reg fifo_wren;
	reg fifo_rden;
	
	
	
	reg rst_n;
	initial begin 
	
		fifo_clk = 1'b0;
		rst_n = 1'b0;
		#300.1
		rst_n = 1'b1;
	
	end 
	
	always #10 fifo_clk = ~fifo_clk;
	
	
	reg [15:0]work_cnt;
	
	always @ (posedge fifo_clk or negedge rst_n)
	begin 
		if(~rst_n)
			begin 
				work_cnt <= 16'd0;
			end 
		else if(work_cnt == 16'd1000)
			begin 
				work_cnt <= work_cnt;
			end 
		else 
			begin 
				work_cnt <= work_cnt + 1'b1;
			end 
	end 
	
	
	always @ (posedge fifo_clk or negedge rst_n)
	begin 
		if(~rst_n)
			begin 
				fifo_wrdata <= 16'd0;
				fifo_wren <= 1'b0;
			end 
		else if((work_cnt >= 100) && (work_cnt <= 199))//写了100个随机数据
			begin 
				fifo_wrdata <= {$random} %3000;
				fifo_wren <= 1'b1;
			end 
		else 
			begin 
				fifo_wren <= 1'b0;
				fifo_wrdata <= 16'd0;
			end 
	end 
	
	
	always @ (posedge fifo_clk or negedge rst_n)
	begin 
		if(~rst_n)
			begin 
				fifo_rden <= 1'b0;
			end 
		else if((work_cnt >= 200) && (work_cnt <= 299))
			begin 
				fifo_rden <= 1'b1;
			end 
		else 
			begin 
				fifo_rden <= 1'b0;
			end 
	end 
	
	
	
	wire fifo_full;
	wire fifo_empty;
	wire [15:0]fifo_dataout;
	wire [10:0] fifo_data_count;//表示FIFO内部已经存在的数据量
    wire [10:0] wr_data_count;
	
	
	
	
	
	//异步FIFO测试
	FWFT_FIFO FWFT_FIFO (
	  .wr_clk(fifo_clk),                // input wire wr_clk
	  .rd_clk(fifo_clk),                // input wire rd_clk
	  .din(fifo_wrdata),                      // input wire [15 : 0] din
	  .wr_en(fifo_wren),                  // input wire wr_en
	  .rd_en(fifo_rden),                  // input wire rd_en
	  .dout(fifo_dataout),                    // output wire [15 : 0] dout
	  .full(fifo_full),                    // output wire full
	  .empty(fifo_empty),                  // output wire empty
	  .rd_data_count(fifo_data_count),  // output wire [10 : 0] rd_data_count
	  .wr_data_count(wr_data_count)  // output wire [10 : 0] wr_data_count
	);
	
	
	
	
	
	
	
	
	
endmodule

仿真验证

由于使用的首字先出模式,会在写数据时,将第一个数据放在读数据端口上,以此来实现的0拍的延迟。所以才会导致上面这种情况。但是不影响后续读数据时序。

相关推荐
公众号:fuwuqiBMC5 小时前
(转自“服务器BMC”)服务器BMC芯片——AST1840
运维·服务器·fpga开发
国科安芯5 小时前
还是4位?ASC8T245S 与 ASC4T245S 的双向电平转换选型实战
单片机·嵌入式硬件·物联网·fpga开发·机器人·云计算
Rambo.xia1 天前
接口协议避坑 · 第5篇:多器件级联时序踩坑实录
fpga开发
紫霄芯语1 天前
观察者模式在FPGA中断系统的实战重构
观察者模式·fpga开发·重构
ARM+FPGA+AI工业主板定制专家2 天前
国产化RK3576+FPGA架构|晶圆传输机器人高速定位+AI瑕疵检测一体化方案
fpga开发·架构·机器人·嵌入式·fpga·工控·机器人运控
Eloudy3 天前
FPGA (QSFP28 + CMAC US+ RoCEv2) 与 Ubuntu22 + Mellanox 网卡直连分析
fpga开发
szxinmai主板定制专家3 天前
RK3568+FPGA高速并行采集|半导体探针测试设备多通道同步数据采集系统设计
人工智能·嵌入式硬件·计算机视觉·fpga开发
ARM|X86+FPGA工业主板厂家4 天前
RK3588+FPGA+EtherCAT异构架构解析|工业场景如何同时保住AI算力与微秒级运动实时性
人工智能·fpga开发·架构
zlinear数据采集卡4 天前
从“脏信号”到“纳伏级纯净”:硬核拆解DABL7606的多级抗混叠滤波与24位过采样算法
arm开发·科技·嵌入式硬件·fpga开发·开源