siliconcompiler 0.28.3__py3-none-any.whl → 0.28.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 (86) hide show
  1. siliconcompiler/_metadata.py +1 -1
  2. siliconcompiler/apps/_common.py +88 -56
  3. siliconcompiler/apps/sc.py +33 -14
  4. siliconcompiler/apps/sc_dashboard.py +17 -10
  5. siliconcompiler/apps/sc_show.py +17 -15
  6. siliconcompiler/core.py +95 -55
  7. siliconcompiler/flows/drcflow.py +13 -0
  8. siliconcompiler/flows/interposerflow.py +17 -0
  9. siliconcompiler/fpgas/vpr_example.py +8 -0
  10. siliconcompiler/libs/interposer.py +8 -0
  11. siliconcompiler/package.py +3 -2
  12. siliconcompiler/pdks/interposer.py +8 -0
  13. siliconcompiler/remote/schema.py +11 -1
  14. siliconcompiler/remote/server.py +7 -2
  15. siliconcompiler/report/dashboard/__init__.py +9 -0
  16. siliconcompiler/report/dashboard/components/__init__.py +13 -1
  17. siliconcompiler/report/dashboard/layouts/vertical_flowgraph.py +4 -3
  18. siliconcompiler/report/dashboard/layouts/vertical_flowgraph_node_tab.py +4 -1
  19. siliconcompiler/report/dashboard/layouts/vertical_flowgraph_sac_tabs.py +4 -1
  20. siliconcompiler/report/dashboard/state.py +3 -1
  21. siliconcompiler/report/summary_table.py +1 -2
  22. siliconcompiler/report/utils.py +1 -2
  23. siliconcompiler/scheduler/__init__.py +95 -0
  24. siliconcompiler/schema/schema_cfg.py +15 -3
  25. siliconcompiler/schema/schema_obj.py +51 -1
  26. siliconcompiler/sphinx_ext/dynamicgen.py +6 -0
  27. siliconcompiler/targets/interposer_demo.py +56 -0
  28. siliconcompiler/templates/tcl/manifest.tcl.j2 +2 -0
  29. siliconcompiler/tools/_common/__init__.py +44 -6
  30. siliconcompiler/tools/_common/asic.py +79 -23
  31. siliconcompiler/tools/genfasm/genfasm.py +7 -0
  32. siliconcompiler/tools/ghdl/convert.py +7 -0
  33. siliconcompiler/tools/klayout/convert_drc_db.py +60 -0
  34. siliconcompiler/tools/klayout/drc.py +156 -0
  35. siliconcompiler/tools/klayout/export.py +9 -4
  36. siliconcompiler/tools/klayout/klayout.py +0 -1
  37. siliconcompiler/tools/klayout/klayout_convert_drc_db.py +182 -0
  38. siliconcompiler/tools/klayout/klayout_export.py +3 -0
  39. siliconcompiler/tools/klayout/klayout_utils.py +8 -2
  40. siliconcompiler/tools/klayout/operations.py +2 -0
  41. siliconcompiler/tools/klayout/screenshot.py +2 -0
  42. siliconcompiler/tools/klayout/show.py +4 -4
  43. siliconcompiler/tools/magic/drc.py +21 -0
  44. siliconcompiler/tools/magic/extspice.py +21 -0
  45. siliconcompiler/tools/magic/magic.py +29 -0
  46. siliconcompiler/tools/magic/sc_drc.tcl +2 -12
  47. siliconcompiler/tools/magic/sc_extspice.tcl +3 -15
  48. siliconcompiler/tools/openroad/metrics.py +45 -0
  49. siliconcompiler/tools/openroad/openroad.py +47 -2
  50. siliconcompiler/tools/openroad/rdlroute.py +97 -0
  51. siliconcompiler/tools/openroad/scripts/sc_apr.tcl +16 -1
  52. siliconcompiler/tools/openroad/scripts/sc_floorplan.tcl +55 -9
  53. siliconcompiler/tools/openroad/scripts/sc_metrics.tcl +0 -159
  54. siliconcompiler/tools/openroad/scripts/sc_procs.tcl +3 -1
  55. siliconcompiler/tools/openroad/scripts/sc_rdlroute.tcl +184 -0
  56. siliconcompiler/tools/openroad/scripts/sc_report.tcl +170 -0
  57. siliconcompiler/tools/openroad/scripts/sc_route.tcl +8 -2
  58. siliconcompiler/tools/openroad/scripts/sc_screenshot.tcl +0 -5
  59. siliconcompiler/tools/openroad/scripts/sc_write_images.tcl +36 -6
  60. siliconcompiler/tools/opensta/scripts/sc_report_libraries.tcl +11 -1
  61. siliconcompiler/tools/surelog/__init__.py +12 -0
  62. siliconcompiler/tools/verilator/compile.py +27 -0
  63. siliconcompiler/tools/verilator/verilator.py +9 -0
  64. siliconcompiler/tools/vpr/vpr.py +18 -0
  65. siliconcompiler/tools/xyce/__init__.py +1 -1
  66. siliconcompiler/tools/yosys/{syn_asic_fpga_shared.tcl → procs.tcl} +23 -0
  67. siliconcompiler/tools/yosys/sc_screenshot.tcl +104 -0
  68. siliconcompiler/tools/yosys/sc_syn.tcl +7 -9
  69. siliconcompiler/tools/yosys/screenshot.py +153 -0
  70. siliconcompiler/tools/yosys/syn_asic.py +3 -0
  71. siliconcompiler/tools/yosys/syn_asic.tcl +1 -3
  72. siliconcompiler/tools/yosys/syn_fpga.tcl +3 -2
  73. siliconcompiler/toolscripts/_tools.json +5 -6
  74. siliconcompiler/toolscripts/rhel8/install-xyce.sh +4 -5
  75. siliconcompiler/toolscripts/rhel9/install-xyce.sh +4 -5
  76. siliconcompiler/toolscripts/ubuntu20/install-xyce.sh +5 -5
  77. siliconcompiler/toolscripts/ubuntu22/install-xyce.sh +2 -2
  78. siliconcompiler/toolscripts/ubuntu24/install-xyce.sh +2 -2
  79. siliconcompiler/utils/__init__.py +30 -1
  80. siliconcompiler/utils/showtools.py +4 -0
  81. {siliconcompiler-0.28.3.dist-info → siliconcompiler-0.28.5.dist-info}/METADATA +18 -5
  82. {siliconcompiler-0.28.3.dist-info → siliconcompiler-0.28.5.dist-info}/RECORD +86 -72
  83. {siliconcompiler-0.28.3.dist-info → siliconcompiler-0.28.5.dist-info}/WHEEL +1 -1
  84. {siliconcompiler-0.28.3.dist-info → siliconcompiler-0.28.5.dist-info}/LICENSE +0 -0
  85. {siliconcompiler-0.28.3.dist-info → siliconcompiler-0.28.5.dist-info}/entry_points.txt +0 -0
  86. {siliconcompiler-0.28.3.dist-info → siliconcompiler-0.28.5.dist-info}/top_level.txt +0 -0
@@ -2,7 +2,7 @@ import os
2
2
  import pkgutil
3
3
 
4
4
 
5
- def get_libraries(chip, include_asic=True, library=None, libraries=None):
5
+ def __get_library_keys(chip, include_asic=True, library=None, libraries=None):
6
6
  '''
7
7
  Returns a list of libraries included in this step/index
8
8
 
@@ -24,18 +24,52 @@ def get_libraries(chip, include_asic=True, library=None, libraries=None):
24
24
 
25
25
  def get_libs(*key):
26
26
  if chip.valid(*key) and chip.get(*key, step=step, index=index):
27
- return chip.get(*key, step=step, index=index)
27
+ if chip.get(*key, step=step, index=index):
28
+ return [key]
28
29
  return []
29
30
 
30
31
  if include_asic:
31
32
  libs.extend(get_libs(*pref_key, 'asic', 'logiclib'))
32
33
  libs.extend(get_libs(*pref_key, 'asic', 'macrolib'))
33
34
 
34
- for lib in get_libs(*pref_key, 'option', 'library'):
35
- if lib in libs or lib in libraries:
35
+ libnames = set()
36
+ if library:
37
+ libnames.add(library)
38
+ for lib_key in get_libs(*pref_key, 'option', 'library'):
39
+ if lib_key in libs:
36
40
  continue
37
- libs.append(lib)
38
- libs.extend(get_libraries(chip, include_asic=include_asic, library=lib, libraries=libs))
41
+
42
+ libs.append(lib_key)
43
+
44
+ for libname in chip.get(*lib_key, step=step, index=index):
45
+ if libname in libnames:
46
+ continue
47
+
48
+ libnames.add(libname)
49
+ libs.extend(__get_library_keys(
50
+ chip,
51
+ include_asic=include_asic,
52
+ library=libname,
53
+ libraries=libnames))
54
+
55
+ return set(libs)
56
+
57
+
58
+ def get_libraries(chip, include_asic=True):
59
+ '''
60
+ Returns a list of libraries included in this step/index
61
+
62
+ Args:
63
+ chip (Chip): Chip object
64
+ include_asic (bool): include the asic libraries.
65
+ '''
66
+ step = chip.get('arg', 'step')
67
+ index = chip.get('arg', 'index')
68
+
69
+ libs = []
70
+
71
+ for key in __get_library_keys(chip, include_asic=include_asic):
72
+ libs.extend(chip.get(*key, step=step, index=index))
39
73
 
40
74
  return set(libs)
41
75
 
@@ -212,6 +246,10 @@ def add_frontend_requires(chip, supports=None):
212
246
  step = chip.get('arg', 'step')
213
247
  index = chip.get('arg', 'index')
214
248
  tool, task = get_tool_task(chip, step, index)
249
+
250
+ for libkey in __get_library_keys(chip):
251
+ chip.add('tool', tool, 'task', task, 'require', ','.join(libkey), step=step, index=index)
252
+
215
253
  for opt in supports:
216
254
  for key in opt_keys[opt]:
217
255
  chip.add('tool', tool, 'task', task, 'require', ','.join(key), step=step, index=index)
@@ -47,7 +47,8 @@ def set_tool_task_var(chip,
47
47
  option_key=None,
48
48
  pdk_key=None,
49
49
  lib_key=None,
50
- require=None):
50
+ require=None,
51
+ skip=None):
51
52
  '''
52
53
  Set parameter from PDK -> main library -> option -> default_value
53
54
  '''
@@ -56,7 +57,11 @@ def set_tool_task_var(chip,
56
57
  tool, task = _common.get_tool_task(chip, step, index)
57
58
  pdkname = chip.get('option', 'pdk')
58
59
  stackup = chip.get('option', 'stackup')
59
- mainlib = get_mainlib(chip)
60
+
61
+ if not skip:
62
+ skip = []
63
+ if not isinstance(skip, (list, tuple)):
64
+ skip = [skip]
60
65
 
61
66
  if not require:
62
67
  require = []
@@ -66,31 +71,35 @@ def set_tool_task_var(chip,
66
71
  check_keys = []
67
72
 
68
73
  # 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)
74
+ if 'pdk' not in skip:
75
+ if not pdk_key:
76
+ pdk_key = param_key
77
+ check_keys.append(['pdk', pdkname, 'var', tool, stackup, pdk_key])
78
+ if 'pdk' in require:
79
+ chip.add('tool', tool, 'task', task, 'require',
80
+ ','.join(check_keys[-1]),
81
+ step=step, index=index)
76
82
 
77
83
  # 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)
84
+ if 'lib' not in skip:
85
+ mainlib = get_mainlib(chip)
86
+ if not lib_key:
87
+ lib_key = f'{tool}_{param_key}'
88
+ check_keys.append(['library', mainlib, 'option', 'var', lib_key])
89
+ if 'lib' in require:
90
+ chip.add('tool', tool, 'task', task, 'require',
91
+ ','.join(check_keys[-1]),
92
+ step=step, index=index)
85
93
 
86
94
  # 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)
95
+ if 'option' not in skip:
96
+ if not option_key:
97
+ option_key = f'{tool}_{param_key}'
98
+ check_keys.append(['option', 'var', option_key])
99
+ if 'option' in require:
100
+ chip.add('tool', tool, 'task', task, 'require',
101
+ ','.join(check_keys[-1]),
102
+ step=step, index=index)
94
103
 
95
104
  require_key, value = _common.pick_key(chip, reversed(check_keys), step=step, index=index)
96
105
  if not value:
@@ -113,3 +122,50 @@ def set_tool_task_var(chip,
113
122
  if schelp:
114
123
  chip.set('tool', tool, 'task', task, 'var', param_key,
115
124
  schelp, field='help')
125
+
126
+ return value
127
+
128
+
129
+ def get_tool_task_var(chip,
130
+ param_key,
131
+ option_key=None,
132
+ pdk_key=None,
133
+ lib_key=None,
134
+ skip=None):
135
+ '''
136
+ Get parameter from PDK -> main library -> option -> default_value
137
+ '''
138
+ step = chip.get('arg', 'step')
139
+ index = chip.get('arg', 'index')
140
+ tool, _ = _common.get_tool_task(chip, step, index)
141
+ pdkname = chip.get('option', 'pdk')
142
+ stackup = chip.get('option', 'stackup')
143
+
144
+ if not skip:
145
+ skip = []
146
+ if not isinstance(skip, (list, tuple)):
147
+ skip = [skip]
148
+
149
+ check_keys = []
150
+ # Add PDK key
151
+ if 'pdk' not in skip:
152
+ if not pdk_key:
153
+ pdk_key = param_key
154
+ check_keys.append(['pdk', pdkname, 'var', tool, stackup, pdk_key])
155
+
156
+ # Add library key
157
+ if 'lib' not in skip:
158
+ mainlib = get_mainlib(chip)
159
+ if not lib_key:
160
+ lib_key = f'{tool}_{param_key}'
161
+ check_keys.append(['library', mainlib, 'option', 'var', lib_key])
162
+
163
+ # Add option key
164
+ if 'option' not in skip:
165
+ if not option_key:
166
+ option_key = f'{tool}_{param_key}'
167
+ check_keys.append(['option', 'var', option_key])
168
+
169
+ _, value = _common.pick_key(chip, reversed(check_keys), step=step, index=index)
170
+
171
+ return value
@@ -1,5 +1,6 @@
1
1
  from siliconcompiler.tools.vpr.vpr import parse_version as vpr_parse_version
2
2
  from siliconcompiler.tools.vpr.vpr import normalize_version as vpr_normalize_version
3
+ from siliconcompiler.tools.vpr.vpr import add_tool_requirements as add_vpr_requirements
3
4
 
4
5
  '''
5
6
  Generate a `FSAM <https://github.com/chipsalliance/fasm>`_ file from the output of
@@ -25,6 +26,12 @@ def setup(chip):
25
26
  chip.set('tool', 'genfasm', 'vswitch', '--version')
26
27
  chip.set('tool', 'genfasm', 'version', '>=8.1.0', clobber=False)
27
28
 
29
+ add_tool_requirements(chip)
30
+
31
+
32
+ def add_tool_requirements(chip):
33
+ add_vpr_requirements(chip)
34
+
28
35
 
29
36
  def parse_version(chip):
30
37
  return vpr_parse_version(chip)
@@ -40,6 +40,13 @@ def setup(chip):
40
40
 
41
41
  chip.set('tool', tool, 'task', task, 'output', f'{design}.v', step=step, index=index)
42
42
 
43
+ chip.set('tool', tool, 'task', task, 'var', 'extraopts', 'extra options to pass to ghdl',
44
+ field='help')
45
+ if chip.get('tool', tool, 'task', task, 'var', 'extraopts', step=step, index=index):
46
+ chip.add('tool', tool, 'task', task, 'require',
47
+ ','.join(['tool', tool, 'task', task, 'var', 'extraopts']),
48
+ step=step, index=index)
49
+
43
50
 
44
51
  ################################
45
52
  # Custom runtime options
@@ -0,0 +1,60 @@
1
+ from siliconcompiler.tools._common import input_provides, input_file_node_name, get_tool_task
2
+
3
+ from siliconcompiler.tools.klayout import klayout
4
+ from siliconcompiler.tools.klayout.klayout import setup as setup_tool
5
+
6
+
7
+ def make_docs(chip):
8
+ klayout.make_docs(chip)
9
+
10
+
11
+ def setup(chip):
12
+ '''
13
+ Convert a DRC db from .lyrdb or .ascii to an openroad json marker file
14
+ '''
15
+
16
+ # Generic tool setup.
17
+ setup_tool(chip)
18
+
19
+ step = chip.get('arg', 'step')
20
+ index = chip.get('arg', 'index')
21
+ tool, task = get_tool_task(chip, step, index)
22
+ design = chip.top()
23
+
24
+ clobber = False
25
+
26
+ chip.set('tool', tool, 'task', task, 'threads', 1,
27
+ step=step, index=index, clobber=clobber)
28
+
29
+ script = 'klayout_convert_drc_db.py'
30
+ option = ['-z', '-nc', '-rx', '-r']
31
+ chip.set('tool', tool, 'task', task, 'script', script,
32
+ step=step, index=index, clobber=clobber)
33
+ chip.set('tool', tool, 'task', task, 'option', option,
34
+ step=step, index=index, clobber=clobber)
35
+
36
+ input_nodes = set()
37
+ for nodes in input_provides(chip, step, index).values():
38
+ input_nodes.update(nodes)
39
+
40
+ chip.set('tool', tool, 'task', task, 'input', [], step=step, index=index)
41
+ chip.set('tool', tool, 'task', task, 'output', [], step=step, index=index)
42
+ for file, nodes in input_provides(chip, step, index).items():
43
+ if file not in (f'{design}.lyrdb', f'{design}.ascii'):
44
+ continue
45
+
46
+ if len(input_nodes) == 1:
47
+ chip.add('tool', tool, 'task', task, 'input',
48
+ file,
49
+ step=step, index=index)
50
+ else:
51
+ for in_step, in_index in nodes:
52
+ chip.add('tool', tool, 'task', task, 'input',
53
+ input_file_node_name(file, in_step, in_index),
54
+ step=step, index=index)
55
+ if not chip.get('tool', tool, 'task', task, 'input', step=step, index=index):
56
+ chip.add('tool', tool, 'task', task, 'input', f'{design}.lyrdb',
57
+ step=step, index=index)
58
+
59
+ chip.set('tool', tool, 'task', task, 'output', f'{design}.json',
60
+ step=step, index=index)
@@ -0,0 +1,156 @@
1
+ import os
2
+ import shlex
3
+
4
+ from siliconcompiler.tools._common import input_provides, has_input_files, \
5
+ get_input_files, get_tool_task, record_metric
6
+ from siliconcompiler.tools._common.asic import set_tool_task_var, get_tool_task_var
7
+
8
+ from siliconcompiler.tools.klayout import klayout
9
+ from siliconcompiler.tools.klayout.klayout import setup as setup_tool
10
+ import xml.etree.ElementTree as ET
11
+
12
+
13
+ def make_docs(chip):
14
+ klayout.make_docs(chip)
15
+ chip.set('tool', 'klayout', 'task', 'drc', 'var', 'drc_name', '<drc_name>',
16
+ step='<step>', index='<index>')
17
+
18
+
19
+ def setup(chip):
20
+ '''
21
+ Performs a design rule check on the provided layout
22
+ '''
23
+
24
+ # Generic tool setup.
25
+ setup_tool(chip)
26
+
27
+ step = chip.get('arg', 'step')
28
+ index = chip.get('arg', 'index')
29
+ tool, task = get_tool_task(chip, step, index)
30
+ design = chip.top()
31
+
32
+ clobber = False
33
+
34
+ option = ['-z', '-nc', '-rx']
35
+ chip.set('tool', tool, 'task', task, 'option', option,
36
+ step=step, index=index, clobber=clobber)
37
+
38
+ chip.set('tool', tool, 'task', task, 'threads', os.cpu_count(),
39
+ step=step, index=index, clobber=clobber)
40
+
41
+ chip.add('tool', tool, 'task', task, 'require', 'option,pdk')
42
+ chip.add('tool', tool, 'task', task, 'require', 'option,stackup')
43
+
44
+ chip.set('tool', tool, 'task', task, 'var', 'drc_name', 'drc',
45
+ step=step, index=index, clobber=False)
46
+ chip.add('tool', tool, 'task', task, 'require', f'tool,{tool},task,{task},var,drc_name',
47
+ step=step, index=index)
48
+
49
+ drc_name = chip.get('tool', tool, 'task', task, 'var', 'drc_name', step=step, index=index)
50
+ if not drc_name:
51
+ raise ValueError('drc_name is required')
52
+ drc_name = drc_name[0]
53
+
54
+ pdk = chip.get('option', 'pdk')
55
+ stackup = chip.get('option', 'stackup')
56
+ chip.add('tool', tool, 'task', task, 'require',
57
+ f'pdk,{pdk},drc,runset,klayout,{stackup},{drc_name}')
58
+
59
+ if f'{design}.gds' in input_provides(chip, step, index):
60
+ chip.add('tool', tool, 'task', task, 'input', design + '.gds',
61
+ step=step, index=index)
62
+ elif f'{design}.oas' in input_provides(chip, step, index):
63
+ chip.add('tool', tool, 'task', task, 'input', design + '.oas',
64
+ step=step, index=index)
65
+ elif has_input_files(chip, 'input', 'layout', 'oas', check_library_files=False):
66
+ chip.add('tool', tool, 'task', task, 'require', 'input,layout,oas',
67
+ step=step, index=index)
68
+ else:
69
+ chip.add('tool', tool, 'task', task, 'require', 'input,layout,gds',
70
+ step=step, index=index)
71
+
72
+ chip.add('tool', tool, 'task', task, 'output', design + '.lyrdb',
73
+ step=step, index=index)
74
+
75
+ set_tool_task_var(
76
+ chip,
77
+ f'drc_params:{drc_name}',
78
+ schelp="Input parameter to DRC script, in the form of key=value, if the value "
79
+ "is <topcell>, <input>, <report>, <threads> these will be automatically "
80
+ "determined.",
81
+ skip='lib')
82
+
83
+
84
+ def runtime_options(chip):
85
+ design = chip.top()
86
+
87
+ step = chip.get('arg', 'step')
88
+ index = chip.get('arg', 'index')
89
+ tool, task = get_tool_task(chip, step, index)
90
+
91
+ pdk = chip.get('option', 'pdk')
92
+ stackup = chip.get('option', 'stackup')
93
+
94
+ layout = None
95
+ for file in [f'inputs/{design}.gds', f'inputs/{design}.oas']:
96
+ if os.path.isfile(file):
97
+ layout = file
98
+ break
99
+
100
+ if not layout:
101
+ for file in [
102
+ get_input_files(chip, 'input', 'layout', 'oas', add_library_files=False),
103
+ get_input_files(chip, 'input', 'layout', 'gds', add_library_files=False)]:
104
+ if file:
105
+ layout = file[0]
106
+
107
+ threads = chip.get('tool', tool, 'task', task, 'threads', step=step, index=index)
108
+ if not threads:
109
+ threads = 1
110
+
111
+ drc_name = chip.get('tool', tool, 'task', task, 'var', 'drc_name',
112
+ step=step, index=index)[0]
113
+ report = os.path.abspath(f"outputs/{chip.top()}.lyrdb")
114
+
115
+ runset = chip.find_files('pdk', pdk, 'drc', 'runset', 'klayout', stackup, drc_name)[0]
116
+
117
+ params_lookup = {
118
+ "<topcell>": chip.top(),
119
+ "<report>": shlex.quote(report),
120
+ "<threads>": threads,
121
+ "<input>": shlex.quote(layout)
122
+ }
123
+
124
+ args = [
125
+ '-r', shlex.quote(runset)
126
+ ]
127
+
128
+ for param in get_tool_task_var(chip, f'drc_params:{drc_name}', skip='lib'):
129
+ for lookup, value in params_lookup.items():
130
+ param = param.replace(lookup, str(value))
131
+ args.extend(
132
+ ['-rd', param]
133
+ )
134
+ return args
135
+
136
+
137
+ def post_process(chip):
138
+ step = chip.get('arg', 'step')
139
+ index = chip.get('arg', 'index')
140
+
141
+ drc_db = f"outputs/{chip.top()}.lyrdb"
142
+
143
+ drc_report = None
144
+ if os.path.isfile(drc_db):
145
+ with open(drc_db, "r") as f:
146
+ drc_report = ET.fromstring(f.read())
147
+ if drc_report is None:
148
+ drc_db = []
149
+
150
+ violation_count = 0
151
+ if drc_report:
152
+ violations = drc_report.find('items')
153
+ if violations:
154
+ violation_count = len(violations.findall('item'))
155
+
156
+ record_metric(chip, step, index, 'drcs', violation_count, drc_db)
@@ -19,6 +19,8 @@ def setup(chip):
19
19
  _, task = get_tool_task(chip, step, index)
20
20
  clobber = False
21
21
 
22
+ chip.set('tool', tool, 'task', task, 'threads', 1, step=step, index=index, clobber=clobber)
23
+
22
24
  script = 'klayout_export.py'
23
25
  option = ['-z', '-nc', '-rx', '-r']
24
26
  chip.set('tool', tool, 'task', task, 'script', script, step=step, index=index, clobber=clobber)
@@ -39,11 +41,9 @@ def setup(chip):
39
41
  step=step, index=index)[0]
40
42
  sc_stream_order = [default_stream, *[s for s in streams if s != default_stream]]
41
43
 
42
- if stackup and targetlibs:
44
+ if stackup:
43
45
  macrolibs = get_libraries(chip, 'macro')
44
46
 
45
- chip.add('tool', tool, 'task', task, 'require', ",".join(['asic', 'logiclib']),
46
- step=step, index=index)
47
47
  chip.add('tool', tool, 'task', task, 'require', ",".join(['option', 'stackup']),
48
48
  step=step, index=index)
49
49
  req_set = False
@@ -81,7 +81,12 @@ def setup(chip):
81
81
  ",".join(['library', lib, 'output', stackup, 'lef']),
82
82
  step=step, index=index)
83
83
  else:
84
- chip.error('Stackup and targetlib parameters required for Klayout.')
84
+ chip.error('Stackup parameter required for Klayout.')
85
+
86
+ if not targetlibs:
87
+ chip.add('tool', tool, 'task', task, 'require',
88
+ 'option,var,klayout_libtype',
89
+ step=step, index=index)
85
90
 
86
91
  # Input/Output requirements for default flow
87
92
  design = chip.top()
@@ -82,7 +82,6 @@ def setup(chip, mode="batch"):
82
82
 
83
83
  chip.set('tool', tool, 'task', task, 'refdir', refdir, step=step, index=index,
84
84
  package='siliconcompiler', clobber=clobber)
85
- chip.set('tool', tool, 'task', task, 'threads', 1, step=step, index=index, clobber=clobber)
86
85
 
87
86
  if chip.get('option', 'nodisplay'):
88
87
  # Tells QT to use the offscreen platform if nodisplay is used