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
File without changes
@@ -0,0 +1,8 @@
1
+ import siliconcompiler
2
+ from lambdapdk.asap7.libs.asap7sc7p5t import setup
3
+
4
+
5
+ #########################
6
+ if __name__ == "__main__":
7
+ for lib in setup(siliconcompiler.Chip('<lib>')):
8
+ lib.write_manifest(f'{lib.top()}.json')
@@ -0,0 +1,8 @@
1
+ import siliconcompiler
2
+ from lambdapdk.gf180.libs.gf180mcu import setup
3
+
4
+
5
+ #########################
6
+ if __name__ == "__main__":
7
+ lib = setup(siliconcompiler.Chip('<lib>'))
8
+ lib.write_manifest(f'{lib.top()}.json')
@@ -0,0 +1,8 @@
1
+ import siliconcompiler
2
+ from lambdapdk.freepdk45.libs.nangate45 import setup
3
+
4
+
5
+ #########################
6
+ if __name__ == "__main__":
7
+ lib = setup(siliconcompiler.Chip('<lib>'))
8
+ lib.write_manifest(f'{lib.top()}.json')
@@ -0,0 +1,8 @@
1
+ import siliconcompiler
2
+ from lambdapdk.sky130.libs.sky130sc import setup
3
+
4
+
5
+ #########################
6
+ if __name__ == "__main__":
7
+ lib = setup(siliconcompiler.Chip('<lib>'))
8
+ lib.write_manifest(f'{lib.top()}.json')
@@ -0,0 +1,8 @@
1
+ import siliconcompiler
2
+ from lambdapdk.sky130.libs.sky130io import setup
3
+
4
+
5
+ #########################
6
+ if __name__ == "__main__":
7
+ lib = setup(siliconcompiler.Chip('<lib>'))
8
+ lib.write_manifest(f'{lib.top()}.json')
@@ -0,0 +1,412 @@
1
+ import os
2
+ import requests
3
+ import tarfile
4
+ import zipfile
5
+ from git import Repo, GitCommandError
6
+ from urllib.parse import urlparse
7
+ import importlib
8
+ import shutil
9
+ import re
10
+ from siliconcompiler import SiliconCompilerError
11
+ from siliconcompiler.utils import default_cache_dir, _resolve_env_vars
12
+ import json
13
+ from importlib.metadata import distributions, distribution
14
+ import functools
15
+ import fasteners
16
+ import time
17
+ from pathlib import Path
18
+ from io import BytesIO
19
+
20
+ from github import Github
21
+ import github.Auth
22
+
23
+
24
+ def get_cache_path(chip):
25
+ cache_path = chip.get('option', 'cachedir')
26
+ if cache_path:
27
+ cache_path = chip.find_files('option', 'cachedir', missing_ok=True)
28
+ if not cache_path:
29
+ cache_path = os.path.join(chip.cwd, chip.get('option', 'cachedir'))
30
+ if not cache_path:
31
+ cache_path = default_cache_dir()
32
+
33
+ return cache_path
34
+
35
+
36
+ def _path(chip, package, download_handler):
37
+ if package in chip._packages:
38
+ return chip._packages[package]
39
+
40
+ # Initially try retrieving data source from schema
41
+ data = {}
42
+ data['path'] = chip.get('package', 'source', package, 'path')
43
+ data['ref'] = chip.get('package', 'source', package, 'ref')
44
+ if not data['path']:
45
+ raise SiliconCompilerError(
46
+ f'Could not find package source for {package} in schema. '
47
+ 'You can use register_source() to add it.', chip=chip)
48
+
49
+ data['path'] = _resolve_env_vars(chip, data['path'])
50
+
51
+ url = urlparse(data['path'])
52
+
53
+ # check network drive for package data source
54
+ if data['path'].startswith('file://') or os.path.exists(data['path']):
55
+ path = os.path.abspath(data['path'].replace('file://', ''))
56
+ chip.logger.info(f'Found {package} data at {path}')
57
+ chip._packages[package] = path
58
+ return path
59
+ elif data['path'].startswith('python://'):
60
+ path = path_from_python(chip, url.netloc)
61
+ chip.logger.info(f'Found {package} data at {path}')
62
+ chip._packages[package] = path
63
+ return path
64
+
65
+ # location of the python package
66
+ cache_path = get_cache_path(chip)
67
+ if not os.path.exists(cache_path):
68
+ os.makedirs(cache_path, exist_ok=True)
69
+ project_id = f'{package}-{data.get("ref")}'
70
+ if url.scheme not in ['git', 'git+https', 'https', 'git+ssh', 'ssh'] or not project_id:
71
+ raise SiliconCompilerError(
72
+ f'Could not find data path in package {package}: {data["path"]}',
73
+ chip=chip)
74
+
75
+ data_path = os.path.join(cache_path, project_id)
76
+
77
+ if download_handler:
78
+ download_handler(chip,
79
+ package,
80
+ data,
81
+ url,
82
+ data_path,
83
+ os.path.join(cache_path, f'{project_id}.lock'))
84
+
85
+ if os.path.exists(data_path):
86
+ if package not in chip._packages:
87
+ chip.logger.info(f'Saved {package} data to {data_path}')
88
+ chip._packages[package] = data_path
89
+ return data_path
90
+
91
+ raise SiliconCompilerError(f'Extracting {package} data to {data_path} failed')
92
+
93
+
94
+ def path(chip, package):
95
+ """
96
+ Compute data source data path
97
+ Additionally cache data source data if possible
98
+ Parameters:
99
+ package (str): Name of the data source
100
+ Returns:
101
+ path: Location of data source on the local system
102
+ """
103
+
104
+ return _path(chip, package, __download_data)
105
+
106
+
107
+ def __download_data(chip, package, data, url, data_path, data_path_lock):
108
+ data_lock = fasteners.InterProcessLock(data_path_lock)
109
+
110
+ _aquire_data_lock(data_path, data_lock)
111
+
112
+ # check cached package data source
113
+ if os.path.exists(data_path):
114
+ chip.logger.info(f'Found cached {package} data at {data_path}')
115
+ if url.scheme in ['git', 'git+https', 'ssh', 'git+ssh']:
116
+ try:
117
+ repo = Repo(data_path)
118
+ if repo.untracked_files or repo.index.diff("HEAD"):
119
+ chip.logger.warning('The repo of the cached data is dirty.')
120
+ _release_data_lock(data_lock)
121
+ chip._packages[package] = data_path
122
+ return
123
+ except GitCommandError:
124
+ chip.logger.warning('Deleting corrupted cache data.')
125
+ shutil.rmtree(path)
126
+ else:
127
+ _release_data_lock(data_lock)
128
+ chip._packages[package] = data_path
129
+ return
130
+
131
+ # download package data source
132
+ if url.scheme in ['git', 'git+https', 'ssh', 'git+ssh']:
133
+ clone_synchronized(chip, package, data, data_path)
134
+ elif url.scheme == 'https':
135
+ extract_from_url(chip, package, data, data_path)
136
+
137
+ _release_data_lock(data_lock)
138
+
139
+
140
+ def __get_filebased_lock(data_lock):
141
+ base, _ = os.path.splitext(os.fsdecode(data_lock.path))
142
+ return Path(f'{base}.sc_lock')
143
+
144
+
145
+ def _aquire_data_lock(data_path, data_lock):
146
+ # Wait a maximum of 10 minutes for other processes to finish
147
+ max_seconds = 10 * 60
148
+ try:
149
+ if data_lock.acquire(timeout=max_seconds):
150
+ return
151
+ except RuntimeError:
152
+ # Fall back to file based locking method
153
+ lock_file = __get_filebased_lock(data_lock)
154
+ while (lock_file.exists()):
155
+ if max_seconds == 0:
156
+ raise SiliconCompilerError(f'Failed to access {data_path}.'
157
+ f'Lock {lock_file} still exists.')
158
+ time.sleep(1)
159
+ max_seconds -= 1
160
+
161
+ lock_file.touch()
162
+
163
+ return
164
+
165
+ raise SiliconCompilerError(f'Failed to access {data_path}. '
166
+ f'{data_lock.path} is still locked, if this is a mistake, '
167
+ 'please delete it.')
168
+
169
+
170
+ def _release_data_lock(data_lock):
171
+ # Check if file based locking method was used
172
+ lock_file = __get_filebased_lock(data_lock)
173
+ if lock_file.exists():
174
+ lock_file.unlink(missing_ok=True)
175
+ return
176
+
177
+ data_lock.release()
178
+
179
+
180
+ def clone_synchronized(chip, package, data, data_path):
181
+ url = urlparse(data['path'])
182
+ try:
183
+ clone_from_git(chip, package, data, data_path)
184
+ except GitCommandError as e:
185
+ if 'Permission denied' in repr(e):
186
+ if url.scheme in ['ssh', 'git+ssh']:
187
+ chip.logger.error('Failed to authenticate. Please setup your git ssh.')
188
+ elif url.scheme in ['git', 'git+https']:
189
+ chip.logger.error('Failed to authenticate. Please use a token or ssh.')
190
+ else:
191
+ raise e
192
+
193
+
194
+ def clone_from_git(chip, package, data, repo_path):
195
+ url = urlparse(data['path'])
196
+ if url.scheme in ['git', 'git+https'] and url.username:
197
+ chip.logger.warning('Your token is in the data source path and will be stored in the '
198
+ 'schema. If you do not want this set the env variable GIT_TOKEN '
199
+ 'or use ssh for authentication.')
200
+ if url.scheme in ['git+ssh', 'ssh']:
201
+ chip.logger.info(f'Cloning {package} data from {url.netloc}:{url.path[1:]}')
202
+ # Git requires the format git@github.com:org/repo instead of git@github.com/org/repo
203
+ repo = Repo.clone_from(f'{url.netloc}:{url.path[1:]}',
204
+ repo_path,
205
+ recurse_submodules=True)
206
+ else:
207
+ if os.environ.get('GIT_TOKEN') and not url.username:
208
+ url = url._replace(netloc=f'{os.environ.get("GIT_TOKEN")}@{url.hostname}')
209
+ url = url._replace(scheme='https')
210
+ chip.logger.info(f'Cloning {package} data from {url.geturl()}')
211
+ repo = Repo.clone_from(url.geturl(), repo_path, recurse_submodules=True)
212
+ chip.logger.info(f'Checking out {data["ref"]}')
213
+ repo.git.checkout(data["ref"])
214
+ for submodule in repo.submodules:
215
+ submodule.update(init=True)
216
+
217
+
218
+ def extract_from_url(chip, package, data, data_path):
219
+ url = urlparse(data['path'])
220
+ data_url = data.get('path')
221
+ headers = {}
222
+ if os.environ.get('GIT_TOKEN') or url.username:
223
+ headers['Authorization'] = f'token {os.environ.get("GIT_TOKEN") or url.username}'
224
+ if "github" in data_url:
225
+ headers['Accept'] = 'application/octet-stream'
226
+ data_url = data['path']
227
+ if data_url.endswith('/'):
228
+ data_url = f"{data_url}{data['ref']}.tar.gz"
229
+ chip.logger.info(f'Downloading {package} data from {data_url}')
230
+ response = requests.get(data_url, stream=True, headers=headers)
231
+ if not response.ok:
232
+ raise SiliconCompilerError(f'Failed to download {package} data source.', chip=chip)
233
+
234
+ fileobj = BytesIO(response.content)
235
+ try:
236
+ with tarfile.open(fileobj=fileobj, mode='r|gz') as tar_ref:
237
+ tar_ref.extractall(path=data_path)
238
+ except tarfile.ReadError:
239
+ fileobj.seek(0)
240
+ # Try as zip
241
+ with zipfile.ZipFile(fileobj) as zip_ref:
242
+ zip_ref.extractall(path=data_path)
243
+
244
+ if 'github' in url.netloc and len(os.listdir(data_path)) == 1:
245
+ # Github inserts one folder at the highest level of the tar file
246
+ # this compensates for this behavior
247
+ gh_url = urlparse(data_url)
248
+
249
+ repo = gh_url.path.split('/')[2]
250
+
251
+ ref = gh_url.path.split('/')[-1]
252
+ if repo.endswith('.git'):
253
+ ref = data['ref']
254
+ elif ref.endswith('.tar.gz'):
255
+ ref = ref[0:-7]
256
+ elif ref.endswith('.tgz'):
257
+ ref = ref[0:-4]
258
+ else:
259
+ ref = ref.split('.')[0]
260
+
261
+ if ref.startswith('v'):
262
+ ref = ref[1:]
263
+
264
+ github_folder = f"{repo}-{ref}"
265
+
266
+ if github_folder in os.listdir(data_path):
267
+ # This moves all files one level up
268
+ git_path = os.path.join(data_path, github_folder)
269
+ for data_file in os.listdir(git_path):
270
+ shutil.move(os.path.join(git_path, data_file), data_path)
271
+ os.removedirs(git_path)
272
+
273
+
274
+ def path_from_python(chip, python_package, append_path=None):
275
+ try:
276
+ module = importlib.import_module(python_package)
277
+ except: # noqa E722
278
+ raise SiliconCompilerError(f'Failed to import {python_package}.', chip=chip)
279
+
280
+ python_path = os.path.dirname(module.__file__)
281
+ if append_path:
282
+ if isinstance(append_path, str):
283
+ append_path = [append_path]
284
+ python_path = os.path.join(python_path, *append_path)
285
+
286
+ python_path = os.path.abspath(python_path)
287
+
288
+ return python_path
289
+
290
+
291
+ def is_python_module_editable(module_name):
292
+ dist_map = __get_python_module_mapping()
293
+ dist = dist_map[module_name][0]
294
+
295
+ is_editable = False
296
+ for f in distribution(dist).files:
297
+ if f.name == 'direct_url.json':
298
+ info = None
299
+ with open(f.locate(), 'r') as f:
300
+ info = json.load(f)
301
+
302
+ if "dir_info" in info:
303
+ is_editable = info["dir_info"].get("editable", False)
304
+
305
+ return is_editable
306
+
307
+
308
+ def register_python_data_source(chip,
309
+ package_name,
310
+ python_module,
311
+ alternative_path,
312
+ alternative_ref=None,
313
+ python_module_path_append=None):
314
+ '''
315
+ Helper function to register a python module as data source with an alternative in case
316
+ the module is not installed in an editable state
317
+ '''
318
+ # check if installed in an editable state
319
+ if is_python_module_editable(python_module):
320
+ if python_module_path_append:
321
+ path = path_from_python(chip, python_module, append_path=python_module_path_append)
322
+ else:
323
+ path = f"python://{python_module}"
324
+ ref = None
325
+ else:
326
+ path = alternative_path
327
+ ref = alternative_ref
328
+
329
+ chip.register_source(name=package_name,
330
+ path=path,
331
+ ref=ref)
332
+
333
+
334
+ def register_private_github_data_source(chip,
335
+ package_name,
336
+ repository,
337
+ release,
338
+ artifact):
339
+ gh = Github(auth=github.Auth.Token(__get_github_auth_token(package_name)))
340
+ repo = gh.get_repo(repository)
341
+
342
+ if not release:
343
+ release = repo.get_latest_release().tag_name
344
+
345
+ url = None
346
+ for repo_release in repo.get_releases():
347
+ if repo_release.tag_name == release:
348
+ for asset in repo_release.assets:
349
+ if asset.name == artifact:
350
+ url = asset.url
351
+
352
+ if not url:
353
+ raise ValueError(f'Unable to find release asset: {repository}/{release}/{artifact}')
354
+
355
+ chip.register_source(
356
+ package_name,
357
+ path=url,
358
+ ref=release)
359
+
360
+
361
+ def __get_github_auth_token(package_name):
362
+ token_name = package_name.upper()
363
+ for tok in ('#', '$', '&', '-', '=', '!', '/'):
364
+ token_name = token_name.replace(tok, '')
365
+
366
+ search_env = (
367
+ f'GITHUB_{token_name}_TOKEN',
368
+ 'GITHUB_TOKEN',
369
+ 'GIT_TOKEN'
370
+ )
371
+
372
+ token = None
373
+ for env in search_env:
374
+ token = os.environ.get(env, None)
375
+
376
+ if token:
377
+ break
378
+
379
+ if not token:
380
+ raise ValueError('Unable to determine authorization token for GitHub, '
381
+ f'please set one of the following environmental variables: {search_env}')
382
+
383
+ return token
384
+
385
+
386
+ @functools.lru_cache(maxsize=1)
387
+ def __get_python_module_mapping():
388
+ mapping = {}
389
+
390
+ for dist in distributions():
391
+ dist_name = None
392
+ if hasattr(dist, 'name'):
393
+ dist_name = dist.name
394
+ else:
395
+ metadata = dist.read_text('METADATA')
396
+ if metadata:
397
+ find_name = re.compile(r'Name: (.*)')
398
+ for data in metadata.splitlines():
399
+ group = find_name.findall(data)
400
+ if group:
401
+ dist_name = group[0]
402
+ break
403
+
404
+ if not dist_name:
405
+ continue
406
+
407
+ provides = dist.read_text('top_level.txt')
408
+ if provides:
409
+ for module in dist.read_text('top_level.txt').split():
410
+ mapping.setdefault(module, []).append(dist_name)
411
+
412
+ return mapping
File without changes
@@ -0,0 +1,8 @@
1
+ import siliconcompiler
2
+ from lambdapdk.asap7 import setup
3
+
4
+
5
+ #########################
6
+ if __name__ == "__main__":
7
+ pdk = setup(siliconcompiler.Chip('<pdk>'))
8
+ pdk.write_manifest(f'{pdk.top()}.json')
@@ -0,0 +1,8 @@
1
+ import siliconcompiler
2
+ from lambdapdk.freepdk45 import setup
3
+
4
+
5
+ #########################
6
+ if __name__ == "__main__":
7
+ pdk = setup(siliconcompiler.Chip('<pdk>'))
8
+ pdk.write_manifest(f'{pdk.top()}.json')
@@ -0,0 +1,8 @@
1
+ import siliconcompiler
2
+ from lambdapdk.gf180 import setup
3
+
4
+
5
+ #########################
6
+ if __name__ == "__main__":
7
+ pdk = setup(siliconcompiler.Chip('<pdk>'))
8
+ pdk.write_manifest(f'{pdk.top()}.json')
@@ -0,0 +1,8 @@
1
+ import siliconcompiler
2
+ from lambdapdk.sky130 import setup
3
+
4
+
5
+ #########################
6
+ if __name__ == "__main__":
7
+ pdk = setup(siliconcompiler.Chip('<pdk>'))
8
+ pdk.write_manifest(f'{pdk.top()}.json')
@@ -0,0 +1,36 @@
1
+ from siliconcompiler._common import NodeStatus as SCNodeStatus
2
+
3
+ # CLI entry banner autogenerated using pyfiglet.
4
+ # >> pyfiglet.figlet_format("SC Server")
5
+ banner = r'''
6
+ ____ ____ ____
7
+ / ___| / ___| / ___| ___ _ ____ _____ _ __
8
+ \___ \| | \___ \ / _ \ '__\ \ / / _ \ '__|
9
+ ___) | |___ ___) | __/ | \ V / __/ |
10
+ |____/ \____| |____/ \___|_| \_/ \___|_|
11
+ '''
12
+
13
+
14
+ class NodeStatus(SCNodeStatus):
15
+ '''
16
+ Enum class to help ensure consistent status messages
17
+ '''
18
+
19
+ # special code for uploaded
20
+ UPLOADED = 'uploaded'
21
+
22
+
23
+ class JobStatus():
24
+ '''
25
+ Enum class to help ensure consistent status messages
26
+ '''
27
+
28
+ RUNNING = "running"
29
+
30
+ COMPLETED = "completed"
31
+ FAILED = "failed"
32
+ CANCELED = "canceled"
33
+ REJECTED = "rejected"
34
+ TIMEOUT = "timeout"
35
+
36
+ UNKNOWN = "unknown"