3、网表基础知识回顾:综合网表结构、标准单元库、网表文件格式

各位同学,咱们今天聊网表。说实话,网表这东西,在硬件安全领域就是个“照妖镜”。你设计的RTL代码再花哨,综合成网表之后,所有逻辑都摊在台面上了。后门检测,说白了就是在这张“摊开的牌”里找猫腻。

我个人习惯把网表比作芯片的“骨架”。RTL是设计意图,网表就是具体实现。你想想看,一个后门要是藏在RTL里,可能还能用代码风格掩饰一下。但到了网表层面,每个门、每条连线都清清楚楚,想藏东西?难度大得多。

3.1 综合网表结构

综合网表,就是EDA工具把RTL代码“翻译”成标准单元库里的元件后,生成的连接关系描述。它长什么样?我直接给你看个例子。

module top (clk, rst, data_in, data_out);
  input  clk, rst;
  input  [7:0] data_in;
  output [7:0] data_out;

  wire [7:0] n1, n2;
  wire       n3;

  DFFRQX1 \reg_out_reg[0]  (.D(n2[0]), .CK(clk), .RN(rst), .Q(data_out[0]));
  DFFRQX1 \reg_out_reg[1]  (.D(n2[1]), .CK(clk), .RN(rst), .Q(data_out[1]));
  // ... 省略中间连线
  AND2X1   U1              (.A(data_in[0]), .B(n3), .Y(n1[0]));
  INVX1    U2              (.A(n1[0]), .Y(n2[0]));
endmodule

看到了吗?这就是综合后的网表。它由三部分组成:端口声明内部连线(wire)实例化单元。每个实例化单元,比如DFFRQX1AND2X1,都是标准单元库里的“积木块”。

核心要点:网表结构是层次化的。顶层模块调用底层模块,底层模块再调用标准单元。后门检测时,我们重点关注的是那些“不该出现的连线”或“异常的逻辑锥”。

我在项目中遇到过一种情况:攻击者在网表里偷偷加了一个“额外”的触发器,平时不工作,只在特定温度或电压下才激活。这种后门,光看RTL根本发现不了,但网表里多出来的那个DFF,就是铁证。

3.2 标准单元库

标准单元库,说白了就是芯片设计的“乐高积木”。里面有与门、或门、非门、触发器、锁存器等等。每个单元都有固定的功能、面积、功耗、时序参数。

为什么后门检测要懂标准单元库?因为攻击者可能会篡改标准单元本身。比如,把一个正常的“与门”改成“与或门”,或者给触发器加一个“隐藏的置位端”。

单元类型 常见名称 功能描述 后门风险
组合逻辑 AND2X1, OR2X1, INVX1 基本布尔运算 功能被篡改(如AND变OR)
时序逻辑 DFFRQX1, DFFSQX2 带复位/置位的触发器 增加隐藏复位或时钟门控
特殊单元 TIEH, TIEL, DELAY 固定电平、延迟单元 用于构造“时间炸弹”后门

我的经验:检查标准单元库时,我习惯先看“非常用单元”。比如,一个设计里突然出现了大量DELAY单元,或者TIEH/TIEL的使用方式很奇怪,那就要警惕了。我曾经在一个项目里发现,攻击者用TIEHAND2X1组合,构造了一个“永远为真”的条件,从而绕过了关键的安全校验。

3.3 网表文件格式

网表文件格式有好几种,咱们做后门检测,至少得认识三种:Verilog网表EDIFLiberty。每种格式的“脾气”不一样,解析方法也不同。

3.3.1 Verilog网表

这个最常见。就是上面代码示例那种格式。可读性好,适合人工审查。但缺点是文件体积大,尤其是几百万门的芯片,打开一个网表文件,电脑都能卡半天。

Verilog网表里,我特别关注assign语句和always块。正常情况下,综合工具生成的网表里,assign应该很少,always块更是几乎绝迹。如果看到大量always块,那八成是有人手动修改过网表。

3.3.2 EDIF格式

EDIF(Electronic Design Interchange Format)是一种中间格式。说白了,它是为了不同EDA工具之间交换数据用的。EDIF文件长这样:

(edif top
  (edifVersion 2 0 0)
  (cell top
    (cellType GENERIC)
    (view netlist
      (viewType NETLIST)
      (interface
        (port clk (direction INPUT))
        (port rst (direction INPUT))
        (port data_in (direction INPUT))
        (port data_out (direction OUTPUT))
      )
      (contents
        (instance reg_out_reg_0
          (cellRef DFFRQX1)
        )
        (net n1
          (joined
            (portRef data_in)
            (portRef A (instanceRef U1))
          )
        )
      )
    )
  )
)

EDIF的优点是标准化程度高,缺点是“啰嗦”。同样的逻辑,Verilog可能一行搞定,EDIF要写十几行。解析EDIF时,我建议用专门的解析库,别自己手写正则,容易出bug。

避坑指南:我曾经手写过一个EDIF解析器,结果被一个嵌套了8层的括号结构搞崩溃了。后来老老实实用了开源库。记住:不要重复造轮子,除非你想体验“括号地狱”。

3.3.3 Liberty格式

Liberty(.lib)文件不是网表,而是标准单元库的时序和功耗描述文件。它告诉EDA工具:每个单元在不同输入转换时间、输出负载下的延迟是多少,功耗是多少。

为什么后门检测要懂Liberty?因为攻击者可能会修改Liberty文件里的时序参数。比如,把一个关键路径上的单元延迟改小,让静态时序分析(STA)误以为时序满足要求,但实际上芯片流片后根本跑不到目标频率。

cell (AND2X1) {
  area : 5.6;
  pin (A) {
    direction : input;
    capacitance : 0.002;
  }
  pin (Y) {
    direction : output;
    function : "A & B";
    timing () {
      related_pin : "A";
      timing_type : combinational;
      cell_rise (delay_template_7x7) {
        index_1 ("0.1, 0.3, 0.5, 0.7, 0.9, 1.1, 1.3");
        index_2 ("0.01, 0.02, 0.05, 0.1, 0.2, 0.4, 0.8");
        values ( \
          "0.05, 0.08, 0.12, 0.18, 0.25, 0.35, 0.50", \
          "0.06, 0.09, 0.13, 0.19, 0.26, 0.36, 0.51", \
          // ... 省略
        );
      }
    }
  }
}

你看,Liberty文件里每个单元的延迟都是一个二维查找表。攻击者要是把某个cell_rise值改小0.1ns,在几百万门的芯片上,STA根本查不出来。但实际芯片可能就因为这条路径的时序违规,导致功能异常。

3.4 知识体系总览

为了让你更直观地理解这三者的关系,我画了一张图。你可以把它当作本章的“思维导图”。

网表基础知识体系 网表 (Netlist) 综合网表结构 标准单元库 网表文件格式 端口声明 内部连线 实例化单元 组合逻辑 时序逻辑 特殊单元 Verilog网表 EDIF格式 Liberty格式

这张图把本章的三个核心知识点串起来了。你记住:综合网表结构是“骨架”标准单元库是“血肉”网表文件格式是“皮囊”。后门检测,就是透过皮囊看血肉,再通过血肉分析骨架,最终找出那些“不该存在的东西”。

嗯,今天就先聊到这儿。网表这块内容多,但都是基础。基础不牢,地动山摇。后面咱们讲后门检测的具体方法时,你会频繁用到今天这些知识。


专注资料整理