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.
- librelane/__init__.py +38 -0
- librelane/__main__.py +470 -0
- librelane/__version__.py +43 -0
- librelane/common/__init__.py +61 -0
- librelane/common/cli.py +75 -0
- librelane/common/drc.py +245 -0
- librelane/common/generic_dict.py +319 -0
- librelane/common/metrics/__init__.py +35 -0
- librelane/common/metrics/__main__.py +413 -0
- librelane/common/metrics/library.py +354 -0
- librelane/common/metrics/metric.py +186 -0
- librelane/common/metrics/util.py +279 -0
- librelane/common/misc.py +402 -0
- librelane/common/ring_buffer.py +63 -0
- librelane/common/tcl.py +80 -0
- librelane/common/toolbox.py +549 -0
- librelane/common/tpe.py +41 -0
- librelane/common/types.py +117 -0
- librelane/config/__init__.py +32 -0
- librelane/config/__main__.py +158 -0
- librelane/config/config.py +1025 -0
- librelane/config/flow.py +490 -0
- librelane/config/pdk_compat.py +255 -0
- librelane/config/preprocessor.py +464 -0
- librelane/config/removals.py +45 -0
- librelane/config/variable.py +722 -0
- librelane/container.py +264 -0
- librelane/env_info.py +306 -0
- librelane/examples/spm/config.yaml +33 -0
- librelane/examples/spm/pin_order.cfg +14 -0
- librelane/examples/spm/src/impl.sdc +73 -0
- librelane/examples/spm/src/signoff.sdc +68 -0
- librelane/examples/spm/src/spm.v +73 -0
- librelane/examples/spm/verify/spm_tb.v +106 -0
- librelane/examples/spm-user_project_wrapper/SPM_example.v +286 -0
- librelane/examples/spm-user_project_wrapper/base_sdc_file.sdc +145 -0
- librelane/examples/spm-user_project_wrapper/config-tut.json +12 -0
- librelane/examples/spm-user_project_wrapper/config.json +13 -0
- librelane/examples/spm-user_project_wrapper/defines.v +66 -0
- librelane/examples/spm-user_project_wrapper/template.def +7656 -0
- librelane/examples/spm-user_project_wrapper/user_project_wrapper.v +123 -0
- librelane/flows/__init__.py +24 -0
- librelane/flows/builtins.py +18 -0
- librelane/flows/classic.py +330 -0
- librelane/flows/cli.py +463 -0
- librelane/flows/flow.py +985 -0
- librelane/flows/misc.py +71 -0
- librelane/flows/optimizing.py +179 -0
- librelane/flows/sequential.py +367 -0
- librelane/flows/synth_explore.py +173 -0
- librelane/logging/__init__.py +40 -0
- librelane/logging/logger.py +323 -0
- librelane/open_pdks_rev +1 -0
- librelane/plugins.py +21 -0
- librelane/py.typed +0 -0
- librelane/scripts/base.sdc +80 -0
- librelane/scripts/klayout/Readme.md +2 -0
- librelane/scripts/klayout/open_design.py +63 -0
- librelane/scripts/klayout/render.py +121 -0
- librelane/scripts/klayout/stream_out.py +176 -0
- librelane/scripts/klayout/xml_drc_report_to_json.py +45 -0
- librelane/scripts/klayout/xor.drc +120 -0
- librelane/scripts/magic/Readme.md +1 -0
- librelane/scripts/magic/common/read.tcl +114 -0
- librelane/scripts/magic/def/antenna_check.tcl +35 -0
- librelane/scripts/magic/def/mag.tcl +19 -0
- librelane/scripts/magic/def/mag_gds.tcl +81 -0
- librelane/scripts/magic/drc.tcl +79 -0
- librelane/scripts/magic/extract_spice.tcl +98 -0
- librelane/scripts/magic/gds/drc_batch.tcl +74 -0
- librelane/scripts/magic/gds/erase_box.tcl +32 -0
- librelane/scripts/magic/gds/extras_mag.tcl +47 -0
- librelane/scripts/magic/gds/mag_with_pointers.tcl +32 -0
- librelane/scripts/magic/get_bbox.tcl +11 -0
- librelane/scripts/magic/lef/extras_maglef.tcl +63 -0
- librelane/scripts/magic/lef/maglef.tcl +27 -0
- librelane/scripts/magic/lef.tcl +57 -0
- librelane/scripts/magic/open.tcl +28 -0
- librelane/scripts/magic/wrapper.tcl +19 -0
- librelane/scripts/netgen/setup.tcl +28 -0
- librelane/scripts/odbpy/apply_def_template.py +49 -0
- librelane/scripts/odbpy/cell_frequency.py +107 -0
- librelane/scripts/odbpy/check_antenna_properties.py +116 -0
- librelane/scripts/odbpy/contextualize.py +109 -0
- librelane/scripts/odbpy/defutil.py +574 -0
- librelane/scripts/odbpy/diodes.py +373 -0
- librelane/scripts/odbpy/disconnected_pins.py +305 -0
- librelane/scripts/odbpy/exception_codes.py +17 -0
- librelane/scripts/odbpy/filter_unannotated.py +100 -0
- librelane/scripts/odbpy/io_place.py +482 -0
- librelane/scripts/odbpy/label_macro_pins.py +277 -0
- librelane/scripts/odbpy/lefutil.py +97 -0
- librelane/scripts/odbpy/placers.py +162 -0
- librelane/scripts/odbpy/power_utils.py +395 -0
- librelane/scripts/odbpy/random_place.py +57 -0
- librelane/scripts/odbpy/reader.py +246 -0
- librelane/scripts/odbpy/remove_buffers.py +173 -0
- librelane/scripts/odbpy/snap_to_grid.py +57 -0
- librelane/scripts/odbpy/wire_lengths.py +93 -0
- librelane/scripts/openroad/antenna_check.tcl +20 -0
- librelane/scripts/openroad/antenna_repair.tcl +31 -0
- librelane/scripts/openroad/basic_mp.tcl +24 -0
- librelane/scripts/openroad/buffer_list.tcl +10 -0
- librelane/scripts/openroad/common/dpl.tcl +24 -0
- librelane/scripts/openroad/common/dpl_cell_pad.tcl +26 -0
- librelane/scripts/openroad/common/grt.tcl +32 -0
- librelane/scripts/openroad/common/io.tcl +476 -0
- librelane/scripts/openroad/common/pdn_cfg.tcl +135 -0
- librelane/scripts/openroad/common/resizer.tcl +103 -0
- librelane/scripts/openroad/common/set_global_connections.tcl +78 -0
- librelane/scripts/openroad/common/set_layer_adjustments.tcl +31 -0
- librelane/scripts/openroad/common/set_power_nets.tcl +30 -0
- librelane/scripts/openroad/common/set_rc.tcl +75 -0
- librelane/scripts/openroad/common/set_routing_layers.tcl +30 -0
- librelane/scripts/openroad/cts.tcl +80 -0
- librelane/scripts/openroad/cut_rows.tcl +24 -0
- librelane/scripts/openroad/dpl.tcl +24 -0
- librelane/scripts/openroad/drt.tcl +37 -0
- librelane/scripts/openroad/fill.tcl +30 -0
- librelane/scripts/openroad/floorplan.tcl +145 -0
- librelane/scripts/openroad/gpl.tcl +88 -0
- librelane/scripts/openroad/grt.tcl +30 -0
- librelane/scripts/openroad/gui.tcl +15 -0
- librelane/scripts/openroad/insert_buffer.tcl +127 -0
- librelane/scripts/openroad/ioplacer.tcl +67 -0
- librelane/scripts/openroad/irdrop.tcl +51 -0
- librelane/scripts/openroad/pdn.tcl +52 -0
- librelane/scripts/openroad/rcx.tcl +32 -0
- librelane/scripts/openroad/repair_design.tcl +70 -0
- librelane/scripts/openroad/repair_design_postgrt.tcl +48 -0
- librelane/scripts/openroad/rsz_timing_postcts.tcl +68 -0
- librelane/scripts/openroad/rsz_timing_postgrt.tcl +70 -0
- librelane/scripts/openroad/sta/check_macro_instances.tcl +53 -0
- librelane/scripts/openroad/sta/corner.tcl +393 -0
- librelane/scripts/openroad/tapcell.tcl +25 -0
- librelane/scripts/openroad/write_views.tcl +27 -0
- librelane/scripts/pyosys/construct_abc_script.py +177 -0
- librelane/scripts/pyosys/json_header.py +84 -0
- librelane/scripts/pyosys/synthesize.py +493 -0
- librelane/scripts/pyosys/ys_common.py +153 -0
- librelane/scripts/tclsh/hello.tcl +1 -0
- librelane/state/__init__.py +24 -0
- librelane/state/__main__.py +61 -0
- librelane/state/design_format.py +180 -0
- librelane/state/state.py +351 -0
- librelane/steps/__init__.py +61 -0
- librelane/steps/__main__.py +511 -0
- librelane/steps/checker.py +637 -0
- librelane/steps/common_variables.py +340 -0
- librelane/steps/cvc_rv.py +169 -0
- librelane/steps/klayout.py +509 -0
- librelane/steps/magic.py +566 -0
- librelane/steps/misc.py +160 -0
- librelane/steps/netgen.py +253 -0
- librelane/steps/odb.py +955 -0
- librelane/steps/openroad.py +2433 -0
- librelane/steps/openroad_alerts.py +102 -0
- librelane/steps/pyosys.py +629 -0
- librelane/steps/step.py +1547 -0
- librelane/steps/tclstep.py +288 -0
- librelane/steps/verilator.py +222 -0
- librelane/steps/yosys.py +371 -0
- librelane-2.4.0.dev0.dist-info/METADATA +151 -0
- librelane-2.4.0.dev0.dist-info/RECORD +166 -0
- librelane-2.4.0.dev0.dist-info/WHEEL +4 -0
- librelane-2.4.0.dev0.dist-info/entry_points.txt +8 -0
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
# Copyright 2023 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
|
+
from decimal import Decimal
|
|
15
|
+
from typing import Optional, List
|
|
16
|
+
|
|
17
|
+
from ..config import Variable
|
|
18
|
+
|
|
19
|
+
io_layer_variables = [
|
|
20
|
+
Variable(
|
|
21
|
+
"FP_IO_VEXTEND",
|
|
22
|
+
Decimal,
|
|
23
|
+
"Extends the vertical io pins outside of the die by the specified units.",
|
|
24
|
+
default=0,
|
|
25
|
+
units="µm",
|
|
26
|
+
),
|
|
27
|
+
Variable(
|
|
28
|
+
"FP_IO_HEXTEND",
|
|
29
|
+
Decimal,
|
|
30
|
+
"Extends the horizontal io pins outside of the die by the specified units.",
|
|
31
|
+
default=0,
|
|
32
|
+
units="µm",
|
|
33
|
+
),
|
|
34
|
+
Variable(
|
|
35
|
+
"FP_IO_VTHICKNESS_MULT",
|
|
36
|
+
Decimal,
|
|
37
|
+
"A multiplier for vertical pin thickness. Base thickness is the pins layer min width.",
|
|
38
|
+
default=2,
|
|
39
|
+
),
|
|
40
|
+
Variable(
|
|
41
|
+
"FP_IO_HTHICKNESS_MULT",
|
|
42
|
+
Decimal,
|
|
43
|
+
"A multiplier for horizontal pin thickness. Base thickness is the pins layer min width.",
|
|
44
|
+
default=2,
|
|
45
|
+
),
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
pdn_variables = [
|
|
49
|
+
Variable(
|
|
50
|
+
"FP_PDN_SKIPTRIM",
|
|
51
|
+
bool,
|
|
52
|
+
"Enables `-skip_trim` option during pdngen which skips the metal trim step, which attempts to remove metal stubs.",
|
|
53
|
+
default=False,
|
|
54
|
+
),
|
|
55
|
+
Variable(
|
|
56
|
+
"FP_PDN_CORE_RING",
|
|
57
|
+
bool,
|
|
58
|
+
"Enables adding a core ring around the design. More details on the control variables in the PDK config documentation.",
|
|
59
|
+
default=False,
|
|
60
|
+
),
|
|
61
|
+
Variable(
|
|
62
|
+
"FP_PDN_ENABLE_RAILS",
|
|
63
|
+
bool,
|
|
64
|
+
"Enables the creation of rails in the power grid.",
|
|
65
|
+
default=True,
|
|
66
|
+
),
|
|
67
|
+
Variable(
|
|
68
|
+
"FP_PDN_HORIZONTAL_HALO",
|
|
69
|
+
Decimal,
|
|
70
|
+
"Sets the horizontal halo around the macros during power grid insertion.",
|
|
71
|
+
default=10,
|
|
72
|
+
units="µm",
|
|
73
|
+
),
|
|
74
|
+
Variable(
|
|
75
|
+
"FP_PDN_VERTICAL_HALO",
|
|
76
|
+
Decimal,
|
|
77
|
+
"Sets the vertical halo around the macros during power grid insertion.",
|
|
78
|
+
default=10,
|
|
79
|
+
units="µm",
|
|
80
|
+
),
|
|
81
|
+
Variable(
|
|
82
|
+
"FP_PDN_MULTILAYER",
|
|
83
|
+
bool,
|
|
84
|
+
"Controls the layers used in the power grid. If set to false, only the lower layer will be used, which is useful when hardening a macro for integrating into a larger top-level design.",
|
|
85
|
+
default=True,
|
|
86
|
+
deprecated_names=["DESIGN_IS_CORE"],
|
|
87
|
+
),
|
|
88
|
+
Variable(
|
|
89
|
+
"FP_PDN_RAIL_OFFSET",
|
|
90
|
+
Decimal,
|
|
91
|
+
"The offset for the power distribution network rails for first metal layer.",
|
|
92
|
+
units="µm",
|
|
93
|
+
pdk=True,
|
|
94
|
+
),
|
|
95
|
+
Variable(
|
|
96
|
+
"FP_PDN_VWIDTH",
|
|
97
|
+
Decimal,
|
|
98
|
+
"The strap width for the vertical layer in generated power distribution networks.",
|
|
99
|
+
units="µm",
|
|
100
|
+
pdk=True,
|
|
101
|
+
),
|
|
102
|
+
Variable(
|
|
103
|
+
"FP_PDN_HWIDTH",
|
|
104
|
+
Decimal,
|
|
105
|
+
"The strap width for the horizontal layer in generated power distribution networks.",
|
|
106
|
+
units="µm",
|
|
107
|
+
pdk=True,
|
|
108
|
+
),
|
|
109
|
+
Variable(
|
|
110
|
+
"FP_PDN_VSPACING",
|
|
111
|
+
Decimal,
|
|
112
|
+
"Intra-spacing (within a set) of vertical straps in generated power distribution networks.",
|
|
113
|
+
units="µm",
|
|
114
|
+
pdk=True,
|
|
115
|
+
),
|
|
116
|
+
Variable(
|
|
117
|
+
"FP_PDN_HSPACING",
|
|
118
|
+
Decimal,
|
|
119
|
+
"Intra-spacing (within a set) of horizontal straps in generated power distribution networks.",
|
|
120
|
+
units="µm",
|
|
121
|
+
pdk=True,
|
|
122
|
+
),
|
|
123
|
+
Variable(
|
|
124
|
+
"FP_PDN_VPITCH",
|
|
125
|
+
Decimal,
|
|
126
|
+
"Inter-distance (between sets) of vertical power straps in generated power distribution networks.",
|
|
127
|
+
units="µm",
|
|
128
|
+
pdk=True,
|
|
129
|
+
),
|
|
130
|
+
Variable(
|
|
131
|
+
"FP_PDN_HPITCH",
|
|
132
|
+
Decimal,
|
|
133
|
+
"Inter-distance (between sets) of horizontal power straps in generated power distribution networks.",
|
|
134
|
+
units="µm",
|
|
135
|
+
pdk=True,
|
|
136
|
+
),
|
|
137
|
+
Variable(
|
|
138
|
+
"FP_PDN_VOFFSET",
|
|
139
|
+
Decimal,
|
|
140
|
+
"Initial offset for sets of vertical power straps.",
|
|
141
|
+
units="µm",
|
|
142
|
+
pdk=True,
|
|
143
|
+
),
|
|
144
|
+
Variable(
|
|
145
|
+
"FP_PDN_HOFFSET",
|
|
146
|
+
Decimal,
|
|
147
|
+
"Initial offset for sets of horizontal power straps.",
|
|
148
|
+
units="µm",
|
|
149
|
+
pdk=True,
|
|
150
|
+
),
|
|
151
|
+
Variable(
|
|
152
|
+
"FP_PDN_CORE_RING_VWIDTH",
|
|
153
|
+
Decimal,
|
|
154
|
+
"The width for the vertical layer in the core ring of generated power distribution networks.",
|
|
155
|
+
units="µm",
|
|
156
|
+
pdk=True,
|
|
157
|
+
),
|
|
158
|
+
Variable(
|
|
159
|
+
"FP_PDN_CORE_RING_HWIDTH",
|
|
160
|
+
Decimal,
|
|
161
|
+
"The width for the horizontal layer in the core ring of generated power distribution networks.",
|
|
162
|
+
units="µm",
|
|
163
|
+
pdk=True,
|
|
164
|
+
),
|
|
165
|
+
Variable(
|
|
166
|
+
"FP_PDN_CORE_RING_VSPACING",
|
|
167
|
+
Decimal,
|
|
168
|
+
"The spacing for the vertical layer in the core ring of generated power distribution networks.",
|
|
169
|
+
units="µm",
|
|
170
|
+
pdk=True,
|
|
171
|
+
),
|
|
172
|
+
Variable(
|
|
173
|
+
"FP_PDN_CORE_RING_HSPACING",
|
|
174
|
+
Decimal,
|
|
175
|
+
"The spacing for the horizontal layer in the core ring of generated power distribution networks.",
|
|
176
|
+
units="µm",
|
|
177
|
+
pdk=True,
|
|
178
|
+
),
|
|
179
|
+
Variable(
|
|
180
|
+
"FP_PDN_CORE_RING_VOFFSET",
|
|
181
|
+
Decimal,
|
|
182
|
+
"The offset for the vertical layer in the core ring of generated power distribution networks.",
|
|
183
|
+
units="µm",
|
|
184
|
+
pdk=True,
|
|
185
|
+
),
|
|
186
|
+
Variable(
|
|
187
|
+
"FP_PDN_CORE_RING_HOFFSET",
|
|
188
|
+
Decimal,
|
|
189
|
+
"The offset for the horizontal layer in the core ring of generated power distribution networks.",
|
|
190
|
+
units="µm",
|
|
191
|
+
pdk=True,
|
|
192
|
+
),
|
|
193
|
+
Variable(
|
|
194
|
+
"FP_PDN_RAIL_LAYER",
|
|
195
|
+
str,
|
|
196
|
+
"Defines the metal layer used for PDN rails.",
|
|
197
|
+
deprecated_names=["FP_PDN_RAILS_LAYER"],
|
|
198
|
+
pdk=True,
|
|
199
|
+
),
|
|
200
|
+
Variable(
|
|
201
|
+
"FP_PDN_RAIL_WIDTH",
|
|
202
|
+
Decimal,
|
|
203
|
+
"Defines the width of PDN rails on the `FP_PDN_RAILS_LAYER` layer.",
|
|
204
|
+
units="µm",
|
|
205
|
+
pdk=True,
|
|
206
|
+
),
|
|
207
|
+
Variable(
|
|
208
|
+
"FP_PDN_HORIZONTAL_LAYER",
|
|
209
|
+
str,
|
|
210
|
+
"Defines the horizontal PDN layer.",
|
|
211
|
+
deprecated_names=["FP_PDN_UPPER_LAYER"],
|
|
212
|
+
pdk=True,
|
|
213
|
+
),
|
|
214
|
+
Variable(
|
|
215
|
+
"FP_PDN_VERTICAL_LAYER",
|
|
216
|
+
str,
|
|
217
|
+
"Defines the vertical PDN layer.",
|
|
218
|
+
deprecated_names=["FP_PDN_LOWER_LAYER"],
|
|
219
|
+
pdk=True,
|
|
220
|
+
),
|
|
221
|
+
]
|
|
222
|
+
|
|
223
|
+
routing_layer_variables = [
|
|
224
|
+
Variable(
|
|
225
|
+
"RT_CLOCK_MIN_LAYER",
|
|
226
|
+
Optional[str],
|
|
227
|
+
"The name of lowest layer to be used in routing the clock net.",
|
|
228
|
+
),
|
|
229
|
+
Variable(
|
|
230
|
+
"RT_CLOCK_MAX_LAYER",
|
|
231
|
+
Optional[str],
|
|
232
|
+
"The name of highest layer to be used in routing the clock net.",
|
|
233
|
+
),
|
|
234
|
+
Variable(
|
|
235
|
+
"GRT_ADJUSTMENT",
|
|
236
|
+
Decimal,
|
|
237
|
+
"Reduction in the routing capacity of the edges between the cells in the global routing graph for all layers. Values range from 0 to 1. 1 = most reduction, 0 = least reduction.",
|
|
238
|
+
default=0.3,
|
|
239
|
+
),
|
|
240
|
+
Variable(
|
|
241
|
+
"GRT_MACRO_EXTENSION",
|
|
242
|
+
int,
|
|
243
|
+
"Sets the number of GCells added to the blockages boundaries from macros. A GCell is typically defined in terms of Mx routing tracks. The default GCell size is 15 M3 pitches.",
|
|
244
|
+
default=0,
|
|
245
|
+
),
|
|
246
|
+
Variable(
|
|
247
|
+
"GRT_LAYER_ADJUSTMENTS",
|
|
248
|
+
List[Decimal],
|
|
249
|
+
"Layer-specific reductions in the routing capacity of the edges between the cells in the global routing graph, delimited by commas. Values range from 0 through 1.",
|
|
250
|
+
pdk=True,
|
|
251
|
+
),
|
|
252
|
+
]
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
dpl_variables = [
|
|
256
|
+
Variable(
|
|
257
|
+
"PL_OPTIMIZE_MIRRORING",
|
|
258
|
+
bool,
|
|
259
|
+
"Specifies whether or not to run an optimize_mirroring pass whenever detailed placement happens. This pass will mirror the cells whenever possible to optimize the design.",
|
|
260
|
+
default=True,
|
|
261
|
+
),
|
|
262
|
+
Variable(
|
|
263
|
+
"PL_MAX_DISPLACEMENT_X",
|
|
264
|
+
Decimal,
|
|
265
|
+
"Specifies how far an instance can be moved along the X-axis when finding a site where it can be placed during detailed placement.",
|
|
266
|
+
default=500,
|
|
267
|
+
units="µm",
|
|
268
|
+
),
|
|
269
|
+
Variable(
|
|
270
|
+
"PL_MAX_DISPLACEMENT_Y",
|
|
271
|
+
Decimal,
|
|
272
|
+
"Specifies how far an instance can be moved along the Y-axis when finding a site where it can be placed during detailed placement.",
|
|
273
|
+
default=100,
|
|
274
|
+
units="µm",
|
|
275
|
+
),
|
|
276
|
+
Variable(
|
|
277
|
+
"DPL_CELL_PADDING",
|
|
278
|
+
Decimal,
|
|
279
|
+
"Cell padding value (in sites) for detailed placement. The number will be integer divided by 2 and placed on both sides. Should be <= global placement.",
|
|
280
|
+
units="sites",
|
|
281
|
+
pdk=True,
|
|
282
|
+
),
|
|
283
|
+
]
|
|
284
|
+
|
|
285
|
+
grt_variables = routing_layer_variables + [
|
|
286
|
+
Variable(
|
|
287
|
+
"DIODE_PADDING",
|
|
288
|
+
Optional[int],
|
|
289
|
+
"Diode cell padding; increases the width of diode cells during placement checks..",
|
|
290
|
+
units="sites",
|
|
291
|
+
),
|
|
292
|
+
Variable(
|
|
293
|
+
"GRT_ALLOW_CONGESTION",
|
|
294
|
+
bool,
|
|
295
|
+
"Allow congestion during global routing",
|
|
296
|
+
default=False,
|
|
297
|
+
),
|
|
298
|
+
Variable(
|
|
299
|
+
"GRT_ANTENNA_ITERS",
|
|
300
|
+
int,
|
|
301
|
+
"The maximum number of iterations for global antenna repairs.",
|
|
302
|
+
default=3,
|
|
303
|
+
deprecated_names=["GRT_ANT_ITERS"],
|
|
304
|
+
),
|
|
305
|
+
Variable(
|
|
306
|
+
"GRT_OVERFLOW_ITERS",
|
|
307
|
+
int,
|
|
308
|
+
"The maximum number of iterations waiting for the overflow to reach the desired value.",
|
|
309
|
+
default=50,
|
|
310
|
+
),
|
|
311
|
+
Variable(
|
|
312
|
+
"GRT_ANTENNA_MARGIN",
|
|
313
|
+
int,
|
|
314
|
+
"The margin to over fix antenna violations.",
|
|
315
|
+
default=10,
|
|
316
|
+
units="%",
|
|
317
|
+
deprecated_names=["GRT_ANT_MARGIN"],
|
|
318
|
+
),
|
|
319
|
+
]
|
|
320
|
+
|
|
321
|
+
rsz_variables = dpl_variables + [
|
|
322
|
+
Variable(
|
|
323
|
+
"RSZ_DONT_TOUCH_RX",
|
|
324
|
+
str,
|
|
325
|
+
'A single regular expression designating nets or instances as "don\'t touch" by design repairs or resizer optimizations.',
|
|
326
|
+
default="$^",
|
|
327
|
+
deprecated_names=["UNBUFFER_NETS"],
|
|
328
|
+
),
|
|
329
|
+
Variable(
|
|
330
|
+
"RSZ_DONT_TOUCH_LIST",
|
|
331
|
+
Optional[List[str]],
|
|
332
|
+
'A list of nets and instances as "don\'t touch" by design repairs or resizer optimizations.',
|
|
333
|
+
default=None,
|
|
334
|
+
),
|
|
335
|
+
Variable(
|
|
336
|
+
"RSZ_CORNERS",
|
|
337
|
+
Optional[List[str]],
|
|
338
|
+
"A list of fully-qualified IPVT corners to use during resizer optimizations. If unspecified, the value for `STA_CORNERS` from the PDK will be used.",
|
|
339
|
+
),
|
|
340
|
+
]
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# Copyright 2023 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
|
+
import os
|
|
15
|
+
import re
|
|
16
|
+
import json
|
|
17
|
+
from enum import Enum
|
|
18
|
+
from io import StringIO, TextIOWrapper
|
|
19
|
+
from typing import List, Optional, Tuple
|
|
20
|
+
|
|
21
|
+
from .step import StepException, ViewsUpdate, MetricsUpdate, Step
|
|
22
|
+
from ..common import Path
|
|
23
|
+
from ..config import Variable, Config
|
|
24
|
+
from ..state import DesignFormat, State
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class CVCNoSupport(Exception):
|
|
28
|
+
pass
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def power_file_for(config: Config, json_header_str: str) -> str:
|
|
32
|
+
try:
|
|
33
|
+
json_header = json.loads(json_header_str)
|
|
34
|
+
except json.JSONDecodeError as e:
|
|
35
|
+
raise StepException(f"Invalid JSON file passed to step: {e}")
|
|
36
|
+
|
|
37
|
+
vdd_nets = config["VDD_NETS"] or [config["VDD_PIN"]]
|
|
38
|
+
gnd_nets = config["GND_NETS"] or [config["GND_PIN"]]
|
|
39
|
+
if len(vdd_nets) != 1 or len(gnd_nets) != 1:
|
|
40
|
+
raise CVCNoSupport("more than one power or ground net")
|
|
41
|
+
|
|
42
|
+
vdd = vdd_nets[0]
|
|
43
|
+
gnd = gnd_nets[0]
|
|
44
|
+
|
|
45
|
+
if vdd != config["VDD_PIN"] or gnd != config["GND_PIN"]:
|
|
46
|
+
raise CVCNoSupport("mismatched power/gnd nets")
|
|
47
|
+
|
|
48
|
+
sio = StringIO()
|
|
49
|
+
print(f"{vdd} power {config['VDD_PIN_VOLTAGE']}", file=sio)
|
|
50
|
+
print(f"{gnd} power 0.0", file=sio)
|
|
51
|
+
print(f"#define std_input min@{gnd} max@{vdd}", file=sio)
|
|
52
|
+
|
|
53
|
+
module = json_header["modules"][config["DESIGN_NAME"]]
|
|
54
|
+
for port, info in module["ports"].items():
|
|
55
|
+
if info["direction"] != "input":
|
|
56
|
+
continue
|
|
57
|
+
if port in [vdd, gnd]:
|
|
58
|
+
continue
|
|
59
|
+
|
|
60
|
+
port_string = port
|
|
61
|
+
bits = len(info["bits"])
|
|
62
|
+
if len(info["bits"]) != 1:
|
|
63
|
+
offset = info.get("offset", 0)
|
|
64
|
+
upto = info.get("upto", 0)
|
|
65
|
+
|
|
66
|
+
msb = bits - offset - 1
|
|
67
|
+
lsb = offset
|
|
68
|
+
|
|
69
|
+
if upto == 1:
|
|
70
|
+
msb, lsb = lsb, msb
|
|
71
|
+
|
|
72
|
+
port_string = f"{port}[{msb}:{lsb}]"
|
|
73
|
+
|
|
74
|
+
print(f"{port_string} input std_input", file=sio)
|
|
75
|
+
|
|
76
|
+
return sio.getvalue()
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def cdl_clean(istream: TextIOWrapper, ostream: TextIOWrapper):
|
|
80
|
+
class State(Enum):
|
|
81
|
+
printing = 0
|
|
82
|
+
in_bb = 0
|
|
83
|
+
|
|
84
|
+
state = State.printing
|
|
85
|
+
|
|
86
|
+
bb_rx = re.compile("Black-box entry subcircuit")
|
|
87
|
+
|
|
88
|
+
for line in istream:
|
|
89
|
+
line = line.strip()
|
|
90
|
+
elements = line.split()
|
|
91
|
+
if state == State.printing:
|
|
92
|
+
if bb_rx.search(line):
|
|
93
|
+
state = State.in_bb
|
|
94
|
+
elif line.startswith("*"):
|
|
95
|
+
pass
|
|
96
|
+
elif line.startswith(".ENDS"):
|
|
97
|
+
print(".ENDS", file=ostream)
|
|
98
|
+
else:
|
|
99
|
+
print(line, file=ostream)
|
|
100
|
+
elif state == State.in_bb:
|
|
101
|
+
if elements[1] == ".ends":
|
|
102
|
+
state = State.printing
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
class ERC(Step):
|
|
106
|
+
id = "CVCRV.ERC"
|
|
107
|
+
long_name = "Electrical Rule Checking (CVC-RV)"
|
|
108
|
+
inputs = [
|
|
109
|
+
DesignFormat.JSON_HEADER,
|
|
110
|
+
DesignFormat.SPICE,
|
|
111
|
+
]
|
|
112
|
+
outputs = []
|
|
113
|
+
|
|
114
|
+
config_vars = [
|
|
115
|
+
Variable(
|
|
116
|
+
"CVCRC",
|
|
117
|
+
Optional[Path], # Only optional for backwards-compat
|
|
118
|
+
description="The CVC RC file for this PDK. If it doesn't exist, this step will do nothing.",
|
|
119
|
+
pdk=True,
|
|
120
|
+
),
|
|
121
|
+
Variable(
|
|
122
|
+
"CVC_MODELS",
|
|
123
|
+
Optional[Path], # Only optional for backwards-compat
|
|
124
|
+
description="",
|
|
125
|
+
pdk=True,
|
|
126
|
+
),
|
|
127
|
+
Variable(
|
|
128
|
+
"CELL_CDLS",
|
|
129
|
+
List[Path],
|
|
130
|
+
description="A circuit-design language view of the standard cell library.",
|
|
131
|
+
pdk=True,
|
|
132
|
+
deprecated_names=["STD_CELL_LIBRARY_CDL"],
|
|
133
|
+
),
|
|
134
|
+
]
|
|
135
|
+
|
|
136
|
+
def run(self, state_in: State, **kwargs) -> Tuple[ViewsUpdate, MetricsUpdate]:
|
|
137
|
+
try:
|
|
138
|
+
json_header = state_in[DesignFormat.JSON_HEADER]
|
|
139
|
+
assert isinstance(json_header, Path), "Invalid input state"
|
|
140
|
+
json_header_str = open(str(json_header), encoding="utf8").read()
|
|
141
|
+
|
|
142
|
+
power_file = os.path.join(
|
|
143
|
+
self.step_dir, f"{self.config['DESIGN_NAME']}.power"
|
|
144
|
+
)
|
|
145
|
+
with open(power_file, "w", encoding="utf8") as f:
|
|
146
|
+
f.write(power_file_for(self.config, json_header_str))
|
|
147
|
+
|
|
148
|
+
cdl_file = os.path.join(self.step_dir, f"{self.config['DESIGN_NAME']}.cdl")
|
|
149
|
+
with open(cdl_file, "w", encoding="utf8") as f:
|
|
150
|
+
for file in self.config["CELL_CDLS"] + [state_in[DesignFormat.SPICE]]:
|
|
151
|
+
cdl_clean(open(file, encoding="utf8"), f)
|
|
152
|
+
kwargs, env = self.extract_env(kwargs)
|
|
153
|
+
|
|
154
|
+
env["DESIGN_NAME"] = self.config["DESIGN_NAME"]
|
|
155
|
+
|
|
156
|
+
# OL1 Nonsense
|
|
157
|
+
env["signoff_tmpfiles"] = self.step_dir
|
|
158
|
+
env["signoff_reports"] = self.step_dir
|
|
159
|
+
env["CVC_SCRIPTS_DIR"] = os.path.dirname(self.config["CVC_MODELS"])
|
|
160
|
+
|
|
161
|
+
log_file = os.path.join(self.step_dir, "cvc.log")
|
|
162
|
+
|
|
163
|
+
self.run_subprocess(
|
|
164
|
+
["cvc_rv", self.config["CVCRC"]], env=env, log_to=log_file, **kwargs
|
|
165
|
+
)
|
|
166
|
+
return {}, {}
|
|
167
|
+
except CVCNoSupport as e:
|
|
168
|
+
self.warn(f"Could not run CVC: {e}. Skipping…")
|
|
169
|
+
return {}, {}
|