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.
Files changed (122) hide show
  1. siliconcompiler/_metadata.py +1 -1
  2. siliconcompiler/apps/sc_remote.py +15 -14
  3. siliconcompiler/apps/sc_show.py +5 -5
  4. siliconcompiler/apps/utils/replay.py +136 -0
  5. siliconcompiler/core.py +14 -12
  6. siliconcompiler/flows/_common.py +11 -13
  7. siliconcompiler/flows/asicflow.py +83 -42
  8. siliconcompiler/remote/__init__.py +11 -0
  9. siliconcompiler/remote/client.py +753 -815
  10. siliconcompiler/report/report.py +2 -0
  11. siliconcompiler/report/summary_table.py +1 -1
  12. siliconcompiler/scheduler/__init__.py +51 -9
  13. siliconcompiler/scheduler/send_messages.py +37 -33
  14. siliconcompiler/scheduler/validation/email_credentials.json +7 -0
  15. siliconcompiler/schema/schema_cfg.py +15 -3
  16. siliconcompiler/schema/schema_obj.py +16 -0
  17. siliconcompiler/sphinx_ext/dynamicgen.py +4 -3
  18. siliconcompiler/targets/fpgaflow_demo.py +6 -7
  19. siliconcompiler/targets/gf180_demo.py +3 -3
  20. siliconcompiler/templates/replay/requirements.txt +6 -0
  21. siliconcompiler/templates/replay/run.py.j2 +22 -0
  22. siliconcompiler/templates/replay/setup.sh +17 -0
  23. siliconcompiler/tools/_common/__init__.py +17 -3
  24. siliconcompiler/tools/_common/asic.py +10 -3
  25. siliconcompiler/tools/builtin/concatenate.py +1 -1
  26. siliconcompiler/tools/openroad/__init__.py +103 -0
  27. siliconcompiler/tools/openroad/{openroad.py → _apr.py} +413 -422
  28. siliconcompiler/tools/openroad/antenna_repair.py +78 -0
  29. siliconcompiler/tools/openroad/clock_tree_synthesis.py +64 -0
  30. siliconcompiler/tools/openroad/detailed_placement.py +59 -0
  31. siliconcompiler/tools/openroad/detailed_route.py +62 -0
  32. siliconcompiler/tools/openroad/endcap_tapcell_insertion.py +52 -0
  33. siliconcompiler/tools/openroad/fillercell_insertion.py +58 -0
  34. siliconcompiler/tools/openroad/{dfm.py → fillmetal_insertion.py} +35 -19
  35. siliconcompiler/tools/openroad/global_placement.py +58 -0
  36. siliconcompiler/tools/openroad/global_route.py +63 -0
  37. siliconcompiler/tools/openroad/init_floorplan.py +103 -0
  38. siliconcompiler/tools/openroad/macro_placement.py +65 -0
  39. siliconcompiler/tools/openroad/metrics.py +23 -8
  40. siliconcompiler/tools/openroad/pin_placement.py +56 -0
  41. siliconcompiler/tools/openroad/power_grid.py +65 -0
  42. siliconcompiler/tools/openroad/rcx_bench.py +7 -4
  43. siliconcompiler/tools/openroad/rcx_extract.py +2 -1
  44. siliconcompiler/tools/openroad/rdlroute.py +4 -4
  45. siliconcompiler/tools/openroad/repair_design.py +59 -0
  46. siliconcompiler/tools/openroad/repair_timing.py +63 -0
  47. siliconcompiler/tools/openroad/screenshot.py +9 -20
  48. siliconcompiler/tools/openroad/scripts/apr/postamble.tcl +44 -0
  49. siliconcompiler/tools/openroad/scripts/apr/preamble.tcl +95 -0
  50. siliconcompiler/tools/openroad/scripts/apr/sc_antenna_repair.tcl +51 -0
  51. siliconcompiler/tools/openroad/scripts/apr/sc_clock_tree_synthesis.tcl +62 -0
  52. siliconcompiler/tools/openroad/scripts/apr/sc_detailed_placement.tcl +41 -0
  53. siliconcompiler/tools/openroad/scripts/apr/sc_detailed_route.tcl +71 -0
  54. siliconcompiler/tools/openroad/scripts/apr/sc_endcap_tapcell_insertion.tcl +55 -0
  55. siliconcompiler/tools/openroad/scripts/apr/sc_fillercell_insertion.tcl +27 -0
  56. siliconcompiler/tools/openroad/scripts/apr/sc_fillmetal_insertion.tcl +36 -0
  57. siliconcompiler/tools/openroad/scripts/apr/sc_global_placement.tcl +26 -0
  58. siliconcompiler/tools/openroad/scripts/apr/sc_global_route.tcl +61 -0
  59. siliconcompiler/tools/openroad/scripts/apr/sc_init_floorplan.tcl +333 -0
  60. siliconcompiler/tools/openroad/scripts/apr/sc_macro_placement.tcl +123 -0
  61. siliconcompiler/tools/openroad/scripts/apr/sc_metrics.tcl +22 -0
  62. siliconcompiler/tools/openroad/scripts/apr/sc_pin_placement.tcl +41 -0
  63. siliconcompiler/tools/openroad/scripts/apr/sc_power_grid.tcl +60 -0
  64. siliconcompiler/tools/openroad/scripts/apr/sc_repair_design.tcl +68 -0
  65. siliconcompiler/tools/openroad/scripts/apr/sc_repair_timing.tcl +83 -0
  66. siliconcompiler/tools/openroad/scripts/apr/sc_write_data.tcl +125 -0
  67. siliconcompiler/tools/openroad/scripts/common/debugging.tcl +28 -0
  68. siliconcompiler/tools/openroad/scripts/common/procs.tcl +675 -0
  69. siliconcompiler/tools/openroad/scripts/common/read_input_files.tcl +59 -0
  70. siliconcompiler/tools/openroad/scripts/common/read_liberty.tcl +20 -0
  71. siliconcompiler/tools/openroad/scripts/common/read_timing_constraints.tcl +16 -0
  72. siliconcompiler/tools/openroad/scripts/common/reports.tcl +180 -0
  73. siliconcompiler/tools/openroad/scripts/common/screenshot.tcl +18 -0
  74. siliconcompiler/tools/openroad/scripts/common/write_images.tcl +395 -0
  75. siliconcompiler/tools/openroad/scripts/{sc_rcx_bench.tcl → rcx/sc_rcx_bench.tcl} +5 -5
  76. siliconcompiler/tools/openroad/scripts/{sc_rcx_extract.tcl → rcx/sc_rcx_extract.tcl} +0 -0
  77. siliconcompiler/tools/openroad/scripts/sc_rcx.tcl +5 -16
  78. siliconcompiler/tools/openroad/scripts/sc_rdlroute.tcl +51 -51
  79. siliconcompiler/tools/openroad/scripts/sc_show.tcl +105 -0
  80. siliconcompiler/tools/openroad/show.py +28 -23
  81. siliconcompiler/tools/openroad/{export.py → write_data.py} +31 -26
  82. siliconcompiler/tools/opensta/__init__.py +1 -1
  83. siliconcompiler/tools/vivado/bitstream.py +8 -2
  84. siliconcompiler/tools/vivado/place.py +6 -2
  85. siliconcompiler/tools/vivado/route.py +6 -2
  86. siliconcompiler/tools/vivado/scripts/sc_bitstream.tcl +1 -1
  87. siliconcompiler/tools/vivado/scripts/sc_place.tcl +1 -1
  88. siliconcompiler/tools/vivado/scripts/sc_route.tcl +1 -1
  89. siliconcompiler/tools/vivado/scripts/sc_run.tcl +4 -2
  90. siliconcompiler/tools/vivado/syn_fpga.py +5 -1
  91. siliconcompiler/tools/vivado/vivado.py +26 -10
  92. siliconcompiler/tools/vpr/vpr.py +5 -0
  93. siliconcompiler/tools/yosys/syn_asic.py +7 -0
  94. siliconcompiler/tools/yosys/syn_asic.tcl +27 -6
  95. siliconcompiler/tools/yosys/syn_fpga.tcl +26 -18
  96. siliconcompiler/toolscripts/_tools.json +5 -5
  97. {siliconcompiler-0.28.8.dist-info → siliconcompiler-0.29.0.dist-info}/METADATA +50 -48
  98. {siliconcompiler-0.28.8.dist-info → siliconcompiler-0.29.0.dist-info}/RECORD +103 -76
  99. {siliconcompiler-0.28.8.dist-info → siliconcompiler-0.29.0.dist-info}/WHEEL +1 -1
  100. siliconcompiler/tools/openroad/cts.py +0 -45
  101. siliconcompiler/tools/openroad/floorplan.py +0 -75
  102. siliconcompiler/tools/openroad/physyn.py +0 -27
  103. siliconcompiler/tools/openroad/place.py +0 -41
  104. siliconcompiler/tools/openroad/route.py +0 -45
  105. siliconcompiler/tools/openroad/scripts/__init__.py +0 -0
  106. siliconcompiler/tools/openroad/scripts/sc_apr.tcl +0 -514
  107. siliconcompiler/tools/openroad/scripts/sc_cts.tcl +0 -68
  108. siliconcompiler/tools/openroad/scripts/sc_dfm.tcl +0 -22
  109. siliconcompiler/tools/openroad/scripts/sc_export.tcl +0 -100
  110. siliconcompiler/tools/openroad/scripts/sc_floorplan.tcl +0 -456
  111. siliconcompiler/tools/openroad/scripts/sc_metrics.tcl +0 -1
  112. siliconcompiler/tools/openroad/scripts/sc_physyn.tcl +0 -6
  113. siliconcompiler/tools/openroad/scripts/sc_place.tcl +0 -84
  114. siliconcompiler/tools/openroad/scripts/sc_procs.tcl +0 -494
  115. siliconcompiler/tools/openroad/scripts/sc_report.tcl +0 -189
  116. siliconcompiler/tools/openroad/scripts/sc_route.tcl +0 -143
  117. siliconcompiler/tools/openroad/scripts/sc_screenshot.tcl +0 -18
  118. siliconcompiler/tools/openroad/scripts/sc_write_images.tcl +0 -393
  119. /siliconcompiler/tools/openroad/scripts/{sc_write.tcl → common/write_data.tcl} +0 -0
  120. {siliconcompiler-0.28.8.dist-info → siliconcompiler-0.29.0.dist-info}/LICENSE +0 -0
  121. {siliconcompiler-0.28.8.dist-info → siliconcompiler-0.29.0.dist-info}/entry_points.txt +0 -0
  122. {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
+ }