3、网表格式详解:Verilog网表、EDIF格式、SPICE网表、通用网表结构解析

做逆向工程这么多年,我接触过的网表格式少说也有十几种。但说实话,真正在芯片安全分析中频繁打交道的,也就那么三四种。今天咱们就把这些「硬骨头」啃一啃。

你可能会问:为什么要懂这么多格式?嗯,我举个例子你就明白了。有一次我拿到一个芯片的网表,客户说是Verilog格式,结果打开一看,里面混着EDIF的语法。当时我就懵了。后来才发现,这是经过多次工具转换留下的「后遗症」。所以,熟悉各种格式的「方言」,是咱们这行的基本功。

3.1 Verilog网表:最熟悉的陌生人

Verilog网表,说白了就是把RTL代码综合后的「门级蓝图」。它保留了Verilog的语法骨架,但内容全是标准单元库里的实例化。

我个人习惯把Verilog网表分成三类:

  • 结构型网表:纯门级连接,没有always块
  • 混合型网表:门级+少量行为级描述
  • 扁平网表:所有层级展开,一个module搞定

来看一个典型的Verilog网表片段:

module AES_TOP (clk, rst, data_in, data_out);
  input clk, rst;
  input [127:0] data_in;
  output [127:0] data_out;

  wire [127:0] round_key;
  wire [127:0] state_reg;

  // 标准单元实例化
  DFF_X1 \state_reg_reg[0]  (.D(n1), .CK(clk), .Q(state_reg[0]), .QN());
  DFF_X1 \state_reg_reg[1]  (.D(n2), .CK(clk), .Q(state_reg[1]), .QN());
  // ... 省略中间连线

  XOR2_X1 xor_inst_0 (.A(state_reg[0]), .B(round_key[0]), .Z(data_out[0]));
endmodule
实战技巧:我在逆向AES芯片时发现,很多工程师喜欢把S盒用LUT(查找表)实现。这时候Verilog网表里会出现大量的LUT4LUT6实例。如果你看到一堆LUT连在一起,十有八九是加密算法。

3.2 EDIF格式:EDA世界的通用语

EDIF(Electronic Design Interchange Format)是个老古董了,但它在芯片安全领域反而特别有用。为什么?因为很多老芯片、军用芯片的设计文档,用的就是EDIF。

EDIF的语法很「啰嗦」,但结构清晰。它用括号嵌套的方式描述整个设计:

(edif AES_TOP
  (edifVersion 2 0 0)
  (edifLevel 0)
  (keywordMap (keywordLevel 0))
  
  (cell AES_TOP (cellType GENERIC)
    (view NETLIST (viewType NETLIST)
      (interface
        (port clk (direction INPUT))
        (port rst (direction INPUT))
        (port data_in (direction INPUT) (array (rename data_in "0") 128))
        (port data_out (direction OUTPUT) (array (rename data_out "0") 128))
      )
      (contents
        (instance state_reg_reg_0
          (cellRef DFF_X1 (libraryRef std_cells))
        )
        (net n1
          (joined
            (portRef state_reg_reg_0 D)
            (portRef xor_inst_0 Z)
          )
        )
      )
    )
  )
)

你看,EDIF用(cell ...)定义模块,用(instance ...)实例化单元,用(net ...)描述连线。这种Lisp风格的语法,刚开始看确实不习惯。

避坑指南:我曾经在处理一个EDIF网表时,发现它的端口定义和实际连接对不上。查了半天,原来是EDIF版本不一致导致的。EDIF 2 0 0和EDIF 3 0 0在数组定义上有细微差别。所以拿到EDIF文件,第一件事就是看版本号。

3.3 SPICE网表:模拟世界的显微镜

SPICE网表是模拟电路和混合信号芯片的「母语」。在芯片安全分析中,SPICE网表的价值在于——它能揭示数字网表里看不到的模拟行为。

比如,一个看似普通的反相器,在SPICE网表里可能是这样的:

.SUBCKT INV_AES VDD VSS A Z
M1 Z A VSS VSS NMOS_VTL W=0.5u L=0.18u
M2 Z A VDD VDD PMOS_VTL W=1.0u L=0.18u
.ENDS INV_AES

这里的关键信息是晶体管的宽长比(W/L)。W=1.0u的PMOS和W=0.5u的NMOS,这个比例决定了驱动能力。我在做侧信道攻击分析时,就经常通过SPICE网表里的晶体管尺寸,判断哪些路径是「关键路径」。

网表格式 抽象层级 安全分析用途 典型文件大小
Verilog 门级/寄存器传输级 逻辑功能逆向、木马检测 10KB - 100MB
EDIF 网表级 设计结构分析、层次恢复 50KB - 500MB
SPICE 晶体管级 模拟行为分析、功耗建模 1MB - 1GB+

3.4 通用网表结构:万变不离其宗

说了这么多格式,其实它们的核心结构都差不多。我总结了一个「网表三要素」:

  1. 单元(Cell/Instance):基本功能块,比如与门、触发器、存储器
  2. 端口(Port/Pin):单元的输入输出接口
  3. 连线(Net/Wire):连接端口之间的信号通路

你想想看,不管是Verilog的wire、EDIF的(net ...),还是SPICE的节点编号,本质上都是在描述这三者的关系。

核心观点:网表逆向的本质,就是从这三要素中重建出芯片的功能结构。我见过最复杂的网表有上亿个实例,但拆解开来,无非就是「单元-端口-连线」的反复嵌套。

下面这张图,是我自己总结的网表结构解析流程,你可以参考一下:

网表结构解析流程 原始网表文件 语法解析 → 提取单元/端口/连线 单元库匹配 端口连接分析 层次结构恢复 功能模块识别 → 安全分析

在实际项目中,我一般会先用脚本把网表转成统一的内部表示(比如JSON格式),然后再做分析。这样不管原始格式是什么,后面的工具链都不用改。

个人经验:如果你刚开始接触网表逆向,我建议先从Verilog网表入手。它最接近数字设计工程师的思维习惯,文档也最多。等熟练了,再挑战EDIF和SPICE。我曾经带过一个实习生,上来就啃SPICE网表,结果一周下来连晶体管都数不清。后来我让他先看Verilog,三天就能上手了。

好了,关于网表格式,今天就聊这么多。记住一点:格式只是表象,核心是理解「单元-端口-连线」这个三元组。掌握了这个,任何网表在你面前都是透明的。

专注资料整理