From 259d53ca3e0305307c5138c6bee876ce842f7a7d Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 19 Dec 2014 22:02:28 -0800 Subject: Simplifying AIG with barrier buffers. --- src/base/abc/abc.h | 2 +- src/base/abc/abcHieGia.c | 149 ++++++++++++++++++++++++++++++++++++++++++++++- src/base/abci/abc.c | 4 +- src/base/ver/verCore.c | 2 +- 4 files changed, 151 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h index b1f3c87f..6e5f3301 100644 --- a/src/base/abc/abc.h +++ b/src/base/abc/abc.h @@ -357,7 +357,7 @@ static inline int Abc_ObjIsLatch( Abc_Obj_t * pObj ) { return pO static inline int Abc_ObjIsBox( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_LATCH || pObj->Type == ABC_OBJ_WHITEBOX || pObj->Type == ABC_OBJ_BLACKBOX; } static inline int Abc_ObjIsWhitebox( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_WHITEBOX;} static inline int Abc_ObjIsBlackbox( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_BLACKBOX;} -static inline int Abc_ObjIsBarBuf( Abc_Obj_t * pObj ) { return Abc_NtkIsLogic(pObj->pNtk) && Vec_IntSize(&pObj->vFanins) == 1 && pObj->pData == NULL; } +static inline int Abc_ObjIsBarBuf( Abc_Obj_t * pObj ) { return Abc_NtkIsLogic(pObj->pNtk) && Abc_ObjIsNode(pObj) && Vec_IntSize(&pObj->vFanins) == 1 && pObj->pData == NULL; } static inline void Abc_ObjBlackboxToWhitebox( Abc_Obj_t * pObj ) { assert( Abc_ObjIsBlackbox(pObj) ); pObj->Type = ABC_OBJ_WHITEBOX; pObj->pNtk->nObjCounts[ABC_OBJ_BLACKBOX]--; pObj->pNtk->nObjCounts[ABC_OBJ_WHITEBOX]++; } // working with fanin/fanout edges diff --git a/src/base/abc/abcHieGia.c b/src/base/abc/abcHieGia.c index 7fc3b75e..ca30459d 100644 --- a/src/base/abc/abcHieGia.c +++ b/src/base/abc/abcHieGia.c @@ -199,6 +199,147 @@ Gia_Man_t * Abc_NtkFlattenHierarchyGia2( Abc_Ntk_t * pNtk ) return pNew; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManPrintBarBufDrivers( Gia_Man_t * p ) +{ + Vec_Int_t * vMap, * vFan, * vCrits; + Gia_Obj_t * pObj; + int i, iFanin, CountCrit[2] = {0}, CountFans[2] = {0}; + // map barbuf drivers into barbuf literals of the first barbuf driven by them + vMap = Vec_IntStart( Gia_ManObjNum(p) ); + vFan = Vec_IntStart( Gia_ManObjNum(p) ); + vCrits = Vec_IntAlloc( 100 ); + Gia_ManForEachObj( p, pObj, i ) + { + // count fanouts + if ( Gia_ObjIsBuf(pObj) || Gia_ObjIsCo(pObj) ) + Vec_IntAddToEntry( vFan, Gia_ObjFaninId0(pObj, i), 1 ); + else if ( Gia_ObjIsAnd(pObj) ) + { + Vec_IntAddToEntry( vFan, Gia_ObjFaninId0(pObj, i), 1 ); + Vec_IntAddToEntry( vFan, Gia_ObjFaninId1(pObj, i), 1 ); + } + // count critical barbufs + if ( Gia_ObjIsBuf(pObj) ) + { + iFanin = Gia_ObjFaninId0( pObj, i ); + if ( iFanin == 0 || Vec_IntEntry(vMap, iFanin) != 0 ) + { + CountCrit[(int)(iFanin != 0)]++; + Vec_IntPush( vCrits, i ); + continue; + } + Vec_IntWriteEntry( vMap, iFanin, Abc_Var2Lit(i, Gia_ObjFaninC0(pObj)) ); + } + } + // check fanouts of the critical barbufs + Gia_ManForEachObjVec( vCrits, p, pObj, i ) + { + assert( Gia_ObjIsBuf(pObj) ); + if ( Vec_IntEntry(vFan, i) == 0 ) + continue; + iFanin = Gia_ObjFaninId0p( p, pObj ); + CountFans[(int)(iFanin != 0)]++; + } + printf( "Detected %d const (out of %d) and %d shared (out of %d) barbufs with fanout.\n", + CountFans[0], CountCrit[0], CountFans[1], CountCrit[1] ); + Vec_IntFree( vMap ); + Vec_IntFree( vFan ); + Vec_IntFree( vCrits ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManPatchBufDriver( Gia_Man_t * p, int iBuf, int iLit0 ) +{ + Gia_Obj_t * pObjBuf = Gia_ManObj( p, iBuf ); + assert( Gia_ObjIsBuf(pObjBuf) ); + assert( Gia_ObjId(p, pObjBuf) > Abc_Lit2Var(iLit0) ); + pObjBuf->iDiff1 = pObjBuf->iDiff0 = Gia_ObjId(p, pObjBuf) - Abc_Lit2Var(iLit0); + pObjBuf->fCompl1 = pObjBuf->fCompl0 = Abc_LitIsCompl(iLit0); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManSweepHierarchy( Gia_Man_t * p ) +{ + Vec_Int_t * vMap = Vec_IntStart( Gia_ManObjNum(p) ); + Gia_Man_t * pNew, * pTemp; + Gia_Obj_t * pObj, * pObjNew, * pObjNewR; + int i, iFanin, CountReals[2] = {0}; + + // duplicate AIG while propagating constants and equivalences + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_ManConst0(p)->Value = 0; + Gia_ManHashAlloc( pNew ); + Gia_ManForEachObj1( p, pObj, i ) + { + if ( Gia_ObjIsBuf(pObj) ) + { + pObj->Value = Gia_ManAppendBuf( pNew, Gia_ObjFanin0Copy(pObj) ); + pObjNew = Gia_ManObj( pNew, Abc_Lit2Var(pObj->Value) ); + iFanin = Gia_ObjFaninId0p( pNew, pObjNew ); + if ( iFanin == 0 ) + { + pObj->Value = Gia_ObjFaninC0(pObjNew); + CountReals[0]++; + Gia_ManPatchBufDriver( pNew, Gia_ObjId(pNew, pObjNew), 0 ); + } + else if ( Vec_IntEntry(vMap, iFanin) ) + { + pObjNewR = Gia_ManObj( pNew, Vec_IntEntry(vMap, iFanin) ); + pObj->Value = Abc_Var2Lit( Vec_IntEntry(vMap, iFanin), Gia_ObjFaninC0(pObjNewR) ^ Gia_ObjFaninC0(pObjNew) ); + CountReals[1]++; + Gia_ManPatchBufDriver( pNew, Gia_ObjId(pNew, pObjNew), 0 ); + } + else + Vec_IntWriteEntry( vMap, iFanin, Gia_ObjId(pNew, pObjNew) ); + } + else if ( Gia_ObjIsAnd(pObj) ) + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + else if ( Gia_ObjIsCi(pObj) ) + pObj->Value = Gia_ManAppendCi( pNew ); + else if ( Gia_ObjIsCo(pObj) ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + } + Gia_ManHashStop( pNew ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); +// printf( "Updated %d const and %d shared.\n", CountReals[0], CountReals[1] ); + Vec_IntFree( vMap ); + return pNew; +} /**Function************************************************************* @@ -325,6 +466,10 @@ Gia_Man_t * Abc_NtkFlattenHierarchyGia( Abc_Ntk_t * pNtk, Vec_Ptr_t ** pvBuffers // 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; } @@ -393,7 +538,7 @@ void Abc_NtkInsertHierarchyGia( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNew, int fVerbose Gia_Man_t * pGia = Abc_NtkFlattenHierarchyGia( pNtk, &vBuffers, 0 ); Abc_Ntk_t * pModel; Abc_Obj_t * pObj; - int i; + int i, k = 0; assert( Gia_ManPiNum(pGia) == Abc_NtkPiNum(pNtk) ); assert( Gia_ManPiNum(pGia) == Abc_NtkPiNum(pNew) ); @@ -416,7 +561,7 @@ void Abc_NtkInsertHierarchyGia( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNew, int fVerbose Abc_NtkForEachPo( pNew, pObj, i ) Abc_NtkPo(pNtk, i)->pCopy = pObj; Abc_NtkForEachBarBuf( pNew, pObj, i ) - ((Abc_Obj_t *)Vec_PtrEntry(vBuffers, i))->pCopy = pObj; + ((Abc_Obj_t *)Vec_PtrEntry(vBuffers, k++))->pCopy = pObj; Vec_PtrFree( vBuffers ); // connect each model diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 2b6bc2be..53a2541d 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -26741,8 +26741,8 @@ int Abc_CommandAbc9Strash( Abc_Frame_t * pAbc, int argc, char ** argv ) else { pTemp = Gia_ManRehash( pAbc->pGia, fAddStrash ); - if ( !Abc_FrameReadFlag("silentmode") ) - printf( "Rehashed the current AIG.\n" ); +// if ( !Abc_FrameReadFlag("silentmode") ) +// printf( "Rehashed the current AIG.\n" ); } if ( !(fCollapse && pAbc->pGia->pAigExtra) ) Gia_ManTransferTiming( pTemp, pAbc->pGia ); diff --git a/src/base/ver/verCore.c b/src/base/ver/verCore.c index c466c4f3..1ac576aa 100644 --- a/src/base/ver/verCore.c +++ b/src/base/ver/verCore.c @@ -2869,7 +2869,7 @@ void Ver_ParsePrintLog( Ver_Man_t * pMan ) ***********************************************************************/ int Ver_ParseAttachBoxes( Ver_Man_t * pMan ) { - int fPrintLog = 1; + int fPrintLog = 0; Abc_Ntk_t * pNtk = NULL; Ver_Bundle_t * pBundle; Vec_Ptr_t * vUndefs; -- cgit v1.2.3