先给出结论:当配置的RAM深度不超过512(≤512)并且位宽超过54(>36+18)的情况下,简单双口RAM的资源就会是真双口RAM资源的一半。
在以前使用双口RAM的时候,总会选择使用真双口RAM,觉得这样很方便,但是殊不知相比简单双口RAM会多消耗几乎一倍的资源。
下面就详细说说为什么会造成这样的结果。
目录
三、A端口4096bit×64,B端口128bit×2048举例
一、宽度为1bit深度为32K
在宽度为1bit、深度为32K情况下各种RAM的资源使用情况
RAM类型 | 实现算法 | 36KRAM使用数量 | 18KRAM使用数量 |
---|---|---|---|
单口RAM | 最小面积 | 1 | |
低功耗 | 2 | ||
固定原语 | 2 | ||
简单双口RAM | 最小面积 | 1 | |
低功耗 | 2 | ||
固定原语 | 2 | ||
真双口RAM | 最小面积 | 1 | |
低功耗 | 2 | ||
固定原语 | 2 |
我们可以发现三者在同一实现算法二点情况下使用数量均相同。
关于实现算法的区别可以参考之前的文章:
Xinlinx FPGA内的存储器BRAM全解-CSDN博客
二、两个端口写宽度均为4096深度为64举例
在宽度为4096bit、深度为64情况下各种RAM的资源使用情况
RAM类型 | 36KRAM使用数量 | 18KRAM使用数量 |
---|---|---|
简单双口RAM | 57 | 0 |
真双口RAM | 114 | 0 |
简单双口
真双口
我们来分析以下为什么是这样的使用量。
1.真双口RAM
(1)Vivado综合结果
首先按照要求生成对应的IP核,均采用最小面积算法生成,综合后得到下面的电路图。
将电路图放大可以发现一共有114个RAMB36E1,并且可以发现:
- ram[0]中外部按照36bit信号输入,对于A端口来说,输入连接到DIADI[31:0]和DIPADI[3:0],输出通过DOADO[31:0]和DOPADOP[3:0]连接到douta[35:0],对B端口也是同样的情况。然后114*36=4096bit,等于两个端口的读写位宽。
- ram[1]至ram[112]和ram[0]一致;
- ram[113]中由于前面113个ram每个输入了36bit数据,这里还留下4096-113*36=28bit数据,因此最后一个ram两个端口的输入数据和输出数据位宽都只有28bit。
(2)原因分析
首先明确很重要的一个点,在可配置位宽最大情况下:
36KB的真双口RAM可以配置成1K(深度)×36(宽度)模式。
36KB的简单双口RAM可以配置成512(深度)×72(宽度)模式。
正是这个原因造就了简单双口在横向上可以采用一半的数量实现同样的宽度。
实际上真双口RAM综合时的思路应该是按照下面的图进行的:
2.简单双口RAM
(1)Vivado综合结果
首先按照要求生成对应的IP核,均采用最小面积算法生成,综合后得到下面的电路图。
将电路图放大可以发现一共有57个RAMB36E1,并且可以发现:
- ram[0]中外部按照72bit信号输入,这是由于36KB的简单双口RAM可以配置成512(深度)×72(宽度)模式。对于A端口来说,输入连接到DIADI[31:0]、DIPADI[3:0]、DIPADIP[3:0]、DIPBDIP[3:0],输出通过DOADO[31:0]、DOBDO[31:0]、DOPADOP[3:0]和DOPBDOP[3:0]连接到douta[71:0],对B端口也是同样的情况。然后114*36=4096bit,等于两个端口的读写位宽。
- ram[1]至ram[55]和ram[0]一致;
- ram[56]中由于前面56个ram每个输入了72bit数据,这里还留下4096-56*72=64bit数据,因此最后一个ram输入数据和输出数据位宽都只有64bit。
(2)原因分析
36KB的简单双口RAM可以配置成512(深度)×72(宽度)模式。
简单双口RAM综合时的思路应该是按照下面的图进行的:
三、A端口4096bit×64,B端口128bit×2048举例
在A端口4096bit×64,B端口128bit×2048情况下各种RAM的资源使用情况
RAM类型 | 36KRAM使用数量 | 18KRAM使用数量 |
---|---|---|
简单双口RAM | 64 | 0 |
真双口RAM | 128 | 0 |
简单双口
真双口
我们来分析以下为什么是这样的使用量。
1.真双口RAM
(1)Vivado综合结果
首先按照要求生成对应的IP核,均采用最小面积算法生成,综合后得到下面的电路图。
将电路图放大可以发现一共有128个RAMB36E1,并且可以发现:
- ram[0]中,对于A端口来说,外部按照32bit信号输入,连接到DIADI[31:0],输出通过DOADO[31:0]连接到douta[31:0],对B端口,外部按照1bit信号输入,连接到DIBDI[0],输出通过DBDO[0]连接到doutb。128×32=4096bit,128×1=128bit,等于两个端口各自的读写位宽。这里我们就可以发现和之前第二章讲的真双口RAM有区别了。
- ram[1]至ram[127]均和ram[0]一致;
那我们来思考一下为什么会有这样的差异?两者中变化的只有读的位宽和深度发生了改变。
RAM类型 | A端口宽度 | A端口深度 | B端口宽度 | B端口深度 |
---|---|---|---|---|
第一种真双口RAM | 4096 | 64 | 4096 | 64 |
第二种真双口RAM | 4096 | 64 | 128 | 2048 |
假若我们依然采用第一种双口RAM的实现方式,按照1K×36进行实现,那我们需要114个RAM才能够实现。那此时的B端口数据接口该如何处理呢?B端口的数据宽度有128,如果按照前113个RAM1bit存储,最后一个RAM存储15bit按理说也是可以的,但是Vivado并没有选择这种方式,不知道是不是综合器认为当前面RAM的宽度都用掉之后后面的才把多的补到最后一个RAM还是别的什么原因。
(2)实现方式
真双口RAM综合时的思路应该是按照下面的图进行的:
2.简单双口RAM
(1)Vivado综合结果
首先按照要求生成对应的IP核,均采用最小面积算法生成,综合后得到下面的电路图。
将电路图放大可以发现一共有64个RAMB36E1,并且可以发现:
- ram[0]中,对于A端口来说,外部按照64bit信号输入,连接到DIADI[31:0]和DIBDI[31:0];对B端口,输出通过DOADO[1:0]连接到doutb。64×64=4096bit,64×2=128bit,等于两个端口的读写位宽
- ram[1]至ram[63]均和ram[0]一致;
(2)实现方式
简单双口RAM综合时的思路应该是按照下面的图进行的:
四、何时会发生资源相差一半的情况
综上我们可以发现有时两者资源使用量一致,有时就会相差一倍,那何时会发生资源相差一半的情况?
为了得到答案,我们再尝试几种情况:
面对上述情况我们可以知道,如果资源相差了一倍那一定说明是简单双口RAM能够被配置成72bit位宽而真双口RAM只能配置成36bit位宽。此时简单双口RAM的深度为512而真双口RAM的深度为1024。
因此只要当配置的RAM深度不超过512(≤512)并且位宽超过54(>36+18)的情况下,简单双口RAM的资源就会是真双口RAM资源的一半。(至于为何是54下午给出解释)
我们以深度为512宽度为55为例,在Vivado的BRAM IP核的Summary中可以看到资源使用情况如下:
RAM类型 | 36KRAM使用数量 | 18KRAM使用数量 |
---|---|---|
简单双口RAM | 1 | 0 |
真双口RAM | 2 | 0 |
以深度为513宽度为55为例:
RAM类型 | 36KRAM使用数量 | 18KRAM使用数量 |
---|---|---|
简单双口RAM | 2 | 0 |
真双口RAM | 2 | 0 |
那如果深度不超过512,宽度大于32而小于等于54,这个时候资源就达不到一半了。因为此时会采用36Kb+18Kb组合的方式,如对于深度为512,位宽为54的情况:
以深度为512宽度为54为例:
RAM类型 | 36KRAM使用数量 | 18KRAM使用数量 |
---|---|---|
简单双口RAM | 1 | 0 |
真双口RAM | 1 | 1 |
简单双口:
真双口: