Skip to content

Commit

Permalink
feat!: multiple pnr corners, custom rc values (#591)
Browse files Browse the repository at this point in the history
Resolves #656, #657

Depends on efabless/openlane2-step-unit-tests#42

---------

Signed-off-by: Kareem Farid <[email protected]>
Co-authored-by: Mohamed Gaber <[email protected]>
  • Loading branch information
kareefardi and donn authored Feb 10, 2025
1 parent 4b7b3a7 commit 634c9b9
Show file tree
Hide file tree
Showing 19 changed files with 622 additions and 226 deletions.
43 changes: 41 additions & 2 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,24 @@

* `OpenROAD.*`

* Added `PNR_CORNERS`. An override for `DEFAULT_CORNER` for PnR steps except
for steps using `RSZ_CORNERS` and `CTS_CORNERS`.
* Added `LAYERS_RC`, `VIAS_R`: Unlike OpenLane 1.0.0 variables with similar
names, these are mappings from corners to layer/via RC values.
* `PNR_CORNERS`, `RSZ_CORNERS`, and `CTS_CORNERS` all now support multiple
corners to have the same set of liberty files (as RC values may differ.)
* Added `SET_RC_VERBOSE`, which (very noisily) logs set-RC-related commands
to logs.
* Always read libs before reading odb.
* Added `log_cmd` from OpenROAD-flow-scripts -- neat idea for consistency
* New convenience methods to append flags to calls based on environment
variables
* Lib files are now *always* read BEFORE reading database files.
* **Internal**: Steps now sensitive to `_OPENROAD_GUI` environment variable --
coupled with `--only`, it runs a step in OpenROAD then doesn't quit so you
may inspect the result.
* This is not part of the OpenLane stable API and may be broken at any
moment.
* **Internal**: New convenience methods to append flags to calls based on
environment variables

* `OpenROAD.CTS`

Expand All @@ -60,10 +70,17 @@
* Added `DRT_ANTENNA_MARGIN` which is similar to `GRT_ANTENNA_MARGIN` but for
the aforementioned antenna repair iterations

* Created `OpenROAD.DumpRCValues`

* Creates three reports to help verify that the RC values used for estimation
are set correctly.

* `OpenROAD.GlobalPlacement`

* Added optional variable `PL_ROUTABILITY_MAX_DENSITY_PCT`

* Corrected `GPL_CELL_PADDING` to be an integer.

* `OpenROAD.RepairDesignPostGPL`

* Added optional variable `DESIGN_REPAIR_MAX_UTIL_PCT`
Expand Down Expand Up @@ -106,6 +123,11 @@

* Added `SYNTH_CORNER`: a step-specific override for `DEFAULT_CORNER`.

## Flows

* Classic
* Added `OpenROAD.DumpRCValues` immediately after floorplanning.

## Tool Updates

* Updated nix-eda
Expand Down Expand Up @@ -143,6 +165,11 @@
* States initialized with keys that have values that are `None` now remove
said keys.

* `openlane.steps`

* TclStep
* All `Decimal` values are now passed to Tcl in exponent notation.

* `openlane.config`

* Moved a number of global variables:
Expand All @@ -159,6 +186,11 @@

## API Breaks

* `*`

* `{GPL,DPL}_CELL_PADDING`, `PL_MAX_DISPLACEMENT_{X,Y}` now all integers to
match OpenROAD.

* `Checker.HoldViolations`

* `HOLD_VIOLATION_CORNERS` now defaulting to all corners will require designs
Expand All @@ -171,6 +203,13 @@
meta version of 2 or higher must update their variables from strings to
tuples.

* `OpenROAD.*`

* `LAYERS_RC` now uses a new format. Refer to the documentation for a
description of the new format.
* `VIAS_RC` removed and replaced by `VIAS_R` with a format similar to
`LAYERS_RC`.

* `openlane.steps`

* `TclStep` now uses the IDs uppercased for `CURRENT_` and `SAVE_`.
Expand Down
12 changes: 6 additions & 6 deletions openlane/common/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,30 +11,30 @@
# 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.
import os
import re
import fnmatch
import glob
import gzip
import typing
import fnmatch
import os
import pathlib
import re
import typing
import unicodedata
from math import inf
from typing import (
Any,
Generator,
Iterable,
List,
TypeVar,
Optional,
SupportsFloat,
TypeVar,
Union,
)

import httpx

from .types import AnyPath, Path
from ..__version__ import __version__
from .types import AnyPath, Path

T = TypeVar("T")

Expand Down
81 changes: 79 additions & 2 deletions openlane/config/pdk_compat.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2023 Efabless Corporation
# Copyright 2023-2025 Efabless Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand All @@ -14,7 +14,7 @@
import os
import re
from glob import glob
from typing import Any, List, Mapping, Dict
from typing import Any, Dict, List, Mapping


def migrate_old_config(config: Mapping[str, Any]) -> Dict[str, Any]:
Expand Down Expand Up @@ -214,6 +214,83 @@ def process_sta(key: str):
"max_ss_100C_1v60",
"max_ff_n40C_1v95",
]

# Code below adapted from OpenROAD Flow Scripts under the following license:
#
# BSD 3-Clause License
#
# Copyright (c) 2018-2023, The Regents of the University of California
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:

# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# * Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# new["LAYERS_RC"] = {
# "*tt*": {
# "li1": {"res": 7.176e-02, "cap": 1.499e-04},
# "met1": {"res": 8.929e-04, "cap": 1.72375e-04},
# "met2": {"res": 8.929e-04, "cap": 1.36233e-04},
# "met3": {"res": 1.567e-04, "cap": 2.14962e-04},
# "met4": {"res": 1.567e-04, "cap": 1.54087e-04},
# "met5": {"res": 1.781e-05, "cap": 1.54087e-04},
# },
# "*ff*": {
# "li1": {"res": 0.050232, "cap": 0.00010493},
# "met1": {"res": 0.0006250299999999999, "cap": 0.0001206625},
# "met2": {"res": 0.0006250299999999999, "cap": 9.53631e-05},
# "met3": {
# "res": 0.00010968999999999999,
# "cap": 0.00015047339999999998,
# },
# "met4": {
# "res": 0.00010968999999999999,
# "cap": 0.00010786089999999998,
# },
# "met5": {"res": 1.2467e-05, "cap": 0.00010786089999999998},
# },
# "*ss*": {
# "li1": {"res": 0.09328800000000001, "cap": 0.00019487},
# "met1": {"res": 0.00116077, "cap": 0.00022408750000000002},
# "met2": {"res": 0.00116077, "cap": 0.0001771029},
# "met3": {"res": 0.00020370999999999999, "cap": 0.0002794506},
# "met4": {
# "res": 0.00020370999999999999,
# "cap": 0.00020031309999999998,
# },
# "met5": {"res": 2.3153e-05, "cap": 0.00020031309999999998},
# },
# }
# new["VIAS_RC"] = {
# "*": {
# "mcon": {"res": 9.249146e-3},
# "via": {"res": 4.5e-3},
# "via2": {"res": 3.368786e-3},
# "via3": {"res": 0.376635e-3},
# "via4": {"res": 0.00580e-3},
# }
# }
elif new["PDK"].startswith("gf180mcu"):
new["STA_CORNERS"] = [
"nom_tt_025C_5v00",
Expand Down
1 change: 1 addition & 0 deletions openlane/flows/classic.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class Classic(SequentialFlow):
OpenROAD.CheckMacroInstances,
OpenROAD.STAPrePNR,
OpenROAD.Floorplan,
OpenROAD.DumpRCValues,
Odb.CheckMacroAntennaProperties,
Odb.SetPowerConnections,
Odb.ManualMacroPlacement,
Expand Down
90 changes: 63 additions & 27 deletions openlane/scripts/openroad/common/io.tcl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2022-2024 Efabless Corporation
# Copyright 2022-2025 Efabless Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -153,7 +153,7 @@ proc read_timing_info {args} {
return
}
set corner_name $::env(_CURRENT_CORNER_NAME)
define_corners $corner_name
log_cm define_corners $corner_name

puts "Reading timing models for corner $corner_name"

Expand Down Expand Up @@ -240,31 +240,35 @@ proc read_spefs {} {
}

proc read_pnr_libs {args} {
# _PNR_LIBS contains all libs and extra libs but with known-bad cells
# excluded, so OpenROAD can use cells by functionality and come up
# with a valid design.

# If there are ANY libs already read- just leave
if { [get_libs -quiet *] != {} } {
return
}

define_corners $::env(DEFAULT_CORNER)

foreach lib $::env(_PNR_LIBS) {
puts "Reading library file at '$lib'…"
read_liberty $lib
}
if { [info exists ::env(_MACRO_LIBS) ] } {
foreach macro_lib $::env(_MACRO_LIBS) {
puts "Reading macro library file at '$macro_lib'…"
read_liberty $macro_lib
set i "0"
set tc_key "_LIB_CORNER_$i"
set corner_names [list]
while { [info exists ::env($tc_key)] } {
set corner_name [lindex $::env($tc_key) 0]
set corner_libs [lreplace $::env($tc_key) 0 0]
set corner($corner_name) $corner_libs
incr i
set tc_key "_LIB_CORNER_$i"
lappend corner_names $corner_name
}

define_corners {*}[array name corner]

foreach corner_name [array name corner] {
puts "Reading timing models for corner $corner_name"

set corner_models $corner($corner_name)
foreach model $corner_models {
puts "Reading timing library for the '$corner_name' corner at '$model'…"
read_liberty -corner $corner_name $model
}
}
if { [info exists ::env(EXTRA_LIBS) ] } {
foreach extra_lib $::env(EXTRA_LIBS) {
puts "Reading extra library file at '$extra_lib'…"
read_liberty $extra_lib

if { [info exists ::env(EXTRA_LIBS) ] } {
puts "Reading explicitly-specified extra libs for $corner_name"
foreach extra_lib $::env(EXTRA_LIBS) {
puts "Reading extra timing library for the '$corner_name' corner at '$extra_lib'…"
read_liberty -corner $corner_name $extra_lib
}
}
}
}
Expand Down Expand Up @@ -302,6 +306,7 @@ proc read_current_odb {args} {
keys {}\
flags {}

read_pnr_libs
puts "Reading OpenROAD database at '$::env(CURRENT_ODB)'…"
if { [ catch {read_db $::env(CURRENT_ODB)} errmsg ]} {
puts stderr $errmsg
Expand All @@ -311,7 +316,6 @@ proc read_current_odb {args} {
set_global_vars

# Read supporting views (if applicable)
read_pnr_libs
read_current_sdc
set_dont_use_cells
}
Expand Down Expand Up @@ -561,6 +565,38 @@ proc find_unfixed_macros {} {
return $macros
}

proc get_layers {args} {
sta::parse_key_args "get_layers" args \
keys {-types -map}\
flags {-constrained}

if { ![info exists keys(-types)] } {
puts "\[ERROR\] Invalid usage of get_layers: -types is required."
}

set layers [$::tech getLayers]
set result [list]
set adding [expr ![info exists flags(-constrained)]]
foreach layer $layers {
set name [$layer getName]
if {"$::env(RT_MIN_LAYER)" == "$name"} {
set adding 1
}
if { [lsearch $keys(-types) [$layer getType]] != -1 && $adding} {
lappend result $layer
}

if {"$::env(RT_MAX_LAYER)" == "$name"} {
set adding [info exists flags(-constrained)]
}

}
if { [info exists keys(-map)] } {
set result [lmap layer $result "\$layer $keys(-map)"]
}
return $result
}

proc append_if_exists_argument {list_arg glob_variable_name option} {
upvar $list_arg local_array
if [info exists ::env($glob_variable_name) ] {
Expand Down
Loading

0 comments on commit 634c9b9

Please sign in to comment.