siliconcompiler 0.35.3__py3-none-any.whl → 0.36.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/_metadata.py +1 -1
- siliconcompiler/apps/sc_issue.py +18 -2
- siliconcompiler/checklist.py +2 -1
- siliconcompiler/constraints/__init__.py +4 -1
- siliconcompiler/constraints/asic_component.py +49 -11
- siliconcompiler/constraints/asic_floorplan.py +23 -21
- siliconcompiler/constraints/asic_pins.py +55 -17
- siliconcompiler/constraints/asic_timing.py +280 -57
- siliconcompiler/constraints/fpga_timing.py +212 -18
- siliconcompiler/constraints/timing_mode.py +82 -0
- siliconcompiler/data/templates/replay/replay.sh.j2 +27 -14
- siliconcompiler/data/templates/tcl/manifest.tcl.j2 +0 -6
- siliconcompiler/flowgraph.py +95 -42
- siliconcompiler/flows/generate_openroad_rcx.py +2 -2
- siliconcompiler/flows/highresscreenshotflow.py +37 -0
- siliconcompiler/library.py +2 -1
- siliconcompiler/package/__init__.py +56 -51
- siliconcompiler/project.py +13 -2
- siliconcompiler/scheduler/docker.py +24 -25
- siliconcompiler/scheduler/scheduler.py +143 -100
- siliconcompiler/scheduler/schedulernode.py +138 -22
- siliconcompiler/scheduler/slurm.py +120 -35
- siliconcompiler/scheduler/taskscheduler.py +19 -23
- siliconcompiler/schema/_metadata.py +1 -1
- siliconcompiler/schema/editableschema.py +29 -0
- siliconcompiler/schema/namedschema.py +2 -4
- siliconcompiler/schema/parametervalue.py +14 -2
- siliconcompiler/schema_support/cmdlineschema.py +0 -3
- siliconcompiler/schema_support/dependencyschema.py +0 -6
- siliconcompiler/schema_support/option.py +82 -1
- siliconcompiler/schema_support/pathschema.py +7 -13
- siliconcompiler/schema_support/record.py +4 -3
- siliconcompiler/tool.py +105 -52
- siliconcompiler/tools/_common/tcl/sc_schema_access.tcl +0 -6
- siliconcompiler/tools/keplerformal/__init__.py +7 -0
- siliconcompiler/tools/keplerformal/lec.py +112 -0
- siliconcompiler/tools/klayout/__init__.py +3 -0
- siliconcompiler/tools/klayout/screenshot.py +66 -1
- siliconcompiler/tools/klayout/scripts/klayout_convert_drc_db.py +1 -0
- siliconcompiler/tools/klayout/scripts/klayout_export.py +11 -40
- siliconcompiler/tools/klayout/scripts/klayout_operations.py +1 -0
- siliconcompiler/tools/klayout/scripts/klayout_show.py +5 -4
- siliconcompiler/tools/klayout/scripts/klayout_utils.py +16 -5
- siliconcompiler/tools/montage/tile.py +26 -12
- siliconcompiler/tools/openroad/__init__.py +27 -1
- siliconcompiler/tools/openroad/_apr.py +107 -14
- siliconcompiler/tools/openroad/clock_tree_synthesis.py +1 -0
- siliconcompiler/tools/openroad/global_placement.py +1 -0
- siliconcompiler/tools/openroad/init_floorplan.py +119 -7
- siliconcompiler/tools/openroad/power_grid_analysis.py +174 -0
- siliconcompiler/tools/openroad/repair_design.py +1 -0
- siliconcompiler/tools/openroad/repair_timing.py +1 -0
- siliconcompiler/tools/openroad/scripts/apr/preamble.tcl +1 -1
- siliconcompiler/tools/openroad/scripts/apr/sc_init_floorplan.tcl +91 -18
- siliconcompiler/tools/openroad/scripts/apr/sc_irdrop.tcl +148 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_repair_design.tcl +1 -1
- siliconcompiler/tools/openroad/scripts/apr/sc_write_data.tcl +8 -10
- siliconcompiler/tools/openroad/scripts/common/procs.tcl +15 -6
- siliconcompiler/tools/openroad/scripts/common/read_liberty.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/common/reports.tcl +7 -4
- siliconcompiler/tools/openroad/scripts/common/screenshot.tcl +1 -1
- siliconcompiler/tools/openroad/scripts/common/write_data_physical.tcl +8 -0
- siliconcompiler/tools/openroad/scripts/common/write_images.tcl +16 -12
- siliconcompiler/tools/openroad/scripts/rcx/sc_rcx_bench.tcl +2 -4
- siliconcompiler/tools/openroad/scripts/sc_rdlroute.tcl +3 -1
- siliconcompiler/tools/openroad/write_data.py +2 -2
- siliconcompiler/tools/opensta/__init__.py +1 -1
- siliconcompiler/tools/opensta/scripts/sc_check_library.tcl +2 -2
- siliconcompiler/tools/opensta/scripts/sc_report_libraries.tcl +2 -2
- siliconcompiler/tools/opensta/scripts/sc_timing.tcl +13 -10
- siliconcompiler/tools/opensta/timing.py +6 -2
- siliconcompiler/tools/vivado/scripts/sc_bitstream.tcl +11 -0
- siliconcompiler/tools/vivado/scripts/sc_place.tcl +11 -0
- siliconcompiler/tools/vivado/scripts/sc_route.tcl +11 -0
- siliconcompiler/tools/vivado/scripts/sc_syn_fpga.tcl +10 -0
- siliconcompiler/tools/vpr/__init__.py +28 -0
- siliconcompiler/tools/yosys/scripts/sc_screenshot.tcl +1 -1
- siliconcompiler/tools/yosys/scripts/sc_synth_asic.tcl +40 -4
- siliconcompiler/tools/yosys/scripts/sc_synth_fpga.tcl +15 -5
- siliconcompiler/tools/yosys/syn_asic.py +42 -0
- siliconcompiler/tools/yosys/syn_fpga.py +8 -0
- siliconcompiler/toolscripts/_tools.json +12 -7
- siliconcompiler/toolscripts/ubuntu22/install-keplerformal.sh +72 -0
- siliconcompiler/toolscripts/ubuntu24/install-keplerformal.sh +72 -0
- siliconcompiler/utils/__init__.py +243 -51
- siliconcompiler/utils/curation.py +89 -56
- siliconcompiler/utils/issue.py +6 -1
- siliconcompiler/utils/multiprocessing.py +46 -2
- siliconcompiler/utils/paths.py +21 -0
- siliconcompiler/utils/settings.py +162 -0
- {siliconcompiler-0.35.3.dist-info → siliconcompiler-0.36.0.dist-info}/METADATA +5 -4
- {siliconcompiler-0.35.3.dist-info → siliconcompiler-0.36.0.dist-info}/RECORD +96 -87
- {siliconcompiler-0.35.3.dist-info → siliconcompiler-0.36.0.dist-info}/WHEEL +0 -0
- {siliconcompiler-0.35.3.dist-info → siliconcompiler-0.36.0.dist-info}/entry_points.txt +0 -0
- {siliconcompiler-0.35.3.dist-info → siliconcompiler-0.36.0.dist-info}/licenses/LICENSE +0 -0
- {siliconcompiler-0.35.3.dist-info → siliconcompiler-0.36.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
from typing import Optional, Union
|
|
2
|
+
|
|
3
|
+
from siliconcompiler.tools.openroad._apr import APRTask
|
|
4
|
+
from siliconcompiler.tools.openroad._apr import OpenROADSTAParameter, OpenROADPSMParameter
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class PowerGridAnalysisTask(APRTask, OpenROADPSMParameter, OpenROADSTAParameter):
|
|
8
|
+
'''
|
|
9
|
+
Performs static IR drop analysis on the power grid using OpenROAD.
|
|
10
|
+
|
|
11
|
+
This task utilizes the OpenROAD PDN (Power Distribution Network) analysis
|
|
12
|
+
capabilities (PSM) to calculate static IR drop based on instance power
|
|
13
|
+
consumption and grid resistance.
|
|
14
|
+
'''
|
|
15
|
+
|
|
16
|
+
def __init__(self):
|
|
17
|
+
super().__init__()
|
|
18
|
+
|
|
19
|
+
self.add_parameter("source_disconnection_rate", "float",
|
|
20
|
+
"Fraction (0.0-100.0) of power source bumps to simulate "
|
|
21
|
+
"disconnected/failing bumps.",
|
|
22
|
+
defvalue=0.0)
|
|
23
|
+
self.add_parameter("source_disconnection_seed", "int",
|
|
24
|
+
"Random seed used for determining which power bumps to disconnect.",
|
|
25
|
+
defvalue=123)
|
|
26
|
+
|
|
27
|
+
self.add_parameter("instance_power", "[(str,float)]",
|
|
28
|
+
"List of (instance_name, power_value) tuples to override specific "
|
|
29
|
+
"instance power consumption.")
|
|
30
|
+
|
|
31
|
+
self.add_parameter("net", "{str}",
|
|
32
|
+
"Set of specific power/ground nets to analyze (e.g., VDD, VSS).")
|
|
33
|
+
|
|
34
|
+
self.add_parameter("heatmap_grid", "(float,float)",
|
|
35
|
+
"Resolution of the IR drop heatmap grid (x_step, y_step).",
|
|
36
|
+
defvalue=(10, 10), units="um")
|
|
37
|
+
|
|
38
|
+
self.add_parameter("external_resistance", "float",
|
|
39
|
+
"Resistance value to add to the power grid model to account for "
|
|
40
|
+
"external factors (e.g., package, PCB).",
|
|
41
|
+
units="ohm")
|
|
42
|
+
|
|
43
|
+
def set_openroad_disconnectrate(self, rate: float,
|
|
44
|
+
step: Optional[str] = None,
|
|
45
|
+
index: Optional[Union[str, int]] = None):
|
|
46
|
+
'''
|
|
47
|
+
Sets the fraction of power pads/bumps to disconnect to simulate robustness.
|
|
48
|
+
|
|
49
|
+
Args:
|
|
50
|
+
rate (float): A value between 0.0 and 100.0 representing the percentage to disconnect.
|
|
51
|
+
step (str, optional): step name
|
|
52
|
+
index (str, optional): index
|
|
53
|
+
'''
|
|
54
|
+
self.set("var", "source_disconnection_rate", rate, step=step, index=index)
|
|
55
|
+
|
|
56
|
+
def set_openroad_disconnectseed(self, seed: int,
|
|
57
|
+
step: Optional[str] = None,
|
|
58
|
+
index: Optional[Union[str, int]] = None):
|
|
59
|
+
'''
|
|
60
|
+
Sets the random seed for the power bump disconnection logic.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
seed (int): The random seed integer.
|
|
64
|
+
step (str, optional): step name
|
|
65
|
+
index (str, optional): index
|
|
66
|
+
'''
|
|
67
|
+
self.set("var", "source_disconnection_seed", seed, step=step, index=index)
|
|
68
|
+
|
|
69
|
+
def set_openroad_heatmapgrid(self, x: float, y: float,
|
|
70
|
+
step: Optional[str] = None,
|
|
71
|
+
index: Optional[Union[str, int]] = None):
|
|
72
|
+
'''
|
|
73
|
+
Sets the resolution for the IR drop heatmap generation.
|
|
74
|
+
|
|
75
|
+
Args:
|
|
76
|
+
x (float): Grid spacing in the X direction (microns).
|
|
77
|
+
y (float): Grid spacing in the Y direction (microns).
|
|
78
|
+
step (str, optional): step name
|
|
79
|
+
index (str, optional): index
|
|
80
|
+
'''
|
|
81
|
+
self.set("var", "heatmap_grid", (x, y), step=step, index=index)
|
|
82
|
+
|
|
83
|
+
def set_openroad_externalresistance(self, res: float,
|
|
84
|
+
step: Optional[str] = None,
|
|
85
|
+
index: Optional[Union[str, int]] = None):
|
|
86
|
+
'''
|
|
87
|
+
Sets the external resistance to be modeled in the power grid analysis.
|
|
88
|
+
|
|
89
|
+
Args:
|
|
90
|
+
res (float): External resistance to add.
|
|
91
|
+
step (str, optional): step name
|
|
92
|
+
index (str, optional): index
|
|
93
|
+
'''
|
|
94
|
+
self.set("var", "external_resistance", res, step=step, index=index)
|
|
95
|
+
|
|
96
|
+
def add_openroad_irdropnet(self, net: str,
|
|
97
|
+
step: Optional[str] = None, index: Optional[Union[str, int]] = None,
|
|
98
|
+
clobber: bool = False):
|
|
99
|
+
'''
|
|
100
|
+
Adds a specific net to the list of nets to be analyzed for IR drop.
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
net (str): The name of the net (e.g., "VDD").
|
|
104
|
+
step (str, optional): step name
|
|
105
|
+
index (str, optional): index
|
|
106
|
+
clobber (bool): If True, replaces existing nets. If False, appends to the list.
|
|
107
|
+
'''
|
|
108
|
+
if clobber:
|
|
109
|
+
self.set("var", "net", net, step=step, index=index)
|
|
110
|
+
else:
|
|
111
|
+
self.add("var", "net", net, step=step, index=index)
|
|
112
|
+
|
|
113
|
+
def add_openroad_instancepower(self, inst: str, power: float,
|
|
114
|
+
step: Optional[str] = None,
|
|
115
|
+
index: Optional[Union[str, int]] = None,
|
|
116
|
+
clobber: bool = False):
|
|
117
|
+
'''
|
|
118
|
+
Manually sets the power consumption for a specific instance.
|
|
119
|
+
|
|
120
|
+
Args:
|
|
121
|
+
inst (str): The name of the instance.
|
|
122
|
+
power (float): The power value (typically in Watts, depending on library units).
|
|
123
|
+
step (str, optional): step name
|
|
124
|
+
index (str, optional): index
|
|
125
|
+
clobber (bool): If True, replaces the existing list. If False, appends.
|
|
126
|
+
'''
|
|
127
|
+
if clobber:
|
|
128
|
+
self.set("var", "instance_power", (inst, power), step=step, index=index)
|
|
129
|
+
else:
|
|
130
|
+
self.add("var", "instance_power", (inst, power), step=step, index=index)
|
|
131
|
+
|
|
132
|
+
def task(self) -> str:
|
|
133
|
+
'''
|
|
134
|
+
Returns the internal task name for this tool task.
|
|
135
|
+
'''
|
|
136
|
+
return "irdrop_analysis"
|
|
137
|
+
|
|
138
|
+
def setup(self):
|
|
139
|
+
'''
|
|
140
|
+
Configures the tool runtime parameters, scripts, and requirements.
|
|
141
|
+
'''
|
|
142
|
+
super().setup()
|
|
143
|
+
self.set_script("apr/sc_irdrop.tcl")
|
|
144
|
+
|
|
145
|
+
self.add_version(">=v2.0-26866", clobber=True)
|
|
146
|
+
|
|
147
|
+
# Output is not a standard design file, unset default expectation
|
|
148
|
+
self.unset("output")
|
|
149
|
+
|
|
150
|
+
# Define keys required for this task to run successfully
|
|
151
|
+
self.add_required_key("var", "source_disconnection_rate")
|
|
152
|
+
self.add_required_key("var", "source_disconnection_seed")
|
|
153
|
+
self.add_required_key("var", "heatmap_grid")
|
|
154
|
+
|
|
155
|
+
# Conditionally require these keys if they have been set
|
|
156
|
+
if self.get("var", "instance_power"):
|
|
157
|
+
self.add_required_key("var", "instance_power")
|
|
158
|
+
|
|
159
|
+
if self.get("var", "net"):
|
|
160
|
+
self.add_required_key("var", "net")
|
|
161
|
+
if self.get("var", "external_resistance") is not None:
|
|
162
|
+
self.add_required_key("var", "external_resistance")
|
|
163
|
+
|
|
164
|
+
def runtime_options(self):
|
|
165
|
+
'''
|
|
166
|
+
Returns the command line arguments for the OpenROAD executable.
|
|
167
|
+
|
|
168
|
+
Ensures the GUI flag is present, as visualization is often required
|
|
169
|
+
or implied for heatmap analysis contexts in this workflow.
|
|
170
|
+
'''
|
|
171
|
+
args = super().runtime_options()
|
|
172
|
+
if "-gui" not in args:
|
|
173
|
+
args.append("-gui")
|
|
174
|
+
return args
|
|
@@ -89,6 +89,6 @@ if { [llength $openroad_dont_touch] > 0 } {
|
|
|
89
89
|
tee -quiet -file reports/dont_touch.start.rpt {report_dont_touch}
|
|
90
90
|
tee -quiet -file reports/dont_use.start.rpt {report_dont_use}
|
|
91
91
|
tee -file reports/global_connections.start.rpt {report_global_connect}
|
|
92
|
-
if { [sc_check_version 23264] } {
|
|
92
|
+
if { [sc_cfg_tool_task_check_in_list report_buffers var reports] && [sc_check_version 23264] } {
|
|
93
93
|
tee -quiet -file reports/report_buffers.rpt {report_buffers -filtered}
|
|
94
94
|
}
|
|
@@ -73,14 +73,52 @@ if { $sc_openroad_tracks != "" } {
|
|
|
73
73
|
make_tracks
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
|
|
76
|
+
###############################
|
|
77
|
+
# Bump Creation
|
|
78
|
+
###############################
|
|
79
|
+
|
|
77
80
|
set do_automatic_pins 1
|
|
81
|
+
if { [llength [sc_cfg_tool_task_get var bumpmapfileset]] > 0 } {
|
|
82
|
+
if { [sc_check_version 26154] == 0 } {
|
|
83
|
+
utl::error FLW 1 "bmaps are not supported in this version of openroad"
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
set do_automatic_pins 0
|
|
87
|
+
|
|
88
|
+
set bmaps_read []
|
|
89
|
+
set bumpmapfileset [sc_cfg_tool_task_get var bumpmapfileset]
|
|
90
|
+
set bmapfiles [sc_cfg_get_fileset $sc_designlib $bumpmapfileset bmap]
|
|
91
|
+
foreach bmap_file $bmapfiles {
|
|
92
|
+
if { [lsearch -exact $bmaps_read $bmap_file] != -1 } {
|
|
93
|
+
continue
|
|
94
|
+
}
|
|
95
|
+
puts "Reading 3DBlox bump map: ${bmap_file}"
|
|
96
|
+
read_3dblox_bmap $bmap_file
|
|
97
|
+
|
|
98
|
+
lappend bmaps_read $bmap_file
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
# Check ports
|
|
102
|
+
set failed 0
|
|
103
|
+
foreach port [[ord::get_db_block] getBTerms] {
|
|
104
|
+
set placement [$port getFirstPinPlacementStatus]
|
|
105
|
+
if { $placement != "FIRM" } {
|
|
106
|
+
incr failed
|
|
107
|
+
utl::warn FLW 2 "Unplaced port: [$port getName]"
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
if { $failed > 0 } {
|
|
111
|
+
utl::warn FLW 3 "There are $failed unplaced ports in the design"
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
###############################
|
|
116
|
+
# Generate pad ring
|
|
117
|
+
###############################
|
|
118
|
+
|
|
78
119
|
if { [llength [sc_cfg_tool_task_get var padringfileset]] > 0 } {
|
|
79
120
|
set do_automatic_pins 0
|
|
80
121
|
|
|
81
|
-
###############################
|
|
82
|
-
# Generate pad ring
|
|
83
|
-
###############################
|
|
84
122
|
set padringfiles_read []
|
|
85
123
|
set padringfileset [sc_cfg_tool_task_get var padringfileset]
|
|
86
124
|
set padringfiles [sc_cfg_get_fileset $sc_designlib $padringfileset tcl]
|
|
@@ -261,6 +299,8 @@ if { [sc_cfg_exists constraint component] } {
|
|
|
261
299
|
set x_grid [ord::dbu_to_microns $x_grid]
|
|
262
300
|
set y_grid [ord::dbu_to_microns $y_grid]
|
|
263
301
|
|
|
302
|
+
set sc_placed_insts []
|
|
303
|
+
|
|
264
304
|
dict for {name params} [sc_cfg_get constraint component] {
|
|
265
305
|
set location [dict get $params placement]
|
|
266
306
|
set rotation [sc_convert_rotation [dict get $params rotation]]
|
|
@@ -270,11 +310,27 @@ if { [sc_cfg_exists constraint component] } {
|
|
|
270
310
|
} else {
|
|
271
311
|
set cell ""
|
|
272
312
|
}
|
|
313
|
+
set halo {}
|
|
273
314
|
if { [llength [dict get $params halo]] != 0 } {
|
|
274
|
-
|
|
315
|
+
if { [llength [dict get $params halo]] == 2 } {
|
|
316
|
+
set halo [dict get $params halo]
|
|
317
|
+
} else {
|
|
318
|
+
utl::warn FLW 1 "Halo must be a list of 2 elements"
|
|
319
|
+
}
|
|
275
320
|
}
|
|
276
321
|
|
|
277
|
-
set
|
|
322
|
+
set stainst [get_cells -quiet $name]
|
|
323
|
+
if { $stainst != {} } {
|
|
324
|
+
if { [llength $stainst] > 1 } {
|
|
325
|
+
utl::error FLW 1 "Multiple cells found for instance $name"
|
|
326
|
+
}
|
|
327
|
+
set inst [sta::sta_to_db_inst $stainst]
|
|
328
|
+
} else {
|
|
329
|
+
set inst "NULL"
|
|
330
|
+
}
|
|
331
|
+
if { $inst == "NULL" } {
|
|
332
|
+
set inst [[ord::get_db_block] findInst $name]
|
|
333
|
+
}
|
|
278
334
|
if { $inst == "NULL" } {
|
|
279
335
|
utl::warn FLW 1 "Could not find instance: $name"
|
|
280
336
|
|
|
@@ -286,23 +342,40 @@ if { [sc_cfg_exists constraint component] } {
|
|
|
286
342
|
set cell ""
|
|
287
343
|
}
|
|
288
344
|
|
|
289
|
-
|
|
290
|
-
|
|
345
|
+
if { $inst != "NULL" } {
|
|
346
|
+
set name [$inst getName]
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
if { [llength $location] == 2 } {
|
|
350
|
+
# Only place if location is specified
|
|
351
|
+
set x_loc [expr { round([lindex $location 0] / $x_grid) * $x_grid }]
|
|
352
|
+
set y_loc [expr { round([lindex $location 1] / $y_grid) * $y_grid }]
|
|
291
353
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
354
|
+
set place_inst_args []
|
|
355
|
+
if { $cell != "" } {
|
|
356
|
+
lappend place_inst_args -cell $cell
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
place_inst \
|
|
360
|
+
-name $name \
|
|
361
|
+
-origin "$x_loc $y_loc" \
|
|
362
|
+
-orient $rotation \
|
|
363
|
+
-status FIRM \
|
|
364
|
+
{*}$place_inst_args
|
|
295
365
|
}
|
|
296
366
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
367
|
+
if { $halo != {} } {
|
|
368
|
+
set inst [[ord::get_db_block] findInst $name]
|
|
369
|
+
odb::dbBox_create $inst \
|
|
370
|
+
[ord::microns_to_dbu [lindex $halo 0]] \
|
|
371
|
+
[ord::microns_to_dbu [lindex $halo 1]] \
|
|
372
|
+
[ord::microns_to_dbu [lindex $halo 0]] \
|
|
373
|
+
[ord::microns_to_dbu [lindex $halo 1]]
|
|
374
|
+
}
|
|
375
|
+
lappend sc_placed_insts $name
|
|
303
376
|
}
|
|
304
377
|
|
|
305
|
-
sc_print_macro_information
|
|
378
|
+
sc_print_macro_information $sc_placed_insts
|
|
306
379
|
}
|
|
307
380
|
|
|
308
381
|
if { [sc_check_version 23008] } {
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
###############################
|
|
2
|
+
# Reading SC Schema
|
|
3
|
+
###############################
|
|
4
|
+
|
|
5
|
+
source ./sc_manifest.tcl
|
|
6
|
+
|
|
7
|
+
###############################
|
|
8
|
+
# Task Preamble
|
|
9
|
+
###############################
|
|
10
|
+
|
|
11
|
+
set sc_refdir [sc_cfg_tool_task_get refdir]
|
|
12
|
+
source "$sc_refdir/apr/preamble.tcl"
|
|
13
|
+
|
|
14
|
+
set nets []
|
|
15
|
+
if { [llength [sc_cfg_tool_task_get var net]] > 0 } {
|
|
16
|
+
set nets [sc_cfg_tool_task_get var net]
|
|
17
|
+
} else {
|
|
18
|
+
set nets [sc_psm_check_nets]
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
###############################
|
|
22
|
+
# Assign power
|
|
23
|
+
###############################
|
|
24
|
+
|
|
25
|
+
foreach inst_setting [sc_cfg_tool_task_get var instance_power] {
|
|
26
|
+
lassign $inst_setting inst power
|
|
27
|
+
set pwr_mw [expr { $power * 1000 }]
|
|
28
|
+
puts "Setting power for $inst to: [format "%.3f" $pwr_mw]mW"
|
|
29
|
+
|
|
30
|
+
set_pdnsim_inst_power \
|
|
31
|
+
-inst $inst \
|
|
32
|
+
-power $power
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
###############################
|
|
36
|
+
# Depopulate Terminals
|
|
37
|
+
###############################
|
|
38
|
+
|
|
39
|
+
if { [sc_cfg_tool_task_get var source_disconnection_rate] > 0 } {
|
|
40
|
+
expr { srand([sc_cfg_tool_task_get var source_disconnection_seed]) }
|
|
41
|
+
|
|
42
|
+
set depop_target [expr { [sc_cfg_tool_task_get var source_disconnection_rate] / 100.0 }]
|
|
43
|
+
|
|
44
|
+
foreach net $nets {
|
|
45
|
+
set count 0
|
|
46
|
+
set disabled 0
|
|
47
|
+
foreach bpin [[[ord::get_db_block] findBTerm $net] getBPins] {
|
|
48
|
+
foreach box [$bpin getBoxes] {
|
|
49
|
+
incr count
|
|
50
|
+
if { rand() < $depop_target } {
|
|
51
|
+
incr disabled
|
|
52
|
+
odb::dbBoolProperty_create $box PSM_DISCONNECT 1
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
set term_proc [expr { 100 * (double($disabled) / $count) }]
|
|
57
|
+
utl::info FLW 1 "$net terminals disabled $disabled / $count ([format "%.1f" $term_proc]%)"
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
###############################
|
|
62
|
+
# Setup power grid analysis
|
|
63
|
+
###############################
|
|
64
|
+
|
|
65
|
+
set source_args []
|
|
66
|
+
|
|
67
|
+
set res [sc_cfg_tool_task_get var external_resistance]
|
|
68
|
+
if { $res > 0 } {
|
|
69
|
+
puts "Setting external resistance to $res ohms"
|
|
70
|
+
lappend source_args -external_resistance $res
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if { [llength $source_args] != 0 } {
|
|
74
|
+
set_pdnsim_source_settings {*}$source_args
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
###############################
|
|
78
|
+
# Analyze nets
|
|
79
|
+
###############################
|
|
80
|
+
|
|
81
|
+
lassign [sc_cfg_tool_task_get var heatmap_grid] heatmap_x heatmap_y
|
|
82
|
+
gui::save_display_controls
|
|
83
|
+
|
|
84
|
+
sc_image_setup_default
|
|
85
|
+
gui::set_display_controls "Shape Types/Pin*" visible false
|
|
86
|
+
|
|
87
|
+
foreach net $nets {
|
|
88
|
+
file mkdir reports/${net}
|
|
89
|
+
foreach corner $sc_scenarios {
|
|
90
|
+
analyze_power_grid -net $net -corner $corner -allow_reuse
|
|
91
|
+
|
|
92
|
+
set gif [save_animated_gif -start "reports/${net}/${corner}.gif"]
|
|
93
|
+
set gif_log [save_animated_gif -start "reports/${net}/${corner}_log.gif"]
|
|
94
|
+
|
|
95
|
+
foreach layer [[ord::get_db_tech] getLayers] {
|
|
96
|
+
if { [$layer getRoutingLevel] == 0 } {
|
|
97
|
+
continue
|
|
98
|
+
}
|
|
99
|
+
set layer_name [$layer getName]
|
|
100
|
+
|
|
101
|
+
gui::set_heatmap IRDrop Net $net
|
|
102
|
+
gui::set_heatmap IRDrop Corner $corner
|
|
103
|
+
gui::set_heatmap IRDrop Layer $layer_name
|
|
104
|
+
gui::set_heatmap IRDrop LogScale 0
|
|
105
|
+
gui::set_heatmap IRDrop ShowLegend 1
|
|
106
|
+
gui::set_heatmap IRDrop GridX $heatmap_x
|
|
107
|
+
gui::set_heatmap IRDrop GridY $heatmap_y
|
|
108
|
+
gui::set_display_controls "Heat Maps/IR Drop" visible true
|
|
109
|
+
|
|
110
|
+
gui::set_heatmap IRDrop rebuild
|
|
111
|
+
|
|
112
|
+
if { ![gui::get_heatmap_bool IRDrop has_data] } {
|
|
113
|
+
continue
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
# Save CSV
|
|
117
|
+
gui::dump_heatmap IRDrop reports/${net}/${corner}.${layer_name}.csv
|
|
118
|
+
|
|
119
|
+
set box [[ord::get_db_block] getDieArea]
|
|
120
|
+
set x [ord::dbu_to_microns [$box xMax]]
|
|
121
|
+
set y [ord::dbu_to_microns [$box yMin]]
|
|
122
|
+
set label [add_label -position "$x $y" -anchor "bottom right" -color white $layer_name]
|
|
123
|
+
|
|
124
|
+
sc_save_image \
|
|
125
|
+
"IR drop for $net on $layer_name for $corner heatmap" \
|
|
126
|
+
reports/${net}/${corner}.${layer_name}.png \
|
|
127
|
+
$gif
|
|
128
|
+
|
|
129
|
+
gui::set_heatmap IRDrop LogScale 1
|
|
130
|
+
gui::set_heatmap IRDrop rebuild
|
|
131
|
+
|
|
132
|
+
sc_save_image \
|
|
133
|
+
"IR drop for $net on $layer_name for $corner heatmap" \
|
|
134
|
+
reports/${net}/${corner}.${layer_name}_log.png \
|
|
135
|
+
$gif_log
|
|
136
|
+
|
|
137
|
+
gui::set_display_controls "Heat Maps/IR Drop" visible false
|
|
138
|
+
|
|
139
|
+
if { $label != "" } {
|
|
140
|
+
gui::delete_label $label
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
save_animated_gif -end -key $gif
|
|
144
|
+
save_animated_gif -end -key $gif_log
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
gui::restore_display_controls
|
|
@@ -52,7 +52,7 @@ sc_set_dont_use
|
|
|
52
52
|
# Tie-off cell insertion
|
|
53
53
|
###############################
|
|
54
54
|
|
|
55
|
-
set tie_separation [
|
|
55
|
+
set tie_separation [sc_cfg_tool_task_get {var} ifp_tie_separation]
|
|
56
56
|
foreach tie_type "high low" {
|
|
57
57
|
if { [sc_has_tie_cell $tie_type] } {
|
|
58
58
|
repair_tie_fanout \
|
|
@@ -33,12 +33,10 @@ write_abstract_lef {*}$lef_args "outputs/${sc_topmodule}.lef"
|
|
|
33
33
|
if { [sc_cfg_tool_task_get var write_cdl] } {
|
|
34
34
|
# Write CDL
|
|
35
35
|
set sc_cdl_masters []
|
|
36
|
-
foreach lib
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
lappend sc_cdl_masters $cdl_file
|
|
41
|
-
}
|
|
36
|
+
foreach lib $sc_logiclibs {
|
|
37
|
+
set filesets [sc_cfg_get library $lib asic aprfileset]
|
|
38
|
+
foreach cdl_file [sc_cfg_get_fileset $lib $filesets cdl] {
|
|
39
|
+
lappend sc_cdl_masters $cdl_file
|
|
42
40
|
}
|
|
43
41
|
}
|
|
44
42
|
write_cdl -masters $sc_cdl_masters "outputs/${sc_topmodule}.cdl"
|
|
@@ -62,7 +60,7 @@ if { [sc_cfg_tool_task_get var write_spef] } {
|
|
|
62
60
|
if { [sc_cfg_tool_task_get var use_spef] } {
|
|
63
61
|
set lib_pex [dict create]
|
|
64
62
|
foreach scenario $sc_scenarios {
|
|
65
|
-
set pexcorner [sc_cfg_get constraint timing $scenario pexcorner]
|
|
63
|
+
set pexcorner [sc_cfg_get constraint timing scenario $scenario pexcorner]
|
|
66
64
|
|
|
67
65
|
dict set lib_pex $scenario $pexcorner
|
|
68
66
|
}
|
|
@@ -109,11 +107,11 @@ foreach corner $sc_scenarios {
|
|
|
109
107
|
###############################
|
|
110
108
|
|
|
111
109
|
foreach corner $sc_scenarios {
|
|
112
|
-
if { [sc_cfg_exists constraint timing $corner voltage] } {
|
|
113
|
-
foreach net [dict keys [sc_cfg_get constraint timing $corner voltage]] {
|
|
110
|
+
if { [sc_cfg_exists constraint timing scenario $corner voltage] } {
|
|
111
|
+
foreach net [dict keys [sc_cfg_get constraint timing scenario $corner voltage]] {
|
|
114
112
|
set_pdnsim_net_voltage -corner $corner \
|
|
115
113
|
-net $net \
|
|
116
|
-
-voltage [sc_cfg_get constraint timing $corner voltage $net]
|
|
114
|
+
-voltage [sc_cfg_get constraint timing scenario $corner voltage $net]
|
|
117
115
|
}
|
|
118
116
|
}
|
|
119
117
|
}
|
|
@@ -14,7 +14,7 @@ proc sc_global_placement_density { args } {
|
|
|
14
14
|
|
|
15
15
|
set density_args []
|
|
16
16
|
if { ![info exists flags(-exclude_padding)] } {
|
|
17
|
-
set gpl_padding [
|
|
17
|
+
set gpl_padding [sc_cfg_tool_task_get var pad_global_place]
|
|
18
18
|
|
|
19
19
|
lappend density_args -pad_left $gpl_padding
|
|
20
20
|
lappend density_args -pad_right $gpl_padding
|
|
@@ -238,10 +238,10 @@ proc sc_design_has_unplaced_macros { } {
|
|
|
238
238
|
# Print macros placement
|
|
239
239
|
###########################
|
|
240
240
|
|
|
241
|
-
proc sc_print_macro_information { } {
|
|
241
|
+
proc sc_print_macro_information { { insts [] } } {
|
|
242
242
|
set print_header "true"
|
|
243
243
|
foreach inst [[ord::get_db_block] getInsts] {
|
|
244
|
-
if { [$inst isBlock] } {
|
|
244
|
+
if { [$inst isBlock] || [lsearch -exact $insts [$inst getName]] != -1 } {
|
|
245
245
|
set master [$inst getMaster]
|
|
246
246
|
set status [$inst getPlacementStatus]
|
|
247
247
|
|
|
@@ -388,17 +388,22 @@ proc sc_psm_check_nets { } {
|
|
|
388
388
|
# Save an image
|
|
389
389
|
###########################
|
|
390
390
|
|
|
391
|
-
proc sc_save_image { title path { gif
|
|
391
|
+
proc sc_save_image { title path { gif -1 } { pixels 1000 } } {
|
|
392
392
|
utl::info FLW 1 "Saving \"$title\" to $path"
|
|
393
393
|
|
|
394
394
|
save_image -resolution [sc_image_resolution $pixels] \
|
|
395
395
|
-area [sc_image_area] \
|
|
396
396
|
$path
|
|
397
397
|
|
|
398
|
-
if { $gif } {
|
|
398
|
+
if { $gif >= 0 } {
|
|
399
|
+
set gif_args []
|
|
400
|
+
if { [sc_check_version 26866] } {
|
|
401
|
+
lappend gif_args -key $gif
|
|
402
|
+
}
|
|
399
403
|
save_animated_gif -add \
|
|
400
404
|
-resolution [sc_image_resolution $pixels] \
|
|
401
|
-
-area [sc_image_area]
|
|
405
|
+
-area [sc_image_area] \
|
|
406
|
+
{*}$gif_args
|
|
402
407
|
}
|
|
403
408
|
}
|
|
404
409
|
|
|
@@ -458,6 +463,10 @@ proc sc_image_setup_default { } {
|
|
|
458
463
|
gui::set_display_controls "Nets/*" visible true
|
|
459
464
|
gui::set_display_controls "Instances/*" visible true
|
|
460
465
|
gui::set_display_controls "Shape Types/*" visible true
|
|
466
|
+
if { [llength [[ord::get_db_block] getBTerms]] > 10000 } {
|
|
467
|
+
# Avoid performance issues with too many IOs
|
|
468
|
+
gui::set_display_controls "Shape Types/Pins" visible false
|
|
469
|
+
}
|
|
461
470
|
gui::set_display_controls "Misc/Instances/*" visible true
|
|
462
471
|
gui::set_display_controls "Misc/Instances/Pin Names" visible false
|
|
463
472
|
gui::set_display_controls "Misc/Scale bar" visible true
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
set sc_scenarios [dict keys [sc_cfg_get constraint timing]]
|
|
1
|
+
set sc_scenarios [dict keys [sc_cfg_get constraint timing scenario]]
|
|
2
2
|
set sc_delaymodel [sc_cfg_get asic delaymodel]
|
|
3
3
|
|
|
4
4
|
# Read Liberty
|
|
@@ -7,7 +7,7 @@ define_corners {*}$sc_scenarios
|
|
|
7
7
|
foreach corner $sc_scenarios {
|
|
8
8
|
foreach lib $sc_logiclibs {
|
|
9
9
|
set lib_filesets []
|
|
10
|
-
foreach libcorner [sc_cfg_get constraint timing $corner libcorner] {
|
|
10
|
+
foreach libcorner [sc_cfg_get constraint timing scenario $corner libcorner] {
|
|
11
11
|
if { [sc_cfg_exists library $lib asic libcornerfileset $libcorner $sc_delaymodel] } {
|
|
12
12
|
lappend lib_filesets \
|
|
13
13
|
{*}[sc_cfg_get library $lib asic libcornerfileset $libcorner $sc_delaymodel]
|
|
@@ -8,7 +8,7 @@ file mkdir reports/power
|
|
|
8
8
|
file mkdir reports/markers
|
|
9
9
|
|
|
10
10
|
set fields "{capacitance slew input_pins hierarcial_pins net fanout}"
|
|
11
|
-
set sta_top_n_paths [
|
|
11
|
+
set sta_top_n_paths [sc_cfg_tool_task_get var sta_top_n_paths]
|
|
12
12
|
set PREFIX "SC_METRIC:"
|
|
13
13
|
|
|
14
14
|
if { [sc_cfg_tool_task_check_in_list setup var reports] } {
|
|
@@ -84,13 +84,16 @@ if { [sc_cfg_tool_task_check_in_list drv_violations var reports] } {
|
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
puts "$PREFIX floating nets"
|
|
87
|
-
|
|
87
|
+
puts "Reporting floating nets: reports/floating_nets.rpt"
|
|
88
|
+
tee -quiet -file reports/floating_nets.rpt \
|
|
88
89
|
"report_floating_nets -verbose"
|
|
89
90
|
if { [sc_check_version 19048] } {
|
|
90
91
|
puts "$PREFIX overdriven nets"
|
|
91
|
-
|
|
92
|
+
puts "Reporting overdriven nets: reports/overdriven_nets.rpt"
|
|
93
|
+
tee -quiet -file reports/overdriven_nets.rpt \
|
|
92
94
|
"report_overdriven_nets -verbose"
|
|
93
|
-
|
|
95
|
+
puts "Reporting overdriven nets: reports/overdriven_nets_with_parallel.rpt"
|
|
96
|
+
tee -quiet -file reports/overdriven_nets_with_parallel.rpt \
|
|
94
97
|
"report_overdriven_nets -include_parallel_driven -verbose"
|
|
95
98
|
}
|
|
96
99
|
|
|
@@ -1,3 +1,11 @@
|
|
|
1
1
|
write_db "outputs/${sc_topmodule}.odb"
|
|
2
2
|
write_def "outputs/${sc_topmodule}.def"
|
|
3
3
|
write_verilog -include_pwr_gnd "outputs/${sc_topmodule}.vg"
|
|
4
|
+
|
|
5
|
+
set remove_cells []
|
|
6
|
+
foreach lib [sc_cfg_get asic asiclib] {
|
|
7
|
+
foreach celltype "decap tie filler tap endcap antenna physicalonly" {
|
|
8
|
+
lappend remove_cells {*}[sc_cfg_get library $lib asic cells $celltype]
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
write_verilog -remove_cells $remove_cells "outputs/${sc_topmodule}.lec.vg"
|