4. Lattice FPGA逻辑资源与DSP使用
在Lattice FPGA上做算法加速,第一步不是写RTL,而是先弄清楚“算法要消耗哪些资源、这些资源在器件里长什么样、综合器会把它推断成什么”。Lattice的ECP5、Nexus、CertusPro-NX等系列,其可编程逻辑单元(PLC)通常由查找表(LUT)、进位链、寄存器(FF)和分布式RAM(Distributed RAM)组成,再配合专用的块RAM(EBR)和DSP Slice(乘法累加单元)。理解这些资源的物理结构和推断规则,才能把算法映射到合适的硬件上,并在选型时判断“这颗芯片装不装得下”。
一、LUT与寄存器:逻辑的基本单元
Lattice的4输入LUT(LUT4)本质上是一块16×1的SRAM,通过4位输入地址查表输出1位结果。它不仅能实现任意4输入组合逻辑,还能被综合器推断为分布式RAM或移位寄存器(SRL)。例如,一个4位输入、1位输出的异或逻辑,综合后占用1个LUT4;而一个8位输入的与门,则需要多个LUT4级联。寄存器是LUT输出后的D触发器,用于时序路径的暂存。Lattice PLC中LUT和FF通常成对出现,但并非强制绑定——纯组合逻辑可以只用LUT,纯寄存器可以只用FF。
推断方法上,综合器(如Lattice Diamond的Synplify Pro或Radiant的LSE)会根据代码风格自动选择LUT或分布式RAM。例如,当代码中出现小容量、异步读的数组时,综合器倾向于用分布式RAM实现;而同步读、容量较大的数组则优先映射到EBR。关键判断依据是:读地址是否同步、容量是否超过单个LUT可实现的深度、是否需要复位等。
二、分布式RAM与块RAM:存储资源的两种形态
分布式RAM由多个LUT4拼接而成,每个LUT4可提供16×1的存储深度。例如,一个32×4的分布式RAM需要约8个LUT4(32/16=2,再乘以4位宽)。它的优点是灵活、可分散布局、支持异步读;缺点是容量小、占用逻辑资源。块RAM(EBR)是专用存储块,Lattice ECP5每个EBR为18Kb,可配置为单口、双口、伪双口等模式,支持同步读写。例如,一个1024×18的缓冲区,用1个EBR即可实现;若用分布式RAM,则需要约1152个LUT4,显然不现实。
推断时,综合器通常遵循以下规则:容量小于64位且异步读的数组,倾向分布式RAM;容量大于256位或需要同步读的数组,倾向EBR。但这不是绝对的——可以通过综合属性(如ram_style)强制指定。在Lattice Radiant中,常用属性为syn_ramstyle="block_ram"或"distributed_ram"。实际工程中,建议对关键存储显式指定,避免综合器“猜错”导致资源浪费或时序不收敛。
三、DSP Slice:算法加速的核心
Lattice的DSP Slice(在ECP5中称为sysDSP,在Nexus中称为DSP48)通常包含一个乘法器、一个累加器、预加器和流水线寄存器。以ECP5为例,每个sysDSP支持18×18或36×36乘法,并可级联形成更宽的乘法器。DSP Slice的推断非常依赖代码风格:当综合器看到a * b + c这样的乘累加结构时,会优先映射到DSP;而如果写成a * b后再单独加c,可能被拆成LUT乘法加LUT加法,导致资源浪费和时序恶化。
实际工程中,建议将乘累加写成单条表达式,并显式使用流水线寄存器。例如,在Verilog中:
always @(posedge clk) begin
mult_reg <= a * b; // 推断为DSP乘法
acc_reg <= acc_reg + mult_reg; // 推断为DSP累加
end
若写成acc_reg <= acc_reg + a * b;,综合器通常也能识别为DSP,但流水线级别可能不同。对于需要高吞吐率的算法(如FIR滤波、矩阵乘法),应确保DSP的输入和输出都经过寄存器,以提升时序余量。
四、资源估算与选型依据
资源估算的核心是“算法→资源”的映射。以16阶FIR滤波器为例,假设系数为16位、数据为16位、输出为32位。每个抽头需要一个16×16乘法器和一个32位累加器。若用DSP实现,每个抽头占用1个DSP Slice(ECP5的sysDSP支持18×18),16阶共需16个DSP。若用LUT实现乘法,一个16×16乘法器约需200~300个LUT4,16阶则需3200~4800个LUT,显然不经济。因此,FIR滤波器应优先使用DSP。
存储方面,若FIR需要缓存16个历史数据,每个16位,共256位。这可以用分布式RAM实现(约16个LUT4),也可以用EBR实现(1个EBR即可,但会浪费容量)。此时应选择分布式RAM,因为容量小且读地址异步。若缓存1024个数据,则必须用EBR。
选型时,先统计算法所需的乘法器数量、累加器位宽、存储容量和读写带宽,再对照器件手册中的LUT、FF、分布式RAM、EBR和DSP数量。例如,Lattice ECP5-45F拥有约44K LUT、44K FF、1.8Mb EBR和72个sysDSP。若算法需要80个DSP,则ECP5-45F不够,需选更大器件或优化算法(如时分复用DSP)。
- 乘法器数量 ≤ DSP Slice数量?若超出,考虑时分复用或LUT乘法。
- 存储容量 ≤ EBR总容量?小容量优先分布式RAM。
- 逻辑资源(LUT+FF)是否满足控制逻辑和接口需求?
- 时序约束下,DSP和EBR的流水线级数是否足够?
最后,资源估算不是一次性的,而应在综合后查看报告(如Radiant的.mrp文件),对比预估与实际占用。若LUT占用远超预期,检查是否有大数组被推断为分布式RAM;若DSP占用不足,检查乘法代码是否被拆散。通过“代码风格→推断结果→资源报告”的闭环,才能逐步优化算法在Lattice FPGA上的实现。