siliconcompiler 0.34.0__py3-none-any.whl → 0.34.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- siliconcompiler/__init__.py +14 -2
- siliconcompiler/_metadata.py +1 -1
- siliconcompiler/apps/_common.py +1 -1
- siliconcompiler/apps/sc.py +1 -1
- siliconcompiler/apps/sc_issue.py +1 -1
- siliconcompiler/apps/sc_remote.py +3 -3
- siliconcompiler/apps/sc_show.py +3 -3
- siliconcompiler/apps/utils/replay.py +4 -4
- siliconcompiler/checklist.py +203 -2
- 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 +31 -249
- siliconcompiler/data/templates/email/general.j2 +3 -3
- siliconcompiler/data/templates/email/summary.j2 +1 -1
- siliconcompiler/data/templates/issue/README.txt +1 -1
- siliconcompiler/data/templates/report/sc_report.j2 +7 -7
- siliconcompiler/dependencyschema.py +10 -174
- siliconcompiler/design.py +325 -114
- siliconcompiler/flowgraph.py +63 -15
- 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/optimizer/vizier.py +2 -2
- siliconcompiler/package/__init__.py +138 -35
- siliconcompiler/package/github.py +6 -10
- siliconcompiler/packageschema.py +256 -12
- siliconcompiler/pathschema.py +226 -0
- siliconcompiler/pdk.py +5 -5
- siliconcompiler/project.py +459 -0
- siliconcompiler/remote/client.py +18 -12
- siliconcompiler/remote/server.py +2 -2
- siliconcompiler/report/dashboard/cli/__init__.py +6 -6
- siliconcompiler/report/dashboard/cli/board.py +3 -3
- siliconcompiler/report/dashboard/web/components/__init__.py +5 -5
- siliconcompiler/report/dashboard/web/components/flowgraph.py +4 -4
- siliconcompiler/report/dashboard/web/components/graph.py +2 -2
- siliconcompiler/report/dashboard/web/state.py +1 -1
- siliconcompiler/report/dashboard/web/utils/__init__.py +5 -5
- siliconcompiler/report/html_report.py +1 -1
- siliconcompiler/report/report.py +4 -4
- siliconcompiler/report/summary_table.py +2 -2
- siliconcompiler/report/utils.py +5 -5
- siliconcompiler/scheduler/docker.py +4 -10
- siliconcompiler/scheduler/run_node.py +4 -8
- siliconcompiler/scheduler/scheduler.py +18 -24
- siliconcompiler/scheduler/schedulernode.py +161 -143
- siliconcompiler/scheduler/send_messages.py +3 -3
- siliconcompiler/scheduler/slurm.py +5 -3
- siliconcompiler/scheduler/taskscheduler.py +10 -8
- siliconcompiler/schema/__init__.py +0 -2
- siliconcompiler/schema/baseschema.py +148 -26
- siliconcompiler/schema/editableschema.py +14 -6
- siliconcompiler/schema/journal.py +23 -15
- siliconcompiler/schema/namedschema.py +30 -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 +591 -179
- siliconcompiler/tools/__init__.py +2 -0
- siliconcompiler/tools/builtin/_common.py +5 -5
- siliconcompiler/tools/builtin/concatenate.py +5 -5
- siliconcompiler/tools/builtin/minimum.py +4 -4
- siliconcompiler/tools/builtin/mux.py +4 -4
- siliconcompiler/tools/builtin/nop.py +4 -4
- siliconcompiler/tools/builtin/verify.py +7 -7
- siliconcompiler/tools/execute/exec_input.py +1 -1
- siliconcompiler/tools/genfasm/genfasm.py +1 -6
- siliconcompiler/tools/openroad/_apr.py +5 -1
- siliconcompiler/tools/openroad/antenna_repair.py +1 -1
- siliconcompiler/tools/openroad/macro_placement.py +1 -1
- siliconcompiler/tools/openroad/power_grid.py +1 -1
- siliconcompiler/tools/openroad/scripts/common/procs.tcl +5 -0
- siliconcompiler/tools/opensta/timing.py +26 -3
- siliconcompiler/tools/slang/__init__.py +2 -2
- siliconcompiler/tools/surfer/__init__.py +0 -0
- siliconcompiler/tools/surfer/show.py +53 -0
- siliconcompiler/tools/surfer/surfer.py +30 -0
- siliconcompiler/tools/vpr/route.py +27 -14
- siliconcompiler/tools/vpr/vpr.py +23 -6
- siliconcompiler/tools/yosys/__init__.py +1 -1
- siliconcompiler/tools/yosys/scripts/procs.tcl +143 -0
- siliconcompiler/tools/yosys/{sc_synth_asic.tcl → scripts/sc_synth_asic.tcl} +4 -0
- siliconcompiler/tools/yosys/{sc_synth_fpga.tcl → scripts/sc_synth_fpga.tcl} +24 -77
- siliconcompiler/tools/yosys/syn_fpga.py +14 -0
- siliconcompiler/toolscripts/_tools.json +9 -13
- siliconcompiler/toolscripts/rhel9/install-vpr.sh +0 -2
- siliconcompiler/toolscripts/ubuntu22/install-surfer.sh +33 -0
- siliconcompiler/toolscripts/ubuntu24/install-surfer.sh +33 -0
- siliconcompiler/utils/__init__.py +2 -1
- siliconcompiler/utils/flowgraph.py +24 -23
- siliconcompiler/utils/issue.py +23 -29
- siliconcompiler/utils/logging.py +35 -6
- siliconcompiler/utils/showtools.py +6 -1
- {siliconcompiler-0.34.0.dist-info → siliconcompiler-0.34.2.dist-info}/METADATA +15 -25
- {siliconcompiler-0.34.0.dist-info → siliconcompiler-0.34.2.dist-info}/RECORD +109 -97
- siliconcompiler/schema/packageschema.py +0 -101
- siliconcompiler/tools/yosys/procs.tcl +0 -71
- siliconcompiler/toolscripts/rhel9/install-yosys-parmys.sh +0 -68
- siliconcompiler/toolscripts/ubuntu22/install-yosys-parmys.sh +0 -68
- siliconcompiler/toolscripts/ubuntu24/install-yosys-parmys.sh +0 -68
- /siliconcompiler/tools/yosys/{sc_lec.tcl → scripts/sc_lec.tcl} +0 -0
- /siliconcompiler/tools/yosys/{sc_screenshot.tcl → scripts/sc_screenshot.tcl} +0 -0
- /siliconcompiler/tools/yosys/{syn_strategies.tcl → scripts/syn_strategies.tcl} +0 -0
- {siliconcompiler-0.34.0.dist-info → siliconcompiler-0.34.2.dist-info}/WHEEL +0 -0
- {siliconcompiler-0.34.0.dist-info → siliconcompiler-0.34.2.dist-info}/entry_points.txt +0 -0
- {siliconcompiler-0.34.0.dist-info → siliconcompiler-0.34.2.dist-info}/licenses/LICENSE +0 -0
- {siliconcompiler-0.34.0.dist-info → siliconcompiler-0.34.2.dist-info}/top_level.txt +0 -0
siliconcompiler/flowgraph.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import inspect
|
|
2
|
+
import importlib
|
|
2
3
|
|
|
3
4
|
from siliconcompiler import Schema
|
|
4
5
|
from siliconcompiler.schema import BaseSchema, NamedSchema
|
|
@@ -9,8 +10,9 @@ from siliconcompiler import NodeStatus
|
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
class FlowgraphSchema(NamedSchema):
|
|
12
|
-
def __init__(self, name):
|
|
13
|
-
super().__init__(
|
|
13
|
+
def __init__(self, name=None):
|
|
14
|
+
super().__init__()
|
|
15
|
+
self.set_name(name)
|
|
14
16
|
|
|
15
17
|
schema = EditableSchema(self)
|
|
16
18
|
schema.insert("default", "default", FlowgraphNodeSchema())
|
|
@@ -30,6 +32,8 @@ class FlowgraphSchema(NamedSchema):
|
|
|
30
32
|
|
|
31
33
|
self.__cache_node_outputs = None
|
|
32
34
|
|
|
35
|
+
self.__cache_tasks = None
|
|
36
|
+
|
|
33
37
|
def node(self, step, task, index=0):
|
|
34
38
|
'''
|
|
35
39
|
Creates a flowgraph node.
|
|
@@ -64,6 +68,11 @@ class FlowgraphSchema(NamedSchema):
|
|
|
64
68
|
if index in (Schema.GLOBAL_KEY, 'default'):
|
|
65
69
|
raise ValueError(f"{index} is a reserved name")
|
|
66
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
|
+
|
|
67
76
|
# Determine task name and module
|
|
68
77
|
task_module = None
|
|
69
78
|
if isinstance(task, str):
|
|
@@ -114,7 +123,7 @@ class FlowgraphSchema(NamedSchema):
|
|
|
114
123
|
|
|
115
124
|
for step, index in [(head, head_index), (tail, tail_index)]:
|
|
116
125
|
if not self.valid(step, index):
|
|
117
|
-
raise ValueError(f"{step}{index} is not a defined node in {self.name()}.")
|
|
126
|
+
raise ValueError(f"{step}/{index} is not a defined node in {self.name()}.")
|
|
118
127
|
|
|
119
128
|
tail_node = (tail, tail_index)
|
|
120
129
|
if tail_node in self.get(head, head_index, 'input'):
|
|
@@ -183,7 +192,7 @@ class FlowgraphSchema(NamedSchema):
|
|
|
183
192
|
before_index = str(before_index)
|
|
184
193
|
|
|
185
194
|
if (before_step, before_index) not in self.get_nodes():
|
|
186
|
-
raise ValueError(f'{before_step}{before_index} is not a valid node in {self.name()}')
|
|
195
|
+
raise ValueError(f'{before_step}/{before_index} is not a valid node in {self.name()}')
|
|
187
196
|
|
|
188
197
|
# add the node
|
|
189
198
|
self.node(step, task, index=index)
|
|
@@ -388,7 +397,7 @@ class FlowgraphSchema(NamedSchema):
|
|
|
388
397
|
index = str(index)
|
|
389
398
|
|
|
390
399
|
if (step, index) not in self.get_nodes():
|
|
391
|
-
raise ValueError(f"{step}{index} is not a valid node")
|
|
400
|
+
raise ValueError(f"{step}/{index} is not a valid node")
|
|
392
401
|
|
|
393
402
|
if self.__cache_node_outputs is not None:
|
|
394
403
|
return self.__cache_node_outputs[(step, index)]
|
|
@@ -464,15 +473,15 @@ class FlowgraphSchema(NamedSchema):
|
|
|
464
473
|
if input_nodes.count(node) > 1:
|
|
465
474
|
in_step, in_index = node
|
|
466
475
|
if logger:
|
|
467
|
-
logger.error(f'Duplicate edge from {in_step}{in_index} to '
|
|
468
|
-
f'{step}{index} in the {self.name()} flowgraph')
|
|
476
|
+
logger.error(f'Duplicate edge from {in_step}/{in_index} to '
|
|
477
|
+
f'{step}/{index} in the {self.name()} flowgraph')
|
|
469
478
|
error = True
|
|
470
479
|
|
|
471
480
|
diff_nodes = check_nodes.difference(self.get_nodes())
|
|
472
481
|
if diff_nodes:
|
|
473
482
|
if logger:
|
|
474
483
|
for step, index in diff_nodes:
|
|
475
|
-
logger.error(f'{step}{index} is missing in the {self.name()} flowgraph')
|
|
484
|
+
logger.error(f'{step}/{index} is missing in the {self.name()} flowgraph')
|
|
476
485
|
error = True
|
|
477
486
|
|
|
478
487
|
# Detect missing definitions
|
|
@@ -480,7 +489,7 @@ class FlowgraphSchema(NamedSchema):
|
|
|
480
489
|
for item in ('tool', 'task', 'taskmodule'):
|
|
481
490
|
if not self.get(step, index, item):
|
|
482
491
|
if logger:
|
|
483
|
-
logger.error(f'{step}{index} is missing a {item} definition in the '
|
|
492
|
+
logger.error(f'{step}/{index} is missing a {item} definition in the '
|
|
484
493
|
f'{self.name()} flowgraph')
|
|
485
494
|
error = True
|
|
486
495
|
|
|
@@ -490,11 +499,50 @@ class FlowgraphSchema(NamedSchema):
|
|
|
490
499
|
if loop_path:
|
|
491
500
|
error = True
|
|
492
501
|
if logger:
|
|
493
|
-
loop_path = [f"{step}{index}" for step, index in loop_path]
|
|
502
|
+
loop_path = [f"{step}/{index}" for step, index in loop_path]
|
|
494
503
|
logger.error(f"{' -> '.join(loop_path)} forms a loop in {self.name()}")
|
|
495
504
|
|
|
496
505
|
return not error
|
|
497
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
|
+
|
|
518
|
+
def get_task_module(self, step, index):
|
|
519
|
+
"""
|
|
520
|
+
Returns the module for a given task
|
|
521
|
+
|
|
522
|
+
Args:
|
|
523
|
+
step (str): Step name
|
|
524
|
+
index (int/str): Step index
|
|
525
|
+
"""
|
|
526
|
+
|
|
527
|
+
index = str(index)
|
|
528
|
+
|
|
529
|
+
if (step, index) not in self.get_nodes():
|
|
530
|
+
raise ValueError(f"{step}/{index} is not a valid node in {self.name()}.")
|
|
531
|
+
|
|
532
|
+
return self.__get_task_module(self.get(step, index, 'taskmodule'))
|
|
533
|
+
|
|
534
|
+
def get_all_tasks(self):
|
|
535
|
+
'''
|
|
536
|
+
Returns all the task modules used in this flow
|
|
537
|
+
|
|
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
|
|
545
|
+
|
|
498
546
|
|
|
499
547
|
class RuntimeFlowgraph:
|
|
500
548
|
'''
|
|
@@ -649,13 +697,13 @@ class RuntimeFlowgraph:
|
|
|
649
697
|
index = str(index)
|
|
650
698
|
|
|
651
699
|
if (step, index) not in self.get_nodes():
|
|
652
|
-
raise ValueError(f"{step}{index} is not a valid node")
|
|
700
|
+
raise ValueError(f"{step}/{index} is not a valid node")
|
|
653
701
|
|
|
654
702
|
return tuple(sorted(self.__walk_graph((step, str(index)), reverse=False)))
|
|
655
703
|
|
|
656
704
|
def get_node_inputs(self, step, index, record=None):
|
|
657
705
|
if (step, index) not in self.get_nodes():
|
|
658
|
-
raise ValueError(f"{step}{index} is not a valid node")
|
|
706
|
+
raise ValueError(f"{step}/{index} is not a valid node")
|
|
659
707
|
|
|
660
708
|
if record is None:
|
|
661
709
|
inputs = set()
|
|
@@ -722,7 +770,7 @@ class RuntimeFlowgraph:
|
|
|
722
770
|
# Check for undefined prunes
|
|
723
771
|
for step, index in sorted(prune_nodes.difference(flow.get_nodes())):
|
|
724
772
|
if logger:
|
|
725
|
-
logger.error(f'{step}{index} is not defined in the {flow.name()} flowgraph')
|
|
773
|
+
logger.error(f'{step}/{index} is not defined in the {flow.name()} flowgraph')
|
|
726
774
|
error = True
|
|
727
775
|
|
|
728
776
|
if not error:
|
|
@@ -763,9 +811,9 @@ class RuntimeFlowgraph:
|
|
|
763
811
|
if entrynode in runtime.__walk_graph(exitnode):
|
|
764
812
|
found = True
|
|
765
813
|
if not found:
|
|
766
|
-
exits = ",".join([f"{step}{index}"
|
|
814
|
+
exits = ",".join([f"{step}/{index}"
|
|
767
815
|
for step, index in runtime.get_exit_nodes()])
|
|
768
|
-
missing.append(f'no path from {entrynode[0]}{entrynode[1]} to {exits} '
|
|
816
|
+
missing.append(f'no path from {entrynode[0]}/{entrynode[1]} to {exits} '
|
|
769
817
|
f'in the {flow.name()} flowgraph')
|
|
770
818
|
if found:
|
|
771
819
|
found_any = True
|
|
@@ -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.""")))
|