网表格式解析:EDIF、XNF、BLIF、Verilog网表格式差异与解析要点

做FPGA逆向,第一步就是跟网表打交道。但网表这东西,不是只有一种格式。我见过不少新手,拿着EDIF的解析器去读XNF,结果一堆乱码,还以为是工具坏了。其实说白了,每种格式都有自己的脾气。

今天我就把这四种最常见的网表格式——EDIF、XNF、BLIF、Verilog网表——掰开揉碎了讲。你想想看,搞清楚了它们的差异,解析的时候能少踩多少坑。

1. EDIF:EDA界的通用语,但太啰嗦

EDIF(Electronic Design Interchange Format)是电子设计交换格式,算是老前辈了。我最早接触它是在一个古董级项目里,客户给了一个90年代的网表,就是EDIF格式。

核心特点:

  • 基于Lisp语法,括号套括号,层级很深
  • 每个单元(cell)都有完整的端口定义和实例化
  • 支持层次化设计,子模块可以嵌套

解析要点:

  • 注意括号匹配,EDIF的括号嵌套经常超过10层,手动解析容易出错
  • 端口方向(INPUT/OUTPUT/BIDIR)定义在cell内部,不是实例化时
  • 我习惯用递归下降解析器,比正则表达式靠谱得多
; EDIF示例片段
(edif test
  (cell AND2
    (cellType GENERIC)
    (view view_1
      (interface
        (port A (direction INPUT))
        (port B (direction INPUT))
        (port Y (direction OUTPUT))
      )
      (implementation
        (net n1
          (joined
            (portRef A)
            (portRef B)
          )
        )
      )
    )
  )
)

避坑指南:我曾经遇到过一个EDIF文件,里面混用了大写和小写的关键字。EDIF标准是大小写不敏感的,但有些工具解析时却区分大小写。我的建议是:解析前先统一转成大写或小写。

2. XNF:Xilinx的专属格式,简洁但隐晦

XNF(Xilinx Netlist Format)是Xilinx公司早期的网表格式。现在用的人少了,但老项目里还能见到。我记得有一次逆向一个通信设备,里面的FPGA就是Xilinx的,网表全是XNF。

核心特点:

  • 基于文本行,每行一个指令,结构扁平
  • 符号(SYM)和网络(NET)是核心元素
  • 没有层次化,所有逻辑都在同一层

个人经验:XNF的解析其实比EDIF简单,因为它没有嵌套结构。但要注意,XNF的符号名和网络名经常被工具自动缩短,比如"U1/A"变成"U1_A"。解析时最好保留原始命名,方便后续追踪。

; XNF示例片段
SYM, AND2, U1, A=net1, B=net2, Y=net3
SYM, OR2, U2, A=net3, B=net4, Y=net5
NET, net1, I, pin1
NET, net2, I, pin2
NET, net5, O, pin3

避坑指南:XNF文件里,符号的端口顺序很重要。比如AND2的端口顺序是A、B、Y,但有些变种可能是B、A、Y。我曾经因为没注意端口顺序,把整个网表的连接关系都搞反了,排查了两天才发现。

3. BLIF:伯克利的学术派,逻辑清晰

BLIF(Berkeley Logic Interchange Format)来自加州大学伯克利分校,是学术界常用的格式。做逆向时,如果遇到学术项目或者开源工具生成的网表,大概率是BLIF。

核心特点:

  • 基于文本,以.model开头,以.end结尾
  • 逻辑门用查表(LUT)或逻辑表达式表示
  • 支持层次化,但通常用于扁平化设计
; BLIF示例片段
.model test
.inputs a b
.outputs y
.names a b y
11 1
.end

解析要点:

  • .names指令定义了一个逻辑函数,后面跟着输入输出列表
  • 逻辑表达式用"0"和"1"表示,比如"11 1"表示a=1且b=1时y=1
  • 我建议解析时把.names转换成真值表,方便后续分析

个人经验:BLIF的解析难点在于处理.latch(锁存器)和.gate(门)指令。有些工具生成的BLIF文件里,锁存器的时钟和复位信号定义得很隐晦。我一般会先提取所有.latch,再根据连接关系推断时钟域。

4. Verilog网表:现代工业标准,但陷阱多

Verilog网表是目前最主流的格式。说白了,就是把RTL代码综合后的结果,用Verilog语法写出来。我日常工作中接触最多的就是这种格式。

核心特点:

  • 基于Verilog语法,可读性好
  • 支持层次化,模块可以嵌套
  • 门级原语(AND、OR、DFF等)直接实例化
// Verilog网表示例
module test (input a, b, output y);
  wire n1;
  AND2 U1 (.A(a), .B(b), .Y(n1));
  OR2  U2 (.A(n1), .B(a), .Y(y));
endmodule

避坑指南:Verilog网表里最常见的陷阱是端口连接方式。有的工具用.name连接(如.A(a)),有的用位置连接(如AND2 U1(a, b, n1))。我建议解析时优先支持.name连接,因为位置连接容易出错。

5. 四种格式对比:一张表说清楚

特性 EDIF XNF BLIF Verilog网表
语法基础 Lisp风格 文本行 文本行 Verilog语法
层次化支持
解析难度
常见陷阱 括号嵌套、大小写 端口顺序、命名 锁存器定义 端口连接方式
适用场景 老项目、EDA工具交换 Xilinx老器件 学术项目、开源工具 现代工业设计

6. 知识体系结构图

下面这张图展示了四种网表格式的核心差异和解析要点。我画这张图的时候,特意把每种格式的"坑"标了出来,方便你快速定位。

网表格式解析知识体系 网表格式解析 EDIF XNF BLIF Verilog网表 解析要点 • 括号匹配,递归解析 • 端口方向在cell内部 • 大小写统一处理 • 注意层次化嵌套 解析要点 • 文本行解析,结构扁平 • 注意端口顺序 • 保留原始命名 • 符号与网络映射 解析要点 • .names转真值表 • 锁存器时钟推断 • 注意.latch定义 • 层次化支持弱 解析要点 • 支持.name连接 • 注意位置连接陷阱 • 模块层次化解析 • 门级原语识别 核心原则:先识别格式,再选择解析策略 每种格式都有其历史背景和设计哲学,理解这些才能避开陷阱

7. 解析策略:我的实战建议

搞清楚了格式差异,接下来就是怎么解析了。我个人习惯分三步走:

  1. 格式识别:看文件头。EDIF以(edif开头,XNF以XNF开头,BLIF以.model开头,Verilog网表以module开头。
  2. 语法解析:根据格式选择解析器。EDIF用递归下降,XNF用行解析,BLIF用状态机,Verilog网表用语法分析器。
  3. 语义提取:提取出统一的内部表示,比如模块、实例、网络、端口。这一步最关键,因为后续的逆向分析都基于这个内部表示。

个人经验:我建议在解析时保留原始格式的元数据,比如EDIF的cellType、XNF的SYM类型。这些信息在后续分析中可能派上用场。我曾经因为没保留cellType,导致无法区分组合逻辑和时序逻辑,后来不得不重新解析。

嗯,网表格式解析这块,说白了就是"知己知彼"。你了解了每种格式的脾气,解析起来就顺手多了。下次遇到一个陌生的网表文件,先别急着写解析器,花几分钟看看文件头,判断一下格式,能省下不少时间。

专注资料整理