siliconcompiler 0.32.3__py3-none-any.whl → 0.33.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- siliconcompiler/__init__.py +19 -2
- siliconcompiler/_metadata.py +1 -1
- siliconcompiler/apps/sc.py +2 -2
- siliconcompiler/apps/sc_install.py +3 -3
- siliconcompiler/apps/sc_issue.py +1 -1
- siliconcompiler/apps/sc_remote.py +4 -4
- siliconcompiler/apps/sc_show.py +2 -2
- siliconcompiler/apps/utils/replay.py +5 -3
- siliconcompiler/asic.py +120 -0
- siliconcompiler/checklist.py +150 -0
- siliconcompiler/core.py +267 -289
- siliconcompiler/flowgraph.py +803 -515
- siliconcompiler/fpga.py +84 -0
- siliconcompiler/metric.py +420 -0
- siliconcompiler/optimizer/vizier.py +2 -3
- siliconcompiler/package/__init__.py +29 -6
- siliconcompiler/pdk.py +415 -0
- siliconcompiler/record.py +449 -0
- siliconcompiler/remote/client.py +6 -3
- siliconcompiler/remote/schema.py +116 -112
- siliconcompiler/remote/server.py +3 -5
- siliconcompiler/report/dashboard/cli/__init__.py +13 -722
- siliconcompiler/report/dashboard/cli/board.py +895 -0
- siliconcompiler/report/dashboard/web/__init__.py +10 -10
- siliconcompiler/report/dashboard/web/components/__init__.py +5 -4
- siliconcompiler/report/dashboard/web/components/flowgraph.py +3 -3
- siliconcompiler/report/dashboard/web/components/graph.py +6 -3
- siliconcompiler/report/dashboard/web/state.py +1 -1
- siliconcompiler/report/dashboard/web/utils/__init__.py +4 -3
- siliconcompiler/report/html_report.py +2 -3
- siliconcompiler/report/report.py +13 -7
- siliconcompiler/report/summary_image.py +1 -1
- siliconcompiler/report/summary_table.py +3 -3
- siliconcompiler/report/utils.py +11 -10
- siliconcompiler/scheduler/__init__.py +145 -280
- siliconcompiler/scheduler/run_node.py +2 -1
- siliconcompiler/scheduler/send_messages.py +4 -4
- siliconcompiler/scheduler/slurm.py +2 -2
- siliconcompiler/schema/__init__.py +19 -2
- siliconcompiler/schema/baseschema.py +493 -0
- siliconcompiler/schema/cmdlineschema.py +250 -0
- siliconcompiler/{sphinx_ext → schema/docs}/__init__.py +3 -1
- siliconcompiler/{sphinx_ext → schema/docs}/dynamicgen.py +63 -81
- siliconcompiler/{sphinx_ext → schema/docs}/schemagen.py +73 -85
- siliconcompiler/{sphinx_ext → schema/docs}/utils.py +12 -13
- siliconcompiler/schema/editableschema.py +136 -0
- siliconcompiler/schema/journalingschema.py +238 -0
- siliconcompiler/schema/namedschema.py +41 -0
- siliconcompiler/schema/packageschema.py +101 -0
- siliconcompiler/schema/parameter.py +791 -0
- siliconcompiler/schema/parametertype.py +323 -0
- siliconcompiler/schema/parametervalue.py +736 -0
- siliconcompiler/schema/safeschema.py +37 -0
- siliconcompiler/schema/schema_cfg.py +109 -1789
- siliconcompiler/schema/utils.py +5 -68
- siliconcompiler/schema_obj.py +119 -0
- siliconcompiler/tool.py +1308 -0
- siliconcompiler/tools/_common/__init__.py +6 -10
- siliconcompiler/tools/_common/sdc/sc_constraints.sdc +1 -1
- siliconcompiler/tools/bluespec/convert.py +7 -7
- siliconcompiler/tools/builtin/_common.py +1 -1
- siliconcompiler/tools/builtin/concatenate.py +2 -2
- siliconcompiler/tools/builtin/minimum.py +1 -1
- siliconcompiler/tools/builtin/mux.py +2 -1
- siliconcompiler/tools/builtin/nop.py +1 -1
- siliconcompiler/tools/builtin/verify.py +6 -4
- siliconcompiler/tools/chisel/convert.py +4 -4
- siliconcompiler/tools/genfasm/bitstream.py +3 -3
- siliconcompiler/tools/ghdl/convert.py +1 -1
- siliconcompiler/tools/icarus/compile.py +4 -4
- siliconcompiler/tools/icepack/bitstream.py +6 -1
- siliconcompiler/tools/klayout/convert_drc_db.py +5 -0
- siliconcompiler/tools/klayout/klayout_export.py +0 -1
- siliconcompiler/tools/klayout/klayout_utils.py +3 -10
- siliconcompiler/tools/nextpnr/apr.py +6 -1
- siliconcompiler/tools/nextpnr/nextpnr.py +4 -4
- siliconcompiler/tools/openroad/_apr.py +13 -0
- siliconcompiler/tools/openroad/rdlroute.py +3 -3
- siliconcompiler/tools/openroad/scripts/apr/postamble.tcl +1 -1
- siliconcompiler/tools/openroad/scripts/apr/preamble.tcl +5 -5
- siliconcompiler/tools/openroad/scripts/apr/sc_antenna_repair.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_clock_tree_synthesis.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_detailed_placement.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_detailed_route.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_endcap_tapcell_insertion.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_fillercell_insertion.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_fillmetal_insertion.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_global_placement.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_global_route.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_init_floorplan.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_macro_placement.tcl +3 -3
- siliconcompiler/tools/openroad/scripts/apr/sc_metrics.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_pin_placement.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_power_grid.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_repair_design.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_repair_timing.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_write_data.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/common/procs.tcl +57 -1
- siliconcompiler/tools/openroad/scripts/common/screenshot.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/common/write_images.tcl +28 -3
- siliconcompiler/tools/openroad/scripts/sc_rcx.tcl +1 -1
- siliconcompiler/tools/openroad/scripts/sc_rdlroute.tcl +3 -3
- siliconcompiler/tools/openroad/scripts/sc_show.tcl +6 -6
- siliconcompiler/tools/slang/__init__.py +10 -10
- siliconcompiler/tools/surelog/parse.py +4 -4
- siliconcompiler/tools/sv2v/convert.py +20 -3
- siliconcompiler/tools/verilator/compile.py +2 -2
- siliconcompiler/tools/verilator/verilator.py +3 -3
- siliconcompiler/tools/vpr/place.py +1 -1
- siliconcompiler/tools/vpr/route.py +4 -4
- siliconcompiler/tools/vpr/screenshot.py +1 -1
- siliconcompiler/tools/vpr/show.py +5 -5
- siliconcompiler/tools/vpr/vpr.py +24 -24
- siliconcompiler/tools/xdm/convert.py +2 -2
- siliconcompiler/tools/xyce/simulate.py +1 -1
- siliconcompiler/tools/yosys/sc_synth_asic.tcl +74 -68
- siliconcompiler/tools/yosys/syn_asic.py +2 -2
- siliconcompiler/toolscripts/_tools.json +7 -7
- siliconcompiler/toolscripts/ubuntu22/install-vpr.sh +0 -2
- siliconcompiler/toolscripts/ubuntu24/install-vpr.sh +0 -2
- siliconcompiler/utils/__init__.py +8 -112
- siliconcompiler/utils/flowgraph.py +339 -0
- siliconcompiler/{issue.py → utils/issue.py} +4 -3
- siliconcompiler/utils/logging.py +1 -2
- {siliconcompiler-0.32.3.dist-info → siliconcompiler-0.33.0.dist-info}/METADATA +9 -8
- {siliconcompiler-0.32.3.dist-info → siliconcompiler-0.33.0.dist-info}/RECORD +151 -134
- {siliconcompiler-0.32.3.dist-info → siliconcompiler-0.33.0.dist-info}/WHEEL +1 -1
- {siliconcompiler-0.32.3.dist-info → siliconcompiler-0.33.0.dist-info}/entry_points.txt +8 -8
- siliconcompiler/schema/schema_obj.py +0 -1936
- siliconcompiler/toolscripts/ubuntu20/install-vpr.sh +0 -29
- siliconcompiler/toolscripts/ubuntu20/install-yosys-parmys.sh +0 -61
- /siliconcompiler/{templates → data/templates}/__init__.py +0 -0
- /siliconcompiler/{templates → data/templates}/email/__init__.py +0 -0
- /siliconcompiler/{templates → data/templates}/email/general.j2 +0 -0
- /siliconcompiler/{templates → data/templates}/email/summary.j2 +0 -0
- /siliconcompiler/{templates → data/templates}/issue/README.txt +0 -0
- /siliconcompiler/{templates → data/templates}/issue/__init__.py +0 -0
- /siliconcompiler/{templates → data/templates}/issue/run.sh +0 -0
- /siliconcompiler/{templates → data/templates}/replay/replay.py.j2 +0 -0
- /siliconcompiler/{templates → data/templates}/replay/replay.sh.j2 +0 -0
- /siliconcompiler/{templates → data/templates}/replay/requirements.txt +0 -0
- /siliconcompiler/{templates → data/templates}/replay/setup.sh +0 -0
- /siliconcompiler/{templates → data/templates}/report/__init__.py +0 -0
- /siliconcompiler/{templates → data/templates}/report/bootstrap.min.css +0 -0
- /siliconcompiler/{templates → data/templates}/report/bootstrap.min.js +0 -0
- /siliconcompiler/{templates → data/templates}/report/bootstrap_LICENSE.md +0 -0
- /siliconcompiler/{templates → data/templates}/report/sc_report.j2 +0 -0
- /siliconcompiler/{templates → data/templates}/slurm/__init__.py +0 -0
- /siliconcompiler/{templates → data/templates}/slurm/run.sh +0 -0
- /siliconcompiler/{templates → data/templates}/tcl/__init__.py +0 -0
- /siliconcompiler/{templates → data/templates}/tcl/manifest.tcl.j2 +0 -0
- /siliconcompiler/{units.py → utils/units.py} +0 -0
- {siliconcompiler-0.32.3.dist-info → siliconcompiler-0.33.0.dist-info}/licenses/LICENSE +0 -0
- {siliconcompiler-0.32.3.dist-info → siliconcompiler-0.33.0.dist-info}/top_level.txt +0 -0
siliconcompiler/fpga.py
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
from siliconcompiler.schema import BaseSchema
|
|
2
|
+
from siliconcompiler.schema import EditableSchema, Parameter, Scope
|
|
3
|
+
from siliconcompiler.schema.utils import trim
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class FPGASchema(BaseSchema):
|
|
7
|
+
def __init__(self):
|
|
8
|
+
super().__init__()
|
|
9
|
+
|
|
10
|
+
schema_fpga(self)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
###############################################################################
|
|
14
|
+
# FPGA
|
|
15
|
+
###############################################################################
|
|
16
|
+
def schema_fpga(schema):
|
|
17
|
+
schema = EditableSchema(schema)
|
|
18
|
+
|
|
19
|
+
partname = 'default'
|
|
20
|
+
key = 'default'
|
|
21
|
+
|
|
22
|
+
schema.insert(
|
|
23
|
+
'partname',
|
|
24
|
+
Parameter(
|
|
25
|
+
'str',
|
|
26
|
+
scope=Scope.GLOBAL,
|
|
27
|
+
shorthelp="FPGA: part name",
|
|
28
|
+
switch="-fpga_partname <str>",
|
|
29
|
+
example=["cli: -fpga_partname fpga64k",
|
|
30
|
+
"api: chip.set('fpga', 'partname', 'fpga64k')"],
|
|
31
|
+
help=trim("""
|
|
32
|
+
Complete part name used as a device target by the FPGA compilation
|
|
33
|
+
tool. The part name must be an exact string match to the partname
|
|
34
|
+
hard coded within the FPGA EDA tool.""")))
|
|
35
|
+
|
|
36
|
+
schema.insert(
|
|
37
|
+
partname, 'vendor',
|
|
38
|
+
Parameter(
|
|
39
|
+
'str',
|
|
40
|
+
scope=Scope.GLOBAL,
|
|
41
|
+
shorthelp="FPGA: vendor name",
|
|
42
|
+
switch="-fpga_vendor 'partname <str>'",
|
|
43
|
+
example=["cli: -fpga_vendor 'fpga64k acme'",
|
|
44
|
+
"api: chip.set('fpga', 'fpga64k', 'vendor', 'acme')"],
|
|
45
|
+
help=trim("""
|
|
46
|
+
Name of the FPGA vendor for the FPGA partname.""")))
|
|
47
|
+
|
|
48
|
+
schema.insert(
|
|
49
|
+
partname, 'lutsize',
|
|
50
|
+
Parameter(
|
|
51
|
+
'int',
|
|
52
|
+
scope=Scope.GLOBAL,
|
|
53
|
+
shorthelp="FPGA: lutsize",
|
|
54
|
+
switch="-fpga_lutsize 'partname <int>'",
|
|
55
|
+
example=["cli: -fpga_lutsize 'fpga64k 4'",
|
|
56
|
+
"api: chip.set('fpga', 'fpga64k', 'lutsize', '4')"],
|
|
57
|
+
help=trim("""
|
|
58
|
+
Specify the number of inputs in each lookup table (LUT) for the
|
|
59
|
+
FPGA partname. For architectures with fracturable LUTs, this is
|
|
60
|
+
the number of inputs of the unfractured LUT.""")))
|
|
61
|
+
|
|
62
|
+
schema.insert(
|
|
63
|
+
partname, 'file', key,
|
|
64
|
+
Parameter(
|
|
65
|
+
'[file]',
|
|
66
|
+
scope=Scope.GLOBAL,
|
|
67
|
+
shorthelp="FPGA: file",
|
|
68
|
+
switch="-fpga_file 'partname key <file>'",
|
|
69
|
+
example=["cli: -fpga_file 'fpga64k archfile my_arch.xml'",
|
|
70
|
+
"api: chip.set('fpga', 'fpga64k', 'file', 'archfile', 'my_arch.xml')"],
|
|
71
|
+
help=trim("""
|
|
72
|
+
Specify a file for the FPGA partname.""")))
|
|
73
|
+
|
|
74
|
+
schema.insert(
|
|
75
|
+
partname, 'var', key,
|
|
76
|
+
Parameter(
|
|
77
|
+
'[str]',
|
|
78
|
+
scope=Scope.GLOBAL,
|
|
79
|
+
shorthelp="FPGA: var",
|
|
80
|
+
switch="-fpga_var 'partname key <str>'",
|
|
81
|
+
example=["cli: -fpga_var 'fpga64k channelwidth 100'",
|
|
82
|
+
"api: chip.set('fpga', 'fpga64k', 'var', 'channelwidth', '100')"],
|
|
83
|
+
help=trim("""
|
|
84
|
+
Specify a variable value for the FPGA partname.""")))
|
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
from siliconcompiler.schema import BaseSchema
|
|
2
|
+
from siliconcompiler.schema import EditableSchema, Parameter, PerNode, Scope
|
|
3
|
+
from siliconcompiler.schema.utils import trim
|
|
4
|
+
|
|
5
|
+
from siliconcompiler.utils.units import convert
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class MetricSchema(BaseSchema):
|
|
9
|
+
def __init__(self):
|
|
10
|
+
super().__init__()
|
|
11
|
+
|
|
12
|
+
schema_metric(self)
|
|
13
|
+
|
|
14
|
+
def clear(self, step, index):
|
|
15
|
+
'''
|
|
16
|
+
Clear all saved metrics for a given step and index
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
step (str): Step name to clear.
|
|
20
|
+
index (str/int): Index name to clear.
|
|
21
|
+
'''
|
|
22
|
+
for metric in self.getkeys():
|
|
23
|
+
self.unset(metric, step=step, index=str(index))
|
|
24
|
+
|
|
25
|
+
def record(self, step, index, metric, value, unit=None):
|
|
26
|
+
"""
|
|
27
|
+
Record a metric
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
step (str): step to record
|
|
31
|
+
index (str/int): index to record
|
|
32
|
+
metric (str): name of metric
|
|
33
|
+
value (int/float): value to record
|
|
34
|
+
unit (str): unit associated with value
|
|
35
|
+
"""
|
|
36
|
+
metric_unit = self.get(metric, field='unit')
|
|
37
|
+
|
|
38
|
+
if not metric_unit and unit:
|
|
39
|
+
raise ValueError(f"{metric} does not have a unit, but {unit} was supplied")
|
|
40
|
+
|
|
41
|
+
if metric_unit:
|
|
42
|
+
value = convert(value, from_unit=unit, to_unit=metric_unit)
|
|
43
|
+
|
|
44
|
+
return self.set(metric, value, step=step, index=str(index))
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
###########################################################################
|
|
48
|
+
# Metrics to Track
|
|
49
|
+
###########################################################################
|
|
50
|
+
def schema_metric(schema):
|
|
51
|
+
schema = EditableSchema(schema)
|
|
52
|
+
|
|
53
|
+
metrics = {'errors': 'errors',
|
|
54
|
+
'warnings': 'warnings',
|
|
55
|
+
'drvs': 'design rule violations',
|
|
56
|
+
'drcs': 'physical design rule violations',
|
|
57
|
+
'unconstrained': 'unconstrained timing paths'}
|
|
58
|
+
|
|
59
|
+
for item, description in metrics.items():
|
|
60
|
+
schema.insert(
|
|
61
|
+
item,
|
|
62
|
+
Parameter(
|
|
63
|
+
'int',
|
|
64
|
+
scope=Scope.JOB,
|
|
65
|
+
shorthelp=f"Metric: total {item}",
|
|
66
|
+
switch=f"-metric_{item} 'step index <int>'",
|
|
67
|
+
example=[
|
|
68
|
+
f"cli: -metric_{item} 'dfm 0 0'",
|
|
69
|
+
f"api: chip.set('metric', '{item}', 0, step='dfm', index=0)"],
|
|
70
|
+
pernode=PerNode.REQUIRED,
|
|
71
|
+
help=trim(f"""Metric tracking the total number of {description} on a
|
|
72
|
+
per step and index basis.""")))
|
|
73
|
+
|
|
74
|
+
schema.insert(
|
|
75
|
+
'coverage',
|
|
76
|
+
Parameter(
|
|
77
|
+
'float',
|
|
78
|
+
unit='%',
|
|
79
|
+
scope=Scope.JOB,
|
|
80
|
+
shorthelp="Metric: coverage",
|
|
81
|
+
switch="-metric_coverage 'step index <float>'",
|
|
82
|
+
example=[
|
|
83
|
+
"cli: -metric_coverage 'place 0 99.9'",
|
|
84
|
+
"api: chip.set('metric', 'coverage', 99.9, step='place', index=0)"],
|
|
85
|
+
pernode=PerNode.REQUIRED,
|
|
86
|
+
help=trim("""
|
|
87
|
+
Metric tracking the test coverage in the design expressed as a percentage
|
|
88
|
+
with 100 meaning full coverage. The meaning of the metric depends on the
|
|
89
|
+
task being executed. It can refer to code coverage, feature coverage,
|
|
90
|
+
stuck at fault coverage.""")))
|
|
91
|
+
|
|
92
|
+
schema.insert(
|
|
93
|
+
'security',
|
|
94
|
+
Parameter(
|
|
95
|
+
'float',
|
|
96
|
+
unit='%',
|
|
97
|
+
scope=Scope.JOB,
|
|
98
|
+
shorthelp="Metric: security",
|
|
99
|
+
switch="-metric_security 'step index <float>'",
|
|
100
|
+
example=[
|
|
101
|
+
"cli: -metric_security 'place 0 100'",
|
|
102
|
+
"api: chip.set('metric', 'security', 100, step='place', index=0)"],
|
|
103
|
+
pernode=PerNode.REQUIRED,
|
|
104
|
+
help=trim("""
|
|
105
|
+
Metric tracking the level of security (1/vulnerability) of the design.
|
|
106
|
+
A completely secure design would have a score of 100. There is no
|
|
107
|
+
absolute scale for the security metrics (like with power, area, etc)
|
|
108
|
+
so the metric will be task and tool dependent.""")))
|
|
109
|
+
|
|
110
|
+
metrics = {'luts': 'FPGA LUTs used',
|
|
111
|
+
'dsps': 'FPGA DSP slices used',
|
|
112
|
+
'brams': 'FPGA BRAM tiles used'}
|
|
113
|
+
|
|
114
|
+
for item, description in metrics.items():
|
|
115
|
+
schema.insert(
|
|
116
|
+
item,
|
|
117
|
+
Parameter(
|
|
118
|
+
'int',
|
|
119
|
+
scope=Scope.JOB,
|
|
120
|
+
shorthelp=f"Metric: {description}",
|
|
121
|
+
switch=f"-metric_{item} 'step index <int>'",
|
|
122
|
+
example=[
|
|
123
|
+
f"cli: -metric_{item} 'place 0 100'",
|
|
124
|
+
f"api: chip.set('metric', '{item}', 100, step='place', index=0)"],
|
|
125
|
+
pernode=PerNode.REQUIRED,
|
|
126
|
+
help=trim(f"""
|
|
127
|
+
Metric tracking the total {description} used by the design as reported
|
|
128
|
+
by the implementation tool. There is no standardized definition
|
|
129
|
+
for this metric across vendors, so metric comparisons can
|
|
130
|
+
generally only be done between runs on identical tools and
|
|
131
|
+
device families.""")))
|
|
132
|
+
|
|
133
|
+
metrics = {'cellarea': 'cell area (ignoring fillers)',
|
|
134
|
+
'totalarea': 'physical die area',
|
|
135
|
+
'macroarea': 'macro cell area',
|
|
136
|
+
'padcellarea': 'io pad cell area',
|
|
137
|
+
'stdcellarea': 'standard cell area'}
|
|
138
|
+
|
|
139
|
+
for item, description in metrics.items():
|
|
140
|
+
schema.insert(
|
|
141
|
+
item,
|
|
142
|
+
Parameter(
|
|
143
|
+
'float',
|
|
144
|
+
unit='um^2',
|
|
145
|
+
scope=Scope.JOB,
|
|
146
|
+
shorthelp=f"Metric: {item}",
|
|
147
|
+
switch=f"-metric_{item} 'step index <float>'",
|
|
148
|
+
example=[
|
|
149
|
+
f"cli: -metric_{item} 'place 0 100.00'",
|
|
150
|
+
f"api: chip.set('metric', '{item}', 100.00, step='place', index=0)"],
|
|
151
|
+
pernode=PerNode.REQUIRED,
|
|
152
|
+
help=trim(f"""
|
|
153
|
+
Metric tracking the total {description} occupied by the design.""")))
|
|
154
|
+
|
|
155
|
+
schema.insert(
|
|
156
|
+
'utilization',
|
|
157
|
+
Parameter(
|
|
158
|
+
'float',
|
|
159
|
+
unit='%',
|
|
160
|
+
scope=Scope.JOB,
|
|
161
|
+
shorthelp="Metric: area utilization",
|
|
162
|
+
switch="-metric_utilization 'step index <float>'",
|
|
163
|
+
example=[
|
|
164
|
+
"cli: -metric_utilization 'place 0 50.00'",
|
|
165
|
+
"api: chip.set('metric', 'utilization', 50.00, step='place', index=0)"],
|
|
166
|
+
pernode=PerNode.REQUIRED,
|
|
167
|
+
help=trim("""
|
|
168
|
+
Metric tracking the area utilization of the design calculated as
|
|
169
|
+
100 * (cellarea/totalarea).""")))
|
|
170
|
+
|
|
171
|
+
schema.insert(
|
|
172
|
+
'logicdepth',
|
|
173
|
+
Parameter(
|
|
174
|
+
'int',
|
|
175
|
+
scope=Scope.JOB,
|
|
176
|
+
shorthelp="Metric: logic depth",
|
|
177
|
+
switch="-metric_logicdepth 'step index <int>'",
|
|
178
|
+
example=[
|
|
179
|
+
"cli: -metric_logicdepth 'place 0 8'",
|
|
180
|
+
"api: chip.set('metric', 'logicdepth', 8, step='place', index=0)"],
|
|
181
|
+
pernode=PerNode.REQUIRED,
|
|
182
|
+
help=trim("""
|
|
183
|
+
Metric tracking the logic depth of the design. This is determined
|
|
184
|
+
by the number of logic gates between the start of the critital timing
|
|
185
|
+
path to the end of the path.""")))
|
|
186
|
+
|
|
187
|
+
metrics = {'peakpower': 'worst case total peak power',
|
|
188
|
+
'averagepower': 'average workload power',
|
|
189
|
+
'leakagepower': 'leakage power with rails active but without any dynamic '
|
|
190
|
+
'switching activity'}
|
|
191
|
+
|
|
192
|
+
for item, description in metrics.items():
|
|
193
|
+
schema.insert(
|
|
194
|
+
item,
|
|
195
|
+
Parameter(
|
|
196
|
+
'float',
|
|
197
|
+
unit='mw',
|
|
198
|
+
scope=Scope.JOB,
|
|
199
|
+
shorthelp=f"Metric: {item}",
|
|
200
|
+
switch=f"-metric_{item} 'step index <float>'",
|
|
201
|
+
example=[
|
|
202
|
+
f"cli: -metric_{item} 'place 0 0.01'",
|
|
203
|
+
f"api: chip.set('metric', '{item}', 0.01, step='place', index=0)"],
|
|
204
|
+
pernode=PerNode.REQUIRED,
|
|
205
|
+
help=trim(f"""
|
|
206
|
+
Metric tracking the {description} of the design specified on a per step
|
|
207
|
+
and index basis. Power metric depend heavily on the method
|
|
208
|
+
being used for extraction: dynamic vs static, workload
|
|
209
|
+
specification (vcd vs saif), power models, process/voltage/temperature.
|
|
210
|
+
The power {item} metric tries to capture the data that would
|
|
211
|
+
usually be reflected inside a datasheet given the appropriate
|
|
212
|
+
footnote conditions.""")))
|
|
213
|
+
|
|
214
|
+
schema.insert(
|
|
215
|
+
'irdrop',
|
|
216
|
+
Parameter(
|
|
217
|
+
'float',
|
|
218
|
+
unit='mv',
|
|
219
|
+
scope=Scope.JOB,
|
|
220
|
+
shorthelp="Metric: peak IR drop",
|
|
221
|
+
switch="-metric_irdrop 'step index <float>'",
|
|
222
|
+
example=[
|
|
223
|
+
"cli: -metric_irdrop 'place 0 0.05'",
|
|
224
|
+
"api: chip.set('metric', 'irdrop', 0.05, step='place', index=0)"],
|
|
225
|
+
pernode=PerNode.REQUIRED,
|
|
226
|
+
help=trim("""
|
|
227
|
+
Metric tracking the peak IR drop in the design based on extracted
|
|
228
|
+
power and ground rail parasitics, library power models, and
|
|
229
|
+
switching activity. The switching activity calculated on a per
|
|
230
|
+
node basis is taken from one of three possible sources, in order
|
|
231
|
+
of priority: VCD file, SAIF file, 'activityfactor' parameter.""")))
|
|
232
|
+
|
|
233
|
+
metrics = {'holdpaths': 'hold',
|
|
234
|
+
'setuppaths': 'setup'}
|
|
235
|
+
|
|
236
|
+
for item, description in metrics.items():
|
|
237
|
+
schema.insert(
|
|
238
|
+
item,
|
|
239
|
+
Parameter(
|
|
240
|
+
'int',
|
|
241
|
+
scope=Scope.JOB,
|
|
242
|
+
shorthelp=f"Metric: {item}",
|
|
243
|
+
switch=f"-metric_{item} 'step index <int>'",
|
|
244
|
+
example=[
|
|
245
|
+
f"cli: -metric_{item} 'place 0 10'",
|
|
246
|
+
f"api: chip.set('metric', '{item}', 10, step='place', index=0)"],
|
|
247
|
+
pernode=PerNode.REQUIRED,
|
|
248
|
+
help=trim(f"""
|
|
249
|
+
Metric tracking the total number of timing paths violating {description}
|
|
250
|
+
constraints.""")))
|
|
251
|
+
|
|
252
|
+
metrics = {'holdslack': 'worst hold slack (positive or negative)',
|
|
253
|
+
'holdwns': 'worst negative hold slack (positive values truncated to zero)',
|
|
254
|
+
'holdtns': 'total negative hold slack (TNS)',
|
|
255
|
+
'holdskew': 'hold clock skew',
|
|
256
|
+
'setupslack': 'worst setup slack (positive or negative)',
|
|
257
|
+
'setupwns': 'worst negative setup slack (positive values truncated to zero)',
|
|
258
|
+
'setuptns': 'total negative setup slack (TNS)',
|
|
259
|
+
'setupskew': 'setup clock skew'}
|
|
260
|
+
|
|
261
|
+
for item, description in metrics.items():
|
|
262
|
+
schema.insert(
|
|
263
|
+
item,
|
|
264
|
+
Parameter(
|
|
265
|
+
'float',
|
|
266
|
+
unit='ns',
|
|
267
|
+
scope=Scope.JOB,
|
|
268
|
+
shorthelp=f"Metric: {item}",
|
|
269
|
+
switch=f"-metric_{item} 'step index <float>'",
|
|
270
|
+
example=[
|
|
271
|
+
f"cli: -metric_{item} 'place 0 0.01'",
|
|
272
|
+
f"api: chip.set('metric', '{item}', 0.01, step='place', index=0)"],
|
|
273
|
+
pernode=PerNode.REQUIRED,
|
|
274
|
+
help=trim(f"""
|
|
275
|
+
Metric tracking the {description} on a per step and index basis.""")))
|
|
276
|
+
|
|
277
|
+
metrics = {'fmax': 'maximum clock frequency'}
|
|
278
|
+
|
|
279
|
+
for item, description in metrics.items():
|
|
280
|
+
schema.insert(
|
|
281
|
+
item,
|
|
282
|
+
Parameter(
|
|
283
|
+
'float',
|
|
284
|
+
unit='Hz',
|
|
285
|
+
scope=Scope.JOB,
|
|
286
|
+
shorthelp=f"Metric: {item}",
|
|
287
|
+
switch=f"-metric_{item} 'step index <float>'",
|
|
288
|
+
example=[
|
|
289
|
+
f"cli: -metric_{item} 'place 0 100e6'",
|
|
290
|
+
f"api: chip.set('metric', '{item}', 100e6, step='place', index=0)"],
|
|
291
|
+
pernode=PerNode.REQUIRED,
|
|
292
|
+
help=trim(f"""
|
|
293
|
+
Metric tracking the {description} on a per step and index basis.""")))
|
|
294
|
+
|
|
295
|
+
metrics = {'macros': 'macros',
|
|
296
|
+
'cells': 'cell instances',
|
|
297
|
+
'registers': 'register instances',
|
|
298
|
+
'buffers': 'buffer instances',
|
|
299
|
+
'inverters': 'inverter instances',
|
|
300
|
+
'transistors': 'transistors',
|
|
301
|
+
'pins': 'pins',
|
|
302
|
+
'nets': 'nets',
|
|
303
|
+
'vias': 'vias'}
|
|
304
|
+
|
|
305
|
+
for item, description in metrics.items():
|
|
306
|
+
schema.insert(
|
|
307
|
+
item,
|
|
308
|
+
Parameter(
|
|
309
|
+
'int',
|
|
310
|
+
scope=Scope.JOB,
|
|
311
|
+
shorthelp=f"Metric: {item}",
|
|
312
|
+
switch=f"-metric_{item} 'step index <int>'",
|
|
313
|
+
example=[
|
|
314
|
+
f"cli: -metric_{item} 'place 0 100'",
|
|
315
|
+
f"api: chip.set('metric', '{item}', 50, step='place', index=0)"],
|
|
316
|
+
pernode=PerNode.REQUIRED,
|
|
317
|
+
help=trim(f"""
|
|
318
|
+
Metric tracking the total number of {description} in the design
|
|
319
|
+
on a per step and index basis.""")))
|
|
320
|
+
|
|
321
|
+
schema.insert(
|
|
322
|
+
'wirelength',
|
|
323
|
+
Parameter(
|
|
324
|
+
'float',
|
|
325
|
+
unit='um',
|
|
326
|
+
scope=Scope.JOB,
|
|
327
|
+
shorthelp="Metric: wirelength",
|
|
328
|
+
switch="-metric_wirelength 'step index <float>'",
|
|
329
|
+
example=[
|
|
330
|
+
"cli: -metric_wirelength 'place 0 100.0'",
|
|
331
|
+
"api: chip.set('metric', 'wirelength', 50.0, step='place', index=0)"],
|
|
332
|
+
pernode=PerNode.REQUIRED,
|
|
333
|
+
help=trim("""
|
|
334
|
+
Metric tracking the total wirelength of the design on a per step
|
|
335
|
+
and index basis.""")))
|
|
336
|
+
|
|
337
|
+
schema.insert(
|
|
338
|
+
'overflow',
|
|
339
|
+
Parameter(
|
|
340
|
+
'int',
|
|
341
|
+
scope=Scope.JOB,
|
|
342
|
+
shorthelp="Metric: overflow",
|
|
343
|
+
switch="-metric_overflow 'step index <int>'",
|
|
344
|
+
example=[
|
|
345
|
+
"cli: -metric_overflow 'place 0 0'",
|
|
346
|
+
"api: chip.set('metric', 'overflow', 50, step='place', index=0)"],
|
|
347
|
+
pernode=PerNode.REQUIRED,
|
|
348
|
+
help=trim("""
|
|
349
|
+
Metric tracking the total number of overflow tracks for the routing
|
|
350
|
+
on per step and index basis. Any non-zero number suggests an over
|
|
351
|
+
congested design. To analyze where the congestion is occurring
|
|
352
|
+
inspect the router log files for detailed per metal overflow
|
|
353
|
+
reporting and open up the design to find routing hotspots.""")))
|
|
354
|
+
|
|
355
|
+
schema.insert(
|
|
356
|
+
'memory',
|
|
357
|
+
Parameter(
|
|
358
|
+
'float',
|
|
359
|
+
unit='B',
|
|
360
|
+
scope=Scope.JOB,
|
|
361
|
+
shorthelp="Metric: memory",
|
|
362
|
+
switch="-metric_memory 'step index <float>'",
|
|
363
|
+
example=[
|
|
364
|
+
"cli: -metric_memory 'dfm 0 10e9'",
|
|
365
|
+
"api: chip.set('metric', 'memory', 10e9, step='dfm', index=0)"],
|
|
366
|
+
pernode=PerNode.REQUIRED,
|
|
367
|
+
help=trim("""
|
|
368
|
+
Metric tracking total peak program memory footprint on a per
|
|
369
|
+
step and index basis.""")))
|
|
370
|
+
|
|
371
|
+
schema.insert(
|
|
372
|
+
'exetime',
|
|
373
|
+
Parameter(
|
|
374
|
+
'float',
|
|
375
|
+
unit='s',
|
|
376
|
+
scope=Scope.JOB,
|
|
377
|
+
shorthelp="Metric: exetime",
|
|
378
|
+
switch="-metric_exetime 'step index <float>'",
|
|
379
|
+
example=[
|
|
380
|
+
"cli: -metric_exetime 'dfm 0 10.0'",
|
|
381
|
+
"api: chip.set('metric', 'exetime', 10.0, step='dfm', index=0)"],
|
|
382
|
+
pernode=PerNode.REQUIRED,
|
|
383
|
+
help=trim("""
|
|
384
|
+
Metric tracking time spent by the EDA executable :keypath:`tool,<tool>,exe` on a
|
|
385
|
+
per step and index basis. It does not include the SiliconCompiler
|
|
386
|
+
runtime overhead or time waiting for I/O operations and
|
|
387
|
+
inter-processor communication to complete.""")))
|
|
388
|
+
|
|
389
|
+
schema.insert(
|
|
390
|
+
'tasktime',
|
|
391
|
+
Parameter(
|
|
392
|
+
'float',
|
|
393
|
+
unit='s',
|
|
394
|
+
scope=Scope.JOB,
|
|
395
|
+
shorthelp="Metric: tasktime",
|
|
396
|
+
switch="-metric_tasktime 'step index <float>'",
|
|
397
|
+
example=[
|
|
398
|
+
"cli: -metric_tasktime 'dfm 0 10.0'",
|
|
399
|
+
"api: chip.set('metric', 'tasktime', 10.0, step='dfm', index=0)"],
|
|
400
|
+
pernode=PerNode.REQUIRED,
|
|
401
|
+
help=trim("""
|
|
402
|
+
Metric tracking the total amount of time spent on a task from
|
|
403
|
+
beginning to end, including data transfers and pre/post
|
|
404
|
+
processing.""")))
|
|
405
|
+
|
|
406
|
+
schema.insert(
|
|
407
|
+
'totaltime',
|
|
408
|
+
Parameter(
|
|
409
|
+
'float',
|
|
410
|
+
unit='s',
|
|
411
|
+
scope=Scope.JOB,
|
|
412
|
+
shorthelp="Metric: totaltime",
|
|
413
|
+
switch="-metric_totaltime 'step index <float>'",
|
|
414
|
+
example=[
|
|
415
|
+
"cli: -metric_totaltime 'dfm 0 10.0'",
|
|
416
|
+
"api: chip.set('metric', 'totaltime', 10.0, step='dfm', index=0)"],
|
|
417
|
+
pernode=PerNode.REQUIRED,
|
|
418
|
+
help=trim("""
|
|
419
|
+
Metric tracking the total amount of time spent from the beginning
|
|
420
|
+
of the run up to and including the current step and index.""")))
|
|
@@ -3,7 +3,6 @@ import uuid
|
|
|
3
3
|
import math
|
|
4
4
|
from siliconcompiler import Chip
|
|
5
5
|
from siliconcompiler.optimizer import Optimizer
|
|
6
|
-
from siliconcompiler.flowgraph import _get_flowgraph_nodes
|
|
7
6
|
|
|
8
7
|
try:
|
|
9
8
|
from vizier.service import clients as vz_clients
|
|
@@ -158,7 +157,7 @@ class VizierOptimizier(Optimizer):
|
|
|
158
157
|
chip.graph(flow, org_flow, name=graph_name)
|
|
159
158
|
|
|
160
159
|
# Complete nodes
|
|
161
|
-
nodes =
|
|
160
|
+
nodes = chip.schema.get("flowgraph", org_flow, field="schema").get_nodes()
|
|
162
161
|
for step, _ in list(nodes):
|
|
163
162
|
nodes.append((step, None))
|
|
164
163
|
nodes = set(nodes)
|
|
@@ -168,7 +167,7 @@ class VizierOptimizier(Optimizer):
|
|
|
168
167
|
if key[0] == 'history':
|
|
169
168
|
continue
|
|
170
169
|
|
|
171
|
-
for value, step, index in chip.schema.
|
|
170
|
+
for value, step, index in chip.schema.get(*key, field=None).getvalues():
|
|
172
171
|
node = (step, index)
|
|
173
172
|
|
|
174
173
|
if node in nodes:
|
|
@@ -3,14 +3,15 @@ from urllib.parse import urlparse
|
|
|
3
3
|
import importlib
|
|
4
4
|
import re
|
|
5
5
|
from siliconcompiler import SiliconCompilerError
|
|
6
|
-
from siliconcompiler.utils import default_cache_dir
|
|
6
|
+
from siliconcompiler.utils import default_cache_dir
|
|
7
7
|
import json
|
|
8
8
|
from importlib.metadata import distributions, distribution
|
|
9
9
|
import functools
|
|
10
10
|
import time
|
|
11
11
|
from pathlib import Path
|
|
12
12
|
|
|
13
|
-
from siliconcompiler.utils import get_plugins
|
|
13
|
+
from siliconcompiler.utils import get_plugins, get_env_vars
|
|
14
|
+
from siliconcompiler.schema.parametervalue import PathNodeValue
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
def get_cache_path(chip):
|
|
@@ -46,6 +47,18 @@ def _python_path_resolver(chip, package, path, ref, url, fetch):
|
|
|
46
47
|
return path_from_python(chip, url.netloc)
|
|
47
48
|
|
|
48
49
|
|
|
50
|
+
def _key_path_resolver(chip, package, path, ref, url, fetch):
|
|
51
|
+
key = url.netloc.split(',')
|
|
52
|
+
if chip.get(*key, field='pernode').is_never():
|
|
53
|
+
paths = chip.find_files(*key)
|
|
54
|
+
else:
|
|
55
|
+
paths = chip.find_files(*key, step=chip.get('arg', 'step'), index=chip.get('arg', 'index'))
|
|
56
|
+
|
|
57
|
+
if isinstance(paths, list):
|
|
58
|
+
return paths[0]
|
|
59
|
+
return paths
|
|
60
|
+
|
|
61
|
+
|
|
49
62
|
def _get_path_resolver(path):
|
|
50
63
|
url = urlparse(path)
|
|
51
64
|
|
|
@@ -54,6 +67,9 @@ def _get_path_resolver(path):
|
|
|
54
67
|
if func:
|
|
55
68
|
return func, url
|
|
56
69
|
|
|
70
|
+
if url.scheme == "key":
|
|
71
|
+
return _key_path_resolver, url
|
|
72
|
+
|
|
57
73
|
if url.scheme == "file":
|
|
58
74
|
return _file_path_resolver, url
|
|
59
75
|
|
|
@@ -69,11 +85,15 @@ def _path(chip, package, fetch):
|
|
|
69
85
|
data['path'] = chip.get('package', 'source', package, 'path')
|
|
70
86
|
data['ref'] = chip.get('package', 'source', package, 'ref')
|
|
71
87
|
if not data['path']:
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
88
|
+
if package.startswith("key://"):
|
|
89
|
+
data['path'] = package
|
|
90
|
+
else:
|
|
91
|
+
raise SiliconCompilerError(
|
|
92
|
+
f'Could not find package source for {package} in schema. '
|
|
93
|
+
'You can use register_source() to add it.', chip=chip)
|
|
75
94
|
|
|
76
|
-
|
|
95
|
+
env_vars = get_env_vars(chip, None, None)
|
|
96
|
+
data['path'] = PathNodeValue.resolve_env_vars(data['path'], envvars=env_vars)
|
|
77
97
|
|
|
78
98
|
if os.path.exists(data['path']):
|
|
79
99
|
# Path is already a path
|
|
@@ -102,6 +122,9 @@ def path(chip, package, fetch=True):
|
|
|
102
122
|
if isinstance(data_path, tuple) and len(data_path) == 2:
|
|
103
123
|
data_path, changed = data_path
|
|
104
124
|
|
|
125
|
+
if package.startswith("key://"):
|
|
126
|
+
return data_path
|
|
127
|
+
|
|
105
128
|
if os.path.exists(data_path):
|
|
106
129
|
if package not in chip._packages and changed:
|
|
107
130
|
chip.logger.info(f'Saved {package} data to {data_path}')
|