diff options
Diffstat (limited to 'src/base/cba/cbaBlast.c')
-rw-r--r-- | src/base/cba/cbaBlast.c | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/src/base/cba/cbaBlast.c b/src/base/cba/cbaBlast.c index f4cea24a..8d2d53cd 100644 --- a/src/base/cba/cbaBlast.c +++ b/src/base/cba/cbaBlast.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "cba.h" +#include "base/abc/abc.h" ABC_NAMESPACE_IMPL_START @@ -41,7 +42,218 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ +void Cba_ManExtractSave( Cba_Man_t * p, int iLNtk, int iLObj, int iRNtk, int iRObj ) +{ + Vec_IntPush( p->vBuf2LeafNtk, iLNtk ); + Vec_IntPush( p->vBuf2LeafObj, iLObj ); + Vec_IntPush( p->vBuf2RootNtk, iRNtk ); + Vec_IntPush( p->vBuf2RootObj, iRObj ); +} +int Cba_ManExtract_rec( Gia_Man_t * pNew, Cba_Ntk_t * p, int i ) +{ + int iRes = Cba_NtkCopy( p, i ); + if ( iRes >= 0 ) + return iRes; + if ( Cba_ObjIsCo(p, i) ) + iRes = Cba_ManExtract_rec( pNew, p, Cba_ObjFanin0(p, i) ); + else if ( Cba_ObjIsBo(p, i) ) + { + Cba_Ntk_t * pBox = Cba_ObjBoModel( p, i ); + int iObj = Cba_NtkPo( pBox, Cba_ObjCioIndex(p, i) ); + iRes = Cba_ManExtract_rec( pNew, pBox, iObj ); + iRes = Gia_ManAppendBuf( pNew, iRes ); + Cba_ManExtractSave( p->pDesign, Cba_NtkId(p), i, Cba_NtkId(pBox), iObj ); + } + else if ( Cba_ObjIsPi(p, i) ) + { + Cba_Ntk_t * pHost = Cba_NtkHost( p ); + int iObj = Cba_ObjBoxBi( pHost, p->iBoxObj, Cba_ObjCioIndex(p, i) ); + iRes = Cba_ManExtract_rec( pNew, pHost, iObj ); + iRes = Gia_ManAppendBuf( pNew, iRes ); + Cba_ManExtractSave( p->pDesign, Cba_NtkId(p), i, Cba_NtkId(pHost), iObj ); + } + else if ( Cba_ObjIsNode(p, i) ) + { + int * pFanins = Cba_ObjFaninArray(p, i); + int k, pLits[3], Type = Cba_ObjNodeType(p, i); + assert( pFanins[0] <= 3 ); + for ( k = 0; k < pFanins[0]; k++ ) + pLits[k] = Cba_ManExtract_rec( pNew, p, pFanins[k+1] ); + if ( Type == CBA_NODE_AND ) + iRes = Gia_ManHashAnd( pNew, pLits[0], pLits[1] ); + else if ( Type == CBA_NODE_OR ) + iRes = Gia_ManHashAnd( pNew, pLits[0], pLits[1] ); + else if ( Type == CBA_NODE_XOR ) + iRes = Gia_ManHashXor( pNew, pLits[0], pLits[1] ); + else if ( Type == CBA_NODE_XNOR ) + iRes = Abc_LitNot( Gia_ManHashXor( pNew, pLits[0], pLits[1] ) ); + else assert( 0 ), iRes = -1; + } + else assert( 0 ); + Cba_NtkSetCopy( p, i, iRes ); + return iRes; +} +Gia_Man_t * Cba_ManExtract( Cba_Man_t * p, int fVerbose ) +{ + Cba_Ntk_t * pRoot = Cba_ManRoot(p); + Gia_Man_t * pNew, * pTemp; + int i, iObj; + p->vBuf2LeafNtk = Vec_IntAlloc( 1000 ); + p->vBuf2LeafObj = Vec_IntAlloc( 1000 ); + p->vBuf2RootNtk = Vec_IntAlloc( 1000 ); + p->vBuf2RootObj = Vec_IntAlloc( 1000 ); + + // start the manager + pNew = Gia_ManStart( Cba_ManObjNum(p) ); + pNew->pName = Abc_UtilStrsav(p->pName); + pNew->pSpec = Abc_UtilStrsav(p->pSpec); + + Vec_IntFill( &p->vCopies, Cba_ManObjNum(p), -1 ); + Cba_NtkForEachPi( pRoot, iObj, i ) + Cba_NtkSetCopy( pRoot, iObj, Gia_ManAppendCi(pNew) ); + Cba_NtkForEachPo( pRoot, iObj, i ) + Cba_ManExtract_rec( pNew, pRoot, iObj ); + Cba_NtkForEachPo( pRoot, iObj, i ) + Gia_ManAppendCo( pNew, Cba_NtkCopy(pRoot, iObj) ); + assert( Vec_IntSize(p->vBuf2LeafNtk) == pNew->nBufs ); + + // cleanup + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); +// Gia_ManPrintStats( pNew, NULL ); +// pNew = Gia_ManSweepHierarchy( pTemp = pNew ); +// Gia_ManStop( pTemp ); +// Gia_ManPrintStats( pNew, NULL ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +// return the array of object counters for each network +void Cba_ManCountNodes_rec( Cba_Man_t * p, Abc_Obj_t * pObj, int iNtk, Vec_Int_t * vObjCounts, Vec_Int_t * vBufDrivers, Vec_Int_t * vObj2Ntk, Vec_Int_t * vObj2Obj ) +{ + if ( Abc_ObjIsBarBuf(pObj) ) + { + Abc_Obj_t * pFanin = Abc_ObjFanin0(pObj); + if ( Abc_ObjIsPi(pFanin) || (Abc_ObjIsNode(pFanin) && Abc_ObjFaninNum(pFanin) > 0) ) + Vec_IntAddToEntry( vBufDrivers, iNtk, 1 ); + Cba_ManCountNodes_rec( p, Abc_ObjFanin0(pObj), pObj->iTemp, vObjCounts, vBufDrivers, vObj2Ntk, vObj2Obj ); + } + else if ( Abc_ObjFaninNum(pObj) > 0 ) + { + Abc_Obj_t * pFanin; int i; + Abc_ObjForEachFanin( pObj, pFanin, i ) + Cba_ManCountNodes_rec( p, pFanin, iNtk, vObjCounts, vBufDrivers, vObj2Ntk, vObj2Obj ); + Vec_IntWriteEntry( vObj2Ntk, Abc_ObjId(pObj), iNtk ); + Vec_IntWriteEntry( vObj2Obj, Abc_ObjId(pObj), Vec_IntEntry(vObjCounts, iNtk) ); + Vec_IntAddToEntry( vObjCounts, iNtk, 1 ); + } +} +Vec_Int_t * Cba_ManCountNodes( Cba_Man_t * p, Abc_Ntk_t * pAbcNtk, Vec_Int_t * vBuf2RootNtk, Vec_Int_t ** pvObj2Ntk, Vec_Int_t ** pvObj2Obj ) +{ + Cba_Ntk_t * pNtk; + Abc_Obj_t * pObj; + Vec_Int_t * vObjCounts = Vec_IntStart( Cba_ManNtkNum(p) + 1 ); + Vec_Int_t * vBufDrivers = Vec_IntStart( Cba_ManNtkNum(p) + 1 ); + // set networks to which barbufs belong + int i, k, iBox, iBarBuf = Vec_IntSize( vBuf2RootNtk ); + assert( Vec_IntSize(vBuf2RootNtk) == pAbcNtk->nBarBufs2 ); + Abc_NtkForEachNodeReverse( pAbcNtk, pObj, i ) + pObj->iTemp = Vec_IntEntry( vBuf2RootNtk, --iBarBuf ); + assert( iBarBuf == 0 ); + // start with primary inputs + Cba_ManForEachNtk( p, pNtk, i ) + { + Vec_IntAddToEntry( vObjCounts, i, Cba_NtkPiNum(pNtk) ); + Cba_NtkForEachBox( pNtk, iBox, k ) + Vec_IntAddToEntry( vObjCounts, i, Cba_NtkPiNum(Cba_ObjBoxModel(pNtk, iBox)) + Cba_NtkPoNum(Cba_ObjBoxModel(pNtk, iBox)) + 1 ); + } + // count internal nodes (network is in topo order) + *pvObj2Ntk = Vec_IntStartFull( Abc_NtkObjNumMax(pAbcNtk) ); + *pvObj2Obj = Vec_IntStartFull( Abc_NtkObjNumMax(pAbcNtk) ); + Abc_NtkForEachPo( pAbcNtk, pObj, i ) + Cba_ManCountNodes_rec( p, Abc_ObjFanin0(pObj), p->iRoot, vObjCounts, vBufDrivers, *pvObj2Ntk, *pvObj2Obj ); + // count PIs, POs, and PO drivers + Cba_ManForEachNtk( p, pNtk, i ) + Vec_IntAddToEntry( vObjCounts, i, 2 * Cba_NtkPoNum(pNtk) - Vec_IntEntry(vBufDrivers, i) ); + Vec_IntFree( vBufDrivers ); + return vObjCounts; +} +Cba_Man_t * Cba_ManInsert( Cba_Man_t * p, Abc_Ntk_t * pAbcNtk, int fVerbose ) +{ + Cba_Man_t * pNew; + Cba_Ntk_t * pNtk; + Abc_Obj_t * pObj, * pFanin; + Vec_Int_t * vObj2Ntk, * vObj2Obj; + Vec_Int_t * vObjCounts = Cba_ManCountNodes( p, pAbcNtk, p->vBuf2RootNtk, &vObj2Ntk, &vObj2Obj ); + Vec_Int_t * vFanins; + int i, k, iNtk, iBuf = 0; + // create initial mapping + pNew = Cba_ManDupStart( p, vObjCounts ); + // set PIs point to the leaves + Abc_NtkForEachPi( pAbcNtk, pObj, i ) + { + Vec_IntWriteEntry( vObj2Ntk, Abc_ObjId(pObj), p->iRoot ); + Vec_IntWriteEntry( vObj2Obj, Abc_ObjId(pObj), i ); + } + // set buffers to point to the leaves + assert( Vec_IntSize(p->vBuf2LeafNtk) == pAbcNtk->nBarBufs2 ); + assert( Vec_IntSize(p->vBuf2LeafObj) == pAbcNtk->nBarBufs2 ); + Abc_NtkForEachBarBuf( pAbcNtk, pObj, i ) + { + Vec_IntWriteEntry( vObj2Ntk, Abc_ObjId(pObj), Vec_IntEntry(p->vBuf2LeafNtk, iBuf) ); + Vec_IntWriteEntry( vObj2Obj, Abc_ObjId(pObj), Vec_IntEntry(p->vBuf2LeafObj, iBuf) ); + iBuf++; + } + assert( iBuf == pAbcNtk->nBarBufs2 ); + // copy internal nodes + vFanins = Vec_IntAlloc( 100 ); + Abc_NtkForEachNode( pAbcNtk, pObj, i ) + { + if ( Abc_ObjIsBarBuf(pObj) ) + continue; + if ( Abc_ObjFaninNum(pObj) == 0 ) + continue; + Vec_IntClear( vFanins ); + iNtk = Vec_IntEntry(vObj2Ntk, Abc_ObjId(pObj)); + Abc_ObjForEachFanin( pObj, pFanin, k ) + { + assert( Vec_IntEntry(vObj2Ntk, Abc_ObjId(pFanin)) == iNtk ); + Vec_IntPush( vFanins, Vec_IntEntry(vObj2Obj, Abc_ObjId(pFanin)) ); + } + pNtk = Cba_ManNtk( pNew, iNtk ); + Vec_IntPush( &pNtk->vTypes, CBA_OBJ_NODE ); + Vec_IntPush( &pNtk->vFuncs, -1 ); + Vec_IntPush( &pNtk->vFanins, Cba_ManHandleArray(pNew, vFanins) ); + } + // set buffers to point to the roots + assert( Vec_IntSize(p->vBuf2RootNtk) == pAbcNtk->nBarBufs2 ); + assert( Vec_IntSize(p->vBuf2RootObj) == pAbcNtk->nBarBufs2 ); + iBuf = 0; + Abc_NtkForEachBarBuf( pAbcNtk, pObj, i ) + { + Vec_IntWriteEntry( vObj2Ntk, Abc_ObjId(pObj), Vec_IntEntry(p->vBuf2RootNtk, iBuf) ); + Vec_IntWriteEntry( vObj2Obj, Abc_ObjId(pObj), Vec_IntEntry(p->vBuf2RootObj, iBuf) ); + iBuf++; + } + assert( iBuf == pAbcNtk->nBarBufs2 ); + // connect driven root nodes + + + Vec_IntFree( vObj2Ntk ); + Vec_IntFree( vObj2Obj ); + return pNew; +} //////////////////////////////////////////////////////////////////////// /// END OF FILE /// |