第二讲:网表基础回顾
各位同学好,我是老张。今天咱们聊聊网表的基础知识。说实话,网表这东西,看着简单,但很多安全漏洞恰恰就藏在这些基础结构里。我做了十几年芯片安全分析,见过太多因为对网表理解不透彻而踩坑的案例。
一、网表的基本结构
网表是什么?说白了,它就是芯片的「电路连接图」的文本描述。你想想看,一个芯片里有几亿个晶体管,总不能一个个画出来吧?网表就是用文本的方式,把这些连接关系说清楚。
网表由三个核心要素组成:
- 标准单元(Standard Cell):就是那些基础逻辑门,比如与门、或门、触发器、锁存器。这些是芯片设计的基本积木块。
- 宏单元(Macro Cell):比如SRAM、ROM、PLL、ADC这些大块头。它们内部结构复杂,但在网表里被当作一个黑盒子处理。
- 连线(Net):就是把这些单元连接起来的「导线」。在网表里,每条线都有一个名字。
重点提醒:标准单元和宏单元的区分,在安全分析中非常关键。我曾经遇到过一个案例,攻击者利用宏单元内部的未使用引脚,悄悄注入了后门电路。如果你不了解宏单元的接口定义,根本发现不了。
二、网表格式
网表格式有好几种,我挑最常用的三种讲讲。
1. Verilog网表
这是数字芯片设计中最常见的格式。它用Verilog语言描述电路连接。举个例子:
module top (
input clk,
input rst_n,
input [7:0] data_in,
output [7:0] data_out
);
wire [7:0] reg_data;
DFF dff_inst (
.clk(clk),
.rst_n(rst_n),
.d(data_in),
.q(reg_data)
);
assign data_out = reg_data;
endmodule
这段代码描述了一个简单的寄存器电路。注意看,每个实例化(比如DFF dff_inst)对应一个标准单元,wire声明就是连线。
我的经验:做安全分析时,我习惯先把Verilog网表里的所有wire和reg列出来,画个连接图。这样能快速发现异常连接——比如某条线不该连到某个模块,结果连上了,那八成有问题。
2. EDIF格式
EDIF(Electronic Design Interchange Format)是一种中间格式,用于不同EDA工具之间交换数据。它长得像Lisp语言,全是括号:
(edif top
(cell top
(view netlist
(interface
(port clk (direction INPUT))
(port rst_n (direction INPUT))
(port data_in (direction INPUT))
(port data_out (direction OUTPUT))
)
(contents
(instance dff_inst
(cellref DFF (library std_cells))
)
(net clk
(joined
(portref clk)
(portref dff_inst clk)
)
)
)
)
)
)
说实话,EDIF可读性很差。我当年刚入行时,看到这种格式就头疼。但没办法,有些老工具只认EDIF。我的建议是:用脚本把EDIF转成Verilog再分析,别硬啃。
3. SPICE网表
SPICE网表用于模拟电路和晶体管级描述。它长这样:
.SUBCKT inverter vin vout vdd vss
M1 vout vin vdd vdd PMOS W=1u L=0.18u
M2 vout vin vss vss NMOS W=0.5u L=0.18u
.ENDS inverter
这里描述了一个反相器,包含两个晶体管(PMOS和NMOS)。SPICE网表在安全分析中主要用于检查模拟电路部分,比如电源管理模块、时钟生成电路等。
| 格式 | 适用场景 | 可读性 | 安全分析重点 |
|---|---|---|---|
| Verilog网表 | 数字电路 | 高 | 逻辑连接、状态机 |
| EDIF | 工具交换 | 低 | 接口一致性 |
| SPICE网表 | 模拟/混合信号 | 中 | 晶体管级后门 |
三、网表层次化设计
现代芯片动辄上亿门,不可能平铺直叙地设计。层次化设计是必须的。简单说,就是把大模块拆成小模块,小模块再拆成更小的模块,直到标准单元级别。
举个例子:一个CPU芯片,顶层是CPU核,下面拆成取指单元、译码单元、执行单元、访存单元、写回单元。每个单元又拆成更小的模块,比如ALU、寄存器堆、控制逻辑等。
在网表里,层次化通过模块实例化来实现:
module cpu_core (
input clk, rst_n,
input [31:0] instr,
output [31:0] result
);
wire [31:0] pc, alu_out;
fetch_unit u_fetch (
.clk(clk),
.rst_n(rst_n),
.pc(pc)
);
alu u_alu (
.a(pc),
.b(32'd4),
.op(3'b001),
.result(alu_out)
);
assign result = alu_out;
endmodule
这里cpu_core是顶层,里面实例化了fetch_unit和alu两个子模块。每个子模块又可以继续展开。
避坑指南:我曾经遇到过一个案例,攻击者在层次化网表的某个中间层级,悄悄插入了一个「幽灵模块」。这个模块在顶层网表里看不到,只有展开到特定层级才能发现。所以做安全分析时,一定要把网表完全展开到标准单元级别,不能只看顶层。
四、知识体系结构图
下面我用一张图来总结本章的知识体系:
这张图展示了网表知识的层次关系。从最底层的标准单元、宏单元、连线,到不同格式的网表,再到层次化设计,最终都服务于安全漏洞挖掘这个目标。
我的建议:刚开始学网表分析时,别急着看复杂电路。先把标准单元库的文档吃透,搞清楚每个单元的输入输出、功能、时序。这是基本功,就像练武要先扎马步一样。我当年花了整整两周时间,把公司标准单元库的500多个单元全部过了一遍,后来做安全分析时,很多问题一眼就能看出来。
好了,网表基础就讲到这里。记住,网表是芯片的「骨架」,理解它才能找到藏在里面的「毒刺」。下一讲我们聊聊如何用工具自动化分析网表,到时候我会分享一些实用的脚本技巧。
公众号:蓝海资料掘金营,微信deep3321