第三章 FPGA基础回顾:Lattice FPGA内部结构
各位同学,欢迎来到第三讲。今天咱们要聊的,是Lattice FPGA的“五脏六腑”。
很多初学者拿到芯片手册,看到那一堆PFU、PIO、DSP、Block RAM,头都大了。我当年也一样,第一次看Lattice的文档,密密麻麻的框图,差点劝退。但后来我发现,搞懂这些结构,就像熟悉自己工具箱里的每一把螺丝刀——用对了地方,事半功倍。
好,咱们一个一个来看。
3.1 PFU——FPGA的“逻辑细胞”
PFU,全称Programmable Function Unit,可编程功能单元。说白了,它就是FPGA里最基础的逻辑单元,负责实现你写的那些组合逻辑和时序逻辑。
每个PFU里包含几个Slice(切片),每个Slice又有查找表(LUT)、触发器和进位链。LUT是核心,4输入或6输入,查表实现任意布尔函数。触发器用来寄存数据,进位链用来做加法器。
关键点:Lattice的PFU结构比较灵活,Slice之间可以共享资源。比如两个Slice可以合并成一个更大的LUT,或者共享一个进位链。这在做加法器或比较器时特别有用。
我在项目中遇到过一个问题:用Lattice的MachXO2做一个小型状态机,资源占用率突然飙升。后来发现是综合工具把状态机映射到了多个Slice上,没有充分利用Slice内部的共享资源。手动调整了一下综合选项,资源占用直接降了30%。
3.2 PIO——FPGA的“手脚”
PIO,Programmable I/O,可编程输入输出。FPGA要和外界打交道,全靠这些引脚。
Lattice的PIO支持多种电平标准:LVCMOS、LVTTL、SSTL、HSTL等等。每个PIO还可以配置成输入、输出或双向。更高级的,还有DDR寄存器,可以直接在引脚上做双沿采样。
个人经验:我建议你在做PCB布局时,先把高速信号的PIO位置定好。Lattice的PIO分组是有讲究的,同一个Bank里的引脚共享同一个Vccio电压。如果你把3.3V和1.8V的信号混在同一个Bank里,那就麻烦了。
嗯,这里要注意:PIO的驱动能力是可以编程的。默认是4mA,但如果你要驱动长走线或重负载,可以调到8mA甚至12mA。不过功耗也会跟着涨,自己权衡。
3.3 DSP——数字信号处理的“加速器”
DSP块,说白了就是硬核的乘法器和累加器。Lattice的DSP块通常包含一个18x18的乘法器,后面跟着一个48位的累加器。
为什么要用DSP块?你想想看,如果用LUT搭一个乘法器,资源消耗大、速度还慢。而DSP块是硬连线,一个时钟周期就能出结果,频率还能跑到几百兆。
我曾经在一个光纤通信项目里做色散补偿滤波器,需要大量的乘累加运算。如果用LUT实现,整个芯片的资源都不够用。后来改用DSP块,一个块搞定一个抽头,效率极高。
避坑指南:我曾经犯过一个错误——DSP块的输入输出都有流水线寄存器,默认是使能的。如果你忘了配置,综合工具可能会自动插入额外的寄存器,导致时序违例。所以,用DSP块时,一定要仔细看它的流水线级数。
3.4 Block RAM——FPGA的“内存”
Block RAM,块RAM,是FPGA内部的存储资源。Lattice的Block RAM通常是9Kb或18Kb一个块,可以配置成单口、双口或真双口RAM。
每个Block RAM可以独立工作,也可以级联成更大的RAM。比如两个9Kb的块可以拼成一个18Kb的RAM。但要注意,级联时会有额外的延迟。
| 配置模式 | 位宽 | 深度 | 说明 |
|---|---|---|---|
| 单口RAM | 1~36位 | 256~9K | 一个端口读写 |
| 双口RAM | 1~18位 | 512~9K | 两个端口独立读写 |
| 真双口RAM | 1~9位 | 1024~9K | 两个端口可同时读写不同地址 |
| ROM | 1~36位 | 256~9K | 只读,初始化数据 |
我个人习惯,在做FIFO或数据缓存时,优先用Block RAM。因为它的读写速度比分布式RAM(用LUT搭的)快得多,而且不占用逻辑资源。
3.5 时钟资源——FPGA的“心跳”
时钟,是FPGA的命脉。没有稳定的时钟,一切逻辑都是空谈。
Lattice的时钟资源主要包括:
- PLL/DLL:锁相环/延迟锁相环,用来倍频、分频、移相。比如把外部50MHz晶振倍频到200MHz,或者产生一个90度相移的时钟。
- 全局时钟网络:低 skew、低延迟的时钟树,能把时钟信号均匀地送到芯片的每一个角落。
- 时钟缓冲器:用来驱动多个时钟负载。
嗯,这里要注意:全局时钟网络的输入引脚是固定的,通常只有几个专用引脚。如果你把时钟信号接到普通IO上,它走不了全局时钟网络,skew会很大,时序很难收敛。
关键点:Lattice的PLL输出可以连接到全局时钟网络,也可以直接驱动DSP或Block RAM的时钟输入。我建议你把所有高速时钟都通过PLL生成,然后走全局时钟网络。这样时钟质量最好。
3.6 全局时钟网络——让所有逻辑“同步”
全局时钟网络,说白了就是一条低延迟、低抖动的时钟高速公路。它从时钟输入引脚出发,经过一级级缓冲器,最终到达每一个触发器的时钟端。
Lattice的全局时钟网络通常有4~8条,每条都可以独立驱动。你可以把不同的时钟域放在不同的全局时钟网络上,避免互相干扰。
我曾经在一个多时钟域的项目里,把两个不同频率的时钟都接在了同一条全局时钟网络上。结果发现,高频时钟的抖动被低频时钟的切换干扰了。后来把它们分开,问题就解决了。
个人经验:如果你有多个时钟域,尽量让每个时钟域使用独立的全局时钟网络。如果全局时钟网络不够用,可以用局部时钟网络(比如PIO的时钟)来驱动小范围的逻辑。
3.7 知识体系总览
为了让你更直观地理解Lattice FPGA的内部结构,我画了一张图。这张图展示了PFU、PIO、DSP、Block RAM和时钟资源之间的关系。
这张图里,PFU、PIO、DSP、Block RAM是四大核心模块,时钟资源和全局时钟网络则是它们的“动力系统”。所有模块通过内部的互联网络(Routing)连接在一起,形成一个完整的可编程逻辑系统。
好了,这一讲的内容就到这里。记住,理解FPGA的内部结构,是做好设计的第一步。下一讲,我们会深入Lattice的开发工具,看看怎么把这些资源用起来。
总结一下:
- PFU:逻辑实现的核心,LUT+触发器+进位链
- PIO:与外界通信的接口,支持多种电平标准
- DSP:硬核乘累加器,适合数字信号处理
- Block RAM:片上存储,适合FIFO和缓存
- 时钟资源:PLL+全局时钟网络,保证时序稳定
公众号:蓝海资料掘金营,微信deep3321