3. 网表逻辑功能提取:组合逻辑提取、时序逻辑提取、黑盒模块识别
好,咱们进入第三章。说实话,网表逆向里最核心的活儿,就是「看懂它到底干了什么」。你手里拿着一张门级网表,里面全是 AND、OR、DFF、MUX 这些东西,怎么把它还原成有意义的逻辑功能?这就是本章要聊的。
我个人习惯把功能提取分成三块:组合逻辑、时序逻辑、还有黑盒模块。这三块的处理思路完全不同,咱们一个一个来。
3.1 组合逻辑提取:从门级到布尔表达式
组合逻辑,说白了就是没有记忆功能的电路。输入一变,输出立刻跟着变。网表里常见的组合单元包括 AND2、OR2、NAND2、NOR2、INV、AOI(与或非)、OAI(或与非)等等。
提取组合逻辑的核心思路是:从输出引脚往回追,把所有输入信号用布尔代数表示出来。
核心方法:
- 找到目标输出节点
- 递归遍历其扇入(fan-in)路径
- 遇到标准门单元,替换为对应的布尔运算符
- 遇到 AOI/OAI 等复合门,拆解为基本运算
- 化简冗余路径(比如两个反相器串联)
举个例子。假设网表里有一段这样的连接:
// 网表片段
AND2 U1 (.A(sel), .B(a), .Y(n1));
INV U2 (.A(n1), .Y(n2));
OR2 U3 (.A(n2), .B(b), .Y(out));
提取出来的布尔表达式就是:
out = (sel & a)' + b
= !(sel & a) | b
嗯,这里要注意:网表里的信号名往往被工具重命名过,比如 a 可能变成了 net_1234。我在项目中遇到过这种情况——追了三天逻辑,最后发现那个 net_5678 其实就是时钟使能信号。所以提取之前,最好先做一轮信号别名分析。
我的小技巧:
写脚本提取时,建议用「深度优先遍历 + 缓存已处理节点」。否则遇到反馈路径(比如锁存器结构),你的脚本会无限递归下去。我曾经因为这个把服务器跑崩了……嗯,从那以后我都在递归函数里加了个 visited 集合。
3.2 时序逻辑提取:DFF、锁存器与状态机
时序逻辑比组合逻辑复杂一些。因为它有「状态」,也就是记忆单元。网表里常见的时序单元包括 DFF(D触发器)、DFFR(带复位)、DFFE(带使能)、LATCH(锁存器)等。
提取时序逻辑时,我一般关注三个要素:
- 时钟引脚:CK 或 CLK,决定触发沿
- 数据输入:D 或 SI,决定下一状态
- 控制引脚:RST(复位)、SET(置位)、EN(使能)
提取出来的结果通常是这样一张表:
| DFF 实例名 | 时钟 | 数据输入表达式 | 复位方式 | 使能条件 |
|---|---|---|---|---|
| DFF_inst_1 | clk (posedge) | a & b | 异步高有效 | en |
| DFF_inst_2 | clk (negedge) | q1 | c | 同步低有效 | 1'b1 |
有了这张表,你就能进一步分析出状态机结构。比如多个 DFF 共享同一组时钟和使能,且数据输入之间存在相互引用,那大概率就是一个有限状态机(FSM)。
避坑指南:
我曾经遇到过一种情况:网表里所有 DFF 的时钟引脚都连到了同一个全局时钟网络,但仔细一看,有些 DFF 的时钟路径上插了门控单元(比如 AND 门)。这意味着实际触发时刻被修改了。如果你直接按全局时钟分析,时序逻辑提取结果会完全错误。所以,提取时序逻辑前,一定要先做时钟树分析。
3.3 黑盒模块识别:那些「看不见」的单元
黑盒模块,就是网表里只给了端口定义、没有内部实现的单元。常见于:
- 第三方 IP 核(比如 DDR 控制器、PLL)
- 硬宏单元(比如 SerDes、ADC)
- 被加密或混淆的模块
识别黑盒模块的方法其实很简单:在网表里搜索所有实例化语句,检查每个模块是否有对应的定义。如果只有实例化、没有定义,那就是黑盒。
举个例子,网表里可能有这样的内容:
// 实例化
PLL_IP u_pll (
.CLK_IN(clk_50m),
.CLK_OUT(clk_200m),
.LOCKED(pll_locked)
);
// 但整个网表里找不到 module PLL_IP ... endmodule
那 PLL_IP 就是一个黑盒模块。
识别出来后,我们需要记录它的端口信息:
| 黑盒名称 | 端口名 | 方向 | 位宽 | 连接信号 |
|---|---|---|---|---|
| PLL_IP | CLK_IN | input | 1 | clk_50m |
| PLL_IP | CLK_OUT | output | 1 | clk_200m |
| PLL_IP | LOCKED | output | 1 | pll_locked |
有了这个信息,你就能在后续的仿真验证中,给黑盒模块搭建行为级模型(behavioral model)。说白了,就是自己写一个功能等效的 Verilog 模块来替代它。
我的经验:
对于常见的黑盒(比如 PLL、DDR PHY),网上往往能找到开源的行为模型。但要注意——这些模型通常只保证功能正确,不保证时序精确。如果你在做时序仿真,最好还是找原厂提供的仿真模型。我吃过这个亏,用开源模型仿了三天,结果发现 PLL 的锁定时间差了 10 倍……
3.4 本章知识体系总览
为了让你更直观地理解这三块内容的关系,我画了一张流程图:
你看,整个流程其实很清晰:从门级网表出发,根据单元类型分流处理,最终得到三种不同形式的输出。这些输出就是后续仿真验证的输入素材。
好了,关于逻辑功能提取,我就聊这么多。记住一句话:组合逻辑看路径,时序逻辑看状态,黑盒模块看接口。把这三点吃透了,网表在你眼里就不再是一堆乱线,而是一张有逻辑的电路图。
公众号:蓝海资料掘金营,微信deep3321