From f3b785361d82824b4838def17d36637cdc4557a8 Mon Sep 17 00:00:00 2001 From: James Cherry Date: Fri, 20 Jun 2025 16:15:54 -0700 Subject: [PATCH] equiv cells only require timing arc equivs missing functions Signed-off-by: James Cherry --- include/sta/EquivCells.hh | 6 ++--- liberty/EquivCells.cc | 53 +++++++++++++++++++++++---------------- liberty/LibertyReader.cc | 9 +++++-- 3 files changed, 42 insertions(+), 26 deletions(-) diff --git a/include/sta/EquivCells.hh b/include/sta/EquivCells.hh index af6c1766..2b201d2b 100644 --- a/include/sta/EquivCells.hh +++ b/include/sta/EquivCells.hh @@ -67,10 +67,10 @@ bool equivCellPorts(const LibertyCell *cell1, const LibertyCell *cell2); -// Predicate that is true when the ports and their functions match. +// Predicate that is true cell functions match. bool -equivCellPortsAndFuncs(const LibertyCell *cell1, - const LibertyCell *cell2); +equivCellFuncs(const LibertyCell *cell1, + const LibertyCell *cell2); // Predicate that is true when the timing arc sets match. bool diff --git a/liberty/EquivCells.cc b/liberty/EquivCells.cc index e7c2c0fd..84e57cc0 100644 --- a/liberty/EquivCells.cc +++ b/liberty/EquivCells.cc @@ -71,6 +71,8 @@ static unsigned hashCellPgPorts(const LibertyCell *cell); static unsigned hashPgPort(const LibertyPgPort *port); +static bool +cellHasFuncs(const LibertyCell *cell); static bool equivCellPgPorts(const LibertyCell *cell1, @@ -329,35 +331,44 @@ bool equivCells(const LibertyCell *cell1, const LibertyCell *cell2) { - return equivCellPortsAndFuncs(cell1, cell2) + return equivCellPorts(cell1, cell2) + && equivCellFuncs(cell1, cell2) && equivCellPgPorts(cell1, cell2) && equivCellSequentials(cell1, cell2) && equivCellStatetables(cell1, cell2) - && equivCellTimingArcSets(cell1, cell2); + // Reqwuire timing arc equivalence if there are no functions. + && (cellHasFuncs(cell1) + || equivCellTimingArcSets(cell1, cell2)); +} + +static bool +cellHasFuncs(const LibertyCell *cell) +{ + LibertyCellPortIterator port_iter(cell); + while (port_iter.hasNext()) { + LibertyPort *port = port_iter.next(); + if (port->function()) + return true; + } + return false; } bool -equivCellPortsAndFuncs(const LibertyCell *cell1, - const LibertyCell *cell2) +equivCellFuncs(const LibertyCell *cell1, + const LibertyCell *cell2) { - if (cell1->portCount() != cell2->portCount()) - return false; - else { - LibertyCellPortIterator port_iter1(cell1); - while (port_iter1.hasNext()) { - LibertyPort *port1 = port_iter1.next(); - const char *name = port1->name(); - LibertyPort *port2 = cell2->findLibertyPort(name); - if (!(port2 - && LibertyPort::equiv(port1, port2) - && FuncExpr::equiv(port1->function(), port2->function()) - && FuncExpr::equiv(port1->tristateEnable(), - port2->tristateEnable()))){ - return false; - } - } - return true; + LibertyCellPortIterator port_iter1(cell1); + while (port_iter1.hasNext()) { + LibertyPort *port1 = port_iter1.next(); + const char *name = port1->name(); + LibertyPort *port2 = cell2->findLibertyPort(name); + if (!(port2 + && FuncExpr::equiv(port1->function(), port2->function()) + && FuncExpr::equiv(port1->tristateEnable(), + port2->tristateEnable()))) + return false; } + return true; } bool diff --git a/liberty/LibertyReader.cc b/liberty/LibertyReader.cc index 0d7e66de..06288752 100644 --- a/liberty/LibertyReader.cc +++ b/liberty/LibertyReader.cc @@ -2303,8 +2303,13 @@ void LibertyReader::checkScaledCell(LibertyGroup *group) { if (equivCellPorts(cell_, scaled_cell_owner_)) { - if (!equivCellPortsAndFuncs(cell_, scaled_cell_owner_)) - libWarn(1206, group, "scaled_cell %s, %s port functions do not match cell port functions.", + if (!equivCellPorts(cell_, scaled_cell_owner_)) + libWarn(1206, group, "scaled_cell %s, %s ports do not match cell ports", + cell_->name(), + op_cond_->name()); + if (!equivCellFuncs(cell_, scaled_cell_owner_)) + libWarn(1206, group, + "scaled_cell %s, %s port functions do not match cell port functions.", cell_->name(), op_cond_->name()); }