siliconcompiler 0.34.1__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.
Files changed (129) hide show
  1. siliconcompiler/__init__.py +23 -4
  2. siliconcompiler/__main__.py +1 -7
  3. siliconcompiler/_metadata.py +1 -1
  4. siliconcompiler/apps/_common.py +104 -23
  5. siliconcompiler/apps/sc.py +4 -8
  6. siliconcompiler/apps/sc_dashboard.py +6 -4
  7. siliconcompiler/apps/sc_install.py +10 -6
  8. siliconcompiler/apps/sc_issue.py +7 -5
  9. siliconcompiler/apps/sc_remote.py +1 -1
  10. siliconcompiler/apps/sc_server.py +9 -14
  11. siliconcompiler/apps/sc_show.py +7 -6
  12. siliconcompiler/apps/smake.py +130 -94
  13. siliconcompiler/apps/utils/replay.py +4 -7
  14. siliconcompiler/apps/utils/summarize.py +3 -5
  15. siliconcompiler/asic.py +420 -0
  16. siliconcompiler/checklist.py +25 -2
  17. siliconcompiler/cmdlineschema.py +534 -0
  18. siliconcompiler/constraints/__init__.py +17 -0
  19. siliconcompiler/constraints/asic_component.py +378 -0
  20. siliconcompiler/constraints/asic_floorplan.py +449 -0
  21. siliconcompiler/constraints/asic_pins.py +489 -0
  22. siliconcompiler/constraints/asic_timing.py +517 -0
  23. siliconcompiler/core.py +10 -35
  24. siliconcompiler/data/templates/tcl/manifest.tcl.j2 +8 -0
  25. siliconcompiler/dependencyschema.py +96 -202
  26. siliconcompiler/design.py +327 -241
  27. siliconcompiler/filesetschema.py +250 -0
  28. siliconcompiler/flowgraph.py +298 -106
  29. siliconcompiler/fpga.py +124 -1
  30. siliconcompiler/library.py +331 -0
  31. siliconcompiler/metric.py +327 -92
  32. siliconcompiler/metrics/__init__.py +7 -0
  33. siliconcompiler/metrics/asic.py +245 -0
  34. siliconcompiler/metrics/fpga.py +220 -0
  35. siliconcompiler/package/__init__.py +391 -67
  36. siliconcompiler/package/git.py +92 -16
  37. siliconcompiler/package/github.py +114 -22
  38. siliconcompiler/package/https.py +79 -16
  39. siliconcompiler/packageschema.py +341 -16
  40. siliconcompiler/pathschema.py +255 -0
  41. siliconcompiler/pdk.py +566 -1
  42. siliconcompiler/project.py +1460 -0
  43. siliconcompiler/record.py +38 -1
  44. siliconcompiler/remote/__init__.py +5 -2
  45. siliconcompiler/remote/client.py +11 -6
  46. siliconcompiler/remote/schema.py +5 -23
  47. siliconcompiler/remote/server.py +41 -54
  48. siliconcompiler/report/__init__.py +3 -3
  49. siliconcompiler/report/dashboard/__init__.py +48 -14
  50. siliconcompiler/report/dashboard/cli/__init__.py +99 -21
  51. siliconcompiler/report/dashboard/cli/board.py +364 -179
  52. siliconcompiler/report/dashboard/web/__init__.py +90 -12
  53. siliconcompiler/report/dashboard/web/components/__init__.py +219 -240
  54. siliconcompiler/report/dashboard/web/components/flowgraph.py +49 -26
  55. siliconcompiler/report/dashboard/web/components/graph.py +139 -100
  56. siliconcompiler/report/dashboard/web/layouts/__init__.py +29 -1
  57. siliconcompiler/report/dashboard/web/layouts/_common.py +38 -2
  58. siliconcompiler/report/dashboard/web/layouts/vertical_flowgraph.py +39 -26
  59. siliconcompiler/report/dashboard/web/layouts/vertical_flowgraph_node_tab.py +50 -50
  60. siliconcompiler/report/dashboard/web/layouts/vertical_flowgraph_sac_tabs.py +49 -46
  61. siliconcompiler/report/dashboard/web/state.py +141 -14
  62. siliconcompiler/report/dashboard/web/utils/__init__.py +79 -16
  63. siliconcompiler/report/dashboard/web/utils/file_utils.py +74 -11
  64. siliconcompiler/report/dashboard/web/viewer.py +25 -1
  65. siliconcompiler/report/report.py +5 -2
  66. siliconcompiler/report/summary_image.py +29 -11
  67. siliconcompiler/scheduler/__init__.py +9 -1
  68. siliconcompiler/scheduler/docker.py +81 -4
  69. siliconcompiler/scheduler/run_node.py +37 -20
  70. siliconcompiler/scheduler/scheduler.py +211 -36
  71. siliconcompiler/scheduler/schedulernode.py +394 -60
  72. siliconcompiler/scheduler/send_messages.py +77 -29
  73. siliconcompiler/scheduler/slurm.py +76 -12
  74. siliconcompiler/scheduler/taskscheduler.py +142 -21
  75. siliconcompiler/schema/__init__.py +0 -4
  76. siliconcompiler/schema/baseschema.py +338 -59
  77. siliconcompiler/schema/editableschema.py +14 -6
  78. siliconcompiler/schema/journal.py +28 -17
  79. siliconcompiler/schema/namedschema.py +22 -14
  80. siliconcompiler/schema/parameter.py +89 -28
  81. siliconcompiler/schema/parametertype.py +2 -0
  82. siliconcompiler/schema/parametervalue.py +258 -15
  83. siliconcompiler/schema/safeschema.py +25 -2
  84. siliconcompiler/schema/schema_cfg.py +23 -19
  85. siliconcompiler/schema/utils.py +2 -2
  86. siliconcompiler/schema_obj.py +24 -5
  87. siliconcompiler/tool.py +1131 -265
  88. siliconcompiler/tools/bambu/__init__.py +41 -0
  89. siliconcompiler/tools/builtin/concatenate.py +2 -2
  90. siliconcompiler/tools/builtin/minimum.py +2 -1
  91. siliconcompiler/tools/builtin/mux.py +2 -1
  92. siliconcompiler/tools/builtin/nop.py +2 -1
  93. siliconcompiler/tools/builtin/verify.py +2 -1
  94. siliconcompiler/tools/klayout/__init__.py +95 -0
  95. siliconcompiler/tools/openroad/__init__.py +289 -0
  96. siliconcompiler/tools/openroad/scripts/apr/preamble.tcl +3 -0
  97. siliconcompiler/tools/openroad/scripts/apr/sc_detailed_route.tcl +7 -2
  98. siliconcompiler/tools/openroad/scripts/apr/sc_global_route.tcl +8 -4
  99. siliconcompiler/tools/openroad/scripts/apr/sc_init_floorplan.tcl +9 -5
  100. siliconcompiler/tools/openroad/scripts/common/write_images.tcl +5 -1
  101. siliconcompiler/tools/slang/__init__.py +1 -1
  102. siliconcompiler/tools/slang/elaborate.py +2 -1
  103. siliconcompiler/tools/vivado/scripts/sc_run.tcl +1 -1
  104. siliconcompiler/tools/vivado/scripts/sc_syn_fpga.tcl +8 -1
  105. siliconcompiler/tools/vivado/syn_fpga.py +6 -0
  106. siliconcompiler/tools/vivado/vivado.py +35 -2
  107. siliconcompiler/tools/vpr/__init__.py +150 -0
  108. siliconcompiler/tools/yosys/__init__.py +369 -1
  109. siliconcompiler/tools/yosys/scripts/procs.tcl +0 -1
  110. siliconcompiler/toolscripts/_tools.json +5 -10
  111. siliconcompiler/utils/__init__.py +66 -0
  112. siliconcompiler/utils/flowgraph.py +2 -2
  113. siliconcompiler/utils/issue.py +2 -1
  114. siliconcompiler/utils/logging.py +14 -0
  115. siliconcompiler/utils/multiprocessing.py +256 -0
  116. siliconcompiler/utils/showtools.py +10 -0
  117. {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.3.dist-info}/METADATA +6 -6
  118. {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.3.dist-info}/RECORD +122 -115
  119. {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.3.dist-info}/entry_points.txt +3 -0
  120. siliconcompiler/schema/cmdlineschema.py +0 -250
  121. siliconcompiler/schema/packageschema.py +0 -101
  122. siliconcompiler/toolscripts/rhel8/install-slang.sh +0 -40
  123. siliconcompiler/toolscripts/rhel9/install-slang.sh +0 -40
  124. siliconcompiler/toolscripts/ubuntu20/install-slang.sh +0 -47
  125. siliconcompiler/toolscripts/ubuntu22/install-slang.sh +0 -37
  126. siliconcompiler/toolscripts/ubuntu24/install-slang.sh +0 -37
  127. {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.3.dist-info}/WHEEL +0 -0
  128. {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.3.dist-info}/licenses/LICENSE +0 -0
  129. {siliconcompiler-0.34.1.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")