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.
Files changed (121) hide show
  1. siliconcompiler/__init__.py +12 -5
  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 +6 -5
  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/asic_component.py +2 -2
  19. siliconcompiler/constraints/asic_pins.py +2 -2
  20. siliconcompiler/constraints/asic_timing.py +3 -3
  21. siliconcompiler/core.py +7 -32
  22. siliconcompiler/data/templates/tcl/manifest.tcl.j2 +8 -0
  23. siliconcompiler/dependencyschema.py +89 -31
  24. siliconcompiler/design.py +176 -207
  25. siliconcompiler/filesetschema.py +250 -0
  26. siliconcompiler/flowgraph.py +274 -95
  27. siliconcompiler/fpga.py +124 -1
  28. siliconcompiler/library.py +218 -20
  29. siliconcompiler/metric.py +233 -20
  30. siliconcompiler/package/__init__.py +271 -50
  31. siliconcompiler/package/git.py +92 -16
  32. siliconcompiler/package/github.py +108 -12
  33. siliconcompiler/package/https.py +79 -16
  34. siliconcompiler/packageschema.py +88 -7
  35. siliconcompiler/pathschema.py +31 -2
  36. siliconcompiler/pdk.py +566 -1
  37. siliconcompiler/project.py +1095 -94
  38. siliconcompiler/record.py +38 -1
  39. siliconcompiler/remote/__init__.py +5 -2
  40. siliconcompiler/remote/client.py +11 -6
  41. siliconcompiler/remote/schema.py +5 -23
  42. siliconcompiler/remote/server.py +41 -54
  43. siliconcompiler/report/__init__.py +3 -3
  44. siliconcompiler/report/dashboard/__init__.py +48 -14
  45. siliconcompiler/report/dashboard/cli/__init__.py +99 -21
  46. siliconcompiler/report/dashboard/cli/board.py +364 -179
  47. siliconcompiler/report/dashboard/web/__init__.py +90 -12
  48. siliconcompiler/report/dashboard/web/components/__init__.py +219 -240
  49. siliconcompiler/report/dashboard/web/components/flowgraph.py +49 -26
  50. siliconcompiler/report/dashboard/web/components/graph.py +139 -100
  51. siliconcompiler/report/dashboard/web/layouts/__init__.py +29 -1
  52. siliconcompiler/report/dashboard/web/layouts/_common.py +38 -2
  53. siliconcompiler/report/dashboard/web/layouts/vertical_flowgraph.py +39 -26
  54. siliconcompiler/report/dashboard/web/layouts/vertical_flowgraph_node_tab.py +50 -50
  55. siliconcompiler/report/dashboard/web/layouts/vertical_flowgraph_sac_tabs.py +49 -46
  56. siliconcompiler/report/dashboard/web/state.py +141 -14
  57. siliconcompiler/report/dashboard/web/utils/__init__.py +79 -16
  58. siliconcompiler/report/dashboard/web/utils/file_utils.py +74 -11
  59. siliconcompiler/report/dashboard/web/viewer.py +25 -1
  60. siliconcompiler/report/report.py +5 -2
  61. siliconcompiler/report/summary_image.py +29 -11
  62. siliconcompiler/scheduler/__init__.py +9 -1
  63. siliconcompiler/scheduler/docker.py +79 -1
  64. siliconcompiler/scheduler/run_node.py +35 -19
  65. siliconcompiler/scheduler/scheduler.py +208 -24
  66. siliconcompiler/scheduler/schedulernode.py +372 -46
  67. siliconcompiler/scheduler/send_messages.py +77 -29
  68. siliconcompiler/scheduler/slurm.py +76 -12
  69. siliconcompiler/scheduler/taskscheduler.py +140 -20
  70. siliconcompiler/schema/__init__.py +0 -2
  71. siliconcompiler/schema/baseschema.py +194 -38
  72. siliconcompiler/schema/journal.py +7 -4
  73. siliconcompiler/schema/namedschema.py +16 -10
  74. siliconcompiler/schema/parameter.py +55 -9
  75. siliconcompiler/schema/parametervalue.py +60 -0
  76. siliconcompiler/schema/safeschema.py +25 -2
  77. siliconcompiler/schema/schema_cfg.py +5 -5
  78. siliconcompiler/schema/utils.py +2 -2
  79. siliconcompiler/schema_obj.py +20 -3
  80. siliconcompiler/tool.py +979 -302
  81. siliconcompiler/tools/bambu/__init__.py +41 -0
  82. siliconcompiler/tools/builtin/concatenate.py +2 -2
  83. siliconcompiler/tools/builtin/minimum.py +2 -1
  84. siliconcompiler/tools/builtin/mux.py +2 -1
  85. siliconcompiler/tools/builtin/nop.py +2 -1
  86. siliconcompiler/tools/builtin/verify.py +2 -1
  87. siliconcompiler/tools/klayout/__init__.py +95 -0
  88. siliconcompiler/tools/openroad/__init__.py +289 -0
  89. siliconcompiler/tools/openroad/scripts/apr/preamble.tcl +3 -0
  90. siliconcompiler/tools/openroad/scripts/apr/sc_detailed_route.tcl +7 -2
  91. siliconcompiler/tools/openroad/scripts/apr/sc_global_route.tcl +8 -4
  92. siliconcompiler/tools/openroad/scripts/apr/sc_init_floorplan.tcl +9 -5
  93. siliconcompiler/tools/openroad/scripts/common/write_images.tcl +5 -1
  94. siliconcompiler/tools/slang/__init__.py +1 -1
  95. siliconcompiler/tools/slang/elaborate.py +2 -1
  96. siliconcompiler/tools/vivado/scripts/sc_run.tcl +1 -1
  97. siliconcompiler/tools/vivado/scripts/sc_syn_fpga.tcl +8 -1
  98. siliconcompiler/tools/vivado/syn_fpga.py +6 -0
  99. siliconcompiler/tools/vivado/vivado.py +35 -2
  100. siliconcompiler/tools/vpr/__init__.py +150 -0
  101. siliconcompiler/tools/yosys/__init__.py +369 -1
  102. siliconcompiler/tools/yosys/scripts/procs.tcl +0 -1
  103. siliconcompiler/toolscripts/_tools.json +5 -10
  104. siliconcompiler/utils/__init__.py +66 -0
  105. siliconcompiler/utils/flowgraph.py +2 -2
  106. siliconcompiler/utils/issue.py +2 -1
  107. siliconcompiler/utils/logging.py +14 -0
  108. siliconcompiler/utils/multiprocessing.py +256 -0
  109. siliconcompiler/utils/showtools.py +10 -0
  110. {siliconcompiler-0.34.2.dist-info → siliconcompiler-0.34.3.dist-info}/METADATA +5 -5
  111. {siliconcompiler-0.34.2.dist-info → siliconcompiler-0.34.3.dist-info}/RECORD +115 -118
  112. {siliconcompiler-0.34.2.dist-info → siliconcompiler-0.34.3.dist-info}/entry_points.txt +3 -0
  113. siliconcompiler/schema/cmdlineschema.py +0 -250
  114. siliconcompiler/toolscripts/rhel8/install-slang.sh +0 -40
  115. siliconcompiler/toolscripts/rhel9/install-slang.sh +0 -40
  116. siliconcompiler/toolscripts/ubuntu20/install-slang.sh +0 -47
  117. siliconcompiler/toolscripts/ubuntu22/install-slang.sh +0 -37
  118. siliconcompiler/toolscripts/ubuntu24/install-slang.sh +0 -37
  119. {siliconcompiler-0.34.2.dist-info → siliconcompiler-0.34.3.dist-info}/WHEEL +0 -0
  120. {siliconcompiler-0.34.2.dist-info → siliconcompiler-0.34.3.dist-info}/licenses/LICENSE +0 -0
  121. {siliconcompiler-0.34.2.dist-info → siliconcompiler-0.34.3.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,534 @@
1
+ import argparse
2
+ import re
3
+ import sys
4
+
5
+ import os.path
6
+
7
+ from typing import Set, List
8
+
9
+ from siliconcompiler.schema import BaseSchema, EditableSchema, Parameter, Scope, PerNode
10
+ from siliconcompiler.schema.utils import trim
11
+ from siliconcompiler import _metadata
12
+
13
+
14
+ class CommandLineSchemaTmp:
15
+ '''
16
+ Class to provide the :meth:`create_cmdline` option to a schema object.
17
+
18
+ This class should not be instantiated by itself.
19
+
20
+ Examples:
21
+ class NewSchema(BaseSchema, CommandLineSchema):
22
+ creates a new class with the commandline options available
23
+ '''
24
+
25
+ ###########################################################################
26
+ def create_cmdline(self,
27
+ progname,
28
+ description=None,
29
+ switchlist=None,
30
+ additional_args=None,
31
+ version=None,
32
+ print_banner=None,
33
+ input_map_handler=None,
34
+ preprocess_keys=None,
35
+ post_process=None,
36
+ logger=None):
37
+ """Creates a Schema command line interface.
38
+
39
+ Exposes parameters in the SC schema as command line switches,
40
+ simplifying creation of SC apps with a restricted set of schema
41
+ parameters exposed at the command line. The order of command
42
+ line switch settings parsed from the command line is as follows:
43
+
44
+ 1. loglevel, if available in schema
45
+ 2. read_manifest([cfg]), if available in schema
46
+ 3. read inputs with input_map_handler
47
+ 4. all other switches
48
+ 5. Run post_process
49
+
50
+ The cmdline interface is implemented using the Python argparse package
51
+ and the following use restrictions apply.
52
+
53
+ * Help is accessed with the '-h' switch.
54
+ * Arguments that include spaces must be enclosed with double quotes.
55
+ * List parameters are entered individually. (ie. -y libdir1 -y libdir2)
56
+ * For parameters with Boolean types, the switch implies "true".
57
+ * Special characters (such as '-') must be enclosed in double quotes.
58
+ * Compiler compatible switches include: -D, -I, -O{0,1,2,3}
59
+ * Legacy switch formats are supported: +libext+, +incdir+
60
+
61
+ Args:
62
+ progname (str): Name of program to be executed.
63
+ description (str): Short program description.
64
+ switchlist (list of str): List of SC parameter switches to expose
65
+ at the command line. By default all SC schema switches are
66
+ available. Parameter switches should be entered based on the
67
+ parameter 'switch' field in the schema. For parameters with
68
+ multiple switches, both will be accepted if any one is included
69
+ in this list.
70
+ input_map (dict of str): Dictionary mapping file extensions to input
71
+ filetypes. This is used to automatically assign positional
72
+ source arguments to ['input', 'fileset', ...] keypaths based on their file
73
+ extension. If None, the CLI will not accept positional source
74
+ arguments.
75
+ additional_args (dict of dict): Dictionary of extra arguments to add
76
+ to the command line parser, with the arguments matching the
77
+ argparse.add_argument() call.
78
+ version (str): Version to report when calling with -version
79
+ print_banner (function): Function callback to print command line banner
80
+ input_map_handler (function): Function callback handle inputs to the input map
81
+ preprocess_keys (function): Function callback to preprocess keys that need to be
82
+ corrected
83
+ post_process (function): Function callback to process arguments before returning
84
+
85
+ Returns:
86
+ None if additional_args is not provided, otherwise a dictionary with the
87
+ command line options detected from the additional_args
88
+
89
+ Examples:
90
+ >>> schema.create_cmdline(progname='sc-show',switchlist=['-input','-cfg'])
91
+ Creates a command line interface for 'sc-show' app.
92
+ >>> schema.create_cmdline(progname='sc', input_map={'v': ('rtl', 'verilog')})
93
+ All sources ending in .v will be stored in ['input', 'rtl', 'verilog']
94
+ >>> extra = schema.create_cmdline(progname='sc',
95
+ additional_args={'-demo': {'action': 'store_true'}})
96
+ Returns extra = {'demo': False/True}
97
+ """
98
+
99
+ # Argparse
100
+ parser = argparse.ArgumentParser(prog=progname,
101
+ prefix_chars='-+',
102
+ formatter_class=argparse.RawDescriptionHelpFormatter,
103
+ description=description,
104
+ allow_abbrev=False)
105
+
106
+ # Create empty copy of schema
107
+ schema = type(self)()
108
+
109
+ # Track arguments
110
+ argument_map = {}
111
+ arguments = set()
112
+
113
+ # Iterate over all keys from an empty schema to add parser arguments
114
+ for keypath in sorted(schema.allkeys()):
115
+ param = schema.get(*keypath, field=None)
116
+
117
+ dest, switches = param.add_commandline_arguments(
118
+ parser,
119
+ *keypath,
120
+ switchlist=switchlist)
121
+
122
+ if switches:
123
+ argument_map[dest] = (keypath, param)
124
+ arguments.update(switches)
125
+
126
+ print_additional_arg_value = {}
127
+ if additional_args:
128
+ # Add additional user specified arguments
129
+ arg_dests = []
130
+ for arg, arg_detail in additional_args.items():
131
+ do_print = True
132
+ if "sc_print" in arg_detail:
133
+ do_print = arg_detail["sc_print"]
134
+ del arg_detail["sc_print"]
135
+ argument = parser.add_argument(arg, **arg_detail)
136
+ print_additional_arg_value[argument.dest] = do_print
137
+
138
+ arg_dests.append(argument.dest)
139
+ arguments.add(arg)
140
+ # rewrite additional_args with new dest information
141
+ additional_args = arg_dests
142
+
143
+ if version:
144
+ parser.add_argument('-version', action='version', version=version)
145
+
146
+ # Check if there are invalid switches
147
+ if switchlist:
148
+ for switch in switchlist:
149
+ if switch not in arguments:
150
+ raise ValueError(f'{switch} is not a valid commandline argument')
151
+
152
+ if input_map_handler:
153
+ parser.add_argument('source',
154
+ nargs='*',
155
+ help='Input files with filetype inferred by extension')
156
+
157
+ # Preprocess sys.argv to enable linux commandline switch formats
158
+ # (gcc, verilator, etc)
159
+ scargs = []
160
+
161
+ # Iterate from index 1, otherwise we end up with script name as a
162
+ # 'source' positional argument
163
+ for argument in sys.argv[1:]:
164
+ # Split switches with one character and a number after (O0,O1,O2)
165
+ opt = re.match(r'(\-\w)(\d+)', argument)
166
+ # Split assign switches (-DCFG_ASIC=1)
167
+ assign = re.search(r'(\-\w)(\w+\=\w+)', argument)
168
+ # Split plusargs (+incdir+/path)
169
+ plusarg = re.search(r'(\+\w+\+)(.*)', argument)
170
+ if opt:
171
+ scargs.append(opt.group(1))
172
+ scargs.append(opt.group(2))
173
+ elif plusarg:
174
+ scargs.append(plusarg.group(1))
175
+ scargs.append(plusarg.group(2))
176
+ elif assign:
177
+ scargs.append(assign.group(1))
178
+ scargs.append(assign.group(2))
179
+ else:
180
+ scargs.append(argument)
181
+
182
+ # Grab argument from pre-process sysargs
183
+ cmdargs = vars(parser.parse_args(scargs))
184
+
185
+ # Set loglevel if set at command line
186
+ do_print_banner = True
187
+ if 'option_loglevel' in cmdargs:
188
+ log_level = cmdargs['option_loglevel']
189
+ if isinstance(log_level, list):
190
+ # if multiple found, pick the first one
191
+ log_level = log_level[0]
192
+ if log_level == 'quiet':
193
+ do_print_banner = False
194
+ if logger:
195
+ logger.setLevel(log_level.split()[-1].upper())
196
+
197
+ if print_banner and do_print_banner:
198
+ print_banner()
199
+
200
+ extra_params = None
201
+ if additional_args:
202
+ # Grab user specified arguments
203
+ extra_params = {}
204
+ for arg in additional_args:
205
+ if arg in cmdargs:
206
+ val = cmdargs[arg]
207
+ if print_additional_arg_value[arg] and val and logger:
208
+ logger.info(
209
+ f'Command line argument entered: "{arg}" Value: {val}')
210
+ extra_params[arg] = val
211
+ # Remove from cmdargs
212
+ del cmdargs[arg]
213
+
214
+ # Read in all cfg files
215
+ if 'option_cfg' in cmdargs.keys():
216
+ for item in cmdargs['option_cfg']:
217
+ self.read_manifest(item)
218
+
219
+ if input_map_handler:
220
+ # Map sources to ['input'] keypath.
221
+ if 'source' in cmdargs:
222
+ input_map_handler(cmdargs['source'])
223
+ # we don't want to handle this in the next loop
224
+ del cmdargs['source']
225
+
226
+ # Cycle through all command args and write to manifest
227
+ for dest, vals in sorted(cmdargs.items(), key=lambda d: d[0]):
228
+ keypath, param = argument_map[dest]
229
+
230
+ # Turn everything into a list for uniformity
231
+ if not isinstance(vals, list):
232
+ vals = [vals]
233
+
234
+ # Cycle through all items
235
+ for item in vals:
236
+ if preprocess_keys:
237
+ item = preprocess_keys(keypath, item)
238
+
239
+ valkeypath, step, index, item = param.parse_commandline_arguments(item, *keypath)
240
+
241
+ if logger:
242
+ msg = f'Command line argument entered: [{",".join(valkeypath)}] Value: {item}'
243
+ if step is not None:
244
+ msg += f' step: {step}'
245
+ if index is not None:
246
+ msg += f' index: {index}'
247
+ logger.info(msg)
248
+
249
+ # Storing in manifest
250
+ if param.is_list():
251
+ self.add(*valkeypath, item, step=step, index=index)
252
+ else:
253
+ self.set(*valkeypath, item, step=step, index=index)
254
+
255
+ if post_process:
256
+ extra_params = post_process(cmdargs, extra_params)
257
+
258
+ return extra_params
259
+
260
+
261
+ class CommandLineSchema(BaseSchema):
262
+ '''
263
+ Class to provide the :meth:`create_cmdline` option to a schema object.
264
+
265
+ This class should not be instantiated by itself.
266
+
267
+ Examples:
268
+ class NewSchema(BaseSchema, CommandLineSchema):
269
+ creates a new class with the commandline options available
270
+ '''
271
+ def _add_commandline_argument(self,
272
+ name: str,
273
+ type: str,
274
+ help: str,
275
+ switch: List[str] = None,
276
+ defvalue=None,
277
+ **kwargs):
278
+ '''
279
+ Adds a parameter to the commandline definition.
280
+
281
+ Args:
282
+ name (str): name of parameter
283
+ type (str): schema type of the parameter
284
+ help (str): help string for this parameter
285
+ defvalue (any): default value for the parameter
286
+ '''
287
+ if isinstance(help, str):
288
+ # grab first line for short help
289
+ help = trim(help)
290
+ shorthelp = help.splitlines()[0].strip()
291
+ else:
292
+ raise TypeError("help must be a string")
293
+
294
+ kwargs["scope"] = Scope.GLOBAL
295
+ kwargs["pernode"] = PerNode.NEVER
296
+ kwargs["shorthelp"] = shorthelp
297
+ kwargs["help"] = help
298
+
299
+ if switch is None:
300
+ switch = f"-{name} <{type}>"
301
+
302
+ if switch is not ... and not switch:
303
+ raise ValueError("switch is required")
304
+
305
+ if switch is ...:
306
+ switch = None
307
+
308
+ kwargs["switch"] = switch
309
+ if defvalue is not None:
310
+ kwargs["defvalue"] = defvalue
311
+
312
+ EditableSchema(self).insert("cmdarg", name, Parameter(type, **kwargs))
313
+
314
+ @classmethod
315
+ def create_cmdline(cls,
316
+ progname: str = None,
317
+ description: str = None,
318
+ switchlist: Set[str] = None,
319
+ version: str = None,
320
+ print_banner: bool = True,
321
+ use_cfg: bool = False,
322
+ use_sources: bool = True):
323
+ """
324
+ Creates an SC command line interface.
325
+
326
+ Exposes parameters in the SC schema as command line switches,
327
+ simplifying creation of SC apps with a restricted set of schema
328
+ parameters exposed at the command line. The order of command
329
+ line switch settings parsed from the command line is as follows:
330
+
331
+ 1. read_manifest (-cfg), if specified by `use_cfg`
332
+ 2. read commandline inputs
333
+ 3. all other switches
334
+
335
+ The cmdline interface is implemented using the Python argparse package
336
+ and the following use restrictions apply.
337
+
338
+ * Help is accessed with the '-h' switch.
339
+ * Arguments that include spaces must be enclosed with double quotes.
340
+ * List parameters are entered individually. (ie. -y libdir1 -y libdir2)
341
+ * For parameters with Boolean types, the switch implies "true".
342
+ * Special characters (such as '-') must be enclosed in double quotes.
343
+
344
+ Args:
345
+ progname (str): Name of program to be executed.
346
+ description (str): Short program description.
347
+ switchlist (list of str): List of SC parameter switches to expose
348
+ at the command line. By default all SC schema switches are
349
+ available. Parameter switches should be entered based on the
350
+ parameter 'switch' field in the schema. For parameters with
351
+ multiple switches, both will be accepted if any one is included
352
+ in this list.
353
+ version (str): version of this program.
354
+ print_banner (bool): if True, will print the siliconcompiler banner
355
+ use_cfg (bool): if True, add and parse the -cfg flag
356
+ use_sources (bool): if True, add positional arguments for files
357
+
358
+ Returns:
359
+ new project object
360
+
361
+ Examples:
362
+ >>> chip.create_cmdline(progname='sc-show',switchlist=['-input','-cfg'])
363
+ Creates a command line interface for 'sc-show' app.
364
+
365
+ >>> chip.create_cmdline(progname='sc')
366
+ """
367
+
368
+ if progname and os.path.isfile(progname):
369
+ progname = os.path.basename(progname)
370
+
371
+ parser = argparse.ArgumentParser(
372
+ prog=progname,
373
+ description=description,
374
+ prefix_chars='-+',
375
+ formatter_class=argparse.RawDescriptionHelpFormatter,
376
+ allow_abbrev=False)
377
+
378
+ cfg_file = None
379
+ if use_cfg:
380
+ parser.add_argument(
381
+ '-cfg',
382
+ metavar='<file>',
383
+ help="configuration manifest")
384
+
385
+ # Grab config from argv
386
+ try:
387
+ cfg_index = sys.argv.index("-cfg", 1)
388
+ if cfg_index < len(sys.argv):
389
+ cfg_file = sys.argv[cfg_index + 1]
390
+ except ValueError:
391
+ pass
392
+
393
+ if cfg_file:
394
+ schema = cls.from_manifest(filepath=cfg_file)
395
+ else:
396
+ # Create new schema
397
+ schema = cls()
398
+
399
+ # Create empty schema for parameter generation
400
+ keyschema = schema.__class__()
401
+
402
+ if use_sources:
403
+ # Add commandline key for input files
404
+ if not isinstance(schema, CommandLineSchema):
405
+ raise TypeError("Schema is not a commandline class")
406
+ if "cmdarg" not in schema.getkeys() or "file" not in schema.getkeys("cmdarg"):
407
+ schema._add_commandline_argument("input", "[file]", "input files", ...)
408
+ keyschema._add_commandline_argument("input", "[file]", "input files", ...)
409
+
410
+ # Get logger if available
411
+ logger = getattr(schema, "logger", None)
412
+
413
+ # Track arguments
414
+ argumentmap = {}
415
+ arguments = set()
416
+
417
+ # Iterate over all keys from an empty schema to add parser arguments
418
+ for keypath in sorted(keyschema.allkeys()):
419
+ if keypath == ("option", "cfg"): # TODO: remove this when cfg is removed from schema
420
+ continue
421
+
422
+ param = keyschema.get(*keypath, field=None)
423
+
424
+ dest, switches = param.add_commandline_arguments(
425
+ parser,
426
+ *keypath,
427
+ switchlist=switchlist)
428
+
429
+ if switches:
430
+ argumentmap[dest] = (keypath, param)
431
+ arguments.update(switches)
432
+
433
+ # Check if there are invalid switches
434
+ if switchlist:
435
+ switchlist = set(switchlist)
436
+ unsed_switches = switchlist.difference(arguments)
437
+ if unsed_switches:
438
+ raise ValueError(f'{", ".join(unsed_switches)} is/are not a valid '
439
+ 'commandline arguments')
440
+
441
+ prog_version = ""
442
+ if progname:
443
+ prog_version = f"{progname}"
444
+ if version is not None:
445
+ prog_version = f"{prog_version} {version}"
446
+ prog_version += " / "
447
+
448
+ parser.add_argument(
449
+ # '-v',
450
+ '-version',
451
+ # '--version',
452
+ action='version',
453
+ version=f"{prog_version}SiliconCompiler {_metadata.version}")
454
+
455
+ if use_sources:
456
+ parser.add_argument('source',
457
+ nargs='*',
458
+ help='Input files')
459
+
460
+ # Preprocess sys.argv to enable linux commandline switch formats
461
+ # (gcc, verilator, etc)
462
+ scargs = []
463
+
464
+ # Iterate from index 1, otherwise we end up with script name as a
465
+ # 'source' positional argument
466
+ for argument in sys.argv[1:]:
467
+ # Split switches with one character and a number after (O0,O1,O2)
468
+ opt = re.match(r'(\-\w)(\d+)', argument)
469
+ # Split assign switches (-DCFG_ASIC=1)
470
+ assign = re.search(r'(\-\w)(\w+\=\w+)', argument)
471
+ # Split plusargs (+incdir+/path)
472
+ plusarg = re.search(r'(\+\w+\+)(.*)', argument)
473
+ if opt:
474
+ scargs.append(opt.group(1))
475
+ scargs.append(opt.group(2))
476
+ elif plusarg:
477
+ scargs.append(plusarg.group(1))
478
+ scargs.append(plusarg.group(2))
479
+ elif assign:
480
+ scargs.append(assign.group(1))
481
+ scargs.append(assign.group(2))
482
+ else:
483
+ scargs.append(argument)
484
+
485
+ # Grab argument from pre-process sysargs
486
+ cmdargs = vars(parser.parse_args(scargs))
487
+
488
+ if print_banner:
489
+ print(_metadata.banner)
490
+ authors = []
491
+ for name in _metadata.authors:
492
+ name = name.split(" ")
493
+ authors.append(f"{name[0][0]}. {' '.join(name[1:])}")
494
+ print("Authors:", ", ".join(authors))
495
+ print("Version:", _metadata.version, "\n")
496
+ print("-" * 80)
497
+
498
+ if 'source' in cmdargs:
499
+ if cmdargs['source']:
500
+ schema.set("cmdarg", "input", cmdargs['source'])
501
+ # we don't want to handle this in the next loop
502
+ del cmdargs['source']
503
+
504
+ # Cycle through all command args and write to manifest
505
+ for dest, vals in list(sorted(cmdargs.items(), key=lambda d: d[0])):
506
+ if dest not in argumentmap:
507
+ continue
508
+
509
+ keypath, param = argumentmap[dest]
510
+ del cmdargs[dest]
511
+
512
+ # Turn everything into a list for uniformity
513
+ if not isinstance(vals, list):
514
+ vals = [vals]
515
+
516
+ # Cycle through all items
517
+ for item in vals:
518
+ valkeypath, step, index, item = param.parse_commandline_arguments(item, *keypath)
519
+
520
+ if logger:
521
+ msg = f'Command line argument entered: [{",".join(valkeypath)}] Value: {item}'
522
+ if step is not None:
523
+ msg += f' step: {step}'
524
+ if index is not None:
525
+ msg += f' index: {index}'
526
+ logger.info(msg)
527
+
528
+ # Storing in manifest
529
+ if param.is_list():
530
+ schema.add(*valkeypath, item, step=step, index=index)
531
+ else:
532
+ schema.set(*valkeypath, item, step=step, index=index)
533
+
534
+ return schema
@@ -281,10 +281,10 @@ class ASICComponentConstraints(BaseSchema):
281
281
  if not isinstance(component, ASICComponentConstraint):
282
282
  raise TypeError("component must be a component constraint object")
283
283
 
284
- if component.name() is None:
284
+ if component.name is None:
285
285
  raise ValueError("component constraint must have a name")
286
286
 
287
- EditableSchema(self).insert(component.name(), component, clobber=True)
287
+ EditableSchema(self).insert(component.name, component, clobber=True)
288
288
 
289
289
  def get_component(self, component: str = None):
290
290
  """
@@ -393,10 +393,10 @@ class ASICPinConstraints(BaseSchema):
393
393
  if not isinstance(pin, ASICPinConstraint):
394
394
  raise TypeError("pin must be a pin copnstraint object")
395
395
 
396
- if pin.name() is None:
396
+ if pin.name is None:
397
397
  raise ValueError("pin constraint must have a name")
398
398
 
399
- EditableSchema(self).insert(pin.name(), pin, clobber=True)
399
+ EditableSchema(self).insert(pin.name, pin, clobber=True)
400
400
 
401
401
  def get_pinconstraint(self, pin: str = None):
402
402
  """
@@ -323,7 +323,7 @@ class ASICTimingScenarioSchema(NamedSchema):
323
323
  a string.
324
324
  """
325
325
  if isinstance(design, DesignSchema):
326
- design = design.name()
326
+ design = design.name
327
327
 
328
328
  if not isinstance(design, str):
329
329
  raise TypeError("design must be a design object or string")
@@ -420,10 +420,10 @@ class ASICTimingConstraintSchema(BaseSchema):
420
420
  if not isinstance(scenario, ASICTimingScenarioSchema):
421
421
  raise TypeError("scenario must be a timing scenario object")
422
422
 
423
- if scenario.name() is None:
423
+ if scenario.name is None:
424
424
  raise ValueError("scenario must have a name")
425
425
 
426
- EditableSchema(self).insert(scenario.name(), scenario, clobber=True)
426
+ EditableSchema(self).insert(scenario.name, scenario, clobber=True)
427
427
 
428
428
  def get_scenario(self, scenario: str = None):
429
429
  """
siliconcompiler/core.py CHANGED
@@ -31,8 +31,7 @@ from siliconcompiler.report import _generate_summary_image, _open_summary_image
31
31
  from siliconcompiler.report.dashboard.web import WebDashboard
32
32
  from siliconcompiler.report.dashboard.cli import CliDashboard
33
33
  from siliconcompiler.report.dashboard import DashboardType
34
- import glob
35
- from siliconcompiler.scheduler.scheduler import Scheduler
34
+ from siliconcompiler.scheduler import Scheduler, SchedulerNode
36
35
  from siliconcompiler.utils.flowgraph import _check_flowgraph_io, _get_flowgraph_information
37
36
  from siliconcompiler.tools._common import get_tool_task
38
37
  from types import FunctionType, ModuleType
@@ -1790,6 +1789,7 @@ class Chip:
1790
1789
  fout.write(template.render(manifest_dict='\n'.join(tcl_set_cmds),
1791
1790
  scroot=os.path.abspath(
1792
1791
  os.path.join(os.path.dirname(__file__))),
1792
+ toolvars={},
1793
1793
  record_access=record,
1794
1794
  record_access_id=Schema._RECORD_ACCESS_IDENTIFIER))
1795
1795
  else:
@@ -2448,34 +2448,6 @@ class Chip:
2448
2448
  else:
2449
2449
  raise SiliconCompilerError(f'Failed to copy {path}', chip=self)
2450
2450
 
2451
- ###########################################################################
2452
- def _archive_node(self, tar, step, index, include=None, verbose=True):
2453
- if verbose:
2454
- self.logger.info(f'Archiving {step}/{index}...')
2455
-
2456
- basedir = self.getworkdir(step=step, index=index)
2457
-
2458
- def arcname(path):
2459
- return os.path.relpath(path, self.cwd)
2460
-
2461
- if not os.path.isdir(basedir):
2462
- if self.get('record', 'status', step=step, index=index) != NodeStatus.SKIPPED:
2463
- self.logger.error(f'Unable to archive {step}/{index} due to missing node directory')
2464
- return
2465
-
2466
- if include:
2467
- for pattern in include:
2468
- for path in glob.iglob(os.path.join(basedir, pattern)):
2469
- tar.add(path, arcname=arcname(path))
2470
- else:
2471
- for folder in ('reports', 'outputs'):
2472
- path = os.path.join(basedir, folder)
2473
- tar.add(path, arcname=arcname(path))
2474
-
2475
- logfile = os.path.join(basedir, f'{step}.log')
2476
- if os.path.isfile(logfile):
2477
- tar.add(logfile, arcname=arcname(logfile))
2478
-
2479
2451
  ###########################################################################
2480
2452
  def __archive_job(self, tar, job, flowgraph_nodes, index=None, include=None):
2481
2453
  design = self.get('design')
@@ -2489,7 +2461,7 @@ class Chip:
2489
2461
  self.logger.warning('Archiving job with failed or incomplete run.')
2490
2462
 
2491
2463
  for (step, idx) in flowgraph_nodes:
2492
- self._archive_node(tar, step, idx, include=include)
2464
+ SchedulerNode(self, step, idx).archive(tar, include=include)
2493
2465
 
2494
2466
  ###########################################################################
2495
2467
  def archive(self, jobs=None, step=None, index=None, include=None, archive_name=None):
@@ -2961,7 +2933,7 @@ class Chip:
2961
2933
  >>> run()
2962
2934
  Runs the execution flow defined by the flowgraph dictionary.
2963
2935
  '''
2964
- from siliconcompiler.remote.client import ClientScheduler
2936
+ from siliconcompiler.remote import ClientScheduler
2965
2937
 
2966
2938
  try:
2967
2939
  if self.get('option', 'remote'):
@@ -3241,3 +3213,6 @@ class Chip:
3241
3213
 
3242
3214
  def copy(self):
3243
3215
  return copy.deepcopy(self)
3216
+
3217
+ def _init_run(self):
3218
+ pass
@@ -21,3 +21,11 @@ proc sc_root {} {
21
21
  proc _sc_cfg_get_debug { args } {
22
22
  {% if record_access %}puts "{{ record_access_id }} [join $args ,]"{% endif %}
23
23
  }
24
+
25
+
26
+ #############################################
27
+ # Tool variables
28
+ #############################################
29
+
30
+ {% for var, val in toolvars.items() %}set {{ var }} {{ val }}
31
+ {% endfor %}