siliconcompiler 0.31.0__py3-none-any.whl → 0.32.0__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/sc.py +1 -0
- siliconcompiler/apps/sc_install.py +19 -1
- siliconcompiler/apps/utils/summarize.py +1 -1
- siliconcompiler/core.py +33 -39
- siliconcompiler/flows/_common.py +10 -4
- siliconcompiler/{package.py → package/__init__.py} +64 -177
- siliconcompiler/package/git.py +84 -0
- siliconcompiler/package/https.py +97 -0
- siliconcompiler/report/dashboard/components/__init__.py +16 -6
- siliconcompiler/report/report.py +6 -6
- siliconcompiler/scheduler/__init__.py +19 -10
- siliconcompiler/scheduler/docker_runner.py +3 -3
- siliconcompiler/scheduler/run_node.py +6 -3
- siliconcompiler/schema/schema_obj.py +7 -11
- siliconcompiler/templates/tcl/manifest.tcl.j2 +1 -1
- siliconcompiler/tools/_common/tcl/sc_pin_constraints.tcl +3 -5
- siliconcompiler/tools/genfasm/genfasm.py +1 -1
- siliconcompiler/tools/openroad/_apr.py +15 -5
- siliconcompiler/tools/openroad/rdlroute.py +4 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_init_floorplan.tcl +3 -3
- siliconcompiler/tools/openroad/scripts/common/reports.tcl +10 -0
- siliconcompiler/tools/openroad/scripts/common/write_images.tcl +27 -0
- siliconcompiler/tools/openroad/scripts/sc_rdlroute.tcl +3 -13
- siliconcompiler/tools/slang/__init__.py +123 -33
- siliconcompiler/tools/slang/elaborate.py +123 -18
- siliconcompiler/tools/slang/lint.py +20 -10
- siliconcompiler/tools/surelog/__init__.py +17 -4
- siliconcompiler/tools/vpr/vpr.py +86 -6
- siliconcompiler/toolscripts/_tools.json +4 -4
- siliconcompiler/units.py +10 -7
- siliconcompiler/use.py +5 -2
- {siliconcompiler-0.31.0.dist-info → siliconcompiler-0.32.0.dist-info}/METADATA +17 -22
- {siliconcompiler-0.31.0.dist-info → siliconcompiler-0.32.0.dist-info}/RECORD +38 -36
- {siliconcompiler-0.31.0.dist-info → siliconcompiler-0.32.0.dist-info}/WHEEL +1 -1
- {siliconcompiler-0.31.0.dist-info → siliconcompiler-0.32.0.dist-info}/entry_points.txt +4 -0
- {siliconcompiler-0.31.0.dist-info → siliconcompiler-0.32.0.dist-info}/LICENSE +0 -0
- {siliconcompiler-0.31.0.dist-info → siliconcompiler-0.32.0.dist-info}/top_level.txt +0 -0
|
@@ -10,55 +10,56 @@ Sources: https://github.com/MikePopoloski/slang
|
|
|
10
10
|
|
|
11
11
|
Installation: https://sv-lang.com/building.html
|
|
12
12
|
'''
|
|
13
|
-
import
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
import os
|
|
14
|
+
|
|
15
|
+
try:
|
|
16
|
+
import pyslang
|
|
17
|
+
except ModuleNotFoundError:
|
|
18
|
+
pyslang = None
|
|
19
|
+
|
|
16
20
|
from siliconcompiler.tools._common import \
|
|
17
|
-
get_frontend_options, get_input_files,
|
|
21
|
+
add_require_input, add_frontend_requires, get_frontend_options, get_input_files, \
|
|
22
|
+
get_tool_task, record_metric
|
|
18
23
|
|
|
19
24
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
################################
|
|
23
|
-
def setup(chip):
|
|
24
|
-
tool = 'slang'
|
|
25
|
+
def has_pyslang():
|
|
26
|
+
return pyslang is not None
|
|
25
27
|
|
|
26
|
-
# Standard Setup
|
|
27
|
-
chip.set('tool', tool, 'exe', 'slang')
|
|
28
|
-
chip.set('tool', tool, 'vswitch', '--version')
|
|
29
|
-
chip.set('tool', tool, 'version', '>=6.0', clobber=False)
|
|
30
28
|
|
|
29
|
+
def test_version():
|
|
30
|
+
if not has_pyslang():
|
|
31
|
+
return "pyslang is not installed"
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
version = pyslang.VersionInfo
|
|
34
|
+
if version.getMajor() >= 7 and version.getMinor() >= 0:
|
|
35
|
+
return None
|
|
35
36
|
|
|
36
|
-
|
|
37
|
-
return stdout.strip().split()[-1].split('+')[0]
|
|
37
|
+
ver = f"{version.getMajor()}.{version.getMinor()}.{version.getPatch()}"
|
|
38
38
|
|
|
39
|
+
return f"incorrect pyslang version: {ver}"
|
|
39
40
|
|
|
40
|
-
def post_process(chip):
|
|
41
|
-
step = chip.get('arg', 'step')
|
|
42
|
-
index = chip.get('arg', 'index')
|
|
43
41
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
42
|
+
################################
|
|
43
|
+
# Setup Tool (pre executable)
|
|
44
|
+
################################
|
|
45
|
+
def setup(chip):
|
|
46
|
+
add_require_input(chip, 'input', 'rtl', 'verilog')
|
|
47
|
+
add_require_input(chip, 'input', 'rtl', 'systemverilog')
|
|
48
|
+
add_require_input(chip, 'input', 'cmdfile', 'f')
|
|
49
|
+
add_frontend_requires(chip, ['ydir', 'idir', 'vlib', 'libext', 'define', 'param'])
|
|
51
50
|
|
|
52
51
|
|
|
53
52
|
def common_runtime_options(chip):
|
|
54
|
-
options = []
|
|
55
|
-
|
|
56
53
|
step = chip.get('arg', 'step')
|
|
57
54
|
index = chip.get('arg', 'index')
|
|
58
55
|
tool, task = get_tool_task(chip, step, index)
|
|
59
56
|
|
|
60
|
-
options
|
|
61
|
-
|
|
57
|
+
options = chip.get('tool', tool, 'task', task, 'option', step=step, index=index)
|
|
58
|
+
|
|
59
|
+
options.append('--single-unit')
|
|
60
|
+
|
|
61
|
+
options.extend(['--threads', str(chip.get('tool', tool, 'task', task, 'threads',
|
|
62
|
+
step=step, index=index))])
|
|
62
63
|
|
|
63
64
|
opts = get_frontend_options(chip,
|
|
64
65
|
['ydir',
|
|
@@ -113,7 +114,7 @@ def common_runtime_options(chip):
|
|
|
113
114
|
#######################
|
|
114
115
|
# Top Module
|
|
115
116
|
#######################
|
|
116
|
-
options.append('--top ' + chip.top())
|
|
117
|
+
options.append('--top ' + chip.top(step, index))
|
|
117
118
|
|
|
118
119
|
###############################
|
|
119
120
|
# Parameters (top module only)
|
|
@@ -124,3 +125,92 @@ def common_runtime_options(chip):
|
|
|
124
125
|
options.append(f'-G {param}={value}')
|
|
125
126
|
|
|
126
127
|
return options
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def _get_driver(chip, options_func, ignored_diagnotics=None):
|
|
131
|
+
driver = pyslang.Driver()
|
|
132
|
+
driver.addStandardArgs()
|
|
133
|
+
|
|
134
|
+
options = options_func(chip)
|
|
135
|
+
|
|
136
|
+
parseOpts = pyslang.CommandLineOptions()
|
|
137
|
+
parseOpts.ignoreProgramName = True
|
|
138
|
+
opts = " ".join(options)
|
|
139
|
+
code = 0
|
|
140
|
+
if not driver.parseCommandLine(opts, parseOpts):
|
|
141
|
+
code = 1
|
|
142
|
+
|
|
143
|
+
if code == 0 and not driver.processOptions():
|
|
144
|
+
code = 2
|
|
145
|
+
|
|
146
|
+
step = chip.get('arg', 'step')
|
|
147
|
+
index = chip.get('arg', 'index')
|
|
148
|
+
tool, task = get_tool_task(chip, step, index)
|
|
149
|
+
for warning in chip.get('tool', tool, 'task', task, 'warningoff', step=step, index=index):
|
|
150
|
+
if hasattr(pyslang.Diags, warning):
|
|
151
|
+
driver.diagEngine.setSeverity(
|
|
152
|
+
getattr(pyslang.Diags, warning),
|
|
153
|
+
pyslang.DiagnosticSeverity.Ignored)
|
|
154
|
+
elif not chip.get('option', 'quiet', step=step, index=index):
|
|
155
|
+
chip.logger.warning(f'{warning} is not a valid slang category')
|
|
156
|
+
|
|
157
|
+
if not ignored_diagnotics:
|
|
158
|
+
ignored_diagnotics = []
|
|
159
|
+
for ignore in ignored_diagnotics:
|
|
160
|
+
driver.diagEngine.setSeverity(
|
|
161
|
+
ignore,
|
|
162
|
+
pyslang.DiagnosticSeverity.Ignored)
|
|
163
|
+
|
|
164
|
+
return driver, code
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def _compile(chip, driver):
|
|
168
|
+
ok = driver.parseAllSources()
|
|
169
|
+
compilation = driver.createCompilation()
|
|
170
|
+
return compilation, ok
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def _diagnostics(chip, driver, compilation):
|
|
174
|
+
step = chip.get('arg', 'step')
|
|
175
|
+
index = chip.get('arg', 'index')
|
|
176
|
+
|
|
177
|
+
report = {
|
|
178
|
+
"error": [],
|
|
179
|
+
"warning": [],
|
|
180
|
+
}
|
|
181
|
+
diags = driver.diagEngine
|
|
182
|
+
for diag in compilation.getAllDiagnostics():
|
|
183
|
+
severity = diags.getSeverity(diag.code, diag.location)
|
|
184
|
+
report_level = None
|
|
185
|
+
if severity == pyslang.DiagnosticSeverity.Warning:
|
|
186
|
+
report_level = "warning"
|
|
187
|
+
elif severity == pyslang.DiagnosticSeverity.Error:
|
|
188
|
+
report_level = "error"
|
|
189
|
+
elif severity == pyslang.DiagnosticSeverity.Fatal:
|
|
190
|
+
report_level = "error"
|
|
191
|
+
|
|
192
|
+
if report_level:
|
|
193
|
+
for n, line in enumerate(diags.reportAll(driver.sourceManager, [diag]).splitlines()):
|
|
194
|
+
if line.strip():
|
|
195
|
+
if n == 0:
|
|
196
|
+
line_parts = line.split(":")
|
|
197
|
+
if os.path.exists(line_parts[0]):
|
|
198
|
+
line_parts[0] = os.path.abspath(line_parts[0])
|
|
199
|
+
line = ":".join(line_parts)
|
|
200
|
+
|
|
201
|
+
report[report_level].append(line)
|
|
202
|
+
|
|
203
|
+
if not chip.get('option', 'quiet', step=step, index=index):
|
|
204
|
+
if report["warning"]:
|
|
205
|
+
for line in report["warning"]:
|
|
206
|
+
chip.logger.warning(line)
|
|
207
|
+
if report["error"]:
|
|
208
|
+
for line in report["error"]:
|
|
209
|
+
chip.logger.error(line)
|
|
210
|
+
|
|
211
|
+
diags.clearCounts()
|
|
212
|
+
for diag in compilation.getAllDiagnostics():
|
|
213
|
+
diags.issue(diag)
|
|
214
|
+
|
|
215
|
+
record_metric(chip, step, index, 'errors', diags.numErrors, [])
|
|
216
|
+
record_metric(chip, step, index, 'warnings', diags.numWarnings, [])
|
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
from siliconcompiler import utils
|
|
2
2
|
from siliconcompiler.tools import slang
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
import os
|
|
4
|
+
from siliconcompiler.tools._common import get_tool_task, has_input_files
|
|
5
|
+
from siliconcompiler.tools.slang import pyslang
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
def setup(chip):
|
|
8
9
|
'''
|
|
9
10
|
Elaborate verilog design files and generate a unified file.
|
|
10
11
|
'''
|
|
12
|
+
if slang.test_version():
|
|
13
|
+
return slang.test_version()
|
|
14
|
+
|
|
15
|
+
if not has_input_files(chip, 'input', 'rtl', 'verilog') and \
|
|
16
|
+
not has_input_files(chip, 'input', 'rtl', 'systemverilog'):
|
|
17
|
+
return "no files in [input,rtl,systemverilog] or [input,rtl,verilog]"
|
|
18
|
+
|
|
11
19
|
slang.setup(chip)
|
|
12
20
|
|
|
13
21
|
step = chip.get('arg', 'step')
|
|
@@ -17,30 +25,127 @@ def setup(chip):
|
|
|
17
25
|
chip.set('tool', tool, 'task', task, 'threads', utils.get_cores(chip),
|
|
18
26
|
clobber=False, step=step, index=index)
|
|
19
27
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
add_frontend_requires(chip, ['ydir', 'idir', 'vlib', 'libext', 'define', 'param'])
|
|
23
|
-
|
|
24
|
-
chip.set('tool', tool, 'task', task, 'stdout', 'destination', 'output', step=step, index=index)
|
|
25
|
-
chip.set('tool', tool, 'task', task, 'stdout', 'suffix', 'v', step=step, index=index)
|
|
28
|
+
chip.set('tool', tool, 'task', task, 'stdout', 'destination', 'log', step=step, index=index)
|
|
29
|
+
chip.set('tool', tool, 'task', task, 'stderr', 'destination', 'log', step=step, index=index)
|
|
26
30
|
|
|
27
31
|
chip.set('tool', tool, 'task', task, 'output', __outputfile(chip), step=step, index=index)
|
|
28
32
|
|
|
33
|
+
chip.set('tool', tool, 'task', task, 'var', 'include_source_paths', True,
|
|
34
|
+
step=step, index=index, clobber=False)
|
|
35
|
+
chip.set('tool', tool, 'task', task, 'var', 'include_source_paths',
|
|
36
|
+
"true/false, if true add the source file path information", field="help")
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def __outputfile(chip):
|
|
40
|
+
is_systemverilog = has_input_files(chip, 'input', 'rtl', 'systemverilog')
|
|
41
|
+
if is_systemverilog:
|
|
42
|
+
return f'{chip.top()}.sv'
|
|
43
|
+
return f'{chip.top()}.v'
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def __get_files(manager, tree):
|
|
47
|
+
files = set()
|
|
48
|
+
|
|
49
|
+
from queue import Queue
|
|
50
|
+
nodes = Queue(maxsize=0)
|
|
51
|
+
nodes.put(tree.root)
|
|
52
|
+
|
|
53
|
+
def procRange(range):
|
|
54
|
+
files.add(manager.getFileName(range.start))
|
|
55
|
+
files.add(manager.getFileName(range.end))
|
|
56
|
+
|
|
57
|
+
while not nodes.empty():
|
|
58
|
+
node = nodes.get()
|
|
59
|
+
procRange(node.sourceRange)
|
|
60
|
+
for token in node:
|
|
61
|
+
if isinstance(token, pyslang.Token):
|
|
62
|
+
procRange(token.range)
|
|
63
|
+
else:
|
|
64
|
+
nodes.put(token)
|
|
65
|
+
|
|
66
|
+
return sorted([os.path.abspath(f) for f in files if os.path.isfile(f)])
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def run(chip):
|
|
70
|
+
# Override default errors
|
|
71
|
+
ignored = [
|
|
72
|
+
pyslang.Diags.MissingTimeScale,
|
|
73
|
+
pyslang.Diags.UsedBeforeDeclared,
|
|
74
|
+
pyslang.Diags.UnusedParameter,
|
|
75
|
+
pyslang.Diags.UnusedDefinition,
|
|
76
|
+
pyslang.Diags.UnusedVariable,
|
|
77
|
+
pyslang.Diags.UnusedPort,
|
|
78
|
+
pyslang.Diags.UnusedButSetNet,
|
|
79
|
+
pyslang.Diags.UnusedImplicitNet,
|
|
80
|
+
pyslang.Diags.UnusedButSetVariable,
|
|
81
|
+
pyslang.Diags.UnusedButSetPort,
|
|
82
|
+
pyslang.Diags.UnusedTypedef,
|
|
83
|
+
pyslang.Diags.UnusedGenvar,
|
|
84
|
+
pyslang.Diags.UnusedAssertionDecl
|
|
85
|
+
]
|
|
86
|
+
|
|
87
|
+
driver, exitcode = slang._get_driver(
|
|
88
|
+
chip,
|
|
89
|
+
runtime_options,
|
|
90
|
+
ignored_diagnotics=ignored)
|
|
91
|
+
if exitcode:
|
|
92
|
+
return exitcode
|
|
93
|
+
|
|
94
|
+
compilation, ok = slang._compile(chip, driver)
|
|
95
|
+
|
|
96
|
+
slang._diagnostics(chip, driver, compilation)
|
|
97
|
+
|
|
98
|
+
manager = compilation.sourceManager
|
|
99
|
+
|
|
100
|
+
step = chip.get('arg', 'step')
|
|
101
|
+
index = chip.get('arg', 'index')
|
|
102
|
+
tool, task = get_tool_task(chip, step, index)
|
|
103
|
+
add_source = chip.get('tool', tool, 'task', task, 'var', 'include_source_paths',
|
|
104
|
+
step=step, index=index)[0] == 'true'
|
|
105
|
+
|
|
106
|
+
def printFiles(out, files):
|
|
107
|
+
for src_file in files:
|
|
108
|
+
out.write(f'// File: {src_file}\n')
|
|
109
|
+
|
|
110
|
+
with open(f'outputs/{__outputfile(chip)}', 'w') as out:
|
|
111
|
+
for tree in compilation.getSyntaxTrees():
|
|
112
|
+
files = []
|
|
113
|
+
if add_source:
|
|
114
|
+
files = __get_files(manager, tree)
|
|
115
|
+
|
|
116
|
+
writer = pyslang.SyntaxPrinter(manager)
|
|
117
|
+
|
|
118
|
+
writer.setIncludeMissing(False)
|
|
119
|
+
writer.setIncludeSkipped(False)
|
|
120
|
+
writer.setIncludeDirectives(False)
|
|
121
|
+
|
|
122
|
+
writer.setIncludePreprocessed(True)
|
|
123
|
+
writer.setIncludeTrivia(True)
|
|
124
|
+
writer.setIncludeComments(True)
|
|
125
|
+
writer.setSquashNewlines(True)
|
|
126
|
+
|
|
127
|
+
out.write("////////////////////////////////////////////////////////////////\n")
|
|
128
|
+
out.write("// Start:\n")
|
|
129
|
+
printFiles(out, files)
|
|
130
|
+
|
|
131
|
+
out.write(writer.print(tree).str() + '\n')
|
|
132
|
+
|
|
133
|
+
out.write("// End:\n")
|
|
134
|
+
printFiles(out, files)
|
|
135
|
+
out.write("////////////////////////////////////////////////////////////////\n")
|
|
136
|
+
|
|
137
|
+
if ok:
|
|
138
|
+
return 0
|
|
139
|
+
else:
|
|
140
|
+
return 1
|
|
141
|
+
|
|
29
142
|
|
|
30
143
|
def runtime_options(chip):
|
|
31
144
|
options = slang.common_runtime_options(chip)
|
|
32
145
|
options.extend([
|
|
33
|
-
"--
|
|
34
|
-
"--comments",
|
|
146
|
+
"--allow-use-before-declare",
|
|
35
147
|
"--ignore-unknown-modules",
|
|
36
|
-
"
|
|
148
|
+
"-Weverything"
|
|
37
149
|
])
|
|
38
150
|
|
|
39
151
|
return options
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
def __outputfile(chip):
|
|
43
|
-
is_systemverilog = has_input_files(chip, 'input', 'rtl', 'systemverilog')
|
|
44
|
-
if is_systemverilog:
|
|
45
|
-
return f'{chip.top()}.sv'
|
|
46
|
-
return f'{chip.top()}.v'
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
from siliconcompiler import utils
|
|
2
2
|
from siliconcompiler.tools import slang
|
|
3
|
-
from siliconcompiler.tools._common import
|
|
4
|
-
add_require_input, add_frontend_requires, get_tool_task
|
|
3
|
+
from siliconcompiler.tools._common import get_tool_task
|
|
5
4
|
|
|
6
5
|
|
|
7
6
|
def setup(chip):
|
|
8
7
|
'''
|
|
9
8
|
Lint system verilog
|
|
10
9
|
'''
|
|
10
|
+
if slang.test_version():
|
|
11
|
+
return slang.test_version()
|
|
12
|
+
|
|
11
13
|
slang.setup(chip)
|
|
12
14
|
|
|
13
15
|
step = chip.get('arg', 'step')
|
|
@@ -17,19 +19,27 @@ def setup(chip):
|
|
|
17
19
|
chip.set('tool', tool, 'task', task, 'threads', utils.get_cores(chip),
|
|
18
20
|
clobber=False, step=step, index=index)
|
|
19
21
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
|
|
23
|
+
def run(chip):
|
|
24
|
+
driver, exitcode = slang._get_driver(chip, runtime_options)
|
|
25
|
+
if exitcode:
|
|
26
|
+
return exitcode
|
|
27
|
+
|
|
28
|
+
compilation, ok = slang._compile(chip, driver)
|
|
29
|
+
slang._diagnostics(chip, driver, compilation)
|
|
30
|
+
|
|
31
|
+
if ok:
|
|
32
|
+
return 0
|
|
33
|
+
else:
|
|
34
|
+
return 1
|
|
23
35
|
|
|
24
36
|
|
|
25
37
|
def runtime_options(chip):
|
|
26
38
|
options = slang.common_runtime_options(chip)
|
|
27
39
|
options.extend([
|
|
28
|
-
"--lint-only"
|
|
40
|
+
"--lint-only",
|
|
41
|
+
"-Weverything",
|
|
42
|
+
"-Werror"
|
|
29
43
|
])
|
|
30
44
|
|
|
31
45
|
return options
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
def post_process(chip):
|
|
35
|
-
slang.post_process(chip)
|
|
@@ -10,7 +10,12 @@ Sources: https://github.com/chipsalliance/Surelog
|
|
|
10
10
|
Installation: https://github.com/chipsalliance/Surelog
|
|
11
11
|
'''
|
|
12
12
|
|
|
13
|
-
import
|
|
13
|
+
import sys
|
|
14
|
+
try:
|
|
15
|
+
import surelog
|
|
16
|
+
except ModuleNotFoundError:
|
|
17
|
+
surelog = None
|
|
18
|
+
|
|
14
19
|
from siliconcompiler.tools._common import get_tool_task
|
|
15
20
|
|
|
16
21
|
|
|
@@ -31,9 +36,17 @@ def setup(chip):
|
|
|
31
36
|
|
|
32
37
|
is_docker = chip.get('option', 'scheduler', 'name', step=step, index=index) == 'docker'
|
|
33
38
|
if not is_docker:
|
|
34
|
-
|
|
39
|
+
if surelog:
|
|
40
|
+
exe = surelog.get_bin()
|
|
41
|
+
else:
|
|
42
|
+
exe = 'surelog'
|
|
43
|
+
if sys.platform.startswith("win32"):
|
|
44
|
+
exe = f"{exe}.exe"
|
|
35
45
|
else:
|
|
36
|
-
|
|
46
|
+
if surelog:
|
|
47
|
+
exe = surelog.get_bin('linux')
|
|
48
|
+
else:
|
|
49
|
+
exe = 'surelog'
|
|
37
50
|
|
|
38
51
|
# Standard Setup
|
|
39
52
|
chip.set('tool', tool, 'exe', exe)
|
|
@@ -43,7 +56,7 @@ def setup(chip):
|
|
|
43
56
|
# We package SC wheels with a precompiled copy of Surelog installed to
|
|
44
57
|
# tools/surelog/bin. If the user doesn't have Surelog installed on their
|
|
45
58
|
# system path, set the path to the bundled copy in the schema.
|
|
46
|
-
if not surelog.has_system_surelog() and not is_docker:
|
|
59
|
+
if surelog and not surelog.has_system_surelog() and not is_docker:
|
|
47
60
|
chip.set('tool', tool, 'path', surelog.get_path(), clobber=False)
|
|
48
61
|
|
|
49
62
|
# Log file parsing
|
siliconcompiler/tools/vpr/vpr.py
CHANGED
|
@@ -16,6 +16,7 @@ Sources: https://github.com/verilog-to-routing/vtr-verilog-to-routing
|
|
|
16
16
|
Installation: https://github.com/verilog-to-routing/vtr-verilog-to-routing
|
|
17
17
|
'''
|
|
18
18
|
|
|
19
|
+
import glob
|
|
19
20
|
import os
|
|
20
21
|
import shutil
|
|
21
22
|
import json
|
|
@@ -42,7 +43,7 @@ def setup_tool(chip, clobber=True):
|
|
|
42
43
|
|
|
43
44
|
chip.set('tool', 'vpr', 'exe', 'vpr', clobber=clobber)
|
|
44
45
|
chip.set('tool', 'vpr', 'vswitch', '--version')
|
|
45
|
-
chip.set('tool', 'vpr', 'version', '>=
|
|
46
|
+
chip.set('tool', 'vpr', 'version', '>=9.0.0', clobber=clobber)
|
|
46
47
|
|
|
47
48
|
step = chip.get('arg', 'step')
|
|
48
49
|
index = chip.get('arg', 'index')
|
|
@@ -80,6 +81,16 @@ def add_tool_requirements(chip):
|
|
|
80
81
|
chip.add('tool', tool, 'task', task, 'require', f'fpga,{part_name},var,vpr_device_code',
|
|
81
82
|
step=step, index=index)
|
|
82
83
|
|
|
84
|
+
chip.set('tool', tool, 'task', task, 'var', 'timing_paths',
|
|
85
|
+
'number of timing paths to report', field='help')
|
|
86
|
+
chip.set('tool', tool, 'task', task, 'var', 'timing_paths', '20',
|
|
87
|
+
step=step, index=index, clobber=False)
|
|
88
|
+
|
|
89
|
+
chip.set('tool', tool, 'task', task, 'var', 'timing_report_type',
|
|
90
|
+
'type of timing report', field='help')
|
|
91
|
+
chip.set('tool', tool, 'task', task, 'var', 'timing_report_type', 'aggregated',
|
|
92
|
+
step=step, index=index, clobber=False)
|
|
93
|
+
|
|
83
94
|
|
|
84
95
|
def runtime_options(chip):
|
|
85
96
|
|
|
@@ -163,13 +174,22 @@ def runtime_options(chip):
|
|
|
163
174
|
'vpr_clock model must be set to ideal, route, or dedicated_clock_network',
|
|
164
175
|
chip=chip)
|
|
165
176
|
|
|
177
|
+
sdc_file = None
|
|
166
178
|
if chip.valid('input', 'constraint', 'sdc'):
|
|
167
179
|
sdc_file = find_single_file(chip, 'input', 'constraint', 'sdc',
|
|
168
180
|
step=step, index=index,
|
|
169
181
|
file_not_found_msg="SDC file not found")
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
182
|
+
|
|
183
|
+
if sdc_file:
|
|
184
|
+
sdc_arg = f"--sdc_file {sdc_file}"
|
|
185
|
+
options.append(sdc_arg)
|
|
186
|
+
|
|
187
|
+
report_type = chip.get('tool', tool, 'task', task, 'var', 'timing_report_type',
|
|
188
|
+
step=step, index=index)[0]
|
|
189
|
+
options.append(f'--timing_report_detail {report_type}')
|
|
190
|
+
report_paths = chip.get('tool', tool, 'task', task, 'var', 'timing_paths',
|
|
191
|
+
step=step, index=index)[0]
|
|
192
|
+
options.append(f'--timing_report_npaths {report_paths}')
|
|
173
193
|
else:
|
|
174
194
|
options.append("--timing_analysis off")
|
|
175
195
|
|
|
@@ -295,8 +315,8 @@ def vpr_post_process(chip):
|
|
|
295
315
|
step = chip.get('arg', 'step')
|
|
296
316
|
index = chip.get('arg', 'index')
|
|
297
317
|
|
|
298
|
-
|
|
299
|
-
shutil.move(
|
|
318
|
+
for report in glob.glob("*.rpt"):
|
|
319
|
+
shutil.move(report, 'reports')
|
|
300
320
|
|
|
301
321
|
part_name = chip.get('fpga', 'partname')
|
|
302
322
|
dff_cells = []
|
|
@@ -379,6 +399,66 @@ def vpr_post_process(chip):
|
|
|
379
399
|
|
|
380
400
|
record_metric(chip, step, index, "pins", io, __block_file)
|
|
381
401
|
|
|
402
|
+
for setup_report in ("reports/report_timing.setup.rpt",
|
|
403
|
+
"reports/pre_pack.report_timing.setup.rpt"):
|
|
404
|
+
if not os.path.exists(setup_report):
|
|
405
|
+
continue
|
|
406
|
+
|
|
407
|
+
slack = _parse_timing_report(setup_report)
|
|
408
|
+
if slack is not None:
|
|
409
|
+
wns = min([slack, 0])
|
|
410
|
+
record_metric(chip, step, index, "setupslack", slack, setup_report, source_unit="ns")
|
|
411
|
+
record_metric(chip, step, index, "setupwns", wns, setup_report, source_unit="ns")
|
|
412
|
+
break
|
|
413
|
+
|
|
414
|
+
for hold_report in ("reports/report_timing.hold.rpt", ):
|
|
415
|
+
if not os.path.exists(hold_report):
|
|
416
|
+
continue
|
|
417
|
+
|
|
418
|
+
slack = _parse_timing_report(hold_report)
|
|
419
|
+
if slack is not None:
|
|
420
|
+
wns = min([slack, 0])
|
|
421
|
+
record_metric(chip, step, index, "holdslack", slack, hold_report, source_unit="ns")
|
|
422
|
+
record_metric(chip, step, index, "holdwns", wns, hold_report, source_unit="ns")
|
|
423
|
+
break
|
|
424
|
+
|
|
425
|
+
unconstrained = None
|
|
426
|
+
unconstrained_reports = []
|
|
427
|
+
for unconstrained_report in ("reports/report_unconstrained_timing.hold.rpt",
|
|
428
|
+
"reports/report_unconstrained_timing.setup.rpt"):
|
|
429
|
+
if not os.path.exists(unconstrained_report):
|
|
430
|
+
continue
|
|
431
|
+
|
|
432
|
+
paths = _parse_unconstrained_report(unconstrained_report)
|
|
433
|
+
if unconstrained is None:
|
|
434
|
+
unconstrained = paths
|
|
435
|
+
|
|
436
|
+
unconstrained = max([paths, unconstrained])
|
|
437
|
+
unconstrained_reports.append(unconstrained_report)
|
|
438
|
+
|
|
439
|
+
if unconstrained is not None:
|
|
440
|
+
record_metric(chip, step, index, "unconstrained", unconstrained, unconstrained_reports)
|
|
441
|
+
|
|
442
|
+
|
|
443
|
+
def _parse_timing_report(report):
|
|
444
|
+
slack = re.compile(r"slack \(.*\)\s+(-?\d+\.?\d*)")
|
|
445
|
+
with sc_open(report) as f:
|
|
446
|
+
for line in f:
|
|
447
|
+
match_slack = slack.findall(line)
|
|
448
|
+
if match_slack:
|
|
449
|
+
return float(match_slack[0])
|
|
450
|
+
return None
|
|
451
|
+
|
|
452
|
+
|
|
453
|
+
def _parse_unconstrained_report(report):
|
|
454
|
+
path = re.compile(r"\d+ .*")
|
|
455
|
+
count = 0
|
|
456
|
+
with sc_open(report) as f:
|
|
457
|
+
for line in f:
|
|
458
|
+
if path.match(line):
|
|
459
|
+
count += 1
|
|
460
|
+
return count
|
|
461
|
+
|
|
382
462
|
|
|
383
463
|
##################################################
|
|
384
464
|
if __name__ == "__main__":
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"openroad": {
|
|
3
3
|
"git-url": "https://github.com/The-OpenROAD-Project/OpenROAD.git",
|
|
4
|
-
"git-commit": "
|
|
4
|
+
"git-commit": "0fbd4d94c81ef070249ad9d9037a740d0c6e58fa",
|
|
5
5
|
"docker-cmds": [
|
|
6
6
|
"# Remove OR-Tools files",
|
|
7
7
|
"RUN rm -f $SC_PREFIX/Makefile $SC_PREFIX/README.md",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"auto-update": false
|
|
37
37
|
},
|
|
38
38
|
"klayout": {
|
|
39
|
-
"version": "0.29.
|
|
39
|
+
"version": "0.29.12",
|
|
40
40
|
"git-url": "https://github.com/KLayout/klayout.git",
|
|
41
41
|
"docker-skip": true,
|
|
42
42
|
"auto-update": true,
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
},
|
|
67
67
|
"vpr": {
|
|
68
68
|
"git-url": "https://github.com/verilog-to-routing/vtr-verilog-to-routing.git",
|
|
69
|
-
"git-commit": "
|
|
69
|
+
"git-commit": "v9.0.0",
|
|
70
70
|
"auto-update": false
|
|
71
71
|
},
|
|
72
72
|
"icepack": {
|
|
@@ -139,7 +139,7 @@
|
|
|
139
139
|
},
|
|
140
140
|
"yosys-slang": {
|
|
141
141
|
"git-url": "https://github.com/povik/yosys-slang.git",
|
|
142
|
-
"git-commit": "
|
|
142
|
+
"git-commit": "8f2239b2b12dac43f8f47f56deef1095d5262fa2",
|
|
143
143
|
"docker-depends": "yosys",
|
|
144
144
|
"auto-update": true
|
|
145
145
|
},
|
siliconcompiler/units.py
CHANGED
|
@@ -41,7 +41,7 @@ SI_TYPES = (
|
|
|
41
41
|
'V',
|
|
42
42
|
'W',
|
|
43
43
|
'ohm',
|
|
44
|
-
'C'
|
|
44
|
+
'C'
|
|
45
45
|
)
|
|
46
46
|
|
|
47
47
|
|
|
@@ -107,8 +107,6 @@ def get_si_prefix(unit):
|
|
|
107
107
|
if matches:
|
|
108
108
|
return matches[0][0]
|
|
109
109
|
|
|
110
|
-
return ''
|
|
111
|
-
|
|
112
110
|
|
|
113
111
|
def get_si_power(unit):
|
|
114
112
|
'''
|
|
@@ -164,6 +162,11 @@ def format_si(value, unit, margin=3, digits=3):
|
|
|
164
162
|
digits (int): number of digits to print after .
|
|
165
163
|
'''
|
|
166
164
|
scaled_value, prefix = scale_si(value, unit, margin=margin, digits=digits)
|
|
165
|
+
|
|
166
|
+
if digits < 0:
|
|
167
|
+
# Default to 1
|
|
168
|
+
digits = 1
|
|
169
|
+
|
|
167
170
|
# need to do this in case float shortens scaled_value
|
|
168
171
|
return f'{scaled_value:.{digits}f}{prefix}'
|
|
169
172
|
|
|
@@ -179,14 +182,14 @@ def scale_si(value, unit, margin=3, digits=3):
|
|
|
179
182
|
when picking the right magnitude
|
|
180
183
|
digits (int): number of digits to print after .
|
|
181
184
|
'''
|
|
185
|
+
if digits < 0:
|
|
186
|
+
# Default to 1
|
|
187
|
+
digits = 1
|
|
188
|
+
|
|
182
189
|
if unit and is_base_si_unit(unit):
|
|
183
190
|
value = float(value)
|
|
184
191
|
log_value = math.log10(value) - margin
|
|
185
192
|
|
|
186
|
-
if digits < 0:
|
|
187
|
-
# Default to 0
|
|
188
|
-
digits = 0
|
|
189
|
-
|
|
190
193
|
for prefix, scale in SI_UNITS:
|
|
191
194
|
if log_value <= scale:
|
|
192
195
|
value /= 10**scale
|