用tcl在dc里为所有的sram输入输出pin插一对反相器
专栏:iLoveIC Sept. 1, 2025, 7:07 p.m. 43 阅读
因为APR place位置原因,需要dc综合时,在sram输入输出pin上插一对反相器,那么应该怎么做呢?

因为APR place位置原因,需要dc综合时,在sram输入输出pin上插一对反相器,如下图,那么应该怎么做呢?

image.png

由于设计里sram较多,手工修改网表效率低,且容易出错。我们选择编写tcl脚本来统一处理。

首先,我们需要找到所有的sram inst。如果sram的inst命令有固定的前缀,就比较简单了,可以用get_cells -hier u_sram_*。由于get_cells返回的是一个collection,并不是inst path的list,因此需要用get_attribte xxx full_name来转换一下。

set sram_cells [get_attribute [get_cells -hier u_sram_sp_*] full_name]

第二步,为了脚本不影响到其他层次,我们用current_design xxx切到sram的上一个层次的module里处理。用正则把上一步的sram inst path拆成两部分:sram上层module的inst path和sram本身的inst name。

foreach sram_cell_name $sram_cells {
    regexp {(.*)/(.*)} $sram_cell_name matched path_base cell_name
    puts ${path_base}
    puts ${cell_name}
    #...
}

get_attribute xxx ref_name获得sram上层module的名字,并切过去。

current_design [get_attribute $path_base ref_name]

get_pins -hier ${cell_name}/*找到sram的每一个pin,如下。

foreach_in_collection pin [get_pins -hier ${cell_name}/*] {
    #...
}

第三步,对每个pin进行输入和输出方向的判断,因为输入和输出方向的处理方法有差异。

if {[get_attribute $pin pin_direction] == "in"} {
    # input pin
	
} else {
    # output pin
	
}

第四步,对于某个输入pin,需要用get_nets -of_objects $pin_name先找到pin连接的net名,再把net名中的[]替换成下划线,然后就可以用create_cellcreate_net来新建cell和net,最后把该断开的net断开,该连上的net连上。

image.png

set pin_name [get_attribute $pin full_name]
set net_name [get_attribute [get_nets -of_objects $pin_name] full_name]

regexp {(.*)/(.*)} $pin_name matched pin_path_base pin_short_name
regsub -all {\[|\]} $pin_short_name "_" safe_pin_name

create_cell "u_INV_${safe_pin_name}_1" ss_max_1p08v_125c/INV_X4_A7TR
create_cell "u_INV_${safe_pin_name}_2" ss_max_1p08v_125c/INV_X4_A7TR
create_net "n_INV_${safe_pin_name}_1"
create_net "n_INV_${safe_pin_name}_2"

disconnect_net ${net_name} ${pin_name}
connect_net "n_INV_${safe_pin_name}_2" ${pin_name}
connect_net "n_INV_${safe_pin_name}_2" "u_INV_${safe_pin_name}_2/Y"
connect_net "n_INV_${safe_pin_name}_1" "u_INV_${safe_pin_name}_2/A"
connect_net "n_INV_${safe_pin_name}_1" "u_INV_${safe_pin_name}_1/Y"
connect_net ${net_name} "u_INV_${safe_pin_name}_1/A"

第五步,对于某个输出pin,方法类似。

image.png

set pin_name [get_attribute $sram_pin name]
set net_name [get_attribute [get_nets -of_objects $pin_name] full_name]

regsub -all {\[|\]} $pin_name "_" safe_pin_name

create_cell "u_INV_${safe_pin_name}_1" ss_max_1p08v_125c/INV_X4_A7TR
create_cell "u_INV_${safe_pin_name}_2" ss_max_1p08v_125c/INV_X4_A7TR
create_net "n_INV_${safe_pin_name}_1"
create_net "n_INV_${safe_pin_name}_2"
	
disconnect_net ${net_name} ${pin_name}
connect_net "n_INV_${safe_pin_name}_2" ${pin_name}
connect_net "n_INV_${safe_pin_name}_2" "u_INV_${safe_pin_name}_2/A"
connect_net "n_INV_${safe_pin_name}_1" "u_INV_${safe_pin_name}_2/Y"
connect_net "n_INV_${safe_pin_name}_1" "u_INV_${safe_pin_name}_1/A"
connect_net ${net_name} "u_INV_${safe_pin_name}_1/Y"

总结:

本文通过get_pinsget_cellsget_nets -of_objectget_attribute等命令来获取netlist的例化和连接关系。并通过create_cellcreate_netdisconnect_netconnect_net等命令来修改netlist。提值一提的是,本文中通过用get_attribute inst_path ref_name获得module名字并用current_design切换设计层次,降低了netlist修改的复杂度。

 

感谢阅读,更多文章点击这里:【专栏:iLoveIC】
最新20篇 开设专栏