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
librelane/steps/yosys.py
ADDED
|
@@ -0,0 +1,371 @@
|
|
|
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 textwrap
|
|
16
|
+
import subprocess
|
|
17
|
+
from abc import abstractmethod
|
|
18
|
+
from typing import List, Literal, Optional, Set, Tuple
|
|
19
|
+
|
|
20
|
+
from .tclstep import TclStep
|
|
21
|
+
from .step import ViewsUpdate, MetricsUpdate, Step
|
|
22
|
+
from .pyosys import JsonHeader, verilog_rtl_cfg_vars, Synthesis, VHDLSynthesis
|
|
23
|
+
|
|
24
|
+
from ..config import Variable, Config
|
|
25
|
+
from ..state import State, DesignFormat
|
|
26
|
+
from ..logging import info
|
|
27
|
+
from ..common import Path, Toolbox, TclUtils, process_list_file
|
|
28
|
+
|
|
29
|
+
# Re-export for back-compat
|
|
30
|
+
JsonHeader
|
|
31
|
+
Synthesis
|
|
32
|
+
VHDLSynthesis
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
# This is now only used by EQY since we moved our Yosys scripts to Python.
|
|
36
|
+
def _generate_read_deps(
|
|
37
|
+
config: Config,
|
|
38
|
+
toolbox: Toolbox,
|
|
39
|
+
power_defines: bool = False,
|
|
40
|
+
tcl: bool = True,
|
|
41
|
+
) -> str:
|
|
42
|
+
commands = ""
|
|
43
|
+
|
|
44
|
+
synth_defines = [
|
|
45
|
+
f"PDK_{config['PDK']}",
|
|
46
|
+
f"SCL_{config['STD_CELL_LIBRARY']}",
|
|
47
|
+
"__librelane__",
|
|
48
|
+
"__pnr__",
|
|
49
|
+
]
|
|
50
|
+
synth_defines += (
|
|
51
|
+
config.get("VERILOG_DEFINES") or []
|
|
52
|
+
) # VERILOG_DEFINES not defined for VHDLSynthesis
|
|
53
|
+
if tcl:
|
|
54
|
+
commands += "set ::_synlig_defines [list]\n"
|
|
55
|
+
for define in synth_defines:
|
|
56
|
+
commands += f"verilog_defines {TclUtils.escape(f'-D{define}')}\n"
|
|
57
|
+
if tcl:
|
|
58
|
+
commands += (
|
|
59
|
+
f"lappend ::_synlig_defines {TclUtils.escape(f'+define+{define}')}\n"
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
scl_lib_list = toolbox.filter_views(config, config["LIB"])
|
|
63
|
+
|
|
64
|
+
if power_defines:
|
|
65
|
+
if power_define := config.get(
|
|
66
|
+
"VERILOG_POWER_DEFINE"
|
|
67
|
+
): # VERILOG_POWER_DEFINE not defined for VHDLSynthesis
|
|
68
|
+
commands += f"verilog_defines {TclUtils.escape(f'-D{power_define}')}\n"
|
|
69
|
+
if tcl:
|
|
70
|
+
commands += f"lappend ::_synlig_defines {TclUtils.escape(f'+define+{power_define}')}\n"
|
|
71
|
+
|
|
72
|
+
# Try your best to use powered blackbox models if power_defines is true
|
|
73
|
+
if power_defines and config["CELL_VERILOG_MODELS"] is not None:
|
|
74
|
+
scl_blackbox_models = toolbox.create_blackbox_model(
|
|
75
|
+
frozenset(config["CELL_VERILOG_MODELS"]),
|
|
76
|
+
frozenset(["USE_POWER_PINS"]),
|
|
77
|
+
)
|
|
78
|
+
commands += f"read_verilog -sv -lib {scl_blackbox_models}\n"
|
|
79
|
+
else:
|
|
80
|
+
# Fall back to scl_lib_list if you cant
|
|
81
|
+
for lib in scl_lib_list:
|
|
82
|
+
lib_str = TclUtils.escape(str(lib))
|
|
83
|
+
commands += (
|
|
84
|
+
f"read_liberty -lib -ignore_miss_dir -setattr blackbox {lib_str}\n"
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
excluded_cells: Set[str] = set(config["EXTRA_EXCLUDED_CELLS"] or [])
|
|
88
|
+
excluded_cells.update(process_list_file(config["SYNTH_EXCLUDED_CELL_FILE"]))
|
|
89
|
+
excluded_cells.update(process_list_file(config["PNR_EXCLUDED_CELL_FILE"]))
|
|
90
|
+
|
|
91
|
+
lib_synth = toolbox.remove_cells_from_lib(
|
|
92
|
+
frozenset([str(lib) for lib in scl_lib_list]),
|
|
93
|
+
excluded_cells=frozenset(excluded_cells),
|
|
94
|
+
)
|
|
95
|
+
if tcl:
|
|
96
|
+
commands += (
|
|
97
|
+
f"set ::env(SYNTH_LIBS) {TclUtils.escape(TclUtils.join(lib_synth))}\n"
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
verilog_include_args = []
|
|
101
|
+
if dirs := config.get("VERILOG_INCLUDE_DIRS"):
|
|
102
|
+
for dir in dirs:
|
|
103
|
+
verilog_include_args.append(f"-I{dir}")
|
|
104
|
+
|
|
105
|
+
# Priorities from higher to lower
|
|
106
|
+
format_list = (
|
|
107
|
+
[
|
|
108
|
+
DesignFormat.VERILOG_HEADER,
|
|
109
|
+
DesignFormat.POWERED_NETLIST,
|
|
110
|
+
DesignFormat.NETLIST,
|
|
111
|
+
DesignFormat.LIB,
|
|
112
|
+
]
|
|
113
|
+
if power_defines
|
|
114
|
+
else [
|
|
115
|
+
DesignFormat.VERILOG_HEADER,
|
|
116
|
+
DesignFormat.NETLIST,
|
|
117
|
+
DesignFormat.POWERED_NETLIST,
|
|
118
|
+
DesignFormat.LIB,
|
|
119
|
+
]
|
|
120
|
+
)
|
|
121
|
+
for view, format in toolbox.get_macro_views_by_priority(config, format_list):
|
|
122
|
+
view_escaped = TclUtils.escape(str(view))
|
|
123
|
+
if format == DesignFormat.LIB:
|
|
124
|
+
commands += (
|
|
125
|
+
f"read_liberty -lib -ignore_miss_dir -setattr blackbox {view_escaped}\n"
|
|
126
|
+
)
|
|
127
|
+
else:
|
|
128
|
+
commands += f"read_verilog -sv -lib {TclUtils.join(verilog_include_args)} {view_escaped}\n"
|
|
129
|
+
|
|
130
|
+
if libs := config.get("EXTRA_LIBS"):
|
|
131
|
+
for lib in libs:
|
|
132
|
+
lib_str = TclUtils.escape(str(lib))
|
|
133
|
+
commands += (
|
|
134
|
+
f"read_liberty -lib -ignore_miss_dir -setattr blackbox {lib_str}\n"
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
if models := config["EXTRA_VERILOG_MODELS"]:
|
|
138
|
+
for model in models:
|
|
139
|
+
model_str = TclUtils.escape(str(model))
|
|
140
|
+
commands += f"read_verilog -sv -lib {TclUtils.join(verilog_include_args)} {model_str}\n"
|
|
141
|
+
|
|
142
|
+
return commands
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
# No longer used by us, kept for back-compat
|
|
146
|
+
class YosysStep(TclStep):
|
|
147
|
+
config_vars = [
|
|
148
|
+
Variable(
|
|
149
|
+
"SYNTH_LATCH_MAP",
|
|
150
|
+
Optional[Path],
|
|
151
|
+
"A path to a file containing the latch mapping for Yosys.",
|
|
152
|
+
pdk=True,
|
|
153
|
+
),
|
|
154
|
+
Variable(
|
|
155
|
+
"SYNTH_TRISTATE_MAP",
|
|
156
|
+
Optional[Path],
|
|
157
|
+
"A path to a file containing the tri-state buffer mapping for Yosys.",
|
|
158
|
+
deprecated_names=["TRISTATE_BUFFER_MAP"],
|
|
159
|
+
pdk=True,
|
|
160
|
+
),
|
|
161
|
+
Variable(
|
|
162
|
+
"SYNTH_CSA_MAP",
|
|
163
|
+
Optional[Path],
|
|
164
|
+
"A path to a file containing the carry-select adder mapping for Yosys.",
|
|
165
|
+
deprecated_names=["CARRY_SELECT_ADDER_MAP"],
|
|
166
|
+
pdk=True,
|
|
167
|
+
),
|
|
168
|
+
Variable(
|
|
169
|
+
"SYNTH_RCA_MAP",
|
|
170
|
+
Optional[Path],
|
|
171
|
+
"A path to a file containing the ripple-carry adder mapping for Yosys.",
|
|
172
|
+
deprecated_names=["RIPPLE_CARRY_ADDER_MAP"],
|
|
173
|
+
pdk=True,
|
|
174
|
+
),
|
|
175
|
+
Variable(
|
|
176
|
+
"SYNTH_FA_MAP",
|
|
177
|
+
Optional[Path],
|
|
178
|
+
"A path to a file containing the full adder mapping for Yosys.",
|
|
179
|
+
deprecated_names=["FULL_ADDER_MAP"],
|
|
180
|
+
pdk=True,
|
|
181
|
+
),
|
|
182
|
+
Variable(
|
|
183
|
+
"SYNTH_MUX_MAP",
|
|
184
|
+
Optional[Path],
|
|
185
|
+
"A path to a file containing the mux mapping for Yosys.",
|
|
186
|
+
pdk=True,
|
|
187
|
+
),
|
|
188
|
+
Variable(
|
|
189
|
+
"SYNTH_MUX4_MAP",
|
|
190
|
+
Optional[Path],
|
|
191
|
+
"A path to a file containing the mux4 mapping for Yosys.",
|
|
192
|
+
pdk=True,
|
|
193
|
+
),
|
|
194
|
+
Variable(
|
|
195
|
+
"USE_LIGHTER",
|
|
196
|
+
bool,
|
|
197
|
+
"Activates Lighter, an experimental plugin that attempts to optimize clock-gated flip-flops.",
|
|
198
|
+
default=False,
|
|
199
|
+
),
|
|
200
|
+
Variable(
|
|
201
|
+
"LIGHTER_DFF_MAP",
|
|
202
|
+
Optional[Path],
|
|
203
|
+
"An override to the custom DFF map file provided for the given SCL by Lighter.",
|
|
204
|
+
),
|
|
205
|
+
Variable(
|
|
206
|
+
"YOSYS_LOG_LEVEL",
|
|
207
|
+
Literal["ALL", "WARNING", "ERROR"],
|
|
208
|
+
"Which log level for Yosys. At WARNING or higher, the initialization splash is also disabled.",
|
|
209
|
+
default="ALL",
|
|
210
|
+
),
|
|
211
|
+
]
|
|
212
|
+
|
|
213
|
+
def get_command(self) -> List[str]:
|
|
214
|
+
script_path = self.get_script_path()
|
|
215
|
+
cmd = ["yosys", "-c", script_path]
|
|
216
|
+
if self.config["YOSYS_LOG_LEVEL"] != "ALL":
|
|
217
|
+
cmd += ["-Q"]
|
|
218
|
+
if self.config["YOSYS_LOG_LEVEL"] == "WARNING":
|
|
219
|
+
cmd += ["-q"]
|
|
220
|
+
elif self.config["YOSYS_LOG_LEVEL"] == "ERROR":
|
|
221
|
+
cmd += ["-qq"]
|
|
222
|
+
return cmd
|
|
223
|
+
|
|
224
|
+
@abstractmethod
|
|
225
|
+
def get_script_path(self) -> str:
|
|
226
|
+
pass
|
|
227
|
+
|
|
228
|
+
def run(self, state_in: State, **kwargs) -> Tuple[ViewsUpdate, MetricsUpdate]:
|
|
229
|
+
power_defines = False
|
|
230
|
+
if "power_defines" in kwargs:
|
|
231
|
+
power_defines = kwargs.pop("power_defines")
|
|
232
|
+
|
|
233
|
+
kwargs, env = self.extract_env(kwargs)
|
|
234
|
+
|
|
235
|
+
_deps_script = os.path.join(self.step_dir, "_deps.tcl")
|
|
236
|
+
|
|
237
|
+
with open(_deps_script, "w") as f:
|
|
238
|
+
f.write(
|
|
239
|
+
_generate_read_deps(
|
|
240
|
+
self.config, self.toolbox, power_defines=power_defines
|
|
241
|
+
)
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
env["_DEPS_SCRIPT"] = _deps_script
|
|
245
|
+
|
|
246
|
+
return super().run(state_in, env=env, **kwargs)
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
@Step.factory.register()
|
|
250
|
+
class EQY(Step):
|
|
251
|
+
id = "Yosys.EQY"
|
|
252
|
+
name = "Equivalence Check"
|
|
253
|
+
long_name = "RTL/Netlist Equivalence Check"
|
|
254
|
+
|
|
255
|
+
inputs = [DesignFormat.NETLIST]
|
|
256
|
+
outputs = []
|
|
257
|
+
|
|
258
|
+
config_vars = (
|
|
259
|
+
YosysStep.config_vars
|
|
260
|
+
+ verilog_rtl_cfg_vars
|
|
261
|
+
+ [
|
|
262
|
+
Variable(
|
|
263
|
+
"EQY_SCRIPT",
|
|
264
|
+
Optional[Path],
|
|
265
|
+
"An optional override for the automatically generated EQY script for more complex designs.",
|
|
266
|
+
),
|
|
267
|
+
Variable(
|
|
268
|
+
"MACRO_PLACEMENT_CFG",
|
|
269
|
+
Optional[Path],
|
|
270
|
+
"This step will warn if this deprecated variable is used, as it indicates Macros are used without the new Macro object.",
|
|
271
|
+
),
|
|
272
|
+
Variable(
|
|
273
|
+
"EQY_FORCE_ACCEPT_PDK",
|
|
274
|
+
bool,
|
|
275
|
+
"Attempt to run EQY even if the PDK's Verilog models are supported by this step. Will likely result in a failure.",
|
|
276
|
+
default=False,
|
|
277
|
+
),
|
|
278
|
+
]
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
def run(self, state_in: State, **kwargs) -> Tuple[ViewsUpdate, MetricsUpdate]:
|
|
282
|
+
processed_pdk = os.path.join(self.step_dir, "formal_pdk.v")
|
|
283
|
+
|
|
284
|
+
if self.config["PDK"].startswith("sky130A"):
|
|
285
|
+
subprocess.check_call(
|
|
286
|
+
[
|
|
287
|
+
"eqy.formal_pdk_proc",
|
|
288
|
+
"--output",
|
|
289
|
+
processed_pdk,
|
|
290
|
+
]
|
|
291
|
+
+ [str(model) for model in self.config["CELL_VERILOG_MODELS"]]
|
|
292
|
+
)
|
|
293
|
+
elif self.config["EQY_FORCE_ACCEPT_PDK"]:
|
|
294
|
+
subprocess.check_call(
|
|
295
|
+
["iverilog", "-E", "-o", processed_pdk, "-DFUNCTIONAL"]
|
|
296
|
+
+ [str(model) for model in self.config["CELL_VERILOG_MODELS"]]
|
|
297
|
+
)
|
|
298
|
+
else:
|
|
299
|
+
info(
|
|
300
|
+
f"PDK {self.config['PDK']} is not supported by the EQY step. Skipping…"
|
|
301
|
+
)
|
|
302
|
+
return {}, {}
|
|
303
|
+
|
|
304
|
+
eqy_script_path = os.path.join(
|
|
305
|
+
self.step_dir, f"{self.config['DESIGN_NAME']}.eqy"
|
|
306
|
+
)
|
|
307
|
+
|
|
308
|
+
with open(eqy_script_path, "w", encoding="utf8") as f:
|
|
309
|
+
if eqy_script := self.config["EQY_SCRIPT"]:
|
|
310
|
+
for line in open(eqy_script, "r", encoding="utf8"):
|
|
311
|
+
f.write(line)
|
|
312
|
+
else:
|
|
313
|
+
script = textwrap.dedent(
|
|
314
|
+
"""
|
|
315
|
+
[script]
|
|
316
|
+
{dep_commands}
|
|
317
|
+
blackbox
|
|
318
|
+
|
|
319
|
+
[gold]
|
|
320
|
+
read_verilog -formal -sv {files}
|
|
321
|
+
|
|
322
|
+
[gate]
|
|
323
|
+
read_verilog -formal -sv {processed_pdk} {nl}
|
|
324
|
+
|
|
325
|
+
[script]
|
|
326
|
+
hierarchy -top {design_name}
|
|
327
|
+
proc
|
|
328
|
+
prep -top {design_name} -flatten
|
|
329
|
+
|
|
330
|
+
memory -nomap
|
|
331
|
+
async2sync
|
|
332
|
+
|
|
333
|
+
[gold]
|
|
334
|
+
write_verilog {step_dir}/gold.v
|
|
335
|
+
|
|
336
|
+
[gate]
|
|
337
|
+
write_verilog {step_dir}/gate.v
|
|
338
|
+
|
|
339
|
+
[strategy sat]
|
|
340
|
+
use sat
|
|
341
|
+
depth 5
|
|
342
|
+
|
|
343
|
+
[strategy pdr]
|
|
344
|
+
use sby
|
|
345
|
+
engine abc pdr -rfi
|
|
346
|
+
|
|
347
|
+
[strategy bitwuzla]
|
|
348
|
+
use sby
|
|
349
|
+
depth 2
|
|
350
|
+
engine smtbmc bitwuzla
|
|
351
|
+
"""
|
|
352
|
+
).format(
|
|
353
|
+
design_name=self.config["DESIGN_NAME"],
|
|
354
|
+
dep_commands=_generate_read_deps(
|
|
355
|
+
self.config, self.toolbox, tcl=False
|
|
356
|
+
),
|
|
357
|
+
files=TclUtils.join(
|
|
358
|
+
[str(file) for file in self.config["VERILOG_FILES"]]
|
|
359
|
+
),
|
|
360
|
+
nl=state_in[DesignFormat.NETLIST],
|
|
361
|
+
processed_pdk=processed_pdk,
|
|
362
|
+
step_dir=self.step_dir,
|
|
363
|
+
)
|
|
364
|
+
f.write(script)
|
|
365
|
+
work_dir = os.path.join(self.step_dir, "scratch")
|
|
366
|
+
|
|
367
|
+
subprocess_result = self.run_subprocess(
|
|
368
|
+
["eqy", "-f", eqy_script_path, "-d", work_dir]
|
|
369
|
+
)
|
|
370
|
+
|
|
371
|
+
return {}, subprocess_result["generated_metrics"]
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: librelane
|
|
3
|
+
Version: 2.4.0.dev0
|
|
4
|
+
Summary: An infrastructure for implementing chip design flows
|
|
5
|
+
License: Apache-2.0
|
|
6
|
+
Author: Mohamed Gaber
|
|
7
|
+
Author-email: me@donn.website
|
|
8
|
+
Requires-Python: >=3.8,<4
|
|
9
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Requires-Dist: ciel (>=0.16.0)
|
|
18
|
+
Requires-Dist: click (>=8,<9)
|
|
19
|
+
Requires-Dist: cloup (>=3.0.5,<4)
|
|
20
|
+
Requires-Dist: deprecated (>=1.2.10,<2)
|
|
21
|
+
Requires-Dist: httpx (>=0.22.0,<0.29)
|
|
22
|
+
Requires-Dist: ioplace-parser (>=0.3.0,<0.5.0)
|
|
23
|
+
Requires-Dist: klayout (>=0.29.0,<0.30.0)
|
|
24
|
+
Requires-Dist: libparse (>=0.3.1,<1)
|
|
25
|
+
Requires-Dist: lxml (>=4.9.0)
|
|
26
|
+
Requires-Dist: psutil (>=5.9.0)
|
|
27
|
+
Requires-Dist: pyyaml (>=5,<7)
|
|
28
|
+
Requires-Dist: rapidfuzz (>=3.9.0,<4)
|
|
29
|
+
Requires-Dist: rich (>=12,<14)
|
|
30
|
+
Requires-Dist: semver (>=3.0.2,<4.0.0)
|
|
31
|
+
Requires-Dist: yamlcore (>=0.0.2,<0.0.3)
|
|
32
|
+
Project-URL: Documentation, https://librelane.readthedocs.io
|
|
33
|
+
Project-URL: Repository, https://github.com/librelane/librelane
|
|
34
|
+
Description-Content-Type: text/markdown
|
|
35
|
+
|
|
36
|
+
<h1 align="center">LibreLane</h1>
|
|
37
|
+
<p align="center">
|
|
38
|
+
<a href="https://opensource.org/licenses/Apache-2.0"><img src="https://img.shields.io/badge/License-Apache%202.0-blue.svg" alt="License: Apache 2.0"/></a>
|
|
39
|
+
<a href="https://www.python.org"><img src="https://img.shields.io/badge/Python-3.8-3776AB.svg?style=flat&logo=python&logoColor=white" alt="Python 3.8 or higher" /></a>
|
|
40
|
+
<a href="https://github.com/psf/black"><img src="https://img.shields.io/badge/code%20style-black-000000.svg" alt="Code Style: black"/></a>
|
|
41
|
+
<a href="https://mypy-lang.org/"><img src="https://www.mypy-lang.org/static/mypy_badge.svg" alt="Checked with mypy"/></a>
|
|
42
|
+
<a href="https://nixos.org/"><img src="https://img.shields.io/static/v1?logo=nixos&logoColor=white&label=&message=Built%20with%20Nix&color=41439a" alt="Built with Nix"/></a>
|
|
43
|
+
</p>
|
|
44
|
+
<p align="center">
|
|
45
|
+
<a href="https://colab.research.google.com/github/librelane/librelane/blob/main/notebook.ipynb"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open in Colab"></a>
|
|
46
|
+
<a href="https://librelane.readthedocs.io/"><img src="https://readthedocs.org/projects/librelane/badge/?version=latest" alt="Documentation Build Status Badge"/></a>
|
|
47
|
+
<a href="https://fossi-chat.org"><img src="https://img.shields.io/badge/Community-FOSSi%20Chat-1bb378?logo=element" alt="Invite to FOSSi Chat"/></a>
|
|
48
|
+
</p>
|
|
49
|
+
|
|
50
|
+
LibreLane is an ASIC infrastructure library based on several components including
|
|
51
|
+
OpenROAD, Yosys, Magic, Netgen, CVC, KLayout and a number of custom scripts for
|
|
52
|
+
design exploration and optimization, currently developed and maintained by the
|
|
53
|
+
American University in Cairo Open Hardware Lab (AUCOHL.)
|
|
54
|
+
|
|
55
|
+
A reference flow, "Classic", performs all ASIC implementation steps from RTL all
|
|
56
|
+
the way down to GDSII.
|
|
57
|
+
|
|
58
|
+
You can find the documentation
|
|
59
|
+
[here](https://librelane.readthedocs.io/en/latest/getting_started/) to get
|
|
60
|
+
started. You can discuss LibreLane in the
|
|
61
|
+
[FOSSi Chat Matrix Server](https://fossi-chat.org).
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
## Try it out
|
|
65
|
+
|
|
66
|
+
You can try LibreLane right in your browser, free-of-charge, using Google
|
|
67
|
+
Colaboratory by following
|
|
68
|
+
[**this link**](https://colab.research.google.com/github/librelane/librelane/blob/main/notebook.ipynb).
|
|
69
|
+
|
|
70
|
+
## Installation
|
|
71
|
+
|
|
72
|
+
You'll need the following:
|
|
73
|
+
|
|
74
|
+
* Python **3.8** or higher with PIP, Venv and Tkinter
|
|
75
|
+
|
|
76
|
+
### Nix (Recommended)
|
|
77
|
+
|
|
78
|
+
Works for macOS and Linux (x86-64 and aarch64). Recommended, as it is more
|
|
79
|
+
integrated with your filesystem and overall has less upload and download deltas.
|
|
80
|
+
|
|
81
|
+
See
|
|
82
|
+
[Nix-based installation](https://librelane.readthedocs.io/en/latest/getting_started/common/nix_installation/index.html)
|
|
83
|
+
in the docs for more info.
|
|
84
|
+
|
|
85
|
+
### Docker
|
|
86
|
+
|
|
87
|
+
Works for Windows, macOS and Linux (x86-64 and aarch64).
|
|
88
|
+
|
|
89
|
+
See
|
|
90
|
+
[Docker-based installation](https://librelane.readthedocs.io/en/latest/getting_started/common/docker_installation/index.html)
|
|
91
|
+
in the docs for more info.
|
|
92
|
+
|
|
93
|
+
Do note you'll need to add `--dockerized` right after `librelane` in most CLI
|
|
94
|
+
invocations.
|
|
95
|
+
|
|
96
|
+
### Python-only Installation (Advanced, Not Recommended)
|
|
97
|
+
|
|
98
|
+
**You'll need to bring your own compiled utilities**, but otherwise, simply
|
|
99
|
+
install LibreLane as follows:
|
|
100
|
+
|
|
101
|
+
```sh
|
|
102
|
+
python3 -m pip install --upgrade librelane
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Python-only installations are presently unsupported and entirely at your own
|
|
106
|
+
risk.
|
|
107
|
+
|
|
108
|
+
## Usage
|
|
109
|
+
|
|
110
|
+
In the root folder of the repository, you may invoke:
|
|
111
|
+
|
|
112
|
+
```sh
|
|
113
|
+
python3 -m librelane --pdk-root <path/to/pdk> </path/to/config.json>
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
To start with, you can try:
|
|
117
|
+
|
|
118
|
+
```sh
|
|
119
|
+
python3 -m librelane --pdk-root $HOME/.ciel ./designs/spm/config.json
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Publication
|
|
123
|
+
|
|
124
|
+
If you use LibreLane in your research, please cite the following paper.
|
|
125
|
+
|
|
126
|
+
* M. Shalan and T. Edwards, “Building OpenLANE: A 130nm OpenROAD-based
|
|
127
|
+
Tapeout-Proven Flow: Invited Paper,” *2020 IEEE/ACM International Conference
|
|
128
|
+
On Computer Aided Design (ICCAD)*, San Diego, CA, USA, 2020, pp. 1-6.
|
|
129
|
+
[Paper](https://ieeexplore.ieee.org/document/9256623)
|
|
130
|
+
|
|
131
|
+
```bibtex
|
|
132
|
+
@INPROCEEDINGS{9256623,
|
|
133
|
+
author={Shalan, Mohamed and Edwards, Tim},
|
|
134
|
+
booktitle={2020 IEEE/ACM International Conference On Computer Aided Design (ICCAD)},
|
|
135
|
+
title={Building OpenLANE: A 130nm OpenROAD-based Tapeout- Proven Flow : Invited Paper},
|
|
136
|
+
year={2020},
|
|
137
|
+
volume={},
|
|
138
|
+
number={},
|
|
139
|
+
pages={1-6},
|
|
140
|
+
doi={}}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## License and Legal Info
|
|
144
|
+
|
|
145
|
+
LibreLane is a trademark of the FOSSi Foundation.
|
|
146
|
+
|
|
147
|
+
[The Apache License, version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt).
|
|
148
|
+
|
|
149
|
+
LibreLane is based on OpenLane 2.0 by Efabless Corporation
|
|
150
|
+
(https://github.com/efabless/openlane2) under the same license.
|
|
151
|
+
|