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领域最常见的是两种:EDIF和Verilog网表。我建议你两种都掌握,因为不同工具、不同厂商用的格式不一样。
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 网表逆向的核心流程
我个人习惯把网表逆向分成三步走:
- 格式解析:把EDIF或Verilog网表读进内存,建立数据结构
- 层次化分析:识别顶层模块、子模块、基本单元(LUT、FF等)
- 功能提取:从LUT的INIT值、连线关系反推逻辑功能
举个例子,你看到一个LUT4的INIT值是16'h8000,这意味着什么?8000二进制是1000 0000 0000 0000,只有最高位是1。这说明这个LUT实现的是4输入与门——只有所有输入都是1时,输出才为1。你看,一个十六进制数就暴露了逻辑功能。
下面这张图展示了网表逆向的整体知识体系:
1.5 实战中的避坑指南
讲几个我踩过的坑:
- 别信网表的注释:综合工具生成的网表,注释经常是错的。我见过一个网表,注释写着“加法器”,实际是个比较器。永远以连线关系和INIT值为准。
- 注意全局信号:时钟、复位、使能这些信号在网表里可能被优化掉一部分。比如异步复位,综合工具可能把它合并到LUT的输入里了。你光看网表可能找不到复位信号——它藏在了LUT的INIT值里。
- 小心层次扁平化:有些综合工具会把所有层级拍平,所有模块变成一个巨大的网表。这时候逆向就难了——你得自己重新划分模块边界。我一般靠“高扇出信号”来找模块边界,比如一个信号驱动了几十个LUT,那它很可能是模块的输出。
我的建议:刚开始学逆向,先从简单的组合逻辑网表入手。比如一个4位加法器,综合后看看LUT怎么连的,INIT值怎么算的。等熟悉了再碰时序电路。别一上来就搞几百兆的网表文件——你会崩溃的。
好了,这一章的内容就到这里。网表逆向是个手艺活,得多练。下一章我们会深入LUT的INIT值计算,到时候我会带大家手算几个例子,保证你一看就懂。
公众号:蓝海资料掘金营,微信deep3321