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
LUT4或LUT6实例。如果你看到一堆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风格的语法,刚开始看确实不习惯。
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 通用网表结构:万变不离其宗
说了这么多格式,其实它们的核心结构都差不多。我总结了一个「网表三要素」:
- 单元(Cell/Instance):基本功能块,比如与门、触发器、存储器
- 端口(Port/Pin):单元的输入输出接口
- 连线(Net/Wire):连接端口之间的信号通路
你想想看,不管是Verilog的wire、EDIF的(net ...),还是SPICE的节点编号,本质上都是在描述这三者的关系。
下面这张图,是我自己总结的网表结构解析流程,你可以参考一下:
在实际项目中,我一般会先用脚本把网表转成统一的内部表示(比如JSON格式),然后再做分析。这样不管原始格式是什么,后面的工具链都不用改。
好了,关于网表格式,今天就聊这么多。记住一点:格式只是表象,核心是理解「单元-端口-连线」这个三元组。掌握了这个,任何网表在你面前都是透明的。