第二章 网表文件格式解析:从EDIF到XDL

各位同学,欢迎来到网表逆向工程的核心环节。说实话,很多新手一上来就盯着二进制比特流猛看,结果把自己绕晕了。我的经验是——先搞懂网表文件,你就拿到了FPGA逆向的"地图"。

网表文件,说白了就是描述电路连接关系的文本。它不像原理图那么直观,但胜在精确、完整。今天咱们就啃三块硬骨头:EDIF、Verilog网表、Xilinx的NGD/XDL。

2.1 EDIF格式详解

EDIF(Electronic Design Interchange Format)是电子设计交换格式的缩写。这玩意儿诞生于80年代,现在还在用,说明它确实有两把刷子。

2.1.1 语法结构

EDIF文件是纯文本,用Lisp风格的括号嵌套。我刚开始看的时候也觉得别扭,但习惯了会发现它其实很规整。

(edif 网表名称
  (edifVersion 2 0 0)
  (edifLevel 0)
  (keywordMap (keywordLevel 0))
  
  (status
    (written
      (timeStamp 2024 01 15 10 30 00)
      (program "Vivado" (version "2023.1"))
      (comment "Generated by Vivado"))
  )
  
  (library 库名称
    (edifLevel 0)
    (technology (numberDefinition))
    
    (cell 单元名称
      (cellType GENERIC)
      (view 视图名称
        (viewType NETLIST)
        (interface
          (port 端口名称 (direction INPUT))
          (port 端口名称 (direction OUTPUT))
        )
        (contents
          (instance 实例名称
            (viewRef 视图名称 (cellRef 单元名称 (libraryRef 库名称)))
          )
          (net 网络名称
            (joined
              (portRef 端口名称 (instanceRef 实例名称))
              (portRef 端口名称 (instanceRef 实例名称))
            )
          )
        )
      )
    )
  )
)

关键点:EDIF的核心是cell(单元)和net(网络)。cell代表逻辑门或宏单元,net代表连线。逆向时,你就是在解析这些cell之间的net关系。

2.1.2 模块定义

每个EDIF文件至少包含一个library,library里包含多个cell。每个cell可以有多个view,但网表视图(NETLIST)才是我们关心的。

EDIF元素 对应硬件 逆向意义
cell 逻辑单元(LUT、FF、BRAM等) 识别功能模块
port 输入/输出引脚 确定信号流向
net 互连线 重建连接关系
instance 实例化的子模块 层次化分析

个人技巧:我习惯用Python的pyparsing库解析EDIF。写一个递归下降解析器,把括号嵌套转成树结构,后面分析就方便多了。

2.2 Verilog网表格式

Verilog网表,也叫结构级描述。它不像RTL代码那样描述行为,而是直接例化门级单元并连线。说白了,就是"把电路图翻译成文本"。

2.2.1 结构级描述的特点

看一个简单的例子:

module top (a, b, c, y);
  input a, b, c;
  output y;
  
  wire n1, n2;
  
  AND2 U1 (.I0(a), .I1(b), .O(n1));
  OR2  U2 (.I0(n1), .I1(c), .O(n2));
  INV  U3 (.I(n2), .O(y));
  
endmodule

这里每个U1、U2、U3都是标准单元库里的门。我在逆向一些老芯片时,经常遇到这种网表。它比EDIF更直观,因为语法和RTL很像。

2.2.2 网表与RTL的区别

  • RTL代码:描述"做什么"(行为级)
  • 网表:描述"怎么连"(结构级)

举个例子,RTL写 y = a & b | c,综合后网表就变成上面那三段例化。逆向时,你要从网表反推RTL逻辑。

避坑指南:我曾经遇到一个网表,里面全是XOR门,但功能却是加法器。如果只看门类型不看连接关系,很容易误判。记住:连接关系比门类型更重要。

2.3 Xilinx NGD/XDL格式概览

NGD(Native Generic Database)是Xilinx的中间格式,XDL(Xilinx Design Language)是它的文本表示。这两个格式是逆向Xilinx芯片的关键。

2.3.1 NGD格式

NGD是二进制格式,但可以用ngd2edifngd2ver转成文本。它包含:

  • 逻辑单元(LUT、FF、DSP等)
  • 互连信息(PIP、BEL等)
  • 时序约束

我个人觉得NGD最大的价值在于它保留了综合后的逻辑信息,还没被布局布线打散。逆向时,从NGD入手比从比特流入手容易得多。

2.3.2 XDL格式

XDL是Xilinx的文本网表格式,可以用xdl -ncd2xdl命令从NCD文件生成。它的结构大致如下:

design "top" xc7a35tcsg324-1 v3.0;
cell "U1" "SLICEL" {
  cfg "INIT:8'hFF" "LUT_OR_MEM:RAM" ...;
  pin "A1" "I" ;
  pin "O" "O" ;
}
net "n1" {
  outpin "U1" "O" ;
  inpin "U2" "I0" ;
  pip "SLICE_X0Y0" "A1" "D" ;
}

XDL里最核心的是pip(可编程互连点)。它描述了信号在FPGA内部走哪条路径。逆向时,解析pip就能重建完整的布线图。

实战经验:我逆向过一个Virtex-6的加密比特流,就是先用XDL把布局信息导出来,然后对照LUT的INIT值反推逻辑功能。这个过程虽然繁琐,但每一步都有章可循。

2.4 三种格式的对比

特性 EDIF Verilog网表 XDL
可读性 中等(括号多) 高(类似RTL) 中等(需要了解Xilinx架构)
信息完整度 高(含库信息) 中(不含布局信息) 极高(含布局布线)
逆向难度 中等
适用场景 跨平台交换 逻辑功能分析 物理逆向

2.5 知识体系总览

下面这张图是我自己整理的网表格式知识体系,帮你快速建立全局观:

网表格式知识体系 EDIF格式 语法:括号嵌套Lisp风格 核心:cell + net 模块:library → cell → view Verilog网表 结构级描述 门级例化 + 连线 反推RTL逻辑 Xilinx XDL NGD → XDL转换 PIP互连点解析 LUT INIT值提取 逆向工程中的选择策略 逻辑功能分析 → 优先用Verilog网表 跨平台交换 → 用EDIF 物理逆向/布局分析 → 必须用XDL

嗯,看到这里你应该明白了——网表格式解析不是死记硬背语法,而是要理解每种格式在设计流程中的位置。EDIF是交换格式,Verilog网表是逻辑视图,XDL是物理视图。逆向时,根据你的目标选择合适的切入点。

我记得第一次用XDL逆向一个加密模块时,花了整整三天才把LUT的INIT值全部提取出来。但当我重建出原始逻辑时,那种成就感——嗯,这就是逆向工程的魅力。


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