diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2015-01-17 20:27:23 -0800 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2015-01-17 20:27:23 -0800 |
commit | 17610c039f79e30679b7950e7d91de166b34d2fa (patch) | |
tree | 3e9885c0fad76b1ca8f122323683fb11b87d290f /src/base/cba/cbaBlast.c | |
parent | 42cc56576b0ab244f0834fc8d80a3ced406576bd (diff) | |
download | abc-17610c039f79e30679b7950e7d91de166b34d2fa.tar.gz abc-17610c039f79e30679b7950e7d91de166b34d2fa.tar.bz2 abc-17610c039f79e30679b7950e7d91de166b34d2fa.zip |
Organizing commands for barbuf-aware flow.
Diffstat (limited to 'src/base/cba/cbaBlast.c')
-rw-r--r-- | src/base/cba/cbaBlast.c | 242 |
1 files changed, 221 insertions, 21 deletions
diff --git a/src/base/cba/cbaBlast.c b/src/base/cba/cbaBlast.c index 808f3035..45ced7d2 100644 --- a/src/base/cba/cbaBlast.c +++ b/src/base/cba/cbaBlast.c @@ -20,6 +20,8 @@ #include "cba.h" #include "base/abc/abc.h" +#include "map/mio/mio.h" +#include "bool/dec/dec.h" ABC_NAMESPACE_IMPL_START @@ -42,6 +44,44 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ +void Cba_ManPrepareGates( Cba_Man_t * p ) +{ + int i; + if ( p->pMioLib == NULL ) + return; + assert( p->ppGraphs == NULL ); + p->ppGraphs = ABC_ALLOC( Dec_Graph_t *, Abc_NamObjNumMax(p->pFuncs) ); + p->ppGraphs[0] = NULL; + for ( i = 1; i < Abc_NamObjNumMax(p->pFuncs); i++ ) + { + char * pGateName = Abc_NamStr( p->pFuncs, i ); + Mio_Gate_t * pGate = Mio_LibraryReadGateByName( (Mio_Library_t *)p->pMioLib, pGateName, NULL ); + char * pSop = Mio_GateReadSop( pGate ); + p->ppGraphs[i] = Dec_Factor( pSop ); + } +} +void Cba_ManUndoGates( Cba_Man_t * p ) +{ + int i; + if ( p->pMioLib == NULL ) + return; + for ( i = 1; i < Abc_NamObjNumMax(p->pFuncs); i++ ) + Dec_GraphFree( p->ppGraphs[i] ); + ABC_FREE( p->ppGraphs ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ int Cba_ManAddBarbuf( Gia_Man_t * pNew, int iRes, Cba_Man_t * p, int iLNtk, int iLObj, int iRNtk, int iRObj, Vec_Int_t * vMap ) { int iBufLit, iIdLit; @@ -86,6 +126,17 @@ int Cba_ManExtract_rec( Gia_Man_t * pNew, Cba_Ntk_t * p, int i, int fBuffers, Ve if ( fBuffers ) iRes = Cba_ManAddBarbuf( pNew, iRes, p->pDesign, Cba_NtkId(p), i, Cba_NtkId(pHost), iObj, vMap ); } + else if ( Cba_ObjIsNode(p, i) && p->pDesign->ppGraphs ) + { + extern int Gia_ManFactorGraph( Gia_Man_t * p, Dec_Graph_t * pFForm, Vec_Int_t * vLeaves ); + Dec_Graph_t * pGraph = (Dec_Graph_t *)p->pDesign->ppGraphs[Cba_ObjFuncId(p, i)]; + int k, pLits[32], * pFanins = Cba_ObjFaninArray(p, i); + Vec_Int_t Leaves = { pFanins[0], pFanins[0], pLits }; + assert( pFanins[0] < 32 ); + for ( k = 0; k < pFanins[0]; k++ ) + pLits[k] = Cba_ManExtract_rec( pNew, p, pFanins[k+1], fBuffers, vMap ); + return Gia_ManFactorGraph( pNew, pGraph, &Leaves ); + } else if ( Cba_ObjIsNode(p, i) ) { int * pFanins = Cba_ObjFaninArray(p, i); @@ -115,10 +166,14 @@ int Cba_ManExtract_rec( Gia_Man_t * pNew, Cba_Ntk_t * p, int i, int fBuffers, Ve iRes = Gia_ManHashAnd( pNew, pLits[0], pLits[1] ); else if ( Type == CBA_NODE_OR ) iRes = Gia_ManHashOr( pNew, pLits[0], pLits[1] ); + else if ( Type == CBA_NODE_NOR ) + iRes = Abc_LitNot( Gia_ManHashOr( 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 if ( Type == CBA_NODE_SHARP ) + iRes = Gia_ManHashAnd( pNew, pLits[0], Abc_LitNot(pLits[1]) ); else assert( 0 ); } } @@ -155,8 +210,10 @@ Gia_Man_t * Cba_ManExtract( Cba_Man_t * p, int fBuffers, int fVerbose ) Gia_ManHashAlloc( pNew ); pNew->vBarBufs = Vec_IntAlloc( 10000 ); vMap = Vec_IntStartFull( 10000 ); + Cba_ManPrepareGates( p ); Cba_NtkForEachPo( pRoot, iObj, i ) Cba_ManExtract_rec( pNew, pRoot, iObj, fBuffers, vMap ); + Cba_ManUndoGates( p ); Vec_IntFreeP( &vMap ); Gia_ManHashStop( pNew ); @@ -187,8 +244,8 @@ Vec_Int_t * Cba_ManCountGia( Cba_Man_t * p, Gia_Man_t * pGia, int fAlwaysAdd ) { Cba_Ntk_t * pNtk; Gia_Obj_t * pObj; - int i, k, iBox, Count = 0; - Vec_Int_t * vNtkSizes = Vec_IntStart( Cba_ManNtkNum(p) + 1 ); + int i, iBox, Count = 0; + Vec_Int_t * vNtkSizes = Vec_IntStart( Cba_ManNtkNum(p) + 1 ); Vec_Int_t * vDrivenCos = Vec_IntStart( Cba_ManNtkNum(p) + 1 ); assert( Vec_IntSize(p->vBuf2LeafNtk) == Gia_ManBufNum(pGia) ); // assing for each GIA node, the network it belongs to and count nodes for all networks @@ -222,7 +279,7 @@ Vec_Int_t * Cba_ManCountGia( Cba_Man_t * p, Gia_Man_t * pGia, int fAlwaysAdd ) Cba_ManForEachNtk( p, pNtk, i ) { Count = Cba_NtkPiNum(pNtk) + 2 * Cba_NtkPoNum(pNtk) - (fAlwaysAdd ? 0 : Vec_IntEntry(vDrivenCos, i)); - Cba_NtkForEachBox( pNtk, iBox, k ) + Cba_NtkForEachBox( pNtk, iBox ) Count += Cba_ObjBoxSize(pNtk, iBox) + Cba_ObjBoxBiNum(pNtk, iBox); Vec_IntAddToEntry( vNtkSizes, i, Count ); } @@ -249,21 +306,21 @@ void Cba_ManRemapBarbufs( Cba_Man_t * pNew, Cba_Man_t * p ) Vec_IntWriteEntry( pNew->vBuf2RootObj, i, Cba_NtkCopy(pNtk, Entry) ); } } -void Cba_NtkCreateAndConnectBuffer( Gia_Man_t * pGia, Gia_Obj_t * pObj, Cba_Ntk_t * pNtk, int iTerm ) +void Cba_NtkCreateAndConnectBuffer( Gia_Man_t * pGia, Gia_Obj_t * pObj, Cba_Ntk_t * p, int iTerm ) { - Vec_IntWriteEntry( &pNtk->vTypes, pNtk->nObjs, CBA_OBJ_NODE ); - if ( !pGia || !Gia_ObjFaninId0p(pGia, pObj) ) + Vec_IntWriteEntry( &p->vTypes, p->nObjs, CBA_OBJ_NODE ); + if ( pGia && Gia_ObjFaninId0p(pGia, pObj) > 0 ) { - Vec_IntWriteEntry( &pNtk->vFuncs, pNtk->nObjs, pGia && Gia_ObjFaninC0(pObj) ? CBA_NODE_C1 : CBA_NODE_C0 ); - Vec_IntWriteEntry( &pNtk->vFanins, pNtk->nObjs, Cba_ManHandleBuffer(pNtk->pDesign, -1) ); + Vec_IntWriteEntry( &p->vFuncs, p->nObjs, Gia_ObjFaninC0(pObj) ? CBA_NODE_INV : CBA_NODE_BUF ); + Vec_IntWriteEntry( &p->vFanins, p->nObjs, Cba_ManHandleBuffer(p->pDesign, Gia_ObjFanin0(pObj)->Value) ); } else { - Vec_IntWriteEntry( &pNtk->vFuncs, pNtk->nObjs, Gia_ObjFaninC0(pObj) ? CBA_NODE_INV : CBA_NODE_BUF ); - Vec_IntWriteEntry( &pNtk->vFanins, pNtk->nObjs, Cba_ManHandleBuffer(pNtk->pDesign, Gia_ObjFanin0(pObj)->Value) ); + Vec_IntWriteEntry( &p->vFuncs, p->nObjs, pGia && Gia_ObjFaninC0(pObj) ? CBA_NODE_C1 : CBA_NODE_C0 ); + Vec_IntWriteEntry( &p->vFanins, p->nObjs, Cba_ManHandleBuffer(p->pDesign, -1) ); } - Vec_IntWriteEntry( &pNtk->vNameIds, pNtk->nObjs, Cba_ObjNameId(pNtk, iTerm) ); - Vec_IntWriteEntry( &pNtk->vFanins, iTerm, pNtk->nObjs++ ); + Vec_IntWriteEntry( &p->vNameIds, p->nObjs, Cba_ObjNameId(p, iTerm) ); + Vec_IntWriteEntry( &p->vFanins, iTerm, p->nObjs++ ); } void Cba_NtkInsertGia( Cba_Man_t * p, Gia_Man_t * pGia ) { @@ -288,17 +345,22 @@ void Cba_NtkInsertGia( Cba_Man_t * p, Gia_Man_t * pGia ) } else { + int iLit0 = Gia_ObjFanin0(pObj)->Value; + int iLit1 = Gia_ObjFanin1(pObj)->Value; Cba_NodeType_t Type; pNtk = Cba_ManNtk( p, pObj->Value ); if ( Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) ) - Type = CBA_NODE_AND00; - else if ( Gia_ObjFaninC0(pObj) ) - Type = CBA_NODE_AND01; + Type = CBA_NODE_NOR; else if ( Gia_ObjFaninC1(pObj) ) - Type = CBA_NODE_AND10; + Type = CBA_NODE_SHARP; + else if ( Gia_ObjFaninC0(pObj) ) + { + Type = CBA_NODE_SHARP; + ABC_SWAP( int, iLit0, iLit1 ); + } else Type = CBA_NODE_AND; - Vec_IntFillTwo( vTemp, 2, Gia_ObjFanin0(pObj)->Value, Gia_ObjFanin1(pObj)->Value ); + Vec_IntFillTwo( vTemp, 2, iLit0, iLit1 ); Vec_IntWriteEntry( &pNtk->vTypes, pNtk->nObjs, CBA_OBJ_NODE ); Vec_IntWriteEntry( &pNtk->vFuncs, pNtk->nObjs, Type ); Vec_IntWriteEntry( &pNtk->vFanins, pNtk->nObjs, Cba_ManHandleArray(p, vTemp) ); @@ -311,7 +373,7 @@ void Cba_NtkInsertGia( Cba_Man_t * p, Gia_Man_t * pGia ) // create constant 0 drivers for COs without barbufs Cba_ManForEachNtk( p, pNtk, i ) { - Cba_NtkForEachBox( pNtk, iBox, k ) + Cba_NtkForEachBox( pNtk, iBox ) Cba_BoxForEachBi( pNtk, iBox, iTerm, j ) if ( Cba_ObjFanin0(pNtk, iTerm) == -1 ) Cba_NtkCreateAndConnectBuffer( NULL, NULL, pNtk, iTerm ); @@ -333,7 +395,6 @@ Cba_Man_t * Cba_ManInsertGia( Cba_Man_t * p, Gia_Man_t * pGia ) Cba_NtkInsertGia( pNew, pGia ); Vec_IntFree( vNtkSizes ); return pNew; - } /**Function************************************************************* @@ -368,10 +429,149 @@ Cba_Man_t * Cba_ManBlastTest( Cba_Man_t * p ) SeeAlso [] ***********************************************************************/ +static inline int Abc_NodeIsSeriousGate( Abc_Obj_t * p ) +{ + return Abc_ObjIsNode(p) && (Abc_ObjFaninNum(p) > 0); +} +Vec_Int_t * Cba_ManCountAbc( Cba_Man_t * p, Abc_Ntk_t * pNtk, int fAlwaysAdd ) +{ + Cba_Ntk_t * pCbaNtk; + Abc_Obj_t * pObj, * pFanin; + int i, k, iBox, Count = 0; + Vec_Int_t * vNtkSizes = Vec_IntStart( Cba_ManNtkNum(p) + 1 ); + Vec_Int_t * vDrivenCos = Vec_IntStart( Cba_ManNtkNum(p) + 1 ); + assert( Vec_IntSize(p->vBuf2LeafNtk) == pNtk->nBarBufs2 ); + // assing for each GIA node, the network it belongs to and count nodes for all networks + Abc_NtkForEachPi( pNtk, pObj, i ) + pObj->iTemp = 1; + Abc_NtkForEachNode( pNtk, pObj, i ) + { + if ( Abc_ObjIsBarBuf(pObj) ) + { + if ( Abc_NodeIsSeriousGate(Abc_ObjFanin0(pObj)) ) + Vec_IntAddToEntry( vDrivenCos, Abc_ObjFanin0(pObj)->iTemp, 1 ); + pObj->iTemp = Vec_IntEntry( p->vBuf2LeafNtk, Count++ ); + } + else if ( Abc_NodeIsSeriousGate(pObj) ) + { + pObj->iTemp = Abc_ObjFanin0(pObj)->iTemp; + Abc_ObjForEachFanin( pObj, pFanin, k ) + assert( pObj->iTemp == pFanin->iTemp ); + Vec_IntAddToEntry( vNtkSizes, pObj->iTemp, 1 ); + } + } + assert( Count == pNtk->nBarBufs2 ); + Abc_NtkForEachPo( pNtk, pObj, i ) + { + assert( Abc_ObjFanin0(pObj)->iTemp == 1 ); + pObj->iTemp = Abc_ObjFanin0(pObj)->iTemp; + if ( Abc_NodeIsSeriousGate(Abc_ObjFanin0(pObj)) ) + Vec_IntAddToEntry( vDrivenCos, pObj->iTemp, 1 ); + } + // for each network, count the total number of COs + Cba_ManForEachNtk( p, pCbaNtk, i ) + { + Count = Cba_NtkPiNum(pCbaNtk) + 2 * Cba_NtkPoNum(pCbaNtk) - (fAlwaysAdd ? 0 : Vec_IntEntry(vDrivenCos, i)); + Cba_NtkForEachBox( pCbaNtk, iBox ) + Count += Cba_ObjBoxSize(pCbaNtk, iBox) + Cba_ObjBoxBiNum(pCbaNtk, iBox); + Vec_IntAddToEntry( vNtkSizes, i, Count ); + } + Vec_IntFree( vDrivenCos ); + return vNtkSizes; +} +void Cba_NtkCreateOrConnectFanin( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin, Cba_Ntk_t * p, int iTerm ) +{ + if ( pNtk && Abc_NodeIsSeriousGate(pFanin) ) + { + Vec_IntWriteEntry( &p->vNameIds, pFanin->iTemp, Cba_ObjNameId(p, iTerm) ); + Vec_IntWriteEntry( &p->vFanins, iTerm, pFanin->iTemp ); + } + else + { + assert( !pFanin || Abc_NodeIsConst0(pFanin) || Abc_NodeIsConst1(pFanin) ); + Vec_IntWriteEntry( &p->vTypes, p->nObjs, CBA_OBJ_NODE ); + Vec_IntWriteEntry( &p->vFuncs, p->nObjs, pNtk && Abc_NodeIsConst1(pFanin) ? 2 : 1 ); // assuming elem gates are added first + Vec_IntWriteEntry( &p->vFanins, p->nObjs, Cba_ManHandleBuffer(p->pDesign, -1) ); + Vec_IntWriteEntry( &p->vNameIds, p->nObjs, Cba_ObjNameId(p, iTerm) ); + Vec_IntWriteEntry( &p->vFanins, iTerm, p->nObjs++ ); + } +} +void Cba_NtkPrepareLibrary( Cba_Man_t * p, Mio_Library_t * pLib ) +{ + Mio_Gate_t * pGate; + Mio_Gate_t * pGate0 = Mio_LibraryReadConst0( pLib ); + Mio_Gate_t * pGate1 = Mio_LibraryReadConst1( pLib ); + assert( Abc_NamObjNumMax(p->pFuncs) == 1 ); + Abc_NamStrFindOrAdd( p->pFuncs, Mio_GateReadName(pGate0), NULL ); + Abc_NamStrFindOrAdd( p->pFuncs, Mio_GateReadName(pGate1), NULL ); + assert( Abc_NamObjNumMax(p->pFuncs) == 3 ); + Mio_LibraryForEachGate( pLib, pGate ) + if ( pGate != pGate0 && pGate != pGate1 ) + Abc_NamStrFindOrAdd( p->pFuncs, Mio_GateReadName(pGate), NULL ); + assert( Abc_NamObjNumMax(p->pFuncs) > 1 ); +} +void Cba_NtkInsertNtk( Cba_Man_t * p, Abc_Ntk_t * pNtk ) +{ + Cba_Ntk_t * pCbaNtk, * pRoot = Cba_ManRoot( p ); + Vec_Int_t * vTemp = Vec_IntAlloc( 100 ); + int i, j, k, iBox, iTerm, Count = 0; + Abc_Obj_t * pObj, * pFanin; + assert( Abc_NtkHasMapping(pNtk) ); + Cba_NtkPrepareLibrary( p, (Mio_Library_t *)pNtk->pManFunc ); + + Abc_NtkForEachPi( pNtk, pObj, i ) + pObj->iTemp = Cba_NtkPi( pRoot, i ); + Abc_NtkForEachNode( pNtk, pObj, i ) + { + if ( Abc_ObjIsBarBuf(pObj) ) + { + pCbaNtk = Cba_ManNtk( p, Vec_IntEntry(p->vBuf2RootNtk, Count) ); + iTerm = Vec_IntEntry( p->vBuf2RootObj, Count ); + assert( Cba_ObjIsCo(pCbaNtk, iTerm) ); + Cba_NtkCreateOrConnectFanin( pNtk, Abc_ObjFanin0(pObj), pCbaNtk, iTerm ); + // prepare leaf + pObj->iTemp = Vec_IntEntry( p->vBuf2LeafObj, Count++ ); + } + else if ( Abc_NodeIsSeriousGate(pObj) ) + { + Vec_IntClear( vTemp ); + Abc_ObjForEachFanin( pObj, pFanin, k ) + Vec_IntPush( vTemp, pFanin->iTemp ); + pCbaNtk = Cba_ManNtk( p, pObj->iTemp ); + Vec_IntWriteEntry( &pCbaNtk->vTypes, pCbaNtk->nObjs, CBA_OBJ_NODE ); + Vec_IntWriteEntry( &pCbaNtk->vFuncs, pCbaNtk->nObjs, Abc_NamStrFind(p->pFuncs, Mio_GateReadName((Mio_Gate_t *)pObj->pData)) ); + Vec_IntWriteEntry( &pCbaNtk->vFanins, pCbaNtk->nObjs, Cba_ManHandleArray(p, vTemp) ); + pObj->iTemp = pCbaNtk->nObjs++; + } + } + assert( Count == pNtk->nBarBufs2 ); + Vec_IntFree( vTemp ); + + // create constant 0 drivers for COs without barbufs + Cba_ManForEachNtk( p, pCbaNtk, i ) + { + Cba_NtkForEachBox( pCbaNtk, iBox ) + Cba_BoxForEachBi( pCbaNtk, iBox, iTerm, j ) + if ( Cba_ObjFanin0(pCbaNtk, iTerm) == -1 ) + Cba_NtkCreateOrConnectFanin( NULL, NULL, pCbaNtk, iTerm ); + Cba_NtkForEachPo( pCbaNtk, iTerm, k ) + if ( pCbaNtk != pRoot && Cba_ObjFanin0(pCbaNtk, iTerm) == -1 ) + Cba_NtkCreateOrConnectFanin( NULL, NULL, pCbaNtk, iTerm ); + } + // create node and connect POs + Abc_NtkForEachPo( pNtk, pObj, i ) + Cba_NtkCreateOrConnectFanin( pNtk, Abc_ObjFanin0(pObj), pRoot, Cba_NtkPo(pRoot, i) ); + Cba_ManForEachNtk( p, pCbaNtk, i ) + assert( Cba_NtkObjNum(pCbaNtk) == pCbaNtk->nObjs ); +} void * Cba_ManInsertAbc( Cba_Man_t * p, void * pAbc ) { - Abc_Ntk_t * pNtk = pAbc; - Cba_Man_t * pNew = NULL; + Abc_Ntk_t * pNtk = (Abc_Ntk_t *)pAbc; + Vec_Int_t * vNtkSizes = Cba_ManCountAbc( p, pNtk, 0 ); + Cba_Man_t * pNew = Cba_ManDupStart( p, vNtkSizes ); + Cba_ManRemapBarbufs( pNew, p ); + Cba_NtkInsertNtk( pNew, pNtk ); + Vec_IntFree( vNtkSizes ); return pNew; } |