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
2 changes: 2 additions & 0 deletions src/dbSta/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,10 @@ cc_library(
"include",
],
deps = [
":dbNetwork",
":dbSta",
"//src/odb/src/db",
"//src/sta:opensta_lib",
"//src/utl",
],
)
Expand Down
4 changes: 4 additions & 0 deletions src/dbSta/include/db_sta/IpChecker.hh
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ namespace sta {
// LEF-CHK-009: Pin geometry presence
// LEF-CHK-010a: Pin minimum width (perpendicular to routing direction)
// LEF-CHK-010b: Pin minimum area
// LEF/LIB-CHK-012: LEF signal pins exist in Liberty

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

// LEF/LIB-CHK-012: LEF signal pins exist in Liberty
void checkLibertyPinPresence(odb::dbMaster* master);

// Helper: Check if a pin shape has at least one accessible edge
bool hasAccessibleEdge(odb::dbMaster* master,
const odb::Rect& pin_rect,
Expand Down
35 changes: 35 additions & 0 deletions src/dbSta/src/IpChecker.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@
#include <map>
#include <numeric>
#include <string>
#include <string_view>
#include <vector>

#include "db_sta/dbNetwork.hh"
#include "db_sta/dbSta.hh"
#include "odb/PtrSetMap.h"
#include "odb/db.h"
#include "odb/dbTypes.h"
#include "odb/geom.h"
#include "sta/Liberty.hh"
#include "utl/Logger.h"

namespace sta {
Expand Down Expand Up @@ -121,6 +124,7 @@ void IpChecker::checkLefMaster(odb::dbMaster* master)
checkPinGeometryPresence(master); // LEF-CHK-009
checkPinMinDimensions(master); // LEF-CHK-010a
checkPinMinArea(master); // LEF-CHK-010b
checkLibertyPinPresence(master); // LEF/LIB-CHK-012
}

// LEF-CHK-001: Macro dimensions aligned to manufacturing grid
Expand Down Expand Up @@ -693,4 +697,35 @@ void IpChecker::checkPinMinArea(odb::dbMaster* master)
}
}

// LEF/LIB-CHK-012: LEF signal pins exist in Liberty.
void IpChecker::checkLibertyPinPresence(odb::dbMaster* master)
{
if (sta_ == nullptr || sta_->getDbNetwork() == nullptr) {
return;
}

LibertyCell* liberty_cell = sta_->getDbNetwork()->findLibertyCell(
std::string_view(master->getName()));
if (liberty_cell == nullptr) {
return;
}

const std::string master_name = master->getName();
for (odb::dbMTerm* mterm : master->getMTerms()) {
if (mterm->getSigType().isSupply()) {
continue;
}

if (liberty_cell->findLibertyPort(mterm->getName()) == nullptr) {
logger_->warn(utl::CHK,
121,
"Pin {}/{} missing from Liberty cell {}",
master_name,
mterm->getName(),
liberty_cell->name());
warning_count_++;
}
}
}

} // namespace sta
10 changes: 8 additions & 2 deletions src/dbSta/test/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ ALL_TESTS = [
"write_verilog9_hier",
]

PASSFAIL_TESTS = [
"check_ip_liberty_pins",
]

filegroup(
name = "regression_resources",
srcs = [
Expand Down Expand Up @@ -288,16 +292,18 @@ filegroup(
],
}.get(test_name, []),
)
for test_name in ALL_TESTS
for test_name in ALL_TESTS + PASSFAIL_TESTS
]

[
regression_test(
name = test_name,
check_log = False if test_name in PASSFAIL_TESTS else True,
check_passfail = True if test_name in PASSFAIL_TESTS else False,
data = [":" + test_name + "_resources"],
visibility = ["//visibility:public"],
)
for test_name in ALL_TESTS
for test_name in ALL_TESTS + PASSFAIL_TESTS
]

cc_test(
Expand Down
2 changes: 2 additions & 0 deletions src/dbSta/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ or_integration_tests(
write_verilog8
write_verilog9
write_verilog9_hier
PASSFAIL_TESTS
check_ip_liberty_pins
)

if(ENABLE_TESTS)
Expand Down
83 changes: 83 additions & 0 deletions src/dbSta/test/check_ip_liberty_pins.lef
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
VERSION 5.8 ;
BUSBITCHARS "[]" ;
DIVIDERCHAR "/" ;

UNITS
DATABASE MICRONS 1000 ;
END UNITS

MANUFACTURINGGRID 0.005 ;

LAYER M1
TYPE ROUTING ;
DIRECTION HORIZONTAL ;
PITCH 0.200 ;
WIDTH 0.100 ;
AREA 0.020 ;
END M1

MACRO lef_lib_pins_match
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 Z
DIRECTION OUTPUT ;
USE SIGNAL ;
ANTENNAMODEL OXIDE1 ;
PORT
LAYER M1 ;
RECT 0.500 0.500 0.700 0.700 ;
END
END Z
PIN VDD
DIRECTION INOUT ;
USE POWER ;
PORT
LAYER M1 ;
RECT 0.000 0.000 1.000 0.200 ;
END
END VDD
END lef_lib_pins_match

MACRO lef_lib_pin_missing
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 Z
DIRECTION OUTPUT ;
USE SIGNAL ;
ANTENNAMODEL OXIDE1 ;
PORT
LAYER M1 ;
RECT 0.500 0.500 0.700 0.700 ;
END
END Z
PIN VDD
DIRECTION INOUT ;
USE POWER ;
PORT
LAYER M1 ;
RECT 0.000 0.000 1.000 0.200 ;
END
END VDD
END lef_lib_pin_missing

END LIBRARY
36 changes: 36 additions & 0 deletions src/dbSta/test/check_ip_liberty_pins.lib
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
library (check_ip_liberty_pins) {
delay_model : table_lookup;
capacitive_load_unit (1,pf);
current_unit : "1A";
pulling_resistance_unit : "1kohm";
time_unit : "1ns";
voltage_unit : "1V";

cell (lef_lib_pins_match) {
area : 1;
pin (A) {
capacitance : 0.001;
direction : input;
}
pin (Z) {
direction : output;
function : "A";
}
pg_pin (VDD) {
pg_type : primary_power;
voltage_name : VDD;
}
}

cell (lef_lib_pin_missing) {
area : 1;
pin (A) {
capacitance : 0.001;
direction : input;
}
pg_pin (VDD) {
pg_type : primary_power;
voltage_name : VDD;
}
}
}
26 changes: 26 additions & 0 deletions src/dbSta/test/check_ip_liberty_pins.tcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2026, The OpenROAD Authors

source "helpers.tcl"

read_lef check_ip_liberty_pins.lef
read_liberty check_ip_liberty_pins.lib

proc expect_check_ip_pass { master_name } {
if { [catch { check_ip -master $master_name } err] } {
puts "FAIL: expected $master_name to pass: $err"
exit 1
}
}

proc expect_check_ip_fail { master_name } {
if { ![catch { check_ip -master $master_name } err] } {
puts "FAIL: expected $master_name to fail"
exit 1
}
}

expect_check_ip_pass lef_lib_pins_match
expect_check_ip_fail lef_lib_pin_missing

puts "pass"
Loading