siliconcompiler 0.28.4__py3-none-any.whl → 0.28.5__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 (41) 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/core.py +3 -1
  7. siliconcompiler/flows/drcflow.py +13 -0
  8. siliconcompiler/flows/interposerflow.py +17 -0
  9. siliconcompiler/libs/interposer.py +8 -0
  10. siliconcompiler/pdks/interposer.py +8 -0
  11. siliconcompiler/remote/schema.py +11 -1
  12. siliconcompiler/remote/server.py +7 -2
  13. siliconcompiler/scheduler/__init__.py +93 -0
  14. siliconcompiler/schema/schema_cfg.py +15 -3
  15. siliconcompiler/schema/schema_obj.py +51 -1
  16. siliconcompiler/targets/interposer_demo.py +56 -0
  17. siliconcompiler/templates/tcl/manifest.tcl.j2 +2 -0
  18. siliconcompiler/tools/klayout/export.py +7 -4
  19. siliconcompiler/tools/klayout/klayout_export.py +3 -0
  20. siliconcompiler/tools/klayout/klayout_utils.py +8 -2
  21. siliconcompiler/tools/openroad/metrics.py +45 -0
  22. siliconcompiler/tools/openroad/openroad.py +3 -0
  23. siliconcompiler/tools/openroad/rdlroute.py +97 -0
  24. siliconcompiler/tools/openroad/scripts/sc_apr.tcl +1 -1
  25. siliconcompiler/tools/openroad/scripts/sc_metrics.tcl +0 -169
  26. siliconcompiler/tools/openroad/scripts/sc_rdlroute.tcl +184 -0
  27. siliconcompiler/tools/openroad/scripts/sc_report.tcl +170 -0
  28. siliconcompiler/tools/opensta/scripts/sc_report_libraries.tcl +11 -1
  29. siliconcompiler/tools/xyce/__init__.py +1 -1
  30. siliconcompiler/toolscripts/_tools.json +3 -4
  31. siliconcompiler/toolscripts/rhel8/install-xyce.sh +4 -5
  32. siliconcompiler/toolscripts/rhel9/install-xyce.sh +4 -5
  33. siliconcompiler/toolscripts/ubuntu20/install-xyce.sh +5 -5
  34. siliconcompiler/toolscripts/ubuntu22/install-xyce.sh +2 -2
  35. siliconcompiler/toolscripts/ubuntu24/install-xyce.sh +2 -2
  36. {siliconcompiler-0.28.4.dist-info → siliconcompiler-0.28.5.dist-info}/METADATA +4 -4
  37. {siliconcompiler-0.28.4.dist-info → siliconcompiler-0.28.5.dist-info}/RECORD +41 -32
  38. {siliconcompiler-0.28.4.dist-info → siliconcompiler-0.28.5.dist-info}/WHEEL +1 -1
  39. {siliconcompiler-0.28.4.dist-info → siliconcompiler-0.28.5.dist-info}/LICENSE +0 -0
  40. {siliconcompiler-0.28.4.dist-info → siliconcompiler-0.28.5.dist-info}/entry_points.txt +0 -0
  41. {siliconcompiler-0.28.4.dist-info → siliconcompiler-0.28.5.dist-info}/top_level.txt +0 -0
@@ -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,45 @@
1
+
2
+ from siliconcompiler.tools.openroad.openroad import setup as setup_tool
3
+ from siliconcompiler.tools.openroad.openroad import build_pex_corners
4
+ from siliconcompiler.tools.openroad.openroad import post_process as or_post_process
5
+ from siliconcompiler.tools.openroad.openroad import pre_process as or_pre_process
6
+ from siliconcompiler.tools.openroad.openroad import _set_reports, set_pnr_inputs, set_pnr_outputs
7
+
8
+
9
+ def setup(chip):
10
+ '''
11
+ Extract metrics
12
+ '''
13
+
14
+ # Generic tool setup.
15
+ setup_tool(chip)
16
+
17
+ set_pnr_inputs(chip)
18
+ set_pnr_outputs(chip)
19
+
20
+ _set_reports(chip, [
21
+ 'setup',
22
+ 'hold',
23
+ 'unconstrained',
24
+ 'clock_skew',
25
+ 'power',
26
+ 'drv_violations',
27
+ 'fmax',
28
+
29
+ # Images
30
+ 'placement_density',
31
+ 'routing_congestion',
32
+ 'power_density',
33
+ 'clock_placement',
34
+ 'clock_trees',
35
+ 'optimization_placement'
36
+ ])
37
+
38
+
39
+ def pre_process(chip):
40
+ or_pre_process(chip)
41
+ build_pex_corners(chip)
42
+
43
+
44
+ def post_process(chip):
45
+ 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)
@@ -504,7 +504,7 @@ if { $sc_task == "show" || $sc_task == "screenshot" } {
504
504
  ###############################
505
505
 
506
506
  utl::push_metrics_stage "sc__metric__{}"
507
- source "$sc_refdir/sc_metrics.tcl"
507
+ source "$sc_refdir/sc_report.tcl"
508
508
  utl::pop_metrics_stage
509
509
 
510
510
  # Images
@@ -1,170 +1 @@
1
- ###############################
2
- # Report Metrics
3
- ###############################
4
1
 
5
- proc sc_display_report { report } {
6
- if { ![file exists $report] } {
7
- return
8
- }
9
- set fid [open $report r]
10
- set report_content [read $fid]
11
- close $fid
12
- puts $report_content
13
- }
14
-
15
- set fields "{capacitance slew input_pins nets fanout}"
16
- set PREFIX "SC_METRIC:"
17
-
18
- if { [sc_cfg_tool_task_check_in_list setup var reports] } {
19
- puts "$PREFIX report_checks -path_delay max"
20
- report_checks -fields $fields -path_delay max -format full_clock_expanded \
21
- > reports/timing/setup.rpt
22
- sc_display_report reports/timing/setup.rpt
23
- report_checks -path_delay max -group_count $openroad_sta_top_n_paths \
24
- > reports/timing/setup.topN.rpt
25
-
26
- puts "$PREFIX setupslack"
27
- report_worst_slack -max > reports/timing/worst_slack.setup.rpt
28
- sc_display_report reports/timing/worst_slack.setup.rpt
29
- report_worst_slack_metric -setup
30
-
31
- puts "$PREFIX tns"
32
- report_tns > reports/timing/total_negative_slack.rpt
33
- sc_display_report reports/timing/total_negative_slack.rpt
34
- report_tns_metric -setup
35
- }
36
-
37
- if { [sc_cfg_tool_task_check_in_list hold var reports] } {
38
- puts "$PREFIX report_checks -path_delay min"
39
- report_checks -fields $fields -path_delay min -format full_clock_expanded \
40
- > reports/timing/hold.rpt
41
- sc_display_report reports/timing/hold.rpt
42
- report_checks -path_delay min -group_count $openroad_sta_top_n_paths \
43
- > reports/timing/hold.topN.rpt
44
-
45
- puts "$PREFIX holdslack"
46
- report_worst_slack -min > reports/timing/worst_slack.hold.rpt
47
- sc_display_report reports/timing/worst_slack.hold.rpt
48
- report_worst_slack_metric -hold
49
-
50
- report_tns_metric -hold
51
- }
52
-
53
- if { [sc_cfg_tool_task_check_in_list unconstrained var reports] } {
54
- puts "$PREFIX unconstrained"
55
- report_checks -fields $fields -unconstrained -format full_clock_expanded \
56
- > reports/timing/unconstrained.rpt
57
- sc_display_report reports/timing/unconstrained.rpt
58
- report_checks -unconstrained -group_count $openroad_sta_top_n_paths \
59
- > reports/timing/unconstrained.topN.rpt
60
- }
61
-
62
- if {
63
- [sc_cfg_tool_task_check_in_list clock_skew var reports] &&
64
- [llength [all_clocks]] > 0
65
- } {
66
- puts "$PREFIX clock_skew"
67
- report_clock_skew -setup -digits 4 > reports/timing/skew.setup.rpt
68
- sc_display_report reports/timing/skew.setup.rpt
69
- report_clock_skew_metric -setup
70
- report_clock_skew -hold -digits 4 > reports/timing/skew.hold.rpt
71
- sc_display_report reports/timing/skew.hold.rpt
72
- report_clock_skew_metric -hold
73
- }
74
-
75
- if { [sc_cfg_tool_task_check_in_list drv_violations var reports] } {
76
- puts "$PREFIX DRV violators"
77
- report_check_types -max_slew -max_capacitance -max_fanout -violators \
78
- > reports/timing/drv_violators.rpt
79
- sc_display_report reports/timing/drv_violators.rpt
80
- report_erc_metrics
81
-
82
- puts "$PREFIX floating nets"
83
- report_floating_nets -verbose > reports/floating_nets.rpt
84
- sc_display_report reports/floating_nets.rpt
85
- }
86
-
87
- utl::metric_int "timing__clocks" [llength [all_clocks]]
88
-
89
- if { [sc_cfg_tool_task_check_in_list fmax var reports] } {
90
- puts "$PREFIX fmax"
91
- # Model on: https://github.com/The-OpenROAD-Project/OpenSTA/blob/f913c3ddbb3e7b4364ed4437c65ac78c4da9174b/tcl/Search.tcl#L1078
92
- set fmax_metric 0
93
- foreach clk [sta::sort_by_name [all_clocks]] {
94
- set clk_name [get_name $clk]
95
- set min_period [sta::find_clk_min_period $clk 1]
96
- if { $min_period == 0.0 } {
97
- continue
98
- }
99
- set fmax [expr { 1.0 / $min_period }]
100
- utl::metric_float "timing__fmax__clock:${clk_name}" $fmax
101
- puts "$clk_name fmax = [format %.2f [expr { $fmax / 1e6 }]] MHz"
102
- set fmax_metric [expr { max($fmax_metric, $fmax) }]
103
- }
104
- if { $fmax_metric > 0 } {
105
- utl::metric_float "timing__fmax" $fmax_metric
106
- }
107
- }
108
-
109
- # get logic depth of design
110
- utl::metric_int "design__logic__depth" [count_logic_depth]
111
-
112
- if { [sc_cfg_tool_task_check_in_list power var reports] } {
113
- puts "$PREFIX power"
114
- foreach corner [sta::corners] {
115
- set corner_name [$corner name]
116
- puts "Power for corner: $corner_name"
117
- report_power -corner $corner_name > reports/power/${corner_name}.rpt
118
- sc_display_report reports/power/${corner_name}.rpt
119
- }
120
- report_power_metric -corner $sc_power_corner
121
- }
122
-
123
- puts "$PREFIX cellarea"
124
- report_design_area
125
- report_design_area_metrics
126
-
127
- # get number of nets in design
128
- utl::metric_int "design__nets" [llength [[ord::get_db_block] getNets]]
129
-
130
- # get number of registers
131
- utl::metric_int "design__registers" [llength [all_registers]]
132
-
133
- # get number of buffers
134
- set bufs 0
135
- set invs 0
136
- foreach inst [get_cells -hierarchical *] {
137
- set cell [$inst cell]
138
- if { $cell == "NULL" } {
139
- continue
140
- }
141
- set liberty_cell [$cell liberty_cell]
142
- if { $liberty_cell == "NULL" } {
143
- continue
144
- }
145
- if { [$liberty_cell is_buffer] } {
146
- incr bufs
147
- } elseif { [$liberty_cell is_inverter] } {
148
- incr invs
149
- }
150
- }
151
- utl::metric_int "design__buffers" $bufs
152
- utl::metric_int "design__inverters" $invs
153
-
154
- # get number of unconstrained endpoints
155
- with_output_to_variable endpoints {check_setup -unconstrained_endpoints}
156
- set unconstrained_endpoints [regexp -all -inline {[0-9]+} $endpoints]
157
- if { $unconstrained_endpoints == "" } {
158
- set unconstrained_endpoints 0
159
- }
160
- utl::metric_int "timing__unconstrained" $unconstrained_endpoints
161
-
162
- # Write markers
163
- foreach markerdb [[ord::get_db_block] getMarkerCategories] {
164
- if { [$markerdb getMarkerCount] == 0 } {
165
- continue
166
- }
167
-
168
- $markerdb writeTR "reports/markers/${sc_design}.[$markerdb getName].rpt"
169
- $markerdb writeJSON "reports/markers/${sc_design}.[$markerdb getName].json"
170
- }