XILINX FPGA 7系之 CLB/LUT 可以知道 CLB 是基本的组成单元,SLICE 也是 CLB 的基本组成单元,为了更好的使用 XILINX FPGA ,有必要在深挖一下 Distribute RAM(分布式内存);
XILINX 的 “ ug474_7Series_CLB.pdf ” 文档的 “Ch.2 中的 Distribute RAM ”章节有对此的详细描述
值得注意的是 XILINX CLB 的 LUT内部结构决定,Distribute RAM 只能够由 SLICEM 组成,SLICEL 是无法组成 Distribute RAM 的;SLICEM 构成 Distribute RAM 是通过其中的 LUT 实现的,1 个 SLICEM 是如下的结构:
可以看到 1 个 SLICEM 有 4 个 LUT,每个 LUT 都是 6 输入,所以 1 个 LUT 可以寻址空间是 2^6=64bits,那么 4 个 LUT 便可以级联组成 4x2^6=256bits,即,一个 SLICEM 最大可以包含 256bits RAM内容;
通过配置可以使用 1 个 SLICEM 实现如下 RAM:
- Single-Port 32 x 1-bit RAM
- Dual-Port 32 x 1-bit RAM
- Quad-Port 32 x 2-bit RAM
- Simple Dual-Port 32 x 6-bit RAM
- Single-Port 64 x 1-bit RAM
- Dual-Port 64 x 1-bit RAM
- Quad-Port 64 x 1-bit RAM
- Simple Dual-Port 64 x 3-bit RAM
- Single-Port 128 x 1-bit RAM
- Dual-Port 128 x 1-bit RAM
SLICEM 的 LUT 信号描述如下:
- 地址输入:A6:A1 W6:W1
- 数据输入:DI1 DI2
- 时钟输入:CK
- 写使能 :WE
- 数据输出:O6 O5
- 移位输出:MC31 (在此处不使用)
分布式 RAM 使用的同样的时钟 clock 输入,对于写操作,WE 信号(被 SLICEM 的 CE或者 WE驱动)必须被拉高;
下面是 XILINX 官方关于构建不同 Distribute RAM 的配置相关的图:
可以看到,在一个 SLICEM 中实现每一种 Distribute RAM 使用的 LUT 资源,同时,通过调用 XILINX 原语也能够搭建出 Distribute RAM;
这里有必要解释一下 Single/Dual/Qual/Simple Port:
Single Port :单口 RAM,读写使用同样的地址总线;
Dual Port:双端 RAM,一个通道共享读写,另一个通道只读通道;
Simple dual port:双端 RAM,一个读通道,一个写通道;
Quad Port:4 通道 RAM,一个读写共享通道,3个读通道;
值得注意的是,最左边的 4 个 LUT 并不是一样的:
D LUT 和A、B、C LUT有所区别,其地址输入都由D6:1驱动,而其它LUT的地址输入除了W6:1统一由D6:1驱动,A6:1分别由A6:1、B6:1、C6:1驱动,因此 D LUT只能作为单端口RAM使用,而A、B、C LUT除了能作为单端口RAM使用之外,还能作为双端口RAM。
对于 32 X 2 Quad Port 的情况,如下所示:
从此可以看出:
1、A6 和 WA6 需要被拉高,因为需要保持 O5 和 O6 需要输出独立;
2、DI1和DI2 是数据输入端口,DI1 由 DI 驱动,DI2 由 AX/BX/CX/DX 驱动,也就是输入端为 D[1:0] 一共两位;
3、WCLK 为每个 LUT 提供时钟;
4、WED 为每个 LUT 提供 WE 信号;
5、第一个 LUT 读写公用地址信号 WA 作为写地址信号,其他的 3 个 LUT 都用这个作为写地址信号;
6、输出端为 DOA[1:0]、DOB[1:0]、DOC[1:0]、DOD[1:0];
对于 32 X 6 Simple Dual Port 的情况,如下所示:
1、A6 和 WA6 需要被拉高,因为需要保持 O5 和 O6 需要输出独立;
2、读写地址总线分开,读地址总线由 RADDR[5:1]提供,连接到 A[6:1] 的A[5:1],写地址总线由 WADDR[5:1]提供,直接连接到每个 LUT 的WA [5:1];
3、读写数据总线分开,写数据有DATA[5:1] 提供,读数据总线为 O[5:1];
4、WCLK 为每个 LUT 提供时钟;
5、WED 为每个 LUT 提供 WE 信号;
对于 6 X 1 Single Port 的情况,如下所示:
在使用单口 64bit RAM 的时候,需要达到 64bits的寻址,所以 A[5:0] 需要全部有效,共享读写地址总线和数据总线,D 为数据输入,O 为输出;
64 X 1 Dual Port 的情况:
当然,寻址空间为 64bits,所以地址线需要 6 根,独立的读写地址总线(A[5:0] 是写地址总线,DPRA[5:0] 是读地址总线),数据输入为 1 bit 宽度的 D,输出输出为 SPO/DPO;
对于 64 X 1 Quad Port 类型的 RAM 如下所示:
4个 LUT 构成,读写地址通道分开,一个写地址通道 D[6:1],三个读地址通道 A[6:1]、B[6:1]、C[6:1];
输入数据通道为 1bit 的 DI,读数据通道为 DOA、DOB、DOC;
64 X 3 Simple Dual Port 的构成如下所示:
不再多说,数据通道 DATA[3:1] ,写地址通道 WADDR[6:1],读地址通道 RADDR[6:1],数据输出通道 O[3:1]
128 X 1 Signle Port 如下所示:
略
128 X 1 Dual Port 如下所示:
略
256 X 1 Signle Port 如下所示:
256 bit 是一个 SLICEM 最大能够支持的 4 个 LUT x 每个 LUT 的 2^6 = 256bit 寻址空间;
可以看到输入地址变为了 A[7:0] ,也就是 2^8=256bit,8bit 的地址到每个 LUT 进行了处理,并将地址的 A6 接入到了 F7BMUX 和 F7AMUX 同时 A7 接到了 F8MUX,来进行 LUT 的输出选通信号,级联成为 256bits RAM;
除了上述各种情况,如果需要更大的 RAM 空间,那么 1 个 SLICEM 就搞不定了,需要多 SLICEM 进行级联;
同步写 Distributed RAM:
同步写入只需要单个时钟周期边沿即可,当然 WE 需要处于高电平;
异步读 Distributed RAM:
当地址线上的信号有效,数据会在访问指定地址的 LUT 的延时后,再数据线上变得有效;
SLICEL 和 SLICEM 的每个函数发生器(LUT)都可以实现一个 64 x 1-bit 的 ROM;这里有 3 种类型的 ROM:
ROM64X1
ROM128X1
ROM256X1
最后,
Xilinx公司的这种分布式RAM结构在需要少量RAM的情况下可以代替Block RAM使用,毕竟在7系列FPGA中一块Block RAM就有36Kbits。以下列举了一些适用于分布式RAM的情况:
1. 深度小于64-bit
2. 在深度大于64-bit小于128-bit情况下,有时延要求并需要异步输出(其clock-to-out时间小,并且布线比Block RAM自由)
3. 数据宽度小于16-bit
毕竟分布式 RAM 使用了 LUT 资源,本来就有 BRAM,不用白不用;
参考文献:
https://blog.csdn.net/huxiaokai2005/article/details/89460324
来源:CSDN
作者:混子老腊肉
链接:https://blog.csdn.net/zhoutaopower/article/details/103967664