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,173 @@
|
|
|
1
|
+
# Copyright 2021-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
|
+
import odb
|
|
15
|
+
|
|
16
|
+
import re
|
|
17
|
+
from typing import List
|
|
18
|
+
|
|
19
|
+
from reader import click_odb, click
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def get_pin_name(pin: odb.dbITerm):
|
|
23
|
+
cell = pin.getInst()
|
|
24
|
+
cell_name = cell.getName()
|
|
25
|
+
master_pin = pin.getMTerm()
|
|
26
|
+
master_pin_name = master_pin.getConstName()
|
|
27
|
+
return f"{cell_name}/{master_pin_name}"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def get_sinks_terms(net: odb.dbNet) -> List[odb.dbITerm]:
|
|
31
|
+
sinks = []
|
|
32
|
+
for it in net.getITerms():
|
|
33
|
+
cell = it.getInst()
|
|
34
|
+
cell_pin = it.getMTerm()
|
|
35
|
+
|
|
36
|
+
master_instance = cell.getMaster()
|
|
37
|
+
master_name = master_instance.getConstName()
|
|
38
|
+
|
|
39
|
+
if cell_pin.getIoType() == "INPUT":
|
|
40
|
+
print(
|
|
41
|
+
f" * Net {net.getConstName()} sinks into {get_pin_name(it)} ({master_name})..."
|
|
42
|
+
)
|
|
43
|
+
sinks.append(it)
|
|
44
|
+
|
|
45
|
+
return sinks
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def get_drivers(net: odb.dbNet) -> List[odb.dbInst]:
|
|
49
|
+
drivers = []
|
|
50
|
+
for it in net.getITerms():
|
|
51
|
+
cell = it.getInst()
|
|
52
|
+
cell_pin = it.getMTerm()
|
|
53
|
+
|
|
54
|
+
master_instance = cell.getMaster()
|
|
55
|
+
master_name = master_instance.getConstName()
|
|
56
|
+
|
|
57
|
+
if cell_pin.getIoType() == "OUTPUT":
|
|
58
|
+
print(
|
|
59
|
+
f" * Net {net.getConstName()} is driven by {get_pin_name(it)} ({master_name})..."
|
|
60
|
+
)
|
|
61
|
+
drivers.append(cell)
|
|
62
|
+
|
|
63
|
+
return drivers
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def get_io(cell: odb.dbInst):
|
|
67
|
+
inputs = []
|
|
68
|
+
outputs = []
|
|
69
|
+
for iterm in cell.getITerms():
|
|
70
|
+
if iterm.isSpecial(): # Skip special nets
|
|
71
|
+
continue
|
|
72
|
+
|
|
73
|
+
if iterm.isInputSignal():
|
|
74
|
+
input_pin_net = iterm.getNet()
|
|
75
|
+
inputs.append((iterm, input_pin_net))
|
|
76
|
+
|
|
77
|
+
if iterm.isOutputSignal():
|
|
78
|
+
output_pin_net = iterm.getNet()
|
|
79
|
+
outputs.append((iterm, output_pin_net))
|
|
80
|
+
|
|
81
|
+
return inputs, outputs
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
@click.command()
|
|
85
|
+
@click.option(
|
|
86
|
+
"-m",
|
|
87
|
+
"--match",
|
|
88
|
+
"rx_str",
|
|
89
|
+
required=True,
|
|
90
|
+
help="A regular expression matching all nets to remove.",
|
|
91
|
+
)
|
|
92
|
+
@click_odb
|
|
93
|
+
def remove_buffers(reader, rx_str):
|
|
94
|
+
if rx_str != "^$":
|
|
95
|
+
# Save some compute time :)
|
|
96
|
+
|
|
97
|
+
rx = re.compile(rx_str)
|
|
98
|
+
|
|
99
|
+
design_nets = reader.block.getNets()
|
|
100
|
+
dont_buffer_nets = [
|
|
101
|
+
net for net in design_nets if rx.match(net.getConstName()) is not None
|
|
102
|
+
]
|
|
103
|
+
|
|
104
|
+
for net in dont_buffer_nets:
|
|
105
|
+
net_name = net.getConstName()
|
|
106
|
+
print(f"* Attempting to unbuffer {net_name}...")
|
|
107
|
+
# get the cells driving the dont buffer net
|
|
108
|
+
drivers = get_drivers(net)
|
|
109
|
+
|
|
110
|
+
if len(drivers) > 1:
|
|
111
|
+
print(f"Net {net_name} is driven by multiple cells.")
|
|
112
|
+
exit(1)
|
|
113
|
+
elif len(drivers) == 0:
|
|
114
|
+
print(f"Net {net_name} is not driven by any cell..")
|
|
115
|
+
exit(1)
|
|
116
|
+
|
|
117
|
+
buffer = drivers[0]
|
|
118
|
+
buffer_name = drivers[0].getName()
|
|
119
|
+
master = buffer.getMaster()
|
|
120
|
+
master_name = master.getConstName()
|
|
121
|
+
|
|
122
|
+
if "buf" not in master_name:
|
|
123
|
+
print(
|
|
124
|
+
f"* {net_name} isn't driven by a buffer cell. It is driven by {buffer_name} ({master_name}). Skipping..."
|
|
125
|
+
)
|
|
126
|
+
continue
|
|
127
|
+
|
|
128
|
+
# get the net connected to the input pin of this buffer
|
|
129
|
+
inputs, outputs = get_io(buffer)
|
|
130
|
+
|
|
131
|
+
if len(inputs) != 1:
|
|
132
|
+
print(
|
|
133
|
+
f"* {master_name} has more than one output port. Doesn't appear to actually be a buffer. Skipping..."
|
|
134
|
+
)
|
|
135
|
+
continue
|
|
136
|
+
if len(outputs) != 1:
|
|
137
|
+
print(
|
|
138
|
+
f"{master_name} has more than one output port. Doesn't appear to actually be a buffer. Skipping..."
|
|
139
|
+
)
|
|
140
|
+
continue
|
|
141
|
+
|
|
142
|
+
_, input_net = inputs[0]
|
|
143
|
+
_, output_net = outputs[0]
|
|
144
|
+
|
|
145
|
+
print(" * Reconnecting IO...")
|
|
146
|
+
# We connect the driver's output to the output_net: there may not be a
|
|
147
|
+
# sink with ITerms in case of things like output ports for example.
|
|
148
|
+
buffer_input_driver = get_drivers(input_net)[0]
|
|
149
|
+
_, bid_outputs = get_io(buffer_input_driver)
|
|
150
|
+
(bid_iterm, _) = bid_outputs[0]
|
|
151
|
+
bid_iterm.connect(output_net)
|
|
152
|
+
print(
|
|
153
|
+
f" * Connected buffer output({output_net.getConstName()}) to {get_pin_name(bid_iterm)}."
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
print(f" * Removing buffer {buffer_name} ({master_name})...")
|
|
157
|
+
odb.dbInst.destroy(buffer)
|
|
158
|
+
|
|
159
|
+
input_net_sinks = get_sinks_terms(input_net)
|
|
160
|
+
for iterm in input_net_sinks:
|
|
161
|
+
iterm.connect(output_net)
|
|
162
|
+
print(
|
|
163
|
+
f" * Connected buffer output({output_net.getConstName()}) to {get_pin_name(iterm)}."
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
print(f" * Removing net {input_net.getName()}...")
|
|
167
|
+
odb.dbNet.destroy(input_net)
|
|
168
|
+
|
|
169
|
+
print(" * Done.")
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
if __name__ == "__main__":
|
|
173
|
+
remove_buffers()
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Copyright 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
|
+
import math
|
|
15
|
+
from decimal import Decimal
|
|
16
|
+
|
|
17
|
+
from reader import OdbReader, click
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def snap_value(value: Decimal, manufacturing_grid: Decimal) -> Decimal:
|
|
21
|
+
adjusted = math.floor(value / manufacturing_grid) * manufacturing_grid
|
|
22
|
+
if adjusted == Decimal(0):
|
|
23
|
+
adjusted = math.ceil(value / manufacturing_grid) * manufacturing_grid
|
|
24
|
+
return adjusted
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@click.command()
|
|
28
|
+
@click.option(
|
|
29
|
+
"-o",
|
|
30
|
+
"--output",
|
|
31
|
+
required=True,
|
|
32
|
+
help="A text file to which final values are output.",
|
|
33
|
+
)
|
|
34
|
+
@click.option(
|
|
35
|
+
"-l",
|
|
36
|
+
"--input-lef",
|
|
37
|
+
required=True,
|
|
38
|
+
help="Input LEF file (for the manufacturing grid)",
|
|
39
|
+
)
|
|
40
|
+
@click.argument("input_values", type=Decimal, nargs=-1)
|
|
41
|
+
def cli(output, input_lef, input_values):
|
|
42
|
+
reader = OdbReader(input_lef, None)
|
|
43
|
+
manufacturing_grid = Decimal(reader.db.getTech().getManufacturingGrid()) / Decimal(
|
|
44
|
+
reader.db.getTech().getDbUnitsPerMicron()
|
|
45
|
+
)
|
|
46
|
+
with open(output, "w") as f:
|
|
47
|
+
print(
|
|
48
|
+
" ".join(
|
|
49
|
+
[str(snap_value(value, manufacturing_grid)) for value in input_values]
|
|
50
|
+
),
|
|
51
|
+
end="",
|
|
52
|
+
file=f,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
if __name__ == "__main__":
|
|
57
|
+
cli()
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Copyright 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
|
+
from decimal import Decimal
|
|
15
|
+
|
|
16
|
+
import utl
|
|
17
|
+
|
|
18
|
+
from reader import click, click_odb, OdbReader
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def to_si(microns: Decimal) -> str:
|
|
22
|
+
units = ["µm", "mm", "m"]
|
|
23
|
+
unit = 0
|
|
24
|
+
value = microns
|
|
25
|
+
while value >= 1000 and unit < len(units):
|
|
26
|
+
value /= 1000
|
|
27
|
+
unit += 1
|
|
28
|
+
return f"{value}{units[unit]}"
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@click.command()
|
|
32
|
+
@click.option(
|
|
33
|
+
"-h",
|
|
34
|
+
"--human-readable",
|
|
35
|
+
default=False,
|
|
36
|
+
is_flag=True,
|
|
37
|
+
help="Print with SI units instead of database units.",
|
|
38
|
+
)
|
|
39
|
+
@click.option(
|
|
40
|
+
"-t",
|
|
41
|
+
"--threshold",
|
|
42
|
+
default=Decimal("Infinity"),
|
|
43
|
+
type=Decimal,
|
|
44
|
+
help="Threshold above which to print the wire (Default: ∞)",
|
|
45
|
+
)
|
|
46
|
+
@click.option(
|
|
47
|
+
"-R",
|
|
48
|
+
"--report-out",
|
|
49
|
+
default=None,
|
|
50
|
+
help="Output to print CSV file to. (Default: input + .wire_lengths.csv)",
|
|
51
|
+
)
|
|
52
|
+
@click_odb
|
|
53
|
+
def main(
|
|
54
|
+
report_out,
|
|
55
|
+
threshold,
|
|
56
|
+
human_readable,
|
|
57
|
+
input_db,
|
|
58
|
+
reader: OdbReader,
|
|
59
|
+
):
|
|
60
|
+
db = reader.db
|
|
61
|
+
if report_out is None:
|
|
62
|
+
report_out = f"{input_db}.wire_length.csv"
|
|
63
|
+
|
|
64
|
+
block = db.getChip().getBlock()
|
|
65
|
+
dbunits = block.getDefUnits()
|
|
66
|
+
nets = list(filter(lambda net: net.getWire() is not None, block.getNets()))
|
|
67
|
+
nets.sort(key=lambda net: net.getWire().getLength(), reverse=True)
|
|
68
|
+
|
|
69
|
+
max_wire_length = 0
|
|
70
|
+
above_threshold = []
|
|
71
|
+
with open(report_out, "w") as f:
|
|
72
|
+
print("net,length_um", file=f)
|
|
73
|
+
for net in nets:
|
|
74
|
+
length = net.getWire().getLength()
|
|
75
|
+
length_microns = Decimal(length) / Decimal(dbunits)
|
|
76
|
+
max_wire_length = max(length_microns, max_wire_length)
|
|
77
|
+
if length_microns >= threshold:
|
|
78
|
+
above_threshold.append((net, length_microns))
|
|
79
|
+
length_printable: str = str(length_microns)
|
|
80
|
+
if human_readable:
|
|
81
|
+
length_printable = str(to_si(length_microns))
|
|
82
|
+
print(f"{net.getName()},{length_printable}", file=f)
|
|
83
|
+
|
|
84
|
+
for net, length_microns in above_threshold:
|
|
85
|
+
print(
|
|
86
|
+
f"Net {net.getName()} is above the length threshold ({length_microns}/{threshold} µm)."
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
utl.metric_float("route__wirelength__max", float(max_wire_length))
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
if __name__ == "__main__":
|
|
93
|
+
main()
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Copyright 2020-2022 Efabless Corporation
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
source $::env(SCRIPTS_DIR)/openroad/common/io.tcl
|
|
15
|
+
read_current_odb
|
|
16
|
+
|
|
17
|
+
# start checking antennas and generate a detailed report
|
|
18
|
+
puts "%OL_CREATE_REPORT $::env(_ANTENNA_REPORT)"
|
|
19
|
+
check_antennas -verbose
|
|
20
|
+
puts "%OL_END_REPORT"
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Copyright 2020-2022 Efabless Corporation
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
source $::env(SCRIPTS_DIR)/openroad/common/io.tcl
|
|
15
|
+
read_current_odb
|
|
16
|
+
source $::env(SCRIPTS_DIR)/openroad/common/dpl_cell_pad.tcl
|
|
17
|
+
|
|
18
|
+
set_propagated_clock [all_clocks]
|
|
19
|
+
|
|
20
|
+
source $::env(SCRIPTS_DIR)/openroad/common/grt.tcl
|
|
21
|
+
|
|
22
|
+
set diode_split [split $::env(DIODE_CELL) "/"]
|
|
23
|
+
repair_antennas "[lindex $diode_split 0]" -iterations $::env(GRT_ANTENNA_ITERS) -ratio_margin $::env(GRT_ANTENNA_MARGIN)
|
|
24
|
+
|
|
25
|
+
source $::env(SCRIPTS_DIR)/openroad/common/dpl.tcl
|
|
26
|
+
source $::env(SCRIPTS_DIR)/openroad/common/grt.tcl
|
|
27
|
+
|
|
28
|
+
source $::env(SCRIPTS_DIR)/openroad/common/set_rc.tcl
|
|
29
|
+
estimate_parasitics -global_routing
|
|
30
|
+
|
|
31
|
+
write_views
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Copyright 2020-2022 Efabless Corporation
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
source $::env(SCRIPTS_DIR)/openroad/common/io.tcl
|
|
15
|
+
read_current_odb
|
|
16
|
+
|
|
17
|
+
macro_placement\
|
|
18
|
+
-channel $::env(PL_MACRO_CHANNEL)\
|
|
19
|
+
-halo $::env(PL_MACRO_HALO)
|
|
20
|
+
|
|
21
|
+
write_views
|
|
22
|
+
|
|
23
|
+
report_design_area_metrics
|
|
24
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Copyright 2022 Efabless Corporation
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
source $::env(SCRIPTS_DIR)/openroad/common/dpl_cell_pad.tcl
|
|
15
|
+
|
|
16
|
+
remove_fillers
|
|
17
|
+
|
|
18
|
+
detailed_placement\
|
|
19
|
+
-max_displacement [subst { $::env(PL_MAX_DISPLACEMENT_X) $::env(PL_MAX_DISPLACEMENT_Y) }]
|
|
20
|
+
|
|
21
|
+
if { [info exists ::env(PL_OPTIMIZE_MIRRORING)] && $::env(PL_OPTIMIZE_MIRRORING) } {
|
|
22
|
+
optimize_mirroring
|
|
23
|
+
}
|
|
24
|
+
check_placement -verbose
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Copyright 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
|
+
set cell_pad_value $::env(DPL_CELL_PADDING)
|
|
15
|
+
|
|
16
|
+
set cell_pad_side [expr $cell_pad_value / 2]
|
|
17
|
+
|
|
18
|
+
set_placement_padding -global -right $cell_pad_side -left $cell_pad_side
|
|
19
|
+
|
|
20
|
+
foreach wildcard $::env(CELL_PAD_EXCLUDE) {
|
|
21
|
+
set_placement_padding -masters $wildcard -right 0 -left 0
|
|
22
|
+
}
|
|
23
|
+
if { [info exists ::env(DIODE_PADDING)] && $::env(DIODE_PADDING) } {
|
|
24
|
+
set diode_split [split $::env(DIODE_CELL) "/"]
|
|
25
|
+
set_placement_padding -masters [lindex $diode_split 0] -left $::env(DIODE_PADDING)
|
|
26
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Copyright 2022-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
|
+
if { ![info exists ::grt_preamble] } {
|
|
15
|
+
set ::grt_preamble 1
|
|
16
|
+
|
|
17
|
+
source $::env(SCRIPTS_DIR)/openroad/common/set_routing_layers.tcl
|
|
18
|
+
source $::env(SCRIPTS_DIR)/openroad/common/set_layer_adjustments.tcl
|
|
19
|
+
|
|
20
|
+
set_macro_extension $::env(GRT_MACRO_EXTENSION)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
set arg_list [list]
|
|
24
|
+
lappend arg_list -congestion_iterations $::env(GRT_OVERFLOW_ITERS)
|
|
25
|
+
lappend arg_list -verbose
|
|
26
|
+
if { $::env(GRT_ALLOW_CONGESTION) == 1 } {
|
|
27
|
+
lappend arg_list -allow_congestion
|
|
28
|
+
}
|
|
29
|
+
puts $arg_list
|
|
30
|
+
global_route {*}$arg_list
|
|
31
|
+
|
|
32
|
+
write_guide $::env(STEP_DIR)/after_grt.guide
|