【Backend Flow工程实践 12】Collection / Property / Filter:为什么对象查询能力决定 Backend 脚本工程上限?

作者:Darren H. Chen

方向:Backend Flow / 后端实现流程 / EDA 工具工程 / Tcl 脚本工程

demo:LAY-BE-12_collection_property_filter

标签:Backend Flow、EDA、Tcl、Collection、Property、Filter、Design Object Model、后端实现

在前面的文章里,我们已经讨论了一个基础问题:Backend 工具真正理解设计之后,内部看到的不是 Verilog 文本,而是一组可被查询、可被筛选、可被操作的设计对象。

这些对象包括:

text 复制代码
cell
net
pin
port
module
clock
site
row
shape
violation
property

但是,仅仅知道有这些对象还不够。真正进入工程阶段后,最关键的问题会变成:

text 复制代码
如何从几十万、几百万甚至上千万个对象中,稳定地找到你要处理的那一小部分?

这就引出了 Backend Tcl 脚本里最重要的三类能力:

text 复制代码
Collection
Property
Filter

它们看起来只是对象查询接口的一部分,但从底层架构看,它们决定的是:

工具数据库如何把"海量设计对象"转化成"可控工程操作集合"。

本文不讨论某个具体命令怎么背,而是从系统模型角度讲清楚:为什么 Collection / Property / Filter 是 Backend 脚本工程的核心能力。


一、对象查询为什么不能只靠名字匹配?

很多人最开始写 Tcl 脚本时,会习惯这样想:

text 复制代码
我要找某个 cell,就按名字找;
我要找某个 net,就按名字找;
我要找某个 pin,就按名字找。

例如:

tcl 复制代码
get_cells U123
get_nets clk
get_pins U123/A

这当然是必要能力,但远远不够。因为真实设计中,很多工程问题不是"找一个名字",而是"找一类对象"。

例如:

text 复制代码
找所有未放置的 cell;
找所有 fixed macro;
找所有 clock net;
找所有 high fanout net;
找所有属于某个 hierarchy 的 instance;
找所有没有物理 shape 的 pin;
找所有 timing critical path 上的 cell;
找所有 power/ground port;
找所有某个 property 满足条件的对象。

这类问题如果只靠名字匹配,会很快失控。因为名字只是对象的一种外部标识,而 Backend 工程真正关心的是对象的状态、属性、关系和上下文。

所以,Backend Tcl 查询的核心不是字符串处理,而是:

在设计数据库中构造对象集合,并在集合上进行属性判断和关系筛选。


二、Collection 是什么?

可以把 Collection 理解成:

一组被工具数据库识别的对象引用。

它不是普通字符串列表。普通字符串列表只是文本:

text 复制代码
U1 U2 U3

而 Collection 背后通常对应数据库对象:

text 复制代码
cell object handle
net object handle
pin object handle
port object handle

这意味着 Collection 至少有三个重要特点。

1. 它有对象类型

一个 Collection 可能是:

text 复制代码
cell collection
net collection
pin collection
port collection
shape collection
violation collection

不同类型的 Collection 能被不同命令消费。

2. 它有数据库身份

对象不只是名字。一个 cell 的名字可能显示为:

text 复制代码
U123

但在工具内部,它还可能有:

text 复制代码
object id
hierarchical path
master cell
location
orientation
fixed status
physical status
properties

Collection 保存的是对象引用,而不只是名字文本。

3. 它可以继续被操作

Collection 的价值不在于"查出来",而在于它可以继续作为后续命令的输入。

text 复制代码
查询对象
↓
筛选对象
↓
读取属性
↓
生成报告
↓
修改状态
↓
再次查询

这就是 Backend Tcl 脚本和普通文本脚本的根本差异。


三、Property 是什么?

如果 Collection 回答的是:

text 复制代码
有哪些对象?

那么 Property 回答的是:

text 复制代码
这些对象是什么状态?

一个 cell 可能有属性:

text 复制代码
name
ref_name
is_fixed
is_placed
location
orientation
area
is_macro
is_sequential
is_clock_cell
dont_touch

一个 net 可能有属性:

text 复制代码
name
usage
fanout
is_clock
is_power
is_ground
total_capacitance
driver
loads

一个 pin 可能有属性:

text 复制代码
name
direction
net
cell
is_clock_pin
capacitance
location
layer

Property 是对象模型的可观测层。没有 Property,Collection 只是一堆对象。有了 Property,脚本才知道这些对象有什么差异,哪些该被处理,哪些不该被处理。


四、Filter 是什么?

Filter 可以理解成:

基于对象属性和关系条件,对 Collection 进行选择。

例如:

text 复制代码
从所有 cell 中筛出 macro;
从所有 net 中筛出 clock net;
从所有 pin 中筛出 input pin;
从所有 cell 中筛出未放置对象;
从所有 object 中筛出某个 property 为 true 的对象。

Filter 的本质是谓词判断:

text 复制代码
对象是否满足某个条件?

用系统模型表示:

text 复制代码
FilteredCollection = Filter(Collection, Predicate(Property, Relation, Context))

也就是说:

text 复制代码
输入:一组对象
条件:属性 / 关系 / 上下文判断
输出:一组更小、更准确的对象

这就是 Collection / Property / Filter 的完整闭环。


五、对象查询流水线

Backend 脚本中的对象查询,通常不是单条命令,而是一条流水线。
Design Database
get_* 查询对象
Collection
get_property / list_property
Filter Predicate
Filtered Collection
Report / Check / Modify

这条流水线的核心思想是:

text 复制代码
先得到对象集合;
再观察对象属性;
再根据条件筛选;
最后执行报告、检查或状态修改。

所以,一个成熟的 Backend 脚本,不应该是大量硬编码名字堆起来的文本,而应该是:

text 复制代码
对象查询 + 属性判断 + 集合变换 + 阶段动作

六、为什么对象查询能力决定脚本工程上限?

因为 Backend 工程问题的规模通常不是单点问题。它处理的是大规模对象集合。

例如:

text 复制代码
不是改一个 cell,而是处理某类 cell;
不是查一个 net,而是查一批 high fanout net;
不是看一个 pin,而是看某类 pin 的物理可达性;
不是读一条 timing path,而是分析一组 critical path 的共性。

如果查询能力弱,脚本就只能写成:

text 复制代码
手工列名字
手工改路径
手工判断类型
手工排除例外
手工生成局部报告

这种脚本短期能用,但很难维护。

相反,如果 Collection / Property / Filter 能力强,脚本可以变成:

text 复制代码
根据对象状态构造处理集合;
根据属性决定处理策略;
根据报告反馈更新筛选条件;
根据阶段上下文控制命令边界。

这里说的不是让工具替代工程师判断,而是让脚本从"文本拼接"升级为"数据库对象操作"。这就是脚本工程上限的来源。


七、名字、对象和属性三者不能混淆

Backend Tcl 中最常见的错误之一,就是把名字、对象和属性混在一起。

概念 本质 示例 风险
name 文本标识 U123 可能重名、转义、层次路径变化
object 数据库对象 cell handle 依赖当前 session 和数据库状态
property 对象状态 is_fixed 需要对象类型和上下文支持

例如:

tcl 复制代码
set cells [get_cells *]

这里 cells 不应该简单理解成字符串列表,而应该理解成 cell 对象集合。

再比如:

tcl 复制代码
get_property $cells ref_name

这里读取的是对象属性,而不是从名字中解析字符串。

一旦把对象当字符串处理,很多脚本就会出现隐性问题:

text 复制代码
hierarchy 分隔符处理错误;
bus name 转义错误;
对象已经不存在但名字仍在;
名字匹配过宽或过窄;
同名对象在不同 scope 下混淆。

所以,Backend 脚本的第一原则是:

能用对象集合解决的问题,不要退回到纯字符串处理。


八、Filter 的底层思想:把经验变成条件

工程师的经验通常是这样表达的:

text 复制代码
这些 macro 不要动;
clock net 不应该当普通 signal net 处理;
fixed cell 不能随便移动;
critical path 上的 cell 要重点看;
power/ground net 不参与普通信号逻辑判断;
hierarchy A 下面的对象要单独报告。

这些经验如果停留在脑子里,只能靠人操作。如果写进脚本,就要变成 filter 条件:

text 复制代码
is_macro == true
usage == clock
is_fixed == true
slack < threshold
usage == power || usage == ground
full_name matches hierarchy pattern

Filter 的真正价值是:

把工程经验转换成可执行的对象选择条件。

一个团队对 Flow 的理解越深入,往往不是脚本越长,而是 filter 条件越清楚、越可解释。


九、为什么 list_property 很重要?

很多人只知道 get_property,却忽略 list_property

但从工程角度看,list_property 很关键。因为它回答的是:

text 复制代码
某类对象到底有哪些可观察状态?

如果不知道有哪些 property,就无法写出稳定 filter。

例如你想筛选 fixed object,但不知道工具里属性叫:

text 复制代码
is_fixed
fixed
place_status
status

这时就不能靠猜。

正确方式是:

text 复制代码
先查询对象;
再列出属性;
再确认属性语义;
最后写 filter。

十、空集合意识与类型意识

对象查询要区分三种状态:

text 复制代码
命令失败;
命令成功但集合为空;
命令成功且集合非空。

这三个状态不能混在一起。

例如,设计中没有 macro 时,查询 macro collection 为空,这不应该被当作错误。但如果 get_cells 命令本身失败,那就是另一类问题。

同时,不同对象类型的属性不同:

text 复制代码
cell 有 ref_name;
net 有 fanout;
pin 有 direction;
port 有 input/output;
shape 有 layer;
violation 有 rule_name。

所以一个可靠脚本必须在关键入口检查对象类型,避免对 net 读取 cell 属性,对 pin 读取 net 属性。


十一、对象关系比单个对象更重要

Backend 设计数据库不是一堆孤立对象,而是一张关系图。

典型关系包括:

text 复制代码
cell owns pin
pin connects net
net connects driver/load pins
cell instantiates lib cell
pin belongs to port or instance
object has physical location
object belongs to hierarchy
clock traverses timing graph

所以,Collection / Property / Filter 的高级用法,不只是筛对象,而是沿关系图走。

例如:

text 复制代码
从 critical path 找 cell;
从 cell 找 input/output pins;
从 pin 找 net;
从 net 找 fanout;
从 fanout 找 downstream cell;
从 cell 找 placement location。

这时脚本处理的就不再是平面集合,而是对象关系网络。


十二、一个推荐的对象查询分层

为了让脚本可维护,可以把对象查询分为四层。

text 复制代码
基础查询层
属性封装层
过滤条件层
业务动作层

1. 基础查询层

负责调用工具原生命令:

tcl 复制代码
get_cells
get_nets
get_pins
get_ports

2. 属性封装层

负责统一读取属性:

tcl 复制代码
get_object_name
get_object_type
get_object_property

3. 过滤条件层

负责定义选择规则:

tcl 复制代码
is_macro_cell
is_clock_net
is_fixed_object
is_io_port

4. 业务动作层

负责真正做报告或检查:

tcl 复制代码
report_macro_summary
check_unplaced_cells
report_clock_net_summary

这种分层可以避免脚本到处散落复杂 filter。


十三、一个简化的对象查询模板

下面是一个抽象模板,不绑定具体工具语法。

tcl 复制代码
set all_cells [get_cells *]
set all_nets  [get_nets *]
set all_ports [get_ports *]

list_property $all_cells
list_property $all_nets
list_property $all_ports

foreach_in_collection cell $all_cells {
    set name [get_property $cell name]
    set ref  [get_property $cell ref_name]
    puts "CELL $name REF $ref"
}

set macro_cells [filter_collection $all_cells "is_macro == true"]

if {[sizeof_collection $macro_cells] == 0} {
    puts "No macro cells found. Skip macro report."
} else {
    report_property $macro_cells
}

这个模板的重点不是具体命令名,而是流程:

text 复制代码
查询
观察
筛选
检查空集合
再执行动作

十四、Demo 应该验证什么?

本篇对应的 demo 不需要做完整后端流程。它应该验证对象查询机制本身:

text 复制代码
是否能读取 cell/net/pin/port;
是否能列出 property;
是否能对对象读取关键属性;
是否能处理空集合;
是否能输出对象关系报告;
是否能把查询结果写入 report。

建议输出:

text 复制代码
object_inventory.rpt
cell_property_summary.rpt
net_property_summary.rpt
pin_property_summary.rpt
filter_result_summary.rpt
empty_collection_check.rpt

Demo 的重点不是做 placement,而是验证对象查询层是否可靠。


十五、总结

Collection 让脚本可以操作对象集合。

Property 让脚本可以观察对象状态。

Filter 让脚本可以把工程经验转换成对象选择条件。

三者组合起来,才形成真正可靠的对象查询能力。

它们解决的是:

text 复制代码
从海量设计对象中,稳定、可解释、可复查地找到目标对象。

一个 Backend Flow 能不能长期维护,往往不取决于命令写得多不多,而取决于对象查询层是否清楚、稳定、可扩展。


结尾一句话

Backend 脚本真正成熟的标志,不是能执行很多命令,而是能准确回答:

text 复制代码
我正在操作哪些对象?为什么是这些对象?它们的状态是什么?结果能不能被复查?

Collection / Property / Filter,就是回答这些问题的基础。

相关推荐
DarrenHChen_EDA17 天前
【Backend Flow工程实践 27】Backend Script Template:一个可维护的后端脚本体系应该如何组织?
eda·log·tcl·parameter·regression·backend flow·script template
DarrenHChen_EDA18 天前
【Backend Flow工程实践 21】DRC / Antenna / Metal Fill:为什么 route 之后还远没有结束?
antenna·eda·routing·apr·drc·backend flow·metal fill
DarrenHChen_EDA18 天前
【Backend Flow工程实践 23】Backend-to-PV Handoff:从 DEF/GDS 到物理验证,后端如何完成签核交接?
lvs·eda·pv·gds·drc·backend flow·def
DarrenHChen_EDA19 天前
【Backend Flow工程实践 16】从 Scan Chain 到 Placement:测试结构为什么会影响后端布局?
eda·dft·apr·placement·scan chain·backend flow·可测性设计
DarrenHChen_EDA19 天前
【Backend Flow工程实践 19】CTS:从 skew group 到 clock route rule,时钟树综合到底在综合什
eda·apr·cts·backend flow·skew group
DarrenHChen_EDA22 天前
【Backend Flow工程实践 14】IO / Macro / Row:物理约束如何决定后端实现的搜索空间?
eda
倾心琴心2 个月前
【agent辅助pcb routing coding学习】实践9 CU GR 代码 算法学习
算法·agent·pcb·eda·routing
倾心琴心2 个月前
【agent辅助pcb routing coding学习】实践3 kicad routing tools 从PCB文件获取了哪些信息
算法·agent·pcb·eda·routing
倾心琴心2 个月前
【agent辅助pcb routing coding学习】实践4 kicad pcb 核心类层次关系
算法·agent·pcb·eda·routing