siliconcompiler 0.34.1__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.
- siliconcompiler/__init__.py +14 -2
- siliconcompiler/_metadata.py +1 -1
- siliconcompiler/apps/sc_show.py +1 -1
- siliconcompiler/constraints/__init__.py +17 -0
- siliconcompiler/constraints/asic_component.py +378 -0
- siliconcompiler/constraints/asic_floorplan.py +449 -0
- siliconcompiler/constraints/asic_pins.py +489 -0
- siliconcompiler/constraints/asic_timing.py +517 -0
- siliconcompiler/core.py +3 -3
- siliconcompiler/dependencyschema.py +10 -174
- siliconcompiler/design.py +235 -118
- siliconcompiler/flowgraph.py +27 -14
- siliconcompiler/library.py +133 -0
- siliconcompiler/metric.py +94 -72
- siliconcompiler/metrics/__init__.py +7 -0
- siliconcompiler/metrics/asic.py +245 -0
- siliconcompiler/metrics/fpga.py +220 -0
- siliconcompiler/package/__init__.py +138 -35
- siliconcompiler/package/github.py +6 -10
- siliconcompiler/packageschema.py +256 -12
- siliconcompiler/pathschema.py +226 -0
- siliconcompiler/project.py +459 -0
- siliconcompiler/scheduler/docker.py +2 -3
- siliconcompiler/scheduler/run_node.py +2 -1
- siliconcompiler/scheduler/scheduler.py +4 -13
- siliconcompiler/scheduler/schedulernode.py +25 -17
- siliconcompiler/scheduler/taskscheduler.py +2 -1
- siliconcompiler/schema/__init__.py +0 -2
- siliconcompiler/schema/baseschema.py +147 -24
- siliconcompiler/schema/editableschema.py +14 -6
- siliconcompiler/schema/journal.py +23 -15
- siliconcompiler/schema/namedschema.py +6 -4
- siliconcompiler/schema/parameter.py +34 -19
- siliconcompiler/schema/parametertype.py +2 -0
- siliconcompiler/schema/parametervalue.py +198 -15
- siliconcompiler/schema/schema_cfg.py +18 -14
- siliconcompiler/schema_obj.py +5 -3
- siliconcompiler/tool.py +199 -10
- siliconcompiler/toolscripts/_tools.json +4 -4
- {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.2.dist-info}/METADATA +3 -3
- {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.2.dist-info}/RECORD +45 -35
- siliconcompiler/schema/packageschema.py +0 -101
- {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.2.dist-info}/WHEEL +0 -0
- {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.2.dist-info}/entry_points.txt +0 -0
- {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.2.dist-info}/licenses/LICENSE +0 -0
- {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.2.dist-info}/top_level.txt +0 -0
siliconcompiler/flowgraph.py
CHANGED
|
@@ -68,6 +68,11 @@ class FlowgraphSchema(NamedSchema):
|
|
|
68
68
|
if index in (Schema.GLOBAL_KEY, 'default'):
|
|
69
69
|
raise ValueError(f"{index} is a reserved name")
|
|
70
70
|
|
|
71
|
+
if '/' in step:
|
|
72
|
+
raise ValueError(f"{step} is not a valid step, it cannot contain '/'")
|
|
73
|
+
if '/' in index:
|
|
74
|
+
raise ValueError(f"{index} is not a valid index, it cannot contain '/'")
|
|
75
|
+
|
|
71
76
|
# Determine task name and module
|
|
72
77
|
task_module = None
|
|
73
78
|
if isinstance(task, str):
|
|
@@ -83,11 +88,6 @@ class FlowgraphSchema(NamedSchema):
|
|
|
83
88
|
raise ValueError(f"{task} is not a valid task, it must be associated with "
|
|
84
89
|
"a tool '<tool>.<task>'.")
|
|
85
90
|
|
|
86
|
-
if '/' in step:
|
|
87
|
-
raise ValueError(f"{step} is not a valid step, it cannot contain '/'")
|
|
88
|
-
if '/' in index:
|
|
89
|
-
raise ValueError(f"{index} is not a valid index, it cannot contain '/'")
|
|
90
|
-
|
|
91
91
|
tool_name, task_name = task_parts[-2:]
|
|
92
92
|
|
|
93
93
|
# bind tool to node
|
|
@@ -504,6 +504,17 @@ class FlowgraphSchema(NamedSchema):
|
|
|
504
504
|
|
|
505
505
|
return not error
|
|
506
506
|
|
|
507
|
+
def __get_task_module(self, name):
|
|
508
|
+
# Create cache
|
|
509
|
+
if self.__cache_tasks is None:
|
|
510
|
+
self.__cache_tasks = {}
|
|
511
|
+
|
|
512
|
+
if name in self.__cache_tasks:
|
|
513
|
+
return self.__cache_tasks[name]
|
|
514
|
+
|
|
515
|
+
self.__cache_tasks[name] = importlib.import_module(name)
|
|
516
|
+
return self.__cache_tasks[name]
|
|
517
|
+
|
|
507
518
|
def get_task_module(self, step, index):
|
|
508
519
|
"""
|
|
509
520
|
Returns the module for a given task
|
|
@@ -518,17 +529,19 @@ class FlowgraphSchema(NamedSchema):
|
|
|
518
529
|
if (step, index) not in self.get_nodes():
|
|
519
530
|
raise ValueError(f"{step}/{index} is not a valid node in {self.name()}.")
|
|
520
531
|
|
|
521
|
-
|
|
532
|
+
return self.__get_task_module(self.get(step, index, 'taskmodule'))
|
|
522
533
|
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
if taskmodule in self.__cache_tasks:
|
|
528
|
-
return self.__cache_tasks[taskmodule]
|
|
534
|
+
def get_all_tasks(self):
|
|
535
|
+
'''
|
|
536
|
+
Returns all the task modules used in this flow
|
|
529
537
|
|
|
530
|
-
|
|
531
|
-
|
|
538
|
+
Returns:
|
|
539
|
+
set of modules
|
|
540
|
+
'''
|
|
541
|
+
tasks = set()
|
|
542
|
+
for step, index in self.get_nodes():
|
|
543
|
+
tasks.add(self.get_task_module(step, index))
|
|
544
|
+
return tasks
|
|
532
545
|
|
|
533
546
|
|
|
534
547
|
class RuntimeFlowgraph:
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
from typing import final, Union, List
|
|
2
|
+
|
|
3
|
+
from siliconcompiler.design import DesignSchema
|
|
4
|
+
|
|
5
|
+
from siliconcompiler.schema import EditableSchema, Parameter, Scope, PerNode
|
|
6
|
+
from siliconcompiler.schema.utils import trim
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class LibrarySchema(DesignSchema):
|
|
10
|
+
def __init__(self, name: str = None):
|
|
11
|
+
super().__init__()
|
|
12
|
+
self.set_name(name)
|
|
13
|
+
|
|
14
|
+
@final
|
|
15
|
+
def define_tool_parameter(self, tool: str, name: str, type: str, help: str, **kwargs):
|
|
16
|
+
"""
|
|
17
|
+
Define a new tool parameter for the library
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
tool (str): name of the tool
|
|
21
|
+
name (str): name of the parameter
|
|
22
|
+
type (str): type of parameter, see :class:`.Parameter`.
|
|
23
|
+
help (str): help information for this parameter
|
|
24
|
+
kwargs: passthrough for :class:`.Parameter`.
|
|
25
|
+
"""
|
|
26
|
+
if isinstance(help, str):
|
|
27
|
+
# grab first line for short help
|
|
28
|
+
help = trim(help)
|
|
29
|
+
shorthelp = help.splitlines()[0].strip()
|
|
30
|
+
else:
|
|
31
|
+
raise TypeError("help must be a string")
|
|
32
|
+
|
|
33
|
+
kwargs["scope"] = Scope.GLOBAL
|
|
34
|
+
kwargs["pernode"] = PerNode.NEVER
|
|
35
|
+
kwargs["shorthelp"] = shorthelp
|
|
36
|
+
kwargs["help"] = help
|
|
37
|
+
|
|
38
|
+
EditableSchema(self).insert(
|
|
39
|
+
"tool", tool, name,
|
|
40
|
+
Parameter(type, **kwargs)
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class StdCellLibrarySchema(LibrarySchema):
|
|
45
|
+
def __init__(self, name: str = None):
|
|
46
|
+
super().__init__()
|
|
47
|
+
self.set_name(name)
|
|
48
|
+
|
|
49
|
+
schema = EditableSchema(self)
|
|
50
|
+
|
|
51
|
+
schema.insert(
|
|
52
|
+
'asic', 'cornerfilesets', 'default',
|
|
53
|
+
Parameter(
|
|
54
|
+
'[str]',
|
|
55
|
+
scope=Scope.GLOBAL,
|
|
56
|
+
shorthelp="ASIC: map of filesets to timing or pex corners",
|
|
57
|
+
example=["api: schema.set('asic', 'cornerfilesets', 'slow', 'timing.slow')"],
|
|
58
|
+
help=trim("""Map between filesets and timing or pex corners.""")))
|
|
59
|
+
|
|
60
|
+
# TODO: Expand on the exact definitions of these types of cells.
|
|
61
|
+
# minimize typing
|
|
62
|
+
for item in [
|
|
63
|
+
'decap',
|
|
64
|
+
'tie',
|
|
65
|
+
'hold',
|
|
66
|
+
'clkbuf',
|
|
67
|
+
'clkgate',
|
|
68
|
+
'clklogic',
|
|
69
|
+
'dontuse',
|
|
70
|
+
'filler',
|
|
71
|
+
'tap',
|
|
72
|
+
'endcap',
|
|
73
|
+
'antenna']:
|
|
74
|
+
schema.insert(
|
|
75
|
+
'asic', 'cells', item,
|
|
76
|
+
Parameter(
|
|
77
|
+
'[str]',
|
|
78
|
+
scope=Scope.GLOBAL,
|
|
79
|
+
shorthelp=f"ASIC: {item} cell list",
|
|
80
|
+
example=[f"api: schema.set('asic', 'cells', '{item}', '*eco*')"],
|
|
81
|
+
help=trim("""
|
|
82
|
+
List of cells grouped by a property that can be accessed
|
|
83
|
+
directly by the designer and tools. The example below shows how
|
|
84
|
+
all cells containing the string 'eco' could be marked as dont use
|
|
85
|
+
for the tool.""")))
|
|
86
|
+
|
|
87
|
+
schema.insert(
|
|
88
|
+
'asic', 'site',
|
|
89
|
+
Parameter(
|
|
90
|
+
'[str]',
|
|
91
|
+
scope=Scope.GLOBAL,
|
|
92
|
+
shorthelp="ASIC: library sites",
|
|
93
|
+
example=["api: schema.set('asic', 'site', 'Site_12T')"],
|
|
94
|
+
help="Site names for a given library architecture."))
|
|
95
|
+
|
|
96
|
+
def add_asic_corner_fileset(self, corner: str, fileset: str = None):
|
|
97
|
+
"""
|
|
98
|
+
Adds a mapping between filesets a corners defined in the library
|
|
99
|
+
|
|
100
|
+
Args:
|
|
101
|
+
corner (str): name of the timing or parasitic corner
|
|
102
|
+
fileset (str): name of the fileset
|
|
103
|
+
"""
|
|
104
|
+
if not fileset:
|
|
105
|
+
fileset = self._get_active("fileset")
|
|
106
|
+
|
|
107
|
+
if not isinstance(fileset, str):
|
|
108
|
+
raise TypeError("fileset must be a string")
|
|
109
|
+
|
|
110
|
+
if fileset not in self.getkeys("fileset"):
|
|
111
|
+
raise ValueError(f"{fileset} is not defined")
|
|
112
|
+
|
|
113
|
+
return self.add("asic", "cornerfilesets", corner, fileset)
|
|
114
|
+
|
|
115
|
+
def add_asic_cell_list(self, type: str, cells: Union[List[str], str]):
|
|
116
|
+
"""
|
|
117
|
+
Adds a standard cell library to the specified type.
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
type (str): category of cell type
|
|
121
|
+
cells (list of str): cells to add
|
|
122
|
+
"""
|
|
123
|
+
return self.add("asic", "cells", type, cells)
|
|
124
|
+
|
|
125
|
+
def add_asic_site(self, site: Union[List[str], str]):
|
|
126
|
+
"""
|
|
127
|
+
Adds a standard site to the library
|
|
128
|
+
|
|
129
|
+
Args:
|
|
130
|
+
type (str): category of cell type
|
|
131
|
+
cells (list of str): cells to add
|
|
132
|
+
"""
|
|
133
|
+
return self.add("asic", "site", site)
|
siliconcompiler/metric.py
CHANGED
|
@@ -10,7 +10,91 @@ class MetricSchema(BaseSchema):
|
|
|
10
10
|
def __init__(self):
|
|
11
11
|
super().__init__()
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
schema = EditableSchema(self)
|
|
14
|
+
|
|
15
|
+
for item, description in [
|
|
16
|
+
('errors', 'errors'),
|
|
17
|
+
('warnings', 'warnings')]:
|
|
18
|
+
schema.insert(
|
|
19
|
+
item,
|
|
20
|
+
Parameter(
|
|
21
|
+
'int',
|
|
22
|
+
scope=Scope.JOB,
|
|
23
|
+
shorthelp=f"Metric: total {item}",
|
|
24
|
+
switch=f"-metric_{item} 'step index <int>'",
|
|
25
|
+
example=[
|
|
26
|
+
f"cli: -metric_{item} 'dfm 0 0'",
|
|
27
|
+
f"api: chip.set('metric', '{item}', 0, step='dfm', index=0)"],
|
|
28
|
+
pernode=PerNode.REQUIRED,
|
|
29
|
+
help=trim(f"""Metric tracking the total number of {description} on a
|
|
30
|
+
per step and index basis.""")))
|
|
31
|
+
|
|
32
|
+
schema.insert(
|
|
33
|
+
'memory',
|
|
34
|
+
Parameter(
|
|
35
|
+
'float',
|
|
36
|
+
unit='B',
|
|
37
|
+
scope=Scope.JOB,
|
|
38
|
+
shorthelp="Metric: memory",
|
|
39
|
+
switch="-metric_memory 'step index <float>'",
|
|
40
|
+
example=[
|
|
41
|
+
"cli: -metric_memory 'dfm 0 10e9'",
|
|
42
|
+
"api: chip.set('metric', 'memory', 10e9, step='dfm', index=0)"],
|
|
43
|
+
pernode=PerNode.REQUIRED,
|
|
44
|
+
help=trim("""
|
|
45
|
+
Metric tracking total peak program memory footprint on a per
|
|
46
|
+
step and index basis.""")))
|
|
47
|
+
|
|
48
|
+
schema.insert(
|
|
49
|
+
'exetime',
|
|
50
|
+
Parameter(
|
|
51
|
+
'float',
|
|
52
|
+
unit='s',
|
|
53
|
+
scope=Scope.JOB,
|
|
54
|
+
shorthelp="Metric: exetime",
|
|
55
|
+
switch="-metric_exetime 'step index <float>'",
|
|
56
|
+
example=[
|
|
57
|
+
"cli: -metric_exetime 'dfm 0 10.0'",
|
|
58
|
+
"api: chip.set('metric', 'exetime', 10.0, step='dfm', index=0)"],
|
|
59
|
+
pernode=PerNode.REQUIRED,
|
|
60
|
+
help=trim("""
|
|
61
|
+
Metric tracking time spent by the EDA executable :keypath:`tool,<tool>,exe` on a
|
|
62
|
+
per step and index basis. It does not include the SiliconCompiler
|
|
63
|
+
runtime overhead or time waiting for I/O operations and
|
|
64
|
+
inter-processor communication to complete.""")))
|
|
65
|
+
|
|
66
|
+
schema.insert(
|
|
67
|
+
'tasktime',
|
|
68
|
+
Parameter(
|
|
69
|
+
'float',
|
|
70
|
+
unit='s',
|
|
71
|
+
scope=Scope.JOB,
|
|
72
|
+
shorthelp="Metric: tasktime",
|
|
73
|
+
switch="-metric_tasktime 'step index <float>'",
|
|
74
|
+
example=[
|
|
75
|
+
"cli: -metric_tasktime 'dfm 0 10.0'",
|
|
76
|
+
"api: chip.set('metric', 'tasktime', 10.0, step='dfm', index=0)"],
|
|
77
|
+
pernode=PerNode.REQUIRED,
|
|
78
|
+
help=trim("""
|
|
79
|
+
Metric tracking the total amount of time spent on a task from
|
|
80
|
+
beginning to end, including data transfers and pre/post
|
|
81
|
+
processing.""")))
|
|
82
|
+
|
|
83
|
+
schema.insert(
|
|
84
|
+
'totaltime',
|
|
85
|
+
Parameter(
|
|
86
|
+
'float',
|
|
87
|
+
unit='s',
|
|
88
|
+
scope=Scope.JOB,
|
|
89
|
+
shorthelp="Metric: totaltime",
|
|
90
|
+
switch="-metric_totaltime 'step index <float>'",
|
|
91
|
+
example=[
|
|
92
|
+
"cli: -metric_totaltime 'dfm 0 10.0'",
|
|
93
|
+
"api: chip.set('metric', 'totaltime', 10.0, step='dfm', index=0)"],
|
|
94
|
+
pernode=PerNode.REQUIRED,
|
|
95
|
+
help=trim("""
|
|
96
|
+
Metric tracking the total amount of time spent from the beginning
|
|
97
|
+
of the run up to and including the current step and index.""")))
|
|
14
98
|
|
|
15
99
|
def clear(self, step, index):
|
|
16
100
|
'''
|
|
@@ -122,15 +206,20 @@ class MetricSchema(BaseSchema):
|
|
|
122
206
|
return self.record(step, index, "totaltime", total_time, unit="s")
|
|
123
207
|
|
|
124
208
|
|
|
209
|
+
class MetricSchemaTmp(MetricSchema):
|
|
210
|
+
def __init__(self):
|
|
211
|
+
super().__init__()
|
|
212
|
+
|
|
213
|
+
schema_metric_tmp(self)
|
|
214
|
+
|
|
215
|
+
|
|
125
216
|
###########################################################################
|
|
126
217
|
# Metrics to Track
|
|
127
218
|
###########################################################################
|
|
128
|
-
def
|
|
219
|
+
def schema_metric_tmp(schema):
|
|
129
220
|
schema = EditableSchema(schema)
|
|
130
221
|
|
|
131
|
-
metrics = {'
|
|
132
|
-
'warnings': 'warnings',
|
|
133
|
-
'drvs': 'design rule violations',
|
|
222
|
+
metrics = {'drvs': 'design rule violations',
|
|
134
223
|
'drcs': 'physical design rule violations',
|
|
135
224
|
'unconstrained': 'unconstrained timing paths'}
|
|
136
225
|
|
|
@@ -429,70 +518,3 @@ def schema_metric(schema):
|
|
|
429
518
|
congested design. To analyze where the congestion is occurring
|
|
430
519
|
inspect the router log files for detailed per metal overflow
|
|
431
520
|
reporting and open up the design to find routing hotspots.""")))
|
|
432
|
-
|
|
433
|
-
schema.insert(
|
|
434
|
-
'memory',
|
|
435
|
-
Parameter(
|
|
436
|
-
'float',
|
|
437
|
-
unit='B',
|
|
438
|
-
scope=Scope.JOB,
|
|
439
|
-
shorthelp="Metric: memory",
|
|
440
|
-
switch="-metric_memory 'step index <float>'",
|
|
441
|
-
example=[
|
|
442
|
-
"cli: -metric_memory 'dfm 0 10e9'",
|
|
443
|
-
"api: chip.set('metric', 'memory', 10e9, step='dfm', index=0)"],
|
|
444
|
-
pernode=PerNode.REQUIRED,
|
|
445
|
-
help=trim("""
|
|
446
|
-
Metric tracking total peak program memory footprint on a per
|
|
447
|
-
step and index basis.""")))
|
|
448
|
-
|
|
449
|
-
schema.insert(
|
|
450
|
-
'exetime',
|
|
451
|
-
Parameter(
|
|
452
|
-
'float',
|
|
453
|
-
unit='s',
|
|
454
|
-
scope=Scope.JOB,
|
|
455
|
-
shorthelp="Metric: exetime",
|
|
456
|
-
switch="-metric_exetime 'step index <float>'",
|
|
457
|
-
example=[
|
|
458
|
-
"cli: -metric_exetime 'dfm 0 10.0'",
|
|
459
|
-
"api: chip.set('metric', 'exetime', 10.0, step='dfm', index=0)"],
|
|
460
|
-
pernode=PerNode.REQUIRED,
|
|
461
|
-
help=trim("""
|
|
462
|
-
Metric tracking time spent by the EDA executable :keypath:`tool,<tool>,exe` on a
|
|
463
|
-
per step and index basis. It does not include the SiliconCompiler
|
|
464
|
-
runtime overhead or time waiting for I/O operations and
|
|
465
|
-
inter-processor communication to complete.""")))
|
|
466
|
-
|
|
467
|
-
schema.insert(
|
|
468
|
-
'tasktime',
|
|
469
|
-
Parameter(
|
|
470
|
-
'float',
|
|
471
|
-
unit='s',
|
|
472
|
-
scope=Scope.JOB,
|
|
473
|
-
shorthelp="Metric: tasktime",
|
|
474
|
-
switch="-metric_tasktime 'step index <float>'",
|
|
475
|
-
example=[
|
|
476
|
-
"cli: -metric_tasktime 'dfm 0 10.0'",
|
|
477
|
-
"api: chip.set('metric', 'tasktime', 10.0, step='dfm', index=0)"],
|
|
478
|
-
pernode=PerNode.REQUIRED,
|
|
479
|
-
help=trim("""
|
|
480
|
-
Metric tracking the total amount of time spent on a task from
|
|
481
|
-
beginning to end, including data transfers and pre/post
|
|
482
|
-
processing.""")))
|
|
483
|
-
|
|
484
|
-
schema.insert(
|
|
485
|
-
'totaltime',
|
|
486
|
-
Parameter(
|
|
487
|
-
'float',
|
|
488
|
-
unit='s',
|
|
489
|
-
scope=Scope.JOB,
|
|
490
|
-
shorthelp="Metric: totaltime",
|
|
491
|
-
switch="-metric_totaltime 'step index <float>'",
|
|
492
|
-
example=[
|
|
493
|
-
"cli: -metric_totaltime 'dfm 0 10.0'",
|
|
494
|
-
"api: chip.set('metric', 'totaltime', 10.0, step='dfm', index=0)"],
|
|
495
|
-
pernode=PerNode.REQUIRED,
|
|
496
|
-
help=trim("""
|
|
497
|
-
Metric tracking the total amount of time spent from the beginning
|
|
498
|
-
of the run up to and including the current step and index.""")))
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
from siliconcompiler import MetricSchema
|
|
2
|
+
|
|
3
|
+
from siliconcompiler.schema import EditableSchema, Parameter, Scope, PerNode
|
|
4
|
+
from siliconcompiler.schema.utils import trim
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ASICMetricsSchema(MetricSchema):
|
|
8
|
+
def __init__(self):
|
|
9
|
+
super().__init__()
|
|
10
|
+
|
|
11
|
+
schema = EditableSchema(self)
|
|
12
|
+
|
|
13
|
+
for item, description in [
|
|
14
|
+
('drvs', 'design rule violations'),
|
|
15
|
+
('drcs', 'physical design rule violations'),
|
|
16
|
+
('unconstrained', 'unconstrained timing paths')]:
|
|
17
|
+
schema.insert(
|
|
18
|
+
item,
|
|
19
|
+
Parameter(
|
|
20
|
+
'int',
|
|
21
|
+
scope=Scope.JOB,
|
|
22
|
+
shorthelp=f"Metric: total {item}",
|
|
23
|
+
switch=f"-metric_{item} 'step index <int>'",
|
|
24
|
+
example=[
|
|
25
|
+
f"cli: -metric_{item} 'dfm 0 0'",
|
|
26
|
+
f"api: chip.set('metric', '{item}', 0, step='dfm', index=0)"],
|
|
27
|
+
pernode=PerNode.REQUIRED,
|
|
28
|
+
help=trim(f"""Metric tracking the total number of {description} on a
|
|
29
|
+
per step and index basis.""")))
|
|
30
|
+
|
|
31
|
+
for item, description in [
|
|
32
|
+
('cellarea', 'cell area (ignoring fillers)'),
|
|
33
|
+
('totalarea', 'physical die area'),
|
|
34
|
+
('macroarea', 'macro cell area'),
|
|
35
|
+
('padcellarea', 'io pad cell area'),
|
|
36
|
+
('stdcellarea', 'standard cell area')]:
|
|
37
|
+
schema.insert(
|
|
38
|
+
item,
|
|
39
|
+
Parameter(
|
|
40
|
+
'float',
|
|
41
|
+
unit='um^2',
|
|
42
|
+
scope=Scope.JOB,
|
|
43
|
+
shorthelp=f"Metric: {item}",
|
|
44
|
+
switch=f"-metric_{item} 'step index <float>'",
|
|
45
|
+
example=[
|
|
46
|
+
f"cli: -metric_{item} 'place 0 100.00'",
|
|
47
|
+
f"api: chip.set('metric', '{item}', 100.00, step='place', index=0)"],
|
|
48
|
+
pernode=PerNode.REQUIRED,
|
|
49
|
+
help=trim(f"""
|
|
50
|
+
Metric tracking the total {description} occupied by the design.""")))
|
|
51
|
+
|
|
52
|
+
schema.insert(
|
|
53
|
+
'utilization',
|
|
54
|
+
Parameter(
|
|
55
|
+
'float',
|
|
56
|
+
unit='%',
|
|
57
|
+
scope=Scope.JOB,
|
|
58
|
+
shorthelp="Metric: area utilization",
|
|
59
|
+
switch="-metric_utilization 'step index <float>'",
|
|
60
|
+
example=[
|
|
61
|
+
"cli: -metric_utilization 'place 0 50.00'",
|
|
62
|
+
"api: chip.set('metric', 'utilization', 50.00, step='place', index=0)"],
|
|
63
|
+
pernode=PerNode.REQUIRED,
|
|
64
|
+
help=trim("""
|
|
65
|
+
Metric tracking the area utilization of the design calculated as
|
|
66
|
+
100 * (cellarea/totalarea).""")))
|
|
67
|
+
|
|
68
|
+
schema.insert(
|
|
69
|
+
'logicdepth',
|
|
70
|
+
Parameter(
|
|
71
|
+
'int',
|
|
72
|
+
scope=Scope.JOB,
|
|
73
|
+
shorthelp="Metric: logic depth",
|
|
74
|
+
switch="-metric_logicdepth 'step index <int>'",
|
|
75
|
+
example=[
|
|
76
|
+
"cli: -metric_logicdepth 'place 0 8'",
|
|
77
|
+
"api: chip.set('metric', 'logicdepth', 8, step='place', index=0)"],
|
|
78
|
+
pernode=PerNode.REQUIRED,
|
|
79
|
+
help=trim("""
|
|
80
|
+
Metric tracking the logic depth of the design. This is determined
|
|
81
|
+
by the number of logic gates between the start of the critital timing
|
|
82
|
+
path to the end of the path.""")))
|
|
83
|
+
|
|
84
|
+
for item, description in [
|
|
85
|
+
('peakpower', 'worst case total peak power'),
|
|
86
|
+
('averagepower', 'average workload power'),
|
|
87
|
+
('leakagepower', 'leakage power with rails active but without any dynamic '
|
|
88
|
+
'switching activity')]:
|
|
89
|
+
schema.insert(
|
|
90
|
+
item,
|
|
91
|
+
Parameter(
|
|
92
|
+
'float',
|
|
93
|
+
unit='mw',
|
|
94
|
+
scope=Scope.JOB,
|
|
95
|
+
shorthelp=f"Metric: {item}",
|
|
96
|
+
switch=f"-metric_{item} 'step index <float>'",
|
|
97
|
+
example=[
|
|
98
|
+
f"cli: -metric_{item} 'place 0 0.01'",
|
|
99
|
+
f"api: chip.set('metric', '{item}', 0.01, step='place', index=0)"],
|
|
100
|
+
pernode=PerNode.REQUIRED,
|
|
101
|
+
help=trim(f"""
|
|
102
|
+
Metric tracking the {description} of the design specified on a per step
|
|
103
|
+
and index basis. Power metric depend heavily on the method
|
|
104
|
+
being used for extraction: dynamic vs static, workload
|
|
105
|
+
specification (vcd vs saif), power models, process/voltage/temperature.
|
|
106
|
+
The power {item} metric tries to capture the data that would
|
|
107
|
+
usually be reflected inside a datasheet given the appropriate
|
|
108
|
+
footnote conditions.""")))
|
|
109
|
+
|
|
110
|
+
schema.insert(
|
|
111
|
+
'irdrop',
|
|
112
|
+
Parameter(
|
|
113
|
+
'float',
|
|
114
|
+
unit='mv',
|
|
115
|
+
scope=Scope.JOB,
|
|
116
|
+
shorthelp="Metric: peak IR drop",
|
|
117
|
+
switch="-metric_irdrop 'step index <float>'",
|
|
118
|
+
example=[
|
|
119
|
+
"cli: -metric_irdrop 'place 0 0.05'",
|
|
120
|
+
"api: chip.set('metric', 'irdrop', 0.05, step='place', index=0)"],
|
|
121
|
+
pernode=PerNode.REQUIRED,
|
|
122
|
+
help=trim("""
|
|
123
|
+
Metric tracking the peak IR drop in the design based on extracted
|
|
124
|
+
power and ground rail parasitics, library power models, and
|
|
125
|
+
switching activity. The switching activity calculated on a per
|
|
126
|
+
node basis is taken from one of three possible sources, in order
|
|
127
|
+
of priority: VCD file, SAIF file, 'activityfactor' parameter.""")))
|
|
128
|
+
|
|
129
|
+
for item, description in [
|
|
130
|
+
('holdpaths', 'hold'),
|
|
131
|
+
('setuppaths', 'setup')]:
|
|
132
|
+
schema.insert(
|
|
133
|
+
item,
|
|
134
|
+
Parameter(
|
|
135
|
+
'int',
|
|
136
|
+
scope=Scope.JOB,
|
|
137
|
+
shorthelp=f"Metric: {item}",
|
|
138
|
+
switch=f"-metric_{item} 'step index <int>'",
|
|
139
|
+
example=[
|
|
140
|
+
f"cli: -metric_{item} 'place 0 10'",
|
|
141
|
+
f"api: chip.set('metric', '{item}', 10, step='place', index=0)"],
|
|
142
|
+
pernode=PerNode.REQUIRED,
|
|
143
|
+
help=trim(f"""
|
|
144
|
+
Metric tracking the total number of timing paths violating {description}
|
|
145
|
+
constraints.""")))
|
|
146
|
+
|
|
147
|
+
for item, description in [
|
|
148
|
+
('holdslack', 'worst hold slack (positive or negative)'),
|
|
149
|
+
('holdwns', 'worst negative hold slack (positive values truncated to zero)'),
|
|
150
|
+
('holdtns', 'total negative hold slack (TNS)'),
|
|
151
|
+
('holdskew', 'hold clock skew'),
|
|
152
|
+
('setupslack', 'worst setup slack (positive or negative)'),
|
|
153
|
+
('setupwns', 'worst negative setup slack (positive values truncated to zero)'),
|
|
154
|
+
('setuptns', 'total negative setup slack (TNS)'),
|
|
155
|
+
('setupskew', 'setup clock skew')]:
|
|
156
|
+
schema.insert(
|
|
157
|
+
item,
|
|
158
|
+
Parameter(
|
|
159
|
+
'float',
|
|
160
|
+
unit='ns',
|
|
161
|
+
scope=Scope.JOB,
|
|
162
|
+
shorthelp=f"Metric: {item}",
|
|
163
|
+
switch=f"-metric_{item} 'step index <float>'",
|
|
164
|
+
example=[
|
|
165
|
+
f"cli: -metric_{item} 'place 0 0.01'",
|
|
166
|
+
f"api: chip.set('metric', '{item}', 0.01, step='place', index=0)"],
|
|
167
|
+
pernode=PerNode.REQUIRED,
|
|
168
|
+
help=trim(f"""
|
|
169
|
+
Metric tracking the {description} on a per step and index basis.""")))
|
|
170
|
+
|
|
171
|
+
for item, description in [
|
|
172
|
+
('fmax', 'maximum clock frequency')]:
|
|
173
|
+
schema.insert(
|
|
174
|
+
item,
|
|
175
|
+
Parameter(
|
|
176
|
+
'float',
|
|
177
|
+
unit='Hz',
|
|
178
|
+
scope=Scope.JOB,
|
|
179
|
+
shorthelp=f"Metric: {item}",
|
|
180
|
+
switch=f"-metric_{item} 'step index <float>'",
|
|
181
|
+
example=[
|
|
182
|
+
f"cli: -metric_{item} 'place 0 100e6'",
|
|
183
|
+
f"api: chip.set('metric', '{item}', 100e6, step='place', index=0)"],
|
|
184
|
+
pernode=PerNode.REQUIRED,
|
|
185
|
+
help=trim(f"""
|
|
186
|
+
Metric tracking the {description} on a per step and index basis.""")))
|
|
187
|
+
|
|
188
|
+
for item, description in [
|
|
189
|
+
('macros', 'macros'),
|
|
190
|
+
('cells', 'cell instances'),
|
|
191
|
+
('registers', 'register instances'),
|
|
192
|
+
('buffers', 'buffer instances'),
|
|
193
|
+
('inverters', 'inverter instances'),
|
|
194
|
+
('transistors', 'transistors'),
|
|
195
|
+
('pins', 'pins'),
|
|
196
|
+
('nets', 'nets'),
|
|
197
|
+
('vias', 'vias')]:
|
|
198
|
+
schema.insert(
|
|
199
|
+
item,
|
|
200
|
+
Parameter(
|
|
201
|
+
'int',
|
|
202
|
+
scope=Scope.JOB,
|
|
203
|
+
shorthelp=f"Metric: {item}",
|
|
204
|
+
switch=f"-metric_{item} 'step index <int>'",
|
|
205
|
+
example=[
|
|
206
|
+
f"cli: -metric_{item} 'place 0 100'",
|
|
207
|
+
f"api: chip.set('metric', '{item}', 50, step='place', index=0)"],
|
|
208
|
+
pernode=PerNode.REQUIRED,
|
|
209
|
+
help=trim(f"""
|
|
210
|
+
Metric tracking the total number of {description} in the design
|
|
211
|
+
on a per step and index basis.""")))
|
|
212
|
+
|
|
213
|
+
schema.insert(
|
|
214
|
+
'wirelength',
|
|
215
|
+
Parameter(
|
|
216
|
+
'float',
|
|
217
|
+
unit='um',
|
|
218
|
+
scope=Scope.JOB,
|
|
219
|
+
shorthelp="Metric: wirelength",
|
|
220
|
+
switch="-metric_wirelength 'step index <float>'",
|
|
221
|
+
example=[
|
|
222
|
+
"cli: -metric_wirelength 'place 0 100.0'",
|
|
223
|
+
"api: chip.set('metric', 'wirelength', 50.0, step='place', index=0)"],
|
|
224
|
+
pernode=PerNode.REQUIRED,
|
|
225
|
+
help=trim("""
|
|
226
|
+
Metric tracking the total wirelength of the design on a per step
|
|
227
|
+
and index basis.""")))
|
|
228
|
+
|
|
229
|
+
schema.insert(
|
|
230
|
+
'overflow',
|
|
231
|
+
Parameter(
|
|
232
|
+
'int',
|
|
233
|
+
scope=Scope.JOB,
|
|
234
|
+
shorthelp="Metric: overflow",
|
|
235
|
+
switch="-metric_overflow 'step index <int>'",
|
|
236
|
+
example=[
|
|
237
|
+
"cli: -metric_overflow 'place 0 0'",
|
|
238
|
+
"api: chip.set('metric', 'overflow', 50, step='place', index=0)"],
|
|
239
|
+
pernode=PerNode.REQUIRED,
|
|
240
|
+
help=trim("""
|
|
241
|
+
Metric tracking the total number of overflow tracks for the routing
|
|
242
|
+
on per step and index basis. Any non-zero number suggests an over
|
|
243
|
+
congested design. To analyze where the congestion is occurring
|
|
244
|
+
inspect the router log files for detailed per metal overflow
|
|
245
|
+
reporting and open up the design to find routing hotspots.""")))
|