4、网表解析工具入门:Tcl脚本基础、Vivado/Quartus命令行操作、网表文件结构分析

好,咱们进入第四章。这一章我打算聊聊工具链的入门。你可能会问:“不就是打开Vivado点几下鼠标吗?” 嗯,如果你只是做常规开发,那确实够了。但咱们搞的是网表逆向,要跟底层文件打交道,GUI那套就不太够用了。

我个人习惯,一上来先搞定三样东西:Tcl脚本命令行操作网表文件结构。这三样是基本功,就像练武要先扎马步。咱们一个一个来。

4.1 Tcl脚本基础:为什么是它?

你可能好奇,为什么FPGA工具都用Tcl?说白了,Tcl天生就是用来“粘合”各种工具的。它语法简单,解释执行,特别适合做自动化流程。我在项目中遇到过好几次,需要批量处理几百个网表文件,要是靠手动操作,那得加班到天亮。用Tcl脚本,几分钟搞定。

咱们先看几个最常用的Tcl命令,你记住这些就够了:

# 变量赋值
set my_file "top.edf"
set my_dir "./output/"

# 列表操作
set file_list [list "a.edf" "b.edf" "c.edf"]
lappend file_list "d.edf"

# 条件判断
if { [file exists $my_file] } {
    puts "文件存在:$my_file"
} else {
    puts "文件不存在,请检查路径"
}

# 循环遍历
foreach f $file_list {
    puts "正在处理:$f"
}

# 字符串处理
set base_name [file rootname $my_file]
puts "去掉扩展名后:$base_name"
我的小技巧: 调试Tcl脚本时,多用 puts 打印中间变量。我曾经因为一个变量名拼写错误,查了整整两个小时。从那以后,我每写几行就加一句打印,定位问题快多了。

你可能会问:“这些命令跟网表解析有什么关系?” 关系大了。你想想看,网表文件本质上就是文本,我们需要用脚本去读取、解析、提取信息。Tcl的字符串处理能力,正好派上用场。

4.2 Vivado/Quartus命令行操作:告别鼠标

我刚开始用Vivado时,也是习惯点鼠标。后来发现,每次都要重复点同样的菜单,太浪费时间了。而且,有些高级功能,GUI里根本找不到,只能在命令行里用。

咱们先看Vivado的Tcl模式。启动方式很简单:

# 在终端中启动Vivado Tcl模式
vivado -mode tcl

# 或者直接运行脚本
vivado -mode batch -source my_script.tcl

进入Tcl模式后,常用的命令有这些:

命令 功能 我的使用场景
open_project 打开已有工程 批量处理多个工程时
read_edif 读取EDIF网表 导入第三方网表文件
link_design 链接设计 将网表与约束文件关联
report_timing 生成时序报告 验证逆向后的时序是否一致
write_verilog 导出Verilog网表 将EDIF转为Verilog,便于对比

Quartus这边也类似,不过命令名略有不同:

# Quartus Tcl模式启动
quartus_sh -t

# 常用命令
project_open my_project
set_global_assignment -name EDIF_FILE top.edf
export_assignments
注意: 不同版本的Vivado和Quartus,命令可能会有细微差别。我曾经在Vivado 2018.3上写好的脚本,拿到2020.1版本就跑不起来了。所以,建议你每次换版本时,先跑一遍 help 命令,确认一下。

4.3 网表文件结构分析:解剖麻雀

好了,工具会用了,脚本能跑了,接下来咱们看看网表文件到底长什么样。我以最常见的EDIF格式为例,给你拆解一下。

EDIF文件,说白了就是一个文本文件,里面用括号嵌套的方式描述电路。你看这个例子:

(edif top
    (cell top
        (celltype GENERIC)
        (view netlist
            (interface
                (port clk (direction INPUT))
                (port rst (direction INPUT))
                (port data_out (direction OUTPUT))
            )
            (contents
                (instance u1
                    (cellref AND2)
                )
                (instance u2
                    (cellref DFF)
                )
                (net net1
                    (joined
                        (portref u1.O)
                        (portref u2.D)
                    )
                )
            )
        )
    )
)

这个结构其实很清晰:

  • edif:最外层,相当于一个容器
  • cell:代表一个模块,比如top顶层
  • port:端口,就是模块的输入输出
  • instance:实例,比如调用了AND2门和DFF触发器
  • net:连线,把各个实例的端口连起来

你可能会问:“这跟RTL对比验证有什么关系?” 关系大了。我们做逆向时,就是要从网表里提取出这些实例和连线,然后跟原始RTL综合出来的网表做对比。如果实例类型对不上,或者连线关系错了,那肯定就是有问题。

核心思路: 网表解析,本质上就是做三件事——
1. 提取所有实例(instance)
2. 提取所有连线(net)
3. 建立实例与连线之间的连接关系
这三件事搞定了,网表的结构就清楚了。

4.4 知识体系总览

为了让你更直观地理解这一章的知识结构,我画了一张图。你可以看到,Tcl脚本是基础工具,Vivado/Quartus命令行是操作平台,网表文件结构是分析对象。三者缺一不可。

网表解析工具入门 - 知识体系 Tcl脚本基础 命令行操作 网表文件结构 变量/列表 条件/循环 字符串处理 Vivado Tcl Quartus Tcl 批处理模式 EDIF格式 Verilog网表 实例/连线 三者结合:自动化网表解析与对比验证

看到这张图,你应该能明白,这三块内容是环环相扣的。Tcl脚本是“手”,命令行是“工具”,网表文件是“材料”。只有三者都掌握了,你才能高效地完成网表逆向与对比验证。

我的建议: 刚开始学的时候,不要贪多。先把Tcl的基本语法练熟,然后试着用命令行打开一个简单的网表文件,看看里面的结构。等你觉得顺手了,再去做复杂的自动化脚本。我曾经带过一个新人,上来就想写一个全自动对比脚本,结果写了三天没跑通。后来我让他先手动分析一个网表,他花了一小时就搞明白了。所以,循序渐进,别急。

嗯,这一章的内容就到这里。记住,工具只是手段,理解网表的结构才是核心。下一章咱们会深入具体的网表解析实战,到时候你会用到今天学的这些知识。


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