librelane 2.4.0.dev7__py3-none-any.whl → 3.0.0.dev22__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of librelane might be problematic. Click here for more details.
- librelane/__main__.py +12 -15
- librelane/common/__init__.py +1 -1
- librelane/common/drc.py +88 -7
- librelane/common/misc.py +6 -6
- librelane/common/toolbox.py +1 -1
- librelane/config/config.py +5 -1
- librelane/config/flow.py +51 -66
- librelane/config/pdk_compat.py +79 -2
- librelane/config/preprocessor.py +1 -1
- librelane/config/variable.py +2 -2
- librelane/flows/classic.py +1 -0
- librelane/flows/flow.py +3 -6
- librelane/flows/sequential.py +85 -40
- librelane/plugins.py +1 -1
- librelane/scripts/magic/common/read.tcl +2 -2
- librelane/scripts/magic/gds/extras_mag.tcl +2 -2
- librelane/scripts/odbpy/diodes.py +2 -2
- librelane/scripts/openroad/common/dpl.tcl +1 -1
- librelane/scripts/openroad/common/grt.tcl +3 -3
- librelane/scripts/openroad/common/io.tcl +163 -45
- librelane/scripts/openroad/common/resizer.tcl +1 -40
- librelane/scripts/openroad/common/set_global_connections.tcl +2 -2
- librelane/scripts/openroad/common/set_power_nets.tcl +1 -1
- librelane/scripts/openroad/common/set_rc.tcl +159 -40
- librelane/scripts/openroad/cts.tcl +37 -6
- librelane/scripts/openroad/cut_rows.tcl +19 -4
- librelane/scripts/openroad/drt.tcl +59 -8
- librelane/scripts/openroad/dump_rc.tcl +105 -0
- librelane/scripts/openroad/fill.tcl +2 -2
- librelane/scripts/openroad/floorplan.tcl +5 -3
- librelane/scripts/openroad/gpl.tcl +7 -8
- librelane/scripts/openroad/gui.tcl +22 -2
- librelane/scripts/openroad/insert_buffer.tcl +2 -2
- librelane/scripts/openroad/ioplacer.tcl +1 -2
- librelane/scripts/openroad/irdrop.tcl +3 -3
- librelane/scripts/openroad/pdn.tcl +17 -18
- librelane/scripts/openroad/rcx.tcl +1 -1
- librelane/scripts/openroad/repair_design.tcl +14 -7
- librelane/scripts/openroad/repair_design_postgrt.tcl +13 -6
- librelane/scripts/openroad/rsz_timing_postcts.tcl +13 -12
- librelane/scripts/openroad/rsz_timing_postgrt.tcl +13 -12
- librelane/scripts/openroad/sta/check_macro_instances.tcl +1 -1
- librelane/scripts/openroad/tapcell.tcl +13 -6
- librelane/scripts/openroad/ungpl.tcl +23 -0
- librelane/state/__init__.py +1 -1
- librelane/state/design_format.py +194 -142
- librelane/state/state.py +20 -21
- librelane/steps/checker.py +12 -1
- librelane/steps/common_variables.py +4 -4
- librelane/steps/cvc_rv.py +1 -1
- librelane/steps/klayout.py +14 -6
- librelane/steps/magic.py +18 -2
- librelane/steps/misc.py +1 -1
- librelane/steps/odb.py +50 -31
- librelane/steps/openroad.py +455 -128
- librelane/steps/pyosys.py +20 -5
- librelane/steps/step.py +17 -20
- librelane/steps/tclstep.py +9 -7
- librelane/steps/yosys.py +1 -1
- {librelane-2.4.0.dev7.dist-info → librelane-3.0.0.dev22.dist-info}/METADATA +1 -1
- {librelane-2.4.0.dev7.dist-info → librelane-3.0.0.dev22.dist-info}/RECORD +63 -61
- {librelane-2.4.0.dev7.dist-info → librelane-3.0.0.dev22.dist-info}/WHEEL +0 -0
- {librelane-2.4.0.dev7.dist-info → librelane-3.0.0.dev22.dist-info}/entry_points.txt +0 -0
|
@@ -14,62 +14,181 @@
|
|
|
14
14
|
|
|
15
15
|
# Resistance/Capacitance Overrides
|
|
16
16
|
# Via resistance
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
set_layer_rc -via $layer_name -resistance $resistance
|
|
17
|
+
|
|
18
|
+
proc log_cmd_rc {cmd args} {
|
|
19
|
+
if { $::env(SET_RC_VERBOSE) } {
|
|
20
|
+
log_cmd $cmd {*}$args
|
|
21
|
+
} else {
|
|
22
|
+
$cmd {*}$args
|
|
24
23
|
}
|
|
25
24
|
}
|
|
26
25
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
set
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
26
|
+
proc set_layers_custom_rc {args} {
|
|
27
|
+
# Returns: All corners for which RC values were found
|
|
28
|
+
set i "0"
|
|
29
|
+
set tc_key "_LAYER_RC_$i"
|
|
30
|
+
set custom_corner_rc [list]
|
|
31
|
+
while { [info exists ::env($tc_key)] } {
|
|
32
|
+
# [$corner] + [layer] + [str(round(res, 8))] + [str(round(cap, 8))]
|
|
33
|
+
set corner_name [lindex $::env($tc_key) 0]
|
|
34
|
+
set layer_name [lindex $::env($tc_key) 1]
|
|
35
|
+
set res_value [lindex $::env($tc_key) 2]
|
|
36
|
+
set cap_value [lindex $::env($tc_key) 3]
|
|
37
|
+
log_cmd_rc set_layer_rc \
|
|
38
|
+
-layer $layer_name\
|
|
39
|
+
-capacitance $cap_value\
|
|
40
|
+
-corner $corner_name\
|
|
41
|
+
-resistance $res_value
|
|
42
|
+
incr i
|
|
43
|
+
set tc_key "_LAYER_RC_$i"
|
|
44
|
+
set corner [sta::find_corner $corner_name]
|
|
45
|
+
if { [lsearch $custom_corner_rc $corner] == -1 } {
|
|
46
|
+
lappend custom_corner_rc $corner
|
|
47
|
+
}
|
|
35
48
|
}
|
|
49
|
+
return $custom_corner_rc
|
|
36
50
|
}
|
|
37
51
|
|
|
38
|
-
|
|
39
|
-
set
|
|
40
|
-
set
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
set
|
|
44
|
-
|
|
45
|
-
|
|
52
|
+
proc set_via_custom_r {args} {
|
|
53
|
+
set i "0"
|
|
54
|
+
set tc_key "_VIA_R_$i"
|
|
55
|
+
set custom_corner_r [list]
|
|
56
|
+
while { [info exists ::env($tc_key)] } {
|
|
57
|
+
set corner_name [lindex $::env($tc_key) 0]
|
|
58
|
+
set via_name [lindex $::env($tc_key) 1]
|
|
59
|
+
set res_value [lindex $::env($tc_key) 2]
|
|
60
|
+
log_cmd_rc set_layer_rc \
|
|
61
|
+
-via $via_name\
|
|
62
|
+
-resistance $res_value\
|
|
63
|
+
-corner $corner_name
|
|
64
|
+
incr i
|
|
65
|
+
set tc_key "_VIA_R_$i"
|
|
66
|
+
set corner [sta::find_corner $corner_name]
|
|
67
|
+
if { [lsearch $custom_corner_r $corner] == -1 } {
|
|
68
|
+
lappend custom_corner_r $corner
|
|
46
69
|
}
|
|
47
|
-
|
|
48
|
-
|
|
70
|
+
}
|
|
71
|
+
return $custom_corner_r
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
proc set_layers_default_rc {corners} {
|
|
75
|
+
foreach layer [get_layers -type ROUTING] {
|
|
76
|
+
set layer_name [$layer getName]
|
|
77
|
+
lassign [rsz::dblayer_wire_rc $layer] layer_wire_res_ohm_m layer_wire_cap_farad_m
|
|
78
|
+
set layer_wire_res_per_unit_distance [expr $layer_wire_res_ohm_m * [sta::unit_scale distance] / [sta::unit_scale resistance]]
|
|
79
|
+
set layer_wire_cap_per_unit_distance [expr $layer_wire_cap_farad_m * [sta::unit_scale distance] / [sta::unit_scale capacitance]]
|
|
80
|
+
foreach corner "$corners" {
|
|
81
|
+
log_cmd_rc set_layer_rc \
|
|
82
|
+
-layer $layer_name\
|
|
83
|
+
-corner $corner\
|
|
84
|
+
-resistance $layer_wire_res_per_unit_distance\
|
|
85
|
+
-capacitance $layer_wire_cap_per_unit_distance
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
proc set_vias_default_r {corners} {
|
|
91
|
+
foreach layer [get_layers -types "CUT"] {
|
|
92
|
+
set layer_name [$layer getName]
|
|
93
|
+
set res [expr [$layer getResistance] / [sta::unit_scale resistance]]
|
|
94
|
+
foreach corner $corners {
|
|
95
|
+
log_cmd_rc set_layer_rc \
|
|
96
|
+
-corner $corner\
|
|
97
|
+
-resistance $res\
|
|
98
|
+
-via $layer_name
|
|
49
99
|
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
proc set_wire_rc_wrapper {args} {
|
|
104
|
+
sta::parse_key_args "set_wire_rc_wrapper" args \
|
|
105
|
+
keys {}\
|
|
106
|
+
flags {-use_corners}
|
|
107
|
+
|
|
108
|
+
# We only want the layers that will actually be used for set_wire_rc's estimations.
|
|
109
|
+
set layer_names [get_layers -constrained -type ROUTING -map getName]
|
|
110
|
+
set signal_wire_rc_layers $layer_names
|
|
111
|
+
set clock_wire_rc_layers $layer_names
|
|
112
|
+
if { [info exist ::env(SIGNAL_WIRE_RC_LAYERS)] } {
|
|
113
|
+
set signal_wire_rc_layers $::env(SIGNAL_WIRE_RC_LAYERS)
|
|
114
|
+
}
|
|
115
|
+
if { [info exist ::env(CLOCK_WIRE_RC_LAYERS)] } {
|
|
116
|
+
set clock_wire_rc_layers $::env(CLOCK_WIRE_RC_LAYERS)
|
|
117
|
+
}
|
|
118
|
+
set signal_args [list]
|
|
119
|
+
lappend signal_args -signal
|
|
120
|
+
if { [llength $signal_wire_rc_layers] > 1 } {
|
|
121
|
+
lappend signal_args -layers "$signal_wire_rc_layers"
|
|
122
|
+
} else {
|
|
123
|
+
lappend signal_args -layer "$signal_wire_rc_layers"
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
set clock_args [list]
|
|
127
|
+
lappend clock_args -clock
|
|
128
|
+
if { [llength $clock_wire_rc_layers] > 1 } {
|
|
129
|
+
lappend clock_args -layers "$clock_wire_rc_layers"
|
|
130
|
+
} else {
|
|
131
|
+
lappend clock_args -layer "$clock_wire_rc_layers"
|
|
132
|
+
}
|
|
50
133
|
|
|
51
|
-
|
|
52
|
-
|
|
134
|
+
if { [info exists flags(-use_corners)] } {
|
|
135
|
+
foreach corner [sta::corners] {
|
|
136
|
+
log_cmd_rc set_wire_rc {*}$clock_args -corner [$corner name]
|
|
137
|
+
log_cmd_rc set_wire_rc {*}$signal_args -corner [$corner name]
|
|
53
138
|
}
|
|
139
|
+
} else {
|
|
140
|
+
log_cmd_rc set_wire_rc {*}$clock_args
|
|
141
|
+
log_cmd_rc set_wire_rc {*}$signal_args
|
|
54
142
|
}
|
|
55
143
|
}
|
|
56
144
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
145
|
+
# TODO: Replace with actual Tcl sets once we have access to the standard library
|
|
146
|
+
proc set_diff {setA setB} {
|
|
147
|
+
set setC [list]
|
|
148
|
+
foreach element $setA {
|
|
149
|
+
if {[lsearch $setB $element] == -1} {
|
|
150
|
+
lappend setC $element
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return $setC
|
|
61
154
|
}
|
|
62
|
-
|
|
63
|
-
|
|
155
|
+
|
|
156
|
+
# Flow as follows
|
|
157
|
+
# 1. Set layers custom rc - if defined
|
|
158
|
+
# 2. Set vias custom r - if defined
|
|
159
|
+
# 3. If (1) doesn't override all the corners, set the default techlef value for the remaining corners for layers
|
|
160
|
+
# 3.a If (2) doesn't override all the corners, set the default techlef value for the remaining corners for vias
|
|
161
|
+
# 4. If (1) doesn't override the corners at all, call set_wire_rc without -corner, to ensure the default behavior
|
|
162
|
+
# 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
|
|
163
|
+
|
|
164
|
+
set corners_with_custom_layer_rc [set_layers_custom_rc]
|
|
165
|
+
set corners_with_custom_via_r [set_via_custom_r]
|
|
166
|
+
set corners_without_custom_layer_rc [set_diff [sta::corners] $corners_with_custom_layer_rc]
|
|
167
|
+
set corners_without_custom_via_r [set_diff [sta::corners] $corners_with_custom_via_r]
|
|
168
|
+
|
|
169
|
+
# If ANY CORNERS have custom RC values set, set the tech LEF values for the
|
|
170
|
+
# remaining corners.
|
|
171
|
+
#
|
|
172
|
+
# If NO CORNERS have custom RC values set, do nothing. The set_wire_rc LATER
|
|
173
|
+
# will automatically average the Tech LEF values.
|
|
174
|
+
#
|
|
175
|
+
# This is because, technically, while both behaviors SHOULD be identical, they
|
|
176
|
+
# aren't because of roundoff errors emblematic of IEEE 754.
|
|
177
|
+
if { [llength $corners_with_custom_layer_rc] } {
|
|
178
|
+
log_cmd_rc set_layers_default_rc [lmap corner $corners_without_custom_layer_rc "\$corner name"]
|
|
64
179
|
}
|
|
65
|
-
if { [llength $
|
|
66
|
-
|
|
67
|
-
} else {
|
|
68
|
-
set_wire_rc -signal -layer "$signal_wire_rc_layers"
|
|
180
|
+
if { [llength $corners_with_custom_via_r] } {
|
|
181
|
+
log_cmd_rc set_vias_default_r $corners_without_custom_via_r
|
|
69
182
|
}
|
|
70
183
|
|
|
71
|
-
|
|
72
|
-
|
|
184
|
+
|
|
185
|
+
# If ANY corners are set, supply -corner with the set_wire_rc command.
|
|
186
|
+
#
|
|
187
|
+
# If NONE are set, just use set_wire_rc and let it handle all corners.
|
|
188
|
+
# For some godforsaken reason, set_wire_rc actually alters its own calculations
|
|
189
|
+
# slightly depending on if -corner is passed or not.
|
|
190
|
+
if { [llength $corners_with_custom_layer_rc] } {
|
|
191
|
+
log_cmd_rc set_wire_rc_wrapper -use_corners
|
|
73
192
|
} else {
|
|
74
|
-
|
|
193
|
+
log_cmd_rc set_wire_rc_wrapper
|
|
75
194
|
}
|
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
source $::env(SCRIPTS_DIR)/openroad/common/io.tcl
|
|
15
15
|
source $::env(SCRIPTS_DIR)/openroad/common/resizer.tcl
|
|
16
16
|
|
|
17
|
-
load_rsz_corners
|
|
18
17
|
read_current_odb
|
|
19
18
|
|
|
20
19
|
# set rc values
|
|
@@ -33,15 +32,36 @@ if { [info exists ::env(CTS_MAX_CAP)] } {
|
|
|
33
32
|
if { [info exists ::env(CTS_MAX_SLEW)] } {
|
|
34
33
|
lappend cts_characterization_args -max_slew [expr {$::env(CTS_MAX_SLEW) * 1e-9}]; # ns -> S
|
|
35
34
|
}
|
|
36
|
-
configure_cts_characterization {*}$cts_characterization_args
|
|
35
|
+
log_cmd configure_cts_characterization {*}$cts_characterization_args
|
|
37
36
|
|
|
38
37
|
puts "\[INFO\] Performing clock tree synthesis…"
|
|
39
38
|
puts "\[INFO\] Looking for the following net(s): $::env(CLOCK_NET)"
|
|
40
39
|
puts "\[INFO\] Running Clock Tree Synthesis…"
|
|
41
40
|
|
|
42
|
-
|
|
41
|
+
proc get_buflist {} {
|
|
42
|
+
set result [list]
|
|
43
|
+
foreach selector $::env(CTS_CLK_BUFFERS) {
|
|
44
|
+
# if we can find an exact match, avoid expensive search operation
|
|
45
|
+
set exact_match [$::db findMaster $selector]
|
|
46
|
+
if { "$exact_match" == "NULL" } {
|
|
47
|
+
# time to dig for matches…
|
|
48
|
+
foreach lib $::libs {
|
|
49
|
+
foreach master [$lib getMasters] {
|
|
50
|
+
set name [$master getName]
|
|
51
|
+
if { [string match $selector $name] } {
|
|
52
|
+
lappend result $name
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
} else {
|
|
57
|
+
lappend result [$exact_match getName]
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return $result
|
|
61
|
+
}
|
|
43
62
|
|
|
44
|
-
|
|
63
|
+
set arg_list [list]
|
|
64
|
+
lappend arg_list -buf_list [get_buflist]
|
|
45
65
|
lappend arg_list -root_buf $::env(CTS_ROOT_BUFFER)
|
|
46
66
|
lappend arg_list -sink_clustering_size $::env(CTS_SINK_CLUSTERING_SIZE)
|
|
47
67
|
lappend arg_list -sink_clustering_max_diameter $::env(CTS_SINK_CLUSTERING_MAX_DIAMETER)
|
|
@@ -50,12 +70,23 @@ lappend arg_list -sink_clustering_enable
|
|
|
50
70
|
if { $::env(CTS_DISTANCE_BETWEEN_BUFFERS) != 0 } {
|
|
51
71
|
lappend arg_list -distance_between_buffers $::env(CTS_DISTANCE_BETWEEN_BUFFERS)
|
|
52
72
|
}
|
|
53
|
-
|
|
54
73
|
if { $::env(CTS_DISABLE_POST_PROCESSING) } {
|
|
55
74
|
lappend arg_list -post_cts_disable
|
|
56
75
|
}
|
|
76
|
+
if { [info exists ::env(CTS_OBSTRUCTION_AWARE)] && $::env(CTS_OBSTRUCTION_AWARE) } {
|
|
77
|
+
lappend arg_list -obstruction_aware
|
|
78
|
+
}
|
|
79
|
+
if { [info exists ::env(CTS_SINK_BUFFER_MAX_CAP_DERATE_PCT)] } {
|
|
80
|
+
lappend arg_list -sink_buffer_max_cap_derate [expr $::env(CTS_SINK_BUFFER_MAX_CAP_DERATE_PCT) / 100.0]
|
|
81
|
+
}
|
|
82
|
+
if { [info exists ::env(CTS_DELAY_BUFFER_DERATE_PCT)] } {
|
|
83
|
+
lappend arg_list -delay_buffer_derate [expr $::env(CTS_DELAY_BUFFER_DERATE_PCT) / 100]
|
|
84
|
+
}
|
|
85
|
+
if { [info exists ::env(CTS_BALANCE_LEVELS)] && $::env(CTS_BALANCE_LEVELS) } {
|
|
86
|
+
lappend arg_list -balance_levels
|
|
87
|
+
}
|
|
57
88
|
|
|
58
|
-
clock_tree_synthesis {*}$arg_list
|
|
89
|
+
log_cmd clock_tree_synthesis {*}$arg_list
|
|
59
90
|
|
|
60
91
|
set_propagated_clock [all_clocks]
|
|
61
92
|
|
|
@@ -14,10 +14,25 @@
|
|
|
14
14
|
source $::env(SCRIPTS_DIR)/openroad/common/io.tcl
|
|
15
15
|
read_current_odb
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
set arg_list [list]
|
|
18
|
+
lappend arg_list -halo_width_x $::env(FP_MACRO_HORIZONTAL_HALO)
|
|
19
|
+
lappend arg_list -halo_width_y $::env(FP_MACRO_VERTICAL_HALO)
|
|
20
|
+
append_if_exists_argument arg_list FP_PRUNE_THRESHOLD -row_min_width
|
|
21
|
+
append_if_exists_argument arg_list ENDCAP_CELL -endcap_master
|
|
22
|
+
log_cmd cut_rows {*}$arg_list
|
|
23
|
+
|
|
24
|
+
# # verify -row_min_width worked
|
|
25
|
+
# if { [info exists ::env(FP_PRUNE_THRESHOLD)] } {
|
|
26
|
+
# foreach row [$::block getRows] {
|
|
27
|
+
# set bbox [$row getBBox]
|
|
28
|
+
# set width [expr ([$bbox xMax] - [$bbox xMin])]
|
|
29
|
+
# set width_um [expr $width / $::dbu]
|
|
30
|
+
# if { $width < $::env(FP_PRUNE_THRESHOLD) } {
|
|
31
|
+
# exit -1
|
|
32
|
+
# # odb::dbRow_destroy $row
|
|
33
|
+
# }
|
|
34
|
+
# }
|
|
35
|
+
# }
|
|
21
36
|
|
|
22
37
|
write_views
|
|
23
38
|
|
|
@@ -11,6 +11,22 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
+
proc drt_run {i args} {
|
|
15
|
+
set directory "drt-run-${i}"
|
|
16
|
+
file mkdir "$::env(STEP_DIR)/$directory"
|
|
17
|
+
set output_drc "-output_drc $::env(STEP_DIR)/$directory/$::env(DESIGN_NAME).drc"
|
|
18
|
+
log_cmd detailed_route {*}$args {*}$output_drc
|
|
19
|
+
if { $::env(DRT_SAVE_SNAPSHOTS) } {
|
|
20
|
+
foreach snapshot [glob -nocomplain drt_iter*.odb] {
|
|
21
|
+
file rename -force $snapshot $directory/[file tail $snapshot]
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
foreach drc_file [glob -nocomplain $::env(STEP_DIR)/$directory/*.drc] {
|
|
25
|
+
file copy -force $drc_file $::env(STEP_DIR)/[file tail $drc_file]
|
|
26
|
+
}
|
|
27
|
+
write_db $::env(STEP_DIR)/$directory/$::env(DESIGN_NAME).odb
|
|
28
|
+
}
|
|
29
|
+
|
|
14
30
|
source $::env(SCRIPTS_DIR)/openroad/common/io.tcl
|
|
15
31
|
read_current_odb
|
|
16
32
|
|
|
@@ -25,13 +41,48 @@ set max_layer $::env(RT_MAX_LAYER)
|
|
|
25
41
|
if { [info exists ::env(DRT_MAX_LAYER)] } {
|
|
26
42
|
set max_layer $::env(DRT_MAX_LAYER)
|
|
27
43
|
}
|
|
44
|
+
if { $::env(DRT_SAVE_SNAPSHOTS) } {
|
|
45
|
+
set_debug_level DRT snapshot 1
|
|
46
|
+
}
|
|
47
|
+
set drc_report_iter_step_arg ""
|
|
48
|
+
if { $::env(DRT_SAVE_SNAPSHOTS) } {
|
|
49
|
+
set_debug_level DRT snapshot 1
|
|
50
|
+
set drc_report_iter_step_arg "-drc_report_iter_step 1"
|
|
51
|
+
}
|
|
52
|
+
if { [info exists ::env(DRT_SAVE_DRC_REPORT_ITERS)] } {
|
|
53
|
+
set drc_report_iter_step_arg "-drc_report_iter_step $::env(DRT_SAVE_DRC_REPORT_ITERS)"
|
|
54
|
+
}
|
|
28
55
|
|
|
29
|
-
|
|
30
|
-
-bottom_routing_layer $min_layer\
|
|
31
|
-
-top_routing_layer $max_layer\
|
|
32
|
-
-output_drc $::env(STEP_DIR)/$::env(DESIGN_NAME).drc\
|
|
33
|
-
-droute_end_iter $::env(DRT_OPT_ITERS)\
|
|
34
|
-
-or_seed 42\
|
|
35
|
-
-verbose 1
|
|
56
|
+
set i 0
|
|
36
57
|
|
|
37
|
-
|
|
58
|
+
set drt_args [list]
|
|
59
|
+
lappend drt_args -bottom_routing_layer $min_layer
|
|
60
|
+
lappend drt_args -top_routing_layer $max_layer
|
|
61
|
+
lappend drt_args -droute_end_iter $::env(DRT_OPT_ITERS)
|
|
62
|
+
lappend drt_args -or_seed 42
|
|
63
|
+
lappend drt_args -verbose 1
|
|
64
|
+
lappend drt_args {*}$drc_report_iter_step_arg
|
|
65
|
+
drt_run $i {*}$drt_args
|
|
66
|
+
|
|
67
|
+
incr i
|
|
68
|
+
|
|
69
|
+
if { ![info exists ::env(DIODE_CELL)] } {
|
|
70
|
+
puts "\[INFO\] Skipping post-DRT antenna repair: 'DIODE_CELL' not set."
|
|
71
|
+
} elseif { $::env(DRT_ANTENNA_REPAIR_ITERS) == 0 } {
|
|
72
|
+
puts "\[INFO\] Skipping post-DRT antenna repair: DRT_ANTENNA_REPAIR_ITERS set to 0."
|
|
73
|
+
} else {
|
|
74
|
+
set diode_cell [lindex [split $::env(DIODE_CELL) "/"] 0]
|
|
75
|
+
|
|
76
|
+
while {$i <= $::env(DRT_ANTENNA_REPAIR_ITERS) && [log_cmd check_antennas]} {
|
|
77
|
+
puts "\[INFO\] Running antenna repair iteration $i…"
|
|
78
|
+
set diodes_inserted [log_cmd repair_antennas $diode_cell -ratio_margin $::env(DRT_ANTENNA_MARGIN)]
|
|
79
|
+
if {$diodes_inserted} {
|
|
80
|
+
drt_run $i {*}$drt_args
|
|
81
|
+
} else {
|
|
82
|
+
puts "\[INFO\] No diodes inserted. Ending antenna repair iterations."
|
|
83
|
+
break
|
|
84
|
+
}
|
|
85
|
+
incr i
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
write_views
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Copyright 2020-2022 Efabless Corporation
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
source $::env(SCRIPTS_DIR)/openroad/common/io.tcl
|
|
15
|
+
read_pnr_libs
|
|
16
|
+
read_lefs
|
|
17
|
+
read_def $::env(CURRENT_DEF)
|
|
18
|
+
set_global_vars
|
|
19
|
+
|
|
20
|
+
set rc_header {%-20s%-20s%-20s%-20s}
|
|
21
|
+
set rc_entry {%-20s%-20s%-20e%-20e}
|
|
22
|
+
set r_header {%-20s%-20s}
|
|
23
|
+
set r_entry {%-20s%-20e}
|
|
24
|
+
|
|
25
|
+
proc scale_ohm_per_meter {value} {
|
|
26
|
+
set ohm_per_unit_distance [expr "$value * [sta::unit_scale distance]"]
|
|
27
|
+
set unit_res_per_unit_distance [expr "$ohm_per_unit_distance / [sta::unit_scale resistance]"]
|
|
28
|
+
return $unit_res_per_unit_distance
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
proc scale_f_per_meter {value} {
|
|
32
|
+
set f_per_unit_distance [expr "$value * [sta::unit_scale distance]"]
|
|
33
|
+
set unit_cap_per_unit_distance [expr "$f_per_unit_distance / [sta::unit_scale capacitance]"]
|
|
34
|
+
return $unit_cap_per_unit_distance
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
proc dblayer_rc_values {header} {
|
|
38
|
+
upvar 1 rc_header rc_header
|
|
39
|
+
upvar 1 rc_entry rc_entry
|
|
40
|
+
upvar 1 r_header r_header
|
|
41
|
+
upvar 1 r_entry r_entry
|
|
42
|
+
|
|
43
|
+
puts $header
|
|
44
|
+
puts "=== Routing Layers ==="
|
|
45
|
+
puts [format $rc_header "Name" "Direction" "Res/Unit Distance" "Cap/Unit Distance"]
|
|
46
|
+
foreach layer [get_layers -types "ROUTING"] {
|
|
47
|
+
lassign [rsz::dblayer_wire_rc $layer] layer_wire_res_ohm_m layer_wire_cap_farad_m
|
|
48
|
+
puts [format $rc_entry [$layer getName] [$layer getDirection] [scale_ohm_per_meter $layer_wire_res_ohm_m] [scale_f_per_meter $layer_wire_cap_farad_m]]
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
puts "=== Vias ==="
|
|
52
|
+
puts [format $r_header "Name" "Cut Resistance"]
|
|
53
|
+
foreach layer [get_layers -types "CUT"] {
|
|
54
|
+
set ohms_per_cut [$layer getResistance]
|
|
55
|
+
puts [format $r_entry [$layer getName] [expr "$ohms_per_cut / [sta::unit_scale resistance]"]]
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
proc resizer_rc_values {header} {
|
|
60
|
+
upvar 1 rc_header rc_header
|
|
61
|
+
upvar 1 rc_entry rc_entry
|
|
62
|
+
upvar 1 r_header r_header
|
|
63
|
+
upvar 1 r_entry r_entry
|
|
64
|
+
|
|
65
|
+
puts $header
|
|
66
|
+
foreach corner [sta::corners] {
|
|
67
|
+
puts "=== Corner [$corner name] ==="
|
|
68
|
+
puts "==== Estimation RC Values ===="
|
|
69
|
+
puts [format $rc_header "Name" "Direction" "Res/Unit Distance" "Cap/Unit Distance"]
|
|
70
|
+
puts [format $rc_entry "Signal" "Avg" [scale_ohm_per_meter [rsz::wire_signal_resistance $corner]] [scale_f_per_meter [rsz::wire_signal_capacitance $corner]]]
|
|
71
|
+
puts [format $rc_entry "Clock" "Avg" [scale_ohm_per_meter [rsz::wire_clk_resistance $corner]] [scale_f_per_meter [rsz::wire_clk_capacitance $corner]]]
|
|
72
|
+
puts "==== Rt. Layer RC Values ===="
|
|
73
|
+
puts [format $rc_header "Name" "Direction" "Res/Unit Distance" "Cap/Unit Distance"]
|
|
74
|
+
foreach layer [get_layers -types "ROUTING"] {
|
|
75
|
+
set resistance [expr [rsz::layer_resistance $layer $corner] / [sta::unit_scale resistance] * [sta::unit_scale distance]]
|
|
76
|
+
set capacitance [expr [rsz::layer_capacitance $layer $corner] / [sta::unit_scale capacitance] * [sta::unit_scale distance]]
|
|
77
|
+
puts [format $rc_entry [$layer getName] [$layer getDirection] $resistance $capacitance]
|
|
78
|
+
}
|
|
79
|
+
puts "==== Via R Values ===="
|
|
80
|
+
puts [format $r_header "Name" "Res/Unit Distance"]
|
|
81
|
+
foreach layer [get_layers -types "CUT"] {
|
|
82
|
+
set ohms_per_cut [rsz::layer_resistance $layer $corner]
|
|
83
|
+
set units_resistance_per_cut [expr $ohms_per_cut / [sta::unit_scale resistance]]
|
|
84
|
+
puts [format $r_entry [$layer getName] $units_resistance_per_cut]
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
puts "%OL_CREATE_REPORT tlef_values.rpt"
|
|
91
|
+
report_units
|
|
92
|
+
dblayer_rc_values "== Technology LEF Values =="
|
|
93
|
+
puts "%OL_END_REPORT"
|
|
94
|
+
|
|
95
|
+
source $::env(SCRIPTS_DIR)/openroad/common/set_rc.tcl
|
|
96
|
+
|
|
97
|
+
puts "%OL_CREATE_REPORT layer_values_after.rpt"
|
|
98
|
+
report_units
|
|
99
|
+
dblayer_rc_values "== Layer Values (After Set RC) =="
|
|
100
|
+
puts "%OL_END_REPORT"
|
|
101
|
+
|
|
102
|
+
puts "%OL_CREATE_REPORT resizer_values_after.rpt"
|
|
103
|
+
report_units
|
|
104
|
+
resizer_rc_values "== Resizer RC Values (After Set RC) =="
|
|
105
|
+
puts "%OL_END_REPORT"
|
|
@@ -15,11 +15,11 @@ source $::env(SCRIPTS_DIR)/openroad/common/io.tcl
|
|
|
15
15
|
read_current_odb
|
|
16
16
|
|
|
17
17
|
set fill_list [list]
|
|
18
|
-
foreach {pattern} $::env(
|
|
18
|
+
foreach {pattern} $::env(DECAP_CELLS) {
|
|
19
19
|
set stripped [string map {' {}} $pattern]
|
|
20
20
|
lappend fill_list $stripped
|
|
21
21
|
}
|
|
22
|
-
foreach {pattern} $::env(
|
|
22
|
+
foreach {pattern} $::env(FILL_CELLS) {
|
|
23
23
|
set stripped [string map {' {}} $pattern]
|
|
24
24
|
lappend fill_list $stripped
|
|
25
25
|
}
|
|
@@ -53,7 +53,7 @@ puts "\[INFO\] Using $::env(FP_SIZING) sizing for the floorplan."
|
|
|
53
53
|
if {$::env(FP_SIZING) == "absolute"} {
|
|
54
54
|
if { [llength $::env(DIE_AREA)] != 4 } {
|
|
55
55
|
puts stderr "Invalid die area string '$::env(DIE_AREA)'."
|
|
56
|
-
|
|
56
|
+
exit_unless_gui 1
|
|
57
57
|
}
|
|
58
58
|
if { ! [info exists ::env(CORE_AREA)] } {
|
|
59
59
|
set die_x0 [lindex $::env(DIE_AREA) 0]
|
|
@@ -73,7 +73,7 @@ if {$::env(FP_SIZING) == "absolute"} {
|
|
|
73
73
|
} else {
|
|
74
74
|
if { [llength $::env(CORE_AREA)] != 4 } {
|
|
75
75
|
puts stderr "Invalid core area string '$::env(CORE_AREA)'."
|
|
76
|
-
|
|
76
|
+
exit_unless_gui 1
|
|
77
77
|
}
|
|
78
78
|
puts "\[INFO\] Using the set CORE_AREA; ignoring core margin parameters"
|
|
79
79
|
}
|
|
@@ -97,7 +97,9 @@ if { [info exists ::env(FP_OBSTRUCTIONS)] } {
|
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
|
|
100
|
+
append_if_exists_argument arg_list FP_FLIP_SITES -flip_sites
|
|
101
|
+
|
|
102
|
+
log_cmd initialize_floorplan {*}$arg_list
|
|
101
103
|
|
|
102
104
|
insert_tiecells $::env(SYNTH_TIELO_CELL) -prefix "TIE_ZERO_"
|
|
103
105
|
insert_tiecells $::env(SYNTH_TIEHI_CELL) -prefix "TIE_ONE_"
|
|
@@ -26,11 +26,11 @@ foreach inst $::insts {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
if { !$placement_needed } {
|
|
29
|
-
puts
|
|
30
|
-
puts
|
|
31
|
-
puts
|
|
29
|
+
puts "\[INFO\] All instances are FIXED/FIRM."
|
|
30
|
+
puts "\[INFO\] No need to perform global placement."
|
|
31
|
+
puts "\[INFO\] Skipping…"
|
|
32
32
|
write_views
|
|
33
|
-
|
|
33
|
+
exit_unless_gui
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
set arg_list [list]
|
|
@@ -56,8 +56,7 @@ if { $::env(PL_SKIP_INITIAL_PLACEMENT) } {
|
|
|
56
56
|
lappend arg_list -skip_initial_place
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
if { [info exists ::env(__PL_SKIP_IO)] } {
|
|
59
|
+
if { [info exists ::env(__PL_SKIP_IO)] && $::env(__PL_SKIP_IO) == "1" } {
|
|
61
60
|
lappend arg_list -skip_io
|
|
62
61
|
}
|
|
63
62
|
|
|
@@ -74,9 +73,9 @@ set cell_pad_side [expr $::env(GPL_CELL_PADDING) / 2]
|
|
|
74
73
|
lappend arg_list -pad_right $cell_pad_side
|
|
75
74
|
lappend arg_list -pad_left $cell_pad_side
|
|
76
75
|
lappend arg_list -init_wirelength_coef $::env(PL_WIRE_LENGTH_COEF)
|
|
76
|
+
append_if_exists_argument arg_list PL_KEEP_RESIZE_BELOW_OVERFLOW -keep_resize_below_overflow
|
|
77
77
|
|
|
78
|
-
|
|
79
|
-
global_placement {*}$arg_list
|
|
78
|
+
log_cmd global_placement {*}$arg_list
|
|
80
79
|
|
|
81
80
|
|
|
82
81
|
source $::env(SCRIPTS_DIR)/openroad/common/set_rc.tcl
|
|
@@ -13,5 +13,25 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
source $::env(SCRIPTS_DIR)/openroad/common/io.tcl
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
puts "Reading OpenROAD database at '$::env(CURRENT_ODB)'…"
|
|
17
|
+
if { [ catch {read_db $::env(CURRENT_ODB)} errmsg ]} {
|
|
18
|
+
puts stderr $errmsg
|
|
19
|
+
exit 1
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
set_global_vars
|
|
23
|
+
|
|
24
|
+
define_corners $::env(DEFAULT_CORNER)
|
|
25
|
+
|
|
26
|
+
foreach lib $::env(_PNR_LIBS) {
|
|
27
|
+
puts "Reading library file at '$lib'…"
|
|
28
|
+
read_liberty $lib
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
read_current_sdc
|
|
32
|
+
|
|
33
|
+
if { [info exists ::env(_CURRENT_SPEF_BY_CORNER)] } {
|
|
34
|
+
set corner_name $::env(_CURRENT_CORNER_NAME)
|
|
35
|
+
puts "Reading top-level design parasitics for the '$corner_name' corner at '$::env(_CURRENT_SPEF_BY_CORNER)'…"
|
|
36
|
+
read_spef -corner $corner_name $::env(_CURRENT_SPEF_BY_CORNER)
|
|
37
|
+
}
|
|
@@ -55,8 +55,7 @@ if { $::env(FP_PPL_MODE) == "annealing" } {
|
|
|
55
55
|
set HMETAL $::env(FP_IO_HLAYER)
|
|
56
56
|
set VMETAL $::env(FP_IO_VLAYER)
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
place_pins {*}$arg_list \
|
|
58
|
+
log_cmd place_pins {*}$arg_list \
|
|
60
59
|
-random_seed 42 \
|
|
61
60
|
-hor_layers $HMETAL \
|
|
62
61
|
-ver_layers $VMETAL
|
|
@@ -27,7 +27,7 @@ if { [info exists ::env(VSRC_LOC_FILES)] } {
|
|
|
27
27
|
lappend arg_list -net $net
|
|
28
28
|
lappend arg_list -voltage_file $::env(STEP_DIR)/net-$net.csv
|
|
29
29
|
lappend arg_list -vsrc $vsrc_file
|
|
30
|
-
analyze_power_grid {*}$arg_list
|
|
30
|
+
log_cmd analyze_power_grid {*}$arg_list
|
|
31
31
|
}
|
|
32
32
|
puts "%OL_END_REPORT"
|
|
33
33
|
} else {
|
|
@@ -38,14 +38,14 @@ if { [info exists ::env(VSRC_LOC_FILES)] } {
|
|
|
38
38
|
lappend arg_list -net $net
|
|
39
39
|
lappend arg_list -voltage_file $::env(STEP_DIR)/net-$net.csv
|
|
40
40
|
set_pdnsim_net_voltage -net $net -voltage $::env(LIB_VOLTAGE)
|
|
41
|
-
analyze_power_grid {*}$arg_list
|
|
41
|
+
log_cmd analyze_power_grid {*}$arg_list
|
|
42
42
|
}
|
|
43
43
|
foreach net "$::env(GND_NETS)" {
|
|
44
44
|
set arg_list [list]
|
|
45
45
|
lappend arg_list -net $net
|
|
46
46
|
lappend arg_list -voltage_file $::env(STEP_DIR)/net-$net.csv
|
|
47
47
|
set_pdnsim_net_voltage -net $net -voltage 0
|
|
48
|
-
analyze_power_grid {*}$arg_list
|
|
48
|
+
log_cmd analyze_power_grid {*}$arg_list
|
|
49
49
|
}
|
|
50
50
|
puts "%OL_END_REPORT"
|
|
51
51
|
}
|