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,88 @@
1
+ import os
2
+ from siliconcompiler import SiliconCompilerError
3
+ from siliconcompiler.tools.vpr import vpr
4
+ from siliconcompiler.tools._common import get_tool_task
5
+
6
+
7
+ def setup(chip, clobber=True):
8
+ '''
9
+ Show placed and/or routed designs in VPR GUI
10
+ '''
11
+
12
+ tool = 'vpr'
13
+ step = chip.get('arg', 'step')
14
+ index = chip.get('arg', 'index')
15
+ _, task = get_tool_task(chip, step, index)
16
+
17
+ vpr.setup_tool(chip, clobber=clobber)
18
+
19
+ chip.set('tool', tool, 'task', task, 'threads', os.cpu_count(),
20
+ step=step, index=index, clobber=False)
21
+
22
+
23
+ def runtime_options(chip):
24
+ '''Command line options to vpr for show
25
+ '''
26
+
27
+ options = generic_show_options(chip)
28
+
29
+ options.append('--disp on')
30
+
31
+ return options
32
+
33
+
34
+ def generic_show_options(chip):
35
+ ''' Helper function to setup options for show and screenshot
36
+ '''
37
+
38
+ design = chip.top()
39
+
40
+ step = chip.get('arg', 'step')
41
+ index = chip.get('arg', 'index')
42
+ tool, task = get_tool_task(chip, step, index)
43
+
44
+ options = vpr.runtime_options(chip)
45
+
46
+ file_path = chip.get('tool', tool, 'task', task, 'var', 'show_filepath',
47
+ step=step, index=index)
48
+ if not file_path:
49
+ raise SiliconCompilerError("Please provide a place or route file", chip=chip)
50
+
51
+ if os.path.exists(file_path[0]):
52
+ file_dir = os.path.dirname(file_path[0])
53
+ blif_file = os.path.join(file_dir, f'{design}.blif')
54
+ net_file = os.path.join(file_dir, f'{design}.net')
55
+ place_file = os.path.join(file_dir, f'{design}.place')
56
+ route_file = os.path.join(file_dir, f'{design}.route')
57
+ else:
58
+ raise SiliconCompilerError("Invalid filepath", chip=chip)
59
+
60
+ if os.path.exists(blif_file):
61
+ options.append(blif_file)
62
+ else:
63
+ raise SiliconCompilerError("Blif file does not exist", chip=chip)
64
+
65
+ if os.path.exists(net_file):
66
+ options.append(f'--net_file {net_file}')
67
+ else:
68
+ raise SiliconCompilerError("Net file does not exist", chip=chip)
69
+
70
+ if os.path.exists(route_file) and os.path.exists(place_file):
71
+ options.append('--analysis')
72
+ options.append(f'--place_file {place_file}')
73
+ options.append(f'--route_file {route_file}')
74
+ elif os.path.exists(place_file):
75
+ # NOTE: This is a workaround to display the VPR GUI on the output of the place step.
76
+ # VPR GUI can be invoked during the place, route or analysis steps - not after they are run.
77
+ # Analysis can only be run after route. Hence, the only way to display the output
78
+ # of the is to run the route step. Performing routing could take a significant amount
79
+ # of time, which would not be useful if the user is simply looking to visualize
80
+ # the placed design. Setting max_router_iterations to 0 avoids running routing iterations
81
+ # and provides a fast way to invoke VPR GUI on the placed design.
82
+ options.append('--route')
83
+ options.append('--max_router_iterations 0')
84
+ options.append(f'--place_file {place_file}')
85
+ else:
86
+ raise SiliconCompilerError("Place file does not exist", chip=chip)
87
+
88
+ return options
@@ -0,0 +1,357 @@
1
+ '''
2
+ VPR (Versatile Place and Route) is an open source CAD
3
+ tool designed for the exploration of new FPGA architectures and
4
+ CAD algorithms, at the packing, placement and routing phases of
5
+ the CAD flow. VPR takes, as input, a description of an FPGA
6
+ architecture along with a technology-mapped user circuit. It
7
+ then performs packing, placement, and routing to map the
8
+ circuit onto the FPGA. The output of VPR includes the FPGA
9
+ configuration needed to implement the circuit and statistics about
10
+ the final mapped design (eg. critical path delay, area, etc).
11
+
12
+ Documentation: https://docs.verilogtorouting.org/en/latest
13
+
14
+ Sources: https://github.com/verilog-to-routing/vtr-verilog-to-routing
15
+
16
+ Installation: https://github.com/verilog-to-routing/vtr-verilog-to-routing
17
+ '''
18
+
19
+ import os
20
+ import shutil
21
+ import json
22
+ import re
23
+ from siliconcompiler import sc_open, SiliconCompilerError
24
+ from siliconcompiler.tools._common import get_tool_task, record_metric
25
+
26
+
27
+ __block_file = "reports/block_usage.json"
28
+
29
+
30
+ ######################################################################
31
+ # Make Docs
32
+ ######################################################################
33
+ def make_docs(chip):
34
+ chip.set('fpga', 'partname', 'example_arch_X005Y005')
35
+ chip.load_target("fpgaflow_demo")
36
+ setup_tool(chip)
37
+ return chip
38
+
39
+
40
+ def setup_tool(chip, clobber=True):
41
+
42
+ chip.set('tool', 'vpr', 'exe', 'vpr', clobber=clobber)
43
+ chip.set('tool', 'vpr', 'vswitch', '--version')
44
+ chip.set('tool', 'vpr', 'version', '>=8.1.0', clobber=clobber)
45
+
46
+ step = chip.get('arg', 'step')
47
+ index = chip.get('arg', 'index')
48
+ tool, task = get_tool_task(chip, step, index)
49
+ chip.set('tool', tool, 'task', task, 'regex', 'warnings', "^Warning",
50
+ step=step, index=index, clobber=False)
51
+ chip.set('tool', tool, 'task', task, 'regex', 'errors', "^Error",
52
+ step=step, index=index, clobber=False)
53
+
54
+ chip.set('tool', tool, 'task', task, 'var', 'enable_images', 'true',
55
+ step=step, index=index, clobber=False)
56
+ chip.set('tool', tool, 'task', task, 'var', 'enable_images',
57
+ 'true/false generate images of the design at the end of the task', field='help')
58
+
59
+ part_name = chip.get('fpga', 'partname')
60
+ for resource in ('vpr_registers', 'vpr_brams', 'vpr_dsps'):
61
+ if not chip.valid('fpga', part_name, 'var', resource):
62
+ continue
63
+ if not chip.get('fpga', part_name, 'var', resource):
64
+ continue
65
+ chip.add('tool', tool, 'task', task, 'require', f'fpga,{part_name},var,{resource}',
66
+ step=step, index=index)
67
+
68
+
69
+ def runtime_options(chip):
70
+
71
+ part_name = chip.get('fpga', 'partname')
72
+ step = chip.get('arg', 'step')
73
+ index = chip.get('arg', 'index')
74
+ tool, task = get_tool_task(chip, step, index)
75
+
76
+ options = []
77
+
78
+ options.append(f"--write_block_usage {__block_file}")
79
+ options.append("--outfile_prefix outputs/")
80
+
81
+ if chip.valid('fpga', part_name, 'file', 'archfile') and \
82
+ chip.get('fpga', part_name, 'file', 'archfile'):
83
+
84
+ archs = chip.find_files('fpga', part_name, 'file', 'archfile',
85
+ step=None, index=None)
86
+
87
+ else:
88
+ archs = []
89
+
90
+ if (len(archs) == 1):
91
+ options.append(archs[0])
92
+ elif (len(archs) == 0):
93
+ raise SiliconCompilerError(
94
+ "VPR requires an architecture file as one of its command line arguments",
95
+ chip=chip)
96
+ else:
97
+ raise SiliconCompilerError(
98
+ "Only one architecture XML file can be passed to VPR", chip=chip)
99
+
100
+ threads = chip.get('tool', tool, 'task', task, 'threads', step=step, index=index)
101
+ options.append(f"--num_workers {threads}")
102
+
103
+ # For most architectures, constant nets need to be routed
104
+ # like regular nets to be functionally correct (however inefficient
105
+ # that might be...); these two options help control that
106
+ options.append('--constant_net_method route')
107
+ options.append('--const_gen_inference none')
108
+
109
+ # If we allow VPR to sweep dangling primary I/Os and logic blocks
110
+ # it can interfere with circuit debugging; so disable that
111
+ options.append('--sweep_dangling_primary_ios off')
112
+ options.append('--sweep_constant_primary_outputs off')
113
+ options.append('--sweep_dangling_blocks off')
114
+
115
+ # Explicitly specify the clock modeling type in the part driver
116
+ # to avoid ambiguity and future-proof against new VPR clock models
117
+ clock_model = chip.get('fpga', part_name, 'var', 'vpr_clock_model')
118
+ if not clock_model:
119
+ raise SiliconCompilerError(f'no clock model defined for {part_name}', chip=chip)
120
+ else:
121
+ selected_clock_model = clock_model[0]
122
+ # When dedicated networks are used, tell VPR to use the two-stage router,
123
+ # otherwise not.
124
+ if (selected_clock_model == 'ideal'):
125
+ options.append(f'--clock_modeling {selected_clock_model}')
126
+ elif (selected_clock_model == 'route'):
127
+ options.append(f'--clock_modeling {selected_clock_model}')
128
+ elif (selected_clock_model == 'dedicated_network'):
129
+ options.append(f'--clock_modeling {selected_clock_model}')
130
+ options.append('--two_stage_clock_routing')
131
+ else:
132
+ raise SiliconCompilerError(
133
+ 'vpr_clock model must be set to ideal, route, or dedicated_clock_network',
134
+ chip=chip)
135
+
136
+ if 'sdc' in chip.getkeys('input', 'constraint'):
137
+ sdc_file = find_single_file(chip, 'input', 'constraint', 'sdc',
138
+ step=step, index=index,
139
+ file_not_found_msg="SDC file not found")
140
+ if (sdc_file is not None):
141
+ sdc_arg = f"--sdc_file {sdc_file}"
142
+ options.append(sdc_arg)
143
+ else:
144
+ options.append("--timing_analysis off")
145
+
146
+ # Per the scheme implemented in the placement pre-process step,
147
+ # if a constraints file exists it will always be in the auto_constraints()
148
+ # location:
149
+ if (os.path.isfile(auto_constraints())):
150
+ pin_constraint_arg = f"--read_vpr_constraints {auto_constraints()}"
151
+ options.append(pin_constraint_arg)
152
+
153
+ # Routing graph XML:
154
+ rr_graph = find_single_file(chip, 'fpga', part_name, 'file', 'graphfile',
155
+ step=None, index=None,
156
+ file_not_found_msg="VPR RR Graph not found")
157
+ if (rr_graph is None):
158
+ chip.logger.info("No VPR RR graph file specified")
159
+ chip.logger.info("Routing architecture will come from architecture XML file")
160
+ else:
161
+ options.append("--read_rr_graph " + rr_graph)
162
+
163
+ # ***NOTE: For real FPGA chips you need to specify the routing channel
164
+ # width explicitly. VPR requires an explicit routing channel
165
+ # with when --read_rr_graph is used (typically the case for
166
+ # real chips). Otherwise VPR performs a binary search for
167
+ # the minimum routing channel width that the circuit fits in.
168
+ # Given the above, it may be appropriate to couple these variables somehow,
169
+ # but --route_chan_width CAN be used by itself.
170
+ num_routing_channels = chip.get('fpga', part_name, 'var', 'channelwidth')
171
+
172
+ if (len(num_routing_channels) == 0):
173
+ raise SiliconCompilerError("Number of routing channels not specified", chip=chip)
174
+ elif (len(num_routing_channels) == 1):
175
+ options.append("--route_chan_width " + num_routing_channels[0])
176
+ elif (len(num_routing_channels) > 1):
177
+ raise SiliconCompilerError(
178
+ "Only one routing channel width argument can be passed to VPR", chip=chip)
179
+
180
+ return options
181
+
182
+
183
+ ############################
184
+ # Get common graphics files
185
+ ############################
186
+
187
+ def get_common_graphics(chip):
188
+
189
+ design = chip.top()
190
+
191
+ graphics_commands = []
192
+
193
+ # set_draw_block_text 1 displays the label for various blocks in the design
194
+ # set_draw_block_outlines 1 displays the outline/boundary for various blocks in the design
195
+ # save_graphics saves the block diagram as a png/svg/pdf
196
+ # Refer: https://docs.verilogtorouting.org/en/latest/vpr/command_line_usage/#graphics-options
197
+ graphics_commands.append("set_draw_block_text 1; " +
198
+ "set_draw_block_outlines 1; " +
199
+ f"save_graphics reports/{design}_place.png;")
200
+
201
+ return graphics_commands
202
+
203
+
204
+ ################################
205
+ # Wrapper around find files to
206
+ # help with error checking that
207
+ # only a single file is found
208
+ ################################
209
+
210
+ def find_single_file(chip, *keypath, step=None, index=None, file_not_found_msg="File not found"):
211
+
212
+ if chip.valid(*keypath) and chip.get(*keypath, step=step, index=index):
213
+ file_list = chip.find_files(*keypath, step=step, index=index)
214
+ else:
215
+ file_list = []
216
+
217
+ if (len(file_list) == 1):
218
+ return file_list[0]
219
+ elif (len(file_list) == 0):
220
+ chip.logger.info(file_not_found_msg)
221
+ return None
222
+ else:
223
+ raise SiliconCompilerError("Only one file of this type can be passed to VPR", chip=chip)
224
+
225
+
226
+ ################################
227
+ # Version Check
228
+ ################################
229
+
230
+
231
+ def parse_version(stdout):
232
+
233
+ # Example output of vpr --version:
234
+ # Note that blank comment lines in this example
235
+ # represent newlines printed by vpr --version
236
+
237
+ # VPR FPGA Placement and Routing.
238
+ # Version: 8.1.0-dev+c4156f225
239
+ # Revision: v8.0.0-7887-gc4156f225
240
+ # Compiled: 2023-06-14T17:32:05
241
+ # Compiler: GNU 9.4.0 on Linux-5.14.0-1059-oem x86_64
242
+ # Build Info: release IPO VTR_ASSERT_LEVEL=2
243
+ #
244
+ # University of Toronto
245
+ # verilogtorouting.org
246
+ # vtr-users@googlegroups.com
247
+ # This is free open source code under MIT license.
248
+ #
249
+ #
250
+ return stdout.split()[6]
251
+
252
+
253
+ def normalize_version(version):
254
+ if '-' in version:
255
+ return version.split('-')[0]
256
+ else:
257
+ return version
258
+
259
+
260
+ def auto_constraints():
261
+ return 'inputs/sc_constraints.xml'
262
+
263
+
264
+ def vpr_post_process(chip):
265
+ step = chip.get('arg', 'step')
266
+ index = chip.get('arg', 'index')
267
+
268
+ if os.path.exists('packing_pin_util.rpt'):
269
+ shutil.move('packing_pin_util.rpt', 'reports')
270
+
271
+ part_name = chip.get('fpga', 'partname')
272
+ dff_cells = []
273
+ if chip.valid('fpga', part_name, 'var', 'vpr_registers'):
274
+ dff_cells = chip.get('fpga', part_name, 'var', 'vpr_registers')
275
+ brams_cells = []
276
+ if chip.valid('fpga', part_name, 'var', 'vpr_brams'):
277
+ brams_cells = chip.get('fpga', part_name, 'var', 'vpr_brams')
278
+ dsps_cells = []
279
+ if chip.valid('fpga', part_name, 'var', 'vpr_dsps'):
280
+ dsps_cells = chip.get('fpga', part_name, 'var', 'vpr_dsps')
281
+
282
+ stat_extract = re.compile(r' \s*(.*)\s*:\s*([0-9]+)')
283
+ lut_match = re.compile(r'([0-9]+)-LUT')
284
+ route_length = re.compile(r' Total wirelength: ([0-9]+)')
285
+ log_file = f'{step}.log'
286
+ mdata = {
287
+ "registers": 0,
288
+ "luts": 0,
289
+ "dsps": 0,
290
+ "brams": 0
291
+ }
292
+ with sc_open(log_file) as f:
293
+ in_stats = False
294
+ for line in f:
295
+ if in_stats:
296
+ if not line.startswith(" "):
297
+ in_stats = False
298
+ continue
299
+ data = stat_extract.findall(line)
300
+ if data:
301
+ dtype, value = data[0]
302
+ dtype = dtype.strip()
303
+ value = int(value)
304
+
305
+ if dtype == "Blocks":
306
+ record_metric(chip, step, index, "cells", value, log_file)
307
+ elif dtype == "Nets":
308
+ record_metric(chip, step, index, "nets", value, log_file)
309
+ elif dtype in dff_cells:
310
+ mdata["registers"] += value
311
+ elif dtype in dsps_cells:
312
+ mdata["dsps"] += value
313
+ elif dtype in brams_cells:
314
+ mdata["brams"] += value
315
+ else:
316
+ lut_type = lut_match.findall(dtype)
317
+ if lut_type:
318
+ if int(lut_type[0]) == 0:
319
+ pass
320
+ else:
321
+ mdata["luts"] += value
322
+ else:
323
+ if line.startswith("Circuit Statistics:"):
324
+ in_stats = True
325
+ route_len_data = route_length.findall(line)
326
+ if route_len_data:
327
+ # Fake the unit since this is meaningless for the FPGA
328
+ units = chip.get('metric', 'wirelength', field='unit')
329
+ record_metric(chip, step, index, 'wirelength',
330
+ int(route_len_data[0]),
331
+ log_file,
332
+ source_unit=units)
333
+
334
+ for metric, value in mdata.items():
335
+ record_metric(chip, step, index, metric, value, log_file)
336
+
337
+ if os.path.exists(__block_file):
338
+ with sc_open(__block_file) as f:
339
+ data = json.load(f)
340
+
341
+ if "num_nets" in data and chip.get('metric', 'nets', step=step, index=index) is None:
342
+ record_metric(chip, step, index, "nets", int(data["num_nets"]), __block_file)
343
+
344
+ io = 0
345
+ if "input_pins" in data:
346
+ io += int(data["input_pins"])
347
+ if "output_pins" in data:
348
+ io += int(data["output_pins"])
349
+
350
+ record_metric(chip, step, index, "pins", io, __block_file)
351
+
352
+
353
+ ##################################################
354
+ if __name__ == "__main__":
355
+
356
+ chip = make_docs()
357
+ chip.write_manifest("vpr.json")
@@ -0,0 +1,36 @@
1
+ '''
2
+ Xyce is a high performance SPICE-compatible circuit simulator
3
+ capable capable of solving extremely large circuit problems by
4
+ supporting large-scale parallel computing platforms. It also
5
+ supports serial execution on all common desktop platforms,
6
+ and small-scale parallel runs on Unix-like systems.
7
+
8
+ Documentation: https://xyce.sandia.gov/documentation-tutorials/
9
+
10
+ Sources: https://github.com/Xyce/Xyce
11
+
12
+ Installation: https://xyce.sandia.gov/documentation-tutorials/building-guide/
13
+
14
+ Status: SC integration WIP
15
+ '''
16
+
17
+ import os
18
+ from siliconcompiler.tools._common import get_tool_task
19
+
20
+
21
+ ################################
22
+ # Setup Tool (pre executable)
23
+ ################################
24
+ def setup(chip):
25
+
26
+ tool = 'xyce'
27
+ step = chip.get('arg', 'step')
28
+ index = chip.get('arg', 'index')
29
+ _, task = get_tool_task(chip, step, index)
30
+
31
+ clobber = False
32
+
33
+ chip.set('tool', tool, 'exe', tool)
34
+ chip.set('tool', tool, 'version', '0.0', clobber=clobber)
35
+ chip.set('tool', tool, 'task', task, 'threads', os.cpu_count(),
36
+ step=step, index=index, clobber=clobber)
@@ -0,0 +1,56 @@
1
+ import re
2
+
3
+ from siliconcompiler.tools.yosys.yosys import setup as setup_tool
4
+ from siliconcompiler.tools.yosys.syn_asic import setup_asic
5
+ from siliconcompiler import sc_open
6
+ from siliconcompiler.tools._common import get_tool_task, record_metric
7
+
8
+
9
+ def setup(chip):
10
+ '''
11
+ Perform logical equivalence checks
12
+ '''
13
+
14
+ # Generic tool setup.
15
+ setup_tool(chip)
16
+
17
+ # Generic setup.
18
+ setup_asic(chip)
19
+
20
+ tool = 'yosys'
21
+ step = chip.get('arg', 'step')
22
+ index = chip.get('arg', 'index')
23
+ _, task = get_tool_task(chip, step, index)
24
+ design = chip.top()
25
+
26
+ # Set yosys script path.
27
+ chip.set('tool', tool, 'task', task, 'script', 'sc_lec.tcl',
28
+ step=step, index=index, clobber=False)
29
+
30
+ # Input/output requirements.
31
+ if not chip.valid('input', 'netlist', 'verilog') or \
32
+ not chip.get('input', 'netlist', 'verilog', step=step, index=index):
33
+ chip.set('tool', tool, 'task', task, 'input', design + '.vg', step=step, index=index)
34
+ # if not chip.get('input', 'rtl', 'verilog'):
35
+ # TODO: Not sure this logic makes sense? Seems like reverse of tcl
36
+ # chip.set('tool', tool, 'task', task, 'input', design + '.v', step=step, index=index)
37
+
38
+
39
+ ##################################################
40
+ def post_process(chip):
41
+ ''' Tool specific function to run after step execution
42
+ '''
43
+
44
+ step = chip.get('arg', 'step')
45
+ index = chip.get('arg', 'index')
46
+
47
+ with sc_open(step + ".log") as f:
48
+ for line in f:
49
+ if line.endswith('Equivalence successfully proven!\n'):
50
+ record_metric(chip, step, index, 'drvs', 0, step + ".log")
51
+ continue
52
+
53
+ errors = re.search(r'Found a total of (\d+) unproven \$equiv cells.', line)
54
+ if errors is not None:
55
+ num_errors = int(errors.group(1))
56
+ record_metric(chip, step, index, 'drvs', num_errors, step + ".log")
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env python3
2
+ # Based on https://github.com/The-OpenROAD-Project/OpenROAD-flow-scripts/blob/84545863573a90bca3612298361adb35bf39e692/flow/util/markDontUse.py # noqa E501
3
+
4
+ import re
5
+ import gzip
6
+ import argparse # argument parsing
7
+
8
+
9
+ def processLibertyFile(input_file, logger=None):
10
+ # Read input file
11
+ if logger:
12
+ logger.info(f"Opening file for replace: {input_file}")
13
+ if input_file.endswith(".gz") or input_file.endswith(".GZ"):
14
+ f = gzip.open(input_file, 'rt', encoding="utf-8")
15
+ else:
16
+ f = open(input_file, encoding="utf-8")
17
+ content = f.read().encode("ascii", "ignore").decode("ascii")
18
+ f.close()
19
+
20
+ # Yosys-abc throws an error if original_pin is found within the liberty file.
21
+ # removing
22
+ pattern = r"(.*original_pin.*)"
23
+ replace = r"/* \1 */;"
24
+ content, count = re.subn(pattern, replace, content)
25
+ if logger:
26
+ logger.info(f"Commented {count} lines containing \"original_pin\"")
27
+
28
+ # Yosys, does not like properties that start with : !, without quotes
29
+ pattern = r":\s+(!.*)\s+;"
30
+ replace = r': "\1" ;'
31
+ content, count = re.subn(pattern, replace, content)
32
+ if logger:
33
+ logger.info(f"Replaced malformed functions {count}")
34
+
35
+ # Yosys-abc throws an error if the units are specified in 0.001pf, instead of 1ff
36
+ pattern = r"capacitive_load_unit\s+\(0.001,pf\);"
37
+ replace = "capacitive_load_unit (1,ff);"
38
+ content, count = re.subn(pattern, replace, content)
39
+ if logger:
40
+ logger.info(f"Replaced capacitive load {count}")
41
+
42
+ # Return new text
43
+ return content
44
+
45
+
46
+ if __name__ == "__main__":
47
+ # Parse and validate arguments
48
+ # ==============================================================================
49
+ parser = argparse.ArgumentParser(
50
+ description='Replaces occurrences of cells in def or verilog files')
51
+ parser.add_argument('--patterns', '-p', required=True,
52
+ help='List of search patterns')
53
+ parser.add_argument('--inputFile', '-i', required=True,
54
+ help='Input File')
55
+ parser.add_argument('--outputFile', '-o', required=True,
56
+ help='Output File')
57
+ args = parser.parse_args()
58
+
59
+ processLibertyFile(args.inputFile, args.outputFile, args.patterns)
@@ -0,0 +1,84 @@
1
+ # Script adapted from
2
+ # https://github.com/The-OpenROAD-Project/OpenLane/blob/d052a918f4a46ddbae0ad09812f6cd0b8eb4a1e5/scripts/logic_equiv_check.tcl
3
+
4
+ source ./sc_manifest.tcl
5
+ set sc_tool yosys
6
+ yosys echo on
7
+
8
+ #Handling remote/local script execution
9
+ set sc_step [sc_cfg_get arg step]
10
+ set sc_index [sc_cfg_get arg index]
11
+ set sc_flow [sc_cfg_get option flow]
12
+ set sc_task [sc_cfg_get flowgraph $sc_flow $sc_step $sc_index task]
13
+ set sc_refdir [sc_cfg_tool_task_get refdir ]
14
+
15
+ set sc_design [sc_top]
16
+ set sc_targetlibs [sc_get_asic_libraries logic]
17
+
18
+ # TODO: properly handle complexity here
19
+ set lib [lindex $sc_targetlibs 0]
20
+ set sc_delaymodel [sc_cfg_get asic delaymodel]
21
+ set sc_scenarios [dict keys [sc_cfg_get constraint timing]]
22
+ set sc_libcorner [sc_cfg_get constraint timing [lindex $sc_scenarios 0] libcorner]
23
+ set sc_liberty [sc_cfg_get library $lib output $sc_libcorner $sc_delaymodel]
24
+
25
+ if { [sc_cfg_tool_task_exists "variable" induction_steps] } {
26
+ set sc_induction_steps \
27
+ [lindex [sc_cfg_tool_task_get "variable" induction_steps] 0]
28
+ } else {
29
+ # Yosys default
30
+ set sc_induction_steps 4
31
+ }
32
+
33
+ # Gold netlist
34
+ yosys read_liberty -ignore_miss_func $sc_liberty
35
+ if { [file exists "inputs/$sc_design.v"] } {
36
+ set source "inputs/$sc_design.v"
37
+ } else {
38
+ set source [lindex [sc_cfg_get input rtl verilog] 0]
39
+ }
40
+ yosys read_verilog $source
41
+
42
+ yosys proc
43
+ yosys rmports
44
+ yosys splitnets -ports
45
+ yosys hierarchy -auto-top
46
+ yosys flatten
47
+
48
+ yosys setattr -set keep 1
49
+ yosys stat
50
+ yosys rename -top gold
51
+ yosys design -stash gold
52
+
53
+ # Gate netlist
54
+ yosys read_liberty -ignore_miss_func $sc_liberty
55
+ if { [sc_cfg_exists input netlist verilog] } {
56
+ set netlist [lindex [sc_cfg_get input netlist verilog] 0]
57
+ } else {
58
+ set netlist "inputs/$sc_design.vg"
59
+ }
60
+ yosys read_verilog $netlist
61
+
62
+ yosys proc
63
+ yosys rmports
64
+ yosys splitnets -ports
65
+ yosys hierarchy -auto-top
66
+ yosys flatten
67
+
68
+ yosys setattr -set keep 1
69
+ yosys stat
70
+ yosys rename -top gate
71
+ yosys design -stash gate
72
+
73
+ yosys design -copy-from gold -as gold gold
74
+ yosys design -copy-from gate -as gate gate
75
+
76
+ # Rebuild the database due to -stash
77
+ yosys read_liberty -ignore_miss_func $sc_liberty
78
+
79
+ yosys equiv_make gold gate equiv
80
+
81
+ yosys setattr -set keep 1
82
+ yosys prep -flatten -top equiv
83
+ yosys equiv_induct -seq $sc_induction_steps
84
+ yosys equiv_status