siliconcompiler 0.29.3__py3-none-any.whl → 0.30.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.
Files changed (60) hide show
  1. siliconcompiler/_metadata.py +1 -1
  2. siliconcompiler/apps/sc.py +1 -1
  3. siliconcompiler/apps/sc_install.py +46 -3
  4. siliconcompiler/core.py +15 -4
  5. siliconcompiler/remote/client.py +3 -0
  6. siliconcompiler/scheduler/__init__.py +9 -3
  7. siliconcompiler/schema/schema_cfg.py +149 -92
  8. siliconcompiler/tools/__init__.py +4 -2
  9. siliconcompiler/tools/_common/asic.py +3 -0
  10. siliconcompiler/tools/_common/asic_clock.py +101 -0
  11. siliconcompiler/tools/bambu/__init__.py +32 -0
  12. siliconcompiler/tools/bambu/convert.py +93 -12
  13. siliconcompiler/tools/bluespec/__init__.py +35 -0
  14. siliconcompiler/tools/bluespec/convert.py +44 -5
  15. siliconcompiler/tools/graphviz/__init__.py +12 -0
  16. siliconcompiler/tools/graphviz/screenshot.py +48 -0
  17. siliconcompiler/tools/graphviz/show.py +20 -0
  18. siliconcompiler/tools/openroad/_apr.py +17 -0
  19. siliconcompiler/tools/openroad/fillmetal_insertion.py +0 -1
  20. siliconcompiler/tools/openroad/init_floorplan.py +7 -1
  21. siliconcompiler/tools/openroad/macro_placement.py +10 -2
  22. siliconcompiler/tools/openroad/pin_placement.py +0 -1
  23. siliconcompiler/tools/openroad/power_grid.py +6 -0
  24. siliconcompiler/tools/openroad/scripts/apr/preamble.tcl +3 -2
  25. siliconcompiler/tools/openroad/scripts/apr/sc_clock_tree_synthesis.tcl +2 -0
  26. siliconcompiler/tools/openroad/scripts/apr/sc_detailed_route.tcl +2 -0
  27. siliconcompiler/tools/openroad/scripts/apr/sc_global_route.tcl +15 -5
  28. siliconcompiler/tools/openroad/scripts/apr/sc_init_floorplan.tcl +1 -0
  29. siliconcompiler/tools/openroad/scripts/apr/sc_macro_placement.tcl +9 -1
  30. siliconcompiler/tools/openroad/scripts/apr/sc_power_grid.tcl +54 -0
  31. siliconcompiler/tools/openroad/scripts/apr/sc_repair_timing.tcl +24 -0
  32. siliconcompiler/tools/openroad/scripts/common/procs.tcl +28 -6
  33. siliconcompiler/tools/openroad/scripts/common/read_input_files.tcl +1 -0
  34. siliconcompiler/tools/openroad/scripts/common/reports.tcl +10 -16
  35. siliconcompiler/tools/slang/__init__.py +1 -0
  36. siliconcompiler/tools/verilator/verilator.py +1 -0
  37. siliconcompiler/tools/yosys/__init__.py +26 -23
  38. siliconcompiler/tools/yosys/procs.tcl +17 -0
  39. siliconcompiler/tools/yosys/syn_asic.py +12 -65
  40. siliconcompiler/tools/yosys/syn_asic.tcl +6 -51
  41. siliconcompiler/toolscripts/_tools.json +5 -5
  42. siliconcompiler/toolscripts/rhel8/install-yosys.sh +1 -1
  43. siliconcompiler/toolscripts/rhel9/install-openroad.sh +34 -0
  44. siliconcompiler/toolscripts/rhel9/install-yosys.sh +1 -1
  45. siliconcompiler/toolscripts/ubuntu20/install-openroad.sh +1 -1
  46. siliconcompiler/toolscripts/ubuntu20/install-yosys.sh +1 -1
  47. siliconcompiler/toolscripts/ubuntu22/install-openroad.sh +1 -1
  48. siliconcompiler/toolscripts/ubuntu22/install-yosys.sh +1 -1
  49. siliconcompiler/toolscripts/ubuntu24/install-openroad.sh +1 -1
  50. siliconcompiler/toolscripts/ubuntu24/install-yosys.sh +1 -1
  51. siliconcompiler/utils/__init__.py +13 -0
  52. siliconcompiler/utils/showtools.py +7 -0
  53. {siliconcompiler-0.29.3.dist-info → siliconcompiler-0.30.0.dist-info}/METADATA +9 -9
  54. {siliconcompiler-0.29.3.dist-info → siliconcompiler-0.30.0.dist-info}/RECORD +58 -55
  55. siliconcompiler/tools/bambu/bambu.py +0 -32
  56. siliconcompiler/tools/bluespec/bluespec.py +0 -40
  57. {siliconcompiler-0.29.3.dist-info → siliconcompiler-0.30.0.dist-info}/LICENSE +0 -0
  58. {siliconcompiler-0.29.3.dist-info → siliconcompiler-0.30.0.dist-info}/WHEEL +0 -0
  59. {siliconcompiler-0.29.3.dist-info → siliconcompiler-0.30.0.dist-info}/entry_points.txt +0 -0
  60. {siliconcompiler-0.29.3.dist-info → siliconcompiler-0.30.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,101 @@
1
+ import re
2
+ from siliconcompiler.utils import sc_open
3
+ from siliconcompiler.tools._common.asic import get_tool_task
4
+
5
+
6
+ def __get_clock_data(chip, clock_units_multiplier=1):
7
+ step = chip.get('arg', 'step')
8
+ index = chip.get('arg', 'index')
9
+
10
+ period = None
11
+ # get clock information from sdc files
12
+ if chip.valid('input', 'constraint', 'sdc'):
13
+ for sdc in chip.find_files('input', 'constraint', 'sdc', step=step, index=index):
14
+ lines = []
15
+ with sc_open(sdc) as f:
16
+ lines = f.read().splitlines()
17
+
18
+ # collect simple variables in case clock is specified with a variable
19
+ re_var = r"[A-Za-z0-9_]+"
20
+ re_num = r"[0-9\.]+"
21
+ sdc_vars = {}
22
+ for line in lines:
23
+ tcl_variable = re.findall(fr"^\s*set\s+({re_var})\s+({re_num}|\${re_var})", line)
24
+ if tcl_variable:
25
+ var_name, var_value = tcl_variable[0]
26
+ sdc_vars[f'${var_name}'] = var_value
27
+
28
+ # TODO: handle line continuations
29
+ for line in lines:
30
+ clock_period = re.findall(fr"create_clock\s.*-period\s+({re_num}|\${re_var})",
31
+ line)
32
+ if clock_period:
33
+ convert_period = clock_period[0]
34
+ while isinstance(convert_period, str) and convert_period[0] == "$":
35
+ if convert_period in sdc_vars:
36
+ convert_period = sdc_vars[convert_period]
37
+ else:
38
+ break
39
+ if isinstance(convert_period, str) and convert_period[0] == "$":
40
+ chip.logger.warning('Unable to identify clock period from '
41
+ f'{clock_period[0]}.')
42
+ continue
43
+ else:
44
+ try:
45
+ clock_period = float(convert_period)
46
+ except TypeError:
47
+ continue
48
+
49
+ clock_period = clock_period * clock_units_multiplier
50
+
51
+ if period is None:
52
+ period = clock_period
53
+ else:
54
+ period = min(period, clock_period)
55
+
56
+ if period is not None:
57
+ return period, None, [('input', 'constraint', 'sdc')]
58
+
59
+ if period is None:
60
+ keys = []
61
+ key_pin = None
62
+ # get clock information from defined clocks
63
+ for pin in chip.getkeys('datasheet', 'pin'):
64
+ for mode in chip.getkeys('datasheet', 'pin', pin, 'type'):
65
+ if chip.get('datasheet', 'pin', pin, 'type', mode) == 'clock':
66
+ clock_period = min(chip.get('datasheet', 'pin', pin, 'tperiod', mode)) * 1e9
67
+
68
+ if period is None:
69
+ period = clock_period
70
+ keys = [
71
+ ('datasheet', 'pin', pin, 'type', mode),
72
+ ('datasheet', 'pin', pin, 'tperiod', mode)
73
+ ]
74
+ key_pin = pin
75
+ else:
76
+ if clock_period < period:
77
+ period = clock_period
78
+ keys = [
79
+ ('datasheet', 'pin', pin, 'type', mode),
80
+ ('datasheet', 'pin', pin, 'tperiod', mode)
81
+ ]
82
+ key_pin = pin
83
+ return period, key_pin, keys
84
+
85
+ return None, None, []
86
+
87
+
88
+ def add_clock_requirements(chip):
89
+ _, _, keys = __get_clock_data(chip)
90
+
91
+ step = chip.get('arg', 'step')
92
+ index = chip.get('arg', 'index')
93
+ tool, task = get_tool_task(chip, step, index)
94
+ for key in keys:
95
+ chip.add('tool', tool, 'task', task, 'require', ','.join(key),
96
+ step=step, index=index)
97
+
98
+
99
+ def get_clock_period(chip, clock_units_multiplier=1):
100
+ period, name, _ = __get_clock_data(chip, clock_units_multiplier=clock_units_multiplier)
101
+ return name, period
@@ -0,0 +1,32 @@
1
+ '''
2
+ The primary objective of the PandA project is to develop a usable framework that will
3
+ enable the research of new ideas in the HW-SW Co-Design field.
4
+
5
+ The PandA framework includes methodologies supporting the research on high-level synthesis
6
+ of hardware accelerators, on parallelism extraction for embedded systems, on hardware/software
7
+ partitioning and mapping, on metrics for performance estimation of embedded software
8
+ applications and on dynamic reconfigurable devices.
9
+
10
+ Documentation: https://github.com/ferrandi/PandA-bambu
11
+
12
+ Sources: https://github.com/ferrandi/PandA-bambu
13
+
14
+ Installation: https://panda.dei.polimi.it/?page_id=88
15
+ '''
16
+
17
+ from siliconcompiler.tools.bambu import convert
18
+
19
+
20
+ ####################################################################
21
+ # Make Docs
22
+ ####################################################################
23
+ def make_docs(chip):
24
+ convert.setup(chip)
25
+ return chip
26
+
27
+
28
+ def parse_version(stdout):
29
+ # Long multiline output, but second-to-last line looks like:
30
+ # Version: PandA 0.9.6 - Revision 5e5e306b86383a7d85274d64977a3d71fdcff4fe-main
31
+ version_line = stdout.split('\n')[-3]
32
+ return version_line.split()[2]
@@ -1,9 +1,19 @@
1
1
  import os
2
+ import re
2
3
  import shutil
3
- from siliconcompiler import utils
4
+ from siliconcompiler.utils import sc_open
5
+ from siliconcompiler.tools._common.asic import set_tool_task_var, set_tool_task_lib_var, get_mainlib
6
+ from siliconcompiler.tools._common.asic_clock import get_clock_period, add_clock_requirements
4
7
  from siliconcompiler.tools._common import \
5
8
  add_frontend_requires, add_require_input, get_frontend_options, get_input_files, \
6
- get_tool_task, has_input_files
9
+ get_tool_task, has_input_files, record_metric
10
+
11
+
12
+ def make_docs(chip):
13
+ from siliconcompiler.targets import freepdk45_demo
14
+ chip.use(freepdk45_demo)
15
+ chip.input('<design>.c')
16
+ return setup(chip)
7
17
 
8
18
 
9
19
  def setup(chip):
@@ -11,13 +21,13 @@ def setup(chip):
11
21
  Performs high level synthesis to generate a verilog output
12
22
  '''
13
23
 
14
- if not has_input_files(chip, 'input', 'hll', 'c'):
15
- return "no files in [input,hll,c]"
24
+ if not has_input_files(chip, 'input', 'hll', 'c') and \
25
+ not has_input_files(chip, 'input', 'hll', 'llvm'):
26
+ return "no files in [input,hll,c] or [input,hll,llvm]"
16
27
 
17
- tool = 'bambu'
18
28
  step = chip.get('arg', 'step')
19
29
  index = chip.get('arg', 'index')
20
- _, task = get_tool_task(chip, step, index)
30
+ tool, task = get_tool_task(chip, step, index)
21
31
 
22
32
  # Standard Setup
23
33
  refdir = 'tools/' + tool
@@ -28,24 +38,41 @@ def setup(chip):
28
38
  chip.set('tool', tool, 'task', task, 'refdir', refdir,
29
39
  step=step, index=index,
30
40
  package='siliconcompiler', clobber=False)
31
- chip.set('tool', tool, 'task', task, 'threads', utils.get_cores(chip),
32
- step=step, index=index, clobber=False)
33
41
 
34
42
  # Input/Output requirements
35
43
  chip.add('tool', tool, 'task', task, 'output', chip.top() + '.v', step=step, index=index)
36
44
 
45
+ add_clock_requirements(chip)
46
+
37
47
  # Schema requirements
38
48
  add_require_input(chip, 'input', 'hll', 'c')
49
+ add_require_input(chip, 'input', 'hll', 'llvm')
39
50
  add_frontend_requires(chip, ['idir', 'define'])
40
51
 
52
+ set_tool_task_var(chip, 'device',
53
+ schelp="Device to use during bambu synthesis")
54
+ set_tool_task_lib_var(chip, 'memorychannels', default_value=1,
55
+ schelp="Number of memory channels available")
56
+
57
+ # Require clock conversion factor, from library units to ns
58
+ mainlib = get_mainlib(chip)
59
+ chip.add('tool', tool, 'task', task, 'require',
60
+ ','.join(['library', mainlib, 'option', 'var', 'bambu_clock_multiplier']),
61
+ step=step, index=index)
62
+
63
+ set_tool_task_var(chip, 'clock_multiplier',
64
+ schelp="Clock multiplier used to convert library units to ns")
65
+
41
66
 
42
67
  ################################
43
68
  # Custom runtime options
44
69
  ################################
45
70
  def runtime_options(chip):
46
- cmdlist = []
71
+ step = chip.get('arg', 'step')
72
+ index = chip.get('arg', 'index')
73
+ tool, task = get_tool_task(chip, step, index)
47
74
 
48
- cmdlist.append('--memory-allocation-policy=NO_BRAM')
75
+ cmdlist = []
49
76
 
50
77
  opts = get_frontend_options(chip, ['idir', 'define'])
51
78
 
@@ -55,11 +82,34 @@ def runtime_options(chip):
55
82
  cmdlist.append('-D' + value)
56
83
  for value in get_input_files(chip, 'input', 'hll', 'c'):
57
84
  cmdlist.append(value)
85
+ if not has_input_files(chip, 'input', 'hll', 'c'):
86
+ # Only use llvm if C is empty
87
+ for value in get_input_files(chip, 'input', 'hll', 'llvm'):
88
+ cmdlist.append(value)
58
89
 
90
+ cmdlist.append('--soft-float')
59
91
  cmdlist.append('--memory-allocation-policy=NO_BRAM')
60
92
 
61
- step = chip.get('arg', 'step')
62
- index = chip.get('arg', 'index')
93
+ mem_channels = int(chip.get('tool', tool, 'task', task, 'var', 'memorychannels',
94
+ step=step, index=index)[0])
95
+ if mem_channels > 0:
96
+ cmdlist.append(f'--channels-number={mem_channels}')
97
+
98
+ mainlib = get_mainlib(chip)
99
+ clock_multiplier = float(chip.get('library', mainlib, 'option', 'var',
100
+ 'bambu_clock_multiplier')[0])
101
+ clock_name, period = get_clock_period(chip, clock_units_multiplier=clock_multiplier)
102
+ if clock_name:
103
+ cmdlist.append(f'--clock-name={clock_name}')
104
+ if period:
105
+ cmdlist.append(f'--clock-period={period}')
106
+
107
+ cmdlist.append('--disable-function-proxy')
108
+
109
+ device = chip.get('tool', tool, 'task', task, 'var', 'device',
110
+ step=step, index=index)
111
+ if device:
112
+ cmdlist.append(f'--device={device[0]}')
63
113
 
64
114
  cmdlist.append(f'--top-fname={chip.top(step, index)}')
65
115
 
@@ -76,3 +126,34 @@ def post_process(chip):
76
126
  index = chip.get('arg', 'index')
77
127
 
78
128
  shutil.copy2(f'{chip.top(step, index)}.v', os.path.join('outputs', f'{chip.top()}.v'))
129
+
130
+ ff = re.compile(fr"Total number of flip-flops in function {chip.top(step, index)}: (\d+)")
131
+ area = re.compile(r"Total estimated area: (\d+)")
132
+ fmax = re.compile(r"Estimated max frequency \(MHz\): (\d+\.?\d*)")
133
+ slack = re.compile(r"Minimum slack: (\d+\.?\d*)")
134
+
135
+ log_file = f"{step}.log"
136
+ with sc_open(log_file) as log:
137
+ for line in log:
138
+ ff_match = ff.findall(line)
139
+ area_match = area.findall(line)
140
+ fmax_match = fmax.findall(line)
141
+ slack_match = slack.findall(line)
142
+ if ff_match:
143
+ record_metric(chip, step, index, "registers", int(ff_match[0]), log_file)
144
+ if area_match:
145
+ record_metric(chip, step, index, "cellarea", float(area_match[0]), log_file,
146
+ source_unit='um^2')
147
+ if fmax_match:
148
+ record_metric(chip, step, index, "fmax", float(fmax_match[0]), log_file,
149
+ source_unit='MHz')
150
+ if slack_match:
151
+ slack_ns = float(slack_match[0])
152
+ if slack_ns >= 0:
153
+ record_metric(chip, step, index, "setupwns", 0, log_file,
154
+ source_unit='ns')
155
+ else:
156
+ record_metric(chip, step, index, "setupwns", slack_ns, log_file,
157
+ source_unit='ns')
158
+ record_metric(chip, step, index, "setupslack", slack_ns, log_file,
159
+ source_unit='ns')
@@ -0,0 +1,35 @@
1
+ '''
2
+ Bluespec is a high-level hardware description language. It has a variety of
3
+ advanced features including a powerful type system that can prevent errors
4
+ prior to synthesis time, and its most distinguishing feature, Guarded Atomic
5
+ Actions, allow you to define hardware components in a modular manner based
6
+ on their invariants, and let the compiler pick a scheduler.
7
+
8
+ Documentation: https://github.com/B-Lang-org/bsc#documentation
9
+
10
+ Sources: https://github.com/B-Lang-org/bsc
11
+
12
+ Installation: https://github.com/B-Lang-org/bsc#download
13
+ '''
14
+
15
+ from siliconcompiler.tools.bluespec import convert
16
+
17
+
18
+ ####################################################################
19
+ # Make Docs
20
+ ####################################################################
21
+ def make_docs(chip):
22
+ convert.setup(chip)
23
+ return chip
24
+
25
+
26
+ ################################
27
+ # Setup Tool (pre executable)
28
+ ################################
29
+ def parse_version(stdout):
30
+ # Examples:
31
+ # Bluespec Compiler, version 2021.12.1-27-g9a7d5e05 (build 9a7d5e05)
32
+ # Bluespec Compiler, version 2021.07 (build 4cac6eba)
33
+
34
+ long_version = stdout.split()[3]
35
+ return long_version.split('-')[0]
@@ -8,6 +8,7 @@ from siliconcompiler import sc_open
8
8
 
9
9
  # Directory inside step/index dir to store bsc intermediate results.
10
10
  VLOG_DIR = 'verilog'
11
+ BSC_DIR = 'bluespec'
11
12
 
12
13
 
13
14
  def setup(chip):
@@ -39,6 +40,7 @@ def setup(chip):
39
40
 
40
41
  # Input/Output requirements
41
42
  chip.add('tool', tool, 'task', task, 'output', chip.top() + '.v', step=step, index=index)
43
+ chip.add('tool', tool, 'task', task, 'output', chip.top() + '.dot', step=step, index=index)
42
44
 
43
45
  # Schema requirements
44
46
  add_require_input(chip, 'input', 'hll', 'bsv')
@@ -50,9 +52,10 @@ def setup(chip):
50
52
  ################################
51
53
  def pre_process(chip):
52
54
  # bsc requires its output directory exists before being called.
53
- if os.path.isdir(VLOG_DIR):
54
- shutil.rmtree(VLOG_DIR)
55
- os.makedirs(VLOG_DIR)
55
+ for path in (VLOG_DIR, BSC_DIR):
56
+ if os.path.isdir(path):
57
+ shutil.rmtree(path)
58
+ os.makedirs(path)
56
59
 
57
60
 
58
61
  ################################
@@ -68,7 +71,13 @@ def runtime_options(chip):
68
71
 
69
72
  cmdlist.append('-verilog')
70
73
  cmdlist.append(f'-vdir {VLOG_DIR}')
74
+ cmdlist.append(f'-bdir {BSC_DIR}')
75
+ cmdlist.append('-info-dir reports')
71
76
  cmdlist.append('-u')
77
+ cmdlist.append('-v')
78
+
79
+ cmdlist.append('-show-module-use')
80
+ cmdlist.append('-sched-dot')
72
81
 
73
82
  cmdlist.append(f'-g {chip.top(step, index)}')
74
83
 
@@ -95,10 +104,40 @@ def post_process(chip):
95
104
  ''' Tool specific function to run after step execution
96
105
  '''
97
106
 
107
+ step = chip.get('arg', 'step')
108
+ index = chip.get('arg', 'index')
109
+
110
+ shutil.copyfile(f"reports/{chip.top(step, index)}_combined_full.dot",
111
+ f"outputs/{chip.top()}.dot")
112
+
113
+ extra_modules = set()
114
+ use_file = os.path.join(VLOG_DIR, f"{chip.top(step, index)}.use")
115
+ if os.path.exists(use_file):
116
+ BSC_BASE = os.path.dirname(
117
+ os.path.dirname(
118
+ chip.get('record', 'toolpath', step=step, index=index)))
119
+ BSC_LIB = os.path.join(BSC_BASE, "lib", "Verilog")
120
+
121
+ with sc_open(use_file) as f:
122
+ for module in f:
123
+ module = module.strip()
124
+ mod_path = os.path.join(BSC_LIB, f"{module}.v")
125
+ if os.path.exists(mod_path):
126
+ extra_modules.add(mod_path)
127
+ else:
128
+ chip.logger.warn(f"Unable to find module {module} source files at: {BSC_LIB}")
129
+
98
130
  # bsc outputs each compiled module to its own Verilog file, so we
99
131
  # concatenate them all to create a pickled output we can pass along.
100
132
  design = chip.top()
101
133
  with open(os.path.join('outputs', f'{design}.v'), 'w') as pickled_vlog:
102
134
  for src in os.listdir(VLOG_DIR):
103
- with sc_open(os.path.join(VLOG_DIR, src)) as vlog_mod:
104
- pickled_vlog.write(vlog_mod.read())
135
+ if src.endswith(".v"):
136
+ with sc_open(os.path.join(VLOG_DIR, src)) as vlog_mod:
137
+ pickled_vlog.write(vlog_mod.read())
138
+
139
+ pickled_vlog.write("\n")
140
+ pickled_vlog.write("// Bluespec imports\n\n")
141
+ for vfile in extra_modules:
142
+ with sc_open(os.path.join(BSC_LIB, vfile)) as vlog_mod:
143
+ pickled_vlog.write(vlog_mod.read() + "\n")
@@ -0,0 +1,12 @@
1
+ '''
2
+ Graphviz is open source graph visualization software.
3
+ Graph visualization is a way of representing structural information as diagrams
4
+ of abstract graphs and networks.
5
+ It has important applications in networking, bioinformatics, software engineering,
6
+ database and web design, machine learning, and in visual interfaces for other
7
+ technical domains.
8
+ '''
9
+
10
+
11
+ def make_docs(chip):
12
+ return chip
@@ -0,0 +1,48 @@
1
+ import graphviz
2
+ import os
3
+
4
+ from siliconcompiler import sc_open
5
+ from siliconcompiler.tools._common import get_tool_task
6
+
7
+
8
+ def setup(chip):
9
+ '''
10
+ Generate a screenshot of a dot file
11
+ '''
12
+
13
+ step = chip.get('arg', 'step')
14
+ index = chip.get('arg', 'index')
15
+ tool, task = get_tool_task(chip, step, index)
16
+
17
+ chip.set('tool', tool, 'task', task, 'threads', 1, step=step, index=index)
18
+
19
+ chip.add('tool', tool, 'task', task, 'output', chip.top() + '.png', step=step, index=index)
20
+
21
+
22
+ def run(chip):
23
+ step = chip.get('arg', 'step')
24
+ index = chip.get('arg', 'index')
25
+ tool, task = get_tool_task(chip, step, index)
26
+
27
+ if os.path.exists(f'inputs/{chip.top()}.dot'):
28
+ file = f'inputs/{chip.top()}.dot'
29
+ elif os.path.exists(f'inputs/{chip.top()}.xdot'):
30
+ file = f'inputs/{chip.top()}.xdot'
31
+ elif chip.valid('tool', tool, 'task', task, 'var', 'show_filepath') and \
32
+ chip.get('tool', tool, 'task', task, 'var', 'show_filepath', step=step, index=index):
33
+ file = chip.get('tool', tool, 'task', task, 'var', 'show_filepath',
34
+ step=step, index=index)[0]
35
+ else:
36
+ file = chip.find_files('input', 'image', 'dot', step=step, index=index)[0]
37
+
38
+ with sc_open(file) as dot:
39
+ dot_content = dot.read()
40
+
41
+ try:
42
+ dot = graphviz.Source(dot_content, format="png")
43
+ dot.render(filename=f"outputs/{chip.top()}", cleanup=True)
44
+ pass
45
+ except graphviz.ExecutableNotFound:
46
+ return 1
47
+
48
+ return 0
@@ -0,0 +1,20 @@
1
+ from PIL import Image
2
+ from siliconcompiler.tools.graphviz import screenshot
3
+
4
+
5
+ def setup(chip):
6
+ '''
7
+ Show a graphviz dot file
8
+ '''
9
+
10
+ screenshot.setup(chip)
11
+
12
+
13
+ def run(chip):
14
+ screenshot_ret = screenshot.run(chip)
15
+ if screenshot_ret != 0:
16
+ return screenshot_ret
17
+
18
+ Image.open(f"outputs/{chip.top()}.png").show()
19
+
20
+ return 0
@@ -128,6 +128,8 @@ def extract_metrics(chip):
128
128
  "drvs": [
129
129
  "timing/drv_violators.rpt",
130
130
  "floating_nets.rpt",
131
+ "overdriven_nets.rpt",
132
+ "overdriven_nets_with_parallel.rpt",
131
133
  f"{chip.design}_antenna.rpt",
132
134
  f"{chip.design}_antenna_post_repair.rpt"
133
135
  ],
@@ -148,6 +150,10 @@ def extract_metrics(chip):
148
150
 
149
151
  metrics_file = "reports/metrics.json"
150
152
 
153
+ if not os.path.exists(metrics_file):
154
+ chip.logger.warning("OpenROAD metrics file is missing")
155
+ return
156
+
151
157
  def get_metric_sources(metric):
152
158
  metric_sources = [metrics_file]
153
159
  if metric in metric_reports:
@@ -277,6 +283,10 @@ def extract_metrics(chip):
277
283
  'sc__metric__timing__drv__max_slew',
278
284
  'sc__metric__timing__drv__max_cap',
279
285
  'sc__metric__timing__drv__max_fanout',
286
+ 'sc__metric__timing__drv__max_fanout',
287
+ 'sc__metric__timing__drv__floating__nets',
288
+ 'sc__metric__timing__drv__floating__pins',
289
+ 'sc__metric__timing__drv__overdriven__nets',
280
290
  'sc__metric__antenna__violating__nets',
281
291
  'sc__metric__antenna__violating__pins']:
282
292
  if metric in metrics:
@@ -572,6 +582,13 @@ def define_rsz_params(chip):
572
582
  default_value='100',
573
583
  schelp='percentage of violating nets to attempt to repair (0 - 100)')
574
584
 
585
+ set_tool_task_var(chip, param_key='rsz_skip_recover_power',
586
+ default_value=False,
587
+ schelp='skip power recovery')
588
+ set_tool_task_var(chip, param_key='rsz_recover_power',
589
+ default_value=100,
590
+ schelp='percentage of paths to attempt to recover power (0 - 100)')
591
+
575
592
  step = chip.get('arg', 'step')
576
593
  index = chip.get('arg', 'index')
577
594
  tool, task = get_tool_task(chip, step, index)
@@ -43,7 +43,6 @@ def setup(chip):
43
43
  'hold',
44
44
  'unconstrained',
45
45
  'clock_skew',
46
- 'power',
47
46
  'drv_violations',
48
47
  'fmax',
49
48
 
@@ -1,5 +1,5 @@
1
1
  from siliconcompiler.tools._common import input_provides, add_common_file, get_tool_task
2
- from siliconcompiler.tools._common.asic import set_tool_task_var
2
+ from siliconcompiler.tools._common.asic import set_tool_task_var, get_mainlib
3
3
 
4
4
  from siliconcompiler.tools.openroad._apr import setup as apr_setup
5
5
  from siliconcompiler.tools.openroad._apr import set_reports, set_pnr_inputs, set_pnr_outputs
@@ -74,6 +74,8 @@ def setup(chip):
74
74
  'power'
75
75
  ])
76
76
 
77
+ mainlib = get_mainlib(chip)
78
+
77
79
  # Setup required
78
80
  for component in chip.getkeys('constraint', 'component'):
79
81
  for key in chip.getkeys('constraint', 'component', component):
@@ -92,6 +94,10 @@ def setup(chip):
92
94
  chip.add('tool', tool, 'task', task, 'require',
93
95
  ','.join(['constraint', ifp]),
94
96
  step=step, index=index)
97
+ if chip.valid('library', mainlib, 'option', 'file', 'openroad_tracks'):
98
+ chip.add('tool', tool, 'task', task, 'require',
99
+ ','.join(['library', mainlib, 'option', 'file', 'openroad_tracks']),
100
+ step=step, index=index)
95
101
 
96
102
 
97
103
  def pre_process(chip):
@@ -40,10 +40,18 @@ def setup(chip):
40
40
 
41
41
  set_reports(chip, [
42
42
  'setup',
43
- 'unconstrained',
44
- 'power'
43
+ 'unconstrained'
45
44
  ])
46
45
 
46
+ chip.set('tool', tool, 'task', task, 'file', 'rtlmp_constraints',
47
+ 'contraints script for macro placement',
48
+ field='help')
49
+
50
+ if chip.get('tool', tool, 'task', task, 'file', 'rtlmp_constraints', step=step, index=index):
51
+ chip.add('tool', tool, 'task', task, 'require',
52
+ ",".join(['tool', tool, 'task', task, 'file', 'rtlmp_constraints']),
53
+ step=step, index=index)
54
+
47
55
 
48
56
  def pre_process(chip):
49
57
  step = chip.get('arg', 'step')
@@ -38,7 +38,6 @@ def setup(chip):
38
38
  set_reports(chip, [
39
39
  'setup',
40
40
  'unconstrained',
41
- 'power',
42
41
 
43
42
  # Images
44
43
  'placement_density',
@@ -1,6 +1,7 @@
1
1
  from siliconcompiler import NodeStatus
2
2
 
3
3
  from siliconcompiler.tools._common import get_tool_task, has_pre_post_script
4
+ from siliconcompiler.tools._common.asic import set_tool_task_var
4
5
 
5
6
  from siliconcompiler.tools.openroad._apr import setup as apr_setup
6
7
  from siliconcompiler.tools.openroad._apr import set_reports, set_pnr_inputs, set_pnr_outputs
@@ -39,6 +40,11 @@ def setup(chip):
39
40
  define_pdn_params(chip)
40
41
  define_psm_params(chip)
41
42
 
43
+ set_tool_task_var(chip, param_key='fixed_pin_keepout',
44
+ default_value=0,
45
+ schelp='if > 0, applies a blockage in multiples of the routing pitch '
46
+ 'to each fixed pin to ensure there is room for routing.')
47
+
42
48
  set_reports(chip, [])
43
49
 
44
50
 
@@ -91,5 +91,6 @@ if { [llength $openroad_dont_touch] > 0 } {
91
91
  # set don't touch list
92
92
  set_dont_touch $openroad_dont_touch
93
93
  }
94
- tee -file reports/dont_touch.start.rpt {report_dont_touch}
95
- tee -file reports/dont_use.start.rpt {report_dont_use}
94
+ tee -quiet -file reports/dont_touch.start.rpt {report_dont_touch}
95
+ tee -quiet -file reports/dont_use.start.rpt {report_dont_use}
96
+ tee -file reports/global_connections.start.rpt {report_global_connect}
@@ -43,6 +43,8 @@ if { [llength [all_clocks]] > 0 } {
43
43
  -distance_between_buffers $cts_distance_between_buffers \
44
44
  {*}$sc_cts_arguments
45
45
 
46
+ tee -file reports/cts.rpt {report_cts}
47
+
46
48
  set_propagated_clock [all_clocks]
47
49
 
48
50
  estimate_parasitics -placement
@@ -15,6 +15,8 @@ source -echo "$sc_refdir/apr/preamble.tcl"
15
15
  # Detailed Routing
16
16
  ###############################
17
17
 
18
+ sc_setup_detailed_route
19
+
18
20
  set drt_arguments []
19
21
  if { [lindex [sc_cfg_tool_task_get {var} drt_disable_via_gen] 0] == "true" } {
20
22
  lappend drt_arguments "-disable_via_gen"