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
|
@@ -15,16 +15,36 @@ class NamedSchema(BaseSchema):
|
|
|
15
15
|
name (str): name of the schema
|
|
16
16
|
'''
|
|
17
17
|
|
|
18
|
-
def __init__(self, name):
|
|
18
|
+
def __init__(self, name: str = None):
|
|
19
19
|
super().__init__()
|
|
20
20
|
|
|
21
|
-
self.
|
|
21
|
+
self.set_name(name)
|
|
22
22
|
|
|
23
|
-
def name(self):
|
|
23
|
+
def name(self) -> str:
|
|
24
24
|
'''
|
|
25
25
|
Returns the name of the schema
|
|
26
26
|
'''
|
|
27
|
-
|
|
27
|
+
try:
|
|
28
|
+
return self.__name
|
|
29
|
+
except AttributeError:
|
|
30
|
+
return None
|
|
31
|
+
|
|
32
|
+
def set_name(self, name: str) -> None:
|
|
33
|
+
"""
|
|
34
|
+
Set the name of this object
|
|
35
|
+
|
|
36
|
+
Raises:
|
|
37
|
+
RuntimeError: if called after object name is set.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
name (str): name for object
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
if self.name() is not None:
|
|
44
|
+
raise RuntimeError("Cannot call set_name more than once.")
|
|
45
|
+
if name is not None and "." in name:
|
|
46
|
+
raise ValueError("Named schema object cannot contains: .")
|
|
47
|
+
self.__name = name
|
|
28
48
|
|
|
29
49
|
def _reset(self) -> None:
|
|
30
50
|
"""
|
|
@@ -32,6 +52,12 @@ class NamedSchema(BaseSchema):
|
|
|
32
52
|
"""
|
|
33
53
|
pass
|
|
34
54
|
|
|
55
|
+
def type(self) -> str:
|
|
56
|
+
"""
|
|
57
|
+
Returns the type of this object
|
|
58
|
+
"""
|
|
59
|
+
raise NotImplementedError("Must be implemented by the child classes.")
|
|
60
|
+
|
|
35
61
|
@classmethod
|
|
36
62
|
def from_manifest(cls, name, filepath=None, cfg=None):
|
|
37
63
|
'''
|
|
@@ -11,7 +11,8 @@ import shlex
|
|
|
11
11
|
|
|
12
12
|
from enum import Enum
|
|
13
13
|
|
|
14
|
-
from .parametervalue import NodeValue, DirectoryNodeValue, FileNodeValue, NodeListValue
|
|
14
|
+
from .parametervalue import NodeValue, DirectoryNodeValue, FileNodeValue, NodeListValue, \
|
|
15
|
+
NodeSetValue
|
|
15
16
|
from .parametertype import NodeType, NodeEnumType
|
|
16
17
|
|
|
17
18
|
|
|
@@ -59,6 +60,7 @@ class Parameter:
|
|
|
59
60
|
example (list of str): example field
|
|
60
61
|
help (str): help field
|
|
61
62
|
pernode (:class:`.PerNode`): pernode field
|
|
63
|
+
kwargs: forwarded to default value constructor
|
|
62
64
|
'''
|
|
63
65
|
|
|
64
66
|
GLOBAL_KEY = 'global'
|
|
@@ -77,7 +79,8 @@ class Parameter:
|
|
|
77
79
|
switch=None,
|
|
78
80
|
example=None,
|
|
79
81
|
help=None,
|
|
80
|
-
pernode=PerNode.NEVER
|
|
82
|
+
pernode=PerNode.NEVER,
|
|
83
|
+
**kwargs):
|
|
81
84
|
|
|
82
85
|
self.__type = NodeType.parse(type)
|
|
83
86
|
self.__scope = Scope(scope)
|
|
@@ -108,7 +111,7 @@ class Parameter:
|
|
|
108
111
|
|
|
109
112
|
self.__pernode = PerNode(pernode)
|
|
110
113
|
|
|
111
|
-
self.__setdefvalue(defvalue)
|
|
114
|
+
self.__setdefvalue(defvalue, **kwargs)
|
|
112
115
|
|
|
113
116
|
self.__node = {}
|
|
114
117
|
|
|
@@ -123,26 +126,33 @@ class Parameter:
|
|
|
123
126
|
self.__hashalgo = str(hashalgo)
|
|
124
127
|
self.__copy = bool(copy)
|
|
125
128
|
|
|
126
|
-
def __setdefvalue(self, defvalue):
|
|
129
|
+
def __setdefvalue(self, defvalue, **kwargs):
|
|
127
130
|
if NodeType.contains(self.__type, 'file'):
|
|
128
|
-
base = FileNodeValue(defvalue)
|
|
129
131
|
if isinstance(self.__type, list):
|
|
130
|
-
self.__defvalue = NodeListValue(
|
|
132
|
+
self.__defvalue = NodeListValue(FileNodeValue(defvalue, **kwargs))
|
|
133
|
+
elif isinstance(self.__type, set):
|
|
134
|
+
self.__defvalue = NodeSetValue(FileNodeValue(defvalue, **kwargs))
|
|
131
135
|
else:
|
|
132
|
-
self.__defvalue =
|
|
136
|
+
self.__defvalue = FileNodeValue(defvalue, **kwargs)
|
|
133
137
|
elif NodeType.contains(self.__type, 'dir'):
|
|
134
|
-
base = DirectoryNodeValue(defvalue)
|
|
135
138
|
if isinstance(self.__type, list):
|
|
136
|
-
self.__defvalue = NodeListValue(
|
|
139
|
+
self.__defvalue = NodeListValue(DirectoryNodeValue(defvalue, **kwargs))
|
|
140
|
+
elif isinstance(self.__type, set):
|
|
141
|
+
self.__defvalue = NodeSetValue(DirectoryNodeValue(defvalue, **kwargs))
|
|
137
142
|
else:
|
|
138
|
-
self.__defvalue =
|
|
143
|
+
self.__defvalue = DirectoryNodeValue(defvalue, **kwargs)
|
|
139
144
|
else:
|
|
145
|
+
kwargs = {}
|
|
140
146
|
if isinstance(self.__type, list):
|
|
141
|
-
self.__defvalue = NodeListValue(NodeValue(self.__type[0]))
|
|
147
|
+
self.__defvalue = NodeListValue(NodeValue(self.__type[0], **kwargs))
|
|
148
|
+
if defvalue:
|
|
149
|
+
self.__defvalue.set(defvalue)
|
|
150
|
+
elif isinstance(self.__type, set):
|
|
151
|
+
self.__defvalue = NodeSetValue(NodeValue(list(self.__type)[0], **kwargs))
|
|
142
152
|
if defvalue:
|
|
143
153
|
self.__defvalue.set(defvalue)
|
|
144
154
|
else:
|
|
145
|
-
self.__defvalue = NodeValue(self.__type, value=defvalue)
|
|
155
|
+
self.__defvalue = NodeValue(self.__type, value=defvalue, **kwargs)
|
|
146
156
|
|
|
147
157
|
def __str__(self):
|
|
148
158
|
return str(self.getvalues())
|
|
@@ -344,7 +354,7 @@ class Parameter:
|
|
|
344
354
|
|
|
345
355
|
if field in self.__defvalue.fields:
|
|
346
356
|
if not self.is_list() and field == 'value':
|
|
347
|
-
raise ValueError("add can only be used on lists")
|
|
357
|
+
raise ValueError("add can only be used on lists or sets")
|
|
348
358
|
|
|
349
359
|
if isinstance(index, int):
|
|
350
360
|
index = str(index)
|
|
@@ -409,6 +419,12 @@ class Parameter:
|
|
|
409
419
|
|
|
410
420
|
return True
|
|
411
421
|
|
|
422
|
+
def reset(self):
|
|
423
|
+
"""
|
|
424
|
+
Resets a parameter back to its default state
|
|
425
|
+
"""
|
|
426
|
+
self.__node = {}
|
|
427
|
+
|
|
412
428
|
def getdict(self, include_default=True, values_only=False):
|
|
413
429
|
"""
|
|
414
430
|
Returns a schema dictionary.
|
|
@@ -523,15 +539,14 @@ class Parameter:
|
|
|
523
539
|
requires_set = NodeType.contains(self.__type, tuple) or NodeType.contains(self.__type, set)
|
|
524
540
|
|
|
525
541
|
try:
|
|
526
|
-
defvalue = manifest["node"]["default"]["default"]
|
|
542
|
+
defvalue = manifest["node"]["default"]["default"]
|
|
527
543
|
del manifest["node"]["default"]
|
|
528
544
|
except KeyError:
|
|
529
545
|
defvalue = None
|
|
530
546
|
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
self.__setdefvalue(defvalue)
|
|
547
|
+
self.__setdefvalue(None)
|
|
548
|
+
if defvalue:
|
|
549
|
+
self.__defvalue._from_dict(defvalue, keypath, version)
|
|
535
550
|
|
|
536
551
|
for step, indexdata in manifest["node"].items():
|
|
537
552
|
self.__node[step] = {}
|
|
@@ -607,7 +622,7 @@ class Parameter:
|
|
|
607
622
|
Returns true is this parameter is a list type
|
|
608
623
|
"""
|
|
609
624
|
|
|
610
|
-
return isinstance(self.__type, list)
|
|
625
|
+
return isinstance(self.__type, (list, set))
|
|
611
626
|
|
|
612
627
|
def is_empty(self):
|
|
613
628
|
'''
|
|
@@ -100,6 +100,8 @@ class NodeType:
|
|
|
100
100
|
return True
|
|
101
101
|
if isinstance(value, list):
|
|
102
102
|
return NodeType.contains(value[0], check)
|
|
103
|
+
if isinstance(value, set):
|
|
104
|
+
return NodeType.contains(list(value)[0], check)
|
|
103
105
|
if isinstance(value, tuple):
|
|
104
106
|
return any([NodeType.contains(v, check) for v in value])
|
|
105
107
|
return value == check
|
|
@@ -83,11 +83,15 @@ class NodeListValue:
|
|
|
83
83
|
field (str): name of schema field.
|
|
84
84
|
"""
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
86
|
+
if self.__values:
|
|
87
|
+
vals = []
|
|
88
|
+
for val in self.__values:
|
|
89
|
+
vals.append(val.get(field=field))
|
|
90
|
+
return vals
|
|
91
|
+
if self.__base.get("value") is None:
|
|
92
|
+
return []
|
|
93
|
+
|
|
94
|
+
return [self.__base.get(field=field)]
|
|
91
95
|
|
|
92
96
|
def set(self, value, field='value'):
|
|
93
97
|
"""
|
|
@@ -178,6 +182,185 @@ class NodeListValue:
|
|
|
178
182
|
return [self.__base.type]
|
|
179
183
|
|
|
180
184
|
|
|
185
|
+
class NodeSetValue:
|
|
186
|
+
'''
|
|
187
|
+
Holds the data for a set schema type.
|
|
188
|
+
|
|
189
|
+
Args:
|
|
190
|
+
base (:class:`NodeValue`): base type for this set.
|
|
191
|
+
'''
|
|
192
|
+
|
|
193
|
+
def __init__(self, base):
|
|
194
|
+
self.__base = base
|
|
195
|
+
self.__values = []
|
|
196
|
+
|
|
197
|
+
def getdict(self):
|
|
198
|
+
"""
|
|
199
|
+
Returns a schema dictionary.
|
|
200
|
+
|
|
201
|
+
Examples:
|
|
202
|
+
>>> value.getdict()
|
|
203
|
+
Returns the complete dictionary for the value
|
|
204
|
+
"""
|
|
205
|
+
|
|
206
|
+
manifest = {}
|
|
207
|
+
for field in self.fields:
|
|
208
|
+
if field is None:
|
|
209
|
+
continue
|
|
210
|
+
|
|
211
|
+
value = self.get(field=field, ordered=True)
|
|
212
|
+
manifest.setdefault(field, []).extend(value)
|
|
213
|
+
|
|
214
|
+
if field == "author":
|
|
215
|
+
tmplist = []
|
|
216
|
+
for a in manifest[field]:
|
|
217
|
+
tmplist.extend(a)
|
|
218
|
+
manifest[field] = tmplist
|
|
219
|
+
return manifest
|
|
220
|
+
|
|
221
|
+
def _from_dict(self, manifest, keypath, version):
|
|
222
|
+
'''
|
|
223
|
+
Create a new value based on the provided dictionary.
|
|
224
|
+
|
|
225
|
+
Args:
|
|
226
|
+
manifest (dict): Manifest to decide.
|
|
227
|
+
keypath (list of str): Path to the current keypath.
|
|
228
|
+
version (packaging.Version): Version of the dictionary schema
|
|
229
|
+
sctype (str): schema type for this value
|
|
230
|
+
'''
|
|
231
|
+
|
|
232
|
+
self.__values.clear()
|
|
233
|
+
for n in range(len(manifest["value"])):
|
|
234
|
+
param = self.__base.copy()
|
|
235
|
+
self.__values.append(param)
|
|
236
|
+
|
|
237
|
+
for field in self.fields:
|
|
238
|
+
if field is None:
|
|
239
|
+
continue
|
|
240
|
+
|
|
241
|
+
if len(manifest[field]) <= n:
|
|
242
|
+
continue
|
|
243
|
+
param.set(manifest[field][n], field=field)
|
|
244
|
+
|
|
245
|
+
def get(self, field='value', ordered: bool = False):
|
|
246
|
+
"""
|
|
247
|
+
Returns the value in the specified field
|
|
248
|
+
|
|
249
|
+
Args:
|
|
250
|
+
field (str): name of schema field.
|
|
251
|
+
ordered (bool): if true, returns a list instead of set for values
|
|
252
|
+
"""
|
|
253
|
+
|
|
254
|
+
vals = []
|
|
255
|
+
|
|
256
|
+
if self.__values:
|
|
257
|
+
for val in self.__values:
|
|
258
|
+
vals.append(val.get(field=field))
|
|
259
|
+
elif self.__base.get("value") is None:
|
|
260
|
+
pass
|
|
261
|
+
else:
|
|
262
|
+
vals.append(self.__base.get(field=field))
|
|
263
|
+
|
|
264
|
+
if not ordered and field == "value":
|
|
265
|
+
return set(vals)
|
|
266
|
+
return vals
|
|
267
|
+
|
|
268
|
+
def set(self, value, field='value'):
|
|
269
|
+
value = NodeType.normalize(value, [self.__base.type])
|
|
270
|
+
|
|
271
|
+
if field == 'value':
|
|
272
|
+
self.__values.clear()
|
|
273
|
+
else:
|
|
274
|
+
if len(value) != len(self.__values):
|
|
275
|
+
raise ValueError(f"set on {field} field must match number of values")
|
|
276
|
+
|
|
277
|
+
current_values = []
|
|
278
|
+
if field == "value":
|
|
279
|
+
current_values = [v.get() for v in self.__values]
|
|
280
|
+
|
|
281
|
+
modified = list()
|
|
282
|
+
m = 0
|
|
283
|
+
for n in range(len(value)):
|
|
284
|
+
if field == 'value':
|
|
285
|
+
if value[n] in current_values:
|
|
286
|
+
continue
|
|
287
|
+
|
|
288
|
+
self.__values.append(self.__base.copy())
|
|
289
|
+
current_values.append(value[n])
|
|
290
|
+
self.__values[m].set(value[n], field=field)
|
|
291
|
+
modified.append(self.__values[m])
|
|
292
|
+
m += 1
|
|
293
|
+
return tuple(modified)
|
|
294
|
+
|
|
295
|
+
def add(self, value, field='value'):
|
|
296
|
+
"""
|
|
297
|
+
Adds the value in a specific field and ensures it has been normalized.
|
|
298
|
+
|
|
299
|
+
Returns:
|
|
300
|
+
tuple of modified values
|
|
301
|
+
|
|
302
|
+
Args:
|
|
303
|
+
value (any): value to set
|
|
304
|
+
field (str): field to set
|
|
305
|
+
"""
|
|
306
|
+
|
|
307
|
+
current_values = []
|
|
308
|
+
if field == "value":
|
|
309
|
+
current_values = [v.get() for v in self.__values]
|
|
310
|
+
|
|
311
|
+
modified = list()
|
|
312
|
+
if field == 'value':
|
|
313
|
+
value = NodeType.normalize(value, [self.__base.type])
|
|
314
|
+
|
|
315
|
+
for n in range(len(value)):
|
|
316
|
+
if value[n] in current_values:
|
|
317
|
+
continue
|
|
318
|
+
|
|
319
|
+
self.__values.append(self.__base.copy())
|
|
320
|
+
self.__values[-1].set(value[n], field=field)
|
|
321
|
+
current_values.append(value[n])
|
|
322
|
+
modified.append(self.__values[-1])
|
|
323
|
+
else:
|
|
324
|
+
for val in self.__values:
|
|
325
|
+
val.add(value, field=field)
|
|
326
|
+
modified.append(val)
|
|
327
|
+
return tuple(modified)
|
|
328
|
+
|
|
329
|
+
@property
|
|
330
|
+
def fields(self):
|
|
331
|
+
"""
|
|
332
|
+
Returns a list of valid fields for this value
|
|
333
|
+
"""
|
|
334
|
+
return self.__base.fields
|
|
335
|
+
|
|
336
|
+
@property
|
|
337
|
+
def values(self):
|
|
338
|
+
'''
|
|
339
|
+
Returns a copy of the values stored in the list
|
|
340
|
+
'''
|
|
341
|
+
return self.__values.copy()
|
|
342
|
+
|
|
343
|
+
def copy(self):
|
|
344
|
+
"""
|
|
345
|
+
Returns a copy of this value.
|
|
346
|
+
"""
|
|
347
|
+
|
|
348
|
+
return copy.deepcopy(self)
|
|
349
|
+
|
|
350
|
+
def _set_type(self, sctype):
|
|
351
|
+
sctype = NodeType.parse(sctype)[0]
|
|
352
|
+
self.__base._set_type(sctype)
|
|
353
|
+
for val in self.__values:
|
|
354
|
+
val._set_type(sctype)
|
|
355
|
+
|
|
356
|
+
@property
|
|
357
|
+
def type(self):
|
|
358
|
+
"""
|
|
359
|
+
Returns the type for this value
|
|
360
|
+
"""
|
|
361
|
+
return set([self.__base.type])
|
|
362
|
+
|
|
363
|
+
|
|
181
364
|
class NodeValue:
|
|
182
365
|
'''
|
|
183
366
|
Holds the data for a parameter.
|
|
@@ -375,10 +558,10 @@ class PathNodeValue(NodeValue):
|
|
|
375
558
|
value (any): default value for this parameter
|
|
376
559
|
'''
|
|
377
560
|
|
|
378
|
-
def __init__(self, type, value=None):
|
|
561
|
+
def __init__(self, type, value=None, package=None):
|
|
379
562
|
super().__init__(type, value=value)
|
|
380
563
|
self.__filehash = None
|
|
381
|
-
self.__package =
|
|
564
|
+
self.__package = package
|
|
382
565
|
|
|
383
566
|
def getdict(self):
|
|
384
567
|
return {
|
|
@@ -439,7 +622,7 @@ class PathNodeValue(NodeValue):
|
|
|
439
622
|
|
|
440
623
|
return None
|
|
441
624
|
|
|
442
|
-
def resolve_path(self, search=None, collection_dir=None):
|
|
625
|
+
def resolve_path(self, search=None, collection_dir=None) -> str:
|
|
443
626
|
"""
|
|
444
627
|
Resolve the path of this value.
|
|
445
628
|
|
|
@@ -457,10 +640,10 @@ class PathNodeValue(NodeValue):
|
|
|
457
640
|
if collection_dir:
|
|
458
641
|
collect_path = self.__resolve_collection_path(value, collection_dir)
|
|
459
642
|
if collect_path:
|
|
460
|
-
return collect_path
|
|
643
|
+
return str(pathlib.Path(collect_path))
|
|
461
644
|
|
|
462
645
|
if os.path.isabs(value) and os.path.exists(value):
|
|
463
|
-
return value
|
|
646
|
+
return str(pathlib.Path(value))
|
|
464
647
|
|
|
465
648
|
# Search for file
|
|
466
649
|
if search is None:
|
|
@@ -469,7 +652,7 @@ class PathNodeValue(NodeValue):
|
|
|
469
652
|
for searchdir in search:
|
|
470
653
|
abspath = os.path.abspath(os.path.join(searchdir, value))
|
|
471
654
|
if os.path.exists(abspath):
|
|
472
|
-
return abspath
|
|
655
|
+
return str(pathlib.Path(abspath))
|
|
473
656
|
|
|
474
657
|
# File not found
|
|
475
658
|
raise FileNotFoundError(value)
|
|
@@ -603,8 +786,8 @@ class DirectoryNodeValue(PathNodeValue):
|
|
|
603
786
|
value (any): default value for this parameter
|
|
604
787
|
'''
|
|
605
788
|
|
|
606
|
-
def __init__(self, value=None):
|
|
607
|
-
super().__init__("dir", value=value)
|
|
789
|
+
def __init__(self, value=None, package=None):
|
|
790
|
+
super().__init__("dir", value=value, package=package)
|
|
608
791
|
|
|
609
792
|
def hash(self, function, **kwargs):
|
|
610
793
|
"""
|
|
@@ -631,8 +814,8 @@ class FileNodeValue(PathNodeValue):
|
|
|
631
814
|
value (any): default value for this parameter
|
|
632
815
|
'''
|
|
633
816
|
|
|
634
|
-
def __init__(self, value=None):
|
|
635
|
-
super().__init__("file", value=value)
|
|
817
|
+
def __init__(self, value=None, package=None):
|
|
818
|
+
super().__init__("file", value=value, package=package)
|
|
636
819
|
self.__date = None
|
|
637
820
|
self.__author = []
|
|
638
821
|
|
|
@@ -59,16 +59,7 @@ def schema_cfg(schema):
|
|
|
59
59
|
# Basic schema setup
|
|
60
60
|
cfg = EditableSchema(schema)
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
sctype='str',
|
|
64
|
-
scope=Scope.GLOBAL,
|
|
65
|
-
defvalue=SCHEMA_VERSION,
|
|
66
|
-
require=True,
|
|
67
|
-
shorthelp="Schema version number",
|
|
68
|
-
lock=True,
|
|
69
|
-
switch="-schemaversion <str>",
|
|
70
|
-
example=["api: chip.get('schemaversion')"],
|
|
71
|
-
schelp="""SiliconCompiler schema version number.""")
|
|
62
|
+
schema_version(cfg)
|
|
72
63
|
|
|
73
64
|
# Design topmodule/entrypoint
|
|
74
65
|
scparam(cfg, ['design'],
|
|
@@ -139,6 +130,19 @@ def schema_cfg(schema):
|
|
|
139
130
|
cfg = schema_schematic(cfg)
|
|
140
131
|
|
|
141
132
|
|
|
133
|
+
def schema_version(cfg):
|
|
134
|
+
scparam(cfg, ['schemaversion'],
|
|
135
|
+
sctype='str',
|
|
136
|
+
scope=Scope.GLOBAL,
|
|
137
|
+
defvalue=SCHEMA_VERSION,
|
|
138
|
+
require=True,
|
|
139
|
+
shorthelp="Schema version number",
|
|
140
|
+
lock=True,
|
|
141
|
+
switch="-schemaversion <str>",
|
|
142
|
+
example=["api: chip.get('schemaversion')"],
|
|
143
|
+
schelp="""SiliconCompiler schema version number.""")
|
|
144
|
+
|
|
145
|
+
|
|
142
146
|
###############################################################################
|
|
143
147
|
# SCHEMATIC
|
|
144
148
|
###############################################################################
|
|
@@ -1071,8 +1075,8 @@ def schema_arg(cfg):
|
|
|
1071
1075
|
# Metrics to Track
|
|
1072
1076
|
###########################################################################
|
|
1073
1077
|
def schema_metric(cfg):
|
|
1074
|
-
from siliconcompiler.metric import
|
|
1075
|
-
cfg.insert("metric",
|
|
1078
|
+
from siliconcompiler.metric import MetricSchemaTmp
|
|
1079
|
+
cfg.insert("metric", MetricSchemaTmp())
|
|
1076
1080
|
return cfg
|
|
1077
1081
|
|
|
1078
1082
|
|
|
@@ -1773,8 +1777,8 @@ def schema_option_frontend(cfg):
|
|
|
1773
1777
|
# Package information
|
|
1774
1778
|
############################################
|
|
1775
1779
|
def schema_package(cfg):
|
|
1776
|
-
from siliconcompiler.packageschema import
|
|
1777
|
-
cfg.insert("package",
|
|
1780
|
+
from siliconcompiler.packageschema import PackageSchemaTmp
|
|
1781
|
+
cfg.insert("package", PackageSchemaTmp())
|
|
1778
1782
|
return cfg
|
|
1779
1783
|
|
|
1780
1784
|
|
siliconcompiler/schema_obj.py
CHANGED
|
@@ -9,7 +9,6 @@ from siliconcompiler.schema import SafeSchema
|
|
|
9
9
|
from siliconcompiler.schema import EditableSchema
|
|
10
10
|
from siliconcompiler.schema import CommandLineSchema
|
|
11
11
|
from siliconcompiler.schema import Parameter
|
|
12
|
-
from siliconcompiler.schema.baseschema import json
|
|
13
12
|
|
|
14
13
|
from siliconcompiler.schema.schema_cfg import schema_cfg
|
|
15
14
|
|
|
@@ -85,6 +84,9 @@ class SchemaTmp(Schema, CommandLineSchema):
|
|
|
85
84
|
|
|
86
85
|
super()._from_dict(manifest, keypath, version=version)
|
|
87
86
|
|
|
87
|
+
def _find_files_dataroot_resolvers(self):
|
|
88
|
+
return self.get("package", field="schema").get_resolvers()
|
|
89
|
+
|
|
88
90
|
def record_history(self):
|
|
89
91
|
'''
|
|
90
92
|
Copies all non-empty parameters from current job into the history
|
|
@@ -115,5 +117,5 @@ class SchemaTmp(Schema, CommandLineSchema):
|
|
|
115
117
|
##############################################################################
|
|
116
118
|
# Main routine
|
|
117
119
|
if __name__ == "__main__":
|
|
118
|
-
import json
|
|
119
|
-
print(
|
|
120
|
+
import json
|
|
121
|
+
print(json.dumps(SchemaTmp().getdict(), indent=4, sort_keys=True))
|