1. FPGA网表逆向基础:网表概念、逆向工程概述、网表格式解析

大家好,我是你们的FPGA逆向分析讲师。今天咱们聊聊网表逆向的入门知识。说实话,这行干久了你会发现,网表就像芯片的“DNA”——它记录了设计最底层的逻辑关系。我刚开始接触逆向时,对着密密麻麻的网表文件头皮发麻,后来慢慢摸清了门道,才发现这东西其实挺有意思的。

1.1 网表到底是什么?

网表,说白了就是一张“连线图”。它告诉你:哪些逻辑门连在一起,信号怎么走,模块之间怎么通信。你可以把它理解成数字电路的“电路原理图”,只不过是用文本描述的。

举个例子,你写了一段Verilog代码:

module add(a, b, sum);
  input [3:0] a, b;
  output [3:0] sum;
  assign sum = a + b;
endmodule

综合工具会把它变成网表。网表里没有“加法”这个概念,只有一堆LUT(查找表)、进位链、寄存器。我当年第一次看到综合后的网表,心想:“这跟我写的代码完全不一样啊!”——嗯,这就是网表的本质:它把高级语言翻译成了底层硬件的“方言”。

核心要点:网表是综合工具的输出,是FPGA布局布线的输入。它描述了逻辑单元(LUT、FF、DSP、BRAM等)以及它们之间的连接关系。

1.2 逆向工程概述——为什么要逆向网表?

你可能会问:“好好的设计,为什么要逆向?”我遇到过几种典型场景:

  • IP核分析:拿到一个黑盒IP,想知道它内部怎么工作的
  • 安全审计:检查有没有后门、木马逻辑
  • 兼容性验证:老项目丢了源码,只有网表,需要改功能
  • 竞品分析:看看别人家的实现思路(当然要在法律允许范围内)

我记得有一次,客户拿了个加密的比特流文件,说设备坏了想修。我们只能从比特流反推网表,再反推RTL。那过程就像拼图——你手里只有碎片,得靠经验把图案拼出来。

注意:逆向工程有法律风险。请确保你有合法授权,或者用于学习研究目的。我曾经见过有人因为逆向商业IP吃官司,得不偿失。

1.3 网表格式解析——EDIF与Verilog网表

网表格式有很多种,但FPGA领域最常见的是两种:EDIFVerilog网表。我建议你两种都掌握,因为不同工具、不同厂商用的格式不一样。

1.3.1 EDIF格式

EDIF(Electronic Design Interchange Format)是一种标准格式,很多EDA工具都支持。它的语法有点像Lisp,全是括号嵌套括号。我第一次看EDIF文件时,差点看吐了——括号套括号,层级深得吓人。

一个简单的EDIF片段长这样:

(edif add
  (cell ADD_TOP
    (view VIEW_NETLIST
      (interface
        (port a (direction INPUT))
        (port b (direction INPUT))
        (port sum (direction OUTPUT))
      )
      (contents
        (instance U1 (cellref LUT4))
        (net n1
          (joined
            (portref a)
            (portref U1.I0)
          )
        )
      )
    )
  )
)

你看,每个单元(cell)都有端口(port)和实例(instance),网络(net)描述连线。解析EDIF的关键是:找到顶层模块,然后一层层往下剥。我习惯用Python写解析器,递归处理括号结构。

小技巧:解析EDIF时,先把所有cell定义提取出来,再找顶层cell。顶层cell通常没有父cell引用它。这招我在多个项目里屡试不爽。

1.3.2 Verilog网表

Verilog网表比EDIF友好多了。它就是用Verilog语法描述的门级电路。比如:

module add_netlist (a, b, sum);
  input [3:0] a;
  input [3:0] b;
  output [3:0] sum;

  wire [3:0] n1, n2;
  LUT4 #(.INIT(16'h6996)) U1 (.I0(a[0]), .I1(b[0]), .O(n1[0]));
  LUT4 #(.INIT(16'h6996)) U2 (.I0(a[1]), .I1(b[1]), .O(n1[1]));
  // ... 更多实例
endmodule

看到没?每个LUT都有一个INIT参数,这个参数决定了LUT的逻辑功能。比如16'h6996就是异或门的真值表。我刚开始逆向时,经常对着INIT值发呆——这串十六进制数到底代表什么逻辑?后来我写了个小工具,把INIT值转成真值表,一目了然。

两种格式对比一下:

特性 EDIF Verilog网表
可读性 差(括号地狱) 较好(类RTL语法)
工具支持 广泛(标准格式) 主流EDA都支持
解析难度 中等(需处理嵌套) 简单(可用Verilog解析器)
信息密度 高(包含完整层级) 中等(有时会丢失部分信息)

1.4 网表逆向的核心流程

我个人习惯把网表逆向分成三步走:

  1. 格式解析:把EDIF或Verilog网表读进内存,建立数据结构
  2. 层次化分析:识别顶层模块、子模块、基本单元(LUT、FF等)
  3. 功能提取:从LUT的INIT值、连线关系反推逻辑功能

举个例子,你看到一个LUT4的INIT值是16'h8000,这意味着什么?8000二进制是1000 0000 0000 0000,只有最高位是1。这说明这个LUT实现的是4输入与门——只有所有输入都是1时,输出才为1。你看,一个十六进制数就暴露了逻辑功能。

下面这张图展示了网表逆向的整体知识体系:

FPGA网表逆向知识体系 输入文件 EDIF / Verilog网表 格式解析 语法分析 / 数据结构构建 层次化分析 模块识别 / 单元提取 LUT功能提取 INIT值 → 真值表 连线关系重建 信号追踪 / 扇出分析 时序单元识别 FF / 锁存器 / 时钟域 功能级RTL重建 组合逻辑 → 时序逻辑 → 模块化

1.5 实战中的避坑指南

讲几个我踩过的坑:

  • 别信网表的注释:综合工具生成的网表,注释经常是错的。我见过一个网表,注释写着“加法器”,实际是个比较器。永远以连线关系和INIT值为准。
  • 注意全局信号:时钟、复位、使能这些信号在网表里可能被优化掉一部分。比如异步复位,综合工具可能把它合并到LUT的输入里了。你光看网表可能找不到复位信号——它藏在了LUT的INIT值里。
  • 小心层次扁平化:有些综合工具会把所有层级拍平,所有模块变成一个巨大的网表。这时候逆向就难了——你得自己重新划分模块边界。我一般靠“高扇出信号”来找模块边界,比如一个信号驱动了几十个LUT,那它很可能是模块的输出。

我的建议:刚开始学逆向,先从简单的组合逻辑网表入手。比如一个4位加法器,综合后看看LUT怎么连的,INIT值怎么算的。等熟悉了再碰时序电路。别一上来就搞几百兆的网表文件——你会崩溃的。

好了,这一章的内容就到这里。网表逆向是个手艺活,得多练。下一章我们会深入LUT的INIT值计算,到时候我会带大家手算几个例子,保证你一看就懂。


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