1、Path Grouping(路径分组) 这部分代码的专业术语叫 Path Grouping(路径分组)。如果说之前的 OCV 设置是在给芯片“加难度”,那么这段代码就是你在给 Innovus 这个优化工具**“划重点、分配算力”**。
在默认情况下,EDA 工具是个“死心眼”。它看到哪里有时序违例(Violation)就去修哪里。如果你的输入输出引脚(I/O)因为外部环境设置得太严苛而出现了巨大的违例,工具就会把 90% 的 CPU 时间和内存都耗在修 I/O 上,反而把你芯片内部真正核心的计算逻辑给忽略了。
这段代码,就是大厂 Team Leader 用来夺回优化控制权的终极武器。
2、整个代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 # Group path # Reset all existing path groups, including basic path groupsreset_path_group -#? Reset all options set on all path groups.resetPathGroupOptions?(CUI :reset_path_group_options) reset_path_group -all ### get sequentials set reg [filter_collection [all_registers ] "is_integrated_clock_gating_cell != true"] set inp [all_inputs] set out [all_outputs] set mem [get_cells -q -hier -filter "@is_hierarchical == false && @is_macro_cell == true"] set ckgating [filter_collection [all_registers] "is_integrated_clock_gating_cell == true"] set ignore_path_groups [list inp2reg reg2out feedthr] ### create path groups group_path -name reg2reg -from $reg -to $reg group_path -name mem2reg -from $mem -to $reg group_path -name mem2cg -from $mem -to $ckgating group_path -name reg2mem -from $reg -to $mem group_path -name mem2mem -from $mem -to $mem group_path -name reg2cg -from $reg -to $ckgating group_path -name in2reg -from $inp group_path -name reg2out -to $out group_path -name feedthr -from $inp -to $out ### set weight setPathGroupOptions reg2reg -effortLevel high setPathGroupOptions reg2cg -effortLevel high setPathGroupOptions mem2cg -effortLevel high setPathGroupOptions reg2mem -effortLevel high setPathGroupOptions mem2reg -effortLevel high setPathGroupOptions mem2mem -effortLevel high setPathGroupOptions in2reg -effortLevel low setPathGroupOptions reg2out -effortLevel low setPathGroupOptions feedthr -effortLevel low #setPathGroupOptions? $name? -effortLevel $effort -weight $weight -slackAdjustment $slack_adj puts "ignore path groups for hold : \{$ignore_path_groups\} ." setOptMode -ignorePathGroupsForHold $ignore_path_groups
3、代码的注释:
作用:清除工具默认按时钟域划分的所有路径组。
潜台词:“别用你默认的那套笨办法,接下来按我的规矩来分。”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ### get sequentials (获取时序逻辑元件) # 1. 提取普通步兵:常规寄存器 # all_registers 会抓取设计中所有的时序单元。 # filter_collection 结合 "is_integrated_clock_gating_cell != true" 条件, # 把那些作为“时钟门控”的特殊单元剔除掉,只保留纯粹用来打拍子、存数据的普通触发器 (Flip-Flops)。 set reg [filter_collection [all_registers ] "is_integrated_clock_gating_cell != true"] # 2. 提取边防哨所:输入/输出端口 # 获取芯片最外围的所有输入管脚 (Input Ports) 和输出管脚 (Output Ports)。 set inp [all_inputs] set out [all_outputs] # 3. 提取重型装甲:宏单元 (SRAM / IP) # get_cells -hier: 遍历整个层级结构去抓取单元。 # @is_hierarchical == false: 必须是底层物理单元 (Leaf Cell),不能是逻辑模块 (Module)。 # @is_macro_cell == true: 必须是宏单元 (通常指 SRAM 存储器、PLL、ROM 等硬核 IP)。 set mem [get_cells -q -hier -filter "@is_hierarchical == false && @is_macro_cell == true"] # 4. 提取指挥枢纽:时钟门控单元 (ICG) # 专门把刚才剔除掉的“集成时钟门控单元” (ICG) 单独抓取出来。 # 它是低功耗设计的核心,负责在模块不工作时关断时钟网络。 set ckgating [filter_collection [all_registers] "is_integrated_clock_gating_cell == true"]
ICG 的全称是 Integrated Clock Gating(集成时钟门控单元)。
如果把芯片里的时钟网络(Clock Tree)比作城市的供水管网,把成千上万的寄存器比作千家万户的自来水龙头,那么 ICG 就是安装在每个小区门口的“智能总阀门”。
它存在的唯一目的就是四个字:极致省电。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 ### create path groups (创建时序路径分组) # 1. 核心计算战区 (纯逻辑打拍子) # reg2reg: 普通寄存器到普通寄存器。这是芯片算力的基本盘,通常占芯片路径的 80% 以上。 group_path -name reg2reg -from $reg -to $reg # 2. 存储器交互战区 (SRAM 读写) # mem2reg: 内存读出路径。SRAM 的 clock-to-q 延迟通常比较大,这部分数据跑到下一级寄存器很容易违例。 group_path -name mem2reg -from $mem -to $reg # reg2mem: 内存写入路径(包含地址线、数据线、写使能)。SRAM 的 Setup 要求极为苛刻,必须单独盯防。 group_path -name reg2mem -from $reg -to $mem # mem2mem: 内存到内存直连。极其罕见且危险,两个巨无霸直接对话,通常延迟极大。 group_path -name mem2mem -from $mem -to $mem # 3. 低功耗生命线 (时钟门控使能信号) # mem2cg: 内存的输出直接去控制某个模块的时钟门控单元 (ICG)。 group_path -name mem2cg -from $mem -to $ckgating # reg2cg: 普通寄存器去控制 ICG 的 Enable 引脚。 # 【TL 划重点】:ICG 内部带 Latch,Setup 要求极高,如果跟 reg2reg 混在一起,工具根本照应不过来。必须单独建组! group_path -name reg2cg -from $reg -to $ckgating # 4. 外部接口战区 (I/O 边界) # in2reg: 外部输入引脚到第一级寄存器 (Input Delay 路径)。 group_path -name in2reg -from $inp # reg2out: 最后一级寄存器到外部输出引脚 (Output Delay 路径)。 group_path -name reg2out -to $out # feedthr: 纯直通路径。从输入引脚进来,连个触发器都没过,直接做点纯组合逻辑就送出去了(最不受待见的路径,外部环境决定它的生死)。 group_path -name feedthr -from $inp -to $out
1 group_path -name reg2cg -from $reg -to $ckgating
谁来决定它的最终位置?(后端流程)
Placement 阶段(初步占位):就是咱们刚聊完的那个阶段。工具会根据逻辑连线关系,给 ICG 找个大概的合理位置。
CTS 阶段(最终定死):在跑 时钟树综合(Clock Tree Synthesis, 比如 Innovus 里的 ccopt_design) 时,工具会对 ICG 的位置进行微调。为了保证时钟树的完美平衡(Balance),工具可能会把 ICG 稍微挪动一下,甚至在它前面或后面插入几个 Clock Buffer,然后把它的坐标彻底锁死。
4、导出报告 最后的setOptMode则是告诉工具,关于IO相关的path我们是不修hold的,虽然此时是place阶段,但是我们也可以提前设置这个约束,避免在ctsopt和route阶段修hold的时候在io path上插入过多的buffer,因为我们预估的input delay和output delay是不准的,所以io path的hold timing可能存在violation,此时插入过多的buffer去修hold也是没有什么意义的。
上述命令设置完毕之后,我们也可以report_path_groups > path_groups.rpt这条命令将设计中的group path划分写入到path_groups.rpt这个文件里面,然后打开这个文件来查看工具有没有按照我们的约束正确设置上面的group path。