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,137 @@
1
+ #############################################
2
+ #!!!! AUTO-GENERATED FILE. DO NOT EDIT!!!!!!
3
+ #############################################
4
+
5
+ #############################################
6
+ # Manifest
7
+ #############################################
8
+ {{ manifest_dict }}
9
+
10
+ #############################################
11
+ # Helper functions
12
+ #############################################
13
+
14
+ # Shortcut to get values from configuration
15
+ proc sc_cfg_get { args } {
16
+ # Refer to global sc_cfg dictionary
17
+ global sc_cfg
18
+
19
+ if { ![sc_cfg_exists {*}$args] } {
20
+ throw {FLOW KEYERROR} "key \"$args\" is not in the siliconcompiler configuration"
21
+ }
22
+
23
+ return [dict get $sc_cfg {*}$args]
24
+ }
25
+
26
+ proc sc_cfg_exists { args } {
27
+ # Refer to global sc_cfg dictionary
28
+ global sc_cfg
29
+
30
+ return [dict exists $sc_cfg {*}$args]
31
+ }
32
+
33
+ proc sc_top {} {
34
+ set sc_entrypoint [sc_cfg_get option entrypoint]
35
+ if {$sc_entrypoint == ""} {
36
+ return [sc_cfg_get design]
37
+ }
38
+ return $sc_entrypoint
39
+ }
40
+
41
+ proc sc_root {} {
42
+ return "{{ scroot }}"
43
+ }
44
+
45
+ # Shortcut to get tool vars
46
+ proc sc_cfg_tool_task_get { args } {
47
+ set sc_step [sc_cfg_get arg step]
48
+ set sc_index [sc_cfg_get arg index]
49
+
50
+ set sc_flow [sc_cfg_get option flow]
51
+
52
+ set sc_task [sc_cfg_get flowgraph $sc_flow $sc_step $sc_index task]
53
+ set sc_tool [sc_cfg_get flowgraph $sc_flow $sc_step $sc_index tool]
54
+
55
+ return [sc_cfg_get tool $sc_tool task $sc_task {*}$args]
56
+ }
57
+
58
+ proc sc_cfg_tool_task_exists { args } {
59
+ set sc_step [sc_cfg_get arg step]
60
+ set sc_index [sc_cfg_get arg index]
61
+
62
+ set sc_flow [sc_cfg_get option flow]
63
+
64
+ set sc_task [sc_cfg_get flowgraph $sc_flow $sc_step $sc_index task]
65
+ set sc_tool [sc_cfg_get flowgraph $sc_flow $sc_step $sc_index tool]
66
+
67
+ return [sc_cfg_exists tool $sc_tool task $sc_task {*}$args]
68
+ }
69
+
70
+ # Check if an item is present in a list
71
+ proc sc_cfg_tool_task_check_in_list { item args } {
72
+ set result [sc_cfg_tool_task_get {*}$args]
73
+
74
+ if { [lsearch -exact $result $item] != -1 } {
75
+ return 1
76
+ } else {
77
+ return 0
78
+ }
79
+ }
80
+
81
+ proc sc_section_banner { text { method puts } } {
82
+ $method "============================================================"
83
+ $method "| $text"
84
+ $method "============================================================"
85
+ }
86
+
87
+ # Get list of soft libraries
88
+ proc sc_get_libraries { {library {}} {libraries {}} } {
89
+ set key []
90
+ if { [llength $library] != 0 } {
91
+ lappend key library $library
92
+ }
93
+ lappend key option library
94
+
95
+ set libs []
96
+ foreach lib [sc_cfg_get {*}$key] {
97
+ if { [lsearch -exact $libs $lib] != -1 || [lsearch -exact $libraries $lib] != -1 } {
98
+ continue
99
+ }
100
+
101
+ lappend libs $lib
102
+
103
+ foreach sublib [sc_get_libraries $lib $libs] {
104
+ lappend libs $sublib
105
+ }
106
+ }
107
+
108
+ return [lsort -unique $libs]
109
+ }
110
+
111
+ # Get list of asic libraries
112
+ proc sc_get_asic_libraries { type } {
113
+ set libs []
114
+
115
+ foreach lib [sc_cfg_get asic ${type}lib] {
116
+ if { [lsearch -exact $libs $lib] != -1 } {
117
+ continue
118
+ }
119
+ lappend libs $lib
120
+ }
121
+
122
+ foreach lib [sc_get_libraries] {
123
+ if { ![sc_cfg_exists library $lib asic ${type}lib] } {
124
+ continue
125
+ }
126
+
127
+ foreach sublib [sc_cfg_get library $lib asic ${type}lib] {
128
+ if { [lsearch -exact $libs $sublib] != -1 } {
129
+ continue
130
+ }
131
+
132
+ lappend libs $sublib
133
+ }
134
+ }
135
+
136
+ return $libs
137
+ }
File without changes
@@ -0,0 +1,432 @@
1
+ import os
2
+ import pkgutil
3
+
4
+
5
+ def get_libraries(chip, include_asic=True, library=None, libraries=None):
6
+ '''
7
+ Returns a list of libraries included in this step/index
8
+
9
+ Args:
10
+ chip (Chip): Chip object
11
+ include_asic (bool): include the asic libraries.
12
+ '''
13
+ step = chip.get('arg', 'step')
14
+ index = chip.get('arg', 'index')
15
+
16
+ libs = []
17
+
18
+ if not libraries:
19
+ libraries = set()
20
+
21
+ pref_key = []
22
+ if library:
23
+ pref_key = ['library', library]
24
+
25
+ def get_libs(*key):
26
+ if chip.valid(*key) and chip.get(*key, step=step, index=index):
27
+ return chip.get(*key, step=step, index=index)
28
+ return []
29
+
30
+ if include_asic:
31
+ libs.extend(get_libs(*pref_key, 'asic', 'logiclib'))
32
+ libs.extend(get_libs(*pref_key, 'asic', 'macrolib'))
33
+
34
+ for lib in get_libs(*pref_key, 'option', 'library'):
35
+ if lib in libs or lib in libraries:
36
+ continue
37
+ libs.append(lib)
38
+ libs.extend(get_libraries(chip, include_asic=include_asic, library=lib, libraries=libs))
39
+
40
+ return set(libs)
41
+
42
+
43
+ def add_require_input(chip, *key, include_library_files=True):
44
+ '''
45
+ Adds input files to the require list of the task.
46
+
47
+ Args:
48
+ chip (Chip): Chip object
49
+ key (list): Key to check for requirements
50
+ add_library_files (bool): When True, files from library keys
51
+ will be included
52
+ '''
53
+ step = chip.get('arg', 'step')
54
+ index = chip.get('arg', 'index')
55
+ tool, task = get_tool_task(chip, step, index)
56
+
57
+ keys = []
58
+ for key in __get_keys(chip, *key, include_library_files=False):
59
+ keys.append(key)
60
+
61
+ if include_library_files:
62
+ for item in get_libraries(chip, include_asic=False):
63
+ lib_key = ('library', item, *key)
64
+ if __is_key_valid(chip, *lib_key):
65
+ keys.append(lib_key)
66
+
67
+ for key in keys:
68
+ chip.add('tool', tool, 'task', task, 'require',
69
+ ",".join(key),
70
+ step=step, index=index)
71
+
72
+
73
+ def get_input_files(chip, *key, add_library_files=True):
74
+ '''
75
+ Returns a list of files from the key input and includes files
76
+ from libraries if requested.
77
+
78
+ Args:
79
+ chip (Chip): Chip object
80
+ key (list): Key to collect files from
81
+ add_library_files (bool): When True, files from library keys
82
+ will be included
83
+ '''
84
+ step = chip.get('arg', 'step')
85
+ index = chip.get('arg', 'index')
86
+
87
+ files = []
88
+ for key in __get_keys(chip, *key, include_library_files=False):
89
+ files.extend(chip.find_files(*key, step=step, index=index))
90
+
91
+ if add_library_files:
92
+ for item in get_libraries(chip, include_asic=False):
93
+ lib_key = ('library', item, *key)
94
+ if __is_key_valid(chip, *lib_key):
95
+ files.extend(chip.find_files(*lib_key, step=step, index=index))
96
+
97
+ return __remove_duplicates(chip, files, list(key))
98
+
99
+
100
+ def has_input_files(chip, *key, check_library_files=True):
101
+ '''
102
+ Returns true if the specified key is set.
103
+
104
+ Args:
105
+ chip (Chip): Chip object
106
+ key (list): Key to check
107
+ check_library_files (bool): When True, files from library keys
108
+ will be checked
109
+ '''
110
+ if __get_keys(chip, *key, include_library_files=check_library_files):
111
+ return True
112
+
113
+ return False
114
+
115
+
116
+ def __remove_duplicates(chip, values, type):
117
+ new_values = []
118
+ for v in values:
119
+ if v not in new_values:
120
+ new_values.append(v)
121
+ else:
122
+ chip.logger.warning(f"Removing duplicate {type}: {v}")
123
+ return new_values
124
+
125
+
126
+ def __get_step_index(chip, *key):
127
+ step = chip.get('arg', 'step')
128
+ index = chip.get('arg', 'index')
129
+
130
+ if chip.get(*key, field='pernode') == 'never':
131
+ step = None
132
+ index = None
133
+
134
+ return step, index
135
+
136
+
137
+ def __is_key_valid(chip, *key):
138
+ if chip.valid(*key):
139
+ step, index = __get_step_index(chip, *key)
140
+ if chip.get(*key, step=step, index=index):
141
+ return True
142
+ return False
143
+
144
+
145
+ def __get_keys(chip, *key, include_library_files=True):
146
+ keys = []
147
+ if __is_key_valid(chip, *key):
148
+ keys.append(key)
149
+
150
+ if include_library_files:
151
+ for item in get_libraries(chip):
152
+ lib_key = ['library', item, *key]
153
+ if __is_key_valid(chip, *lib_key):
154
+ keys.append(tuple(lib_key))
155
+
156
+ return keys
157
+
158
+
159
+ def __assert_support(chip, opt_keys, supports):
160
+ from siliconcompiler import SiliconCompilerError
161
+
162
+ if not supports:
163
+ supports = []
164
+
165
+ step = chip.get('arg', 'step')
166
+ index = chip.get('arg', 'index')
167
+ tool, task = get_tool_task(chip, step, index)
168
+ for opt, vals in opt_keys.items():
169
+ val_list = ', '.join([str(list(v)) for v in vals])
170
+ if opt not in supports and val_list:
171
+ msg = f'{tool}/{task} does not support [\'option\', \'{opt}\']'
172
+ if len(vals) != 1 or len(vals[0]) != 2:
173
+ msg += f', the following values will be ignored: {val_list}'
174
+ pass
175
+ chip.logger.warning(msg)
176
+
177
+ for opt in supports:
178
+ if opt not in opt_keys:
179
+ raise SiliconCompilerError(
180
+ f'{tool}/{task} is requesting support for {opt}, which does not exist',
181
+ chip=chip)
182
+
183
+
184
+ def __get_frontend_option_keys(chip):
185
+ opts = {
186
+ 'ydir': __get_keys(chip, 'option', 'ydir'),
187
+ 'vlib': __get_keys(chip, 'option', 'vlib'),
188
+ 'idir': __get_keys(chip, 'option', 'idir'),
189
+ 'define': __get_keys(chip, 'option', 'define'),
190
+ 'libext': __get_keys(chip, 'option', 'libext'),
191
+ 'param': [] # Only from 'option', no libraries
192
+ }
193
+
194
+ for param in chip.getkeys('option', 'param'):
195
+ opts['param'].append(('option', 'param', param))
196
+
197
+ return opts
198
+
199
+
200
+ def add_frontend_requires(chip, supports=None):
201
+ '''
202
+ Adds keys to the require list for the frontend task and checks if
203
+ options are set, which the current frontend does not support.
204
+
205
+ Args:
206
+ chip (Chip): Chip object
207
+ supports (list): List of ['option', '*'] which the frontend supports
208
+ '''
209
+ opt_keys = __get_frontend_option_keys(chip)
210
+ __assert_support(chip, opt_keys, supports)
211
+
212
+ step = chip.get('arg', 'step')
213
+ index = chip.get('arg', 'index')
214
+ tool, task = get_tool_task(chip, step, index)
215
+ for opt in supports:
216
+ for key in opt_keys[opt]:
217
+ chip.add('tool', tool, 'task', task, 'require', ','.join(key), step=step, index=index)
218
+
219
+
220
+ def get_frontend_options(chip, supports=None):
221
+ '''
222
+ Returns a dictionary of options set for the frontend and checks if
223
+ options are set, which the current frontend does not support.
224
+
225
+ Args:
226
+ chip (Chip): Chip object
227
+ supports (list): List of ['option', '*'] which the frontend supports
228
+ '''
229
+ opt_keys = __get_frontend_option_keys(chip)
230
+ __assert_support(chip, opt_keys, supports)
231
+
232
+ params = opt_keys['param']
233
+ del opt_keys['param']
234
+
235
+ opts = {}
236
+ for opt, keys in opt_keys.items():
237
+ opts[opt] = []
238
+ for key in keys:
239
+ sc_type = chip.get(*key, field='type')
240
+ step, index = __get_step_index(chip, *key)
241
+ if 'file' in sc_type or 'dir' in sc_type:
242
+ opts[opt].extend(chip.find_files(*key, step=step, index=index))
243
+ else:
244
+ opts[opt].extend(chip.get(*key, step=step, index=index))
245
+
246
+ opts[opt] = __remove_duplicates(chip, opts[opt], ['option', opt])
247
+
248
+ opts['param'] = []
249
+ for key in params:
250
+ param = key[-1]
251
+ value = chip.get(*key)
252
+ opts['param'].append((param, value))
253
+
254
+ return opts
255
+
256
+
257
+ def find_incoming_ext(chip, support_exts, default_ext):
258
+ from siliconcompiler.utils import get_file_ext
259
+
260
+ step = chip.get('arg', 'step')
261
+ index = chip.get('arg', 'index')
262
+ flow = chip.get('option', 'flow')
263
+
264
+ for input_step, input_index in chip.get('flowgraph', flow, step, index, 'input'):
265
+ tool, task = get_tool_task(chip, input_step, input_index, flow=flow)
266
+ output_exts = {get_file_ext(f): f for f in chip.get('tool', tool, 'task', task, 'output',
267
+ step=input_step, index=input_index)}
268
+ # Search the supported order
269
+ for ext in support_exts:
270
+ if ext in output_exts:
271
+ if output_exts[ext].lower().endswith('.gz'):
272
+ return f'{ext}.gz'
273
+ return ext
274
+
275
+ for ext in support_exts:
276
+ for fileset in chip.getkeys('input'):
277
+ if chip.valid('input', fileset, ext):
278
+ return ext
279
+
280
+ # Nothing found return the default
281
+ return default_ext
282
+
283
+
284
+ def pick_key(chip, check_keys, step=None, index=None):
285
+ if not step:
286
+ step = chip.get('arg', 'step')
287
+ if not index:
288
+ index = chip.get('arg', 'index')
289
+
290
+ for key in check_keys:
291
+ if chip.valid(*key):
292
+ check_step = step
293
+ check_index = index
294
+
295
+ if chip.get(*key, field='pernode') == 'never':
296
+ check_step = None
297
+ check_index = None
298
+
299
+ check_value = chip.get(*key, step=check_step, index=check_index)
300
+ if check_value:
301
+ return key, check_value
302
+
303
+ return None, None
304
+
305
+
306
+ def input_provides(chip, step, index, flow=None):
307
+ from siliconcompiler import NodeStatus
308
+
309
+ if not flow:
310
+ flow = chip.get('option', 'flow')
311
+
312
+ nodes = chip.get('flowgraph', flow, step, index, 'input')
313
+ inputs = {}
314
+ for in_step, in_index in nodes:
315
+ if chip.get('record', 'status', step=in_step, index=in_index) == \
316
+ NodeStatus.SKIPPED:
317
+ for file, nodes in input_provides(chip, in_step, in_index, flow=flow).items():
318
+ inputs.setdefault(file, []).extend(nodes)
319
+ continue
320
+ tool, task = get_tool_task(chip, in_step, in_index, flow=flow)
321
+
322
+ for output in chip.get('tool', tool, 'task', task, 'output',
323
+ step=in_step, index=in_index):
324
+ inputs.setdefault(output, []).append((in_step, in_index))
325
+
326
+ return inputs
327
+
328
+
329
+ def input_file_node_name(filename, step, index):
330
+ from siliconcompiler.utils import get_file_ext
331
+
332
+ file_type = get_file_ext(filename)
333
+
334
+ base = filename
335
+ total_ext = []
336
+ ext = None
337
+ while ext != file_type:
338
+ base, ext = os.path.splitext(base)
339
+ ext = ext[1:].lower()
340
+ total_ext.append(ext)
341
+
342
+ total_ext.reverse()
343
+
344
+ return f'{base}.{step}{index}.{".".join(total_ext)}'
345
+
346
+
347
+ def add_common_file(chip, key, file):
348
+ step = chip.get('arg', 'step')
349
+ index = chip.get('arg', 'index')
350
+ tool, task = get_tool_task(chip, step, index)
351
+
352
+ chip.set('tool', tool, 'task', task, 'file', key,
353
+ f'tools/_common/{file}',
354
+ step=step, index=index,
355
+ package='siliconcompiler')
356
+ chip.add('tool', tool, 'task', task, 'require',
357
+ ','.join(['tool', tool, 'task', task, 'file', key]),
358
+ step=step, index=index)
359
+
360
+
361
+ ###########################################################################
362
+ def get_tool_task(chip, step, index, flow=None):
363
+ '''
364
+ Helper function to get the name of the tool and task associated with a given step/index.
365
+ '''
366
+ if not flow:
367
+ flow = chip.get('option', 'flow')
368
+
369
+ tool = chip.get('flowgraph', flow, step, index, 'tool')
370
+ task = chip.get('flowgraph', flow, step, index, 'task')
371
+ return tool, task
372
+
373
+
374
+ def get_tool_tasks(chip, tool):
375
+ tool_dir = os.path.dirname(tool.__file__)
376
+ tool_base_module = tool.__name__.split('.')[0:-1]
377
+ tool_name = tool.__name__.split('.')[-1]
378
+
379
+ task_candidates = []
380
+ for task_mod in pkgutil.iter_modules([tool_dir]):
381
+ if task_mod.name == tool_name:
382
+ continue
383
+ task_candidates.append(task_mod.name)
384
+
385
+ tasks = []
386
+ for task in sorted(task_candidates):
387
+ task_module = '.'.join([*tool_base_module, task])
388
+ if getattr(chip._load_module(task_module), 'setup', None):
389
+ tasks.append(task)
390
+
391
+ return tasks
392
+
393
+
394
+ #######################################
395
+ def record_metric(chip, step, index, metric, value, source, source_unit=None):
396
+ '''
397
+ Records a metric from a given step and index.
398
+
399
+ This function ensures the metrics are recorded in the correct units
400
+ as specified in the schema, additionally, this will record the source
401
+ of the value if provided.
402
+
403
+ Args:
404
+ step (str): step to record the metric into
405
+ index (str): index to record the metric into
406
+ metric (str): metric to record
407
+ value (float/int): value of the metric that is being recorded
408
+ source (str): file the value came from
409
+ source_unit (str): unit of the value, if not provided it is assumed to have no units
410
+
411
+ Examples:
412
+ >>> record_metric(chip, 'floorplan', '0', 'cellarea', 500.0, 'reports/metrics.json', \\
413
+ source_units='um^2')
414
+ Records the metric cell area under 'floorplan0' and notes the source as
415
+ 'reports/metrics.json'
416
+ '''
417
+ from siliconcompiler import units
418
+
419
+ metric_unit = None
420
+ if chip.schema.has_field('metric', metric, 'unit'):
421
+ metric_unit = chip.get('metric', metric, field='unit')
422
+
423
+ if metric_unit:
424
+ value = units.convert(value, from_unit=source_unit, to_unit=metric_unit)
425
+
426
+ chip.set('metric', metric, value, step=step, index=index)
427
+
428
+ if source:
429
+ flow = chip.get('option', 'flow')
430
+ tool, task = get_tool_task(chip, step, index, flow=flow)
431
+
432
+ chip.add('tool', tool, 'task', task, 'report', metric, source, step=step, index=index)
@@ -0,0 +1,115 @@
1
+ from .. import _common
2
+
3
+
4
+ def get_mainlib(chip):
5
+ return get_libraries(chip, 'logic')[0]
6
+
7
+
8
+ def get_libraries(chip, type):
9
+ step = chip.get('arg', 'step')
10
+ index = chip.get('arg', 'index')
11
+
12
+ if type not in ('logic', 'macro'):
13
+ raise ValueError(f'Cannot collect {type} libraries')
14
+
15
+ libs = []
16
+ for lib in chip.get('asic', f'{type}lib', step=step, index=index):
17
+ if lib in libs:
18
+ continue
19
+ libs.append(lib)
20
+
21
+ for lib in _common.get_libraries(chip, include_asic=False):
22
+ if not chip.valid('library', lib, 'asic', f'{type}lib'):
23
+ continue
24
+ for sublib in chip.get('library', lib, 'asic', f'{type}lib', step=step, index=index):
25
+ if sublib in libs:
26
+ continue
27
+ libs.append(sublib)
28
+
29
+ return libs
30
+
31
+
32
+ def get_timing_modes(chip):
33
+ step = chip.get('arg', 'step')
34
+ index = chip.get('arg', 'index')
35
+
36
+ modes = set()
37
+ for scenario in chip.getkeys('constraint', 'timing'):
38
+ modes.add(chip.get('constraint', 'timing', scenario, 'mode',
39
+ step=step, index=index))
40
+ return sorted(modes)
41
+
42
+
43
+ def set_tool_task_var(chip,
44
+ param_key,
45
+ default_value=None,
46
+ schelp=None,
47
+ option_key=None,
48
+ pdk_key=None,
49
+ lib_key=None,
50
+ require=None):
51
+ '''
52
+ Set parameter from PDK -> main library -> option -> default_value
53
+ '''
54
+ step = chip.get('arg', 'step')
55
+ index = chip.get('arg', 'index')
56
+ tool, task = _common.get_tool_task(chip, step, index)
57
+ pdkname = chip.get('option', 'pdk')
58
+ stackup = chip.get('option', 'stackup')
59
+ mainlib = get_mainlib(chip)
60
+
61
+ if not require:
62
+ require = []
63
+ if not isinstance(require, (list, tuple)):
64
+ require = [require]
65
+
66
+ check_keys = []
67
+
68
+ # Add PDK key
69
+ if not pdk_key:
70
+ pdk_key = param_key
71
+ check_keys.append(['pdk', pdkname, 'var', tool, stackup, pdk_key])
72
+ if 'pdk' in require:
73
+ chip.add('tool', tool, 'task', task, 'require',
74
+ ','.join(check_keys[-1]),
75
+ step=step, index=index)
76
+
77
+ # Add library key
78
+ if not lib_key:
79
+ lib_key = f'{tool}_{param_key}'
80
+ check_keys.append(['library', mainlib, 'option', 'var', lib_key])
81
+ if 'lib' in require:
82
+ chip.add('tool', tool, 'task', task, 'require',
83
+ ','.join(check_keys[-1]),
84
+ step=step, index=index)
85
+
86
+ # Add option key
87
+ if not option_key:
88
+ option_key = f'{tool}_{param_key}'
89
+ check_keys.append(['option', 'var', option_key])
90
+ if 'option' in require:
91
+ chip.add('tool', tool, 'task', task, 'require',
92
+ ','.join(check_keys[-1]),
93
+ step=step, index=index)
94
+
95
+ require_key, value = _common.pick_key(chip, reversed(check_keys), step=step, index=index)
96
+ if not value:
97
+ value = default_value
98
+
99
+ if value:
100
+ chip.set('tool', tool, 'task', task, 'var', param_key, value,
101
+ step=step, index=index, clobber=False)
102
+
103
+ if require_key:
104
+ chip.add('tool', tool, 'task', task, 'require',
105
+ ','.join(require_key),
106
+ step=step, index=index)
107
+
108
+ if value or 'key' in require:
109
+ chip.add('tool', tool, 'task', task, 'require',
110
+ ','.join(['tool', tool, 'task', task, 'var', param_key]),
111
+ step=step, index=index)
112
+
113
+ if schelp:
114
+ chip.set('tool', tool, 'task', task, 'var', param_key,
115
+ schelp, field='help')