Skip to content

Commit 913ada2

Browse files
authored
Merge pull request #10051 from gadfort/designmetrics
ord: move report design metrics to c++
2 parents 2a9191b + 209671a commit 913ada2

4 files changed

Lines changed: 129 additions & 111 deletions

File tree

src/Metrics.tcl

Lines changed: 1 addition & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -187,117 +187,7 @@ proc report_units_metric { args } {
187187

188188
define_cmd_args "report_design_area_metrics" {}
189189
proc report_design_area_metrics { args } {
190-
set db [::ord::get_db]
191-
set dbu_per_uu [expr double([[$db getTech] getDbUnitsPerMicron])]
192-
set block [[$db getChip] getBlock]
193-
set die_bbox [$block getDieArea]
194-
set die_area [expr [$die_bbox dx] * [$die_bbox dy]]
195-
set core_bbox [$block getCoreArea]
196-
set core_area [expr [$core_bbox dx] * [$core_bbox dy]]
197-
198-
set num_ios [llength [$block getBTerms]]
199-
200-
set num_insts 0
201-
set num_stdcells 0
202-
set num_macros 0
203-
set num_padcells 0
204-
set num_cover 0
205-
206-
set total_area 0.0
207-
set stdcell_area 0.0
208-
set macro_area 0.0
209-
set padcell_area 0.0
210-
set cover_area 0.0
211-
212-
foreach inst [$block getInsts] {
213-
set inst_master [$inst getMaster]
214-
if { [$inst_master isFiller] } {
215-
continue
216-
}
217-
set wid [$inst_master getWidth]
218-
set ht [$inst_master getHeight]
219-
set inst_area [expr $wid * $ht]
220-
set total_area [expr $total_area + $inst_area]
221-
set num_insts [expr $num_insts + 1]
222-
223-
if { [$inst_master isBlock] } {
224-
set num_macros [expr $num_macros + 1]
225-
set macro_area [expr $macro_area + $inst_area]
226-
} elseif { [$inst_master isCover] } {
227-
set num_cover [expr $num_cover + 1]
228-
set cover_area [expr $cover_area + $inst_area]
229-
} elseif { [$inst_master isPad] } {
230-
set num_padcells [expr $num_padcells + 1]
231-
set padcell_area [expr $padcell_area + $inst_area]
232-
} else {
233-
set num_stdcells [expr $num_stdcells + 1]
234-
set stdcell_area [expr $stdcell_area + $inst_area]
235-
}
236-
}
237-
238-
set die_area [expr $die_area / [expr $dbu_per_uu * $dbu_per_uu]]
239-
set core_area [expr $core_area / [expr $dbu_per_uu * $dbu_per_uu]]
240-
set total_area [expr $total_area / [expr $dbu_per_uu * $dbu_per_uu]]
241-
set stdcell_area [expr $stdcell_area / [expr $dbu_per_uu * $dbu_per_uu]]
242-
set macro_area [expr $macro_area / [expr $dbu_per_uu * $dbu_per_uu]]
243-
set padcell_area [expr $padcell_area / [expr $dbu_per_uu * $dbu_per_uu]]
244-
set cover_area [expr $cover_area / [expr $dbu_per_uu * $dbu_per_uu]]
245-
246-
set total_active_area [expr $stdcell_area + $macro_area]
247-
248-
if { $core_area > 0 } {
249-
set core_util [expr $total_active_area / $core_area]
250-
if { $core_area > $macro_area } {
251-
set stdcell_util [expr $stdcell_area / [expr $core_area - $macro_area]]
252-
} else {
253-
set stdcell_util 0.0
254-
}
255-
} else {
256-
set core_util -1.0
257-
set stdcell_util -1.0
258-
}
259-
260-
set std_rows 0
261-
set std_sites 0
262-
set rows [dict create]
263-
set sites [dict create]
264-
foreach row [$block getRows] {
265-
set site [$row getSite]
266-
267-
if { [$site getClass] == "NONE" || [$site getClass] == "CORE" } {
268-
incr std_rows
269-
set std_sites [expr { $std_sites + [$row getSiteCount] }]
270-
}
271-
272-
dict incr rows [$site getName] 1
273-
dict incr sites [$site getName] [$row getSiteCount]
274-
}
275-
276-
utl::metric_int "design__io" $num_ios
277-
utl::metric_float "design__die__area" $die_area
278-
utl::metric_float "design__core__area" $core_area
279-
utl::metric_int "design__instance__count" $num_insts
280-
utl::metric_float "design__instance__area" $total_active_area
281-
utl::metric_int "design__instance__count__stdcell" $num_stdcells
282-
utl::metric_float "design__instance__area__stdcell" $stdcell_area
283-
utl::metric_int "design__instance__count__macros" $num_macros
284-
utl::metric_float "design__instance__area__macros" $macro_area
285-
utl::metric_int "design__instance__count__padcells" $num_padcells
286-
utl::metric_float "design__instance__area__padcells" $padcell_area
287-
utl::metric_int "design__instance__count__cover" $num_cover
288-
utl::metric_float "design__instance__area__cover" $cover_area
289-
utl::metric_float "design__instance__utilization" $core_util
290-
utl::metric_float "design__instance__utilization__stdcell" $stdcell_util
291-
292-
utl::metric_int "design__rows" $std_rows
293-
dict for {site_name count} $rows {
294-
utl::metric_int "design__rows:$site_name" $count
295-
}
296-
297-
utl::metric_int "design__sites" $std_sites
298-
dict for {site_name count} $sites {
299-
utl::metric_int "design__sites:$site_name" $count
300-
}
190+
ord::report_design_area_metrics_cmd
301191
}
302192

303193
# namespace

src/OpenRoad.i

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,17 @@ void report_hpwl()
648648
w.reportHpwl(getLogger());
649649
}
650650

651+
void report_design_area_metrics_cmd()
652+
{
653+
dbDatabase* db = OpenRoad::openRoad()->getDb();
654+
odb::dbChip* chip = db->getChip();
655+
if (chip == nullptr) {
656+
return;
657+
}
658+
dbBlock* block = chip->getBlock();
659+
odb::blockMetrics(block, getLogger());
651660
}
652661

662+
} // namespace ord
663+
653664
%} // inline

src/odb/include/odb/util.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ void set_bterm_top_layer_grid(dbBlock* block,
4949

5050
bool dbHasCoreRows(dbDatabase* db);
5151

52+
void blockMetrics(dbBlock* block, utl::Logger* logger);
53+
5254
class WireLengthEvaluator
5355
{
5456
public:

src/odb/src/zutil/util.cpp

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,121 @@ bool hasOneSiteMaster(dbDatabase* db)
376376
return false;
377377
}
378378

379+
void blockMetrics(dbBlock* block, utl::Logger* logger)
380+
{
381+
if (block == nullptr) {
382+
return;
383+
}
384+
385+
const double dbu_per_uu = block->getDbUnitsPerMicron();
386+
387+
const odb::Rect die_bbox = block->getDieArea();
388+
const auto die_area = die_bbox.area();
389+
390+
const odb::Rect core_bbox = block->getCoreArea();
391+
const auto core_area = core_bbox.area();
392+
393+
const int num_ios = block->getBTerms().size();
394+
395+
const int num_insts = block->getInsts().size();
396+
int num_stdcells = 0;
397+
int num_macros = 0;
398+
int num_padcells = 0;
399+
int num_cover = 0;
400+
401+
double stdcell_area = 0.0;
402+
double macro_area = 0.0;
403+
double padcell_area = 0.0;
404+
double cover_area = 0.0;
405+
406+
for (odb::dbInst* inst : block->getInsts()) {
407+
odb::dbMaster* inst_master = inst->getMaster();
408+
if (inst_master->isFiller()) {
409+
continue;
410+
}
411+
412+
const int wid = inst_master->getWidth();
413+
const int ht = inst_master->getHeight();
414+
const double inst_area = static_cast<double>(wid) * ht;
415+
416+
if (inst_master->isBlock()) {
417+
num_macros++;
418+
macro_area += inst_area;
419+
} else if (inst_master->isCover()) {
420+
num_cover++;
421+
cover_area += inst_area;
422+
} else if (inst_master->isPad()) {
423+
num_padcells++;
424+
padcell_area += inst_area;
425+
} else {
426+
num_stdcells++;
427+
stdcell_area += inst_area;
428+
}
429+
}
430+
431+
const double die_area_um = die_area / (dbu_per_uu * dbu_per_uu);
432+
const double core_area_um = core_area / (dbu_per_uu * dbu_per_uu);
433+
stdcell_area /= (dbu_per_uu * dbu_per_uu);
434+
macro_area /= (dbu_per_uu * dbu_per_uu);
435+
padcell_area /= (dbu_per_uu * dbu_per_uu);
436+
cover_area /= (dbu_per_uu * dbu_per_uu);
437+
438+
const double total_active_area = stdcell_area + macro_area;
439+
440+
logger->metric("design__io", num_ios);
441+
logger->metric("design__nets", block->getNets().size());
442+
logger->metric("design__die__area", die_area_um);
443+
logger->metric("design__core__area", core_area_um);
444+
logger->metric("design__instance__count", num_insts);
445+
logger->metric("design__instance__area", total_active_area);
446+
logger->metric("design__instance__count__stdcell", num_stdcells);
447+
logger->metric("design__instance__area__stdcell", stdcell_area);
448+
logger->metric("design__instance__count__macros", num_macros);
449+
logger->metric("design__instance__area__macros", macro_area);
450+
logger->metric("design__instance__count__padcells", num_padcells);
451+
logger->metric("design__instance__area__padcells", padcell_area);
452+
logger->metric("design__instance__count__cover", num_cover);
453+
logger->metric("design__instance__area__cover", cover_area);
454+
455+
if (core_area_um > 0) {
456+
logger->metric("design__instance__utilization",
457+
total_active_area / core_area_um);
458+
double stdcell_util = 0.0;
459+
if (core_area_um > macro_area) {
460+
stdcell_util = stdcell_area / (core_area_um - macro_area);
461+
}
462+
logger->metric("design__instance__utilization__stdcell", stdcell_util);
463+
}
464+
465+
int std_rows = 0;
466+
int64_t std_sites = 0;
467+
std::map<std::string, int> rows;
468+
std::map<std::string, int64_t> sites;
469+
470+
for (odb::dbRow* row : block->getRows()) {
471+
odb::dbSite* site = row->getSite();
472+
473+
if (site->getClass() == odb::dbSiteClass::NONE
474+
|| site->getClass() == odb::dbSiteClass::CORE) {
475+
std_rows++;
476+
std_sites += row->getSiteCount();
477+
}
478+
479+
rows[site->getName()]++;
480+
sites[site->getName()] += row->getSiteCount();
481+
}
482+
483+
logger->metric("design__rows", std_rows);
484+
for (const auto& [site_name, count] : rows) {
485+
logger->metric("design__rows:" + site_name, count);
486+
}
487+
488+
logger->metric("design__sites", std_sites);
489+
for (const auto& [site_name, count] : sites) {
490+
logger->metric("design__sites:" + site_name, count);
491+
}
492+
}
493+
379494
int64_t WireLengthEvaluator::hpwl() const
380495
{
381496
int64_t hpwl_sum = 0;

0 commit comments

Comments
 (0)