第二讲:网表基础回顾

各位同学好,我是老张。今天咱们聊聊网表的基础知识。说实话,网表这东西,看着简单,但很多安全漏洞恰恰就藏在这些基础结构里。我做了十几年芯片安全分析,见过太多因为对网表理解不透彻而踩坑的案例。

一、网表的基本结构

网表是什么?说白了,它就是芯片的「电路连接图」的文本描述。你想想看,一个芯片里有几亿个晶体管,总不能一个个画出来吧?网表就是用文本的方式,把这些连接关系说清楚。

网表由三个核心要素组成:

  • 标准单元(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两个子模块。每个子模块又可以继续展开。

避坑指南:我曾经遇到过一个案例,攻击者在层次化网表的某个中间层级,悄悄插入了一个「幽灵模块」。这个模块在顶层网表里看不到,只有展开到特定层级才能发现。所以做安全分析时,一定要把网表完全展开到标准单元级别,不能只看顶层。

四、知识体系结构图

下面我用一张图来总结本章的知识体系:

网表基础回顾 - 知识体系 网表 标准单元 宏单元 连线 Verilog网表 EDIF格式 SPICE网表 层次化设计(模块实例化) 安全漏洞挖掘

这张图展示了网表知识的层次关系。从最底层的标准单元、宏单元、连线,到不同格式的网表,再到层次化设计,最终都服务于安全漏洞挖掘这个目标。

我的建议:刚开始学网表分析时,别急着看复杂电路。先把标准单元库的文档吃透,搞清楚每个单元的输入输出、功能、时序。这是基本功,就像练武要先扎马步一样。我当年花了整整两周时间,把公司标准单元库的500多个单元全部过了一遍,后来做安全分析时,很多问题一眼就能看出来。

好了,网表基础就讲到这里。记住,网表是芯片的「骨架」,理解它才能找到藏在里面的「毒刺」。下一讲我们聊聊如何用工具自动化分析网表,到时候我会分享一些实用的脚本技巧。


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