DC(Design Compiler)综合入门(3)

这一节主要介绍 objects 和 collection 相关知识

Verilog 视角下的Design objects

如图,Verilog 的Design objects分类主要有

  • Design(设计):代表顶层模块,例如这里的 TOP
  • Port(端口):模块的输入输出接口,用于连接外部信号。例如输入端口input A, B, C, D, CLK; 输出端口如 output [1:0] OUT1;
  • Clock(时钟):特殊信号,通常用于同步模块行为。例如这里的 CLK 是时钟信号。
  • Net(网络):于连接模块内部信号的路径。例如图中wire 定义了网络信号 INV1, INV0, bus1, bus0
  • Cell(单元):描述模块内部具体逻辑的实例化单元。例如ENCODE U1INV U2, U3 是被实例化的单元。
  • Pin(引脚):单元的连接点,用于接收或输出信号。例如U3(.A(BUS1), .Z(INV1));AZ 是引脚。

下面这张图可以更清晰的看出几种design objects。注意这里clk,对于最右边的clk来说它是top的port,对于图中连线上的clk来说它是net,对于regfile模块的clk来说它是pin

在这里介绍一下Ports 和 Pins 的区别,Ports(端口)和 Pins(引脚)是描述模块输入输出的关键概念,但两者的定义和作用是相对的,与设计层次相关。

Ports(端口) 是current design的输入和输出。当当前设计被作为子模块实例化到更高层次的设计中时,这些端口将变成引脚。如图,在模块 MID 中,MI 是一个端口,但在 TOP 中,MI 被视为 U8/MI 的引脚。

Pins(引脚)是current design中任何被实例化子模块的输入和输出。如果该子模块被提升为当前设计层次的顶层模块,其引脚会被视为端口。如图,在模块 BOT 中,BO 是引脚,但在 MID 设计中,它被视为 MID 的端口。

相同名称对象的歧义处理

在设计中,可能会出现多个对象(如端口和网络)使用相同的名称的情况。这种情况可能导致工具在操作时出现歧义,尤其是在分配负载或进行约束设置时。

如图,名为 SUM 的对象既可以表示模块的输出端口,也可以表示连接该端口的网络(net)。使用命令 set_load 5 SUM 时,工具需要知道该负载是应用到端口 SUM 还是网络 SUM。加载位置的不同会造成不同的影响。若负载设定到端口,会影响整体模块的输入输出负载估计。若负载设定到网络,会直接影响相关连接的网络驱动能力和时序。当DC检测到相同名称的对象时,默认情况下会优先选择端口作为操作目标。

为避免歧义,我们要在命令中使用get_* 命令来明确的对象类型(如 get_portsget_nets)。get_* 命令会在current_design、DC memory或库中查找并返回匹配的对象。它既可以独立使用,也可以嵌入到其他命令中,以下是一些get_* 命令的用法。

  • 直接返回对象列表,例如 get_portsget_nets
  • 嵌入到命令中,例如 set_load 5 [get_nets SUM]
  • 支持 ? 和 `` 通配符,用于匹配多个对象。例如get_ports addr_bus*可以匹配所有以 addr_bus 开头的端口。get_ports Y??M Z*可以匹配格式为 Y任意两个字符M 的端口,以及所有以 Z 开头的端口。
  • get_* 命令会返回与匹配条件一致的对象集合。如果没有匹配成功的对象,则返回空集合(empty collection)。

get_* ****命令作用类似的是all_*命令,all_*命令也用于获取当前设计中不同类型的对象,例如:

  • 命令:all_inputs 用于获取当前设计中所有输入端口。
  • 命令:all_outputs 用于获取当前设计中所有输出端口和输入/输出端口。
  • 命令:all_clocks 用于获取当前设计及其层级中定义的所有时钟信号。
  • 命令:all_registers 用于获取当前设计层级中定义的所有寄存器单元。

两者的区别如下

特性get_* 命令all_* 命令
灵活性支持筛选、模糊匹配,适合特定对象操作获取所有对象,无筛选功能
使用范围需要精确选择设计中某些对象快速获取某类对象的完整列表
返回值返回匹配的对象集合(可以为空)返回所有符合类型的对象(不能为空)
嵌套支持可嵌套在其他命令中使用通常单独使用

举例

remove_from_collection [all_inputs] [get_ports CLK]
  • all_inputs: 获取设计中所有的输入端口,返回一个集合。
  • get_ports CLK: 精确获取名称为 CLK 的端口(无论它是输入、输出还是双向端口),返回一个单独的对象。
  • remove_from_collection: 从第一个集合(即所有输入端口 all_inputs)中移除第二个集合中的对象(即 CLK 端口)。

返回结果

  • 返回的是从 all_inputs 集合中移除了 CLK 端口之后剩余的输入端口集合。

Library objects

Library objects有File Name (文件名)、Library Name (库名)、Library Cell (库单元)。

这里Library Cell里面的具体内容已经在上一节学过,不再赘述。

Obejcts and attributes

为了追踪电路的功能与时序,DC 为每种对象附加了多种属性。例如:

Ports(端口)

  • direction:端口的方向(输入/输出/双向)。
  • driving_cell_rise:驱动单元的上升时间。
  • load:端口的负载值。
  • max_capacitance:端口的最大允许电容。
  • 其他属性

Cells(单元)

  • dont_touch:指示该单元是否不可修改。
  • is_hierarchical:单元是否是层次化模块。
  • is_mapped:单元是否已映射到库中。
  • is_sequential:单元是否为时序逻辑单元。
  • 其他属性

访问 Synopsys 数据库

在 Synopsys 的 DC-TCL 中,访问 DC objects是通过collection实现的

get_*all_* 命令

  • 创建集合:这些命令根据查询条件生成一个对象集合,同时包括它们的属性。
  • 显示内容:命令会将集合的内容回显到屏幕上,便于检查。
  • 返回集合句柄:命令返回的是集合的“句柄”(作用类似于指针),而非实际的对象列表。

TCL 示例

  • 定义集合变量:将与 P 匹配的所有端口存储为集合,并赋给变量 foo

    set foo [get_ports P]
    
  • 显示集合内容:使用 echo 命令可以查看集合的内容,输出的内容为集合句柄

    echo $foo
    

访问和操作collection

创建集合

set foo [get_ports p*]
  • 将所有以 p 开头的端口加入集合 foo
  • 集合内容示例:{pclk pframe_n pidsel pad[31] ...}

查询集合大小

sizeof_collection $foo
  • 返回集合 foo 的大小,例如:50。

查看集合内容

query_objects $foo
  • 列出集合中所有对象的详细信息。

添加元素到集合

set pci_ports [add_to_collection $pci_ports [get_ports CTRL*]]
  • 原集合 pci_ports 中包含 {DATA[0] DATA[1] DATA[2]}
  • 新增符合条件 CTRL* 的端口后,集合内容变为 {DATA[0] DATA[1] DATA[2] CTRLA CTRLB}

从集合中移除元素

set all_inputs_except_clk \\
    [remove_from_collection [all_inputs] [get_ports CLK]]
  • 从所有输入端口中移除与 CLK 匹配的端口,生成新的集合。

Filter Collections

在 DC 中,可以通过 filter_collection-filter 选项对集合进行过滤,提取特定的设计对象。

示例

获取名称以 AN 开头的寄存器:

filter_collection [get_cells *] "reg_name =~ AN*"

获取未映射的单元:

filter_collection [get_cells *] "is_mapped != true

获取 dont_touch 属性为 true 的单元:

get_cells * -filter "dont_touch == true"

获取周期小于 10 的时钟:

set fastclks [get_clocks * -filter "period < 10"]

支持的关系操作符

  • 等于:==
  • 不等于:!=
  • 大于/小于:>, <
  • 大于等于/小于等于:>=, <=
  • 正则匹配:=~
  • 非匹配:!~

遍历集合(Iterate Over a Collection)

在 DC 脚本中,可以使用 foreach_in_collection 命令对集合内的对象逐一进行操作。

foreach_in_collection <变量名> <集合> {
    <操作>
}
  • <变量名>:表示当前遍历到的对象。
  • <集合>:通过 get_*filter_collection 创建的对象集合。
  • <操作>:在每次循环中执行的具体命令。
  • 示例:输出设计中所有具有层次结构的单元实例名称。
foreach_in_collection cell [get_cells -hier * -filter "is_hierarchical == true"] {
    echo "Instance [get_object_name $cell] is hierarchical"
}
  • get_cells -hier *:获取所有层次化单元。

  • filter "is_hierarchical == true":筛选出 is_hierarchical 属性为 true 的单元。

  • get_object_name $cell:获取当前单元的名称。

  • echo:输出结果。

  • 输出结果:

    Instance I_Ablock is hierarchical
    Instance I_CONTROL is hierarchical
    Instance I_Bblock is hierarchical
    ...
    

Collection VS TCL List

List往往用来存放用户定义的,Collection是DC自己提取出来的东西

Collection 用于访问数据库中的objects,例如设计中的端口、单元、时钟等。访问 objects 时,Collections 相比普通 TCL Lists 更加节省内存。直接与 DC 数据库集成。

  • get_*:如 get_portsget_cells,用于创建 Collection。
  • foreach_in_collection:遍历 Collection。
  • filter_collection:从 Collection 中筛选符合条件的对象。

TCL List 用于存储用户定义的数据,可以是任意类型的数据集合。

  • 通用结构:与 TCL 的其他脚本逻辑兼容。
  • 不直接与 DC 数据库交互。
  • foreach:用于遍历普通的 List。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值