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 本章知识体系总览

为了让你更直观地理解这三块内容的关系,我画了一张流程图:

网表逻辑功能提取流程 门级网表 组合逻辑提取 时序逻辑提取 黑盒模块识别 扇入遍历 → 布尔表达式 时钟/数据/控制引脚分析 实例化 vs 定义检查 布尔方程 / 真值表 状态转移表 / FSM 端口列表 / 行为模型

你看,整个流程其实很清晰:从门级网表出发,根据单元类型分流处理,最终得到三种不同形式的输出。这些输出就是后续仿真验证的输入素材。

好了,关于逻辑功能提取,我就聊这么多。记住一句话:组合逻辑看路径,时序逻辑看状态,黑盒模块看接口。把这三点吃透了,网表在你眼里就不再是一堆乱线,而是一张有逻辑的电路图。


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