赞
踩
部分转载~
FIFO:First Input First Output,即先入先出队列,在计算机中,先进先出队列是一种传统的按序执行方法,先进入的指令先完成并引退,跟着才执行第二条指令。
主要功能包括:
(1)数据的缓冲。如果数据的写入速率高,但间隔大,且会有突发;读出速率小,但相对均匀。则通过设置相应深度的FIFO,可以起到数据暂存的功能,且能够使后续处理流程平滑,避免前级突发时,后级来不及处理而丢弃数据。
(2)时钟域的隔离。对于不同时钟域的数据传递,则数据可以通过FIFO进行隔离,避免跨时钟域的数据传输带来的设计与约束上的复杂度。
(3)不同宽度的数据接口。例如单片机8位数据输出,而DSP是16位数据输入,在单片机和DSP连接时就可以使用FIFO来达到数据匹配的目的。
example:
当模块A要发送数据给模块B,其中模块A的工作时钟是100MHz,模块B的工作时钟是80MHz。若要直接讲A数据送给B,由于时钟不同,B模块势必会丢失数据或多采集数据。
解决问题的方案:使用FIFO,由于FIFO内部可以做跨时钟域处理,读写时钟可以不同,因此非常适合解决这类问题。
如图所示,模块C的功能如下:
a. 模块内部包含一个FIFO,该FIFO数据位宽16bit,深度是64,有rdusedw、wrusedw、empty等指示信号。
b. 输入数据data_in和data_in_vld都是输入clk_in时钟域的,模块首先将数据写入到内部FIFO中,等待被模块B读取。
c. 如果内部FIFO快满时(wrusede>=61),仍然有数据要写入,为了防止FIFO溢出,丢弃该数据,不再写入FIFO。
d. Data_out、data_out_vld和b_rdy都属于clk_out时钟域的。
e. b_rdy是模块B产生的接收数据准备好信号,当此信号为1时,表示模块B已经准备好接收数据,本模块可以将数据发送给模块B。如果为0,表示未准备好,不能将数据发送给模块B。
f. 当b_rdy为1时,且FIFO内有数据(rdempey==0)时,将数据送给模块B。
使用FIFO时要保证当FIFO已经处于满状态时,就不再往FIFO里写数据;当FIFO处于空状态时,不再读FIFO的数据。
基于Vivdao的FIFO IP核使用实例
1、打开IP Catalog–>搜索fifo—>选择FIFO Generator
2、打开FIFO IP核的配置界面
Vivado的IP一般分为以下几个步骤:
一、Basic 基本设置
(1)IP核的一般命名规则:同步/一般_fifo_数据位宽_数据深度
(2) Interface Type:端口类型。一般选择第一个,AXI是Xilinx特有的高速接口。
(3)Fifo Implementation:FIFO的实现方式。
FIFO实现方式有Common Clock同步和Independent Clocks异步两种,每种FIFO下有四种存储形式:
二、Native Ports本地接口
1.Read Mode读模式
Standard FIFO:标准FIFO。选择这个模式,读出的数据会之后使能信号1个时钟周期,第1个数据先暂存在存储单元中,当信号变为高电平后,下1个时钟周期输出;
First Word Fall Through:简称FWFT FIFO。第1个数据直接送入输出缓冲区,并保持在输出总线上,当读信号变为高电平后,当前周期输出第1个数据,第2个周期输出第2个数据。
第1个写入数据将被从ram中提前读出到读数据线,第1个数据有效与empty无效同时,即当信号有效后,读数据线将显示下一个数据地址(读出的数据与读使能信号同一个时钟周期)
Data Port Parameters 数据接口参数
write width 写宽度
write depth 写深度
read width 读宽度
read depth 读深度
(后面读的设置通常与写的设置相同)
Initialization 初始化
Reset Pin 复位引脚
Enable Safety Circuit 启用安全电路,一般都要选上
Reset Type 复位类型,有两种:异步复位和同步复位
Full Flag Reset Value 复位的值,0为低电平复位,1为高电平复 位
三、Status Flag 标志位设置
四、Data Counts:数据数量
尽量不采用读/写计数,因为它采用二级制划分存储容量,会导致区分的颗粒度较大。
五、Summary 总结
对FIFO进行读写的逻辑设计:
module fifo_read_write( input wire sclk , input wire rst_n , input wire [7:0] datain , input wire data_v , input wire r_flag , output wire [7:0] dout ); wire almost_full,wr_ack,overflow,almost_empty,valid,underflow,prog_full,prog_empty; wire w_full,r_empty; wire wr_en; wire rd_en; assign wr_en = (~w_full) & data_v; assign rd_en = (~r_empty) & r_flag; fifo_generator_0 U1( .clk ( sclk ) , .srst ( rst_n ) , .din ( datain ) , .wr_en ( wr_en ) , .rd_en ( rd_en ) , .dout ( dout ) , .full ( w_full ) , .almost_full ( almost_full ) , .wr_ack ( wr_ack ) , .overflow ( overflow ) , .empty ( r_empty ) , .almost_empty ( almost_empty ) , .valid ( valid ) , .underflow ( underflow ) , .prog_full ( prog_full ) , .prog_empty ( prog_empty ) ); endmodule
testbench
`timescale 1ns/1ns module tb_fifo_read_write; reg sclk,rst_n; reg data_v; reg r_flag; reg [7:0] datain; wire [7:0] dout; initial begin sclk = 0; rst_n = 1; #10000; rst_n = 0; end initial begin data_v = 0; datain = 0; r_flag = 0; #20000; send_data(); #60; read_data(); end always #10 sclk = ~sclk; fifo_read_write tb_fifo_read_write( .sclk ( sclk ) , .rst_n ( rst_n ) , .datain ( datain ) , .data_v ( data_v ) , .r_flag ( r_flag ) , .dout ( dout ) ); task send_data; integer i; begin for(i=0; i<400; i=i+1) begin @(posedge sclk) data_v = 1'b1; datain = i; end @(posedge sclk) data_v = 1'b0; datain = 0; end endtask task read_data; integer i; begin for(i=0;i<259;i=i+1) begin @(posedge sclk) r_flag = 1'b1; end @(posedge sclk) data_v = 1'b0; end endtask endmodule
仿真波形图:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。