equiv cells only require timing arc equivs missing functions

Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
James Cherry 2025-06-20 16:15:54 -07:00
parent b431135550
commit f3b785361d
3 changed files with 42 additions and 26 deletions

View File

@ -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

View File

@ -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

View File

@ -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());
}