目录
一、什么是RAM
二、RAM IP介绍
1、RAM分类简介
2、可选的内存算法
(1)Minimum Area Algorithm(最小面积算法)
(2)Low Power Algorithm (低功耗算法)
(3)Fixed Primitive Algorithm (固定模块算法)
(4)小结
3、位宽
4、工作模式(对于每个端口来说都是独立设置的)
(1)Write First Mode(写优先模式)
(2)Read First Mode(读优先模式)
(3)No Change Mode(保持模式)
(4)小结
5、数据位宽比
6、字节写(Byte-Writes)
7、可选的输出寄存器
8、可选的流水线(Optional Pipeline Stages)
9、关于可选寄存器的额外引脚
三、总结
一、什么是RAM
RAM 的英文全称是 Random Access Memory,即随机存取存储器,它可以随时把数据写入任一指定地址的存储单元,也可以随时从任一指定地址中读出数据,其读写速度是由时钟频率决定的。RAM 主要用来存放程序及程序执行过程中产生的中间数据、运算结果等。
在FPGA中我们讨论RAM时一般分成2种:由LUT资源配置的分布式RAM(DRAM),嵌入式的RAM(BRAM),这里我们考虑的是BRAM。
xilinx为了帮助开发者更好地使用BRAM资源,为我们提供了RAM IP核,这就是我们今天的主角:Block Memory Generator v8.4
二、RAM IP介绍
xilinx的BRAM资源可以被配置成3种形式的RAM:单端口RAM,简单双端口RAM,真双端口RAM
1、RAM分类简介
(1)Single-Port RAM(单端口RAM)
只有一个端口,读写共用相同的地址总线,读写不能同时进行
(2)Simple Dual-port RAM(简单双端口RAM)
两个端口A和B,一个用来写(A),另一个用来读(B),通过A端口写入的数据可以通过B端口读出
(3)True Dual-port RAM(真双端口RAM)
两个通道都支持读写,互相独立。A端口和B端口可同时读写数据
2、可选的内存算法
在这里我们讨论的是BRAM的底层资源,BRAM在FPGA中是整块的形式存在,一块BRAM的大小为36Kb。它可以分成2块18Kb的RAM进行使用,这也是FPGA中BRAM的最小存在形式。针对这种情况,xilinx给出了3种内存算法:最小面积算法,低功耗算法,固定模块算法。
(1)Minimum Area Algorithm(最小面积算法)
最小面积算法提供了一个高度优化的解决方案,可以使得我们使用到的BRAM资源最少,同时减少输出多路复用。这里有2个最小面积算法的例子:
在第一个例子(左边)中,一个3k × 16的存储单元用到了3个RAM(每个都是18Kb), 尽管我们也可以用3个1k × 18的方式来实现,但是这样会使用更多的数据选择器,最小面积算法以这种方式最大化性能,同时保持最小块RAM的使用。
在第二个示例(右边)中,一个5k x 17的存储器,进一步演示了该算法如何能够有效地封装BRAM,以使用最少的资源,同时通过减少输出多路复用来最大化性能。
(2)Low Power Algorithm (低功耗算法)
低功耗算法使得在读写操作发生时使能的BRAM块最少,其实就是字面意思实现了低功耗算法,由于没有进行面积优化,这样可能会占用较多的资源。同样的我们有2个低功耗算法的例子:
(3)Fixed Primitive Algorithm (固定模块算法)
固定模块算法允许开发者设定一个RAM的原语类型(其实就是确定了RAM的位宽和深度,例如16k x 1, 8k x 2, 4k x 4, 2k x 9, 1k x 18, 512 x 36),然后系统就只会使用这种类型的RAM。同样的我们举两个例子:
在左图中我们限制只能用2k × 9 的RAM,在右图中我们限制只能用4k × 4的RAM。
(4)小结
其实对于我们一般的,没有特殊需求的FPGA设计来说,这里的内存算法造成的性能差异并不是很大,这里主要是做一个了解,以免在实际使用时留下疑惑。
3、位宽
单口 | 一个36Kb的Block RAM支持的最大数据位宽是72,一个18Kb的Block RAM支持的最大数据位宽是36 |
简单双口 | 一个36Kb的Block RAM支持的最大数据位宽是72,一个18Kb的Block RAM支持的最大数据位宽是36 |
真双口 | 一个36Kb的Block RAM支持的最大数据位宽是36,一个18Kb的Block RAM支持的最大数据位宽是18。所以在相同的位宽和深度的情况下,真双口RAM使用的Block RAM的个数是单口/简单双口RAM的两倍 |
4、工作模式(对于每个端口来说都是独立设置的)
真双口RAM或简单双口RAM的读写会有发生冲突的可能性,对于简单双口RAM而言,通过A端口写入数据同时通过B端口读出数据时,存在读-写冲突的可能性;对于真双口RAM而言,通过一个端口写入同时通过另一个端口读出数据,同样也存在读-写冲突的可能性,而且在通过两个端口同时写入数据时,还存在写-写冲突的可能性。为了解决这样的问题,xilinx提供了3种不同的端口模式来进行规范:WRITE FIRST(写优先), READ FIRST(读优先), and NO CHANGE(保持)
(1)Write First Mode(写优先模式)
在写优先模式下,当RAM通过某个端口向写地址写入数据的同时,写入的数据也会被驱动到数据的输出端口。也就是说,在写操作期间,数据输出端口会输出写地址中的最新数据。
我们以上图的案例来进行讲解,在第二个时钟上升沿,读写操作同时进行,就发生了我们所说的读-写冲突 ,此时我们需要将数据1111写入地址bb,同时需要从地址bb中读出数据,在写操作优先模式下,数据1111在写入地址bb的同时,也被驱动到了数据输出端,所以我们最终读出的数据就是我们写入的1111 。在第三个时钟上升沿也是同理,最终地址cc读出的数据就是此时刻写入的数据2222 。
(2)Read First Mode(读优先模式)
在读优先模式下,当RAM通过某个端口向写地址写入数据的同时,写地址中的旧数据会被驱动到数据输出端口。也就是说,在写操作期间,数据输出端口会输出写地址中的旧数据。
从上图的案例可以看出,在第二个时钟上升沿,读写操作同时进行,我们需要向地址bb写入数据1111,同时需要从地址bb中读出数据,在读优先模式下,我们读出的数据是地址中原来的数据,所以这里输出数据为old MEM(bb)。同理,在第三个时钟周期读出的数据是old MEM(cc) 。
(3)No Change Mode(保持模式)
当RAM通过某个端口向写地址写入数据的同时,输出锁存器保持不变。在写操作期间,数据输出端口不会输出写地址的数据,而是保持上次读地址的数据。
以上图为例,在第二个时钟上升沿有数据1111写入地址bb,在第三个时钟上升沿有数据2222要写入地址cc,同时我们要进行读数据操作,在保持模式下,读数据不会改变,所以我们的输出依然是上一时刻的输出,即MEM(aa)。
(4)小结
我们可以根据定义端口的模式来规范端口的读写操作,防止无法预测的错误出现,但是在实际进行RAM设计的时候,如果两个端口的读写时钟不同(单端口不存在这样的问题),我们还是要尽可能地在设计时就避免读-写冲突和写-写冲突。
5、数据位宽比
我们所讨论的这个IP核支持让端口之间的位宽不同也就是说端口A和端口B可以设置成不同的位宽,所有的4条数据总线都可以拥有不同的位宽:dina(A端口输入),douta(A端口输出),dinb(B端口输入),doutb(B端口输出)。
但是数据位宽不是任意设置的,还是具有一定的限制,具体为位宽之间必须满足一定的比例:1:32, 1:16, 1:8, 1:4, 1:2, 1:1, 2:1, 4:1, 8:1, 16:1, 32:1。
6、字节写(Byte-Writes)
BRAM的IP核还支持字节写的操作,每个字节的位宽可以是8 bit或者9 bit 。当字节宽度为8 bit的时候,没有校验位(就是我们正常认知的一个字节的宽度)RAM宽度被设定为8的倍数,当字节的宽度为9 bit的时候,额外增加了一位奇偶校验位,RAM宽度被设定为9的位数。
当字节写模式启用时,使能信号wea/web是N位宽的(N是数据din的比特数)。这样可以使得使能信号与我们的输入数据的字节是一一对应的关系,只有当使能信号有效,对应比特位的数据才会被写入。
我们举个例子来理解字节写操作:
这是一个单口RAM,数据位宽位32bit(也可以说是3个字节),写使能信号WEA位宽为3,在第一个时钟沿,WEA为3'b011,意思是第一个byte无效,其他两个有效,所以最终写入的数据只有后两个byte有效,即DINA = FF EE DD,但是写入的数据为00 EE DD(00即没有数据写入,这里设定所有的RAM都初始化为0了)。后面的例子都可以以此类推,这里就不做展开了。
7、可选的输出寄存器
BRAM的IP核提供了可选择的寄存器,它也许可以提高IP核的表现。开发者可以在两个地方选择添加寄存器:在块RAM原语的输出处和在ip核的输出处。
在BRAM原语输出处的寄存器可以减少时钟输出延迟的影响。在IP核输出处的寄存器,通过输出多路复用器隔离延迟,改善IP核的时钟输出延迟。对于端口A和端口B,可以分别选择这两个可选的寄存器。请注意,所使用的每个可选寄存器都会为Read操作添加了一个额外的时钟延迟周期。
8、可选的流水线(Optional Pipeline Stages)
除了可选的寄存器输出,这个IP核还提供了可选的流水线输出结构,用户可以设置0~3级流水。这是因为大容量的RAM往往需要通过多个BRAM级联组成,而多个BRAM则会使用到多个MUX来进行控制,MUX作为一个组合逻辑器件,无疑会引入潜在的亚稳态问题,所以为了改善时序,额外引入了寄存器,最终构成了0~3级可选的流水线管道。
9、关于可选寄存器的额外引脚
可选寄存器的引入之后,IP核还为我们提供了诸多例如时钟使能,复位等各种功能的引脚和设计帮助,这里不做展开,需要用到时自行查阅手册即可。
三、总结
BRAM的IP核很常用,本文提取了部分常规使用中重点的内容进行详细展开,主要要知道BRAM可以实现单端口,简单双端口,真双端口三种模式的RAM。端口可以独立的设置工作模式来应对读写冲突,写写冲突,但是我们还是要尽可能避免冲突的发生。此外IP核也给我们提供了很多的附加功能,可供用户根据需要自行设计选择。关于BRAM IP核的具体使用和案例,请阅读:
FPGA原理与结构——RAM IP核的使用与测试