一、Lattice FPGA 存储器概览
大家好,我是你们的讲师。今天咱们聊聊 Lattice FPGA 内部存储器的那些事儿。说实话,存储器这块儿,是很多初学者容易忽略但又特别关键的部分。你想想看,一个 FPGA 项目做大了,光靠寄存器去存数据,那资源消耗简直不敢想。所以,搞明白 Lattice 内部有哪些存储器、它们长什么样、能干什么,是咱们用好 FPGA 的第一步。
1.1 存储器的三大主力
Lattice FPGA 内部,主要提供了三种类型的存储资源。我个人习惯把它们分成三兄弟:EBR、DRM 和 PLL(嗯,PLL 严格来说不算存储器,但它跟存储器的时钟供给密不可分,我后面会解释)。
| 存储器类型 | 全称 | 主要用途 | 容量范围 |
|---|---|---|---|
| EBR | Embedded Block RAM | 数据缓存、FIFO、查找表 | 每块 9Kbit ~ 18Kbit |
| DRM | Distributed RAM | 小容量寄存器堆、移位寄存器 | 每 LUT 可配 16~64bit |
| PLL | Phase-Locked Loop | 时钟生成、频率合成 | 不直接存储数据 |
说白了,EBR 是“大仓库”,DRM 是“小抽屉”,PLL 是“时钟管家”。它们各司其职,配合好了,你的设计才能跑得稳、跑得快。
1.2 EBR:嵌入式块 RAM
EBR 是 Lattice FPGA 里最常用的存储器。我在项目中遇到过好几次,客户说“我的数据量不大,用寄存器凑合一下”,结果综合出来资源爆红。这时候我就会建议:换成 EBR 吧,一块 EBR 顶你几百个寄存器。
EBR 的特点很鲜明:
- 容量大:每块 EBR 通常是 9Kbit 或 18Kbit,具体看器件型号。比如 Lattice ECP5 系列,每块是 18Kbit。
- 速度快:可以跑到几百 MHz,跟 FPGA 内部逻辑无缝对接。
- 配置灵活:可以配成单口 RAM、双口 RAM、ROM、FIFO,甚至支持真双口(True Dual-Port)。
嗯,这里要注意:EBR 的位置通常在 FPGA 的四周或中间列,具体看芯片布局。Lattice 的 EBR 是排列成列的,比如 ECP5 有 4 列 EBR,每列若干块。这种布局的好处是,走线延迟比较均衡,不会出现“东边取数据、西边存数据”的尴尬。
核心要点:EBR 是 Lattice FPGA 存储体系的主力,适合中等容量、高性能的场景。比如视频行缓存、网络数据包缓冲、FFT 的中间结果存储等。
1.3 DRM:分布式 RAM
DRM 说白了就是“用 LUT 拼出来的存储器”。每个 LUT 可以配置成 16x1 或 32x1 的 RAM。你想想看,如果你只需要存几十个 bit,用 EBR 太浪费了,这时候 DRM 就派上用场了。
我记得有一次做一个小型状态机,需要存 8 个 8bit 的配置参数。如果用 EBR,得浪费一整块(18Kbit 只用 64bit,太奢侈了)。后来我用 DRM,只用了 8 个 LUT 就搞定了,资源利用率瞬间提升。
DRM 的几个特点:
- 容量小:一般每个 LUT 只能配 16~64bit,适合小规模存储。
- 延迟低:因为是 LUT 直接实现,读写延迟只有 1~2 个时钟周期。
- 位置灵活:可以在 FPGA 的任何位置生成,不受 EBR 列的限制。
避坑指南:我曾经在一个项目中,为了省资源,把所有小 RAM 都用 DRM 实现。结果综合工具报错说“DRM 数量超限”。后来才知道,每个 slice 能用的 DRM 是有限的,不能无限制地配。所以,小规模用 DRM,中等规模用 EBR,这个分寸要把握好。
1.4 PLL:时钟的“存储器”
PLL 虽然不是传统意义上的存储器,但它跟存储器的关系非常密切。为什么?因为 EBR 和 DRM 都需要时钟来驱动。如果时钟抖动大、频率不稳,存储器的读写时序就会出问题。
PLL 在 Lattice FPGA 里的作用:
- 频率合成:把输入时钟倍频或分频,生成你需要的频率。
- 相位调整:可以精确调整时钟相位,满足存储器的建立/保持时间要求。
- 时钟去抖:滤除输入时钟的抖动,给存储器提供干净的时钟源。
我个人的经验是:凡是涉及 EBR 的高速读写,一定要用 PLL 生成的时钟,不要直接用外部晶振的时钟。因为外部时钟经过 PCB 走线、IO 缓冲后,抖动会变大,容易导致 EBR 读写错误。
1.5 存储器在 FPGA 架构中的位置
咱们来看看 Lattice FPGA 的整体架构。下面这张图是我用 SVG 画的,展示了 EBR、DRM、PLL 在芯片里的相对位置。
从这张图可以看出来:
- DRM 分布在可编程逻辑单元内部,每个 LUT 都可以变成一小块 RAM。所以它无处不在,但容量有限。
- EBR 是独立的列,位于逻辑区域的旁边。这种布局让 EBR 既能快速访问逻辑单元的数据,又不会占用逻辑资源。
- PLL 通常在芯片的角落或边缘,靠近时钟输入引脚。这样能最短路径接收外部时钟,减少干扰。
注意:不同型号的 Lattice FPGA,EBR 和 PLL 的数量、位置会有差异。比如 Lattice iCE40 系列,EBR 只有几块,而 ECP5 系列可以有几十块。选型的时候一定要先看数据手册,别等到布局布线了才发现资源不够。
1.6 它们是怎么协同工作的?
我举个例子你就明白了。假设你要做一个视频缩放器,需要缓存一行视频数据(比如 1920 像素,每个像素 24bit)。这时候:
- PLL 负责生成像素时钟,比如 148.5MHz,保证数据读写同步。
- EBR 配置成双口 RAM,一端写、一端读,实现行缓存。一块 EBR 不够?那就级联几块。
- DRM 用来存一些小的系数表,比如缩放滤波器的系数,只有几十个值,用 EBR 太浪费。
你看,三兄弟各司其职,配合得天衣无缝。我在实际项目中,就是这么干的。而且我建议你,在设计初期就把存储器的类型和数量规划好,别等到综合完了再回头改,那代价就大了。
1.7 小结
好了,这一章咱们把 Lattice FPGA 的存储器家族捋了一遍。EBR 是大块头,负责主力存储;DRM 是小巧灵活的补充;PLL 是时钟的“定海神针”。它们的位置和角色,决定了你在设计时该怎么选、怎么用。
下一章,咱们会深入 EBR 的具体配置和使用方法,包括怎么例化、怎么配成 FIFO、怎么处理读写冲突。到时候我会拿一个实际项目中的例子来拆解,保证你听完就能上手。