siliconcompiler 0.34.2__py3-none-any.whl → 0.34.3__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 +12 -5
- siliconcompiler/__main__.py +1 -7
- siliconcompiler/_metadata.py +1 -1
- siliconcompiler/apps/_common.py +104 -23
- siliconcompiler/apps/sc.py +4 -8
- siliconcompiler/apps/sc_dashboard.py +6 -4
- siliconcompiler/apps/sc_install.py +10 -6
- siliconcompiler/apps/sc_issue.py +7 -5
- siliconcompiler/apps/sc_remote.py +1 -1
- siliconcompiler/apps/sc_server.py +9 -14
- siliconcompiler/apps/sc_show.py +6 -5
- siliconcompiler/apps/smake.py +130 -94
- siliconcompiler/apps/utils/replay.py +4 -7
- siliconcompiler/apps/utils/summarize.py +3 -5
- siliconcompiler/asic.py +420 -0
- siliconcompiler/checklist.py +25 -2
- siliconcompiler/cmdlineschema.py +534 -0
- siliconcompiler/constraints/asic_component.py +2 -2
- siliconcompiler/constraints/asic_pins.py +2 -2
- siliconcompiler/constraints/asic_timing.py +3 -3
- siliconcompiler/core.py +7 -32
- siliconcompiler/data/templates/tcl/manifest.tcl.j2 +8 -0
- siliconcompiler/dependencyschema.py +89 -31
- siliconcompiler/design.py +176 -207
- siliconcompiler/filesetschema.py +250 -0
- siliconcompiler/flowgraph.py +274 -95
- siliconcompiler/fpga.py +124 -1
- siliconcompiler/library.py +218 -20
- siliconcompiler/metric.py +233 -20
- siliconcompiler/package/__init__.py +271 -50
- siliconcompiler/package/git.py +92 -16
- siliconcompiler/package/github.py +108 -12
- siliconcompiler/package/https.py +79 -16
- siliconcompiler/packageschema.py +88 -7
- siliconcompiler/pathschema.py +31 -2
- siliconcompiler/pdk.py +566 -1
- siliconcompiler/project.py +1095 -94
- siliconcompiler/record.py +38 -1
- siliconcompiler/remote/__init__.py +5 -2
- siliconcompiler/remote/client.py +11 -6
- siliconcompiler/remote/schema.py +5 -23
- siliconcompiler/remote/server.py +41 -54
- siliconcompiler/report/__init__.py +3 -3
- siliconcompiler/report/dashboard/__init__.py +48 -14
- siliconcompiler/report/dashboard/cli/__init__.py +99 -21
- siliconcompiler/report/dashboard/cli/board.py +364 -179
- siliconcompiler/report/dashboard/web/__init__.py +90 -12
- siliconcompiler/report/dashboard/web/components/__init__.py +219 -240
- siliconcompiler/report/dashboard/web/components/flowgraph.py +49 -26
- siliconcompiler/report/dashboard/web/components/graph.py +139 -100
- siliconcompiler/report/dashboard/web/layouts/__init__.py +29 -1
- siliconcompiler/report/dashboard/web/layouts/_common.py +38 -2
- siliconcompiler/report/dashboard/web/layouts/vertical_flowgraph.py +39 -26
- siliconcompiler/report/dashboard/web/layouts/vertical_flowgraph_node_tab.py +50 -50
- siliconcompiler/report/dashboard/web/layouts/vertical_flowgraph_sac_tabs.py +49 -46
- siliconcompiler/report/dashboard/web/state.py +141 -14
- siliconcompiler/report/dashboard/web/utils/__init__.py +79 -16
- siliconcompiler/report/dashboard/web/utils/file_utils.py +74 -11
- siliconcompiler/report/dashboard/web/viewer.py +25 -1
- siliconcompiler/report/report.py +5 -2
- siliconcompiler/report/summary_image.py +29 -11
- siliconcompiler/scheduler/__init__.py +9 -1
- siliconcompiler/scheduler/docker.py +79 -1
- siliconcompiler/scheduler/run_node.py +35 -19
- siliconcompiler/scheduler/scheduler.py +208 -24
- siliconcompiler/scheduler/schedulernode.py +372 -46
- siliconcompiler/scheduler/send_messages.py +77 -29
- siliconcompiler/scheduler/slurm.py +76 -12
- siliconcompiler/scheduler/taskscheduler.py +140 -20
- siliconcompiler/schema/__init__.py +0 -2
- siliconcompiler/schema/baseschema.py +194 -38
- siliconcompiler/schema/journal.py +7 -4
- siliconcompiler/schema/namedschema.py +16 -10
- siliconcompiler/schema/parameter.py +55 -9
- siliconcompiler/schema/parametervalue.py +60 -0
- siliconcompiler/schema/safeschema.py +25 -2
- siliconcompiler/schema/schema_cfg.py +5 -5
- siliconcompiler/schema/utils.py +2 -2
- siliconcompiler/schema_obj.py +20 -3
- siliconcompiler/tool.py +979 -302
- siliconcompiler/tools/bambu/__init__.py +41 -0
- siliconcompiler/tools/builtin/concatenate.py +2 -2
- siliconcompiler/tools/builtin/minimum.py +2 -1
- siliconcompiler/tools/builtin/mux.py +2 -1
- siliconcompiler/tools/builtin/nop.py +2 -1
- siliconcompiler/tools/builtin/verify.py +2 -1
- siliconcompiler/tools/klayout/__init__.py +95 -0
- siliconcompiler/tools/openroad/__init__.py +289 -0
- siliconcompiler/tools/openroad/scripts/apr/preamble.tcl +3 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_detailed_route.tcl +7 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_global_route.tcl +8 -4
- siliconcompiler/tools/openroad/scripts/apr/sc_init_floorplan.tcl +9 -5
- siliconcompiler/tools/openroad/scripts/common/write_images.tcl +5 -1
- siliconcompiler/tools/slang/__init__.py +1 -1
- siliconcompiler/tools/slang/elaborate.py +2 -1
- siliconcompiler/tools/vivado/scripts/sc_run.tcl +1 -1
- siliconcompiler/tools/vivado/scripts/sc_syn_fpga.tcl +8 -1
- siliconcompiler/tools/vivado/syn_fpga.py +6 -0
- siliconcompiler/tools/vivado/vivado.py +35 -2
- siliconcompiler/tools/vpr/__init__.py +150 -0
- siliconcompiler/tools/yosys/__init__.py +369 -1
- siliconcompiler/tools/yosys/scripts/procs.tcl +0 -1
- siliconcompiler/toolscripts/_tools.json +5 -10
- siliconcompiler/utils/__init__.py +66 -0
- siliconcompiler/utils/flowgraph.py +2 -2
- siliconcompiler/utils/issue.py +2 -1
- siliconcompiler/utils/logging.py +14 -0
- siliconcompiler/utils/multiprocessing.py +256 -0
- siliconcompiler/utils/showtools.py +10 -0
- {siliconcompiler-0.34.2.dist-info → siliconcompiler-0.34.3.dist-info}/METADATA +5 -5
- {siliconcompiler-0.34.2.dist-info → siliconcompiler-0.34.3.dist-info}/RECORD +115 -118
- {siliconcompiler-0.34.2.dist-info → siliconcompiler-0.34.3.dist-info}/entry_points.txt +3 -0
- siliconcompiler/schema/cmdlineschema.py +0 -250
- siliconcompiler/toolscripts/rhel8/install-slang.sh +0 -40
- siliconcompiler/toolscripts/rhel9/install-slang.sh +0 -40
- siliconcompiler/toolscripts/ubuntu20/install-slang.sh +0 -47
- siliconcompiler/toolscripts/ubuntu22/install-slang.sh +0 -37
- siliconcompiler/toolscripts/ubuntu24/install-slang.sh +0 -37
- {siliconcompiler-0.34.2.dist-info → siliconcompiler-0.34.3.dist-info}/WHEEL +0 -0
- {siliconcompiler-0.34.2.dist-info → siliconcompiler-0.34.3.dist-info}/licenses/LICENSE +0 -0
- {siliconcompiler-0.34.2.dist-info → siliconcompiler-0.34.3.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import contextlib
|
|
2
|
+
|
|
3
|
+
from typing import List
|
|
4
|
+
|
|
5
|
+
from siliconcompiler import utils
|
|
6
|
+
|
|
7
|
+
from siliconcompiler.pathschema import PathSchema
|
|
8
|
+
from siliconcompiler.schema import EditableSchema, Parameter, Scope
|
|
9
|
+
from siliconcompiler.schema.utils import trim
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
###########################################################################
|
|
13
|
+
class FileSetSchema(PathSchema):
|
|
14
|
+
'''
|
|
15
|
+
Schema for storing and managing file sets.
|
|
16
|
+
|
|
17
|
+
This class provides methods to add, retrieve, and manage named groups of
|
|
18
|
+
files, known as filesets.
|
|
19
|
+
'''
|
|
20
|
+
|
|
21
|
+
def __init__(self):
|
|
22
|
+
'''Initializes the FileSetSchema.'''
|
|
23
|
+
super().__init__()
|
|
24
|
+
|
|
25
|
+
schema = EditableSchema(self)
|
|
26
|
+
|
|
27
|
+
fileset = 'default'
|
|
28
|
+
filetype = 'default'
|
|
29
|
+
schema.insert(
|
|
30
|
+
'fileset', fileset, 'file', filetype,
|
|
31
|
+
Parameter(
|
|
32
|
+
'[file]',
|
|
33
|
+
scope=Scope.GLOBAL,
|
|
34
|
+
shorthelp="Fileset files",
|
|
35
|
+
example=[
|
|
36
|
+
"api: chip.set('fileset', 'rtl', 'file', 'verilog', 'mytop.v')",
|
|
37
|
+
"api: chip.set('fileset', 'testbench', 'file', 'verilog', 'tb.v')"],
|
|
38
|
+
help=trim("""
|
|
39
|
+
List of files grouped as a named set ('fileset'). The exact names of
|
|
40
|
+
filetypes and filesets must match the names used in tasks
|
|
41
|
+
called during flowgraph execution. The files are processed in
|
|
42
|
+
the order specified by the ordered file list.""")))
|
|
43
|
+
|
|
44
|
+
###############################################
|
|
45
|
+
def add_file(self,
|
|
46
|
+
filename: str,
|
|
47
|
+
fileset: str = None,
|
|
48
|
+
filetype: str = None,
|
|
49
|
+
clobber: bool = False,
|
|
50
|
+
dataroot: str = None) -> List[str]:
|
|
51
|
+
"""
|
|
52
|
+
Adds files to a fileset.
|
|
53
|
+
|
|
54
|
+
Based on the file's extension, this method can often infer the correct
|
|
55
|
+
fileset and filetype. For example:
|
|
56
|
+
|
|
57
|
+
* .v -> (source, verilog)
|
|
58
|
+
* .vhd -> (source, vhdl)
|
|
59
|
+
* .sdc -> (constraint, sdc)
|
|
60
|
+
* .lef -> (input, lef)
|
|
61
|
+
* .def -> (input, def)
|
|
62
|
+
* etc.
|
|
63
|
+
|
|
64
|
+
Args:
|
|
65
|
+
filename (Path or list[Path]): File path or list of paths to add.
|
|
66
|
+
fileset (str): Logical group to associate the file with.
|
|
67
|
+
filetype (str, optional): Type of the file (e.g., 'verilog', 'sdc').
|
|
68
|
+
clobber (bool, optional): If True, clears the list before adding the
|
|
69
|
+
item. Defaults to False.
|
|
70
|
+
dataroot (str, optional): Data directory reference name.
|
|
71
|
+
|
|
72
|
+
Raises:
|
|
73
|
+
ValueError: If `fileset` or `filetype` cannot be inferred from
|
|
74
|
+
the file extension.
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
list[str]: A list of the file paths that were added.
|
|
78
|
+
|
|
79
|
+
Notes:
|
|
80
|
+
* This method normalizes `filename` to a string for consistency.
|
|
81
|
+
* If `filetype` is not specified, it is inferred from the
|
|
82
|
+
file extension.
|
|
83
|
+
"""
|
|
84
|
+
|
|
85
|
+
if fileset is None:
|
|
86
|
+
fileset = self._get_active("fileset")
|
|
87
|
+
|
|
88
|
+
if not isinstance(fileset, str):
|
|
89
|
+
raise ValueError("fileset key must be a string")
|
|
90
|
+
|
|
91
|
+
# handle list inputs
|
|
92
|
+
if isinstance(filename, (list, tuple)):
|
|
93
|
+
params = []
|
|
94
|
+
for item in filename:
|
|
95
|
+
params.extend(
|
|
96
|
+
self.add_file(
|
|
97
|
+
item,
|
|
98
|
+
fileset=fileset,
|
|
99
|
+
clobber=clobber,
|
|
100
|
+
filetype=filetype,
|
|
101
|
+
dataroot=dataroot))
|
|
102
|
+
return params
|
|
103
|
+
|
|
104
|
+
if filename is None:
|
|
105
|
+
raise ValueError("add_file cannot process None")
|
|
106
|
+
|
|
107
|
+
# Normalize value to string in case we receive a pathlib.Path
|
|
108
|
+
filename = str(filename)
|
|
109
|
+
|
|
110
|
+
# map extension to default filetype/fileset
|
|
111
|
+
if not filetype:
|
|
112
|
+
ext = utils.get_file_ext(filename)
|
|
113
|
+
iomap = utils.get_default_iomap()
|
|
114
|
+
if ext in iomap:
|
|
115
|
+
_, default_filetype = iomap[ext]
|
|
116
|
+
filetype = default_filetype
|
|
117
|
+
else:
|
|
118
|
+
raise ValueError(f"Unrecognized file extension: {ext}")
|
|
119
|
+
|
|
120
|
+
if not dataroot:
|
|
121
|
+
dataroot = self._get_active("package")
|
|
122
|
+
|
|
123
|
+
# adding files to dictionary
|
|
124
|
+
with self.active_dataroot(dataroot):
|
|
125
|
+
if clobber:
|
|
126
|
+
return self.set('fileset', fileset, 'file', filetype, filename)
|
|
127
|
+
else:
|
|
128
|
+
return self.add('fileset', fileset, 'file', filetype, filename)
|
|
129
|
+
|
|
130
|
+
###############################################
|
|
131
|
+
def get_file(self,
|
|
132
|
+
fileset: str = None,
|
|
133
|
+
filetype: str = None):
|
|
134
|
+
"""Returns a list of files from one or more filesets.
|
|
135
|
+
|
|
136
|
+
Args:
|
|
137
|
+
fileset (str or list[str]): Fileset(s) to query. If not provided,
|
|
138
|
+
the active fileset is used.
|
|
139
|
+
filetype (str or list[str], optional): File type(s) to filter by
|
|
140
|
+
(e.g., 'verilog'). If not provided, all filetypes in the
|
|
141
|
+
fileset are returned.
|
|
142
|
+
|
|
143
|
+
Returns:
|
|
144
|
+
list[str]: A list of resolved file paths.
|
|
145
|
+
"""
|
|
146
|
+
|
|
147
|
+
if fileset is None:
|
|
148
|
+
fileset = self._get_active("fileset")
|
|
149
|
+
|
|
150
|
+
if not isinstance(fileset, list):
|
|
151
|
+
fileset = [fileset]
|
|
152
|
+
|
|
153
|
+
if filetype and not isinstance(filetype, list):
|
|
154
|
+
filetype = [filetype]
|
|
155
|
+
|
|
156
|
+
filelist = []
|
|
157
|
+
for fs in fileset:
|
|
158
|
+
if not isinstance(fs, str):
|
|
159
|
+
raise ValueError("fileset key must be a string")
|
|
160
|
+
# handle scalar+list in argument
|
|
161
|
+
if not filetype:
|
|
162
|
+
filetype = self.getkeys('fileset', fs, 'file')
|
|
163
|
+
# grab the files
|
|
164
|
+
for ftype in filetype:
|
|
165
|
+
filelist.extend(self.find_files('fileset', fs, 'file', ftype))
|
|
166
|
+
|
|
167
|
+
return filelist
|
|
168
|
+
|
|
169
|
+
@contextlib.contextmanager
|
|
170
|
+
def active_fileset(self, fileset: str):
|
|
171
|
+
"""
|
|
172
|
+
Provides a context to temporarily set an active design fileset.
|
|
173
|
+
|
|
174
|
+
This is useful for applying a set of configurations to a specific
|
|
175
|
+
fileset without repeatedly passing its name.
|
|
176
|
+
|
|
177
|
+
Raises:
|
|
178
|
+
TypeError: If `fileset` is not a string.
|
|
179
|
+
ValueError: If `fileset` is an empty string.
|
|
180
|
+
|
|
181
|
+
Args:
|
|
182
|
+
fileset (str): The name of the fileset to activate.
|
|
183
|
+
|
|
184
|
+
Example:
|
|
185
|
+
>>> with design.active_fileset("rtl"):
|
|
186
|
+
... design.set_topmodule("top")
|
|
187
|
+
# This sets the top module for the 'rtl' fileset to 'top'.
|
|
188
|
+
"""
|
|
189
|
+
if not isinstance(fileset, str):
|
|
190
|
+
raise TypeError("fileset must a string")
|
|
191
|
+
if not fileset:
|
|
192
|
+
raise ValueError("fileset cannot be an empty string")
|
|
193
|
+
|
|
194
|
+
with self._active(fileset=fileset):
|
|
195
|
+
yield
|
|
196
|
+
|
|
197
|
+
def copy_fileset(self, src_fileset: str, dst_fileset: str, clobber: bool = False):
|
|
198
|
+
"""
|
|
199
|
+
Creates a new copy of a source fileset.
|
|
200
|
+
|
|
201
|
+
The entire configuration of the source fileset is duplicated and stored
|
|
202
|
+
under the destination fileset's name.
|
|
203
|
+
|
|
204
|
+
Args:
|
|
205
|
+
src_fileset (str): The name of the source fileset to copy.
|
|
206
|
+
dst_fileset (str): The name of the new destination fileset.
|
|
207
|
+
clobber (bool): If True, an existing destination fileset will be
|
|
208
|
+
overwritten. Defaults to False.
|
|
209
|
+
|
|
210
|
+
Raises:
|
|
211
|
+
ValueError: If the destination fileset already exists and `clobber`
|
|
212
|
+
is False.
|
|
213
|
+
"""
|
|
214
|
+
if not clobber and self.has_fileset(dst_fileset):
|
|
215
|
+
raise ValueError(f"{dst_fileset} already exists")
|
|
216
|
+
|
|
217
|
+
new_fs = self.get("fileset", src_fileset, field="schema").copy()
|
|
218
|
+
EditableSchema(self).insert("fileset", dst_fileset, new_fs, clobber=True)
|
|
219
|
+
|
|
220
|
+
def _assert_fileset(self, fileset: str) -> None:
|
|
221
|
+
"""
|
|
222
|
+
Raises an error if the specified fileset does not exist.
|
|
223
|
+
|
|
224
|
+
Raises:
|
|
225
|
+
TypeError: If `fileset` is not a string.
|
|
226
|
+
LookupError: If the fileset is not found.
|
|
227
|
+
"""
|
|
228
|
+
|
|
229
|
+
if not isinstance(fileset, str):
|
|
230
|
+
raise TypeError("fileset must be a string")
|
|
231
|
+
|
|
232
|
+
if not self.has_fileset(fileset):
|
|
233
|
+
name = getattr(self, "name", None)
|
|
234
|
+
if name:
|
|
235
|
+
raise LookupError(f"{fileset} is not defined in {name}")
|
|
236
|
+
else:
|
|
237
|
+
raise LookupError(f"{fileset} is not defined")
|
|
238
|
+
|
|
239
|
+
def has_fileset(self, fileset: str) -> bool:
|
|
240
|
+
"""
|
|
241
|
+
Checks if a fileset exists in the schema.
|
|
242
|
+
|
|
243
|
+
Args:
|
|
244
|
+
fileset (str): The name of the fileset to check.
|
|
245
|
+
|
|
246
|
+
Returns:
|
|
247
|
+
bool: True if the fileset exists, False otherwise.
|
|
248
|
+
"""
|
|
249
|
+
|
|
250
|
+
return fileset in self.getkeys("fileset")
|