【FPGA IP系列】FIFO深度计算详解

本文转载自:FPGA入门到精通(微信号:weilaikejisaidao)

FIFO(First In First Out)是一种先进先出的存储结构,经常被用来在FPGA设计中进行数据缓存或者匹配传输速率。

本文主要介绍FIFO深度计算的方法,FIFO的一个关键参数是其深度,也就是FIFO能够存储的数据条数,FIFO深度设计的合理,可以防止数据溢出,也可以节省FPGA资源的消耗。

一、FIFO深度计算影响因素

影响FIFO深度计算的主要因素包括:

  • FIFO的位宽:决定了每个FIFO存储单元的大小
  • FIFO的数据字长:决定每个数据词包含多少比特有效数据
  • FIFO的总存储容量:决定最大可以存储的数据条数
  • 以32位位宽,8位字长的FIFO为例,每个FIFO存储单元需要32/8=4个字节。

    如果FIFO总容量为128字节,那么可以存储128/4=32个数据。

    此外,FIFO深度还需要考虑:

  • FPGA资源约束条件:过大的FIFO会占用过多资源
  • 实际应用需求:深度过小可能导致数据丢失
  • 存储密度:选择2的整数次幂作为深度可以优化资源利用
  • 综合考虑上述各因素后确定最佳的FIFO深度。

    二、FIFO深度计算步骤

    FPGA FIFO深度计算的基本步骤如下:

  • 根据传输最恶劣的情况(一段时间内缓存数据量最大的时候),计算剩余数据量(写数据量 - 读数据量)。
  • 根据剩余数据总存储容量/写位宽,计算FIFO最大可存储的数据量
  • 选择大于等于最大数据量的2的幂作为FIFO深度
  • 将FIFO深度转换为二进制表示
  • 如果写比读慢,那就不用担心数据溢出,只有读比写慢的时候,需要考虑fifo深度设计,以防止数据溢出。

    三、Verilog代码示例

    下面是使用Verilog代码计算FIFO深度的示例:

    // FIFO参数
    parameter DATA_WIDTH = 32; // 32位
    parameter WORD_SIZE = 8; // 8位字长
    parameter FIFO_SIZE = 128; // 总容量128字节

    // 每个FIFO存储单元的大小
    localparam FIFO_CELL_SIZE = DATA_WIDTH / WORD_SIZE;

    // FIFO最大可存储数据量
    localparam FIFO_MAX_WORDS = FIFO_SIZE / FIFO_CELL_SIZE;

    // 选择大于FIFO_MAX_WORDS的2的幂
    localparam FIFO_DEPTH = (FIFO_MAX_WORDS > 0) ?
    (2**$clog2(FIFO_MAX_WORDS)) : 1;

    // FIFO深度比特宽
    localparam FIFO_DEPTH_WIDTH = $clog2(FIFO_DEPTH);

    这个示例中,根据位宽32位、字长8位和容量128字节,计算出FIFO深度为32,需要5比特表示。

    四、SystemVerilog代码示例

    下面是使用SystemVerilog编写的等价代码:

    // FIFO参数
    localparam int DATA_WIDTH = 32;
    localparam int WORD_SIZE = 8;
    localparam int FIFO_SIZE = 128;

    // 每个FIFO存储单元的大小
    localparam int FIFO_CELL_SIZE = DATA_WIDTH / WORD_SIZE;

    // FIFO最大可存储数据量
    localparam int FIFO_MAX_WORDS = FIFO_SIZE / FIFO_CELL_SIZE;

    // 选择大于FIFO_MAX_WORDS的2的幂
    localparam int FIFO_DEPTH = (FIFO_MAX_WORDS > 0) ?
    2**(FIFO_MAX_WORDS.log2) : 1;

    // FIFO深度比特宽
    localparam int FIFO_DEPTH_WIDTH = $clog2(FIFO_DEPTH);

    SystemVerilog通过使用内置的log2函数可以简化代码。

    五、FIFO深度计算实例

    下面通过一些具体实例进一步说明FIFO深度计算过程。

    1、匹配数据带宽

    如果FIFO需要匹配指定的数据带宽,那么深度计算要考虑串行化因子的影响。

    例如需要200MHz的串行LVDS接口,使用10位数据,那么单位时间内可以传输200MHz * 10位 = 2Gbps的数据。

    如果后端接口是32位宽,100MHz,,那么其带宽为100MHz * 32位 = 3.2Gbps。为匹配带宽,前端数据需要缓存,此时FIFO深度计算如下:

    后端带宽 = 3.2Gbps
    前端带宽 = 2Gbps
    串行化因子 = 后端带宽/前端带宽 = 3.2/2 = 1.6
    FIFO深度 > 串行化因子 = 1.6

    因此,选择FIFO深度为2才能匹配带宽需求。

    2、防止数据溢出

    如果写入FIFO的数据速率可能高于读取速率,那么需要增加FIFO深度来防止数据溢出。

    场景1:如写入速率是100MB/s,读取速率是80MB/s,允许最大等待时间为50μs,那么需要的FIFO大小计算如下:

    写入速率 = 100MB/s
    读取速率 = 80MB/s
    最大等待时间 = 50μs
    额外存储量 = 写入速率 × 最大等待时间
    = 100MB/s × 50μs
    = 5000bit

    因此,FIFO深度需要考虑额外存储5000bit的数据量,也就是除了正常存储量外还需要确保至少有5000bit的额外FIFO深度。

    场景2:异步FIFO,写时钟100MHZ,读时钟80MHZ。读写位宽均为16bit。已知每100个写周期最多写入960bit数据,读侧每时钟读取一个数据。问:FIFO深度至少为多少?

    最恶劣情况:前100个周期的后连续60个周期写入960bit数据,后100个周期的前连续60个周期写入960bit数据。

    写数据:最大数量为连续120个写周期内,写入数据量960*2bit = 1920 bit,用时为120/100 ns。

    读数据:这段时间内的数据量为 120/100 * 80 * 16bit = 1536 bit 。

    最大缓存数据量为 1920 - 1536 = 384 bit

    写数据最大缓存深度:384/16 = 24

    最大深度需要是2的幂次方,即为32

    3、优化资源利用

    有时为了优化资源利用,可能需要降低FIFO深度。

    例如根据带宽计算,一个18Kb block RAM可以实现depth=512的FIFO,但考虑到资源限制,只能使用一个9Kb RAM,这时可以将FIFO设计为depth=256,节省block RAM资源。

    同样,为了优化资源利用,FIFO深度通常设计为2的整数次幂,这可以减少地址解码逻辑所需资源。

    六、结论

    FIFO深度计算并不复杂,但需要考虑许多实际因素,如带宽匹配、防溢出和资源优化等。一般来说,根据存储需求计算出最大深度,再综合考虑资源和性能约束,选择大于等于该最大深度的2的幂次方作为最终FIFO深度,既能满足存储需求,又可以优化FPGA资源利用。

    最新文章

    最新文章