siliconcompiler 0.34.0__py3-none-any.whl → 0.34.2__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.
- siliconcompiler/__init__.py +14 -2
- siliconcompiler/_metadata.py +1 -1
- siliconcompiler/apps/_common.py +1 -1
- siliconcompiler/apps/sc.py +1 -1
- siliconcompiler/apps/sc_issue.py +1 -1
- siliconcompiler/apps/sc_remote.py +3 -3
- siliconcompiler/apps/sc_show.py +3 -3
- siliconcompiler/apps/utils/replay.py +4 -4
- siliconcompiler/checklist.py +203 -2
- siliconcompiler/constraints/__init__.py +17 -0
- siliconcompiler/constraints/asic_component.py +378 -0
- siliconcompiler/constraints/asic_floorplan.py +449 -0
- siliconcompiler/constraints/asic_pins.py +489 -0
- siliconcompiler/constraints/asic_timing.py +517 -0
- siliconcompiler/core.py +31 -249
- siliconcompiler/data/templates/email/general.j2 +3 -3
- siliconcompiler/data/templates/email/summary.j2 +1 -1
- siliconcompiler/data/templates/issue/README.txt +1 -1
- siliconcompiler/data/templates/report/sc_report.j2 +7 -7
- siliconcompiler/dependencyschema.py +10 -174
- siliconcompiler/design.py +325 -114
- siliconcompiler/flowgraph.py +63 -15
- siliconcompiler/library.py +133 -0
- siliconcompiler/metric.py +94 -72
- siliconcompiler/metrics/__init__.py +7 -0
- siliconcompiler/metrics/asic.py +245 -0
- siliconcompiler/metrics/fpga.py +220 -0
- siliconcompiler/optimizer/vizier.py +2 -2
- siliconcompiler/package/__init__.py +138 -35
- siliconcompiler/package/github.py +6 -10
- siliconcompiler/packageschema.py +256 -12
- siliconcompiler/pathschema.py +226 -0
- siliconcompiler/pdk.py +5 -5
- siliconcompiler/project.py +459 -0
- siliconcompiler/remote/client.py +18 -12
- siliconcompiler/remote/server.py +2 -2
- siliconcompiler/report/dashboard/cli/__init__.py +6 -6
- siliconcompiler/report/dashboard/cli/board.py +3 -3
- siliconcompiler/report/dashboard/web/components/__init__.py +5 -5
- siliconcompiler/report/dashboard/web/components/flowgraph.py +4 -4
- siliconcompiler/report/dashboard/web/components/graph.py +2 -2
- siliconcompiler/report/dashboard/web/state.py +1 -1
- siliconcompiler/report/dashboard/web/utils/__init__.py +5 -5
- siliconcompiler/report/html_report.py +1 -1
- siliconcompiler/report/report.py +4 -4
- siliconcompiler/report/summary_table.py +2 -2
- siliconcompiler/report/utils.py +5 -5
- siliconcompiler/scheduler/docker.py +4 -10
- siliconcompiler/scheduler/run_node.py +4 -8
- siliconcompiler/scheduler/scheduler.py +18 -24
- siliconcompiler/scheduler/schedulernode.py +161 -143
- siliconcompiler/scheduler/send_messages.py +3 -3
- siliconcompiler/scheduler/slurm.py +5 -3
- siliconcompiler/scheduler/taskscheduler.py +10 -8
- siliconcompiler/schema/__init__.py +0 -2
- siliconcompiler/schema/baseschema.py +148 -26
- siliconcompiler/schema/editableschema.py +14 -6
- siliconcompiler/schema/journal.py +23 -15
- siliconcompiler/schema/namedschema.py +30 -4
- siliconcompiler/schema/parameter.py +34 -19
- siliconcompiler/schema/parametertype.py +2 -0
- siliconcompiler/schema/parametervalue.py +198 -15
- siliconcompiler/schema/schema_cfg.py +18 -14
- siliconcompiler/schema_obj.py +5 -3
- siliconcompiler/tool.py +591 -179
- siliconcompiler/tools/__init__.py +2 -0
- siliconcompiler/tools/builtin/_common.py +5 -5
- siliconcompiler/tools/builtin/concatenate.py +5 -5
- siliconcompiler/tools/builtin/minimum.py +4 -4
- siliconcompiler/tools/builtin/mux.py +4 -4
- siliconcompiler/tools/builtin/nop.py +4 -4
- siliconcompiler/tools/builtin/verify.py +7 -7
- siliconcompiler/tools/execute/exec_input.py +1 -1
- siliconcompiler/tools/genfasm/genfasm.py +1 -6
- siliconcompiler/tools/openroad/_apr.py +5 -1
- siliconcompiler/tools/openroad/antenna_repair.py +1 -1
- siliconcompiler/tools/openroad/macro_placement.py +1 -1
- siliconcompiler/tools/openroad/power_grid.py +1 -1
- siliconcompiler/tools/openroad/scripts/common/procs.tcl +5 -0
- siliconcompiler/tools/opensta/timing.py +26 -3
- siliconcompiler/tools/slang/__init__.py +2 -2
- siliconcompiler/tools/surfer/__init__.py +0 -0
- siliconcompiler/tools/surfer/show.py +53 -0
- siliconcompiler/tools/surfer/surfer.py +30 -0
- siliconcompiler/tools/vpr/route.py +27 -14
- siliconcompiler/tools/vpr/vpr.py +23 -6
- siliconcompiler/tools/yosys/__init__.py +1 -1
- siliconcompiler/tools/yosys/scripts/procs.tcl +143 -0
- siliconcompiler/tools/yosys/{sc_synth_asic.tcl → scripts/sc_synth_asic.tcl} +4 -0
- siliconcompiler/tools/yosys/{sc_synth_fpga.tcl → scripts/sc_synth_fpga.tcl} +24 -77
- siliconcompiler/tools/yosys/syn_fpga.py +14 -0
- siliconcompiler/toolscripts/_tools.json +9 -13
- siliconcompiler/toolscripts/rhel9/install-vpr.sh +0 -2
- siliconcompiler/toolscripts/ubuntu22/install-surfer.sh +33 -0
- siliconcompiler/toolscripts/ubuntu24/install-surfer.sh +33 -0
- siliconcompiler/utils/__init__.py +2 -1
- siliconcompiler/utils/flowgraph.py +24 -23
- siliconcompiler/utils/issue.py +23 -29
- siliconcompiler/utils/logging.py +35 -6
- siliconcompiler/utils/showtools.py +6 -1
- {siliconcompiler-0.34.0.dist-info → siliconcompiler-0.34.2.dist-info}/METADATA +15 -25
- {siliconcompiler-0.34.0.dist-info → siliconcompiler-0.34.2.dist-info}/RECORD +109 -97
- siliconcompiler/schema/packageschema.py +0 -101
- siliconcompiler/tools/yosys/procs.tcl +0 -71
- siliconcompiler/toolscripts/rhel9/install-yosys-parmys.sh +0 -68
- siliconcompiler/toolscripts/ubuntu22/install-yosys-parmys.sh +0 -68
- siliconcompiler/toolscripts/ubuntu24/install-yosys-parmys.sh +0 -68
- /siliconcompiler/tools/yosys/{sc_lec.tcl → scripts/sc_lec.tcl} +0 -0
- /siliconcompiler/tools/yosys/{sc_screenshot.tcl → scripts/sc_screenshot.tcl} +0 -0
- /siliconcompiler/tools/yosys/{syn_strategies.tcl → scripts/syn_strategies.tcl} +0 -0
- {siliconcompiler-0.34.0.dist-info → siliconcompiler-0.34.2.dist-info}/WHEEL +0 -0
- {siliconcompiler-0.34.0.dist-info → siliconcompiler-0.34.2.dist-info}/entry_points.txt +0 -0
- {siliconcompiler-0.34.0.dist-info → siliconcompiler-0.34.2.dist-info}/licenses/LICENSE +0 -0
- {siliconcompiler-0.34.0.dist-info → siliconcompiler-0.34.2.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
from typing import Tuple, Union
|
|
2
|
+
|
|
3
|
+
from siliconcompiler.schema import BaseSchema, NamedSchema, EditableSchema, Parameter, \
|
|
4
|
+
PerNode, Scope
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ASICComponentConstraint(NamedSchema):
|
|
8
|
+
"""
|
|
9
|
+
Represents a single ASIC component constraint within the design configuration.
|
|
10
|
+
|
|
11
|
+
This class defines various constraints that can be applied to an individual
|
|
12
|
+
ASIC component instance, such as its placement, part name (cell name),
|
|
13
|
+
keepout halo, and rotation.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
def __init__(self, name: str = None):
|
|
17
|
+
super().__init__()
|
|
18
|
+
self.set_name(name)
|
|
19
|
+
|
|
20
|
+
schema = EditableSchema(self)
|
|
21
|
+
|
|
22
|
+
schema.insert(
|
|
23
|
+
'placement',
|
|
24
|
+
Parameter(
|
|
25
|
+
'(float,float)',
|
|
26
|
+
unit='um',
|
|
27
|
+
pernode=PerNode.OPTIONAL,
|
|
28
|
+
scope=Scope.GLOBAL,
|
|
29
|
+
shorthelp="Constraint: component placement",
|
|
30
|
+
example=["api: chip.set('constraint', 'component', 'i0', 'placement', (2.0, 3.0))"],
|
|
31
|
+
schelp="""
|
|
32
|
+
Placement location of a named instance, specified as a (x, y) tuple of
|
|
33
|
+
floats. The location refers to the distance from the substrate origin to
|
|
34
|
+
the anchor point of the placed component, defined by
|
|
35
|
+
the :keypath:`datasheet,package,<name>,anchor` parameter."""))
|
|
36
|
+
|
|
37
|
+
schema.insert(
|
|
38
|
+
'partname',
|
|
39
|
+
Parameter(
|
|
40
|
+
'str',
|
|
41
|
+
pernode=PerNode.OPTIONAL,
|
|
42
|
+
scope=Scope.GLOBAL,
|
|
43
|
+
shorthelp="Constraint: component part name",
|
|
44
|
+
example=["api: chip.set('constraint', 'component', 'i0', 'partname', 'filler_x1')"],
|
|
45
|
+
schelp="""
|
|
46
|
+
Name of the model, type, or variant of the placed component. In the chip
|
|
47
|
+
design domain, 'partname' is synonymous to 'cellname' or 'cell'. The
|
|
48
|
+
'partname' is required for instances that are not represented within
|
|
49
|
+
the design netlist (ie. physical only cells)."""))
|
|
50
|
+
|
|
51
|
+
schema.insert(
|
|
52
|
+
'halo',
|
|
53
|
+
Parameter(
|
|
54
|
+
'(float,float)',
|
|
55
|
+
unit='um',
|
|
56
|
+
pernode=PerNode.OPTIONAL,
|
|
57
|
+
scope=Scope.GLOBAL,
|
|
58
|
+
shorthelp="Constraint: component halo",
|
|
59
|
+
switch="-constraint_component_halo 'inst <(float,float)>'",
|
|
60
|
+
example=[
|
|
61
|
+
"cli: -constraint_component_halo 'i0 (1,1)'",
|
|
62
|
+
"api: chip.set('constraint', 'component', 'i0', 'halo', (1, 1))"],
|
|
63
|
+
schelp="""
|
|
64
|
+
Placement keepout halo around the named component, specified as a
|
|
65
|
+
(horizontal, vertical) tuple."""))
|
|
66
|
+
|
|
67
|
+
rotations = ['R0', 'R90', 'R180', 'R270',
|
|
68
|
+
'MX', 'MX_R90', 'MX_R180', 'MX_R270',
|
|
69
|
+
'MY', 'MY_R90', 'MY_R180', 'MY_R270',
|
|
70
|
+
'MZ', 'MZ_R90', 'MZ_R180', 'MZ_R270',
|
|
71
|
+
'MZ_MX', 'MZ_MX_R90', 'MZ_MX_R180', 'MZ_MX_R270',
|
|
72
|
+
'MZ_MY', 'MZ_MY_R90', 'MZ_MY_R180', 'MZ_MY_R270']
|
|
73
|
+
schema.insert(
|
|
74
|
+
'rotation',
|
|
75
|
+
Parameter(
|
|
76
|
+
f'<{",".join(rotations)}>',
|
|
77
|
+
pernode=PerNode.OPTIONAL,
|
|
78
|
+
scope=Scope.GLOBAL,
|
|
79
|
+
defvalue='R0',
|
|
80
|
+
shorthelp="Constraint: component rotation",
|
|
81
|
+
switch="-constraint_component_rotation 'inst <str>'",
|
|
82
|
+
example=[
|
|
83
|
+
"cli: -constraint_component_rotation 'i0 R90'",
|
|
84
|
+
"api: chip.set('constraint', 'component', 'i0', 'rotation', 'R90')"],
|
|
85
|
+
schelp="""
|
|
86
|
+
Placement rotation of the component. Components are always placed
|
|
87
|
+
such that the lower left corner of the cell is at the anchor point
|
|
88
|
+
(0,0) after any orientation. The MZ type rotations are for 3D design and
|
|
89
|
+
typically not supported by 2D layout systems like traditional
|
|
90
|
+
ASIC tools. For graphical illustrations of the rotation types, see
|
|
91
|
+
the SiliconCompiler documentation.
|
|
92
|
+
|
|
93
|
+
* ``R0``: North orientation (no rotation)
|
|
94
|
+
* ``R90``: West orientation, rotate 90 deg counter clockwise (ccw)
|
|
95
|
+
* ``R180``: South orientation, rotate 180 deg counter ccw
|
|
96
|
+
* ``R270``: East orientation, rotate 180 deg counter ccw
|
|
97
|
+
|
|
98
|
+
* ``MX``, ``MY_R180``: Flip on x-axis
|
|
99
|
+
* ``MX_R90``, ``MY_R270``: Flip on x-axis and rotate 90 deg ccw
|
|
100
|
+
* ``MX_R180``, ``MY``: Flip on x-axis and rotate 180 deg ccw
|
|
101
|
+
* ``MX_R270``, ``MY_R90``: Flip on x-axis and rotate 270 deg ccw
|
|
102
|
+
|
|
103
|
+
* ``MZ``: Reverse component metal stack
|
|
104
|
+
* ``MZ_R90``: Reverse metal stack and rotate 90 deg ccw
|
|
105
|
+
* ``MZ_R180``: Reverse metal stack and rotate 180 deg ccw
|
|
106
|
+
* ``MZ_R270``: Reverse metal stack and rotate 270 deg ccw
|
|
107
|
+
* ``MZ_MX``, ``MZ_MY_R180``: Reverse metal stack and flip on x-axis
|
|
108
|
+
* ``MZ_MX_R90``, ``MZ_MY_R270``: Reverse metal stack, flip on x-axis, and
|
|
109
|
+
rotate 90 deg ccw
|
|
110
|
+
* ``MZ_MX_R180``, ``MZ_MY``: Reverse metal stack, flip on x-axis, and rotate
|
|
111
|
+
180 deg ccw
|
|
112
|
+
* ``MZ_MX_R270``, ``MZ_MY_R90``: Reverse metal stack, flip on x-axis and rotate
|
|
113
|
+
270 deg ccw
|
|
114
|
+
"""))
|
|
115
|
+
|
|
116
|
+
def set_placement(self, x: float, y: float, step: str = None, index: Union[str, int] = None):
|
|
117
|
+
"""
|
|
118
|
+
Sets the placement constraint for the component.
|
|
119
|
+
|
|
120
|
+
Args:
|
|
121
|
+
x (float): The X-coordinate for the component's anchor point in
|
|
122
|
+
micrometers (um) relative to the substrate origin.
|
|
123
|
+
y (float): The Y-coordinate for the component's anchor point in
|
|
124
|
+
micrometers (um) relative to the substrate origin.
|
|
125
|
+
step (str, optional): step name.
|
|
126
|
+
index (str, optional): index name.
|
|
127
|
+
|
|
128
|
+
Raises:
|
|
129
|
+
TypeError: If `x` or `y` is not an int or float.
|
|
130
|
+
"""
|
|
131
|
+
if not isinstance(x, (int, float)):
|
|
132
|
+
raise TypeError("x must be a number")
|
|
133
|
+
if not isinstance(y, (int, float)):
|
|
134
|
+
raise TypeError("y must be a number")
|
|
135
|
+
return self.set("placement", (x, y), step=step, index=index)
|
|
136
|
+
|
|
137
|
+
def get_placement(self, step: str = None, index: Union[str, int] = None) -> Tuple[float, float]:
|
|
138
|
+
"""
|
|
139
|
+
Retrieves the current placement constraint of the component.
|
|
140
|
+
|
|
141
|
+
Args:
|
|
142
|
+
step (str, optional): step name.
|
|
143
|
+
index (str, optional): index name.
|
|
144
|
+
|
|
145
|
+
Returns:
|
|
146
|
+
Tuple[float, float]: A tuple (x, y) representing the component's
|
|
147
|
+
anchor point coordinates in micrometers (um).
|
|
148
|
+
"""
|
|
149
|
+
return self.get("placement", step=step, index=index)
|
|
150
|
+
|
|
151
|
+
def set_partname(self, name: str, step: str = None, index: Union[str, int] = None):
|
|
152
|
+
"""
|
|
153
|
+
Sets the part name (cell name) constraint for the component.
|
|
154
|
+
|
|
155
|
+
Args:
|
|
156
|
+
name (str): The name of the model, type, or variant of the placed component.
|
|
157
|
+
This is required for instances not in the design netlist.
|
|
158
|
+
step (str, optional): step name.
|
|
159
|
+
index (str, optional): index name.
|
|
160
|
+
|
|
161
|
+
Raises:
|
|
162
|
+
ValueError: If `name` is an empty string or None.
|
|
163
|
+
"""
|
|
164
|
+
if not name:
|
|
165
|
+
raise ValueError("a partname is required")
|
|
166
|
+
return self.set("partname", name, step=step, index=index)
|
|
167
|
+
|
|
168
|
+
def get_partname(self, step: str = None, index: Union[str, int] = None) -> str:
|
|
169
|
+
"""
|
|
170
|
+
Retrieves the current part name (cell name) constraint of the component.
|
|
171
|
+
|
|
172
|
+
Args:
|
|
173
|
+
step (str, optional): step name.
|
|
174
|
+
index (str, optional): index name.
|
|
175
|
+
|
|
176
|
+
Returns:
|
|
177
|
+
str: The part name of the component.
|
|
178
|
+
"""
|
|
179
|
+
return self.get("partname", step=step, index=index)
|
|
180
|
+
|
|
181
|
+
def set_halo(self, x: float, y: float, step: str = None, index: Union[str, int] = None):
|
|
182
|
+
"""
|
|
183
|
+
Sets the placement keepout halo constraint around the component.
|
|
184
|
+
|
|
185
|
+
Args:
|
|
186
|
+
x (float): The horizontal extent of the halo in micrometers (um).
|
|
187
|
+
Must be a non-negative numeric value.
|
|
188
|
+
y (float): The vertical extent of the halo in micrometers (um).
|
|
189
|
+
Must be a non-negative numeric value.
|
|
190
|
+
step (str, optional): step name.
|
|
191
|
+
index (str, optional): index name.
|
|
192
|
+
|
|
193
|
+
Raises:
|
|
194
|
+
TypeError: If `x` or `y` is not an int or float.
|
|
195
|
+
ValueError: If `x` or `y` is a negative value.
|
|
196
|
+
"""
|
|
197
|
+
if not isinstance(x, (int, float)):
|
|
198
|
+
raise TypeError("x must be a number")
|
|
199
|
+
if not isinstance(y, (int, float)):
|
|
200
|
+
raise TypeError("y must be a number")
|
|
201
|
+
if x < 0:
|
|
202
|
+
raise ValueError("x must be a positive number")
|
|
203
|
+
if y < 0:
|
|
204
|
+
raise ValueError("y must be a positive number")
|
|
205
|
+
return self.set("halo", (x, y), step=step, index=index)
|
|
206
|
+
|
|
207
|
+
def get_halo(self, step: str = None, index: Union[str, int] = None) -> Tuple[float, float]:
|
|
208
|
+
"""
|
|
209
|
+
Retrieves the current placement keepout halo constraint of the component.
|
|
210
|
+
|
|
211
|
+
Args:
|
|
212
|
+
step (str, optional): step name.
|
|
213
|
+
index (str, optional): index name.
|
|
214
|
+
|
|
215
|
+
Returns:
|
|
216
|
+
Tuple[float, float]: A tuple (horizontal, vertical) representing the
|
|
217
|
+
halo extents in micrometers (um).
|
|
218
|
+
"""
|
|
219
|
+
return self.get("halo", step=step, index=index)
|
|
220
|
+
|
|
221
|
+
def set_rotation(self, rotation: str, step: str = None, index: Union[str, int] = None):
|
|
222
|
+
"""
|
|
223
|
+
Sets the rotation constraint for the component.
|
|
224
|
+
|
|
225
|
+
Args:
|
|
226
|
+
rotation (str): The desired rotation of the component. Valid values
|
|
227
|
+
are defined by the `rotations` list schema help
|
|
228
|
+
(e.g., 'R0', 'R90', 'MX', 'MZ_R90').
|
|
229
|
+
step (str, optional): step name.
|
|
230
|
+
index (str, optional): index name.
|
|
231
|
+
"""
|
|
232
|
+
return self.set("rotation", rotation, step=step, index=index)
|
|
233
|
+
|
|
234
|
+
def get_rotation(self, step: str = None, index: Union[str, int] = None) -> str:
|
|
235
|
+
"""
|
|
236
|
+
Retrieves the current rotation constraint of the component.
|
|
237
|
+
|
|
238
|
+
Args:
|
|
239
|
+
step (str, optional): step name.
|
|
240
|
+
index (str, optional): index name.
|
|
241
|
+
|
|
242
|
+
Returns:
|
|
243
|
+
str: The rotation of the component.
|
|
244
|
+
"""
|
|
245
|
+
return self.get("rotation", step=step, index=index)
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
class ASICComponentConstraints(BaseSchema):
|
|
249
|
+
"""
|
|
250
|
+
Manages a collection of ASIC component constraints.
|
|
251
|
+
|
|
252
|
+
This class provides methods to add, retrieve, create, and remove
|
|
253
|
+
individual :class:`ASICComponentConstraint` objects, allowing for organized
|
|
254
|
+
management of component-level placement and property constraints.
|
|
255
|
+
"""
|
|
256
|
+
def __init__(self):
|
|
257
|
+
super().__init__()
|
|
258
|
+
|
|
259
|
+
schema = EditableSchema(self)
|
|
260
|
+
schema.insert("default", ASICComponentConstraint())
|
|
261
|
+
|
|
262
|
+
def add_component(self, component: ASICComponentConstraint):
|
|
263
|
+
"""
|
|
264
|
+
Adds a component constraint to the design configuration.
|
|
265
|
+
|
|
266
|
+
This method incorporates a new or updated component constraint into the system's
|
|
267
|
+
configuration. If a constraint with the same name already exists, it will
|
|
268
|
+
be overwritten (`clobber=True`).
|
|
269
|
+
|
|
270
|
+
Args:
|
|
271
|
+
component: The :class:`ASICComponentConstraint` object representing the component
|
|
272
|
+
constraint to add. This object must have a valid name defined
|
|
273
|
+
via its `name()` method.
|
|
274
|
+
|
|
275
|
+
Raises:
|
|
276
|
+
TypeError: If the provided `component` argument is not an instance of
|
|
277
|
+
`ASICComponentConstraint`.
|
|
278
|
+
ValueError: If the `component` object's `name()` method returns None,
|
|
279
|
+
indicating that the component constraint does not have a defined name.
|
|
280
|
+
"""
|
|
281
|
+
if not isinstance(component, ASICComponentConstraint):
|
|
282
|
+
raise TypeError("component must be a component constraint object")
|
|
283
|
+
|
|
284
|
+
if component.name() is None:
|
|
285
|
+
raise ValueError("component constraint must have a name")
|
|
286
|
+
|
|
287
|
+
EditableSchema(self).insert(component.name(), component, clobber=True)
|
|
288
|
+
|
|
289
|
+
def get_component(self, component: str = None):
|
|
290
|
+
"""
|
|
291
|
+
Retrieves one or all component constraints from the configuration.
|
|
292
|
+
|
|
293
|
+
This method provides flexibility to fetch either a specific component constraint
|
|
294
|
+
by its name or a collection of all currently defined constraints.
|
|
295
|
+
|
|
296
|
+
Args:
|
|
297
|
+
component (str, optional): The name (string) of the specific component
|
|
298
|
+
constraint to retrieve. If this argument is
|
|
299
|
+
omitted or set to None, the method will return
|
|
300
|
+
a dictionary containing all available component constraints.
|
|
301
|
+
|
|
302
|
+
Returns:
|
|
303
|
+
- If `component` is provided: The :class:`ASICComponentConstraint` object
|
|
304
|
+
corresponding to the specified component name.
|
|
305
|
+
- If `component` is None: A dictionary where keys are component names (str) and
|
|
306
|
+
values are their respective :class:`ASICComponentConstraint` objects.
|
|
307
|
+
|
|
308
|
+
Raises:
|
|
309
|
+
LookupError: If a specific `component` name is provided but no component
|
|
310
|
+
constraint with that name is found in the configuration.
|
|
311
|
+
"""
|
|
312
|
+
if component is None:
|
|
313
|
+
components = {}
|
|
314
|
+
for component in self.getkeys():
|
|
315
|
+
components[component] = self.get(component, field="schema")
|
|
316
|
+
return components
|
|
317
|
+
|
|
318
|
+
if not self.valid(component):
|
|
319
|
+
raise LookupError(f"{component} is not defined")
|
|
320
|
+
return self.get(component, field="schema")
|
|
321
|
+
|
|
322
|
+
def make_component(self, component: str) -> ASICComponentConstraint:
|
|
323
|
+
"""
|
|
324
|
+
Creates and adds a new component constraint with the specified name.
|
|
325
|
+
|
|
326
|
+
This method initializes a new :class:`ASICComponentConstraint` object with the given
|
|
327
|
+
name and immediately adds it to the design configuration. It ensures that
|
|
328
|
+
a constraint with the same name does not already exist, preventing accidental
|
|
329
|
+
overwrites.
|
|
330
|
+
|
|
331
|
+
Args:
|
|
332
|
+
component (str): The name for the new component constraint. This name must be
|
|
333
|
+
a non-empty string and unique within the current configuration.
|
|
334
|
+
|
|
335
|
+
Returns:
|
|
336
|
+
ASICComponentConstraint: The newly created :class:`ASICComponentConstraint` object.
|
|
337
|
+
|
|
338
|
+
Raises:
|
|
339
|
+
ValueError: If the provided `component` name is empty or None.
|
|
340
|
+
LookupError: If a component constraint with the specified `component` name
|
|
341
|
+
already exists in the configuration.
|
|
342
|
+
"""
|
|
343
|
+
if not component:
|
|
344
|
+
raise ValueError("component name is required")
|
|
345
|
+
|
|
346
|
+
if self.valid(component):
|
|
347
|
+
raise LookupError(f"{component} constraint already exists")
|
|
348
|
+
|
|
349
|
+
constraint = ASICComponentConstraint(component)
|
|
350
|
+
self.add_component(constraint)
|
|
351
|
+
return constraint
|
|
352
|
+
|
|
353
|
+
def remove_component(self, component: str) -> bool:
|
|
354
|
+
"""
|
|
355
|
+
Removes a component constraint from the design configuration.
|
|
356
|
+
|
|
357
|
+
This method deletes the specified component constraint from the system's
|
|
358
|
+
configuration.
|
|
359
|
+
|
|
360
|
+
Args:
|
|
361
|
+
component (str): The name of the component constraint to remove.
|
|
362
|
+
This name must be a non-empty string.
|
|
363
|
+
|
|
364
|
+
Returns:
|
|
365
|
+
bool: True if the component constraint was successfully removed, False if no
|
|
366
|
+
component constraint with the given name was found.
|
|
367
|
+
|
|
368
|
+
Raises:
|
|
369
|
+
ValueError: If the provided `component` name is empty or None.
|
|
370
|
+
"""
|
|
371
|
+
if not component:
|
|
372
|
+
raise ValueError("component name is required")
|
|
373
|
+
|
|
374
|
+
if not self.valid(component):
|
|
375
|
+
return False
|
|
376
|
+
|
|
377
|
+
EditableSchema(self).remove(component)
|
|
378
|
+
return True
|