网表格式解析:SPICE、Verilog与EDIF

做逆向分析这么多年,我接触过的网表格式少说也有十几种。但真正在实战中绕不开的,就是SPICE、Verilog和EDIF这三种。说白了,它们就像三种不同的语言,描述的是同一个电路,但语法和侧重点完全不同。

我个人习惯把网表格式分成两类:一类是给仿真器看的,比如SPICE;另一类是给综合工具和布局布线工具看的,比如Verilog网表和EDIF。你想想看,如果你连网表文件里写的是什么都不清楚,那逆向分析根本无从下手。

SPICE网表格式

SPICE网表是历史最悠久的格式之一。我刚开始做逆向时,遇到过一个老项目,所有文档都丢了,只剩下一堆.SP文件。那时候真是硬着头皮啃下来的。

SPICE网表的核心结构其实很简单:

.subckt INV_INTERNAL A Z VDD VSS
M1 Z A VSS VSS NMOS W=0.5U L=0.18U
M2 Z A VDD VDD PMOS W=1.0U L=0.18U
.ends INV_INTERNAL

这里有几个关键点:

  • .subckt / .ends:定义子电路,相当于一个模块的边界。我见过有人把整个芯片写成一个巨大的.subckt,那逆向起来简直噩梦。
  • 器件声明:M代表MOS管,Q代表双极型晶体管,R/C/L分别代表电阻电容电感。每个器件后面跟着节点连接和参数。
  • 节点连接:SPICE里节点名可以是数字或字符串。数字0通常代表地(GND)。

重要提示:SPICE网表里没有显式的逻辑门概念。一个反相器就是两个MOS管的连接。所以做逆向时,你需要自己识别出这些基本单元。

我在项目中遇到过一种情况:有些老设计会用数字节点名,比如1、2、3。但后来发现这些数字和管脚编号完全没关系,纯粹是EDA工具随机生成的。嗯,这里要注意,别被数字迷惑了。

Verilog网表格式

Verilog网表是现在最主流的格式。它比SPICE抽象了一层,直接用门级原语来描述电路。

module top (clk, rst, data_in, data_out);
  input clk, rst, data_in;
  output data_out;
  wire n1, n2, n3;

  INVX1 U1 (.A(data_in), .Y(n1));
  NAND2X1 U2 (.A(n1), .B(clk), .Y(n2));
  DFFX1 U3 (.D(n2), .CK(clk), .Q(data_out));
endmodule

Verilog网表的特点:

  • module / endmodule:定义模块边界,和SPICE的.subckt类似。
  • wire声明:定义内部连线。我建议你养成好习惯,先看wire声明,这能帮你快速了解模块内部有多少信号。
  • 门实例化:像INVX1、NAND2X1这样的标准单元。名字后面的X1通常代表驱动强度。

个人技巧:做逆向时,我通常会先找DFF(触发器)的实例化。因为时序逻辑的起点和终点都在DFF上,找到它们就能画出时序路径。

我曾经遇到过一个坑:某个Verilog网表里所有wire都叫_n1、_n2这种名字,而且没有注释。后来我写了个脚本,根据连接关系自动重命名,才把电路理清楚。

EDIF格式简介

EDIF(Electronic Design Interchange Format)是一种中间格式,用来在不同EDA工具之间传递网表数据。说实话,现在直接用EDIF的人不多了,但逆向分析时偶尔会遇到。

EDIF的语法比较啰嗦,我举个例子:

(edif top
  (cell INVX1
    (view netlist
      (interface
        (port A (direction INPUT))
        (port Y (direction OUTPUT))
      )
      (contents
        (instance M1 (cellRef NMOS))
        (instance M2 (cellRef PMOS))
        (net n1 (joined (portRef A) (portRef M1.G)))
      )
    )
  )
)

EDIF的特点:

  • 使用Lisp风格的括号嵌套,阅读起来不太直观。
  • 每个元素都有明确的类型声明,比如cell、instance、net。
  • 支持层次化设计,可以嵌套子电路。

避坑指南:我曾经处理过一个EDIF文件,里面居然混用了两种不同的命名规范。同一个信号,在顶层叫CLK,在底层叫clock。这种不一致会让逆向分析变得非常痛苦。建议先做一次标准化处理。

三种格式的对比

特性 SPICE Verilog EDIF
抽象层次 晶体管级 门级 门级/行为级
可读性 较低 较高 中等
工具支持 仿真为主 综合/仿真/布局布线 数据交换
逆向难度 高(需识别晶体管连接) 中(门级较直观) 中高(括号嵌套复杂)

为什么会这样?因为SPICE保留了最底层的物理信息,而Verilog和EDIF已经做了逻辑抽象。你想想看,从两个MOS管识别出一个反相器,和直接看到一个INVX1的门实例,难度完全不一样。

知识体系结构图

下面这张图展示了三种网表格式在逆向分析中的定位和关系:

网表格式知识体系 SPICE网表 .subckt / .ends 器件声明 (M/Q/R/C) 节点连接 晶体管级描述 逆向难度:高 Verilog网表 module / endmodule wire声明 门实例化 门级抽象 逆向难度:中 EDIF格式 括号嵌套语法 cell / instance / net 层次化设计 数据交换格式 逆向难度:中高 抽象 转换 核心:理解不同格式的抽象层次,是网表逆向分析的基础

这张图其实反映了我做逆向分析时的思考路径。拿到一个网表,先看它是什么格式,然后根据格式特点选择不同的分析策略。SPICE格式需要从晶体管连接中提取逻辑门,Verilog格式可以直接识别门级结构,EDIF格式则需要先解析括号嵌套。

嗯,最后说一句。不管你用哪种格式,命名规范层次化结构永远是逆向分析的两大法宝。我见过太多乱七八糟的网表,但只要抓住这两个点,再乱的电路也能理出头绪。


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