siliconcompiler 0.28.9__py3-none-any.whl → 0.29.1__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 (164) hide show
  1. siliconcompiler/_metadata.py +1 -1
  2. siliconcompiler/apps/__init__.py +26 -0
  3. siliconcompiler/apps/sc_remote.py +15 -14
  4. siliconcompiler/apps/sc_show.py +5 -5
  5. siliconcompiler/apps/utils/replay.py +194 -0
  6. siliconcompiler/checklists/__init__.py +12 -0
  7. siliconcompiler/core.py +89 -22
  8. siliconcompiler/flows/__init__.py +34 -0
  9. siliconcompiler/flows/_common.py +11 -13
  10. siliconcompiler/flows/asicflow.py +83 -42
  11. siliconcompiler/flows/showflow.py +1 -1
  12. siliconcompiler/libs/__init__.py +5 -0
  13. siliconcompiler/optimizer/__init__.py +199 -0
  14. siliconcompiler/optimizer/vizier.py +259 -0
  15. siliconcompiler/pdks/__init__.py +5 -0
  16. siliconcompiler/remote/__init__.py +11 -0
  17. siliconcompiler/remote/client.py +753 -815
  18. siliconcompiler/report/report.py +2 -0
  19. siliconcompiler/report/summary_table.py +1 -1
  20. siliconcompiler/scheduler/__init__.py +118 -58
  21. siliconcompiler/scheduler/send_messages.py +1 -1
  22. siliconcompiler/schema/schema_cfg.py +16 -4
  23. siliconcompiler/schema/schema_obj.py +29 -10
  24. siliconcompiler/schema/utils.py +2 -0
  25. siliconcompiler/sphinx_ext/__init__.py +85 -0
  26. siliconcompiler/sphinx_ext/dynamicgen.py +19 -34
  27. siliconcompiler/sphinx_ext/schemagen.py +3 -2
  28. siliconcompiler/targets/__init__.py +26 -0
  29. siliconcompiler/targets/gf180_demo.py +3 -3
  30. siliconcompiler/templates/replay/replay.py.j2 +62 -0
  31. siliconcompiler/templates/replay/requirements.txt +7 -0
  32. siliconcompiler/templates/replay/setup.sh +130 -0
  33. siliconcompiler/tools/__init__.py +60 -0
  34. siliconcompiler/tools/_common/__init__.py +15 -1
  35. siliconcompiler/tools/_common/asic.py +17 -9
  36. siliconcompiler/tools/builtin/concatenate.py +1 -1
  37. siliconcompiler/tools/ghdl/ghdl.py +1 -2
  38. siliconcompiler/tools/klayout/convert_drc_db.py +1 -1
  39. siliconcompiler/tools/klayout/drc.py +1 -1
  40. siliconcompiler/tools/klayout/export.py +8 -1
  41. siliconcompiler/tools/klayout/klayout.py +2 -2
  42. siliconcompiler/tools/klayout/klayout_convert_drc_db.py +2 -2
  43. siliconcompiler/tools/klayout/klayout_export.py +7 -5
  44. siliconcompiler/tools/klayout/klayout_operations.py +4 -3
  45. siliconcompiler/tools/klayout/klayout_show.py +3 -2
  46. siliconcompiler/tools/klayout/klayout_utils.py +1 -1
  47. siliconcompiler/tools/klayout/operations.py +8 -0
  48. siliconcompiler/tools/klayout/screenshot.py +6 -1
  49. siliconcompiler/tools/klayout/show.py +8 -1
  50. siliconcompiler/tools/magic/magic.py +1 -1
  51. siliconcompiler/tools/openroad/__init__.py +103 -0
  52. siliconcompiler/tools/openroad/{openroad.py → _apr.py} +415 -423
  53. siliconcompiler/tools/openroad/antenna_repair.py +78 -0
  54. siliconcompiler/tools/openroad/clock_tree_synthesis.py +64 -0
  55. siliconcompiler/tools/openroad/detailed_placement.py +59 -0
  56. siliconcompiler/tools/openroad/detailed_route.py +62 -0
  57. siliconcompiler/tools/openroad/endcap_tapcell_insertion.py +52 -0
  58. siliconcompiler/tools/openroad/fillercell_insertion.py +58 -0
  59. siliconcompiler/tools/openroad/{dfm.py → fillmetal_insertion.py} +35 -19
  60. siliconcompiler/tools/openroad/global_placement.py +58 -0
  61. siliconcompiler/tools/openroad/global_route.py +63 -0
  62. siliconcompiler/tools/openroad/init_floorplan.py +103 -0
  63. siliconcompiler/tools/openroad/macro_placement.py +65 -0
  64. siliconcompiler/tools/openroad/metrics.py +23 -8
  65. siliconcompiler/tools/openroad/pin_placement.py +56 -0
  66. siliconcompiler/tools/openroad/power_grid.py +65 -0
  67. siliconcompiler/tools/openroad/rcx_bench.py +7 -4
  68. siliconcompiler/tools/openroad/rcx_extract.py +2 -1
  69. siliconcompiler/tools/openroad/rdlroute.py +4 -4
  70. siliconcompiler/tools/openroad/repair_design.py +59 -0
  71. siliconcompiler/tools/openroad/repair_timing.py +63 -0
  72. siliconcompiler/tools/openroad/screenshot.py +9 -20
  73. siliconcompiler/tools/openroad/scripts/apr/postamble.tcl +44 -0
  74. siliconcompiler/tools/openroad/scripts/apr/preamble.tcl +95 -0
  75. siliconcompiler/tools/openroad/scripts/apr/sc_antenna_repair.tcl +51 -0
  76. siliconcompiler/tools/openroad/scripts/apr/sc_clock_tree_synthesis.tcl +66 -0
  77. siliconcompiler/tools/openroad/scripts/apr/sc_detailed_placement.tcl +41 -0
  78. siliconcompiler/tools/openroad/scripts/apr/sc_detailed_route.tcl +71 -0
  79. siliconcompiler/tools/openroad/scripts/apr/sc_endcap_tapcell_insertion.tcl +55 -0
  80. siliconcompiler/tools/openroad/scripts/apr/sc_fillercell_insertion.tcl +27 -0
  81. siliconcompiler/tools/openroad/scripts/apr/sc_fillmetal_insertion.tcl +36 -0
  82. siliconcompiler/tools/openroad/scripts/apr/sc_global_placement.tcl +26 -0
  83. siliconcompiler/tools/openroad/scripts/apr/sc_global_route.tcl +61 -0
  84. siliconcompiler/tools/openroad/scripts/apr/sc_init_floorplan.tcl +333 -0
  85. siliconcompiler/tools/openroad/scripts/apr/sc_macro_placement.tcl +123 -0
  86. siliconcompiler/tools/openroad/scripts/apr/sc_metrics.tcl +22 -0
  87. siliconcompiler/tools/openroad/scripts/apr/sc_pin_placement.tcl +41 -0
  88. siliconcompiler/tools/openroad/scripts/apr/sc_power_grid.tcl +60 -0
  89. siliconcompiler/tools/openroad/scripts/apr/sc_repair_design.tcl +68 -0
  90. siliconcompiler/tools/openroad/scripts/apr/sc_repair_timing.tcl +83 -0
  91. siliconcompiler/tools/openroad/scripts/apr/sc_write_data.tcl +125 -0
  92. siliconcompiler/tools/openroad/scripts/common/debugging.tcl +28 -0
  93. siliconcompiler/tools/openroad/scripts/common/procs.tcl +727 -0
  94. siliconcompiler/tools/openroad/scripts/common/read_input_files.tcl +59 -0
  95. siliconcompiler/tools/openroad/scripts/common/read_liberty.tcl +20 -0
  96. siliconcompiler/tools/openroad/scripts/common/read_timing_constraints.tcl +16 -0
  97. siliconcompiler/tools/openroad/scripts/common/reports.tcl +180 -0
  98. siliconcompiler/tools/openroad/scripts/common/screenshot.tcl +18 -0
  99. siliconcompiler/tools/openroad/scripts/common/write_images.tcl +395 -0
  100. siliconcompiler/tools/openroad/scripts/{sc_rcx_bench.tcl → rcx/sc_rcx_bench.tcl} +5 -5
  101. siliconcompiler/tools/openroad/scripts/{sc_rcx_extract.tcl → rcx/sc_rcx_extract.tcl} +0 -0
  102. siliconcompiler/tools/openroad/scripts/sc_rcx.tcl +5 -16
  103. siliconcompiler/tools/openroad/scripts/sc_rdlroute.tcl +51 -51
  104. siliconcompiler/tools/openroad/scripts/sc_show.tcl +110 -0
  105. siliconcompiler/tools/openroad/show.py +28 -23
  106. siliconcompiler/tools/openroad/{export.py → write_data.py} +31 -26
  107. siliconcompiler/tools/opensta/__init__.py +2 -2
  108. siliconcompiler/tools/opensta/check_library.py +27 -0
  109. siliconcompiler/tools/opensta/scripts/sc_check_library.tcl +255 -0
  110. siliconcompiler/tools/opensta/scripts/sc_timing.tcl +1 -1
  111. siliconcompiler/tools/sv2v/sv2v.py +1 -2
  112. siliconcompiler/tools/verilator/verilator.py +6 -7
  113. siliconcompiler/tools/vivado/vivado.py +1 -1
  114. siliconcompiler/tools/yosys/__init__.py +149 -0
  115. siliconcompiler/tools/yosys/lec.py +22 -9
  116. siliconcompiler/tools/yosys/sc_lec.tcl +94 -49
  117. siliconcompiler/tools/yosys/sc_syn.tcl +1 -0
  118. siliconcompiler/tools/yosys/screenshot.py +2 -2
  119. siliconcompiler/tools/yosys/syn_asic.py +105 -74
  120. siliconcompiler/tools/yosys/syn_asic.tcl +58 -12
  121. siliconcompiler/tools/yosys/syn_fpga.py +2 -3
  122. siliconcompiler/tools/yosys/syn_fpga.tcl +26 -19
  123. siliconcompiler/toolscripts/_tools.json +5 -5
  124. siliconcompiler/utils/__init__.py +7 -3
  125. {siliconcompiler-0.28.9.dist-info → siliconcompiler-0.29.1.dist-info}/METADATA +22 -17
  126. {siliconcompiler-0.28.9.dist-info → siliconcompiler-0.29.1.dist-info}/RECORD +131 -114
  127. {siliconcompiler-0.28.9.dist-info → siliconcompiler-0.29.1.dist-info}/WHEEL +1 -1
  128. {siliconcompiler-0.28.9.dist-info → siliconcompiler-0.29.1.dist-info}/entry_points.txt +13 -0
  129. siliconcompiler/libs/asap7sc7p5t.py +0 -8
  130. siliconcompiler/libs/gf180mcu.py +0 -8
  131. siliconcompiler/libs/interposer.py +0 -8
  132. siliconcompiler/libs/nangate45.py +0 -8
  133. siliconcompiler/libs/sg13g2_stdcell.py +0 -8
  134. siliconcompiler/libs/sky130hd.py +0 -8
  135. siliconcompiler/libs/sky130io.py +0 -8
  136. siliconcompiler/pdks/asap7.py +0 -8
  137. siliconcompiler/pdks/freepdk45.py +0 -8
  138. siliconcompiler/pdks/gf180.py +0 -8
  139. siliconcompiler/pdks/ihp130.py +0 -8
  140. siliconcompiler/pdks/interposer.py +0 -8
  141. siliconcompiler/pdks/skywater130.py +0 -8
  142. siliconcompiler/tools/openroad/cts.py +0 -45
  143. siliconcompiler/tools/openroad/floorplan.py +0 -75
  144. siliconcompiler/tools/openroad/physyn.py +0 -27
  145. siliconcompiler/tools/openroad/place.py +0 -41
  146. siliconcompiler/tools/openroad/route.py +0 -45
  147. siliconcompiler/tools/openroad/scripts/__init__.py +0 -0
  148. siliconcompiler/tools/openroad/scripts/sc_apr.tcl +0 -514
  149. siliconcompiler/tools/openroad/scripts/sc_cts.tcl +0 -68
  150. siliconcompiler/tools/openroad/scripts/sc_dfm.tcl +0 -22
  151. siliconcompiler/tools/openroad/scripts/sc_export.tcl +0 -100
  152. siliconcompiler/tools/openroad/scripts/sc_floorplan.tcl +0 -456
  153. siliconcompiler/tools/openroad/scripts/sc_metrics.tcl +0 -1
  154. siliconcompiler/tools/openroad/scripts/sc_physyn.tcl +0 -6
  155. siliconcompiler/tools/openroad/scripts/sc_place.tcl +0 -84
  156. siliconcompiler/tools/openroad/scripts/sc_procs.tcl +0 -494
  157. siliconcompiler/tools/openroad/scripts/sc_report.tcl +0 -189
  158. siliconcompiler/tools/openroad/scripts/sc_route.tcl +0 -143
  159. siliconcompiler/tools/openroad/scripts/sc_screenshot.tcl +0 -18
  160. siliconcompiler/tools/openroad/scripts/sc_write_images.tcl +0 -393
  161. siliconcompiler/tools/yosys/yosys.py +0 -148
  162. /siliconcompiler/tools/openroad/scripts/{sc_write.tcl → common/write_data.tcl} +0 -0
  163. {siliconcompiler-0.28.9.dist-info → siliconcompiler-0.29.1.dist-info}/LICENSE +0 -0
  164. {siliconcompiler-0.28.9.dist-info → siliconcompiler-0.29.1.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,5 @@
1
1
  # Version number following semver standard.
2
- version = '0.28.9'
2
+ version = '0.29.1'
3
3
 
4
4
  # Default server address for remote runs, if unspecified.
5
5
  default_server = 'https://server.siliconcompiler.com'
@@ -0,0 +1,26 @@
1
+ from siliconcompiler.apps import sc_dashboard
2
+ from siliconcompiler.apps import sc_install
3
+ from siliconcompiler.apps import sc_issue
4
+ from siliconcompiler.apps import sc_remote
5
+ from siliconcompiler.apps import sc_server
6
+ from siliconcompiler.apps import sc_show
7
+ from siliconcompiler.apps import sc
8
+ from siliconcompiler.apps import smake
9
+
10
+
11
+ def get_apps():
12
+ '''
13
+ Returns a dict of builtin apps
14
+ '''
15
+ return {
16
+ module.__name__.split(".")[-1]: module for module in (
17
+ sc_dashboard,
18
+ sc_install,
19
+ sc_issue,
20
+ sc_remote,
21
+ sc_server,
22
+ sc_show,
23
+ sc,
24
+ smake
25
+ )
26
+ }
@@ -5,9 +5,7 @@ import sys
5
5
 
6
6
  from siliconcompiler import Chip
7
7
  from siliconcompiler import SiliconCompilerError
8
- from siliconcompiler.remote.client import cancel_job, check_progress, delete_job, \
9
- remote_ping, remote_run_loop, _remote_ping
10
- from siliconcompiler.remote.client import configure_server, configure_whitelist, configure_print
8
+ from siliconcompiler.remote.client import Client, ConfigureClient
11
9
  from siliconcompiler.scheduler import _finalize_run
12
10
  from siliconcompiler.flowgraph import _get_flowgraph_entry_nodes, _get_flowgraph_node_outputs, \
13
11
  nodes_to_execute
@@ -108,29 +106,33 @@ To delete a job, use:
108
106
 
109
107
  if args['configure']:
110
108
  if args['list']:
111
- configure_print(chip)
109
+ client = Client(chip)
110
+ client.print_configuration()
112
111
  return 0
113
112
 
114
113
  if not args['add'] and not args['remove']:
115
114
  try:
116
- configure_server(chip, server=args['server'])
115
+ client = ConfigureClient(chip)
116
+ client.configure_server(server=args['server'])
117
117
  except ValueError as e:
118
118
  chip.logger.error(e)
119
119
  return 1
120
120
  else:
121
121
  try:
122
- configure_whitelist(chip, add=args['add'], remove=args['remove'])
122
+ client = ConfigureClient(chip)
123
+ client.configure_whitelist(add=args['add'], remove=args['remove'])
123
124
  except ValueError as e:
124
125
  chip.logger.error(e)
125
126
  return 1
126
127
 
127
128
  return 0
128
129
 
130
+ client = Client(chip)
129
131
  # Main logic.
130
132
  # If no job-related options are specified, fetch and report basic info.
131
133
  # Create temporary Chip object and check on the server.
132
134
  try:
133
- remote_ping(chip)
135
+ client.check()
134
136
  except SiliconCompilerError as e:
135
137
  chip.logger.error(f'{e}')
136
138
  return 1
@@ -138,7 +140,7 @@ To delete a job, use:
138
140
  # If the -cancel flag is specified, cancel the job.
139
141
  if args['cancel']:
140
142
  try:
141
- cancel_job(chip)
143
+ client.cancel_job()
142
144
  except SiliconCompilerError as e:
143
145
  chip.logger.error(f'{e}')
144
146
  return 1
@@ -146,7 +148,7 @@ To delete a job, use:
146
148
  # If the -delete flag is specified, delete the job.
147
149
  elif args['delete']:
148
150
  try:
149
- delete_job(chip)
151
+ client.delete_job()
150
152
  except SiliconCompilerError as e:
151
153
  chip.logger.error(f'{e}')
152
154
  return 1
@@ -162,10 +164,8 @@ To delete a job, use:
162
164
  outputs = _get_flowgraph_node_outputs(chip, flow, entry_node)
163
165
  chip.set('option', 'from', list(map(lambda node: node[0], outputs)))
164
166
  # Enter the remote run loop.
165
- chip._init_logger(step='remote', index='0', in_run=True)
166
167
  try:
167
- rsp = _remote_ping(chip)
168
- remote_run_loop(chip, rsp['progress_interval'])
168
+ client._run_loop()
169
169
  except SiliconCompilerError as e:
170
170
  chip.logger.error(f'{e}')
171
171
  return 1
@@ -185,8 +185,9 @@ To delete a job, use:
185
185
  # If only a manifest is specified, make a 'check_progress/' request and report results:
186
186
  elif chip_cfg:
187
187
  try:
188
- check_progress(chip, [], {})
189
- except SiliconCompilerError as e:
188
+ info = client.check_job_status()
189
+ client._report_job_status(info)
190
+ except Exception as e:
190
191
  chip.logger.error(f'{e}')
191
192
  return 1
192
193
 
@@ -19,10 +19,10 @@ def main():
19
19
  Examples:
20
20
 
21
21
  sc-show
22
- (displays build/adder/job0/write_gds/0/outputs/adder.gds)
22
+ (displays build/adder/job0/write.gds/0/outputs/adder.gds)
23
23
 
24
24
  sc-show -design adder
25
- (displays build/adder/job0/write_gds/0/outputs/adder.gds)
25
+ (displays build/adder/job0/write.gds/0/outputs/adder.gds)
26
26
 
27
27
  sc-show -design adder -arg_step floorplan
28
28
  (displays build/adder/job0/floorplan/0/outputs/adder.def)
@@ -31,13 +31,13 @@ def main():
31
31
  (displays build/adder/job0/place/1/outputs/adder.def)
32
32
 
33
33
  sc-show -design adder -jobname rtl2gds
34
- (displays build/adder/rtl2gds/write_gds/0/outputs/adder.gds)
34
+ (displays build/adder/rtl2gds/write.gds/0/outputs/adder.gds)
35
35
 
36
36
  sc-show -cfg build/adder/rtl2gds/adder.pkg.json
37
- (displays build/adder/rtl2gds/write_gds/0/outputs/adder.gds)
37
+ (displays build/adder/rtl2gds/write.gds/0/outputs/adder.gds)
38
38
 
39
39
  sc-show -design adder -ext odb
40
- (displays build/adder/job0/write_data/0/outputs/adder.odb)
40
+ (displays build/adder/job0/write.views/0/outputs/adder.odb)
41
41
 
42
42
  sc-show build/adder/job0/route/1/outputs/adder.def
43
43
  (displays build/adder/job0/route/1/outputs/adder.def)
@@ -0,0 +1,194 @@
1
+ # Copyright 2024 Silicon Compiler Authors. All Rights Reserved.
2
+
3
+ # Standard Modules
4
+ import base64
5
+ import io
6
+ import json
7
+ import gzip
8
+ import os
9
+ import stat
10
+ import sys
11
+ import tarfile
12
+ import tempfile
13
+ import textwrap
14
+
15
+ from datetime import datetime
16
+
17
+ import siliconcompiler
18
+ from siliconcompiler.apps._common import UNSET_DESIGN
19
+ from siliconcompiler import SiliconCompilerError
20
+ from siliconcompiler import utils
21
+
22
+
23
+ def make_bytes(data):
24
+ if isinstance(data, bytes):
25
+ return data
26
+ return data.encode('utf-8')
27
+
28
+
29
+ def compress(data):
30
+ return gzip.compress(make_bytes(data))
31
+
32
+
33
+ def convert_base64(data):
34
+ return base64.b64encode(make_bytes(data))
35
+
36
+
37
+ def wrap_text(data):
38
+ if isinstance(data, bytes):
39
+ data = data.decode('utf-8')
40
+ return textwrap.wrap(data)
41
+
42
+
43
+ ###########################
44
+ def main():
45
+ progname = "summarize"
46
+ description = """
47
+ ------------------------------------------------------------
48
+ Utility script to print job record information from a manifest
49
+ needed to replay that manifest.
50
+ ------------------------------------------------------------
51
+ """
52
+ # Create a base chip class.
53
+ chip = siliconcompiler.Chip(UNSET_DESIGN)
54
+
55
+ # Read command-line inputs and generate Chip objects to run the flow on.
56
+ try:
57
+ file_arg = {
58
+ 'metavar': '<file>',
59
+ 'help': 'Path to generate replay file to.',
60
+ 'default': 'replay.sh',
61
+ 'sc_print': True
62
+ }
63
+ args = chip.create_cmdline(
64
+ progname,
65
+ description=description,
66
+ switchlist=['-cfg',
67
+ '-jobname',
68
+ '-loglevel'],
69
+ additional_args={
70
+ '-file': file_arg
71
+ })
72
+ except SiliconCompilerError:
73
+ return 1
74
+ except Exception as e:
75
+ chip.logger.error(e)
76
+ return 1
77
+
78
+ design = chip.get('design')
79
+ if design == UNSET_DESIGN:
80
+ chip.logger.error('Design not loaded')
81
+ return 1
82
+
83
+ # Print Job Summary
84
+ jobname = chip.get('option', 'jobname')
85
+ pythonpackages = chip.get('record', 'pythonpackage', job=jobname)
86
+
87
+ pythonversion = set()
88
+ nodes = set()
89
+ for version, step, index in chip.schema._getvals('history', jobname, 'record', 'pythonversion'):
90
+ pythonversion.add(version)
91
+ nodes.add((step, index))
92
+
93
+ if len(pythonversion) > 1:
94
+ chip.logger.warning(f"More than one python version detected: {', '.join(pythonversion)}")
95
+ pythonversion = list(pythonversion)[0]
96
+
97
+ tools = {}
98
+ tool_versions = []
99
+ for step, index in nodes:
100
+ toolpath = chip.get('record', 'toolpath', job=jobname, step=step, index=index)
101
+ toolversion = chip.get('record', 'toolversion', job=jobname, step=step, index=index)
102
+
103
+ if toolpath is None:
104
+ continue
105
+
106
+ tools.setdefault(toolpath, set()).add(toolversion)
107
+ if toolversion:
108
+ tool = chip.get('flowgraph', chip.get('option', 'flow'), step, index, 'tool')
109
+ tool_versions.append(
110
+ ((step, index), tool, toolversion)
111
+ )
112
+
113
+ print("SUMMARY :")
114
+ print(f"design : {chip.design}")
115
+ print(f"pythonversion : {pythonversion}")
116
+
117
+ print("Python packages requires:")
118
+ for pkg in sorted(pythonpackages):
119
+ print(f" {pkg}")
120
+
121
+ print("Tool requirements:")
122
+ tool_len = max([len(os.path.basename(tool)) for tool, _ in tools.items()])
123
+ for tool, version in tools.items():
124
+ print(f" {os.path.basename(tool):<{tool_len}}: {', '.join(version)}")
125
+
126
+ path = os.path.abspath(args['file'])
127
+ os.makedirs(os.path.dirname(path), exist_ok=True)
128
+
129
+ starttimes = set()
130
+ for starttime, step, index in chip.schema._getvals('history', jobname, 'record', 'starttime'):
131
+ starttimes.add(datetime.strptime(starttime, '%Y-%m-%d %H:%M:%S'))
132
+ starttime = min(starttimes).strftime('%Y-%m-%d %H:%M:%S')
133
+
134
+ with io.StringIO() as fd:
135
+ fd.write(utils.get_file_template('replay/requirements.txt').render(
136
+ design=chip.design,
137
+ jobname=jobname,
138
+ date=starttime,
139
+ pkgs=pythonpackages
140
+ ))
141
+ fd.flush()
142
+ requirements_file = fd.getvalue()
143
+
144
+ with tempfile.TemporaryDirectory() as collect:
145
+ chip.collect(directory=collect, verbose=True, exclude_packages=['siliconcompiler'])
146
+
147
+ with io.BytesIO() as fd:
148
+ with tarfile.open(fileobj=fd, mode='w:gz') as tar:
149
+ tar.add(collect, arcname='')
150
+
151
+ fd.flush()
152
+ collect_files = convert_base64(fd.getvalue())
153
+
154
+ with io.StringIO() as fd:
155
+ fd.write(utils.get_file_template('replay/replay.py.j2').render(
156
+ design=chip.design,
157
+ jobname=jobname,
158
+ date=starttime,
159
+ src_file=wrap_text(collect_files),
160
+ tool_versions=sorted(tool_versions)
161
+ ))
162
+ fd.flush()
163
+ script = convert_base64(compress(fd.getvalue()))
164
+
165
+ manifest = convert_base64(compress(json.dumps(chip.schema.cfg, indent=2)))
166
+
167
+ tool_info = []
168
+ for tool, version in tools.items():
169
+ tool_info.append(f"{os.path.basename(tool):<{tool_len}}: {', '.join(version)}")
170
+
171
+ description = f"Replay for {chip.design} / {jobname}\nRun on: {starttime}"
172
+
173
+ with open(path, 'w', encoding='utf-8') as wf:
174
+ wf.write(utils.get_file_template('replay/setup.sh').render(
175
+ design=chip.design,
176
+ jobname=jobname,
177
+ date=starttime,
178
+ description=description,
179
+ pythonversion=pythonversion,
180
+ requirements=requirements_file.splitlines(),
181
+ script=wrap_text(script),
182
+ manifest=wrap_text(manifest),
183
+ tools=tool_info
184
+ ))
185
+
186
+ permissions = stat.S_IMODE(os.lstat(path).st_mode)
187
+ os.chmod(path, permissions | stat.S_IXUSR)
188
+
189
+ return 0
190
+
191
+
192
+ #########################
193
+ if __name__ == "__main__":
194
+ sys.exit(main())
@@ -0,0 +1,12 @@
1
+ from siliconcompiler.checklists import oh_tapeout
2
+
3
+
4
+ def get_checklists():
5
+ '''
6
+ Returns a dict of builtin checklists
7
+ '''
8
+ return {
9
+ module.__name__.split(".")[-1]: module for module in (
10
+ oh_tapeout,
11
+ )
12
+ }
siliconcompiler/core.py CHANGED
@@ -255,8 +255,13 @@ class Chip:
255
255
  log_format.append(f'{utils.truncate_text(step, max_step_len): <{max_step_len}}')
256
256
  log_format.append(f'{utils.truncate_text(index, max_step_len): >{max_index_len}}')
257
257
 
258
+ log_formatprefix = "| "
259
+ if loglevel == "quiet":
260
+ log_format = []
261
+ log_formatprefix = ""
262
+
258
263
  log_format.append('%(message)s')
259
- logformat = '| ' + ' | '.join(log_format)
264
+ logformat = log_formatprefix + ' | '.join(log_format)
260
265
 
261
266
  if not self.logger.hasHandlers():
262
267
  stream_handler = logging.StreamHandler(stream=sys.stdout)
@@ -402,19 +407,24 @@ class Chip:
402
407
  if extra_params is not None and "target" in extra_params:
403
408
  if extra_params["target"]:
404
409
  # running target command
405
- # Search order "{name}", and "siliconcompiler.targets.{name}"
410
+ # Search order target plugins -> "{name}"
406
411
  modules = []
407
412
  module = extra_params["target"]
408
- for mod_name in [module, f'siliconcompiler.targets.{module}']:
409
- mod = self._load_module(mod_name)
410
- if mod:
411
- modules.append(mod)
413
+ for plugin in utils.get_plugins('target'):
414
+ plugin_targets = plugin()
415
+ if module in plugin_targets:
416
+ modules.append(plugin_targets[module])
417
+
418
+ mod = self._load_module(module)
419
+ if mod:
420
+ modules.append(mod)
412
421
 
413
422
  if len(modules) == 0:
414
423
  raise SiliconCompilerError(f'Could not find target {module}', chip=self)
415
424
 
416
- self.use(modules[0])
417
- extra_params["target"] = modules[0].__name__
425
+ target = modules[0]
426
+ self.use(target)
427
+ extra_params["target"] = target.__name__
418
428
 
419
429
  if extra_params is not None and "use" in extra_params:
420
430
  if extra_params["use"]:
@@ -975,7 +985,7 @@ class Chip:
975
985
  self.logger.debug(f'Setting {keypath} to {value}')
976
986
 
977
987
  # Special case to ensure loglevel is updated ASAP
978
- if keypath == ['option', 'loglevel'] and field == 'value' and \
988
+ if tuple(keypath) == ('option', 'loglevel') and field == 'value' and \
979
989
  step == self.get('arg', 'step') and index == self.get('arg', 'index'):
980
990
  self.logger.setLevel(schema_utils.translate_loglevel(value))
981
991
 
@@ -1074,6 +1084,54 @@ class Chip:
1074
1084
  except (ValueError, TypeError) as e:
1075
1085
  self.error(str(e))
1076
1086
 
1087
+ def import_flist(self, filename, package=None):
1088
+ '''
1089
+ Add input files, include directories, and defines from an flist
1090
+
1091
+ Args:
1092
+ filename (path): Path to flist file
1093
+ package (str): name of package
1094
+ '''
1095
+
1096
+ if package:
1097
+ filename = os.path.join(sc_package.path(self, package), filename)
1098
+
1099
+ if not os.path.isfile(filename):
1100
+ raise FileNotFoundError(filename)
1101
+
1102
+ package_name = f'flist-{os.path.basename(filename)}'
1103
+ package_dir = os.path.dirname(os.path.abspath(filename))
1104
+
1105
+ def __make_path(rel, path):
1106
+ path = utils._resolve_env_vars(self, path)
1107
+ if os.path.isabs(path):
1108
+ if path.startswith(rel):
1109
+ return os.path.relpath(path, rel), package_name
1110
+ else:
1111
+ return path, None
1112
+ return path, package_name
1113
+
1114
+ self.register_source(
1115
+ package_name,
1116
+ path=package_dir)
1117
+ with utils.sc_open(filename) as f:
1118
+ for line in f:
1119
+ line = line.strip()
1120
+ if not line:
1121
+ continue
1122
+ if line.startswith("//"):
1123
+ continue
1124
+ if line.startswith("+incdir+"):
1125
+ line = line[8:]
1126
+ path, package = __make_path(package_dir, line)
1127
+ self.add('option', 'idir', path, package=package)
1128
+ elif line.startswith("+define+"):
1129
+ line = line[8:]
1130
+ self.add('option', 'define', line)
1131
+ else:
1132
+ path, package = __make_path(package_dir, line)
1133
+ self.input(path, package=package)
1134
+
1077
1135
  ###########################################################################
1078
1136
  def input(self, filename, fileset=None, filetype=None, iomap=None,
1079
1137
  step=None, index=None, package=None):
@@ -2058,19 +2116,11 @@ class Chip:
2058
2116
  dot.attr(bgcolor=background)
2059
2117
 
2060
2118
  subgraphs = {
2061
- "graphs": {
2062
- "sc-inputs": {
2063
- "graphs": {},
2064
- "nodes": []
2065
- }
2066
- },
2119
+ "graphs": {},
2067
2120
  "nodes": []
2068
2121
  }
2069
2122
  for node, info in nodes.items():
2070
- if info['is_input']:
2071
- subgraph_temp = subgraphs["graphs"]["sc-inputs"]
2072
- else:
2073
- subgraph_temp = subgraphs
2123
+ subgraph_temp = subgraphs
2074
2124
 
2075
2125
  for key in node.split(".")[0:-1]:
2076
2126
  if key not in subgraph_temp["graphs"]:
@@ -2079,6 +2129,15 @@ class Chip:
2079
2129
  "nodes": []
2080
2130
  }
2081
2131
  subgraph_temp = subgraph_temp["graphs"][key]
2132
+
2133
+ if info['is_input']:
2134
+ if "sc-inputs" not in subgraph_temp["graphs"]:
2135
+ subgraph_temp["graphs"]["sc-inputs"] = {
2136
+ "graphs": {},
2137
+ "nodes": []
2138
+ }
2139
+ subgraph_temp = subgraph_temp["graphs"]["sc-inputs"]
2140
+
2082
2141
  subgraph_temp["nodes"].append(node)
2083
2142
 
2084
2143
  with dot.subgraph(name='inputs') as input_graph:
@@ -2131,7 +2190,8 @@ class Chip:
2131
2190
  for subgraph in graph_info["graphs"]:
2132
2191
  child_prefix = prefix
2133
2192
  if get_node_count(graph_info["graphs"][subgraph]) > 1:
2134
- child_prefix = f"{child_prefix}{subgraph}."
2193
+ if subgraph != "sc-inputs":
2194
+ child_prefix = f"{child_prefix}{subgraph}."
2135
2195
  graph = graphviz.Digraph(name=f"cluster_{graph_idx}")
2136
2196
  graph_idx += 1
2137
2197
 
@@ -2382,7 +2442,7 @@ class Chip:
2382
2442
  swap('library', lib, 'option', 'library')
2383
2443
 
2384
2444
  ########################################################################
2385
- def collect(self, directory=None, verbose=True, whitelist=None):
2445
+ def collect(self, directory=None, verbose=True, whitelist=None, exclude_packages=None):
2386
2446
  '''
2387
2447
  Collects files found in the configuration dictionary and places
2388
2448
  them in inputs/. The function only copies in files that have the 'copy'
@@ -2400,6 +2460,8 @@ class Chip:
2400
2460
  whitelist (list[path]): List of directories that are allowed to be
2401
2461
  collected. If a directory is is found that is not on this list
2402
2462
  a RuntimeError will be raised.
2463
+ package_filter (list[str]): List of packages to exclude from
2464
+ collection.
2403
2465
  '''
2404
2466
 
2405
2467
  if not directory:
@@ -2412,6 +2474,9 @@ class Chip:
2412
2474
  if verbose:
2413
2475
  self.logger.info('Collecting input sources')
2414
2476
 
2477
+ if not exclude_packages:
2478
+ exclude_packages = []
2479
+
2415
2480
  dirs = {}
2416
2481
  files = {}
2417
2482
 
@@ -2451,6 +2516,8 @@ class Chip:
2451
2516
  if not package:
2452
2517
  # Ensure package is an empty string
2453
2518
  package = ''
2519
+ if package in exclude_packages:
2520
+ continue
2454
2521
  if is_dir:
2455
2522
  dirs[(package, path)] = abspath
2456
2523
  else:
@@ -3126,7 +3193,7 @@ class Chip:
3126
3193
  extension (str): extension of file to show
3127
3194
 
3128
3195
  Examples:
3129
- >>> show('build/oh_add/job0/write_gds/0/outputs/oh_add.gds')
3196
+ >>> show('build/oh_add/job0/write.gds/0/outputs/oh_add.gds')
3130
3197
  Displays gds file with a viewer assigned by showtool
3131
3198
  '''
3132
3199
 
@@ -0,0 +1,34 @@
1
+ from siliconcompiler.flows import asicflow
2
+ from siliconcompiler.flows import asictopflow
3
+ from siliconcompiler.flows import drcflow
4
+ from siliconcompiler.flows import dvflow
5
+ from siliconcompiler.flows import fpgaflow
6
+ from siliconcompiler.flows import generate_openroad_rcx
7
+ from siliconcompiler.flows import interposerflow
8
+ from siliconcompiler.flows import lintflow
9
+ from siliconcompiler.flows import screenshotflow
10
+ from siliconcompiler.flows import showflow
11
+ from siliconcompiler.flows import signoffflow
12
+ from siliconcompiler.flows import synflow
13
+
14
+
15
+ def get_flows():
16
+ '''
17
+ Returns a dict of builtin flows
18
+ '''
19
+ return {
20
+ module.__name__.split(".")[-1]: module for module in (
21
+ asicflow,
22
+ asictopflow,
23
+ drcflow,
24
+ dvflow,
25
+ fpgaflow,
26
+ generate_openroad_rcx,
27
+ interposerflow,
28
+ lintflow,
29
+ screenshotflow,
30
+ showflow,
31
+ signoffflow,
32
+ synflow
33
+ )
34
+ }
@@ -22,17 +22,17 @@ def _make_docs(chip):
22
22
 
23
23
  def __get_frontends(allow_system_verilog):
24
24
  systemverilog_frontend = [
25
- ('import', surelog_parse)
25
+ ('import.verilog', surelog_parse)
26
26
  ]
27
27
  if not allow_system_verilog:
28
- systemverilog_frontend.append(('convert', sv2v_convert))
28
+ systemverilog_frontend.append(('import.convert', sv2v_convert))
29
29
 
30
30
  return {
31
31
  "verilog": systemverilog_frontend,
32
- "chisel": [('import', chisel_convert)],
33
- "c": [('import', bambu_convert)],
34
- "bluespec": [('import', bluespec_convert)],
35
- "vhdl": [('import', ghdl_convert)]
32
+ "chisel": [('import.chisel', chisel_convert)],
33
+ "c": [('import.c', bambu_convert)],
34
+ "bluespec": [('import.bluespec', bluespec_convert)],
35
+ "vhdl": [('import.vhdl', ghdl_convert)]
36
36
  }
37
37
 
38
38
 
@@ -45,21 +45,19 @@ def setup_multiple_frontends(flow, allow_system_verilog=False):
45
45
 
46
46
  concat_nodes = []
47
47
  flowname = flow.design
48
- for frontend, pipe in __get_frontends(allow_system_verilog).items():
48
+ for _, pipe in __get_frontends(allow_system_verilog).items():
49
49
  prev_step = None
50
50
  for step, task in pipe:
51
- step_name = f'{step}_{frontend}'
52
-
53
- flow.node(flowname, step_name, task)
51
+ flow.node(flowname, step, task)
54
52
  if prev_step:
55
- flow.edge(flowname, prev_step, step_name)
53
+ flow.edge(flowname, prev_step, step)
56
54
 
57
- prev_step = step_name
55
+ prev_step = step
58
56
 
59
57
  if prev_step:
60
58
  concat_nodes.append(prev_step)
61
59
 
62
- final_node = 'combine'
60
+ final_node = 'import.combine'
63
61
  flow.node(flowname, final_node, concatenate)
64
62
  for node in concat_nodes:
65
63
  flow.edge(flowname, node, final_node)