Menu Close

Vivado真双端口(TDP)RAM IP核的生成与配置详解

前几节课在Vivado下学习并使用了ROM IP核。除了ROM之外,CPU内还有另外一类非常重要的储存类型,RAM(Random Access Memory,随机存取存储器)。相比于ROM只可初始化和进行读操作。RAM更加灵活,可以随时读写存储。RAM的用处十分广泛,可以作为CPU的程序存储器(ITCM),数据存储器(DTCM),可以用于数字信号处理,图像处理等。实际上,在Vivado下生成RAM IP核也比较容易,本节课将讲述在Vivado下配置一个Block Memory的真双端口RAM IP核的详细步骤。

 

1.Vivado下RAM分类

在配置RAM IP核之前,先了解下Vivado可生成RAM IP核的种类。Vivado对于Xilinx 7系列FPGA支持以下3种RAM(可参考文章Xilinx 7系列FPGA Block RAM概述):

  • 单端口RAM
  • 简单双端口RAM
  • 真双端口RAM

它们的特点如下:

  • Single Port RAM,单端口RAM,只有一组地址线,读写分时进行。
  • Simple Dual-port (SDP)RAM,简单双端口RAM,有完整两组数据和地址线,但是一个端口只能读,另外一个端口只能写。
  • True Dual-port (TDP)RAM,真双端口RAM,可以看作是两个单端口RAM共用了相同的存储空间。

注意:简单双端口RAM和真双端口RAM的区别是,简单双端口RAM一个端口只能读,另外一个端口只能写;真双端口RAM的两个端口都可以读写。也就是说,只有真双端口RAM的A端写入接口,只连接了B端的读取接口,真双端口RAM才和简单双端口RAM等效。

 

2.生成RAM IP的步骤与配置选项详解

这里为了使两个端口都可以进行读写操作,将生成真双端口RAM的IP核。

  • 参照之前Vivado下ROM IP核的生成方法,打开Vivado下IP Catalog,在搜索栏中输入“ram”,选择Memories & Storage Elements –> RAMs & ROMs & BRAM –> Block Memory Generator,如下图所示:

图1 选择Block Memory Generator IP核

 

  • 双击IP核,打开之后,界面如下图所示。

图2 Block Memory Generator IP核 Basic

 

  • 选择Interface Type为Native(这里不选择AXI4,关于配置成AXI4接口的例子,在之后会有专门的文章进行讨论)。
  • 在配置Block Memory Generator的过程中可以选择Memory Type,其中就有RAM的选项,这里选择True Dual Port RAM。
  • 在Write Enable下有Byte Write Enable的选项,这里不勾选。

Byte Write可以将数据的Byte Size设定为8-bit的字节宽度,也可以设定为9-bit的字节宽度。9-bit字节宽度包括了8-bit数据和1-bit的奇偶(parity)。设置之后,数据宽度会被严格限制为整数倍字节宽度(8-bit或9-bit)。Byte Write会对数据的每一个字节生成相应的写使能,顺序是高数据字节对应高位的写使能。使用如下图所示(图中是单端口RAM,RAM全初始化为0):

图3 Byte Write时序图

 

从上图可以看出6次写操作都是对一个相同的地址000。数据宽度是24-bit,因此对应的写使能需要3-bit,分别控制相应的数据字节。注意只有写使能被置位时,DINA对应的字节才能被写进RAM,否则不能写进RAM。比如当写使能为3’b011时,数据24’hFFEEDD中,只有字节EE和DD被成功写入RAM,下一次的写使能为3’b010时,数据24’hCCBBAA只有对应的字节BB能被成功写入RAM,剩下的两个字节将不做任何操作,即字节00和DD保持不变,所以第二次写操作后,RAM中的数据是24’h00BBDD。

  • Algorithm Options 可选Minimum Area,Low Power和Fixed Primitives 3种。这里选择Minimum Area。 三种算法的举例如下图所示:

IMG_256

图4

Minimum Area算法可以使用最少的RAM原语块。Low Power算法最小化读取或写入操作期间启用的原语数量,但是可能会用更多的RAM原语块。Fixed Primtives算法只需要一种RAM原语块,并根据需要进行拼接。

图5 Block Memory Generator IP核 Port A Options

 

  • Port A的配置如上图所示,A端口读写数据的宽度都为8-bit,深度为256。

注意:Vivado下支持读写数据不同步:

Block Memory Generator允许不同的读写数据宽度比(相对宽松,可选的比例为1:32,1:16,1:8,1:4,1:1,2:1,4:1,8:1,16:1和32:1),比如A端口写数据的宽度为8-bit,A端口读数据的宽度可以为16-bit。实际上,A,B端口的输入输出:dinA,doutA,dinB和doutB的数据宽度可以都不相同。注意如果数据宽度不同,那么数据深度也会相应的自动变化。比如A端口写数据的宽度为8-bit,A端口读数据的宽度为16-bit。那么如果设定A端口写数据的深度为256,A端口读数据的深度会自动设置成128。数据宽度的比率,会在数据深度比中以倒数出现。在RAM中,数据是以小端格式(little-endian)存储的。

  • 这里Operating Mode选择 Write First

因为RAM是可以读写的内存,在同时读写一个地址时会发生冲突。Xilinx公司的Block Memory Generator对于每个端口都提供了3种写模式:

Write First Mode:

图6 Write First Mode时序图

如上图所示,在Write First模式下执行写入操作时,并发的读操作会在输出上显示新写入的数据。 但是,在某些情况下(比如使用byte-Write 或者读写数据宽度不同时),无法保证内存输出的正确性。

Read First Mode:

图7 Read First Mode时序图

如上图所示,在Read First模式下,地址里存储的旧数据先被读出来,写进的新数据再被存储到地址中,即先读后写。

No Change Mode:

图8 No Change Mode时序图

在No Change模式中,在写操作的时候,读出的数据会保持不变。输出的数据仍然是之前读出的数据,不受同一个端口的写操作影响,如上图所示。

  • Enable Port Type选择Always Enabled
  • 对于Port A Optional Output Registers有两个选项:Primitive Output Register和Core Output Register,优点是会提升性能,缺点是都会为读取操作增加一个额外的时钟周期延迟。这里不选择输出寄存器。

Primitive Output Register是Block Memory Generator里的嵌入式输出寄存器,不需要额外的FPGA资源,而Core Output Register需要FPGA的额外资源和通用的内部连线,如图所示:

IMG_256

图9

 

图10 Block Memory Generator IP核 Port B Options

 

  • 对于Port B,读写的数据宽度也选择8-bit,Vivado会自动生成相应的读写数据深度。其它的选项与Port A一致。Operating Mode选择Write First,Enable Port Type选择Always Enabled,也不选择输出寄存器。

图11 Block Memory Generator IP核 Other Options

 

  • 这里没有选择装载初始化内存的*.coe文件,因为RAM和ROM不同,RAM除了初始化外,还可以进行写操作,所以需要的数据可以在工程运行时填充进去。

图12 Block Memory Generator IP核 Summary

 

  • Block Memory Generator IP核的总结。Memory Type是真双端口,因为8 * 256 = 2K,所以只需要使用1个18K BRAM就足够。
  • 读操作有1个时钟周期的延时(内部逻辑自有,无法消除)。
  • A,B端读写操作的数据宽度都是8-bit。

之后的文章会讲解如何使用这个生成的真双端口RAM IP核。

文章参考:

[1]Xilinx.com, 2021. [Online]. Available: https://www.xilinx.com/support/documentation/ip_documentation/blk_mem_gen/v8_3/pg058-blk-mem-gen.pdf. [Accessed: 06- Jul- 2021].

Posted in FPGA, FPGA 教材教案, FPGA开发板, FPGA硬件资源, Verilog, Verilog, Vivado, Vivado, 开发工具, 开发工具, 开发板, 开发语言, 教材与教案, 文章, 编程语言

发表回复

相关链接