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

Add more instance count-related metrics #563

Merged
merged 18 commits into from
Oct 8, 2024
Merged
Show file tree
Hide file tree
Changes from 11 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
4 changes: 2 additions & 2 deletions default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
libparse,
magic-vlsi,
netgen,
opensta-stable,
opensta,
openroad,
ruby,
surelog,
Expand Down Expand Up @@ -84,7 +84,7 @@
];

includedTools = [
opensta-stable
opensta
yosys-env
openroad-env
klayout
Expand Down
4 changes: 0 additions & 4 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,6 @@
});
colab-env = callPackage ./nix/colab-env.nix {};
opensta = callPackage ./nix/opensta.nix {};
opensta-stable = callPackage ./nix/opensta.nix {
rev = "cc9eb1f12a0d5030aebc1f1428e4300480e30b40";
sha256 = "sha256-/ShPD4xWq3lkN0Z3uONKm7i9eqbT+IU41UF7yIvDJy4=";
};
openroad-abc = callPackage ./nix/openroad-abc.nix {};
openroad = callPythonPackage ./nix/openroad.nix {
inherit (nix-eda) buildPythonEnvForInterpreter;
Expand Down
8 changes: 6 additions & 2 deletions nix/openroad.nix
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
opensta,
boost183,
eigen,
cudd,
tcl,
python3,
readline,
Expand All @@ -45,8 +46,8 @@
buildEnv,
makeBinaryWrapper,
buildPythonEnvForInterpreter,
rev ? "b16bda7e82721d10566ff7e2b68f1ff0be9f9e38",
sha256 ? "sha256-+JGyX81Km2XidptA3k1Y5ZPwv+4Ed39LCsPfIHWd6ac=",
rev ? "bbe940134bddf836894bfd1fe02153f4a38f8ae5",
sha256 ? "sha256-1K64FRoYFmD1seGTxLJoLakOiDCM3BgKljE8/bkjw9Q=",
}: let
self = clangStdenv.mkDerivation (finalAttrs: {
name = "openroad";
Expand All @@ -73,6 +74,7 @@
++ [
"-DUSE_SYSTEM_ABC:BOOL=ON"
"-DUSE_SYSTEM_OPENSTA:BOOL=ON"
"-DCMAKE_CXX_FLAGS=-I${eigen}/include/eigen3"
"-DOPENSTA_HOME=${opensta}"
"-DABC_LIBRARY=${openroad-abc}/lib/libabc.a"
];
Expand All @@ -85,12 +87,14 @@
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
sed -i 's@''${TCL_LIBRARY}@''${TCL_LIBRARY}\n${cudd}/lib/libcudd.a@' src/CMakeLists.txt
'';

buildInputs = [
openroad-abc
boost183
eigen
cudd
tcl
python3
readline
Expand Down
8 changes: 6 additions & 2 deletions nix/opensta.nix
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@
flex,
bison,
tcl,
tclreadline,
cudd,
zlib,
eigen,
rev ? "e01d3f163f483f233db00410b6515a767a6ca03b",
sha256 ? "sha256-0LbY5RcM+11oV3iPfAUd7hpyFPwCfCjnG0EE1LkXg5E=",
rev ? "20925bb00965c1199c45aca0318c2baeb4042c5a",
sha256 ? "sha256-gWAN+d6ioxQtxtgeq3vR+Zgq3nYRyn/u104L/xqumuY=",
}:
clangStdenv.mkDerivation (finalAttrs: {
name = "opensta";
Expand All @@ -44,6 +46,8 @@ clangStdenv.mkDerivation (finalAttrs: {
];

buildInputs = [
cudd
tclreadline
eigen
tcl
zlib
Expand Down
10 changes: 10 additions & 0 deletions openlane/common/metrics/library.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,15 @@
"design__instance__count",
higher_is_better=False,
)
Metric(
"design__instance__count__macros",
higher_is_better=False,
)
Metric(
"design__instance__count__stdcell",
aggregator=sum_aggregator,
higher_is_better=False,
)

# Power
Metric(
Expand Down Expand Up @@ -101,6 +110,7 @@
higher_is_better=False,
critical=True,
)

Metric(
"timing__setup_r2r_vio__count",
aggregator=sum_aggregator,
Expand Down
22 changes: 13 additions & 9 deletions openlane/common/metrics/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def parse_metric_modifiers(metric_name: str) -> Tuple[str, Mapping[str, str]]:
while ":" in mn_mut[-1]:
key, value = mn_mut.pop().split(":", maxsplit=1)
modifiers[key] = value
return "__".join(mn_mut), modifiers
return "__".join(mn_mut), {k: modifiers[k] for k in reversed(modifiers)}


def aggregate_metrics(
Expand All @@ -85,25 +85,29 @@ def aggregate_metrics(
aggregated: Dict[str, Any] = {}
for name, value in input.items():
metric_name, modifiers = parse_metric_modifiers(name)
if len(modifiers) != 1:
if len(modifiers) < 1:
# No modifiers = final aggregate, don't double-represent in sums
# >1 modifiers = n-level nesting, not supported atm
continue

modifier = list(modifiers.keys())[0]

modifier_names = list(modifiers.keys())
dont_aggregate: Iterable[str] = []
entry = aggregator_by_metric.get(metric_name)
if isinstance(entry, Metric):
dont_aggregate = entry.dont_aggregate or []
entry = entry.aggregator

if entry is None:
continue
if modifier in dont_aggregate:

if len(set(modifier_names).intersection(set(dont_aggregate))):
continue
start, aggregator = entry
current = aggregated.get(metric_name) or start
aggregated[metric_name] = aggregator([current, value])

metric_name_so_far = metric_name
for modifier in modifier_names:
start, aggregation_fn = entry
current = aggregated.get(metric_name_so_far) or start
aggregated[metric_name_so_far] = aggregation_fn([current, value])
metric_name_so_far += f"__{modifier}:{modifiers[modifier]}"

final_values = dict(input)
final_values.update(aggregated)
Expand Down
107 changes: 107 additions & 0 deletions openlane/scripts/odbpy/cell_frequency.py
donn marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Copyright 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.
# 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 re

from collections import Counter
from reader import click, click_odb, OdbReader

import rich
from rich.table import Table
from rich.console import Console


@click.command()
@click.option(
"--out-dir",
type=click.Path(file_okay=False, dir_okay=True),
required=True,
help="Directory to output tables to",
)
@click.option(
"--buffer-list",
type=click.Path(file_okay=True, dir_okay=False),
help="List of wildcard strings",
)
@click_odb
def main(
out_dir,
buffer_list,
reader: OdbReader,
):
db = reader.db
block = db.getChip().getBlock()

pattern = r"^(\S+)__(\S+)_\d+"
compiled_pattern = re.compile(pattern)

cell_frequency_table = Table(
"Cell",
"Count",
title="Cells by Master",
)
scl_table = Table(
"SCL",
"Count",
title="Cells by SCL",
)
cell_fn_table = Table(
"Cell Function",
"Count",
title="Cells by Function",
title_justify="center",
)
buffer_table = Table(
"Buffer",
"Count",
title="Buffers by Cell Master",
)

cells = [instance.getMaster().getName() for instance in block.getInsts()]
buffers = open(buffer_list).read().split()
buffer_frequency = Counter([cell for cell in cells if cell in buffers])
cell_frequency = Counter(cells)
scl_frequency = Counter()
cell_fn_frequency = Counter()

for cell in cell_frequency.keys():
if match := compiled_pattern.search(cell):
scl, cell_type = match[1], match[2]
cell_type_key = f"{scl}__{cell_type}"
scl_frequency[scl] += cell_frequency[cell]
cell_fn_frequency[cell_type_key] += cell_frequency[cell]

console = Console()
for table, frequency, name in [
(cell_frequency_table, cell_frequency, "cell"),
(cell_fn_table, cell_fn_frequency, "cell_function"),
(scl_table, scl_frequency, "by_scl"),
(buffer_table, buffer_frequency, "buffers"),
]:
freqs = sorted(frequency.items(), key=lambda x: x[1], reverse=True)
for key, value in freqs:
table.add_row(key, str(value))

table.min_width = console.width
console.print(table)

full_table_path = os.path.join(out_dir, f"{name}.rpt")
table.min_width = 160
with open(full_table_path, "w") as f:
file_console = rich.console.Console(file=f, width=160)
file_console.print(table)


if __name__ == "__main__":
main()
5 changes: 1 addition & 4 deletions openlane/scripts/odbpy/disconnected_pins.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
# 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
# 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,
Expand Down
5 changes: 1 addition & 4 deletions openlane/scripts/odbpy/wire_lengths.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
# 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
# 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,
Expand Down
10 changes: 10 additions & 0 deletions openlane/scripts/openroad/buffer_list.tcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
foreach lib $::env(_PNR_LIBS) {
read_liberty $lib
}

set cells [get_lib_cells *]
foreach cell $cells {
if { [$cell is_buffer] } {
puts [get_property $cell name]
}
}
35 changes: 19 additions & 16 deletions openlane/scripts/openroad/common/io.tcl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2022 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 @@ -13,6 +13,7 @@
# limitations under the License.
source $::env(_TCL_ENV_IN)
source $::env(SCRIPTS_DIR)/openroad/common/set_global_connections.tcl
source $::env(SCRIPTS_DIR)/openroad/common/report_cell_count.tcl

proc string_in_file {file_path substring} {
set f [open $file_path r]
Expand All @@ -29,6 +30,17 @@ proc env_var_used {file var} {
return [string_in_file $file "\$::env($var)"]
}

proc set_global_vars {} {
if { [namespace exists ::ord] } {
set ::db [::ord::get_db]
set ::chip [$::db getChip]
set ::tech [$::db getTech]
set ::block [$::chip getBlock]
set ::dbu [$::tech getDbUnitsPerMicron]
set ::libs [$::db getLibs]
}
}

proc read_current_sdc {} {
if { ![info exists ::env(_SDC_IN)]} {
puts "\[INFO\] _SDC_IN not found. Not reading an SDC file."
Expand Down Expand Up @@ -129,15 +141,7 @@ proc read_current_netlist {args} {

puts "Linking design '$::env(DESIGN_NAME)' from netlist…"
link_design $::env(DESIGN_NAME)
if { [namespace exists ::ord] } {
set ::db [::ord::get_db]
set ::chip [$::db getChip]
set ::tech [$::db getTech]
set ::block [$::chip getBlock]
set ::dbu [$::tech getDbUnitsPerMicron]
set ::libs [$::db getLibs]
}

set_global_vars
read_current_sdc
}

Expand Down Expand Up @@ -305,12 +309,7 @@ proc read_current_odb {args} {
exit 1
}

set ::db [::ord::get_db]
set ::chip [$::db getChip]
set ::tech [$::db getTech]
set ::block [$::chip getBlock]
set ::dbu [$::tech getDbUnitsPerMicron]
set ::libs [$::db getLibs]
set_global_vars

# Read supporting views (if applicable)
read_pnr_libs
Expand All @@ -331,6 +330,10 @@ proc write_views {args} {
puts "Setting global connections for newly added cells…"
set_global_connections

puts "Updating metrics…"
report_design_area_metrics
report_cell_count

if { [info exists ::env(SAVE_ODB)] } {
puts "Writing OpenROAD database to '$::env(SAVE_ODB)'…"
write_db $::env(SAVE_ODB)
Expand Down
Loading
Loading