Skip to content
Merged
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
112 changes: 1 addition & 111 deletions src/Metrics.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -187,117 +187,7 @@ proc report_units_metric { args } {

define_cmd_args "report_design_area_metrics" {}
proc report_design_area_metrics { args } {
set db [::ord::get_db]
set dbu_per_uu [expr double([[$db getTech] getDbUnitsPerMicron])]
set block [[$db getChip] getBlock]
set die_bbox [$block getDieArea]
set die_area [expr [$die_bbox dx] * [$die_bbox dy]]
set core_bbox [$block getCoreArea]
set core_area [expr [$core_bbox dx] * [$core_bbox dy]]

set num_ios [llength [$block getBTerms]]

set num_insts 0
set num_stdcells 0
set num_macros 0
set num_padcells 0
set num_cover 0

set total_area 0.0
set stdcell_area 0.0
set macro_area 0.0
set padcell_area 0.0
set cover_area 0.0

foreach inst [$block getInsts] {
set inst_master [$inst getMaster]
if { [$inst_master isFiller] } {
continue
}
set wid [$inst_master getWidth]
set ht [$inst_master getHeight]
set inst_area [expr $wid * $ht]
set total_area [expr $total_area + $inst_area]
set num_insts [expr $num_insts + 1]

if { [$inst_master isBlock] } {
set num_macros [expr $num_macros + 1]
set macro_area [expr $macro_area + $inst_area]
} elseif { [$inst_master isCover] } {
set num_cover [expr $num_cover + 1]
set cover_area [expr $cover_area + $inst_area]
} elseif { [$inst_master isPad] } {
set num_padcells [expr $num_padcells + 1]
set padcell_area [expr $padcell_area + $inst_area]
} else {
set num_stdcells [expr $num_stdcells + 1]
set stdcell_area [expr $stdcell_area + $inst_area]
}
}

set die_area [expr $die_area / [expr $dbu_per_uu * $dbu_per_uu]]
set core_area [expr $core_area / [expr $dbu_per_uu * $dbu_per_uu]]
set total_area [expr $total_area / [expr $dbu_per_uu * $dbu_per_uu]]
set stdcell_area [expr $stdcell_area / [expr $dbu_per_uu * $dbu_per_uu]]
set macro_area [expr $macro_area / [expr $dbu_per_uu * $dbu_per_uu]]
set padcell_area [expr $padcell_area / [expr $dbu_per_uu * $dbu_per_uu]]
set cover_area [expr $cover_area / [expr $dbu_per_uu * $dbu_per_uu]]

set total_active_area [expr $stdcell_area + $macro_area]

if { $core_area > 0 } {
set core_util [expr $total_active_area / $core_area]
if { $core_area > $macro_area } {
set stdcell_util [expr $stdcell_area / [expr $core_area - $macro_area]]
} else {
set stdcell_util 0.0
}
} else {
set core_util -1.0
set stdcell_util -1.0
}

set std_rows 0
set std_sites 0
set rows [dict create]
set sites [dict create]
foreach row [$block getRows] {
set site [$row getSite]

if { [$site getClass] == "NONE" || [$site getClass] == "CORE" } {
incr std_rows
set std_sites [expr { $std_sites + [$row getSiteCount] }]
}

dict incr rows [$site getName] 1
dict incr sites [$site getName] [$row getSiteCount]
}

utl::metric_int "design__io" $num_ios
utl::metric_float "design__die__area" $die_area
utl::metric_float "design__core__area" $core_area
utl::metric_int "design__instance__count" $num_insts
utl::metric_float "design__instance__area" $total_active_area
utl::metric_int "design__instance__count__stdcell" $num_stdcells
utl::metric_float "design__instance__area__stdcell" $stdcell_area
utl::metric_int "design__instance__count__macros" $num_macros
utl::metric_float "design__instance__area__macros" $macro_area
utl::metric_int "design__instance__count__padcells" $num_padcells
utl::metric_float "design__instance__area__padcells" $padcell_area
utl::metric_int "design__instance__count__cover" $num_cover
utl::metric_float "design__instance__area__cover" $cover_area
utl::metric_float "design__instance__utilization" $core_util
utl::metric_float "design__instance__utilization__stdcell" $stdcell_util

utl::metric_int "design__rows" $std_rows
dict for {site_name count} $rows {
utl::metric_int "design__rows:$site_name" $count
}

utl::metric_int "design__sites" $std_sites
dict for {site_name count} $sites {
utl::metric_int "design__sites:$site_name" $count
}
ord::report_design_area_metrics_cmd
}

# namespace
Expand Down
11 changes: 11 additions & 0 deletions src/OpenRoad.i
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,17 @@ void report_hpwl()
w.reportHpwl(getLogger());
}

void report_design_area_metrics_cmd()
{
dbDatabase* db = OpenRoad::openRoad()->getDb();
odb::dbChip* chip = db->getChip();
if (chip == nullptr) {
return;
}
dbBlock* block = chip->getBlock();
odb::blockMetrics(block, getLogger());
}

} // namespace ord

%} // inline
2 changes: 2 additions & 0 deletions src/odb/include/odb/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ void set_bterm_top_layer_grid(dbBlock* block,

bool dbHasCoreRows(dbDatabase* db);

void blockMetrics(dbBlock* block, utl::Logger* logger);

class WireLengthEvaluator
{
public:
Expand Down
115 changes: 115 additions & 0 deletions src/odb/src/zutil/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,121 @@ bool hasOneSiteMaster(dbDatabase* db)
return false;
}

void blockMetrics(dbBlock* block, utl::Logger* logger)
{
if (block == nullptr) {
return;
}

const double dbu_per_uu = block->getDbUnitsPerMicron();

const odb::Rect die_bbox = block->getDieArea();
const auto die_area = die_bbox.area();

const odb::Rect core_bbox = block->getCoreArea();
const auto core_area = core_bbox.area();

const int num_ios = block->getBTerms().size();

const int num_insts = block->getInsts().size();
int num_stdcells = 0;
int num_macros = 0;
int num_padcells = 0;
int num_cover = 0;

double stdcell_area = 0.0;
double macro_area = 0.0;
double padcell_area = 0.0;
double cover_area = 0.0;

for (odb::dbInst* inst : block->getInsts()) {
odb::dbMaster* inst_master = inst->getMaster();
if (inst_master->isFiller()) {
continue;
}

const int wid = inst_master->getWidth();
const int ht = inst_master->getHeight();
const double inst_area = static_cast<double>(wid) * ht;

if (inst_master->isBlock()) {
num_macros++;
macro_area += inst_area;
} else if (inst_master->isCover()) {
num_cover++;
cover_area += inst_area;
} else if (inst_master->isPad()) {
num_padcells++;
padcell_area += inst_area;
} else {
num_stdcells++;
stdcell_area += inst_area;
}
}

const double die_area_um = die_area / (dbu_per_uu * dbu_per_uu);
const double core_area_um = core_area / (dbu_per_uu * dbu_per_uu);
stdcell_area /= (dbu_per_uu * dbu_per_uu);
macro_area /= (dbu_per_uu * dbu_per_uu);
padcell_area /= (dbu_per_uu * dbu_per_uu);
cover_area /= (dbu_per_uu * dbu_per_uu);

const double total_active_area = stdcell_area + macro_area;

logger->metric("design__io", num_ios);
logger->metric("design__nets", block->getNets().size());
logger->metric("design__die__area", die_area_um);
logger->metric("design__core__area", core_area_um);
logger->metric("design__instance__count", num_insts);
logger->metric("design__instance__area", total_active_area);
logger->metric("design__instance__count__stdcell", num_stdcells);
logger->metric("design__instance__area__stdcell", stdcell_area);
logger->metric("design__instance__count__macros", num_macros);
logger->metric("design__instance__area__macros", macro_area);
logger->metric("design__instance__count__padcells", num_padcells);
logger->metric("design__instance__area__padcells", padcell_area);
logger->metric("design__instance__count__cover", num_cover);
logger->metric("design__instance__area__cover", cover_area);

if (core_area_um > 0) {
logger->metric("design__instance__utilization",
total_active_area / core_area_um);
double stdcell_util = 0.0;
if (core_area_um > macro_area) {
stdcell_util = stdcell_area / (core_area_um - macro_area);
}
logger->metric("design__instance__utilization__stdcell", stdcell_util);
}

int std_rows = 0;
int64_t std_sites = 0;
std::map<std::string, int> rows;
std::map<std::string, int64_t> sites;

for (odb::dbRow* row : block->getRows()) {
odb::dbSite* site = row->getSite();

if (site->getClass() == odb::dbSiteClass::NONE
|| site->getClass() == odb::dbSiteClass::CORE) {
std_rows++;
std_sites += row->getSiteCount();
}

rows[site->getName()]++;
sites[site->getName()] += row->getSiteCount();
}

logger->metric("design__rows", std_rows);
for (const auto& [site_name, count] : rows) {
logger->metric("design__rows:" + site_name, count);
}

logger->metric("design__sites", std_sites);
for (const auto& [site_name, count] : sites) {
logger->metric("design__sites:" + site_name, count);
}
}

int64_t WireLengthEvaluator::hpwl() const
{
int64_t hpwl_sum = 0;
Expand Down
Loading