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,147 @@
|
|
|
1
|
+
'''
|
|
2
|
+
Vivado is an FPGA programming tool suite from Xilinx used to
|
|
3
|
+
program Xilinx devices.
|
|
4
|
+
|
|
5
|
+
Documentation: https://www.xilinx.com/products/design-tools/vivado.html
|
|
6
|
+
'''
|
|
7
|
+
|
|
8
|
+
import json
|
|
9
|
+
import os
|
|
10
|
+
import re
|
|
11
|
+
from siliconcompiler import sc_open
|
|
12
|
+
from siliconcompiler.tools._common import record_metric
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def make_docs(chip):
|
|
16
|
+
chip.set('fpga', 'partname', 'ice40up5k-sg48')
|
|
17
|
+
chip.load_target("fpgaflow_demo")
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
tool = 'vivado'
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def setup(chip):
|
|
24
|
+
vendor = 'xilinx'
|
|
25
|
+
|
|
26
|
+
chip.set('tool', tool, 'exe', tool)
|
|
27
|
+
chip.set('tool', tool, 'vendor', vendor)
|
|
28
|
+
chip.set('tool', tool, 'vswitch', '-version')
|
|
29
|
+
chip.set('tool', tool, 'format', 'tcl')
|
|
30
|
+
|
|
31
|
+
# report_design_analysis -json flag requires Vivado 2021 or greater
|
|
32
|
+
chip.set('tool', tool, 'version', '>=2021', clobber=False)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def setup_task(chip, task):
|
|
36
|
+
setup(chip)
|
|
37
|
+
|
|
38
|
+
step = chip.get('arg', 'step')
|
|
39
|
+
index = chip.get('arg', 'index')
|
|
40
|
+
|
|
41
|
+
script = 'sc_run.tcl'
|
|
42
|
+
|
|
43
|
+
refdir = f'tools/{tool}/scripts'
|
|
44
|
+
option = ['-nolog', '-nojournal', '-mode', 'batch', '-source']
|
|
45
|
+
|
|
46
|
+
chip.set('tool', tool, 'task', task, 'refdir', refdir, step=step, index=index,
|
|
47
|
+
package='siliconcompiler', clobber=False)
|
|
48
|
+
chip.set('tool', tool, 'task', task, 'script', script, step=step, index=index, clobber=False)
|
|
49
|
+
chip.set('tool', tool, 'task', task, 'threads', os.cpu_count(),
|
|
50
|
+
step=step, index=index, clobber=False)
|
|
51
|
+
chip.set('tool', tool, 'task', task, 'option', option, step=step, index=index, clobber=False)
|
|
52
|
+
|
|
53
|
+
chip.set('tool', tool, 'task', task, 'regex', 'errors', r'^ERROR:',
|
|
54
|
+
step=step, index=index, clobber=False)
|
|
55
|
+
chip.set('tool', tool, 'task', task, 'regex', 'warnings', r'^(CRITICAL )?WARNING:',
|
|
56
|
+
step=step, index=index, clobber=False)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def parse_version(stdout):
|
|
60
|
+
# Vivado v2021.2 (64-bit)
|
|
61
|
+
return stdout.split()[1]
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def normalize_version(version):
|
|
65
|
+
return version.lstrip('v')
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _parse_qor_summary(chip, step, index):
|
|
69
|
+
if not os.path.isfile('qor_summary.json'):
|
|
70
|
+
return
|
|
71
|
+
|
|
72
|
+
with sc_open('qor_summary.json') as f:
|
|
73
|
+
data = json.load(f)
|
|
74
|
+
|
|
75
|
+
# Data is organized as list of tasks that Vivado has completed, with
|
|
76
|
+
# metrics associated with each. The tasks appear to be in chronological
|
|
77
|
+
# order, so we pull metrics from the last one.
|
|
78
|
+
task = data['Design QoR Summary'][-1]
|
|
79
|
+
setup_wns = task['Wns(ns)']
|
|
80
|
+
setup_tns = task['Tns(ns)']
|
|
81
|
+
hold_wns = task['Whs(ns)']
|
|
82
|
+
hold_tns = task['Ths(ns)']
|
|
83
|
+
|
|
84
|
+
if setup_wns:
|
|
85
|
+
record_metric(chip, step, index, 'setupwns', setup_wns,
|
|
86
|
+
'qor_summary.json',
|
|
87
|
+
source_unit='ns')
|
|
88
|
+
if setup_tns:
|
|
89
|
+
record_metric(chip, step, index, 'setuptns', setup_tns,
|
|
90
|
+
'qor_summary.json',
|
|
91
|
+
source_unit='ns')
|
|
92
|
+
if hold_wns:
|
|
93
|
+
record_metric(chip, step, index, 'holdwns', hold_wns,
|
|
94
|
+
'qor_summary.json',
|
|
95
|
+
source_unit='ns')
|
|
96
|
+
if hold_tns:
|
|
97
|
+
record_metric(chip, step, index, 'holdtns', hold_tns,
|
|
98
|
+
'qor_summary.json',
|
|
99
|
+
source_unit='ns')
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def _parse_utilization(chip, step, index):
|
|
103
|
+
if not os.path.isfile('reports/total_utilization.rpt'):
|
|
104
|
+
return
|
|
105
|
+
|
|
106
|
+
with sc_open('reports/total_utilization.rpt') as f:
|
|
107
|
+
regexes = {
|
|
108
|
+
'luts': (re.compile(r'(?:CLB|Slice) LUTs\*?\s+\|\s+(\d+)'), int),
|
|
109
|
+
'regs': (re.compile(r'(?:CLB|Slice) Registers\s+\|\s+(\d+)'), int),
|
|
110
|
+
'bram': (re.compile(r'Block RAM Tile\s+\|\s+(\d+(.\d+)?)'), float),
|
|
111
|
+
# TODO: should URAM be float?
|
|
112
|
+
'uram': (re.compile(r'URAM\s+\|\s+(\d+(.\d+)?)'), float)
|
|
113
|
+
}
|
|
114
|
+
vals = {}
|
|
115
|
+
|
|
116
|
+
for line in f:
|
|
117
|
+
for metric, (regex, datatype) in regexes.items():
|
|
118
|
+
if metric in vals:
|
|
119
|
+
continue
|
|
120
|
+
match = regex.search(line)
|
|
121
|
+
if match:
|
|
122
|
+
vals[metric] = datatype(match.group(1))
|
|
123
|
+
continue
|
|
124
|
+
|
|
125
|
+
if 'luts' in vals:
|
|
126
|
+
record_metric(chip, step, index, 'luts', vals['luts'],
|
|
127
|
+
'reports/total_utilization.rpt')
|
|
128
|
+
if 'regs' in vals:
|
|
129
|
+
record_metric(chip, step, index, 'registers', vals['regs'],
|
|
130
|
+
'reports/total_utilization.rpt')
|
|
131
|
+
|
|
132
|
+
total_bram = 0
|
|
133
|
+
if 'bram' in vals:
|
|
134
|
+
total_bram += vals['bram']
|
|
135
|
+
if 'uram' in vals:
|
|
136
|
+
total_bram += vals['uram']
|
|
137
|
+
if 'bram' in vals or 'uram' in vals:
|
|
138
|
+
record_metric(chip, step, index, 'brams', total_bram,
|
|
139
|
+
'reports/total_utilization.rpt')
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def post_process(chip):
|
|
143
|
+
step = chip.get('arg', 'step')
|
|
144
|
+
index = chip.get('arg', 'index')
|
|
145
|
+
|
|
146
|
+
_parse_qor_summary(chip, step, index)
|
|
147
|
+
_parse_utilization(chip, step, index)
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import json
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def load_json_constraints(json_constraints_file):
|
|
5
|
+
|
|
6
|
+
json_generic_constraints = {}
|
|
7
|
+
with (open(json_constraints_file, "r")) as json_constraints_data:
|
|
8
|
+
json_generic_constraints = json.loads(json_constraints_data.read())
|
|
9
|
+
|
|
10
|
+
return json_generic_constraints
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def load_constraints_map(constraints_map_file):
|
|
14
|
+
|
|
15
|
+
constraints_map = {}
|
|
16
|
+
with (open(constraints_map_file, "r")) as constraints_map_data:
|
|
17
|
+
constraints_map = json.loads(constraints_map_data.read())
|
|
18
|
+
|
|
19
|
+
return constraints_map
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def map_constraints(chip,
|
|
23
|
+
json_generic_constraints,
|
|
24
|
+
constraints_map):
|
|
25
|
+
|
|
26
|
+
design_constraints = {}
|
|
27
|
+
errors = 0
|
|
28
|
+
|
|
29
|
+
# If no constraints map is provided pass the constraints directly
|
|
30
|
+
if not constraints_map:
|
|
31
|
+
|
|
32
|
+
for design_pin in json_generic_constraints:
|
|
33
|
+
design_constraints[design_pin] = json_generic_constraints[design_pin]['pin']
|
|
34
|
+
|
|
35
|
+
# Otherwise use the constraints map to remap the constraints to the correct
|
|
36
|
+
# internal FPGA core pin:
|
|
37
|
+
else:
|
|
38
|
+
for design_pin in json_generic_constraints:
|
|
39
|
+
|
|
40
|
+
# VPR has a quirk that it prepends "out:" to outputs to differentiate
|
|
41
|
+
# the pin from any block name that may have inherited its instance name
|
|
42
|
+
# from an output. Compensate for that quirk here
|
|
43
|
+
if (json_generic_constraints[design_pin]['direction'] == "output"):
|
|
44
|
+
named_design_pin = f'out:{design_pin}'
|
|
45
|
+
else:
|
|
46
|
+
named_design_pin = design_pin
|
|
47
|
+
|
|
48
|
+
design_pin_assignment = json_generic_constraints[design_pin]['pin']
|
|
49
|
+
|
|
50
|
+
if (design_pin_assignment in constraints_map):
|
|
51
|
+
# Convert the dictionary entries in the constraints map into a tuple:
|
|
52
|
+
design_pin_constraint_assignment = (
|
|
53
|
+
constraints_map[design_pin_assignment]['x'],
|
|
54
|
+
constraints_map[design_pin_assignment]['y'],
|
|
55
|
+
constraints_map[design_pin_assignment]['subtile'])
|
|
56
|
+
|
|
57
|
+
design_constraints[named_design_pin] = design_pin_constraint_assignment
|
|
58
|
+
|
|
59
|
+
else:
|
|
60
|
+
chip.logger.error(f'Cannot map to pin {design_pin_assignment}')
|
|
61
|
+
errors += 1
|
|
62
|
+
|
|
63
|
+
return design_constraints, errors
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import xml.etree.ElementTree as ET
|
|
2
|
+
import xml.dom.minidom
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def generate_vpr_constraints_xml_file(pin_map, filename):
|
|
6
|
+
|
|
7
|
+
constraints_xml = generate_vpr_constraints_xml(pin_map)
|
|
8
|
+
write_vpr_constraints_xml_file(constraints_xml, filename)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def generate_vpr_constraints_xml(pin_map):
|
|
12
|
+
|
|
13
|
+
constraints_xml = ET.Element("vpr_constraints")
|
|
14
|
+
|
|
15
|
+
# Generate partition list section
|
|
16
|
+
partition_list = generate_partition_list_xml(pin_map)
|
|
17
|
+
|
|
18
|
+
constraints_xml.append(partition_list)
|
|
19
|
+
|
|
20
|
+
return constraints_xml
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def generate_partition_list_xml(pin_map):
|
|
24
|
+
|
|
25
|
+
partition_list = ET.Element("partition_list")
|
|
26
|
+
|
|
27
|
+
# ***ASSUMPTION: pin map is a dictionary of block names
|
|
28
|
+
# and tuples, where the tuples specify the
|
|
29
|
+
# (X,Y,subtile) locations that each block
|
|
30
|
+
# is constrained to
|
|
31
|
+
for pin, region in pin_map.items():
|
|
32
|
+
|
|
33
|
+
cur_partition = generate_partition_xml(pin, region)
|
|
34
|
+
partition_list.append(cur_partition)
|
|
35
|
+
|
|
36
|
+
return partition_list
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def generate_partition_xml(pin, pin_region):
|
|
40
|
+
|
|
41
|
+
partition = ET.Element("partition")
|
|
42
|
+
|
|
43
|
+
partition_name = generate_partition_name(pin)
|
|
44
|
+
partition.set("name", partition_name)
|
|
45
|
+
|
|
46
|
+
atom_xml = generate_add_atom_xml(pin)
|
|
47
|
+
partition.append(atom_xml)
|
|
48
|
+
|
|
49
|
+
x_low, x_high, y_low, y_high, subtile = generate_region_from_pin(pin_region)
|
|
50
|
+
region_xml = generate_add_region_xml(x_low, x_high, y_low, y_high, subtile)
|
|
51
|
+
partition.append(region_xml)
|
|
52
|
+
|
|
53
|
+
return partition
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def generate_region_from_pin(pin_region):
|
|
57
|
+
|
|
58
|
+
# ***ASSUMPTION: Pin region is a 3-element tuple
|
|
59
|
+
# containing (X,Y,subtile) coordinates
|
|
60
|
+
|
|
61
|
+
# TODO figure out a scheme that supports VPR's notion
|
|
62
|
+
# of specifying a region size of > 1x1
|
|
63
|
+
x_low = int(pin_region[0])
|
|
64
|
+
x_high = int(pin_region[0])
|
|
65
|
+
y_low = int(pin_region[1])
|
|
66
|
+
y_high = int(pin_region[1])
|
|
67
|
+
subtile = int(pin_region[2])
|
|
68
|
+
return x_low, x_high, y_low, y_high, subtile
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def generate_partition_name(pin):
|
|
72
|
+
|
|
73
|
+
partition_name = pin
|
|
74
|
+
partition_name = partition_name.replace('[', '_')
|
|
75
|
+
partition_name = partition_name.replace(']', '')
|
|
76
|
+
partition_name = "part_" + partition_name
|
|
77
|
+
|
|
78
|
+
return partition_name
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def generate_add_atom_xml(pin_name):
|
|
82
|
+
|
|
83
|
+
atom_xml = ET.Element("add_atom")
|
|
84
|
+
|
|
85
|
+
atom_xml.set("name_pattern", str(pin_name))
|
|
86
|
+
|
|
87
|
+
return atom_xml
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def generate_add_region_xml(x_low, x_high, y_low, y_high, subtile):
|
|
91
|
+
|
|
92
|
+
region_xml = ET.Element("add_region")
|
|
93
|
+
|
|
94
|
+
region_xml.set("x_low", str(x_low))
|
|
95
|
+
region_xml.set("y_low", str(y_low))
|
|
96
|
+
region_xml.set("x_high", str(x_high))
|
|
97
|
+
region_xml.set("y_high", str(y_high))
|
|
98
|
+
region_xml.set("subtile", str(subtile))
|
|
99
|
+
|
|
100
|
+
return region_xml
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def write_vpr_constraints_xml_file(constraints: ET.Element, filename: str):
|
|
104
|
+
|
|
105
|
+
dom = xml.dom.minidom.parseString(ET.tostring(constraints))
|
|
106
|
+
xml_string = dom.toprettyxml()
|
|
107
|
+
|
|
108
|
+
with open(filename, 'w') as xfile:
|
|
109
|
+
xfile.write(str(xml_string))
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import shutil
|
|
3
|
+
from siliconcompiler import SiliconCompilerError
|
|
4
|
+
from siliconcompiler.tools.vpr import vpr
|
|
5
|
+
from siliconcompiler.tools.vpr._json_constraint import load_constraints_map
|
|
6
|
+
from siliconcompiler.tools.vpr._json_constraint import load_json_constraints
|
|
7
|
+
from siliconcompiler.tools.vpr._json_constraint import map_constraints
|
|
8
|
+
from siliconcompiler.tools.vpr._xml_constraint import generate_vpr_constraints_xml_file
|
|
9
|
+
from siliconcompiler.tools._common import get_tool_task
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def setup(chip, clobber=True):
|
|
13
|
+
'''
|
|
14
|
+
Perform automated place and route with VPR
|
|
15
|
+
'''
|
|
16
|
+
|
|
17
|
+
tool = 'vpr'
|
|
18
|
+
step = chip.get('arg', 'step')
|
|
19
|
+
index = chip.get('arg', 'index')
|
|
20
|
+
_, task = get_tool_task(chip, step, index)
|
|
21
|
+
|
|
22
|
+
vpr.setup_tool(chip, clobber=clobber)
|
|
23
|
+
|
|
24
|
+
chip.set('tool', tool, 'task', task, 'threads', os.cpu_count(),
|
|
25
|
+
step=step, index=index, clobber=False)
|
|
26
|
+
|
|
27
|
+
design = chip.top()
|
|
28
|
+
chip.set('tool', tool, 'task', task, 'input', design + '.blif', step=step, index=index)
|
|
29
|
+
|
|
30
|
+
chip.set('tool', tool, 'task', task, 'output', design + '.blif', step=step, index=index)
|
|
31
|
+
chip.add('tool', tool, 'task', task, 'output', design + '.net', step=step, index=index)
|
|
32
|
+
chip.add('tool', tool, 'task', task, 'output', design + '.place', step=step, index=index)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def runtime_options(chip):
|
|
36
|
+
'''Command line options to vpr for the place step
|
|
37
|
+
'''
|
|
38
|
+
|
|
39
|
+
step = chip.get('arg', 'step')
|
|
40
|
+
index = chip.get('arg', 'index')
|
|
41
|
+
tool, task = get_tool_task(chip, step, index)
|
|
42
|
+
|
|
43
|
+
design = chip.top()
|
|
44
|
+
|
|
45
|
+
options = vpr.runtime_options(chip)
|
|
46
|
+
|
|
47
|
+
blif = f"inputs/{design}.blif"
|
|
48
|
+
options.append(blif)
|
|
49
|
+
|
|
50
|
+
options.append('--pack')
|
|
51
|
+
options.append('--place')
|
|
52
|
+
|
|
53
|
+
enable_images = chip.get('tool', tool, 'task', task, 'var', 'enable_images',
|
|
54
|
+
step=step, index=index)[0]
|
|
55
|
+
|
|
56
|
+
if enable_images == 'true':
|
|
57
|
+
graphics_commands = vpr.get_common_graphics(chip)
|
|
58
|
+
|
|
59
|
+
graphics_command_str = " ".join(graphics_commands)
|
|
60
|
+
|
|
61
|
+
options.append("--graphics_commands")
|
|
62
|
+
options.append(f"\"{graphics_command_str}\"")
|
|
63
|
+
|
|
64
|
+
return options
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
################################
|
|
68
|
+
# Pre_process (pre executable)
|
|
69
|
+
################################
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def pre_process(chip):
|
|
73
|
+
''' Tool specific function to run before step execution
|
|
74
|
+
'''
|
|
75
|
+
|
|
76
|
+
step = chip.get('arg', 'step')
|
|
77
|
+
index = chip.get('arg', 'index')
|
|
78
|
+
|
|
79
|
+
part_name = chip.get('fpga', 'partname')
|
|
80
|
+
|
|
81
|
+
# If the user explicitly provides an XML constraints file, give that
|
|
82
|
+
# priority over other constraints input types:
|
|
83
|
+
if 'vpr_pins' in chip.getkeys('input', 'constraint'):
|
|
84
|
+
constraint_file = vpr.find_single_file(chip, 'input', 'constraint', 'vpr_pins',
|
|
85
|
+
step=step, index=index,
|
|
86
|
+
file_not_found_msg="VPR constraints file not found")
|
|
87
|
+
|
|
88
|
+
if (constraint_file is not None):
|
|
89
|
+
shutil.copy2(constraint_file, vpr.auto_constraints())
|
|
90
|
+
|
|
91
|
+
elif 'pcf' in chip.getkeys('input', 'constraint'):
|
|
92
|
+
constraint_file = vpr.find_single_file(chip, 'input', 'constraint', 'pcf',
|
|
93
|
+
step=step, index=index,
|
|
94
|
+
file_not_found_msg="PCF constraints file not found")
|
|
95
|
+
|
|
96
|
+
map_file = vpr.find_single_file(chip, 'fpga', part_name, 'file', 'constraints_map',
|
|
97
|
+
file_not_found_msg="constraints map not found")
|
|
98
|
+
|
|
99
|
+
if not map_file:
|
|
100
|
+
raise SiliconCompilerError('FPGA does not have required constraints map', chip=chip)
|
|
101
|
+
|
|
102
|
+
constraints_map = load_constraints_map(map_file)
|
|
103
|
+
json_constraints = load_json_constraints(constraint_file)
|
|
104
|
+
all_place_constraints, missing_pins = map_constraints(chip,
|
|
105
|
+
json_constraints,
|
|
106
|
+
constraints_map)
|
|
107
|
+
if (missing_pins > 0):
|
|
108
|
+
raise SiliconCompilerError(
|
|
109
|
+
"Pin constraints specify I/O ports not in this architecture", chip=chip)
|
|
110
|
+
|
|
111
|
+
generate_vpr_constraints_xml_file(all_place_constraints, vpr.auto_constraints())
|
|
112
|
+
|
|
113
|
+
else:
|
|
114
|
+
all_component_constraints = chip.getkeys('constraint', 'component')
|
|
115
|
+
all_place_constraints = {}
|
|
116
|
+
for component in all_component_constraints:
|
|
117
|
+
place_constraint = chip.get('constraint', 'component', component, 'placement',
|
|
118
|
+
step=step, index=index)
|
|
119
|
+
chip.logger.info(f'Place constraint for {component} at {place_constraint}')
|
|
120
|
+
all_place_constraints[component] = place_constraint
|
|
121
|
+
|
|
122
|
+
if all_place_constraints:
|
|
123
|
+
generate_vpr_constraints_xml_file(all_place_constraints, vpr.auto_constraints())
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
################################
|
|
127
|
+
# Post_process (post executable)
|
|
128
|
+
################################
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def post_process(chip):
|
|
132
|
+
''' Tool specific function to run after step execution
|
|
133
|
+
'''
|
|
134
|
+
vpr.vpr_post_process(chip)
|
|
135
|
+
|
|
136
|
+
design = chip.top()
|
|
137
|
+
shutil.copy2(f'inputs/{design}.blif', 'outputs')
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import shutil
|
|
3
|
+
|
|
4
|
+
from siliconcompiler.tools.vpr import vpr
|
|
5
|
+
from siliconcompiler.tools._common import get_tool_task
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def setup(chip, clobber=True):
|
|
9
|
+
'''
|
|
10
|
+
Perform automated place and route with VPR
|
|
11
|
+
'''
|
|
12
|
+
|
|
13
|
+
tool = 'vpr'
|
|
14
|
+
step = chip.get('arg', 'step')
|
|
15
|
+
index = chip.get('arg', 'index')
|
|
16
|
+
_, task = get_tool_task(chip, step, index)
|
|
17
|
+
|
|
18
|
+
vpr.setup_tool(chip, clobber=clobber)
|
|
19
|
+
|
|
20
|
+
# Match VPR's default max router iterations value so that
|
|
21
|
+
# the parameter is traceable by SC through the flow.
|
|
22
|
+
chip.set('tool', tool, 'task', task, 'var', 'max_router_iterations', "50",
|
|
23
|
+
step=step, index=index, clobber=False)
|
|
24
|
+
|
|
25
|
+
chip.set('tool', tool, 'task', task, 'var', 'max_router_iterations',
|
|
26
|
+
'set maximum number of routing iterations',
|
|
27
|
+
field='help')
|
|
28
|
+
|
|
29
|
+
chip.add('tool', tool, 'task', task, 'require',
|
|
30
|
+
",".join(['tool', tool, 'task', task, 'var', 'max_router_iterations']),
|
|
31
|
+
step=step, index=index)
|
|
32
|
+
|
|
33
|
+
chip.set('tool', tool, 'task', task, 'threads', os.cpu_count(),
|
|
34
|
+
step=step, index=index, clobber=clobber)
|
|
35
|
+
|
|
36
|
+
# TO-DO: PRIOROTIZE the post-routing packing results?
|
|
37
|
+
design = chip.top()
|
|
38
|
+
chip.set('tool', tool, 'task', task, 'input', design + '.blif', step=step, index=index)
|
|
39
|
+
chip.add('tool', tool, 'task', task, 'input', design + '.net', step=step, index=index)
|
|
40
|
+
chip.add('tool', tool, 'task', task, 'input', design + '.place', step=step, index=index)
|
|
41
|
+
|
|
42
|
+
chip.set('tool', tool, 'task', task, 'output', design + '.route', step=step, index=index)
|
|
43
|
+
chip.add('tool', tool, 'task', task, 'output', design + '.blif', step=step, index=index)
|
|
44
|
+
chip.add('tool', tool, 'task', task, 'output', design + '.net', step=step, index=index)
|
|
45
|
+
chip.add('tool', tool, 'task', task, 'output', design + '.place', step=step, index=index)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def runtime_options(chip):
|
|
49
|
+
'''Command line options to vpr for the route step
|
|
50
|
+
'''
|
|
51
|
+
|
|
52
|
+
step = chip.get('arg', 'step')
|
|
53
|
+
index = chip.get('arg', 'index')
|
|
54
|
+
tool, task = get_tool_task(chip, step, index)
|
|
55
|
+
|
|
56
|
+
design = chip.top()
|
|
57
|
+
|
|
58
|
+
options = vpr.runtime_options(chip)
|
|
59
|
+
|
|
60
|
+
blif = f"inputs/{design}.blif"
|
|
61
|
+
options.append(blif)
|
|
62
|
+
|
|
63
|
+
options.append('--route')
|
|
64
|
+
# To run only the routing step we need to pass in the placement files
|
|
65
|
+
options.append(f'--net_file inputs/{design}.net')
|
|
66
|
+
options.append(f'--place_file inputs/{design}.place')
|
|
67
|
+
|
|
68
|
+
enable_images = chip.get('tool', tool, 'task', task, 'var', 'enable_images',
|
|
69
|
+
step=step, index=index)[0]
|
|
70
|
+
|
|
71
|
+
route_iterations = chip.get('tool', tool, 'task', task, 'var', 'max_router_iterations',
|
|
72
|
+
step=step, index=index)
|
|
73
|
+
|
|
74
|
+
if (len(route_iterations) > 0):
|
|
75
|
+
options.append(f'--max_router_iterations {route_iterations[0]}')
|
|
76
|
+
|
|
77
|
+
if enable_images == 'true':
|
|
78
|
+
design = chip.top()
|
|
79
|
+
|
|
80
|
+
graphics_commands = vpr.get_common_graphics(chip)
|
|
81
|
+
|
|
82
|
+
# set_draw_block_text 0 hides the label for various blocks in the design
|
|
83
|
+
# set_draw_block_outlines 0 removes the outline/boundary for various blocks in the design
|
|
84
|
+
# set_routing_util 1 displays the routing utilization as a heat map
|
|
85
|
+
# set_routing_util 4 displays the routing utilization as a heat map over placed blocks
|
|
86
|
+
# Refer: https://github.com/verilog-to-routing/vtr-verilog-to-routing/blob/master/
|
|
87
|
+
# vpr/src/draw/draw_types.h#L89
|
|
88
|
+
# save_graphics saves the block diagram as a png/svg/pdf
|
|
89
|
+
# Refer:
|
|
90
|
+
# https://docs.verilogtorouting.org/en/latest/vpr/command_line_usage/#graphics-options
|
|
91
|
+
graphics_commands.append("set_draw_block_text 0; " +
|
|
92
|
+
"set_draw_block_outlines 0; " +
|
|
93
|
+
"set_routing_util 1; " +
|
|
94
|
+
"save_graphics "
|
|
95
|
+
f"reports/{design}_route_utilization_with_placement.png;")
|
|
96
|
+
graphics_commands.append("set_draw_block_text 0; " +
|
|
97
|
+
"set_draw_block_outlines 0; " +
|
|
98
|
+
"set_routing_util 4; " +
|
|
99
|
+
"save_graphics "
|
|
100
|
+
f"reports/{design}_route_utilization.png;")
|
|
101
|
+
|
|
102
|
+
graphics_command_str = " ".join(graphics_commands)
|
|
103
|
+
|
|
104
|
+
options.append("--graphics_commands")
|
|
105
|
+
options.append(f"\"{graphics_command_str}\"")
|
|
106
|
+
|
|
107
|
+
return options
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
################################
|
|
111
|
+
# Post_process (post executable)
|
|
112
|
+
################################
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def post_process(chip):
|
|
116
|
+
''' Tool specific function to run after step execution
|
|
117
|
+
'''
|
|
118
|
+
vpr.vpr_post_process(chip)
|
|
119
|
+
|
|
120
|
+
design = chip.top()
|
|
121
|
+
# Forward all of the prior step inputs forward for bitstream generation
|
|
122
|
+
shutil.copy2(f'inputs/{design}.blif', 'outputs')
|
|
123
|
+
shutil.copy2(f'inputs/{design}.net', 'outputs')
|
|
124
|
+
shutil.copy2(f'inputs/{design}.place', 'outputs')
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
from siliconcompiler import SiliconCompilerError
|
|
2
|
+
from siliconcompiler.tools.vpr import show
|
|
3
|
+
from siliconcompiler.tools._common import get_tool_task
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def setup(chip, clobber=True):
|
|
7
|
+
'''
|
|
8
|
+
Screenshot placed and/or routed designs
|
|
9
|
+
'''
|
|
10
|
+
|
|
11
|
+
show.setup(chip, clobber=clobber)
|
|
12
|
+
|
|
13
|
+
step = chip.get('arg', 'step')
|
|
14
|
+
index = chip.get('arg', 'index')
|
|
15
|
+
tool, task = get_tool_task(chip, step, index)
|
|
16
|
+
|
|
17
|
+
design = chip.top()
|
|
18
|
+
chip.add('tool', tool, 'task', task, 'output', f'{design}.png', step=step, index=index)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def runtime_options(chip):
|
|
22
|
+
'''Command line options to vpr for screenshot
|
|
23
|
+
'''
|
|
24
|
+
|
|
25
|
+
design = chip.top()
|
|
26
|
+
|
|
27
|
+
step = chip.get('arg', 'step')
|
|
28
|
+
index = chip.get('arg', 'index')
|
|
29
|
+
tool, task = get_tool_task(chip, step, index)
|
|
30
|
+
|
|
31
|
+
if chip.valid('tool', tool, 'task', task, 'var', 'show_filepath'):
|
|
32
|
+
show_type = chip.get('tool', tool, 'task', task, 'var', 'show_filetype',
|
|
33
|
+
step=step, index=index)[0]
|
|
34
|
+
else:
|
|
35
|
+
raise SiliconCompilerError("Invalid filepath", chip=chip)
|
|
36
|
+
|
|
37
|
+
options = show.generic_show_options(chip)
|
|
38
|
+
|
|
39
|
+
if show_type == 'route':
|
|
40
|
+
screenshot_command_str = ("set_draw_block_text 0; " +
|
|
41
|
+
"set_draw_block_outlines 0; " +
|
|
42
|
+
"set_routing_util 1; " +
|
|
43
|
+
f"save_graphics outputs/{design}.png;")
|
|
44
|
+
elif show_type == 'place':
|
|
45
|
+
screenshot_command_str = ("set_draw_block_text 1; " +
|
|
46
|
+
"set_draw_block_outlines 1; " +
|
|
47
|
+
f"save_graphics outputs/{design}.png;")
|
|
48
|
+
else:
|
|
49
|
+
raise SiliconCompilerError(f"Incorrect file type {show_type}", chip=chip)
|
|
50
|
+
|
|
51
|
+
options.append("--graphics_commands")
|
|
52
|
+
options.append(f"\"{screenshot_command_str}\"")
|
|
53
|
+
|
|
54
|
+
return options
|