siliconcompiler 0.26.5__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 +24 -0
- siliconcompiler/__main__.py +12 -0
- siliconcompiler/_common.py +49 -0
- siliconcompiler/_metadata.py +36 -0
- siliconcompiler/apps/__init__.py +0 -0
- siliconcompiler/apps/_common.py +76 -0
- siliconcompiler/apps/sc.py +92 -0
- siliconcompiler/apps/sc_dashboard.py +94 -0
- siliconcompiler/apps/sc_issue.py +178 -0
- siliconcompiler/apps/sc_remote.py +199 -0
- siliconcompiler/apps/sc_server.py +39 -0
- siliconcompiler/apps/sc_show.py +142 -0
- siliconcompiler/apps/smake.py +232 -0
- siliconcompiler/checklists/__init__.py +0 -0
- siliconcompiler/checklists/oh_tapeout.py +41 -0
- siliconcompiler/core.py +3221 -0
- siliconcompiler/data/RobotoMono/LICENSE.txt +202 -0
- siliconcompiler/data/RobotoMono/RobotoMono-Regular.ttf +0 -0
- siliconcompiler/data/heartbeat.v +18 -0
- siliconcompiler/data/logo.png +0 -0
- siliconcompiler/flowgraph.py +570 -0
- siliconcompiler/flows/__init__.py +0 -0
- siliconcompiler/flows/_common.py +67 -0
- siliconcompiler/flows/asicflow.py +180 -0
- siliconcompiler/flows/asictopflow.py +38 -0
- siliconcompiler/flows/dvflow.py +86 -0
- siliconcompiler/flows/fpgaflow.py +202 -0
- siliconcompiler/flows/generate_openroad_rcx.py +66 -0
- siliconcompiler/flows/lintflow.py +35 -0
- siliconcompiler/flows/screenshotflow.py +51 -0
- siliconcompiler/flows/showflow.py +59 -0
- siliconcompiler/flows/signoffflow.py +53 -0
- siliconcompiler/flows/synflow.py +128 -0
- siliconcompiler/fpgas/__init__.py +0 -0
- siliconcompiler/fpgas/lattice_ice40.py +42 -0
- siliconcompiler/fpgas/vpr_example.py +109 -0
- siliconcompiler/issue.py +300 -0
- siliconcompiler/libs/__init__.py +0 -0
- siliconcompiler/libs/asap7sc7p5t.py +8 -0
- siliconcompiler/libs/gf180mcu.py +8 -0
- siliconcompiler/libs/nangate45.py +8 -0
- siliconcompiler/libs/sky130hd.py +8 -0
- siliconcompiler/libs/sky130io.py +8 -0
- siliconcompiler/package.py +412 -0
- siliconcompiler/pdks/__init__.py +0 -0
- siliconcompiler/pdks/asap7.py +8 -0
- siliconcompiler/pdks/freepdk45.py +8 -0
- siliconcompiler/pdks/gf180.py +8 -0
- siliconcompiler/pdks/skywater130.py +8 -0
- siliconcompiler/remote/__init__.py +36 -0
- siliconcompiler/remote/client.py +891 -0
- siliconcompiler/remote/schema.py +106 -0
- siliconcompiler/remote/server.py +507 -0
- siliconcompiler/remote/server_schema/requests/cancel_job.json +51 -0
- siliconcompiler/remote/server_schema/requests/check_progress.json +61 -0
- siliconcompiler/remote/server_schema/requests/check_server.json +38 -0
- siliconcompiler/remote/server_schema/requests/delete_job.json +51 -0
- siliconcompiler/remote/server_schema/requests/get_results.json +48 -0
- siliconcompiler/remote/server_schema/requests/remote_run.json +40 -0
- siliconcompiler/remote/server_schema/responses/cancel_job.json +18 -0
- siliconcompiler/remote/server_schema/responses/check_progress.json +30 -0
- siliconcompiler/remote/server_schema/responses/check_server.json +32 -0
- siliconcompiler/remote/server_schema/responses/delete_job.json +18 -0
- siliconcompiler/remote/server_schema/responses/get_results.json +21 -0
- siliconcompiler/remote/server_schema/responses/remote_run.json +25 -0
- siliconcompiler/report/__init__.py +13 -0
- siliconcompiler/report/html_report.py +74 -0
- siliconcompiler/report/report.py +355 -0
- siliconcompiler/report/streamlit_report.py +137 -0
- siliconcompiler/report/streamlit_viewer.py +944 -0
- siliconcompiler/report/summary_image.py +117 -0
- siliconcompiler/report/summary_table.py +105 -0
- siliconcompiler/report/utils.py +163 -0
- siliconcompiler/scheduler/__init__.py +2092 -0
- siliconcompiler/scheduler/docker_runner.py +253 -0
- siliconcompiler/scheduler/run_node.py +138 -0
- siliconcompiler/scheduler/send_messages.py +178 -0
- siliconcompiler/scheduler/slurm.py +208 -0
- siliconcompiler/scheduler/validation/email_credentials.json +54 -0
- siliconcompiler/schema/__init__.py +7 -0
- siliconcompiler/schema/schema_cfg.py +4014 -0
- siliconcompiler/schema/schema_obj.py +1841 -0
- siliconcompiler/schema/utils.py +93 -0
- siliconcompiler/sphinx_ext/__init__.py +0 -0
- siliconcompiler/sphinx_ext/dynamicgen.py +1006 -0
- siliconcompiler/sphinx_ext/schemagen.py +221 -0
- siliconcompiler/sphinx_ext/utils.py +166 -0
- siliconcompiler/targets/__init__.py +0 -0
- siliconcompiler/targets/asap7_demo.py +68 -0
- siliconcompiler/targets/asic_demo.py +38 -0
- siliconcompiler/targets/fpgaflow_demo.py +47 -0
- siliconcompiler/targets/freepdk45_demo.py +59 -0
- siliconcompiler/targets/gf180_demo.py +77 -0
- siliconcompiler/targets/skywater130_demo.py +70 -0
- siliconcompiler/templates/email/general.j2 +66 -0
- siliconcompiler/templates/email/summary.j2 +43 -0
- siliconcompiler/templates/issue/README.txt +26 -0
- siliconcompiler/templates/issue/run.sh +6 -0
- siliconcompiler/templates/report/bootstrap.min.css +7 -0
- siliconcompiler/templates/report/bootstrap.min.js +7 -0
- siliconcompiler/templates/report/bootstrap_LICENSE.md +24 -0
- siliconcompiler/templates/report/sc_report.j2 +427 -0
- siliconcompiler/templates/slurm/run.sh +9 -0
- siliconcompiler/templates/tcl/manifest.tcl.j2 +137 -0
- siliconcompiler/tools/__init__.py +0 -0
- siliconcompiler/tools/_common/__init__.py +432 -0
- siliconcompiler/tools/_common/asic.py +115 -0
- siliconcompiler/tools/_common/sdc/sc_constraints.sdc +76 -0
- siliconcompiler/tools/_common/tcl/sc_pin_constraints.tcl +63 -0
- siliconcompiler/tools/bambu/bambu.py +32 -0
- siliconcompiler/tools/bambu/convert.py +77 -0
- siliconcompiler/tools/bluespec/bluespec.py +40 -0
- siliconcompiler/tools/bluespec/convert.py +103 -0
- siliconcompiler/tools/builtin/_common.py +155 -0
- siliconcompiler/tools/builtin/builtin.py +26 -0
- siliconcompiler/tools/builtin/concatenate.py +85 -0
- siliconcompiler/tools/builtin/join.py +27 -0
- siliconcompiler/tools/builtin/maximum.py +46 -0
- siliconcompiler/tools/builtin/minimum.py +57 -0
- siliconcompiler/tools/builtin/mux.py +70 -0
- siliconcompiler/tools/builtin/nop.py +38 -0
- siliconcompiler/tools/builtin/verify.py +83 -0
- siliconcompiler/tools/chisel/SCDriver.scala +10 -0
- siliconcompiler/tools/chisel/build.sbt +27 -0
- siliconcompiler/tools/chisel/chisel.py +37 -0
- siliconcompiler/tools/chisel/convert.py +140 -0
- siliconcompiler/tools/execute/exec_input.py +41 -0
- siliconcompiler/tools/execute/execute.py +17 -0
- siliconcompiler/tools/genfasm/bitstream.py +61 -0
- siliconcompiler/tools/genfasm/genfasm.py +40 -0
- siliconcompiler/tools/ghdl/convert.py +87 -0
- siliconcompiler/tools/ghdl/ghdl.py +41 -0
- siliconcompiler/tools/icarus/compile.py +87 -0
- siliconcompiler/tools/icarus/icarus.py +36 -0
- siliconcompiler/tools/icepack/bitstream.py +20 -0
- siliconcompiler/tools/icepack/icepack.py +43 -0
- siliconcompiler/tools/klayout/export.py +117 -0
- siliconcompiler/tools/klayout/klayout.py +119 -0
- siliconcompiler/tools/klayout/klayout_export.py +205 -0
- siliconcompiler/tools/klayout/klayout_operations.py +363 -0
- siliconcompiler/tools/klayout/klayout_show.py +242 -0
- siliconcompiler/tools/klayout/klayout_utils.py +176 -0
- siliconcompiler/tools/klayout/operations.py +194 -0
- siliconcompiler/tools/klayout/screenshot.py +98 -0
- siliconcompiler/tools/klayout/show.py +101 -0
- siliconcompiler/tools/magic/drc.py +49 -0
- siliconcompiler/tools/magic/extspice.py +19 -0
- siliconcompiler/tools/magic/magic.py +85 -0
- siliconcompiler/tools/magic/sc_drc.tcl +96 -0
- siliconcompiler/tools/magic/sc_extspice.tcl +54 -0
- siliconcompiler/tools/magic/sc_magic.tcl +47 -0
- siliconcompiler/tools/montage/montage.py +30 -0
- siliconcompiler/tools/montage/tile.py +66 -0
- siliconcompiler/tools/netgen/count_lvs.py +132 -0
- siliconcompiler/tools/netgen/lvs.py +90 -0
- siliconcompiler/tools/netgen/netgen.py +36 -0
- siliconcompiler/tools/netgen/sc_lvs.tcl +46 -0
- siliconcompiler/tools/nextpnr/apr.py +24 -0
- siliconcompiler/tools/nextpnr/nextpnr.py +59 -0
- siliconcompiler/tools/openfpgaloader/openfpgaloader.py +39 -0
- siliconcompiler/tools/openroad/__init__.py +0 -0
- siliconcompiler/tools/openroad/cts.py +45 -0
- siliconcompiler/tools/openroad/dfm.py +66 -0
- siliconcompiler/tools/openroad/export.py +131 -0
- siliconcompiler/tools/openroad/floorplan.py +70 -0
- siliconcompiler/tools/openroad/openroad.py +977 -0
- siliconcompiler/tools/openroad/physyn.py +27 -0
- siliconcompiler/tools/openroad/place.py +41 -0
- siliconcompiler/tools/openroad/rcx_bench.py +95 -0
- siliconcompiler/tools/openroad/rcx_extract.py +34 -0
- siliconcompiler/tools/openroad/route.py +45 -0
- siliconcompiler/tools/openroad/screenshot.py +60 -0
- siliconcompiler/tools/openroad/scripts/sc_apr.tcl +499 -0
- siliconcompiler/tools/openroad/scripts/sc_cts.tcl +64 -0
- siliconcompiler/tools/openroad/scripts/sc_dfm.tcl +20 -0
- siliconcompiler/tools/openroad/scripts/sc_export.tcl +98 -0
- siliconcompiler/tools/openroad/scripts/sc_floorplan.tcl +413 -0
- siliconcompiler/tools/openroad/scripts/sc_metrics.tcl +158 -0
- siliconcompiler/tools/openroad/scripts/sc_physyn.tcl +7 -0
- siliconcompiler/tools/openroad/scripts/sc_place.tcl +84 -0
- siliconcompiler/tools/openroad/scripts/sc_procs.tcl +423 -0
- siliconcompiler/tools/openroad/scripts/sc_rcx.tcl +63 -0
- siliconcompiler/tools/openroad/scripts/sc_rcx_bench.tcl +20 -0
- siliconcompiler/tools/openroad/scripts/sc_rcx_extract.tcl +12 -0
- siliconcompiler/tools/openroad/scripts/sc_route.tcl +133 -0
- siliconcompiler/tools/openroad/scripts/sc_screenshot.tcl +21 -0
- siliconcompiler/tools/openroad/scripts/sc_write.tcl +5 -0
- siliconcompiler/tools/openroad/scripts/sc_write_images.tcl +361 -0
- siliconcompiler/tools/openroad/show.py +94 -0
- siliconcompiler/tools/openroad/templates/pex.tcl +8 -0
- siliconcompiler/tools/opensta/__init__.py +101 -0
- siliconcompiler/tools/opensta/report_libraries.py +28 -0
- siliconcompiler/tools/opensta/scripts/sc_procs.tcl +47 -0
- siliconcompiler/tools/opensta/scripts/sc_report_libraries.tcl +74 -0
- siliconcompiler/tools/opensta/scripts/sc_timing.tcl +268 -0
- siliconcompiler/tools/opensta/timing.py +214 -0
- siliconcompiler/tools/slang/__init__.py +49 -0
- siliconcompiler/tools/slang/lint.py +101 -0
- siliconcompiler/tools/surelog/__init__.py +123 -0
- siliconcompiler/tools/surelog/parse.py +183 -0
- siliconcompiler/tools/surelog/templates/output.v +7 -0
- siliconcompiler/tools/sv2v/convert.py +46 -0
- siliconcompiler/tools/sv2v/sv2v.py +37 -0
- siliconcompiler/tools/template/template.py +125 -0
- siliconcompiler/tools/verilator/compile.py +139 -0
- siliconcompiler/tools/verilator/lint.py +19 -0
- siliconcompiler/tools/verilator/parse.py +27 -0
- siliconcompiler/tools/verilator/verilator.py +172 -0
- siliconcompiler/tools/vivado/__init__.py +7 -0
- siliconcompiler/tools/vivado/bitstream.py +21 -0
- siliconcompiler/tools/vivado/place.py +21 -0
- siliconcompiler/tools/vivado/route.py +21 -0
- siliconcompiler/tools/vivado/scripts/sc_bitstream.tcl +6 -0
- siliconcompiler/tools/vivado/scripts/sc_place.tcl +2 -0
- siliconcompiler/tools/vivado/scripts/sc_route.tcl +4 -0
- siliconcompiler/tools/vivado/scripts/sc_run.tcl +45 -0
- siliconcompiler/tools/vivado/scripts/sc_syn_fpga.tcl +25 -0
- siliconcompiler/tools/vivado/syn_fpga.py +20 -0
- siliconcompiler/tools/vivado/vivado.py +147 -0
- siliconcompiler/tools/vpr/_json_constraint.py +63 -0
- siliconcompiler/tools/vpr/_xml_constraint.py +109 -0
- siliconcompiler/tools/vpr/place.py +137 -0
- siliconcompiler/tools/vpr/route.py +124 -0
- siliconcompiler/tools/vpr/screenshot.py +54 -0
- siliconcompiler/tools/vpr/show.py +88 -0
- siliconcompiler/tools/vpr/vpr.py +357 -0
- siliconcompiler/tools/xyce/xyce.py +36 -0
- siliconcompiler/tools/yosys/lec.py +56 -0
- siliconcompiler/tools/yosys/prepareLib.py +59 -0
- siliconcompiler/tools/yosys/sc_lec.tcl +84 -0
- siliconcompiler/tools/yosys/sc_syn.tcl +79 -0
- siliconcompiler/tools/yosys/syn_asic.py +565 -0
- siliconcompiler/tools/yosys/syn_asic.tcl +377 -0
- siliconcompiler/tools/yosys/syn_asic_fpga_shared.tcl +31 -0
- siliconcompiler/tools/yosys/syn_fpga.py +146 -0
- siliconcompiler/tools/yosys/syn_fpga.tcl +233 -0
- siliconcompiler/tools/yosys/syn_strategies.tcl +81 -0
- siliconcompiler/tools/yosys/techmaps/lcu_kogge_stone.v +39 -0
- siliconcompiler/tools/yosys/templates/abc.const +2 -0
- siliconcompiler/tools/yosys/yosys.py +147 -0
- siliconcompiler/units.py +259 -0
- siliconcompiler/use.py +177 -0
- siliconcompiler/utils/__init__.py +423 -0
- siliconcompiler/utils/asic.py +158 -0
- siliconcompiler/utils/showtools.py +25 -0
- siliconcompiler-0.26.5.dist-info/LICENSE +190 -0
- siliconcompiler-0.26.5.dist-info/METADATA +195 -0
- siliconcompiler-0.26.5.dist-info/RECORD +251 -0
- siliconcompiler-0.26.5.dist-info/WHEEL +5 -0
- siliconcompiler-0.26.5.dist-info/entry_points.txt +12 -0
- siliconcompiler-0.26.5.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
# Copyright 2023 Silicon Compiler Authors. All Rights Reserved.
|
|
2
|
+
import copy
|
|
3
|
+
import os
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
from siliconcompiler import Chip
|
|
7
|
+
from siliconcompiler import SiliconCompilerError
|
|
8
|
+
from siliconcompiler.remote.client import cancel_job, check_progress, delete_job, \
|
|
9
|
+
remote_ping, remote_run_loop, _remote_ping
|
|
10
|
+
from siliconcompiler.remote.client import configure_server, configure_whitelist, configure_print
|
|
11
|
+
from siliconcompiler.scheduler import _finalize_run
|
|
12
|
+
from siliconcompiler.flowgraph import _get_flowgraph_entry_nodes, _get_flowgraph_node_outputs, \
|
|
13
|
+
nodes_to_execute
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def main():
|
|
17
|
+
progname = "sc-remote"
|
|
18
|
+
description = """
|
|
19
|
+
-----------------------------------------------------------
|
|
20
|
+
SC app that provides an entry point to common remote / server
|
|
21
|
+
interactions.
|
|
22
|
+
|
|
23
|
+
To generate a configuration file, use:
|
|
24
|
+
sc-remote -configure
|
|
25
|
+
|
|
26
|
+
or to specify a specific server and/or port:
|
|
27
|
+
sc-remote -configure -server https://example.com
|
|
28
|
+
sc-remote -configure -server https://example.com:1234
|
|
29
|
+
|
|
30
|
+
to add or remove directories from upload whitelist, these
|
|
31
|
+
also support globbing:
|
|
32
|
+
sc-remote -configure -add ./fine_to_upload
|
|
33
|
+
sc-remote -configure -remove ./no_longer_okay_to_upload
|
|
34
|
+
|
|
35
|
+
to display the full configuration of the credentials file
|
|
36
|
+
sc-remote -configure -list
|
|
37
|
+
|
|
38
|
+
To check an ongoing job's progress, use:
|
|
39
|
+
sc-remote -cfg <stepdir>/outputs/<design>.pkg.json
|
|
40
|
+
|
|
41
|
+
To cancel an ongoing job, use:
|
|
42
|
+
sc-remote -cancel -cfg <stepdir>/outputs/<design>.pkg.json
|
|
43
|
+
|
|
44
|
+
To reconnect an ongoing job, use:
|
|
45
|
+
sc-remote -reconnect -cfg <stepdir>/outputs/<design>.pkg.json
|
|
46
|
+
|
|
47
|
+
To delete a job, use:
|
|
48
|
+
sc-remote -delete -cfg <stepdir>/outputs/<design>.pkg.json
|
|
49
|
+
-----------------------------------------------------------
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
# Argument Parser
|
|
53
|
+
progname = 'sc-remote'
|
|
54
|
+
chip = Chip(progname)
|
|
55
|
+
switchlist = ['-cfg', '-credentials']
|
|
56
|
+
extra_args = {
|
|
57
|
+
'-configure': {'action': 'store_true',
|
|
58
|
+
'help': 'create configuration file for the remote',
|
|
59
|
+
'sc_print': False},
|
|
60
|
+
'-server': {'help': 'address of server for configure (only valid with -configure)',
|
|
61
|
+
'metavar': '<server>',
|
|
62
|
+
'sc_print': False},
|
|
63
|
+
'-add': {'help': 'path to add to the upload whitelist (only valid with -configure)',
|
|
64
|
+
'metavar': '<path>',
|
|
65
|
+
'nargs': '+',
|
|
66
|
+
'sc_print': False},
|
|
67
|
+
'-remove': {'help': 'path to remove from the upload whitelist (only valid with -configure)',
|
|
68
|
+
'metavar': '<path>',
|
|
69
|
+
'nargs': '+',
|
|
70
|
+
'sc_print': False},
|
|
71
|
+
'-list': {'help': 'print the current configuration (only valid with -configure)',
|
|
72
|
+
'action': 'store_true',
|
|
73
|
+
'sc_print': False},
|
|
74
|
+
'-reconnect': {'action': 'store_true',
|
|
75
|
+
'help': 'reconnect to a running job on the remote',
|
|
76
|
+
'sc_print': False},
|
|
77
|
+
'-cancel': {'action': 'store_true',
|
|
78
|
+
'help': 'cancel a running job on the remote',
|
|
79
|
+
'sc_print': False},
|
|
80
|
+
'-delete': {'action': 'store_true',
|
|
81
|
+
'help': 'delete a job on the remote',
|
|
82
|
+
'sc_print': False},
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
try:
|
|
86
|
+
args = chip.create_cmdline(progname,
|
|
87
|
+
switchlist=switchlist,
|
|
88
|
+
additional_args=extra_args,
|
|
89
|
+
description=description)
|
|
90
|
+
except Exception as e:
|
|
91
|
+
chip.logger.error(e)
|
|
92
|
+
return 1
|
|
93
|
+
|
|
94
|
+
# Sanity checks.
|
|
95
|
+
exclusive = ['configure', 'reconnect', 'cancel', 'delete']
|
|
96
|
+
cfg_only = ['reconnect', 'cancel', 'delete']
|
|
97
|
+
|
|
98
|
+
exclusive_count = sum([1 for arg in exclusive if args[arg]])
|
|
99
|
+
if exclusive_count > 1:
|
|
100
|
+
chip.logger.error(f'Error: {", ".join(["-"+e for e in exclusive])} are mutually exclusive')
|
|
101
|
+
return 1
|
|
102
|
+
chip_cfg = chip.get('option', 'cfg')
|
|
103
|
+
if chip_cfg and not any([args[arg] for arg in cfg_only]):
|
|
104
|
+
chip.logger.error(f'Error: -cfg is required for {", ".join(["-"+e for e in cfg_only])}')
|
|
105
|
+
if any([args[arg] for arg in cfg_only]) and args['server']:
|
|
106
|
+
chip.logger.error('Error: -server cannot be specified with '
|
|
107
|
+
f'{", ".join(["-"+e for e in cfg_only])}')
|
|
108
|
+
|
|
109
|
+
if args['configure']:
|
|
110
|
+
if args['list']:
|
|
111
|
+
configure_print(chip)
|
|
112
|
+
return 0
|
|
113
|
+
|
|
114
|
+
if not args['add'] and not args['remove']:
|
|
115
|
+
try:
|
|
116
|
+
configure_server(chip, server=args['server'])
|
|
117
|
+
except ValueError as e:
|
|
118
|
+
chip.logger.error(e)
|
|
119
|
+
return 1
|
|
120
|
+
else:
|
|
121
|
+
try:
|
|
122
|
+
configure_whitelist(chip, add=args['add'], remove=args['remove'])
|
|
123
|
+
except ValueError as e:
|
|
124
|
+
chip.logger.error(e)
|
|
125
|
+
return 1
|
|
126
|
+
|
|
127
|
+
return 0
|
|
128
|
+
|
|
129
|
+
# Main logic.
|
|
130
|
+
# If no job-related options are specified, fetch and report basic info.
|
|
131
|
+
# Create temporary Chip object and check on the server.
|
|
132
|
+
try:
|
|
133
|
+
remote_ping(chip)
|
|
134
|
+
except SiliconCompilerError as e:
|
|
135
|
+
chip.logger.error(f'{e}')
|
|
136
|
+
return 1
|
|
137
|
+
|
|
138
|
+
# If the -cancel flag is specified, cancel the job.
|
|
139
|
+
if args['cancel']:
|
|
140
|
+
try:
|
|
141
|
+
cancel_job(chip)
|
|
142
|
+
except SiliconCompilerError as e:
|
|
143
|
+
chip.logger.error(f'{e}')
|
|
144
|
+
return 1
|
|
145
|
+
|
|
146
|
+
# If the -delete flag is specified, delete the job.
|
|
147
|
+
elif args['delete']:
|
|
148
|
+
try:
|
|
149
|
+
delete_job(chip)
|
|
150
|
+
except SiliconCompilerError as e:
|
|
151
|
+
chip.logger.error(f'{e}')
|
|
152
|
+
return 1
|
|
153
|
+
|
|
154
|
+
# If the -reconnect flag is specified, re-enter the client flow
|
|
155
|
+
# in its "check_progress/ until job is done" loop.
|
|
156
|
+
elif args['reconnect']:
|
|
157
|
+
# Start from successors of entry nodes, so entry nodes are not fetched from remote.
|
|
158
|
+
environment = copy.deepcopy(os.environ)
|
|
159
|
+
flow = chip.get('option', 'flow')
|
|
160
|
+
entry_nodes = _get_flowgraph_entry_nodes(chip, flow)
|
|
161
|
+
for entry_node in entry_nodes:
|
|
162
|
+
outputs = _get_flowgraph_node_outputs(chip, flow, entry_node)
|
|
163
|
+
chip.set('option', 'from', list(map(lambda node: node[0], outputs)))
|
|
164
|
+
# Enter the remote run loop.
|
|
165
|
+
chip._init_logger(step='remote', index='0', in_run=True)
|
|
166
|
+
try:
|
|
167
|
+
rsp = _remote_ping(chip)
|
|
168
|
+
remote_run_loop(chip, rsp['progress_interval'])
|
|
169
|
+
except SiliconCompilerError as e:
|
|
170
|
+
chip.logger.error(f'{e}')
|
|
171
|
+
return 1
|
|
172
|
+
|
|
173
|
+
# Wrap up run
|
|
174
|
+
for step, index in nodes_to_execute(chip):
|
|
175
|
+
manifest = os.path.join(chip.getworkdir(step=step, index=index),
|
|
176
|
+
'outputs',
|
|
177
|
+
f'{chip.design}.pkg.json')
|
|
178
|
+
if os.path.exists(manifest):
|
|
179
|
+
chip.schema.read_journal(manifest)
|
|
180
|
+
_finalize_run(chip, environment)
|
|
181
|
+
|
|
182
|
+
# Summarize the run.
|
|
183
|
+
chip.summary()
|
|
184
|
+
|
|
185
|
+
# If only a manifest is specified, make a 'check_progress/' request and report results:
|
|
186
|
+
elif chip_cfg:
|
|
187
|
+
try:
|
|
188
|
+
check_progress(chip)
|
|
189
|
+
except SiliconCompilerError as e:
|
|
190
|
+
chip.logger.error(f'{e}')
|
|
191
|
+
return 1
|
|
192
|
+
|
|
193
|
+
# Done
|
|
194
|
+
return 0
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
#########################
|
|
198
|
+
if __name__ == "__main__":
|
|
199
|
+
sys.exit(main())
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Copyright 2020 Silicon Compiler Authors. All Rights Reserved.
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
from siliconcompiler.remote.server import Server
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
###############################################
|
|
9
|
+
# Main method to run the sc-server application.
|
|
10
|
+
###############################################
|
|
11
|
+
def main():
|
|
12
|
+
progname = "sc-server"
|
|
13
|
+
description = """
|
|
14
|
+
-----------------------------------------------------------
|
|
15
|
+
Silicon Compiler Collection Remote Job Server (sc-server)
|
|
16
|
+
-----------------------------------------------------------
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
server = Server()
|
|
20
|
+
|
|
21
|
+
try:
|
|
22
|
+
server.create_cmdline(
|
|
23
|
+
progname,
|
|
24
|
+
description=description)
|
|
25
|
+
except ValueError as e:
|
|
26
|
+
server.logger.error(f'{e}')
|
|
27
|
+
return 1
|
|
28
|
+
|
|
29
|
+
try:
|
|
30
|
+
server.run()
|
|
31
|
+
except Exception as e:
|
|
32
|
+
server.logger.error(f'{e}')
|
|
33
|
+
return 1
|
|
34
|
+
|
|
35
|
+
return 0
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
if __name__ == '__main__':
|
|
39
|
+
sys.exit(main())
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Copyright 2020 Silicon Compiler Authors. All Rights Reserved.
|
|
2
|
+
import sys
|
|
3
|
+
import os
|
|
4
|
+
import siliconcompiler
|
|
5
|
+
from siliconcompiler.utils import get_default_iomap
|
|
6
|
+
from siliconcompiler.apps._common import load_manifest, manifest_switches
|
|
7
|
+
from siliconcompiler.utils import get_file_ext
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def main():
|
|
11
|
+
progname = "sc-show"
|
|
12
|
+
description = """
|
|
13
|
+
--------------------------------------------------------------
|
|
14
|
+
Restricted SC app that displays the layout of a design
|
|
15
|
+
based on a file provided or tries to display the final
|
|
16
|
+
layout based on loading the json manifest from:
|
|
17
|
+
build/<design>/job0/<design>.pkg.json
|
|
18
|
+
|
|
19
|
+
Examples:
|
|
20
|
+
|
|
21
|
+
sc-show -design adder
|
|
22
|
+
(displays build/adder/job0/write_gds/0/outputs/adder.gds)
|
|
23
|
+
|
|
24
|
+
sc-show -design adder -arg_step floorplan
|
|
25
|
+
(displays build/adder/job0/floorplan/0/outputs/adder.def)
|
|
26
|
+
|
|
27
|
+
sc-show -design adder -arg_step place -arg_index 1
|
|
28
|
+
(displays build/adder/job0/place/1/outputs/adder.def)
|
|
29
|
+
|
|
30
|
+
sc-show -design adder -jobname rtl2gds
|
|
31
|
+
(displays build/adder/rtl2gds/write_gds/0/outputs/adder.gds)
|
|
32
|
+
|
|
33
|
+
sc-show -cfg build/adder/rtl2gds/adder.pkg.json
|
|
34
|
+
(displays build/adder/rtl2gds/write_gds/0/outputs/adder.gds)
|
|
35
|
+
|
|
36
|
+
sc-show -design adder -ext odb
|
|
37
|
+
(displays build/adder/job0/write_data/0/outputs/adder.odb)
|
|
38
|
+
|
|
39
|
+
sc-show build/adder/job0/route/1/outputs/adder.def
|
|
40
|
+
(displays build/adder/job0/route/1/outputs/adder.def)
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
# TODO: this is a hack to get around design name requirement: since legal
|
|
44
|
+
# design names probably can't contain spaces, we can detect if it is unset.
|
|
45
|
+
UNSET_DESIGN = ' unset '
|
|
46
|
+
|
|
47
|
+
# Create a base chip class.
|
|
48
|
+
chip = siliconcompiler.Chip(UNSET_DESIGN)
|
|
49
|
+
|
|
50
|
+
# Fill input map with default mapping only for showable files
|
|
51
|
+
input_map = {}
|
|
52
|
+
default_input_map = get_default_iomap()
|
|
53
|
+
for ext in chip._showtools:
|
|
54
|
+
if ext in default_input_map:
|
|
55
|
+
input_map[ext] = default_input_map[ext]
|
|
56
|
+
|
|
57
|
+
extension_arg = {
|
|
58
|
+
'metavar': '<ext>',
|
|
59
|
+
'help': '(optional) Specify the extension of the file to show.',
|
|
60
|
+
'sc_print': False
|
|
61
|
+
}
|
|
62
|
+
screenshot_arg = {
|
|
63
|
+
'action': 'store_true',
|
|
64
|
+
'help': '(optional) Will generate a screenshot and exit.',
|
|
65
|
+
'sc_print': False
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
try:
|
|
69
|
+
args = chip.create_cmdline(
|
|
70
|
+
progname,
|
|
71
|
+
switchlist=[*manifest_switches(),
|
|
72
|
+
'-input',
|
|
73
|
+
'-loglevel'],
|
|
74
|
+
description=description,
|
|
75
|
+
input_map=input_map,
|
|
76
|
+
additional_args={
|
|
77
|
+
'-ext': extension_arg,
|
|
78
|
+
'-screenshot': screenshot_arg
|
|
79
|
+
})
|
|
80
|
+
except Exception as e:
|
|
81
|
+
chip.logger.error(e)
|
|
82
|
+
return 1
|
|
83
|
+
|
|
84
|
+
# Error checking
|
|
85
|
+
design = chip.get('design')
|
|
86
|
+
design_set = design != UNSET_DESIGN
|
|
87
|
+
|
|
88
|
+
# Search input keys for files
|
|
89
|
+
input_mode = []
|
|
90
|
+
for fileset in chip.getkeys('input'):
|
|
91
|
+
for mode in chip.getkeys('input', fileset):
|
|
92
|
+
if chip.schema._getvals('input', fileset, mode):
|
|
93
|
+
input_mode = [('input', fileset, mode)]
|
|
94
|
+
|
|
95
|
+
if not (design_set or input_mode):
|
|
96
|
+
chip.logger.error('Nothing to load: please define a target with '
|
|
97
|
+
'-cfg, -design, and/or inputs.')
|
|
98
|
+
return 1
|
|
99
|
+
|
|
100
|
+
filename = None
|
|
101
|
+
if input_mode:
|
|
102
|
+
check_ext = list(chip._showtools.keys())
|
|
103
|
+
|
|
104
|
+
if args['ext']:
|
|
105
|
+
check_ext = [args['ext']]
|
|
106
|
+
|
|
107
|
+
def get_file_from_keys():
|
|
108
|
+
for ext in check_ext:
|
|
109
|
+
for key in input_mode:
|
|
110
|
+
for files, _, _ in chip.schema._getvals(*key):
|
|
111
|
+
for file in files:
|
|
112
|
+
if get_file_ext(file) == ext:
|
|
113
|
+
return file
|
|
114
|
+
return None
|
|
115
|
+
|
|
116
|
+
filename = get_file_from_keys()
|
|
117
|
+
|
|
118
|
+
if not load_manifest(chip, filename):
|
|
119
|
+
return 1
|
|
120
|
+
|
|
121
|
+
# Read in file
|
|
122
|
+
if filename:
|
|
123
|
+
chip.logger.info(f"Displaying {filename}")
|
|
124
|
+
|
|
125
|
+
if not chip.find_files('option', 'builddir', missing_ok=True):
|
|
126
|
+
chip.logger.warning("Unable to access original build directory "
|
|
127
|
+
f"\"{chip.get('option', 'builddir')}\", using \"build\" instead")
|
|
128
|
+
chip.set('option', 'builddir', 'build')
|
|
129
|
+
|
|
130
|
+
success = chip.show(filename,
|
|
131
|
+
extension=args['ext'],
|
|
132
|
+
screenshot=args['screenshot'])
|
|
133
|
+
|
|
134
|
+
if args['screenshot'] and os.path.isfile(success):
|
|
135
|
+
chip.logger.info(f'Screenshot file: {success}')
|
|
136
|
+
|
|
137
|
+
return 0 if success else 1
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
#########################
|
|
141
|
+
if __name__ == "__main__":
|
|
142
|
+
sys.exit(main())
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# Copyright 2023 Silicon Compiler Authors. All Rights Reserved.
|
|
2
|
+
import argparse
|
|
3
|
+
import sys
|
|
4
|
+
import os
|
|
5
|
+
import importlib
|
|
6
|
+
from inspect import getmembers, isfunction, getfullargspec
|
|
7
|
+
from siliconcompiler._metadata import version
|
|
8
|
+
from siliconcompiler.schema import utils
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
__default_source_file = "make.py"
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def __process_file(path):
|
|
15
|
+
if not os.path.exists(path):
|
|
16
|
+
return {}, None, None
|
|
17
|
+
mod_name = 'scmake'
|
|
18
|
+
spec = importlib.util.spec_from_file_location(mod_name, path)
|
|
19
|
+
make = importlib.util.module_from_spec(spec)
|
|
20
|
+
sys.modules[mod_name] = make
|
|
21
|
+
syspath = sys.path.copy()
|
|
22
|
+
sys.path.insert(0, os.getcwd())
|
|
23
|
+
spec.loader.exec_module(make)
|
|
24
|
+
sys.path = syspath
|
|
25
|
+
|
|
26
|
+
args = {}
|
|
27
|
+
for name, func in getmembers(make, isfunction):
|
|
28
|
+
if name.startswith('_'):
|
|
29
|
+
continue
|
|
30
|
+
|
|
31
|
+
# generate doc
|
|
32
|
+
docstring = utils.trim(func.__doc__)
|
|
33
|
+
if not docstring:
|
|
34
|
+
docstring = f"run \"{name}\""
|
|
35
|
+
short_help = docstring.splitlines()[0]
|
|
36
|
+
|
|
37
|
+
func_spec = getfullargspec(func)
|
|
38
|
+
|
|
39
|
+
func_args = {}
|
|
40
|
+
for arg in func_spec.args:
|
|
41
|
+
arg_type = str
|
|
42
|
+
if arg in func_spec.annotations:
|
|
43
|
+
arg_type = func_spec.annotations[arg]
|
|
44
|
+
func_args[arg] = {
|
|
45
|
+
"type": arg_type
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if func_spec.defaults:
|
|
49
|
+
for arg, defval in zip(reversed(func_spec.args), reversed(func_spec.defaults)):
|
|
50
|
+
func_args[arg]["default"] = defval
|
|
51
|
+
|
|
52
|
+
if defval is None:
|
|
53
|
+
continue
|
|
54
|
+
|
|
55
|
+
if type(defval) is not func_args[arg]["type"]:
|
|
56
|
+
if isinstance(defval, (bool, str, float, int)):
|
|
57
|
+
func_args[arg]["type"] = type(defval)
|
|
58
|
+
|
|
59
|
+
args[name] = {
|
|
60
|
+
"function": func,
|
|
61
|
+
"help": short_help,
|
|
62
|
+
"full_help": docstring,
|
|
63
|
+
"args": func_args
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if args:
|
|
67
|
+
default_arg = list(args.keys())[0]
|
|
68
|
+
else:
|
|
69
|
+
default_arg = None
|
|
70
|
+
|
|
71
|
+
default_arg = getattr(make, '__scdefault', default_arg)
|
|
72
|
+
|
|
73
|
+
module_help = utils.trim(make.__doc__)
|
|
74
|
+
|
|
75
|
+
return args, default_arg, module_help
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def main(source_file=None):
|
|
79
|
+
progname = "smake"
|
|
80
|
+
description = f"""-----------------------------------------------------------
|
|
81
|
+
SC app that provides an Makefile like interface to python
|
|
82
|
+
configuration files. This utility app will analyze a file
|
|
83
|
+
"{__default_source_file}" or the file specified with --file to determine
|
|
84
|
+
the available targets.
|
|
85
|
+
|
|
86
|
+
To view the help, use:
|
|
87
|
+
smake --help
|
|
88
|
+
|
|
89
|
+
or view the help for a specific target:
|
|
90
|
+
smake --help <target>
|
|
91
|
+
|
|
92
|
+
To run a target, use:
|
|
93
|
+
smake <target>
|
|
94
|
+
|
|
95
|
+
or run a target from a file other than "{__default_source_file}":
|
|
96
|
+
smake --file <file> <target>
|
|
97
|
+
|
|
98
|
+
or run a target in a different directory:
|
|
99
|
+
smake --directory <directory> <target>
|
|
100
|
+
|
|
101
|
+
To run a target with supported arguments, use:
|
|
102
|
+
smake <target> --flow asicflow
|
|
103
|
+
-----------------------------------------------------------"""
|
|
104
|
+
|
|
105
|
+
# handle source file identification before arg parse
|
|
106
|
+
file_args = None
|
|
107
|
+
if not source_file:
|
|
108
|
+
source_file = __default_source_file
|
|
109
|
+
file_args = ('--file', '-f')
|
|
110
|
+
for file_arg in file_args:
|
|
111
|
+
if file_arg in sys.argv:
|
|
112
|
+
source_file_idx = sys.argv.index(file_arg) + 1
|
|
113
|
+
if source_file_idx < len(sys.argv):
|
|
114
|
+
source_file = sys.argv[source_file_idx]
|
|
115
|
+
else:
|
|
116
|
+
source_file = None
|
|
117
|
+
break
|
|
118
|
+
|
|
119
|
+
# handle directory identification before arg parse
|
|
120
|
+
source_dir = os.getcwd()
|
|
121
|
+
dir_args = ('--directory', '-C')
|
|
122
|
+
for file_arg in dir_args:
|
|
123
|
+
if file_arg in sys.argv:
|
|
124
|
+
source_dir_idx = sys.argv.index(file_arg) + 1
|
|
125
|
+
if source_dir_idx < len(sys.argv):
|
|
126
|
+
source_dir = sys.argv[source_dir_idx]
|
|
127
|
+
else:
|
|
128
|
+
source_dir = None
|
|
129
|
+
break
|
|
130
|
+
|
|
131
|
+
if source_dir:
|
|
132
|
+
if not os.path.isdir(source_dir):
|
|
133
|
+
print(f"Unable to change directory to {source_dir}")
|
|
134
|
+
return 1
|
|
135
|
+
|
|
136
|
+
os.chdir(source_dir)
|
|
137
|
+
|
|
138
|
+
make_args = {}
|
|
139
|
+
default_arg = None
|
|
140
|
+
module_help = None
|
|
141
|
+
if source_file:
|
|
142
|
+
make_args, default_arg, module_help = __process_file(source_file)
|
|
143
|
+
|
|
144
|
+
if module_help:
|
|
145
|
+
description += \
|
|
146
|
+
f"\n\n{module_help}\n\n-----------------------------------------------------------"
|
|
147
|
+
|
|
148
|
+
parser = argparse.ArgumentParser(
|
|
149
|
+
progname,
|
|
150
|
+
description=description,
|
|
151
|
+
formatter_class=argparse.RawDescriptionHelpFormatter)
|
|
152
|
+
|
|
153
|
+
if file_args:
|
|
154
|
+
parser.add_argument(
|
|
155
|
+
*file_args,
|
|
156
|
+
metavar='<file>',
|
|
157
|
+
help=f'Use file as makefile, default is {__default_source_file}')
|
|
158
|
+
|
|
159
|
+
parser.add_argument(
|
|
160
|
+
*dir_args,
|
|
161
|
+
metavar='<directory>',
|
|
162
|
+
help='Change to directory <directory> before reading the makefile.')
|
|
163
|
+
|
|
164
|
+
parser.add_argument(
|
|
165
|
+
'--version', '-v',
|
|
166
|
+
action='version',
|
|
167
|
+
version=version)
|
|
168
|
+
|
|
169
|
+
targetparsers = parser.add_subparsers(
|
|
170
|
+
dest='target',
|
|
171
|
+
metavar='<target>',
|
|
172
|
+
help='Target to execute')
|
|
173
|
+
|
|
174
|
+
for arg, info in make_args.items():
|
|
175
|
+
subparse = targetparsers.add_parser(
|
|
176
|
+
arg,
|
|
177
|
+
description=info['full_help'],
|
|
178
|
+
help=info['help'],
|
|
179
|
+
formatter_class=argparse.RawDescriptionHelpFormatter)
|
|
180
|
+
|
|
181
|
+
for subarg, subarg_info in info['args'].items():
|
|
182
|
+
# print(subarg, subarg_info)
|
|
183
|
+
add_args = {}
|
|
184
|
+
|
|
185
|
+
if "default" not in subarg_info:
|
|
186
|
+
add_args["required"] = True
|
|
187
|
+
else:
|
|
188
|
+
if type(subarg_info["default"]) is subarg_info["type"]:
|
|
189
|
+
add_args["default"] = subarg_info["default"]
|
|
190
|
+
|
|
191
|
+
if subarg_info["type"] is bool:
|
|
192
|
+
def str2bool(v):
|
|
193
|
+
# modified from:
|
|
194
|
+
# https://github.com/pypa/distutils/blob/8993718731b951ee36d08cb784f02aa13542ce15/distutils/util.py
|
|
195
|
+
val = v.lower()
|
|
196
|
+
if val in ('y', 'yes', 't', 'true', 'on', '1'):
|
|
197
|
+
return True
|
|
198
|
+
elif val in ('n', 'no', 'f', 'false', 'off', '0'):
|
|
199
|
+
return False
|
|
200
|
+
else:
|
|
201
|
+
raise ValueError(f"invalid truth value {val!r}")
|
|
202
|
+
subarg_info["type"] = str2bool
|
|
203
|
+
|
|
204
|
+
subparse.add_argument(
|
|
205
|
+
f'--{subarg}',
|
|
206
|
+
dest=f'sub_{subarg}',
|
|
207
|
+
metavar=f'<{subarg}>',
|
|
208
|
+
type=subarg_info["type"],
|
|
209
|
+
**add_args)
|
|
210
|
+
|
|
211
|
+
args = parser.parse_args()
|
|
212
|
+
target = args.target
|
|
213
|
+
if not target:
|
|
214
|
+
target = default_arg
|
|
215
|
+
|
|
216
|
+
if not os.path.isfile(source_file):
|
|
217
|
+
print(f"Unable to load {source_file}")
|
|
218
|
+
return 1
|
|
219
|
+
|
|
220
|
+
call_args = {}
|
|
221
|
+
args_vars = vars(args)
|
|
222
|
+
for arg in make_args[target]["args"]:
|
|
223
|
+
if f'sub_{arg}' in args_vars and args_vars[f'sub_{arg}'] is not None:
|
|
224
|
+
call_args[arg] = args_vars[f'sub_{arg}']
|
|
225
|
+
make_args[target]["function"](**call_args)
|
|
226
|
+
|
|
227
|
+
return 0
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
#########################
|
|
231
|
+
if __name__ == "__main__":
|
|
232
|
+
sys.exit(main())
|
|
File without changes
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import siliconcompiler
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def setup(chip):
|
|
5
|
+
'''Subset of OH! library tapeout checklist.
|
|
6
|
+
|
|
7
|
+
https://github.com/aolofsson/oh/blob/master/docs/tapeout_checklist.md
|
|
8
|
+
'''
|
|
9
|
+
standard = 'oh_tapeout'
|
|
10
|
+
|
|
11
|
+
checklist = siliconcompiler.Checklist(chip, standard)
|
|
12
|
+
|
|
13
|
+
# Automated
|
|
14
|
+
checklist.set('checklist', standard, 'drc_clean', 'description',
|
|
15
|
+
'Is block DRC clean?')
|
|
16
|
+
checklist.set('checklist', standard, 'drc_clean', 'criteria', 'drcs==0')
|
|
17
|
+
|
|
18
|
+
checklist.set('checklist', standard, 'lvs_clean', 'description',
|
|
19
|
+
'Is block LVS clean?')
|
|
20
|
+
checklist.set('checklist', standard, 'lvs_clean', 'criteria', 'drcs==0')
|
|
21
|
+
|
|
22
|
+
checklist.set('checklist', standard, 'setup_time', 'description',
|
|
23
|
+
'Setup time met?')
|
|
24
|
+
checklist.set('checklist', standard, 'setup_time', 'criteria', 'setupslack>=0')
|
|
25
|
+
|
|
26
|
+
checklist.set('checklist', standard, 'errors_warnings', 'description',
|
|
27
|
+
'Are all EDA warnings/errors acceptable?')
|
|
28
|
+
checklist.set('checklist', standard, 'errors_warnings', 'criteria',
|
|
29
|
+
['errors==0', 'warnings==0'])
|
|
30
|
+
|
|
31
|
+
# Manual
|
|
32
|
+
checklist.set('checklist', standard, 'spec', 'description',
|
|
33
|
+
'Is there a written specification?')
|
|
34
|
+
|
|
35
|
+
return checklist
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
##################################################
|
|
39
|
+
if __name__ == "__main__":
|
|
40
|
+
checklist = setup(siliconcompiler.Chip('<checklist>'))
|
|
41
|
+
checklist.write_manifest(f"{checklist.top()}.json")
|