Menu Close

Quartus II FIFO生成与配置详解

Quartus II FIFO生成与配置详解

FIFO(first in first out)是先进先出存储器结构,目前在计算机数据缓冲,通信数据流缓冲,图像与语音缓冲等领域应用非常广泛,尤其在FPGA内部是主要数据缓冲器之一,目前比较流行的FPGA芯片几乎都有独立的块存储器(block memory)或分布式存储器可以配置成FIFO。FIFO与DPRAM(双口RAM)是FPGA内部数据缓冲的两大神器,用好FIFO和双口RAM是FPGA设计与应用必备的技术之一。下面就FIFO在Quartus II 环境下生成步骤为例,结合生成过程中的技术术语作比较详细介绍。

  1. 新建测试工程

工程名 : test_fifo

顶层模块名称 : test_fifo

  • 添加新文件

新建顶层设计文件,顶层文件名称为 test_fifo.v ,要求数据的宽度参数化,便于对FIFO输入、输出不同宽度数据进行测试。

module test_fifo

#(parameter IN_WIDTH=32,

parameter OUT_WIDTH=32

)

(

input inclk,

input outclk,

input rst,

input wrreq, //

input rdreq,

input [IN_WIDTH-1:0] datain,

output[OUT_WIDTH-1:0] dataout

);

endmodule

  • 添加FIFO(IPcore ),下面按照FIFO的创建步骤,逐一解释生成过程。
    • 在Quartus II 主界面的右边IP catalog的窗口中找到FIFO(installed IP–>Library–>Basic Functions–>On Chip Memory–>FIFO), 如图1
    • 双击选中的标价签,如图2,

图1

    • 在图2的对话框中选择 IP variation file type 为Verilog,生成IPcore的文件名为fifo1,点击OK,弹出图3对话框。

 

图2

    • 图3中的选项

图3

    • FIFO 输入、输出数据宽度设置:输入、输出数据宽度缺省值是8 bits, 可以在1–256bits之间选择, 可见FIFO的数据宽度选择是非常灵活的,根据实际需要选择。输入、输出也可以设置为不等宽(How wide should the FIFO be?),选中”use different output width and set to “,可以设置输出的数据宽度,常用的模式为一字节输入,2或4字节输出,或4字节输入1字节输出等,具体根据实际需求进行设置。
    • FIFO数据深度选择如图4,FIFO的深度是指FIFO总计占有多少存储单元,由于考虑到空、满标志,以及数据同步等内容,FIFO的深度最低为4个单元,而且FIFO深度是按照2n(2的幂次方)设定。如深度可以设为4,8,16…131072. 一般最大深度为131072,如有更深的需求,可以生成2个或多个FIFO进行级联。

图4

      • 输入、输出时钟设置(do you want common clock for both reading and writing of the fifo),这里有两种选择:
      • 输入、输出同步时钟(synchronize both reading and writing clock,create one set of full/empty control signals)

输入、输出采用同步时钟,创建一套空/满等控制信号为输入输出共同使用。这种FIFO的应用场景是,当输入、输出的数据在同一个时钟控制下数据流,仅仅需要处理输出缓存的情况,如在网络通信的过程中IP数据包到UDP数据包的变换,UDP到应用程序的变换等。

    • 异步时钟(synchronize reading and writing to rdclk and wrclk respectively, create s set of full/empty control signals to each clock),读写时钟完全分离,控制信号也由各自时钟控制。这种FIFO的应用场景更为广泛,在不同时钟的接口中FIFO和异步时钟的双口RAM几乎是必然的选择。如在AD转换的数据读取中,ADC的输出时钟与FPGA内部时钟不一致时,往往会选择FIFO作缓冲。
      1. 选择异步时钟,点击NEXT,弹出的界面如图5所示,本页面介绍了如何平衡延时,最高时钟频率,面积,亚稳态保护等之间的关系。

图5

    • 低延迟,只有一个时钟的延迟(是指从写入当前数据到读出当前数据的延迟,一般指FIFO空时写入一笔数据到该笔数据的读出),但这种模式没有亚稳态保护,在异步时钟时不建议使用。
    •  两个时钟的延迟,有亚稳态太保护,这是异步时钟的最低选择
    •  3个以上的延迟,这种模式对亚稳态保护最好,FIFO的读写速度 (fmax)也可以达到最大,在异步时钟时推荐使用。
    • 点击next,弹出对话框如图6

图6

    • 控制及状态信号选择,图6显示了可用的控制及状态信号,这些可以有效地用于控制FIFO的操作。
        • 读端:有满(full),空(empty), 现存数据(usedw[]指当前FIFO中有多少数据尚未读出)。如果选择了usedw还可以配套选择Add an extra MSB to usedw, 该项选择的目的用于指示FIFO半空或半满。一般在读端选择的控制信号为空(empty),或usedw(with MSB),根据实际需要选择。注意这些信号都与读端的时钟同步,特别应注意rdreq,empty,FIFO 中剩余数据的时序关系,后续课程中会通过编程应用实例进行分析介绍。
        • 写端:有满(full),空(empty), 现存数据(usedw[]指当前FIFO中有多少数据尚未读出)。如果选择了usedw还可以配套选择Add an extra MSB to usedw, 该项选择的目的用于指示FIFO半空或半满。一般在写端常用的选择信号为满(full),或usedw(with MSB)。注意这些信号都与写端的时钟同步,特别应注意wrreq,empty,FIFO 中剩余数据的时序关系,后续课程中会通过编程应用实例进行分析介绍。
        • 按图6选择后点击next, 弹出对话框如图7,

图7

    • 图7描述了FIFO在读操作数据输出方式,
        • FIFO输出数据在rdreq为高电平(‘rdreq’ is asserted)后,才会有有效数据输出,其含义是正常情况下FIFO写入的数据都在FIFO形成的存储器中,当rdreq有效后在FIFO的输出端口上才会得到FIFO内部数据中最先写入的数据。此时rdreq被认为数据请求或使能。
        • 先得到数据,即在rdreq有效前先有一笔有效数据放在输出端口上,因此可以先使用后置位 rdreq, 或同时使用同时置位。此时rdreq被认为数据应答。
        • FIFO使用的存储器类型,在 FPGA 中一般有M9K, M144K,MLAB 等类型可以使用,M9K 是指 memory black的容量总9K bits, 144K 为144K bits, MLAB不是memory block的结构,而是由查找表组成的逻辑单元构成。这里选择M9K 或直接选择Auto类型。
        • 按图7选择后点击next, 如图8

图8

    • 图8中介绍了需要的时候可以省略full 或empty信号。省略这两个信号会带来一定的风险。只有极少数的应用场景才会使用,一般是同步时钟而且写入和读出的速度相同,FIFO内存储的数据始终维持在同一个水平(如watermark不变),典型的应用是利用FIFO提供信号延迟,这种用法在数字信号处理以及无线信号处理中应用比较常用。

选择”Implement FIFO storage with logic cells only,even if the device contains memory blocks” 将会利用内部的逻辑单元生成FIFO,即使FPGA内有memory block。如果FIFO使用的存储单元较多,将会占用大量的FPGA逻辑单元的资源。较好的选择是在图7中选AUTO ,图8中该项处在非选中状态。点击next,弹出对话框如图9,

图9

    • 图9提示了,在仿真时需要alrera_mf宏函数库。点击next,弹出对话框如图10,

图10

    • 图10列出了将会生成的文件,根据需要选择,点击finish.
  1. 例化并修改接口
    1. 生成的FIFO模块将会自动添加到测试工程中,如图11,

图11

  • 修改test_fifo.v文件,并对fifo1模块例化,修改后的源文件如下,

module test_fifo

#(parameter IN_WIDTH=32,

parameter OUT_WIDTH=32,

parameter DEEP=256

)

(

input inclk,

input rst,

input wren,

input rden,

input [IN_WIDTH-1:0] datain,

output [OUT_WIDTH-1:0] dataout,

output rdempty,

output[$log2(DEEP):0] wrusedw,

output wrfull,

output[$log2(DEEP):0] wrusedw,

);

fifo1 fifo1_inst

(

.data ( datain ),

.rdclk ( rdclk ),

.rdreq ( rdreq ),

.wrclk ( wrclk ),

.wrreq ( wrreq ),

.q ( data_out ),

.rdempty ( rdempty_sig ),

.wrfull ( wrfull ),

.wrusedw ( wrusedw )

);

endmodule

  • 编辑完成后存储,可以编写testbench文件进行测试。测试内容在后续章节中介绍。

 

Posted in FPGA, FPGA 教材教案, FPGA硬件资源, Quartus II, Quartus II, 教材与教案, 文章

发表评论

您的电子邮箱地址不会被公开。

Leave the field below empty!

相关链接