Skip to content

Commit

Permalink
rewrite set_rc
Browse files Browse the repository at this point in the history
Signed-off-by: Kareem Farid <[email protected]>
  • Loading branch information
kareefardi committed Jan 23, 2025
1 parent 07f2c92 commit c5529e0
Show file tree
Hide file tree
Showing 2 changed files with 145 additions and 84 deletions.
2 changes: 1 addition & 1 deletion openlane/scripts/openroad/common/io.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ proc read_timing_info {args} {
return
}
set corner_name $::env(_CURRENT_CORNER_NAME)
define_corners $corner_name
log_cm define_corners $corner_name

puts "Reading timing models for corner $corner_name"

Expand Down
227 changes: 144 additions & 83 deletions openlane/scripts/openroad/common/set_rc.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -37,97 +37,158 @@ proc get_routing_layer_names {} {
return $layer_names
}

# Set custom layer RC
set i "0"
set tc_key "_LAYER_RC_$i"
while { [info exists ::env($tc_key)] } {
# [$corner] + [layer] + [str(round(res, 8))] + [str(round(cap, 8))]
set corner_name [lindex $::env($tc_key) 0]
set layer_name [lindex $::env($tc_key) 1]
set res_value [lindex $::env($tc_key) 2]
set cap_value [lindex $::env($tc_key) 3]
log_cmd set_layer_rc \
-layer $layer_name\
-capacitance $cap_value\
-corner $corner_name\
-resistance $res_value
incr i
proc set_layers_custom_rc {args} {
set i "0"
set tc_key "_LAYER_RC_$i"
set custom_corner_rc [list]
while { [info exists ::env($tc_key)] } {
# [$corner] + [layer] + [str(round(res, 8))] + [str(round(cap, 8))]
set corner_name [lindex $::env($tc_key) 0]
set layer_name [lindex $::env($tc_key) 1]
set res_value [lindex $::env($tc_key) 2]
set cap_value [lindex $::env($tc_key) 3]
log_cmd set_layer_rc \
-layer $layer_name\
-capacitance $cap_value\
-corner $corner_name\
-resistance $res_value
incr i
set tc_key "_LAYER_RC_$i"
if { [lsearch $custom_corner_rc $corner_name] == -1 } {
lappend custom_corner_rc $corner_name
}
}
return $custom_corner_rc
}

# Set custom via RC
set i "0"
set tc_key "_VIA_R_$i"
while { [info exists ::env($tc_key)] } {
set corner_name [lindex $::env($tc_key) 0]
set via_name [lindex $::env($tc_key) 1]
set res_value [lindex $::env($tc_key) 2]
log_cmd set_layer_rc \
-via $via_name\
-resistance $res_value\
-corner $corner_name
incr i
proc set_via_custom_r {args} {
set i "0"
set tc_key "_VIA_R_$i"
set custom_corner_r [list]
while { [info exists ::env($tc_key)] } {
set corner_name [lindex $::env($tc_key) 0]
set via_name [lindex $::env($tc_key) 1]
set res_value [lindex $::env($tc_key) 2]
log_cmd set_layer_rc \
-via $via_name\
-resistance $res_value\
-corner $corner_name
incr i
set tc_key "_VIA_R_$i"

if { [lsearch $custom_corner_r $corner_name] == -1 } {
lappend custom_corner_r $corner_name
}
}
return $custom_corner_r
}

set layer_names [get_routing_layer_names]
set signal_wire_rc_layers $layer_names
set clock_wire_rc_layers $layer_names
if { [info exist ::env(SIGNAL_WIRE_RC_LAYERS)] } {
set signal_wire_rc_layers $::env(SIGNAL_WIRE_RC_LAYERS)

proc get_missing_corners {corners_with_custom_layer_rc} {
set corners [sta::corners]
set corners_without_custom_layer_rc [list]
foreach corner $corners {
if {[string first [$corner name] "$corners_with_custom_layer_rc"] == -1} {
lappend corners_without_custom_layer_rc [$corner name]
}
}
return $corners_without_custom_layer_rc
}
if { [info exist ::env(CLOCK_WIRE_RC_LAYERS)] } {
set clock_wire_rc_layers $::env(CLOCK_WIRE_RC_LAYERS)

proc set_layers_default_rc {corners} {
set res_unit [sta::unit_scale resistance]
set cap_unit [sta::unit_scale capacitance]
foreach layer [$::tech getLayers] {
if { [$layer getType] == "ROUTING" } {
set layer_name [$layer getName]
lassign [rsz::dblayer_wire_rc $layer] layer_wire_res_ohm_m layer_wire_cap_farad_m
set layer_wire_res_unit_microns [expr $layer_wire_res_ohm_m * 1e-6 / $res_unit]
set layer_wire_cap_unit_microns [expr $layer_wire_cap_farad_m * 1e-6 / $cap_unit]
foreach corner "$corners" {
log_cmd set_layer_rc \
-layer $layer_name\
-capacitance $layer_wire_cap_unit_microns\
-corner $corner\
-resistance $layer_wire_res_unit_microns
}
}
}
}
if { [llength $signal_wire_rc_layers] > 1 } {
log_cmd set_wire_rc -signal -layers "$signal_wire_rc_layers"
} else {
log_cmd set_wire_rc -signal -layer "$signal_wire_rc_layers"

proc set_vias_default_r {corners} {
foreach layer [$::tech getLayers] {
if { [$layer getType] == "CUT" } {
set layer_name [$layer getName]
set res [$layer getResistance]
foreach corner $corners {
log_cmd set_layer_rc \
-corner $corner\
-resistance $res\
-via $layer_name
}
}
}
}
if { [llength $clock_wire_rc_layers] > 1 } {
log_cmd set_wire_rc -clock -layers "$clock_wire_rc_layers"
} else {
log_cmd set_wire_rc -clock -layer "$clock_wire_rc_layers"

proc set_wire_rc_wrapper {use_corners} {
set layer_names [get_routing_layer_names]
set signal_wire_rc_layers $layer_names
set clock_wire_rc_layers $layer_names
if { [info exist ::env(SIGNAL_WIRE_RC_LAYERS)] } {
set signal_wire_rc_layers $::env(SIGNAL_WIRE_RC_LAYERS)
}
if { [info exist ::env(CLOCK_WIRE_RC_LAYERS)] } {
set clock_wire_rc_layers $::env(CLOCK_WIRE_RC_LAYERS)
}
set signal_args [list]
lappend signal_args -signal
if { [llength $signal_wire_rc_layers] > 1 } {
lappend signal_args -layers "$signal_wire_rc_layers"
} else {
lappend signal_args -layer "$signal_wire_rc_layers"
}

set clock_args [list]
lappend clock_args -clock
if { [llength $clock_wire_rc_layers] > 1 } {
lappend clock_args -layers "$clock_wire_rc_layers"
} else {
lappend clock_args -layer "$clock_wire_rc_layers"
}

if { $use_corners } {
foreach corner [sta::corners] {
log_cmd set_wire_rc {*}$clock_args -corner [$corner name]
log_cmd set_wire_rc {*}$signal_args -corner [$corner name]
}
} else {
log_cmd set_wire_rc {*}$clock_args
log_cmd set_wire_rc {*}$signal_args
}
}

# keeping this until there is a clear resolution for https://github.com/The-OpenROAD-Project/OpenROAD/issues/6175
#if { ![info exists ::env($tc_key)] } {
# puts "\[INFO\] Using default RC values from the technology for metal layers"
# set res_unit [sta::unit_scale resistance]
# set cap_unit [sta::unit_scale capacitance]
#
# foreach layer [$::tech getLayers] {
# if { [$layer getType] == "ROUTING" } {
# set layer_name [$layer getName]
#
# lassign [rsz::dblayer_wire_rc $layer] layer_wire_res_ohm_m layer_wire_cap_farad_m
# set layer_wire_res_unit_microns [expr $layer_wire_res_ohm_m * 1e-6 / $res_unit]
# set layer_wire_cap_unit_microns [expr $layer_wire_cap_farad_m * 1e-6 / $cap_unit]
#
# foreach corner [sta::corners] {
# set_layer_rc \
# -layer $layer_name\
# -capacitance $layer_wire_cap_unit_microns\
# -corner [$corner name]\
# -resistance $layer_wire_res_unit_microns
# }
# }
# }
#}
#
#if { ![info exists ::env($tc_key)] } {
# puts "\[INFO\] Using default RC values from the technology for vias"
#
# foreach layer [$::tech getLayers] {
# if { [$layer getType] == "CUT" } {
# set layer_name [$layer getName]
# set res [$layer getResistance]
# foreach corner [sta::corners] {
# set_layer_rc \
# -corner [$corner name]\
# -resistance $res\
# -via $layer_name
# }
# }
# }
#}
# Flow as follows
# 1. Set layers custom rc - if defined
# 2. Set vias custom r - if defined
# 3. If (1) doesn't override all the corners, set the default techlef value for the remaining corners for layers
# 3.a If (2) doesn't override all the corners, set the default techlef value for the remaining corners for vias
# 4. If (1) doesn't override the corners at all, call set_wire_rc without -corner, to ensure the default behavior
# 5. If (1) does override (some) corners, we must use set_wire_rc with -corner, becuase otherwise set_wire_rc will set the default techlef value for all existing corners

set corners_with_custom_layer_rc [set_layers_custom_rc]
set corners_with_custom_via_r [set_via_custom_r]
set corners_without_custom_layer_rc [get_missing_corners $corners_with_custom_layer_rc]
set corners_witout_custom_via_r [get_missing_corners $corners_with_custom_via_r]

if { [llength $corners_with_custom_layer_rc] } {
# to avoid setting the default values again for round off error and maintain old behavior
log_cmd set_layers_default_rc $corners_without_custom_layer_rc
}
if { [llength $corners_with_custom_via_r] } {
log_cmd set_vias_default_r $corners_witout_custom_via_r
}
if { [llength $corners_with_custom_layer_rc] } {
log_cmd set_wire_rc_wrapper 1
} else {
log_cmd set_wire_rc_wrapper 0
}

0 comments on commit c5529e0

Please sign in to comment.