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

feat!: Read multi corner libs during PNR steps #591

Draft
wants to merge 9 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all 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
11 changes: 6 additions & 5 deletions openlane/common/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,29 @@
# 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 fnmatch
import glob
import os
import pathlib
import re
import glob
import typing
import fnmatch
import pathlib
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
79 changes: 78 additions & 1 deletion openlane/config/pdk_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,78 @@ def process_sta(key: str):
"max_ss_100C_1v60",
"max_ff_n40C_1v95",
]
new["PNR_CORNERS"] = [
"nom_tt_025C_1v80",
"nom_ss_100C_1v60",
"nom_ff_n40C_1v95",
]
## correlateRC.py gcd,ibex,aes,jpeg,chameleon,riscv32i,chameleon_hier
## cap units pf/um
# set_layer_rc -layer li1 -capacitance 1.499e-04 -resistance 7.176e-02
# set_layer_rc -layer met1 -capacitance 1.72375E-04 -resistance 8.929e-04
# set_layer_rc -layer met2 -capacitance 1.36233E-04 -resistance 8.929e-04
# set_layer_rc -layer met3 -capacitance 2.14962E-04 -resistance 1.567e-04
# set_layer_rc -layer met4 -capacitance 1.48128E-04 -resistance 1.567e-04
# set_layer_rc -layer met5 -capacitance 1.54087E-04 -resistance 1.781e-05
## end correlate
#
# set_layer_rc -via mcon -resistance 9.249146E-3
# set_layer_rc -via via -resistance 4.5E-3
# set_layer_rc -via via2 -resistance 3.368786E-3
# set_layer_rc -via via3 -resistance 0.376635E-3
# set_layer_rc -via via4 -resistance 0.00580E-3
#
# set_wire_rc -signal -layer met1
# set_wire_rc -clock -layer met3
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},
},
}
# set_layer_rc -via mcon -resistance 9.249146E-3
# set_layer_rc -via via -resistance 4.5E-3
# set_layer_rc -via via2 -resistance 3.368786E-3
# set_layer_rc -via via3 -resistance 0.376635E-3
# set_layer_rc -via via4 -resistance 0.00580E-3
new["VIAS_RC"] = {
"*": {
"mcon": {"res": 9.249146},
"via": {"res": 4.5},
"via2": {"res": 3.368786},
"via3": {"res": 0.376635},
"via4": {"res": 0.00580},
}
}
elif new["PDK"].startswith("gf180mcu"):
new["STA_CORNERS"] = [
"nom_tt_025C_5v00",
Expand All @@ -226,6 +298,11 @@ def process_sta(key: str):
"max_ss_125C_4v50",
"max_ff_n40C_5v50",
]
new["PNR_CORNERS"] = [
"nom_tt_025C_5v00",
"nom_ss_125C_4v50",
"nom_ff_n40C_5v50",
]

new["DEFAULT_CORNER"] = f"nom_{default_pvt}"
new["LIB"] = lib_sta
Expand Down
49 changes: 29 additions & 20 deletions openlane/scripts/openroad/common/io.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -240,31 +240,40 @@ 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.
set i "0"
set tc_key "_LIB_CORNER_$i"
while { [info exists ::env($tc_key)] } {
set corner_name [lindex $::env($tc_key) 0]
set corner_libs [lreplace $::env($tc_key) 0 0]

# If there are ANY libs already read- just leave
if { [get_libs -quiet *] != {} } {
set corner($corner_name) $corner_libs

incr i
set tc_key "_LIB_CORNER_$i"
}

if { $i == "0" } {
puts stderr "\[WARNING\] No resizer-specific timing information read."
return
}

define_corners $::env(DEFAULT_CORNER)
define_corners {*}[array name 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
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 +311,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 +321,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
41 changes: 1 addition & 40 deletions openlane/scripts/openroad/common/resizer.tcl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2022-2023 Efabless Corporation
# Copyright 2022-2024 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 @@ -11,45 +11,6 @@
# 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.
proc load_rsz_corners {args} {
set i "0"
set tc_key "RSZ_CORNER_$i"
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 "RSZ_CORNER_$i"
}

if { $i == "0" } {
puts stderr "\[WARNING\] No resizer-specific timing information read."
return
}

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) ] } {
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
}
}
}
}

proc set_dont_touch_objects {args} {
set rx $::env(RSZ_DONT_TOUCH_RX)
if { $rx != {^$} } {
Expand Down
114 changes: 89 additions & 25 deletions openlane/scripts/openroad/common/set_rc.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,85 @@

# Resistance/Capacitance Overrides
# Via resistance
puts "\[INFO\] Setting RC values…"
if { [info exist ::env(VIAS_RC)] } {
set vias_rc [split $::env(VIAS_RC) ","]
foreach via_rc $vias_rc {
set layer_name [lindex $via_rc 0]
set resistance [lindex $via_rc 1]
set_layer_rc -via $layer_name -resistance $resistance

set i "0"
set tc_key "_LAYER_RC_$i"
if { ![info exists ::env($tc_key)] } {
puts "\[INFO\] Using default RC values from the technology for metal layers"
set res_unit [sta::unit_scale resistance]
set cap_unit [sta::unit_scale capacitance]

foreach layer [$::tech getLayers] {
if { [$layer getType] == "ROUTING" } {
set layer_name [$layer getName]

lassign [rsz::dblayer_wire_rc $layer] layer_wire_res_ohm_m layer_wire_cap_farad_m
set layer_wire_res_unit_microns [expr $layer_wire_res_ohm_m * 1e-6 / $res_unit]
set layer_wire_cap_unit_microns [expr $layer_wire_cap_farad_m * 1e-6 / $cap_unit]

foreach corner [sta::corners] {
set_layer_rc \
-layer $layer_name\
-capacitance $layer_wire_cap_unit_microns\
-corner [$corner name]\
-resistance $layer_wire_res_unit_microns
}
}
}
}

# Metal resistance and capacitence
if { [info exist ::env(LAYERS_RC)] } {
set layers_rc [split $::env(LAYERS_RC) ","]
foreach layer_rc $layers_rc {
set layer_name [lindex $layer_rc 0]
set capacitance [lindex $layer_rc 1]
set resistance [lindex $layer_rc 2]
set_layer_rc -layer $layer_name -capacitance $capacitance -resistance $resistance
while { [info exists ::env($tc_key)] } {
# [$corner] + [layer] + [str(round(res, 8))] + [str(round(cap, 8))]
set corner_name [lindex $::env($tc_key) 0]
set layer_name [lindex $::env($tc_key) 1]
set res_value [lindex $::env($tc_key) 2]
set cap_value [lindex $::env($tc_key) 3]

puts "\[INFO\] Setting $layer_name $corner_name to res $res_value and cap $cap_value"
set_layer_rc \
-layer $layer_name\
-capacitance $cap_value\
-corner $corner_name\
-resistance $res_value

incr i
set tc_key "_LAYER_RC_$i"
}


set i "0"
set tc_key "_VIA_RC_$i"

if { ![info exists ::env($tc_key)] } {
puts "\[INFO\] Using default RC values from the technology for vias"

foreach layer [$::tech getLayers] {
if { [$layer getType] == "CUT" } {
set layer_name [$layer getName]
set res [$layer getResistance]
foreach corner [sta::corners] {
set_layer_rc \
-corner [$corner name]\
-resistance $res\
-via $layer_name
}
}
}
}
while { [info exists ::env($tc_key)] } {
set corner_name [lindex $::env($tc_key) 0]
set via_name [lindex $::env($tc_key) 1]
set res_value [lindex $::env($tc_key) 2]

puts "\[INFO\] Setting $via_name $corner_name to res $res_value"
set_layer_rc \
-via $via_name\
-resistance $res_value\
-corner $corner_name

incr i
set tc_key "_VIA_RC_$i"
}

set layer_names [list]
set layers [$::tech getLayers]
Expand Down Expand Up @@ -62,14 +121,19 @@ if { [info exist ::env(SIGNAL_WIRE_RC_LAYERS)] } {
if { [info exist ::env(CLOCK_WIRE_RC_LAYERS)] } {
set clock_wire_rc_layers $::env(CLOCK_WIRE_RC_LAYERS)
}
if { [llength $signal_wire_rc_layers] > 1 } {
set_wire_rc -signal -layers "$signal_wire_rc_layers"
} else {
set_wire_rc -signal -layer "$signal_wire_rc_layers"
}

if { [llength $clock_wire_rc_layers] > 1 } {
set_wire_rc -clock -layers "$clock_wire_rc_layers"
} else {
set_wire_rc -clock -layer "$clock_wire_rc_layers"
foreach corner [sta::corners] {
if { [llength $signal_wire_rc_layers] > 1 } {
puts "set_wire_rc -signal -layers signal_wire_rc_layers-corner [$corner name]"
set_wire_rc -signal -layers "$signal_wire_rc_layers" -corner [$corner name]
} else {
puts "set_wire_rc -signal -layer $signal_wire_rc_layers -corner [$corner name]"
set_wire_rc -signal -layer "$signal_wire_rc_layers" -corner [$corner name]
}
if { [llength $clock_wire_rc_layers] > 1 } {
puts "set_wire_rc -clock -layers $clock_wire_rc_layers -corner [$corner name]"
set_wire_rc -clock -layers "$clock_wire_rc_layers" -corner [$corner name]
} else {
puts "set_wire_rc -clock -layer $clock_wire_rc_layers -corner [$corner name]"
set_wire_rc -clock -layer "$clock_wire_rc_layers" -corner [$corner name]
}
}
Loading
Loading