siliconcompiler 0.35.2__py3-none-any.whl → 0.35.4__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/apps/smake.py +106 -100
- siliconcompiler/checklist.py +2 -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 +53 -22
- siliconcompiler/constraints/fpga_timing.py +5 -6
- siliconcompiler/data/templates/replay/replay.sh.j2 +27 -14
- siliconcompiler/flowgraph.py +418 -129
- siliconcompiler/library.py +5 -4
- siliconcompiler/package/__init__.py +17 -6
- siliconcompiler/package/https.py +10 -5
- siliconcompiler/project.py +92 -33
- siliconcompiler/remote/client.py +17 -6
- siliconcompiler/scheduler/docker.py +24 -25
- siliconcompiler/scheduler/scheduler.py +284 -121
- siliconcompiler/scheduler/schedulernode.py +196 -90
- siliconcompiler/scheduler/slurm.py +113 -29
- siliconcompiler/scheduler/taskscheduler.py +0 -7
- siliconcompiler/schema/__init__.py +3 -2
- siliconcompiler/schema/_metadata.py +1 -1
- siliconcompiler/schema/baseschema.py +205 -93
- siliconcompiler/schema/editableschema.py +29 -0
- siliconcompiler/schema/namedschema.py +21 -13
- siliconcompiler/schema/parametervalue.py +14 -2
- siliconcompiler/schema/safeschema.py +18 -7
- siliconcompiler/schema_support/dependencyschema.py +4 -3
- siliconcompiler/schema_support/option.py +82 -1
- siliconcompiler/schema_support/pathschema.py +14 -15
- siliconcompiler/schema_support/record.py +5 -4
- siliconcompiler/targets/asap7_demo.py +4 -1
- siliconcompiler/tool.py +56 -29
- siliconcompiler/tools/builtin/__init__.py +2 -0
- siliconcompiler/tools/builtin/filter.py +8 -1
- siliconcompiler/tools/builtin/importfiles.py +2 -0
- siliconcompiler/tools/klayout/__init__.py +3 -0
- siliconcompiler/tools/klayout/scripts/klayout_convert_drc_db.py +1 -0
- siliconcompiler/tools/klayout/scripts/klayout_export.py +1 -0
- siliconcompiler/tools/klayout/scripts/klayout_operations.py +1 -0
- siliconcompiler/tools/klayout/scripts/klayout_show.py +2 -1
- siliconcompiler/tools/klayout/scripts/klayout_utils.py +3 -4
- siliconcompiler/tools/klayout/show.py +17 -5
- siliconcompiler/tools/openroad/__init__.py +27 -1
- siliconcompiler/tools/openroad/_apr.py +81 -4
- siliconcompiler/tools/openroad/clock_tree_synthesis.py +1 -0
- siliconcompiler/tools/openroad/global_placement.py +1 -0
- siliconcompiler/tools/openroad/init_floorplan.py +116 -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 +42 -4
- siliconcompiler/tools/openroad/scripts/apr/sc_irdrop.tcl +146 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_repair_design.tcl +1 -1
- siliconcompiler/tools/openroad/scripts/apr/sc_write_data.tcl +4 -6
- siliconcompiler/tools/openroad/scripts/common/procs.tcl +1 -1
- siliconcompiler/tools/openroad/scripts/common/reports.tcl +1 -1
- siliconcompiler/tools/openroad/scripts/rcx/sc_rcx_bench.tcl +2 -4
- siliconcompiler/tools/opensta/__init__.py +1 -1
- siliconcompiler/tools/opensta/scripts/sc_timing.tcl +17 -12
- 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/prepareLib.py +7 -2
- 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 +62 -2
- siliconcompiler/tools/yosys/syn_fpga.py +8 -0
- siliconcompiler/toolscripts/_tools.json +6 -6
- siliconcompiler/utils/__init__.py +243 -51
- siliconcompiler/utils/curation.py +89 -56
- siliconcompiler/utils/issue.py +6 -1
- siliconcompiler/utils/multiprocessing.py +35 -2
- siliconcompiler/utils/paths.py +21 -0
- siliconcompiler/utils/settings.py +141 -0
- {siliconcompiler-0.35.2.dist-info → siliconcompiler-0.35.4.dist-info}/METADATA +5 -4
- {siliconcompiler-0.35.2.dist-info → siliconcompiler-0.35.4.dist-info}/RECORD +86 -83
- {siliconcompiler-0.35.2.dist-info → siliconcompiler-0.35.4.dist-info}/WHEEL +0 -0
- {siliconcompiler-0.35.2.dist-info → siliconcompiler-0.35.4.dist-info}/entry_points.txt +0 -0
- {siliconcompiler-0.35.2.dist-info → siliconcompiler-0.35.4.dist-info}/licenses/LICENSE +0 -0
- {siliconcompiler-0.35.2.dist-info → siliconcompiler-0.35.4.dist-info}/top_level.txt +0 -0
|
@@ -10,7 +10,7 @@ Sources: https://github.com/The-OpenROAD-Project/OpenROAD
|
|
|
10
10
|
|
|
11
11
|
Installation: https://github.com/The-OpenROAD-Project/OpenROAD
|
|
12
12
|
'''
|
|
13
|
-
from typing import List, Union
|
|
13
|
+
from typing import List, Union, Optional
|
|
14
14
|
|
|
15
15
|
from siliconcompiler import StdCellLibrary
|
|
16
16
|
from siliconcompiler import PDK
|
|
@@ -346,12 +346,38 @@ class OpenROADStdCellLibrary(StdCellLibrary):
|
|
|
346
346
|
|
|
347
347
|
|
|
348
348
|
class OpenROADTask(ASICTask):
|
|
349
|
+
"""
|
|
350
|
+
Base class for tasks involving the OpenROAD EDA tool chain.
|
|
351
|
+
|
|
352
|
+
This class provides common functionality for configuring OpenROAD execution,
|
|
353
|
+
such as setting up debug levels for internal tools.
|
|
354
|
+
"""
|
|
349
355
|
def __init__(self):
|
|
350
356
|
super().__init__()
|
|
351
357
|
|
|
352
358
|
self.add_parameter("debug_level", "{(str,str,int)}",
|
|
353
359
|
'list of "tool key level" to enable debugging of OpenROAD')
|
|
354
360
|
|
|
361
|
+
def add_openroad_debuglevel(self, tool: str, category: str, level: int,
|
|
362
|
+
step: Optional[str] = None, index: Optional[str] = None,
|
|
363
|
+
clobber: bool = False) -> None:
|
|
364
|
+
"""
|
|
365
|
+
Configures the debug logging level for a specific OpenROAD tool and category.
|
|
366
|
+
|
|
367
|
+
Args:
|
|
368
|
+
tool: The name of the OpenROAD tool (e.g., "GRT", "PSM").
|
|
369
|
+
category: The specific debug category or keyword within the tool.
|
|
370
|
+
level: The integer verbosity level for the debug output.
|
|
371
|
+
step: The specific step to apply this configuration to.
|
|
372
|
+
index: The specific index to apply this configuration to.
|
|
373
|
+
clobber: If True, overwrites the existing debug level configuration.
|
|
374
|
+
If False, appends this configuration to the existing list.
|
|
375
|
+
"""
|
|
376
|
+
if clobber:
|
|
377
|
+
self.set("var", "debug_level", (tool, category, level), step=step, index=index)
|
|
378
|
+
else:
|
|
379
|
+
self.add("var", "debug_level", (tool, category, level), step=step, index=index)
|
|
380
|
+
|
|
355
381
|
def tool(self):
|
|
356
382
|
return "openroad"
|
|
357
383
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import json
|
|
3
3
|
|
|
4
|
-
from typing import List
|
|
4
|
+
from typing import List, Union, Optional
|
|
5
5
|
|
|
6
6
|
from siliconcompiler import sc_open
|
|
7
7
|
from siliconcompiler import utils
|
|
@@ -411,6 +411,14 @@ class OpenROADDRTParameter(_OpenROADDRTCommonParameter):
|
|
|
411
411
|
|
|
412
412
|
|
|
413
413
|
class APRTask(OpenROADTask):
|
|
414
|
+
"""
|
|
415
|
+
Base class for OpenROAD-based Automatic Place and Route (APR) tasks.
|
|
416
|
+
|
|
417
|
+
This task initializes specific configurations for OpenROAD, including
|
|
418
|
+
report filtering, image generation settings, heatmap binning, and
|
|
419
|
+
power analysis corners.
|
|
420
|
+
"""
|
|
421
|
+
|
|
414
422
|
def __init__(self):
|
|
415
423
|
super().__init__()
|
|
416
424
|
|
|
@@ -423,6 +431,7 @@ class APRTask(OpenROADTask):
|
|
|
423
431
|
"fmax",
|
|
424
432
|
"power",
|
|
425
433
|
"check_setup",
|
|
434
|
+
"report_buffers",
|
|
426
435
|
"placement_density",
|
|
427
436
|
"routing_congestion",
|
|
428
437
|
"power_density",
|
|
@@ -456,11 +465,79 @@ class APRTask(OpenROADTask):
|
|
|
456
465
|
self.add_parameter("global_connect_fileset", "[(str,str)]",
|
|
457
466
|
"list of libraries and filesets to generate connects from")
|
|
458
467
|
|
|
459
|
-
def
|
|
468
|
+
def add_openroad_skipreport(self, report_type: Union[List[str], str],
|
|
469
|
+
step: Optional[str] = None, index: Optional[str] = None,
|
|
470
|
+
clobber: bool = False) -> None:
|
|
471
|
+
"""
|
|
472
|
+
Adds or sets report types to be skipped during OpenROAD execution.
|
|
473
|
+
|
|
474
|
+
Args:
|
|
475
|
+
report_type: The name of the report(s) to skip (e.g., 'routing_congestion').
|
|
476
|
+
step: The specific step to apply this configuration to.
|
|
477
|
+
index: The specific index to apply this configuration to.
|
|
478
|
+
clobber: If True, overwrites the existing list of skipped reports.
|
|
479
|
+
If False, appends to the existing list.
|
|
480
|
+
"""
|
|
481
|
+
if clobber:
|
|
482
|
+
self.set("var", "skip_reports", report_type, step=step, index=index)
|
|
483
|
+
else:
|
|
484
|
+
self.add("var", "skip_reports", report_type, step=step, index=index)
|
|
485
|
+
|
|
486
|
+
def set_openroad_enableimages(self, enable: bool,
|
|
487
|
+
step: Optional[str] = None, index: Optional[str] = None) -> None:
|
|
488
|
+
"""
|
|
489
|
+
Enables or disables the generation of design images at the end of the task.
|
|
490
|
+
|
|
491
|
+
Args:
|
|
492
|
+
enable: True to generate images, False to disable.
|
|
493
|
+
step: The specific step to apply this configuration to.
|
|
494
|
+
index: The specific index to apply this configuration to.
|
|
495
|
+
"""
|
|
496
|
+
self.set("var", "ord_enable_images", enable, step=step, index=index)
|
|
497
|
+
|
|
498
|
+
def set_openroad_heatmapbins(self, x: int, y: int,
|
|
499
|
+
step: Optional[str] = None, index: Optional[str] = None) -> None:
|
|
500
|
+
"""
|
|
501
|
+
Configures the resolution of the heatmap images.
|
|
502
|
+
|
|
503
|
+
Args:
|
|
504
|
+
x: The number of bins in the X direction.
|
|
505
|
+
y: The number of bins in the Y direction.
|
|
506
|
+
step: The specific step to apply this configuration to.
|
|
507
|
+
index: The specific index to apply this configuration to.
|
|
508
|
+
"""
|
|
509
|
+
self.set("var", "ord_heatmap_bins", (x, y), step=step, index=index)
|
|
510
|
+
|
|
511
|
+
def set_openroad_powercorner(self, corner: str,
|
|
512
|
+
step: Optional[str] = None, index: Optional[str] = None) -> None:
|
|
513
|
+
"""
|
|
514
|
+
Sets the specific process corner used for power analysis.
|
|
515
|
+
|
|
516
|
+
Args:
|
|
517
|
+
corner: The name of the timing/power corner.
|
|
518
|
+
step: The specific step to apply this configuration to.
|
|
519
|
+
index: The specific index to apply this configuration to.
|
|
520
|
+
"""
|
|
521
|
+
self.set("var", "power_corner", corner, step=step, index=index)
|
|
522
|
+
|
|
523
|
+
def add_openroad_globalconnectfileset(self, library: str, fileset: str,
|
|
524
|
+
step: Optional[str] = None, index: Optional[str] = None,
|
|
525
|
+
clobber: bool = False):
|
|
526
|
+
"""
|
|
527
|
+
Adds a library and fileset pair to the global connect configuration.
|
|
528
|
+
|
|
529
|
+
Args:
|
|
530
|
+
library: The name of the library.
|
|
531
|
+
fileset: The name of the fileset.
|
|
532
|
+
step: The specific step to apply this configuration to.
|
|
533
|
+
index: The specific index to apply this configuration to.
|
|
534
|
+
clobber: If True, overwrites the existing global connect settings.
|
|
535
|
+
If False, appends to the existing settings.
|
|
536
|
+
"""
|
|
460
537
|
if clobber:
|
|
461
|
-
self.set("var", "global_connect_fileset", (library, fileset))
|
|
538
|
+
self.set("var", "global_connect_fileset", (library, fileset), step=step, index=index)
|
|
462
539
|
else:
|
|
463
|
-
self.add("var", "global_connect_fileset", (library, fileset))
|
|
540
|
+
self.add("var", "global_connect_fileset", (library, fileset), step=step, index=index)
|
|
464
541
|
|
|
465
542
|
def setup(self):
|
|
466
543
|
"""
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from typing import Union, List, Optional
|
|
2
|
+
|
|
1
3
|
from siliconcompiler.tools.openroad._apr import APRTask
|
|
2
4
|
from siliconcompiler.tools.openroad._apr import OpenROADSTAParameter, OpenROADPPLParameter
|
|
3
5
|
|
|
@@ -5,9 +7,13 @@ from siliconcompiler.tools.openroad._apr import OpenROADSTAParameter, OpenROADPP
|
|
|
5
7
|
class InitFloorplanTask(APRTask,
|
|
6
8
|
OpenROADSTAParameter,
|
|
7
9
|
OpenROADPPLParameter):
|
|
8
|
-
|
|
9
|
-
Perform floorplanning and initial pin placements
|
|
10
|
-
|
|
10
|
+
"""
|
|
11
|
+
Perform floorplanning and initial pin placements.
|
|
12
|
+
|
|
13
|
+
This task handles the initialization of the floorplan, including macro placement
|
|
14
|
+
snapping strategies, cleaning up synthesis artifacts (buffers/dead logic),
|
|
15
|
+
and defining padring or bumpmap configurations.
|
|
16
|
+
"""
|
|
11
17
|
def __init__(self):
|
|
12
18
|
super().__init__()
|
|
13
19
|
|
|
@@ -19,6 +25,79 @@ class InitFloorplanTask(APRTask,
|
|
|
19
25
|
"remove logic which does not drive a primary output", defvalue=True)
|
|
20
26
|
|
|
21
27
|
self.add_parameter("padringfileset", "[str]", "filesets to generate a padring")
|
|
28
|
+
self.add_parameter("bumpmapfileset", "[str]", "filesets to generate a bumpmap")
|
|
29
|
+
|
|
30
|
+
def set_openroad_snapstrategy(self, snap: str,
|
|
31
|
+
step: Optional[str] = None, index: Optional[str] = None):
|
|
32
|
+
"""
|
|
33
|
+
Sets the snapping strategy for macro placement.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
snap: The snapping mode. Options are typically 'none', 'site', or 'grid'.
|
|
37
|
+
step: The specific step to apply this configuration to.
|
|
38
|
+
index: The specific index to apply this configuration to.
|
|
39
|
+
"""
|
|
40
|
+
self.set("var", "ifp_snap_strategy", snap, step=step, index=index)
|
|
41
|
+
|
|
42
|
+
def set_openroad_removebuffers(self, enable: bool,
|
|
43
|
+
step: Optional[str] = None, index: Optional[str] = None):
|
|
44
|
+
"""
|
|
45
|
+
Enables or disables the removal of buffers inserted during synthesis.
|
|
46
|
+
|
|
47
|
+
Args:
|
|
48
|
+
enable: True to remove synthesis buffers, False to keep them.
|
|
49
|
+
step: The specific step to apply this configuration to.
|
|
50
|
+
index: The specific index to apply this configuration to.
|
|
51
|
+
"""
|
|
52
|
+
self.set("var", "remove_synth_buffers", enable, step=step, index=index)
|
|
53
|
+
|
|
54
|
+
def set_openroad_removedeadlogic(self, enable: bool,
|
|
55
|
+
step: Optional[str] = None, index: Optional[str] = None):
|
|
56
|
+
"""
|
|
57
|
+
Enables or disables the removal of logic that does not drive a primary output.
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
enable: True to remove dead logic, False to keep it.
|
|
61
|
+
step: The specific step to apply this configuration to.
|
|
62
|
+
index: The specific index to apply this configuration to.
|
|
63
|
+
"""
|
|
64
|
+
self.set("var", "remove_dead_logic", enable, step=step, index=index)
|
|
65
|
+
|
|
66
|
+
def add_openroad_padringfileset(self, fileset: Union[str, List[str]],
|
|
67
|
+
step: Optional[str] = None, index: Optional[str] = None,
|
|
68
|
+
clobber: bool = False):
|
|
69
|
+
"""
|
|
70
|
+
Adds fileset(s) used to generate the I/O pad ring.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
fileset: A string name or list of names representing the padring filesets.
|
|
74
|
+
step: The specific step to apply this configuration to.
|
|
75
|
+
index: The specific index to apply this configuration to.
|
|
76
|
+
clobber: If True, overwrites the existing padring fileset list.
|
|
77
|
+
If False, appends to the existing list.
|
|
78
|
+
"""
|
|
79
|
+
if clobber:
|
|
80
|
+
self.set("var", "padringfileset", fileset, step=step, index=index)
|
|
81
|
+
else:
|
|
82
|
+
self.add("var", "padringfileset", fileset, step=step, index=index)
|
|
83
|
+
|
|
84
|
+
def add_openroad_bumpmapfileset(self, fileset: Union[str, List[str]],
|
|
85
|
+
step: Optional[str] = None, index: Optional[str] = None,
|
|
86
|
+
clobber: bool = False):
|
|
87
|
+
"""
|
|
88
|
+
Adds fileset(s) used to generate the bump map for flip-chip or 3D designs.
|
|
89
|
+
|
|
90
|
+
Args:
|
|
91
|
+
fileset: A string name or list of names representing the bumpmap filesets.
|
|
92
|
+
step: The specific step to apply this configuration to.
|
|
93
|
+
index: The specific index to apply this configuration to.
|
|
94
|
+
clobber: If True, overwrites the existing bumpmap fileset list.
|
|
95
|
+
If False, appends to the existing list.
|
|
96
|
+
"""
|
|
97
|
+
if clobber:
|
|
98
|
+
self.set("var", "bumpmapfileset", fileset, step=step, index=index)
|
|
99
|
+
else:
|
|
100
|
+
self.add("var", "bumpmapfileset", fileset, step=step, index=index)
|
|
22
101
|
|
|
23
102
|
def task(self):
|
|
24
103
|
return "init_floorplan"
|
|
@@ -62,8 +141,38 @@ class InitFloorplanTask(APRTask,
|
|
|
62
141
|
for fileset in self.get("var", "padringfileset"):
|
|
63
142
|
self.add_required_key(self.project.design, "fileset", fileset, "file", "tcl")
|
|
64
143
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
144
|
+
if self.get("var", "bumpmapfileset"):
|
|
145
|
+
self.add_required_key("var", "bumpmapfileset")
|
|
146
|
+
|
|
147
|
+
for fileset in self.get("var", "bumpmapfileset"):
|
|
148
|
+
self.add_required_key(self.project.design, "fileset", fileset, "file", "bmap")
|
|
149
|
+
|
|
150
|
+
# Mark requires for components, pin, and floorplan placements
|
|
151
|
+
for component in self.project.constraint.component.get_component().values():
|
|
152
|
+
self.add_required_key(component, "placement")
|
|
153
|
+
self.add_required_key(component, "rotation")
|
|
154
|
+
if component.get_partname(step=self.step, index=self.index):
|
|
155
|
+
self.add_required_key(component, "partname")
|
|
156
|
+
|
|
157
|
+
for pin in self.project.constraint.pin.get_pinconstraint().values():
|
|
158
|
+
if pin.get_placement(step=self.step, index=self.index) is not None:
|
|
159
|
+
self.add_required_key(pin, "placement")
|
|
160
|
+
if pin.get_layer(step=self.step, index=self.index) is not None:
|
|
161
|
+
self.add_required_key(pin, "layer")
|
|
162
|
+
if pin.get_side(step=self.step, index=self.index) is not None:
|
|
163
|
+
self.add_required_key(pin, "side")
|
|
164
|
+
if pin.get_order(step=self.step, index=self.index) is not None:
|
|
165
|
+
self.add_required_key(pin, "order")
|
|
166
|
+
|
|
167
|
+
self.add_required_key(self.mainlib, "asic", "site")
|
|
168
|
+
if self.project.constraint.area.get_diearea(step=self.step, index=self.index) and \
|
|
169
|
+
self.project.constraint.area.get_corearea(step=self.step, index=self.index):
|
|
170
|
+
self.add_required_key(self.project.constraint.area, "diearea")
|
|
171
|
+
self.add_required_key(self.project.constraint.area, "corearea")
|
|
68
172
|
else:
|
|
69
|
-
self.
|
|
173
|
+
self.add_required_key(self.project.constraint.area, "aspectratio")
|
|
174
|
+
self.add_required_key(self.project.constraint.area, "density")
|
|
175
|
+
self.add_required_key(self.project.constraint.area, "coremargin")
|
|
176
|
+
|
|
177
|
+
if self.mainlib.get("tool", "openroad", "tracks"):
|
|
178
|
+
self.add_required_key(self.mainlib, "tool", "openroad", "tracks")
|
|
@@ -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-26750", 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]
|