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.
- siliconcompiler/_metadata.py +1 -1
- siliconcompiler/apps/_common.py +88 -56
- siliconcompiler/apps/sc.py +33 -14
- siliconcompiler/apps/sc_dashboard.py +17 -10
- siliconcompiler/apps/sc_show.py +17 -15
- siliconcompiler/core.py +95 -55
- siliconcompiler/flows/drcflow.py +13 -0
- siliconcompiler/flows/interposerflow.py +17 -0
- siliconcompiler/fpgas/vpr_example.py +8 -0
- siliconcompiler/libs/interposer.py +8 -0
- siliconcompiler/package.py +3 -2
- siliconcompiler/pdks/interposer.py +8 -0
- siliconcompiler/remote/schema.py +11 -1
- siliconcompiler/remote/server.py +7 -2
- siliconcompiler/report/dashboard/__init__.py +9 -0
- siliconcompiler/report/dashboard/components/__init__.py +13 -1
- siliconcompiler/report/dashboard/layouts/vertical_flowgraph.py +4 -3
- siliconcompiler/report/dashboard/layouts/vertical_flowgraph_node_tab.py +4 -1
- siliconcompiler/report/dashboard/layouts/vertical_flowgraph_sac_tabs.py +4 -1
- siliconcompiler/report/dashboard/state.py +3 -1
- siliconcompiler/report/summary_table.py +1 -2
- siliconcompiler/report/utils.py +1 -2
- siliconcompiler/scheduler/__init__.py +95 -0
- siliconcompiler/schema/schema_cfg.py +15 -3
- siliconcompiler/schema/schema_obj.py +51 -1
- siliconcompiler/sphinx_ext/dynamicgen.py +6 -0
- siliconcompiler/targets/interposer_demo.py +56 -0
- siliconcompiler/templates/tcl/manifest.tcl.j2 +2 -0
- siliconcompiler/tools/_common/__init__.py +44 -6
- siliconcompiler/tools/_common/asic.py +79 -23
- siliconcompiler/tools/genfasm/genfasm.py +7 -0
- siliconcompiler/tools/ghdl/convert.py +7 -0
- siliconcompiler/tools/klayout/convert_drc_db.py +60 -0
- siliconcompiler/tools/klayout/drc.py +156 -0
- siliconcompiler/tools/klayout/export.py +9 -4
- siliconcompiler/tools/klayout/klayout.py +0 -1
- siliconcompiler/tools/klayout/klayout_convert_drc_db.py +182 -0
- siliconcompiler/tools/klayout/klayout_export.py +3 -0
- siliconcompiler/tools/klayout/klayout_utils.py +8 -2
- siliconcompiler/tools/klayout/operations.py +2 -0
- siliconcompiler/tools/klayout/screenshot.py +2 -0
- siliconcompiler/tools/klayout/show.py +4 -4
- siliconcompiler/tools/magic/drc.py +21 -0
- siliconcompiler/tools/magic/extspice.py +21 -0
- siliconcompiler/tools/magic/magic.py +29 -0
- siliconcompiler/tools/magic/sc_drc.tcl +2 -12
- siliconcompiler/tools/magic/sc_extspice.tcl +3 -15
- siliconcompiler/tools/openroad/metrics.py +45 -0
- siliconcompiler/tools/openroad/openroad.py +47 -2
- siliconcompiler/tools/openroad/rdlroute.py +97 -0
- siliconcompiler/tools/openroad/scripts/sc_apr.tcl +16 -1
- siliconcompiler/tools/openroad/scripts/sc_floorplan.tcl +55 -9
- siliconcompiler/tools/openroad/scripts/sc_metrics.tcl +0 -159
- siliconcompiler/tools/openroad/scripts/sc_procs.tcl +3 -1
- siliconcompiler/tools/openroad/scripts/sc_rdlroute.tcl +184 -0
- siliconcompiler/tools/openroad/scripts/sc_report.tcl +170 -0
- siliconcompiler/tools/openroad/scripts/sc_route.tcl +8 -2
- siliconcompiler/tools/openroad/scripts/sc_screenshot.tcl +0 -5
- siliconcompiler/tools/openroad/scripts/sc_write_images.tcl +36 -6
- siliconcompiler/tools/opensta/scripts/sc_report_libraries.tcl +11 -1
- siliconcompiler/tools/surelog/__init__.py +12 -0
- siliconcompiler/tools/verilator/compile.py +27 -0
- siliconcompiler/tools/verilator/verilator.py +9 -0
- siliconcompiler/tools/vpr/vpr.py +18 -0
- siliconcompiler/tools/xyce/__init__.py +1 -1
- siliconcompiler/tools/yosys/{syn_asic_fpga_shared.tcl → procs.tcl} +23 -0
- siliconcompiler/tools/yosys/sc_screenshot.tcl +104 -0
- siliconcompiler/tools/yosys/sc_syn.tcl +7 -9
- siliconcompiler/tools/yosys/screenshot.py +153 -0
- siliconcompiler/tools/yosys/syn_asic.py +3 -0
- siliconcompiler/tools/yosys/syn_asic.tcl +1 -3
- siliconcompiler/tools/yosys/syn_fpga.tcl +3 -2
- siliconcompiler/toolscripts/_tools.json +5 -6
- siliconcompiler/toolscripts/rhel8/install-xyce.sh +4 -5
- siliconcompiler/toolscripts/rhel9/install-xyce.sh +4 -5
- siliconcompiler/toolscripts/ubuntu20/install-xyce.sh +5 -5
- siliconcompiler/toolscripts/ubuntu22/install-xyce.sh +2 -2
- siliconcompiler/toolscripts/ubuntu24/install-xyce.sh +2 -2
- siliconcompiler/utils/__init__.py +30 -1
- siliconcompiler/utils/showtools.py +4 -0
- {siliconcompiler-0.28.3.dist-info → siliconcompiler-0.28.5.dist-info}/METADATA +18 -5
- {siliconcompiler-0.28.3.dist-info → siliconcompiler-0.28.5.dist-info}/RECORD +86 -72
- {siliconcompiler-0.28.3.dist-info → siliconcompiler-0.28.5.dist-info}/WHEEL +1 -1
- {siliconcompiler-0.28.3.dist-info → siliconcompiler-0.28.5.dist-info}/LICENSE +0 -0
- {siliconcompiler-0.28.3.dist-info → siliconcompiler-0.28.5.dist-info}/entry_points.txt +0 -0
- {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
|
|
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
|
-
|
|
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
|
-
|
|
35
|
-
|
|
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
|
-
|
|
38
|
-
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
|
-
|
|
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
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
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
|
|
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
|
|
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
|