siliconcompiler 0.28.8__py3-none-any.whl → 0.29.0__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.
- siliconcompiler/_metadata.py +1 -1
- siliconcompiler/apps/sc_remote.py +15 -14
- siliconcompiler/apps/sc_show.py +5 -5
- siliconcompiler/apps/utils/replay.py +136 -0
- siliconcompiler/core.py +14 -12
- siliconcompiler/flows/_common.py +11 -13
- siliconcompiler/flows/asicflow.py +83 -42
- siliconcompiler/remote/__init__.py +11 -0
- siliconcompiler/remote/client.py +753 -815
- siliconcompiler/report/report.py +2 -0
- siliconcompiler/report/summary_table.py +1 -1
- siliconcompiler/scheduler/__init__.py +51 -9
- siliconcompiler/scheduler/send_messages.py +37 -33
- siliconcompiler/scheduler/validation/email_credentials.json +7 -0
- siliconcompiler/schema/schema_cfg.py +15 -3
- siliconcompiler/schema/schema_obj.py +16 -0
- siliconcompiler/sphinx_ext/dynamicgen.py +4 -3
- siliconcompiler/targets/fpgaflow_demo.py +6 -7
- siliconcompiler/targets/gf180_demo.py +3 -3
- siliconcompiler/templates/replay/requirements.txt +6 -0
- siliconcompiler/templates/replay/run.py.j2 +22 -0
- siliconcompiler/templates/replay/setup.sh +17 -0
- siliconcompiler/tools/_common/__init__.py +17 -3
- siliconcompiler/tools/_common/asic.py +10 -3
- siliconcompiler/tools/builtin/concatenate.py +1 -1
- siliconcompiler/tools/openroad/__init__.py +103 -0
- siliconcompiler/tools/openroad/{openroad.py → _apr.py} +413 -422
- siliconcompiler/tools/openroad/antenna_repair.py +78 -0
- siliconcompiler/tools/openroad/clock_tree_synthesis.py +64 -0
- siliconcompiler/tools/openroad/detailed_placement.py +59 -0
- siliconcompiler/tools/openroad/detailed_route.py +62 -0
- siliconcompiler/tools/openroad/endcap_tapcell_insertion.py +52 -0
- siliconcompiler/tools/openroad/fillercell_insertion.py +58 -0
- siliconcompiler/tools/openroad/{dfm.py → fillmetal_insertion.py} +35 -19
- siliconcompiler/tools/openroad/global_placement.py +58 -0
- siliconcompiler/tools/openroad/global_route.py +63 -0
- siliconcompiler/tools/openroad/init_floorplan.py +103 -0
- siliconcompiler/tools/openroad/macro_placement.py +65 -0
- siliconcompiler/tools/openroad/metrics.py +23 -8
- siliconcompiler/tools/openroad/pin_placement.py +56 -0
- siliconcompiler/tools/openroad/power_grid.py +65 -0
- siliconcompiler/tools/openroad/rcx_bench.py +7 -4
- siliconcompiler/tools/openroad/rcx_extract.py +2 -1
- siliconcompiler/tools/openroad/rdlroute.py +4 -4
- siliconcompiler/tools/openroad/repair_design.py +59 -0
- siliconcompiler/tools/openroad/repair_timing.py +63 -0
- siliconcompiler/tools/openroad/screenshot.py +9 -20
- siliconcompiler/tools/openroad/scripts/apr/postamble.tcl +44 -0
- siliconcompiler/tools/openroad/scripts/apr/preamble.tcl +95 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_antenna_repair.tcl +51 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_clock_tree_synthesis.tcl +62 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_detailed_placement.tcl +41 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_detailed_route.tcl +71 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_endcap_tapcell_insertion.tcl +55 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_fillercell_insertion.tcl +27 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_fillmetal_insertion.tcl +36 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_global_placement.tcl +26 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_global_route.tcl +61 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_init_floorplan.tcl +333 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_macro_placement.tcl +123 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_metrics.tcl +22 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_pin_placement.tcl +41 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_power_grid.tcl +60 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_repair_design.tcl +68 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_repair_timing.tcl +83 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_write_data.tcl +125 -0
- siliconcompiler/tools/openroad/scripts/common/debugging.tcl +28 -0
- siliconcompiler/tools/openroad/scripts/common/procs.tcl +675 -0
- siliconcompiler/tools/openroad/scripts/common/read_input_files.tcl +59 -0
- siliconcompiler/tools/openroad/scripts/common/read_liberty.tcl +20 -0
- siliconcompiler/tools/openroad/scripts/common/read_timing_constraints.tcl +16 -0
- siliconcompiler/tools/openroad/scripts/common/reports.tcl +180 -0
- siliconcompiler/tools/openroad/scripts/common/screenshot.tcl +18 -0
- siliconcompiler/tools/openroad/scripts/common/write_images.tcl +395 -0
- siliconcompiler/tools/openroad/scripts/{sc_rcx_bench.tcl → rcx/sc_rcx_bench.tcl} +5 -5
- siliconcompiler/tools/openroad/scripts/{sc_rcx_extract.tcl → rcx/sc_rcx_extract.tcl} +0 -0
- siliconcompiler/tools/openroad/scripts/sc_rcx.tcl +5 -16
- siliconcompiler/tools/openroad/scripts/sc_rdlroute.tcl +51 -51
- siliconcompiler/tools/openroad/scripts/sc_show.tcl +105 -0
- siliconcompiler/tools/openroad/show.py +28 -23
- siliconcompiler/tools/openroad/{export.py → write_data.py} +31 -26
- siliconcompiler/tools/opensta/__init__.py +1 -1
- siliconcompiler/tools/vivado/bitstream.py +8 -2
- siliconcompiler/tools/vivado/place.py +6 -2
- siliconcompiler/tools/vivado/route.py +6 -2
- siliconcompiler/tools/vivado/scripts/sc_bitstream.tcl +1 -1
- siliconcompiler/tools/vivado/scripts/sc_place.tcl +1 -1
- siliconcompiler/tools/vivado/scripts/sc_route.tcl +1 -1
- siliconcompiler/tools/vivado/scripts/sc_run.tcl +4 -2
- siliconcompiler/tools/vivado/syn_fpga.py +5 -1
- siliconcompiler/tools/vivado/vivado.py +26 -10
- siliconcompiler/tools/vpr/vpr.py +5 -0
- siliconcompiler/tools/yosys/syn_asic.py +7 -0
- siliconcompiler/tools/yosys/syn_asic.tcl +27 -6
- siliconcompiler/tools/yosys/syn_fpga.tcl +26 -18
- siliconcompiler/toolscripts/_tools.json +5 -5
- {siliconcompiler-0.28.8.dist-info → siliconcompiler-0.29.0.dist-info}/METADATA +50 -48
- {siliconcompiler-0.28.8.dist-info → siliconcompiler-0.29.0.dist-info}/RECORD +103 -76
- {siliconcompiler-0.28.8.dist-info → siliconcompiler-0.29.0.dist-info}/WHEEL +1 -1
- siliconcompiler/tools/openroad/cts.py +0 -45
- siliconcompiler/tools/openroad/floorplan.py +0 -75
- siliconcompiler/tools/openroad/physyn.py +0 -27
- siliconcompiler/tools/openroad/place.py +0 -41
- siliconcompiler/tools/openroad/route.py +0 -45
- siliconcompiler/tools/openroad/scripts/__init__.py +0 -0
- siliconcompiler/tools/openroad/scripts/sc_apr.tcl +0 -514
- siliconcompiler/tools/openroad/scripts/sc_cts.tcl +0 -68
- siliconcompiler/tools/openroad/scripts/sc_dfm.tcl +0 -22
- siliconcompiler/tools/openroad/scripts/sc_export.tcl +0 -100
- siliconcompiler/tools/openroad/scripts/sc_floorplan.tcl +0 -456
- siliconcompiler/tools/openroad/scripts/sc_metrics.tcl +0 -1
- siliconcompiler/tools/openroad/scripts/sc_physyn.tcl +0 -6
- siliconcompiler/tools/openroad/scripts/sc_place.tcl +0 -84
- siliconcompiler/tools/openroad/scripts/sc_procs.tcl +0 -494
- siliconcompiler/tools/openroad/scripts/sc_report.tcl +0 -189
- siliconcompiler/tools/openroad/scripts/sc_route.tcl +0 -143
- siliconcompiler/tools/openroad/scripts/sc_screenshot.tcl +0 -18
- siliconcompiler/tools/openroad/scripts/sc_write_images.tcl +0 -393
- /siliconcompiler/tools/openroad/scripts/{sc_write.tcl → common/write_data.tcl} +0 -0
- {siliconcompiler-0.28.8.dist-info → siliconcompiler-0.29.0.dist-info}/LICENSE +0 -0
- {siliconcompiler-0.28.8.dist-info → siliconcompiler-0.29.0.dist-info}/entry_points.txt +0 -0
- {siliconcompiler-0.28.8.dist-info → siliconcompiler-0.29.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,675 @@
|
|
|
1
|
+
#######################
|
|
2
|
+
# Global Placement
|
|
3
|
+
#######################
|
|
4
|
+
|
|
5
|
+
proc sc_global_placement_density { } {
|
|
6
|
+
set gpl_padding [lindex [sc_cfg_tool_task_get var pad_global_place] 0]
|
|
7
|
+
set gpl_place_density [lindex [sc_cfg_tool_task_get var place_density] 0]
|
|
8
|
+
set gpl_uniform_placement_adjustment \
|
|
9
|
+
[lindex [sc_cfg_tool_task_get var gpl_uniform_placement_adjustment] 0]
|
|
10
|
+
|
|
11
|
+
set or_uniform_density [gpl::get_global_placement_uniform_density \
|
|
12
|
+
-pad_left $gpl_padding \
|
|
13
|
+
-pad_right $gpl_padding]
|
|
14
|
+
|
|
15
|
+
# Small adder to ensure requested density is slightly over the uniform density
|
|
16
|
+
set or_adjust_density_adder 0.001
|
|
17
|
+
|
|
18
|
+
set selected_density $gpl_place_density
|
|
19
|
+
|
|
20
|
+
# User specified adjustment
|
|
21
|
+
if { $gpl_uniform_placement_adjustment > 0.0 } {
|
|
22
|
+
set or_uniform_adjusted_density \
|
|
23
|
+
[expr {
|
|
24
|
+
$or_uniform_density + ((1.0 - $or_uniform_density) *
|
|
25
|
+
$gpl_uniform_placement_adjustment) + $or_adjust_density_adder
|
|
26
|
+
}]
|
|
27
|
+
if { $or_uniform_adjusted_density > 1.00 } {
|
|
28
|
+
utl::warn FLW 1 "Adjusted density exceeds 1.00 \
|
|
29
|
+
([format %0.3f $or_uniform_adjusted_density]), reverting to use \
|
|
30
|
+
($gpl_place_density) for global placement"
|
|
31
|
+
set selected_density $gpl_place_density
|
|
32
|
+
} else {
|
|
33
|
+
utl::info FLW 1 "Using computed density of \
|
|
34
|
+
([format %0.3f $or_uniform_adjusted_density]) for global placement"
|
|
35
|
+
set selected_density $or_uniform_adjusted_density
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
# Final selection
|
|
40
|
+
set or_uniform_zero_adjusted_density \
|
|
41
|
+
[expr { min($or_uniform_density + $or_adjust_density_adder, 1.0) }]
|
|
42
|
+
|
|
43
|
+
if { $selected_density < $or_uniform_density } {
|
|
44
|
+
utl::warn FLW 1 "Using computed density of \
|
|
45
|
+
([format %0.3f $or_uniform_zero_adjusted_density]) for global placement as \
|
|
46
|
+
[format %0.3f $selected_density] < [format %0.3f $or_uniform_density]"
|
|
47
|
+
set selected_density $or_uniform_zero_adjusted_density
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return $selected_density
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
proc sc_global_placement { args } {
|
|
54
|
+
sta::parse_key_args "sc_global_placement" args \
|
|
55
|
+
keys {} \
|
|
56
|
+
flags {-skip_io -disable_routability_driven}
|
|
57
|
+
sta::check_argc_eq0 "sc_global_placement" $args
|
|
58
|
+
|
|
59
|
+
set gpl_routability_driven [lindex [sc_cfg_tool_task_get var gpl_routability_driven] 0]
|
|
60
|
+
set gpl_timing_driven [lindex [sc_cfg_tool_task_get var gpl_timing_driven] 0]
|
|
61
|
+
set gpl_padding [lindex [sc_cfg_tool_task_get var pad_global_place] 0]
|
|
62
|
+
|
|
63
|
+
set gpl_args []
|
|
64
|
+
if {
|
|
65
|
+
$gpl_routability_driven == "true" &&
|
|
66
|
+
![info exists flags(-disable_routability_driven)]
|
|
67
|
+
} {
|
|
68
|
+
lappend gpl_args "-routability_driven"
|
|
69
|
+
}
|
|
70
|
+
if { $gpl_timing_driven == "true" } {
|
|
71
|
+
lappend gpl_args "-timing_driven"
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if { [info exists flags(-skip_io)] } {
|
|
75
|
+
lappend gpl_args "-skip_io"
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
set density [sc_global_placement_density]
|
|
79
|
+
|
|
80
|
+
global_placement {*}$gpl_args \
|
|
81
|
+
-density $density \
|
|
82
|
+
-pad_left $gpl_padding \
|
|
83
|
+
-pad_right $gpl_padding
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
###########################
|
|
87
|
+
# Detailed Placement
|
|
88
|
+
###########################
|
|
89
|
+
|
|
90
|
+
proc sc_detailed_placement { } {
|
|
91
|
+
set dpl_padding [lindex [sc_cfg_tool_task_get var pad_detail_place] 0]
|
|
92
|
+
set dpl_disallow_one_site [lindex [sc_cfg_tool_task_get var dpl_disallow_one_site] 0]
|
|
93
|
+
set dpl_max_displacement [lindex [sc_cfg_tool_task_get var dpl_max_displacement] 0]
|
|
94
|
+
|
|
95
|
+
set_placement_padding -global \
|
|
96
|
+
-left $dpl_padding \
|
|
97
|
+
-right $dpl_padding
|
|
98
|
+
|
|
99
|
+
set dpl_args []
|
|
100
|
+
if { $dpl_disallow_one_site == "true" } {
|
|
101
|
+
lappend dpl_args "-disallow_one_site_gaps"
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
detailed_placement \
|
|
105
|
+
-max_displacement $dpl_max_displacement \
|
|
106
|
+
{*}$dpl_args
|
|
107
|
+
check_placement -verbose
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
###########################
|
|
111
|
+
# Pin Placement
|
|
112
|
+
###########################
|
|
113
|
+
|
|
114
|
+
proc sc_pin_placement { args } {
|
|
115
|
+
sta::parse_key_args "sc_pin_placement" args \
|
|
116
|
+
keys {} \
|
|
117
|
+
flags {-random}
|
|
118
|
+
sta::check_argc_eq0 "sc_pin_placement" $args
|
|
119
|
+
|
|
120
|
+
global sc_pdk
|
|
121
|
+
global sc_stackup
|
|
122
|
+
global sc_tool
|
|
123
|
+
|
|
124
|
+
set sc_hpinmetal [sc_cfg_get pdk $sc_pdk {var} $sc_tool pin_layer_horizontal $sc_stackup]
|
|
125
|
+
set sc_hpinmetal [sc_get_layer_name $sc_hpinmetal]
|
|
126
|
+
set sc_vpinmetal [sc_cfg_get pdk $sc_pdk {var} $sc_tool pin_layer_vertical $sc_stackup]
|
|
127
|
+
set sc_vpinmetal [sc_get_layer_name $sc_vpinmetal]
|
|
128
|
+
|
|
129
|
+
if { [sc_cfg_tool_task_exists var pin_thickness_h] } {
|
|
130
|
+
set h_mult [lindex [sc_cfg_tool_task_get var pin_thickness_h] 0]
|
|
131
|
+
set_pin_thick_multiplier -hor_multiplier $h_mult
|
|
132
|
+
}
|
|
133
|
+
if { [sc_cfg_tool_task_exists var pin_thickness_v] } {
|
|
134
|
+
set v_mult [lindex [sc_cfg_tool_task_get var pin_thickness_v] 0]
|
|
135
|
+
set_pin_thick_multiplier -ver_multiplier $v_mult
|
|
136
|
+
}
|
|
137
|
+
if { [sc_cfg_tool_task_exists {file} ppl_constraints] } {
|
|
138
|
+
foreach pin_constraint [sc_cfg_tool_task_get {file} ppl_constraints] {
|
|
139
|
+
puts "Sourcing pin constraints: ${pin_constraint}"
|
|
140
|
+
source $pin_constraint
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
set ppl_args []
|
|
145
|
+
if { [info exists flags(-random)] } {
|
|
146
|
+
lappend ppl_args "-random"
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
place_pins -hor_layers $sc_hpinmetal \
|
|
150
|
+
-ver_layers $sc_vpinmetal \
|
|
151
|
+
{*}[sc_cfg_tool_task_get {var} ppl_arguments] \
|
|
152
|
+
{*}$ppl_args
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
###########################
|
|
156
|
+
# Check if OR has a GUI
|
|
157
|
+
###########################
|
|
158
|
+
|
|
159
|
+
proc sc_has_gui { } {
|
|
160
|
+
return [gui::supported]
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
###########################
|
|
164
|
+
# Check if design has placed instances
|
|
165
|
+
###########################
|
|
166
|
+
|
|
167
|
+
proc sc_has_placed_instances { } {
|
|
168
|
+
foreach inst [[ord::get_db_block] getInsts] {
|
|
169
|
+
if { [$inst isPlaced] } {
|
|
170
|
+
return true
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return false
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
###########################
|
|
177
|
+
# Check if design has unplaced instances
|
|
178
|
+
###########################
|
|
179
|
+
|
|
180
|
+
proc sc_has_unplaced_instances { } {
|
|
181
|
+
foreach inst [[ord::get_db_block] getInsts] {
|
|
182
|
+
if { ![$inst isPlaced] } {
|
|
183
|
+
return true
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return false
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
###########################
|
|
190
|
+
# Check if design has routing
|
|
191
|
+
###########################
|
|
192
|
+
|
|
193
|
+
proc sc_has_routing { } {
|
|
194
|
+
foreach net [[ord::get_db_block] getNets] {
|
|
195
|
+
if { [$net getWire] != "NULL" } {
|
|
196
|
+
return true
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return false
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
###########################
|
|
203
|
+
# Check if design has global routing
|
|
204
|
+
###########################
|
|
205
|
+
|
|
206
|
+
proc sc_has_global_routing { } {
|
|
207
|
+
foreach net [[ord::get_db_block] getNets] {
|
|
208
|
+
if { [llength [$net getGuides]] != 0 } {
|
|
209
|
+
return true
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return false
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
###########################
|
|
216
|
+
# Design has unplaced macros
|
|
217
|
+
###########################
|
|
218
|
+
|
|
219
|
+
# Function adapted from OpenROAD:
|
|
220
|
+
# https://github.com/The-OpenROAD-Project/OpenROAD-flow-scripts/blob/ca3004b85e0d4fbee3470115e63b83c498cfed85/flow/scripts/macro_place.tcl#L26
|
|
221
|
+
proc sc_design_has_unplaced_macros { } {
|
|
222
|
+
foreach inst [[ord::get_db_block] getInsts] {
|
|
223
|
+
if { [$inst isBlock] && ![$inst isFixed] } {
|
|
224
|
+
return true
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return false
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
###########################
|
|
231
|
+
# Print macros placement
|
|
232
|
+
###########################
|
|
233
|
+
|
|
234
|
+
proc sc_print_macro_information { } {
|
|
235
|
+
set print_header "true"
|
|
236
|
+
foreach inst [[ord::get_db_block] getInsts] {
|
|
237
|
+
if { [$inst isBlock] } {
|
|
238
|
+
set master [$inst getMaster]
|
|
239
|
+
set status [$inst getPlacementStatus]
|
|
240
|
+
|
|
241
|
+
if { $print_header == "true" } {
|
|
242
|
+
puts "Macro placement information:"
|
|
243
|
+
set print_header "false"
|
|
244
|
+
}
|
|
245
|
+
if { [$inst isPlaced] } {
|
|
246
|
+
set location [$inst getLocation]
|
|
247
|
+
set orient [$inst getOrient]
|
|
248
|
+
set xloc [ord::dbu_to_microns [lindex $location 0]]
|
|
249
|
+
set yloc [ord::dbu_to_microns [lindex $location 1]]
|
|
250
|
+
puts " [$inst getName] ([$master getName]): $status at\
|
|
251
|
+
($xloc um, $yloc um) $orient"
|
|
252
|
+
} else {
|
|
253
|
+
utl::warn FLW 1 " [$inst getName] ([$master getName]): UNPLACED"
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
###########################
|
|
260
|
+
# Design has unplaced pads
|
|
261
|
+
###########################
|
|
262
|
+
|
|
263
|
+
proc sc_design_has_unplaced_pads { } {
|
|
264
|
+
foreach inst [[ord::get_db_block] getInsts] {
|
|
265
|
+
if { [$inst isPad] && ![$inst isFixed] } {
|
|
266
|
+
return true
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
return false
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
###########################
|
|
273
|
+
# Design has placable IOs
|
|
274
|
+
###########################
|
|
275
|
+
|
|
276
|
+
proc sc_design_has_placeable_ios { } {
|
|
277
|
+
foreach bterm [[ord::get_db_block] getBTerms] {
|
|
278
|
+
if {
|
|
279
|
+
[$bterm getFirstPinPlacementStatus] != "FIRM" &&
|
|
280
|
+
[$bterm getFirstPinPlacementStatus] != "LOCKED"
|
|
281
|
+
} {
|
|
282
|
+
return true
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
return false
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
###########################
|
|
289
|
+
# Check if net has placed bpins
|
|
290
|
+
###########################
|
|
291
|
+
|
|
292
|
+
proc sc_bterm_has_placed_io { net } {
|
|
293
|
+
set net [[ord::get_db_block] findNet $net]
|
|
294
|
+
|
|
295
|
+
foreach bterm [$net getBTerms] {
|
|
296
|
+
if { [$bterm getFirstPinPlacementStatus] != "UNPLACED" } {
|
|
297
|
+
return true
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
return false
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
###########################
|
|
304
|
+
# Find nets regex
|
|
305
|
+
###########################
|
|
306
|
+
|
|
307
|
+
proc sc_find_net_regex { net_name } {
|
|
308
|
+
set nets []
|
|
309
|
+
|
|
310
|
+
foreach net [[ord::get_db_block] getNets] {
|
|
311
|
+
if { [string match $net_name [$net getName]] } {
|
|
312
|
+
lappend nets [$net getName]
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
return $nets
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
###########################
|
|
320
|
+
# Get supply nets in design
|
|
321
|
+
###########################
|
|
322
|
+
|
|
323
|
+
proc sc_supply_nets { } {
|
|
324
|
+
set nets []
|
|
325
|
+
|
|
326
|
+
foreach net [[ord::get_db_block] getNets] {
|
|
327
|
+
set type [$net getSigType]
|
|
328
|
+
if { $type == "POWER" || $type == "GROUND" } {
|
|
329
|
+
lappend nets [$net getName]
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
return $nets
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
###########################
|
|
337
|
+
# Get nets for PSM to check
|
|
338
|
+
###########################
|
|
339
|
+
|
|
340
|
+
proc sc_psm_check_nets { } {
|
|
341
|
+
if { [lindex [sc_cfg_tool_task_get var psm_enable] 0] == "true" } {
|
|
342
|
+
set psm_nets []
|
|
343
|
+
|
|
344
|
+
foreach net [sc_supply_nets] {
|
|
345
|
+
set skipped false
|
|
346
|
+
foreach skip_pattern [sc_cfg_tool_task_get var psm_skip_nets] {
|
|
347
|
+
if { [string match $skip_pattern $net] } {
|
|
348
|
+
set skipped true
|
|
349
|
+
break
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
if { !$skipped } {
|
|
353
|
+
lappend psm_nets $net
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
return $psm_nets
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
return []
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
###########################
|
|
364
|
+
# Save an image
|
|
365
|
+
###########################
|
|
366
|
+
|
|
367
|
+
proc sc_save_image { title path { pixels 1000 } } {
|
|
368
|
+
utl::info FLW 1 "Saving \"$title\" to $path"
|
|
369
|
+
|
|
370
|
+
save_image -resolution [sc_image_resolution $pixels] \
|
|
371
|
+
-area [sc_image_area] \
|
|
372
|
+
$path
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
###########################
|
|
376
|
+
# Get the image bounding box
|
|
377
|
+
###########################
|
|
378
|
+
|
|
379
|
+
proc sc_image_area { } {
|
|
380
|
+
set box [[ord::get_db_block] getDieArea]
|
|
381
|
+
set width [$box dx]
|
|
382
|
+
set height [$box dy]
|
|
383
|
+
|
|
384
|
+
# apply 5% margin
|
|
385
|
+
set xmargin [expr { int(0.05 * $width) }]
|
|
386
|
+
set ymargin [expr { int(0.05 * $height) }]
|
|
387
|
+
|
|
388
|
+
set area []
|
|
389
|
+
lappend area [ord::dbu_to_microns [expr { [$box xMin] - $xmargin }]]
|
|
390
|
+
lappend area [ord::dbu_to_microns [expr { [$box yMin] - $ymargin }]]
|
|
391
|
+
lappend area [ord::dbu_to_microns [expr { [$box xMax] + $xmargin }]]
|
|
392
|
+
lappend area [ord::dbu_to_microns [expr { [$box yMax] + $ymargin }]]
|
|
393
|
+
return $area
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
###########################
|
|
397
|
+
# Get the image resolution (um / pixel)
|
|
398
|
+
###########################
|
|
399
|
+
|
|
400
|
+
proc sc_image_resolution { pixels } {
|
|
401
|
+
set box [[ord::get_db_block] getDieArea]
|
|
402
|
+
return [expr { [ord::dbu_to_microns [$box maxDXDY]] / $pixels }]
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
###########################
|
|
406
|
+
# Clear gui selections
|
|
407
|
+
###########################
|
|
408
|
+
|
|
409
|
+
proc sc_image_clear_selection { } {
|
|
410
|
+
gui::clear_highlights -1
|
|
411
|
+
gui::clear_selections
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
###########################
|
|
415
|
+
# Setup default GUI setting for images
|
|
416
|
+
###########################
|
|
417
|
+
|
|
418
|
+
proc sc_image_setup_default { } {
|
|
419
|
+
gui::restore_display_controls
|
|
420
|
+
|
|
421
|
+
sc_image_clear_selection
|
|
422
|
+
|
|
423
|
+
gui::fit
|
|
424
|
+
|
|
425
|
+
# Setup initial visibility to avoid any previous settings
|
|
426
|
+
gui::set_display_controls "*" visible false
|
|
427
|
+
gui::set_display_controls "Layers/*" visible true
|
|
428
|
+
gui::set_display_controls "Nets/*" visible true
|
|
429
|
+
gui::set_display_controls "Instances/*" visible true
|
|
430
|
+
gui::set_display_controls "Shape Types/*" visible true
|
|
431
|
+
gui::set_display_controls "Misc/Instances/*" visible true
|
|
432
|
+
gui::set_display_controls "Misc/Instances/Pin Names" visible false
|
|
433
|
+
gui::set_display_controls "Misc/Scale bar" visible true
|
|
434
|
+
gui::set_display_controls "Misc/Highlight selected" visible true
|
|
435
|
+
gui::set_display_controls "Misc/Detailed view" visible true
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
###########################
|
|
439
|
+
# Count the logic depth of the critical path
|
|
440
|
+
###########################
|
|
441
|
+
|
|
442
|
+
proc sc_count_logic_depth { } {
|
|
443
|
+
set count 0
|
|
444
|
+
set paths [find_timing_paths -sort_by_slack]
|
|
445
|
+
if { [llength $paths] == 0 } {
|
|
446
|
+
return 0
|
|
447
|
+
}
|
|
448
|
+
set path_ref [[lindex $paths 0] path]
|
|
449
|
+
set pins [$path_ref pins]
|
|
450
|
+
foreach pin $pins {
|
|
451
|
+
if { [$pin is_driver] } {
|
|
452
|
+
incr count
|
|
453
|
+
}
|
|
454
|
+
set vertex [lindex [$pin vertices] 0]
|
|
455
|
+
# Stop at clock vertex
|
|
456
|
+
if { [$vertex is_clock] } {
|
|
457
|
+
break
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
# Subtract 1 to account for initial launch
|
|
461
|
+
return [expr { $count - 1 }]
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
###########################
|
|
465
|
+
# Translate schema rotation
|
|
466
|
+
###########################
|
|
467
|
+
|
|
468
|
+
proc sc_convert_rotation { rot } {
|
|
469
|
+
if { [string match "MZ*" $rot] } {
|
|
470
|
+
utl::error FLW 1 "Z mirroring is not supported in OpenROAD"
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
switch $rot {
|
|
474
|
+
"R0" { return "R0" }
|
|
475
|
+
"R90" { return "R90" }
|
|
476
|
+
"R180" { return "R180" }
|
|
477
|
+
"R270" { return "R270" }
|
|
478
|
+
"MX" { return "MX" }
|
|
479
|
+
"MX_R90" { return "MXR90" }
|
|
480
|
+
"MX_R180" { return "MY" }
|
|
481
|
+
"MX_R270" { return "MYR90" }
|
|
482
|
+
"MY" { return "MY" }
|
|
483
|
+
"MY_R90" { return "MYR90" }
|
|
484
|
+
"MY_R180" { return "MX" }
|
|
485
|
+
"MY_R270" { return "MXR90" }
|
|
486
|
+
default { utl::error FLW 1 "$rot not recognized" }
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
proc sc_get_layer_name { name } {
|
|
491
|
+
if { [llength $name] > 1 } {
|
|
492
|
+
set layers []
|
|
493
|
+
foreach l $name {
|
|
494
|
+
lappend layers [sc_get_layer_name $l]
|
|
495
|
+
}
|
|
496
|
+
return $layers
|
|
497
|
+
}
|
|
498
|
+
if { [string length $name] == 0 } {
|
|
499
|
+
return ""
|
|
500
|
+
}
|
|
501
|
+
if { [string is integer $name] } {
|
|
502
|
+
set layer [[ord::get_db_tech] findRoutingLayer $name]
|
|
503
|
+
if { $layer == "NULL" } {
|
|
504
|
+
utl::error FLW 1 "$name is not a valid routing layer."
|
|
505
|
+
}
|
|
506
|
+
return [$layer getName]
|
|
507
|
+
}
|
|
508
|
+
return $name
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
proc sc_has_tie_cell { type } {
|
|
512
|
+
upvar sc_cfg sc_cfg
|
|
513
|
+
upvar sc_mainlib sc_mainlib
|
|
514
|
+
upvar sc_tool sc_tool
|
|
515
|
+
|
|
516
|
+
set library_vars [sc_cfg_get library $sc_mainlib option {var}]
|
|
517
|
+
return [expr {
|
|
518
|
+
[dict exists $library_vars openroad_tie${type}_cell] &&
|
|
519
|
+
[dict exists $library_vars openroad_tie${type}_port]
|
|
520
|
+
}]
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
proc sc_get_tie_cell { type } {
|
|
524
|
+
upvar sc_cfg sc_cfg
|
|
525
|
+
upvar sc_mainlib sc_mainlib
|
|
526
|
+
upvar sc_tool sc_tool
|
|
527
|
+
|
|
528
|
+
set cell [lindex [sc_cfg_get library $sc_mainlib option {var} openroad_tie${type}_cell] 0]
|
|
529
|
+
set port [lindex [sc_cfg_get library $sc_mainlib option {var} openroad_tie${type}_port] 0]
|
|
530
|
+
|
|
531
|
+
return "$cell/$port"
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
proc sc_get_input_files { type key } {
|
|
535
|
+
global sc_design
|
|
536
|
+
|
|
537
|
+
set input_file "inputs/${sc_design}.${type}"
|
|
538
|
+
if { [file exists $input_file] } {
|
|
539
|
+
return [list $input_file]
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
if { [sc_cfg_exists {*}$key] } {
|
|
543
|
+
return [sc_cfg_get {*}$key]
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
return []
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
proc sc_has_input_files { type key } {
|
|
550
|
+
return [expr { [sc_get_input_files $type $key] != [] }]
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
proc sc_setup_sta { } {
|
|
554
|
+
set sta_early_timing_derate [lindex [sc_cfg_tool_task_get var sta_early_timing_derate] 0]
|
|
555
|
+
set sta_late_timing_derate [lindex [sc_cfg_tool_task_get var sta_late_timing_derate] 0]
|
|
556
|
+
|
|
557
|
+
# Setup timing derating
|
|
558
|
+
if { $sta_early_timing_derate != 0.0 } {
|
|
559
|
+
set_timing_derate -early $sta_early_timing_derate
|
|
560
|
+
}
|
|
561
|
+
if { $sta_late_timing_derate != 0.0 } {
|
|
562
|
+
set_timing_derate -late $sta_late_timing_derate
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
# Check timing setup
|
|
566
|
+
if { [sc_cfg_tool_task_check_in_list check_setup var reports] } {
|
|
567
|
+
check_setup
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
if { [llength [all_clocks]] == 0 } {
|
|
571
|
+
utl::warn FLW 1 "No clocks defined."
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
proc sc_setup_global_routing { } {
|
|
576
|
+
global sc_tool
|
|
577
|
+
global sc_stackup
|
|
578
|
+
global sc_pdk
|
|
579
|
+
|
|
580
|
+
## Setup global routing
|
|
581
|
+
|
|
582
|
+
# Adjust routing track density
|
|
583
|
+
foreach layer [[ord::get_db_tech] getLayers] {
|
|
584
|
+
if { [$layer getRoutingLevel] == 0 } {
|
|
585
|
+
continue
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
set layername [$layer getName]
|
|
589
|
+
if { ![sc_cfg_exists pdk $sc_pdk {var} $sc_tool "${layername}_adjustment" $sc_stackup] } {
|
|
590
|
+
utl::warn FLW 1 "Missing global routing adjustment for ${layername}"
|
|
591
|
+
} else {
|
|
592
|
+
set adjustment [lindex \
|
|
593
|
+
[sc_cfg_get pdk $sc_pdk {var} $sc_tool "${layername}_adjustment" $sc_stackup] 0]
|
|
594
|
+
utl::info FLW 1 \
|
|
595
|
+
"Setting global routing adjustment for $layername to [expr { $adjustment * 100 }]%"
|
|
596
|
+
set_global_routing_layer_adjustment $layername $adjustment
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
if {
|
|
601
|
+
[sc_cfg_tool_task_exists var grt_setup] &&
|
|
602
|
+
[lindex [sc_cfg_tool_task_get var grt_setup] 0] == "true"
|
|
603
|
+
} {
|
|
604
|
+
set grt_macro_extension [lindex [sc_cfg_tool_task_get var grt_macro_extension] 0]
|
|
605
|
+
if { $grt_macro_extension > 0 } {
|
|
606
|
+
utl::info FLW 1 "Setting global routing macro extension to $grt_macro_extension gcells"
|
|
607
|
+
set_macro_extension $grt_macro_extension
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
set openroad_grt_signal_min_layer [lindex [sc_cfg_tool_task_get var grt_signal_min_layer] 0]
|
|
611
|
+
set openroad_grt_signal_max_layer [lindex [sc_cfg_tool_task_get var grt_signal_max_layer] 0]
|
|
612
|
+
set openroad_grt_clock_min_layer [lindex [sc_cfg_tool_task_get var grt_clock_min_layer] 0]
|
|
613
|
+
set openroad_grt_clock_max_layer [lindex [sc_cfg_tool_task_get var grt_clock_max_layer] 0]
|
|
614
|
+
|
|
615
|
+
set openroad_grt_signal_min_layer [sc_get_layer_name $openroad_grt_signal_min_layer]
|
|
616
|
+
set openroad_grt_signal_max_layer [sc_get_layer_name $openroad_grt_signal_max_layer]
|
|
617
|
+
set openroad_grt_clock_min_layer [sc_get_layer_name $openroad_grt_clock_min_layer]
|
|
618
|
+
set openroad_grt_clock_max_layer [sc_get_layer_name $openroad_grt_clock_max_layer]
|
|
619
|
+
|
|
620
|
+
utl::info FLW 1 "Setting global routing signal routing layers to:\
|
|
621
|
+
${openroad_grt_signal_min_layer}-${openroad_grt_signal_max_layer}"
|
|
622
|
+
set_routing_layers -signal \
|
|
623
|
+
"${openroad_grt_signal_min_layer}-${openroad_grt_signal_max_layer}"
|
|
624
|
+
utl::info FLW 1 "Setting global routing clock routing layers to:\
|
|
625
|
+
${openroad_grt_signal_min_layer}-${openroad_grt_signal_max_layer}"
|
|
626
|
+
set_routing_layers -clock \
|
|
627
|
+
"${openroad_grt_clock_min_layer}-${openroad_grt_clock_max_layer}"
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
proc sc_setup_parasitics { } {
|
|
632
|
+
global sc_tool
|
|
633
|
+
global sc_pdk
|
|
634
|
+
global sc_stackup
|
|
635
|
+
|
|
636
|
+
set sc_rc_signal [lindex [sc_cfg_get pdk $sc_pdk {var} $sc_tool rclayer_signal $sc_stackup] 0]
|
|
637
|
+
set sc_rc_signal [sc_get_layer_name $sc_rc_signal]
|
|
638
|
+
|
|
639
|
+
set sc_rc_clk [lindex [sc_cfg_get pdk $sc_pdk {var} $sc_tool rclayer_clock $sc_stackup] 0]
|
|
640
|
+
set sc_rc_clk [sc_get_layer_name $sc_rc_clk]
|
|
641
|
+
|
|
642
|
+
set sc_parasitics [lindex [sc_cfg_tool_task_get {file} parasitics] 0]
|
|
643
|
+
source $sc_parasitics
|
|
644
|
+
|
|
645
|
+
set_wire_rc -clock -layer $sc_rc_clk
|
|
646
|
+
set_wire_rc -signal -layer $sc_rc_signal
|
|
647
|
+
utl::info FLW 1 "Using $sc_rc_clk for clock parasitics estimation"
|
|
648
|
+
utl::info FLW 1 "Using $sc_rc_signal for signal parasitics estimation"
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
proc sc_insert_fillers { } {
|
|
652
|
+
global sc_mainlib
|
|
653
|
+
|
|
654
|
+
set fillers [sc_cfg_get library $sc_mainlib asic cells filler]
|
|
655
|
+
|
|
656
|
+
if { [lindex [sc_cfg_tool_task_get var dpl_use_decap_fillers] 0] == "true" } {
|
|
657
|
+
lappend fillers {*}[sc_cfg_get library $sc_mainlib asic cells decap]
|
|
658
|
+
}
|
|
659
|
+
if { $fillers != "" } {
|
|
660
|
+
filler_placement $fillers
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
check_placement -verbose
|
|
664
|
+
|
|
665
|
+
global_connect
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
proc sc_check_version { min_required } {
|
|
669
|
+
set version [split [ord::openroad_version] "-"]
|
|
670
|
+
if { [lindex $version 0] != "v2.0" } {
|
|
671
|
+
return false
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
return [expr { [lindex $version 1] >= $min_required }]
|
|
675
|
+
}
|