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,517 @@
|
|
|
1
|
+
from typing import Union, Set, List, Tuple
|
|
2
|
+
|
|
3
|
+
from siliconcompiler.schema import BaseSchema, NamedSchema, EditableSchema, Parameter, \
|
|
4
|
+
PerNode, Scope
|
|
5
|
+
from siliconcompiler import DesignSchema
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ASICTimingScenarioSchema(NamedSchema):
|
|
9
|
+
"""
|
|
10
|
+
Represents a single timing scenario for ASIC design constraints.
|
|
11
|
+
|
|
12
|
+
This class encapsulates various parameters that define a specific timing
|
|
13
|
+
scenario, such as operating voltage, temperature, library corners, PEX corners,
|
|
14
|
+
operating mode, SDC filesets, and timing checks to be performed.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
def __init__(self, name: str = None):
|
|
18
|
+
super().__init__()
|
|
19
|
+
self.set_name(name)
|
|
20
|
+
|
|
21
|
+
schema = EditableSchema(self)
|
|
22
|
+
schema.insert(
|
|
23
|
+
'voltage', 'default',
|
|
24
|
+
Parameter(
|
|
25
|
+
"float",
|
|
26
|
+
pernode=PerNode.OPTIONAL,
|
|
27
|
+
unit='V',
|
|
28
|
+
scope=Scope.GLOBAL,
|
|
29
|
+
shorthelp="Constraint: pin voltage level",
|
|
30
|
+
switch="-constraint_timing_voltage 'scenario pin <float>'",
|
|
31
|
+
example=["api: chip.set('constraint', 'timing', 'worst', 'voltage', 'VDD', '0.9')"],
|
|
32
|
+
help="""Operating voltage applied to a specific pin in the scenario."""))
|
|
33
|
+
|
|
34
|
+
schema.insert(
|
|
35
|
+
'temperature',
|
|
36
|
+
Parameter(
|
|
37
|
+
'float',
|
|
38
|
+
pernode=PerNode.OPTIONAL,
|
|
39
|
+
unit='C',
|
|
40
|
+
scope=Scope.GLOBAL,
|
|
41
|
+
shorthelp="Constraint: temperature",
|
|
42
|
+
switch="-constraint_timing_temperature 'scenario <float>'",
|
|
43
|
+
example=["api: chip.set('constraint', 'timing', 'worst', 'temperature', '125')"],
|
|
44
|
+
help="""Chip temperature applied to the scenario specified in degrees C."""))
|
|
45
|
+
|
|
46
|
+
schema.insert(
|
|
47
|
+
'libcorner',
|
|
48
|
+
Parameter(
|
|
49
|
+
'{str}',
|
|
50
|
+
pernode=PerNode.OPTIONAL,
|
|
51
|
+
scope=Scope.GLOBAL,
|
|
52
|
+
shorthelp="Constraint: library corner",
|
|
53
|
+
switch="-constraint_timing_libcorner 'scenario <str>'",
|
|
54
|
+
example=["api: chip.set('constraint', 'timing', 'worst', 'libcorner', 'ttt')"],
|
|
55
|
+
help="""List of characterization corners used to select
|
|
56
|
+
timing files for all logiclibs and macrolibs."""))
|
|
57
|
+
|
|
58
|
+
schema.insert(
|
|
59
|
+
'pexcorner',
|
|
60
|
+
Parameter(
|
|
61
|
+
'str',
|
|
62
|
+
pernode=PerNode.OPTIONAL,
|
|
63
|
+
scope=Scope.GLOBAL,
|
|
64
|
+
shorthelp="Constraint: pex corner",
|
|
65
|
+
switch="-constraint_timing_pexcorner 'scenario <str>'",
|
|
66
|
+
example=["api: chip.set('constraint', 'timing', 'worst', 'pexcorner', 'max')"],
|
|
67
|
+
help="""Parasitic corner applied to the scenario. The
|
|
68
|
+
'pexcorner' string must match a corner found in :keypath:`pdk,<pdk>,pexmodel`."""))
|
|
69
|
+
|
|
70
|
+
schema.insert(
|
|
71
|
+
'opcond',
|
|
72
|
+
Parameter(
|
|
73
|
+
'str',
|
|
74
|
+
pernode=PerNode.OPTIONAL,
|
|
75
|
+
scope=Scope.GLOBAL,
|
|
76
|
+
shorthelp="Constraint: operating condition",
|
|
77
|
+
switch="-constraint_timing_opcond 'scenario <str>'",
|
|
78
|
+
example=["api: chip.set('constraint', 'timing', 'worst', 'opcond', 'typical_1.0')"],
|
|
79
|
+
help="""Operating condition applied to the scenario. The value
|
|
80
|
+
can be used to access specific conditions within the library
|
|
81
|
+
timing models from the :keypath:`asic,logiclib` timing models."""))
|
|
82
|
+
|
|
83
|
+
schema.insert(
|
|
84
|
+
'mode',
|
|
85
|
+
Parameter(
|
|
86
|
+
'str',
|
|
87
|
+
pernode=PerNode.OPTIONAL,
|
|
88
|
+
scope=Scope.GLOBAL,
|
|
89
|
+
shorthelp="Constraint: operating mode",
|
|
90
|
+
switch="-constraint_timing_mode 'scenario <str>'",
|
|
91
|
+
example=["api: chip.set('constraint', 'timing', 'worst', 'mode', 'test')"],
|
|
92
|
+
help="""Operating mode for the scenario. Operating mode strings
|
|
93
|
+
can be values such as test, functional, standby."""))
|
|
94
|
+
|
|
95
|
+
schema.insert(
|
|
96
|
+
'sdcfileset',
|
|
97
|
+
Parameter(
|
|
98
|
+
'[(str,str)]',
|
|
99
|
+
pernode=PerNode.OPTIONAL,
|
|
100
|
+
scope=Scope.GLOBAL,
|
|
101
|
+
shorthelp="Constraint: SDC files",
|
|
102
|
+
switch="-constraint_timing_file 'scenario <file>'",
|
|
103
|
+
example=["api: chip.set('constraint', 'timing', 'worst', 'file', 'hello.sdc')"],
|
|
104
|
+
help="""List of timing constraint sets files to use for the scenario. The
|
|
105
|
+
values are combined with any constraints specified by the design
|
|
106
|
+
'constraint' parameter. If no constraints are found, a default
|
|
107
|
+
constraint file is used based on the clock definitions."""))
|
|
108
|
+
|
|
109
|
+
schema.insert(
|
|
110
|
+
'check',
|
|
111
|
+
Parameter(
|
|
112
|
+
'{<setup,hold,maxtran,maxcap,mincap,power,leakagepower,dynamicpower,signalem>}',
|
|
113
|
+
pernode=PerNode.OPTIONAL,
|
|
114
|
+
scope=Scope.GLOBAL,
|
|
115
|
+
shorthelp="Constraint: timing checks",
|
|
116
|
+
switch="-constraint_timing_check 'scenario <str>'",
|
|
117
|
+
example=["api: chip.add('constraint', 'timing', 'worst', 'check', 'setup')"],
|
|
118
|
+
help="""
|
|
119
|
+
List of checks for to perform for the scenario. The checks must
|
|
120
|
+
align with the capabilities of the EDA tools and flow being used.
|
|
121
|
+
Checks generally include objectives like meeting setup and hold goals
|
|
122
|
+
and minimize power. Standard check names include setup, hold, power,
|
|
123
|
+
noise, reliability."""))
|
|
124
|
+
|
|
125
|
+
def set_pin_voltage(self,
|
|
126
|
+
pin: str,
|
|
127
|
+
voltage: float,
|
|
128
|
+
step: str = None, index: Union[str, int] = None):
|
|
129
|
+
"""
|
|
130
|
+
Sets the voltage for a specified pin.
|
|
131
|
+
|
|
132
|
+
Args:
|
|
133
|
+
pin (str): The name of the pin.
|
|
134
|
+
voltage (float): The voltage value to set.
|
|
135
|
+
step (str, optional): step name.
|
|
136
|
+
index (str, optional): index name.
|
|
137
|
+
"""
|
|
138
|
+
return self.set("voltage", pin, voltage, step=step, index=index)
|
|
139
|
+
|
|
140
|
+
def get_pin_voltage(self,
|
|
141
|
+
pin: str,
|
|
142
|
+
step: str = None, index: Union[str, int] = None) -> float:
|
|
143
|
+
"""
|
|
144
|
+
Gets the voltage of a specified pin.
|
|
145
|
+
|
|
146
|
+
Args:
|
|
147
|
+
pin (str): The name of the pin.
|
|
148
|
+
step (str, optional): step name.
|
|
149
|
+
index (str, optional): index name.
|
|
150
|
+
|
|
151
|
+
Returns:
|
|
152
|
+
The voltage of the pin.
|
|
153
|
+
|
|
154
|
+
Raises:
|
|
155
|
+
LookupError: If the specified pin does not have a voltage defined.
|
|
156
|
+
"""
|
|
157
|
+
if not self.valid("voltage", pin):
|
|
158
|
+
raise LookupError(f"{pin} does not have voltage")
|
|
159
|
+
return self.get("voltage", pin, step=step, index=index)
|
|
160
|
+
|
|
161
|
+
def add_libcorner(self,
|
|
162
|
+
libcorner: str,
|
|
163
|
+
clobber: bool = False,
|
|
164
|
+
step: str = None, index: Union[str, int] = None):
|
|
165
|
+
"""
|
|
166
|
+
Adds a library corner to the design.
|
|
167
|
+
|
|
168
|
+
Args:
|
|
169
|
+
libcorner (str): The name of the library corner to add.
|
|
170
|
+
clobber (bool): If True, existing library corners at the specified step/index will
|
|
171
|
+
be overwritten.
|
|
172
|
+
If False (default), the library corner will be added.
|
|
173
|
+
step (str, optional): step name.
|
|
174
|
+
index (str, optional): index name.
|
|
175
|
+
"""
|
|
176
|
+
if clobber:
|
|
177
|
+
return self.set("libcorner", libcorner, step=step, index=index)
|
|
178
|
+
else:
|
|
179
|
+
return self.add("libcorner", libcorner, step=step, index=index)
|
|
180
|
+
|
|
181
|
+
def get_libcorner(self,
|
|
182
|
+
step: str = None, index: Union[str, int] = None) -> Set[str]:
|
|
183
|
+
"""
|
|
184
|
+
Gets the set of library corners.
|
|
185
|
+
|
|
186
|
+
Args:
|
|
187
|
+
step (str, optional): step name.
|
|
188
|
+
index (str, optional): index name.
|
|
189
|
+
|
|
190
|
+
Returns:
|
|
191
|
+
A set of library corner names.
|
|
192
|
+
"""
|
|
193
|
+
return self.get("libcorner", step=step, index=index)
|
|
194
|
+
|
|
195
|
+
def set_pexcorner(self,
|
|
196
|
+
pexcorner: str,
|
|
197
|
+
step: str = None, index: Union[str, int] = None):
|
|
198
|
+
"""
|
|
199
|
+
Sets the parasitic extraction (PEX) corner for the design.
|
|
200
|
+
|
|
201
|
+
Args:
|
|
202
|
+
pexcorner (str): The name of the PEX corner to set.
|
|
203
|
+
step (str, optional): step name.
|
|
204
|
+
index (str, optional): index name.
|
|
205
|
+
"""
|
|
206
|
+
return self.set("pexcorner", pexcorner, step=step, index=index)
|
|
207
|
+
|
|
208
|
+
def get_pexcorner(self,
|
|
209
|
+
step: str = None, index: Union[str, int] = None) -> str:
|
|
210
|
+
"""
|
|
211
|
+
Gets the parasitic extraction (PEX) corner currently set for the design.
|
|
212
|
+
|
|
213
|
+
Args:
|
|
214
|
+
step (str, optional): step name.
|
|
215
|
+
index (str, optional): index name.
|
|
216
|
+
|
|
217
|
+
Returns:
|
|
218
|
+
The name of the PEX corner.
|
|
219
|
+
"""
|
|
220
|
+
return self.get("pexcorner", step=step, index=index)
|
|
221
|
+
|
|
222
|
+
def set_mode(self,
|
|
223
|
+
mode: str,
|
|
224
|
+
step: str = None, index: Union[str, int] = None):
|
|
225
|
+
"""
|
|
226
|
+
Sets the operational mode for the design.
|
|
227
|
+
|
|
228
|
+
Args:
|
|
229
|
+
mode (str): The operational mode to set (e.g., "func", "scan").
|
|
230
|
+
step (str, optional): step name.
|
|
231
|
+
index (str, optional): index name.
|
|
232
|
+
"""
|
|
233
|
+
return self.set("mode", mode, step=step, index=index)
|
|
234
|
+
|
|
235
|
+
def get_mode(self,
|
|
236
|
+
step: str = None, index: Union[str, int] = None) -> str:
|
|
237
|
+
"""
|
|
238
|
+
Gets the operational mode currently set for the design.
|
|
239
|
+
|
|
240
|
+
Args:
|
|
241
|
+
step (str, optional): step name.
|
|
242
|
+
index (str, optional): index name.
|
|
243
|
+
|
|
244
|
+
Returns:
|
|
245
|
+
The name of the operational mode.
|
|
246
|
+
"""
|
|
247
|
+
return self.get("mode", step=step, index=index)
|
|
248
|
+
|
|
249
|
+
def set_opcond(self,
|
|
250
|
+
opcond: str,
|
|
251
|
+
step: str = None, index: Union[str, int] = None):
|
|
252
|
+
"""
|
|
253
|
+
Sets the operating condition for the design.
|
|
254
|
+
|
|
255
|
+
Args:
|
|
256
|
+
opcond (str): The operating condition to set (e.g., "WC", "BC").
|
|
257
|
+
step (str, optional): step name.
|
|
258
|
+
index (str, optional): index name.
|
|
259
|
+
"""
|
|
260
|
+
return self.set("opcond", opcond, step=step, index=index)
|
|
261
|
+
|
|
262
|
+
def get_opcond(self,
|
|
263
|
+
step: str = None, index: Union[str, int] = None) -> str:
|
|
264
|
+
"""
|
|
265
|
+
Gets the operating condition currently set for the design.
|
|
266
|
+
|
|
267
|
+
Args:
|
|
268
|
+
step (str, optional): step name.
|
|
269
|
+
index (str, optional): index name.
|
|
270
|
+
|
|
271
|
+
Returns:
|
|
272
|
+
The name of the operating condition.
|
|
273
|
+
"""
|
|
274
|
+
return self.get("opcond", step=step, index=index)
|
|
275
|
+
|
|
276
|
+
def set_temperature(self,
|
|
277
|
+
temperature: float,
|
|
278
|
+
step: str = None, index: Union[str, int] = None):
|
|
279
|
+
"""
|
|
280
|
+
Sets the temperature for the design.
|
|
281
|
+
|
|
282
|
+
Args:
|
|
283
|
+
temperature (float): The temperature value to set in degrees Celsius.
|
|
284
|
+
step (str, optional): step name.
|
|
285
|
+
index (str, optional): index name.
|
|
286
|
+
"""
|
|
287
|
+
return self.set("temperature", temperature, step=step, index=index)
|
|
288
|
+
|
|
289
|
+
def get_temperature(self,
|
|
290
|
+
step: str = None, index: Union[str, int] = None) -> float:
|
|
291
|
+
"""
|
|
292
|
+
Gets the temperature currently set for the design.
|
|
293
|
+
|
|
294
|
+
Args:
|
|
295
|
+
step (str, optional): step name.
|
|
296
|
+
index (str, optional): index name.
|
|
297
|
+
|
|
298
|
+
Returns:
|
|
299
|
+
The temperature in degrees Celsius.
|
|
300
|
+
"""
|
|
301
|
+
return self.get("temperature", step=step, index=index)
|
|
302
|
+
|
|
303
|
+
def add_sdcfileset(self,
|
|
304
|
+
design: Union[DesignSchema, str],
|
|
305
|
+
fileset: str,
|
|
306
|
+
clobber: bool = False,
|
|
307
|
+
step: str = None, index: Union[str, int] = None):
|
|
308
|
+
"""
|
|
309
|
+
Adds an SDC fileset for a given design.
|
|
310
|
+
|
|
311
|
+
Args:
|
|
312
|
+
design (:class:`DesignSchema` or str): The design object or the name of the design to
|
|
313
|
+
associate the fileset with.
|
|
314
|
+
fileset (str): The name of the SDC fileset to add.
|
|
315
|
+
clobber (bool): If True, existing SDC filesets for the design at the specified
|
|
316
|
+
step/index will be overwritten.
|
|
317
|
+
If False (default), the SDC fileset will be added.
|
|
318
|
+
step (str, optional): step name.
|
|
319
|
+
index (str, optional): index name.
|
|
320
|
+
|
|
321
|
+
Raises:
|
|
322
|
+
TypeError: If `design` is not a DesignSchema object or a string, or if `fileset` is not
|
|
323
|
+
a string.
|
|
324
|
+
"""
|
|
325
|
+
if isinstance(design, DesignSchema):
|
|
326
|
+
design = design.name()
|
|
327
|
+
|
|
328
|
+
if not isinstance(design, str):
|
|
329
|
+
raise TypeError("design must be a design object or string")
|
|
330
|
+
|
|
331
|
+
if not isinstance(fileset, str):
|
|
332
|
+
raise TypeError("fileset must be a string")
|
|
333
|
+
|
|
334
|
+
if clobber:
|
|
335
|
+
return self.set("sdcfileset", (design, fileset), step=step, index=index)
|
|
336
|
+
else:
|
|
337
|
+
return self.add("sdcfileset", (design, fileset), step=step, index=index)
|
|
338
|
+
|
|
339
|
+
def get_sdcfileset(self,
|
|
340
|
+
step: str = None, index: Union[str, int] = None) -> List[Tuple[str, str]]:
|
|
341
|
+
"""
|
|
342
|
+
Gets the list of SDC filesets.
|
|
343
|
+
|
|
344
|
+
Args:
|
|
345
|
+
step (str, optional): step name.
|
|
346
|
+
index (str, optional): index name.
|
|
347
|
+
|
|
348
|
+
Returns:
|
|
349
|
+
A list of tuples, where each tuple contains the design name and the SDC fileset name.
|
|
350
|
+
"""
|
|
351
|
+
return self.get("sdcfileset", step=step, index=index)
|
|
352
|
+
|
|
353
|
+
def add_check(self,
|
|
354
|
+
check: str,
|
|
355
|
+
clobber: bool = False,
|
|
356
|
+
step: str = None, index: Union[str, int] = None):
|
|
357
|
+
"""
|
|
358
|
+
Adds a check to the design process.
|
|
359
|
+
|
|
360
|
+
Args:
|
|
361
|
+
check (str): The name of the check to add.
|
|
362
|
+
clobber (bool): If True, existing checks at the specified step/index will
|
|
363
|
+
be overwritten.
|
|
364
|
+
If False (default), the check will be added.
|
|
365
|
+
step (str, optional): step name.
|
|
366
|
+
index (str, optional): index name.
|
|
367
|
+
"""
|
|
368
|
+
if clobber:
|
|
369
|
+
return self.set("check", check, step=step, index=index)
|
|
370
|
+
else:
|
|
371
|
+
return self.add("check", check, step=step, index=index)
|
|
372
|
+
|
|
373
|
+
def get_check(self, step: str = None, index: Union[str, int] = None) -> Set[str]:
|
|
374
|
+
"""
|
|
375
|
+
Gets the set of checks configured for the design process.
|
|
376
|
+
|
|
377
|
+
Args:
|
|
378
|
+
step (str, optional): step name.
|
|
379
|
+
index (str, optional): index name.
|
|
380
|
+
|
|
381
|
+
Returns:
|
|
382
|
+
A set of check names.
|
|
383
|
+
"""
|
|
384
|
+
return self.get("check", step=step, index=index)
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
class ASICTimingConstraintSchema(BaseSchema):
|
|
388
|
+
"""
|
|
389
|
+
Manages a collection of ASIC timing scenarios for design constraints.
|
|
390
|
+
|
|
391
|
+
This class provides methods to add, retrieve, create, and remove
|
|
392
|
+
individual :class:`ASICTimingScenarioSchema` objects, allowing for organized
|
|
393
|
+
management of various timing-related constraints for different operating
|
|
394
|
+
conditions or analysis modes.
|
|
395
|
+
"""
|
|
396
|
+
|
|
397
|
+
def __init__(self):
|
|
398
|
+
super().__init__()
|
|
399
|
+
|
|
400
|
+
EditableSchema(self).insert("default", ASICTimingScenarioSchema())
|
|
401
|
+
|
|
402
|
+
def add_scenario(self, scenario: ASICTimingScenarioSchema):
|
|
403
|
+
"""
|
|
404
|
+
Adds a timing scenario to the design configuration.
|
|
405
|
+
|
|
406
|
+
This method is responsible for incorporating a new or updated timing scenario
|
|
407
|
+
into the system's configuration. If a scenario with the same name already
|
|
408
|
+
exists, it will be overwritten (`clobber=True`).
|
|
409
|
+
|
|
410
|
+
Args:
|
|
411
|
+
scenario: The :class:`ASICTimingScenarioSchema` object representing the timing scenario
|
|
412
|
+
to add. This object must have a valid name defined via its `name()` method.
|
|
413
|
+
|
|
414
|
+
Raises:
|
|
415
|
+
TypeError: If the provided `scenario` argument is not an instance of
|
|
416
|
+
:class:`ASICTimingScenarioSchema`.
|
|
417
|
+
ValueError: If the `scenario` object's `name()` method returns None, indicating
|
|
418
|
+
that the scenario does not have a defined name.
|
|
419
|
+
"""
|
|
420
|
+
if not isinstance(scenario, ASICTimingScenarioSchema):
|
|
421
|
+
raise TypeError("scenario must be a timing scenario object")
|
|
422
|
+
|
|
423
|
+
if scenario.name() is None:
|
|
424
|
+
raise ValueError("scenario must have a name")
|
|
425
|
+
|
|
426
|
+
EditableSchema(self).insert(scenario.name(), scenario, clobber=True)
|
|
427
|
+
|
|
428
|
+
def get_scenario(self, scenario: str = None):
|
|
429
|
+
"""
|
|
430
|
+
Retrieves one or all timing scenarios from the configuration.
|
|
431
|
+
|
|
432
|
+
This method provides flexibility to fetch either a specific timing scenario
|
|
433
|
+
by its name or a collection of all currently defined scenarios.
|
|
434
|
+
|
|
435
|
+
Args:
|
|
436
|
+
scenario (str, optional): The name (string) of the specific timing scenario to retrieve.
|
|
437
|
+
If this argument is omitted or set to None, the method will return
|
|
438
|
+
a dictionary containing all available timing scenarios.
|
|
439
|
+
|
|
440
|
+
Returns:
|
|
441
|
+
- If `scenario` is provided: The :class:`ASICTimingScenarioSchema` object corresponding
|
|
442
|
+
to the specified scenario name.
|
|
443
|
+
- If `scenario` is None: A dictionary where keys are scenario names (str) and
|
|
444
|
+
values are their respective :class:`ASICTimingScenarioSchema` objects.
|
|
445
|
+
|
|
446
|
+
Raises:
|
|
447
|
+
LookupError: If a specific `scenario` name is provided but no scenario with
|
|
448
|
+
that name is found in the configuration.
|
|
449
|
+
"""
|
|
450
|
+
if scenario is None:
|
|
451
|
+
scenarios = {}
|
|
452
|
+
for scenario in self.getkeys():
|
|
453
|
+
scenarios[scenario] = self.get(scenario, field="schema")
|
|
454
|
+
return scenarios
|
|
455
|
+
|
|
456
|
+
if not self.valid(scenario):
|
|
457
|
+
raise LookupError(f"{scenario} is not defined")
|
|
458
|
+
return self.get(scenario, field="schema")
|
|
459
|
+
|
|
460
|
+
def make_scenario(self, scenario: str) -> ASICTimingScenarioSchema:
|
|
461
|
+
"""
|
|
462
|
+
Creates and adds a new timing scenario with the specified name.
|
|
463
|
+
|
|
464
|
+
This method initializes a new :class:`ASICTimingScenarioSchema` object with the given
|
|
465
|
+
name and immediately adds it to the constraint configuration. It ensures that
|
|
466
|
+
a scenario with the same name does not already exist, preventing accidental
|
|
467
|
+
overwrites.
|
|
468
|
+
|
|
469
|
+
Args:
|
|
470
|
+
scenario (str): The name for the new timing scenario. This name must be
|
|
471
|
+
a non-empty string and unique within the current configuration.
|
|
472
|
+
|
|
473
|
+
Returns:
|
|
474
|
+
:class:ASICTimingScenarioSchema: The newly created :class:`ASICTimingScenarioSchema`
|
|
475
|
+
object.
|
|
476
|
+
|
|
477
|
+
Raises:
|
|
478
|
+
ValueError: If the provided `scenario` name is empty or None.
|
|
479
|
+
LookupError: If a scenario with the specified `scenario` name already exists
|
|
480
|
+
in the configuration.
|
|
481
|
+
"""
|
|
482
|
+
if not scenario:
|
|
483
|
+
raise ValueError("scenario name is required")
|
|
484
|
+
|
|
485
|
+
if self.valid(scenario):
|
|
486
|
+
raise LookupError(f"{scenario} scenario already exists")
|
|
487
|
+
|
|
488
|
+
scenarioobj = ASICTimingScenarioSchema(scenario)
|
|
489
|
+
self.add_scenario(scenarioobj)
|
|
490
|
+
return scenarioobj
|
|
491
|
+
|
|
492
|
+
def remove_scenario(self, scenario: str) -> bool:
|
|
493
|
+
"""
|
|
494
|
+
Removes a timing scenario from the design configuration.
|
|
495
|
+
|
|
496
|
+
This method deletes the specified timing scenario from the system's
|
|
497
|
+
configuration.
|
|
498
|
+
|
|
499
|
+
Args:
|
|
500
|
+
scenario (str): The name of the timing scenario to remove.
|
|
501
|
+
This name must be a non-empty string.
|
|
502
|
+
|
|
503
|
+
Returns:
|
|
504
|
+
bool: True if the scenario was successfully removed, False if no
|
|
505
|
+
scenario with the given name was found.
|
|
506
|
+
|
|
507
|
+
Raises:
|
|
508
|
+
ValueError: If the provided `scenario` name is empty or None.
|
|
509
|
+
"""
|
|
510
|
+
if not scenario:
|
|
511
|
+
raise ValueError("scenario name is required")
|
|
512
|
+
|
|
513
|
+
if not self.valid(scenario):
|
|
514
|
+
return False
|
|
515
|
+
|
|
516
|
+
EditableSchema(self).remove(scenario)
|
|
517
|
+
return True
|