Files
OpenLane/scripts/odbpy/wire_lengths.py
Mohamed Gaber 46d8e5a042 Upgrade to nix-eda (#2135)
~ Avoid using `/dev/null` for writing DEF files (it tries to create a temp file and fail)
~ PDK now has a default value of sky130A even outside the Makefile
~ PDK_ROOT now set automatically if Volare is installed
~ Upgrade to a newer version of OpenLane 2, which in turns uses `nix-eda` 
~ Format nix packages using Alejandra
~ OpenROAD scripts now read liberty files before database files (they are linked together when the database is read)
~ Update Readme to remove Colab and add banner directing people to OpenLane 2
2024-07-07 23:08:26 +03:00

99 lines
2.9 KiB
Python

# Copyright ©2022 Efabless Corporation
#
# This file is part of the DFFRAM Memory Compiler.
# See https://github.com/Cloud-V/DFFRAM for further info.
#
# 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.
import os
import click
from decimal import Decimal
from reader import click_odb, OdbReader
def to_si(microns: Decimal) -> str:
units = ["μm", "mm", "m"]
unit = 0
value = microns
while value >= 1000 and unit < len(units):
value /= 1000
unit += 1
return f"{value}{units[unit]}"
@click.command()
@click.option(
"-h",
"--human-readable",
default=False,
is_flag=True,
help="Print with SI units instead of database units.",
)
@click.option(
"-t",
"--threshold",
default=Decimal("Infinity"),
type=Decimal,
help="Threshold above which to print the wire (Default: ∞)",
)
@click.option(
"-F",
"--fail",
default=False,
is_flag=True,
help="Exit with a non-zero code if any wire surpasses the threshold.",
)
@click.option(
"-R",
"--report-out",
default=None,
help="Output to print CSV file to. (Default: input + .wire_lengths.csv)",
)
@click_odb
def main(report_out, threshold, fail, human_readable, input_db, reader: OdbReader):
db = reader.db
if report_out is None:
report_out = f"{input_db}.wire_length.csv"
block = db.getChip().getBlock()
dbunits = block.getDefUnits()
nets = list(filter(lambda net: net.getWire() is not None, block.getNets()))
nets.sort(key=lambda net: net.getWire().getLength(), reverse=True)
above_threshold = []
with open(report_out, "w") as f:
print("net,length_um", file=f)
for net in nets:
length = net.getWire().getLength()
length_microns = Decimal(length) / Decimal(dbunits)
if length_microns >= threshold:
above_threshold.append((net, length_microns))
length_printable: str = str(length_microns)
if human_readable:
length_printable = str(to_si(length_microns))
print(f"{net.getName()},{length_printable}", file=f)
for net, length_microns in above_threshold:
print(
f"Net {net.getName()} is above the length threshold ({length_microns}/{threshold} μm)."
)
if len(above_threshold) == 0:
print(f"No wire length surpasses the threshold ({threshold} μm).")
elif fail:
exit(os.EX_DATAERR)
if __name__ == "__main__":
main()