第三章 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。但要注意,级联时会有额外的延迟。

配置模式位宽深度说明
单口RAM1~36位256~9K一个端口读写
双口RAM1~18位512~9K两个端口独立读写
真双口RAM1~9位1024~9K两个端口可同时读写不同地址
ROM1~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和时钟资源之间的关系。

Lattice FPGA 内部结构总览 PFU 逻辑单元 LUT + 触发器 + 进位链 实现组合/时序逻辑 可配置为RAM/ROM PIO 输入输出 多种电平标准 输入/输出/双向 DDR寄存器 DSP 数字信号处理 18x18 乘法器 48位累加器 流水线寄存器 Block RAM 块RAM 9Kb/18Kb 每块 单口/双口/真双口 可级联成大RAM 时钟资源 PLL/DLL 倍频分频 全局时钟网络 时钟缓冲器 全局时钟网络 低skew时钟树 4~8条独立网络 连接所有逻辑单元 各模块通过内部互联网络(Routing)连接,时钟资源为所有模块提供同步时钟

这张图里,PFU、PIO、DSP、Block RAM是四大核心模块,时钟资源和全局时钟网络则是它们的“动力系统”。所有模块通过内部的互联网络(Routing)连接在一起,形成一个完整的可编程逻辑系统。

好了,这一讲的内容就到这里。记住,理解FPGA的内部结构,是做好设计的第一步。下一讲,我们会深入Lattice的开发工具,看看怎么把这些资源用起来。

总结一下:

  • PFU:逻辑实现的核心,LUT+触发器+进位链
  • PIO:与外界通信的接口,支持多种电平标准
  • DSP:硬核乘累加器,适合数字信号处理
  • Block RAM:片上存储,适合FIFO和缓存
  • 时钟资源:PLL+全局时钟网络,保证时序稳定

公众号:蓝海资料掘金营,微信deep3321