FPGA内部模块详解之三 FPGA的“记忆细胞”——嵌入式块内存(Block RAM)

第3篇:FPGA的"记忆细胞"------嵌入式块内存(Block RAM)深度解析

FPGA中实现存储有两种主要方式:一种是用SLICEM中的LUT搭建的 分布式存储器 (Distributed RAM),另一种是本章的主角------ 嵌入式块内存(Block RAM,简称BRAM) 。如果把SLICEM比作街边的小卖部,可以满足零散的小额存储需求,那么BRAM就是专业的大型超市,专门应对大容量、高性能的存储任务。本章将带你全面了解BRAM的结构、配置模式以及设计中的实用技巧。

一、为什么需要专用的块内存?

在深入BRAM之前,我们先思考一个问题:既然SLICEM已经可以实现分布式RAM,为什么还需要专门的BRAM?

1.1 分布式RAM的局限性
维度 分布式RAM(SLICEM) 块内存(BRAM)
容量 小(每个LUT6最多64bit) 大(通常18Kb/36Kb每块)
效率 实现较大存储时占用大量LUT 专用硬核,面积效率高
速度 随容量增加延迟增大 固定延迟,性能稳定
功耗 随LUT使用量增加而增加 优化设计,功耗较低

分布式RAM适合容量小(几百bit以内)、对布局灵活性要求高的场景。但当需要几千甚至几兆比特的存储时,如果全部用LUT搭建,会消耗大量逻辑资源,导致芯片利用率低下、布线困难、时序恶化。BRAM正是为解决这些问题而生的专用硬核存储资源。

1.2 BRAM的地位

在大多数现代FPGA中,BRAM是仅次于逻辑单元的第二大资源。例如,Xilinx 7系列中,中等规模的芯片可能包含几百块BRAM,每块18Kb或36Kb,总容量可达数兆比特。BRAM的位置在芯片上固定分布,通过专用布线资源与周围的逻辑单元相连,既保证了高性能,又简化了布局布线。

二、BRAM的物理架构

不同厂商、不同系列的BRAM略有差异,但基本原理相似。本节以Xilinx 7系列18Kb BRAM为例进行讲解。

2.1 基本规格
  • 容量 :18Kb(即18432比特)。也可以配置为16Kb ×1、8Kb ×2等,但物理容量固定。
  • 组织方式 :可以配置为不同的位宽和深度组合,例如:
  • 16K × 1(16384个地址,每个地址1位)
  • 8K × 2(8192个地址,每个地址2位)
  • 4K × 4
  • 2K × 9(注意9位包含一个校验位,可配置为8位数据+1位奇偶校验)
  • 1K × 18
  • 512 × 36
  • 级联 :两块18Kb BRAM可以组合成一个36Kb BRAM,实现更深或更宽的存储。
2.2 内部结构

一个典型的18Kb BRAM包含以下主要部分:

  • 存储阵列 :真正的存储单元阵列。
  • 地址解码器 :将输入的地址转换为对存储单元的选择信号。
  • 读写控制逻辑 :处理时钟、使能、写使能等控制信号。
  • 数据输入/输出寄存器 :可选的输入输出寄存器,用于提高时序性能。
  • 输出锁存器 :保持输出数据。

关键特性 :BRAM支持 同步读写 ,即所有操作都与时钟边沿对齐。这意味着BRAM本质上是 同步存储器 ,这与异步的分布式RAM(读操作组合输出)不同。

三、BRAM的端口配置模式

BRAM最强大的地方在于其端口的可配置性。根据一个BRAM块可以被多少个独立的端口访问,分为以下几种模式。

3.1 单端口RAM(Single-Port RAM)

特点

  • 只有一套地址总线、一套数据输入总线、一套数据输出总线。
  • 读写操作共享同一地址端口, 不能同时进行读写 (但可以在不同时钟周期交替进行)。
  • 控制信号包括时钟(CLK)、使能(EN)、写使能(WE)。

应用场景

  • 简单的数据缓冲。
  • 寄存器文件。
  • 查找表(LUT)的系数存储。

时序

  • 写操作:在时钟沿,如果WE有效,则将数据写入地址对应的单元。
  • 读操作:在时钟沿,如果WE无效,则从地址单元读出数据(通常经过一个时钟周期延迟)。
3.2 简单双端口RAM(Simple Dual-Port RAM)

特点

  • 两个独立的端口: 一个只写端口 (Port A)和 一个只读端口 (Port B)。
  • 两套独立的地址、数据和控制信号。
  • 可同时进行一读一写操作,互不干扰(只要访问的地址不冲突,见下文)。
  • 注意:两个端口不能同时写同一个地址(这在双端口中很少发生,因为一个端口只读)。

应用场景

  • FIFO的核心存储。
  • 跨时钟域数据缓冲(异步FIFO)。
  • 图像处理中的行缓冲。

优势

  • 读写可以并行,提高了吞吐量。
3.3 真双端口RAM(True Dual-Port RAM)

特点

  • 两个完全对称的端口, 每个端口都可以进行读或写
  • 每个端口都有自己的地址、数据输入、数据输出、时钟、使能、写使能。
  • 两个端口可以同时读写同一个地址,但需要处理写冲突(同时写同一地址数据不一致)。

应用场景

  • 多核处理器间的共享内存。
  • 视频处理中的帧缓冲(多个处理单元同时访问)。
  • 复杂的网络数据包处理。

冲突处理

  • 当两个端口同时写同一地址时,结果是不确定的。设计中必须避免这种情况,或通过仲裁机制确保同一时刻只有一个端口写。
3.4 不同端口模式的对比
模式 端口A 端口B 典型应用
单端口 读/写 简单缓存、寄存器文件
简单双端口 只写 只读 FIFO、异步数据缓冲
真双端口 读/写 读/写 共享内存、多核系统

四、BRAM的高级应用模式

除了作为RAM,BRAM还可以配置为其他常用存储结构。

4.1 FIFO(先进先出队列)

FIFO是数字系统中极其常用的组件,用于缓冲数据、跨时钟域传输。FPGA厂商通常提供专门的FIFO IP核,可以直接调用。这些FIFO底层大多基于BRAM实现。

FIFO的核心特性

  • 写端口 :写数据、写使能、写时钟、满标志。
  • 读端口 :读数据、读使能、读时钟、空标志。
  • 跨时钟域 :异步FIFO使用两个独立的时钟(写时钟和读时钟),内部通过格雷码同步指针。

FIFO与直接使用BRAM的区别

  • FIFO封装了地址管理逻辑,用户不需要关心地址指针,只需控制读写使能。
  • 内置了空、满、几乎空、几乎满等状态标志。
  • 支持标准接口(如FWFT,First-Word Fall-Through)。
4.2 ROM(只读存储器)

BRAM可以配置为ROM,即初始数据在配置时写入,运行过程中只读不写。

实现方式

  • 在HDL代码中定义初始化向量,使用 initial语句或 readmemh任务。
  • 在IP核配置时指定初始化COE文件。
  • 综合工具会将初始化数据写入BRAM的配置位流中,上电后自动载入。

应用场景

  • 查找表(如正弦波表、CRC表)。
  • 微码存储。
  • 固定系数存储器。
4.3 内容可寻址存储器(CAM)

CAM是一种特殊的存储器,输入数据,输出该数据所在的地址。常用于网络交换中的MAC地址表查找。虽然可以用BRAM配合逻辑实现CAM,但会消耗较多资源。部分高端FPGA(如Xilinx Ultrascale+)提供专门的CAM硬核,但主流FPGA中,CAM通常是通过BRAM+LUT组合实现。

五、BRAM的级联与扩展

单块BRAM容量有限,实际设计中经常需要将多块BRAM拼接成更大、更宽的存储阵列。

5.1 深度扩展(增加存储深度)

原理 :将多块BRAM的地址并联,通过高位地址选择哪一块BRAM使能,数据总线共享。

例如:用4块18Kb BRAM组成一个64K×18的RAM。每块BRAM深度16K,宽度18。高位地址(A15-A14)用于片选,低位地址(A13-A0)输入到所有BRAM,但只有被选中的BRAM输出使能。

5.2 位宽扩展(增加数据宽度)

原理 :将多块BRAM的地址并联,数据总线拼接,所有BRAM同时使能。

例如:用4块18Kb BRAM组成一个16K×72的RAM(假设需要72位数据)。每块BRAM配置为16K×18,四块的数据输出拼接成72位。

5.3 同时扩展深度和位宽

可以组合以上两种方式,形成矩阵式扩展。现代FPGA的BRAM还支持级联专用硬件(如CASCADE引脚),使得级联多个BRAM时无需占用通用布线资源,时序更好。

注意 :BRAM级联会引入额外的延迟,需要在时序分析中考虑。

六、BRAM vs. 分布式RAM:如何选择?

比较维度 BRAM 分布式RAM(SLICEM)
容量 大(Kb级别) 小(几十到几百bit)
速度 高,时序固定 随LUT布线变化
功耗 相对较低(每bit) 高(每bit)
位置 固定位置 散布在逻辑单元中
灵活性 端口模式丰富 可实现小型、任意位宽的RAM
初始化 支持 支持

选型建议

  1. 优先用BRAM :当存储容量大于几百bit时,优先考虑BRAM。这能节省宝贵的LUT资源,且时序更可控。
  2. 用分布式RAM的场景
  • 需要小容量、多个分散的存储(如寄存器文件)。
  • 需要额外的小型FIFO,但BRAM资源紧张。
  • 需要真正异步读(BRAM读是同步的,需加输出寄存器才能同步读)。
  • 需要实现移位寄存器(SLICEM专用)。
  1. 用BRAM的典型场景
  • 大容量数据缓冲。
  • FIFO、帧缓冲。
  • 查找表(系数存储)。
  • 跨时钟域同步(异步FIFO)。

七、设计中的注意事项

7.1 初始化与复位
  • BRAM在FPGA配置完成后,其内容由位流文件决定。可以通过初始化文件(如COE)预先写入数据。
  • BRAM通常没有全局复位引脚,上电后内容随机(除非初始化)。因此,如果设计依赖RAM的初始值(如状态机跳转表),必须确保正确初始化。
  • BRAM的输出寄存器有复位引脚,可以复位输出寄存器,但不会复位存储阵列本身。
7.2 读写冲突

在双端口模式下,如果两个端口同时写同一地址,结果未知。设计时必须保证:

  • 对于真双端口,通过软件协议或外部逻辑避免同时写同一地址。
  • 对于简单双端口,读端口和写端口地址重叠时,读出的数据可能是旧数据、新数据或不定态。通常建议在写周期内读端口不要访问被写的地址。
7.3 输出流水线

BRAM内部通常有可选输出寄存器。启用输出寄存器会增加一个时钟周期的读延迟,但可以大幅提高时序性能,因为输出数据被寄存器同步,避免了组合路径过长。对于高速设计,建议开启输出寄存器。

7.4 字节写使能

部分BRAM支持字节写使能(Byte-Write Enable),允许在一个宽位宽写入时,只更新其中几个字节。例如,36位宽时,可以按9位字节分别控制写入。这在实现CPU数据缓存时非常有用。

7.5 功耗优化

BRAM在不访问时可以关闭时钟或使能,降低动态功耗。许多FPGA工具支持自动门控时钟,或在IP配置中提供"禁用"选项。

八、本章小结

本章我们深入探讨了FPGA的专用存储资源------嵌入式块内存(BRAM)。核心要点如下:

方面 内容
为什么需要BRAM 大容量、高性能存储需求,分布式RAM无法胜任
物理规格 典型18Kb/36Kb每块,可配置多种位宽深度
端口模式 单端口、简单双端口、真双端口,满足不同应用
高级模式 FIFO、ROM、CAM(需额外逻辑)
级联扩展 深度扩展、位宽扩展,专用级联路径
选型对比 容量大优先用BRAM;小容量、分散存储用分布式RAM
注意事项 初始化、冲突避免、输出寄存器、字节写使能

一句话总结 :BRAM是FPGA中的"记忆细胞",以专用硬核的形式高效实现大容量存储,是现代数字设计中不可或缺的资源。

相关推荐
良许Linux3 小时前
ASIC的设计和制造
单片机·嵌入式硬件·fpga开发·程序员·嵌入式·制造
minglie13 小时前
Amaranth HDL
python·fpga开发
s09071367 小时前
保姆级教程一:ZYNQ-7030开发板安装/烧录Linux系统详细指南(小白必看)
linux·fpga开发·系统安装·zynq
lf2824814318 小时前
03 xilinx除法IP核的使用
fpga开发
智能物联网开发8 小时前
机器人电子皮肤系统开发:36通道柔性触觉阵列 + FPGA高速采集
fpga开发·计算机外设·嵌入式·fpga数据采集
沐欣工作室_lvyiyi9 小时前
基于FPGA的智能音箱设计(论文+源码)
fpga开发·毕业设计·智能音箱
我爱C编程10 小时前
【硬件片内测试】基于FPGA的4FSK扩频通信链路测试,包含帧同步,定时点,扩频伪码同步,信道,误码统计
fpga开发·帧同步·定时点·扩频通信·扩频伪码同步·4fsk
GateWorld10 小时前
Lattice FPGA开发全攻略--十余种输出文件格式及其区别
fpga开发·lattice·fpga开发工具
芯门1 天前
基于 Xilinx K7 FPGA 的全套万兆 10G GigE Vision 商业级传输方案
计算机视觉·fpga开发·万兆gige