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,59 @@
|
|
|
1
|
+
import siliconcompiler
|
|
2
|
+
from siliconcompiler import SiliconCompilerError
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
############################################################################
|
|
6
|
+
# DOCS
|
|
7
|
+
############################################################################
|
|
8
|
+
def make_docs(chip):
|
|
9
|
+
chip.load_target('freepdk45_demo')
|
|
10
|
+
return setup(chip, filetype='gds', np=3)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
###########################################################################
|
|
14
|
+
# Flowgraph Setup
|
|
15
|
+
############################################################################
|
|
16
|
+
def setup(chip, flowname='showflow', filetype=None, screenshot=False, np=1):
|
|
17
|
+
'''
|
|
18
|
+
A flow to show the output files generated from other flows.
|
|
19
|
+
|
|
20
|
+
Required settings for this flow are below:
|
|
21
|
+
|
|
22
|
+
* filetype : Type of file to show
|
|
23
|
+
|
|
24
|
+
Optional settings for this flow are below:
|
|
25
|
+
|
|
26
|
+
* np : Number of parallel show jobs to launch
|
|
27
|
+
* screenshot : true/false, indicate if this should be configured as a screenshot
|
|
28
|
+
'''
|
|
29
|
+
|
|
30
|
+
flow = siliconcompiler.Flow(chip, flowname)
|
|
31
|
+
|
|
32
|
+
# Get required parameters first
|
|
33
|
+
if not filetype:
|
|
34
|
+
raise ValueError('filetype is a required argument')
|
|
35
|
+
|
|
36
|
+
if filetype not in chip._showtools:
|
|
37
|
+
raise SiliconCompilerError(f'Show tool for {filetype} is not defined.')
|
|
38
|
+
|
|
39
|
+
show_tool = chip._showtools[filetype]
|
|
40
|
+
|
|
41
|
+
stepname = 'show'
|
|
42
|
+
if screenshot:
|
|
43
|
+
stepname = 'screenshot'
|
|
44
|
+
|
|
45
|
+
if stepname not in show_tool:
|
|
46
|
+
raise SiliconCompilerError(f'{stepname} for {filetype} is not defined.')
|
|
47
|
+
|
|
48
|
+
for idx in range(np):
|
|
49
|
+
flow.node(flowname, stepname, show_tool[stepname], index=idx)
|
|
50
|
+
|
|
51
|
+
return flow
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
##################################################
|
|
55
|
+
if __name__ == "__main__":
|
|
56
|
+
chip = siliconcompiler.Chip('design')
|
|
57
|
+
flow = make_docs(chip)
|
|
58
|
+
chip.use(flow)
|
|
59
|
+
chip.write_flowgraph(f"{flow.top()}.png", flow=flow.top())
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import siliconcompiler
|
|
2
|
+
|
|
3
|
+
from siliconcompiler.tools.magic import extspice
|
|
4
|
+
from siliconcompiler.tools.magic import drc
|
|
5
|
+
from siliconcompiler.tools.netgen import lvs
|
|
6
|
+
from siliconcompiler.tools.builtin import nop
|
|
7
|
+
from siliconcompiler.tools.builtin import join
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def make_docs(chip):
|
|
11
|
+
chip.set('input', 'netlist', 'verilog', 'test')
|
|
12
|
+
return setup(chip)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def setup(chip):
|
|
16
|
+
'''A flow for running LVS/DRC signoff on a GDS layout.
|
|
17
|
+
|
|
18
|
+
Inputs must be passed to this flow as follows::
|
|
19
|
+
|
|
20
|
+
flow.input('<path-to-layout>.gds')
|
|
21
|
+
flow.input('<path-to-netlist>.vg')
|
|
22
|
+
'''
|
|
23
|
+
flowname = 'signoffflow'
|
|
24
|
+
|
|
25
|
+
flow = siliconcompiler.Flow(chip, flowname)
|
|
26
|
+
|
|
27
|
+
# nop import since we don't need to pull in any sources
|
|
28
|
+
flow.node(flowname, 'import', nop)
|
|
29
|
+
|
|
30
|
+
flow.node(flowname, 'extspice', extspice)
|
|
31
|
+
flow.node(flowname, 'drc', drc)
|
|
32
|
+
flow.node(flowname, 'lvs', lvs)
|
|
33
|
+
flow.node(flowname, 'signoff', join)
|
|
34
|
+
|
|
35
|
+
flow.edge(flowname, 'import', 'drc')
|
|
36
|
+
flow.edge(flowname, 'import', 'extspice')
|
|
37
|
+
flow.edge(flowname, 'extspice', 'lvs')
|
|
38
|
+
flow.edge(flowname, 'lvs', 'signoff')
|
|
39
|
+
flow.edge(flowname, 'drc', 'signoff')
|
|
40
|
+
|
|
41
|
+
# Set default goal
|
|
42
|
+
for step in flow.getkeys('flowgraph', flowname):
|
|
43
|
+
flow.set('flowgraph', flowname, step, '0', 'goal', 'errors', 0)
|
|
44
|
+
|
|
45
|
+
return flow
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
##################################################
|
|
49
|
+
if __name__ == "__main__":
|
|
50
|
+
chip = siliconcompiler.Chip('design')
|
|
51
|
+
flow = make_docs(chip)
|
|
52
|
+
chip.use(flow)
|
|
53
|
+
chip.write_flowgraph(f"{flow.top()}.png", flow=flow.top())
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import siliconcompiler
|
|
2
|
+
|
|
3
|
+
from siliconcompiler.flows._common import setup_multiple_frontends
|
|
4
|
+
from siliconcompiler.flows._common import _make_docs
|
|
5
|
+
|
|
6
|
+
from siliconcompiler.tools.yosys import syn_asic
|
|
7
|
+
from siliconcompiler.tools.opensta import timing
|
|
8
|
+
|
|
9
|
+
from siliconcompiler.tools.builtin import minimum
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
############################################################################
|
|
13
|
+
# DOCS
|
|
14
|
+
############################################################################
|
|
15
|
+
def make_docs(chip):
|
|
16
|
+
n = 3
|
|
17
|
+
_make_docs(chip)
|
|
18
|
+
return setup(chip, syn_np=n, timing_np=n)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
###########################################################################
|
|
22
|
+
# Flowgraph Setup
|
|
23
|
+
############################################################################
|
|
24
|
+
def setup(chip,
|
|
25
|
+
flowname='synflow',
|
|
26
|
+
syn_np=1,
|
|
27
|
+
timing_np=1):
|
|
28
|
+
'''
|
|
29
|
+
A configurable ASIC synthesys flow with static timing.
|
|
30
|
+
|
|
31
|
+
The 'synflow' includes the stages below. The steps syn have
|
|
32
|
+
minimization associated with them.
|
|
33
|
+
To view the flowgraph, see the .png file.
|
|
34
|
+
|
|
35
|
+
* **import**: Sources are collected and packaged for compilation
|
|
36
|
+
* **syn**: Translates RTL to netlist using Yosys
|
|
37
|
+
* **timing**: Create timing reports of design
|
|
38
|
+
|
|
39
|
+
The syn and timing steps supports per process
|
|
40
|
+
options that can be set up by setting 'syn_np' or 'timing_np'
|
|
41
|
+
arg to a value > 1, as detailed below:
|
|
42
|
+
|
|
43
|
+
* syn_np : Number of parallel synthesis jobs to launch
|
|
44
|
+
* timing_np : Number of parallel timing jobs to launch
|
|
45
|
+
'''
|
|
46
|
+
|
|
47
|
+
flow = siliconcompiler.Flow(chip, flowname)
|
|
48
|
+
|
|
49
|
+
# Linear flow, up until branch to run parallel verification steps.
|
|
50
|
+
longpipe = ['syn',
|
|
51
|
+
'synmin',
|
|
52
|
+
'timing']
|
|
53
|
+
|
|
54
|
+
# step --> task
|
|
55
|
+
tasks = {
|
|
56
|
+
'syn': syn_asic,
|
|
57
|
+
'synmin': minimum,
|
|
58
|
+
'timing': timing
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
np = {
|
|
62
|
+
"syn": syn_np,
|
|
63
|
+
"timing": timing_np
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
prevstep = None
|
|
67
|
+
# Remove built in steps where appropriate
|
|
68
|
+
flowpipe = []
|
|
69
|
+
for step in longpipe:
|
|
70
|
+
task = tasks[step]
|
|
71
|
+
if task == minimum:
|
|
72
|
+
if prevstep in np and np[prevstep] > 1:
|
|
73
|
+
flowpipe.append(step)
|
|
74
|
+
else:
|
|
75
|
+
flowpipe.append(step)
|
|
76
|
+
prevstep = step
|
|
77
|
+
|
|
78
|
+
flowtasks = []
|
|
79
|
+
for step in flowpipe:
|
|
80
|
+
flowtasks.append((step, tasks[step]))
|
|
81
|
+
|
|
82
|
+
# Programmatically build linear portion of flowgraph and fanin/fanout args
|
|
83
|
+
prevstep = setup_multiple_frontends(chip, flow)
|
|
84
|
+
for step, task in flowtasks:
|
|
85
|
+
fanout = 1
|
|
86
|
+
if step in np:
|
|
87
|
+
fanout = np[step]
|
|
88
|
+
# create nodes
|
|
89
|
+
for index in range(fanout):
|
|
90
|
+
# nodes
|
|
91
|
+
flow.node(flowname, step, task, index=index)
|
|
92
|
+
|
|
93
|
+
# edges
|
|
94
|
+
if task == minimum:
|
|
95
|
+
fanin = 1
|
|
96
|
+
if prevstep in np:
|
|
97
|
+
fanin = np[prevstep]
|
|
98
|
+
for i in range(fanin):
|
|
99
|
+
flow.edge(flowname, prevstep, step, tail_index=i)
|
|
100
|
+
elif prevstep:
|
|
101
|
+
flow.edge(flowname, prevstep, step, head_index=index)
|
|
102
|
+
|
|
103
|
+
# metrics
|
|
104
|
+
goal_metrics = ()
|
|
105
|
+
weight_metrics = ()
|
|
106
|
+
if task in (syn_asic, ):
|
|
107
|
+
goal_metrics = ('errors',)
|
|
108
|
+
weight_metrics = ()
|
|
109
|
+
elif task in (timing, ):
|
|
110
|
+
goal_metrics = ('errors', 'setupwns', 'setuptns')
|
|
111
|
+
weight_metrics = ('cellarea', 'peakpower', 'leakagepower')
|
|
112
|
+
|
|
113
|
+
for metric in goal_metrics:
|
|
114
|
+
flow.set('flowgraph', flowname, step, str(index), 'goal', metric, 0)
|
|
115
|
+
for metric in weight_metrics:
|
|
116
|
+
flow.set('flowgraph', flowname, step, str(index), 'weight', metric, 1.0)
|
|
117
|
+
prevstep = step
|
|
118
|
+
|
|
119
|
+
return flow
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
##################################################
|
|
123
|
+
if __name__ == "__main__":
|
|
124
|
+
chip = siliconcompiler.Chip('design')
|
|
125
|
+
chip.set('input', 'constraint', 'sdc', 'test')
|
|
126
|
+
flow = make_docs(chip)
|
|
127
|
+
chip.use(flow)
|
|
128
|
+
chip.write_flowgraph(f"{flow.top()}.png", flow=flow.top())
|
|
File without changes
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import siliconcompiler
|
|
2
|
+
from siliconcompiler.utils import register_sc_data_source
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
####################################################
|
|
6
|
+
# Setup for ICE40 Family FPGAs
|
|
7
|
+
####################################################
|
|
8
|
+
def setup(chip):
|
|
9
|
+
'''
|
|
10
|
+
Lattice ICE40 FPGAs are a family of small parts
|
|
11
|
+
made by Lattice Semiconductor. A fully open source
|
|
12
|
+
RTL to bitstream flow for ICE40 is available using
|
|
13
|
+
yosys + nextpnr
|
|
14
|
+
'''
|
|
15
|
+
|
|
16
|
+
vendor = 'lattice'
|
|
17
|
+
|
|
18
|
+
lut_size = '4'
|
|
19
|
+
|
|
20
|
+
all_fpgas = []
|
|
21
|
+
|
|
22
|
+
all_part_names = [
|
|
23
|
+
"ice40up5k-sg48",
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
register_sc_data_source(chip)
|
|
27
|
+
|
|
28
|
+
for part_name in all_part_names:
|
|
29
|
+
fpga = siliconcompiler.FPGA(chip, part_name, package='siliconcompiler_data')
|
|
30
|
+
|
|
31
|
+
fpga.set('fpga', part_name, 'vendor', vendor)
|
|
32
|
+
fpga.set('fpga', part_name, 'lutsize', lut_size)
|
|
33
|
+
|
|
34
|
+
all_fpgas.append(fpga)
|
|
35
|
+
|
|
36
|
+
return all_fpgas
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
#########################
|
|
40
|
+
if __name__ == "__main__":
|
|
41
|
+
for fpga in setup(siliconcompiler.Chip('<fpga>')):
|
|
42
|
+
fpga.write_manifest(f'{fpga.design}.json')
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import siliconcompiler
|
|
3
|
+
from siliconcompiler.utils import register_sc_data_source
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
####################################################
|
|
7
|
+
# Setup for vpr_example Family FPGAs
|
|
8
|
+
####################################################
|
|
9
|
+
def setup(chip):
|
|
10
|
+
'''
|
|
11
|
+
The vpr_example FPGA family is a set of
|
|
12
|
+
open source architectures used as illustrative
|
|
13
|
+
examples for academic FPGA architectures. They
|
|
14
|
+
are based on numerous examples furnished over the
|
|
15
|
+
the years by the University of Toronto with different
|
|
16
|
+
distributions of VPR
|
|
17
|
+
|
|
18
|
+
For more information about VPR and its architecture models,
|
|
19
|
+
see Murray et. al, "VTR 8: High Performance CAD and Customizable
|
|
20
|
+
FPGA Architecture Modelling", ACM Trans. Reconfigurable Technol.
|
|
21
|
+
Syst., 2020, https://www.eecg.utoronto.ca/~kmurray/vtr/vtr8_trets.pdf
|
|
22
|
+
'''
|
|
23
|
+
|
|
24
|
+
vendor = 'N/A'
|
|
25
|
+
|
|
26
|
+
flow_root = os.path.join('examples', 'fpga_flow')
|
|
27
|
+
|
|
28
|
+
lut_size = '4'
|
|
29
|
+
|
|
30
|
+
all_fpgas = []
|
|
31
|
+
|
|
32
|
+
all_part_names = [
|
|
33
|
+
'example_arch_X005Y005',
|
|
34
|
+
'example_arch_X008Y008',
|
|
35
|
+
'example_arch_X014Y014',
|
|
36
|
+
'example_arch_X030Y030',
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
register_sc_data_source(chip)
|
|
40
|
+
|
|
41
|
+
# Settings common to all parts in family
|
|
42
|
+
for part_name in all_part_names:
|
|
43
|
+
fpga = siliconcompiler.FPGA(chip, part_name, package='siliconcompiler_data')
|
|
44
|
+
|
|
45
|
+
fpga.set('fpga', part_name, 'vendor', vendor)
|
|
46
|
+
|
|
47
|
+
fpga.set('fpga', part_name, 'lutsize', lut_size)
|
|
48
|
+
|
|
49
|
+
arch_root = os.path.join(flow_root, 'arch', part_name)
|
|
50
|
+
fpga.set('fpga', part_name, 'file', 'archfile', os.path.join(arch_root, f'{part_name}.xml'))
|
|
51
|
+
|
|
52
|
+
fpga.set('fpga', part_name, 'var', 'vpr_clock_model', 'ideal')
|
|
53
|
+
|
|
54
|
+
if (part_name == 'example_arch_X005Y005'):
|
|
55
|
+
arch_root = os.path.join(flow_root, 'arch', part_name)
|
|
56
|
+
fpga.set('fpga', part_name, 'file', 'graphfile',
|
|
57
|
+
os.path.join(arch_root, 'example_arch_X005Y005_rr_graph.xml'))
|
|
58
|
+
fpga.set('fpga', part_name, 'var', 'channelwidth', '32')
|
|
59
|
+
|
|
60
|
+
if (part_name == 'example_arch_X008Y008'):
|
|
61
|
+
# No RR graph for this architecture to support testing
|
|
62
|
+
fpga.set('fpga', part_name, 'var', 'channelwidth', '32')
|
|
63
|
+
|
|
64
|
+
if ((part_name == 'example_arch_X014Y014') or (part_name == 'example_arch_X030Y030')):
|
|
65
|
+
|
|
66
|
+
techlib_root = os.path.join(flow_root, 'techlib')
|
|
67
|
+
|
|
68
|
+
if (part_name == 'example_arch_X014Y014'):
|
|
69
|
+
fpga.set('fpga', part_name, 'file', 'constraints_map',
|
|
70
|
+
os.path.join(arch_root, f'{part_name}_constraint_map.json'))
|
|
71
|
+
|
|
72
|
+
fpga.set('fpga', part_name, 'var', 'channelwidth', '80')
|
|
73
|
+
fpga.add('fpga', part_name, 'var', 'feature_set', 'async_set')
|
|
74
|
+
fpga.add('fpga', part_name, 'var', 'feature_set', 'async_reset')
|
|
75
|
+
fpga.add('fpga', part_name, 'var', 'feature_set', 'enable')
|
|
76
|
+
fpga.add('fpga', part_name, 'file', 'yosys_flop_techmap',
|
|
77
|
+
os.path.join(techlib_root, 'example_arch_techmap_flops.v'))
|
|
78
|
+
|
|
79
|
+
fpga.add('fpga', part_name, 'file', 'yosys_dsp_techmap',
|
|
80
|
+
os.path.join(techlib_root, 'example_arch_techmap_dsp.v'))
|
|
81
|
+
|
|
82
|
+
fpga.add('fpga', part_name, 'file', 'yosys_extractlib',
|
|
83
|
+
os.path.join(techlib_root, 'example_arch_techmap_dsp_extract.v'))
|
|
84
|
+
|
|
85
|
+
# The same library used for the extraction pass can also be used to
|
|
86
|
+
# define macros that can be passed through synthesis, specify that here
|
|
87
|
+
fpga.add('fpga', part_name, 'file', 'yosys_macrolib',
|
|
88
|
+
os.path.join(techlib_root, 'example_arch_techmap_dsp_extract.v'))
|
|
89
|
+
|
|
90
|
+
fpga.add('fpga', part_name, 'var', 'yosys_dsp_options', 'DSP_A_MAXWIDTH=18')
|
|
91
|
+
fpga.add('fpga', part_name, 'var', 'yosys_dsp_options', 'DSP_B_MAXWIDTH=18')
|
|
92
|
+
fpga.add('fpga', part_name, 'var', 'yosys_dsp_options', 'DSP_A_MINWIDTH=2')
|
|
93
|
+
fpga.add('fpga', part_name, 'var', 'yosys_dsp_options', 'DSP_B_MINWIDTH=2')
|
|
94
|
+
fpga.add('fpga', part_name, 'var', 'yosys_dsp_options', 'DSP_NAME=_dsp_block_')
|
|
95
|
+
|
|
96
|
+
fpga.add('fpga', part_name, 'file', 'yosys_memory_techmap',
|
|
97
|
+
os.path.join(techlib_root, 'example_arch_techmap_bram.v'))
|
|
98
|
+
fpga.add('fpga', part_name, 'file', 'yosys_memory_libmap',
|
|
99
|
+
os.path.join(techlib_root, 'example_arch_bram_memory_map.txt'))
|
|
100
|
+
|
|
101
|
+
all_fpgas.append(fpga)
|
|
102
|
+
|
|
103
|
+
return all_fpgas
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
#########################
|
|
107
|
+
if __name__ == "__main__":
|
|
108
|
+
for fpga in setup(siliconcompiler.Chip('<fpga>')):
|
|
109
|
+
fpga.write_manifest(f'{fpga.design}.json')
|
siliconcompiler/issue.py
ADDED
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
import git
|
|
2
|
+
import json
|
|
3
|
+
import os
|
|
4
|
+
import shutil
|
|
5
|
+
import sys
|
|
6
|
+
import tarfile
|
|
7
|
+
import time
|
|
8
|
+
import tempfile
|
|
9
|
+
from datetime import datetime
|
|
10
|
+
from siliconcompiler.utils import get_file_template
|
|
11
|
+
from siliconcompiler.scheduler import _makecmd, _write_task_manifest, _get_machine_info
|
|
12
|
+
from siliconcompiler.tools._common import get_tool_task
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def generate_testcase(chip,
|
|
16
|
+
step,
|
|
17
|
+
index,
|
|
18
|
+
archive_name=None,
|
|
19
|
+
archive_directory=None,
|
|
20
|
+
include_pdks=True,
|
|
21
|
+
include_specific_pdks=None,
|
|
22
|
+
include_libraries=True,
|
|
23
|
+
include_specific_libraries=None,
|
|
24
|
+
hash_files=False,
|
|
25
|
+
verbose_collect=True):
|
|
26
|
+
|
|
27
|
+
# Save original schema since it will be modified
|
|
28
|
+
schema_copy = chip.schema.copy()
|
|
29
|
+
|
|
30
|
+
issue_dir = tempfile.TemporaryDirectory(prefix='sc_issue_')
|
|
31
|
+
|
|
32
|
+
chip.set('option', 'continue', True)
|
|
33
|
+
if hash_files:
|
|
34
|
+
for key in chip.allkeys():
|
|
35
|
+
if key[0] == 'history':
|
|
36
|
+
continue
|
|
37
|
+
if len(key) > 1:
|
|
38
|
+
if key[-2] == 'option' and key[-1] == 'builddir':
|
|
39
|
+
continue
|
|
40
|
+
if key[-2] == 'option' and key[-1] == 'cachedir':
|
|
41
|
+
continue
|
|
42
|
+
sc_type = chip.get(*key, field='type')
|
|
43
|
+
if 'file' not in sc_type and 'dir' not in sc_type:
|
|
44
|
+
continue
|
|
45
|
+
for _, key_step, key_index in chip.schema._getvals(*key):
|
|
46
|
+
chip.hash_files(*key,
|
|
47
|
+
check=False,
|
|
48
|
+
allow_cache=True,
|
|
49
|
+
verbose=False,
|
|
50
|
+
skip_missing=True,
|
|
51
|
+
step=key_step, index=key_index)
|
|
52
|
+
|
|
53
|
+
manifest_path = os.path.join(issue_dir.name, 'orig_manifest.json')
|
|
54
|
+
chip.write_manifest(manifest_path)
|
|
55
|
+
|
|
56
|
+
flow = chip.get('option', 'flow')
|
|
57
|
+
tool, task = get_tool_task(chip, step, index, flow=flow)
|
|
58
|
+
task_requires = chip.get('tool', tool, 'task', task, 'require',
|
|
59
|
+
step=step, index=index)
|
|
60
|
+
|
|
61
|
+
def determine_copy(*keypath, in_require):
|
|
62
|
+
copy = in_require
|
|
63
|
+
|
|
64
|
+
if keypath[0] == 'library':
|
|
65
|
+
# only copy libraries if selected
|
|
66
|
+
if include_specific_libraries and keypath[1] in include_specific_libraries:
|
|
67
|
+
copy = True
|
|
68
|
+
else:
|
|
69
|
+
copy = include_libraries
|
|
70
|
+
|
|
71
|
+
copy = copy and determine_copy(*keypath[2:], in_require=in_require)
|
|
72
|
+
elif keypath[0] == 'pdk':
|
|
73
|
+
# only copy pdks if selected
|
|
74
|
+
if include_specific_pdks and keypath[1] in include_specific_pdks:
|
|
75
|
+
copy = True
|
|
76
|
+
else:
|
|
77
|
+
copy = include_pdks
|
|
78
|
+
elif keypath[0] == 'history':
|
|
79
|
+
# Skip history
|
|
80
|
+
copy = False
|
|
81
|
+
elif keypath[0] == 'package':
|
|
82
|
+
# Skip packages
|
|
83
|
+
copy = False
|
|
84
|
+
elif keypath[0] == 'tool':
|
|
85
|
+
# Only grab tool / tasks
|
|
86
|
+
copy = False
|
|
87
|
+
if list(keypath[0:4]) == ['tool', tool, 'task', task]:
|
|
88
|
+
# Get files associated with testcase tool / task
|
|
89
|
+
copy = True
|
|
90
|
+
if len(keypath) >= 5:
|
|
91
|
+
if keypath[4] in ('output', 'input', 'report'):
|
|
92
|
+
# Skip input, output, and report files
|
|
93
|
+
copy = False
|
|
94
|
+
elif keypath[0] == 'option':
|
|
95
|
+
if keypath[1] == 'builddir':
|
|
96
|
+
# Avoid build directory
|
|
97
|
+
copy = False
|
|
98
|
+
elif keypath[1] == 'cachedir':
|
|
99
|
+
# Avoid cache directory
|
|
100
|
+
copy = False
|
|
101
|
+
elif keypath[1] == 'cfg':
|
|
102
|
+
# Avoid all of cfg, since we are getting the manifest separately
|
|
103
|
+
copy = False
|
|
104
|
+
elif keypath[1] == 'credentials':
|
|
105
|
+
# Exclude credentials file
|
|
106
|
+
copy = False
|
|
107
|
+
|
|
108
|
+
return copy
|
|
109
|
+
|
|
110
|
+
for keypath in chip.allkeys():
|
|
111
|
+
if 'default' in keypath:
|
|
112
|
+
continue
|
|
113
|
+
|
|
114
|
+
sctype = chip.get(*keypath, field='type')
|
|
115
|
+
if 'file' not in sctype and 'dir' not in sctype:
|
|
116
|
+
continue
|
|
117
|
+
|
|
118
|
+
chip.set(*keypath,
|
|
119
|
+
determine_copy(*keypath,
|
|
120
|
+
in_require=','.join(keypath) in task_requires),
|
|
121
|
+
field='copy')
|
|
122
|
+
|
|
123
|
+
# Collect files
|
|
124
|
+
work_dir = chip.getworkdir(step=step, index=index)
|
|
125
|
+
|
|
126
|
+
builddir = chip.get('option', 'builddir')
|
|
127
|
+
if os.path.isabs(builddir):
|
|
128
|
+
# If build is an abs path, grab last directory
|
|
129
|
+
chip.set('option', 'builddir', os.path.basename(builddir))
|
|
130
|
+
|
|
131
|
+
# Temporarily change current directory to appear to be issue_dir
|
|
132
|
+
original_cwd = chip.cwd
|
|
133
|
+
chip.cwd = issue_dir.name
|
|
134
|
+
|
|
135
|
+
# Get new directories
|
|
136
|
+
job_dir = chip.getworkdir()
|
|
137
|
+
new_work_dir = chip.getworkdir(step=step, index=index)
|
|
138
|
+
collection_dir = chip._getcollectdir()
|
|
139
|
+
|
|
140
|
+
# Restore current directory
|
|
141
|
+
chip.cwd = original_cwd
|
|
142
|
+
|
|
143
|
+
# Copy in issue run files
|
|
144
|
+
shutil.copytree(work_dir, new_work_dir, dirs_exist_ok=True)
|
|
145
|
+
# Copy in source files
|
|
146
|
+
chip.collect(directory=collection_dir, verbose=verbose_collect)
|
|
147
|
+
|
|
148
|
+
# Set relative path to generate runnable files
|
|
149
|
+
chip._relative_path = new_work_dir
|
|
150
|
+
chip.cwd = issue_dir.name
|
|
151
|
+
|
|
152
|
+
current_work_dir = os.getcwd()
|
|
153
|
+
os.chdir(new_work_dir)
|
|
154
|
+
|
|
155
|
+
# Rewrite replay.sh
|
|
156
|
+
prev_quiet = chip.get('option', 'quiet', step=step, index=index)
|
|
157
|
+
chip.set('option', 'quiet', True, step=step, index=index)
|
|
158
|
+
from siliconcompiler import SiliconCompilerError
|
|
159
|
+
try:
|
|
160
|
+
# Rerun setup
|
|
161
|
+
chip.set('arg', 'step', step)
|
|
162
|
+
chip.set('arg', 'index', index)
|
|
163
|
+
func = getattr(chip._get_task_module(step, index, flow=flow), 'pre_process', None)
|
|
164
|
+
if func:
|
|
165
|
+
try:
|
|
166
|
+
# Rerun pre_process
|
|
167
|
+
func(chip)
|
|
168
|
+
except Exception:
|
|
169
|
+
pass
|
|
170
|
+
except SiliconCompilerError:
|
|
171
|
+
pass
|
|
172
|
+
chip.set('option', 'quiet', prev_quiet, step=step, index=index)
|
|
173
|
+
|
|
174
|
+
flow = chip.get('option', 'flow')
|
|
175
|
+
is_python_tool = hasattr(chip._get_task_module(step, index, flow=flow), 'run')
|
|
176
|
+
|
|
177
|
+
if not is_python_tool:
|
|
178
|
+
_makecmd(chip,
|
|
179
|
+
tool, task, step, index,
|
|
180
|
+
script_name=f'{chip.getworkdir(step=step, index=index)}/replay.sh',
|
|
181
|
+
include_path=False)
|
|
182
|
+
|
|
183
|
+
# Rewrite tool manifest
|
|
184
|
+
chip.set('arg', 'step', step)
|
|
185
|
+
chip.set('arg', 'index', index)
|
|
186
|
+
_write_task_manifest(chip, tool, path=new_work_dir)
|
|
187
|
+
|
|
188
|
+
# Restore normal path behavior
|
|
189
|
+
chip._relative_path = None
|
|
190
|
+
|
|
191
|
+
# Restore current directory
|
|
192
|
+
chip.cwd = original_cwd
|
|
193
|
+
os.chdir(current_work_dir)
|
|
194
|
+
|
|
195
|
+
git_data = {}
|
|
196
|
+
try:
|
|
197
|
+
# Check git information
|
|
198
|
+
repo = git.Repo(path=os.path.join(chip.scroot, '..'))
|
|
199
|
+
commit = repo.head.commit
|
|
200
|
+
git_data['commit'] = commit.hexsha
|
|
201
|
+
git_data['date'] = time.strftime('%Y-%m-%d %H:%M:%S',
|
|
202
|
+
time.gmtime(commit.committed_date))
|
|
203
|
+
git_data['author'] = f'{commit.author.name} <{commit.author.email}>'
|
|
204
|
+
git_data['msg'] = commit.message
|
|
205
|
+
# Count number of commits ahead of version
|
|
206
|
+
version_tag = repo.tag(f'v{chip.scversion}')
|
|
207
|
+
count = 0
|
|
208
|
+
for c in commit.iter_parents():
|
|
209
|
+
count += 1
|
|
210
|
+
if c == version_tag.commit:
|
|
211
|
+
break
|
|
212
|
+
git_data['count'] = count
|
|
213
|
+
except git.InvalidGitRepositoryError:
|
|
214
|
+
pass
|
|
215
|
+
except Exception as e:
|
|
216
|
+
git_data['failed'] = str(e)
|
|
217
|
+
pass
|
|
218
|
+
|
|
219
|
+
tool, task = get_tool_task(chip, step=step, index=index)
|
|
220
|
+
|
|
221
|
+
issue_time = time.time()
|
|
222
|
+
issue_information = {}
|
|
223
|
+
issue_information['environment'] = {key: value for key, value in os.environ.items()}
|
|
224
|
+
issue_information['python'] = {"path": sys.path,
|
|
225
|
+
"version": sys.version}
|
|
226
|
+
issue_information['date'] = datetime.fromtimestamp(issue_time).strftime('%Y-%m-%d %H:%M:%S')
|
|
227
|
+
issue_information['machine'] = _get_machine_info()
|
|
228
|
+
issue_information['run'] = {'step': step,
|
|
229
|
+
'index': index,
|
|
230
|
+
'libraries_included': include_libraries,
|
|
231
|
+
'pdks_included': include_pdks,
|
|
232
|
+
'tool': tool,
|
|
233
|
+
'toolversion': chip.get('record', 'toolversion',
|
|
234
|
+
step=step, index=index),
|
|
235
|
+
'task': task}
|
|
236
|
+
issue_information['version'] = {'schema': chip.schemaversion,
|
|
237
|
+
'sc': chip.scversion,
|
|
238
|
+
'git': git_data}
|
|
239
|
+
|
|
240
|
+
if not archive_name:
|
|
241
|
+
design = chip.design
|
|
242
|
+
job = chip.get('option', 'jobname')
|
|
243
|
+
file_time = datetime.fromtimestamp(issue_time).strftime('%Y%m%d-%H%M%S')
|
|
244
|
+
archive_name = f'sc_issue_{design}_{job}_{step}{index}_{file_time}.tar.gz'
|
|
245
|
+
|
|
246
|
+
# Make support files
|
|
247
|
+
issue_path = os.path.join(issue_dir.name, 'issue.json')
|
|
248
|
+
with open(issue_path, 'w') as fd:
|
|
249
|
+
json.dump(issue_information, fd, indent=4, sort_keys=True)
|
|
250
|
+
|
|
251
|
+
readme_path = os.path.join(issue_dir.name, 'README.txt')
|
|
252
|
+
with open(readme_path, 'w') as f:
|
|
253
|
+
f.write(get_file_template('issue/README.txt').render(
|
|
254
|
+
archive_name=archive_name,
|
|
255
|
+
has_run=not is_python_tool,
|
|
256
|
+
**issue_information))
|
|
257
|
+
|
|
258
|
+
run_path = None
|
|
259
|
+
if not is_python_tool:
|
|
260
|
+
run_path = os.path.join(issue_dir.name, 'run.sh')
|
|
261
|
+
with open(run_path, 'w') as f:
|
|
262
|
+
replay_dir = os.path.relpath(chip.getworkdir(step=step, index=index),
|
|
263
|
+
chip.cwd)
|
|
264
|
+
issue_title = f'{chip.design} for {step}{index} using {tool}/{task}'
|
|
265
|
+
f.write(get_file_template('issue/run.sh').render(
|
|
266
|
+
title=issue_title,
|
|
267
|
+
exec_dir=replay_dir
|
|
268
|
+
))
|
|
269
|
+
os.chmod(run_path, 0o755)
|
|
270
|
+
|
|
271
|
+
full_archive_path = archive_name
|
|
272
|
+
if archive_directory:
|
|
273
|
+
full_archive_path = os.path.join(archive_directory, archive_name)
|
|
274
|
+
full_archive_path = os.path.abspath(full_archive_path)
|
|
275
|
+
# Build archive
|
|
276
|
+
arch_base_dir = os.path.basename(archive_name).split('.')[0]
|
|
277
|
+
with tarfile.open(full_archive_path, "w:gz") as tar:
|
|
278
|
+
# Add individual files
|
|
279
|
+
add_files = [manifest_path,
|
|
280
|
+
issue_path,
|
|
281
|
+
readme_path]
|
|
282
|
+
if not is_python_tool:
|
|
283
|
+
add_files.append(run_path)
|
|
284
|
+
for path in add_files:
|
|
285
|
+
tar.add(os.path.abspath(path),
|
|
286
|
+
arcname=os.path.join(arch_base_dir,
|
|
287
|
+
os.path.basename(path)))
|
|
288
|
+
|
|
289
|
+
tar.add(job_dir,
|
|
290
|
+
arcname=os.path.join(arch_base_dir,
|
|
291
|
+
os.path.relpath(job_dir,
|
|
292
|
+
issue_dir.name)))
|
|
293
|
+
|
|
294
|
+
issue_dir.cleanup()
|
|
295
|
+
|
|
296
|
+
chip.logger.info(f'Generated testcase for {step}{index} in: '
|
|
297
|
+
f'{full_archive_path}')
|
|
298
|
+
|
|
299
|
+
# Restore original schema
|
|
300
|
+
chip.schema = schema_copy
|