siliconcompiler 0.32.3__py3-none-any.whl → 0.33.0__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 +19 -2
- siliconcompiler/_metadata.py +1 -1
- siliconcompiler/apps/sc.py +2 -2
- siliconcompiler/apps/sc_install.py +3 -3
- siliconcompiler/apps/sc_issue.py +1 -1
- siliconcompiler/apps/sc_remote.py +4 -4
- siliconcompiler/apps/sc_show.py +2 -2
- siliconcompiler/apps/utils/replay.py +5 -3
- siliconcompiler/asic.py +120 -0
- siliconcompiler/checklist.py +150 -0
- siliconcompiler/core.py +267 -289
- siliconcompiler/flowgraph.py +803 -515
- siliconcompiler/fpga.py +84 -0
- siliconcompiler/metric.py +420 -0
- siliconcompiler/optimizer/vizier.py +2 -3
- siliconcompiler/package/__init__.py +29 -6
- siliconcompiler/pdk.py +415 -0
- siliconcompiler/record.py +449 -0
- siliconcompiler/remote/client.py +6 -3
- siliconcompiler/remote/schema.py +116 -112
- siliconcompiler/remote/server.py +3 -5
- siliconcompiler/report/dashboard/cli/__init__.py +13 -722
- siliconcompiler/report/dashboard/cli/board.py +895 -0
- siliconcompiler/report/dashboard/web/__init__.py +10 -10
- siliconcompiler/report/dashboard/web/components/__init__.py +5 -4
- siliconcompiler/report/dashboard/web/components/flowgraph.py +3 -3
- siliconcompiler/report/dashboard/web/components/graph.py +6 -3
- siliconcompiler/report/dashboard/web/state.py +1 -1
- siliconcompiler/report/dashboard/web/utils/__init__.py +4 -3
- siliconcompiler/report/html_report.py +2 -3
- siliconcompiler/report/report.py +13 -7
- siliconcompiler/report/summary_image.py +1 -1
- siliconcompiler/report/summary_table.py +3 -3
- siliconcompiler/report/utils.py +11 -10
- siliconcompiler/scheduler/__init__.py +145 -280
- siliconcompiler/scheduler/run_node.py +2 -1
- siliconcompiler/scheduler/send_messages.py +4 -4
- siliconcompiler/scheduler/slurm.py +2 -2
- siliconcompiler/schema/__init__.py +19 -2
- siliconcompiler/schema/baseschema.py +493 -0
- siliconcompiler/schema/cmdlineschema.py +250 -0
- siliconcompiler/{sphinx_ext → schema/docs}/__init__.py +3 -1
- siliconcompiler/{sphinx_ext → schema/docs}/dynamicgen.py +63 -81
- siliconcompiler/{sphinx_ext → schema/docs}/schemagen.py +73 -85
- siliconcompiler/{sphinx_ext → schema/docs}/utils.py +12 -13
- siliconcompiler/schema/editableschema.py +136 -0
- siliconcompiler/schema/journalingschema.py +238 -0
- siliconcompiler/schema/namedschema.py +41 -0
- siliconcompiler/schema/packageschema.py +101 -0
- siliconcompiler/schema/parameter.py +791 -0
- siliconcompiler/schema/parametertype.py +323 -0
- siliconcompiler/schema/parametervalue.py +736 -0
- siliconcompiler/schema/safeschema.py +37 -0
- siliconcompiler/schema/schema_cfg.py +109 -1789
- siliconcompiler/schema/utils.py +5 -68
- siliconcompiler/schema_obj.py +119 -0
- siliconcompiler/tool.py +1308 -0
- siliconcompiler/tools/_common/__init__.py +6 -10
- siliconcompiler/tools/_common/sdc/sc_constraints.sdc +1 -1
- siliconcompiler/tools/bluespec/convert.py +7 -7
- siliconcompiler/tools/builtin/_common.py +1 -1
- siliconcompiler/tools/builtin/concatenate.py +2 -2
- siliconcompiler/tools/builtin/minimum.py +1 -1
- siliconcompiler/tools/builtin/mux.py +2 -1
- siliconcompiler/tools/builtin/nop.py +1 -1
- siliconcompiler/tools/builtin/verify.py +6 -4
- siliconcompiler/tools/chisel/convert.py +4 -4
- siliconcompiler/tools/genfasm/bitstream.py +3 -3
- siliconcompiler/tools/ghdl/convert.py +1 -1
- siliconcompiler/tools/icarus/compile.py +4 -4
- siliconcompiler/tools/icepack/bitstream.py +6 -1
- siliconcompiler/tools/klayout/convert_drc_db.py +5 -0
- siliconcompiler/tools/klayout/klayout_export.py +0 -1
- siliconcompiler/tools/klayout/klayout_utils.py +3 -10
- siliconcompiler/tools/nextpnr/apr.py +6 -1
- siliconcompiler/tools/nextpnr/nextpnr.py +4 -4
- siliconcompiler/tools/openroad/_apr.py +13 -0
- siliconcompiler/tools/openroad/rdlroute.py +3 -3
- siliconcompiler/tools/openroad/scripts/apr/postamble.tcl +1 -1
- siliconcompiler/tools/openroad/scripts/apr/preamble.tcl +5 -5
- siliconcompiler/tools/openroad/scripts/apr/sc_antenna_repair.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_clock_tree_synthesis.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_detailed_placement.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_detailed_route.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_endcap_tapcell_insertion.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_fillercell_insertion.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_fillmetal_insertion.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_global_placement.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_global_route.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_init_floorplan.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_macro_placement.tcl +3 -3
- siliconcompiler/tools/openroad/scripts/apr/sc_metrics.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_pin_placement.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_power_grid.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_repair_design.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_repair_timing.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_write_data.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/common/procs.tcl +57 -1
- siliconcompiler/tools/openroad/scripts/common/screenshot.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/common/write_images.tcl +28 -3
- siliconcompiler/tools/openroad/scripts/sc_rcx.tcl +1 -1
- siliconcompiler/tools/openroad/scripts/sc_rdlroute.tcl +3 -3
- siliconcompiler/tools/openroad/scripts/sc_show.tcl +6 -6
- siliconcompiler/tools/slang/__init__.py +10 -10
- siliconcompiler/tools/surelog/parse.py +4 -4
- siliconcompiler/tools/sv2v/convert.py +20 -3
- siliconcompiler/tools/verilator/compile.py +2 -2
- siliconcompiler/tools/verilator/verilator.py +3 -3
- siliconcompiler/tools/vpr/place.py +1 -1
- siliconcompiler/tools/vpr/route.py +4 -4
- siliconcompiler/tools/vpr/screenshot.py +1 -1
- siliconcompiler/tools/vpr/show.py +5 -5
- siliconcompiler/tools/vpr/vpr.py +24 -24
- siliconcompiler/tools/xdm/convert.py +2 -2
- siliconcompiler/tools/xyce/simulate.py +1 -1
- siliconcompiler/tools/yosys/sc_synth_asic.tcl +74 -68
- siliconcompiler/tools/yosys/syn_asic.py +2 -2
- siliconcompiler/toolscripts/_tools.json +7 -7
- siliconcompiler/toolscripts/ubuntu22/install-vpr.sh +0 -2
- siliconcompiler/toolscripts/ubuntu24/install-vpr.sh +0 -2
- siliconcompiler/utils/__init__.py +8 -112
- siliconcompiler/utils/flowgraph.py +339 -0
- siliconcompiler/{issue.py → utils/issue.py} +4 -3
- siliconcompiler/utils/logging.py +1 -2
- {siliconcompiler-0.32.3.dist-info → siliconcompiler-0.33.0.dist-info}/METADATA +9 -8
- {siliconcompiler-0.32.3.dist-info → siliconcompiler-0.33.0.dist-info}/RECORD +151 -134
- {siliconcompiler-0.32.3.dist-info → siliconcompiler-0.33.0.dist-info}/WHEEL +1 -1
- {siliconcompiler-0.32.3.dist-info → siliconcompiler-0.33.0.dist-info}/entry_points.txt +8 -8
- siliconcompiler/schema/schema_obj.py +0 -1936
- siliconcompiler/toolscripts/ubuntu20/install-vpr.sh +0 -29
- siliconcompiler/toolscripts/ubuntu20/install-yosys-parmys.sh +0 -61
- /siliconcompiler/{templates → data/templates}/__init__.py +0 -0
- /siliconcompiler/{templates → data/templates}/email/__init__.py +0 -0
- /siliconcompiler/{templates → data/templates}/email/general.j2 +0 -0
- /siliconcompiler/{templates → data/templates}/email/summary.j2 +0 -0
- /siliconcompiler/{templates → data/templates}/issue/README.txt +0 -0
- /siliconcompiler/{templates → data/templates}/issue/__init__.py +0 -0
- /siliconcompiler/{templates → data/templates}/issue/run.sh +0 -0
- /siliconcompiler/{templates → data/templates}/replay/replay.py.j2 +0 -0
- /siliconcompiler/{templates → data/templates}/replay/replay.sh.j2 +0 -0
- /siliconcompiler/{templates → data/templates}/replay/requirements.txt +0 -0
- /siliconcompiler/{templates → data/templates}/replay/setup.sh +0 -0
- /siliconcompiler/{templates → data/templates}/report/__init__.py +0 -0
- /siliconcompiler/{templates → data/templates}/report/bootstrap.min.css +0 -0
- /siliconcompiler/{templates → data/templates}/report/bootstrap.min.js +0 -0
- /siliconcompiler/{templates → data/templates}/report/bootstrap_LICENSE.md +0 -0
- /siliconcompiler/{templates → data/templates}/report/sc_report.j2 +0 -0
- /siliconcompiler/{templates → data/templates}/slurm/__init__.py +0 -0
- /siliconcompiler/{templates → data/templates}/slurm/run.sh +0 -0
- /siliconcompiler/{templates → data/templates}/tcl/__init__.py +0 -0
- /siliconcompiler/{templates → data/templates}/tcl/manifest.tcl.j2 +0 -0
- /siliconcompiler/{units.py → utils/units.py} +0 -0
- {siliconcompiler-0.32.3.dist-info → siliconcompiler-0.33.0.dist-info}/licenses/LICENSE +0 -0
- {siliconcompiler-0.32.3.dist-info → siliconcompiler-0.33.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import re
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class CommandLineSchema:
|
|
7
|
+
'''
|
|
8
|
+
Class to provide the :meth:`create_cmdline` option to a schema object.
|
|
9
|
+
|
|
10
|
+
This class should not be instantiated by itself.
|
|
11
|
+
|
|
12
|
+
Examples:
|
|
13
|
+
class NewSchema(BaseSchema, CommandLineSchema):
|
|
14
|
+
creates a new class with the commandline options available
|
|
15
|
+
'''
|
|
16
|
+
|
|
17
|
+
###########################################################################
|
|
18
|
+
def create_cmdline(self,
|
|
19
|
+
progname,
|
|
20
|
+
description=None,
|
|
21
|
+
switchlist=None,
|
|
22
|
+
additional_args=None,
|
|
23
|
+
version=None,
|
|
24
|
+
print_banner=None,
|
|
25
|
+
input_map_handler=None,
|
|
26
|
+
preprocess_keys=None,
|
|
27
|
+
post_process=None,
|
|
28
|
+
logger=None):
|
|
29
|
+
"""Creates a Schema command line interface.
|
|
30
|
+
|
|
31
|
+
Exposes parameters in the SC schema as command line switches,
|
|
32
|
+
simplifying creation of SC apps with a restricted set of schema
|
|
33
|
+
parameters exposed at the command line. The order of command
|
|
34
|
+
line switch settings parsed from the command line is as follows:
|
|
35
|
+
|
|
36
|
+
1. loglevel, if available in schema
|
|
37
|
+
2. read_manifest([cfg]), if available in schema
|
|
38
|
+
3. read inputs with input_map_handler
|
|
39
|
+
4. all other switches
|
|
40
|
+
5. Run post_process
|
|
41
|
+
|
|
42
|
+
The cmdline interface is implemented using the Python argparse package
|
|
43
|
+
and the following use restrictions apply.
|
|
44
|
+
|
|
45
|
+
* Help is accessed with the '-h' switch.
|
|
46
|
+
* Arguments that include spaces must be enclosed with double quotes.
|
|
47
|
+
* List parameters are entered individually. (ie. -y libdir1 -y libdir2)
|
|
48
|
+
* For parameters with Boolean types, the switch implies "true".
|
|
49
|
+
* Special characters (such as '-') must be enclosed in double quotes.
|
|
50
|
+
* Compiler compatible switches include: -D, -I, -O{0,1,2,3}
|
|
51
|
+
* Legacy switch formats are supported: +libext+, +incdir+
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
progname (str): Name of program to be executed.
|
|
55
|
+
description (str): Short program description.
|
|
56
|
+
switchlist (list of str): List of SC parameter switches to expose
|
|
57
|
+
at the command line. By default all SC schema switches are
|
|
58
|
+
available. Parameter switches should be entered based on the
|
|
59
|
+
parameter 'switch' field in the schema. For parameters with
|
|
60
|
+
multiple switches, both will be accepted if any one is included
|
|
61
|
+
in this list.
|
|
62
|
+
input_map (dict of str): Dictionary mapping file extensions to input
|
|
63
|
+
filetypes. This is used to automatically assign positional
|
|
64
|
+
source arguments to ['input', 'fileset', ...] keypaths based on their file
|
|
65
|
+
extension. If None, the CLI will not accept positional source
|
|
66
|
+
arguments.
|
|
67
|
+
additional_args (dict of dict): Dictionary of extra arguments to add
|
|
68
|
+
to the command line parser, with the arguments matching the
|
|
69
|
+
argparse.add_argument() call.
|
|
70
|
+
version (str): Version to report when calling with -version
|
|
71
|
+
print_banner (function): Function callback to print command line banner
|
|
72
|
+
input_map_handler (function): Function callback handle inputs to the input map
|
|
73
|
+
preprocess_keys (function): Function callback to preprocess keys that need to be
|
|
74
|
+
corrected
|
|
75
|
+
post_process (function): Function callback to process arguments before returning
|
|
76
|
+
|
|
77
|
+
Returns:
|
|
78
|
+
None if additional_args is not provided, otherwise a dictionary with the
|
|
79
|
+
command line options detected from the additional_args
|
|
80
|
+
|
|
81
|
+
Examples:
|
|
82
|
+
>>> schema.create_cmdline(progname='sc-show',switchlist=['-input','-cfg'])
|
|
83
|
+
Creates a command line interface for 'sc-show' app.
|
|
84
|
+
>>> schema.create_cmdline(progname='sc', input_map={'v': ('rtl', 'verilog')})
|
|
85
|
+
All sources ending in .v will be stored in ['input', 'rtl', 'verilog']
|
|
86
|
+
>>> extra = schema.create_cmdline(progname='sc',
|
|
87
|
+
additional_args={'-demo': {'action': 'store_true'}})
|
|
88
|
+
Returns extra = {'demo': False/True}
|
|
89
|
+
"""
|
|
90
|
+
|
|
91
|
+
# Argparse
|
|
92
|
+
parser = argparse.ArgumentParser(prog=progname,
|
|
93
|
+
prefix_chars='-+',
|
|
94
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
95
|
+
description=description,
|
|
96
|
+
allow_abbrev=False)
|
|
97
|
+
|
|
98
|
+
# Create empty copy of schema
|
|
99
|
+
schema = type(self)()
|
|
100
|
+
|
|
101
|
+
# Track arguments
|
|
102
|
+
argument_map = {}
|
|
103
|
+
arguments = set()
|
|
104
|
+
|
|
105
|
+
# Iterate over all keys from an empty schema to add parser arguments
|
|
106
|
+
for keypath in sorted(schema.allkeys()):
|
|
107
|
+
param = schema.get(*keypath, field=None)
|
|
108
|
+
|
|
109
|
+
dest, switches = param.add_commandline_arguments(
|
|
110
|
+
parser,
|
|
111
|
+
*keypath,
|
|
112
|
+
switchlist=switchlist)
|
|
113
|
+
|
|
114
|
+
if switches:
|
|
115
|
+
argument_map[dest] = (keypath, param)
|
|
116
|
+
arguments.update(switches)
|
|
117
|
+
|
|
118
|
+
print_additional_arg_value = {}
|
|
119
|
+
if additional_args:
|
|
120
|
+
# Add additional user specified arguments
|
|
121
|
+
arg_dests = []
|
|
122
|
+
for arg, arg_detail in additional_args.items():
|
|
123
|
+
do_print = True
|
|
124
|
+
if "sc_print" in arg_detail:
|
|
125
|
+
do_print = arg_detail["sc_print"]
|
|
126
|
+
del arg_detail["sc_print"]
|
|
127
|
+
argument = parser.add_argument(arg, **arg_detail)
|
|
128
|
+
print_additional_arg_value[argument.dest] = do_print
|
|
129
|
+
|
|
130
|
+
arg_dests.append(argument.dest)
|
|
131
|
+
arguments.add(arg)
|
|
132
|
+
# rewrite additional_args with new dest information
|
|
133
|
+
additional_args = arg_dests
|
|
134
|
+
|
|
135
|
+
if version:
|
|
136
|
+
parser.add_argument('-version', action='version', version=version)
|
|
137
|
+
|
|
138
|
+
# Check if there are invalid switches
|
|
139
|
+
if switchlist:
|
|
140
|
+
for switch in switchlist:
|
|
141
|
+
if switch not in arguments:
|
|
142
|
+
raise ValueError(f'{switch} is not a valid commandline argument')
|
|
143
|
+
|
|
144
|
+
if input_map_handler:
|
|
145
|
+
parser.add_argument('source',
|
|
146
|
+
nargs='*',
|
|
147
|
+
help='Input files with filetype inferred by extension')
|
|
148
|
+
|
|
149
|
+
# Preprocess sys.argv to enable linux commandline switch formats
|
|
150
|
+
# (gcc, verilator, etc)
|
|
151
|
+
scargs = []
|
|
152
|
+
|
|
153
|
+
# Iterate from index 1, otherwise we end up with script name as a
|
|
154
|
+
# 'source' positional argument
|
|
155
|
+
for argument in sys.argv[1:]:
|
|
156
|
+
# Split switches with one character and a number after (O0,O1,O2)
|
|
157
|
+
opt = re.match(r'(\-\w)(\d+)', argument)
|
|
158
|
+
# Split assign switches (-DCFG_ASIC=1)
|
|
159
|
+
assign = re.search(r'(\-\w)(\w+\=\w+)', argument)
|
|
160
|
+
# Split plusargs (+incdir+/path)
|
|
161
|
+
plusarg = re.search(r'(\+\w+\+)(.*)', argument)
|
|
162
|
+
if opt:
|
|
163
|
+
scargs.append(opt.group(1))
|
|
164
|
+
scargs.append(opt.group(2))
|
|
165
|
+
elif plusarg:
|
|
166
|
+
scargs.append(plusarg.group(1))
|
|
167
|
+
scargs.append(plusarg.group(2))
|
|
168
|
+
elif assign:
|
|
169
|
+
scargs.append(assign.group(1))
|
|
170
|
+
scargs.append(assign.group(2))
|
|
171
|
+
else:
|
|
172
|
+
scargs.append(argument)
|
|
173
|
+
|
|
174
|
+
# Grab argument from pre-process sysargs
|
|
175
|
+
cmdargs = vars(parser.parse_args(scargs))
|
|
176
|
+
|
|
177
|
+
# Set loglevel if set at command line
|
|
178
|
+
do_print_banner = True
|
|
179
|
+
if 'option_loglevel' in cmdargs:
|
|
180
|
+
log_level = cmdargs['option_loglevel']
|
|
181
|
+
if isinstance(log_level, list):
|
|
182
|
+
# if multiple found, pick the first one
|
|
183
|
+
log_level = log_level[0]
|
|
184
|
+
if log_level == 'quiet':
|
|
185
|
+
do_print_banner = False
|
|
186
|
+
if logger:
|
|
187
|
+
logger.setLevel(log_level.split()[-1].upper())
|
|
188
|
+
|
|
189
|
+
if print_banner and do_print_banner:
|
|
190
|
+
print_banner()
|
|
191
|
+
|
|
192
|
+
extra_params = None
|
|
193
|
+
if additional_args:
|
|
194
|
+
# Grab user specified arguments
|
|
195
|
+
extra_params = {}
|
|
196
|
+
for arg in additional_args:
|
|
197
|
+
if arg in cmdargs:
|
|
198
|
+
val = cmdargs[arg]
|
|
199
|
+
if print_additional_arg_value[arg] and val and logger:
|
|
200
|
+
logger.info(
|
|
201
|
+
f'Command line argument entered: "{arg}" Value: {val}')
|
|
202
|
+
extra_params[arg] = val
|
|
203
|
+
# Remove from cmdargs
|
|
204
|
+
del cmdargs[arg]
|
|
205
|
+
|
|
206
|
+
# Read in all cfg files
|
|
207
|
+
if 'option_cfg' in cmdargs.keys():
|
|
208
|
+
for item in cmdargs['option_cfg']:
|
|
209
|
+
self.read_manifest(item)
|
|
210
|
+
|
|
211
|
+
if input_map_handler:
|
|
212
|
+
# Map sources to ['input'] keypath.
|
|
213
|
+
if 'source' in cmdargs:
|
|
214
|
+
input_map_handler(cmdargs['source'])
|
|
215
|
+
# we don't want to handle this in the next loop
|
|
216
|
+
del cmdargs['source']
|
|
217
|
+
|
|
218
|
+
# Cycle through all command args and write to manifest
|
|
219
|
+
for dest, vals in sorted(cmdargs.items(), key=lambda d: d[0]):
|
|
220
|
+
keypath, param = argument_map[dest]
|
|
221
|
+
|
|
222
|
+
# Turn everything into a list for uniformity
|
|
223
|
+
if not isinstance(vals, list):
|
|
224
|
+
vals = [vals]
|
|
225
|
+
|
|
226
|
+
# Cycle through all items
|
|
227
|
+
for item in vals:
|
|
228
|
+
if preprocess_keys:
|
|
229
|
+
item = preprocess_keys(keypath, item)
|
|
230
|
+
|
|
231
|
+
valkeypath, step, index, item = param.parse_commandline_arguments(item, *keypath)
|
|
232
|
+
|
|
233
|
+
if logger:
|
|
234
|
+
msg = f'Command line argument entered: [{",".join(valkeypath)}] Value: {item}'
|
|
235
|
+
if step is not None:
|
|
236
|
+
msg += f' step: {step}'
|
|
237
|
+
if index is not None:
|
|
238
|
+
msg += f' index: {index}'
|
|
239
|
+
logger.info(msg)
|
|
240
|
+
|
|
241
|
+
# Storing in manifest
|
|
242
|
+
if param.is_list():
|
|
243
|
+
self.add(*valkeypath, item, step=step, index=index)
|
|
244
|
+
else:
|
|
245
|
+
self.set(*valkeypath, item, step=step, index=index)
|
|
246
|
+
|
|
247
|
+
if post_process:
|
|
248
|
+
extra_params = post_process(cmdargs, extra_params)
|
|
249
|
+
|
|
250
|
+
return extra_params
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import os.path
|
|
2
2
|
|
|
3
|
+
from pathlib import PureWindowsPath
|
|
4
|
+
|
|
3
5
|
import siliconcompiler
|
|
4
6
|
from siliconcompiler import __version__ as sc_version
|
|
5
7
|
|
|
@@ -18,7 +20,7 @@ sc_root = os.path.dirname(os.path.dirname(os.path.abspath(siliconcompiler.__file
|
|
|
18
20
|
def relpath(file):
|
|
19
21
|
file = os.path.abspath(file)
|
|
20
22
|
if file.startswith(sc_root):
|
|
21
|
-
return os.path.relpath(file, sc_root)
|
|
23
|
+
return PureWindowsPath(os.path.relpath(file, sc_root)).as_posix()
|
|
22
24
|
return None
|
|
23
25
|
|
|
24
26
|
|
|
@@ -17,9 +17,9 @@ import os
|
|
|
17
17
|
import subprocess
|
|
18
18
|
|
|
19
19
|
import siliconcompiler
|
|
20
|
-
from siliconcompiler.
|
|
21
|
-
from siliconcompiler.schema import
|
|
22
|
-
from siliconcompiler.
|
|
20
|
+
from siliconcompiler.schema import utils
|
|
21
|
+
from siliconcompiler.schema.docs import sc_root as SC_ROOT
|
|
22
|
+
from siliconcompiler.schema.docs.utils import (
|
|
23
23
|
strong,
|
|
24
24
|
code,
|
|
25
25
|
para,
|
|
@@ -39,15 +39,12 @@ from siliconcompiler.sphinx_ext.utils import (
|
|
|
39
39
|
#############
|
|
40
40
|
|
|
41
41
|
|
|
42
|
-
def build_schema_value_table(
|
|
42
|
+
def build_schema_value_table(params, refdoc, keypath_prefix=None):
|
|
43
43
|
'''Helper function for displaying values set in schema as a docutils table.'''
|
|
44
44
|
table = [[strong('Keypath'), strong('Value')]]
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
if keypath_prefix:
|
|
49
|
-
for key in reversed(keypath_prefix):
|
|
50
|
-
rooted_cfg = {key: rooted_cfg}
|
|
46
|
+
if not keypath_prefix:
|
|
47
|
+
keypath_prefix = []
|
|
51
48
|
|
|
52
49
|
def format_value(is_list, value):
|
|
53
50
|
if is_list:
|
|
@@ -81,33 +78,27 @@ def build_schema_value_table(cfg, refdoc, keypath_prefix=None, skip_zero_weight=
|
|
|
81
78
|
val_node = format_single_value_file(value, package)
|
|
82
79
|
return val_node
|
|
83
80
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
if skip_zero_weight and \
|
|
87
|
-
len(kp) == 6 and kp[0] == 'flowgraph' and kp[-2] == 'weight' and \
|
|
88
|
-
schema.get(*kp) == 0:
|
|
89
|
-
continue
|
|
90
|
-
|
|
91
|
-
values = schema._getvals(*kp, return_defvalue=False)
|
|
81
|
+
for key, param in sorted(params.items(), key=lambda d: d[0]):
|
|
82
|
+
values = param.getvalues(return_defvalue=False)
|
|
92
83
|
if values:
|
|
93
84
|
# take first of multiple possible values
|
|
94
85
|
value, step, index = values[0]
|
|
95
|
-
val_type =
|
|
86
|
+
val_type = param.get(field='type')
|
|
96
87
|
is_filedir = 'file' in val_type or 'dir' in val_type
|
|
97
88
|
# Don't display false booleans
|
|
98
89
|
if val_type == 'bool' and value is False:
|
|
99
90
|
continue
|
|
100
91
|
if is_filedir:
|
|
101
92
|
val_node = format_value_file(val_type.startswith('['), value,
|
|
102
|
-
|
|
103
|
-
|
|
93
|
+
param.get(field='package',
|
|
94
|
+
step=step, index=index))
|
|
104
95
|
else:
|
|
105
96
|
val_node = format_value(val_type.startswith('['), value)
|
|
106
97
|
|
|
107
98
|
# HTML builder fails if we don't make a text node the parent of the
|
|
108
99
|
# reference node returned by keypath()
|
|
109
100
|
p = nodes.paragraph()
|
|
110
|
-
p += keypath(
|
|
101
|
+
p += keypath([*keypath_prefix, *key], refdoc)
|
|
111
102
|
table.append([p, val_node])
|
|
112
103
|
|
|
113
104
|
if len(table) > 1:
|
|
@@ -121,21 +112,21 @@ def build_schema_value_table(cfg, refdoc, keypath_prefix=None, skip_zero_weight=
|
|
|
121
112
|
|
|
122
113
|
|
|
123
114
|
def build_package_table(schema):
|
|
124
|
-
def collect_packages(
|
|
115
|
+
def collect_packages():
|
|
125
116
|
packages = []
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
117
|
+
for key in schema.allkeys(include_default=True):
|
|
118
|
+
param = schema.get(*key, field=None)
|
|
119
|
+
if 'dir' in param.get(field='type') or 'file' in param.get(field='type'):
|
|
120
|
+
for _, index_data in param.getdict()["node"].items():
|
|
129
121
|
for _, data in index_data.items():
|
|
122
|
+
if not data['package']:
|
|
123
|
+
continue
|
|
124
|
+
if isinstance(data['package'], str):
|
|
125
|
+
data['package'] = [data['package']]
|
|
130
126
|
packages.extend(data['package'])
|
|
131
|
-
|
|
132
|
-
for key in cfg:
|
|
133
|
-
packages.extend(collect_packages(cfg[key]))
|
|
134
|
-
packages = [p for p in packages if p]
|
|
135
|
-
return list(set(packages))
|
|
127
|
+
return list(set([p for p in packages if p]))
|
|
136
128
|
|
|
137
|
-
|
|
138
|
-
packages = collect_packages(schema.cfg)
|
|
129
|
+
packages = collect_packages()
|
|
139
130
|
|
|
140
131
|
if not packages:
|
|
141
132
|
return None
|
|
@@ -281,7 +272,7 @@ class DynamicGen(SphinxDirective):
|
|
|
281
272
|
nested_parse_with_titles(self.state, rst, s)
|
|
282
273
|
|
|
283
274
|
def package_information(self, chip, modname):
|
|
284
|
-
packages = build_package_table(chip.schema
|
|
275
|
+
packages = build_package_table(chip.schema)
|
|
285
276
|
if packages:
|
|
286
277
|
sec = build_section('Data sources', self.get_data_source_ref_key(modname, chip.design))
|
|
287
278
|
sec += packages
|
|
@@ -435,12 +426,11 @@ class DynamicGen(SphinxDirective):
|
|
|
435
426
|
if sec_key_prefix is None:
|
|
436
427
|
sec_key_prefix = []
|
|
437
428
|
|
|
438
|
-
|
|
429
|
+
params = {}
|
|
439
430
|
child_sections = []
|
|
440
431
|
for key in schema.getkeys(*keypath):
|
|
441
|
-
if
|
|
442
|
-
|
|
443
|
-
leaves.update({key: val})
|
|
432
|
+
if schema.valid(*keypath, key, check_complete=True):
|
|
433
|
+
params[(key,)] = schema.get(*keypath, key, field=None)
|
|
444
434
|
else:
|
|
445
435
|
children = self.build_config_recursive(
|
|
446
436
|
schema,
|
|
@@ -450,9 +440,9 @@ class DynamicGen(SphinxDirective):
|
|
|
450
440
|
child_sections.extend(children)
|
|
451
441
|
|
|
452
442
|
schema_table = None
|
|
453
|
-
if len(
|
|
443
|
+
if len(params) > 0:
|
|
454
444
|
# Might return None is none of the leaves are displayable
|
|
455
|
-
schema_table = build_schema_value_table(
|
|
445
|
+
schema_table = build_schema_value_table(params, refdoc, keypath_prefix=keypath)
|
|
456
446
|
|
|
457
447
|
if schema_table is not None:
|
|
458
448
|
# If we've found leaves, create a new section where we'll display a
|
|
@@ -493,27 +483,22 @@ class FlowGen(DynamicGen):
|
|
|
493
483
|
settings = build_section('Configuration', self.get_configuration_ref_key(name))
|
|
494
484
|
|
|
495
485
|
steps = chip.getkeys('flowgraph', chip.design)
|
|
486
|
+
schema = chip.schema
|
|
496
487
|
# TODO: should try to order?
|
|
497
488
|
|
|
498
489
|
# Build section + table for each step (combining entries under flowgraph
|
|
499
490
|
# and metric)
|
|
500
491
|
for step in steps:
|
|
501
492
|
section = build_section(step, self.get_ref(name, 'step', step))
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
if chip.design not in step_cfg:
|
|
510
|
-
step_cfg[chip.design] = {}
|
|
511
|
-
step_cfg[chip.design][step] = pruned
|
|
512
|
-
|
|
513
|
-
section += build_schema_value_table(step_cfg,
|
|
493
|
+
|
|
494
|
+
params = {}
|
|
495
|
+
for item in schema.allkeys('flowgraph', chip.design, step):
|
|
496
|
+
if item[1] == 'weight' and not schema.get('flowgraph', chip.design, step, *item):
|
|
497
|
+
continue
|
|
498
|
+
params[item] = schema.get('flowgraph', chip.design, step, *item, field=None)
|
|
499
|
+
section += build_schema_value_table(params,
|
|
514
500
|
self.env.docname,
|
|
515
|
-
keypath_prefix=['flowgraph']
|
|
516
|
-
skip_zero_weight=True)
|
|
501
|
+
keypath_prefix=['flowgraph', chip.design, step])
|
|
517
502
|
settings += section
|
|
518
503
|
|
|
519
504
|
return settings
|
|
@@ -636,15 +621,12 @@ class ToolGen(DynamicGen):
|
|
|
636
621
|
|
|
637
622
|
def display_config(self, chip, modname):
|
|
638
623
|
'''Display config under `eda, <modname>` in a single table.'''
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
# by the task documentation
|
|
646
|
-
del pruned['task']
|
|
647
|
-
table = build_schema_value_table(pruned, self.env.docname, keypath_prefix=['tool', modname])
|
|
624
|
+
params = {}
|
|
625
|
+
for key in chip.schema.allkeys('tool', modname):
|
|
626
|
+
if key == 'task':
|
|
627
|
+
continue
|
|
628
|
+
params[key] = chip.schema.get('tool', modname, *key, field=None)
|
|
629
|
+
table = build_schema_value_table(params, self.env.docname, keypath_prefix=['tool', modname])
|
|
648
630
|
if table is not None:
|
|
649
631
|
return table
|
|
650
632
|
else:
|
|
@@ -652,14 +634,13 @@ class ToolGen(DynamicGen):
|
|
|
652
634
|
|
|
653
635
|
def task_display_config(self, chip, toolname, taskname):
|
|
654
636
|
'''Display config under `eda, <modname>` in a single table.'''
|
|
655
|
-
|
|
656
|
-
schema
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
table = build_schema_value_table(pruned, self.env.docname,
|
|
637
|
+
params = {}
|
|
638
|
+
for key in chip.schema.allkeys('tool', toolname, 'task', taskname):
|
|
639
|
+
params[key] = chip.schema.get('tool', toolname, 'task', taskname, *key, field=None)
|
|
640
|
+
if key[0] == "require":
|
|
641
|
+
for vals, step, index in params[key].getvalues():
|
|
642
|
+
params[key].set(sorted(set(vals)), step=step, index=index)
|
|
643
|
+
table = build_schema_value_table(params, self.env.docname,
|
|
663
644
|
keypath_prefix=['tool', toolname, 'task', taskname])
|
|
664
645
|
if table is not None:
|
|
665
646
|
return table
|
|
@@ -731,7 +712,7 @@ class ToolGen(DynamicGen):
|
|
|
731
712
|
s)
|
|
732
713
|
except Exception as e:
|
|
733
714
|
print(f'Failed to document task, Chip object probably not configured correctly: {e}')
|
|
734
|
-
|
|
715
|
+
raise e
|
|
735
716
|
|
|
736
717
|
return s
|
|
737
718
|
|
|
@@ -803,7 +784,7 @@ class TargetGen(DynamicGen):
|
|
|
803
784
|
if len(modules) > 0:
|
|
804
785
|
section = build_section(header, self.get_ref(targetname, modtype))
|
|
805
786
|
modlist = nodes.bullet_list()
|
|
806
|
-
for module in modules:
|
|
787
|
+
for module in sorted(modules):
|
|
807
788
|
list_item = nodes.list_item()
|
|
808
789
|
# TODO: replace with proper docutils nodes: sphinx.addnodes.pending_xref
|
|
809
790
|
modkey = get_ref_id(DynamicGen.get_ref_key(*refprefix, module))
|
|
@@ -839,14 +820,12 @@ class TargetGen(DynamicGen):
|
|
|
839
820
|
|
|
840
821
|
filtered_cfg = {}
|
|
841
822
|
for key in ('asic', 'constraint', 'option'):
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
schema.prune()
|
|
845
|
-
pruned_cfg = schema.cfg
|
|
823
|
+
for subkey in chip.schema.allkeys(key):
|
|
824
|
+
filtered_cfg[(key, *subkey)] = chip.schema.get(key, *subkey, field=None)
|
|
846
825
|
|
|
847
|
-
if
|
|
826
|
+
if filtered_cfg:
|
|
848
827
|
schema_section = build_section('Configuration', self.get_configuration_ref_key(modname))
|
|
849
|
-
schema_section += build_schema_value_table(
|
|
828
|
+
schema_section += build_schema_value_table(filtered_cfg, self.env.docname)
|
|
850
829
|
sections.append(schema_section)
|
|
851
830
|
|
|
852
831
|
return sections
|
|
@@ -892,15 +871,18 @@ class ChecklistGen(DynamicGen):
|
|
|
892
871
|
name = chip.design
|
|
893
872
|
|
|
894
873
|
keypath_prefix = ['checklist', name]
|
|
895
|
-
|
|
874
|
+
schema = chip.schema
|
|
896
875
|
|
|
897
876
|
settings = build_section('Configuration', self.get_configuration_ref_key(name))
|
|
898
877
|
|
|
899
|
-
for key in
|
|
878
|
+
for key in schema.getkeys(*keypath_prefix):
|
|
900
879
|
if key == 'default':
|
|
901
880
|
continue
|
|
902
881
|
settings += build_section(key, self.get_ref(name, 'key', key))
|
|
903
|
-
|
|
882
|
+
params = {}
|
|
883
|
+
for item in schema.allkeys(*keypath_prefix, key):
|
|
884
|
+
params[item] = schema.get(*keypath_prefix, key, *item, field=None)
|
|
885
|
+
settings += build_schema_value_table(params, self.env.docname,
|
|
904
886
|
keypath_prefix=[*keypath_prefix, key])
|
|
905
887
|
|
|
906
888
|
sections.append(settings)
|