siliconcompiler 0.34.0__py3-none-any.whl → 0.34.2__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 (114) hide show
  1. siliconcompiler/__init__.py +14 -2
  2. siliconcompiler/_metadata.py +1 -1
  3. siliconcompiler/apps/_common.py +1 -1
  4. siliconcompiler/apps/sc.py +1 -1
  5. siliconcompiler/apps/sc_issue.py +1 -1
  6. siliconcompiler/apps/sc_remote.py +3 -3
  7. siliconcompiler/apps/sc_show.py +3 -3
  8. siliconcompiler/apps/utils/replay.py +4 -4
  9. siliconcompiler/checklist.py +203 -2
  10. siliconcompiler/constraints/__init__.py +17 -0
  11. siliconcompiler/constraints/asic_component.py +378 -0
  12. siliconcompiler/constraints/asic_floorplan.py +449 -0
  13. siliconcompiler/constraints/asic_pins.py +489 -0
  14. siliconcompiler/constraints/asic_timing.py +517 -0
  15. siliconcompiler/core.py +31 -249
  16. siliconcompiler/data/templates/email/general.j2 +3 -3
  17. siliconcompiler/data/templates/email/summary.j2 +1 -1
  18. siliconcompiler/data/templates/issue/README.txt +1 -1
  19. siliconcompiler/data/templates/report/sc_report.j2 +7 -7
  20. siliconcompiler/dependencyschema.py +10 -174
  21. siliconcompiler/design.py +325 -114
  22. siliconcompiler/flowgraph.py +63 -15
  23. siliconcompiler/library.py +133 -0
  24. siliconcompiler/metric.py +94 -72
  25. siliconcompiler/metrics/__init__.py +7 -0
  26. siliconcompiler/metrics/asic.py +245 -0
  27. siliconcompiler/metrics/fpga.py +220 -0
  28. siliconcompiler/optimizer/vizier.py +2 -2
  29. siliconcompiler/package/__init__.py +138 -35
  30. siliconcompiler/package/github.py +6 -10
  31. siliconcompiler/packageschema.py +256 -12
  32. siliconcompiler/pathschema.py +226 -0
  33. siliconcompiler/pdk.py +5 -5
  34. siliconcompiler/project.py +459 -0
  35. siliconcompiler/remote/client.py +18 -12
  36. siliconcompiler/remote/server.py +2 -2
  37. siliconcompiler/report/dashboard/cli/__init__.py +6 -6
  38. siliconcompiler/report/dashboard/cli/board.py +3 -3
  39. siliconcompiler/report/dashboard/web/components/__init__.py +5 -5
  40. siliconcompiler/report/dashboard/web/components/flowgraph.py +4 -4
  41. siliconcompiler/report/dashboard/web/components/graph.py +2 -2
  42. siliconcompiler/report/dashboard/web/state.py +1 -1
  43. siliconcompiler/report/dashboard/web/utils/__init__.py +5 -5
  44. siliconcompiler/report/html_report.py +1 -1
  45. siliconcompiler/report/report.py +4 -4
  46. siliconcompiler/report/summary_table.py +2 -2
  47. siliconcompiler/report/utils.py +5 -5
  48. siliconcompiler/scheduler/docker.py +4 -10
  49. siliconcompiler/scheduler/run_node.py +4 -8
  50. siliconcompiler/scheduler/scheduler.py +18 -24
  51. siliconcompiler/scheduler/schedulernode.py +161 -143
  52. siliconcompiler/scheduler/send_messages.py +3 -3
  53. siliconcompiler/scheduler/slurm.py +5 -3
  54. siliconcompiler/scheduler/taskscheduler.py +10 -8
  55. siliconcompiler/schema/__init__.py +0 -2
  56. siliconcompiler/schema/baseschema.py +148 -26
  57. siliconcompiler/schema/editableschema.py +14 -6
  58. siliconcompiler/schema/journal.py +23 -15
  59. siliconcompiler/schema/namedschema.py +30 -4
  60. siliconcompiler/schema/parameter.py +34 -19
  61. siliconcompiler/schema/parametertype.py +2 -0
  62. siliconcompiler/schema/parametervalue.py +198 -15
  63. siliconcompiler/schema/schema_cfg.py +18 -14
  64. siliconcompiler/schema_obj.py +5 -3
  65. siliconcompiler/tool.py +591 -179
  66. siliconcompiler/tools/__init__.py +2 -0
  67. siliconcompiler/tools/builtin/_common.py +5 -5
  68. siliconcompiler/tools/builtin/concatenate.py +5 -5
  69. siliconcompiler/tools/builtin/minimum.py +4 -4
  70. siliconcompiler/tools/builtin/mux.py +4 -4
  71. siliconcompiler/tools/builtin/nop.py +4 -4
  72. siliconcompiler/tools/builtin/verify.py +7 -7
  73. siliconcompiler/tools/execute/exec_input.py +1 -1
  74. siliconcompiler/tools/genfasm/genfasm.py +1 -6
  75. siliconcompiler/tools/openroad/_apr.py +5 -1
  76. siliconcompiler/tools/openroad/antenna_repair.py +1 -1
  77. siliconcompiler/tools/openroad/macro_placement.py +1 -1
  78. siliconcompiler/tools/openroad/power_grid.py +1 -1
  79. siliconcompiler/tools/openroad/scripts/common/procs.tcl +5 -0
  80. siliconcompiler/tools/opensta/timing.py +26 -3
  81. siliconcompiler/tools/slang/__init__.py +2 -2
  82. siliconcompiler/tools/surfer/__init__.py +0 -0
  83. siliconcompiler/tools/surfer/show.py +53 -0
  84. siliconcompiler/tools/surfer/surfer.py +30 -0
  85. siliconcompiler/tools/vpr/route.py +27 -14
  86. siliconcompiler/tools/vpr/vpr.py +23 -6
  87. siliconcompiler/tools/yosys/__init__.py +1 -1
  88. siliconcompiler/tools/yosys/scripts/procs.tcl +143 -0
  89. siliconcompiler/tools/yosys/{sc_synth_asic.tcl → scripts/sc_synth_asic.tcl} +4 -0
  90. siliconcompiler/tools/yosys/{sc_synth_fpga.tcl → scripts/sc_synth_fpga.tcl} +24 -77
  91. siliconcompiler/tools/yosys/syn_fpga.py +14 -0
  92. siliconcompiler/toolscripts/_tools.json +9 -13
  93. siliconcompiler/toolscripts/rhel9/install-vpr.sh +0 -2
  94. siliconcompiler/toolscripts/ubuntu22/install-surfer.sh +33 -0
  95. siliconcompiler/toolscripts/ubuntu24/install-surfer.sh +33 -0
  96. siliconcompiler/utils/__init__.py +2 -1
  97. siliconcompiler/utils/flowgraph.py +24 -23
  98. siliconcompiler/utils/issue.py +23 -29
  99. siliconcompiler/utils/logging.py +35 -6
  100. siliconcompiler/utils/showtools.py +6 -1
  101. {siliconcompiler-0.34.0.dist-info → siliconcompiler-0.34.2.dist-info}/METADATA +15 -25
  102. {siliconcompiler-0.34.0.dist-info → siliconcompiler-0.34.2.dist-info}/RECORD +109 -97
  103. siliconcompiler/schema/packageschema.py +0 -101
  104. siliconcompiler/tools/yosys/procs.tcl +0 -71
  105. siliconcompiler/toolscripts/rhel9/install-yosys-parmys.sh +0 -68
  106. siliconcompiler/toolscripts/ubuntu22/install-yosys-parmys.sh +0 -68
  107. siliconcompiler/toolscripts/ubuntu24/install-yosys-parmys.sh +0 -68
  108. /siliconcompiler/tools/yosys/{sc_lec.tcl → scripts/sc_lec.tcl} +0 -0
  109. /siliconcompiler/tools/yosys/{sc_screenshot.tcl → scripts/sc_screenshot.tcl} +0 -0
  110. /siliconcompiler/tools/yosys/{syn_strategies.tcl → scripts/syn_strategies.tcl} +0 -0
  111. {siliconcompiler-0.34.0.dist-info → siliconcompiler-0.34.2.dist-info}/WHEEL +0 -0
  112. {siliconcompiler-0.34.0.dist-info → siliconcompiler-0.34.2.dist-info}/entry_points.txt +0 -0
  113. {siliconcompiler-0.34.0.dist-info → siliconcompiler-0.34.2.dist-info}/licenses/LICENSE +0 -0
  114. {siliconcompiler-0.34.0.dist-info → siliconcompiler-0.34.2.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.schema.get("flowgraph", flow, field="schema")
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.schema.get("record", field="schema"))
162
+ return runtime.get_node_inputs(step, index, record=chip.get("record", field="schema"))
@@ -11,7 +11,7 @@ def make_docs(chip):
11
11
  _make_docs(chip)
12
12
  chip.set('option', 'flow', 'asicflow')
13
13
 
14
- for step, index in chip.schema.get("flowgraph", "asicflow", field="schema").get_entry_nodes():
14
+ for step, index in chip.get("flowgraph", "asicflow", field="schema").get_entry_nodes():
15
15
  SchedulerNode(chip, step, index).setup()
16
16
 
17
17
  chip.set('arg', 'step', 'import.combine')
@@ -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, _ = get_tool_task(chip, in_step, in_index, flow=flow)
68
- task_class = chip.get("tool", in_tool, field="schema")
69
- task_class.set_runtime(chip, step=in_step, index=in_index)
70
- in_task_outputs.append(task_class.get_output_files())
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, _ = get_tool_task(chip, in_step, in_index, flow=flow)
47
- task_class = chip.get("tool", in_tool, field="schema")
48
- task_class.set_runtime(chip, step=in_step, index=in_index)
49
- in_task_outputs.append(task_class.get_output_files())
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, _ = get_tool_task(chip, in_step, in_index, flow=flow)
61
- task_class = chip.get("tool", in_tool, field="schema")
62
- task_class.set_runtime(chip, step=in_step, index=in_index)
63
- in_task_outputs.append(task_class.get_output_files())
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, _ = get_tool_task(chip, in_step, in_index, flow=flow)
28
- task_class = chip.get("tool", in_tool, field="schema")
29
- task_class.set_runtime(chip, step=in_step, index=in_index)
30
- in_task_outputs.append(task_class.get_output_files())
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:])
@@ -25,13 +25,13 @@ def _select_inputs(chip, step, index):
25
25
  inputs = _common._select_inputs(chip, step, index)
26
26
  if len(inputs) != 1:
27
27
  raise SiliconCompilerError(
28
- 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)
29
29
  inputs = inputs[0]
30
30
  flow = chip.get('option', 'flow')
31
31
  arguments = chip.get('flowgraph', flow, step, index, 'args')
32
32
 
33
33
  if len(arguments) == 0:
34
- raise SiliconCompilerError(f'{step}{index} requires arguments for verify', chip=chip)
34
+ raise SiliconCompilerError(f'{step}/{index} requires arguments for verify', chip=chip)
35
35
 
36
36
  passes = True
37
37
  for criteria in arguments:
@@ -55,7 +55,7 @@ def _select_inputs(chip, step, index):
55
55
  metric_type = chip.get('metric', metric, field=None)
56
56
  goal = NodeType.normalize(goal, metric_type.get(field='type'))
57
57
  if not utils.safecompare(chip, value, op, goal):
58
- chip.error(f"{step}{index} fails '{metric}' metric: {value}{op}{goal}")
58
+ chip.error(f"{step}/{index} fails '{metric}' metric: {value}{op}{goal}")
59
59
 
60
60
  if not passes:
61
61
  return []
@@ -69,10 +69,10 @@ def _gather_outputs(chip, step, index):
69
69
  in_nodes = chip.get('flowgraph', flow, step, index, 'input')
70
70
  in_task_outputs = []
71
71
  for in_step, in_index in in_nodes:
72
- in_tool, _ = get_tool_task(chip, in_step, in_index, flow=flow)
73
- task_class = chip.get("tool", in_tool, field="schema")
74
- task_class.set_runtime(chip, step=in_step, index=in_index)
75
- in_task_outputs.append(task_class.get_output_files())
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())
76
76
 
77
77
  if len(in_task_outputs) > 0:
78
78
  return in_task_outputs[0].intersection(*in_task_outputs[1:])
@@ -34,7 +34,7 @@ def pre_process(chip):
34
34
  break
35
35
 
36
36
  if not exec:
37
- chip.error(f'{step}{index} did not receive an executable file')
37
+ chip.error(f'{step}/{index} did not receive an executable file')
38
38
 
39
39
  chip.set('tool', tool, 'exe', exec)
40
40
 
@@ -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', '>=9.0.0', clobber=False)
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='0',
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"
@@ -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.set('tool', tool, 'task', task, 'input', f'{design}.vg',
32
+ chip.add('tool', tool, 'task', task, 'input', f'{design}.vg',
32
33
  step=step, index=index)
33
34
  else:
34
- chip.set('tool', tool, 'task', task, 'require', 'input,netlist,verilog',
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.set('tool', tool, 'task', task, 'input', f'{design}.sdc',
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")
@@ -46,8 +46,12 @@ def setup(chip, clobber=True):
46
46
 
47
47
  # Add a parameter for generating a post-implementation netlist for external
48
48
  # static timing analysis.
49
- chip.set('tool', tool, 'task', task, 'var', 'gen_post_implementation_netlist',
50
- False, step=step, index=index, clobber=False)
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)
51
55
 
52
56
  chip.set('tool', tool, 'task', task, 'var', 'gen_post_implementation_netlist',
53
57
  'set to true to have VPR generate a post-implementation netlist',
@@ -69,19 +73,18 @@ def setup(chip, clobber=True):
69
73
  ",".join(['tool', tool, 'task', task, 'var', 'timing_corner']),
70
74
  step=step, index=index)
71
75
 
72
- # Add the post-implementation timing netlist outputs if requested.
73
- gen_post_implementation_netlist = chip.get('tool', tool, 'task', task, 'var',
74
- 'gen_post_implementation_netlist',
75
- step=step, index=index)[0]
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.
76
79
  timing_corner = chip.get('tool', tool, 'task', task, 'var', 'timing_corner',
77
80
  step=step, index=index)[0]
78
- if gen_post_implementation_netlist == 'true':
79
- chip.add('tool', tool, 'task', task, 'output', f'{design}.vg',
80
- step=step, index=index)
81
- chip.add('tool', tool, 'task', task, 'output', f'{design}.sdc',
82
- step=step, index=index)
83
- chip.add('tool', tool, 'task', task, 'output', f'{design}.{timing_corner}.sdf',
84
- step=step, index=index)
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)
85
88
 
86
89
 
87
90
  def runtime_options(chip):
@@ -187,7 +190,17 @@ def post_process(chip):
187
190
  step=step, index=index)[0]
188
191
  timing_corner = chip.get('tool', tool, 'task', task, 'var', 'timing_corner',
189
192
  step=step, index=index)[0]
190
- if gen_post_implementation_netlist == 'true':
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.
191
197
  shutil.move(f'{design}_post_synthesis.v', f'outputs/{design}.vg')
192
198
  shutil.move(f'{design}_post_synthesis.sdc', f'outputs/{design}.sdc')
193
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')
@@ -43,7 +43,7 @@ def setup_tool(chip, clobber=True):
43
43
 
44
44
  chip.set('tool', 'vpr', 'exe', 'vpr', clobber=clobber)
45
45
  chip.set('tool', 'vpr', 'vswitch', '--version')
46
- chip.set('tool', 'vpr', 'version', '>=9.0.0', clobber=clobber)
46
+ chip.set('tool', 'vpr', 'version', '>=v8.0.0-12677', clobber=clobber)
47
47
 
48
48
  step = chip.get('arg', 'step')
49
49
  index = chip.get('arg', 'index')
@@ -184,6 +184,7 @@ def runtime_options(chip):
184
184
  options.append("--sdc_file")
185
185
  options.append(sdc_file)
186
186
 
187
+ if use_timing_analysis(chip):
187
188
  report_type = chip.get('tool', tool, 'task', task, 'var', 'timing_report_type',
188
189
  step=step, index=index)[0]
189
190
  options.extend(['--timing_report_detail', report_type])
@@ -297,20 +298,36 @@ def parse_version(stdout):
297
298
  # This is free open source code under MIT license.
298
299
  #
299
300
  #
300
- return stdout.split()[6]
301
301
 
302
+ # Grab the revision. Which will be of the form:
303
+ # v8.0.0-7887-gc4156f225
304
+ revision = stdout.split()[8]
302
305
 
303
- def normalize_version(version):
304
- if '-' in version:
305
- return version.split('-')[0]
306
+ # VTR infrequently makes even minor releases, use the number of commits
307
+ # since the last release of VTR as another part of the release segment.
308
+ pieces = revision.split("-")
309
+ if len(pieces) == 3:
310
+ # Strip off the hash if it exists.
311
+ return "-".join(pieces[:-1])
306
312
  else:
307
- return version
313
+ return revision
308
314
 
309
315
 
310
316
  def auto_constraints():
311
317
  return 'inputs/sc_constraints.xml'
312
318
 
313
319
 
320
+ def use_timing_analysis(chip):
321
+ '''
322
+ Return true if the given chip should use timing analysis in the VPR flow.
323
+ '''
324
+ step = chip.get('arg', 'step')
325
+ index = chip.get('arg', 'index')
326
+ return \
327
+ chip.valid('input', 'constraint', 'sdc') and \
328
+ chip.get('input', 'constraint', 'sdc', step=step, index=index)
329
+
330
+
314
331
  def vpr_post_process(chip):
315
332
  step = chip.get('arg', 'step')
316
333
  index = chip.get('arg', 'index')
@@ -51,7 +51,7 @@ def setup(chip):
51
51
  option.append('-C')
52
52
  option.append('-c')
53
53
  chip.set('tool', tool, 'task', task, 'option', option, step=step, index=index, clobber=False)
54
- chip.set('tool', tool, 'task', task, 'refdir', os.path.join('tools', tool),
54
+ chip.set('tool', tool, 'task', task, 'refdir', os.path.join('tools', tool, 'scripts'),
55
55
  step=step, index=index,
56
56
  package='siliconcompiler', clobber=False)
57
57
  chip.set('tool', tool, 'task', task, 'regex', 'warnings', "Warning:",