siliconcompiler 0.28.4__py3-none-any.whl → 0.28.6__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 (43) hide show
  1. siliconcompiler/_metadata.py +1 -1
  2. siliconcompiler/apps/_common.py +88 -56
  3. siliconcompiler/apps/sc.py +33 -14
  4. siliconcompiler/apps/sc_dashboard.py +16 -9
  5. siliconcompiler/apps/sc_show.py +17 -15
  6. siliconcompiler/apps/utils/summarize.py +47 -0
  7. siliconcompiler/core.py +20 -12
  8. siliconcompiler/flows/drcflow.py +13 -0
  9. siliconcompiler/flows/interposerflow.py +17 -0
  10. siliconcompiler/libs/interposer.py +8 -0
  11. siliconcompiler/pdks/interposer.py +8 -0
  12. siliconcompiler/remote/schema.py +11 -1
  13. siliconcompiler/remote/server.py +7 -2
  14. siliconcompiler/report/dashboard/__init__.py +10 -3
  15. siliconcompiler/scheduler/__init__.py +93 -0
  16. siliconcompiler/schema/schema_cfg.py +15 -3
  17. siliconcompiler/schema/schema_obj.py +51 -1
  18. siliconcompiler/targets/interposer_demo.py +56 -0
  19. siliconcompiler/templates/tcl/manifest.tcl.j2 +2 -0
  20. siliconcompiler/tools/klayout/export.py +7 -4
  21. siliconcompiler/tools/klayout/klayout_export.py +3 -0
  22. siliconcompiler/tools/klayout/klayout_utils.py +8 -2
  23. siliconcompiler/tools/openroad/metrics.py +44 -0
  24. siliconcompiler/tools/openroad/openroad.py +3 -0
  25. siliconcompiler/tools/openroad/rdlroute.py +97 -0
  26. siliconcompiler/tools/openroad/scripts/sc_apr.tcl +20 -22
  27. siliconcompiler/tools/openroad/scripts/sc_metrics.tcl +0 -169
  28. siliconcompiler/tools/openroad/scripts/sc_rdlroute.tcl +184 -0
  29. siliconcompiler/tools/openroad/scripts/sc_report.tcl +170 -0
  30. siliconcompiler/tools/opensta/scripts/sc_report_libraries.tcl +11 -1
  31. siliconcompiler/tools/xyce/__init__.py +1 -1
  32. siliconcompiler/toolscripts/_tools.json +3 -4
  33. siliconcompiler/toolscripts/rhel8/install-xyce.sh +4 -5
  34. siliconcompiler/toolscripts/rhel9/install-xyce.sh +4 -5
  35. siliconcompiler/toolscripts/ubuntu20/install-xyce.sh +5 -5
  36. siliconcompiler/toolscripts/ubuntu22/install-xyce.sh +2 -2
  37. siliconcompiler/toolscripts/ubuntu24/install-xyce.sh +2 -2
  38. {siliconcompiler-0.28.4.dist-info → siliconcompiler-0.28.6.dist-info}/METADATA +14 -12
  39. {siliconcompiler-0.28.4.dist-info → siliconcompiler-0.28.6.dist-info}/RECORD +43 -33
  40. {siliconcompiler-0.28.4.dist-info → siliconcompiler-0.28.6.dist-info}/WHEEL +1 -1
  41. {siliconcompiler-0.28.4.dist-info → siliconcompiler-0.28.6.dist-info}/LICENSE +0 -0
  42. {siliconcompiler-0.28.4.dist-info → siliconcompiler-0.28.6.dist-info}/entry_points.txt +0 -0
  43. {siliconcompiler-0.28.4.dist-info → siliconcompiler-0.28.6.dist-info}/top_level.txt +0 -0
@@ -688,7 +688,9 @@ def _makecmd(chip, tool, task, step, index, script_name='replay.sh', include_pat
688
688
  runtime_options = getattr(chip._get_tool_module(step, index), 'runtime_options', None)
689
689
  if runtime_options:
690
690
  try:
691
+ chip.schema._start_record_access()
691
692
  cmdlist.extend(parse_options(runtime_options(chip)))
693
+ chip.schema._stop_record_access()
692
694
  except Exception as e:
693
695
  chip.logger.error(f'Failed to get runtime options for {tool}/{task}')
694
696
  raise e
@@ -983,7 +985,9 @@ def _post_process(chip, step, index):
983
985
  func = getattr(chip._get_task_module(step, index, flow=flow), 'post_process', None)
984
986
  if func:
985
987
  try:
988
+ chip.schema._start_record_access()
986
989
  func(chip)
990
+ chip.schema._stop_record_access()
987
991
  except Exception as e:
988
992
  chip.logger.error(f'Failed to run post-process for {tool}/{task}.')
989
993
  print_traceback(chip, e)
@@ -1076,7 +1080,9 @@ def _pre_process(chip, step, index):
1076
1080
  func = getattr(chip._get_task_module(step, index, flow=flow), 'pre_process', None)
1077
1081
  if func:
1078
1082
  try:
1083
+ chip.schema._start_record_access()
1079
1084
  func(chip)
1085
+ chip.schema._stop_record_access()
1080
1086
  except Exception as e:
1081
1087
  chip.logger.error(f"Pre-processing failed for '{tool}/{task}'.")
1082
1088
  raise e
@@ -1088,6 +1094,8 @@ def _pre_process(chip, step, index):
1088
1094
  def _set_env_vars(chip, step, index):
1089
1095
  flow = chip.get('option', 'flow')
1090
1096
  tool, task = get_tool_task(chip, step, index, flow)
1097
+
1098
+ chip.schema._start_record_access()
1091
1099
  # License file configuration.
1092
1100
  for item in chip.getkeys('tool', tool, 'licenseserver'):
1093
1101
  license_file = chip.get('tool', tool, 'licenseserver', item, step=step, index=index)
@@ -1100,6 +1108,8 @@ def _set_env_vars(chip, step, index):
1100
1108
  if val:
1101
1109
  os.environ[item] = val
1102
1110
 
1111
+ chip.schema._stop_record_access()
1112
+
1103
1113
 
1104
1114
  def _check_tool_version(chip, step, index, run_func=None):
1105
1115
  '''
@@ -1191,6 +1201,9 @@ def _hash_files(chip, step, index, setup=False):
1191
1201
 
1192
1202
 
1193
1203
  def _finalizenode(chip, step, index, replay):
1204
+ if chip.schema._do_record_access():
1205
+ assert_required_accesses(chip, step, index)
1206
+
1194
1207
  flow = chip.get('option', 'flow')
1195
1208
  tool, task = get_tool_task(chip, step, index, flow)
1196
1209
  quiet = (
@@ -1286,6 +1299,86 @@ def assert_output_files(chip, step, index):
1286
1299
  chip=chip)
1287
1300
 
1288
1301
 
1302
+ def assert_required_accesses(chip, step, index):
1303
+ flow = chip.get('option', 'flow')
1304
+ jobname = chip.get('option', 'jobname')
1305
+ tool, task = get_tool_task(chip, step, index, flow)
1306
+
1307
+ if tool == 'builtin':
1308
+ return
1309
+
1310
+ gets = chip.schema._get_record_access()
1311
+ logfile = os.path.join(
1312
+ chip.getworkdir(jobname=jobname, step=step, index=index),
1313
+ f'{step}.log')
1314
+
1315
+ with sc_open(logfile) as f:
1316
+ for line in f:
1317
+ if line.startswith(Schema._RECORD_ACCESS_IDENTIFIER):
1318
+ key = line[len(Schema._RECORD_ACCESS_IDENTIFIER):].strip().split(',')
1319
+ if chip.valid(*key, check_complete=True):
1320
+ gets.add(tuple(key))
1321
+
1322
+ def get_value(*key):
1323
+ if chip.get(*key, field='pernode') == 'never':
1324
+ return chip.get(*key)
1325
+ else:
1326
+ return chip.get(*key, step=step, index=index)
1327
+
1328
+ getkeys = set()
1329
+ # Remove keys with empty values
1330
+ for key in set(sorted(gets)):
1331
+ if get_value(*key):
1332
+ getkeys.add(key)
1333
+
1334
+ # Remove keys that dont matter
1335
+ exempt = [
1336
+ ('design',),
1337
+ ('arg', 'step'), ('arg', 'index'),
1338
+ ('option', 'jobname'), ('option', 'flow'), ('option', 'strict'), ('option', 'builddir'),
1339
+ ('option', 'quiet'),
1340
+ ('tool', tool, 'exe'),
1341
+ ('tool', tool, 'task', task, 'require'),
1342
+ ('tool', tool, 'task', task, 'threads'),
1343
+ ('flowgraph', flow, step, index, 'tool'), ('flowgraph', flow, step, index, 'task'),
1344
+ ('flowgraph', flow, step, index, 'taskmodule')]
1345
+ for key in chip.getkeys('metric'):
1346
+ exempt.append(('metric', key))
1347
+ for key in chip.getkeys('tool', tool, 'task', task, 'report'):
1348
+ exempt.append(('tool', tool, 'task', task, 'report', key))
1349
+
1350
+ # Get exempted keys from task
1351
+ func = getattr(chip._get_task_module(step, index, flow=flow), 'exempt_keys', None)
1352
+ if func:
1353
+ # No need for try / except since this must work properly
1354
+ exempt.extend(func(chip))
1355
+
1356
+ required = set(
1357
+ [tuple(key.split(',')) for key in chip.get('tool', tool, 'task', task, 'require',
1358
+ step=step, index=index)])
1359
+
1360
+ for key in set(exempt):
1361
+ if key in getkeys:
1362
+ getkeys.remove(key)
1363
+ if key in required:
1364
+ required.remove(key)
1365
+
1366
+ excess_require = required.difference(getkeys)
1367
+ if True:
1368
+ for key in sorted(excess_require):
1369
+ chip.logger.error(f"{step}{index} does not require requirement: {','.join(key)}")
1370
+ missing_require = getkeys.difference(required)
1371
+ for key in sorted(missing_require):
1372
+ chip.logger.error(f"{step}{index} has an unexpressed requirement: "
1373
+ f"{','.join(key)} = {get_value(*key)}")
1374
+
1375
+ if missing_require:
1376
+ raise SiliconCompilerError(
1377
+ f'Requirements for {step}{index} does not match access list: '
1378
+ f'{", ".join([",".join(key) for key in sorted(missing_require)])}',
1379
+ chip=chip)
1380
+
1381
+
1289
1382
  def _reset_flow_nodes(chip, flow, nodes_to_execute):
1290
1383
  # Reset flowgraph/records/metrics by probing build directory. We need
1291
1384
  # to set values to None for steps we may re-run so that merging
@@ -10,7 +10,7 @@ try:
10
10
  except ImportError:
11
11
  from siliconcompiler.schema.utils import trim
12
12
 
13
- SCHEMA_VERSION = '0.48.2'
13
+ SCHEMA_VERSION = '0.48.4'
14
14
 
15
15
  #############################################################################
16
16
  # PARAM DEFINITION
@@ -1252,7 +1252,6 @@ def schema_datasheet(cfg, name='default', mode='default'):
1252
1252
  # Package Description
1253
1253
  #########################
1254
1254
 
1255
- # high level description
1256
1255
  scparam(cfg, ['datasheet', 'package', name, 'type'],
1257
1256
  sctype='enum',
1258
1257
  enum=['bga', 'lga', 'csp', 'qfn', 'qfp', 'sop', 'die', 'wafer'],
@@ -1263,6 +1262,16 @@ def schema_datasheet(cfg, name='default', mode='default'):
1263
1262
  "api: chip.set('datasheet', 'package', 'abcd', 'type', 'bga')"],
1264
1263
  schelp="""Package type specified on a named package basis.""")
1265
1264
 
1265
+ scparam(cfg, ['datasheet', 'package', name, 'footprint'],
1266
+ sctype='str',
1267
+ shorthelp="Datasheet: package footprint",
1268
+ switch="-datasheet_package_footprint 'name <str>'",
1269
+ example=[
1270
+ "cli: -datasheet_package_footprint 'abcd soic8'",
1271
+ "api: chip.set('datasheet', 'package', 'abcd', 'footprint', 'soic8')"],
1272
+ schelp="""Package footprint name. The name of the footprint can be a standard
1273
+ footprint name or a reference designator from a footprint library.""")
1274
+
1266
1275
  scparam(cfg, ['datasheet', 'package', name, 'drawing'],
1267
1276
  sctype='[file]',
1268
1277
  shorthelp="Datasheet: package drawing",
@@ -2158,7 +2167,10 @@ def schema_metric(cfg, step='default', index='default'):
2158
2167
  device families.""")
2159
2168
 
2160
2169
  metrics = {'cellarea': 'cell area (ignoring fillers)',
2161
- 'totalarea': 'physical die area'}
2170
+ 'totalarea': 'physical die area',
2171
+ 'macroarea': 'macro cell area',
2172
+ 'padcellarea': 'io pad cell area',
2173
+ 'stdcellarea': 'standard cell area'}
2162
2174
 
2163
2175
  for item, val in metrics.items():
2164
2176
  scparam(cfg, ['metric', item],
@@ -61,6 +61,8 @@ class Schema:
61
61
  logger (logging.Logger): instance of the parent logger if available
62
62
  """
63
63
 
64
+ _RECORD_ACCESS_IDENTIFIER = "SC_CFG_ACCESS_KEY"
65
+
64
66
  # Special key in node dict that represents a value corresponds to a
65
67
  # global default for all steps/indices.
66
68
  GLOBAL_KEY = 'global'
@@ -70,6 +72,9 @@ class Schema:
70
72
  if cfg is not None and manifest is not None:
71
73
  raise ValueError('You may not specify both cfg and manifest')
72
74
 
75
+ # Use during testing to record calls to Schema.get
76
+ self._init_record_access()
77
+
73
78
  self._init_logger(logger)
74
79
 
75
80
  self._stop_journal()
@@ -256,6 +261,10 @@ class Schema:
256
261
 
257
262
  See :meth:`~siliconcompiler.core.Chip.get` for detailed documentation.
258
263
  """
264
+
265
+ if self.__record_access["recording"]:
266
+ self.__record_access["record"].add(tuple(keypath))
267
+
259
268
  # Prevent accidental modifications of the schema content by not passing a reference
260
269
  return copy.copy(self.__get(*keypath, field=field, job=job, step=step, index=index))
261
270
 
@@ -1087,7 +1096,9 @@ class Schema:
1087
1096
 
1088
1097
  if template:
1089
1098
  fout.write(template.render(manifest_dict='\n'.join(tcl_set_cmds),
1090
- scroot=os.path.abspath(PACKAGE_ROOT)))
1099
+ scroot=os.path.abspath(PACKAGE_ROOT),
1100
+ record_access=self._do_record_access(),
1101
+ record_access_id=Schema._RECORD_ACCESS_IDENTIFIER))
1091
1102
  else:
1092
1103
  for cmd in tcl_set_cmds:
1093
1104
  fout.write(cmd + '\n')
@@ -1305,6 +1316,45 @@ class Schema:
1305
1316
  except Exception as e:
1306
1317
  self.logger.error(f'Exception: {e}')
1307
1318
 
1319
+ #######################################
1320
+ def _do_record_access(self):
1321
+ '''
1322
+ Determine if Schema should record calls to .get
1323
+ '''
1324
+ return False
1325
+
1326
+ #######################################
1327
+ def _init_record_access(self):
1328
+ '''
1329
+ Initialize record access data record
1330
+ '''
1331
+ self.__record_access = {
1332
+ "do": self._do_record_access(),
1333
+ "recording": False,
1334
+ "record": set()
1335
+ }
1336
+
1337
+ #######################################
1338
+ def _start_record_access(self):
1339
+ '''
1340
+ Start recording calls to .get
1341
+ '''
1342
+ self.__record_access["recording"] = True
1343
+
1344
+ #######################################
1345
+ def _stop_record_access(self):
1346
+ '''
1347
+ Stop recording calls to .get
1348
+ '''
1349
+ self.__record_access["recording"] = False
1350
+
1351
+ #######################################
1352
+ def _get_record_access(self):
1353
+ '''
1354
+ Return calls to record_access
1355
+ '''
1356
+ return self.__record_access["record"].copy()
1357
+
1308
1358
  #######################################
1309
1359
  def get_default(self, *keypath):
1310
1360
  '''Returns default value of a parameter.
@@ -0,0 +1,56 @@
1
+ from siliconcompiler import Chip
2
+ from siliconcompiler.flows import interposerflow, drcflow
3
+
4
+ from lambdapdk import interposer
5
+ from lambdapdk.interposer.libs import bumps
6
+
7
+
8
+ ####################################################
9
+ # Target Setup
10
+ ####################################################
11
+ def setup(chip):
12
+ '''
13
+ Interposer Demo Target
14
+ '''
15
+
16
+ # 1. Load PDK, flow, libs
17
+ chip.use(interposer)
18
+ chip.use(bumps)
19
+ chip.use(interposerflow)
20
+ chip.use(drcflow)
21
+
22
+ # 2. Set default targets
23
+ chip.set('option', 'flow', 'interposerflow', clobber=False)
24
+ chip.set('option', 'pdk', 'interposer', clobber=False)
25
+ chip.set('option', 'stackup', '3ML_0400', clobber=False)
26
+ chip.set('option', 'var', 'openroad_libtype', 'none', clobber=False)
27
+ chip.set('option', 'var', 'klayout_libtype', 'none', clobber=False)
28
+
29
+ # 3. Set project specific design choices
30
+ chip.set('asic', 'macrolib', 'interposer_bumps', clobber=False)
31
+
32
+ # 4. get project specific design choices
33
+ chip.set('asic', 'delaymodel', 'nldm', clobber=False)
34
+
35
+ # 5. Timing corners
36
+ chip.set('constraint', 'timing', 'slow', 'libcorner', 'slow', clobber=False)
37
+ chip.set('constraint', 'timing', 'slow', 'pexcorner', 'maximum', clobber=False)
38
+ chip.set('constraint', 'timing', 'slow', 'mode', 'func', clobber=False)
39
+ chip.set('constraint', 'timing', 'slow', 'check', ['setup', 'hold'], clobber=False)
40
+
41
+ chip.set('constraint', 'timing', 'fast', 'libcorner', 'fast', clobber=False)
42
+ chip.set('constraint', 'timing', 'fast', 'pexcorner', 'minimum', clobber=False)
43
+ chip.set('constraint', 'timing', 'fast', 'mode', 'func', clobber=False)
44
+ chip.set('constraint', 'timing', 'fast', 'check', ['setup', 'hold'], clobber=False)
45
+
46
+ chip.set('constraint', 'timing', 'typical', 'libcorner', 'typ', clobber=False)
47
+ chip.set('constraint', 'timing', 'typical', 'pexcorner', 'typical', clobber=False)
48
+ chip.set('constraint', 'timing', 'typical', 'mode', 'func', clobber=False)
49
+ chip.set('constraint', 'timing', 'typical', 'check', ['setup', 'hold'], clobber=False)
50
+
51
+
52
+ #########################
53
+ if __name__ == "__main__":
54
+ target = Chip('<target>')
55
+ setup(target)
56
+ target.write_manifest('interposer_demo.json')
@@ -16,6 +16,8 @@ proc sc_cfg_get { args } {
16
16
  # Refer to global sc_cfg dictionary
17
17
  global sc_cfg
18
18
 
19
+ {% if record_access %}puts "{{ record_access_id }} [join $args ,]"{% endif %}
20
+
19
21
  if { ![sc_cfg_exists {*}$args] } {
20
22
  throw {FLOW KEYERROR} "key \"$args\" is not in the siliconcompiler configuration"
21
23
  }
@@ -41,11 +41,9 @@ def setup(chip):
41
41
  step=step, index=index)[0]
42
42
  sc_stream_order = [default_stream, *[s for s in streams if s != default_stream]]
43
43
 
44
- if stackup and targetlibs:
44
+ if stackup:
45
45
  macrolibs = get_libraries(chip, 'macro')
46
46
 
47
- chip.add('tool', tool, 'task', task, 'require', ",".join(['asic', 'logiclib']),
48
- step=step, index=index)
49
47
  chip.add('tool', tool, 'task', task, 'require', ",".join(['option', 'stackup']),
50
48
  step=step, index=index)
51
49
  req_set = False
@@ -83,7 +81,12 @@ def setup(chip):
83
81
  ",".join(['library', lib, 'output', stackup, 'lef']),
84
82
  step=step, index=index)
85
83
  else:
86
- chip.error('Stackup and targetlib parameters required for Klayout.')
84
+ chip.error('Stackup parameter required for Klayout.')
85
+
86
+ if not targetlibs:
87
+ chip.add('tool', tool, 'task', task, 'require',
88
+ 'option,var,klayout_libtype',
89
+ step=step, index=index)
87
90
 
88
91
  # Input/Output requirements for default flow
89
92
  design = chip.top()
@@ -61,6 +61,9 @@ def gds_export(design_name, in_def, in_files, out_file, tech, allow_missing, con
61
61
  for cell in def_cells:
62
62
  print(f" [INFO] DEF cell: {cell}")
63
63
 
64
+ if f"{design_name}_DEF_FILL" in def_cells:
65
+ def_cells.remove(f"{design_name}_DEF_FILL")
66
+
64
67
  # Load in the gds to merge
65
68
  print("[INFO] Merging GDS/OAS files...")
66
69
  for fil in in_files:
@@ -31,8 +31,14 @@ def technology(design, schema):
31
31
  sc_stackup = schema.get('option', 'stackup')
32
32
  else:
33
33
  sc_stackup = schema.get('pdk', sc_pdk, 'stackup')[0]
34
- sc_mainlib = schema.get('asic', 'logiclib', step=sc_step, index=sc_index)[0]
35
- sc_libtype = schema.get('library', sc_mainlib, 'asic', 'libarch', step=sc_step, index=sc_index)
34
+
35
+ logiclibs = schema.get('asic', 'logiclib', step=sc_step, index=sc_index)
36
+ if not logiclibs:
37
+ sc_libtype = schema.get('option', 'var', 'klayout_libtype')[0]
38
+ else:
39
+ sc_mainlib = logiclibs[0]
40
+ sc_libtype = schema.get('library', sc_mainlib, 'asic', 'libarch',
41
+ step=sc_step, index=sc_index)
36
42
 
37
43
  sc_libs = []
38
44
  sc_libs += get_libraries(schema, 'logic')
@@ -0,0 +1,44 @@
1
+ from siliconcompiler.tools.openroad.openroad import setup as setup_tool
2
+ from siliconcompiler.tools.openroad.openroad import build_pex_corners
3
+ from siliconcompiler.tools.openroad.openroad import post_process as or_post_process
4
+ from siliconcompiler.tools.openroad.openroad import pre_process as or_pre_process
5
+ from siliconcompiler.tools.openroad.openroad import _set_reports, set_pnr_inputs, set_pnr_outputs
6
+
7
+
8
+ def setup(chip):
9
+ '''
10
+ Extract metrics
11
+ '''
12
+
13
+ # Generic tool setup.
14
+ setup_tool(chip)
15
+
16
+ set_pnr_inputs(chip)
17
+ set_pnr_outputs(chip)
18
+
19
+ _set_reports(chip, [
20
+ 'setup',
21
+ 'hold',
22
+ 'unconstrained',
23
+ 'clock_skew',
24
+ 'power',
25
+ 'drv_violations',
26
+ 'fmax',
27
+
28
+ # Images
29
+ 'placement_density',
30
+ 'routing_congestion',
31
+ 'power_density',
32
+ 'clock_placement',
33
+ 'clock_trees',
34
+ 'optimization_placement'
35
+ ])
36
+
37
+
38
+ def pre_process(chip):
39
+ or_pre_process(chip)
40
+ build_pex_corners(chip)
41
+
42
+
43
+ def post_process(chip):
44
+ or_post_process(chip)
@@ -326,6 +326,9 @@ def post_process(chip):
326
326
  ('vias', 'sc__step__route__vias', True, None),
327
327
  ('wirelength', 'sc__step__route__wirelength', True, 'distance'),
328
328
  ('cellarea', 'sc__metric__design__instance__area', True, 'area'),
329
+ ('stdcellarea', 'sc__metric__design__instance__area__stdcell', True, 'area'),
330
+ ('macroarea', 'sc__metric__design__instance__area__macros', True, 'area'),
331
+ ('padcellarea', 'sc__metric__design__instance__area__padcells', True, 'area'),
329
332
  ('totalarea', 'sc__metric__design__core__area', True, 'area'),
330
333
  ('utilization', 'sc__metric__design__instance__utilization', True, 100.0),
331
334
  ('setuptns', 'sc__metric__timing__setup__tns', has_timing, 'time'),
@@ -0,0 +1,97 @@
1
+ import os
2
+
3
+ from siliconcompiler.tools._common import input_provides, get_tool_task
4
+ from siliconcompiler.tools._common.asic import set_tool_task_var
5
+ from siliconcompiler.tools.openroad.openroad import build_pex_corners
6
+ from siliconcompiler.tools.openroad.openroad import post_process as or_post_process
7
+
8
+
9
+ def setup(chip):
10
+ '''
11
+ Perform floorplanning, pin placements, macro placements and power grid generation
12
+ '''
13
+
14
+ # Generic tool setup.
15
+ # default tool settings, note, not additive!
16
+
17
+ tool = 'openroad'
18
+ script = 'sc_rdlroute.tcl'
19
+ refdir = os.path.join('tools', tool, 'scripts')
20
+
21
+ step = chip.get('arg', 'step')
22
+ index = chip.get('arg', 'index')
23
+ tool, task = get_tool_task(chip, step, index)
24
+
25
+ design = chip.top()
26
+
27
+ chip.set('tool', tool, 'exe', tool)
28
+ chip.set('tool', tool, 'vswitch', '-version')
29
+ chip.set('tool', tool, 'version', '>=v2.0-16839')
30
+ chip.set('tool', tool, 'format', 'tcl')
31
+
32
+ # exit automatically in batch mode and not breakpoint
33
+ option = ''
34
+ if exit and not chip.get('option', 'breakpoint', step=step, index=index):
35
+ option += " -exit"
36
+
37
+ option += " -metrics reports/metrics.json"
38
+ chip.set('tool', tool, 'task', task, 'option', option, step=step, index=index)
39
+
40
+ # Input/Output requirements for default asicflow steps
41
+
42
+ chip.set('tool', tool, 'task', task, 'refdir', refdir,
43
+ step=step, index=index,
44
+ package='siliconcompiler')
45
+ chip.set('tool', tool, 'task', task, 'script', script,
46
+ step=step, index=index)
47
+ chip.set('tool', tool, 'task', task, 'threads', os.cpu_count(),
48
+ step=step, index=index, clobber=False)
49
+
50
+ if chip.get('option', 'nodisplay'):
51
+ # Tells QT to use the offscreen platform if nodisplay is used
52
+ chip.set('tool', tool, 'task', task, 'env', 'QT_QPA_PLATFORM', 'offscreen',
53
+ step=step, index=index)
54
+
55
+ # basic warning and error grep check on logfile
56
+ chip.set('tool', tool, 'task', task, 'regex', 'warnings', r'^\[WARNING|^Warning',
57
+ step=step, index=index, clobber=False)
58
+ chip.set('tool', tool, 'task', task, 'regex', 'errors', r'^\[ERROR',
59
+ step=step, index=index, clobber=False)
60
+
61
+ chip.add('tool', tool, 'task', task, 'require',
62
+ 'option,var,openroad_libtype',
63
+ step=step, index=index)
64
+ chip.add('tool', tool, 'task', task, 'require',
65
+ ','.join(['tool', tool, 'task', task, 'file', 'rdlroute']),
66
+ step=step, index=index)
67
+ chip.set('tool', tool, 'task', task, 'file', 'rdlroute',
68
+ 'script to perform rdl route',
69
+ field='help')
70
+
71
+ set_tool_task_var(chip, param_key='fin_add_fill',
72
+ default_value='false',
73
+ schelp='true/false, when true enables adding fill, '
74
+ 'if enabled by the PDK, to the design',
75
+ skip='lib')
76
+
77
+ if f'{design}.v' in input_provides(chip, step, index):
78
+ chip.add('tool', tool, 'task', task, 'input', design + '.v', step=step, index=index)
79
+ elif f'{design}.vg' in input_provides(chip, step, index):
80
+ chip.add('tool', tool, 'task', task, 'input', design + '.vg', step=step, index=index)
81
+ else:
82
+ chip.add('tool', tool, 'task', task, 'require',
83
+ ','.join(['input', 'netlist', 'verilog']),
84
+ step=step, index=index)
85
+
86
+ chip.add('tool', tool, 'task', task, 'output', design + '.sdc', step=step, index=index)
87
+ chip.add('tool', tool, 'task', task, 'output', design + '.vg', step=step, index=index)
88
+ chip.add('tool', tool, 'task', task, 'output', design + '.def', step=step, index=index)
89
+ chip.add('tool', tool, 'task', task, 'output', design + '.odb', step=step, index=index)
90
+
91
+
92
+ def pre_process(chip):
93
+ build_pex_corners(chip)
94
+
95
+
96
+ def post_process(chip):
97
+ or_post_process(chip)
@@ -198,30 +198,28 @@ if { [file exists "inputs/$sc_design.odb"] } {
198
198
  }
199
199
  }
200
200
 
201
- if { $sc_task == "floorplan" } {
201
+ if { [file exists "inputs/${sc_design}.def"] } {
202
+ # Read DEF
203
+ # get from previous step
204
+ puts "Reading DEF: inputs/${sc_design}.def"
205
+ read_def "inputs/${sc_design}.def"
206
+ } elseif { [sc_cfg_exists input layout def] } {
207
+ # Read DEF
208
+ set sc_def [lindex [sc_cfg_get input layout def] 0]
209
+ puts "Reading DEF: ${sc_def}"
210
+ read_def $sc_def
211
+ } elseif { [file exists "inputs/${sc_design}.vg"] } {
202
212
  # Read Verilog
203
- if { [file exists "inputs/${sc_design}.vg"] } {
204
- puts "Reading netlist verilog: inputs/${sc_design}.vg"
205
- read_verilog "inputs/${sc_design}.vg"
206
- } else {
207
- foreach netlist [sc_cfg_get input netlist verilog] {
208
- puts "Reading netlist verilog: ${netlist}"
209
- read_verilog $netlist
210
- }
211
- }
213
+ puts "Reading netlist verilog: inputs/${sc_design}.vg"
214
+ read_verilog "inputs/${sc_design}.vg"
212
215
  link_design $sc_design
213
216
  } else {
214
- # Read DEF
215
- if { [file exists "inputs/${sc_design}.def"] } {
216
- # get from previous step
217
- puts "Reading DEF: inputs/${sc_design}.def"
218
- read_def "inputs/${sc_design}.def"
219
- } elseif { [sc_cfg_exists input layout def] } {
220
- # Floorplan initialize handled separately in sc_floorplan.tcl
221
- set sc_def [lindex [sc_cfg_get input layout def] 0]
222
- puts "Reading DEF: ${sc_def}"
223
- read_def $sc_def
217
+ # Read Verilog
218
+ foreach netlist [sc_cfg_get input netlist verilog] {
219
+ puts "Reading netlist verilog: ${netlist}"
220
+ read_verilog $netlist
224
221
  }
222
+ link_design $sc_design
225
223
  }
226
224
  }
227
225
 
@@ -405,7 +403,7 @@ utl::info FLW 1 "Using $sc_rc_signal for signal parasitics estimation"
405
403
 
406
404
  set_thread_count $sc_threads
407
405
 
408
- if { $sc_task != "floorplan" } {
406
+ if { $sc_task != "floorplan" && $sc_task != "metrics" } {
409
407
  ## Setup global routing
410
408
 
411
409
  # Adjust routing track density
@@ -504,7 +502,7 @@ if { $sc_task == "show" || $sc_task == "screenshot" } {
504
502
  ###############################
505
503
 
506
504
  utl::push_metrics_stage "sc__metric__{}"
507
- source "$sc_refdir/sc_metrics.tcl"
505
+ source "$sc_refdir/sc_report.tcl"
508
506
  utl::pop_metrics_stage
509
507
 
510
508
  # Images