siliconcompiler 0.33.2__py3-none-any.whl → 0.34.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- siliconcompiler/__init__.py +2 -0
- siliconcompiler/_metadata.py +1 -1
- siliconcompiler/apps/_common.py +1 -1
- siliconcompiler/apps/sc.py +1 -1
- siliconcompiler/apps/sc_issue.py +6 -4
- siliconcompiler/apps/sc_remote.py +3 -20
- siliconcompiler/apps/sc_show.py +2 -2
- siliconcompiler/apps/utils/replay.py +4 -4
- siliconcompiler/checklist.py +202 -1
- siliconcompiler/core.py +62 -293
- siliconcompiler/data/templates/email/general.j2 +3 -3
- siliconcompiler/data/templates/email/summary.j2 +1 -1
- siliconcompiler/data/templates/issue/README.txt +1 -1
- siliconcompiler/data/templates/report/sc_report.j2 +7 -7
- siliconcompiler/dependencyschema.py +392 -0
- siliconcompiler/design.py +758 -0
- siliconcompiler/flowgraph.py +79 -13
- siliconcompiler/optimizer/vizier.py +2 -2
- siliconcompiler/package/__init__.py +383 -223
- siliconcompiler/package/git.py +75 -77
- siliconcompiler/package/github.py +70 -97
- siliconcompiler/package/https.py +77 -93
- siliconcompiler/packageschema.py +260 -0
- siliconcompiler/pdk.py +5 -5
- siliconcompiler/remote/client.py +33 -15
- siliconcompiler/remote/server.py +2 -2
- siliconcompiler/report/dashboard/cli/__init__.py +6 -6
- siliconcompiler/report/dashboard/cli/board.py +4 -4
- siliconcompiler/report/dashboard/web/components/__init__.py +5 -5
- siliconcompiler/report/dashboard/web/components/flowgraph.py +4 -4
- siliconcompiler/report/dashboard/web/components/graph.py +2 -2
- siliconcompiler/report/dashboard/web/state.py +1 -1
- siliconcompiler/report/dashboard/web/utils/__init__.py +5 -5
- siliconcompiler/report/html_report.py +1 -1
- siliconcompiler/report/report.py +4 -4
- siliconcompiler/report/summary_table.py +2 -2
- siliconcompiler/report/utils.py +5 -5
- siliconcompiler/scheduler/__init__.py +3 -1382
- siliconcompiler/scheduler/docker.py +263 -0
- siliconcompiler/scheduler/run_node.py +10 -21
- siliconcompiler/scheduler/scheduler.py +311 -0
- siliconcompiler/scheduler/schedulernode.py +944 -0
- siliconcompiler/scheduler/send_messages.py +3 -3
- siliconcompiler/scheduler/slurm.py +149 -163
- siliconcompiler/scheduler/taskscheduler.py +45 -57
- siliconcompiler/schema/__init__.py +3 -3
- siliconcompiler/schema/baseschema.py +234 -11
- siliconcompiler/schema/editableschema.py +4 -0
- siliconcompiler/schema/journal.py +210 -0
- siliconcompiler/schema/namedschema.py +55 -2
- siliconcompiler/schema/parameter.py +14 -1
- siliconcompiler/schema/parametervalue.py +1 -34
- siliconcompiler/schema/schema_cfg.py +210 -349
- siliconcompiler/tool.py +412 -148
- siliconcompiler/tools/__init__.py +2 -0
- siliconcompiler/tools/builtin/_common.py +5 -5
- siliconcompiler/tools/builtin/concatenate.py +7 -7
- siliconcompiler/tools/builtin/minimum.py +4 -4
- siliconcompiler/tools/builtin/mux.py +4 -4
- siliconcompiler/tools/builtin/nop.py +4 -4
- siliconcompiler/tools/builtin/verify.py +8 -9
- siliconcompiler/tools/execute/exec_input.py +1 -1
- siliconcompiler/tools/genfasm/genfasm.py +1 -6
- siliconcompiler/tools/openroad/_apr.py +5 -1
- siliconcompiler/tools/openroad/antenna_repair.py +1 -1
- siliconcompiler/tools/openroad/macro_placement.py +1 -1
- siliconcompiler/tools/openroad/power_grid.py +1 -1
- siliconcompiler/tools/openroad/scripts/common/procs.tcl +32 -25
- siliconcompiler/tools/opensta/timing.py +26 -3
- siliconcompiler/tools/slang/__init__.py +2 -2
- siliconcompiler/tools/surfer/__init__.py +0 -0
- siliconcompiler/tools/surfer/show.py +53 -0
- siliconcompiler/tools/surfer/surfer.py +30 -0
- siliconcompiler/tools/vpr/route.py +82 -0
- siliconcompiler/tools/vpr/vpr.py +23 -6
- siliconcompiler/tools/yosys/__init__.py +1 -1
- siliconcompiler/tools/yosys/scripts/procs.tcl +143 -0
- siliconcompiler/tools/yosys/{sc_synth_asic.tcl → scripts/sc_synth_asic.tcl} +4 -0
- siliconcompiler/tools/yosys/{sc_synth_fpga.tcl → scripts/sc_synth_fpga.tcl} +24 -77
- siliconcompiler/tools/yosys/syn_fpga.py +14 -0
- siliconcompiler/toolscripts/_tools.json +9 -13
- siliconcompiler/toolscripts/rhel9/install-vpr.sh +0 -2
- siliconcompiler/toolscripts/ubuntu22/install-surfer.sh +33 -0
- siliconcompiler/toolscripts/ubuntu24/install-surfer.sh +33 -0
- siliconcompiler/utils/__init__.py +4 -24
- siliconcompiler/utils/flowgraph.py +29 -28
- siliconcompiler/utils/issue.py +23 -29
- siliconcompiler/utils/logging.py +37 -7
- siliconcompiler/utils/showtools.py +6 -1
- {siliconcompiler-0.33.2.dist-info → siliconcompiler-0.34.1.dist-info}/METADATA +16 -25
- {siliconcompiler-0.33.2.dist-info → siliconcompiler-0.34.1.dist-info}/RECORD +98 -91
- siliconcompiler/scheduler/docker_runner.py +0 -254
- siliconcompiler/schema/journalingschema.py +0 -242
- siliconcompiler/tools/yosys/procs.tcl +0 -71
- siliconcompiler/toolscripts/rhel9/install-yosys-parmys.sh +0 -68
- siliconcompiler/toolscripts/ubuntu22/install-yosys-parmys.sh +0 -68
- siliconcompiler/toolscripts/ubuntu24/install-yosys-parmys.sh +0 -68
- /siliconcompiler/tools/yosys/{sc_lec.tcl → scripts/sc_lec.tcl} +0 -0
- /siliconcompiler/tools/yosys/{sc_screenshot.tcl → scripts/sc_screenshot.tcl} +0 -0
- /siliconcompiler/tools/yosys/{syn_strategies.tcl → scripts/syn_strategies.tcl} +0 -0
- {siliconcompiler-0.33.2.dist-info → siliconcompiler-0.34.1.dist-info}/WHEEL +0 -0
- {siliconcompiler-0.33.2.dist-info → siliconcompiler-0.34.1.dist-info}/entry_points.txt +0 -0
- {siliconcompiler-0.33.2.dist-info → siliconcompiler-0.34.1.dist-info}/licenses/LICENSE +0 -0
- {siliconcompiler-0.33.2.dist-info → siliconcompiler-0.34.1.dist-info}/top_level.txt +0 -0
|
@@ -18,6 +18,7 @@ from siliconcompiler.tools import openroad
|
|
|
18
18
|
from siliconcompiler.tools import opensta
|
|
19
19
|
from siliconcompiler.tools import slang
|
|
20
20
|
from siliconcompiler.tools import surelog
|
|
21
|
+
from siliconcompiler.tools import surfer
|
|
21
22
|
from siliconcompiler.tools.sv2v import sv2v
|
|
22
23
|
from siliconcompiler.tools.verilator import verilator
|
|
23
24
|
from siliconcompiler.tools.vivado import vivado
|
|
@@ -53,6 +54,7 @@ def get_tools():
|
|
|
53
54
|
opensta,
|
|
54
55
|
slang,
|
|
55
56
|
surelog,
|
|
57
|
+
surfer,
|
|
56
58
|
sv2v,
|
|
57
59
|
verilator,
|
|
58
60
|
vivado,
|
|
@@ -83,10 +83,10 @@ def _minmax(chip, *nodes, op=None):
|
|
|
83
83
|
real = chip.get('metric', metric, step=step, index=index)
|
|
84
84
|
if real is None:
|
|
85
85
|
raise SiliconCompilerError(
|
|
86
|
-
f'Metric {metric} has goal for {step}{index} '
|
|
86
|
+
f'Metric {metric} has goal for {step}/{index} '
|
|
87
87
|
'but it has not been set.', chip=chip)
|
|
88
88
|
if abs(real) > goal:
|
|
89
|
-
chip.logger.warning(f"Step {step}{index} failed "
|
|
89
|
+
chip.logger.warning(f"Step {step}/{index} failed "
|
|
90
90
|
f"because it didn't meet goals for '{metric}' "
|
|
91
91
|
"metric.")
|
|
92
92
|
failed[step][index] = True
|
|
@@ -122,7 +122,7 @@ def _minmax(chip, *nodes, op=None):
|
|
|
122
122
|
real = chip.get('metric', metric, step=step, index=index)
|
|
123
123
|
if real is None:
|
|
124
124
|
raise SiliconCompilerError(
|
|
125
|
-
f'Metric {metric} has weight for {step}{index} '
|
|
125
|
+
f'Metric {metric} has weight for {step}/{index} '
|
|
126
126
|
'but it has not been set.', chip=chip)
|
|
127
127
|
|
|
128
128
|
if not (max_val[metric] - min_val[metric]) == 0:
|
|
@@ -153,10 +153,10 @@ def _select_inputs(chip, step, index):
|
|
|
153
153
|
|
|
154
154
|
flow = chip.get('option', 'flow')
|
|
155
155
|
|
|
156
|
-
flow_schema = chip.
|
|
156
|
+
flow_schema = chip.get("flowgraph", flow, field="schema")
|
|
157
157
|
runtime = RuntimeFlowgraph(
|
|
158
158
|
flow_schema,
|
|
159
159
|
from_steps=set([step for step, _ in flow_schema.get_entry_nodes()]),
|
|
160
160
|
prune_nodes=chip.get('option', 'prune'))
|
|
161
161
|
|
|
162
|
-
return runtime.get_node_inputs(step, index, record=chip.
|
|
162
|
+
return runtime.get_node_inputs(step, index, record=chip.get("record", field="schema"))
|
|
@@ -3,7 +3,7 @@ import os
|
|
|
3
3
|
from siliconcompiler import sc_open, SiliconCompilerError
|
|
4
4
|
from siliconcompiler import utils
|
|
5
5
|
from siliconcompiler.tools._common import input_provides, input_file_node_name, get_tool_task
|
|
6
|
-
from siliconcompiler import
|
|
6
|
+
from siliconcompiler.scheduler.schedulernode import SchedulerNode
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
def make_docs(chip):
|
|
@@ -11,8 +11,8 @@ def make_docs(chip):
|
|
|
11
11
|
_make_docs(chip)
|
|
12
12
|
chip.set('option', 'flow', 'asicflow')
|
|
13
13
|
|
|
14
|
-
for step, index in chip.
|
|
15
|
-
|
|
14
|
+
for step, index in chip.get("flowgraph", "asicflow", field="schema").get_entry_nodes():
|
|
15
|
+
SchedulerNode(chip, step, index).setup()
|
|
16
16
|
|
|
17
17
|
chip.set('arg', 'step', 'import.combine')
|
|
18
18
|
chip.set('arg', 'index', '0')
|
|
@@ -64,10 +64,10 @@ def _gather_outputs(chip, step, index):
|
|
|
64
64
|
in_nodes = chip.get('flowgraph', flow, step, index, 'input')
|
|
65
65
|
in_task_outputs = []
|
|
66
66
|
for in_step, in_index in in_nodes:
|
|
67
|
-
in_tool,
|
|
68
|
-
task_class = chip.get("tool", in_tool, field="schema")
|
|
69
|
-
task_class.
|
|
70
|
-
|
|
67
|
+
in_tool, in_task = get_tool_task(chip, in_step, in_index, flow=flow)
|
|
68
|
+
task_class = chip.get("tool", in_tool, "task", in_task, field="schema")
|
|
69
|
+
with task_class.runtime(chip, step=in_step, index=in_index) as task:
|
|
70
|
+
in_task_outputs.append(task.get_output_files())
|
|
71
71
|
|
|
72
72
|
if len(in_task_outputs) > 0:
|
|
73
73
|
return in_task_outputs[0].union(*in_task_outputs[1:])
|
|
@@ -43,10 +43,10 @@ def _gather_outputs(chip, step, index):
|
|
|
43
43
|
in_nodes = chip.get('flowgraph', flow, step, index, 'input')
|
|
44
44
|
in_task_outputs = []
|
|
45
45
|
for in_step, in_index in in_nodes:
|
|
46
|
-
in_tool,
|
|
47
|
-
task_class = chip.get("tool", in_tool, field="schema")
|
|
48
|
-
task_class.
|
|
49
|
-
|
|
46
|
+
in_tool, in_task = get_tool_task(chip, in_step, in_index, flow=flow)
|
|
47
|
+
task_class = chip.get("tool", in_tool, "task", in_task, field="schema")
|
|
48
|
+
with task_class.runtime(chip, step=in_step, index=in_index) as task:
|
|
49
|
+
in_task_outputs.append(task.get_output_files())
|
|
50
50
|
|
|
51
51
|
if len(in_task_outputs) > 0:
|
|
52
52
|
return in_task_outputs[0].intersection(*in_task_outputs[1:])
|
|
@@ -57,10 +57,10 @@ def _gather_outputs(chip, step, index):
|
|
|
57
57
|
in_nodes = chip.get('flowgraph', flow, step, index, 'input')
|
|
58
58
|
in_task_outputs = []
|
|
59
59
|
for in_step, in_index in in_nodes:
|
|
60
|
-
in_tool,
|
|
61
|
-
task_class = chip.get("tool", in_tool, field="schema")
|
|
62
|
-
task_class.
|
|
63
|
-
|
|
60
|
+
in_tool, in_task = get_tool_task(chip, in_step, in_index, flow=flow)
|
|
61
|
+
task_class = chip.get("tool", in_tool, "task", in_task, field="schema")
|
|
62
|
+
with task_class.runtime(chip, step=in_step, index=in_index) as task:
|
|
63
|
+
in_task_outputs.append(task.get_output_files())
|
|
64
64
|
|
|
65
65
|
if len(in_task_outputs) > 0:
|
|
66
66
|
return in_task_outputs[0].intersection(*in_task_outputs[1:])
|
|
@@ -24,10 +24,10 @@ def _gather_outputs(chip, step, index):
|
|
|
24
24
|
in_nodes = chip.get('flowgraph', flow, step, index, 'input')
|
|
25
25
|
in_task_outputs = []
|
|
26
26
|
for in_step, in_index in in_nodes:
|
|
27
|
-
in_tool,
|
|
28
|
-
task_class = chip.get("tool", in_tool, field="schema")
|
|
29
|
-
task_class.
|
|
30
|
-
|
|
27
|
+
in_tool, in_task = get_tool_task(chip, in_step, in_index, flow=flow)
|
|
28
|
+
task_class = chip.get("tool", in_tool, "task", in_task, field="schema")
|
|
29
|
+
with task_class.runtime(chip, step=in_step, index=in_index) as task:
|
|
30
|
+
in_task_outputs.append(task.get_output_files())
|
|
31
31
|
|
|
32
32
|
if len(in_task_outputs) > 0:
|
|
33
33
|
return in_task_outputs[0].union(*in_task_outputs[1:])
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
from siliconcompiler.tools.builtin import _common
|
|
2
2
|
from siliconcompiler.schema.parametertype import NodeType
|
|
3
|
-
from siliconcompiler.scheduler import _haltstep
|
|
4
3
|
from siliconcompiler.tools.builtin.builtin import set_io_files
|
|
5
4
|
from siliconcompiler import utils, SiliconCompilerError
|
|
6
5
|
from siliconcompiler.tools._common import get_tool_task
|
|
@@ -26,13 +25,13 @@ def _select_inputs(chip, step, index):
|
|
|
26
25
|
inputs = _common._select_inputs(chip, step, index)
|
|
27
26
|
if len(inputs) != 1:
|
|
28
27
|
raise SiliconCompilerError(
|
|
29
|
-
f'{step}{index} receives {len(inputs)} inputs, but only supports one', chip=chip)
|
|
28
|
+
f'{step}/{index} receives {len(inputs)} inputs, but only supports one', chip=chip)
|
|
30
29
|
inputs = inputs[0]
|
|
31
30
|
flow = chip.get('option', 'flow')
|
|
32
31
|
arguments = chip.get('flowgraph', flow, step, index, 'args')
|
|
33
32
|
|
|
34
33
|
if len(arguments) == 0:
|
|
35
|
-
raise SiliconCompilerError(f'{step}{index} requires arguments for verify', chip=chip)
|
|
34
|
+
raise SiliconCompilerError(f'{step}/{index} requires arguments for verify', chip=chip)
|
|
36
35
|
|
|
37
36
|
passes = True
|
|
38
37
|
for criteria in arguments:
|
|
@@ -56,10 +55,10 @@ def _select_inputs(chip, step, index):
|
|
|
56
55
|
metric_type = chip.get('metric', metric, field=None)
|
|
57
56
|
goal = NodeType.normalize(goal, metric_type.get(field='type'))
|
|
58
57
|
if not utils.safecompare(chip, value, op, goal):
|
|
59
|
-
chip.error(f"{step}{index} fails '{metric}' metric: {value}{op}{goal}")
|
|
58
|
+
chip.error(f"{step}/{index} fails '{metric}' metric: {value}{op}{goal}")
|
|
60
59
|
|
|
61
60
|
if not passes:
|
|
62
|
-
|
|
61
|
+
return []
|
|
63
62
|
|
|
64
63
|
return inputs
|
|
65
64
|
|
|
@@ -70,10 +69,10 @@ def _gather_outputs(chip, step, index):
|
|
|
70
69
|
in_nodes = chip.get('flowgraph', flow, step, index, 'input')
|
|
71
70
|
in_task_outputs = []
|
|
72
71
|
for in_step, in_index in in_nodes:
|
|
73
|
-
in_tool,
|
|
74
|
-
task_class = chip.get("tool", in_tool, field="schema")
|
|
75
|
-
task_class.
|
|
76
|
-
|
|
72
|
+
in_tool, in_task = get_tool_task(chip, in_step, in_index, flow=flow)
|
|
73
|
+
task_class = chip.get("tool", in_tool, "task", in_task, field="schema")
|
|
74
|
+
with task_class.runtime(chip, step=in_step, index=in_index) as task:
|
|
75
|
+
in_task_outputs.append(task.get_output_files())
|
|
77
76
|
|
|
78
77
|
if len(in_task_outputs) > 0:
|
|
79
78
|
return in_task_outputs[0].intersection(*in_task_outputs[1:])
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
from siliconcompiler.tools.vpr.vpr import parse_version as vpr_parse_version
|
|
2
|
-
from siliconcompiler.tools.vpr.vpr import normalize_version as vpr_normalize_version
|
|
3
2
|
from siliconcompiler.tools.vpr.vpr import add_tool_requirements as add_vpr_requirements
|
|
4
3
|
|
|
5
4
|
'''
|
|
@@ -24,7 +23,7 @@ def make_docs(chip):
|
|
|
24
23
|
def setup(chip):
|
|
25
24
|
chip.set('tool', 'genfasm', 'exe', 'genfasm', clobber=False)
|
|
26
25
|
chip.set('tool', 'genfasm', 'vswitch', '--version')
|
|
27
|
-
chip.set('tool', 'genfasm', 'version', '>=
|
|
26
|
+
chip.set('tool', 'genfasm', 'version', '>=v8.0.0-12677', clobber=False)
|
|
28
27
|
|
|
29
28
|
add_tool_requirements(chip)
|
|
30
29
|
|
|
@@ -37,10 +36,6 @@ def parse_version(chip):
|
|
|
37
36
|
return vpr_parse_version(chip)
|
|
38
37
|
|
|
39
38
|
|
|
40
|
-
def normalize_version(chip):
|
|
41
|
-
return vpr_normalize_version(chip)
|
|
42
|
-
|
|
43
|
-
|
|
44
39
|
##################################################
|
|
45
40
|
if __name__ == "__main__":
|
|
46
41
|
chip = make_docs()
|
|
@@ -646,6 +646,10 @@ def define_gpl_params(chip):
|
|
|
646
646
|
default_value='true',
|
|
647
647
|
schelp='true/false, when enabled a global placement is performed without '
|
|
648
648
|
'considering the impact of the pin placements')
|
|
649
|
+
set_tool_task_var(chip, param_key='gpl_enable_skip_initial_place',
|
|
650
|
+
default_value='false',
|
|
651
|
+
schelp='true/false, when enabled a global placement skips the initial '
|
|
652
|
+
'placement, before the main global placement pass.')
|
|
649
653
|
|
|
650
654
|
|
|
651
655
|
def define_dpo_params(chip):
|
|
@@ -654,7 +658,7 @@ def define_dpo_params(chip):
|
|
|
654
658
|
schelp='true/false, when true the detailed placement optimization '
|
|
655
659
|
'will be performed')
|
|
656
660
|
set_tool_task_var(chip, param_key='dpo_max_displacement',
|
|
657
|
-
default_value='
|
|
661
|
+
default_value='5',
|
|
658
662
|
schelp='maximum cell movement in detailed placement optimization in microns, '
|
|
659
663
|
'0 will result in the tool default maximum displacement')
|
|
660
664
|
|
|
@@ -68,7 +68,7 @@ def pre_process(chip):
|
|
|
68
68
|
chip.get('tool', tool, 'task', task, 'var', 'ant_check',
|
|
69
69
|
step=step, index=index)[0] == 'false':
|
|
70
70
|
chip.set('record', 'status', NodeStatus.SKIPPED, step=step, index=index)
|
|
71
|
-
chip.logger.warning(f'{step}{index} will be skipped since antenna repair is disabled.')
|
|
71
|
+
chip.logger.warning(f'{step}/{index} will be skipped since antenna repair is disabled.')
|
|
72
72
|
return
|
|
73
73
|
|
|
74
74
|
define_ord_files(chip)
|
|
@@ -62,7 +62,7 @@ def pre_process(chip):
|
|
|
62
62
|
for in_step, in_index in input_nodes
|
|
63
63
|
]):
|
|
64
64
|
chip.set('record', 'status', NodeStatus.SKIPPED, step=step, index=index)
|
|
65
|
-
chip.logger.warning(f'{step}{index} will be skipped since are no macros to place.')
|
|
65
|
+
chip.logger.warning(f'{step}/{index} will be skipped since are no macros to place.')
|
|
66
66
|
return
|
|
67
67
|
|
|
68
68
|
build_pex_corners(chip)
|
|
@@ -60,7 +60,7 @@ def pre_process(chip):
|
|
|
60
60
|
(chip.get('tool', tool, 'task', task, 'var', 'pdn_enable',
|
|
61
61
|
step=step, index=index)[0] == 'false' or len(pdncfg) == 0):
|
|
62
62
|
chip.set('record', 'status', NodeStatus.SKIPPED, step=step, index=index)
|
|
63
|
-
chip.logger.warning(f'{step}{index} will be skipped since power grid is disabled.')
|
|
63
|
+
chip.logger.warning(f'{step}/{index} will be skipped since power grid is disabled.')
|
|
64
64
|
return
|
|
65
65
|
|
|
66
66
|
define_ord_files(chip)
|
|
@@ -68,6 +68,8 @@ proc sc_global_placement { args } {
|
|
|
68
68
|
set gpl_routability_driven [lindex [sc_cfg_tool_task_get var gpl_routability_driven] 0]
|
|
69
69
|
set gpl_timing_driven [lindex [sc_cfg_tool_task_get var gpl_timing_driven] 0]
|
|
70
70
|
set gpl_padding [lindex [sc_cfg_tool_task_get var pad_global_place] 0]
|
|
71
|
+
set gpl_enable_skip_initial_place [lindex \
|
|
72
|
+
[sc_cfg_tool_task_get var gpl_enable_skip_initial_place] 0]
|
|
71
73
|
|
|
72
74
|
set gpl_args []
|
|
73
75
|
if {
|
|
@@ -79,6 +81,9 @@ proc sc_global_placement { args } {
|
|
|
79
81
|
if { $gpl_timing_driven == "true" } {
|
|
80
82
|
lappend gpl_args "-timing_driven"
|
|
81
83
|
}
|
|
84
|
+
if { $gpl_enable_skip_initial_place == "true" } {
|
|
85
|
+
lappend gpl_args "-skip_initial_place"
|
|
86
|
+
}
|
|
82
87
|
|
|
83
88
|
if { [info exists flags(-skip_io)] } {
|
|
84
89
|
lappend gpl_args "-skip_io"
|
|
@@ -634,36 +639,38 @@ proc sc_setup_sta { } {
|
|
|
634
639
|
set_timing_derate -late $sta_late_timing_derate
|
|
635
640
|
}
|
|
636
641
|
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
[lindex [sc_cfg_tool_task_get var sta_define_path_groups] 0] == "true" &&
|
|
640
|
-
[llength [sta::path_group_names]] == 0
|
|
641
|
-
} {
|
|
642
|
-
sc_path_group -name in2out -from [all_inputs -no_clocks] -to [all_outputs]
|
|
643
|
-
|
|
642
|
+
if { [sc_check_version 19370] } {
|
|
643
|
+
# Create path groups
|
|
644
644
|
if {
|
|
645
|
-
[
|
|
646
|
-
[
|
|
645
|
+
[lindex [sc_cfg_tool_task_get var sta_define_path_groups] 0] == "true" &&
|
|
646
|
+
[llength [sta::path_group_names]] == 0
|
|
647
647
|
} {
|
|
648
|
-
sc_path_group -name
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
sc_path_group -name in2reg
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
648
|
+
sc_path_group -name in2out -from [all_inputs -no_clocks] -to [all_outputs]
|
|
649
|
+
|
|
650
|
+
if {
|
|
651
|
+
[llength [all_clocks]] == 1 ||
|
|
652
|
+
[lindex [sc_cfg_tool_task_get var sta_unique_path_groups_per_clock] 0] == "false"
|
|
653
|
+
} {
|
|
654
|
+
sc_path_group -name in2reg -from [all_inputs -no_clocks] -to [all_registers]
|
|
655
|
+
sc_path_group -name reg2reg -from [all_registers] -to [all_registers]
|
|
656
|
+
sc_path_group -name reg2out -from [all_registers] -to [all_outputs]
|
|
657
|
+
} else {
|
|
658
|
+
foreach clock [all_clocks] {
|
|
659
|
+
set clk_name [get_property $clock name]
|
|
660
|
+
sc_path_group -name in2reg.${clk_name} \
|
|
661
|
+
-from [all_inputs -no_clocks] \
|
|
662
|
+
-to [all_registers -clock $clock]
|
|
663
|
+
sc_path_group -name reg2reg.${clk_name} \
|
|
664
|
+
-from [all_registers -clock $clock] \
|
|
665
|
+
-to [all_registers -clock $clock]
|
|
666
|
+
sc_path_group -name reg2out.${clk_name} \
|
|
667
|
+
-from [all_registers -clock $clock] \
|
|
668
|
+
-to [all_outputs]
|
|
669
|
+
}
|
|
663
670
|
}
|
|
664
671
|
}
|
|
672
|
+
utl::info FLW 1 "Timing path groups: [sta::path_group_names]"
|
|
665
673
|
}
|
|
666
|
-
utl::info FLW 1 "Timing path groups: [sta::path_group_names]"
|
|
667
674
|
|
|
668
675
|
# Check timing setup
|
|
669
676
|
if { [sc_cfg_tool_task_check_in_list check_setup var reports] } {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import re
|
|
3
3
|
from siliconcompiler import utils
|
|
4
|
+
from siliconcompiler import NodeStatus
|
|
4
5
|
from siliconcompiler import sc_open, SiliconCompilerError
|
|
5
6
|
from siliconcompiler.tools.opensta import setup as tool_setup
|
|
6
7
|
from siliconcompiler.tools.opensta import runtime_options as tool_runtime_options
|
|
@@ -28,14 +29,14 @@ def setup(chip):
|
|
|
28
29
|
|
|
29
30
|
design = chip.top()
|
|
30
31
|
if f'{design}.vg' in input_provides(chip, step, index):
|
|
31
|
-
chip.
|
|
32
|
+
chip.add('tool', tool, 'task', task, 'input', f'{design}.vg',
|
|
32
33
|
step=step, index=index)
|
|
33
34
|
else:
|
|
34
|
-
chip.
|
|
35
|
+
chip.add('tool', tool, 'task', task, 'require', 'input,netlist,verilog',
|
|
35
36
|
step=step, index=index)
|
|
36
37
|
|
|
37
38
|
if f'{design}.sdc' in input_provides(chip, step, index):
|
|
38
|
-
chip.
|
|
39
|
+
chip.add('tool', tool, 'task', task, 'input', f'{design}.sdc',
|
|
39
40
|
step=step, index=index)
|
|
40
41
|
elif chip.valid('input', 'constraint', 'sdc') and \
|
|
41
42
|
chip.get('input', 'constraint', 'sdc', step=step, index=index):
|
|
@@ -84,6 +85,28 @@ def setup(chip):
|
|
|
84
85
|
add_common_file(chip, 'opensta_generic_sdc', 'sdc/sc_constraints.sdc')
|
|
85
86
|
|
|
86
87
|
|
|
88
|
+
def pre_process(chip):
|
|
89
|
+
'''
|
|
90
|
+
Tool specific function to run before step execution
|
|
91
|
+
'''
|
|
92
|
+
|
|
93
|
+
step = chip.get('arg', 'step')
|
|
94
|
+
index = chip.get('arg', 'index')
|
|
95
|
+
tool, task = get_tool_task(chip, step, index)
|
|
96
|
+
|
|
97
|
+
# If a verilog and sdc file are both provided as input to this tool, but they
|
|
98
|
+
# are both empty, skip this tool step.
|
|
99
|
+
design = chip.top()
|
|
100
|
+
if (f'{design}.vg' in input_provides(chip, step, index)) and \
|
|
101
|
+
(f'{design}.sdc' in input_provides(chip, step, index)):
|
|
102
|
+
if os.path.getsize(f'inputs/{design}.vg') == 0 and \
|
|
103
|
+
os.path.getsize(f'inputs/{design}.sdc') == 0:
|
|
104
|
+
chip.set('record', 'status', NodeStatus.SKIPPED, step=step, index=index)
|
|
105
|
+
chip.logger.warning(f'{step}/{index} will be skipped since no timing '
|
|
106
|
+
'analysis files were provided.')
|
|
107
|
+
return
|
|
108
|
+
|
|
109
|
+
|
|
87
110
|
def __report_map(chip, metric, basefile):
|
|
88
111
|
corners = chip.getkeys('constraint', 'timing')
|
|
89
112
|
mapping = {
|
|
@@ -212,5 +212,5 @@ def _diagnostics(chip, driver, compilation):
|
|
|
212
212
|
for diag in compilation.getAllDiagnostics():
|
|
213
213
|
diags.issue(diag)
|
|
214
214
|
|
|
215
|
-
record_metric(chip, step, index, 'errors', diags.numErrors, [f'sc_{step}{index}.log'])
|
|
216
|
-
record_metric(chip, step, index, 'warnings', diags.numWarnings, [f'sc_{step}{index}.log'])
|
|
215
|
+
record_metric(chip, step, index, 'errors', diags.numErrors, [f'sc_{step}_{index}.log'])
|
|
216
|
+
record_metric(chip, step, index, 'warnings', diags.numWarnings, [f'sc_{step}_{index}.log'])
|
|
File without changes
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from siliconcompiler.tools._common import add_require_input, get_tool_task, input_provides
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def setup(chip):
|
|
6
|
+
'''
|
|
7
|
+
Show a VCD file.
|
|
8
|
+
'''
|
|
9
|
+
step = chip.get('arg', 'step')
|
|
10
|
+
index = chip.get('arg', 'index')
|
|
11
|
+
tool, task = get_tool_task(chip, step, index)
|
|
12
|
+
|
|
13
|
+
# Standard setup
|
|
14
|
+
chip.set('tool', tool, 'exe', tool)
|
|
15
|
+
chip.set('tool', tool, 'vswitch', '--version')
|
|
16
|
+
chip.set('tool', tool, 'version', '>=0.3.0', clobber=False)
|
|
17
|
+
|
|
18
|
+
# Require VCD file
|
|
19
|
+
if f'{chip.top()}.vcd' in input_provides(chip, step, index):
|
|
20
|
+
chip.set('tool', tool, 'task', task, 'input', f'{chip.top()}.vcd',
|
|
21
|
+
step=step, index=index)
|
|
22
|
+
elif chip.valid('tool', tool, 'task', task, 'var', 'show_filepath') and \
|
|
23
|
+
chip.get('tool', tool, 'task', task, 'var', 'show_filepath', step=step, index=index):
|
|
24
|
+
chip.add('tool', tool, 'task', task, 'require',
|
|
25
|
+
','.join(['tool', tool, 'task', task, 'var', 'show_filepath']),
|
|
26
|
+
step=step, index=index)
|
|
27
|
+
else:
|
|
28
|
+
add_require_input(chip, 'input', 'waveform', 'vcd')
|
|
29
|
+
|
|
30
|
+
# Don't exit on show
|
|
31
|
+
chip.set('tool', tool, 'task', task, 'var', 'show_exit', False,
|
|
32
|
+
step=step, index=index, clobber=False)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def runtime_options(chip):
|
|
36
|
+
step = chip.get('arg', 'step')
|
|
37
|
+
index = chip.get('arg', 'index')
|
|
38
|
+
tool, task = get_tool_task(chip, step, index)
|
|
39
|
+
|
|
40
|
+
options = []
|
|
41
|
+
|
|
42
|
+
# Get VCD file
|
|
43
|
+
if os.path.exists(f'inputs/{chip.top()}.vcd'):
|
|
44
|
+
dump = f'inputs/{chip.top()}.vcd'
|
|
45
|
+
elif chip.valid('tool', tool, 'task', task, 'var', 'show_filepath') and \
|
|
46
|
+
chip.get('tool', tool, 'task', task, 'var', 'show_filepath', step=step, index=index):
|
|
47
|
+
dump = chip.get('tool', tool, 'task', task, 'var', 'show_filepath',
|
|
48
|
+
step=step, index=index)[0]
|
|
49
|
+
else:
|
|
50
|
+
dump = chip.find_files('input', 'waveform', 'vcd', step=step, index=index)[0]
|
|
51
|
+
options.append(dump)
|
|
52
|
+
|
|
53
|
+
return options
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'''
|
|
2
|
+
Surfer is a waveform viewer with a focus on a snappy usable
|
|
3
|
+
interface and extensibility.
|
|
4
|
+
|
|
5
|
+
Documentation: https://gitlab.com/surfer-project/surfer/-/wikis/home
|
|
6
|
+
|
|
7
|
+
Sources: https://gitlab.com/surfer-project/surfer
|
|
8
|
+
|
|
9
|
+
Installation: https://gitlab.com/surfer-project/surfer#installation
|
|
10
|
+
'''
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
####################################################################
|
|
14
|
+
# Make Docs
|
|
15
|
+
####################################################################
|
|
16
|
+
def make_docs(chip):
|
|
17
|
+
from siliconcompiler.tools.surfer import show
|
|
18
|
+
show.setup(chip)
|
|
19
|
+
return chip
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def parse_version(stdout):
|
|
23
|
+
# surfer 0.3.0
|
|
24
|
+
return stdout.strip().split()[1]
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
####################################################################
|
|
28
|
+
if __name__ == "__main__":
|
|
29
|
+
chip = make_docs()
|
|
30
|
+
chip.write_manifest("surfer.json")
|
|
@@ -44,6 +44,48 @@ def setup(chip, clobber=True):
|
|
|
44
44
|
chip.add('tool', tool, 'task', task, 'output', design + '.net', step=step, index=index)
|
|
45
45
|
chip.add('tool', tool, 'task', task, 'output', design + '.place', step=step, index=index)
|
|
46
46
|
|
|
47
|
+
# Add a parameter for generating a post-implementation netlist for external
|
|
48
|
+
# static timing analysis.
|
|
49
|
+
if vpr.use_timing_analysis(chip):
|
|
50
|
+
chip.set('tool', tool, 'task', task, 'var', 'gen_post_implementation_netlist',
|
|
51
|
+
True, step=step, index=index, clobber=False)
|
|
52
|
+
else:
|
|
53
|
+
chip.set('tool', tool, 'task', task, 'var', 'gen_post_implementation_netlist',
|
|
54
|
+
False, step=step, index=index, clobber=False)
|
|
55
|
+
|
|
56
|
+
chip.set('tool', tool, 'task', task, 'var', 'gen_post_implementation_netlist',
|
|
57
|
+
'set to true to have VPR generate a post-implementation netlist',
|
|
58
|
+
field='help')
|
|
59
|
+
|
|
60
|
+
chip.set('tool', tool, 'task', task, 'require',
|
|
61
|
+
",".join(['tool', tool, 'task', task, 'var', 'gen_post_implementation_netlist']),
|
|
62
|
+
step=step, index=index)
|
|
63
|
+
|
|
64
|
+
# Add a parameter to control the timing corner used when generating SDF files.
|
|
65
|
+
chip.set('tool', tool, 'task', task, 'var', 'timing_corner', 'typical',
|
|
66
|
+
step=step, index=index, clobber=False)
|
|
67
|
+
|
|
68
|
+
chip.set('tool', tool, 'task', task, 'var', 'timing_corner',
|
|
69
|
+
'set the timing corner for files generated by the post-implementation netlist',
|
|
70
|
+
field='help')
|
|
71
|
+
|
|
72
|
+
chip.set('tool', tool, 'task', task, 'require',
|
|
73
|
+
",".join(['tool', tool, 'task', task, 'var', 'timing_corner']),
|
|
74
|
+
step=step, index=index)
|
|
75
|
+
|
|
76
|
+
# Add the post-implementation timing netlist outputs for the timing step.
|
|
77
|
+
# These files must always be generated so nodes that are connected after this
|
|
78
|
+
# step that are expecting these files do not complain if they are not generated.
|
|
79
|
+
timing_corner = chip.get('tool', tool, 'task', task, 'var', 'timing_corner',
|
|
80
|
+
step=step, index=index)[0]
|
|
81
|
+
|
|
82
|
+
chip.add('tool', tool, 'task', task, 'output', f'{design}.vg',
|
|
83
|
+
step=step, index=index)
|
|
84
|
+
chip.add('tool', tool, 'task', task, 'output', f'{design}.sdc',
|
|
85
|
+
step=step, index=index)
|
|
86
|
+
chip.add('tool', tool, 'task', task, 'output', f'{design}.{timing_corner}.sdf',
|
|
87
|
+
step=step, index=index)
|
|
88
|
+
|
|
47
89
|
|
|
48
90
|
def runtime_options(chip):
|
|
49
91
|
'''Command line options to vpr for the route step
|
|
@@ -104,6 +146,21 @@ def runtime_options(chip):
|
|
|
104
146
|
options.append("--graphics_commands")
|
|
105
147
|
options.append(graphics_command_str)
|
|
106
148
|
|
|
149
|
+
# Generate a post-implementation netlist for use in external timing analysis
|
|
150
|
+
# if requested.
|
|
151
|
+
gen_post_implementation_netlist = chip.get('tool', tool, 'task', task, 'var',
|
|
152
|
+
'gen_post_implementation_netlist',
|
|
153
|
+
step=step, index=index)[0]
|
|
154
|
+
if gen_post_implementation_netlist == 'true':
|
|
155
|
+
# Generate the netlist.
|
|
156
|
+
options.extend(["--gen_post_synthesis_netlist", "on"])
|
|
157
|
+
# Generate the SDC file.
|
|
158
|
+
options.extend(["--gen_post_implementation_sdc", "on"])
|
|
159
|
+
# Create undriven nets for unconnected inputs.
|
|
160
|
+
options.extend(["--post_synth_netlist_unconn_inputs", "nets"])
|
|
161
|
+
# Turn off module parameters.
|
|
162
|
+
options.extend(["--post_synth_netlist_module_parameters", "off"])
|
|
163
|
+
|
|
107
164
|
return options
|
|
108
165
|
|
|
109
166
|
|
|
@@ -122,3 +179,28 @@ def post_process(chip):
|
|
|
122
179
|
shutil.copy2(f'inputs/{design}.blif', 'outputs')
|
|
123
180
|
shutil.copy2(f'inputs/{design}.net', 'outputs')
|
|
124
181
|
shutil.copy2(f'inputs/{design}.place', 'outputs')
|
|
182
|
+
|
|
183
|
+
# Copy and rename the post-implementation netlist results into the output
|
|
184
|
+
# directory to be used in external timing analysis.
|
|
185
|
+
step = chip.get('arg', 'step')
|
|
186
|
+
index = chip.get('arg', 'index')
|
|
187
|
+
tool, task = get_tool_task(chip, step, index)
|
|
188
|
+
gen_post_implementation_netlist = chip.get('tool', tool, 'task', task, 'var',
|
|
189
|
+
'gen_post_implementation_netlist',
|
|
190
|
+
step=step, index=index)[0]
|
|
191
|
+
timing_corner = chip.get('tool', tool, 'task', task, 'var', 'timing_corner',
|
|
192
|
+
step=step, index=index)[0]
|
|
193
|
+
|
|
194
|
+
if vpr.use_timing_analysis(chip) and gen_post_implementation_netlist == 'true':
|
|
195
|
+
# These files will only exist if timing analysis is on and VPR was told
|
|
196
|
+
# to generate them.
|
|
197
|
+
shutil.move(f'{design}_post_synthesis.v', f'outputs/{design}.vg')
|
|
198
|
+
shutil.move(f'{design}_post_synthesis.sdc', f'outputs/{design}.sdc')
|
|
199
|
+
shutil.move(f'{design}_post_synthesis.sdf', f'outputs/{design}.{timing_corner}.sdf')
|
|
200
|
+
else:
|
|
201
|
+
# If timing analysis is on or we are not generating a post-implementation
|
|
202
|
+
# netlist, just produce blank files. These will trigger any future nodes
|
|
203
|
+
# that use them to skip.
|
|
204
|
+
open(f'outputs/{design}.vg', 'a')
|
|
205
|
+
open(f'outputs/{design}.sdc', 'a')
|
|
206
|
+
open(f'outputs/{design}.{timing_corner}.sdf', 'a')
|