siliconcompiler 0.28.3__py3-none-any.whl → 0.28.4__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 (60) hide show
  1. siliconcompiler/_metadata.py +1 -1
  2. siliconcompiler/apps/sc_dashboard.py +1 -1
  3. siliconcompiler/core.py +93 -55
  4. siliconcompiler/fpgas/vpr_example.py +8 -0
  5. siliconcompiler/package.py +3 -2
  6. siliconcompiler/report/dashboard/__init__.py +9 -0
  7. siliconcompiler/report/dashboard/components/__init__.py +13 -1
  8. siliconcompiler/report/dashboard/layouts/vertical_flowgraph.py +4 -3
  9. siliconcompiler/report/dashboard/layouts/vertical_flowgraph_node_tab.py +4 -1
  10. siliconcompiler/report/dashboard/layouts/vertical_flowgraph_sac_tabs.py +4 -1
  11. siliconcompiler/report/dashboard/state.py +3 -1
  12. siliconcompiler/report/summary_table.py +1 -2
  13. siliconcompiler/report/utils.py +1 -2
  14. siliconcompiler/scheduler/__init__.py +2 -0
  15. siliconcompiler/sphinx_ext/dynamicgen.py +6 -0
  16. siliconcompiler/tools/_common/__init__.py +44 -6
  17. siliconcompiler/tools/_common/asic.py +79 -23
  18. siliconcompiler/tools/genfasm/genfasm.py +7 -0
  19. siliconcompiler/tools/ghdl/convert.py +7 -0
  20. siliconcompiler/tools/klayout/convert_drc_db.py +60 -0
  21. siliconcompiler/tools/klayout/drc.py +156 -0
  22. siliconcompiler/tools/klayout/export.py +2 -0
  23. siliconcompiler/tools/klayout/klayout.py +0 -1
  24. siliconcompiler/tools/klayout/klayout_convert_drc_db.py +182 -0
  25. siliconcompiler/tools/klayout/operations.py +2 -0
  26. siliconcompiler/tools/klayout/screenshot.py +2 -0
  27. siliconcompiler/tools/klayout/show.py +4 -4
  28. siliconcompiler/tools/magic/drc.py +21 -0
  29. siliconcompiler/tools/magic/extspice.py +21 -0
  30. siliconcompiler/tools/magic/magic.py +29 -0
  31. siliconcompiler/tools/magic/sc_drc.tcl +2 -12
  32. siliconcompiler/tools/magic/sc_extspice.tcl +3 -15
  33. siliconcompiler/tools/openroad/openroad.py +44 -2
  34. siliconcompiler/tools/openroad/scripts/sc_apr.tcl +15 -0
  35. siliconcompiler/tools/openroad/scripts/sc_floorplan.tcl +55 -9
  36. siliconcompiler/tools/openroad/scripts/sc_metrics.tcl +10 -0
  37. siliconcompiler/tools/openroad/scripts/sc_procs.tcl +3 -1
  38. siliconcompiler/tools/openroad/scripts/sc_route.tcl +8 -2
  39. siliconcompiler/tools/openroad/scripts/sc_screenshot.tcl +0 -5
  40. siliconcompiler/tools/openroad/scripts/sc_write_images.tcl +36 -6
  41. siliconcompiler/tools/surelog/__init__.py +12 -0
  42. siliconcompiler/tools/verilator/compile.py +27 -0
  43. siliconcompiler/tools/verilator/verilator.py +9 -0
  44. siliconcompiler/tools/vpr/vpr.py +18 -0
  45. siliconcompiler/tools/yosys/{syn_asic_fpga_shared.tcl → procs.tcl} +23 -0
  46. siliconcompiler/tools/yosys/sc_screenshot.tcl +104 -0
  47. siliconcompiler/tools/yosys/sc_syn.tcl +7 -9
  48. siliconcompiler/tools/yosys/screenshot.py +153 -0
  49. siliconcompiler/tools/yosys/syn_asic.py +3 -0
  50. siliconcompiler/tools/yosys/syn_asic.tcl +1 -3
  51. siliconcompiler/tools/yosys/syn_fpga.tcl +3 -2
  52. siliconcompiler/toolscripts/_tools.json +3 -3
  53. siliconcompiler/utils/__init__.py +30 -1
  54. siliconcompiler/utils/showtools.py +4 -0
  55. {siliconcompiler-0.28.3.dist-info → siliconcompiler-0.28.4.dist-info}/METADATA +16 -3
  56. {siliconcompiler-0.28.3.dist-info → siliconcompiler-0.28.4.dist-info}/RECORD +60 -55
  57. {siliconcompiler-0.28.3.dist-info → siliconcompiler-0.28.4.dist-info}/WHEEL +1 -1
  58. {siliconcompiler-0.28.3.dist-info → siliconcompiler-0.28.4.dist-info}/LICENSE +0 -0
  59. {siliconcompiler-0.28.3.dist-info → siliconcompiler-0.28.4.dist-info}/entry_points.txt +0 -0
  60. {siliconcompiler-0.28.3.dist-info → siliconcompiler-0.28.4.dist-info}/top_level.txt +0 -0
@@ -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)
@@ -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
@@ -0,0 +1,182 @@
1
+ # KLayout script to export an OpenROAD marker DB from a DRC db
2
+ #
3
+ # Based on:
4
+ # https://github.com/The-OpenROAD-Project/OpenROAD-flow-scripts/blob/master/flow/util/convertDrc.py
5
+
6
+ import pya
7
+ import glob
8
+ import json
9
+ import os
10
+ import sys
11
+
12
+
13
+ def convert_drc(view, path):
14
+ rdb_id = view.create_rdb(os.path.basename(path))
15
+ rdb = view.rdb(rdb_id)
16
+ print(f"[INFO] reading {path}")
17
+ rdb.load(path)
18
+
19
+ source = os.path.abspath(path)
20
+
21
+ ordb = {
22
+ "source": source,
23
+ "description": "KLayout DRC conversion",
24
+ "category": {}
25
+ }
26
+
27
+ for category in rdb.each_category():
28
+ if category.num_items() == 0:
29
+ # ignore categories with no data
30
+ continue
31
+
32
+ ordb_category = {
33
+ "description": category.description,
34
+ "source": source,
35
+ "violations": []
36
+ }
37
+ ordb["category"][category.name()] = ordb_category
38
+
39
+ for item in rdb.each_item_per_category(category.rdb_id()):
40
+ violation = {
41
+ "visited": item.is_visited(),
42
+ "visible": True,
43
+ "waived": "waived" in item.tags_str
44
+ }
45
+
46
+ ordb_category["violations"].append(violation)
47
+
48
+ shapes = []
49
+ violation["shape"] = shapes
50
+
51
+ text = []
52
+
53
+ for value in item.each_value():
54
+ if value.is_box():
55
+ shapes.append({
56
+ "type": "box",
57
+ "points": [{
58
+ "x": value.box().left,
59
+ "y": value.box().bottom
60
+ }, {
61
+ "x": value.box().right,
62
+ "y": value.box().top
63
+ }]
64
+ })
65
+ elif value.is_edge():
66
+ shapes.append({
67
+ "type": "line",
68
+ "points": [{
69
+ "x": value.edge().p1.x,
70
+ "y": value.edge().p1.y
71
+ }, {
72
+ "x": value.edge().p2.x,
73
+ "y": value.edge().p2.y
74
+ }]
75
+ })
76
+ elif value.is_edge_pair():
77
+ edge1 = value.edge_pair().first
78
+ edge2 = value.edge_pair().second
79
+
80
+ shapes.append({
81
+ "type": "line",
82
+ "points": [{
83
+ "x": edge1.p1.x,
84
+ "y": edge1.p1.y
85
+ }, {
86
+ "x": edge1.p2.x,
87
+ "y": edge1.p2.y
88
+ }]
89
+ })
90
+ shapes.append({
91
+ "type": "line",
92
+ "points": [{
93
+ "x": edge2.p1.x,
94
+ "y": edge2.p1.y
95
+ }, {
96
+ "x": edge2.p2.x,
97
+ "y": edge2.p2.y
98
+ }]
99
+ })
100
+ elif value.is_polygon():
101
+ points = []
102
+ for edge in value.polygon().each_edge():
103
+ points.append({
104
+ "x": edge.p1.x,
105
+ "y": edge.p1.y
106
+ })
107
+ points.append({
108
+ "x": edge.p2.x,
109
+ "y": edge.p2.y
110
+ })
111
+ shapes.append({
112
+ "type": "polygon",
113
+ "points": points
114
+ })
115
+ elif value.is_path():
116
+ points = []
117
+ for edge in value.path().polygon().each_edge():
118
+ points.append({
119
+ "x": edge.p1.x,
120
+ "y": edge.p1.y
121
+ })
122
+ points.append({
123
+ "x": edge.p2.x,
124
+ "y": edge.p2.y
125
+ })
126
+ shapes.append({
127
+ "type": "polygon",
128
+ "points": points
129
+ })
130
+ elif value.is_text():
131
+ text.append(value.text())
132
+ elif value.is_string():
133
+ text.append(value.string())
134
+ else:
135
+ print("[WARN] Unknown violation shape:", value)
136
+
137
+ comment = ""
138
+ if hasattr(item, 'comment'):
139
+ comment = item.comment
140
+ if text:
141
+ if comment:
142
+ comment += ": "
143
+ comment += ", ".join(text)
144
+
145
+ if comment:
146
+ violation["comment"] = comment
147
+
148
+ return ordb
149
+
150
+
151
+ def main():
152
+ # SC_ROOT provided by CLI
153
+ sys.path.append(SC_ROOT) # noqa: F821
154
+
155
+ from tools.klayout.klayout_utils import get_schema
156
+
157
+ schema = get_schema(manifest='sc_manifest.json')
158
+
159
+ design = schema.get('design')
160
+
161
+ app = pya.Application.instance()
162
+ win = app.main_window()
163
+
164
+ # Create a dummy view to use for loading
165
+ cell_view = win.create_layout(0)
166
+ layout_view = cell_view.view()
167
+
168
+ ordb = {}
169
+ for file in glob.glob(f'inputs/{design}*.lyrdb') + glob.glob('inputs/{design}*.ascii'):
170
+ name = os.path.basename(file)
171
+
172
+ ordb[name] = convert_drc(layout_view, file)
173
+
174
+ with open(f"outputs/{design}.json", "w") as outfile:
175
+ json.dump(
176
+ ordb,
177
+ outfile,
178
+ indent=2)
179
+
180
+
181
+ if __name__ == '__main__':
182
+ main()
@@ -109,6 +109,8 @@ def setup(chip):
109
109
  _, task = get_tool_task(chip, step, index)
110
110
  clobber = False
111
111
 
112
+ chip.set('tool', tool, 'task', task, 'threads', 1, step=step, index=index, clobber=clobber)
113
+
112
114
  script = 'klayout_operations.py'
113
115
  option = ['-z', '-nc', '-rx', '-r']
114
116
  chip.set('tool', tool, 'task', task, 'script', script, step=step, index=index, clobber=clobber)
@@ -24,6 +24,8 @@ def setup(chip):
24
24
  _, task = get_tool_task(chip, step, index)
25
25
  clobber = False
26
26
 
27
+ chip.set('tool', tool, 'task', task, 'threads', 1, step=step, index=index, clobber=clobber)
28
+
27
29
  setup_gui_screenshot(chip)
28
30
 
29
31
  option = ['-nc', '-z', '-rm']
@@ -73,12 +73,12 @@ def setup(chip):
73
73
 
74
74
  step = chip.get('arg', 'step')
75
75
  index = chip.get('arg', 'index')
76
- _, task = get_tool_task(chip, step, index)
76
+ tool, task = get_tool_task(chip, step, index)
77
+ clobber = False
77
78
 
78
- general_gui_setup(chip, task, False)
79
+ chip.set('tool', tool, 'task', task, 'threads', 1, step=step, index=index, clobber=clobber)
79
80
 
80
- tool = 'klayout'
81
- clobber = False
81
+ general_gui_setup(chip, task, False)
82
82
 
83
83
  option = ['-nc', '-rm']
84
84
  chip.set('tool', tool, 'task', task, 'option', option, step=step, index=index, clobber=clobber)
@@ -1,8 +1,10 @@
1
1
  import re
2
2
 
3
3
  from siliconcompiler.tools.magic.magic import setup as setup_tool
4
+ from siliconcompiler.tools.magic.magic import process_file
4
5
  from siliconcompiler import sc_open
5
6
  from siliconcompiler.tools._common import get_tool_task, record_metric
7
+ from siliconcompiler.tools._common.asic import get_mainlib, get_libraries
6
8
 
7
9
 
8
10
  def setup(chip):
@@ -22,6 +24,25 @@ def setup(chip):
22
24
  chip.set('tool', tool, 'task', task, 'output', f'{design}.drc.mag', step=step, index=index)
23
25
 
24
26
 
27
+ def pre_process(chip):
28
+ step = chip.get('arg', 'step')
29
+ index = chip.get('arg', 'index')
30
+ tool, task = get_tool_task(chip, step, index)
31
+
32
+ pdk = chip.get('option', 'pdk')
33
+ stackup = chip.get('option', 'stackup')
34
+ mainlib = get_mainlib(chip)
35
+ libtype = chip.get('library', mainlib, 'asic', 'libarch', step=step, index=index)
36
+ process_file('lef', chip, 'pdk', pdk, 'aprtech', 'magic', stackup, libtype, 'lef')
37
+
38
+ for lib in get_libraries(chip, 'logic'):
39
+ process_file('lef', chip, 'library', lib, 'output', stackup, 'lef')
40
+
41
+ for lib in get_libraries(chip, 'macro'):
42
+ if lib in chip.get('tool', tool, 'task', task, 'var', 'exclude', step=step, index=index):
43
+ process_file('lef', chip, 'library', lib, 'output', stackup, 'lef')
44
+
45
+
25
46
  ################################
26
47
  # Post_process (post executable)
27
48
  ################################