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.
Files changed (251) hide show
  1. siliconcompiler/__init__.py +24 -0
  2. siliconcompiler/__main__.py +12 -0
  3. siliconcompiler/_common.py +49 -0
  4. siliconcompiler/_metadata.py +36 -0
  5. siliconcompiler/apps/__init__.py +0 -0
  6. siliconcompiler/apps/_common.py +76 -0
  7. siliconcompiler/apps/sc.py +92 -0
  8. siliconcompiler/apps/sc_dashboard.py +94 -0
  9. siliconcompiler/apps/sc_issue.py +178 -0
  10. siliconcompiler/apps/sc_remote.py +199 -0
  11. siliconcompiler/apps/sc_server.py +39 -0
  12. siliconcompiler/apps/sc_show.py +142 -0
  13. siliconcompiler/apps/smake.py +232 -0
  14. siliconcompiler/checklists/__init__.py +0 -0
  15. siliconcompiler/checklists/oh_tapeout.py +41 -0
  16. siliconcompiler/core.py +3221 -0
  17. siliconcompiler/data/RobotoMono/LICENSE.txt +202 -0
  18. siliconcompiler/data/RobotoMono/RobotoMono-Regular.ttf +0 -0
  19. siliconcompiler/data/heartbeat.v +18 -0
  20. siliconcompiler/data/logo.png +0 -0
  21. siliconcompiler/flowgraph.py +570 -0
  22. siliconcompiler/flows/__init__.py +0 -0
  23. siliconcompiler/flows/_common.py +67 -0
  24. siliconcompiler/flows/asicflow.py +180 -0
  25. siliconcompiler/flows/asictopflow.py +38 -0
  26. siliconcompiler/flows/dvflow.py +86 -0
  27. siliconcompiler/flows/fpgaflow.py +202 -0
  28. siliconcompiler/flows/generate_openroad_rcx.py +66 -0
  29. siliconcompiler/flows/lintflow.py +35 -0
  30. siliconcompiler/flows/screenshotflow.py +51 -0
  31. siliconcompiler/flows/showflow.py +59 -0
  32. siliconcompiler/flows/signoffflow.py +53 -0
  33. siliconcompiler/flows/synflow.py +128 -0
  34. siliconcompiler/fpgas/__init__.py +0 -0
  35. siliconcompiler/fpgas/lattice_ice40.py +42 -0
  36. siliconcompiler/fpgas/vpr_example.py +109 -0
  37. siliconcompiler/issue.py +300 -0
  38. siliconcompiler/libs/__init__.py +0 -0
  39. siliconcompiler/libs/asap7sc7p5t.py +8 -0
  40. siliconcompiler/libs/gf180mcu.py +8 -0
  41. siliconcompiler/libs/nangate45.py +8 -0
  42. siliconcompiler/libs/sky130hd.py +8 -0
  43. siliconcompiler/libs/sky130io.py +8 -0
  44. siliconcompiler/package.py +412 -0
  45. siliconcompiler/pdks/__init__.py +0 -0
  46. siliconcompiler/pdks/asap7.py +8 -0
  47. siliconcompiler/pdks/freepdk45.py +8 -0
  48. siliconcompiler/pdks/gf180.py +8 -0
  49. siliconcompiler/pdks/skywater130.py +8 -0
  50. siliconcompiler/remote/__init__.py +36 -0
  51. siliconcompiler/remote/client.py +891 -0
  52. siliconcompiler/remote/schema.py +106 -0
  53. siliconcompiler/remote/server.py +507 -0
  54. siliconcompiler/remote/server_schema/requests/cancel_job.json +51 -0
  55. siliconcompiler/remote/server_schema/requests/check_progress.json +61 -0
  56. siliconcompiler/remote/server_schema/requests/check_server.json +38 -0
  57. siliconcompiler/remote/server_schema/requests/delete_job.json +51 -0
  58. siliconcompiler/remote/server_schema/requests/get_results.json +48 -0
  59. siliconcompiler/remote/server_schema/requests/remote_run.json +40 -0
  60. siliconcompiler/remote/server_schema/responses/cancel_job.json +18 -0
  61. siliconcompiler/remote/server_schema/responses/check_progress.json +30 -0
  62. siliconcompiler/remote/server_schema/responses/check_server.json +32 -0
  63. siliconcompiler/remote/server_schema/responses/delete_job.json +18 -0
  64. siliconcompiler/remote/server_schema/responses/get_results.json +21 -0
  65. siliconcompiler/remote/server_schema/responses/remote_run.json +25 -0
  66. siliconcompiler/report/__init__.py +13 -0
  67. siliconcompiler/report/html_report.py +74 -0
  68. siliconcompiler/report/report.py +355 -0
  69. siliconcompiler/report/streamlit_report.py +137 -0
  70. siliconcompiler/report/streamlit_viewer.py +944 -0
  71. siliconcompiler/report/summary_image.py +117 -0
  72. siliconcompiler/report/summary_table.py +105 -0
  73. siliconcompiler/report/utils.py +163 -0
  74. siliconcompiler/scheduler/__init__.py +2092 -0
  75. siliconcompiler/scheduler/docker_runner.py +253 -0
  76. siliconcompiler/scheduler/run_node.py +138 -0
  77. siliconcompiler/scheduler/send_messages.py +178 -0
  78. siliconcompiler/scheduler/slurm.py +208 -0
  79. siliconcompiler/scheduler/validation/email_credentials.json +54 -0
  80. siliconcompiler/schema/__init__.py +7 -0
  81. siliconcompiler/schema/schema_cfg.py +4014 -0
  82. siliconcompiler/schema/schema_obj.py +1841 -0
  83. siliconcompiler/schema/utils.py +93 -0
  84. siliconcompiler/sphinx_ext/__init__.py +0 -0
  85. siliconcompiler/sphinx_ext/dynamicgen.py +1006 -0
  86. siliconcompiler/sphinx_ext/schemagen.py +221 -0
  87. siliconcompiler/sphinx_ext/utils.py +166 -0
  88. siliconcompiler/targets/__init__.py +0 -0
  89. siliconcompiler/targets/asap7_demo.py +68 -0
  90. siliconcompiler/targets/asic_demo.py +38 -0
  91. siliconcompiler/targets/fpgaflow_demo.py +47 -0
  92. siliconcompiler/targets/freepdk45_demo.py +59 -0
  93. siliconcompiler/targets/gf180_demo.py +77 -0
  94. siliconcompiler/targets/skywater130_demo.py +70 -0
  95. siliconcompiler/templates/email/general.j2 +66 -0
  96. siliconcompiler/templates/email/summary.j2 +43 -0
  97. siliconcompiler/templates/issue/README.txt +26 -0
  98. siliconcompiler/templates/issue/run.sh +6 -0
  99. siliconcompiler/templates/report/bootstrap.min.css +7 -0
  100. siliconcompiler/templates/report/bootstrap.min.js +7 -0
  101. siliconcompiler/templates/report/bootstrap_LICENSE.md +24 -0
  102. siliconcompiler/templates/report/sc_report.j2 +427 -0
  103. siliconcompiler/templates/slurm/run.sh +9 -0
  104. siliconcompiler/templates/tcl/manifest.tcl.j2 +137 -0
  105. siliconcompiler/tools/__init__.py +0 -0
  106. siliconcompiler/tools/_common/__init__.py +432 -0
  107. siliconcompiler/tools/_common/asic.py +115 -0
  108. siliconcompiler/tools/_common/sdc/sc_constraints.sdc +76 -0
  109. siliconcompiler/tools/_common/tcl/sc_pin_constraints.tcl +63 -0
  110. siliconcompiler/tools/bambu/bambu.py +32 -0
  111. siliconcompiler/tools/bambu/convert.py +77 -0
  112. siliconcompiler/tools/bluespec/bluespec.py +40 -0
  113. siliconcompiler/tools/bluespec/convert.py +103 -0
  114. siliconcompiler/tools/builtin/_common.py +155 -0
  115. siliconcompiler/tools/builtin/builtin.py +26 -0
  116. siliconcompiler/tools/builtin/concatenate.py +85 -0
  117. siliconcompiler/tools/builtin/join.py +27 -0
  118. siliconcompiler/tools/builtin/maximum.py +46 -0
  119. siliconcompiler/tools/builtin/minimum.py +57 -0
  120. siliconcompiler/tools/builtin/mux.py +70 -0
  121. siliconcompiler/tools/builtin/nop.py +38 -0
  122. siliconcompiler/tools/builtin/verify.py +83 -0
  123. siliconcompiler/tools/chisel/SCDriver.scala +10 -0
  124. siliconcompiler/tools/chisel/build.sbt +27 -0
  125. siliconcompiler/tools/chisel/chisel.py +37 -0
  126. siliconcompiler/tools/chisel/convert.py +140 -0
  127. siliconcompiler/tools/execute/exec_input.py +41 -0
  128. siliconcompiler/tools/execute/execute.py +17 -0
  129. siliconcompiler/tools/genfasm/bitstream.py +61 -0
  130. siliconcompiler/tools/genfasm/genfasm.py +40 -0
  131. siliconcompiler/tools/ghdl/convert.py +87 -0
  132. siliconcompiler/tools/ghdl/ghdl.py +41 -0
  133. siliconcompiler/tools/icarus/compile.py +87 -0
  134. siliconcompiler/tools/icarus/icarus.py +36 -0
  135. siliconcompiler/tools/icepack/bitstream.py +20 -0
  136. siliconcompiler/tools/icepack/icepack.py +43 -0
  137. siliconcompiler/tools/klayout/export.py +117 -0
  138. siliconcompiler/tools/klayout/klayout.py +119 -0
  139. siliconcompiler/tools/klayout/klayout_export.py +205 -0
  140. siliconcompiler/tools/klayout/klayout_operations.py +363 -0
  141. siliconcompiler/tools/klayout/klayout_show.py +242 -0
  142. siliconcompiler/tools/klayout/klayout_utils.py +176 -0
  143. siliconcompiler/tools/klayout/operations.py +194 -0
  144. siliconcompiler/tools/klayout/screenshot.py +98 -0
  145. siliconcompiler/tools/klayout/show.py +101 -0
  146. siliconcompiler/tools/magic/drc.py +49 -0
  147. siliconcompiler/tools/magic/extspice.py +19 -0
  148. siliconcompiler/tools/magic/magic.py +85 -0
  149. siliconcompiler/tools/magic/sc_drc.tcl +96 -0
  150. siliconcompiler/tools/magic/sc_extspice.tcl +54 -0
  151. siliconcompiler/tools/magic/sc_magic.tcl +47 -0
  152. siliconcompiler/tools/montage/montage.py +30 -0
  153. siliconcompiler/tools/montage/tile.py +66 -0
  154. siliconcompiler/tools/netgen/count_lvs.py +132 -0
  155. siliconcompiler/tools/netgen/lvs.py +90 -0
  156. siliconcompiler/tools/netgen/netgen.py +36 -0
  157. siliconcompiler/tools/netgen/sc_lvs.tcl +46 -0
  158. siliconcompiler/tools/nextpnr/apr.py +24 -0
  159. siliconcompiler/tools/nextpnr/nextpnr.py +59 -0
  160. siliconcompiler/tools/openfpgaloader/openfpgaloader.py +39 -0
  161. siliconcompiler/tools/openroad/__init__.py +0 -0
  162. siliconcompiler/tools/openroad/cts.py +45 -0
  163. siliconcompiler/tools/openroad/dfm.py +66 -0
  164. siliconcompiler/tools/openroad/export.py +131 -0
  165. siliconcompiler/tools/openroad/floorplan.py +70 -0
  166. siliconcompiler/tools/openroad/openroad.py +977 -0
  167. siliconcompiler/tools/openroad/physyn.py +27 -0
  168. siliconcompiler/tools/openroad/place.py +41 -0
  169. siliconcompiler/tools/openroad/rcx_bench.py +95 -0
  170. siliconcompiler/tools/openroad/rcx_extract.py +34 -0
  171. siliconcompiler/tools/openroad/route.py +45 -0
  172. siliconcompiler/tools/openroad/screenshot.py +60 -0
  173. siliconcompiler/tools/openroad/scripts/sc_apr.tcl +499 -0
  174. siliconcompiler/tools/openroad/scripts/sc_cts.tcl +64 -0
  175. siliconcompiler/tools/openroad/scripts/sc_dfm.tcl +20 -0
  176. siliconcompiler/tools/openroad/scripts/sc_export.tcl +98 -0
  177. siliconcompiler/tools/openroad/scripts/sc_floorplan.tcl +413 -0
  178. siliconcompiler/tools/openroad/scripts/sc_metrics.tcl +158 -0
  179. siliconcompiler/tools/openroad/scripts/sc_physyn.tcl +7 -0
  180. siliconcompiler/tools/openroad/scripts/sc_place.tcl +84 -0
  181. siliconcompiler/tools/openroad/scripts/sc_procs.tcl +423 -0
  182. siliconcompiler/tools/openroad/scripts/sc_rcx.tcl +63 -0
  183. siliconcompiler/tools/openroad/scripts/sc_rcx_bench.tcl +20 -0
  184. siliconcompiler/tools/openroad/scripts/sc_rcx_extract.tcl +12 -0
  185. siliconcompiler/tools/openroad/scripts/sc_route.tcl +133 -0
  186. siliconcompiler/tools/openroad/scripts/sc_screenshot.tcl +21 -0
  187. siliconcompiler/tools/openroad/scripts/sc_write.tcl +5 -0
  188. siliconcompiler/tools/openroad/scripts/sc_write_images.tcl +361 -0
  189. siliconcompiler/tools/openroad/show.py +94 -0
  190. siliconcompiler/tools/openroad/templates/pex.tcl +8 -0
  191. siliconcompiler/tools/opensta/__init__.py +101 -0
  192. siliconcompiler/tools/opensta/report_libraries.py +28 -0
  193. siliconcompiler/tools/opensta/scripts/sc_procs.tcl +47 -0
  194. siliconcompiler/tools/opensta/scripts/sc_report_libraries.tcl +74 -0
  195. siliconcompiler/tools/opensta/scripts/sc_timing.tcl +268 -0
  196. siliconcompiler/tools/opensta/timing.py +214 -0
  197. siliconcompiler/tools/slang/__init__.py +49 -0
  198. siliconcompiler/tools/slang/lint.py +101 -0
  199. siliconcompiler/tools/surelog/__init__.py +123 -0
  200. siliconcompiler/tools/surelog/parse.py +183 -0
  201. siliconcompiler/tools/surelog/templates/output.v +7 -0
  202. siliconcompiler/tools/sv2v/convert.py +46 -0
  203. siliconcompiler/tools/sv2v/sv2v.py +37 -0
  204. siliconcompiler/tools/template/template.py +125 -0
  205. siliconcompiler/tools/verilator/compile.py +139 -0
  206. siliconcompiler/tools/verilator/lint.py +19 -0
  207. siliconcompiler/tools/verilator/parse.py +27 -0
  208. siliconcompiler/tools/verilator/verilator.py +172 -0
  209. siliconcompiler/tools/vivado/__init__.py +7 -0
  210. siliconcompiler/tools/vivado/bitstream.py +21 -0
  211. siliconcompiler/tools/vivado/place.py +21 -0
  212. siliconcompiler/tools/vivado/route.py +21 -0
  213. siliconcompiler/tools/vivado/scripts/sc_bitstream.tcl +6 -0
  214. siliconcompiler/tools/vivado/scripts/sc_place.tcl +2 -0
  215. siliconcompiler/tools/vivado/scripts/sc_route.tcl +4 -0
  216. siliconcompiler/tools/vivado/scripts/sc_run.tcl +45 -0
  217. siliconcompiler/tools/vivado/scripts/sc_syn_fpga.tcl +25 -0
  218. siliconcompiler/tools/vivado/syn_fpga.py +20 -0
  219. siliconcompiler/tools/vivado/vivado.py +147 -0
  220. siliconcompiler/tools/vpr/_json_constraint.py +63 -0
  221. siliconcompiler/tools/vpr/_xml_constraint.py +109 -0
  222. siliconcompiler/tools/vpr/place.py +137 -0
  223. siliconcompiler/tools/vpr/route.py +124 -0
  224. siliconcompiler/tools/vpr/screenshot.py +54 -0
  225. siliconcompiler/tools/vpr/show.py +88 -0
  226. siliconcompiler/tools/vpr/vpr.py +357 -0
  227. siliconcompiler/tools/xyce/xyce.py +36 -0
  228. siliconcompiler/tools/yosys/lec.py +56 -0
  229. siliconcompiler/tools/yosys/prepareLib.py +59 -0
  230. siliconcompiler/tools/yosys/sc_lec.tcl +84 -0
  231. siliconcompiler/tools/yosys/sc_syn.tcl +79 -0
  232. siliconcompiler/tools/yosys/syn_asic.py +565 -0
  233. siliconcompiler/tools/yosys/syn_asic.tcl +377 -0
  234. siliconcompiler/tools/yosys/syn_asic_fpga_shared.tcl +31 -0
  235. siliconcompiler/tools/yosys/syn_fpga.py +146 -0
  236. siliconcompiler/tools/yosys/syn_fpga.tcl +233 -0
  237. siliconcompiler/tools/yosys/syn_strategies.tcl +81 -0
  238. siliconcompiler/tools/yosys/techmaps/lcu_kogge_stone.v +39 -0
  239. siliconcompiler/tools/yosys/templates/abc.const +2 -0
  240. siliconcompiler/tools/yosys/yosys.py +147 -0
  241. siliconcompiler/units.py +259 -0
  242. siliconcompiler/use.py +177 -0
  243. siliconcompiler/utils/__init__.py +423 -0
  244. siliconcompiler/utils/asic.py +158 -0
  245. siliconcompiler/utils/showtools.py +25 -0
  246. siliconcompiler-0.26.5.dist-info/LICENSE +190 -0
  247. siliconcompiler-0.26.5.dist-info/METADATA +195 -0
  248. siliconcompiler-0.26.5.dist-info/RECORD +251 -0
  249. siliconcompiler-0.26.5.dist-info/WHEEL +5 -0
  250. siliconcompiler-0.26.5.dist-info/entry_points.txt +12 -0
  251. 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