Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tweak Classic Flow's Antenna Insertion Regime #255

Merged
merged 24 commits into from
Nov 15, 2023
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@
libparse ? import ./nix/libparse.nix { inherit pkgs; },
magic ? import ./nix/magic.nix { inherit pkgs; },
netgen ? import ./nix/netgen.nix { inherit pkgs; },
opensta ? import ./nix/opensta.nix { inherit pkgs; },
openroad ? pkgs.libsForQt5.callPackage ./nix/openroad.nix {
inherit pkgs;
inherit opensta;
},
surelog ? import ./nix/surelog.nix { inherit pkgs; },
verilator ? import ./nix/verilator.nix { inherit pkgs; },
Expand Down Expand Up @@ -57,6 +59,7 @@ with pkgs; with python3.pkgs; buildPythonPackage rec {
lighter
synlig-sv
] ++ (if builtins.currentSystem == "x86_64-linux" then [ys-ghdl] else []) ))
opensta
openroad
klayout
netgen
Expand Down
45 changes: 23 additions & 22 deletions docs/source/usage/hardening_macros.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,22 +217,6 @@ This will treat cells as "wider" than they are, which has an impact on routing
and diode insertion. If you increase the padding, make sure to recalculate the
`PL_TARGET_DENSITY_PCT` as such: {math}`util \approx FP\_CORE\_UTIL + 10 + 5 * GPL\_CELL\_PADDING`.


#### Antenna Mitigation
To help mitigate the antenna effect, after Global Placement there are also two
other steps you may choose to enable, requiring {math}`GPL\_CELL\_PADDING \ge 2`:

* [`Odb.DiodesOnPorts`](../reference/step_config_vars.md#Odb.DiodesOnPorts):
Unconditionally inserts diodes on design ports. This is helpful for hardening
macros, where you don't know how long the wires external to the macro are
going to be.
* [`Odb.HeuristicDiodeInsertion`](../reference/step_config_vars.md#Odb.HeuristicDiodeInsertion):
Inserts diodes based on the virtual wire length, s.t. nets longer than
a specific threshold get a diode inserted by default.

Both are disabled by default, as a later mitigation during Global Routing is
sufficient for most designs.

### Detailed Placement

For a rundown of what detailed placement does, please see the Detailed Placement
Expand Down Expand Up @@ -260,17 +244,34 @@ TODO:
## Routing

Most configurations here were optimized based on a large design set and are
best left as is; see the steps here:
* [`OpenROAD.GlobalRouting`](../reference/step_config_vars.md#OpenROAD.GlobalRouting)
best left as is.

Routing in general goes through four phases:

* [`OpenROAD.GlobalRouting`](../reference/step_config_vars.md#OpenROAD.GlobalRouting): using OpenROAD.GlobalRouting
* [`OpenROAD.DetailedRouting`](../reference/step_config_vars.md#OpenROAD.DetailedRouting)

The subsections include some notes:

### Antenna Mitigation
During global routing, you can set [`GRT_REPAIR_ANTENNAS`](../reference/step_config_vars.md#OpenROAD.GlobalRouting.GRT_REPAIR_ANTENNAS).

This will enable diode insertion during global routing for long nets, which will
mitigate the effect. This is enabled by default.
#### Antenna Mitigation
To help mitigate the antenna effect, after Global Placement there are also three
other steps you may choose to enable:

* [`Odb.DiodesOnPorts`](../reference/step_config_vars.md#Odb.DiodesOnPorts):
Unconditionally inserts diodes on design ports. This is helpful for hardening
macros, where you don't know how long the wires external to the macro are
going to be. Requires {math}`GPL\_CELL\_PADDING \ge 2`.
* [`Odb.HeuristicDiodeInsertion`](../reference/step_config_vars.md#Odb.HeuristicDiodeInsertion):
Inserts diodes based on the virtual wire length, s.t. nets longer than
a specific threshold get a diode inserted by default. Disabled by default, but
can be enabled by setting flow config variable `RUN_HEURISTIC_DIODE_INSERTION` to `true`.
Requires {math}`GPL\_CELL\_PADDING \ge 2`.
* [`OpenROAD.RepairAntennas`](../reference/step_config_vars.md#OpenROAD.RepairAntennas):
Uses a more advanced antenna repair algorithm built into OpenROAD. Enabled by
default, can be disabled by setting flow config variable `RUN_ANTENNA_REPAIR`
to `false`.


### `DRT_THREADS`

Expand Down
10 changes: 7 additions & 3 deletions nix/openroad.nix
Original file line number Diff line number Diff line change
Expand Up @@ -13,28 +13,30 @@
# limitations under the License.
{
pkgs ? import ./pkgs.nix {},
opensta ? import ./opensta.nix {},
libsForQt5 ? pkgs.libsForQt5,
}:

with pkgs; let
abc = import ./openroad-abc.nix { inherit pkgs; };
in clangStdenv.mkDerivation rec {
name = "openroad";
rev = "0a584d123190322b0725d5440c2c486d91d3afd8";
rev = "6f9b2bb8b808b1bb5831d4525d868212ae50517a";

src = fetchFromGitHub {
owner = "The-OpenROAD-Project";
repo = "OpenROAD";
inherit rev;
sha256 = "sha256-VA/AV7eCdjA6NWVahjZFKs3zP512+XEIMhwVJOwT4lY=";
fetchSubmodules = true;
sha256 = "sha256-lLToR+c2oOmgfuw7RX1W/QxwBWhoZWUmdzix3CrxWmA=";
};

cmakeFlags = [
"-DTCL_LIBRARY=${tcl}/lib/libtcl${stdenv.hostPlatform.extensions.sharedLibrary}"
"-DTCL_HEADER=${tcl}/include/tcl.h"
"-DUSE_SYSTEM_ABC:BOOL=ON"
"-DUSE_SYSTEM_BOOST:BOOL=ON"
"-DUSE_SYSTEM_OPENSTA:BOOL=ON"
"-DOPENSTA_HOME=${opensta}"
"-DABC_LIBRARY=${abc}/lib/libabc.a"
"-DCMAKE_CXX_FLAGS=-I${abc}/include"
"-DENABLE_TESTS:BOOL=OFF"
Expand All @@ -48,6 +50,7 @@ in clangStdenv.mkDerivation rec {
sed -i 's@#include "base/abc/abc.h"@#include <base/abc/abc.h>@' src/rmp/src/Restructure.cpp
sed -i 's@#include "base/main/abcapis.h"@#include <base/main/abcapis.h>@' src/rmp/src/Restructure.cpp
sed -i 's@# tclReadline@target_link_libraries(openroad readline)@' src/CMakeLists.txt
sed -i 's@%include "../../src/Exception.i"@%include "../../Exception.i"@' src/dbSta/src/dbSta.i
'';

buildInputs = [
Expand All @@ -65,6 +68,7 @@ in clangStdenv.mkDerivation rec {

lemon-graph
or-tools
opensta
glpk
zlib
clp
Expand Down
64 changes: 64 additions & 0 deletions nix/opensta.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Copyright 2023 Efabless Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
{
pkgs ? import ./pkgs.nix {},
}:

with pkgs; clangStdenv.mkDerivation rec {
name = "opensta";
rev = "3e2295adfd5ffb7053aa6bb68f31b0eae8f2986f";

src = fetchFromGitHub {
owner = "The-OpenROAD-Project";
repo = "OpenSTA";
inherit rev;
sha256 = "sha256-SzwJTg8MvydBsy6+Y8GOQnfumtmGHP81I1D6TcAS+tU=";
};

cmakeFlags = [
"-DTCL_LIBRARY=${tcl}/lib/libtcl${stdenv.hostPlatform.extensions.sharedLibrary}"
"-DTCL_HEADER=${tcl}/include/tcl.h"
];

buildInputs = [
tcl
zlib
];

# Files needed by OpenROAD when building with external OpenSTA
postInstall = ''
for file in $(find ${src} | grep -v examples | grep -E "(\.tcl|\.i)\$"); do
relative_dir=$(dirname $(realpath --relative-to=${src} $file))
true_dir=$out/$relative_dir
mkdir -p $true_dir
cp $file $true_dir
done
for file in $(find ${src} | grep -v examples | grep -E "(\.hh)\$"); do
relative_dir=$(dirname $(realpath --relative-to=${src} $file))
true_dir=$out/include/$relative_dir
mkdir -p $true_dir
cp $file $true_dir
done
find $out
'';

nativeBuildInputs = [
swig
pkg-config
cmake
gnumake
flex
bison
];
}
6 changes: 6 additions & 0 deletions openlane/config/pdk_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,12 @@ def process_sta(key: str):
new["CVCRC"] = os.path.join(config["CVC_SCRIPTS_DIR"], "cvcrc")
new["CVC_MODELS"] = os.path.join(config["CVC_SCRIPTS_DIR"], "models")

# 11. Heuristic Antenna Threshold
if new["PDK"].startswith("sky130"):
new["HEURISTIC_ANTENNA_THRESHOLD"] = 90
elif new["PDK"].startswith("gf180mcu"):
new["HEURISTIC_ANTENNA_THRESHOLD"] = 130

# x1. Disconnected Modules (sky130)
if new["PDK"].startswith("sky130"):
new["IGNORE_DISCONNECTED_MODULES"] = "sky130_fd_sc_hd__conb_1"
Expand Down
16 changes: 13 additions & 3 deletions openlane/config/variable.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,9 +225,19 @@ class Variable:
must be represented in terms of their official symbols.

:param pdk: Whether this variable is expected to be given a default value
by a PDK or not. If this variable is not of an option type and the PDK
does not provide this value, the PDK is considered incompatible with
the Step declaring this value.
by a PDK or not.

If this is true, and the variable is not of an option type, a PDK *must*
give this variable a default value in order to be marked compatible
with a step.

If this is true and the variable is of an option type, a PDK may
optionally provide a default value for this variable, however steps
must presume it is ``null``.

If this is false, a PDK is not allowed to set a default value for
this variable. In current versions of OpenLane, the value will be
silently ignored, but warnings or errors may occur in future versions.
"""

known_variable_names: ClassVar[Set[str]] = set()
Expand Down
84 changes: 30 additions & 54 deletions openlane/flows/classic.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@
"Enables the Odb.HeuristicDiodeInsertion step.",
default=False, # For compatibility with OL1
),
Variable(
"RUN_ANTENNA_REPAIR",
bool,
"Enables the OpenROAD.RepairAntennas step.",
default=True,
deprecated_names=["GRT_REPAIR_ANTENNAS"],
),
Variable(
"RUN_DRT",
bool,
Expand Down Expand Up @@ -212,6 +219,7 @@
"OpenROAD.RCX": ["RUN_SPEF_EXTRACTION"],
"OpenROAD.TapEndcapInsertion": ["RUN_TAP_ENDCAP_INSERTION"],
"Odb.HeuristicDiodeInsertion": ["RUN_HEURISTIC_DIODE_INSERTION"],
"OpenROAD.RepairAntennas": ["RUN_ANTENNA_REPAIR"],
"OpenROAD.DetailedRouting": ["RUN_DRT"],
"OpenROAD.FillInsertion": ["RUN_FILL_INSERTION"],
"OpenROAD.STAPostPNR": ["RUN_MCSTA"],
Expand Down Expand Up @@ -284,18 +292,20 @@ class Classic(SequentialFlow):
Odb.RemovePDNObstructions,
OpenROAD.STAMidPNR,
OpenROAD.RepairDesignPostGPL,
Odb.DiodesOnPorts,
Odb.HeuristicDiodeInsertion,
OpenROAD.DetailedPlacement,
OpenROAD.CTS,
OpenROAD.STAMidPNR,
OpenROAD.ResizerTimingPostCTS,
OpenROAD.STAMidPNR,
OpenROAD.GlobalRouting,
OpenROAD.RepairDesignPostGRT,
Odb.DiodesOnPorts,
Odb.HeuristicDiodeInsertion,
donn marked this conversation as resolved.
Show resolved Hide resolved
OpenROAD.RepairAntennas,
OpenROAD.ResizerTimingPostGRT,
OpenROAD.STAMidPNR,
OpenROAD.DetailedRouting,
OpenROAD.CheckAntennas,
Checker.TrDRC,
Odb.ReportDisconnectedPins,
Checker.DisconnectedPins,
Expand Down Expand Up @@ -373,65 +383,31 @@ class Classic(SequentialFlow):
)


def _vhdlclassic_substitute_verilog_steps(
steps_in: List[Type[Step]],
) -> List[Type[Step]]:
result: List[Type[Step]] = [Yosys.VHDLSynthesis]
for step in steps_in:
# Ignore Verilog-dependent header steps and such
if (
step.id.startswith("Yosys.")
or step.id.startswith("Checker.Lint")
or step.id.startswith("Verilator.")
or step.id == "Odb.SetPowerConnections"
):
continue
result.append(step)
return result


@Flow.factory.register()
class VHDLClassic(SequentialFlow):
"""
A variant of :class:`openlane.flows.Classic` that uses VHDL files as an
input instead of Verilog.
"""

Steps: List[Type[Step]] = [
Yosys.VHDLSynthesis,
Checker.YosysUnmappedCells,
Checker.YosysSynthChecks,
OpenROAD.CheckSDCFiles,
OpenROAD.STAPrePNR,
OpenROAD.Floorplan,
Odb.ManualMacroPlacement,
OpenROAD.TapEndcapInsertion,
OpenROAD.GlobalPlacementSkipIO,
OpenROAD.IOPlacement,
Odb.ApplyDEFTemplate,
Odb.CustomIOPlacement,
OpenROAD.GlobalPlacement,
Odb.AddPDNObstructions,
OpenROAD.GeneratePDN,
Odb.RemovePDNObstructions,
OpenROAD.STAMidPNR,
OpenROAD.RepairDesignPostGPL,
Odb.DiodesOnPorts,
Odb.HeuristicDiodeInsertion,
OpenROAD.DetailedPlacement,
OpenROAD.CTS,
OpenROAD.STAMidPNR,
OpenROAD.ResizerTimingPostCTS,
OpenROAD.STAMidPNR,
OpenROAD.GlobalRouting,
OpenROAD.RepairDesignPostGRT,
OpenROAD.ResizerTimingPostGRT,
OpenROAD.STAMidPNR,
OpenROAD.DetailedRouting,
Checker.TrDRC,
Odb.ReportDisconnectedPins,
Checker.DisconnectedPins,
Odb.ReportWireLength,
Checker.WireLength,
OpenROAD.FillInsertion,
OpenROAD.RCX,
OpenROAD.STAPostPNR,
OpenROAD.IRDropReport,
Magic.StreamOut,
KLayout.StreamOut,
Magic.WriteLEF,
KLayout.XOR,
Checker.XOR,
Magic.DRC,
Checker.MagicDRC,
Magic.SpiceExtraction,
Checker.IllegalOverlap,
Netgen.LVS,
Checker.LVS,
]
Steps: List[Type[Step]] = _vhdlclassic_substitute_verilog_steps(Classic.Steps)

config_vars = _common_config_vars.copy()
gating_config_vars = _common_gating_config_vars.copy()
9 changes: 7 additions & 2 deletions openlane/flows/flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ def get_ordinal_prefix(self) -> str:
used to create a step directory.
"""
max_stage_digits = len(str(self.__max_stage))
return f"%0{max_stage_digits}d-" % self.__ordinal
return f"{str(self.__ordinal).zfill(max_stage_digits)}-"


class Flow(ABC):
Expand Down Expand Up @@ -532,6 +532,11 @@ def start(
# Stored until next start()
self.toolbox = Toolbox(os.path.join(self.run_dir, "tmp"))

log_path = os.path.join(self.run_dir, "flow.log")
log_handler = logging.FileHandler(log_path, mode="a+")
log_handler.setLevel("INFO")
register_additional_handler(log_handler)

warning_log_path = os.path.join(self.run_dir, "warnings.log")
warning_handler = logging.FileHandler(warning_log_path, mode="a+")
warning_handler.setLevel("WARNING")
Expand All @@ -543,7 +548,6 @@ def start(
register_additional_handler(error_handler)

try:

config_res_path = os.path.join(self.run_dir, "resolved.json")
with open(config_res_path, "w") as f:
f.write(self.config.dumps())
Expand All @@ -566,6 +570,7 @@ def start(
finally:
deregister_additional_handler(warning_handler)
deregister_additional_handler(error_handler)
deregister_additional_handler(log_handler)

@protected
@abstractmethod
Expand Down
Loading
Loading