librelane 2.4.0.dev3__py3-none-any.whl → 2.4.0.dev5__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/common/cli.py +1 -1
- librelane/common/metrics/__main__.py +1 -1
- librelane/state/design_format.py +16 -1
- librelane/steps/openroad.py +19 -14
- librelane/steps/pyosys.py +12 -1
- librelane/steps/step.py +12 -3
- {librelane-2.4.0.dev3.dist-info → librelane-2.4.0.dev5.dist-info}/METADATA +2 -2
- {librelane-2.4.0.dev3.dist-info → librelane-2.4.0.dev5.dist-info}/RECORD +10 -10
- {librelane-2.4.0.dev3.dist-info → librelane-2.4.0.dev5.dist-info}/WHEEL +0 -0
- {librelane-2.4.0.dev3.dist-info → librelane-2.4.0.dev5.dist-info}/entry_points.txt +0 -0
librelane/common/cli.py
CHANGED
|
@@ -67,7 +67,7 @@ class IntEnumChoice(Choice):
|
|
|
67
67
|
f"{value} is not a not a valid value for IntEnum {self.__enum.__name__}"
|
|
68
68
|
)
|
|
69
69
|
|
|
70
|
-
def get_metavar(self, param:
|
|
70
|
+
def get_metavar(self, param: Parameter) -> str:
|
|
71
71
|
_bk = self.choices
|
|
72
72
|
self.choices = [f"{e.name} or {e.value}" for e in self.__enum]
|
|
73
73
|
result = super().get_metavar(param)
|
librelane/state/design_format.py
CHANGED
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
from enum import Enum
|
|
15
|
-
from dataclasses import dataclass
|
|
16
15
|
from typing import Dict, Optional
|
|
16
|
+
from dataclasses import dataclass, replace
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
@dataclass
|
|
@@ -44,10 +44,16 @@ class DesignFormatObject:
|
|
|
44
44
|
folder_override: Optional[str] = None
|
|
45
45
|
multiple: bool = False
|
|
46
46
|
|
|
47
|
+
_instance_optional: bool = False
|
|
48
|
+
|
|
47
49
|
@property
|
|
48
50
|
def folder(self) -> str:
|
|
49
51
|
return self.folder_override or self.id
|
|
50
52
|
|
|
53
|
+
@property
|
|
54
|
+
def optional(self) -> bool:
|
|
55
|
+
return self._instance_optional
|
|
56
|
+
|
|
51
57
|
|
|
52
58
|
class DesignFormat(Enum):
|
|
53
59
|
"""
|
|
@@ -174,6 +180,15 @@ class DesignFormat(Enum):
|
|
|
174
180
|
def by_id(id: str) -> Optional["DesignFormat"]:
|
|
175
181
|
return _designformat_by_id.get(id)
|
|
176
182
|
|
|
183
|
+
def mkOptional(self) -> "DesignFormat":
|
|
184
|
+
# HACK: Create ephemeral DesignFormat copy until 3.0.0 lets us do this
|
|
185
|
+
# a bit more appropriately.
|
|
186
|
+
clone = object.__new__(DesignFormat)
|
|
187
|
+
clone._name_ = self._name_
|
|
188
|
+
clone._value_ = replace(self._value_)
|
|
189
|
+
clone._value_._instance_optional = True
|
|
190
|
+
return clone
|
|
191
|
+
|
|
177
192
|
|
|
178
193
|
_designformat_by_id: Dict[str, "DesignFormat"] = {
|
|
179
194
|
format.value.id: format for format in DesignFormat
|
librelane/steps/openroad.py
CHANGED
|
@@ -778,7 +778,10 @@ class STAPostPNR(STAPrePNR):
|
|
|
778
778
|
),
|
|
779
779
|
]
|
|
780
780
|
|
|
781
|
-
inputs = STAPrePNR.inputs + [
|
|
781
|
+
inputs = STAPrePNR.inputs + [
|
|
782
|
+
DesignFormat.SPEF,
|
|
783
|
+
DesignFormat.ODB.mkOptional(),
|
|
784
|
+
]
|
|
782
785
|
outputs = STAPrePNR.outputs + [DesignFormat.LIB]
|
|
783
786
|
|
|
784
787
|
def prepare_env(self, env: dict, state: State) -> dict:
|
|
@@ -851,19 +854,21 @@ class STAPostPNR(STAPrePNR):
|
|
|
851
854
|
) -> MetricsUpdate:
|
|
852
855
|
current_env["_LIB_SAVE_DIR"] = corner_dir
|
|
853
856
|
metrics_updates = super().run_corner(state_in, current_env, corner, corner_dir)
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
857
|
+
filter_unannotated_metrics = {}
|
|
858
|
+
if odb := state_in[DesignFormat.ODB]:
|
|
859
|
+
try:
|
|
860
|
+
filter_unannotated_metrics = self.filter_unannotated_report(
|
|
861
|
+
corner=corner,
|
|
862
|
+
checks_report=os.path.join(corner_dir, "checks.rpt"),
|
|
863
|
+
corner_dir=corner_dir,
|
|
864
|
+
env=current_env,
|
|
865
|
+
odb_design=str(odb),
|
|
866
|
+
)
|
|
867
|
+
except subprocess.CalledProcessError as e:
|
|
868
|
+
self.err(
|
|
869
|
+
f"Failed filtering unannotated nets for the {corner} timing corner."
|
|
870
|
+
)
|
|
871
|
+
raise e
|
|
867
872
|
return {**metrics_updates, **filter_unannotated_metrics}
|
|
868
873
|
|
|
869
874
|
def run(self, state_in: State, **kwargs) -> Tuple[ViewsUpdate, MetricsUpdate]:
|
librelane/steps/pyosys.py
CHANGED
|
@@ -14,8 +14,10 @@
|
|
|
14
14
|
import os
|
|
15
15
|
import re
|
|
16
16
|
import io
|
|
17
|
+
import sys
|
|
17
18
|
import json
|
|
18
19
|
import fnmatch
|
|
20
|
+
import shutil
|
|
19
21
|
import subprocess
|
|
20
22
|
from decimal import Decimal
|
|
21
23
|
from abc import abstractmethod
|
|
@@ -207,7 +209,11 @@ class PyosysStep(Step):
|
|
|
207
209
|
|
|
208
210
|
def get_command(self, state_in: State) -> List[str]:
|
|
209
211
|
script_path = self.get_script_path()
|
|
210
|
-
|
|
212
|
+
# HACK: Get Colab working
|
|
213
|
+
yosys_bin = "yosys"
|
|
214
|
+
if "google.colab" in sys.modules:
|
|
215
|
+
yosys_bin = shutil.which("yosys") or "yosys"
|
|
216
|
+
cmd = [yosys_bin, "-y", script_path]
|
|
211
217
|
if self.config["YOSYS_LOG_LEVEL"] != "ALL":
|
|
212
218
|
cmd += ["-Q"]
|
|
213
219
|
if self.config["YOSYS_LOG_LEVEL"] == "WARNING":
|
|
@@ -220,6 +226,11 @@ class PyosysStep(Step):
|
|
|
220
226
|
|
|
221
227
|
def run(self, state_in: State, **kwargs) -> Tuple[ViewsUpdate, MetricsUpdate]:
|
|
222
228
|
cmd = self.get_command(state_in)
|
|
229
|
+
# HACK: Get Colab working
|
|
230
|
+
if "google.colab" in sys.modules:
|
|
231
|
+
kwargs, env = self.extract_env(kwargs)
|
|
232
|
+
env.pop("PATH", "")
|
|
233
|
+
kwargs["env"] = env
|
|
223
234
|
subprocess_result = super().run_subprocess(cmd, **kwargs)
|
|
224
235
|
return {}, subprocess_result["generated_metrics"]
|
|
225
236
|
|
librelane/steps/step.py
CHANGED
|
@@ -53,7 +53,13 @@ from ..config import (
|
|
|
53
53
|
Variable,
|
|
54
54
|
universal_flow_config_variables,
|
|
55
55
|
)
|
|
56
|
-
from ..state import
|
|
56
|
+
from ..state import (
|
|
57
|
+
DesignFormat,
|
|
58
|
+
DesignFormatObject,
|
|
59
|
+
State,
|
|
60
|
+
InvalidState,
|
|
61
|
+
StateElement,
|
|
62
|
+
)
|
|
57
63
|
from ..common import (
|
|
58
64
|
GenericDict,
|
|
59
65
|
GenericImmutableDict,
|
|
@@ -661,7 +667,10 @@ class Step(ABC):
|
|
|
661
667
|
for input, output in zip_longest(Self.inputs, Self.outputs):
|
|
662
668
|
input_str = ""
|
|
663
669
|
if input is not None:
|
|
664
|
-
|
|
670
|
+
optional = "?" if input.value.optional else ""
|
|
671
|
+
input_str = (
|
|
672
|
+
f"{input.value.name}{optional} (.{input.value.extension})"
|
|
673
|
+
)
|
|
665
674
|
|
|
666
675
|
output_str = ""
|
|
667
676
|
if output is not None:
|
|
@@ -1141,7 +1150,7 @@ class Step(ABC):
|
|
|
1141
1150
|
|
|
1142
1151
|
for input in self.inputs:
|
|
1143
1152
|
value = state_in_result[input]
|
|
1144
|
-
if value is None:
|
|
1153
|
+
if value is None and not input.value.optional:
|
|
1145
1154
|
raise StepException(
|
|
1146
1155
|
f"{type(self).__name__}: missing required input '{input.name}'"
|
|
1147
1156
|
) from None
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: librelane
|
|
3
|
-
Version: 2.4.0.
|
|
3
|
+
Version: 2.4.0.dev5
|
|
4
4
|
Summary: An infrastructure for implementing chip design flows
|
|
5
5
|
Home-page: https://github.com/librelane/librelane
|
|
6
6
|
License: Apache-2.0
|
|
@@ -16,7 +16,7 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.12
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.13
|
|
18
18
|
Requires-Dist: ciel (>=0.16.0)
|
|
19
|
-
Requires-Dist: click (>=8,<
|
|
19
|
+
Requires-Dist: click (>=8,<8.2)
|
|
20
20
|
Requires-Dist: cloup (>=3.0.5,<4)
|
|
21
21
|
Requires-Dist: deprecated (>=1.2.10,<2)
|
|
22
22
|
Requires-Dist: httpx (>=0.22.0,<0.29)
|
|
@@ -2,11 +2,11 @@ librelane/__init__.py,sha256=EMpoZrRmS_wsweKjhyAg52OXCK7HWQ8o8CVrYaX4ub0,1220
|
|
|
2
2
|
librelane/__main__.py,sha256=48sW8mh1MNbG0Mf75f5LekXzerbaEASLInQSrvQqPw4,14802
|
|
3
3
|
librelane/__version__.py,sha256=dbE4stCACDmIoxgKksesAkTa-_hi5dW6nPLWw9Pfq3Q,1486
|
|
4
4
|
librelane/common/__init__.py,sha256=LrzxjZKJu3-i8oEYdXtV1IxkXicHtoSUNRcOGrGVGsw,1516
|
|
5
|
-
librelane/common/cli.py,sha256=
|
|
5
|
+
librelane/common/cli.py,sha256=xi48GBGHRsYrLGwx40ARwpykHx7GnuHbJjHxjOwtZ5Y,2349
|
|
6
6
|
librelane/common/drc.py,sha256=2N5jPbM0cxnOj2Kci2AhHTTgHcynTtkV118ii3kq7IU,9603
|
|
7
7
|
librelane/common/generic_dict.py,sha256=xJjHIRvhp4vDk98kvaj8VPa3nUubMedaSfB5OL08sOE,10008
|
|
8
8
|
librelane/common/metrics/__init__.py,sha256=nzdmeia1fN4CDPT604v-OHaBVydz-M4hz232g-jxJ6M,1521
|
|
9
|
-
librelane/common/metrics/__main__.py,sha256=
|
|
9
|
+
librelane/common/metrics/__main__.py,sha256=VfoOHFkGXtei6GLkPUD42X6io8QKFCHhxLMWOXPz_5E,12473
|
|
10
10
|
librelane/common/metrics/library.py,sha256=CG7rubLdjuCQL9-9bzAC-64hf-KlH-iu_Fg0oKuesqs,7373
|
|
11
11
|
librelane/common/metrics/metric.py,sha256=h3Xd26z5M80IJgVmmrBTjKcdGLb4I0wyjM-H4jdyi_0,6990
|
|
12
12
|
librelane/common/metrics/util.py,sha256=Bl_9znlot7-Os2VigYLSmMf56aAkGdv3evWz9vfK7K4,9344
|
|
@@ -144,7 +144,7 @@ librelane/scripts/pyosys/ys_common.py,sha256=mOni8WmKMNuLWsLRNcE15rcqCxGR1kf-9ck
|
|
|
144
144
|
librelane/scripts/tclsh/hello.tcl,sha256=kkR3akY7QnGHYXsQODYwLkMkUEOgWcNFtzaMTTEV2bY,34
|
|
145
145
|
librelane/state/__init__.py,sha256=rLUdAkeB278r8pB2Jpv-ccmmmP32FR90wANIFHXdA0w,969
|
|
146
146
|
librelane/state/__main__.py,sha256=Ici4Ejg1ICUZNSYZRguC3BfEk_wFxsmE0ag0Vv8iY1I,1679
|
|
147
|
-
librelane/state/design_format.py,sha256=
|
|
147
|
+
librelane/state/design_format.py,sha256=ISl4O18ky1BiMkQn8Si0Tcf8UA5vrlZ1yay0iKPxvfk,5794
|
|
148
148
|
librelane/state/state.py,sha256=J05gAeSVDiF76ITuw4WJZ7WkMyG4oTjt_7kpsI3E3PE,11957
|
|
149
149
|
librelane/steps/__init__.py,sha256=j3JYrdnWM74dYuEvE931oSrQI7FUz-hKWr8Mts8C0wg,1668
|
|
150
150
|
librelane/steps/__main__.py,sha256=GviXtDLISKJCufKxK3oFPOSMF1GyShZbG5RXpVCYFkk,13376
|
|
@@ -156,14 +156,14 @@ librelane/steps/magic.py,sha256=4o_WarBAQdTTuekP72uovjvqW5wsaDCpMB3LtAhC_IY,2005
|
|
|
156
156
|
librelane/steps/misc.py,sha256=Xk_a6JJPljkk8pemu-NtlzDRs-8S7vuRKZKj4pnCRlE,5690
|
|
157
157
|
librelane/steps/netgen.py,sha256=R9sDWv-9wKMdi2rkuLQdOc4uLlbYhXcKKd6WsZsnLt0,8953
|
|
158
158
|
librelane/steps/odb.py,sha256=_WhAFEVbFioSGsVrGbXQVqcXYAnE22gLA4eF1v028EQ,38030
|
|
159
|
-
librelane/steps/openroad.py,sha256=
|
|
159
|
+
librelane/steps/openroad.py,sha256=6YaGHgpvPmAqpC_zpPBBEEc-DRpkS4HwG79zd1P1iKs,85987
|
|
160
160
|
librelane/steps/openroad_alerts.py,sha256=IJyB4piBDCKXhkJswHGMYCRDwbdQsR0GZlrGGDhmW6Q,3364
|
|
161
|
-
librelane/steps/pyosys.py,sha256=
|
|
162
|
-
librelane/steps/step.py,sha256=
|
|
161
|
+
librelane/steps/pyosys.py,sha256=mnbPR267XzJvDhtXW4cdTAB3IqvksUZt4ch5xQHgdY0,22705
|
|
162
|
+
librelane/steps/step.py,sha256=OkFNyW86ZY9VlNQHUeJIOLHtOuO1bioXsnwky7_l1pc,55154
|
|
163
163
|
librelane/steps/tclstep.py,sha256=0PMWJ6C3dKnlQf9mA9rZntgxUBCiByE9csHcEcM1iq0,10027
|
|
164
164
|
librelane/steps/verilator.py,sha256=MWx2TpLqYyea9_jSeLG9c2S5ujvYERQZRFNaMhfHxZE,7916
|
|
165
165
|
librelane/steps/yosys.py,sha256=GX6rTiQG-ZhDxfB9SxrPQ9Sab3WC84p0OUtqiL1Nubk,12533
|
|
166
|
-
librelane-2.4.0.
|
|
167
|
-
librelane-2.4.0.
|
|
168
|
-
librelane-2.4.0.
|
|
169
|
-
librelane-2.4.0.
|
|
166
|
+
librelane-2.4.0.dev5.dist-info/METADATA,sha256=GkRScJalX2iq16FMMUHkxkmr-2Mf_rA0HXjKx9xqNdQ,6602
|
|
167
|
+
librelane-2.4.0.dev5.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
|
168
|
+
librelane-2.4.0.dev5.dist-info/entry_points.txt,sha256=GTBvXykNMMFsNKiJFgtEw7P1wb_VZIqVM35EFSpyZQE,263
|
|
169
|
+
librelane-2.4.0.dev5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|