Skip to content
Open
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
3 changes: 2 additions & 1 deletion src/dbSta/include/db_sta/IpChecker.hh
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ namespace sta {
// LEF-CHK-010b: Pin minimum area
// LEF/LIB-CHK-011: Pin direction matches Liberty
// LEF/LIB-CHK-012: LEF macros and signal pins exist in Liberty
// LEF/LIB-CHK-013: LEF and Liberty cell areas match

class IpChecker
{
Expand Down Expand Up @@ -90,7 +91,7 @@ class IpChecker
// LEF-CHK-010b: Pin minimum area
void checkPinMinArea(odb::dbMaster* master);

// LEF/LIB-CHK-011-012: Check Liberty pin presence and direction
// LEF/LIB-CHK-011-013: Check Liberty pin presence, direction, and area
void checkLibertyPins(odb::dbMaster* master);

// Helper: Check if a pin shape has at least one accessible edge
Expand Down
22 changes: 22 additions & 0 deletions src/dbSta/src/IpChecker.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstddef>
#include <cstdint>
#include <cstdlib>
Expand Down Expand Up @@ -792,6 +793,27 @@ void IpChecker::checkLibertyPins(odb::dbMaster* master)
return;
}

odb::dbTech* tech = db_->getTech();
if (tech != nullptr) {
const double dbu_per_micron = tech->getDbUnitsPerMicron();
const double lef_area
= static_cast<double>(master->getWidth()) * master->getHeight()
/ (dbu_per_micron * dbu_per_micron);
const double liberty_area = liberty_cell->area();
const double area_tolerance = std::max(1e-6, lef_area * 1e-3);

if (std::abs(lef_area - liberty_area) > area_tolerance) {
logger_->warn(utl::CHK,
122,
"Master {} area mismatch between LEF ({:.6f}) and "
"Liberty ({:.6f})",
master_name,
lef_area,
liberty_area);
warning_count_++;
}
Comment on lines +798 to +814

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

If dbu_per_micron is 0 (which can happen if the database units are not properly initialized or defined in the LEF), dividing by it will result in a division-by-zero error, producing inf or nan values. Adding a guard to ensure dbu_per_micron > 0 before performing the division is a safer and more robust approach.

    const double dbu_per_micron = tech->getDbUnitsPerMicron();
    if (dbu_per_micron > 0) {
      const double lef_area
          = static_cast<double>(master->getWidth()) * master->getHeight()
            / (dbu_per_micron * dbu_per_micron);
      const double liberty_area = liberty_cell->area();
      const double area_tolerance = std::max(1e-6, lef_area * 1e-3);

      if (std::abs(lef_area - liberty_area) > area_tolerance) {
        logger_->warn(utl::CHK,
                      122,
                      "Master {} area mismatch between LEF ({:.6f}) and "
                      "Liberty ({:.6f})",
                      master_name,
                      lef_area,
                      liberty_area);
        warning_count_++;
      }
    }

}

for (odb::dbMTerm* mterm : master->getMTerms()) {
if (mterm->getSigType().isSupply()) {
continue;
Expand Down
23 changes: 23 additions & 0 deletions src/dbSta/test/check_ip_liberty_pins.lef
Original file line number Diff line number Diff line change
Expand Up @@ -135,4 +135,27 @@ MACRO lef_lib_direction_mismatch
END VDD
END lef_lib_direction_mismatch

MACRO lef_lib_area_mismatch
CLASS BLOCK ;
ORIGIN 0 0 ;
SIZE 1.000 BY 1.000 ;
PIN A
DIRECTION INPUT ;
USE SIGNAL ;
ANTENNAMODEL OXIDE1 ;
PORT
LAYER M1 ;
RECT 0.100 0.100 0.300 0.300 ;
END
END A
PIN VDD
DIRECTION INOUT ;
USE POWER ;
PORT
LAYER M1 ;
RECT 0.000 0.000 1.000 0.200 ;
END
END VDD
END lef_lib_area_mismatch

END LIBRARY
12 changes: 12 additions & 0 deletions src/dbSta/test/check_ip_liberty_pins.lib
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,16 @@ library (check_ip_liberty_pins) {
voltage_name : VDD;
}
}

cell (lef_lib_area_mismatch) {
area : 2;
pin (A) {
capacitance : 0.001;
direction : input;
}
pg_pin (VDD) {
pg_type : primary_power;
voltage_name : VDD;
}
}
}
1 change: 1 addition & 0 deletions src/dbSta/test/check_ip_liberty_pins.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@ expect_check_ip_pass lef_lib_pins_match
expect_check_ip_fail lef_lib_pin_missing
expect_check_ip_fail lef_lib_cell_missing
expect_check_ip_fail lef_lib_direction_mismatch
expect_check_ip_fail lef_lib_area_mismatch

puts "pass"
Loading