librelane 2.4.0.dev0__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.

Files changed (166) hide show
  1. librelane/__init__.py +38 -0
  2. librelane/__main__.py +470 -0
  3. librelane/__version__.py +43 -0
  4. librelane/common/__init__.py +61 -0
  5. librelane/common/cli.py +75 -0
  6. librelane/common/drc.py +245 -0
  7. librelane/common/generic_dict.py +319 -0
  8. librelane/common/metrics/__init__.py +35 -0
  9. librelane/common/metrics/__main__.py +413 -0
  10. librelane/common/metrics/library.py +354 -0
  11. librelane/common/metrics/metric.py +186 -0
  12. librelane/common/metrics/util.py +279 -0
  13. librelane/common/misc.py +402 -0
  14. librelane/common/ring_buffer.py +63 -0
  15. librelane/common/tcl.py +80 -0
  16. librelane/common/toolbox.py +549 -0
  17. librelane/common/tpe.py +41 -0
  18. librelane/common/types.py +117 -0
  19. librelane/config/__init__.py +32 -0
  20. librelane/config/__main__.py +158 -0
  21. librelane/config/config.py +1025 -0
  22. librelane/config/flow.py +490 -0
  23. librelane/config/pdk_compat.py +255 -0
  24. librelane/config/preprocessor.py +464 -0
  25. librelane/config/removals.py +45 -0
  26. librelane/config/variable.py +722 -0
  27. librelane/container.py +264 -0
  28. librelane/env_info.py +306 -0
  29. librelane/examples/spm/config.yaml +33 -0
  30. librelane/examples/spm/pin_order.cfg +14 -0
  31. librelane/examples/spm/src/impl.sdc +73 -0
  32. librelane/examples/spm/src/signoff.sdc +68 -0
  33. librelane/examples/spm/src/spm.v +73 -0
  34. librelane/examples/spm/verify/spm_tb.v +106 -0
  35. librelane/examples/spm-user_project_wrapper/SPM_example.v +286 -0
  36. librelane/examples/spm-user_project_wrapper/base_sdc_file.sdc +145 -0
  37. librelane/examples/spm-user_project_wrapper/config-tut.json +12 -0
  38. librelane/examples/spm-user_project_wrapper/config.json +13 -0
  39. librelane/examples/spm-user_project_wrapper/defines.v +66 -0
  40. librelane/examples/spm-user_project_wrapper/template.def +7656 -0
  41. librelane/examples/spm-user_project_wrapper/user_project_wrapper.v +123 -0
  42. librelane/flows/__init__.py +24 -0
  43. librelane/flows/builtins.py +18 -0
  44. librelane/flows/classic.py +330 -0
  45. librelane/flows/cli.py +463 -0
  46. librelane/flows/flow.py +985 -0
  47. librelane/flows/misc.py +71 -0
  48. librelane/flows/optimizing.py +179 -0
  49. librelane/flows/sequential.py +367 -0
  50. librelane/flows/synth_explore.py +173 -0
  51. librelane/logging/__init__.py +40 -0
  52. librelane/logging/logger.py +323 -0
  53. librelane/open_pdks_rev +1 -0
  54. librelane/plugins.py +21 -0
  55. librelane/py.typed +0 -0
  56. librelane/scripts/base.sdc +80 -0
  57. librelane/scripts/klayout/Readme.md +2 -0
  58. librelane/scripts/klayout/open_design.py +63 -0
  59. librelane/scripts/klayout/render.py +121 -0
  60. librelane/scripts/klayout/stream_out.py +176 -0
  61. librelane/scripts/klayout/xml_drc_report_to_json.py +45 -0
  62. librelane/scripts/klayout/xor.drc +120 -0
  63. librelane/scripts/magic/Readme.md +1 -0
  64. librelane/scripts/magic/common/read.tcl +114 -0
  65. librelane/scripts/magic/def/antenna_check.tcl +35 -0
  66. librelane/scripts/magic/def/mag.tcl +19 -0
  67. librelane/scripts/magic/def/mag_gds.tcl +81 -0
  68. librelane/scripts/magic/drc.tcl +79 -0
  69. librelane/scripts/magic/extract_spice.tcl +98 -0
  70. librelane/scripts/magic/gds/drc_batch.tcl +74 -0
  71. librelane/scripts/magic/gds/erase_box.tcl +32 -0
  72. librelane/scripts/magic/gds/extras_mag.tcl +47 -0
  73. librelane/scripts/magic/gds/mag_with_pointers.tcl +32 -0
  74. librelane/scripts/magic/get_bbox.tcl +11 -0
  75. librelane/scripts/magic/lef/extras_maglef.tcl +63 -0
  76. librelane/scripts/magic/lef/maglef.tcl +27 -0
  77. librelane/scripts/magic/lef.tcl +57 -0
  78. librelane/scripts/magic/open.tcl +28 -0
  79. librelane/scripts/magic/wrapper.tcl +19 -0
  80. librelane/scripts/netgen/setup.tcl +28 -0
  81. librelane/scripts/odbpy/apply_def_template.py +49 -0
  82. librelane/scripts/odbpy/cell_frequency.py +107 -0
  83. librelane/scripts/odbpy/check_antenna_properties.py +116 -0
  84. librelane/scripts/odbpy/contextualize.py +109 -0
  85. librelane/scripts/odbpy/defutil.py +574 -0
  86. librelane/scripts/odbpy/diodes.py +373 -0
  87. librelane/scripts/odbpy/disconnected_pins.py +305 -0
  88. librelane/scripts/odbpy/exception_codes.py +17 -0
  89. librelane/scripts/odbpy/filter_unannotated.py +100 -0
  90. librelane/scripts/odbpy/io_place.py +482 -0
  91. librelane/scripts/odbpy/label_macro_pins.py +277 -0
  92. librelane/scripts/odbpy/lefutil.py +97 -0
  93. librelane/scripts/odbpy/placers.py +162 -0
  94. librelane/scripts/odbpy/power_utils.py +395 -0
  95. librelane/scripts/odbpy/random_place.py +57 -0
  96. librelane/scripts/odbpy/reader.py +246 -0
  97. librelane/scripts/odbpy/remove_buffers.py +173 -0
  98. librelane/scripts/odbpy/snap_to_grid.py +57 -0
  99. librelane/scripts/odbpy/wire_lengths.py +93 -0
  100. librelane/scripts/openroad/antenna_check.tcl +20 -0
  101. librelane/scripts/openroad/antenna_repair.tcl +31 -0
  102. librelane/scripts/openroad/basic_mp.tcl +24 -0
  103. librelane/scripts/openroad/buffer_list.tcl +10 -0
  104. librelane/scripts/openroad/common/dpl.tcl +24 -0
  105. librelane/scripts/openroad/common/dpl_cell_pad.tcl +26 -0
  106. librelane/scripts/openroad/common/grt.tcl +32 -0
  107. librelane/scripts/openroad/common/io.tcl +476 -0
  108. librelane/scripts/openroad/common/pdn_cfg.tcl +135 -0
  109. librelane/scripts/openroad/common/resizer.tcl +103 -0
  110. librelane/scripts/openroad/common/set_global_connections.tcl +78 -0
  111. librelane/scripts/openroad/common/set_layer_adjustments.tcl +31 -0
  112. librelane/scripts/openroad/common/set_power_nets.tcl +30 -0
  113. librelane/scripts/openroad/common/set_rc.tcl +75 -0
  114. librelane/scripts/openroad/common/set_routing_layers.tcl +30 -0
  115. librelane/scripts/openroad/cts.tcl +80 -0
  116. librelane/scripts/openroad/cut_rows.tcl +24 -0
  117. librelane/scripts/openroad/dpl.tcl +24 -0
  118. librelane/scripts/openroad/drt.tcl +37 -0
  119. librelane/scripts/openroad/fill.tcl +30 -0
  120. librelane/scripts/openroad/floorplan.tcl +145 -0
  121. librelane/scripts/openroad/gpl.tcl +88 -0
  122. librelane/scripts/openroad/grt.tcl +30 -0
  123. librelane/scripts/openroad/gui.tcl +15 -0
  124. librelane/scripts/openroad/insert_buffer.tcl +127 -0
  125. librelane/scripts/openroad/ioplacer.tcl +67 -0
  126. librelane/scripts/openroad/irdrop.tcl +51 -0
  127. librelane/scripts/openroad/pdn.tcl +52 -0
  128. librelane/scripts/openroad/rcx.tcl +32 -0
  129. librelane/scripts/openroad/repair_design.tcl +70 -0
  130. librelane/scripts/openroad/repair_design_postgrt.tcl +48 -0
  131. librelane/scripts/openroad/rsz_timing_postcts.tcl +68 -0
  132. librelane/scripts/openroad/rsz_timing_postgrt.tcl +70 -0
  133. librelane/scripts/openroad/sta/check_macro_instances.tcl +53 -0
  134. librelane/scripts/openroad/sta/corner.tcl +393 -0
  135. librelane/scripts/openroad/tapcell.tcl +25 -0
  136. librelane/scripts/openroad/write_views.tcl +27 -0
  137. librelane/scripts/pyosys/construct_abc_script.py +177 -0
  138. librelane/scripts/pyosys/json_header.py +84 -0
  139. librelane/scripts/pyosys/synthesize.py +493 -0
  140. librelane/scripts/pyosys/ys_common.py +153 -0
  141. librelane/scripts/tclsh/hello.tcl +1 -0
  142. librelane/state/__init__.py +24 -0
  143. librelane/state/__main__.py +61 -0
  144. librelane/state/design_format.py +180 -0
  145. librelane/state/state.py +351 -0
  146. librelane/steps/__init__.py +61 -0
  147. librelane/steps/__main__.py +511 -0
  148. librelane/steps/checker.py +637 -0
  149. librelane/steps/common_variables.py +340 -0
  150. librelane/steps/cvc_rv.py +169 -0
  151. librelane/steps/klayout.py +509 -0
  152. librelane/steps/magic.py +566 -0
  153. librelane/steps/misc.py +160 -0
  154. librelane/steps/netgen.py +253 -0
  155. librelane/steps/odb.py +955 -0
  156. librelane/steps/openroad.py +2433 -0
  157. librelane/steps/openroad_alerts.py +102 -0
  158. librelane/steps/pyosys.py +629 -0
  159. librelane/steps/step.py +1547 -0
  160. librelane/steps/tclstep.py +288 -0
  161. librelane/steps/verilator.py +222 -0
  162. librelane/steps/yosys.py +371 -0
  163. librelane-2.4.0.dev0.dist-info/METADATA +151 -0
  164. librelane-2.4.0.dev0.dist-info/RECORD +166 -0
  165. librelane-2.4.0.dev0.dist-info/WHEEL +4 -0
  166. librelane-2.4.0.dev0.dist-info/entry_points.txt +8 -0
@@ -0,0 +1,476 @@
1
+ # Copyright 2022-2024 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(_TCL_ENV_IN)
15
+ source $::env(SCRIPTS_DIR)/openroad/common/set_global_connections.tcl
16
+
17
+ proc string_in_file {file_path substring} {
18
+ set f [open $file_path r]
19
+ set data [read $f]
20
+ close $f
21
+
22
+ if { [string first $substring $data] != -1} {
23
+ return 1
24
+ }
25
+ return 0
26
+ }
27
+
28
+ proc env_var_used {file var} {
29
+ return [string_in_file $file "\$::env($var)"]
30
+ }
31
+
32
+ proc set_global_vars {} {
33
+ if { [namespace exists ::ord] } {
34
+ set ::db [::ord::get_db]
35
+ set ::chip [$::db getChip]
36
+ set ::tech [$::db getTech]
37
+ set ::block [$::chip getBlock]
38
+ set ::dbu [$::tech getDbUnitsPerMicron]
39
+ set ::libs [$::db getLibs]
40
+ }
41
+ }
42
+
43
+ proc read_current_sdc {} {
44
+ if { ![info exists ::env(_SDC_IN)]} {
45
+ puts "\[INFO\] _SDC_IN not found. Not reading an SDC file."
46
+ return
47
+ }
48
+
49
+ # Compatibility Layer for Deprecated Variables That May Still Be Used By
50
+ # User Files
51
+ set ::env(IO_PCT) [expr $::env(IO_DELAY_CONSTRAINT) / 100]
52
+ set ::env(SYNTH_TIMING_DERATE) [expr $::env(TIME_DERATING_CONSTRAINT) / 100]
53
+ set ::env(SYNTH_MAX_FANOUT) $::env(MAX_FANOUT_CONSTRAINT)
54
+ set ::env(SYNTH_CLOCK_UNCERTAINTY) $::env(CLOCK_UNCERTAINTY_CONSTRAINT)
55
+ set ::env(SYNTH_CLOCK_TRANSITION) $::env(CLOCK_TRANSITION_CONSTRAINT)
56
+ set ::env(SYNTH_CAP_LOAD) $::env(OUTPUT_CAP_LOAD)
57
+ if { [info exists ::env(MAX_TRANSITION_CONSTRAINT)] } {
58
+ set ::env(SYNTH_MAX_TRAN) $::env(MAX_TRANSITION_CONSTRAINT)
59
+ }
60
+ if { [env_var_used $::env(_SDC_IN) SYNTH_DRIVING_CELL_PIN] == 1 } {
61
+ set synth_driving_cell_bk $::env(SYNTH_DRIVING_CELL)
62
+ set ::env(SYNTH_DRIVING_CELL_PIN) [lindex [split $::env(SYNTH_DRIVING_CELL) "/"] 1]
63
+ set ::env(SYNTH_DRIVING_CELL) [lindex [split $::env(SYNTH_DRIVING_CELL) "/"] 0]
64
+ }
65
+
66
+ puts "Reading design constraints file at '$::env(_SDC_IN)'…"
67
+ if {[catch {read_sdc $::env(_SDC_IN)} errmsg]} {
68
+ puts stderr $errmsg
69
+ exit 1
70
+ }
71
+
72
+ if { ![string_in_file $::env(_SDC_IN) "set_propagated_clock"] && ![string_in_file $::env(_SDC_IN) "unset_propagated_clock"] } {
73
+ if { [info exists ::env(OPENLANE_SDC_IDEAL_CLOCKS)] && $::env(OPENLANE_SDC_IDEAL_CLOCKS) } {
74
+ puts "\[INFO\] No information on clock propagation in input SDC file-- unpropagating all clocks."
75
+ unset_propagated_clock [all_clocks]
76
+ } else {
77
+ puts "\[INFO\] No information on clock propagation in input SDC file-- propagating all clocks."
78
+ set_propagated_clock [all_clocks]
79
+ }
80
+ }
81
+
82
+ # Restore Environment
83
+ unset ::env(IO_PCT)
84
+ unset ::env(SYNTH_TIMING_DERATE)
85
+ unset ::env(SYNTH_MAX_FANOUT)
86
+ unset ::env(SYNTH_CLOCK_UNCERTAINTY)
87
+ unset ::env(SYNTH_CLOCK_TRANSITION)
88
+ unset ::env(SYNTH_CAP_LOAD)
89
+ if { [info exists ::env(SYNTH_MAX_TRAN)] } {
90
+ unset ::env(SYNTH_MAX_TRAN)
91
+ }
92
+ if { [info exists ::env(SYNTH_DRIVING_CELL_PIN)] } {
93
+ unset ::env(SYNTH_DRIVING_CELL_PIN)
94
+ set ::env(SYNTH_DRIVING_CELL) $synth_driving_cell_bk
95
+ }
96
+ }
97
+
98
+ proc read_pdn_cfg {} {
99
+
100
+ # Compatibility Layer for Deprecated Variables That May Still Be Used By
101
+ # User Files
102
+ set ::env(DESIGN_IS_CORE) $::env(FP_PDN_MULTILAYER)
103
+ set ::env(FP_PDN_ENABLE_MACROS_GRID) $::env(PDN_CONNECT_MACROS_TO_GRID)
104
+ set ::env(FP_PDN_RAILS_LAYER) $::env(FP_PDN_RAIL_LAYER)
105
+ set ::env(FP_PDN_UPPER_LAYER) $::env(FP_PDN_HORIZONTAL_LAYER)
106
+ set ::env(FP_PDN_LOWER_LAYER) $::env(FP_PDN_VERTICAL_LAYER)
107
+
108
+ if {[catch {source $::env(FP_PDN_CFG)} errmsg]} {
109
+ puts stderr $errmsg
110
+ exit 1
111
+ }
112
+
113
+ # Restore Environment
114
+ unset ::env(DESIGN_IS_CORE)
115
+ unset ::env(FP_PDN_ENABLE_MACROS_GRID)
116
+ unset ::env(FP_PDN_RAILS_LAYER)
117
+ unset ::env(FP_PDN_UPPER_LAYER)
118
+ unset ::env(FP_PDN_LOWER_LAYER)
119
+ }
120
+
121
+
122
+ proc read_current_netlist {args} {
123
+ sta::parse_key_args "read_current_netlist" args \
124
+ keys {}\
125
+ flags {-powered}
126
+
127
+ if { [info exists flags(-powered)] } {
128
+ puts "Reading top-level powered netlist at '$::env(CURRENT_POWERED_NETLIST)'…"
129
+ if {[catch {read_verilog $::env(CURRENT_POWERED_NETLIST)} errmsg]} {
130
+ puts stderr $errmsg
131
+ exit 1
132
+ }
133
+ } else {
134
+ puts "Reading top-level netlist at '$::env(CURRENT_NETLIST)'…"
135
+ if {[catch {read_verilog $::env(CURRENT_NETLIST)} errmsg]} {
136
+ puts stderr $errmsg
137
+ exit 1
138
+ }
139
+ }
140
+
141
+ puts "Linking design '$::env(DESIGN_NAME)' from netlist…"
142
+ link_design $::env(DESIGN_NAME)
143
+ set_global_vars
144
+ read_current_sdc
145
+ }
146
+
147
+ proc read_timing_info {args} {
148
+ sta::parse_key_args "read_timing_info" args \
149
+ keys {}\
150
+ flags {-powered}
151
+
152
+ if { ![info exists ::env(_CURRENT_CORNER_NAME)] } {
153
+ return
154
+ }
155
+ set corner_name $::env(_CURRENT_CORNER_NAME)
156
+ define_corners $corner_name
157
+
158
+ puts "Reading timing models for corner $corner_name…"
159
+
160
+ foreach lib $::env(_CURRENT_CORNER_LIBS) {
161
+ puts "Reading cell library for the '$corner_name' corner at '$lib'…"
162
+ read_liberty -corner $corner_name $lib
163
+ }
164
+
165
+ if { [info exists ::env(EXTRA_LIBS) ] } {
166
+ puts "Reading explicitly-specified extra libs for $corner_name…"
167
+ foreach extra_lib $::env(EXTRA_LIBS) {
168
+ puts "Reading extra timing library for the '$corner_name' corner at '$extra_lib'…"
169
+ read_liberty -corner $corner_name $extra_lib
170
+ }
171
+ }
172
+
173
+ set blackbox_wildcard {/// sta-blackbox}
174
+ foreach nl $::env(_CURRENT_CORNER_NETLISTS) {
175
+ puts "Reading macro netlist at '$nl'…"
176
+ if { [catch {read_verilog $nl} err] } {
177
+ puts "Error while reading macro netlist '$nl':"
178
+ puts $err
179
+ puts "Make sure that this a gate-level netlist and not an RTL file."
180
+ exit 1
181
+ }
182
+ }
183
+ if { [info exists ::env(EXTRA_VERILOG_MODELS)] } {
184
+ foreach verilog_file $::env(EXTRA_VERILOG_MODELS) {
185
+ if { [string_in_file $verilog_file $blackbox_wildcard] } {
186
+ puts "Found '$blackbox_wildcard' in '$verilog_file', skipping…"
187
+ } elseif { [catch {puts "Reading Verilog model at '$verilog_file'…"; read_verilog $verilog_file} err] } {
188
+ puts "Error while reading $verilog_file:"
189
+ puts $err
190
+ puts "Make sure that this a gate-level netlist and not an RTL file, otherwise, you can add the following comment '$blackbox_wildcard' in the file to skip it and blackbox the modules inside if needed."
191
+ exit 1
192
+ }
193
+ }
194
+ }
195
+ if { [info exists flags(-powered)] } {
196
+ read_current_netlist -powered
197
+ } else {
198
+ read_current_netlist
199
+ }
200
+ }
201
+
202
+ proc lshift {inputlist} {
203
+ upvar $inputlist argv
204
+ set arg [lindex $argv 0]
205
+ #set argv [lrange $argv 1 end] ;# below is much faster - lreplace can make use of unshared Tcl_Obj to avoid alloc'ing the result
206
+ set argv [lreplace $argv[set argv {}] 0 0]
207
+ return $arg
208
+ }
209
+
210
+ proc read_spefs {} {
211
+ if { [info exists ::env(_CURRENT_SPEF_BY_CORNER)] } {
212
+ set corner_name $::env(_CURRENT_CORNER_NAME)
213
+ puts "Reading top-level design parasitics for the '$corner_name' corner at '$::env(_CURRENT_SPEF_BY_CORNER)'…"
214
+ read_spef -corner $corner_name $::env(_CURRENT_SPEF_BY_CORNER)
215
+ }
216
+ if { [info exists ::env(_CURRENT_CORNER_SPEFS)] } {
217
+ set corner_name $::env(_CURRENT_CORNER_NAME)
218
+ foreach spefs $::env(_CURRENT_CORNER_SPEFS) {
219
+ set instance_path [lshift spefs]
220
+ foreach spef $spefs {
221
+ puts "Reading '$instance_path' parasitics for the '$corner_name' corner at '$spef'…"
222
+ read_spef -corner $corner_name -path $instance_path $spef
223
+ }
224
+ }
225
+ }
226
+ if { [info exists ::env(_CURRENT_CORNER_EXTRA_SPEFS_BACKCOMPAT)] } {
227
+ set corner_name $::env(_CURRENT_CORNER_NAME)
228
+ foreach pair $::env(_CURRENT_CORNER_EXTRA_SPEFS_BACKCOMPAT) {
229
+ set module_name [lindex $pair 0]
230
+ set spef [lindex $pair 1]
231
+ foreach cell [get_cells * -hierarchical] {
232
+ if { "[get_property $cell ref_name]" eq "$module_name"} {
233
+ set instance_path [get_property $cell full_name]
234
+ puts "Reading '$instance_path' parasitics for the '$corner_name' corner at '$spef'…"
235
+ read_spef -corner $corner_name -path $instance_path $spef
236
+ }
237
+ }
238
+ }
239
+ }
240
+ }
241
+
242
+ proc read_pnr_libs {args} {
243
+ # _PNR_LIBS contains all libs and extra libs but with known-bad cells
244
+ # excluded, so OpenROAD can use cells by functionality and come up
245
+ # with a valid design.
246
+
247
+ # If there are ANY libs already read- just leave
248
+ if { [get_libs -quiet *] != {} } {
249
+ return
250
+ }
251
+
252
+ define_corners $::env(DEFAULT_CORNER)
253
+
254
+ foreach lib $::env(_PNR_LIBS) {
255
+ puts "Reading library file at '$lib'…"
256
+ read_liberty $lib
257
+ }
258
+ if { [info exists ::env(_MACRO_LIBS) ] } {
259
+ foreach macro_lib $::env(_MACRO_LIBS) {
260
+ puts "Reading macro library file at '$macro_lib'…"
261
+ read_liberty $macro_lib
262
+ }
263
+ }
264
+ if { [info exists ::env(EXTRA_LIBS) ] } {
265
+ foreach extra_lib $::env(EXTRA_LIBS) {
266
+ puts "Reading extra library file at '$extra_lib'…"
267
+ read_liberty $extra_lib
268
+ }
269
+ }
270
+ }
271
+
272
+ proc read_lefs {{tlef_key "TECH_LEF"}} {
273
+ set tlef $::env($tlef_key)
274
+
275
+ puts "Reading technology LEF file at '$tlef'…"
276
+ read_lef $tlef
277
+
278
+ foreach lef $::env(CELL_LEFS) {
279
+ puts "Reading cell LEF file at '$lef'…"
280
+ read_lef $lef
281
+ }
282
+ if { [info exist ::env(MACRO_LEFS)] } {
283
+ foreach lef $::env(MACRO_LEFS) {
284
+ puts "Reading macro LEF file at '$lef'…"
285
+ read_lef $lef
286
+ }
287
+ }
288
+ if { [info exist ::env(EXTRA_LEFS)] } {
289
+ foreach lef $::env(EXTRA_LEFS) {
290
+ puts "Reading extra LEF file at '$lef'…"
291
+ read_lef $lef
292
+ }
293
+ }
294
+ }
295
+
296
+ proc set_dont_use_cells {} {
297
+ set_dont_use $::env(_PNR_EXCLUDED_CELLS)
298
+ }
299
+
300
+ proc read_current_odb {args} {
301
+ sta::parse_key_args "read_current_odb" args \
302
+ keys {}\
303
+ flags {}
304
+
305
+ puts "Reading OpenROAD database at '$::env(CURRENT_ODB)'…"
306
+ if { [ catch {read_db $::env(CURRENT_ODB)} errmsg ]} {
307
+ puts stderr $errmsg
308
+ exit 1
309
+ }
310
+
311
+ set_global_vars
312
+
313
+ # Read supporting views (if applicable)
314
+ read_pnr_libs
315
+ read_current_sdc
316
+ set_dont_use_cells
317
+ }
318
+
319
+ proc write_views {args} {
320
+ # This script will attempt to write views based on existing "SAVE_"
321
+ # environment variables. If the SAVE_ variable exists, the script will
322
+ # attempt to write a corresponding view to the specified location.
323
+ sta::parse_key_args "write_views" args \
324
+ keys {}\
325
+ flags {-no_global_connect}
326
+
327
+
328
+ source $::env(SCRIPTS_DIR)/openroad/common/set_power_nets.tcl
329
+ puts "Setting global connections for newly added cells…"
330
+ set_global_connections
331
+
332
+ puts "Updating metrics…"
333
+ report_design_area_metrics
334
+ report_cell_usage
335
+
336
+ if { [info exists ::env(SAVE_ODB)] } {
337
+ puts "Writing OpenROAD database to '$::env(SAVE_ODB)'…"
338
+ write_db $::env(SAVE_ODB)
339
+ }
340
+
341
+ if { [info exists ::env(SAVE_NETLIST)] } {
342
+ puts "Writing netlist to '$::env(SAVE_NETLIST)'…"
343
+ write_verilog $::env(SAVE_NETLIST)
344
+ }
345
+
346
+ if { [info exists ::env(SAVE_POWERED_NETLIST)] } {
347
+ puts "Writing powered netlist to '$::env(SAVE_POWERED_NETLIST)'…"
348
+ write_verilog -include_pwr_gnd $::env(SAVE_POWERED_NETLIST)
349
+ }
350
+
351
+ if { [info exists ::env(SAVE_POWERED_NETLIST_SDF_FRIENDLY)] } {
352
+ set exclude_cells "[join $::env(FILL_CELL)] [join $::env(DECAP_CELL)] [join $::env(WELLTAP_CELL)] [join $::env(ENDCAP_CELL)]"
353
+ puts "Writing nofill powered netlist to '$::env(SAVE_POWERED_NETLIST_SDF_FRIENDLY)'…"
354
+ puts "Excluding $exclude_cells"
355
+ write_verilog -include_pwr_gnd \
356
+ -remove_cells "$exclude_cells"\
357
+ $::env(SAVE_POWERED_NETLIST_SDF_FRIENDLY)
358
+ }
359
+
360
+ if { [info exists ::env(SAVE_POWERED_NETLIST_NO_PHYSICAL_CELLS)] } {
361
+ set exclude_cells "[join [lindex [split $::env(DIODE_CELL) "/"] 0]] [join $::env(FILL_CELL)] [join $::env(DECAP_CELL)] [join $::env(WELLTAP_CELL)] [join $::env(ENDCAP_CELL)]"
362
+ puts "Writing nofilldiode powered netlist to '$::env(SAVE_POWERED_NETLIST_NO_PHYSICAL_CELLS)'…"
363
+ puts "Excluding $exclude_cells"
364
+ write_verilog -include_pwr_gnd \
365
+ -remove_cells "$exclude_cells"\
366
+ $::env(SAVE_POWERED_NETLIST_NO_PHYSICAL_CELLS)
367
+ }
368
+
369
+ if { [info exists ::env(SAVE_OPENROAD_LEF)] } {
370
+ puts "Writing LEF to '$::env(SAVE_OPENROAD_LEF)'…"
371
+ set arg_list [list]
372
+ if {$::env(OPENROAD_LEF_BLOAT_OCCUPIED_LAYERS)} {
373
+ lappend arg_list -bloat_occupied_layers
374
+ }
375
+ write_abstract_lef {*}$arg_list $::env(SAVE_OPENROAD_LEF)
376
+ }
377
+
378
+ if { [info exists ::env(SAVE_DEF)] } {
379
+ puts "Writing layout to '$::env(SAVE_DEF)'…"
380
+ write_def $::env(SAVE_DEF)
381
+ }
382
+
383
+ if { [info exists ::env(SAVE_SDC)] } {
384
+ puts "Writing timing constraints to '$::env(SAVE_SDC)'…"
385
+ write_sdc -no_timestamp $::env(SAVE_SDC)
386
+ }
387
+
388
+ if { [info exists ::env(SAVE_SPEF)] } {
389
+ puts "Writing extracted parasitics to '$::env(SAVE_SPEF)'…"
390
+ write_spef $::env(SAVE_SPEF)
391
+ }
392
+
393
+ if { [info exists ::env(SAVE_GUIDE)] } {
394
+ puts "Writing routing guides to '$::env(SAVE_GUIDE)'…"
395
+ write_guides $::env(SAVE_GUIDE)
396
+ }
397
+
398
+ if { [info exists ::env(SAVE_SDF)] } {
399
+ set corners [sta::corners]
400
+ if { [llength $corners] > 1 } {
401
+ } else {
402
+ puts "Writing SDF to '$::env(SAVE_SDF)'…"
403
+ write_sdf -include_typ -divider . $::env(SAVE_SDF)
404
+ }
405
+ }
406
+ }
407
+
408
+ proc write_sdfs {} {
409
+ if { [info exists ::env(_SDF_SAVE_DIR)] } {
410
+ set corners [sta::corners]
411
+
412
+ puts "Writing SDF files for all corners…"
413
+ foreach corner $corners {
414
+ set corner_name [$corner name]
415
+ set target $::env(_SDF_SAVE_DIR)/$::env(DESIGN_NAME)__$corner_name.sdf
416
+ write_sdf -include_typ -divider . -corner $corner_name $target
417
+ }
418
+ }
419
+ }
420
+
421
+ proc write_libs {} {
422
+ if { [info exists ::env(_LIB_SAVE_DIR)] } {
423
+ puts "Removing Clock latencies before writing libs…"
424
+ # This is to avoid OpenSTA writing a context-dependent timing model
425
+ set_clock_latency -source -max 0 [all_clocks]
426
+ set_clock_latency -source -min 0 [all_clocks]
427
+ set corners [sta::corners]
428
+ puts "Writing timing models for all corners…"
429
+ foreach corner $corners {
430
+ set corner_name [$corner name]
431
+ set target $::env(_LIB_SAVE_DIR)/$::env(DESIGN_NAME)__$corner_name.lib
432
+ puts "Writing timing models for the $corner_name corner to $target…"
433
+ write_timing_model -corner $corner_name $target
434
+ }
435
+ }
436
+ }
437
+
438
+ proc max {a b} {
439
+ if { $a > $b } {
440
+ return $a
441
+ } else {
442
+ return $b
443
+ }
444
+ }
445
+
446
+ set ::metric_count 0
447
+ set ::metrics_file ""
448
+ if { [namespace exists utl] } {
449
+ proc write_metric_str {metric value} {
450
+ puts "Writing metric $metric: $value"
451
+ utl::metric $metric $value
452
+ }
453
+ proc write_metric_int {metric value} {
454
+ puts "Writing metric $metric: $value"
455
+ utl::metric_int $metric $value
456
+ }
457
+ proc write_metric_num {metric value} {
458
+ puts "Writing metric $metric: $value"
459
+ utl::metric_float $metric $value
460
+ }
461
+ } else {
462
+ proc write_metric_num {metric value} {
463
+ if { $value == 1e30 } {
464
+ set value inf
465
+ } elseif { $value == -1e30 } {
466
+ set value -inf
467
+ }
468
+ puts "%OL_METRIC_F $metric $value"
469
+ }
470
+ proc write_metric_int {metric value} {
471
+ puts "%OL_METRIC_I $metric $value"
472
+ }
473
+ proc write_metric_str {metric value} {
474
+ puts "%OL_METRIC $metric $value"
475
+ }
476
+ }
@@ -0,0 +1,135 @@
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
+
15
+ source $::env(SCRIPTS_DIR)/openroad/common/set_global_connections.tcl
16
+ set_global_connections
17
+
18
+ set secondary []
19
+ foreach vdd $::env(VDD_NETS) gnd $::env(GND_NETS) {
20
+ if { $vdd != $::env(VDD_NET)} {
21
+ lappend secondary $vdd
22
+
23
+ set db_net [[ord::get_db_block] findNet $vdd]
24
+ if {$db_net == "NULL"} {
25
+ set net [odb::dbNet_create [ord::get_db_block] $vdd]
26
+ $net setSpecial
27
+ $net setSigType "POWER"
28
+ }
29
+ }
30
+
31
+ if { $gnd != $::env(GND_NET)} {
32
+ lappend secondary $gnd
33
+
34
+ set db_net [[ord::get_db_block] findNet $gnd]
35
+ if {$db_net == "NULL"} {
36
+ set net [odb::dbNet_create [ord::get_db_block] $gnd]
37
+ $net setSpecial
38
+ $net setSigType "GROUND"
39
+ }
40
+ }
41
+ }
42
+
43
+ set_voltage_domain -name CORE -power $::env(VDD_NET) -ground $::env(GND_NET) \
44
+ -secondary_power $secondary
45
+
46
+ if { $::env(FP_PDN_MULTILAYER) == 1 } {
47
+ define_pdn_grid \
48
+ -name stdcell_grid \
49
+ -starts_with POWER \
50
+ -voltage_domain CORE \
51
+ -pins "$::env(FP_PDN_VERTICAL_LAYER) $::env(FP_PDN_HORIZONTAL_LAYER)"
52
+
53
+ add_pdn_stripe \
54
+ -grid stdcell_grid \
55
+ -layer $::env(FP_PDN_VERTICAL_LAYER) \
56
+ -width $::env(FP_PDN_VWIDTH) \
57
+ -pitch $::env(FP_PDN_VPITCH) \
58
+ -offset $::env(FP_PDN_VOFFSET) \
59
+ -spacing $::env(FP_PDN_VSPACING) \
60
+ -starts_with POWER -extend_to_core_ring
61
+
62
+ add_pdn_stripe \
63
+ -grid stdcell_grid \
64
+ -layer $::env(FP_PDN_HORIZONTAL_LAYER) \
65
+ -width $::env(FP_PDN_HWIDTH) \
66
+ -pitch $::env(FP_PDN_HPITCH) \
67
+ -offset $::env(FP_PDN_HOFFSET) \
68
+ -spacing $::env(FP_PDN_HSPACING) \
69
+ -starts_with POWER -extend_to_core_ring
70
+
71
+ add_pdn_connect \
72
+ -grid stdcell_grid \
73
+ -layers "$::env(FP_PDN_VERTICAL_LAYER) $::env(FP_PDN_HORIZONTAL_LAYER)"
74
+ } else {
75
+ define_pdn_grid \
76
+ -name stdcell_grid \
77
+ -starts_with POWER \
78
+ -voltage_domain CORE \
79
+ -pins $::env(FP_PDN_VERTICAL_LAYER)
80
+
81
+ add_pdn_stripe \
82
+ -grid stdcell_grid \
83
+ -layer $::env(FP_PDN_VERTICAL_LAYER) \
84
+ -width $::env(FP_PDN_VWIDTH) \
85
+ -pitch $::env(FP_PDN_VPITCH) \
86
+ -offset $::env(FP_PDN_VOFFSET) \
87
+ -spacing $::env(FP_PDN_VSPACING) \
88
+ -starts_with POWER -extend_to_core_ring
89
+ }
90
+
91
+ # Adds the standard cell rails if enabled.
92
+ if { $::env(FP_PDN_ENABLE_RAILS) == 1 } {
93
+ add_pdn_stripe \
94
+ -grid stdcell_grid \
95
+ -layer $::env(FP_PDN_RAIL_LAYER) \
96
+ -width $::env(FP_PDN_RAIL_WIDTH) \
97
+ -followpins \
98
+ -starts_with POWER
99
+
100
+ add_pdn_connect \
101
+ -grid stdcell_grid \
102
+ -layers "$::env(FP_PDN_RAIL_LAYER) $::env(FP_PDN_VERTICAL_LAYER)"
103
+ }
104
+
105
+
106
+ # Adds the core ring if enabled.
107
+ if { $::env(FP_PDN_CORE_RING) == 1 } {
108
+ if { $::env(FP_PDN_MULTILAYER) == 1 } {
109
+ add_pdn_ring \
110
+ -grid stdcell_grid \
111
+ -layers "$::env(FP_PDN_VERTICAL_LAYER) $::env(FP_PDN_HORIZONTAL_LAYER)" \
112
+ -widths "$::env(FP_PDN_CORE_RING_VWIDTH) $::env(FP_PDN_CORE_RING_HWIDTH)" \
113
+ -spacings "$::env(FP_PDN_CORE_RING_VSPACING) $::env(FP_PDN_CORE_RING_HSPACING)" \
114
+ -core_offset "$::env(FP_PDN_CORE_RING_VOFFSET) $::env(FP_PDN_CORE_RING_HOFFSET)"
115
+ } else {
116
+ throw APPLICATION "FP_PDN_CORE_RING cannot be used when FP_PDN_MULTILAYER is set to false."
117
+ # add_pdn_ring \
118
+ # -grid stdcell_grid \
119
+ # -layers "$::env(FP_PDN_VERTICAL_LAYER)" \
120
+ # -widths "$::env(FP_PDN_CORE_RING_VWIDTH)" \
121
+ # -spacings "$::env(FP_PDN_CORE_RING_VSPACING)" \
122
+ # -core_offset "$::env(FP_PDN_CORE_RING_VOFFSET)"
123
+ }
124
+ }
125
+
126
+ define_pdn_grid \
127
+ -macro \
128
+ -default \
129
+ -name macro \
130
+ -starts_with POWER \
131
+ -halo "$::env(FP_PDN_HORIZONTAL_HALO) $::env(FP_PDN_VERTICAL_HALO)"
132
+
133
+ add_pdn_connect \
134
+ -grid macro \
135
+ -layers "$::env(FP_PDN_VERTICAL_LAYER) $::env(FP_PDN_HORIZONTAL_LAYER)"