Initial support of multi-output gates in sizing.

This commit is contained in:
Alan Mishchenko 2026-05-08 16:03:24 -07:00
parent eaa8496b42
commit f3157272ae
5 changed files with 151 additions and 9 deletions

View File

@ -39,6 +39,86 @@ ABC_NAMESPACE_IMPL_START
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
static int Abc_NtkDupDfsSameFanins( Abc_Obj_t * pObj0, Abc_Obj_t * pObj1 )
{
Abc_Obj_t * pFanin0, * pFanin1;
int i;
if ( pObj0 == NULL || pObj1 == NULL || Abc_ObjFaninNum(pObj0) != Abc_ObjFaninNum(pObj1) )
return 0;
Abc_ObjForEachFanin( pObj0, pFanin0, i )
{
pFanin1 = Abc_ObjFanin( pObj1, i );
if ( pFanin0 != pFanin1 )
return 0;
}
return 1;
}
static Abc_Obj_t * Abc_NtkDupDfsFindTwin( Vec_Ptr_t * vNodes, Vec_Int_t * vSeen, Abc_Obj_t * pObj )
{
Mio_Gate_t * pGate = (Mio_Gate_t *)pObj->pData;
Abc_Obj_t * pObj2;
int i;
if ( pGate == NULL || Mio_GateReadTwin(pGate) == NULL )
return NULL;
Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj2, i )
{
if ( pObj2 == pObj || Vec_IntEntry(vSeen, Abc_ObjId(pObj2)) )
continue;
if ( (Mio_Gate_t *)pObj2->pData != Mio_GateReadTwin(pGate) )
continue;
if ( Abc_NtkDupDfsSameFanins(pObj, pObj2) )
return pObj2;
}
return NULL;
}
static Vec_Ptr_t * Abc_NtkDupDfsOrderTwinNodes( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes )
{
Vec_Int_t * vSeen;
Vec_Ptr_t * vRes;
Abc_Obj_t * pObj, * pTwin;
Mio_Gate_t * pGate, * pGateBase;
int i;
if ( !Abc_NtkHasMapping(pNtk) || pNtk->pManFunc == NULL )
return vNodes;
vSeen = Vec_IntStart( Abc_NtkObjNumMax(pNtk) );
vRes = Vec_PtrAlloc( Vec_PtrSize(vNodes) );
Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
{
if ( Vec_IntEntry(vSeen, Abc_ObjId(pObj)) )
continue;
pGate = (Mio_Gate_t *)pObj->pData;
if ( pGate == NULL || Mio_GateReadTwin(pGate) == NULL )
{
Vec_PtrPush( vRes, pObj );
Vec_IntWriteEntry( vSeen, Abc_ObjId(pObj), 1 );
continue;
}
pTwin = Abc_NtkDupDfsFindTwin( vNodes, vSeen, pObj );
if ( pTwin == NULL )
{
Vec_PtrPush( vRes, pObj );
Vec_IntWriteEntry( vSeen, Abc_ObjId(pObj), 1 );
continue;
}
pGateBase = Mio_LibraryReadGateByName( (Mio_Library_t *)pNtk->pManFunc, Mio_GateReadName(pGate), NULL );
if ( pGateBase == (Mio_Gate_t *)pTwin->pData )
{
Vec_PtrPush( vRes, pTwin );
Vec_PtrPush( vRes, pObj );
}
else
{
Vec_PtrPush( vRes, pObj );
Vec_PtrPush( vRes, pTwin );
}
Vec_IntWriteEntry( vSeen, Abc_ObjId(pObj), 1 );
Vec_IntWriteEntry( vSeen, Abc_ObjId(pTwin), 1 );
}
Vec_IntFree( vSeen );
Vec_PtrFree( vNodes );
return vRes;
}
/**Function*************************************************************
Synopsis [Creates a new Ntk.]
@ -548,6 +628,7 @@ Abc_Ntk_t * Abc_NtkDupDfs( Abc_Ntk_t * pNtk )
pNtkNew = Abc_NtkStartFrom( pNtk, pNtk->ntkType, pNtk->ntkFunc );
// copy the internal nodes
vNodes = Abc_NtkDfs( pNtk, 0 );
vNodes = Abc_NtkDupDfsOrderTwinNodes( pNtk, vNodes );
Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
Abc_NtkDupObj( pNtkNew, pObj, 0 );
Vec_PtrFree( vNodes );
@ -2621,4 +2702,3 @@ Abc_Ntk_t * Abc_NtkCreateFromGias( char * pName, Vec_Ptr_t * vGias, Gia_Man_t *
ABC_NAMESPACE_IMPL_END

View File

@ -149,7 +149,7 @@ p->timeSize += Abc_Clock() - clk;
{
pCellNew = SC_LibCell( p->pLib, gateBest );
Abc_SclObjSetCell( pObj, pCellNew );
p->SumArea += pCellNew->area - pCellOld->area;
p->SumArea += Abc_SclObjAreaDelta( pObj, pCellOld, pCellNew );
// printf( "%f %f -> %f\n", pCellNew->area - pCellOld->area, p->SumArea - (pCellNew->area - pCellOld->area), p->SumArea );
// printf( "%6d %20s -> %20s %f -> %f\n", Abc_ObjId(pObj), pCellOld->pName, pCellNew->pName, pCellOld->area, pCellNew->area );
// mark used nodes with the current trav ID
@ -376,4 +376,3 @@ void Abc_SclDnsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars,
ABC_NAMESPACE_IMPL_END

View File

@ -27,6 +27,7 @@
////////////////////////////////////////////////////////////////////////
#include "base/abc/abc.h"
#include "map/mio/mio.h"
#include "misc/vec/vecQue.h"
#include "misc/vec/vecWec.h"
#include "sclLib.h"
@ -130,6 +131,64 @@ static inline float Abc_SclObjInDrive( SC_Man * p, Abc_Obj_t * pObj )
static inline void Abc_SclObjSetInDrive( SC_Man * p, Abc_Obj_t * pObj, float c){ Vec_FltWriteEntry( p->vInDrive, pObj->iData, c ); }
static inline void Abc_SclManSetFaninCallBack( SC_Man * p, void * pCallBack ) { p->pFuncFanin = (float (*)(void *, Abc_Obj_t *, Abc_Obj_t *, int, int))pCallBack; }
static inline int Abc_SclObjsHaveSameFanins( Abc_Obj_t * pObj0, Abc_Obj_t * pObj1 )
{
Abc_Obj_t * pFanin0, * pFanin1;
int i;
if ( pObj0 == NULL || pObj1 == NULL || Abc_ObjFaninNum(pObj0) != Abc_ObjFaninNum(pObj1) )
return 0;
Abc_ObjForEachFanin( pObj0, pFanin0, i )
{
pFanin1 = Abc_ObjFanin( pObj1, i );
if ( pFanin0 != pFanin1 )
return 0;
}
return 1;
}
static inline int Abc_SclObjIsMogOutput( Abc_Obj_t * pObj )
{
Mio_Gate_t * pGate;
if ( pObj == NULL || !Abc_ObjIsNode(pObj) )
return 0;
pGate = (Mio_Gate_t *)pObj->pData;
return pGate != NULL && Mio_GateReadTwin(pGate) != NULL;
}
static inline int Abc_SclObjIsSecondTwin( Abc_Obj_t * pObj )
{
Abc_Obj_t * pPrev;
Mio_Gate_t * pGate;
if ( !Abc_SclObjIsMogOutput(pObj) || Abc_ObjId(pObj) == 0 )
return 0;
pPrev = Abc_NtkObj( pObj->pNtk, Abc_ObjId(pObj) - 1 );
if ( pPrev == NULL || !Abc_ObjIsNode(pPrev) )
return 0;
pGate = (Mio_Gate_t *)pObj->pData;
if ( Mio_GateReadTwin(pGate) != (Mio_Gate_t *)pPrev->pData )
return 0;
return Abc_SclObjsHaveSameFanins( pObj, pPrev );
}
static inline Abc_Obj_t * Abc_SclObjTwin( Abc_Obj_t * pObj )
{
if ( Abc_SclObjIsSecondTwin(pObj) )
return Abc_NtkObj( pObj->pNtk, Abc_ObjId(pObj) - 1 );
return Abc_NtkFetchTwinNode( pObj );
}
static inline int Abc_SclObjTwinFaninsMatch( Abc_Obj_t * pObj )
{
Abc_Obj_t * pTwin = Abc_SclObjTwin( pObj );
return pTwin != NULL && Abc_SclObjsHaveSameFanins( pObj, pTwin );
}
static inline int Abc_SclObjIsCanonicalMog( Abc_Obj_t * pObj )
{
return Abc_SclObjIsMogOutput(pObj) && !Abc_SclObjIsSecondTwin(pObj);
}
static inline float Abc_SclObjAreaDelta( Abc_Obj_t * pObj, SC_Cell * pCellOld, SC_Cell * pCellNew )
{
if ( Abc_SclObjIsSecondTwin(pObj) )
return 0.0;
return pCellNew->area - pCellOld->area;
}
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
@ -450,7 +509,11 @@ static inline float Abc_SclGetTotalArea( Abc_Ntk_t * pNtk )
Abc_Obj_t * pObj;
int i;
Abc_NtkForEachNodeNotBarBuf1( pNtk, pObj, i )
{
if ( Abc_SclObjIsSecondTwin(pObj) )
continue;
Area += Abc_SclObjCell(pObj)->area;
}
return Area;
}
static inline float Abc_SclGetMaxDelay( SC_Man * p )

View File

@ -489,7 +489,7 @@ int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notc
// update cell
pCellOld = Abc_SclObjCell( pFanin );
pCellNew = SC_LibCell( p->pLib, Vec_IntEntry(p->vNode2Gate, iNode) );
p->SumArea += pCellNew->area - pCellOld->area;
p->SumArea += Abc_SclObjAreaDelta( pFanin, pCellOld, pCellNew );
Abc_SclObjSetCell( pFanin, pCellNew );
Abc_SclUpdateLoad( p, pFanin, pCellOld, pCellNew );
// record the update
@ -646,7 +646,7 @@ int Abc_SclFindUpsizes( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notch
//printf( "gain is %f\n", Vec_FltEntry(p->vNode2Gain, Abc_ObjId(pObj)) );
// update gate
Abc_SclUpdateLoad( p, pObj, pCellOld, pCellNew );
p->SumArea += pCellNew->area - pCellOld->area;
p->SumArea += Abc_SclObjAreaDelta( pObj, pCellOld, pCellNew );
Abc_SclObjSetCell( pObj, pCellNew );
// record the update
Vec_IntPush( p->vUpdates, Abc_ObjId(pObj) );
@ -686,7 +686,7 @@ return Limit;
// if ( pCellOld->Order > 0 )
// printf( "%.2f %d -> %d(%d) ", Vec_FltEntry(p->vNode2Gain, iNode), pCellOld->Order, pCellNew->Order, pCellNew->nGates );
// update gate
p->SumArea += pCellNew->area - pCellOld->area;
p->SumArea += Abc_SclObjAreaDelta( pObj, pCellOld, pCellNew );
Abc_SclObjSetCell( pObj, pCellNew );
Abc_SclUpdateLoad( p, pObj, pCellOld, pCellNew );
// record the update
@ -1043,4 +1043,3 @@ void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars,
ABC_NAMESPACE_IMPL_END

View File

@ -75,9 +75,11 @@ void Abc_SclSclGates2MioGates( SC_Lib * pLib, Abc_Ntk_t * p )
assert( p->vGates != NULL );
Abc_NtkForEachNodeNotBarBuf1( p, pObj, i )
{
Mio_Gate_t * pGateOld = (Mio_Gate_t *)pObj->pData;
char * pOutName = Abc_SclObjIsMogOutput(pObj) ? Mio_GateReadOutName(pGateOld) : NULL;
pCell = Abc_SclObjCell(pObj);
assert( pCell->n_inputs == Abc_ObjFaninNum(pObj) );
pObj->pData = Mio_LibraryReadGateByName( (Mio_Library_t *)p->pManFunc, pCell->pName, NULL );
pObj->pData = Mio_LibraryReadGateByName( (Mio_Library_t *)p->pManFunc, pCell->pName, pOutName );
Counter += (pObj->pData == NULL);
assert( pObj->fMarkA == 0 && pObj->fMarkB == 0 );
CounterAll++;
@ -317,4 +319,3 @@ void Abc_SclInsertBarBufs( Abc_Ntk_t * pNtk, Vec_Int_t * vBufs )
ABC_NAMESPACE_IMPL_END