本节将介绍 UltraScale+架构 FPGA 中的块存储器(Block RAM,BRAM)资源和UltraRAM资源。
除分布式RAM和高速SelectIO存储器接口外,基于UltraScale+架构的FPGA中提供了大量的 36Kb 块存储器(Block RAM,BRAM)。每个 36Kb BRAM 包含两个独立控制的 18Kb RAM。BRAM 放置在 CR 内的列中并且跨越器件。BRAM 数据输出块可级联以实现更深的存储器。此外,BRAM具有用于节能的休眠模式,并且具有可选择的写入模式操作。
每个 BRAM 有两个写端口和两个读端口。一个 36Kb 的 BRAM 可以配置为用于每个端口的独立端口宽度为32K×1、16K×2、8K×4、4K×9、2K×18或1K×36【当用作真正双端口(True Dual Port,TDP)时】。如果只使用一个端口和一个读取端口,则可以额外配置36Kb BRAM,其端口宽度为512×72位【当用作简单双端口(Simple Dual Port,SDP)时】。
18Kb BRAM可以为这些端口中的每一个配置独立的端口宽度,如16K×1、8K×2、4K×4、2K×9或1K×18(当用作TDP存储器时)。如果只使用一个写端口和一个读端口,则可以额外配置18Kb BRAM,其端口宽度为512×36位(当用作SDP存储器时)。
与7系列FPGA BRAM类似,写入和读取是同步操作。这两个端口对称且完全独立,仅共享存储的数据。每个端口都可以配置为一个可用的宽度,与另一个端口无关。此外,每个端口的读端口宽度可以不同于写端口宽度。存储器的内容可以通过配置比特流进行初始化或清除。在写操作期间,可以将存储器设置为数据输出保持不变,反映正在写入的新数据或正在重写的先前数据。
UltraScale+架构FPGA内BRAM的主要特性包括:
(1)每个BRAM可以保存最多36Kb的数据。
(2)支持两个独立的18Kb或单个36Kb的BRAM。
(3)每个36Kb BRAM可与单个读和写端口(SDP)一起使用,可使BRAM的数据宽度加倍,达到72位。18Kb BRAM可与单个读和写端口(SDP)一起使用,可使BRAM的数据宽度加倍,达到 36 位。当用作 RAMB36 SDP 存储器时,一个端口宽度是固定的(512×64 或512×72),另一个端口宽度可以是 32K×1 到 512×72。当用作 RAMB18 SDP 存储器时,一个端口宽度是固定的(512×36),另一个端口宽度可以是16K×1到512×36。
(4)从下到上相邻块 RAM 的数据输出可以级联在一起以构建大块 RAM 块。可选的流水线寄存器可用于支持最大性能。
(5)每36Kb BRAM或36Kb FIFO(First Input&First Output)提供一个64位的纠错编码(Error Correction Coding,ECC)块。提供独立的编码/解码功能。ECC模式具有注入错误的能力。
(6)BRAM输出的锁存和寄存器模式均可将输出同步置位/复位为初始值。
(7)单独的同步置位/复位引脚独立控制BRAM中可选输出寄存器和输出锁存级的置位与复位。
(8)将BRAM配置为公共时钟/单个时钟FIFO的属性,用于消除标志延迟的不确定性。
(9)18、36或72位宽的BRAM端口可以每字节具有单独的写使能。
(10)每个 BRAM 包含可选的地址时序和控制电路,作为 FPGA 内建的独立时钟 FIFO 存储器运行。BRAM可配置位18Kb或36Kb FIFO。
(11)所有输入都与端口时钟寄存。
(12)根据写使能(WE)引脚的状态,所有输出都具有读取或写期间读取的功能。输出在时钟到输出时序间隔之后可用。写入期间的读取输出具有 3 种操作模式,包括WRITE_FIRST、READ_FIRST和NO_CHANGE。
①写入操作需要一个时钟沿。
②读取操作需要一个时钟沿。
③锁存或寄存所有输出端口(可选)。输出端口的状态不变,直到端口执行另一个读取或写入操作。默认,BRAM的输出为寄存器模式。
注: 输出数据路径有一个可选的内部流水线寄存器。强烈建议使用寄存器模式,这允许更高的时钟速率。然而,它增加了一个时钟周期延迟。
真正的 36Kb BRAM 双端口存储器由一个 36Kb 存储器阵列和两个完全独立的访问端口 A和B构成,如图1.47所示。类似地,每个18Kb BRAM双端口存储器由18Kb存储器阵列和两个完全独立的访问端口A和B构成。结构完全对称,两个端口可以互换。
图1.47 真正的36Kb BARM双端口存储器
图1.47中端口名字的含义如表1.11所示。
表1.11 图1.47端口名字的含义
续表
1)读操作
在锁存模式下,读操作使用一个时钟沿。读取地址寄存在读端口上,在 RAM 访问时间后,保存的数据加载到输出锁存器中。当使用输出寄存器时,读操作需要一个额外的延迟周期。
2)写操作
写操作是单时钟沿操作。写入地址寄存在写端口上,并且将数据输入保存在存储器中。
(1)WRITE_FIRST 模式:在该模式下,输入数据的同时将数据写入存储器并保存在数据输出中(透明写入),如图1.48所示。当不使用可选的输出流水线寄存器时,波形对应于锁存模式。
图1.48 WRITE_FIRST模式下的写操作
(2)READ_FIRST/Read-Before-Write 模式:在该模式下,当将输入数据保存在存储器中时(先读后写),之前保存在写入地址的数据出现在输出锁存器上,如图 1.49 所示。当不使用可选的输出流水线寄存器时,波形对应于锁存模式。
图1.49 READ_FIRST/Read-Before-Write模式下的写操作
(3)No-Change 模式:在该模式下的写操作期间,输出锁存器保持不变,如图 1.50 所示,数据输出保持上一次读取的数据,不受同一端口上写入操作的影响。当不使用可选的输出流水线寄存器时,波形对应于锁存模式。该模式是最节能的模式。
图1.50 No-Change模式下的写操作
注: (1)可选的输出寄存器通过消除到用于流水线操作的CLB触发器的布线延迟来提高设计性能。FPGA 内为这些输出寄存器提供了独立的时钟和时钟使能输入。输出数据寄存器保持与输入寄存器操作无关的值。
(2)独立的读写端口选择提高了在 BRAM 中实现内容可寻址存储器(Content Addressable Memory,CAM)的效率。该选项适用于所有基于UltraScale/UltraScale+架构FPGA内真正双端口RAM端口的大小和模式。
每个18Kb的块和36Kb的块也能配置为SDP RAM模式。在该模式下,BRAM的端口宽度加倍到36位(对于18Kb的BRAM)或72位(对于36Kb的BRAM)。当BRAM用作SDP存储器时,可以同时进行独立的读写操作,其中端口A指定为写端口,端口B指定为读端口。简单双端口36Kb BARM如图1.51所示,图1.51中端口名字的含义如表1.12所示。
图1.51 简单双端口36Kb BARM
表1.12 图1.51中端口名字的含义
许多设计使用 BRAM 来实现 FIFO。公共时钟或独立时钟 FIFO 均可以很容易使用 BRAM中的专用逻辑实现。这消除了需要额外使用CLB逻辑来实现计数器、比较器或生成状态标志,并且每个FIFO仅使用一个BRAM资源。支持标准模式和首字直通(First Word Fall Through,FWFT)模式。
FIFO 可以配置为 18Kb 或 36Kb 存储器。对于 18Kb 模式,支持的配置有 4K×4、2K×9、1K×18和512×36;对于36Kb模式,支持的配置有8K×4、4K×9、2K×18、1K×36和512×72。FIFO端口可以以非对称的方式进行配置。
BRAM 可以配置为具有公共或独立读写时钟的FIFO 存储器。BRAM 的端口 A 用作 FIFO读取端口,端口B用作FIFO写入端口。数据在读取时钟的上升沿从FIFO读取,并在写入时钟的上升沿写入FIFO。
1)独立时钟/双时钟FIFO
独立时钟 FIFO(也称为双时钟或异步 FIFO)是先进先出队列,其中写入接口和读取接口位于不同的时钟域中。要将FIFO配置为独立时钟FIFO,应将属性CLOCK_DOMAINS设置为INDEPENDENT。
独立时钟 FIFO 提供了一个简单的写入接口和一个简单的读取接口,这两个接口都可以是自由运行的时钟,时钟之间没有频率或相位关系。因此,它非常适合以下情况:
(1)WRCLK和RDCLK具有不同但相关的频率;
(2)WRCLK和RDCLK相位不一致;
(3)WRCLK和RDCLK完全异步(没有关系)。
独立时钟FIFO可以支持指定最大限制的时钟频率。双时钟FIFO设计避免了不确定性、毛刺或亚稳定问题,并提供了在不同时钟域之间传递数据的便捷方式。写接口与 WRCLK 域同步,每当WREN在WRCLK上升沿之前处于有效时,将DIN上可用的数据写入FIFO。读接口与 RDCLK 同步,每当 RDWN 在 RDCLK 上升沿之前处于有效时,就会触发 FIFO 中的读操作,并在标准模式下,在RDCLK上升沿之后的DOUT上显示下一个数据字。
由于 WRCLK 和 RDCLK 之间的内部同步,某些转换需要较长的时钟周期。例如,写操作需要几个时钟周期(WRCLK 和 RDCLK 时钟周期)才能同步到 RDCLK。只有在写操作与RDCLK同步之后,RDCLK中反映的写操作才会输出到EMPTY和PROGEMPTY,这可能会导致这些标志无效。
类似地,RDCLK 和 WRCLK 之间的内部同步也需要延长时钟周期数。例如,读操作需要几个时钟周期(RDCLK 和 WRCLK 时钟周期)才能同步到 WRCLK。只有在读操作和WRCLK 同步后,WRCLK 输出 FULL 和 PROGFULL 状态中反映的读取操作才能导致这些标志无效。
所有 FIFO 的输入和输出都与 WRCLK 或 RDCLK 同步。由于两个不相关时钟域的不确定性,在实现中保留了一个存储器位置以防止错误。
2)公共时钟/单时钟FIFO
公共时钟FIFO的接口与独立时钟FIFO的相同,不同之处在于只有一个时钟输入(CLK),或者有两个时钟输入(WRCLK和RDCLK)但必须连接到同一时钟源(时钟缓冲区)。
公共时钟 FIFO(也称为单时钟或同步 FIFO)是一个先进先出的队列,其写入接口和读取接口共享公共时钟域。当使用同步FIFO时,CLOCK_DOMAINS属性应设置为COMMON,以消除在标志有效和无效时的时钟周期延迟。
因为公共时钟 FIFO 不需要时钟域之间的同步,所以从写入操作到 EMPTY 或PROGEMPTY 无效,或从读取操作到 FULL 或PROGFULL 无效的内部延迟比等效的独立时钟FIFO快得多。
此外,由于公共时钟 FIFO 不需要处理两个不相关时钟的不确定性,因此它可以使用整个存储器内容用于FIFO存储,而不是保留一个存储器位置来防止错误。因此,公共时钟FIFO的深度比等效的独立时钟FIFO多一个字。
UltraScale/UltraScale+架构 FPGA 内建 FIFO 的结构如图 1.52 所示。图 1.52 中端口名字的含义如表1.13所示。
图1.52 UltraScale/UltraScale+架构FPGA内建FIFO的结构
表1.13 图1.52中端口名字的含义
标准模式下的FIFO操作时序如图1.53所示。在标准FIFO中,当从FIFO中读取一个或多个字时,EMPTY 变成无效。通过 RDEN 有效,下一个数据出现在 RDCLK 的下一个上升沿之后的DOUT总线上。当EMPTY标志有效时,不能读取更多的数据,任何额外的读操作都会使RDERR在下一个RDCLK边沿之后变成有效。
图1.53 标准模式下的FIFO操作时序
FWFT 模式下的 FIFO 操作时序如图 1.54 所示。在 RDEN 信号有效之前,数据放置在DOUT 总线上。当把第一个字写入空 FIFO 时,第一个字直接传输到输出,并且在 EMPTY 无效的同时出现在DOUT总线上。
为了防止系统中的数据丢失,在 RDEN 有效之前,第一个输出值不会从 DOUT 总线中消失。如果没有更多的数据可用,则 EMPTY 有效,并且再次写入 FIFO 的下一个字直接传输到输出。因为数据在读取之前出现在 DOUT 总线上,所以 FIFO 可能需要再进行一次最后的读取才能使 EMPTY(空)有效。在任何一种情况下,读需要与写入操作数数量相同的读取操作才能将FIFO返回到空状态。
图1.54 FWFT模式下的FIFO操作时序
一个数据宽度为4位、深度为16的块存储器的Verilog HDL和VHDL描述如代码清单1-24和代码清单1-25所示。
代码清单1-24 一个数据宽度为4位、深度为16的块存储器的Verilog HDL描述例子
注: 读者进入本书提供的\vivado_example\bram_verilog资源目录中,用Vivado 2023.1打开名字为project1.xprj的工程文件。
代码清单1-25 一个数据宽度为4位、深度为16的块存储器的VHDL描述例子
注: 读者进入本书提供的\vivado_example\bram_vhdl资源目录中,用Vivado 2023.1打开名字为project1.xprj的工程文件。
使用Vivado 2023.1对该设计进行综合后的结果如图1.55所示。
图1.55 使用Vivado 2023.1对该设计进行综合后的结果
思考与练习1-15: 根据图1.55给出的结果,分析该设计的原理。
使用Vivado 2023.1对该设计进行布局布线后的结果如图1.56所示。
图1.56 使用Vivado 2023.1对该设计进行布局布线后的结果
思考与练习1-16: 根据图 1.56 给出的布局布线后的结果,查看所使用的 BRAM 的位置,以及布线的连接情况。
UltraRAM 是 UltraScale+架构 FPGA 中提供的单时钟双端口同步存储器。由于 UltraRAM与列状架构兼容,因此可以例化多个 UltraRAM,并将其直接级联到 FPGA 整个高度的UltraRAM列中。单个CR中的一列包含16个UltraRAM块。
具有 UltraRAM 的 FPGA 包含分布在器件中的多个 UltraRAM 列。UltraScale+架构中的大部分器件都包含UltraRAM块。
UltraRAM 块是 288Kb 的单时钟同步存储块,排列在 FPGA 内的一列或多列中。每列每个时钟区域有16个UltraRAM块。多个UltraRAM块可以使用专用级联布线在一列中,唯一的限制是FPGA的高度或SSI器件中的单个超级逻辑区(Super Logic Region,SLR)。此外,可以使用少量逻辑资源将多个列级联在一起。如果级联的 UltraRAM 块被适当地流水线化,则不会有时序损失。
UltraRAM 是一种灵活的高密度存储器构建块。每个 UltraRAM 块最多可以保存 288k 位数据,并配置为4k×72存储块。UltraRAM的容量是BRAM的8倍。与BRAM类似,FPGA中分布着多个UltraRAM列。UltraRAM有两个端口,这两个端口都寻址所有4k×72位。每个端口可以在每个端口的每个时钟周期独立执行一次读或一次写操作。但是,SRAM 阵列内部使用单端口存储单元。双端口操作通过在单个循环中执行端口A操作和端口B操作来实现。因此,两个端口共享一个时钟输入。每个端口在一个周期内智能执行写或读操作。当执行写操作时,读输出保持不变,并保持以前的值。
UltraRAM 块可以级联以便实现更深层次的存储器。大多数与级联相关的布线都包含在UltraRAM 列中。因此,如果适当地将 UltraRAM 流水线化,则只需要很少或不需要一般的互联,并且由于布线而不会产生时序损失。
对于两个端口中的每一个,UltraRAM 最多包含 4 个流水级。在独立的非级联模式中,UltraRAM 可以配置为 1~4 个时钟周期延迟,但通常只需要 1~3 个时钟周期延迟,具体取决于目标频率。级联模式延迟是 UltraRAM 链大小、频率目标和其他约束条件的函数。类似地,时钟输出性能取决于所选的输出寄存器。
BRAM和UltraRAM的主要特性比较如表1.14所示。
表1.14 BRAM和UltraRAM的主要特性比较
UltraRAM URAM288和UltraRAM URAM288_BASE库原语是所有UltraRAM配置的基本构建块。UltraRAM URAM288 原语支持所有可能的配置,包括级联和 ECC。UltraRAM URAM288_BASE 原语是一个子集,支持没有级联功能的单个 UltraRAM 块实例。UltraRAM URAM288_BASE 原语符号如图1.57所示,UltraRAM URAM288 原语符号如图1.58 所示。图中端口名字的含义如表1.15和表1.16所示。
图1.57 UltraRAM URAM288_BASE原语符号
图1.58 UltraRAM URAM288原语符号
表1.15 UltraRAM原语端口名字的含义(非级联端口)
续表
表1.16 UltraRAM原语端口名字的含义(级联端口)
续表
调用UltraRAM的Verilog HDL和VHDL描述如代码清单1-26和代码清单1-27所示。
代码清单1-26 调用UltraRAM的Verilog HDL描述例子
注: 读者进入本书提供的\vivado_example\ultraram_verilog 资源目录中,用 Vivado 2023.1打开名字为project1.xprj的工程文件。
代码清单1-27 调用UltraRAM的VHDL描述例子
注: 读者进入本书提供的\vivado_example\ultraram_vhdl资源目录中,用Vivado 2023.1打开名字为project1.xprj的工程文件。
思考与练习1-17: 在Vivado 2023.1中打开综合后的网表视图,分析该设计的原理。
使用Vivado 2023.1对该设计进行布局布线后的结果如图1.59所示。
图1.59 使用Vivado 2023.1对该设计进行布局布线后的结果
思考与练习1-18: 根据图1.59,查看所使用的UltraRAM的位置,以及布线的连接情况。