siliconcompiler 0.34.1__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/sc_show.py +1 -1
- 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 +3 -3
- siliconcompiler/dependencyschema.py +10 -174
- siliconcompiler/design.py +235 -118
- siliconcompiler/flowgraph.py +27 -14
- 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/package/__init__.py +138 -35
- siliconcompiler/package/github.py +6 -10
- siliconcompiler/packageschema.py +256 -12
- siliconcompiler/pathschema.py +226 -0
- siliconcompiler/project.py +459 -0
- siliconcompiler/scheduler/docker.py +2 -3
- siliconcompiler/scheduler/run_node.py +2 -1
- siliconcompiler/scheduler/scheduler.py +4 -13
- siliconcompiler/scheduler/schedulernode.py +25 -17
- siliconcompiler/scheduler/taskscheduler.py +2 -1
- siliconcompiler/schema/__init__.py +0 -2
- siliconcompiler/schema/baseschema.py +147 -24
- siliconcompiler/schema/editableschema.py +14 -6
- siliconcompiler/schema/journal.py +23 -15
- siliconcompiler/schema/namedschema.py +6 -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 +199 -10
- siliconcompiler/toolscripts/_tools.json +4 -4
- {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.2.dist-info}/METADATA +3 -3
- {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.2.dist-info}/RECORD +45 -35
- siliconcompiler/schema/packageschema.py +0 -101
- {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.2.dist-info}/WHEEL +0 -0
- {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.2.dist-info}/entry_points.txt +0 -0
- {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.2.dist-info}/licenses/LICENSE +0 -0
- {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.2.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,489 @@
|
|
|
1
|
+
from typing import Union, Tuple
|
|
2
|
+
|
|
3
|
+
from siliconcompiler.schema import BaseSchema, NamedSchema, EditableSchema, Parameter, \
|
|
4
|
+
PerNode, Scope
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ASICPinConstraint(NamedSchema):
|
|
8
|
+
"""
|
|
9
|
+
Represents a single ASIC pin constraint within the design configuration.
|
|
10
|
+
|
|
11
|
+
This class defines various constraints that can be applied to an individual
|
|
12
|
+
ASIC pin, such as its placement, dimensions (width, length), shape,
|
|
13
|
+
metal layer, and its relative position on the chip's side.
|
|
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: pin placement",
|
|
30
|
+
example=["api: chip.set('constraint', 'pin', 'nreset', 'placement', (2.0, 3.0))"],
|
|
31
|
+
help="""
|
|
32
|
+
Placement location of a named pin, specified as a (x,y) tuple of
|
|
33
|
+
floats with respect to the lower left corner of the substrate. The location
|
|
34
|
+
refers to the center of the pin. The 'placement' parameter
|
|
35
|
+
is a goal/intent, not an exact specification. The layout system
|
|
36
|
+
may adjust sizes to meet competing goals such as manufacturing design
|
|
37
|
+
rules and grid placement guidelines."""))
|
|
38
|
+
|
|
39
|
+
schema.insert(
|
|
40
|
+
'width',
|
|
41
|
+
Parameter(
|
|
42
|
+
'float',
|
|
43
|
+
unit='um',
|
|
44
|
+
pernode=PerNode.OPTIONAL,
|
|
45
|
+
scope=Scope.GLOBAL,
|
|
46
|
+
shorthelp="Constraint: pin width",
|
|
47
|
+
example=["api: chip.set('constraint', 'pin', 'nreset', 'width', 1.0)"],
|
|
48
|
+
help="""
|
|
49
|
+
Pin width constraint. Package pin width is the lateral
|
|
50
|
+
(side-to-side) thickness of a pin on a physical component.
|
|
51
|
+
This parameter represents goal/intent, not an exact
|
|
52
|
+
specification. The layout system may adjust dimensions to meet
|
|
53
|
+
competing goals such as manufacturing design rules and grid placement
|
|
54
|
+
guidelines."""))
|
|
55
|
+
|
|
56
|
+
schema.insert(
|
|
57
|
+
'length',
|
|
58
|
+
Parameter(
|
|
59
|
+
'float',
|
|
60
|
+
unit='um',
|
|
61
|
+
pernode=PerNode.OPTIONAL,
|
|
62
|
+
scope=Scope.GLOBAL,
|
|
63
|
+
shorthelp="Constraint: pin length",
|
|
64
|
+
example=["api: chip.set('constraint', 'pin', 'nreset', 'length', 1.0)"],
|
|
65
|
+
help="""
|
|
66
|
+
Pin length constraint. Package pin length refers to the
|
|
67
|
+
length of the electrical pins extending out from (or into)
|
|
68
|
+
a component. This parameter represents goal/intent, not an exact
|
|
69
|
+
specification. The layout system may adjust dimensions to meet
|
|
70
|
+
competing goals such as manufacturing design rules and grid placement
|
|
71
|
+
guidelines."""))
|
|
72
|
+
|
|
73
|
+
schema.insert(
|
|
74
|
+
'shape',
|
|
75
|
+
Parameter(
|
|
76
|
+
'<circle,rectangle,square,hexagon,octagon,oval,pill,polygon>',
|
|
77
|
+
pernode=PerNode.OPTIONAL,
|
|
78
|
+
scope=Scope.GLOBAL,
|
|
79
|
+
shorthelp="Constraint: pin shape",
|
|
80
|
+
example=["api: chip.set('constraint', 'pin', 'nreset', 'shape', 'circle')"],
|
|
81
|
+
help="""
|
|
82
|
+
Pin shape constraint specified on a per pin basis. In 3D design systems,
|
|
83
|
+
the pin shape represents the cross section of the pin in the direction
|
|
84
|
+
orthogonal to the signal flow direction. The 'pill' (aka stadium) shape,
|
|
85
|
+
is rectangle with semicircles at a pair of opposite sides. The other
|
|
86
|
+
pin shapes represent common geometric shape definitions."""))
|
|
87
|
+
|
|
88
|
+
schema.insert(
|
|
89
|
+
'layer',
|
|
90
|
+
Parameter(
|
|
91
|
+
'str',
|
|
92
|
+
pernode=PerNode.OPTIONAL,
|
|
93
|
+
scope=Scope.GLOBAL,
|
|
94
|
+
shorthelp="Constraint: pin layer",
|
|
95
|
+
example=["api: chip.set('constraint', 'pin', 'nreset', 'layer', 'm4')"],
|
|
96
|
+
help="""
|
|
97
|
+
Pin metal layer constraint specified on a per pin basis.
|
|
98
|
+
Metal names should either be the PDK specific metal stack name or
|
|
99
|
+
an integer with '1' being the lowest routing layer."""))
|
|
100
|
+
|
|
101
|
+
schema.insert(
|
|
102
|
+
'side',
|
|
103
|
+
Parameter(
|
|
104
|
+
'int',
|
|
105
|
+
pernode=PerNode.OPTIONAL,
|
|
106
|
+
scope=Scope.GLOBAL,
|
|
107
|
+
shorthelp="Constraint: pin side",
|
|
108
|
+
example=["api: chip.set('constraint', 'pin', 'nreset', 'side', 1)"],
|
|
109
|
+
help="""
|
|
110
|
+
Side of block where the named pin should be placed. Sides are
|
|
111
|
+
enumerated as integers with '1' being the lower left side,
|
|
112
|
+
with the side index incremented on right turn in a clock wise
|
|
113
|
+
fashion. In case of conflict between 'lower' and 'left',
|
|
114
|
+
'left' has precedence. The side option and order option are
|
|
115
|
+
orthogonal to the placement option."""))
|
|
116
|
+
|
|
117
|
+
schema.insert(
|
|
118
|
+
'order',
|
|
119
|
+
Parameter(
|
|
120
|
+
'int',
|
|
121
|
+
pernode=PerNode.OPTIONAL,
|
|
122
|
+
scope=Scope.GLOBAL,
|
|
123
|
+
shorthelp="Constraint: pin order",
|
|
124
|
+
example=["api: chip.set('constraint', 'pin', 'nreset', 'order', 1)"],
|
|
125
|
+
help="""
|
|
126
|
+
The relative position of the named pin in a vector of pins
|
|
127
|
+
on the side specified by the 'side' option. Pin order counting
|
|
128
|
+
is done clockwise. If multiple pins on the same side have the
|
|
129
|
+
same order number, the actual order is at the discretion of the
|
|
130
|
+
tool."""))
|
|
131
|
+
|
|
132
|
+
def set_width(self, width: float, step: str = None, index: Union[str, int] = None):
|
|
133
|
+
"""
|
|
134
|
+
Sets the width constraint for the pin.
|
|
135
|
+
|
|
136
|
+
Args:
|
|
137
|
+
width (float): The desired width of the pin in micrometers (um).
|
|
138
|
+
Must be a positive numeric value.
|
|
139
|
+
step (str, optional): step name.
|
|
140
|
+
index (str, optional): index name.
|
|
141
|
+
|
|
142
|
+
Raises:
|
|
143
|
+
TypeError: If `width` is not an int or float.
|
|
144
|
+
ValueError: If `width` is not a positive value.
|
|
145
|
+
"""
|
|
146
|
+
if not isinstance(width, (int, float)):
|
|
147
|
+
raise TypeError("width must be a number")
|
|
148
|
+
if width <= 0:
|
|
149
|
+
raise ValueError("width must be a positive value")
|
|
150
|
+
return self.set("width", width, step=step, index=index)
|
|
151
|
+
|
|
152
|
+
def get_width(self, step: str = None, index: Union[str, int] = None) -> float:
|
|
153
|
+
"""
|
|
154
|
+
Retrieves the current width constraint of the pin.
|
|
155
|
+
|
|
156
|
+
Args:
|
|
157
|
+
step (str, optional): step name.
|
|
158
|
+
index (str, optional): index name.
|
|
159
|
+
|
|
160
|
+
Returns:
|
|
161
|
+
float: The width of the pin in micrometers (um).
|
|
162
|
+
"""
|
|
163
|
+
return self.get("width", step=step, index=index)
|
|
164
|
+
|
|
165
|
+
def set_length(self, length: float, step: str = None, index: Union[str, int] = None):
|
|
166
|
+
"""
|
|
167
|
+
Sets the length constraint for the pin.
|
|
168
|
+
|
|
169
|
+
Args:
|
|
170
|
+
length (float): The desired length of the pin in micrometers (um).
|
|
171
|
+
Must be a positive numeric value.
|
|
172
|
+
step (str, optional): step name.
|
|
173
|
+
index (str, optional): index name.
|
|
174
|
+
|
|
175
|
+
Raises:
|
|
176
|
+
TypeError: If `length` is not an int or float.
|
|
177
|
+
ValueError: If `length` is not a positive value.
|
|
178
|
+
"""
|
|
179
|
+
if not isinstance(length, (int, float)):
|
|
180
|
+
raise TypeError("length must be a number")
|
|
181
|
+
if length <= 0:
|
|
182
|
+
raise ValueError("length must be a positive value")
|
|
183
|
+
return self.set("length", length, step=step, index=index)
|
|
184
|
+
|
|
185
|
+
def get_length(self, step: str = None, index: Union[str, int] = None) -> float:
|
|
186
|
+
"""
|
|
187
|
+
Retrieves the current length constraint of the pin.
|
|
188
|
+
|
|
189
|
+
Args:
|
|
190
|
+
step (str, optional): step name.
|
|
191
|
+
index (str, optional): index name.
|
|
192
|
+
|
|
193
|
+
Returns:
|
|
194
|
+
float: The length of the pin in micrometers (um).
|
|
195
|
+
"""
|
|
196
|
+
return self.get("length", step=step, index=index)
|
|
197
|
+
|
|
198
|
+
def set_placement(self, x: float, y: float, step: str = None, index: Union[str, int] = None):
|
|
199
|
+
"""
|
|
200
|
+
Sets the placement constraint for the pin.
|
|
201
|
+
|
|
202
|
+
Args:
|
|
203
|
+
x (float): The X-coordinate for the pin's center in micrometers (um)
|
|
204
|
+
relative to the lower-left corner of the substrate.
|
|
205
|
+
y (float): The Y-coordinate for the pin's center in micrometers (um)
|
|
206
|
+
relative to the lower-left corner of the substrate.
|
|
207
|
+
step (str, optional): step name.
|
|
208
|
+
index (str, optional): index name.
|
|
209
|
+
|
|
210
|
+
Raises:
|
|
211
|
+
TypeError: If `x` or `y` is not an int or float.
|
|
212
|
+
"""
|
|
213
|
+
if not isinstance(x, (int, float)):
|
|
214
|
+
raise TypeError("x must be a number")
|
|
215
|
+
if not isinstance(y, (int, float)):
|
|
216
|
+
raise TypeError("y must be a number")
|
|
217
|
+
return self.set("placement", (x, y), step=step, index=index)
|
|
218
|
+
|
|
219
|
+
def get_placement(self, step: str = None, index: Union[str, int] = None) -> Tuple[float, float]:
|
|
220
|
+
"""
|
|
221
|
+
Retrieves the current placement constraint of the pin.
|
|
222
|
+
|
|
223
|
+
Args:
|
|
224
|
+
step (str, optional): step name.
|
|
225
|
+
index (str, optional): index name.
|
|
226
|
+
|
|
227
|
+
Returns:
|
|
228
|
+
Tuple[float, float]: A tuple (x, y) representing the pin's center
|
|
229
|
+
coordinates in micrometers (um).
|
|
230
|
+
"""
|
|
231
|
+
return self.get("placement", step=step, index=index)
|
|
232
|
+
|
|
233
|
+
def set_shape(self, shape: str, step: str = None, index: Union[str, int] = None):
|
|
234
|
+
"""
|
|
235
|
+
Sets the shape constraint for the pin.
|
|
236
|
+
|
|
237
|
+
Args:
|
|
238
|
+
shape (str): The desired shape of the pin. Valid values include
|
|
239
|
+
'circle', 'rectangle', 'square', 'hexagon', 'octagon',
|
|
240
|
+
'oval', 'pill', or 'polygon'.
|
|
241
|
+
step (str, optional): step name.
|
|
242
|
+
index (str, optional): index name.
|
|
243
|
+
"""
|
|
244
|
+
return self.set("shape", shape, step=step, index=index)
|
|
245
|
+
|
|
246
|
+
def get_shape(self, step: str = None, index: Union[str, int] = None) -> str:
|
|
247
|
+
"""
|
|
248
|
+
Retrieves the current shape constraint of the pin.
|
|
249
|
+
|
|
250
|
+
Args:
|
|
251
|
+
step (str, optional): step name.
|
|
252
|
+
index (str, optional): index name.
|
|
253
|
+
|
|
254
|
+
Returns:
|
|
255
|
+
str: The shape of the pin.
|
|
256
|
+
"""
|
|
257
|
+
return self.get("shape", step=step, index=index)
|
|
258
|
+
|
|
259
|
+
def set_layer(self, layer: str, step: str = None, index: Union[str, int] = None):
|
|
260
|
+
"""
|
|
261
|
+
Sets the metal layer constraint for the pin.
|
|
262
|
+
|
|
263
|
+
Args:
|
|
264
|
+
layer (str): The name of the metal layer for the pin. This can be
|
|
265
|
+
a PDK-specific metal stack name (e.g., 'm4') or an
|
|
266
|
+
integer (e.g., '1' for the lowest routing layer).
|
|
267
|
+
step (str, optional): step name.
|
|
268
|
+
index (str, optional): index name.
|
|
269
|
+
"""
|
|
270
|
+
return self.set("layer", layer, step=step, index=index)
|
|
271
|
+
|
|
272
|
+
def get_layer(self, step: str = None, index: Union[str, int] = None) -> str:
|
|
273
|
+
"""
|
|
274
|
+
Retrieves the current metal layer constraint of the pin.
|
|
275
|
+
|
|
276
|
+
Args:
|
|
277
|
+
step (str, optional): step name.
|
|
278
|
+
index (str, optional): index name.
|
|
279
|
+
|
|
280
|
+
Returns:
|
|
281
|
+
str: The metal layer of the pin.
|
|
282
|
+
"""
|
|
283
|
+
return self.get("layer", step=step, index=index)
|
|
284
|
+
|
|
285
|
+
def set_side(self, side: Union[int, str], step: str = None, index: Union[str, int] = None):
|
|
286
|
+
"""
|
|
287
|
+
Sets the side constraint for the pin, indicating where it should be placed.
|
|
288
|
+
|
|
289
|
+
Args:
|
|
290
|
+
side (Union[int, str]): The side of the block where the pin should be placed.
|
|
291
|
+
Can be an integer or a string ('left', 'west', 'top',
|
|
292
|
+
'north', 'right', 'east', 'bottom', 'south').
|
|
293
|
+
step (str, optional): step name.
|
|
294
|
+
index (str, optional): index name.
|
|
295
|
+
|
|
296
|
+
Raises:
|
|
297
|
+
TypeError: If `side` is not an int or string.
|
|
298
|
+
ValueError: If `side` is an unrecognized string value or a non-positive integer.
|
|
299
|
+
"""
|
|
300
|
+
if isinstance(side, str):
|
|
301
|
+
side = side.lower()
|
|
302
|
+
if side in ("left", "west"):
|
|
303
|
+
side = 1
|
|
304
|
+
elif side in ("top", "north"):
|
|
305
|
+
side = 2
|
|
306
|
+
elif side in ("right", "east"):
|
|
307
|
+
side = 3
|
|
308
|
+
elif side in ("bottom", "south"):
|
|
309
|
+
side = 4
|
|
310
|
+
else:
|
|
311
|
+
raise ValueError(f"{side} is a not a recognized side")
|
|
312
|
+
|
|
313
|
+
if not isinstance(side, int):
|
|
314
|
+
raise TypeError("side must be an integer")
|
|
315
|
+
|
|
316
|
+
if side <= 0:
|
|
317
|
+
raise ValueError("side must be a positive integer")
|
|
318
|
+
|
|
319
|
+
return self.set("side", side, step=step, index=index)
|
|
320
|
+
|
|
321
|
+
def get_side(self, step: str = None, index: Union[str, int] = None) -> int:
|
|
322
|
+
"""
|
|
323
|
+
Retrieves the current side constraint of the pin.
|
|
324
|
+
|
|
325
|
+
Args:
|
|
326
|
+
step (str, optional): step name.
|
|
327
|
+
index (str, optional): index name.
|
|
328
|
+
|
|
329
|
+
Returns:
|
|
330
|
+
int: The integer representation of the side (1 for lower left, etc.).
|
|
331
|
+
"""
|
|
332
|
+
return self.get("side", step=step, index=index)
|
|
333
|
+
|
|
334
|
+
def set_order(self, order: int, step: str = None, index: Union[str, int] = None):
|
|
335
|
+
"""
|
|
336
|
+
Sets the relative order constraint for the pin on its assigned side.
|
|
337
|
+
|
|
338
|
+
Args:
|
|
339
|
+
order (int): The relative position of the pin in a vector of pins
|
|
340
|
+
on the specified side. Counting is done clockwise.
|
|
341
|
+
step (str, optional): step name.
|
|
342
|
+
index (str, optional): index name.
|
|
343
|
+
"""
|
|
344
|
+
return self.set("order", order, step=step, index=index)
|
|
345
|
+
|
|
346
|
+
def get_order(self, step: str = None, index: Union[str, int] = None) -> int:
|
|
347
|
+
"""
|
|
348
|
+
Retrieves the current order constraint of the pin.
|
|
349
|
+
|
|
350
|
+
Args:
|
|
351
|
+
step (str, optional): step name.
|
|
352
|
+
index (str, optional): index name.
|
|
353
|
+
|
|
354
|
+
Returns:
|
|
355
|
+
int: The relative order of the pin on its side.
|
|
356
|
+
"""
|
|
357
|
+
return self.get("order", step=step, index=index)
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
class ASICPinConstraints(BaseSchema):
|
|
361
|
+
"""
|
|
362
|
+
Manages a collection of ASIC pin constraints.
|
|
363
|
+
|
|
364
|
+
This class provides methods to add, retrieve, create, and remove
|
|
365
|
+
individual :class:`ASICPinConstraint` objects, allowing for organized
|
|
366
|
+
management of pin-level placement and property constraints.
|
|
367
|
+
"""
|
|
368
|
+
|
|
369
|
+
def __init__(self):
|
|
370
|
+
super().__init__()
|
|
371
|
+
|
|
372
|
+
schema = EditableSchema(self)
|
|
373
|
+
schema.insert("default", ASICPinConstraint())
|
|
374
|
+
|
|
375
|
+
def add_pinconstraint(self, pin: ASICPinConstraint):
|
|
376
|
+
"""
|
|
377
|
+
Adds a pin constraint to the design configuration.
|
|
378
|
+
|
|
379
|
+
This method incorporates a new or updated pin constraint into the system's
|
|
380
|
+
configuration. If a constraint with the same name already exists, it will
|
|
381
|
+
be overwritten (`clobber=True`).
|
|
382
|
+
|
|
383
|
+
Args:
|
|
384
|
+
pin: The :class:`ASICPinConstraint` object representing the pin constraint to add.
|
|
385
|
+
This object must have a valid name defined via its `name()` method.
|
|
386
|
+
|
|
387
|
+
Raises:
|
|
388
|
+
TypeError: If the provided `pin` argument is not an instance of
|
|
389
|
+
:class:`ASICPinConstraint`.
|
|
390
|
+
ValueError: If the `pin` object's `name()` method returns None, indicating
|
|
391
|
+
that the pin constraint does not have a defined name.
|
|
392
|
+
"""
|
|
393
|
+
if not isinstance(pin, ASICPinConstraint):
|
|
394
|
+
raise TypeError("pin must be a pin copnstraint object")
|
|
395
|
+
|
|
396
|
+
if pin.name() is None:
|
|
397
|
+
raise ValueError("pin constraint must have a name")
|
|
398
|
+
|
|
399
|
+
EditableSchema(self).insert(pin.name(), pin, clobber=True)
|
|
400
|
+
|
|
401
|
+
def get_pinconstraint(self, pin: str = None):
|
|
402
|
+
"""
|
|
403
|
+
Retrieves one or all pin constraints from the configuration.
|
|
404
|
+
|
|
405
|
+
This method provides flexibility to fetch either a specific pin constraint
|
|
406
|
+
by its name or a collection of all currently defined constraints.
|
|
407
|
+
|
|
408
|
+
Args:
|
|
409
|
+
pin (str, optional): The name (string) of the specific pin constraint to retrieve.
|
|
410
|
+
If this argument is omitted or set to None, the method will return
|
|
411
|
+
a dictionary containing all available pin constraints.
|
|
412
|
+
|
|
413
|
+
Returns:
|
|
414
|
+
- If `pin` is provided: The :class:`ASICPinConstraint` object corresponding
|
|
415
|
+
to the specified pin constraint name.
|
|
416
|
+
- If `pin` is None: A dictionary where keys are pin constraint names (str) and
|
|
417
|
+
values are their respective :class:`ASICPinConstraint` objects.
|
|
418
|
+
|
|
419
|
+
Raises:
|
|
420
|
+
LookupError: If a specific `pin` name is provided but no pin constraint with
|
|
421
|
+
that name is found in the configuration.
|
|
422
|
+
"""
|
|
423
|
+
if pin is None:
|
|
424
|
+
pins = {}
|
|
425
|
+
for pin in self.getkeys():
|
|
426
|
+
pins[pin] = self.get(pin, field="schema")
|
|
427
|
+
return pins
|
|
428
|
+
|
|
429
|
+
if not self.valid(pin):
|
|
430
|
+
raise LookupError(f"{pin} is not defined")
|
|
431
|
+
return self.get(pin, field="schema")
|
|
432
|
+
|
|
433
|
+
def make_pinconstraint(self, pin: str) -> ASICPinConstraint:
|
|
434
|
+
"""
|
|
435
|
+
Creates and adds a new pin constraint with the specified name.
|
|
436
|
+
|
|
437
|
+
This method initializes a new :class:`ASICPinConstraint` object with the given
|
|
438
|
+
name and immediately adds it to the design configuration. It ensures that
|
|
439
|
+
a constraint with the same name does not already exist, preventing accidental
|
|
440
|
+
overwrites.
|
|
441
|
+
|
|
442
|
+
Args:
|
|
443
|
+
pin (str): The name for the new pin constraint. This name must be
|
|
444
|
+
a non-empty string and unique within the current configuration.
|
|
445
|
+
|
|
446
|
+
Returns:
|
|
447
|
+
:class:ASICPinConstraint: The newly created :class:`ASICPinConstraint` object.
|
|
448
|
+
|
|
449
|
+
Raises:
|
|
450
|
+
ValueError: If the provided `pin` name is empty or None.
|
|
451
|
+
LookupError: If a pin constraint with the specified `pin` name already exists
|
|
452
|
+
in the configuration.
|
|
453
|
+
"""
|
|
454
|
+
if not pin:
|
|
455
|
+
raise ValueError("pin name is required")
|
|
456
|
+
|
|
457
|
+
if self.valid(pin):
|
|
458
|
+
raise LookupError(f"{pin} constraint already exists")
|
|
459
|
+
|
|
460
|
+
constraint = ASICPinConstraint(pin)
|
|
461
|
+
self.add_pinconstraint(constraint)
|
|
462
|
+
return constraint
|
|
463
|
+
|
|
464
|
+
def remove_pinconstraint(self, pin: str) -> bool:
|
|
465
|
+
"""
|
|
466
|
+
Removes a pin constraint from the design configuration.
|
|
467
|
+
|
|
468
|
+
This method deletes the specified pin constraint from the system's
|
|
469
|
+
configuration.
|
|
470
|
+
|
|
471
|
+
Args:
|
|
472
|
+
pin (str): The name of the pin constraint to remove.
|
|
473
|
+
This name must be a non-empty string.
|
|
474
|
+
|
|
475
|
+
Returns:
|
|
476
|
+
bool: True if the pin constraint was successfully removed, False if no
|
|
477
|
+
pin constraint with the given name was found.
|
|
478
|
+
|
|
479
|
+
Raises:
|
|
480
|
+
ValueError: If the provided `pin` name is empty or None.
|
|
481
|
+
"""
|
|
482
|
+
if not pin:
|
|
483
|
+
raise ValueError("pin name is required")
|
|
484
|
+
|
|
485
|
+
if not self.valid(pin):
|
|
486
|
+
return False
|
|
487
|
+
|
|
488
|
+
EditableSchema(self).remove(pin)
|
|
489
|
+
return True
|