FPGA架构基础:查找表(LUT)、触发器(FF)、块RAM(BRAM)、数字信号处理单元(DSP)、可编程互连资源

做逆向这么多年,我拆过的比特流少说也有上百个了。每次拿到一个新的FPGA固件,我第一件事不是急着跑脚本,而是先搞清楚这片子里面到底有什么家底。说白了,你得知道FPGA肚子里装的都是什么零件,才能看懂比特流在指挥它们干什么。

FPGA的核心架构,其实就五大件:查找表、触发器、块RAM、DSP单元,还有把它们串起来的可编程互连。今天咱们一个一个聊。

查找表(LUT)—— 最灵活的“查字典”逻辑

LUT是什么?你可以把它想象成一个微型字典。输入几个地址,它直接告诉你对应的输出是什么。比如一个4输入LUT,内部就是一个16×1的SRAM,你往里面写什么真值表,它就实现什么逻辑。

我个人习惯把LUT叫做“万能逻辑块”。为什么?因为任何组合逻辑,只要输入不超过LUT的端口数,都能用一个LUT搞定。我在逆向一个通信协议解析器时,发现对方用LUT实现了复杂的状态编码,而不是用ROM。当时我就想,这哥们儿挺会省资源的。

关键参数:

  • 输入端口数:常见4输入、5输入、6输入(Xilinx 7系列是6输入LUT)
  • 输出端口数:通常1个,部分架构支持双输出
  • 内部存储:本质是SRAM,配置比特流直接写入

嗯,这里要注意:LUT的配置数据在比特流中是按特定格式排列的。我见过不少新手逆向时,把LUT配置位和BRAM配置位搞混,结果解析出来的逻辑完全不对。区分它们其实有个小技巧——看地址映射的连续性。

触发器(FF)—— 时序逻辑的“记忆细胞”

触发器这东西,说白了就是FPGA里的记忆单元。LUT负责算,FF负责存。没有FF,你连个计数器都做不出来。

每个FF通常紧挨着LUT,组成一个“逻辑单元”(Slice或ALM)。FF有几个关键控制端:时钟、复位/置位、使能。我在逆向一个工业控制固件时,发现对方大量使用了异步复位,这在FPGA里其实不太推荐。为什么?因为异步复位对时序收敛不友好,容易出毛刺。

避坑指南:

我曾经在逆向一个视频处理芯片时,发现FF的复位信号被配置成了“高电平有效”,但实际电路里复位信号是低电平。结果仿真时一切正常,上板就乱跳。后来查比特流才发现,是复位极性配置位搞反了。所以逆向时,一定要仔细核对FF的控制信号极性。

FF的配置在比特流中通常包含:时钟极性、复位类型(同步/异步)、初始值(Q端上电状态)。这些信息对理解固件行为至关重要。

块RAM(BRAM)—— 真正的“数据仓库”

LUT和FF存不了多少数据,真要存几百上千字节,就得靠BRAM。BRAM是FPGA里最宝贵的资源之一,因为它速度快、容量大、配置灵活。

典型的BRAM容量是36Kb(Xilinx)或20Kb(Altera),可以配置成单端口、双端口、甚至伪双端口。我见过最骚的操作,是把BRAM配置成FIFO,然后用它做跨时钟域的数据缓冲。这招在高速数据采集卡里特别常见。

配置模式 数据宽度 深度 典型用途
单端口 1-36位 1024-32768 简单数据存储
双端口 1-18位(每端口) 512-16384 跨时钟域通信
FIFO模式 1-36位 可配置 数据缓冲

逆向BRAM时,我最关注的是初始化数据。很多固件会把查找表、系数、甚至微代码放在BRAM里。我曾经从一个BRAM的初始化数据中,直接提取出了整个FFT算法的旋转因子表——这比反推逻辑快多了。

数字信号处理单元(DSP)—— 算力担当

DSP单元是FPGA里的“肌肉男”。它专门干乘法、加法、乘累加这些重活。一个DSP48E1(Xilinx 7系列)可以做到25×18位乘法,然后累加48位结果。

你想想看,如果用LUT+FF搭一个乘法器,得消耗多少资源?一个16×16乘法器大概要吃掉200多个LUT。而DSP单元一个时钟周期就搞定,还不用操心时序。

我在逆向一个雷达信号处理固件时,发现对方把DSP配置成了复数乘法模式。这种模式在通信和雷达里很常见,但配置方式比较特殊——需要把实部和虚部分别送入DSP的不同端口。比特流里对应的配置位,我花了整整两天才理清楚。

注意:DSP单元的配置位非常密集,而且不同厂商、不同系列的编码方式差异很大。逆向时不要想当然地套用已知模板,一定要先确认芯片型号和系列。

可编程互连资源—— 真正的“神经网络”

前面说的LUT、FF、BRAM、DSP,都是孤立的计算节点。把它们连成完整电路的,就是可编程互连资源。这部分在比特流里占的体积最大,也最难逆向。

互连资源包括:

  • 连线矩阵(Switch Matrix):控制信号走线的交叉点
  • 可编程连接点(PIP):决定哪条线和哪条线接通
  • 全局时钟网络:低抖动时钟分配
  • IOB(输入输出块):芯片引脚到内部逻辑的接口

我个人觉得,互连资源的逆向是整个比特流分析里最头疼的部分。因为一个PIP的状态变化,可能影响几十条路径。我习惯的做法是:先定位关键信号(时钟、复位、使能),再逐步展开。

下面这张图,是我自己总结的FPGA内部资源关系,画出来方便大家理解:

FPGA内部核心资源架构图 可编程互连资源(Programmable Interconnect) 查找表(LUT) 4/5/6输入组合逻辑 本质:16×1/32×1/64×1 SRAM 配置:真值表写入 触发器(FF) 时序逻辑记忆单元 控制端:时钟/复位/使能 配置:极性/初始值 块RAM(BRAM) 36Kb/20Kb 存储块 模式:单/双端口/FIFO 关键:初始化数据 DSP单元 25×18乘法器+48位累加 模式:乘/累加/复数乘 配置位密集且复杂 IOB(输入输出块) 芯片引脚接口 电平标准/驱动能力 连线矩阵 + PIP + 全局时钟网络

这张图里,互连资源像一张大网,把LUT、FF、BRAM、DSP、IOB全部串起来。你逆向比特流时,其实就是在逆向这张网——搞清楚每个节点连到了哪里,每个PIP是开还是关。

最后说一句:FPGA架构虽然复杂,但核心逻辑是相通的。你只要吃透了这五大件,再去看不同厂商的比特流格式,会发现很多相似之处。嗯,今天就聊到这儿。


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