在一个项目中使用 FIFO 时,综合过程中出现了如下错误:
[Place 30-640] Place Check:This design requires more BRAM36/FIFO cells than are avaliable in the target device. This Design requires 534 of such cell types but only 445 compatible sites are avaliable in the target device. Please analyze your synthesis results and constraints to ensure the design is mapped to Xilinx primitives as expected. If so, please consider targeting a larger device.
突然意识到,是 BRAM 资源使用的不合理。
另外,如果ILA 调试的时候加载了太多数据,也会导致 BRAM 使用资源溢出。
同样,先看 Xilinx 官方文档ug473 7 Series FPGAs Memory Resources对 BRAM 资源的介绍。
一、Block RAM Introduciton
In addition to distributed RAM and high-speed SelectIO™ memory interfaces, 7 series
ug473 7 Series FPGAs Memory Resources,page 14
devices feature a large number of 36 Kb block RAMs. Each 36 Kb block RAM contains two
independently controlled 18 Kb RAMs. Block RAMs are placed in columns, and the total
number of block RAM resources is listed in Table 1-2 by the 7 series device. The 36 Kb
blocks are cascadable to enable a deeper and wider memory implementation, with a
minimal timing penalty.
在手册中了解到,7 系列的设备都有较大容量的 36Kb block RAMs。每个 36Kb block RAM 包含两个独立控制的 18Kb RAMs。这些 36Kb 的 block 可以级联可以在最小的时序损失下,实现深度更深或者位宽更宽的存储。
例如,查表可知 7K325T 的 Block RAMs 分为 7 列,每一列有 70 个,总共有 490 个,但是用户可用的总共有 445 个 36 Kb Block RAM。
其余的 45 个 36 Kb Block RAM 用做专用资源。
- The right side column contains GTP/GTX Quads that displace ten block RAM blocks in that column per GTP/GTX Quad.
ug473 7 Series FPGAs Memory Resources,page 15
- The column containing Gen1/Gen2 interface blocks for PCI Express® displaces five block RAM blocks per interface block for PCI Express. Block RAM blocks cannot be cascaded across interface blocks for PCI Express.
二、FIFO 的 BRAM 消耗
手册中也有对内部资源使用的介绍:
Embedded dual- or single-port RAM modules, ROM modules, synchronous FIFOs, and
ug473 7 Series FPGAs Memory Resources,page 15
data width converters are implemented using the Xilinx CORE Generator™ block memory
modules. Dual-clock FIFOs can be generated using the CORE Generator FIFO Generator
module. The synchronous or asynchronous (dual-clock) FIFO implementation does not
require additional CLB resources for the FIFO control logic because it uses dedicated
hardware resources.
直译:
嵌入式双端口或单端口 RAM 模块,ROM 模块,同步 FIFO 和数据宽度转换器是使用 Xilinx CORE Generator™块存储模块实现的。 可以使用 CORE Generator FIFO 生成器模块生成双时钟 FIFO。 同步或异步(双时钟)FIFO 实现不需要用于 FIFO 控制逻辑的其他 CLB 资源,因为它使用了专用的硬件资源。
也就是说,使用 FIFO 的时候如果选用 BRAM 存储类型,FIFO 的容量也就取决于片上 BRAM 的容量;
手册中也有给出不同类型的 FIFO 容量,深度与位宽的关系:
在 Standard 模式下,18Kb BRAM 指的是位宽为 18bits,深度为 1K 的 RAM 块。同样 36Kb BRAM 指的是位宽为 36bits,深度为 1K 的 RAM 块。
从上表中能够看出来,使用 1 个 18Kb BRAM 的最大位宽及对应深度为为 36bits * 512,最大深度及对应位宽为 4bits * 4k。
其实,这里还有一个疑问:为啥 Xilinx 选用 36K 来做为一个 Block RAM 的容量呢?
BRAM 的容量是 18K + 18K。我的理解是,为了实现 byte write 这个功能(微处理器等利用很方便),就决定了最小因子是 8,然后加了一个校验位,最小因子就是 9 了,所以用了 18K 这个 9 的倍数,感觉如果是 9K 就切的比较碎了;如果直接一整个 36K,就显得有点大,有时候用不完就容易浪费。
三、FIFO 位宽深度对 BRAM 消耗的影响
如果用户 FIFO 的位宽和深度与上述表格不匹配,在 FIFO Generator 中,会自动计算需要的 BRAM 个数。
举例如下:
- 位宽为 16bits,深度不大于 1024,则需要 18K 的 BRAM 1 个;
- 位宽为 32bits,深度不大于 512 ,则需要 18K 的 BRAM 1 个;
如果位宽大于等于 36bits,那么就需要使用 36K 的 BRAM 了;即如果位宽为 40bits,深度不大于 1024,就需要 36K 的 BRAM1 个。
下面是特例的情况:
(1)如果位宽很宽而深度很浅的情况下,比如位宽 256bits,深度 16
此时需要用 36K 和 18K 的 BRAM 来先凑位宽。一个 18K 的 BRAM 支持位宽为 36bits 以内;一个 36K 的 BRAM 支持位宽为 72bits 以内。
72 * 4 = 288 bits;
所以,至少需要 4 个 36K BRAM,深度也就固定下来最大为 512;在 FIFO Generator 中的 Summary 也可以得到同样的 BRAM 资源分配方式:
这样,本来缓存的数据容量为 256 * 16 = 4 K;而现在却使用了 36 * 4 = 144 K 的容量实现。这就是导致最终 BRAM 不够使用的原因。
(2)再假如需要位宽为 512bits,深度为 16;
72 * 7 + 18 = 522 > 512 bit;
因此,至少需要 7 个 36K BRAM 和 1 个 18K BRAM,深度最大为 512; 在 FIFO Generator 中的 Summary 也可以得到同样的 BRAM 资源分配方式:
与刚才类似,这里因为 FIFO 位宽太长,而深度使用不足的原因也造成了非常多的 BRAM 资源没有使用。
四、怎样避免 BRAM 的浪费
控制好 FIFO 的位宽与深度数值,尽量用满一个 BRAM 之后,再启用第二个甚至更多的 BRAM。
比如想将 768bits 位宽的 48 组数据存储到 FIFO 中:
按照之前的计算需要使用 11 个 36K BRAM 存储,深度 512 只使用了 24;
可以先将 768bit 数据,切分为 4 小组,每组位宽为 192bits;按照 192bit 的位宽存储到 FIFO 中,这样深度就变成为 48 * 4 = 192;
需要使用 3 个 36K BRAM 就可以存储了,虽然还是有很多浪费的空间,但是可比上面节约多了。
根据需求,数据从 FIFO 读出后,也须要进行位拼接,拼接成之前的 768bits(是不是感觉有点繁琐)。
当然,这样也有一定的局限性,即牺牲了数据传输的时间,因为数据切分成片段,是 Delay 一段时间的,分的越零碎,需要的时间也就越长。
还有 FIFO 的读写位宽降低,读写时钟不变,所以 FIFO 的带宽也降低了。
总结
使用 FIFO 的时候需要注意数据位宽,与数据深度,对占用的 BRAM 资源大小的影响,要避免设计超出 FPGA 的 BRAM 资源。
扫码关注尚为网微信公众号
原创文章,作者:sunev,如若转载,请注明出处:https://www.sunev.cn/embedded/1265.html