diff options
Diffstat (limited to 'src/aig')
407 files changed, 39237 insertions, 8298 deletions
diff --git a/src/aig/aig/aig.h b/src/aig/aig/aig.h index 45b509dc..385d93b2 100644 --- a/src/aig/aig/aig.h +++ b/src/aig/aig/aig.h @@ -21,6 +21,7 @@ #ifndef __AIG_H__ #define __AIG_H__ + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -37,9 +38,10 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -105,6 +107,7 @@ struct Aig_Man_t_ int nTruePis; // the number of true primary inputs int nTruePos; // the number of true primary outputs int nAsserts; // the number of asserts among POs (asserts are first POs) + int nConstrs; // the number of constraints (model checking only) // AIG node counters int nObjs[AIG_OBJ_VOID];// the number of objects by type int nCreated; // the number of created objects @@ -148,7 +151,8 @@ struct Aig_Man_t_ Vec_Ptr_t * vMapped; Vec_Int_t * vFlopNums; Vec_Int_t * vFlopReprs; - void * pSeqModel; + Abc_Cex_t * pSeqModel; + Vec_Ptr_t * pSeqModelVec; // vector of counter-examples (for sequential miters) Aig_Man_t * pManExdc; Vec_Ptr_t * vOnehots; Aig_Man_t * pManHaig; @@ -217,10 +221,12 @@ static inline Aig_Cut_t * Aig_CutNext( Aig_Cut_t * pCut ) { return //////////////////////////////////////////////////////////////////////// static inline int Aig_IntAbs( int n ) { return (n < 0)? -n : n; } -static inline int Aig_Float2Int( float Val ) { return *((int *)&Val); } -static inline float Aig_Int2Float( int Num ) { return *((float *)&Num); } -static inline int Aig_Base2Log( unsigned n ) { int r; assert( n >= 0 ); if ( n < 2 ) return n; for ( r = 0, n--; n; n >>= 1, r++ ); return r; } -static inline int Aig_Base10Log( unsigned n ) { int r; assert( n >= 0 ); if ( n < 2 ) return n; for ( r = 0, n--; n; n /= 10, r++ ); return r; } +//static inline int Aig_Float2Int( float Val ) { return *((int *)&Val); } +//static inline float Aig_Int2Float( int Num ) { return *((float *)&Num); } +static inline int Aig_Float2Int( float Val ) { union { int x; float y; } v; v.y = Val; return v.x; } +static inline float Aig_Int2Float( int Num ) { union { int x; float y; } v; v.x = Num; return v.y; } +static inline int Aig_Base2Log( unsigned n ) { int r; if ( n < 2 ) return n; for ( r = 0, n--; n; n >>= 1, r++ ); return r; } +static inline int Aig_Base10Log( unsigned n ) { int r; if ( n < 2 ) return n; for ( r = 0, n--; n; n /= 10, r++ ); return r; } static inline char * Aig_UtilStrsav( char * s ) { return s ? strcpy(ABC_ALLOC(char, strlen(s)+1), s) : NULL; } static inline int Aig_BitWordNum( int nBits ) { return (nBits>>5) + ((nBits&31) > 0); } static inline int Aig_TruthWordNum( int nVars ) { return nVars <= 5 ? 1 : (1 << (nVars - 5)); } @@ -261,6 +267,7 @@ static inline int Aig_ManGetCost( Aig_Man_t * p ) { return p->nO static inline int Aig_ManObjNum( Aig_Man_t * p ) { return p->nCreated - p->nDeleted; } static inline int Aig_ManObjNumMax( Aig_Man_t * p ) { return Vec_PtrSize(p->vObjs); } static inline int Aig_ManRegNum( Aig_Man_t * p ) { return p->nRegs; } +static inline int Aig_ManConstrNum( Aig_Man_t * p ) { return p->nConstrs; } static inline Aig_Obj_t * Aig_ManConst0( Aig_Man_t * p ) { return Aig_Not(p->pConst1); } static inline Aig_Obj_t * Aig_ManConst1( Aig_Man_t * p ) { return p->pConst1; } @@ -284,6 +291,7 @@ static inline int Aig_ObjIsNode( Aig_Obj_t * pObj ) { return pObj- static inline int Aig_ObjIsTerm( Aig_Obj_t * pObj ) { return pObj->Type == AIG_OBJ_PI || pObj->Type == AIG_OBJ_PO || pObj->Type == AIG_OBJ_CONST1; } static inline int Aig_ObjIsHash( Aig_Obj_t * pObj ) { return pObj->Type == AIG_OBJ_AND || pObj->Type == AIG_OBJ_EXOR; } static inline int Aig_ObjIsChoice( Aig_Man_t * p, Aig_Obj_t * pObj ) { return p->pEquivs && p->pEquivs[pObj->Id] && pObj->nRefs > 0; } +static inline int Aig_ObjIsCand( Aig_Obj_t * pObj ) { return pObj->Type == AIG_OBJ_PI || pObj->Type == AIG_OBJ_AND || pObj->Type == AIG_OBJ_EXOR; } static inline int Aig_ObjIsMarkA( Aig_Obj_t * pObj ) { return pObj->fMarkA; } static inline void Aig_ObjSetMarkA( Aig_Obj_t * pObj ) { pObj->fMarkA = 1; } @@ -315,6 +323,9 @@ static inline Aig_Obj_t * Aig_ObjChild0Next( Aig_Obj_t * pObj ) { assert( !Aig static inline Aig_Obj_t * Aig_ObjChild1Next( Aig_Obj_t * pObj ) { assert( !Aig_IsComplement(pObj) ); return Aig_ObjFanin1(pObj)? Aig_NotCond((Aig_Obj_t *)Aig_ObjFanin1(pObj)->pNext, Aig_ObjFaninC1(pObj)) : NULL; } static inline void Aig_ObjChild0Flip( Aig_Obj_t * pObj ) { assert( !Aig_IsComplement(pObj) ); pObj->pFanin0 = Aig_Not(pObj->pFanin0); } static inline void Aig_ObjChild1Flip( Aig_Obj_t * pObj ) { assert( !Aig_IsComplement(pObj) ); pObj->pFanin1 = Aig_Not(pObj->pFanin1); } +static inline Aig_Obj_t * Aig_ObjCopy( Aig_Obj_t * pObj ) { assert( !Aig_IsComplement(pObj) ); return (Aig_Obj_t *)pObj->pData; } +static inline void Aig_ObjSetCopy( Aig_Obj_t * pObj, Aig_Obj_t * pCopy ) { assert( !Aig_IsComplement(pObj) ); pObj->pData = pCopy; } +static inline Aig_Obj_t * Aig_ObjRealCopy( Aig_Obj_t * pObj ) { return Aig_NotCond((Aig_Obj_t *)Aig_Regular(pObj)->pData, Aig_IsComplement(pObj));} static inline int Aig_ObjLevel( Aig_Obj_t * pObj ) { assert( !Aig_IsComplement(pObj) ); return pObj->Level; } static inline int Aig_ObjLevelNew( Aig_Obj_t * pObj ) { assert( !Aig_IsComplement(pObj) ); return Aig_ObjFanin1(pObj)? 1 + Aig_ObjIsExor(pObj) + ABC_MAX(Aig_ObjFanin0(pObj)->Level, Aig_ObjFanin1(pObj)->Level) : Aig_ObjFanin0(pObj)->Level; } static inline int Aig_ObjSetLevel( Aig_Obj_t * pObj, int i ) { assert( !Aig_IsComplement(pObj) ); return pObj->Level = i; } @@ -388,22 +399,22 @@ static inline void Aig_ManRecycleMemory( Aig_Man_t * p, Aig_Obj_t * pEntry ) // iterator over the primary inputs #define Aig_ManForEachPi( p, pObj, i ) \ - Vec_PtrForEachEntry( p->vPis, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vPis, pObj, i ) // iterator over the primary outputs #define Aig_ManForEachPo( p, pObj, i ) \ - Vec_PtrForEachEntry( p->vPos, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vPos, pObj, i ) // iterator over the assertions #define Aig_ManForEachAssert( p, pObj, i ) \ - Vec_PtrForEachEntryStart( p->vPos, pObj, i, Aig_ManPoNum(p)-p->nAsserts ) + Vec_PtrForEachEntryStart( Aig_Obj_t *, p->vPos, pObj, i, Aig_ManPoNum(p)-p->nAsserts ) // iterator over all objects, including those currently not used #define Aig_ManForEachObj( p, pObj, i ) \ - Vec_PtrForEachEntry( p->vObjs, pObj, i ) if ( (pObj) == NULL ) {} else + Vec_PtrForEachEntry( Aig_Obj_t *, p->vObjs, pObj, i ) if ( (pObj) == NULL ) {} else // iterator over all nodes #define Aig_ManForEachNode( p, pObj, i ) \ - Vec_PtrForEachEntry( p->vObjs, pObj, i ) if ( (pObj) == NULL || !Aig_ObjIsNode(pObj) ) {} else + Vec_PtrForEachEntry( Aig_Obj_t *, p->vObjs, pObj, i ) if ( (pObj) == NULL || !Aig_ObjIsNode(pObj) ) {} else // iterator over all nodes #define Aig_ManForEachExor( p, pObj, i ) \ - Vec_PtrForEachEntry( p->vObjs, pObj, i ) if ( (pObj) == NULL || !Aig_ObjIsExor(pObj) ) {} else + Vec_PtrForEachEntry( Aig_Obj_t *, p->vObjs, pObj, i ) if ( (pObj) == NULL || !Aig_ObjIsExor(pObj) ) {} else // iterator over the nodes whose IDs are stored in the array #define Aig_ManForEachNodeVec( p, vIds, pObj, i ) \ for ( i = 0; i < Vec_IntSize(vIds) && ((pObj) = Aig_ManObj(p, Vec_IntEntry(vIds,i))); i++ ) @@ -429,16 +440,16 @@ static inline int Aig_ObjFanoutNext( Aig_Man_t * p, int iFan ) { assert(iF // iterator over the primary inputs #define Aig_ManForEachPiSeq( p, pObj, i ) \ - Vec_PtrForEachEntryStop( p->vPis, pObj, i, Aig_ManPiNum(p)-Aig_ManRegNum(p) ) + Vec_PtrForEachEntryStop( Aig_Obj_t *, p->vPis, pObj, i, Aig_ManPiNum(p)-Aig_ManRegNum(p) ) // iterator over the latch outputs #define Aig_ManForEachLoSeq( p, pObj, i ) \ - Vec_PtrForEachEntryStart( p->vPis, pObj, i, Aig_ManPiNum(p)-Aig_ManRegNum(p) ) + Vec_PtrForEachEntryStart( Aig_Obj_t *, p->vPis, pObj, i, Aig_ManPiNum(p)-Aig_ManRegNum(p) ) // iterator over the primary outputs #define Aig_ManForEachPoSeq( p, pObj, i ) \ - Vec_PtrForEachEntryStop( p->vPos, pObj, i, Aig_ManPoNum(p)-Aig_ManRegNum(p) ) + Vec_PtrForEachEntryStop( Aig_Obj_t *, p->vPos, pObj, i, Aig_ManPoNum(p)-Aig_ManRegNum(p) ) // iterator over the latch inputs #define Aig_ManForEachLiSeq( p, pObj, i ) \ - Vec_PtrForEachEntryStart( p->vPos, pObj, i, Aig_ManPoNum(p)-Aig_ManRegNum(p) ) + Vec_PtrForEachEntryStart( Aig_Obj_t *, p->vPos, pObj, i, Aig_ManPoNum(p)-Aig_ManRegNum(p) ) // iterator over the latch input and outputs #define Aig_ManForEachLiLoSeq( p, pObjLi, pObjLo, k ) \ for ( k = 0; (k < Aig_ManRegNum(p)) && (((pObjLi) = Aig_ManLi(p, k)), 1) \ @@ -475,10 +486,13 @@ extern Aig_Obj_t * Aig_Compose( Aig_Man_t * p, Aig_Obj_t * pRoot, Aig_Obj_t extern void Aig_ObjCollectCut( Aig_Obj_t * pRoot, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vNodes ); extern int Aig_ObjCollectSuper( Aig_Obj_t * pObj, Vec_Ptr_t * vSuper ); /*=== aigDup.c ==========================================================*/ +extern Aig_Obj_t * Aig_ManDupSimpleDfs_rec( Aig_Man_t * pNew, Aig_Man_t * p, Aig_Obj_t * pObj ); extern Aig_Man_t * Aig_ManDupSimple( Aig_Man_t * p ); +extern Aig_Man_t * Aig_ManDupSimpleWithHints( Aig_Man_t * p, Vec_Int_t * vHints ); extern Aig_Man_t * Aig_ManDupSimpleDfs( Aig_Man_t * p ); extern Aig_Man_t * Aig_ManDupSimpleDfsPart( Aig_Man_t * p, Vec_Ptr_t * vPis, Vec_Ptr_t * vPos ); extern Aig_Man_t * Aig_ManDupOrdered( Aig_Man_t * p ); +extern Aig_Man_t * Aig_ManDupCof( Aig_Man_t * p, int iInput, int Value ); extern Aig_Man_t * Aig_ManDupTrim( Aig_Man_t * p ); extern Aig_Man_t * Aig_ManDupExor( Aig_Man_t * p ); extern Aig_Man_t * Aig_ManDupDfs( Aig_Man_t * p ); @@ -503,7 +517,8 @@ extern Aig_Man_t * Aig_ManFrames( Aig_Man_t * pAig, int nFs, int fInit, int extern Aig_Man_t * Aig_ManStart( int nNodesMax ); extern Aig_Man_t * Aig_ManStartFrom( Aig_Man_t * p ); extern Aig_Man_t * Aig_ManExtractMiter( Aig_Man_t * p, Aig_Obj_t * pNode1, Aig_Obj_t * pNode2 ); -extern ABC_DLL void Aig_ManStop( Aig_Man_t * p ); +extern void Aig_ManStop( Aig_Man_t * p ); +extern void Aig_ManStopP( Aig_Man_t ** p ); extern int Aig_ManCleanup( Aig_Man_t * p ); extern int Aig_ManAntiCleanup( Aig_Man_t * p ); extern int Aig_ManPiCleanup( Aig_Man_t * p ); @@ -512,6 +527,7 @@ extern void Aig_ManPrintStats( Aig_Man_t * p ); extern void Aig_ManReportImprovement( Aig_Man_t * p, Aig_Man_t * pNew ); extern void Aig_ManSetRegNum( Aig_Man_t * p, int nRegs ); extern void Aig_ManFlipFirstPo( Aig_Man_t * p ); +extern void * Aig_ManReleaseData( Aig_Man_t * p ); /*=== aigMem.c ==========================================================*/ extern void Aig_ManStartMemory( Aig_Man_t * p ); extern void Aig_ManStopMemory( Aig_Man_t * p ); @@ -620,6 +636,7 @@ extern Aig_Man_t * Aig_ManConstReduce( Aig_Man_t * p, int fVerbose ); /*=== aigUtil.c =========================================================*/ extern unsigned Aig_PrimeCudd( unsigned p ); extern void Aig_ManIncrementTravId( Aig_Man_t * p ); +extern char * Aig_TimeStamp(); extern int Aig_ManHasNoGaps( Aig_Man_t * p ); extern int Aig_ManLevels( Aig_Man_t * p ); extern void Aig_ManResetRefs( Aig_Man_t * p ); @@ -650,6 +667,10 @@ extern unsigned Aig_ManRandom( int fReset ); extern void Aig_ManRandomInfo( Vec_Ptr_t * vInfo, int iInputStart, int iWordStart, int iWordStop ); extern void Aig_NodeUnionLists( Vec_Ptr_t * vArr1, Vec_Ptr_t * vArr2, Vec_Ptr_t * vArr ); extern void Aig_NodeIntersectLists( Vec_Ptr_t * vArr1, Vec_Ptr_t * vArr2, Vec_Ptr_t * vArr ); +extern void Aig_ManSetPhase( Aig_Man_t * pAig ); +extern Vec_Ptr_t * Aig_ManMuxesCollect( Aig_Man_t * pAig ); +extern void Aig_ManMuxesDeref( Aig_Man_t * pAig, Vec_Ptr_t * vMuxes ); +extern void Aig_ManMuxesRef( Aig_Man_t * pAig, Vec_Ptr_t * vMuxes ); /*=== aigWin.c =========================================================*/ extern void Aig_ManFindCut( Aig_Obj_t * pRoot, Vec_Ptr_t * vFront, Vec_Ptr_t * vVisited, int nSizeLimit, int nFanoutLimit ); @@ -676,9 +697,11 @@ extern char * Aig_MmStepEntryFetch( Aig_MmStep_t * p, int nBytes ); extern void Aig_MmStepEntryRecycle( Aig_MmStep_t * p, char * pEntry, int nBytes ); extern int Aig_MmStepReadMemUsage( Aig_MmStep_t * p ); -#ifdef __cplusplus -} -#endif + + +ABC_NAMESPACE_HEADER_END + + #endif diff --git a/src/aig/aig/aigCanon.c b/src/aig/aig/aigCanon.c index 4f241842..706a9c61 100644 --- a/src/aig/aig/aigCanon.c +++ b/src/aig/aig/aigCanon.c @@ -21,6 +21,10 @@ #include "aig.h" #include "kit.h" #include "bdc.h" +#include "ioa.h" + +ABC_NAMESPACE_IMPL_START + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// @@ -277,7 +281,7 @@ void Aig_RManStop( Aig_RMan_t * p ) ***********************************************************************/ void Aig_RManQuit() { - extern void Ioa_WriteAiger( Aig_Man_t * pMan, char * pFileName, int fWriteSymbols, int fCompact ); +// extern void Ioa_WriteAiger( Aig_Man_t * pMan, char * pFileName, int fWriteSymbols, int fCompact ); char Buffer[20]; if ( s_pRMan == NULL ) return; @@ -537,7 +541,7 @@ unsigned Aig_RManSemiCanonicize( unsigned * pOut, unsigned * pIn, int nVars, cha ***********************************************************************/ static inline Aig_Obj_t * Bdc_FunCopyHop( Bdc_Fun_t * pObj ) -{ return Aig_NotCond( Bdc_FuncCopy(Bdc_Regular(pObj)), Bdc_IsComplement(pObj) ); } +{ return Aig_NotCond( (Aig_Obj_t *)Bdc_FuncCopy(Bdc_Regular(pObj)), Bdc_IsComplement(pObj) ); } /**Function************************************************************* @@ -692,3 +696,5 @@ Extra_PrintBinary( stdout, s_pRMan->pTruth, 1<<nVars ); printf( "\n\n" ); //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/aig/aigCheck.c b/src/aig/aig/aigCheck.c index 4cfdaaf1..298c5595 100644 --- a/src/aig/aig/aigCheck.c +++ b/src/aig/aig/aigCheck.c @@ -20,6 +20,9 @@ #include "aig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -161,3 +164,5 @@ void Aig_ManCheckPhase( Aig_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/aig/aigCuts.c b/src/aig/aig/aigCuts.c index dc677269..6de19484 100644 --- a/src/aig/aig/aigCuts.c +++ b/src/aig/aig/aigCuts.c @@ -21,6 +21,9 @@ #include "aig.h" #include "kit.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -207,7 +210,7 @@ static inline float Aig_CutFindCost2( Aig_ManCut_t * p, Aig_Cut_t * pCut ) /**Function************************************************************* - Synopsis [Returns the next ABC_FREE cut to use.] + Synopsis [Returns the next free cut to use.] Description [] @@ -667,3 +670,5 @@ Aig_ManCut_t * Aig_ComputeCuts( Aig_Man_t * pAig, int nCutsMax, int nLeafMax, in //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/aig/aigDfs.c b/src/aig/aig/aigDfs.c index dfc35c83..6b30611a 100644 --- a/src/aig/aig/aigDfs.c +++ b/src/aig/aig/aigDfs.c @@ -21,6 +21,9 @@ #include "aig.h" #include "tim.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -76,15 +79,15 @@ int Aig_ManVerifyTopoOrder( Aig_Man_t * p ) { if ( p->pManTime ) { - iBox = Tim_ManBoxForCi( p->pManTime, Aig_ObjPioNum(pObj) ); + iBox = Tim_ManBoxForCi( (Tim_Man_t *)p->pManTime, Aig_ObjPioNum(pObj) ); if ( iBox >= 0 ) // this is not a true PI { - iTerm1 = Tim_ManBoxInputFirst( p->pManTime, iBox ); - nTerms = Tim_ManBoxInputNum( p->pManTime, iBox ); + iTerm1 = Tim_ManBoxInputFirst( (Tim_Man_t *)p->pManTime, iBox ); + nTerms = Tim_ManBoxInputNum( (Tim_Man_t *)p->pManTime, iBox ); for ( k = 0; k < nTerms; k++ ) { pNext = Aig_ManPo( p, iTerm1 + k ); - assert( Tim_ManBoxForCo( p->pManTime, Aig_ObjPioNum(pNext) ) == iBox ); + assert( Tim_ManBoxForCo( (Tim_Man_t *)p->pManTime, Aig_ObjPioNum(pNext) ) == iBox ); if ( !Aig_ObjIsTravIdCurrent(p,pNext) ) { printf( "Box %d has input %d that is not in a topological order.\n", iBox, pNext->Id ); @@ -276,7 +279,10 @@ Vec_Ptr_t * Aig_ManDfsNodes( Aig_Man_t * p, Aig_Obj_t ** ppNodes, int nNodes ) // go through the nodes vNodes = Vec_PtrAlloc( Aig_ManNodeNum(p) ); for ( i = 0; i < nNodes; i++ ) - Aig_ManDfs_rec( p, ppNodes[i], vNodes ); + if ( Aig_ObjIsPo(ppNodes[i]) ) + Aig_ManDfs_rec( p, Aig_ObjFanin0(ppNodes[i]), vNodes ); + else + Aig_ManDfs_rec( p, ppNodes[i], vNodes ); return vNodes; } @@ -435,11 +441,11 @@ void Aig_ManChoiceLevel_rec( Aig_Man_t * p, Aig_Obj_t * pObj ) { if ( p->pManTime ) { - iBox = Tim_ManBoxForCi( p->pManTime, Aig_ObjPioNum(pObj) ); + iBox = Tim_ManBoxForCi( (Tim_Man_t *)p->pManTime, Aig_ObjPioNum(pObj) ); if ( iBox >= 0 ) // this is not a true PI { - iTerm1 = Tim_ManBoxInputFirst( p->pManTime, iBox ); - nTerms = Tim_ManBoxInputNum( p->pManTime, iBox ); + iTerm1 = Tim_ManBoxInputFirst( (Tim_Man_t *)p->pManTime, iBox ); + nTerms = Tim_ManBoxInputNum( (Tim_Man_t *)p->pManTime, iBox ); for ( i = 0; i < nTerms; i++ ) { pNext = Aig_ManPo(p, iTerm1 + i); @@ -815,7 +821,7 @@ Aig_Obj_t * Aig_Transfer( Aig_Man_t * pSour, Aig_Man_t * pDest, Aig_Obj_t * pRoo Aig_Transfer_rec( pDest, Aig_Regular(pRoot) ); // clear the markings Aig_ConeUnmark_rec( Aig_Regular(pRoot) ); - return Aig_NotCond( Aig_Regular(pRoot)->pData, Aig_IsComplement(pRoot) ); + return Aig_NotCond( (Aig_Obj_t *)Aig_Regular(pRoot)->pData, Aig_IsComplement(pRoot) ); } /**Function************************************************************* @@ -869,7 +875,7 @@ Aig_Obj_t * Aig_Compose( Aig_Man_t * p, Aig_Obj_t * pRoot, Aig_Obj_t * pFunc, in Aig_Compose_rec( p, Aig_Regular(pRoot), pFunc, Aig_ManPi(p, iVar) ); // clear the markings Aig_ConeUnmark_rec( Aig_Regular(pRoot) ); - return Aig_NotCond( Aig_Regular(pRoot)->pData, Aig_IsComplement(pRoot) ); + return Aig_NotCond( (Aig_Obj_t *)Aig_Regular(pRoot)->pData, Aig_IsComplement(pRoot) ); } /**Function************************************************************* @@ -914,7 +920,7 @@ void Aig_ObjCollectCut( Aig_Obj_t * pRoot, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vNod int i; // collect and mark the leaves Vec_PtrClear( vNodes ); - Vec_PtrForEachEntry( vLeaves, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vLeaves, pObj, i ) { assert( pObj->fMarkA == 0 ); pObj->fMarkA = 1; @@ -924,9 +930,9 @@ void Aig_ObjCollectCut( Aig_Obj_t * pRoot, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vNod // collect and mark the nodes Aig_ObjCollectCut_rec( pRoot, vNodes ); // clean the nodes - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) pObj->fMarkA = 0; - Vec_PtrForEachEntry( vLeaves, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vLeaves, pObj, i ) pObj->fMarkA = 0; } @@ -998,7 +1004,7 @@ int Aig_ObjCollectSuper( Aig_Obj_t * pObj, Vec_Ptr_t * vSuper ) RetValue = Aig_ObjCollectSuper_rec( pObj, pObj, vSuper ); assert( Vec_PtrSize(vSuper) > 1 ); // unmark the visited nodes - Vec_PtrForEachEntry( vSuper, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vSuper, pObj, i ) Aig_Regular(pObj)->fMarkA = 0; // if we found the node and its complement in the same implication supergate, // return empty set of nodes (meaning that we should use constant-0 node) @@ -1012,3 +1018,5 @@ int Aig_ObjCollectSuper( Aig_Obj_t * pObj, Vec_Ptr_t * vSuper ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/aig/aigDup.c b/src/aig/aig/aigDup.c index 90579f59..91531093 100644 --- a/src/aig/aig/aigDup.c +++ b/src/aig/aig/aigDup.c @@ -21,6 +21,9 @@ #include "saig.h" #include "tim.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -52,6 +55,7 @@ Aig_Man_t * Aig_ManDupSimple( Aig_Man_t * p ) pNew->pName = Aig_UtilStrsav( p->pName ); pNew->pSpec = Aig_UtilStrsav( p->pSpec ); pNew->nAsserts = p->nAsserts; + pNew->nConstrs = p->nConstrs; if ( p->vFlopNums ) pNew->vFlopNums = Vec_IntDup( p->vFlopNums ); // create the PIs @@ -102,6 +106,57 @@ Aig_Man_t * Aig_ManDupSimple( Aig_Man_t * p ) /**Function************************************************************* + Synopsis [Derives AIG with hints.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Aig_ManDupSimpleWithHints( Aig_Man_t * p, Vec_Int_t * vHints ) +{ + Aig_Man_t * pNew; + Aig_Obj_t * pObj; + int i, Entry; + assert( p->pManHaig == NULL || Aig_ManBufNum(p) == 0 ); + assert( p->nAsserts == 0 || p->nConstrs == 0 ); + // create the new manager + pNew = Aig_ManStart( Aig_ManObjNumMax(p) ); + pNew->pName = Aig_UtilStrsav( p->pName ); + // create the PIs + Aig_ManCleanData( p ); + Aig_ManConst1(p)->pData = Aig_ManConst1(pNew); + Aig_ManForEachPi( p, pObj, i ) + { + pObj->pData = Aig_ObjCreatePi( pNew ); + Entry = Vec_IntEntry( vHints, Aig_ObjId(pObj) ); + if ( Entry == 0 || Entry == 1 ) + pObj->pData = Aig_NotCond( Aig_ManConst1(pNew), Entry ); // restrict to the complement of constraint!!! + } + // duplicate internal nodes + Aig_ManForEachNode( p, pObj, i ) + { + pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + Entry = Vec_IntEntry( vHints, Aig_ObjId(pObj) ); + if ( Entry == 0 || Entry == 1 ) + pObj->pData = Aig_NotCond( Aig_ManConst1(pNew), Entry ); // restrict to the complement of constraint!!! + } + // add the POs + Aig_ManForEachPo( p, pObj, i ) + pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) ); + Aig_ManCleanup( pNew ); + Aig_ManSetRegNum( pNew, Aig_ManRegNum(p) ); + // check the resulting network + if ( !Aig_ManCheck(pNew) ) + printf( "Llb_ManDeriveAigWithHints(): The check has failed.\n" ); + return pNew; +} + + +/**Function************************************************************* + Synopsis [Duplicates the AIG manager recursively.] Description [] @@ -114,14 +169,14 @@ Aig_Man_t * Aig_ManDupSimple( Aig_Man_t * p ) Aig_Obj_t * Aig_ManDupSimpleDfs_rec( Aig_Man_t * pNew, Aig_Man_t * p, Aig_Obj_t * pObj ) { if ( pObj->pData ) - return pObj->pData; + return (Aig_Obj_t *)pObj->pData; Aig_ManDupSimpleDfs_rec( pNew, p, Aig_ObjFanin0(pObj) ); if ( Aig_ObjIsBuf(pObj) ) - return pObj->pData = Aig_ObjChild0Copy(pObj); + return (Aig_Obj_t *)(pObj->pData = Aig_ObjChild0Copy(pObj)); Aig_ManDupSimpleDfs_rec( pNew, p, Aig_ObjFanin1(pObj) ); pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); - Aig_Regular(pObj->pData)->pHaig = pObj->pHaig; - return pObj->pData; + Aig_Regular((Aig_Obj_t *)pObj->pData)->pHaig = pObj->pHaig; + return (Aig_Obj_t *)pObj->pData; } /**Function************************************************************* @@ -151,6 +206,7 @@ Aig_Man_t * Aig_ManDupSimpleDfs( Aig_Man_t * p ) pNew->pName = Aig_UtilStrsav( p->pName ); pNew->pSpec = Aig_UtilStrsav( p->pSpec ); pNew->nAsserts = p->nAsserts; + pNew->nConstrs = p->nConstrs; if ( p->vFlopNums ) pNew->vFlopNums = Vec_IntDup( p->vFlopNums ); // create the PIs @@ -213,10 +269,10 @@ Aig_Man_t * Aig_ManDupSimpleDfsPart( Aig_Man_t * p, Vec_Ptr_t * vPis, Vec_Ptr_t // create the PIs Aig_ManCleanData( p ); Aig_ManConst1(p)->pData = Aig_ManConst1( pNew ); - Vec_PtrForEachEntry( vPis, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vPis, pObj, i ) pObj->pData = Aig_ObjCreatePi( pNew ); // duplicate internal nodes - Vec_PtrForEachEntry( vPos, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vPos, pObj, i ) { pObjNew = Aig_ManDupSimpleDfs_rec( pNew, p, Aig_ObjFanin0(pObj) ); pObjNew = Aig_NotCond( pObjNew, Aig_ObjFaninC0(pObj) ); @@ -250,6 +306,7 @@ Aig_Man_t * Aig_ManDupOrdered( Aig_Man_t * p ) pNew->pName = Aig_UtilStrsav( p->pName ); pNew->pSpec = Aig_UtilStrsav( p->pSpec ); pNew->nAsserts = p->nAsserts; + pNew->nConstrs = p->nConstrs; if ( p->vFlopNums ) pNew->vFlopNums = Vec_IntDup( p->vFlopNums ); // create the PIs @@ -289,7 +346,7 @@ Aig_Man_t * Aig_ManDupOrdered( Aig_Man_t * p ) Aig_ManSetRegNum( pNew, Aig_ManRegNum(p) ); // duplicate the timing manager if ( p->pManTime ) - pNew->pManTime = Tim_ManDup( p->pManTime, 0 ); + pNew->pManTime = Tim_ManDup( (Tim_Man_t *)p->pManTime, 0 ); // pass the HAIG manager if ( p->pManHaig != NULL ) { @@ -301,6 +358,86 @@ Aig_Man_t * Aig_ManDupOrdered( Aig_Man_t * p ) printf( "Aig_ManDupOrdered(): The check has failed.\n" ); return pNew; } + +/**Function************************************************************* + + Synopsis [Duplicates the AIG manager.] + + Description [Orders nodes as follows: PIs, ANDs, POs.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Aig_ManDupCof( Aig_Man_t * p, int iInput, int Value ) +{ + Aig_Man_t * pNew; + Aig_Obj_t * pObj, * pObjNew; + int i; + assert( p->pManTime == NULL ); + assert( p->pManHaig == NULL || Aig_ManBufNum(p) == 0 ); + // create the new manager + pNew = Aig_ManStart( Aig_ManObjNumMax(p) ); + pNew->pName = Aig_UtilStrsav( p->pName ); + pNew->pSpec = Aig_UtilStrsav( p->pSpec ); + pNew->nAsserts = p->nAsserts; + pNew->nConstrs = p->nConstrs; + if ( p->vFlopNums ) + pNew->vFlopNums = Vec_IntDup( p->vFlopNums ); + // create the PIs + Aig_ManCleanData( p ); + Aig_ManConst1(p)->pData = Aig_ManConst1(pNew); + Aig_ManConst1(pNew)->pHaig = Aig_ManConst1(p)->pHaig; + Aig_ManForEachPi( p, pObj, i ) + { + if ( i == iInput ) + pObjNew = Value ? Aig_ManConst1(pNew) : Aig_ManConst0(pNew); + else + { + pObjNew = Aig_ObjCreatePi( pNew ); + pObjNew->pHaig = pObj->pHaig; + pObjNew->Level = pObj->Level; + } + pObj->pData = pObjNew; + } + // duplicate internal nodes + Aig_ManForEachObj( p, pObj, i ) + if ( Aig_ObjIsBuf(pObj) ) + { + pObjNew = Aig_ObjChild0Copy(pObj); + Aig_Regular(pObjNew)->pHaig = pObj->pHaig; + pObj->pData = pObjNew; + } + else if ( Aig_ObjIsNode(pObj) ) + { + pObjNew = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + Aig_Regular(pObjNew)->pHaig = pObj->pHaig; + pObj->pData = pObjNew; + } + // add the POs + Aig_ManForEachPo( p, pObj, i ) + { + pObjNew = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) ); + pObjNew->pHaig = pObj->pHaig; + pObj->pData = pObjNew; + } +// assert( Aig_ManBufNum(p) != 0 || Aig_ManNodeNum(p) == Aig_ManNodeNum(pNew) ); + Aig_ManCleanup( pNew ); + Aig_ManSetRegNum( pNew, Aig_ManRegNum(p) ); + // pass the HAIG manager + if ( p->pManHaig != NULL ) + { + pNew->pManHaig = p->pManHaig; + p->pManHaig = NULL; + } + // check the resulting network + if ( !Aig_ManCheck(pNew) ) + printf( "Aig_ManDupSimple(): The check has failed.\n" ); + return pNew; +} + + /**Function************************************************************* Synopsis [Duplicates the AIG manager.] @@ -321,6 +458,7 @@ Aig_Man_t * Aig_ManDupTrim( Aig_Man_t * p ) pNew = Aig_ManStart( Aig_ManObjNumMax(p) ); pNew->pName = Aig_UtilStrsav( p->pName ); pNew->pSpec = Aig_UtilStrsav( p->pSpec ); + pNew->nConstrs = p->nConstrs; // create the PIs Aig_ManCleanData( p ); // duplicate internal nodes @@ -370,6 +508,7 @@ Aig_Man_t * Aig_ManDupExor( Aig_Man_t * p ) pNew->pName = Aig_UtilStrsav( p->pName ); pNew->pSpec = Aig_UtilStrsav( p->pSpec ); pNew->nAsserts = p->nAsserts; + pNew->nConstrs = p->nConstrs; if ( p->vFlopNums ) pNew->vFlopNums = Vec_IntDup( p->vFlopNums ); // create the PIs @@ -407,7 +546,7 @@ Aig_Man_t * Aig_ManDupExor( Aig_Man_t * p ) Aig_ManSetRegNum( pNew, Aig_ManRegNum(p) ); // duplicate the timing manager if ( p->pManTime ) - pNew->pManTime = Tim_ManDup( p->pManTime, 0 ); + pNew->pManTime = Tim_ManDup( (Tim_Man_t *)p->pManTime, 0 ); // check the resulting network if ( !Aig_ManCheck(pNew) ) printf( "Aig_ManDupExor(): The check has failed.\n" ); @@ -429,12 +568,12 @@ Aig_Obj_t * Aig_ManDupDfs_rec( Aig_Man_t * pNew, Aig_Man_t * p, Aig_Obj_t * pObj { Aig_Obj_t * pObjNew, * pEquivNew = NULL; if ( pObj->pData ) - return pObj->pData; + return (Aig_Obj_t *)pObj->pData; if ( p->pEquivs && Aig_ObjEquiv(p, pObj) ) pEquivNew = Aig_ManDupDfs_rec( pNew, p, Aig_ObjEquiv(p, pObj) ); Aig_ManDupDfs_rec( pNew, p, Aig_ObjFanin0(pObj) ); if ( Aig_ObjIsBuf(pObj) ) - return pObj->pData = Aig_ObjChild0Copy(pObj); + return (Aig_Obj_t *)(pObj->pData = Aig_ObjChild0Copy(pObj)); Aig_ManDupDfs_rec( pNew, p, Aig_ObjFanin1(pObj) ); pObjNew = Aig_Oper( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj), Aig_ObjType(pObj) ); if ( p->pManHaig != NULL ) @@ -448,7 +587,7 @@ Aig_Obj_t * Aig_ManDupDfs_rec( Aig_Man_t * pNew, Aig_Man_t * p, Aig_Obj_t * pObj if ( pNew->pReprs ) pNew->pReprs[Aig_Regular(pEquivNew)->Id] = Aig_Regular(pObjNew); } - return pObj->pData = pObjNew; + return (Aig_Obj_t *)(pObj->pData = pObjNew); } /**Function************************************************************* @@ -472,6 +611,7 @@ Aig_Man_t * Aig_ManDupDfs( Aig_Man_t * p ) pNew->pName = Aig_UtilStrsav( p->pName ); pNew->pSpec = Aig_UtilStrsav( p->pSpec ); pNew->nAsserts = p->nAsserts; + pNew->nConstrs = p->nConstrs; if ( p->vFlopNums ) pNew->vFlopNums = Vec_IntDup( p->vFlopNums ); // duplicate representation of choice nodes @@ -508,7 +648,7 @@ Aig_Man_t * Aig_ManDupDfs( Aig_Man_t * p ) Aig_ManSetRegNum( pNew, Aig_ManRegNum(p) ); // duplicate the timing manager if ( p->pManTime ) - pNew->pManTime = Tim_ManDup( p->pManTime, 0 ); + pNew->pManTime = Tim_ManDup( (Tim_Man_t *)p->pManTime, 0 ); // pass the HAIG manager if ( p->pManHaig != NULL ) { @@ -567,7 +707,7 @@ Aig_Obj_t * Aig_ManDupDfsGuided_rec( Aig_Man_t * pNew, Aig_Man_t * p, Aig_Obj_t { Aig_Obj_t * pObjNew, * pEquivNew = NULL; if ( pObj->pData ) - return pObj->pData; + return (Aig_Obj_t *)pObj->pData; if ( Aig_ObjIsPi(pObj) ) return NULL; if ( p->pEquivs && Aig_ObjEquiv(p, pObj) ) @@ -575,7 +715,7 @@ Aig_Obj_t * Aig_ManDupDfsGuided_rec( Aig_Man_t * pNew, Aig_Man_t * p, Aig_Obj_t if ( !Aig_ManDupDfsGuided_rec( pNew, p, Aig_ObjFanin0(pObj) ) ) return NULL; if ( Aig_ObjIsBuf(pObj) ) - return pObj->pData = Aig_ObjChild0Copy(pObj); + return (Aig_Obj_t *)(pObj->pData = Aig_ObjChild0Copy(pObj)); if ( !Aig_ManDupDfsGuided_rec( pNew, p, Aig_ObjFanin1(pObj) ) ) return NULL; pObjNew = Aig_Oper( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj), Aig_ObjType(pObj) ); @@ -588,7 +728,7 @@ Aig_Obj_t * Aig_ManDupDfsGuided_rec( Aig_Man_t * pNew, Aig_Man_t * p, Aig_Obj_t if ( pNew->pReprs ) pNew->pReprs[Aig_Regular(pEquivNew)->Id] = Aig_Regular(pObjNew); } - return pObj->pData = pObjNew; + return (Aig_Obj_t *)(pObj->pData = pObjNew); } /**Function************************************************************* @@ -612,6 +752,7 @@ Aig_Man_t * Aig_ManDupDfsGuided( Aig_Man_t * p, Vec_Ptr_t * vPios ) pNew->pName = Aig_UtilStrsav( p->pName ); pNew->pSpec = Aig_UtilStrsav( p->pSpec ); pNew->nAsserts = p->nAsserts; + pNew->nConstrs = p->nConstrs; if ( p->vFlopNums ) pNew->vFlopNums = Vec_IntDup( p->vFlopNums ); // duplicate representation of choice nodes @@ -630,7 +771,7 @@ Aig_Man_t * Aig_ManDupDfsGuided( Aig_Man_t * p, Vec_Ptr_t * vPios ) // duplicate internal nodes Aig_ManConst1(p)->pData = Aig_ManConst1(pNew); Aig_ManConst1(pNew)->pHaig = Aig_ManConst1(p)->pHaig; - Vec_PtrForEachEntry( vPios, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vPios, pObj, i ) { if ( Aig_ObjIsPi(pObj) ) { @@ -654,7 +795,7 @@ Aig_Man_t * Aig_ManDupDfsGuided( Aig_Man_t * p, Vec_Ptr_t * vPios ) Aig_ManSetRegNum( pNew, Aig_ManRegNum(p) ); // duplicate the timing manager if ( p->pManTime ) - pNew->pManTime = Tim_ManDup( p->pManTime, 0 ); + pNew->pManTime = Tim_ManDup( (Tim_Man_t *)p->pManTime, 0 ); // check the resulting network if ( !Aig_ManCheck(pNew) ) printf( "Aig_ManDupDfs(): The check has failed.\n" ); @@ -683,6 +824,7 @@ Aig_Man_t * Aig_ManDupLevelized( Aig_Man_t * p ) pNew->pName = Aig_UtilStrsav( p->pName ); pNew->pSpec = Aig_UtilStrsav( p->pSpec ); pNew->nAsserts = p->nAsserts; + pNew->nConstrs = p->nConstrs; if ( p->vFlopNums ) pNew->vFlopNums = Vec_IntDup( p->vFlopNums ); // duplicate representation of choice nodes @@ -708,7 +850,7 @@ Aig_Man_t * Aig_ManDupLevelized( Aig_Man_t * p ) } // duplicate internal nodes vLevels = Aig_ManLevelize( p ); - Vec_VecForEachEntry( vLevels, pObj, i, k ) + Vec_VecForEachEntry( Aig_Obj_t *, vLevels, pObj, i, k ) { pObjNew = Aig_Oper( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj), Aig_ObjType(pObj) ); Aig_Regular(pObjNew)->pHaig = pObj->pHaig; @@ -728,7 +870,7 @@ Aig_Man_t * Aig_ManDupLevelized( Aig_Man_t * p ) Aig_ManSetRegNum( pNew, Aig_ManRegNum(p) ); // duplicate the timing manager if ( p->pManTime ) - pNew->pManTime = Tim_ManDup( p->pManTime, 0 ); + pNew->pManTime = Tim_ManDup( (Tim_Man_t *)p->pManTime, 0 ); // check the resulting network if ( !Aig_ManCheck(pNew) ) printf( "Aig_ManDupLevelized(): The check has failed.\n" ); @@ -787,8 +929,8 @@ static inline Aig_Obj_t * Aig_ObjGetRepres( Aig_Man_t * p, Aig_Obj_t * pObj ) { Aig_Obj_t * pRepr; if ( (pRepr = Aig_ObjRepr(p, pObj)) ) - return Aig_NotCond( pRepr->pData, pObj->fPhase ^ pRepr->fPhase ); - return pObj->pData; + return Aig_NotCond( (Aig_Obj_t *)pRepr->pData, pObj->fPhase ^ pRepr->fPhase ); + return (Aig_Obj_t *)pObj->pData; } static inline Aig_Obj_t * Aig_ObjChild0Repres( Aig_Man_t * p, Aig_Obj_t * pObj ) { return Aig_NotCond( Aig_ObjGetRepres(p, Aig_ObjFanin0(pObj)), Aig_ObjFaninC0(pObj) ); } static inline Aig_Obj_t * Aig_ObjChild1Repres( Aig_Man_t * p, Aig_Obj_t * pObj ) { return Aig_NotCond( Aig_ObjGetRepres(p, Aig_ObjFanin1(pObj)), Aig_ObjFaninC1(pObj) ); } @@ -813,6 +955,7 @@ Aig_Man_t * Aig_ManDupRepres( Aig_Man_t * p ) pNew = Aig_ManStart( Aig_ManObjNumMax(p) ); pNew->pName = Aig_UtilStrsav( p->pName ); pNew->pSpec = Aig_UtilStrsav( p->pSpec ); + pNew->nConstrs = p->nConstrs; if ( p->vFlopNums ) pNew->vFlopNums = Vec_IntDup( p->vFlopNums ); // map the const and primary inputs @@ -855,15 +998,15 @@ Aig_Obj_t * Aig_ManDupRepres_rec( Aig_Man_t * pNew, Aig_Man_t * p, Aig_Obj_t * p { Aig_Obj_t * pRepr; if ( pObj->pData ) - return pObj->pData; + return (Aig_Obj_t *)pObj->pData; if ( (pRepr = Aig_ObjRepr(p, pObj)) ) { Aig_ManDupRepres_rec( pNew, p, pRepr ); - return pObj->pData = Aig_NotCond( pRepr->pData, pRepr->fPhase ^ pObj->fPhase ); + return (Aig_Obj_t *)(pObj->pData = Aig_NotCond( (Aig_Obj_t *)pRepr->pData, pRepr->fPhase ^ pObj->fPhase )); } Aig_ManDupRepres_rec( pNew, p, Aig_ObjFanin0(pObj) ); Aig_ManDupRepres_rec( pNew, p, Aig_ObjFanin1(pObj) ); - return pObj->pData = Aig_And( pNew, Aig_ObjChild0Repres(p, pObj), Aig_ObjChild1Repres(p, pObj) ); + return (Aig_Obj_t *)(pObj->pData = Aig_And( pNew, Aig_ObjChild0Repres(p, pObj), Aig_ObjChild1Repres(p, pObj) )); } /**Function************************************************************* @@ -886,6 +1029,7 @@ Aig_Man_t * Aig_ManDupRepresDfs( Aig_Man_t * p ) pNew = Aig_ManStart( Aig_ManObjNumMax(p) ); pNew->pName = Aig_UtilStrsav( p->pName ); pNew->pSpec = Aig_UtilStrsav( p->pSpec ); + pNew->nConstrs = p->nConstrs; if ( p->vFlopNums ) pNew->vFlopNums = Vec_IntDup( p->vFlopNums ); // map the const and primary inputs @@ -985,6 +1129,11 @@ Aig_Man_t * Aig_ManDupOrpos( Aig_Man_t * p, int fAddRegs ) Aig_Obj_t * pObj, * pMiter; int i; assert( Aig_ManRegNum(p) > 0 ); + if ( p->nConstrs > 0 ) + { + printf( "The AIG manager should have no constraints.\n" ); + return NULL; + } // create the new manager pNew = Aig_ManStart( Aig_ManObjNumMax(p) ); pNew->pName = Aig_UtilStrsav( p->pName ); @@ -1080,6 +1229,11 @@ Aig_Man_t * Aig_ManDupUnsolvedOutputs( Aig_Man_t * p, int fAddRegs ) Aig_Obj_t * pObj; int i, nOuts = 0; assert( Aig_ManRegNum(p) > 0 ); + if ( p->nConstrs > 0 ) + { + printf( "The AIG manager should have no constraints.\n" ); + return NULL; + } // create the new manager pNew = Aig_ManStart( Aig_ManObjNumMax(p) ); pNew->pName = Aig_UtilStrsav( p->pName ); @@ -1120,3 +1274,5 @@ Aig_Man_t * Aig_ManDupUnsolvedOutputs( Aig_Man_t * p, int fAddRegs ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/aig/aigFact.c b/src/aig/aig/aigFact.c index 7004618a..9c4e5689 100644 --- a/src/aig/aig/aigFact.c +++ b/src/aig/aig/aigFact.c @@ -19,6 +19,10 @@ ***********************************************************************/ #include "aig.h" +#include "kit.h" + +ABC_NAMESPACE_IMPL_START + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// @@ -116,7 +120,7 @@ int Aig_ManFindConeOverlap( Aig_Man_t * p, Vec_Ptr_t * vImplics, Aig_Obj_t * pNo assert( !Aig_IsComplement(pNode) ); assert( !Aig_ObjIsConst1(pNode) ); Aig_ManIncrementTravId( p ); - Vec_PtrForEachEntry( vImplics, pTemp, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vImplics, pTemp, i ) Aig_ObjSetTravIdCurrent( p, Aig_Regular(pTemp) ); Aig_ManIncrementTravId( p ); return Aig_ManFindConeOverlap_rec( p, pNode ); @@ -136,13 +140,13 @@ int Aig_ManFindConeOverlap( Aig_Man_t * p, Vec_Ptr_t * vImplics, Aig_Obj_t * pNo Aig_Obj_t * Aig_ManDeriveNewCone_rec( Aig_Man_t * p, Aig_Obj_t * pNode ) { if ( Aig_ObjIsTravIdCurrent( p, pNode ) ) - return pNode->pData; + return (Aig_Obj_t *)pNode->pData; Aig_ObjSetTravIdCurrent( p, pNode ); if ( Aig_ObjIsPi(pNode) ) - return pNode->pData = pNode; + return (Aig_Obj_t *)(pNode->pData = pNode); Aig_ManDeriveNewCone_rec( p, Aig_ObjFanin0(pNode) ); Aig_ManDeriveNewCone_rec( p, Aig_ObjFanin1(pNode) ); - return pNode->pData = Aig_And( p, Aig_ObjChild0Copy(pNode), Aig_ObjChild1Copy(pNode) ); + return (Aig_Obj_t *)(pNode->pData = Aig_And( p, Aig_ObjChild0Copy(pNode), Aig_ObjChild1Copy(pNode) )); } /**Function************************************************************* @@ -163,7 +167,7 @@ Aig_Obj_t * Aig_ManDeriveNewCone( Aig_Man_t * p, Vec_Ptr_t * vImplics, Aig_Obj_t assert( !Aig_IsComplement(pNode) ); assert( !Aig_ObjIsConst1(pNode) ); Aig_ManIncrementTravId( p ); - Vec_PtrForEachEntry( vImplics, pTemp, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vImplics, pTemp, i ) { Aig_ObjSetTravIdCurrent( p, Aig_Regular(pTemp) ); Aig_Regular(pTemp)->pData = Aig_NotCond( Aig_ManConst1(p), Aig_IsComplement(pTemp) ); @@ -267,6 +271,446 @@ void Aig_ManFactorAlgebraicTest( Aig_Man_t * p ) */ } + + +/**Function************************************************************* + + Synopsis [Determines what support variables can be cofactored.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Aig_SuppMinPerform( Aig_Man_t * p, Vec_Ptr_t * vOrGate, Vec_Ptr_t * vNodes, Vec_Ptr_t * vSupp ) +{ + Aig_Obj_t * pObj; + Vec_Ptr_t * vTrSupp, * vTrNode, * vCofs; + unsigned * uFunc, * uCare, * uFunc0, * uFunc1, * uCof; + int i, nWords = Aig_TruthWordNum( Vec_PtrSize(vSupp) ); + // assign support nodes + vTrSupp = Vec_PtrAllocTruthTables( Vec_PtrSize(vSupp) ); + Vec_PtrForEachEntry( Aig_Obj_t *, vSupp, pObj, i ) + { + printf( "%d %d\n", Aig_ObjId(pObj), i ); + pObj->pData = Vec_PtrEntry( vTrSupp, i ); + } + // compute internal nodes + vTrNode = Vec_PtrAllocSimInfo( Vec_PtrSize(vNodes) + 5, nWords ); + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) + { + pObj->pData = uFunc = (unsigned *)Vec_PtrEntry( vTrNode, i ); + uFunc0 = (unsigned *)Aig_ObjFanin0(pObj)->pData; + uFunc1 = (unsigned *)Aig_ObjFanin1(pObj)->pData; + Kit_TruthAndPhase( uFunc, uFunc0, uFunc1, Vec_PtrSize(vSupp), Aig_ObjFaninC0(pObj), Aig_ObjFaninC1(pObj) ); + } + // uFunc contains the result of computation + // compute care set + uCare = (unsigned *)Vec_PtrEntry( vTrNode, Vec_PtrSize(vNodes) ); + Kit_TruthClear( uCare, Vec_PtrSize(vSupp) ); + Vec_PtrForEachEntry( Aig_Obj_t *, vOrGate, pObj, i ) + { + printf( "%d %d %d - or gate\n", Aig_ObjId(Aig_Regular(pObj)), Aig_IsComplement(pObj), i ); + Kit_TruthOrPhase( uCare, uCare, (unsigned *)Aig_Regular(pObj)->pData, Vec_PtrSize(vSupp), 0, Aig_IsComplement(pObj) ); + } + // try cofactoring each variable in both polarities + vCofs = Vec_PtrAlloc( 10 ); + uCof = (unsigned *)Vec_PtrEntry( vTrNode, Vec_PtrSize(vNodes)+1 ); + Vec_PtrForEachEntry( Aig_Obj_t *, vSupp, pObj, i ) + { + // consider negative cofactor + Kit_TruthCofactor0New( uCof, uFunc, Vec_PtrSize(vSupp), i ); + if ( Kit_TruthIsEqualWithCare( uFunc, uCof, uCare, Vec_PtrSize(vSupp) ) ) + { + Vec_PtrPush( vCofs, Aig_Not(pObj) ); + Kit_TruthCopy( uFunc, uCof, Vec_PtrSize(vSupp) ); + Kit_TruthCofactor0( uCare, Vec_PtrSize(vSupp), i ); + continue; + } + // consider positive cofactor + Kit_TruthCofactor1New( uCof, uFunc, Vec_PtrSize(vSupp), i ); + if ( Kit_TruthIsEqualWithCare( uFunc, uCof, uCare, Vec_PtrSize(vSupp) ) ) + { + Vec_PtrPush( vCofs, pObj ); + Kit_TruthCopy( uFunc, uCof, Vec_PtrSize(vSupp) ); + Kit_TruthCofactor1( uCare, Vec_PtrSize(vSupp), i ); + } + } + Vec_PtrFree( vTrNode ); + Vec_PtrFree( vTrSupp ); + return vCofs; +} + + +/**Function************************************************************* + + Synopsis [Returns the new node after cofactoring.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Aig_SuppMinReconstruct( Aig_Man_t * p, Vec_Ptr_t * vCofs, Vec_Ptr_t * vNodes, Vec_Ptr_t * vSupp ) +{ + Aig_Obj_t * pObj; + int i; + // set the value of the support variables + Vec_PtrForEachEntry( Aig_Obj_t *, vSupp, pObj, i ) + assert( !Aig_IsComplement(pObj) ); + Vec_PtrForEachEntry( Aig_Obj_t *, vSupp, pObj, i ) + pObj->pData = pObj; + // set the value of the cofactoring variables + Vec_PtrForEachEntry( Aig_Obj_t *, vCofs, pObj, i ) + Aig_Regular(pObj)->pData = Aig_NotCond( Aig_ManConst1(p), Aig_IsComplement(pObj) ); + // reconstruct the node + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) + pObj->pData = Aig_And( p, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + return (Aig_Obj_t *)pObj->pData; +} + +/**Function************************************************************* + + Synopsis [Returns 1 if all nodes of vOrGate are in vSupp.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Aig_SuppMinGateIsInSupport( Aig_Man_t * p, Vec_Ptr_t * vOrGate, Vec_Ptr_t * vSupp ) +{ + Aig_Obj_t * pObj; + int i; + Aig_ManIncrementTravId( p ); + Vec_PtrForEachEntry( Aig_Obj_t *, vSupp, pObj, i ) + Aig_ObjSetTravIdCurrent( p, pObj ); + Vec_PtrForEachEntry( Aig_Obj_t *, vOrGate, pObj, i ) + if ( !Aig_ObjIsTravIdCurrent( p, Aig_Regular(pObj) ) ) + return 0; + return 1; +} + + +/**Function************************************************************* + + Synopsis [Collects fanins of the marked nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Aig_SuppMinCollectSupport( Aig_Man_t * p, Vec_Ptr_t * vNodes ) +{ + Vec_Ptr_t * vSupp; + Aig_Obj_t * pObj, * pFanin; + int i; + vSupp = Vec_PtrAlloc( 4 ); + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) + { + assert( Aig_ObjIsTravIdCurrent(p, pObj) ); + assert( Aig_ObjIsNode(pObj) ); + pFanin = Aig_ObjFanin0( pObj ); + if ( !Aig_ObjIsTravIdCurrent(p, pFanin) ) + { + Aig_ObjSetTravIdCurrent( p, pFanin ); + Vec_PtrPush( vSupp, pFanin ); + } + pFanin = Aig_ObjFanin1( pObj ); + if ( !Aig_ObjIsTravIdCurrent(p, pFanin) ) + { + Aig_ObjSetTravIdCurrent( p, pFanin ); + Vec_PtrPush( vSupp, pFanin ); + } + } + return vSupp; +} + +/**Function************************************************************* + + Synopsis [Marks the nodes in the cone with current trav ID.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_SuppMinCollectCone_rec( Aig_Man_t * p, Aig_Obj_t * pObj, Vec_Ptr_t * vNodes ) +{ + if ( Aig_ObjIsTravIdCurrent( p, pObj ) ) // visited + return; + if ( !Aig_ObjIsTravIdPrevious( p, pObj ) ) // not visited, but outside + return; + assert( Aig_ObjIsTravIdPrevious(p, pObj) ); // not visited, inside + assert( Aig_ObjIsNode(pObj) ); + Aig_ObjSetTravIdCurrent( p, pObj ); + Aig_SuppMinCollectCone_rec( p, Aig_ObjFanin0(pObj), vNodes ); + Aig_SuppMinCollectCone_rec( p, Aig_ObjFanin1(pObj), vNodes ); + Vec_PtrPush( vNodes, pObj ); +} + +/**Function************************************************************* + + Synopsis [Collects nodes with the current trav ID rooted in the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Aig_SuppMinCollectCone( Aig_Man_t * p, Aig_Obj_t * pRoot ) +{ + Vec_Ptr_t * vNodes; + assert( !Aig_IsComplement(pRoot) ); +// assert( Aig_ObjIsTravIdCurrent( p, pRoot ) ); + vNodes = Vec_PtrAlloc( 4 ); + Aig_ManIncrementTravId( p ); + Aig_SuppMinCollectCone_rec( p, Aig_Regular(pRoot), vNodes ); + return vNodes; +} + +/**Function************************************************************* + + Synopsis [Marks the nodes in the cone with current trav ID.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Aig_SuppMinHighlightCone_rec( Aig_Man_t * p, Aig_Obj_t * pObj ) +{ + int RetValue; + if ( Aig_ObjIsTravIdCurrent( p, pObj ) ) // visited, marks there + return 1; + if ( Aig_ObjIsTravIdPrevious( p, pObj ) ) // visited, no marks there + return 0; + Aig_ObjSetTravIdPrevious( p, pObj ); + if ( Aig_ObjIsPi(pObj) ) + return 0; + RetValue = Aig_SuppMinHighlightCone_rec( p, Aig_ObjFanin0(pObj) ) | + Aig_SuppMinHighlightCone_rec( p, Aig_ObjFanin1(pObj) ); +// printf( "%d %d\n", Aig_ObjId(pObj), RetValue ); + if ( RetValue ) + Aig_ObjSetTravIdCurrent( p, pObj ); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [Marks the nodes in the cone with current trav ID.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Aig_SuppMinHighlightCone( Aig_Man_t * p, Aig_Obj_t * pRoot, Vec_Ptr_t * vOrGate ) +{ + Aig_Obj_t * pLeaf; + int i, RetValue; + assert( !Aig_IsComplement(pRoot) ); + Aig_ManIncrementTravId( p ); + Aig_ManIncrementTravId( p ); + Vec_PtrForEachEntry( Aig_Obj_t *, vOrGate, pLeaf, i ) + Aig_ObjSetTravIdCurrent( p, Aig_Regular(pLeaf) ); + RetValue = Aig_SuppMinHighlightCone_rec( p, pRoot ); + Vec_PtrForEachEntry( Aig_Obj_t *, vOrGate, pLeaf, i ) + Aig_ObjSetTravIdPrevious( p, Aig_Regular(pLeaf) ); + return RetValue; +} + + +/**Function************************************************************* + + Synopsis [Collects the supergate.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_SuppMinCollectSuper_rec( Aig_Obj_t * pObj, Vec_Ptr_t * vSuper ) +{ + // if the new node is complemented or a PI, another gate begins + if ( Aig_IsComplement(pObj) || Aig_ObjIsPi(pObj) ) // || (Aig_ObjRefs(pObj) > 1) ) + { + Vec_PtrPushUnique( vSuper, Aig_Not(pObj) ); + return; + } + // go through the branches + Aig_SuppMinCollectSuper_rec( Aig_ObjChild0(pObj), vSuper ); + Aig_SuppMinCollectSuper_rec( Aig_ObjChild1(pObj), vSuper ); +} + +/**Function************************************************************* + + Synopsis [Collects the supergate.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Aig_SuppMinCollectSuper( Aig_Obj_t * pObj ) +{ + Vec_Ptr_t * vSuper; + assert( !Aig_IsComplement(pObj) ); + assert( !Aig_ObjIsPi(pObj) ); + vSuper = Vec_PtrAlloc( 4 ); + Aig_SuppMinCollectSuper_rec( Aig_ObjChild0(pObj), vSuper ); + Aig_SuppMinCollectSuper_rec( Aig_ObjChild1(pObj), vSuper ); + return vSuper; +} + +/**Function************************************************************* + + Synopsis [Returns the result of support minimization.] + + Description [Returns internal AIG node that is equal to pFunc under + assignment pCond == 1, or NULL if there is no such node. status is + -1 if condition is not OR; + -2 if cone is too large or no cone; + -3 if no support reduction is possible.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Aig_ManSupportMinimization( Aig_Man_t * p, Aig_Obj_t * pCond, Aig_Obj_t * pFunc, int * pStatus ) +{ + int nSuppMax = 16; + Vec_Ptr_t * vOrGate, * vNodes, * vSupp, * vCofs; + Aig_Obj_t * pResult; + int RetValue; + *pStatus = 0; + // if pCond is not OR + if ( !Aig_IsComplement(pCond) || Aig_ObjIsPi(Aig_Regular(pCond)) || Aig_ObjIsConst1(Aig_Regular(pCond)) ) + { + *pStatus = -1; + return NULL; + } + // if pFunc is not a node + if ( !Aig_ObjIsNode(Aig_Regular(pFunc)) ) + { + *pStatus = -2; + return NULL; + } + // collect the multi-input OR gate rooted in the condition + vOrGate = Aig_SuppMinCollectSuper( Aig_Regular(pCond) ); + if ( Vec_PtrSize(vOrGate) > nSuppMax ) + { + Vec_PtrFree( vOrGate ); + *pStatus = -2; + return NULL; + } + // highlight the cone limited by these gates + RetValue = Aig_SuppMinHighlightCone( p, Aig_Regular(pFunc), vOrGate ); + if ( RetValue == 0 ) // no overlap + { + Vec_PtrFree( vOrGate ); + *pStatus = -2; + return NULL; + } + // collect the cone rooted in pFunc limited by vOrGate + vNodes = Aig_SuppMinCollectCone( p, Aig_Regular(pFunc) ); + // collect the support nodes reachable from the cone + vSupp = Aig_SuppMinCollectSupport( p, vNodes ); + if ( Vec_PtrSize(vSupp) > nSuppMax ) + { + Vec_PtrFree( vOrGate ); + Vec_PtrFree( vNodes ); + Vec_PtrFree( vSupp ); + *pStatus = -2; + return NULL; + } + // check if all nodes belonging to OR gate are included in the support + // (if this is not the case, don't-care minimization is not possible) + if ( !Aig_SuppMinGateIsInSupport( p, vOrGate, vSupp ) ) + { + Vec_PtrFree( vOrGate ); + Vec_PtrFree( vNodes ); + Vec_PtrFree( vSupp ); + *pStatus = -3; + return NULL; + } + // create truth tables of all nodes and find the maximal number + // of support varialbles that can be replaced by constants + vCofs = Aig_SuppMinPerform( p, vOrGate, vNodes, vSupp ); + if ( Vec_PtrSize(vCofs) == 0 ) + { + Vec_PtrFree( vCofs ); + Vec_PtrFree( vOrGate ); + Vec_PtrFree( vNodes ); + Vec_PtrFree( vSupp ); + *pStatus = -3; + return NULL; + } + // reconstruct the cone + pResult = Aig_SuppMinReconstruct( p, vCofs, vNodes, vSupp ); + pResult = Aig_NotCond( pResult, Aig_IsComplement(pFunc) ); + Vec_PtrFree( vCofs ); + Vec_PtrFree( vOrGate ); + Vec_PtrFree( vNodes ); + Vec_PtrFree( vSupp ); + return pResult; +} +/**Function************************************************************* + + Synopsis [Testing procedure.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_ManSupportMinimizationTest() +{ + Aig_Man_t * p; + Aig_Obj_t * pFunc, * pCond, * pRes; + int i, Status; + p = Aig_ManStart( 100 ); + for ( i = 0; i < 5; i++ ) + Aig_IthVar(p,i); + pFunc = Aig_Mux( p, Aig_IthVar(p,3), Aig_IthVar(p,1), Aig_IthVar(p,0) ); + pFunc = Aig_Mux( p, Aig_IthVar(p,4), Aig_IthVar(p,2), pFunc ); + pCond = Aig_Or( p, Aig_IthVar(p,3), Aig_IthVar(p,4) ); + pRes = Aig_ManSupportMinimization( p, pCond, pFunc, &Status ); + assert( Status == 0 ); + + Aig_ObjPrint( p, Aig_Regular(pRes) ); printf( "\n" ); + Aig_ObjPrint( p, Aig_ObjFanin0(Aig_Regular(pRes)) ); printf( "\n" ); + Aig_ObjPrint( p, Aig_ObjFanin1(Aig_Regular(pRes)) ); printf( "\n" ); + + Aig_ManStop( p ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/aig/aigFanout.c b/src/aig/aig/aigFanout.c index a3b1e684..d6317f43 100644 --- a/src/aig/aig/aigFanout.c +++ b/src/aig/aig/aigFanout.c @@ -20,6 +20,9 @@ #include "aig.h" +ABC_NAMESPACE_IMPL_START + + // 0: first iFan // 1: prev iFan0 // 2: prev iFan1 @@ -187,3 +190,5 @@ void Aig_ObjRemoveFanout( Aig_Man_t * p, Aig_Obj_t * pObj, Aig_Obj_t * pFanout ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/aig/aigFrames.c b/src/aig/aig/aigFrames.c index f25f7a8f..fdcd14aa 100644 --- a/src/aig/aig/aigFrames.c +++ b/src/aig/aig/aigFrames.c @@ -20,6 +20,9 @@ #include "aig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -133,3 +136,5 @@ Aig_Man_t * Aig_ManFrames( Aig_Man_t * pAig, int nFs, int fInit, int fOuts, int //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/aig/aigInter.c b/src/aig/aig/aigInter.c index 23c1dbf5..aa019191 100644 --- a/src/aig/aig/aigInter.c +++ b/src/aig/aig/aigInter.c @@ -22,6 +22,9 @@ #include "cnf.h" #include "satStore.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -268,7 +271,7 @@ timeSat += clock() - clk; // create the resulting manager clk = clock(); pManInter = Inta_ManAlloc(); - pRes = Inta_ManInterpolate( pManInter, pSatCnf, vVarsAB, fVerbose ); + pRes = (Aig_Man_t *)Inta_ManInterpolate( pManInter, (Sto_Man_t *)pSatCnf, vVarsAB, fVerbose ); Inta_ManFree( pManInter ); timeInt += clock() - clk; /* @@ -283,7 +286,7 @@ timeInt += clock() - clk; } */ Vec_IntFree( vVarsAB ); - Sto_ManFree( pSatCnf ); + Sto_ManFree( (Sto_Man_t *)pSatCnf ); // Ioa_WriteAiger( pRes, "inter2.aig", 0, 0 ); return pRes; @@ -294,3 +297,5 @@ timeInt += clock() - clk; //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/aig/aigMan.c b/src/aig/aig/aigMan.c index 01b29f5f..40fe871b 100644 --- a/src/aig/aig/aigMan.c +++ b/src/aig/aig/aigMan.c @@ -21,6 +21,9 @@ #include "aig.h" #include "tim.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -118,14 +121,14 @@ Aig_Obj_t * Aig_ManDup_rec( Aig_Man_t * pNew, Aig_Man_t * p, Aig_Obj_t * pObj ) { Aig_Obj_t * pObjNew; if ( pObj->pData ) - return pObj->pData; + return (Aig_Obj_t *)pObj->pData; Aig_ManDup_rec( pNew, p, Aig_ObjFanin0(pObj) ); if ( Aig_ObjIsBuf(pObj) ) - return pObj->pData = Aig_ObjChild0Copy(pObj); + return (Aig_Obj_t *)(pObj->pData = Aig_ObjChild0Copy(pObj)); Aig_ManDup_rec( pNew, p, Aig_ObjFanin1(pObj) ); pObjNew = Aig_Oper( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj), Aig_ObjType(pObj) ); Aig_Regular(pObjNew)->pHaig = pObj->pHaig; - return pObj->pData = pObjNew; + return (Aig_Obj_t *)(pObj->pData = pObjNew); } /**Function************************************************************* @@ -157,7 +160,7 @@ Aig_Man_t * Aig_ManExtractMiter( Aig_Man_t * p, Aig_Obj_t * pNode1, Aig_Obj_t * Aig_ManDup_rec( pNew, p, pNode1 ); Aig_ManDup_rec( pNew, p, pNode2 ); // construct the EXOR - pObj = Aig_Exor( pNew, pNode1->pData, pNode2->pData ); + pObj = Aig_Exor( pNew, (Aig_Obj_t *)pNode1->pData, (Aig_Obj_t *)pNode2->pData ); pObj = Aig_NotCond( pObj, Aig_Regular(pObj)->fPhase ^ Aig_IsComplement(pObj) ); // add the PO Aig_ObjCreatePo( pNew, pObj ); @@ -183,35 +186,33 @@ void Aig_ManStop( Aig_Man_t * p ) { Aig_Obj_t * pObj; int i; - if ( p->vMapped ) - Vec_PtrFree( p->vMapped ); - // print time if ( p->time1 ) { ABC_PRT( "time1", p->time1 ); } if ( p->time2 ) { ABC_PRT( "time2", p->time2 ); } - // delete timing - if ( p->pManTime ) - Tim_ManStop( p->pManTime ); - // delete fanout - if ( p->pFanData ) - Aig_ManFanoutStop( p ); // make sure the nodes have clean marks Aig_ManForEachObj( p, pObj, i ) assert( !pObj->fMarkA && !pObj->fMarkB ); + Tim_ManStopP( (Tim_Man_t **)&p->pManTime ); + if ( p->pFanData ) + Aig_ManFanoutStop( p ); + if ( p->pManExdc ) + Aig_ManStop( p->pManExdc ); // Aig_TableProfile( p ); Aig_MmFixedStop( p->pMemObjs, 0 ); - if ( p->vPis ) Vec_PtrFree( p->vPis ); - if ( p->vPos ) Vec_PtrFree( p->vPos ); - if ( p->vObjs ) Vec_PtrFree( p->vObjs ); - if ( p->vBufs ) Vec_PtrFree( p->vBufs ); - if ( p->vLevelR ) Vec_IntFree( p->vLevelR ); - if ( p->vLevels ) Vec_VecFree( p->vLevels ); - if ( p->vFlopNums) Vec_IntFree( p->vFlopNums ); - if ( p->vFlopReprs) Vec_IntFree( p->vFlopReprs ); - if ( p->pManExdc ) Aig_ManStop( p->pManExdc ); - if ( p->vOnehots ) Vec_VecFree( (Vec_Vec_t *)p->vOnehots ); - if ( p->vClockDoms) Vec_VecFree( p->vClockDoms ); - if ( p->vProbs ) Vec_IntFree( p->vProbs ); - if ( p->vCiNumsOrig)Vec_IntFree( p->vCiNumsOrig ); + Vec_PtrFreeP( &p->vPis ); + Vec_PtrFreeP( &p->vPos ); + Vec_PtrFreeP( &p->vObjs ); + Vec_PtrFreeP( &p->vBufs ); + Vec_IntFreeP( &p->vLevelR ); + Vec_VecFreeP( &p->vLevels ); + Vec_IntFreeP( &p->vFlopNums ); + Vec_IntFreeP( &p->vFlopReprs ); + Vec_VecFreeP( (Vec_Vec_t **)&p->vOnehots ); + Vec_VecFreeP( &p->vClockDoms ); + Vec_IntFreeP( &p->vProbs ); + Vec_IntFreeP( &p->vCiNumsOrig ); + Vec_PtrFreeP( &p->vMapped ); + if ( p->pSeqModelVec ) + Vec_PtrFreeFree( p->pSeqModelVec ); ABC_FREE( p->pFastSim ); ABC_FREE( p->pData ); ABC_FREE( p->pSeqModel ); @@ -226,6 +227,25 @@ void Aig_ManStop( Aig_Man_t * p ) /**Function************************************************************* + Synopsis [Stops the AIG manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_ManStopP( Aig_Man_t ** p ) +{ + if ( *p == NULL ) + return; + Aig_ManStop( *p ); + *p = NULL; +} + +/**Function************************************************************* + Synopsis [Removes combinational logic that does not feed into POs.] Description [Returns the number of dangling nodes removed.] @@ -246,7 +266,7 @@ int Aig_ManCleanup( Aig_Man_t * p ) if ( Aig_ObjIsNode(pNode) && Aig_ObjRefs(pNode) == 0 ) Vec_PtrPush( vObjs, pNode ); // recursively remove dangling nodes - Vec_PtrForEachEntry( vObjs, pNode, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vObjs, pNode, i ) Aig_ObjDelete_rec( p, pNode, 1 ); Vec_PtrFree( vObjs ); return nNodesOld - Aig_ManNodeNum(p); @@ -288,7 +308,7 @@ int Aig_ManPiCleanup( Aig_Man_t * p ) { Aig_Obj_t * pObj; int i, k = 0, nPisOld = Aig_ManPiNum(p); - Vec_PtrForEachEntry( p->vPis, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vPis, pObj, i ) { if ( i >= Aig_ManPiNum(p) - Aig_ManRegNum(p) ) Vec_PtrWriteEntry( p->vPis, k++, pObj ); @@ -319,7 +339,7 @@ int Aig_ManPoCleanup( Aig_Man_t * p ) { Aig_Obj_t * pObj; int i, k = 0, nPosOld = Aig_ManPoNum(p); - Vec_PtrForEachEntry( p->vPos, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vPos, pObj, i ) { if ( i >= Aig_ManPoNum(p) - Aig_ManRegNum(p) ) Vec_PtrWriteEntry( p->vPos, k++, pObj ); @@ -453,9 +473,28 @@ void Aig_ManFlipFirstPo( Aig_Man_t * p ) Aig_ObjChild0Flip( Aig_ManPo(p, 0) ); } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void * Aig_ManReleaseData( Aig_Man_t * p ) +{ + void * pD = p->pData; + p->pData = NULL; + return pD; +} //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/aig/aigMem.c b/src/aig/aig/aigMem.c index c0b76ff8..a21b812d 100644 --- a/src/aig/aig/aigMem.c +++ b/src/aig/aig/aigMem.c @@ -20,6 +20,9 @@ #include "aig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -31,7 +34,7 @@ struct Aig_MmFixed_t_ int nEntriesAlloc; // the total number of entries allocated int nEntriesUsed; // the number of entries in use int nEntriesMax; // the max number of entries in use - char * pEntriesFree; // the linked list of ABC_FREE entries + char * pEntriesFree; // the linked list of free entries // this is where the memory is stored int nChunkSize; // the size of one chunk @@ -48,8 +51,8 @@ struct Aig_MmFlex_t_ { // information about individual entries int nEntriesUsed; // the number of entries allocated - char * pCurrent; // the current pointer to ABC_FREE memory - char * pEnd; // the first entry outside the ABC_FREE memory + char * pCurrent; // the current pointer to free memory + char * pEnd; // the first entry outside the free memory // this is where the memory is stored int nChunkSize; // the size of one chunk @@ -160,7 +163,7 @@ char * Aig_MmFixedEntryFetch( Aig_MmFixed_t * p ) char * pTemp; int i; - // check if there are still ABC_FREE entries + // check if there are still free entries if ( p->nEntriesUsed == p->nEntriesAlloc ) { // need to allocate more entries assert( p->pEntriesFree == NULL ); @@ -189,7 +192,7 @@ char * Aig_MmFixedEntryFetch( Aig_MmFixed_t * p ) p->nEntriesUsed++; if ( p->nEntriesMax < p->nEntriesUsed ) p->nEntriesMax = p->nEntriesUsed; - // return the first entry in the ABC_FREE entry list + // return the first entry in the free entry list pTemp = p->pEntriesFree; p->pEntriesFree = *((char **)pTemp); return pTemp; @@ -210,7 +213,7 @@ void Aig_MmFixedEntryRecycle( Aig_MmFixed_t * p, char * pEntry ) { // decrement the counter of used entries p->nEntriesUsed--; - // add the entry to the linked list of ABC_FREE entries + // add the entry to the linked list of free entries *((char **)pEntry) = p->pEntriesFree; p->pEntriesFree = pEntry; } @@ -245,7 +248,7 @@ void Aig_MmFixedRestart( Aig_MmFixed_t * p ) } // set the last link *((char **)pTemp) = NULL; - // set the ABC_FREE entry list + // set the free entry list p->pEntriesFree = p->pChunks[0]; // set the correct statistics p->nMemoryAlloc = p->nEntrySize * p->nChunkSize; @@ -363,7 +366,7 @@ void Aig_MmFlexStop( Aig_MmFlex_t * p, int fVerbose ) char * Aig_MmFlexEntryFetch( Aig_MmFlex_t * p, int nBytes ) { char * pTemp; - // check if there are still ABC_FREE entries + // check if there are still free entries if ( p->pCurrent == NULL || p->pCurrent + nBytes > p->pEnd ) { // need to allocate more entries if ( p->nChunks == p->nChunksAlloc ) @@ -591,3 +594,5 @@ int Aig_MmStepReadMemUsage( Aig_MmStep_t * p ) //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/aig/aigMffc.c b/src/aig/aig/aigMffc.c index b902e609..2f51e442 100644 --- a/src/aig/aig/aigMffc.c +++ b/src/aig/aig/aigMffc.c @@ -20,6 +20,9 @@ #include "aig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -237,11 +240,11 @@ int Aig_NodeMffcLabelCut( Aig_Man_t * p, Aig_Obj_t * pNode, Vec_Ptr_t * vLeaves assert( !Aig_IsComplement(pNode) ); assert( Aig_ObjIsNode(pNode) ); Aig_ManIncrementTravId( p ); - Vec_PtrForEachEntry( vLeaves, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vLeaves, pObj, i ) pObj->nRefs++; ConeSize1 = Aig_NodeDeref_rec( pNode, 0, NULL, NULL ); ConeSize2 = Aig_NodeRefLabel_rec( p, pNode, 0 ); - Vec_PtrForEachEntry( vLeaves, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vLeaves, pObj, i ) pObj->nRefs--; assert( ConeSize1 == ConeSize2 ); assert( ConeSize1 > 0 ); @@ -265,7 +268,7 @@ int Aig_NodeMffcExtendCut( Aig_Man_t * p, Aig_Obj_t * pNode, Vec_Ptr_t * vLeaves int i, LevelMax, ConeSize1, ConeSize2, ConeCur1, ConeCur2, ConeBest; // dereference the current cut LevelMax = 0; - Vec_PtrForEachEntry( vLeaves, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vLeaves, pObj, i ) LevelMax = ABC_MAX( LevelMax, (int)pObj->Level ); if ( LevelMax == 0 ) return 0; @@ -274,7 +277,7 @@ int Aig_NodeMffcExtendCut( Aig_Man_t * p, Aig_Obj_t * pNode, Vec_Ptr_t * vLeaves // try expanding each node in the boundary ConeBest = ABC_INFINITY; pLeafBest = NULL; - Vec_PtrForEachEntry( vLeaves, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vLeaves, pObj, i ) { if ( (int)pObj->Level != LevelMax ) continue; @@ -309,3 +312,5 @@ int Aig_NodeMffcExtendCut( Aig_Man_t * p, Aig_Obj_t * pNode, Vec_Ptr_t * vLeaves //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/aig/aigObj.c b/src/aig/aig/aigObj.c index 9034f272..141afaaa 100644 --- a/src/aig/aig/aigObj.c +++ b/src/aig/aig/aigObj.c @@ -20,6 +20,9 @@ #include "aig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -441,7 +444,7 @@ int Aig_ManPropagateBuffers( Aig_Man_t * p, int fUpdateLevel ) for ( nSteps = 0; Vec_PtrSize(p->vBufs) > 0; nSteps++ ) { // get the node with a buffer fanin - for ( pObj = Vec_PtrEntryLast(p->vBufs); Aig_ObjIsBuf(pObj); pObj = Aig_ObjFanout0(p, pObj) ); + for ( pObj = (Aig_Obj_t *)Vec_PtrEntryLast(p->vBufs); Aig_ObjIsBuf(pObj); pObj = Aig_ObjFanout0(p, pObj) ); // replace this node by a node without buffer Aig_NodeFixBufferFanins( p, pObj, fUpdateLevel ); // stop if a cycle occured @@ -549,3 +552,5 @@ void Aig_ObjReplace( Aig_Man_t * p, Aig_Obj_t * pObjOld, Aig_Obj_t * pObjNew, in //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/aig/aigOper.c b/src/aig/aig/aigOper.c index 208e2d44..127d6ef8 100644 --- a/src/aig/aig/aigOper.c +++ b/src/aig/aig/aigOper.c @@ -20,6 +20,9 @@ #include "aig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -262,6 +265,48 @@ Aig_Obj_t * Aig_Or( Aig_Man_t * p, Aig_Obj_t * p0, Aig_Obj_t * p1 ) Synopsis [Implements ITE operation.] + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Aig_TableLookupInt( Aig_Man_t * p, Aig_Obj_t * p0, Aig_Obj_t * p1 ) +{ + if ( p0 == p1 ) + return p0; + if ( p0 == Aig_ManConst0(p) || p1 == Aig_ManConst0(p) || p0 == Aig_Not(p1) ) + return Aig_ManConst0(p); + if ( p0 == Aig_ManConst1(p) ) + return p1; + if ( p1 == Aig_ManConst1(p) ) + return p0; + if ( Aig_Regular(p0)->Id < Aig_Regular(p1)->Id ) + return Aig_TableLookup( p, Aig_ObjCreateGhost(p, p0, p1, AIG_OBJ_AND) ); + return Aig_TableLookup( p, Aig_ObjCreateGhost(p, p1, p0, AIG_OBJ_AND) ); +} + +/**Function************************************************************* + + Synopsis [Implements ITE operation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Aig_Mux2( Aig_Man_t * p, Aig_Obj_t * pC, Aig_Obj_t * p1, Aig_Obj_t * p0 ) +{ + return Aig_Or( p, Aig_And(p, pC, p1), Aig_And(p, Aig_Not(pC), p0) ); +} + +/**Function************************************************************* + + Synopsis [Implements ITE operation.] + Description [] SideEffects [] @@ -271,46 +316,50 @@ Aig_Obj_t * Aig_Or( Aig_Man_t * p, Aig_Obj_t * p0, Aig_Obj_t * p1 ) ***********************************************************************/ Aig_Obj_t * Aig_Mux( Aig_Man_t * p, Aig_Obj_t * pC, Aig_Obj_t * p1, Aig_Obj_t * p0 ) { -/* + int fUseMuxCanon = 0; Aig_Obj_t * pTempA1, * pTempA2, * pTempB1, * pTempB2, * pTemp; int Count0, Count1; - // consider trivial cases - if ( p0 == Aig_Not(p1) ) + if ( !fUseMuxCanon ) + return Aig_Mux2( p, pC, p1, p0 ); + if ( p0 == p1 ) + return p0; + if ( p1 == Aig_Not(p0) ) return Aig_Exor( p, pC, p0 ); - // other cases can be added + if ( pC == Aig_ManConst0(p) ) + return p0; + if ( pC == Aig_ManConst1(p) ) + return p1; + if ( p0 == Aig_ManConst0(p) ) + return Aig_And( p, pC, p1 ); + if ( p0 == Aig_ManConst1(p) ) + return Aig_Or( p, Aig_Not(pC), p1 ); + if ( p1 == Aig_ManConst0(p) ) + return Aig_And( p, Aig_Not(pC), p0 ); + if ( p1 == Aig_ManConst1(p) ) + return Aig_Or( p, pC, p0 ); // implement the first MUX (F = C * x1 + C' * x0) - - // check for constants here!!! - - pTempA1 = Aig_TableLookup( p, Aig_ObjCreateGhost(p, pC, p1, AIG_OBJ_AND) ); - pTempA2 = Aig_TableLookup( p, Aig_ObjCreateGhost(p, Aig_Not(pC), p0, AIG_OBJ_AND) ); + pTempA1 = Aig_TableLookupInt( p, pC, p1 ); + pTempA2 = Aig_TableLookupInt( p, Aig_Not(pC), p0 ); if ( pTempA1 && pTempA2 ) { - pTemp = Aig_TableLookup( p, Aig_ObjCreateGhost(p, Aig_Not(pTempA1), Aig_Not(pTempA2), AIG_OBJ_AND) ); + pTemp = Aig_TableLookupInt( p, Aig_Not(pTempA1), Aig_Not(pTempA2) ); if ( pTemp ) return Aig_Not(pTemp); } Count0 = (pTempA1 != NULL) + (pTempA2 != NULL); // implement the second MUX (F' = C * x1' + C' * x0') - pTempB1 = Aig_TableLookup( p, Aig_ObjCreateGhost(p, pC, Aig_Not(p1), AIG_OBJ_AND) ); - pTempB2 = Aig_TableLookup( p, Aig_ObjCreateGhost(p, Aig_Not(pC), Aig_Not(p0), AIG_OBJ_AND) ); + pTempB1 = Aig_TableLookupInt( p, pC, Aig_Not(p1) ); + pTempB2 = Aig_TableLookupInt( p, Aig_Not(pC), Aig_Not(p0) ); if ( pTempB1 && pTempB2 ) { - pTemp = Aig_TableLookup( p, Aig_ObjCreateGhost(p, Aig_Not(pTempB1), Aig_Not(pTempB2), AIG_OBJ_AND) ); + pTemp = Aig_TableLookupInt( p, Aig_Not(pTempB1), Aig_Not(pTempB2) ); if ( pTemp ) return pTemp; } Count1 = (pTempB1 != NULL) + (pTempB2 != NULL); // compare and decide which one to implement if ( Count0 >= Count1 ) - { - pTempA1 = pTempA1? pTempA1 : Aig_And(p, pC, p1); - pTempA2 = pTempA2? pTempA2 : Aig_And(p, Aig_Not(pC), p0); - return Aig_Or( p, pTempA1, pTempA2 ); - } - pTempB1 = pTempB1? pTempB1 : Aig_And(p, pC, Aig_Not(p1)); - pTempB2 = pTempB2? pTempB2 : Aig_And(p, Aig_Not(pC), Aig_Not(p0)); - return Aig_Not( Aig_Or( p, pTempB1, pTempB2 ) ); -*/ - return Aig_Or( p, Aig_And(p, pC, p1), Aig_And(p, Aig_Not(pC), p0) ); + return Aig_Or( p, Aig_And(p, pC, p1), Aig_And(p, Aig_Not(pC), p0) ); + return Aig_Not( Aig_Or( p, Aig_And(p, pC, Aig_Not(p1)), Aig_And(p, Aig_Not(pC), Aig_Not(p0)) ) ); +// return Aig_Or( p, Aig_And(p, pC, p1), Aig_And(p, Aig_Not(pC), p0) ); } /**Function************************************************************* @@ -385,7 +434,7 @@ Aig_Obj_t * Aig_Miter( Aig_Man_t * p, Vec_Ptr_t * vPairs ) assert( vPairs->nSize > 0 ); assert( vPairs->nSize % 2 == 0 ); for ( i = 0; i < vPairs->nSize; i += 2 ) - vPairs->pArray[i/2] = Aig_Not( Aig_Exor( p, vPairs->pArray[i], vPairs->pArray[i+1] ) ); + vPairs->pArray[i/2] = Aig_Not( Aig_Exor( p, (Aig_Obj_t *)vPairs->pArray[i], (Aig_Obj_t *)vPairs->pArray[i+1] ) ); vPairs->nSize = vPairs->nSize/2; return Aig_Not( Aig_Multi_rec( p, (Aig_Obj_t **)vPairs->pArray, vPairs->nSize, AIG_OBJ_AND ) ); } @@ -407,7 +456,7 @@ Aig_Obj_t * Aig_MiterTwo( Aig_Man_t * p, Vec_Ptr_t * vNodes1, Vec_Ptr_t * vNodes assert( vNodes1->nSize > 0 && vNodes1->nSize > 0 ); assert( vNodes1->nSize == vNodes2->nSize ); for ( i = 0; i < vNodes1->nSize; i++ ) - vNodes1->pArray[i] = Aig_Not( Aig_Exor( p, vNodes1->pArray[i], vNodes2->pArray[i] ) ); + vNodes1->pArray[i] = Aig_Not( Aig_Exor( p, (Aig_Obj_t *)vNodes1->pArray[i], (Aig_Obj_t *)vNodes2->pArray[i] ) ); return Aig_Not( Aig_Multi_rec( p, (Aig_Obj_t **)vNodes1->pArray, vNodes1->nSize, AIG_OBJ_AND ) ); } @@ -474,8 +523,84 @@ Aig_Obj_t * Aig_CreateExor( Aig_Man_t * p, int nVars ) return pFunc; } +/**Function************************************************************* + + Synopsis [Implements ITE operation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_MuxTest() +{ + Vec_Ptr_t * vNodes; + Aig_Man_t * p; + Aig_Obj_t * pObj, * pFanin0, * pFanin1, * pCtrl; + int nNodes = 2000; + int i,nPIs = 20; +// srand( time(NULL) ); + srand( 321 ); + vNodes = Vec_PtrAlloc( 100 ); + // create a bunch of random MUXes + p = Aig_ManStart( 10000 ); + for ( i = 0; i < nPIs; i++ ) + Aig_IthVar(p,i); + for ( i = 0; i < nNodes; i++ ) + { + if ( rand() % 10 == 0 ) + pCtrl = Aig_ManConst0(p); + else if ( rand() % 10 == 0 ) + pCtrl = Aig_ManConst1(p); + else if ( rand() % 3 == 0 || i < nPIs ) + pCtrl = Aig_IthVar( p, rand() % nPIs ); + else + pCtrl = (Aig_Obj_t *)Vec_PtrEntry(vNodes, rand() % i); + if ( rand() % 2 == 0 ) + pCtrl = Aig_Not( pCtrl ); + + if ( rand() % 10 == 0 ) + pFanin1 = Aig_ManConst0(p); + else if ( rand() % 10 == 0 ) + pFanin1 = Aig_ManConst1(p); + else if ( rand() % 3 == 0 || i < nPIs ) + pFanin1 = Aig_IthVar( p, rand() % nPIs ); + else + pFanin1 = (Aig_Obj_t *)Vec_PtrEntry(vNodes, rand() % i); + if ( rand() % 2 == 0 ) + pFanin1 = Aig_Not( pFanin1 ); + + if ( rand() % 10 == 0 ) + pFanin0 = Aig_ManConst0(p); + else if ( rand() % 10 == 0 ) + pFanin0 = Aig_ManConst1(p); + else if ( rand() % 3 == 0 || i < nPIs ) + pFanin0 = Aig_IthVar( p, rand() % nPIs ); + else + pFanin0 = (Aig_Obj_t *)Vec_PtrEntry(vNodes, rand() % i); + if ( rand() % 2 == 0 ) + pFanin0 = Aig_Not( pFanin0 ); + + pObj = Aig_Mux( p, pCtrl, pFanin1, pFanin0 ); + Vec_PtrPush( vNodes, pObj ); + } + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) + Aig_ObjCreatePo( p, pObj ); + Vec_PtrFree( vNodes ); + + printf( "Number of nodes = %6d.\n", Aig_ManObjNum(p) ); + Aig_ManCleanup( p ); + printf( "Number of nodes = %6d.\n", Aig_ManObjNum(p) ); + Aig_ManDumpBlif( p, "test1.blif", NULL, NULL ); + Aig_ManStop( p ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/aig/aigOrder.c b/src/aig/aig/aigOrder.c index 746f0f18..21bf8b8e 100644 --- a/src/aig/aig/aigOrder.c +++ b/src/aig/aig/aigOrder.c @@ -20,6 +20,9 @@ #include "aig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -169,3 +172,5 @@ void Aig_ObjOrderAdvance( Aig_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/aig/aigPart.c b/src/aig/aig/aigPart.c index 6849ba70..52960cd3 100644 --- a/src/aig/aig/aigPart.c +++ b/src/aig/aig/aigPart.c @@ -20,6 +20,10 @@ #include "aig.h" #include "tim.h" +#include "fra.h" + +ABC_NAMESPACE_IMPL_START + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// @@ -30,10 +34,10 @@ struct Part_Man_t_ { int nChunkSize; // the size of one chunk of memory (~1 Mb) int nStepSize; // the step size in saving memory (~64 bytes) - char * pFreeBuf; // the pointer to ABC_FREE memory - int nFreeSize; // the size of remaining ABC_FREE memory + char * pFreeBuf; // the pointer to free memory + int nFreeSize; // the size of remaining free memory Vec_Ptr_t * vMemory; // the memory allocated - Vec_Ptr_t * vFree; // the vector of ABC_FREE pieces of memory + Vec_Ptr_t * vFree; // the vector of free pieces of memory }; typedef struct Part_One_t_ Part_One_t; @@ -91,7 +95,7 @@ void Part_ManStop( Part_Man_t * p ) { void * pMemory; int i; - Vec_PtrForEachEntry( p->vMemory, pMemory, i ) + Vec_PtrForEachEntry( void *, p->vMemory, pMemory, i ) ABC_FREE( pMemory ); Vec_PtrFree( p->vMemory ); Vec_PtrFree( p->vFree ); @@ -116,7 +120,7 @@ char * Part_ManFetch( Part_Man_t * p, int nSize ) assert( nSize > 0 ); Type = Part_SizeType( nSize, p->nStepSize ); Vec_PtrFillExtra( p->vFree, Type + 1, NULL ); - if ( (pMemory = Vec_PtrEntry( p->vFree, Type )) ) + if ( (pMemory = (char *)Vec_PtrEntry( p->vFree, Type )) ) { Vec_PtrWriteEntry( p->vFree, Type, Part_OneNext(pMemory) ); return pMemory; @@ -151,7 +155,7 @@ void Part_ManRecycle( Part_Man_t * p, char * pMemory, int nSize ) int Type; Type = Part_SizeType( nSize, p->nStepSize ); Vec_PtrFillExtra( p->vFree, Type + 1, NULL ); - Part_OneSetNext( pMemory, Vec_PtrEntry(p->vFree, Type) ); + Part_OneSetNext( pMemory, (char *)Vec_PtrEntry(p->vFree, Type) ); Vec_PtrWriteEntry( p->vFree, Type, pMemory ); } @@ -288,8 +292,8 @@ Vec_Ptr_t * Aig_ManSupports( Aig_Man_t * pMan ) { if ( Aig_ObjIsNode(pObj) ) { - pPart0 = Aig_ObjFanin0(pObj)->pData; - pPart1 = Aig_ObjFanin1(pObj)->pData; + pPart0 = (Part_One_t *)Aig_ObjFanin0(pObj)->pData; + pPart1 = (Part_One_t *)Aig_ObjFanin1(pObj)->pData; pObj->pData = Part_ManMergeEntry( p, pPart0, pPart1, pObj->nRefs ); assert( pPart0->nRefs > 0 ); if ( --pPart0->nRefs == 0 ) @@ -301,7 +305,7 @@ Vec_Ptr_t * Aig_ManSupports( Aig_Man_t * pMan ) } if ( Aig_ObjIsPo(pObj) ) { - pPart0 = Aig_ObjFanin0(pObj)->pData; + pPart0 = (Part_One_t *)Aig_ObjFanin0(pObj)->pData; vSupp = Part_ManTransferEntry(pPart0); Vec_IntPush( vSupp, (int)(long)pObj->pNext ); Vec_PtrPush( vSupports, vSupp ); @@ -369,11 +373,11 @@ Vec_Ptr_t * Aig_ManSupportsInverse( Aig_Man_t * p ) for ( i = 0; i < Aig_ManPiNum(p); i++ ) Vec_PtrPush( vSuppsInv, Vec_IntAlloc(8) ); // transforms the supports into the inverse supports - Vec_PtrForEachEntry( vSupps, vSupp, i ) + Vec_PtrForEachEntry( Vec_Int_t *, vSupps, vSupp, i ) { iOut = Vec_IntPop( vSupp ); Vec_IntForEachEntry( vSupp, iIn, k ) - Vec_IntPush( Vec_PtrEntry(vSuppsInv, iIn), iOut ); + Vec_IntPush( (Vec_Int_t *)Vec_PtrEntry(vSuppsInv, iIn), iOut ); } Vec_VecFree( (Vec_Vec_t *)vSupps ); return vSuppsInv; @@ -399,7 +403,7 @@ Vec_Ptr_t * Aig_ManSupportsRegisters( Aig_Man_t * p ) vSupports = Aig_ManSupports( p ); // transforms the supports into the latch dependency matrix vMatrix = Vec_PtrStart( Aig_ManRegNum(p) ); - Vec_PtrForEachEntry( vSupports, vSupp, i ) + Vec_PtrForEachEntry( Vec_Int_t *, vSupports, vSupp, i ) { // skip true POs iOut = Vec_IntPop( vSupp ); @@ -426,7 +430,7 @@ Vec_Ptr_t * Aig_ManSupportsRegisters( Aig_Man_t * p ) } Vec_PtrFree( vSupports ); // check that all supports are used - Vec_PtrForEachEntry( vMatrix, vSupp, i ) + Vec_PtrForEachEntry( Vec_Int_t *, vMatrix, vSupp, i ) assert( vSupp != NULL ); return vMatrix; } @@ -515,13 +519,13 @@ int Aig_ManPartitionSmartFindPart( Vec_Ptr_t * vPartSuppsAll, Vec_Ptr_t * vParts int i, nCommon, iBest; iBest = -1; ValueBest = 0; - Vec_PtrForEachEntry( vPartSuppsAll, vPartSupp, i ) + Vec_PtrForEachEntry( Vec_Int_t *, vPartSuppsAll, vPartSupp, i ) { // vPart = Vec_PtrEntry( vPartsAll, i ); // if ( nSuppSizeLimit > 0 && Vec_IntSize(vPart) >= nSuppSizeLimit ) // continue; // nCommon = Vec_IntTwoCountCommon( vPartSupp, vOne ); - nCommon = Aig_ManSuppCharCommon( Vec_PtrEntry(vPartSuppsBit, i), vOne ); + nCommon = Aig_ManSuppCharCommon( (unsigned *)Vec_PtrEntry(vPartSuppsBit, i), vOne ); if ( nCommon == 0 ) continue; if ( nCommon == Vec_IntSize(vOne) ) @@ -563,9 +567,9 @@ void Aig_ManPartitionPrint( Aig_Man_t * p, Vec_Ptr_t * vPartsAll, Vec_Ptr_t * vP int i, nOutputs, Counter; Counter = 0; - Vec_PtrForEachEntry( vPartSuppsAll, vOne, i ) + Vec_PtrForEachEntry( Vec_Int_t *, vPartSuppsAll, vOne, i ) { - nOutputs = Vec_IntSize(Vec_PtrEntry(vPartsAll, i)); + nOutputs = Vec_IntSize((Vec_Int_t *)Vec_PtrEntry(vPartsAll, i)); printf( "%d=(%d,%d) ", i, Vec_IntSize(vOne), nOutputs ); Counter += nOutputs; if ( i == Vec_PtrSize(vPartsAll) - 1 ) @@ -597,7 +601,7 @@ void Aig_ManPartitionCompact( Vec_Ptr_t * vPartsAll, Vec_Ptr_t * vPartSuppsAll, // pack smaller partitions into larger blocks iPart = 0; vPart = vPartSupp = NULL; - Vec_PtrForEachEntry( vPartSuppsAll, vOne, i ) + Vec_PtrForEachEntry( Vec_Int_t *, vPartSuppsAll, vOne, i ) { if ( Vec_IntSize(vOne) < nSuppSizeLimit ) { @@ -605,27 +609,27 @@ void Aig_ManPartitionCompact( Vec_Ptr_t * vPartsAll, Vec_Ptr_t * vPartSuppsAll, { assert( vPart == NULL ); vPartSupp = Vec_IntDup(vOne); - vPart = Vec_PtrEntry(vPartsAll, i); + vPart = (Vec_Int_t *)Vec_PtrEntry(vPartsAll, i); } else { vPartSupp = Vec_IntTwoMerge( vTemp = vPartSupp, vOne ); Vec_IntFree( vTemp ); - vPart = Vec_IntTwoMerge( vTemp = vPart, Vec_PtrEntry(vPartsAll, i) ); + vPart = Vec_IntTwoMerge( vTemp = vPart, (Vec_Int_t *)Vec_PtrEntry(vPartsAll, i) ); Vec_IntFree( vTemp ); - Vec_IntFree( Vec_PtrEntry(vPartsAll, i) ); + Vec_IntFree( (Vec_Int_t *)Vec_PtrEntry(vPartsAll, i) ); } if ( Vec_IntSize(vPartSupp) < nSuppSizeLimit ) continue; } else - vPart = Vec_PtrEntry(vPartsAll, i); + vPart = (Vec_Int_t *)Vec_PtrEntry(vPartsAll, i); // add the partition Vec_PtrWriteEntry( vPartsAll, iPart, vPart ); vPart = NULL; if ( vPartSupp ) { - Vec_IntFree( Vec_PtrEntry(vPartSuppsAll, iPart) ); + Vec_IntFree( (Vec_Int_t *)Vec_PtrEntry(vPartSuppsAll, iPart) ); Vec_PtrWriteEntry( vPartSuppsAll, iPart, vPartSupp ); vPartSupp = NULL; } @@ -638,7 +642,7 @@ void Aig_ManPartitionCompact( Vec_Ptr_t * vPartsAll, Vec_Ptr_t * vPartSuppsAll, vPart = NULL; assert( vPartSupp != NULL ); - Vec_IntFree( Vec_PtrEntry(vPartSuppsAll, iPart) ); + Vec_IntFree( (Vec_Int_t *)Vec_PtrEntry(vPartSuppsAll, iPart) ); Vec_PtrWriteEntry( vPartSuppsAll, iPart, vPartSupp ); vPartSupp = NULL; iPart++; @@ -679,7 +683,7 @@ ABC_PRT( "Supps", clock() - clk ); clk = clock(); vPartsAll = Vec_PtrAlloc( 256 ); vPartSuppsAll = Vec_PtrAlloc( 256 ); - Vec_PtrForEachEntry( vSupports, vOne, i ) + Vec_PtrForEachEntry( Vec_Int_t *, vSupports, vOne, i ) { // get the output number iOut = Vec_IntPop(vOne); @@ -701,21 +705,21 @@ clk = clock(); else { // add output to this partition - vPart = Vec_PtrEntry( vPartsAll, iPart ); + vPart = (Vec_Int_t *)Vec_PtrEntry( vPartsAll, iPart ); Vec_IntPush( vPart, iOut ); // merge supports - vPartSupp = Vec_PtrEntry( vPartSuppsAll, iPart ); + vPartSupp = (Vec_Int_t *)Vec_PtrEntry( vPartSuppsAll, iPart ); vPartSupp = Vec_IntTwoMerge( vTemp = vPartSupp, vOne ); Vec_IntFree( vTemp ); // reinsert new support Vec_PtrWriteEntry( vPartSuppsAll, iPart, vPartSupp ); - Aig_ManSuppCharAdd( Vec_PtrEntry(vPartSuppsBit, iPart), vOne, Aig_ManPiNum(p) ); + Aig_ManSuppCharAdd( (unsigned *)Vec_PtrEntry(vPartSuppsBit, iPart), vOne, Aig_ManPiNum(p) ); } } // stop char-based support representation - Vec_PtrForEachEntry( vPartSuppsBit, vTemp, i ) + Vec_PtrForEachEntry( Vec_Int_t *, vPartSuppsBit, vTemp, i ) ABC_FREE( vTemp ); Vec_PtrFree( vPartSuppsBit ); @@ -728,13 +732,13 @@ ABC_PRT( "Parts", clock() - clk ); clk = clock(); // reorder partitions in the decreasing order of support sizes // remember partition number in each partition support - Vec_PtrForEachEntry( vPartSuppsAll, vOne, i ) + Vec_PtrForEachEntry( Vec_Int_t *, vPartSuppsAll, vOne, i ) Vec_IntPush( vOne, i ); // sort the supports in the decreasing order Vec_VecSort( (Vec_Vec_t *)vPartSuppsAll, 1 ); // reproduce partitions vPartsAll2 = Vec_PtrAlloc( 256 ); - Vec_PtrForEachEntry( vPartSuppsAll, vOne, i ) + Vec_PtrForEachEntry( Vec_Int_t *, vPartSuppsAll, vOne, i ) Vec_PtrPush( vPartsAll2, Vec_PtrEntry(vPartsAll, Vec_IntPop(vOne)) ); Vec_PtrFree( vPartsAll ); vPartsAll = vPartsAll2; @@ -759,7 +763,7 @@ if ( fVerbose ) *pvPartSupps = vPartSuppsAll; /* // converts from intergers to nodes - Vec_PtrForEachEntry( vPartsAll, vPart, iPart ) + Vec_PtrForEachEntry( Vec_Int_t *, vPartsAll, vPart, iPart ) { vPartPtr = Vec_PtrAlloc( Vec_IntSize(vPart) ); Vec_IntForEachEntry( vPart, iOut, i ) @@ -793,7 +797,7 @@ Vec_Ptr_t * Aig_ManPartitionSmartRegisters( Aig_Man_t * pAig, int nSuppSizeLimit clk = clock(); vSupports = Aig_ManSupportsRegisters( pAig ); assert( Vec_PtrSize(vSupports) == Aig_ManRegNum(pAig) ); - Vec_PtrForEachEntry( vSupports, vOne, i ) + Vec_PtrForEachEntry( Vec_Int_t *, vSupports, vOne, i ) Vec_IntPush( vOne, i ); if ( fVerbose ) { @@ -807,7 +811,7 @@ ABC_PRT( "Supps", clock() - clk ); clk = clock(); vPartsAll = Vec_PtrAlloc( 256 ); vPartSuppsAll = Vec_PtrAlloc( 256 ); - Vec_PtrForEachEntry( vSupports, vOne, i ) + Vec_PtrForEachEntry( Vec_Int_t *, vSupports, vOne, i ) { // get the output number iOut = Vec_IntPop(vOne); @@ -829,21 +833,21 @@ clk = clock(); else { // add output to this partition - vPart = Vec_PtrEntry( vPartsAll, iPart ); + vPart = (Vec_Int_t *)Vec_PtrEntry( vPartsAll, iPart ); Vec_IntPush( vPart, iOut ); // merge supports - vPartSupp = Vec_PtrEntry( vPartSuppsAll, iPart ); + vPartSupp = (Vec_Int_t *)Vec_PtrEntry( vPartSuppsAll, iPart ); vPartSupp = Vec_IntTwoMerge( vTemp = vPartSupp, vOne ); Vec_IntFree( vTemp ); // reinsert new support Vec_PtrWriteEntry( vPartSuppsAll, iPart, vPartSupp ); - Aig_ManSuppCharAdd( Vec_PtrEntry(vPartSuppsBit, iPart), vOne, Vec_PtrSize(vSupports) ); + Aig_ManSuppCharAdd( (unsigned *)Vec_PtrEntry(vPartSuppsBit, iPart), vOne, Vec_PtrSize(vSupports) ); } } // stop char-based support representation - Vec_PtrForEachEntry( vPartSuppsBit, vTemp, i ) + Vec_PtrForEachEntry( Vec_Int_t *, vPartSuppsBit, vTemp, i ) ABC_FREE( vTemp ); Vec_PtrFree( vPartSuppsBit ); @@ -856,13 +860,13 @@ ABC_PRT( "Parts", clock() - clk ); clk = clock(); // reorder partitions in the decreasing order of support sizes // remember partition number in each partition support - Vec_PtrForEachEntry( vPartSuppsAll, vOne, i ) + Vec_PtrForEachEntry( Vec_Int_t *, vPartSuppsAll, vOne, i ) Vec_IntPush( vOne, i ); // sort the supports in the decreasing order Vec_VecSort( (Vec_Vec_t *)vPartSuppsAll, 1 ); // reproduce partitions vPartsAll2 = Vec_PtrAlloc( 256 ); - Vec_PtrForEachEntry( vPartSuppsAll, vOne, i ) + Vec_PtrForEachEntry( Vec_Int_t *, vPartSuppsAll, vOne, i ) Vec_PtrPush( vPartsAll2, Vec_PtrEntry(vPartsAll, Vec_IntPop(vOne)) ); Vec_PtrFree( vPartsAll ); vPartsAll = vPartsAll2; @@ -888,7 +892,7 @@ if ( fVerbose ) /* // converts from intergers to nodes - Vec_PtrForEachEntry( vPartsAll, vPart, iPart ) + Vec_PtrForEachEntry( Vec_Int_t *, vPartsAll, vPart, iPart ) { vPartPtr = Vec_PtrAlloc( Vec_IntSize(vPart) ); Vec_IntForEachEntry( vPart, iOut, i ) @@ -919,7 +923,7 @@ Vec_Ptr_t * Aig_ManPartitionNaive( Aig_Man_t * p, int nPartSize ) nParts = (Aig_ManPoNum(p) / nPartSize) + ((Aig_ManPoNum(p) % nPartSize) > 0); vParts = (Vec_Ptr_t *)Vec_VecStart( nParts ); Aig_ManForEachPo( p, pObj, i ) - Vec_IntPush( Vec_PtrEntry(vParts, i / nPartSize), i ); + Vec_IntPush( (Vec_Int_t *)Vec_PtrEntry(vParts, i / nPartSize), i ); return vParts; } @@ -940,18 +944,18 @@ Aig_Obj_t * Aig_ManDupPart_rec( Aig_Man_t * pNew, Aig_Man_t * pOld, Aig_Obj_t * { assert( !Aig_IsComplement(pObj) ); if ( Aig_ObjIsTravIdCurrent(pOld, pObj) ) - return pObj->pData; + return (Aig_Obj_t *)pObj->pData; Aig_ObjSetTravIdCurrent(pOld, pObj); if ( Aig_ObjIsPi(pObj) ) { assert( Vec_IntSize(vSuppMap) == Aig_ManPiNum(pNew) ); Vec_IntPush( vSuppMap, (int)(long)pObj->pNext ); - return pObj->pData = Aig_ObjCreatePi(pNew); + return (Aig_Obj_t *)(pObj->pData = Aig_ObjCreatePi(pNew)); } assert( Aig_ObjIsNode(pObj) ); Aig_ManDupPart_rec( pNew, pOld, Aig_ObjFanin0(pObj), vSuppMap ); Aig_ManDupPart_rec( pNew, pOld, Aig_ObjFanin1(pObj), vSuppMap ); - return pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + return (Aig_Obj_t *)(pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) )); } /**Function************************************************************* @@ -1133,7 +1137,7 @@ Vec_Ptr_t * Aig_ManSupportNodes( Aig_Man_t * p, Vec_Ptr_t * vParts ) int i, k, iOut; Aig_ManSetPioNumbers( p ); vPartSupps = Vec_PtrAlloc( Vec_PtrSize(vParts) ); - Vec_PtrForEachEntry( vParts, vPart, i ) + Vec_PtrForEachEntry( Vec_Int_t *, vParts, vPart, i ) { vSupport = Vec_IntAlloc( 100 ); Aig_ManIncrementTravId( p ); @@ -1180,8 +1184,8 @@ Vec_Ptr_t * Aig_ManMiterPartitioned( Aig_Man_t * p1, Aig_Man_t * p2, int nPartSi for ( i = 0; i < Vec_PtrSize(vParts); i++ ) { // get partition and its support - vPart = Vec_PtrEntry( vParts, i ); - vPartSupp = Vec_PtrEntry( vPartSupps, i ); + vPart = (Vec_Int_t *)Vec_PtrEntry( vParts, i ); + vPartSupp = (Vec_Int_t *)Vec_PtrEntry( vPartSupps, i ); // create the new miter pNew = Aig_ManStart( 1000 ); // create the PIs @@ -1221,7 +1225,7 @@ Aig_Man_t * Aig_ManChoicePartitioned( Vec_Ptr_t * vAigs, int nPartSize, int nCon { // extern int Cmd_CommandExecute( void * pAbc, char * sCommand ); // extern void * Abc_FrameGetGlobalFrame(); - extern Aig_Man_t * Fra_FraigChoice( Aig_Man_t * pManAig, int nConfMax, int nLevelMax ); +// extern Aig_Man_t * Fra_FraigChoice( Aig_Man_t * pManAig, int nConfMax, int nLevelMax ); Vec_Ptr_t * vPios; Vec_Ptr_t * vOutsTotal, * vOuts; @@ -1235,11 +1239,11 @@ Aig_Man_t * Aig_ManChoicePartitioned( Vec_Ptr_t * vAigs, int nPartSize, int nCon // compute the total number of IDs nIdMax = 0; - Vec_PtrForEachEntry( vAigs, pAig, i ) + Vec_PtrForEachEntry( Aig_Man_t *, vAigs, pAig, i ) nIdMax += Aig_ManObjNumMax(pAig); // partition the first AIG in the array - pAig = Vec_PtrEntry( vAigs, 0 ); + pAig = (Aig_Man_t *)Vec_PtrEntry( vAigs, 0 ); vParts = Aig_ManPartitionSmart( pAig, nPartSize, 0, NULL ); // start the total fraiged AIG @@ -1248,7 +1252,7 @@ Aig_Man_t * Aig_ManChoicePartitioned( Vec_Ptr_t * vAigs, int nPartSize, int nCon vOutsTotal = Vec_PtrStart( Aig_ManPoNum(pAig) ); // set the PI numbers - Vec_PtrForEachEntry( vAigs, pAig, i ) + Vec_PtrForEachEntry( Aig_Man_t *, vAigs, pAig, i ) Aig_ManForEachPi( pAig, pObj, k ) pObj->pNext = (Aig_Obj_t *)(long)k; @@ -1256,18 +1260,18 @@ Aig_Man_t * Aig_ManChoicePartitioned( Vec_Ptr_t * vAigs, int nPartSize, int nCon // create the total fraiged AIG vPartSupp = Vec_IntAlloc( 100 ); // maps part PI num into total PI num - Vec_PtrForEachEntry( vParts, vPart, i ) + Vec_PtrForEachEntry( Vec_Int_t *, vParts, vPart, i ) { // derive the partition AIG pAigPart = Aig_ManStart( 5000 ); // pAigPart->pName = Extra_UtilStrsav( pAigPart->pName ); Vec_IntClear( vPartSupp ); - Vec_PtrForEachEntry( vAigs, pAig, k ) + Vec_PtrForEachEntry( Aig_Man_t *, vAigs, pAig, k ) { vOuts = Aig_ManDupPart( pAigPart, pAig, vPart, vPartSupp, 0 ); if ( k == 0 ) { - Vec_PtrForEachEntry( vOuts, pObj, m ) + Vec_PtrForEachEntry( Aig_Obj_t *, vOuts, pObj, m ) Aig_ObjCreatePo( pAigPart, pObj ); } Vec_PtrFree( vOuts ); @@ -1275,7 +1279,7 @@ Aig_Man_t * Aig_ManChoicePartitioned( Vec_Ptr_t * vAigs, int nPartSize, int nCon // derive the total AIG from the partitioned AIG vOuts = Aig_ManDupPart( pAigTotal, pAigPart, vPart, vPartSupp, 1 ); // add to the outputs - Vec_PtrForEachEntry( vOuts, pObj, k ) + Vec_PtrForEachEntry( Aig_Obj_t *, vOuts, pObj, k ) { assert( Vec_PtrEntry( vOutsTotal, Vec_IntEntry(vPart,k) ) == NULL ); Vec_PtrWriteEntry( vOutsTotal, Vec_IntEntry(vPart,k), pObj ); @@ -1310,12 +1314,12 @@ Aig_Man_t * Aig_ManChoicePartitioned( Vec_Ptr_t * vAigs, int nPartSize, int nCon // Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "set progressbar" ); // clear the PI numbers - Vec_PtrForEachEntry( vAigs, pAig, i ) + Vec_PtrForEachEntry( Aig_Man_t *, vAigs, pAig, i ) Aig_ManForEachPi( pAig, pObj, k ) pObj->pNext = NULL; // add the outputs in the same order - Vec_PtrForEachEntry( vOutsTotal, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vOutsTotal, pObj, i ) Aig_ObjCreatePo( pAigTotal, pObj ); Vec_PtrFree( vOutsTotal ); @@ -1324,14 +1328,14 @@ Aig_Man_t * Aig_ManChoicePartitioned( Vec_Ptr_t * vAigs, int nPartSize, int nCon // create the equivalent nodes lists Aig_ManMarkValidChoices( pAig ); // reconstruct the network - vPios = Aig_ManOrderPios( pAig, Vec_PtrEntry(vAigs,0) ); + vPios = Aig_ManOrderPios( pAig, (Aig_Man_t *)Vec_PtrEntry(vAigs,0) ); pAig = Aig_ManDupDfsGuided( pTemp = pAig, vPios ); Aig_ManStop( pTemp ); Vec_PtrFree( vPios ); // duplicate the timing manager - pTemp = Vec_PtrEntry( vAigs, 0 ); + pTemp = (Aig_Man_t *)Vec_PtrEntry( vAigs, 0 ); if ( pTemp->pManTime ) - pAig->pManTime = Tim_ManDup( pTemp->pManTime, 0 ); + pAig->pManTime = Tim_ManDup( (Tim_Man_t *)pTemp->pManTime, 0 ); // reset levels Aig_ManChoiceLevel( pAig ); return pAig; @@ -1351,7 +1355,7 @@ Aig_Man_t * Aig_ManChoicePartitioned( Vec_Ptr_t * vAigs, int nPartSize, int nCon ***********************************************************************/ Aig_Man_t * Aig_ManFraigPartitioned( Aig_Man_t * pAig, int nPartSize, int nConfMax, int nLevelMax, int fVerbose ) { - extern Aig_Man_t * Fra_FraigChoice( Aig_Man_t * pManAig, int nConfMax, int nLevelMax ); +// extern Aig_Man_t * Fra_FraigChoice( Aig_Man_t * pManAig, int nConfMax, int nLevelMax ); Aig_Man_t * pAigPart, * pAigTemp; Vec_Int_t * vPart; @@ -1370,7 +1374,7 @@ Aig_Man_t * Aig_ManFraigPartitioned( Aig_Man_t * pAig, int nPartSize, int nConfM Aig_ManSetPioNumbers( pAig ); // create the total fraiged AIG - Vec_PtrForEachEntry( vParts, vPart, i ) + Vec_PtrForEachEntry( Vec_Int_t *, vParts, vPart, i ) { // derive the partition AIG pAigPart = Aig_ManDupPartAll( pAig, vPart ); @@ -1460,7 +1464,7 @@ void Aig_ManChoiceConstructiveOne( Aig_Man_t * pNew, Aig_Man_t * pPrev, Aig_Man_ Aig_ManForEachObj( pNew, pObj, i ) pObj->fMarkB = 1; Aig_ManForEachObj( pPrev, pObj, i ) - assert( Aig_Regular(pObj->pData)->fMarkB ); + assert( Aig_Regular((Aig_Obj_t *)pObj->pData)->fMarkB ); Aig_ManForEachObj( pNew, pObj, i ) pObj->fMarkB = 0; // make sure the nodes of pThis point to pPrev @@ -1484,14 +1488,14 @@ void Aig_ManChoiceConstructiveOne( Aig_Man_t * pNew, Aig_Man_t * pPrev, Aig_Man_ if ( pObj->pHaig == NULL ) continue; // pObj->pData and pObj->pHaig->pData are equivalent - Aig_ObjSetRepr_( pNew, Aig_Regular(pObj->pData), Aig_Regular(pObj->pHaig->pData) ); + Aig_ObjSetRepr_( pNew, Aig_Regular((Aig_Obj_t *)pObj->pData), Aig_Regular((Aig_Obj_t *)pObj->pHaig->pData) ); } // set the inputs of POs as equivalent Aig_ManForEachPo( pThis, pObj, i ) { pObjNew = Aig_ObjFanin0( Aig_ManPo(pNew,i) ); // pObjNew and Aig_ObjFanin0(pObj)->pData are equivalent - Aig_ObjSetRepr_( pNew, pObjNew, Aig_Regular(Aig_ObjFanin0(pObj)->pData) ); + Aig_ObjSetRepr_( pNew, pObjNew, Aig_Regular((Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData) ); } } @@ -1548,7 +1552,7 @@ Aig_Man_t * Aig_ManChoiceConstructive( Vec_Ptr_t * vAigs, int fVerbose ) Aig_Man_t * pNew, * pThis, * pPrev, * pTemp; int i; // start AIG with choices - pPrev = Vec_PtrEntry( vAigs, 0 ); + pPrev = (Aig_Man_t *)Vec_PtrEntry( vAigs, 0 ); pNew = Aig_ManDupOrdered( pPrev ); // create room for equivalent nodes and representatives assert( pNew->pReprs == NULL ); @@ -1556,7 +1560,7 @@ Aig_Man_t * Aig_ManChoiceConstructive( Vec_Ptr_t * vAigs, int fVerbose ) pNew->pReprs = ABC_ALLOC( Aig_Obj_t *, pNew->nReprsAlloc ); memset( pNew->pReprs, 0, sizeof(Aig_Obj_t *) * pNew->nReprsAlloc ); // add other AIGs one by one - Vec_PtrForEachEntryStart( vAigs, pThis, i, 1 ) + Vec_PtrForEachEntryStart( Aig_Man_t *, vAigs, pThis, i, 1 ) { Aig_ManChoiceConstructiveOne( pNew, pPrev, pThis ); pPrev = pThis; @@ -1566,14 +1570,14 @@ Aig_Man_t * Aig_ManChoiceConstructive( Vec_Ptr_t * vAigs, int fVerbose ) // create the equivalent nodes lists Aig_ManMarkValidChoices( pNew ); // reconstruct the network - vPios = Aig_ManOrderPios( pNew, Vec_PtrEntry( vAigs, 0 ) ); + vPios = Aig_ManOrderPios( pNew, (Aig_Man_t *)Vec_PtrEntry( vAigs, 0 ) ); pNew = Aig_ManDupDfsGuided( pTemp = pNew, vPios ); Aig_ManStop( pTemp ); Vec_PtrFree( vPios ); // duplicate the timing manager - pTemp = Vec_PtrEntry( vAigs, 0 ); + pTemp = (Aig_Man_t *)Vec_PtrEntry( vAigs, 0 ); if ( pTemp->pManTime ) - pNew->pManTime = Tim_ManDup( pTemp->pManTime, 0 ); + pNew->pManTime = Tim_ManDup( (Tim_Man_t *)pTemp->pManTime, 0 ); // reset levels Aig_ManChoiceLevel( pNew ); return pNew; @@ -1590,3 +1594,5 @@ Aig_Man_t * Aig_ManChoiceConstructive( Vec_Ptr_t * vAigs, int fVerbose ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/aig/aigPartReg.c b/src/aig/aig/aigPartReg.c index dd10e91e..56fa80e4 100644 --- a/src/aig/aig/aigPartReg.c +++ b/src/aig/aig/aigPartReg.c @@ -21,6 +21,9 @@ #include "aig.h" //#include "fra.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -127,7 +130,7 @@ int Aig_ManRegFindSeed( Aig_ManPre_t * p ) if ( p->pfUsedRegs[i] ) continue; nRegsCur = 0; - vRegs = Vec_PtrEntry( p->vMatrix, i ); + vRegs = (Vec_Int_t *)Vec_PtrEntry( p->vMatrix, i ); Vec_IntForEachEntry( vRegs, iReg, k ) nRegsCur += !p->pfUsedRegs[iReg]; if ( nRegsMax < nRegsCur ) @@ -155,13 +158,13 @@ int Aig_ManRegFindBestVar( Aig_ManPre_t * p ) Vec_Int_t * vSupp; int nNewVars, nNewVarsBest = ABC_INFINITY; int iVarFree, iVarSupp, iVarBest = -1, i, k; - // go through the ABC_FREE variables + // go through the free variables Vec_IntForEachEntry( p->vFreeVars, iVarFree, i ) { // if ( p->pfUsedRegs[iVarFree] ) // continue; // get support of this variable - vSupp = Vec_PtrEntry( p->vMatrix, iVarFree ); + vSupp = (Vec_Int_t *)Vec_PtrEntry( p->vMatrix, iVarFree ); // count the number of new vars nNewVars = 0; Vec_IntForEachEntry( vSupp, iVarSupp, k ) @@ -205,7 +208,7 @@ void Aig_ManRegPartitionAdd( Aig_ManPre_t * p, int iReg ) p->pfUsedRegs[iReg] = 1; Vec_IntPush( p->vUniques, iReg ); } - // remove it from the ABC_FREE variables + // remove it from the free variables if ( Vec_IntSize(p->vFreeVars) > 0 ) { assert( p->pfPartVars[iReg] ); @@ -218,7 +221,7 @@ void Aig_ManRegPartitionAdd( Aig_ManPre_t * p, int iReg ) p->pfPartVars[iReg] = 1; Vec_IntPush( p->vRegs, iReg ); // add new variables - vSupp = Vec_PtrEntry( p->vMatrix, iReg ); + vSupp = (Vec_Int_t *)Vec_PtrEntry( p->vMatrix, iReg ); Vec_IntForEachEntry( vSupp, iVar, i ) { if ( p->pfPartVars[iVar] ) @@ -253,7 +256,7 @@ Vec_Ptr_t * Aig_ManRegProjectOnehots( Aig_Man_t * pAig, Aig_Man_t * pPart, Vec_P pObj->iData = i; // go through each group and check if registers are involved in this one nOffset = Aig_ManPiNum(pAig)-Aig_ManRegNum(pAig); - Vec_PtrForEachEntry( vOnehots, vGroup, i ) + Vec_PtrForEachEntry( Vec_Int_t *, vOnehots, vGroup, i ) { vGroupNew = NULL; Vec_IntForEachEntry( vGroup, iReg, k ) @@ -263,7 +266,7 @@ Vec_Ptr_t * Aig_ManRegProjectOnehots( Aig_Man_t * pAig, Aig_Man_t * pPart, Vec_P continue; if ( vGroupNew == NULL ) vGroupNew = Vec_IntAlloc( Vec_IntSize(vGroup) ); - pObjNew = pObj->pData; + pObjNew = (Aig_Obj_t *)pObj->pData; Vec_IntPush( vGroupNew, pObjNew->iData ); } if ( vGroupNew == NULL ) @@ -284,7 +287,7 @@ Vec_Ptr_t * Aig_ManRegProjectOnehots( Aig_Man_t * pAig, Aig_Man_t * pPart, Vec_P if ( vOnehotsPart && fVerbose ) { printf( "Partition contains %d groups of 1-hot registers: { ", Vec_PtrSize(vOnehotsPart) ); - Vec_PtrForEachEntry( vOnehotsPart, vGroup, k ) + Vec_PtrForEachEntry( Vec_Int_t *, vOnehotsPart, vGroup, k ) printf( "%d ", Vec_IntSize(vGroup) ); printf( "}\n" ); } @@ -335,7 +338,7 @@ Aig_Man_t * Aig_ManRegCreatePart( Aig_Man_t * pAig, Vec_Int_t * vPart, int * pnC nCountPis += Aig_ObjIsTravIdCurrent(pAig, pObj); // count outputs of other registers Aig_ManForEachLoSeq( pAig, pObj, i ) - nCountRegs += Aig_ObjIsTravIdCurrent(pAig, pObj); + nCountRegs += Aig_ObjIsTravIdCurrent(pAig, pObj); if ( pnCountPis ) *pnCountPis = nCountPis; if ( pnCountRegs ) @@ -354,11 +357,11 @@ Aig_Man_t * Aig_ManRegCreatePart( Aig_Man_t * pAig, Vec_Int_t * vPart, int * pnC { pObj = Aig_ManPi(pAig, nOffset+iOut); pObj->pData = Aig_ObjCreatePi(pNew); - Aig_ObjCreatePo( pNew, pObj->pData ); + Aig_ObjCreatePo( pNew, (Aig_Obj_t *)pObj->pData ); Aig_ObjSetTravIdCurrent( pAig, pObj ); // added } // create the nodes - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) if ( Aig_ObjIsNode(pObj) ) pObj->pData = Aig_And(pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); // add real POs for the registers @@ -377,9 +380,9 @@ Aig_Man_t * Aig_ManRegCreatePart( Aig_Man_t * pAig, Vec_Int_t * vPart, int * pnC // map constant nodes pMapBack[0] = 0; // logic cones of register outputs - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) { - pObjNew = Aig_Regular(pObj->pData); + pObjNew = Aig_Regular((Aig_Obj_t *)pObj->pData); pMapBack[pObjNew->Id] = pObj->Id; } // map register outputs @@ -387,7 +390,7 @@ Aig_Man_t * Aig_ManRegCreatePart( Aig_Man_t * pAig, Vec_Int_t * vPart, int * pnC Vec_IntForEachEntry( vPart, iOut, i ) { pObj = Aig_ManPi(pAig, nOffset+iOut); - pObjNew = pObj->pData; + pObjNew = (Aig_Obj_t *)pObj->pData; pMapBack[pObjNew->Id] = pObj->Id; } *ppMapBack = pMapBack; @@ -441,7 +444,7 @@ Vec_Ptr_t * Aig_ManRegPartitionSmart( Aig_Man_t * pAig, int nPartSize ) //printf( "Part %3d Reg %3d : Free = %4d. Total = %4d. Ratio = %6.2f. Unique = %4d.\n", i, k, // Vec_IntSize(p->vFreeVars), Vec_IntSize(p->vRegs), // 1.0*Vec_IntSize(p->vFreeVars)/Vec_IntSize(p->vRegs), Vec_IntSize(p->vUniques) ); - // quit if there are not ABC_FREE variables + // quit if there are not free variables if ( Vec_IntSize(p->vFreeVars) == 0 ) break; } @@ -622,3 +625,5 @@ Vec_Ptr_t * Aig_ManRegPartitionLinear( Aig_Man_t * pAig, int nPartSize ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/aig/aigPartSat.c b/src/aig/aig/aigPartSat.c index a8c9008f..3d9152ae 100644 --- a/src/aig/aig/aigPartSat.c +++ b/src/aig/aig/aigPartSat.c @@ -22,6 +22,9 @@ #include "satSolver.h" #include "cnf.h" +ABC_NAMESPACE_IMPL_START + + /* The node partitioners defined in this file return array of intergers @@ -80,7 +83,7 @@ Vec_Int_t * Aig_ManPartitionLevelized( Aig_Man_t * p, int nPartSize ) int i, k, Counter = 0; vNodes = Aig_ManLevelize( p ); vId2Part = Vec_IntStart( Aig_ManObjNumMax(p) ); - Vec_VecForEachEntryReverseReverse( vNodes, pObj, i, k ) + Vec_VecForEachEntryReverseReverse( Aig_Obj_t *, vNodes, pObj, i, k ) Vec_IntWriteEntry( vId2Part, Aig_ObjId(pObj), Counter++/nPartSize ); Vec_VecFree( vNodes ); return vId2Part; @@ -107,13 +110,13 @@ Vec_Int_t * Aig_ManPartitionDfs( Aig_Man_t * p, int nPartSize, int fPreorder ) if ( fPreorder ) { vNodes = Aig_ManDfsPreorder( p, 1 ); - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) Vec_IntWriteEntry( vId2Part, Aig_ObjId(pObj), Counter++/nPartSize ); } else { vNodes = Aig_ManDfs( p, 1 ); - Vec_PtrForEachEntryReverse( vNodes, pObj, i ) + Vec_PtrForEachEntryReverse( Aig_Obj_t *, vNodes, pObj, i ) Vec_IntWriteEntry( vId2Part, Aig_ObjId(pObj), Counter++/nPartSize ); } Vec_PtrFree( vNodes ); @@ -179,7 +182,7 @@ Aig_Man_t * Aig_ManPartSplitOne( Aig_Man_t * p, Vec_Ptr_t * vNodes, Vec_Int_t ** int i; // mark these nodes Aig_ManIncrementTravId( p ); - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) { Aig_ObjSetTravIdCurrent( p, pObj ); pObj->pData = NULL; @@ -187,14 +190,14 @@ Aig_Man_t * Aig_ManPartSplitOne( Aig_Man_t * p, Vec_Ptr_t * vNodes, Vec_Int_t ** // add these nodes in a DFS order pNew = Aig_ManStart( Vec_PtrSize(vNodes) ); vPio2Id = Vec_IntAlloc( 100 ); - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) Aig_ManPartSplitOne_rec( pNew, p, pObj, vPio2Id ); // add the POs - Vec_PtrForEachEntry( vNodes, pObj, i ) - if ( Aig_ObjRefs(pObj->pData) != Aig_ObjRefs(pObj) ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) + if ( Aig_ObjRefs((Aig_Obj_t *)pObj->pData) != Aig_ObjRefs(pObj) ) { - assert( Aig_ObjRefs(pObj->pData) < Aig_ObjRefs(pObj) ); - Aig_ObjCreatePo( pNew, pObj->pData ); + assert( Aig_ObjRefs((Aig_Obj_t *)pObj->pData) < Aig_ObjRefs(pObj) ); + Aig_ObjCreatePo( pNew, (Aig_Obj_t *)pObj->pData ); Vec_IntPush( vPio2Id, Aig_ObjId(pObj) ); } assert( Aig_ManNodeNum(pNew) == Vec_PtrSize(vNodes) ); @@ -440,7 +443,7 @@ int Aig_ManAddNewCnfToSolver( sat_solver * pSat, Aig_Man_t * pAig, Vec_Int_t * v // remove the CNF Cnf_DataFree( pCnf ); // constrain the solver with the literals corresponding to the original POs - Vec_PtrForEachEntry( vPartPos, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vPartPos, pObj, i ) { iNodeIdOld = Aig_ObjFaninId0( pObj ); iSatVarOld = Vec_IntEntry( vNode2Var, iNodeIdOld ); @@ -537,7 +540,7 @@ int Aig_ManPartitionedSat( Aig_Man_t * p, int nAlgo, int nPartSize, // synthesize partitions if ( fSynthesize ) - Vec_PtrForEachEntry( vAigs, pAig, i ) + Vec_PtrForEachEntry( Aig_Man_t *, vAigs, pAig, i ) { pAig = Dar_ManRwsat( pTemp = pAig, 0, 0 ); Vec_PtrWriteEntry( vAigs, i, pAig ); @@ -551,17 +554,17 @@ int Aig_ManPartitionedSat( Aig_Man_t * p, int nAlgo, int nPartSize, vNode2Var = Vec_IntStart( Aig_ManObjNumMax(p) ); // add partitions, one at a time, and run the SAT solver - Vec_PtrForEachEntry( vAigs, pAig, i ) + Vec_PtrForEachEntry( Aig_Man_t *, vAigs, pAig, i ) { clk = clock(); // transform polarity of the AIG if ( fAlignPol ) - Aig_ManPartSetNodePolarity( p, pAig, Vec_VecEntry(vPio2Id,i) ); + Aig_ManPartSetNodePolarity( p, pAig, (Vec_Int_t *)Vec_VecEntry(vPio2Id,i) ); else Aig_ManPartResetNodePolarity( pAig ); // add CNF of this partition to the SAT solver if ( Aig_ManAddNewCnfToSolver( pSat, pAig, vNode2Var, - Vec_VecEntry(vPio2Id,i), Vec_VecEntry(vPart2Pos,i), fAlignPol ) ) + (Vec_Int_t *)Vec_VecEntry(vPio2Id,i), (Vec_Ptr_t *)Vec_VecEntry(vPart2Pos,i), fAlignPol ) ) { RetValue = 1; break; @@ -596,7 +599,7 @@ ABC_PRT( "Time", clock() - clk ); Aig_ManDeriveCounterExample( p, vNode2Var, pSat ); // cleanup sat_solver_delete( pSat ); - Vec_PtrForEachEntry( vAigs, pTemp, i ) + Vec_PtrForEachEntry( Aig_Man_t *, vAigs, pTemp, i ) Aig_ManStop( pTemp ); Vec_PtrFree( vAigs ); Vec_VecFree( vPio2Id ); @@ -610,3 +613,5 @@ ABC_PRT( "Time", clock() - clk ); //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/aig/aigRepr.c b/src/aig/aig/aigRepr.c index 2d2f2f3d..9966174f 100644 --- a/src/aig/aig/aigRepr.c +++ b/src/aig/aig/aigRepr.c @@ -20,6 +20,9 @@ #include "aig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -188,8 +191,8 @@ static inline Aig_Obj_t * Aig_ObjGetRepr( Aig_Man_t * p, Aig_Obj_t * pObj ) { Aig_Obj_t * pRepr; if ( (pRepr = Aig_ObjFindRepr(p, pObj)) ) - return Aig_NotCond( pRepr->pData, pObj->fPhase ^ pRepr->fPhase ); - return pObj->pData; + return Aig_NotCond( (Aig_Obj_t *)pRepr->pData, pObj->fPhase ^ pRepr->fPhase ); + return (Aig_Obj_t *)pObj->pData; } static inline Aig_Obj_t * Aig_ObjChild0Repr( Aig_Man_t * p, Aig_Obj_t * pObj ) { return Aig_NotCond( Aig_ObjGetRepr(p, Aig_ObjFanin0(pObj)), Aig_ObjFaninC0(pObj) ); } static inline Aig_Obj_t * Aig_ObjChild1Repr( Aig_Man_t * p, Aig_Obj_t * pObj ) { return Aig_NotCond( Aig_ObjGetRepr(p, Aig_ObjFanin1(pObj)), Aig_ObjFaninC1(pObj) ); } @@ -221,7 +224,7 @@ void Aig_ManTransferRepr( Aig_Man_t * pNew, Aig_Man_t * pOld ) // go through the nodes which have representatives Aig_ManForEachObj( pOld, pObj, k ) if ( (pRepr = Aig_ObjFindRepr(pOld, pObj)) ) - Aig_ObjSetRepr_( pNew, Aig_Regular(pRepr->pData), Aig_Regular(pObj->pData) ); + Aig_ObjSetRepr_( pNew, Aig_Regular((Aig_Obj_t *)pRepr->pData), Aig_Regular((Aig_Obj_t *)pObj->pData) ); } /**Function************************************************************* @@ -239,15 +242,15 @@ Aig_Obj_t * Aig_ManDupRepr_rec( Aig_Man_t * pNew, Aig_Man_t * p, Aig_Obj_t * pOb { Aig_Obj_t * pRepr; if ( pObj->pData ) - return pObj->pData; + return (Aig_Obj_t *)pObj->pData; if ( (pRepr = Aig_ObjFindRepr(p, pObj)) ) { Aig_ManDupRepr_rec( pNew, p, pRepr ); - return pObj->pData = Aig_NotCond( pRepr->pData, pRepr->fPhase ^ pObj->fPhase ); + return (Aig_Obj_t *)(pObj->pData = Aig_NotCond( (Aig_Obj_t *)pRepr->pData, pRepr->fPhase ^ pObj->fPhase )); } Aig_ManDupRepr_rec( pNew, p, Aig_ObjFanin0(pObj) ); Aig_ManDupRepr_rec( pNew, p, Aig_ObjFanin1(pObj) ); - return pObj->pData = Aig_And( pNew, Aig_ObjChild0Repr(p, pObj), Aig_ObjChild1Repr(p, pObj) ); + return (Aig_Obj_t *)(pObj->pData = Aig_And( pNew, Aig_ObjChild0Repr(p, pObj), Aig_ObjChild1Repr(p, pObj) )); } /**Function************************************************************* @@ -270,6 +273,7 @@ Aig_Man_t * Aig_ManDupRepr( Aig_Man_t * p, int fOrdered ) pNew = Aig_ManStart( Aig_ManObjNumMax(p) ); pNew->pName = Aig_UtilStrsav( p->pName ); pNew->pSpec = Aig_UtilStrsav( p->pSpec ); + pNew->nConstrs = p->nConstrs; if ( p->vFlopNums ) pNew->vFlopNums = Vec_IntDup( p->vFlopNums ); // map the const and primary inputs @@ -327,7 +331,7 @@ Aig_Man_t * Aig_ManDupReprBasic( Aig_Man_t * p ) Aig_ManSeqCleanupBasic( pNew ); // remove pointers to the dead nodes Aig_ManForEachObj( p, pObj, i ) - if ( pObj->pData && Aig_ObjIsNone(pObj->pData) ) + if ( pObj->pData && Aig_ObjIsNone((Aig_Obj_t *)pObj->pData) ) pObj->pData = NULL; return pNew; } @@ -550,3 +554,5 @@ int Aig_TransferMappedClasses( Aig_Man_t * pAig, Aig_Man_t * pPart, int * pMapBa //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/aig/aigRet.c b/src/aig/aig/aigRet.c index 6dea6503..f7774d22 100644 --- a/src/aig/aig/aigRet.c +++ b/src/aig/aig/aigRet.c @@ -20,6 +20,9 @@ #include "aig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -76,28 +79,28 @@ static inline Rtm_Obj_t * Rtm_ObjFanout( Rtm_Obj_t * pObj, int i ) { retur static inline Rtm_Edg_t * Rtm_ObjEdge( Rtm_Obj_t * pObj, int i ) { return (Rtm_Edg_t *)(pObj->pFanio + 2*i + 1); } static inline Rtm_Edg_t * Rtm_ObjFanoutEdge( Rtm_Obj_t * pObj, int i ) { return (Rtm_Edg_t *)pObj->pFanio[2*(pObj->nFanins+i) + 1]; } -static inline Rtm_Init_t Rtm_InitNot( Rtm_Init_t Val ) { if ( Val == RTM_VAL_ZERO ) return RTM_VAL_ONE; if ( Val == RTM_VAL_ONE ) return RTM_VAL_ZERO; assert( 0 ); return -1; } +static inline Rtm_Init_t Rtm_InitNot( Rtm_Init_t Val ) { if ( Val == RTM_VAL_ZERO ) return (Rtm_Init_t)RTM_VAL_ONE; if ( Val == RTM_VAL_ONE ) return (Rtm_Init_t)RTM_VAL_ZERO; assert( 0 ); return (Rtm_Init_t)-1; } static inline Rtm_Init_t Rtm_InitNotCond( Rtm_Init_t Val, int c ) { return c ? Rtm_InitNot(Val) : Val; } -static inline Rtm_Init_t Rtm_InitAnd(Rtm_Init_t ValA, Rtm_Init_t ValB ) { if ( ValA == RTM_VAL_ONE && ValB == RTM_VAL_ONE ) return RTM_VAL_ONE; if ( ValA == RTM_VAL_ZERO || ValB == RTM_VAL_ZERO ) return RTM_VAL_ZERO; assert( 0 ); return -1; } +static inline Rtm_Init_t Rtm_InitAnd(Rtm_Init_t ValA, Rtm_Init_t ValB ) { if ( ValA == RTM_VAL_ONE && ValB == RTM_VAL_ONE ) return (Rtm_Init_t)RTM_VAL_ONE; if ( ValA == RTM_VAL_ZERO || ValB == RTM_VAL_ZERO ) return (Rtm_Init_t)RTM_VAL_ZERO; assert( 0 ); return (Rtm_Init_t)-1; } static inline int Rtm_InitWordsNum( int nLats ) { return (nLats >> 4) + ((nLats & 15) > 0); } static inline int Rtm_InitGetTwo( unsigned * p, int i ) { return (p[i>>4] >> ((i & 15)<<1)) & 3; } static inline void Rtm_InitSetTwo( unsigned * p, int i, int val ) { p[i>>4] |= (val << ((i & 15)<<1)); } static inline void Rtm_InitXorTwo( unsigned * p, int i, int val ) { p[i>>4] ^= (val << ((i & 15)<<1)); } -static inline Rtm_Init_t Rtm_ObjGetFirst1( Rtm_Edg_t * pEdge ) { return pEdge->LData & 3; } -static inline Rtm_Init_t Rtm_ObjGetLast1( Rtm_Edg_t * pEdge ) { return (pEdge->LData >> ((pEdge->nLats-1)<<1)) & 3; } -static inline Rtm_Init_t Rtm_ObjGetOne1( Rtm_Edg_t * pEdge, int i ) { assert( i < (int)pEdge->nLats ); return (pEdge->LData >> (i << 1)) & 3; } -static inline Rtm_Init_t Rtm_ObjRemFirst1( Rtm_Edg_t * pEdge ) { int Val = pEdge->LData & 3; pEdge->LData >>= 2; assert(pEdge->nLats > 0); pEdge->nLats--; return Val; } -static inline Rtm_Init_t Rtm_ObjRemLast1( Rtm_Edg_t * pEdge ) { int Val = (pEdge->LData >> ((pEdge->nLats-1)<<1)) & 3; pEdge->LData ^= Val << ((pEdge->nLats-1)<<1); assert(pEdge->nLats > 0); pEdge->nLats--; return Val; } +static inline Rtm_Init_t Rtm_ObjGetFirst1( Rtm_Edg_t * pEdge ) { return (Rtm_Init_t)(pEdge->LData & 3); } +static inline Rtm_Init_t Rtm_ObjGetLast1( Rtm_Edg_t * pEdge ) { return (Rtm_Init_t)((pEdge->LData >> ((pEdge->nLats-1)<<1)) & 3); } +static inline Rtm_Init_t Rtm_ObjGetOne1( Rtm_Edg_t * pEdge, int i ) { assert( i < (int)pEdge->nLats ); return (Rtm_Init_t)((pEdge->LData >> (i << 1)) & 3); } +static inline Rtm_Init_t Rtm_ObjRemFirst1( Rtm_Edg_t * pEdge ) { int Val = pEdge->LData & 3; pEdge->LData >>= 2; assert(pEdge->nLats > 0); pEdge->nLats--; return (Rtm_Init_t)Val; } +static inline Rtm_Init_t Rtm_ObjRemLast1( Rtm_Edg_t * pEdge ) { int Val = (pEdge->LData >> ((pEdge->nLats-1)<<1)) & 3; pEdge->LData ^= Val << ((pEdge->nLats-1)<<1); assert(pEdge->nLats > 0); pEdge->nLats--; return (Rtm_Init_t)Val; } static inline void Rtm_ObjAddFirst1( Rtm_Edg_t * pEdge, Rtm_Init_t Val ) { assert( Val > 0 && Val < 4 ); pEdge->LData = (pEdge->LData << 2) | Val; pEdge->nLats++; } static inline void Rtm_ObjAddLast1( Rtm_Edg_t * pEdge, Rtm_Init_t Val ) { assert( Val > 0 && Val < 4 ); pEdge->LData |= Val << (pEdge->nLats<<1); pEdge->nLats++; } -static inline Rtm_Init_t Rtm_ObjGetFirst2( Rtm_Man_t * p, Rtm_Edg_t * pEdge ) { return Rtm_InitGetTwo( p->pExtra + pEdge->LData, 0 ); } -static inline Rtm_Init_t Rtm_ObjGetLast2( Rtm_Man_t * p, Rtm_Edg_t * pEdge ) { return Rtm_InitGetTwo( p->pExtra + pEdge->LData, pEdge->nLats - 1 ); } -static inline Rtm_Init_t Rtm_ObjGetOne2( Rtm_Man_t * p, Rtm_Edg_t * pEdge, int i ) { return Rtm_InitGetTwo( p->pExtra + pEdge->LData, i ); } +static inline Rtm_Init_t Rtm_ObjGetFirst2( Rtm_Man_t * p, Rtm_Edg_t * pEdge ) { return (Rtm_Init_t)Rtm_InitGetTwo( p->pExtra + pEdge->LData, 0 ); } +static inline Rtm_Init_t Rtm_ObjGetLast2( Rtm_Man_t * p, Rtm_Edg_t * pEdge ) { return (Rtm_Init_t)Rtm_InitGetTwo( p->pExtra + pEdge->LData, pEdge->nLats - 1 ); } +static inline Rtm_Init_t Rtm_ObjGetOne2( Rtm_Man_t * p, Rtm_Edg_t * pEdge, int i ) { return (Rtm_Init_t)Rtm_InitGetTwo( p->pExtra + pEdge->LData, i ); } static Rtm_Init_t Rtm_ObjRemFirst2( Rtm_Man_t * p, Rtm_Edg_t * pEdge ); -static inline Rtm_Init_t Rtm_ObjRemLast2( Rtm_Man_t * p, Rtm_Edg_t * pEdge ) { Rtm_Init_t Val = Rtm_ObjGetLast2( p, pEdge ); Rtm_InitXorTwo( p->pExtra + pEdge->LData, pEdge->nLats - 1, Val ); pEdge->nLats--; return Val; } +static inline Rtm_Init_t Rtm_ObjRemLast2( Rtm_Man_t * p, Rtm_Edg_t * pEdge ) { Rtm_Init_t Val = Rtm_ObjGetLast2( p, pEdge ); Rtm_InitXorTwo( p->pExtra + pEdge->LData, pEdge->nLats - 1, Val ); pEdge->nLats--; return (Rtm_Init_t)Val; } static void Rtm_ObjAddFirst2( Rtm_Man_t * p, Rtm_Edg_t * pEdge, Rtm_Init_t Val ); static inline void Rtm_ObjAddLast2( Rtm_Man_t * p, Rtm_Edg_t * pEdge, Rtm_Init_t Val ) { Rtm_InitSetTwo( p->pExtra + pEdge->LData, pEdge->nLats, Val ); pEdge->nLats++; } @@ -116,13 +119,13 @@ static void Rtm_ObjAddLast( Rtm_Man_t * p, Rtm_Edg_t * pEdge, Rtm_ // iterator over the primary inputs #define Rtm_ManForEachPi( p, pObj, i ) \ - Vec_PtrForEachEntry( p->vPis, pObj, i ) + Vec_PtrForEachEntry( Rtm_Obj_t *, p->vPis, pObj, i ) // iterator over the primary outputs #define Rtm_ManForEachPo( p, pObj, i ) \ - Vec_PtrForEachEntry( p->vPos, pObj, i ) + Vec_PtrForEachEntry( Rtm_Obj_t *, p->vPos, pObj, i ) // iterator over all objects, including those currently not used #define Rtm_ManForEachObj( p, pObj, i ) \ - Vec_PtrForEachEntry( p->vObjs, pObj, i ) + Vec_PtrForEachEntry( Rtm_Obj_t *, p->vObjs, pObj, i ) // iterate through the fanins #define Rtm_ObjForEachFanin( pObj, pFanin, i ) \ for ( i = 0; i < (int)(pObj)->nFanins && ((pFanin = Rtm_ObjFanin(pObj, i)), 1); i++ ) @@ -222,11 +225,11 @@ void Rtm_ObjTransferToBigger( Rtm_Man_t * p, Rtm_Edg_t * pEdge ) ***********************************************************************/ Rtm_Init_t Rtm_ObjRemFirst2( Rtm_Man_t * p, Rtm_Edg_t * pEdge ) { - Rtm_Init_t Val = 0, Temp; + Rtm_Init_t Val = (Rtm_Init_t)0, Temp; unsigned * pB = p->pExtra + pEdge->LData, * pE = pB + Rtm_InitWordsNum( pEdge->nLats-- ) - 1; while ( pE >= pB ) { - Temp = *pE & 3; + Temp = (Rtm_Init_t)(*pE & 3); *pE = (*pE >> 2) | (Val << 30); Val = Temp; pE--; @@ -253,7 +256,7 @@ void Rtm_ObjAddFirst2( Rtm_Man_t * p, Rtm_Edg_t * pEdge, Rtm_Init_t Val ) assert( Val != 0 ); while ( pB < pE ) { - Temp = *pB >> 30; + Temp = (Rtm_Init_t)(*pB >> 30); *pB = (*pB << 2) | Val; Val = Temp; pB++; @@ -590,7 +593,7 @@ int Rtm_ManMarkAutoFwd( Rtm_Man_t * pRtm ) Rtm_Obj_t * pObjRtm; int i, Counter = 0; // mark nodes reachable from the PIs - pObjRtm = Vec_PtrEntry( pRtm->vObjs, 0 ); + pObjRtm = (Rtm_Obj_t *)Vec_PtrEntry( pRtm->vObjs, 0 ); Rtm_ObjMarkAutoFwd_rec( pObjRtm ); Rtm_ManForEachPi( pRtm, pObjRtm, i ) Rtm_ObjMarkAutoFwd_rec( pObjRtm ); @@ -642,7 +645,7 @@ int Rtm_ManMarkAutoBwd( Rtm_Man_t * pRtm ) Rtm_Obj_t * pObjRtm; int i, Counter = 0; // mark nodes reachable from the PIs - pObjRtm = Vec_PtrEntry( pRtm->vObjs, 0 ); + pObjRtm = (Rtm_Obj_t *)Vec_PtrEntry( pRtm->vObjs, 0 ); pObjRtm->fAuto = 1; Rtm_ManForEachPi( pRtm, pObjRtm, i ) pObjRtm->fAuto = 1; @@ -699,15 +702,15 @@ Rtm_Man_t * Rtm_ManFromAig( Aig_Man_t * p ) pObj->pData = Rtm_ObjAlloc( pRtm, 2, pObj->nRefs ); // connect objects Aig_ManForEachPoSeq( p, pObj, i ) - Rtm_ObjAddFanin( pObj->pData, Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0(pObj) ); + Rtm_ObjAddFanin( (Rtm_Obj_t *)pObj->pData, (Rtm_Obj_t *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0(pObj) ); Aig_ManForEachLiSeq( p, pObj, i ) - Rtm_ObjAddFanin( pObj->pData, Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0(pObj) ); + Rtm_ObjAddFanin( (Rtm_Obj_t *)pObj->pData, (Rtm_Obj_t *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0(pObj) ); Aig_ManForEachLiLoSeq( p, pObjLi, pObjLo, i ) - Rtm_ObjAddFanin( pObjLo->pData, pObjLi->pData, 0 ); + Rtm_ObjAddFanin( (Rtm_Obj_t *)pObjLo->pData, (Rtm_Obj_t *)pObjLi->pData, 0 ); Aig_ManForEachNode( p, pObj, i ) { - Rtm_ObjAddFanin( pObj->pData, Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0(pObj) ); - Rtm_ObjAddFanin( pObj->pData, Aig_ObjFanin1(pObj)->pData, Aig_ObjFaninC1(pObj) ); + Rtm_ObjAddFanin( (Rtm_Obj_t *)pObj->pData, (Rtm_Obj_t *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0(pObj) ); + Rtm_ObjAddFanin( (Rtm_Obj_t *)pObj->pData, (Rtm_Obj_t *)Aig_ObjFanin1(pObj)->pData, Aig_ObjFaninC1(pObj) ); } return pRtm; } @@ -729,7 +732,7 @@ Aig_Obj_t * Rtm_ManToAig_rec( Aig_Man_t * pNew, Rtm_Man_t * pRtm, Rtm_Obj_t * pO Aig_Obj_t * pRes, * pFanin; int k, Val; if ( pObjRtm->pCopy ) - return pObjRtm->pCopy; + return (Aig_Obj_t *)pObjRtm->pCopy; // get the inputs pRes = Aig_ManConst1( pNew ); Rtm_ObjForEachFaninEdge( pObjRtm, pEdge, k ) @@ -745,7 +748,7 @@ Aig_Obj_t * Rtm_ManToAig_rec( Aig_Man_t * pNew, Rtm_Man_t * pRtm, Rtm_Obj_t * pO pFanin = Aig_NotCond( pFanin, k ? pObjRtm->fCompl1 : pObjRtm->fCompl0 ); pRes = Aig_And( pNew, pRes, pFanin ); } - return pObjRtm->pCopy = pRes; + return (Aig_Obj_t *)(pObjRtm->pCopy = pRes); } /**Function************************************************************* @@ -778,7 +781,7 @@ Aig_Man_t * Rtm_ManToAig( Rtm_Man_t * pRtm ) // create the new manager pNew = Aig_ManStart( Vec_PtrSize(pRtm->vObjs) + nLatches ); // create PIs/POs and latches - pObjRtm = Vec_PtrEntry( pRtm->vObjs, 0 ); + pObjRtm = (Rtm_Obj_t *)Vec_PtrEntry( pRtm->vObjs, 0 ); pObjRtm->pCopy = Aig_ManConst1(pNew); Rtm_ManForEachPi( pRtm, pObjRtm, i ) pObjRtm->pCopy = Aig_ObjCreatePi(pNew); @@ -789,14 +792,14 @@ Aig_Man_t * Rtm_ManToAig( Rtm_Man_t * pRtm ) Rtm_ManToAig_rec( pNew, pRtm, pObjRtm, pLatches ); // create POs Rtm_ManForEachPo( pRtm, pObjRtm, i ) - Aig_ObjCreatePo( pNew, pObjRtm->pCopy ); + Aig_ObjCreatePo( pNew, (Aig_Obj_t *)pObjRtm->pCopy ); // connect latches Rtm_ManForEachObj( pRtm, pObjRtm, i ) Rtm_ObjForEachFaninEdge( pObjRtm, pEdge, k ) { if ( pEdge->nLats == 0 ) continue; - pObjNew = Rtm_ObjFanin( pObjRtm, k )->pCopy; + pObjNew = (Aig_Obj_t *)Rtm_ObjFanin( pObjRtm, k )->pCopy; for ( m = 0; m < (int)pEdge->nLats; m++ ) { Val = Rtm_ObjGetOne( pRtm, pEdge, pEdge->nLats - 1 - m ); @@ -843,7 +846,7 @@ clk = clock(); pRtm = Rtm_ManFromAig( p ); // set registers Aig_ManForEachLoSeq( p, pObjAig, i ) - Rtm_ObjAddFirst( pRtm, Rtm_ObjEdge(pObjAig->pData, 0), fForward? RTM_VAL_ZERO : RTM_VAL_VOID ); + Rtm_ObjAddFirst( pRtm, Rtm_ObjEdge((Rtm_Obj_t *)pObjAig->pData, 0), fForward? RTM_VAL_ZERO : RTM_VAL_VOID ); // detect and mark the autonomous components if ( fForward ) nAutos = Rtm_ManMarkAutoFwd( pRtm ); @@ -870,7 +873,7 @@ clk = clock(); { Aig_ManForEachLoSeq( p, pObjAig, i ) { - pObj = pObjAig->pData; + pObj = (Rtm_Obj_t *)pObjAig->pData; if ( pObj->fAuto ) continue; pObj->fMark = 1; @@ -881,7 +884,7 @@ clk = clock(); { Aig_ManForEachLiSeq( p, pObjAig, i ) { - pObj = pObjAig->pData; + pObj = (Rtm_Obj_t *)pObjAig->pData; if ( pObj->fAuto ) continue; pObj->fMark = 1; @@ -890,7 +893,7 @@ clk = clock(); } // perform retiming DegreeMax = 0; - Vec_PtrForEachEntry( vQueue, pObj, i ) + Vec_PtrForEachEntry( Rtm_Obj_t *, vQueue, pObj, i ) { pObj->fMark = 0; // retime the node @@ -968,3 +971,5 @@ clk = clock(); //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/aig/aigRetF.c b/src/aig/aig/aigRetF.c index f045cac8..0a866c30 100644 --- a/src/aig/aig/aigRetF.c +++ b/src/aig/aig/aigRetF.c @@ -20,6 +20,9 @@ #include "aig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -207,3 +210,5 @@ Aig_Man_t * Aig_ManRetimeFrontier( Aig_Man_t * p, int nStepsMax ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/aig/aigScl.c b/src/aig/aig/aigScl.c index b6331b0e..e31ab74b 100644 --- a/src/aig/aig/aigScl.c +++ b/src/aig/aig/aigScl.c @@ -20,6 +20,9 @@ #include "aig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -50,6 +53,7 @@ Aig_Man_t * Aig_ManRemap( Aig_Man_t * p, Vec_Ptr_t * vMap ) pNew->pName = Aig_UtilStrsav( p->pName ); pNew->pSpec = Aig_UtilStrsav( p->pSpec ); pNew->nAsserts = p->nAsserts; + pNew->nConstrs = p->nConstrs; assert( p->vFlopNums == NULL || Vec_IntSize(p->vFlopNums) == p->nRegs ); if ( p->vFlopNums ) pNew->vFlopNums = Vec_IntDup( p->vFlopNums ); @@ -69,8 +73,8 @@ Aig_Man_t * Aig_ManRemap( Aig_Man_t * p, Vec_Ptr_t * vMap ) } Aig_ManForEachPi( p, pObj, i ) { - pObjMapped = Vec_PtrEntry( vMap, i ); - pObj->pData = Aig_NotCond( Aig_Regular(pObjMapped)->pData, Aig_IsComplement(pObjMapped) ); + pObjMapped = (Aig_Obj_t *)Vec_PtrEntry( vMap, i ); + pObj->pData = Aig_NotCond( (Aig_Obj_t *)Aig_Regular(pObjMapped)->pData, Aig_IsComplement(pObjMapped) ); if ( pNew->vFlopReprs && i >= nTruePis && pObj != pObjMapped ) { Vec_IntPush( pNew->vFlopReprs, Aig_ObjPioNum(pObj) ); @@ -172,7 +176,7 @@ int Aig_ManSeqCleanup( Aig_Man_t * p ) Aig_ManForEachLiLoSeq( p, pObjLi, pObjLo, i ) pObjLo->pNext = pObjLi; // mark the nodes reachable from these nodes - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) Aig_ManSeqCleanup_rec( p, pObj, vNodes ); assert( Vec_PtrSize(vNodes) <= Aig_ManPoNum(p) ); // clean latch output pointers @@ -271,7 +275,7 @@ int Aig_ManSeqCleanupBasic( Aig_Man_t * p ) Aig_ManForEachLiLoSeq( p, pObjLi, pObjLo, i ) pObjLo->pNext = pObjLi; // mark the nodes reachable from these nodes - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) Aig_ManSeqCleanup_rec( p, pObj, vNodes ); assert( Vec_PtrSize(vNodes) <= Aig_ManPoNum(p) ); // clean latch output pointers @@ -496,7 +500,7 @@ void Aig_ManComputeSccs( Aig_Man_t * p ) vSupports = Aig_ManSupports( p ); // transforms the supports into the latch dependency matrix vMatrix = Vec_PtrStart( Aig_ManRegNum(p) ); - Vec_PtrForEachEntry( vSupports, vSupp, i ) + Vec_PtrForEachEntry( Vec_Int_t *, vSupports, vSupp, i ) { // skip true POs iOut = Vec_IntPop( vSupp ); @@ -522,11 +526,11 @@ void Aig_ManComputeSccs( Aig_Man_t * p ) vMatrix2 = Vec_PtrAlloc( Aig_ManRegNum(p) ); for ( i = 0; i < Aig_ManRegNum(p); i++ ) Vec_PtrPush( vMatrix2, Vec_IntAlloc(8) ); - Vec_PtrForEachEntry( vMatrix, vSupp, i ) + Vec_PtrForEachEntry( Vec_Int_t *, vMatrix, vSupp, i ) { Vec_IntForEachEntry( vSupp, iIn, k ) { - vSupp2 = Vec_PtrEntry( vMatrix2, iIn ); + vSupp2 = (Vec_Int_t *)Vec_PtrEntry( vMatrix2, iIn ); Vec_IntPush( vSupp2, i ); } } @@ -548,7 +552,7 @@ void Aig_ManComputeSccs( Aig_Man_t * p ) Vec_IntPush( vComp, iOut ); Vec_IntForEachEntry( vComp, iOut, i ) { - vSupp = Vec_PtrEntry( vMatrix, iOut ); + vSupp = (Vec_Int_t *)Vec_PtrEntry( vMatrix, iOut ); Vec_IntForEachEntry( vSupp, iIn, k ) { if ( pVarsTot[iIn] ) @@ -556,7 +560,7 @@ void Aig_ManComputeSccs( Aig_Man_t * p ) pVarsTot[iIn] = 1; Vec_IntPush( vComp, iIn ); } - vSupp2 = Vec_PtrEntry( vMatrix2, iOut ); + vSupp2 = (Vec_Int_t *)Vec_PtrEntry( vMatrix2, iOut ); Vec_IntForEachEntry( vSupp2, iIn, k ) { if ( pVarsTot[iIn] ) @@ -602,14 +606,14 @@ Aig_Man_t * Aig_ManSclPart( Aig_Man_t * pAig, int fLatchConst, int fLatchEqual, if ( pAig->vClockDoms ) { vResult = Vec_PtrAlloc( 100 ); - Vec_PtrForEachEntry( (Vec_Ptr_t *)pAig->vClockDoms, vPart, i ) + Vec_PtrForEachEntry( Vec_Int_t *, (Vec_Ptr_t *)pAig->vClockDoms, vPart, i ) Vec_PtrPush( vResult, Vec_IntDup(vPart) ); } else vResult = Aig_ManRegPartitionSimple( pAig, 0, 0 ); Aig_ManReprStart( pAig, Aig_ManObjNumMax(pAig) ); - Vec_PtrForEachEntry( vResult, vPart, i ) + Vec_PtrForEachEntry( Vec_Int_t *, vResult, vPart, i ) { pTemp = Aig_ManRegCreatePart( pAig, vPart, &nCountPis, &nCountRegs, &pMapBack ); Aig_ManSetRegNum( pTemp, pTemp->nRegs ); @@ -699,3 +703,5 @@ Aig_Man_t * Aig_ManScl( Aig_Man_t * pAig, int fLatchConst, int fLatchEqual, int //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/aig/aigShow.c b/src/aig/aig/aigShow.c index 1e9e10ac..24b122c3 100644 --- a/src/aig/aig/aigShow.c +++ b/src/aig/aig/aigShow.c @@ -20,6 +20,9 @@ #include "aig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -59,7 +62,7 @@ void Aig_WriteDotAig( Aig_Man_t * pMan, char * pFileName, int fHaig, Vec_Ptr_t * // mark the nodes if ( vBold ) - Vec_PtrForEachEntry( vBold, pNode, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vBold, pNode, i ) pNode->fMarkB = 1; // compute levels @@ -308,7 +311,7 @@ void Aig_WriteDotAig( Aig_Man_t * pMan, char * pFileName, int fHaig, Vec_Ptr_t * // unmark nodes if ( vBold ) - Vec_PtrForEachEntry( vBold, pNode, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vBold, pNode, i ) pNode->fMarkB = 0; Aig_ManForEachPo( pMan, pNode, i ) @@ -354,3 +357,5 @@ void Aig_ManShow( Aig_Man_t * pMan, int fHaig, Vec_Ptr_t * vBold ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/aig/aigSplit.c b/src/aig/aig/aigSplit.c new file mode 100644 index 00000000..51b4f982 --- /dev/null +++ b/src/aig/aig/aigSplit.c @@ -0,0 +1,316 @@ +/**CFile**************************************************************** + + FileName [aigSplit.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [AIG package.] + + Synopsis [Splits the property output cone into a set of cofactor properties.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - April 28, 2007.] + + Revision [$Id: aigSplit.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "aig.h" +#include "saig.h" +#include "cuddInt.h" +#include "extra.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Converts the node to MUXes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Aig_NodeBddToMuxes_rec( DdManager * dd, DdNode * bFunc, Aig_Man_t * pNew, st_table * tBdd2Node ) +{ + Aig_Obj_t * pNode, * pNode0, * pNode1, * pNodeC; + assert( !Cudd_IsComplement(bFunc) ); + if ( st_lookup( tBdd2Node, (char *)bFunc, (char **)&pNode ) ) + return pNode; + // solve for the children nodes + pNode0 = Aig_NodeBddToMuxes_rec( dd, Cudd_Regular(cuddE(bFunc)), pNew, tBdd2Node ); + pNode0 = Aig_NotCond( pNode0, Cudd_IsComplement(cuddE(bFunc)) ); + pNode1 = Aig_NodeBddToMuxes_rec( dd, cuddT(bFunc), pNew, tBdd2Node ); + if ( !st_lookup( tBdd2Node, (char *)Cudd_bddIthVar(dd, bFunc->index), (char **)&pNodeC ) ) + assert( 0 ); + // create the MUX node + pNode = Aig_Mux( pNew, pNodeC, pNode1, pNode0 ); + st_insert( tBdd2Node, (char *)bFunc, (char *)pNode ); + return pNode; +} + +/**Function************************************************************* + + Synopsis [Derives AIG for the BDDs of the cofactors.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Aig_ManConvertBddsToAigs( Aig_Man_t * p, DdManager * dd, Vec_Ptr_t * vCofs ) +{ + DdNode * bFunc; + st_table * tBdd2Node; + Aig_Man_t * pNew; + Aig_Obj_t * pObj; + int i; + Aig_ManCleanData( p ); + // generate AIG for BDD + pNew = Aig_ManStart( Aig_ManObjNum(p) ); + pNew->pName = Aig_UtilStrsav( p->pName ); + Aig_ManConst1(p)->pData = Aig_ManConst1(pNew); + Aig_ManForEachPi( p, pObj, i ) + pObj->pData = Aig_ObjCreatePi( pNew ); + // create the table mapping BDD nodes into the ABC nodes + tBdd2Node = st_init_table( st_ptrcmp, st_ptrhash ); + // add the constant and the elementary vars + st_insert( tBdd2Node, (char *)Cudd_ReadOne(dd), (char *)Aig_ManConst1(pNew) ); + Aig_ManForEachPi( p, pObj, i ) + st_insert( tBdd2Node, (char *)Cudd_bddIthVar(dd, i), (char *)pObj->pData ); + // build primary outputs for the cofactors + Vec_PtrForEachEntry( DdNode *, vCofs, bFunc, i ) + { + if ( bFunc == Cudd_ReadLogicZero(dd) ) + continue; + pObj = Aig_NodeBddToMuxes_rec( dd, Cudd_Regular(bFunc), pNew, tBdd2Node ); + pObj = Aig_NotCond( pObj, Cudd_IsComplement(bFunc) ); + Aig_ObjCreatePo( pNew, pObj ); + } + st_free_table( tBdd2Node ); + + // duplicate the rest of the AIG + // add the POs + Aig_ManForEachPo( p, pObj, i ) + { + if ( i == 0 ) + continue; + Aig_ManDupSimpleDfs_rec( pNew, p, Aig_ObjFanin0(pObj) ); + pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) ); + } + Aig_ManCleanup( pNew ); + Aig_ManSetRegNum( pNew, Aig_ManRegNum(p) ); + // check the resulting network + if ( !Aig_ManCheck(pNew) ) + printf( "Aig_ManConvertBddsToAigs(): The check has failed.\n" ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Returns the array of constraint candidates.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * Aig_ManBuildPoBdd_rec( Aig_Man_t * p, Aig_Obj_t * pObj, DdManager * dd ) +{ + DdNode * bBdd0, * bBdd1; + if ( pObj->pData != NULL ) + return (DdNode *)pObj->pData; + assert( Aig_ObjIsNode(pObj) ); + bBdd0 = Aig_ManBuildPoBdd_rec( p, Aig_ObjFanin0(pObj), dd ); + bBdd1 = Aig_ManBuildPoBdd_rec( p, Aig_ObjFanin1(pObj), dd ); + bBdd0 = Cudd_NotCond( bBdd0, Aig_ObjFaninC0(pObj) ); + bBdd1 = Cudd_NotCond( bBdd1, Aig_ObjFaninC1(pObj) ); + pObj->pData = Cudd_bddAnd( dd, bBdd0, bBdd1 ); Cudd_Ref( (DdNode *)pObj->pData ); + return (DdNode *)pObj->pData; +} + +/**Function************************************************************* + + Synopsis [Derive BDDs for the cofactors.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Aig_ManCofactorBdds( Aig_Man_t * p, Vec_Ptr_t * vSubset, DdManager * dd, DdNode * bFunc ) +{ + Vec_Ptr_t * vCofs; + DdNode * bCube, * bTemp, * bCof, ** pbVars; + int i; + vCofs = Vec_PtrAlloc( 100 ); + pbVars = (DdNode **)Vec_PtrArray(vSubset); + for ( i = 0; i < (1 << Vec_PtrSize(vSubset)); i++ ) + { + bCube = Extra_bddBitsToCube( dd, i, Vec_PtrSize(vSubset), pbVars, 1 ); Cudd_Ref( bCube ); + bCof = Cudd_Cofactor( dd, bFunc, bCube ); Cudd_Ref( bCof ); + bCof = Cudd_bddAnd( dd, bTemp = bCof, bCube ); Cudd_Ref( bCof ); + Cudd_RecursiveDeref( dd, bTemp ); + Cudd_RecursiveDeref( dd, bCube ); + Vec_PtrPush( vCofs, bCof ); + } + return vCofs; +} + +/**Function************************************************************* + + Synopsis [Construct BDDs for the primary output.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdManager * Aig_ManBuildPoBdd( Aig_Man_t * p, DdNode ** pbFunc ) +{ + DdManager * dd; + Aig_Obj_t * pObj; + int i; + assert( Saig_ManPoNum(p) == 1 ); + Aig_ManCleanData( p ); + dd = Cudd_Init( Aig_ManPiNum(p), 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 ); + Cudd_AutodynEnable( dd, CUDD_REORDER_SYMM_SIFT ); + pObj = Aig_ManConst1(p); + pObj->pData = Cudd_ReadOne(dd); Cudd_Ref( (DdNode *)pObj->pData ); + Aig_ManForEachPi( p, pObj, i ) + { + pObj->pData = Cudd_bddIthVar(dd, i); Cudd_Ref( (DdNode *)pObj->pData ); + } + pObj = Aig_ManPo( p, 0 ); + *pbFunc = Aig_ManBuildPoBdd_rec( p, Aig_ObjFanin0(pObj), dd ); Cudd_Ref( *pbFunc ); + *pbFunc = Cudd_NotCond( *pbFunc, Aig_ObjFaninC0(pObj) ); + Aig_ManForEachObj( p, pObj, i ) + { + if ( pObj->pData ) + Cudd_RecursiveDeref( dd, (DdNode *)pObj->pData ); + } + Cudd_ReduceHeap( dd, CUDD_REORDER_SYMM_SIFT, 1 ); + return dd; +} + +/**Function************************************************************* + + Synopsis [Randomly selects a random subset of inputs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Aig_ManVecRandSubset( Vec_Ptr_t * vVec, int nVars ) +{ + Vec_Ptr_t * vRes; + void * pEntry; + unsigned Rand; + vRes = Vec_PtrDup(vVec); + while ( Vec_PtrSize(vRes) > nVars ) + { + Rand = Aig_ManRandom( 0 ); + pEntry = Vec_PtrEntry( vRes, Rand % Vec_PtrSize(vRes) ); + Vec_PtrRemove( vRes, pEntry ); + } + return vRes; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Aig_ManSplit( Aig_Man_t * p, int nVars, int fVerbose ) +{ + Aig_Man_t * pRes; + Aig_Obj_t * pNode; + DdNode * bFunc; + DdManager * dd; + Vec_Ptr_t * vSupp, * vSubs, * vCofs; + int i, clk = clock(); + if ( Saig_ManPoNum(p) != 1 ) + { + printf( "Currently works only for one primary output.\n" ); + return NULL; + } + if ( nVars < 1 ) + { + printf( "The number of cofactoring variables should be a positive number.\n" ); + return NULL; + } + if ( nVars > 16 ) + { + printf( "The number of cofactoring variables should be less than 17.\n" ); + return NULL; + } + vSupp = Aig_Support( p, Aig_ObjFanin0(Aig_ManPo(p,0)) ); + if ( Vec_PtrSize(vSupp) == 0 ) + { + printf( "Property output function is a constant.\n" ); + Vec_PtrFree( vSupp ); + return NULL; + } + dd = Aig_ManBuildPoBdd( p, &bFunc ); // bFunc is referenced + if ( fVerbose ) + printf( "Support =%5d. BDD size =%6d. ", Vec_PtrSize(vSupp), Cudd_DagSize(bFunc) ); + vSubs = Aig_ManVecRandSubset( vSupp, nVars ); + // replace nodes by their BDD variables + Vec_PtrForEachEntry( Aig_Obj_t *, vSubs, pNode, i ) + Vec_PtrWriteEntry( vSubs, i, pNode->pData ); + // derive cofactors and functions + vCofs = Aig_ManCofactorBdds( p, vSubs, dd, bFunc ); + pRes = Aig_ManConvertBddsToAigs( p, dd, vCofs ); + Vec_PtrFree( vSupp ); + Vec_PtrFree( vSubs ); + if ( fVerbose ) + printf( "Created %d cofactors (out of %d). ", Saig_ManPoNum(pRes), Vec_PtrSize(vCofs) ); + if ( fVerbose ) + Abc_PrintTime( 1, "Time", clock() - clk ); + // dereference + Cudd_RecursiveDeref( dd, bFunc ); + Vec_PtrForEachEntry( DdNode *, vCofs, bFunc, i ) + Cudd_RecursiveDeref( dd, bFunc ); + Vec_PtrFree( vCofs ); + Extra_StopManager( dd ); + return pRes; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/aig/aigTable.c b/src/aig/aig/aigTable.c index 81635357..13826065 100644 --- a/src/aig/aig/aigTable.c +++ b/src/aig/aig/aigTable.c @@ -20,6 +20,9 @@ #include "aig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -269,3 +272,5 @@ void Aig_TableClear( Aig_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/aig/aigTest.c b/src/aig/aig/aigTest.c index b97ffb03..42c81c3f 100644 --- a/src/aig/aig/aigTest.c +++ b/src/aig/aig/aigTest.c @@ -2,6 +2,9 @@ #include "aig.h" +ABC_NAMESPACE_IMPL_START + + void Aig_ProcedureTest() { Aig_Man_t * p; @@ -32,4 +35,5 @@ void Aig_ProcedureTest() Aig_ManDumpBlif( p, "aig_test_file.blif", NULL, NULL ); Aig_ManStop( p ); -}
\ No newline at end of file +}ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/aig/aigTiming.c b/src/aig/aig/aigTiming.c index d0cc99e3..4ea93e29 100644 --- a/src/aig/aig/aigTiming.c +++ b/src/aig/aig/aigTiming.c @@ -20,6 +20,9 @@ #include "aig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -150,7 +153,7 @@ void Aig_ManStartReverseLevels( Aig_Man_t * p, int nMaxLevelIncrease ) Vec_IntFill( p->vLevelR, Aig_ManObjNumMax(p), 0 ); // compute levels in reverse topological order vNodes = Aig_ManDfsReverse( p ); - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) { assert( pObj->fMarkA == 0 ); Aig_ObjSetReverseLevel( p, pObj, Aig_ObjReverseLevelNew(p, pObj) ); @@ -209,7 +212,7 @@ void Aig_ManUpdateLevel( Aig_Man_t * p, Aig_Obj_t * pObjNew ) Vec_VecPush( p->vLevels, LevelOld, pObjNew ); pObjNew->fMarkA = 1; // recursively update level - Vec_VecForEachEntryStart( p->vLevels, pTemp, Lev, k, LevelOld ) + Vec_VecForEachEntryStart( Aig_Obj_t *, p->vLevels, pTemp, Lev, k, LevelOld ) { pTemp->fMarkA = 0; assert( Aig_ObjLevel(pTemp) == Lev ); @@ -261,7 +264,7 @@ void Aig_ManUpdateReverseLevel( Aig_Man_t * p, Aig_Obj_t * pObjNew ) Vec_VecPush( p->vLevels, LevelOld, pObjNew ); pObjNew->fMarkA = 1; // recursively update level - Vec_VecForEachEntryStart( p->vLevels, pTemp, Lev, k, LevelOld ) + Vec_VecForEachEntryStart( Aig_Obj_t *, p->vLevels, pTemp, Lev, k, LevelOld ) { pTemp->fMarkA = 0; LevelOld = Aig_ObjReverseLevel(p, pTemp); @@ -349,3 +352,5 @@ void Aig_ManVerifyReverseLevel( Aig_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/aig/aigTruth.c b/src/aig/aig/aigTruth.c index a92f9e1d..ddcb8736 100644 --- a/src/aig/aig/aigTruth.c +++ b/src/aig/aig/aigTruth.c @@ -20,6 +20,9 @@ #include "aig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -43,8 +46,8 @@ unsigned * Aig_ManCutTruthOne( Aig_Obj_t * pNode, unsigned * pTruth, int nWords { unsigned * pTruth0, * pTruth1; int i; - pTruth0 = Aig_ObjFanin0(pNode)->pData; - pTruth1 = Aig_ObjFanin1(pNode)->pData; + pTruth0 = (unsigned *)Aig_ObjFanin0(pNode)->pData; + pTruth1 = (unsigned *)Aig_ObjFanin1(pNode)->pData; if ( Aig_ObjIsExor(pNode) ) for ( i = 0; i < nWords; i++ ) pTruth[i] = pTruth0[i] ^ pTruth1[i]; @@ -82,13 +85,13 @@ unsigned * Aig_ManCutTruth( Aig_Obj_t * pRoot, Vec_Ptr_t * vLeaves, Vec_Ptr_t * assert( Vec_PtrSize(vNodes) <= Vec_PtrSize(vTruthStore) ); assert( Vec_PtrSize(vNodes) == 0 || pRoot == Vec_PtrEntryLast(vNodes) ); // assign elementary truth tables - Vec_PtrForEachEntry( vLeaves, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vLeaves, pObj, i ) pObj->pData = Vec_PtrEntry( vTruthElem, i ); // compute truths for other nodes nWords = Aig_TruthWordNum( Vec_PtrSize(vLeaves) ); - Vec_PtrForEachEntry( vNodes, pObj, i ) - pObj->pData = Aig_ManCutTruthOne( pObj, Vec_PtrEntry(vTruthStore, i), nWords ); - return pRoot->pData; + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) + pObj->pData = Aig_ManCutTruthOne( pObj, (unsigned *)Vec_PtrEntry(vTruthStore, i), nWords ); + return (unsigned *)pRoot->pData; } //////////////////////////////////////////////////////////////////////// @@ -96,3 +99,5 @@ unsigned * Aig_ManCutTruth( Aig_Obj_t * pRoot, Vec_Ptr_t * vLeaves, Vec_Ptr_t * //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/aig/aigTsim.c b/src/aig/aig/aigTsim.c index 94797210..e3387ad1 100644 --- a/src/aig/aig/aigTsim.c +++ b/src/aig/aig/aigTsim.c @@ -20,6 +20,9 @@ #include "aig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -321,7 +324,7 @@ void Aig_TsiStateOrAll( Aig_Tsi_t * pTsi, unsigned * pState ) { unsigned * pPrev; int i, k; - Vec_PtrForEachEntry( pTsi->vStates, pPrev, i ) + Vec_PtrForEachEntry( unsigned *, pTsi->vStates, pPrev, i ) { for ( k = 0; k < pTsi->nWords; k++ ) pState[k] |= pPrev[k]; @@ -423,7 +426,7 @@ Vec_Ptr_t * Aig_ManTernarySimulate( Aig_Man_t * p, int fVerbose ) return NULL; } // OR all the states - pState = Vec_PtrEntry( pTsi->vStates, 0 ); + pState = (unsigned *)Vec_PtrEntry( pTsi->vStates, 0 ); Aig_TsiStateOrAll( pTsi, pState ); // check if there are constants fConstants = 0; @@ -506,3 +509,5 @@ Aig_Man_t * Aig_ManConstReduce( Aig_Man_t * p, int fVerbose ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/aig/aigUtil.c b/src/aig/aig/aigUtil.c index f51b8871..1b97fb2c 100644 --- a/src/aig/aig/aigUtil.c +++ b/src/aig/aig/aigUtil.c @@ -20,6 +20,8 @@ #include "aig.h" +ABC_NAMESPACE_IMPL_START + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -84,6 +86,30 @@ void Aig_ManIncrementTravId( Aig_Man_t * p ) /**Function************************************************************* + Synopsis [Returns the time stamp.] + + Description [The file should be closed.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Aig_TimeStamp() +{ + static char Buffer[100]; + char * TimeStamp; + time_t ltime; + // get the current time + time( <ime ); + TimeStamp = asctime( localtime( <ime ) ); + TimeStamp[ strlen(TimeStamp) - 1 ] = 0; + strcpy( Buffer, TimeStamp ); + return Buffer; +} + +/**Function************************************************************* + Synopsis [Make sure AIG has not gaps in the numeric order.] Description [] @@ -548,10 +574,10 @@ void Aig_ObjPrintEqn( FILE * pFile, Aig_Obj_t * pObj, Vec_Vec_t * vLevels, int L } // AND case Vec_VecExpand( vLevels, Level ); - vSuper = Vec_VecEntry(vLevels, Level); + vSuper = (Vec_Ptr_t *)Vec_VecEntry(vLevels, Level); Aig_ObjCollectMulti( pObj, vSuper ); fprintf( pFile, "%s", (Level==0? "" : "(") ); - Vec_PtrForEachEntry( vSuper, pFanin, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vSuper, pFanin, i ) { Aig_ObjPrintEqn( pFile, Aig_NotCond(pFanin, fCompl), vLevels, Level+1 ); if ( i < Vec_PtrSize(vSuper) - 1 ) @@ -597,10 +623,10 @@ void Aig_ObjPrintVerilog( FILE * pFile, Aig_Obj_t * pObj, Vec_Vec_t * vLevels, i if ( Aig_ObjIsExor(pObj) ) { Vec_VecExpand( vLevels, Level ); - vSuper = Vec_VecEntry( vLevels, Level ); + vSuper = (Vec_Ptr_t *)Vec_VecEntry( vLevels, Level ); Aig_ObjCollectMulti( pObj, vSuper ); fprintf( pFile, "%s", (Level==0? "" : "(") ); - Vec_PtrForEachEntry( vSuper, pFanin, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vSuper, pFanin, i ) { Aig_ObjPrintVerilog( pFile, Aig_NotCond(pFanin, (fCompl && i==0)), vLevels, Level+1 ); if ( i < Vec_PtrSize(vSuper) - 1 ) @@ -635,10 +661,10 @@ void Aig_ObjPrintVerilog( FILE * pFile, Aig_Obj_t * pObj, Vec_Vec_t * vLevels, i } // AND case Vec_VecExpand( vLevels, Level ); - vSuper = Vec_VecEntry(vLevels, Level); + vSuper = (Vec_Ptr_t *)Vec_VecEntry(vLevels, Level); Aig_ObjCollectMulti( pObj, vSuper ); fprintf( pFile, "%s", (Level==0? "" : "(") ); - Vec_PtrForEachEntry( vSuper, pFanin, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vSuper, pFanin, i ) { Aig_ObjPrintVerilog( pFile, Aig_NotCond(pFanin, fCompl), vLevels, Level+1 ); if ( i < Vec_PtrSize(vSuper) - 1 ) @@ -702,7 +728,7 @@ void Aig_ManPrintVerbose( Aig_Man_t * p, int fHaig ) printf( " %p", pObj ); printf( "\n" ); vNodes = Aig_ManDfs( p, 0 ); - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) Aig_ObjPrintVerbose( pObj, fHaig ), printf( "\n" ); printf( "\n" ); } @@ -762,7 +788,7 @@ void Aig_ManDumpBlif( Aig_Man_t * p, char * pFileName, Vec_Ptr_t * vPiNames, Vec pObj->iData = Counter++; Aig_ManForEachPo( p, pObj, i ) pObj->iData = Counter++; - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) pObj->iData = Counter++; nDigits = Aig_Base10Log( Counter ); // write the file @@ -809,7 +835,7 @@ void Aig_ManDumpBlif( Aig_Man_t * p, char * pFileName, Vec_Ptr_t * vPiNames, Vec if ( pConst1 ) fprintf( pFile, ".names n%0*d\n 1\n", nDigits, pConst1->iData ); Aig_ManSetPioNumbers( p ); - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) { fprintf( pFile, ".names" ); if ( vPiNames && Aig_ObjIsPi(Aig_ObjFanin0(pObj)) ) @@ -877,7 +903,7 @@ void Aig_ManDumpVerilog( Aig_Man_t * p, char * pFileName ) pObj->iData = Counter++; Aig_ManForEachPo( p, pObj, i ) pObj->iData = Counter++; - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) pObj->iData = Counter++; nDigits = Aig_Base10Log( Counter ); // write the file @@ -911,14 +937,14 @@ void Aig_ManDumpVerilog( Aig_Man_t * p, char * pFileName ) fprintf( pFile, "wire n%0*d;\n", nDigits, pObjLi->iData ); } // write nodes - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) fprintf( pFile, "wire n%0*d;\n", nDigits, pObj->iData ); if ( pConst1 ) fprintf( pFile, "wire n%0*d;\n", nDigits, pConst1->iData ); // write nodes if ( pConst1 ) fprintf( pFile, "assign n%0*d = 1\'b1;\n", nDigits, pConst1->iData ); - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) { fprintf( pFile, "assign n%0*d = %sn%0*d & %sn%0*d;\n", nDigits, pObj->iData, @@ -1193,7 +1219,7 @@ void Aig_ManRandomInfo( Vec_Ptr_t * vInfo, int iInputStart, int iWordStart, int { unsigned * pInfo; int i, w; - Vec_PtrForEachEntryStart( vInfo, pInfo, i, iInputStart ) + Vec_PtrForEachEntryStart( unsigned *, vInfo, pInfo, i, iInputStart ) for ( w = iWordStart; w < iWordStop; w++ ) pInfo[w] = Aig_ManRandom(0); } @@ -1278,10 +1304,15 @@ void Aig_NodeIntersectLists( Vec_Ptr_t * vArr1, Vec_Ptr_t * vArr2, Vec_Ptr_t * v assert( vArr->nSize <= vArr2->nSize ); } +ABC_NAMESPACE_IMPL_END + #include "fra.h" #include "saig.h" -extern void Aig_ManCounterExampleValueStart( Aig_Man_t * pAig, Fra_Cex_t * pCex ); +ABC_NAMESPACE_IMPL_START + + +extern void Aig_ManCounterExampleValueStart( Aig_Man_t * pAig, Abc_Cex_t * pCex ); extern void Aig_ManCounterExampleValueStop( Aig_Man_t * pAig ); extern int Aig_ManCounterExampleValueLookup( Aig_Man_t * pAig, int Id, int iFrame ); @@ -1297,7 +1328,7 @@ extern int Aig_ManCounterExampleValueLookup( Aig_Man_t * pAig, int Id, int iFra SeeAlso [] ***********************************************************************/ -void Aig_ManCounterExampleValueStart( Aig_Man_t * pAig, Fra_Cex_t * pCex ) +void Aig_ManCounterExampleValueStart( Aig_Man_t * pAig, Abc_Cex_t * pCex ) { Aig_Obj_t * pObj, * pObjRi, * pObjRo; int Val0, Val1, nObjs, i, k, iBit = 0; @@ -1313,36 +1344,36 @@ void Aig_ManCounterExampleValueStart( Aig_Man_t * pAig, Fra_Cex_t * pCex ) for ( i = 0; i <= pCex->iFrame; i++ ) { // set constant 1 node - Aig_InfoSetBit( pAig->pData2, nObjs * i + 0 ); + Aig_InfoSetBit( (unsigned *)pAig->pData2, nObjs * i + 0 ); // set primary inputs according to the counter-example Saig_ManForEachPi( pAig, pObj, k ) if ( Aig_InfoHasBit(pCex->pData, iBit++) ) - Aig_InfoSetBit( pAig->pData2, nObjs * i + Aig_ObjId(pObj) ); + Aig_InfoSetBit( (unsigned *)pAig->pData2, nObjs * i + Aig_ObjId(pObj) ); // compute values for each node Aig_ManForEachNode( pAig, pObj, k ) { - Val0 = Aig_InfoHasBit( pAig->pData2, nObjs * i + Aig_ObjFaninId0(pObj) ); - Val1 = Aig_InfoHasBit( pAig->pData2, nObjs * i + Aig_ObjFaninId1(pObj) ); + Val0 = Aig_InfoHasBit( (unsigned *)pAig->pData2, nObjs * i + Aig_ObjFaninId0(pObj) ); + Val1 = Aig_InfoHasBit( (unsigned *)pAig->pData2, nObjs * i + Aig_ObjFaninId1(pObj) ); if ( (Val0 ^ Aig_ObjFaninC0(pObj)) & (Val1 ^ Aig_ObjFaninC1(pObj)) ) - Aig_InfoSetBit( pAig->pData2, nObjs * i + Aig_ObjId(pObj) ); + Aig_InfoSetBit( (unsigned *)pAig->pData2, nObjs * i + Aig_ObjId(pObj) ); } // derive values for combinational outputs Aig_ManForEachPo( pAig, pObj, k ) { - Val0 = Aig_InfoHasBit( pAig->pData2, nObjs * i + Aig_ObjFaninId0(pObj) ); + Val0 = Aig_InfoHasBit( (unsigned *)pAig->pData2, nObjs * i + Aig_ObjFaninId0(pObj) ); if ( Val0 ^ Aig_ObjFaninC0(pObj) ) - Aig_InfoSetBit( pAig->pData2, nObjs * i + Aig_ObjId(pObj) ); + Aig_InfoSetBit( (unsigned *)pAig->pData2, nObjs * i + Aig_ObjId(pObj) ); } if ( i == pCex->iFrame ) continue; // transfer values to the register output of the next frame Saig_ManForEachLiLo( pAig, pObjRi, pObjRo, k ) - if ( Aig_InfoHasBit( pAig->pData2, nObjs * i + Aig_ObjId(pObjRi) ) ) - Aig_InfoSetBit( pAig->pData2, nObjs * (i+1) + Aig_ObjId(pObjRo) ); + if ( Aig_InfoHasBit( (unsigned *)pAig->pData2, nObjs * i + Aig_ObjId(pObjRi) ) ) + Aig_InfoSetBit( (unsigned *)pAig->pData2, nObjs * (i+1) + Aig_ObjId(pObjRo) ); } assert( iBit == pCex->nBits ); // check that the counter-example is correct, that is, the corresponding output is asserted - assert( Aig_InfoHasBit( pAig->pData2, nObjs * pCex->iFrame + Aig_ObjId(Aig_ManPo(pAig, pCex->iPo)) ) ); + assert( Aig_InfoHasBit( (unsigned *)pAig->pData2, nObjs * pCex->iFrame + Aig_ObjId(Aig_ManPo(pAig, pCex->iPo)) ) ); } /**Function************************************************************* @@ -1379,7 +1410,7 @@ void Aig_ManCounterExampleValueStop( Aig_Man_t * pAig ) int Aig_ManCounterExampleValueLookup( Aig_Man_t * pAig, int Id, int iFrame ) { assert( Id >= 0 && Id < Aig_ManObjNum(pAig) ); - return Aig_InfoHasBit( pAig->pData2, Aig_ManObjNum(pAig) * iFrame + Id ); + return Aig_InfoHasBit( (unsigned *)pAig->pData2, Aig_ManObjNum(pAig) * iFrame + Id ); } /**Function************************************************************* @@ -1393,7 +1424,7 @@ int Aig_ManCounterExampleValueLookup( Aig_Man_t * pAig, int Id, int iFrame ) SeeAlso [] ***********************************************************************/ -void Aig_ManCounterExampleValueTest( Aig_Man_t * pAig, Fra_Cex_t * pCex ) +void Aig_ManCounterExampleValueTest( Aig_Man_t * pAig, Abc_Cex_t * pCex ) { Aig_Obj_t * pObj = Aig_ManObj( pAig, Aig_ManObjNum(pAig)/2 ); int iFrame = ABC_MAX( 0, pCex->iFrame - 1 ); @@ -1404,9 +1435,123 @@ void Aig_ManCounterExampleValueTest( Aig_Man_t * pAig, Fra_Cex_t * pCex ) Aig_ManCounterExampleValueStop( pAig ); } +/**Function************************************************************* + + Synopsis [Handle the counter-example.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_ManSetPhase( Aig_Man_t * pAig ) +{ + Aig_Obj_t * pObj; + int i; + // set the PI simulation information + Aig_ManConst1( pAig )->fPhase = 1; + Aig_ManForEachPi( pAig, pObj, i ) + pObj->fPhase = 0; + // simulate internal nodes + Aig_ManForEachNode( pAig, pObj, i ) + pObj->fPhase = ( Aig_ObjFanin0(pObj)->fPhase ^ Aig_ObjFaninC0(pObj) ) + & ( Aig_ObjFanin1(pObj)->fPhase ^ Aig_ObjFaninC1(pObj) ); + // simulate PO nodes + Aig_ManForEachPo( pAig, pObj, i ) + pObj->fPhase = Aig_ObjFanin0(pObj)->fPhase ^ Aig_ObjFaninC0(pObj); +} + + +/**Function************************************************************* + + Synopsis [Collects muxes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Aig_ManMuxesCollect( Aig_Man_t * pAig ) +{ + Vec_Ptr_t * vMuxes; + Aig_Obj_t * pObj; + int i; + vMuxes = Vec_PtrAlloc( 100 ); + Aig_ManForEachNode( pAig, pObj, i ) + if ( Aig_ObjIsMuxType(pObj) ) + Vec_PtrPush( vMuxes, pObj ); + return vMuxes; +} + +/**Function************************************************************* + + Synopsis [Dereferences muxes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_ManMuxesDeref( Aig_Man_t * pAig, Vec_Ptr_t * vMuxes ) +{ + Aig_Obj_t * pObj, * pNodeT, * pNodeE, * pNodeC; + int i; + Vec_PtrForEachEntry( Aig_Obj_t *, vMuxes, pObj, i ) + { + if ( Aig_ObjRecognizeExor( pObj, &pNodeT, &pNodeE ) ) + { + pNodeT->nRefs--; + pNodeE->nRefs--; + } + else + { + pNodeC = Aig_ObjRecognizeMux( pObj, &pNodeT, &pNodeE ); + pNodeC->nRefs--; + } + } +} + +/**Function************************************************************* + + Synopsis [References muxes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_ManMuxesRef( Aig_Man_t * pAig, Vec_Ptr_t * vMuxes ) +{ + Aig_Obj_t * pObj, * pNodeT, * pNodeE, * pNodeC; + int i; + Vec_PtrForEachEntry( Aig_Obj_t *, vMuxes, pObj, i ) + { + if ( Aig_ObjRecognizeExor( pObj, &pNodeT, &pNodeE ) ) + { + pNodeT->nRefs++; + pNodeE->nRefs++; + } + else + { + pNodeC = Aig_ObjRecognizeMux( pObj, &pNodeT, &pNodeE ); + pNodeC->nRefs++; + } + } +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/aig/aigWin.c b/src/aig/aig/aigWin.c index 0485b243..5568c9ec 100644 --- a/src/aig/aig/aigWin.c +++ b/src/aig/aig/aigWin.c @@ -20,6 +20,9 @@ #include "aig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -82,7 +85,7 @@ int Aig_ManFindCut_int( Vec_Ptr_t * vFront, Vec_Ptr_t * vVisited, int nSizeLimit CostBest = 100; pFaninBest = NULL; //printf( "Evaluating fanins of the cut:\n" ); - Vec_PtrForEachEntry( vFront, pNode, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vFront, pNode, i ) { CostCur = Aig_NodeGetLeafCostOne( pNode, nFanoutLimit ); //printf( " Fanin %s has cost %d.\n", Aig_ObjName(pNode), CostCur ); @@ -173,7 +176,7 @@ void Aig_ManFindCut( Aig_Obj_t * pRoot, Vec_Ptr_t * vFront, Vec_Ptr_t * vVisited assert( Vec_PtrSize(vFront) <= nSizeLimit ); // clean the visit markings - Vec_PtrForEachEntry( vVisited, pNode, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vVisited, pNode, i ) pNode->fMarkA = 0; } @@ -182,3 +185,5 @@ void Aig_ManFindCut( Aig_Obj_t * pRoot, Vec_Ptr_t * vFront, Vec_Ptr_t * vVisited //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/aig/aig_.c b/src/aig/aig/aig_.c index b2313d35..ae0cb568 100644 --- a/src/aig/aig/aig_.c +++ b/src/aig/aig/aig_.c @@ -20,6 +20,9 @@ #include "aig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -46,3 +49,5 @@ //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/aig/module.make b/src/aig/aig/module.make index 5fea4341..03504138 100644 --- a/src/aig/aig/module.make +++ b/src/aig/aig/module.make @@ -20,6 +20,7 @@ SRC += src/aig/aig/aigCheck.c \ src/aig/aig/aigRetF.c \ src/aig/aig/aigScl.c \ src/aig/aig/aigShow.c \ + src/aig/aig/aigSplit.c \ src/aig/aig/aigTable.c \ src/aig/aig/aigTiming.c \ src/aig/aig/aigTruth.c \ diff --git a/src/aig/bar/bar.c b/src/aig/bar/bar.c index 2c5065cb..b5c31779 100644 --- a/src/aig/bar/bar.c +++ b/src/aig/bar/bar.c @@ -21,9 +21,14 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> + #include "abc_global.h" +#include "main.h" #include "bar.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -61,9 +66,7 @@ static void Bar_ProgressClean( Bar_Progress_t * p ); Bar_Progress_t * Bar_ProgressStart( FILE * pFile, int nItemsTotal ) { Bar_Progress_t * p; - void * pFrame; - extern int Abc_FrameShowProgress( void * p ); - extern void * Abc_FrameReadGlobalFrame(); + Abc_Frame_t * pFrame; pFrame = Abc_FrameReadGlobalFrame(); if ( pFrame == NULL ) return NULL; @@ -180,3 +183,5 @@ void Bar_ProgressClean( Bar_Progress_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/bar/bar.h b/src/aig/bar/bar.h index 104c6f47..65c9ec6a 100644 --- a/src/aig/bar/bar.h +++ b/src/aig/bar/bar.h @@ -21,6 +21,7 @@ #ifndef __BAR_H__ #define __BAR_H__ + #ifdef _WIN32 #define inline __inline // compatible with MS VS 6.0 #endif @@ -33,9 +34,10 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + #define BAR_PROGRESS_USE 1 @@ -62,9 +64,11 @@ static inline void Bar_ProgressUpdate( Bar_Progress_t * p, int nItemsCur, if ( BAR_PROGRESS_USE && p && (nItemsCur < *((int*)p)) ) return; Bar_ProgressUpdate_int(p, nItemsCur, pString); } -#ifdef __cplusplus -} -#endif + + +ABC_NAMESPACE_HEADER_END + + #endif diff --git a/src/aig/bbl/bblif.c b/src/aig/bbl/bblif.c index adc10b28..e68258d9 100644 --- a/src/aig/bbl/bblif.c +++ b/src/aig/bbl/bblif.c @@ -24,8 +24,12 @@ #include <assert.h> #include <time.h> +#include "abc_global.h" #include "bblif.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -375,9 +379,10 @@ static inline void Vec_IntFillExtra( Vec_Int_t * p, int nSize, int Fill ) int i; if ( p->nSize >= nSize ) return; - if ( nSize < 2 * p->nSize ) - nSize = 2 * p->nSize; - Vec_IntGrow( p, nSize ); + if ( nSize > 2 * p->nCap ) + Vec_IntGrow( p, nSize ); + else if ( nSize > p->nCap ) + Vec_IntGrow( p, 2 * p->nCap ); for ( i = p->nSize; i < nSize; i++ ) p->pArray[i] = Fill; p->nSize = nSize; @@ -1509,3 +1514,5 @@ void Bbl_ManSimpleDemo() //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/bbl/bblif.h b/src/aig/bbl/bblif.h index 89c58f93..787d649f 100644 --- a/src/aig/bbl/bblif.h +++ b/src/aig/bbl/bblif.h @@ -21,6 +21,7 @@ #ifndef __BBLIF_H__ #define __BBLIF_H__ + /* This file (taken together with "bblif.c") implements a stand-alone interface between ABC and an application that uses ABC. @@ -186,9 +187,10 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + #ifdef _WIN32 #define inline __inline @@ -269,9 +271,11 @@ extern void Bbl_ManDumpBlif( Bbl_Man_t * p, char * pFileName ); extern void Bbl_ManSimpleDemo(); -#ifdef __cplusplus -} -#endif + + +ABC_NAMESPACE_HEADER_END + + #endif diff --git a/src/aig/bbr/bbr.h b/src/aig/bbr/bbr.h index e5d585ce..bb83ac95 100644 --- a/src/aig/bbr/bbr.h +++ b/src/aig/bbr/bbr.h @@ -21,22 +21,24 @@ #ifndef __BBR_H__ #define __BBR_H__ + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// #include <stdio.h> -#include "cuddInt.h" #include "aig.h" #include "saig.h" +#include "cuddInt.h" //////////////////////////////////////////////////////////////////////// /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -46,7 +48,7 @@ extern "C" { /// MACRO DEFINITIONS /// //////////////////////////////////////////////////////////////////////// -static inline DdNode * Aig_ObjGlobalBdd( Aig_Obj_t * pObj ) { return pObj->pData; } +static inline DdNode * Aig_ObjGlobalBdd( Aig_Obj_t * pObj ) { return (DdNode *)pObj->pData; } //////////////////////////////////////////////////////////////////////// /// FUNCTION DECLARATIONS /// @@ -74,11 +76,14 @@ extern void Aig_ManFreeGlobalBdds( Aig_Man_t * p, DdManager * dd ); extern int Aig_ManSizeOfGlobalBdds( Aig_Man_t * p ); extern DdManager * Aig_ManComputeGlobalBdds( Aig_Man_t * p, int nBddSizeMax, int fDropInternal, int fReorder, int fVerbose ); /*=== bbrReach.c ==========================================================*/ -extern int Aig_ManVerifyUsingBdds( Aig_Man_t * p, int nBddMax, int nIterMax, int fPartition, int fReorder, int fReorderImage, int fVerbose, int fSilent ); +extern int Aig_ManVerifyUsingBdds( Aig_Man_t * p, Saig_ParBbr_t * pPars ); +extern void Bbr_ManSetDefaultParams( Saig_ParBbr_t * p ); + + + +ABC_NAMESPACE_HEADER_END + -#ifdef __cplusplus -} -#endif #endif diff --git a/src/aig/bbr/bbrCex.c b/src/aig/bbr/bbrCex.c index 947c393c..8f99ea3c 100644 --- a/src/aig/bbr/bbrCex.c +++ b/src/aig/bbr/bbrCex.c @@ -21,6 +21,9 @@ #include "bbr.h" #include "ssw.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -42,11 +45,11 @@ extern DdNode * Bbr_bddComputeRangeCube( DdManager * dd, int iStart, int iStop ) SeeAlso [] ***********************************************************************/ -Ssw_Cex_t * Aig_ManVerifyUsingBddsCountExample( Aig_Man_t * p, DdManager * dd, +Abc_Cex_t * Aig_ManVerifyUsingBddsCountExample( Aig_Man_t * p, DdManager * dd, DdNode ** pbParts, Vec_Ptr_t * vOnionRings, DdNode * bCubeFirst, int iOutput, int fVerbose, int fSilent ) { - Ssw_Cex_t * pCex; + Abc_Cex_t * pCex; Aig_Obj_t * pObj; Bbr_ImageTree_t * pTree; DdNode * bCubeNs, * bState, * bImage; @@ -96,7 +99,7 @@ Ssw_Cex_t * Aig_ManVerifyUsingBddsCountExample( Aig_Man_t * p, DdManager * dd, } // perform backward analysis - Vec_PtrForEachEntryReverse( vOnionRings, bRing, v ) + Vec_PtrForEachEntryReverse( DdNode *, vOnionRings, bRing, v ) { // compute the next states bImage = Bbr_bddImageCompute( pTree, bState ); @@ -166,3 +169,5 @@ Ssw_Cex_t * Aig_ManVerifyUsingBddsCountExample( Aig_Man_t * p, DdManager * dd, //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/bbr/bbrImage.c b/src/aig/bbr/bbrImage.c index c16a8ff4..8b18d84d 100644 --- a/src/aig/bbr/bbrImage.c +++ b/src/aig/bbr/bbrImage.c @@ -19,7 +19,10 @@ ***********************************************************************/ #include "bbr.h" -#include "mtr.h" +#include "mtr.h" + +ABC_NAMESPACE_IMPL_START + /* The ideas implemented in this file are inspired by the paper: @@ -1320,3 +1323,5 @@ DdNode * Bbr_bddImageRead2( Bbr_ImageTree2_t * pTree ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/bbr/bbrNtbdd.c b/src/aig/bbr/bbrNtbdd.c index 05c98fe1..09456df0 100644 --- a/src/aig/bbr/bbrNtbdd.c +++ b/src/aig/bbr/bbrNtbdd.c @@ -21,6 +21,9 @@ #include "bbr.h" //#include "bar.h" +ABC_NAMESPACE_IMPL_START + + typedef char ProgressBar; //////////////////////////////////////////////////////////////////////// @@ -28,7 +31,7 @@ typedef char ProgressBar; //////////////////////////////////////////////////////////////////////// static inline void Aig_ObjSetGlobalBdd( Aig_Obj_t * pObj, DdNode * bFunc ) { pObj->pData = bFunc; } -static inline void Aig_ObjCleanGlobalBdd( DdManager * dd, Aig_Obj_t * pObj ) { Cudd_RecursiveDeref( dd, pObj->pData ); pObj->pData = NULL; } +static inline void Aig_ObjCleanGlobalBdd( DdManager * dd, Aig_Obj_t * pObj ) { Cudd_RecursiveDeref( dd, (DdNode *)pObj->pData ); pObj->pData = NULL; } //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -211,3 +214,5 @@ DdManager * Aig_ManComputeGlobalBdds( Aig_Man_t * p, int nBddSizeMax, int fDropI //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/bbr/bbrReach.c b/src/aig/bbr/bbrReach.c index 7d0e4bc0..f76c9671 100644 --- a/src/aig/bbr/bbrReach.c +++ b/src/aig/bbr/bbrReach.c @@ -21,11 +21,14 @@ #include "bbr.h" #include "ssw.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -extern void * Aig_ManVerifyUsingBddsCountExample( Aig_Man_t * p, DdManager * dd, +extern Abc_Cex_t * Aig_ManVerifyUsingBddsCountExample( Aig_Man_t * p, DdManager * dd, DdNode ** pbParts, Vec_Ptr_t * vOnionRings, DdNode * bCubeFirst, int iOutput, int fVerbose, int fSilent ); @@ -33,6 +36,31 @@ extern void * Aig_ManVerifyUsingBddsCountExample( Aig_Man_t * p, DdManager * dd, /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [This procedure sets default resynthesis parameters.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bbr_ManSetDefaultParams( Saig_ParBbr_t * p ) +{ + memset( p, 0, sizeof(Saig_ParBbr_t) ); + p->TimeLimit = 0; + p->nBddMax = 50000; + p->nIterMax = 1000; + p->fPartition = 1; + p->fReorder = 1; + p->fReorderImage = 1; + p->fVerbose = 0; + p->fSilent = 0; + p->iFrame = -1; +} + /**Function******************************************************************** Synopsis [Performs the reordering-sensitive step of Extra_bddMove().] @@ -208,7 +236,7 @@ DdNode ** Aig_ManCreatePartitions( DdManager * dd, Aig_Man_t * p, int fReorder, SeeAlso [] ***********************************************************************/ -int Aig_ManComputeReachable( DdManager * dd, Aig_Man_t * p, DdNode ** pbParts, DdNode * bInitial, DdNode ** pbOutputs, int nBddMax, int nIterMax, int fPartition, int fReorder, int fVerbose, int fSilent ) +int Aig_ManComputeReachable( DdManager * dd, Aig_Man_t * p, DdNode ** pbParts, DdNode * bInitial, DdNode ** pbOutputs, Saig_ParBbr_t * pPars, int fCheckOutputs ) { int fInternalReorder = 0; Bbr_ImageTree_t * pTree = NULL; // Suppress "might be used uninitialized" @@ -217,10 +245,10 @@ int Aig_ManComputeReachable( DdManager * dd, Aig_Man_t * p, DdNode ** pbParts, D DdNode * bCurrent; DdNode * bNext = NULL; // Suppress "might be used uninitialized" DdNode * bTemp; - int i, nIters, nBddSize; - int nThreshold = 10000; + Cudd_ReorderingType method; + int i, nIters, nBddSize, status; + int nThreshold = 10000, clk = clock(); Vec_Ptr_t * vOnionRings; - int status, method; status = Cudd_ReorderingStatus( dd, &method ); if ( status ) @@ -228,14 +256,14 @@ int Aig_ManComputeReachable( DdManager * dd, Aig_Man_t * p, DdNode ** pbParts, D // start the image computation bCubeCs = Bbr_bddComputeRangeCube( dd, Saig_ManPiNum(p), Saig_ManCiNum(p) ); Cudd_Ref( bCubeCs ); - if ( fPartition ) - pTree = Bbr_bddImageStart( dd, bCubeCs, Saig_ManRegNum(p), pbParts, Saig_ManRegNum(p), dd->vars+Saig_ManCiNum(p), nBddMax, fVerbose ); + if ( pPars->fPartition ) + pTree = Bbr_bddImageStart( dd, bCubeCs, Saig_ManRegNum(p), pbParts, Saig_ManRegNum(p), dd->vars+Saig_ManCiNum(p), pPars->nBddMax, pPars->fVerbose ); else - pTree2 = Bbr_bddImageStart2( dd, bCubeCs, Saig_ManRegNum(p), pbParts, Saig_ManRegNum(p), dd->vars+Saig_ManCiNum(p), fVerbose ); + pTree2 = Bbr_bddImageStart2( dd, bCubeCs, Saig_ManRegNum(p), pbParts, Saig_ManRegNum(p), dd->vars+Saig_ManCiNum(p), pPars->fVerbose ); Cudd_RecursiveDeref( dd, bCubeCs ); if ( pTree == NULL ) { - if ( !fSilent ) + if ( !pPars->fSilent ) printf( "BDDs blew up during qualitification scheduling. " ); return -1; } @@ -246,30 +274,46 @@ int Aig_ManComputeReachable( DdManager * dd, Aig_Man_t * p, DdNode ** pbParts, D // start the onion rings vOnionRings = Vec_PtrAlloc( 1000 ); - // perform reachability analisys + // perform reachability analysis bCurrent = bInitial; Cudd_Ref( bCurrent ); bReached = bInitial; Cudd_Ref( bReached ); Vec_PtrPush( vOnionRings, bCurrent ); Cudd_Ref( bCurrent ); - for ( nIters = 1; nIters <= nIterMax; nIters++ ) + for ( nIters = 0; nIters < pPars->nIterMax; nIters++ ) { + // check the runtime limit + if ( pPars->TimeLimit && ((float)pPars->TimeLimit <= (float)(clock()-clk)/(float)(CLOCKS_PER_SEC)) ) + { + printf( "Reached timeout after image computation (%d seconds).\n", pPars->TimeLimit ); + Vec_PtrFree( vOnionRings ); + // undo the image tree + if ( pPars->fPartition ) + Bbr_bddImageTreeDelete( pTree ); + else + Bbr_bddImageTreeDelete2( pTree2 ); + pPars->iFrame = nIters - 1; + return -1; + } + // compute the next states - if ( fPartition ) + if ( pPars->fPartition ) bNext = Bbr_bddImageCompute( pTree, bCurrent ); else bNext = Bbr_bddImageCompute2( pTree2, bCurrent ); if ( bNext == NULL ) { - if ( !fSilent ) + if ( !pPars->fSilent ) printf( "BDDs blew up during image computation. " ); - if ( fPartition ) + if ( pPars->fPartition ) Bbr_bddImageTreeDelete( pTree ); else Bbr_bddImageTreeDelete2( pTree2 ); Vec_PtrFree( vOnionRings ); + pPars->iFrame = nIters - 1; return -1; } Cudd_Ref( bNext ); Cudd_RecursiveDeref( dd, bCurrent ); + // remap these states into the current state vars bNext = Cudd_bddVarMap( dd, bTemp = bNext ); Cudd_Ref( bNext ); Cudd_RecursiveDeref( dd, bTemp ); @@ -278,23 +322,24 @@ int Aig_ManComputeReachable( DdManager * dd, Aig_Man_t * p, DdNode ** pbParts, D break; // check the BDD size nBddSize = Cudd_DagSize(bNext); - if ( nBddSize > nBddMax ) + if ( nBddSize > pPars->nBddMax ) break; // check the result for ( i = 0; i < Saig_ManPoNum(p); i++ ) { - if ( !Cudd_bddLeq( dd, bNext, Cudd_Not(pbOutputs[i]) ) ) + if ( fCheckOutputs && !Cudd_bddLeq( dd, bNext, Cudd_Not(pbOutputs[i]) ) ) { DdNode * bIntersect; bIntersect = Cudd_bddIntersect( dd, bNext, pbOutputs[i] ); Cudd_Ref( bIntersect ); assert( p->pSeqModel == NULL ); p->pSeqModel = Aig_ManVerifyUsingBddsCountExample( p, dd, pbParts, - vOnionRings, bIntersect, i, fVerbose, fSilent ); + vOnionRings, bIntersect, i, pPars->fVerbose, pPars->fSilent ); Cudd_RecursiveDeref( dd, bIntersect ); - if ( !fSilent ) + if ( !pPars->fSilent ) printf( "Output %d was asserted in frame %d (use \"write_counter\" to dump a witness). ", i, Vec_PtrSize(vOnionRings) ); Cudd_RecursiveDeref( dd, bReached ); bReached = NULL; + pPars->iFrame = nIters; break; } } @@ -310,38 +355,39 @@ int Aig_ManComputeReachable( DdManager * dd, Aig_Man_t * p, DdNode ** pbParts, D bReached = Cudd_bddOr( dd, bTemp = bReached, bNext ); Cudd_Ref( bReached ); Cudd_RecursiveDeref( dd, bTemp ); Cudd_RecursiveDeref( dd, bNext ); - if ( fVerbose ) + if ( pPars->fVerbose ) fprintf( stdout, "Frame = %3d. BDD = %5d. ", nIters, nBddSize ); - if ( fInternalReorder && fReorder && nBddSize > nThreshold ) + if ( fInternalReorder && pPars->fReorder && nBddSize > nThreshold ) { - if ( fVerbose ) + if ( pPars->fVerbose ) fprintf( stdout, "Reordering... Before = %5d. ", Cudd_DagSize(bReached) ); Cudd_ReduceHeap( dd, CUDD_REORDER_SYMM_SIFT, 100 ); Cudd_AutodynDisable( dd ); - if ( fVerbose ) + if ( pPars->fVerbose ) fprintf( stdout, "After = %5d.\r", Cudd_DagSize(bReached) ); nThreshold *= 2; } - if ( fVerbose ) - fprintf( stdout, "\r" ); + if ( pPars->fVerbose ) +// fprintf( stdout, "\r" ); + fprintf( stdout, "\n" ); } Cudd_RecursiveDeref( dd, bNext ); // free the onion rings - Vec_PtrForEachEntry( vOnionRings, bTemp, i ) + Vec_PtrForEachEntry( DdNode *, vOnionRings, bTemp, i ) Cudd_RecursiveDeref( dd, bTemp ); Vec_PtrFree( vOnionRings ); // undo the image tree - if ( fPartition ) + if ( pPars->fPartition ) Bbr_bddImageTreeDelete( pTree ); else Bbr_bddImageTreeDelete2( pTree2 ); if ( bReached == NULL ) return 0; // proved reachable // report the stats - if ( fVerbose ) + if ( pPars->fVerbose ) { double nMints = Cudd_CountMinterm(dd, bReached, Saig_ManRegNum(p) ); - if ( nIters > nIterMax || Cudd_DagSize(bReached) > nBddMax ) + if ( nIters > pPars->nIterMax || nBddSize > pPars->nBddMax ) fprintf( stdout, "Reachability analysis is stopped after %d frames.\n", nIters ); else fprintf( stdout, "Reachability analysis completed after %d frames.\n", nIters ); @@ -350,14 +396,15 @@ int Aig_ManComputeReachable( DdManager * dd, Aig_Man_t * p, DdNode ** pbParts, D } //ABC_PRB( dd, bReached ); Cudd_RecursiveDeref( dd, bReached ); - if ( nIters > nIterMax || Cudd_DagSize(bReached) > nBddMax ) + if ( nIters > pPars->nIterMax || nBddSize > pPars->nBddMax ) { - if ( !fSilent ) + if ( !pPars->fSilent ) printf( "Verified only for states reachable in %d frames. ", nIters ); return -1; // undecided } - if ( !fSilent ) + if ( !pPars->fSilent ) printf( "The miter is proved unreachable after %d iterations. ", nIters ); + pPars->iFrame = nIters - 1; return 1; // unreachable } @@ -372,8 +419,9 @@ int Aig_ManComputeReachable( DdManager * dd, Aig_Man_t * p, DdNode ** pbParts, D SeeAlso [] ***********************************************************************/ -int Aig_ManVerifyUsingBdds_int( Aig_Man_t * p, int nBddMax, int nIterMax, int fPartition, int fReorder, int fReorderImage, int fVerbose, int fSilent ) +int Aig_ManVerifyUsingBdds_int( Aig_Man_t * p, Saig_ParBbr_t * pPars ) { + int fCheckOutputs = !pPars->fSkipOutCheck; DdManager * dd; DdNode ** pbParts, ** pbOutputs; DdNode * bInitial, * bTemp; @@ -383,16 +431,24 @@ int Aig_ManVerifyUsingBdds_int( Aig_Man_t * p, int nBddMax, int nIterMax, int fP assert( Saig_ManRegNum(p) > 0 ); // compute the global BDDs of the latches - dd = Aig_ManComputeGlobalBdds( p, nBddMax, 1, fReorder, fVerbose ); + dd = Aig_ManComputeGlobalBdds( p, pPars->nBddMax, 1, pPars->fReorder, pPars->fVerbose ); if ( dd == NULL ) { - if ( !fSilent ) - printf( "The number of intermediate BDD nodes exceeded the limit (%d).\n", nBddMax ); + if ( !pPars->fSilent ) + printf( "The number of intermediate BDD nodes exceeded the limit (%d).\n", pPars->nBddMax ); return -1; } - if ( fVerbose ) + if ( pPars->fVerbose ) printf( "Shared BDD size is %6d nodes.\n", Cudd_ReadKeys(dd) - Cudd_ReadDead(dd) ); + // check the runtime limit + if ( pPars->TimeLimit && ((float)pPars->TimeLimit <= (float)(clock()-clk)/(float)(CLOCKS_PER_SEC)) ) + { + printf( "Reached timeout after constructing global BDDs (%d seconds).\n", pPars->TimeLimit ); + Cudd_Quit( dd ); + return -1; + } + // start the onion rings vOnionRings = Vec_PtrAlloc( 1000 ); @@ -400,40 +456,40 @@ int Aig_ManVerifyUsingBdds_int( Aig_Man_t * p, int nBddMax, int nIterMax, int fP pbOutputs = Aig_ManCreateOutputs( dd, p ); // create partitions - pbParts = Aig_ManCreatePartitions( dd, p, fReorder, fVerbose ); + pbParts = Aig_ManCreatePartitions( dd, p, pPars->fReorder, pPars->fVerbose ); // create the initial state and the variable map - bInitial = Aig_ManInitStateVarMap( dd, p, fVerbose ); Cudd_Ref( bInitial ); + bInitial = Aig_ManInitStateVarMap( dd, p, pPars->fVerbose ); Cudd_Ref( bInitial ); // set reordering - if ( fReorderImage ) + if ( pPars->fReorderImage ) Cudd_AutodynEnable( dd, CUDD_REORDER_SYMM_SIFT ); // check the result RetValue = -1; for ( i = 0; i < Saig_ManPoNum(p); i++ ) { - if ( !Cudd_bddLeq( dd, bInitial, Cudd_Not(pbOutputs[i]) ) ) + if ( fCheckOutputs && !Cudd_bddLeq( dd, bInitial, Cudd_Not(pbOutputs[i]) ) ) { DdNode * bIntersect; bIntersect = Cudd_bddIntersect( dd, bInitial, pbOutputs[i] ); Cudd_Ref( bIntersect ); assert( p->pSeqModel == NULL ); p->pSeqModel = Aig_ManVerifyUsingBddsCountExample( p, dd, pbParts, - vOnionRings, bIntersect, i, fVerbose, fSilent ); + vOnionRings, bIntersect, i, pPars->fVerbose, pPars->fSilent ); Cudd_RecursiveDeref( dd, bIntersect ); - if ( !fSilent ) + if ( !pPars->fSilent ) printf( "The miter output %d is proved REACHABLE in the initial state (use \"write_counter\" to dump a witness). ", i ); RetValue = 0; break; } } // free the onion rings - Vec_PtrForEachEntry( vOnionRings, bTemp, i ) + Vec_PtrForEachEntry( DdNode *, vOnionRings, bTemp, i ) Cudd_RecursiveDeref( dd, bTemp ); Vec_PtrFree( vOnionRings ); // explore reachable states if ( RetValue == -1 ) - RetValue = Aig_ManComputeReachable( dd, p, pbParts, bInitial, pbOutputs, nBddMax, nIterMax, fPartition, fReorder, fVerbose, fSilent ); + RetValue = Aig_ManComputeReachable( dd, p, pbParts, bInitial, pbOutputs, pPars, fCheckOutputs ); // cleanup Cudd_RecursiveDeref( dd, bInitial ); @@ -443,13 +499,13 @@ int Aig_ManVerifyUsingBdds_int( Aig_Man_t * p, int nBddMax, int nIterMax, int fP for ( i = 0; i < Saig_ManPoNum(p); i++ ) Cudd_RecursiveDeref( dd, pbOutputs[i] ); ABC_FREE( pbOutputs ); - if ( RetValue == -1 ) +// if ( RetValue == -1 ) Cudd_Quit( dd ); - else - Bbr_StopManager( dd ); +// else +// Bbr_StopManager( dd ); // report the runtime - if ( !fSilent ) + if ( !pPars->fSilent ) { ABC_PRT( "Time", clock() - clk ); fflush( stdout ); @@ -468,24 +524,25 @@ int Aig_ManVerifyUsingBdds_int( Aig_Man_t * p, int nBddMax, int nIterMax, int fP SeeAlso [] ***********************************************************************/ -int Aig_ManVerifyUsingBdds( Aig_Man_t * pInit, int nBddMax, int nIterMax, int fPartition, int fReorder, int fReorderImage, int fVerbose, int fSilent ) +int Aig_ManVerifyUsingBdds( Aig_Man_t * pInit, Saig_ParBbr_t * pPars ) { - Ssw_Cex_t * pCexOld, * pCexNew; + Abc_Cex_t * pCexOld, * pCexNew; Aig_Man_t * p; Aig_Obj_t * pObj; Vec_Int_t * vInputMap; int i, k, Entry, iBitOld, iBitNew, RetValue; +// pPars->fVerbose = 1; // check if there are PIs without fanout Saig_ManForEachPi( pInit, pObj, i ) if ( Aig_ObjRefs(pObj) == 0 ) break; if ( i == Saig_ManPiNum(pInit) ) - return Aig_ManVerifyUsingBdds_int( pInit, nBddMax, nIterMax, fPartition, fReorder, fReorderImage, fVerbose, fSilent ); + return Aig_ManVerifyUsingBdds_int( pInit, pPars ); // create new AIG p = Aig_ManDupTrim( pInit ); assert( Aig_ManPiNum(p) < Aig_ManPiNum(pInit) ); assert( Aig_ManRegNum(p) == Aig_ManRegNum(pInit) ); - RetValue = Aig_ManVerifyUsingBdds_int( p, nBddMax, nIterMax, fPartition, fReorder, fReorderImage, fVerbose, fSilent ); + RetValue = Aig_ManVerifyUsingBdds_int( p, pPars ); if ( RetValue != 0 ) { Aig_ManStop( p ); @@ -498,7 +555,7 @@ int Aig_ManVerifyUsingBdds( Aig_Man_t * pInit, int nBddMax, int nIterMax, int fP vInputMap = Vec_IntAlloc( Saig_ManPiNum(pInit) ); Saig_ManForEachPi( pInit, pObj, i ) if ( pObj->pData != NULL ) - Vec_IntPush( vInputMap, Aig_ObjPioNum(pObj->pData) ); + Vec_IntPush( vInputMap, Aig_ObjPioNum((Aig_Obj_t *)pObj->pData) ); else Vec_IntPush( vInputMap, -1 ); // create new pattern @@ -537,3 +594,5 @@ int Aig_ManVerifyUsingBdds( Aig_Man_t * pInit, int nBddMax, int nIterMax, int fP //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/bbr/bbr_.c b/src/aig/bbr/bbr_.c index f94c50e6..df934f7d 100644 --- a/src/aig/bbr/bbr_.c +++ b/src/aig/bbr/bbr_.c @@ -20,6 +20,9 @@ #include "__Int.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -45,3 +48,5 @@ //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/bdc/bdc.h b/src/aig/bdc/bdc.h index 0bdccf2b..8a240b0c 100644 --- a/src/aig/bdc/bdc.h +++ b/src/aig/bdc/bdc.h @@ -21,6 +21,7 @@ #ifndef __BDC_H__ #define __BDC_H__ + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -29,9 +30,10 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -72,12 +74,15 @@ extern int Bdc_ManNodeNum( Bdc_Man_t * p ); extern Bdc_Fun_t * Bdc_FuncFanin0( Bdc_Fun_t * p ); extern Bdc_Fun_t * Bdc_FuncFanin1( Bdc_Fun_t * p ); extern void * Bdc_FuncCopy( Bdc_Fun_t * p ); +extern int Bdc_FuncCopyInt( Bdc_Fun_t * p ); extern void Bdc_FuncSetCopy( Bdc_Fun_t * p, void * pCopy ); +extern void Bdc_FuncSetCopyInt( Bdc_Fun_t * p, int iCopy ); + + + +ABC_NAMESPACE_HEADER_END -#ifdef __cplusplus -} -#endif #endif diff --git a/src/aig/bdc/bdcCore.c b/src/aig/bdc/bdcCore.c index fea08115..58324f81 100644 --- a/src/aig/bdc/bdcCore.c +++ b/src/aig/bdc/bdcCore.c @@ -20,6 +20,9 @@ #include "bdcInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -46,7 +49,9 @@ int Bdc_ManNodeNum( Bdc_Man_t * p ) { return p->nNode Bdc_Fun_t * Bdc_FuncFanin0( Bdc_Fun_t * p ) { return p->pFan0; } Bdc_Fun_t * Bdc_FuncFanin1( Bdc_Fun_t * p ) { return p->pFan1; } void * Bdc_FuncCopy( Bdc_Fun_t * p ) { return p->pCopy; } +int Bdc_FuncCopyInt( Bdc_Fun_t * p ) { return p->iCopy; } void Bdc_FuncSetCopy( Bdc_Fun_t * p, void * pCopy ) { p->pCopy = pCopy; } +void Bdc_FuncSetCopyInt( Bdc_Fun_t * p, int iCopy ) { p->iCopy = iCopy; } /**Function************************************************************* @@ -160,13 +165,13 @@ void Bdc_ManPrepare( Bdc_Man_t * p, Vec_Ptr_t * vDivs ) { pNode = Bdc_FunNew( p ); pNode->Type = BDC_TYPE_PI; - pNode->puFunc = Vec_PtrEntry( p->vTruths, i ); + pNode->puFunc = (unsigned *)Vec_PtrEntry( p->vTruths, i ); pNode->uSupp = (1 << i); Bdc_TableAdd( p, pNode ); } // add the divisors if ( vDivs ) - Vec_PtrForEachEntry( vDivs, puTruth, i ) + Vec_PtrForEachEntry( unsigned *, vDivs, puTruth, i ) { pNode = Bdc_FunNew( p ); pNode->Type = BDC_TYPE_PI; @@ -305,3 +310,5 @@ void Bdc_ManDecomposeTest( unsigned uTruth, int nVars ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/bdc/bdcDec.c b/src/aig/bdc/bdcDec.c index ccf6248f..61f46f17 100644 --- a/src/aig/bdc/bdcDec.c +++ b/src/aig/bdc/bdcDec.c @@ -20,6 +20,9 @@ #include "bdcInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -744,3 +747,5 @@ Extra_PrintBinary( stdout, pIsf->puOff, 1<<4 );printf("\n"); //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/bdc/bdcInt.h b/src/aig/bdc/bdcInt.h index 71ad8449..74630664 100644 --- a/src/aig/bdc/bdcInt.h +++ b/src/aig/bdc/bdcInt.h @@ -21,6 +21,7 @@ #ifndef __BDC_INT_H__ #define __BDC_INT_H__ + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -32,9 +33,10 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + #define BDC_SCALE 1000 // value used to compute the cost @@ -62,7 +64,9 @@ struct Bdc_Fun_t_ unsigned uSupp; // bit mask of current support unsigned * puFunc; // the function of the node Bdc_Fun_t * pNext; // next function with same support - void * pCopy; // the copy field + union { int iCopy; // the literal of the node (AIG) + void * pCopy; }; // the function of the node (BDD or AIG) + }; typedef struct Bdc_Isf_t_ Bdc_Isf_t; @@ -147,9 +151,11 @@ extern void Bdc_TableAdd( Bdc_Man_t * p, Bdc_Fun_t * pFunc ); extern void Bdc_TableClear( Bdc_Man_t * p ); extern int Bdc_TableCheckContainment( Bdc_Man_t * p, Bdc_Isf_t * pIsf, unsigned * puTruth ); -#ifdef __cplusplus -} -#endif + + +ABC_NAMESPACE_HEADER_END + + #endif diff --git a/src/aig/bdc/bdcTable.c b/src/aig/bdc/bdcTable.c index 3a6ed126..69f35d88 100644 --- a/src/aig/bdc/bdcTable.c +++ b/src/aig/bdc/bdcTable.c @@ -20,6 +20,9 @@ #include "bdcInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -127,3 +130,5 @@ void Bdc_TableClear( Bdc_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/bdc/bdc_.c b/src/aig/bdc/bdc_.c index 9d0a9462..b29d4f5e 100644 --- a/src/aig/bdc/bdc_.c +++ b/src/aig/bdc/bdc_.c @@ -20,6 +20,9 @@ #include "bdcInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -47,3 +50,5 @@ //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/cec/cec.c b/src/aig/cec/cec.c index 17b27ec5..6968a599 100644 --- a/src/aig/cec/cec.c +++ b/src/aig/cec/cec.c @@ -20,6 +20,9 @@ #include "cecInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -46,3 +49,5 @@ //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/cec/cec.h b/src/aig/cec/cec.h index 199d6939..e4547f5e 100644 --- a/src/aig/cec/cec.h +++ b/src/aig/cec/cec.h @@ -21,6 +21,7 @@ #ifndef __CEC_H__ #define __CEC_H__ + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -29,9 +30,10 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -103,8 +105,10 @@ struct Cec_ParFra_t_ // int fFirstStop; // stop on the first sat output int fDualOut; // miter with separate outputs int fColorDiff; // miter with separate outputs + int fSatSweeping; // enable SAT sweeping int fVeryVerbose; // verbose stats int fVerbose; // verbose stats + int iOutFail; // the failed output }; // combinational equivalence checking parameters @@ -118,6 +122,7 @@ struct Cec_ParCec_t_ int fRewriting; // enables AIG rewriting int fVeryVerbose; // verbose stats int fVerbose; // verbose stats + int iOutFail; // the number of failed output }; // sequential register correspodence parameters @@ -129,6 +134,8 @@ struct Cec_ParCor_t_ int nFrames; // the number of time frames int nPrefix; // the number of time frames in the prefix int nBTLimit; // conflict limit at a node + int nLevelMax; // (scorr only) the max number of levels + int nStepsMax; // (scorr only) the max number of induction steps int fLatchCorr; // consider only latch outputs int fUseRings; // use rings int fMakeChoices; // use equilvaences as choices @@ -138,6 +145,9 @@ struct Cec_ParCor_t_ int fVerboseFlops; // verbose stats int fVeryVerbose; // verbose stats int fVerbose; // verbose stats + // callback + void * pData; + void * pFunc; }; // sequential register correspodence parameters @@ -153,6 +163,23 @@ struct Cec_ParChc_t_ int fVerbose; // verbose stats }; +// sequential synthesis parameters +typedef struct Cec_ParSeq_t_ Cec_ParSeq_t; +struct Cec_ParSeq_t_ +{ + int fUseLcorr; // enables latch correspondence + int fUseScorr; // enables signal correspondence + int nBTLimit; // (scorr/lcorr) conflict limit at a node + int nFrames; // (scorr/lcorr) the number of timeframes + int nLevelMax; // (scorr only) the max number of levels + int fConsts; // (scl only) merging constants + int fEquivs; // (scl only) merging equivalences + int fUseMiniSat; // enables MiniSat in lcorr/scorr + int nMinDomSize; // the size of minimum clock domain + int fVeryVerbose; // verbose stats + int fVerbose; // verbose stats +}; + //////////////////////////////////////////////////////////////////////// /// MACRO DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -167,6 +194,7 @@ extern int Cec_ManVerifyTwo( Gia_Man_t * p0, Gia_Man_t * p1, int fVerb /*=== cecChoice.c ==========================================================*/ extern Gia_Man_t * Cec_ManChoiceComputation( Gia_Man_t * pAig, Cec_ParChc_t * pPars ); /*=== cecCorr.c ==========================================================*/ +extern int Cec_ManLSCorrespondenceClasses( Gia_Man_t * pAig, Cec_ParCor_t * pPars ); extern Gia_Man_t * Cec_ManLSCorrespondence( Gia_Man_t * pAig, Cec_ParCor_t * pPars ); /*=== cecCore.c ==========================================================*/ extern void Cec_ManSatSetDefaultParams( Cec_ParSat_t * p ); @@ -180,12 +208,20 @@ extern Gia_Man_t * Cec_ManSatSweeping( Gia_Man_t * pAig, Cec_ParFra_t * pPars extern Gia_Man_t * Cec_ManSatSolving( Gia_Man_t * pAig, Cec_ParSat_t * pPars ); extern void Cec_ManSimulation( Gia_Man_t * pAig, Cec_ParSim_t * pPars ); /*=== cecSeq.c ==========================================================*/ -extern int Cec_ManSeqResimulateCounter( Gia_Man_t * pAig, Cec_ParSim_t * pPars, Gia_Cex_t * pCex ); +extern int Cec_ManSeqResimulateCounter( Gia_Man_t * pAig, Cec_ParSim_t * pPars, Abc_Cex_t * pCex ); extern int Cec_ManSeqSemiformal( Gia_Man_t * pAig, Cec_ParSmf_t * pPars ); +extern int Cec_ManCheckNonTrivialCands( Gia_Man_t * pAig ); +/*=== cecSynth.c ==========================================================*/ +extern int Cec_SeqReadMinDomSize( Cec_ParSeq_t * p ); +extern int Cec_SeqReadVerbose( Cec_ParSeq_t * p ); +extern void Cec_SeqSynthesisSetDefaultParams( Cec_ParSeq_t * pPars ); +extern int Cec_SequentialSynthesisPart( Gia_Man_t * p, Cec_ParSeq_t * pPars ); + + + +ABC_NAMESPACE_HEADER_END + -#ifdef __cplusplus -} -#endif #endif diff --git a/src/aig/cec/cecCec.c b/src/aig/cec/cecCec.c index 1efa9235..0859a9ad 100644 --- a/src/aig/cec/cecCec.c +++ b/src/aig/cec/cecCec.c @@ -19,8 +19,12 @@ ***********************************************************************/ #include "cecInt.h" +#include "fra.h" #include "giaAig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -44,8 +48,8 @@ void Cec_ManTransformPattern( Gia_Man_t * p, int iOut, int * pValues ) { int i; assert( p->pCexComb == NULL ); - p->pCexComb = (Gia_Cex_t *)ABC_CALLOC( char, - sizeof(Gia_Cex_t) + sizeof(unsigned) * Gia_BitWordNum(Gia_ManCiNum(p)) ); + p->pCexComb = (Abc_Cex_t *)ABC_CALLOC( char, + sizeof(Abc_Cex_t) + sizeof(unsigned) * Gia_BitWordNum(Gia_ManCiNum(p)) ); p->pCexComb->iPo = iOut; p->pCexComb->nPis = Gia_ManCiNum(p); p->pCexComb->nBits = Gia_ManCiNum(p); @@ -65,45 +69,53 @@ void Cec_ManTransformPattern( Gia_Man_t * p, int iOut, int * pValues ) SeeAlso [] ***********************************************************************/ -int Cec_ManVerifyOld( Gia_Man_t * pMiter, int fVerbose ) +int Cec_ManVerifyOld( Gia_Man_t * pMiter, int fVerbose, int * piOutFail ) { - extern int Fra_FraigCec( Aig_Man_t ** ppAig, int nConfLimit, int fVerbose ); +// extern int Fra_FraigCec( Aig_Man_t ** ppAig, int nConfLimit, int fVerbose ); extern int Ssw_SecCexResimulate( Aig_Man_t * p, int * pModel, int * pnOutputs ); Gia_Man_t * pTemp = Gia_ManTransformMiter( pMiter ); Aig_Man_t * pMiterCec = Gia_ManToAig( pTemp, 0 ); int RetValue, iOut, nOuts, clkTotal = clock(); + if ( piOutFail ) + *piOutFail = -1; Gia_ManStop( pTemp ); // run CEC on this miter - RetValue = Fra_FraigCec( &pMiterCec, 100000, fVerbose ); + RetValue = Fra_FraigCec( &pMiterCec, 10000000, fVerbose ); // report the miter if ( RetValue == 1 ) { - printf( "Networks are equivalent. " ); -ABC_PRT( "Time", clock() - clkTotal ); + Abc_Print( 1, "Networks are equivalent. " ); +Abc_PrintTime( 1, "Time", clock() - clkTotal ); } else if ( RetValue == 0 ) { - printf( "Networks are NOT EQUIVALENT. " ); -ABC_PRT( "Time", clock() - clkTotal ); + Abc_Print( 1, "Networks are NOT EQUIVALENT. " ); +Abc_PrintTime( 1, "Time", clock() - clkTotal ); if ( pMiterCec->pData == NULL ) - printf( "Counter-example is not available.\n" ); + Abc_Print( 1, "Counter-example is not available.\n" ); else { - iOut = Ssw_SecCexResimulate( pMiterCec, pMiterCec->pData, &nOuts ); + iOut = Ssw_SecCexResimulate( pMiterCec, (int *)pMiterCec->pData, &nOuts ); if ( iOut == -1 ) - printf( "Counter-example verification has failed.\n" ); + Abc_Print( 1, "Counter-example verification has failed.\n" ); else { - printf( "Primary output %d has failed in frame %d.\n", iOut ); - printf( "The counter-example detected %d incorrect outputs.\n", nOuts ); +// Aig_Obj_t * pObj = Aig_ManPo(pMiterCec, iOut); +// Aig_Obj_t * pFan = Aig_ObjFanin0(pObj); + Abc_Print( 1, "Primary output %d has failed", iOut ); + if ( nOuts-1 >= 0 ) + Abc_Print( 1, ", along with other %d incorrect outputs", nOuts-1 ); + Abc_Print( 1, ".\n" ); + if ( piOutFail ) + *piOutFail = iOut; } - Cec_ManTransformPattern( pMiter, iOut, pMiterCec->pData ); + Cec_ManTransformPattern( pMiter, iOut, (int *)pMiterCec->pData ); } } else { - printf( "Networks are UNDECIDED. " ); -ABC_PRT( "Time", clock() - clkTotal ); + Abc_Print( 1, "Networks are UNDECIDED. " ); +Abc_PrintTime( 1, "Time", clock() - clkTotal ); } fflush( stdout ); Aig_ManStop( pMiterCec ); @@ -121,13 +133,18 @@ ABC_PRT( "Time", clock() - clkTotal ); SeeAlso [] ***********************************************************************/ -int Cec_ManVerify( Gia_Man_t * p, Cec_ParCec_t * pPars ) +int Cec_ManVerify( Gia_Man_t * pInit, Cec_ParCec_t * pPars ) { - int fDumpUndecided = 1; + int fDumpUndecided = 0; Cec_ParFra_t ParsFra, * pParsFra = &ParsFra; - Gia_Man_t * pNew; + Gia_Man_t * p, * pNew; int RetValue, clk = clock(); double clkTotal = clock(); + // preprocess + p = Gia_ManDup( pInit ); + Gia_ManEquivFixOutputPairs( p ); + p = Gia_ManCleanup( pNew = p ); + Gia_ManStop( pNew ); // sweep for equivalences Cec_ManFraSetDefaultParams( pParsFra ); pParsFra->nItersMax = 1000; @@ -137,27 +154,60 @@ int Cec_ManVerify( Gia_Man_t * p, Cec_ParCec_t * pPars ) pParsFra->fCheckMiter = 1; pParsFra->fDualOut = 1; pNew = Cec_ManSatSweeping( p, pParsFra ); + pPars->iOutFail = pParsFra->iOutFail; + // update + pInit->pCexComb = p->pCexComb; p->pCexComb = NULL; + Gia_ManStop( p ); + p = pInit; + // continue if ( pNew == NULL ) { - if ( !Gia_ManVerifyCounterExample( p, p->pCexComb, 1 ) ) - printf( "Counter-example simulation has failed.\n" ); - printf( "Networks are NOT EQUIVALENT. " ); - ABC_PRT( "Time", clock() - clk ); - return 0; + if ( p->pCexComb != NULL ) + { + if ( p->pCexComb && !Gia_ManVerifyCounterExample( p, p->pCexComb, 1 ) ) + Abc_Print( 1, "Counter-example simulation has failed.\n" ); + Abc_Print( 1, "Networks are NOT EQUIVALENT. " ); + Abc_PrintTime( 1, "Time", clock() - clk ); + return 0; + } + p = Gia_ManDup( pInit ); + Gia_ManEquivFixOutputPairs( p ); + p = Gia_ManCleanup( pNew = p ); + Gia_ManStop( pNew ); + pNew = p; } if ( Gia_ManAndNum(pNew) == 0 ) { - printf( "Networks are equivalent. " ); - ABC_PRT( "Time", clock() - clk ); + Gia_Obj_t * pObj1, * pObj2; + int i; + Gia_ManForEachPo( pNew, pObj1, i ) + { + pObj2 = Gia_ManPo( pNew, ++i ); + if ( Gia_ObjChild0(pObj1) != Gia_ObjChild0(pObj2) ) + { + Abc_Print( 1, "Networks are NOT EQUIVALENT. Outputs %d trivially differ. ", i/2 ); + Abc_PrintTime( 1, "Time", clock() - clk ); + Gia_ManStop( pNew ); + pPars->iOutFail = i/2; + return 0; + } + } + Abc_Print( 1, "Networks are equivalent. " ); + Abc_PrintTime( 1, "Time", clock() - clk ); Gia_ManStop( pNew ); return 1; } - printf( "Networks are UNDECIDED after the new CEC engine. " ); - ABC_PRT( "Time", clock() - clk ); + if ( pPars->fVerbose ) + { + Abc_Print( 1, "Networks are UNDECIDED after the new CEC engine. " ); + Abc_PrintTime( 1, "Time", clock() - clk ); + } if ( fDumpUndecided ) { + ABC_FREE( pNew->pReprs ); + ABC_FREE( pNew->pNexts ); Gia_WriteAiger( pNew, "gia_cec_undecided.aig", 0, 0 ); - printf( "The result is written into file \"%s\".\n", "gia_cec_undecided.aig" ); + Abc_Print( 1, "The result is written into file \"%s\".\n", "gia_cec_undecided.aig" ); } if ( pPars->TimeLimit && ((double)clock() - clkTotal)/CLOCKS_PER_SEC >= pPars->TimeLimit ) { @@ -165,12 +215,13 @@ int Cec_ManVerify( Gia_Man_t * p, Cec_ParCec_t * pPars ) return -1; } // call other solver - printf( "Calling the old CEC engine.\n" ); + if ( pPars->fVerbose ) + Abc_Print( 1, "Calling the old CEC engine.\n" ); fflush( stdout ); - RetValue = Cec_ManVerifyOld( pNew, pPars->fVerbose ); + RetValue = Cec_ManVerifyOld( pNew, pPars->fVerbose, &pPars->iOutFail ); p->pCexComb = pNew->pCexComb; pNew->pCexComb = NULL; if ( p->pCexComb && !Gia_ManVerifyCounterExample( p, p->pCexComb, 1 ) ) - printf( "Counter-example simulation has failed.\n" ); + Abc_Print( 1, "Counter-example simulation has failed.\n" ); Gia_ManStop( pNew ); return RetValue; } @@ -208,7 +259,7 @@ int Cec_ManVerifyTwo( Gia_Man_t * p0, Gia_Man_t * p1, int fVerbose ) Description [Returns 1 if equivalent, 0 if counter-example, -1 if undecided. Counter-example is returned in the first manager as pAig0->pSeqModel. - The format is given in Gia_Cex_t (file "abc\src\aig\gia\gia.h").] + The format is given in Abc_Cex_t (file "abc\src\aig\gia\gia.h").] SideEffects [] @@ -248,7 +299,6 @@ int Cec_ManVerifyTwoAigs( Aig_Man_t * pAig0, Aig_Man_t * pAig1, int fVerbose ) ***********************************************************************/ Aig_Man_t * Cec_LatchCorrespondence( Aig_Man_t * pAig, int nConfs, int fUseCSat ) { - extern int Cec_ManLSCorrespondenceClasses( Gia_Man_t * pAig, Cec_ParCor_t * pPars ); Gia_Man_t * pGia; Cec_ParCor_t CorPars, * pCorPars = &CorPars; Cec_ManCorSetDefaultParams( pCorPars ); @@ -275,7 +325,6 @@ Aig_Man_t * Cec_LatchCorrespondence( Aig_Man_t * pAig, int nConfs, int fUseCSat ***********************************************************************/ Aig_Man_t * Cec_SignalCorrespondence( Aig_Man_t * pAig, int nConfs, int fUseCSat ) { - extern int Cec_ManLSCorrespondenceClasses( Gia_Man_t * pAig, Cec_ParCor_t * pPars ); Gia_Man_t * pGia; Cec_ParCor_t CorPars, * pCorPars = &CorPars; Cec_ManCorSetDefaultParams( pCorPars ); @@ -304,6 +353,7 @@ Aig_Man_t * Cec_FraigCombinational( Aig_Man_t * pAig, int nConfs, int fVerbose ) Gia_Man_t * pGia; Cec_ParFra_t FraPars, * pFraPars = &FraPars; Cec_ManFraSetDefaultParams( pFraPars ); + pFraPars->fSatSweeping = 1; pFraPars->nBTLimit = nConfs; pFraPars->nItersMax = 20; pFraPars->fVerbose = fVerbose; @@ -319,3 +369,5 @@ Aig_Man_t * Cec_FraigCombinational( Aig_Man_t * pAig, int nConfs, int fVerbose ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/cec/cecChoice.c b/src/aig/cec/cecChoice.c index fc316f46..076b34a2 100644 --- a/src/aig/cec/cecChoice.c +++ b/src/aig/cec/cecChoice.c @@ -22,6 +22,9 @@ #include "giaAig.h" #include "dch.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -175,9 +178,9 @@ Gia_Man_t * Cec_ManCombSpecReduce( Gia_Man_t * p, Vec_Int_t ** pvOutputs, int fR Gia_ManAppendCo( pNew, iObjNew ); Vec_IntFree( vXorLits ); Gia_ManHashStop( pNew ); -//printf( "Before sweeping = %d\n", Gia_ManAndNum(pNew) ); +//Abc_Print( 1, "Before sweeping = %d\n", Gia_ManAndNum(pNew) ); pNew = Gia_ManCleanup( pTemp = pNew ); -//printf( "After sweeping = %d\n", Gia_ManAndNum(pNew) ); +//Abc_Print( 1, "After sweeping = %d\n", Gia_ManAndNum(pNew) ); Gia_ManStop( pTemp ); return pNew; } @@ -219,7 +222,7 @@ int Cec_ManChoiceComputation_int( Gia_Man_t * pAig, Cec_ParChc_t * pPars ) pParsSim->fSeqSimulate = 0; // create equivalence classes of registers pSim = Cec_ManSimStart( pAig, pParsSim ); - Cec_ManSimClassesPrepare( pSim ); + Cec_ManSimClassesPrepare( pSim, -1 ); Cec_ManSimClassesRefine( pSim ); // prepare SAT solving Cec_ManSatSetDefaultParams( pParsSat ); @@ -227,7 +230,7 @@ int Cec_ManChoiceComputation_int( Gia_Man_t * pAig, Cec_ParChc_t * pPars ) pParsSat->fVerbose = pPars->fVerbose; if ( pPars->fVerbose ) { - printf( "Obj = %7d. And = %7d. Conf = %5d. Ring = %d. CSat = %d.\n", + Abc_Print( 1, "Obj = %7d. And = %7d. Conf = %5d. Ring = %d. CSat = %d.\n", Gia_ManObjNum(pAig), Gia_ManAndNum(pAig), pPars->nBTLimit, pPars->fUseRings, pPars->fUseCSat ); Cec_ManRefinedClassPrintStats( pAig, NULL, 0, clock() - clk ); } @@ -280,97 +283,23 @@ int Cec_ManChoiceComputation_int( Gia_Man_t * pAig, Cec_ParChc_t * pPars ) } // check the overflow if ( r == nItersMax ) - printf( "The refinement was not finished. The result may be incorrect.\n" ); + Abc_Print( 1, "The refinement was not finished. The result may be incorrect.\n" ); Cec_ManSimStop( pSim ); clkTotal = clock() - clkTotal; // report the results if ( pPars->fVerbose ) { - ABC_PRTP( "Srm ", clkSrm, clkTotal ); - ABC_PRTP( "Sat ", clkSat, clkTotal ); - ABC_PRTP( "Sim ", clkSim, clkTotal ); - ABC_PRTP( "Other", clkTotal-clkSat-clkSrm-clkSim, clkTotal ); - ABC_PRT( "TOTAL", clkTotal ); + Abc_PrintTimeP( 1, "Srm ", clkSrm, clkTotal ); + Abc_PrintTimeP( 1, "Sat ", clkSat, clkTotal ); + Abc_PrintTimeP( 1, "Sim ", clkSim, clkTotal ); + Abc_PrintTimeP( 1, "Other", clkTotal-clkSat-clkSrm-clkSim, clkTotal ); + Abc_PrintTime( 1, "TOTAL", clkTotal ); } return 0; } /**Function************************************************************* - Synopsis [Duplicates the AIG in the DFS order.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Gia_ManChoiceMiter_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) -{ - if ( ~pObj->Value ) - return pObj->Value; - Gia_ManChoiceMiter_rec( pNew, p, Gia_ObjFanin0(pObj) ); - if ( Gia_ObjIsCo(pObj) ) - return pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); - Gia_ManChoiceMiter_rec( pNew, p, Gia_ObjFanin1(pObj) ); - return pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); -} - -/**Function************************************************************* - - Synopsis [Derives the miter of several AIGs for choice computation.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Gia_Man_t * Gia_ManChoiceMiter( Vec_Ptr_t * vGias ) -{ - Gia_Man_t * pNew, * pGia, * pGia0; - int i, k, iNode, nNodes; - // make sure they have equal parameters - assert( Vec_PtrSize(vGias) > 0 ); - pGia0 = Vec_PtrEntry( vGias, 0 ); - Vec_PtrForEachEntry( vGias, pGia, i ) - { - assert( Gia_ManCiNum(pGia) == Gia_ManCiNum(pGia0) ); - assert( Gia_ManCoNum(pGia) == Gia_ManCoNum(pGia0) ); - assert( Gia_ManRegNum(pGia) == Gia_ManRegNum(pGia0) ); - Gia_ManFillValue( pGia ); - Gia_ManConst0(pGia)->Value = 0; - } - // start the new manager - pNew = Gia_ManStart( Vec_PtrSize(vGias) * Gia_ManObjNum(pGia0) ); - pNew->pName = Gia_UtilStrsav( pGia0->pName ); - // create new CIs and assign them to the old manager CIs - for ( k = 0; k < Gia_ManCiNum(pGia0); k++ ) - { - iNode = Gia_ManAppendCi(pNew); - Vec_PtrForEachEntry( vGias, pGia, i ) - Gia_ManCi( pGia, k )->Value = iNode; - } - // create internal nodes - Gia_ManHashAlloc( pNew ); - for ( k = 0; k < Gia_ManCoNum(pGia0); k++ ) - { - Vec_PtrForEachEntry( vGias, pGia, i ) - Gia_ManChoiceMiter_rec( pNew, pGia, Gia_ManCo( pGia, k ) ); - } - Gia_ManHashStop( pNew ); - // check the presence of dangling nodes - nNodes = Gia_ManHasDandling( pNew ); - assert( nNodes == 0 ); - // finalize -// Gia_ManSetRegNum( pNew, Gia_ManRegNum(pGia0) ); - return pNew; -} - -/**Function************************************************************* - Synopsis [Computes choices for the vector of AIGs.] Description [] @@ -386,6 +315,7 @@ Gia_Man_t * Cec_ManChoiceComputationVec( Gia_Man_t * pGia, int nGias, Cec_ParChc int RetValue; // compute equivalences of the miter // pMiter = Gia_ManChoiceMiter( vGias ); +// Gia_ManSetRegNum( pMiter, 0 ); RetValue = Cec_ManChoiceComputation_int( pGia, pPars ); // derive AIG with choices pNew = Gia_ManEquivToChoices( pGia, nGias ); @@ -394,7 +324,7 @@ Gia_Man_t * Cec_ManChoiceComputationVec( Gia_Man_t * pGia, int nGias, Cec_ParChc // report the results if ( pPars->fVerbose ) { -// printf( "NBeg = %d. NEnd = %d. (Gain = %6.2f %%). RBeg = %d. REnd = %d. (Gain = %6.2f %%).\n", +// Abc_Print( 1, "NBeg = %d. NEnd = %d. (Gain = %6.2f %%). RBeg = %d. REnd = %d. (Gain = %6.2f %%).\n", // Gia_ManAndNum(pAig), Gia_ManAndNum(pNew), // 100.0*(Gia_ManAndNum(pAig)-Gia_ManAndNum(pNew))/(Gia_ManAndNum(pAig)?Gia_ManAndNum(pAig):1), // Gia_ManRegNum(pAig), Gia_ManRegNum(pNew), @@ -416,7 +346,7 @@ Gia_Man_t * Cec_ManChoiceComputationVec( Gia_Man_t * pGia, int nGias, Cec_ParChc ***********************************************************************/ Gia_Man_t * Cec_ManChoiceComputation( Gia_Man_t * pAig, Cec_ParChc_t * pParsChc ) { - extern Aig_Man_t * Dar_ManChoiceNew( Aig_Man_t * pAig, Dch_Pars_t * pPars ); +// extern Aig_Man_t * Dar_ManChoiceNew( Aig_Man_t * pAig, Dch_Pars_t * pPars ); Dch_Pars_t Pars, * pPars = &Pars; Aig_Man_t * pMan, * pManNew; Gia_Man_t * pGia; @@ -456,7 +386,7 @@ Aig_Man_t * Cec_ComputeChoices( Gia_Man_t * pGia, Dch_Pars_t * pPars ) Cec_ParChc_t ParsChc, * pParsChc = &ParsChc; Aig_Man_t * pAig; if ( pPars->fVerbose ) - ABC_PRT( "Synthesis time", pPars->timeSynth ); + Abc_PrintTime( 1, "Synthesis time", pPars->timeSynth ); Cec_ManChcSetDefaultParams( pParsChc ); pParsChc->nBTLimit = pPars->nBTLimit; pParsChc->fUseCSat = pPars->fUseCSat; @@ -475,3 +405,5 @@ Aig_Man_t * Cec_ComputeChoices( Gia_Man_t * pGia, Dch_Pars_t * pPars ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/cec/cecClass.c b/src/aig/cec/cecClass.c index 749f7f71..95414851 100644 --- a/src/aig/cec/cecClass.c +++ b/src/aig/cec/cecClass.c @@ -20,6 +20,9 @@ #include "cecInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -375,7 +378,7 @@ int Cec_ManSimHashKey( unsigned * pSim, int nWords, int nTableSize ) void Cec_ManSimMemRelink( Cec_ManSim_t * p ) { unsigned * pPlace, Ent; - pPlace = &p->MemFree; + pPlace = (unsigned *)&p->MemFree; for ( Ent = p->nMems * (p->nWords + 1); Ent + p->nWords + 1 < (unsigned)p->nWordsAlloc; Ent += p->nWords + 1 ) @@ -518,14 +521,14 @@ void Cec_ManSimSavePattern( Cec_ManSim_t * p, int iPat ) int i; assert( p->pCexComb == NULL ); assert( iPat >= 0 && iPat < 32 * p->nWords ); - p->pCexComb = (Gia_Cex_t *)ABC_CALLOC( char, - sizeof(Gia_Cex_t) + sizeof(unsigned) * Gia_BitWordNum(Gia_ManCiNum(p->pAig)) ); + p->pCexComb = (Abc_Cex_t *)ABC_CALLOC( char, + sizeof(Abc_Cex_t) + sizeof(unsigned) * Gia_BitWordNum(Gia_ManCiNum(p->pAig)) ); p->pCexComb->iPo = p->iOut; p->pCexComb->nPis = Gia_ManCiNum(p->pAig); p->pCexComb->nBits = Gia_ManCiNum(p->pAig); for ( i = 0; i < Gia_ManCiNum(p->pAig); i++ ) { - pInfo = Vec_PtrEntry( p->vCiSimInfo, i ); + pInfo = (unsigned *)Vec_PtrEntry( p->vCiSimInfo, i ); if ( Gia_InfoHasBit( pInfo, iPat ) ) Gia_InfoSetBit( p->pCexComb->pData, i ); } @@ -559,7 +562,7 @@ void Cec_ManSimFindBestPattern( Cec_ManSim_t * p ) assert( p->pBestState->nRegs == Gia_ManRegNum(p->pAig) ); for ( i = 0; i < Gia_ManRegNum(p->pAig); i++ ) { - pInfo = Vec_PtrEntry( p->vCiSimInfo, Gia_ManPiNum(p->pAig) + i ); + pInfo = (unsigned *)Vec_PtrEntry( p->vCiSimInfo, Gia_ManPiNum(p->pAig) + i ); if ( Gia_InfoHasBit(p->pBestState->pData, i) != Gia_InfoHasBit(pInfo, iPatBest) ) Gia_InfoXorBit( p->pBestState->pData, i ); } @@ -591,8 +594,8 @@ int Cec_ManSimAnalyzeOutputs( Cec_ManSim_t * p ) assert( (Gia_ManPoNum(p->pAig) & 1) == 0 ); for ( i = 0; i < Gia_ManPoNum(p->pAig); i++ ) { - pInfo = Vec_PtrEntry( p->vCoSimInfo, i ); - pInfo2 = Vec_PtrEntry( p->vCoSimInfo, ++i ); + pInfo = (unsigned *)Vec_PtrEntry( p->vCoSimInfo, i ); + pInfo2 = (unsigned *)Vec_PtrEntry( p->vCoSimInfo, ++i ); if ( !Cec_ManSimCompareEqual( pInfo, pInfo2, p->nWords ) ) { if ( p->iOut == -1 ) @@ -614,7 +617,7 @@ int Cec_ManSimAnalyzeOutputs( Cec_ManSim_t * p ) { for ( i = 0; i < Gia_ManPoNum(p->pAig); i++ ) { - pInfo = Vec_PtrEntry( p->vCoSimInfo, i ); + pInfo = (unsigned *)Vec_PtrEntry( p->vCoSimInfo, i ); if ( !Cec_ManSimCompareConst( pInfo, p->nWords ) ) { if ( p->iOut == -1 ) @@ -679,7 +682,7 @@ int Cec_ManSimSimulateRound( Cec_ManSim_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t * pRes = Cec_ManSimSimRef( p, i ); if ( vInfoCis ) { - pRes0 = Vec_PtrEntry( vInfoCis, iCiId++ ); + pRes0 = (unsigned *)Vec_PtrEntry( vInfoCis, iCiId++ ); for ( w = 1; w <= p->nWords; w++ ) pRes[w] = pRes0[w-1]; } @@ -697,7 +700,7 @@ int Cec_ManSimSimulateRound( Cec_ManSim_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t * pRes0 = Cec_ManSimSimDeref( p, Gia_ObjFaninId0(pObj,i) ); if ( vInfoCos ) { - pRes = Vec_PtrEntry( vInfoCos, iCoId++ ); + pRes = (unsigned *)Vec_PtrEntry( vInfoCos, iCoId++ ); if ( Gia_ObjFaninC0(pObj) ) for ( w = 1; w <= p->nWords; w++ ) pRes[w-1] = ~pRes0[w]; @@ -712,7 +715,7 @@ int Cec_ManSimSimulateRound( Cec_ManSim_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t * pRes0 = Cec_ManSimSimDeref( p, Gia_ObjFaninId0(pObj,i) ); pRes1 = Cec_ManSimSimDeref( p, Gia_ObjFaninId1(pObj,i) ); -// printf( "%d,%d ", Gia_ObjValue( Gia_ObjFanin0(pObj) ), Gia_ObjValue( Gia_ObjFanin1(pObj) ) ); +// Abc_Print( 1, "%d,%d ", Gia_ObjValue( Gia_ObjFanin0(pObj) ), Gia_ObjValue( Gia_ObjFanin1(pObj) ) ); if ( Gia_ObjFaninC0(pObj) ) { @@ -762,7 +765,7 @@ references: assert( vInfoCos == NULL || iCoId == Gia_ManCoNum(p->pAig) ); assert( p->nMems == 1 ); if ( p->nMems != 1 ) - printf( "Cec_ManSimSimulateRound(): Memory management error!\n" ); + Abc_Print( 1, "Cec_ManSimSimulateRound(): Memory management error!\n" ); if ( p->pPars->fVeryVerbose ) Gia_ManEquivPrintClasses( p->pAig, 0, Cec_MemUsage(p) ); if ( p->pBestState ) @@ -800,14 +803,14 @@ void Cec_ManSimCreateInfo( Cec_ManSim_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t * v assert( vInfoCis && vInfoCos ); for ( i = 0; i < Gia_ManPiNum(p->pAig); i++ ) { - pRes0 = Vec_PtrEntry( vInfoCis, i ); + pRes0 = (unsigned *)Vec_PtrEntry( vInfoCis, i ); for ( w = 0; w < p->nWords; w++ ) pRes0[w] = Gia_ManRandom( 0 ); } for ( i = 0; i < Gia_ManRegNum(p->pAig); i++ ) { - pRes0 = Vec_PtrEntry( vInfoCis, Gia_ManPiNum(p->pAig) + i ); - pRes1 = Vec_PtrEntry( vInfoCos, Gia_ManPoNum(p->pAig) + i ); + pRes0 = (unsigned *)Vec_PtrEntry( vInfoCis, Gia_ManPiNum(p->pAig) + i ); + pRes1 = (unsigned *)Vec_PtrEntry( vInfoCos, Gia_ManPoNum(p->pAig) + i ); for ( w = 0; w < p->nWords; w++ ) pRes0[w] = pRes1[w]; } @@ -816,7 +819,7 @@ void Cec_ManSimCreateInfo( Cec_ManSim_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t * v { for ( i = 0; i < Gia_ManCiNum(p->pAig); i++ ) { - pRes0 = Vec_PtrEntry( vInfoCis, i ); + pRes0 = (unsigned *)Vec_PtrEntry( vInfoCis, i ); for ( w = 0; w < p->nWords; w++ ) pRes0[w] = Gia_ManRandom( 0 ); } @@ -834,7 +837,7 @@ void Cec_ManSimCreateInfo( Cec_ManSim_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t * v SeeAlso [] ***********************************************************************/ -int Cec_ManSimClassesPrepare( Cec_ManSim_t * p ) +int Cec_ManSimClassesPrepare( Cec_ManSim_t * p, int LevelMax ) { Gia_Obj_t * pObj; int i; @@ -848,9 +851,16 @@ int Cec_ManSimClassesPrepare( Cec_ManSim_t * p ) if ( p->pPars->fLatchCorr ) Gia_ManForEachObj( p->pAig, pObj, i ) Gia_ObjSetRepr( p->pAig, i, GIA_VOID ); - else + else if ( LevelMax == -1 ) Gia_ManForEachObj( p->pAig, pObj, i ) Gia_ObjSetRepr( p->pAig, i, Gia_ObjIsAnd(pObj) ? 0 : GIA_VOID ); + else + { + Gia_ManLevelNum( p->pAig ); + Gia_ManForEachObj( p->pAig, pObj, i ) + Gia_ObjSetRepr( p->pAig, i, (Gia_ObjIsAnd(pObj) && Gia_ObjLevel(p->pAig,pObj) <= LevelMax) ? 0 : GIA_VOID ); + Vec_IntFreeP( &p->pAig->vLevels ); + } // if sequential simulation, set starting representative of ROs to be constant 0 if ( p->pPars->fSeqSimulate ) Gia_ManForEachRo( p->pAig, pObj, i ) @@ -906,3 +916,5 @@ int Cec_ManSimClassesRefine( Cec_ManSim_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/cec/cecCore.c b/src/aig/cec/cecCore.c index 10c145ec..5e71dbff 100644 --- a/src/aig/cec/cecCore.c +++ b/src/aig/cec/cecCore.c @@ -20,6 +20,9 @@ #include "cecInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -133,8 +136,10 @@ void Cec_ManFraSetDefaultParams( Cec_ParFra_t * p ) // p->fFirstStop = 0; // stop on the first sat output p->fDualOut = 0; // miter with separate outputs p->fColorDiff = 0; // miter with separate outputs + p->fSatSweeping = 0; // enable SAT sweeping p->fVeryVerbose = 0; // verbose stats p->fVerbose = 0; // verbose stats + p->iOutFail = -1; // the failed output } /**Function************************************************************* @@ -158,6 +163,7 @@ void Cec_ManCecSetDefaultParams( Cec_ParCec_t * p ) p->fRewriting = 0; // enables AIG rewriting p->fVeryVerbose = 0; // verbose stats p->fVerbose = 0; // verbose stats + p->iOutFail = -1; // the number of failed output } /**Function************************************************************* @@ -178,6 +184,8 @@ void Cec_ManCorSetDefaultParams( Cec_ParCor_t * p ) p->nRounds = 15; // the number of simulation rounds p->nFrames = 1; // the number of time frames p->nBTLimit = 100; // conflict limit at a node + p->nLevelMax = -1; // (scorr only) the max number of levels + p->nStepsMax = -1; // (scorr only) the max number of induction steps p->fLatchCorr = 0; // consider only latch outputs p->fUseRings = 1; // combine classes into rings p->fUseCSat = 1; // use circuit-based solver @@ -249,12 +257,12 @@ int Cec_ManSimulationOne( Gia_Man_t * pAig, Cec_ParSim_t * pPars ) Cec_ManSim_t * pSim; int RetValue = 0, clkTotal = clock(); pSim = Cec_ManSimStart( pAig, pPars ); - if ( (pAig->pReprs == NULL && (RetValue = Cec_ManSimClassesPrepare( pSim ))) || + if ( (pAig->pReprs == NULL && (RetValue = Cec_ManSimClassesPrepare( pSim, -1 ))) || (RetValue == 0 && (RetValue = Cec_ManSimClassesRefine( pSim ))) ) - printf( "The number of failed outputs of the miter = %6d. (Words = %4d. Frames = %4d.)\n", + Abc_Print( 1, "The number of failed outputs of the miter = %6d. (Words = %4d. Frames = %4d.)\n", pSim->nOuts, pPars->nWords, pPars->nFrames ); if ( pPars->fVerbose ) - ABC_PRT( "Time", clock() - clkTotal ); + Abc_PrintTime( 1, "Time", clock() - clkTotal ); Cec_ManSimStop( pSim ); return RetValue; } @@ -275,7 +283,7 @@ void Cec_ManSimulation( Gia_Man_t * pAig, Cec_ParSim_t * pPars ) int r, nLitsOld, nLitsNew, nCountNoRef = 0, fStop = 0; Gia_ManRandom( 1 ); if ( pPars->fSeqSimulate ) - printf( "Performing rounds of random simulation of %d frames with %d words.\n", + Abc_Print( 1, "Performing rounds of random simulation of %d frames with %d words.\n", pPars->nRounds, pPars->nFrames, pPars->nWords ); nLitsOld = Gia_ManEquivCountLits( pAig ); for ( r = 0; r < pPars->nRounds; r++ ) @@ -301,14 +309,14 @@ void Cec_ManSimulation( Gia_Man_t * pAig, Cec_ParSim_t * pPars ) } // if ( pPars->fVerbose ) if ( r == pPars->nRounds || fStop ) - printf( "Random simulation is stopped after %d rounds.\n", r ); + Abc_Print( 1, "Random simulation is stopped after %d rounds.\n", r ); else - printf( "Random simulation saturated after %d rounds.\n", r ); + Abc_Print( 1, "Random simulation saturated after %d rounds.\n", r ); if ( pPars->fCheckMiter ) { int nNonConsts = Cec_ManCountNonConstOutputs( pAig ); if ( nNonConsts ) - printf( "The number of POs that are not const-0 candidates = %d.\n", nNonConsts ); + Abc_Print( 1, "The number of POs that are not const-0 candidates = %d.\n", nNonConsts ); } } @@ -366,7 +374,7 @@ Gia_Man_t * Cec_ManSatSweeping( Gia_Man_t * pAig, Cec_ParFra_t * pPars ) clk = clock(); if ( p->pAig->pReprs == NULL ) { - if ( Cec_ManSimClassesPrepare(pSim) || Cec_ManSimClassesRefine(pSim) ) + if ( Cec_ManSimClassesPrepare(pSim, -1) || Cec_ManSimClassesRefine(pSim) ) { Gia_ManStop( p->pAig ); p->pAig = NULL; @@ -395,19 +403,19 @@ p->timeSim += clock() - clk; { Gia_ManStop( pSrm ); if ( p->pPars->fVerbose ) - printf( "Considered all available candidate equivalences.\n" ); + Abc_Print( 1, "Considered all available candidate equivalences.\n" ); if ( pPars->fDualOut && Gia_ManAndNum(p->pAig) > 0 ) { if ( pPars->fColorDiff ) { if ( p->pPars->fVerbose ) - printf( "Switching into reduced mode.\n" ); + Abc_Print( 1, "Switching into reduced mode.\n" ); pPars->fColorDiff = 0; } else { if ( p->pPars->fVerbose ) - printf( "Switching into normal mode.\n" ); + Abc_Print( 1, "Switching into normal mode.\n" ); pPars->fDualOut = 0; } continue; @@ -433,14 +441,14 @@ p->timeSat += clock() - clk; break; if ( p->pPars->fVerbose ) { - printf( "%3d : P =%7d. D =%7d. F =%6d. M = %7d. And =%8d. ", + Abc_Print( 1, "%3d : P =%7d. D =%7d. F =%6d. M = %7d. And =%8d. ", i, p->nAllProved, p->nAllDisproved, p->nAllFailed, nMatches, Gia_ManAndNum(p->pAig) ); - ABC_PRT( "Time", clock() - clk2 ); + Abc_PrintTime( 1, "Time", clock() - clk2 ); } if ( Gia_ManAndNum(p->pAig) == 0 ) { if ( p->pPars->fVerbose ) - printf( "Network after reduction is empty.\n" ); + Abc_Print( 1, "Network after reduction is empty.\n" ); break; } // check resource limits @@ -454,54 +462,63 @@ p->timeSat += clock() - clk; { if ( pParsSat->nBTLimit >= 10001 ) break; + if ( pPars->fSatSweeping ) + { + if ( p->pPars->fVerbose ) + Abc_Print( 1, "Exceeded the limit on the number of conflicts (%d).\n", pParsSat->nBTLimit ); + break; + } pParsSat->nBTLimit *= 10; if ( p->pPars->fVerbose ) { if ( p->pPars->fVerbose ) - printf( "Increasing conflict limit to %d.\n", pParsSat->nBTLimit ); + Abc_Print( 1, "Increasing conflict limit to %d.\n", pParsSat->nBTLimit ); if ( fOutputResult ) { Gia_WriteAiger( p->pAig, "gia_cec_temp.aig", 0, 0 ); - printf("The result is written into file \"%s\".\n", "gia_cec_temp.aig" ); + Abc_Print( 1,"The result is written into file \"%s\".\n", "gia_cec_temp.aig" ); } } } if ( pPars->fDualOut && pPars->fColorDiff && (Gia_ManAndNum(p->pAig) < 100000 || p->nAllProved + p->nAllDisproved < 10) ) { if ( p->pPars->fVerbose ) - printf( "Switching into reduced mode.\n" ); + Abc_Print( 1, "Switching into reduced mode.\n" ); pPars->fColorDiff = 0; } // if ( pPars->fDualOut && Gia_ManAndNum(p->pAig) < 20000 ) else if ( pPars->fDualOut && (Gia_ManAndNum(p->pAig) < 20000 || p->nAllProved + p->nAllDisproved < 10) ) { if ( p->pPars->fVerbose ) - printf( "Switching into normal mode.\n" ); + Abc_Print( 1, "Switching into normal mode.\n" ); pPars->fColorDiff = 0; pPars->fDualOut = 0; } } finalize: - if ( p->pPars->fVerbose ) + if ( p->pPars->fVerbose && p->pAig ) { - printf( "NBeg = %d. NEnd = %d. (Gain = %6.2f %%). RBeg = %d. REnd = %d. (Gain = %6.2f %%).\n", + Abc_Print( 1, "NBeg = %d. NEnd = %d. (Gain = %6.2f %%). RBeg = %d. REnd = %d. (Gain = %6.2f %%).\n", Gia_ManAndNum(pAig), Gia_ManAndNum(p->pAig), 100.0*(Gia_ManAndNum(pAig)-Gia_ManAndNum(p->pAig))/(Gia_ManAndNum(pAig)?Gia_ManAndNum(pAig):1), Gia_ManRegNum(pAig), Gia_ManRegNum(p->pAig), 100.0*(Gia_ManRegNum(pAig)-Gia_ManRegNum(p->pAig))/(Gia_ManRegNum(pAig)?Gia_ManRegNum(pAig):1) ); - ABC_PRTP( "Sim ", p->timeSim, clock() - (int)clkTotal ); - ABC_PRTP( "Sat ", p->timeSat-pPat->timeTotalSave, clock() - (int)clkTotal ); - ABC_PRTP( "Pat ", p->timePat+pPat->timeTotalSave, clock() - (int)clkTotal ); - ABC_PRT( "Time", clock() - clkTotal ); + Abc_PrintTimeP( 1, "Sim ", p->timeSim, clock() - (int)clkTotal ); + Abc_PrintTimeP( 1, "Sat ", p->timeSat-pPat->timeTotalSave, clock() - (int)clkTotal ); + Abc_PrintTimeP( 1, "Pat ", p->timePat+pPat->timeTotalSave, clock() - (int)clkTotal ); + Abc_PrintTime( 1, "Time", (int)(clock() - clkTotal) ); } pTemp = p->pAig; p->pAig = NULL; if ( pTemp == NULL && pSim->iOut >= 0 ) - printf( "Disproved at least one output of the miter (zero-based number %d).\n", pSim->iOut ); + { + Abc_Print( 1, "Disproved at least one output of the miter (zero-based number %d).\n", pSim->iOut ); + pPars->iOutFail = pSim->iOut; + } else if ( pSim->pCexes ) - printf( "Disproved %d outputs of the miter.\n", pSim->nOuts ); + Abc_Print( 1, "Disproved %d outputs of the miter.\n", pSim->nOuts ); if ( fTimeOut ) - printf( "Timed out after %d seconds.\n", (int)((double)clock() - clkTotal)/CLOCKS_PER_SEC ); + Abc_Print( 1, "Timed out after %d seconds.\n", (int)((double)clock() - clkTotal)/CLOCKS_PER_SEC ); pAig->pCexComb = pSim->pCexComb; pSim->pCexComb = NULL; Cec_ManSimStop( pSim ); @@ -516,3 +533,5 @@ finalize: //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/cec/cecCorr.c b/src/aig/cec/cecCorr.c index 52d2b80e..565ca47e 100644 --- a/src/aig/cec/cecCorr.c +++ b/src/aig/cec/cecCorr.c @@ -20,6 +20,9 @@ #include "cecInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -197,9 +200,9 @@ Gia_Man_t * Gia_ManCorrSpecReduce( Gia_Man_t * p, int nFrames, int fScorr, Vec_I Vec_IntFree( vXorLits ); Gia_ManHashStop( pNew ); ABC_FREE( p->pCopies ); -//printf( "Before sweeping = %d\n", Gia_ManAndNum(pNew) ); +//Abc_Print( 1, "Before sweeping = %d\n", Gia_ManAndNum(pNew) ); pNew = Gia_ManCleanup( pTemp = pNew ); -//printf( "After sweeping = %d\n", Gia_ManAndNum(pNew) ); +//Abc_Print( 1, "After sweeping = %d\n", Gia_ManAndNum(pNew) ); Gia_ManStop( pTemp ); return pNew; } @@ -266,9 +269,9 @@ Gia_Man_t * Gia_ManCorrSpecReduceInit( Gia_Man_t * p, int nFrames, int nPrefix, Vec_IntFree( vXorLits ); Gia_ManHashStop( pNew ); ABC_FREE( p->pCopies ); -//printf( "Before sweeping = %d\n", Gia_ManAndNum(pNew) ); +//Abc_Print( 1, "Before sweeping = %d\n", Gia_ManAndNum(pNew) ); pNew = Gia_ManCleanup( pTemp = pNew ); -//printf( "After sweeping = %d\n", Gia_ManAndNum(pNew) ); +//Abc_Print( 1, "After sweeping = %d\n", Gia_ManAndNum(pNew) ); Gia_ManStop( pTemp ); return pNew; } @@ -292,13 +295,13 @@ void Cec_ManStartSimInfo( Vec_Ptr_t * vInfo, int nFlops ) assert( nFlops <= Vec_PtrSize(vInfo) ); for ( k = 0; k < nFlops; k++ ) { - pInfo = Vec_PtrEntry( vInfo, k ); + pInfo = (unsigned *)Vec_PtrEntry( vInfo, k ); for ( w = 0; w < nWords; w++ ) pInfo[w] = 0; } for ( k = nFlops; k < Vec_PtrSize(vInfo); k++ ) { - pInfo = Vec_PtrEntry( vInfo, k ); + pInfo = (unsigned *)Vec_PtrEntry( vInfo, k ); for ( w = 0; w < nWords; w++ ) pInfo[w] = Gia_ManRandom( 0 ); } @@ -327,20 +330,20 @@ void Gia_ManCorrRemapSimInfo( Gia_Man_t * p, Vec_Ptr_t * vInfo ) pRepr = Gia_ObjReprObj( p, Gia_ObjId(p,pObj) ); if ( pRepr == NULL || Gia_ObjFailed(p, Gia_ObjId(p,pObj)) ) continue; - pInfoObj = Vec_PtrEntry( vInfo, i ); + pInfoObj = (unsigned *)Vec_PtrEntry( vInfo, i ); for ( w = 0; w < nWords; w++ ) assert( pInfoObj[w] == 0 ); // skip ROs with constant representatives if ( Gia_ObjIsConst0(pRepr) ) continue; assert( Gia_ObjIsRo(p, pRepr) ); -// printf( "%d -> %d ", i, Gia_ObjId(p, pRepr) ); +// Abc_Print( 1, "%d -> %d ", i, Gia_ObjId(p, pRepr) ); // transfer info from the representative - pInfoRepr = Vec_PtrEntry( vInfo, Gia_ObjCioId(pRepr) - Gia_ManPiNum(p) ); + pInfoRepr = (unsigned *)Vec_PtrEntry( vInfo, Gia_ObjCioId(pRepr) - Gia_ManPiNum(p) ); for ( w = 0; w < nWords; w++ ) pInfoObj[w] = pInfoRepr[w]; } -// printf( "\n" ); +// Abc_Print( 1, "\n" ); } /**Function************************************************************* @@ -368,7 +371,7 @@ Vec_Int_t * Gia_ManCorrCreateRemapping( Gia_Man_t * p ) // if ( pRepr == NULL || Gia_ObjIsConst0(pRepr) || Gia_ObjIsFailedPair(p, Gia_ObjId(p, pRepr), Gia_ObjId(p, pObj)) ) continue; assert( Gia_ObjIsRo(p, pRepr) ); -// printf( "%d -> %d ", Gia_ObjId(p,pObj), Gia_ObjId(p, pRepr) ); +// Abc_Print( 1, "%d -> %d ", Gia_ObjId(p,pObj), Gia_ObjId(p, pRepr) ); // remember the pair Vec_IntPush( vPairs, Gia_ObjCioId(pRepr) - Gia_ManPiNum(p) ); Vec_IntPush( vPairs, i ); @@ -395,8 +398,8 @@ void Gia_ManCorrPerformRemapping( Vec_Int_t * vPairs, Vec_Ptr_t * vInfo ) Vec_IntForEachEntry( vPairs, iRepr, i ) { iObj = Vec_IntEntry( vPairs, ++i ); - pInfoObj = Vec_PtrEntry( vInfo, iObj ); - pInfoRepr = Vec_PtrEntry( vInfo, iRepr ); + pInfoObj = (unsigned *)Vec_PtrEntry( vInfo, iObj ); + pInfoRepr = (unsigned *)Vec_PtrEntry( vInfo, iRepr ); for ( w = 0; w < nWords; w++ ) { assert( pInfoObj[w] == 0 ); @@ -422,16 +425,16 @@ int Cec_ManLoadCounterExamplesTry( Vec_Ptr_t * vInfo, Vec_Ptr_t * vPres, int iBi int i; for ( i = 0; i < nLits; i++ ) { - pInfo = Vec_PtrEntry(vInfo, Gia_Lit2Var(pLits[i])); - pPres = Vec_PtrEntry(vPres, Gia_Lit2Var(pLits[i])); + pInfo = (unsigned *)Vec_PtrEntry(vInfo, Gia_Lit2Var(pLits[i])); + pPres = (unsigned *)Vec_PtrEntry(vPres, Gia_Lit2Var(pLits[i])); if ( Gia_InfoHasBit( pPres, iBit ) && Gia_InfoHasBit( pInfo, iBit ) == Gia_LitIsCompl(pLits[i]) ) return 0; } for ( i = 0; i < nLits; i++ ) { - pInfo = Vec_PtrEntry(vInfo, Gia_Lit2Var(pLits[i])); - pPres = Vec_PtrEntry(vPres, Gia_Lit2Var(pLits[i])); + pInfo = (unsigned *)Vec_PtrEntry(vInfo, Gia_Lit2Var(pLits[i])); + pPres = (unsigned *)Vec_PtrEntry(vPres, Gia_Lit2Var(pLits[i])); Gia_InfoSetBit( pPres, iBit ); if ( Gia_InfoHasBit( pInfo, iBit ) == Gia_LitIsCompl(pLits[i]) ) Gia_InfoXorBit( pInfo, iBit ); @@ -506,7 +509,7 @@ int Cec_ManLoadCounterExamples2( Vec_Ptr_t * vInfo, Vec_Int_t * vCexStore, int i // skip the output number // iStart++; Out = Vec_IntEntry( vCexStore, iStart++ ); -// printf( "iBit = %d. Out = %d.\n", iBit, Out ); +// Abc_Print( 1, "iBit = %d. Out = %d.\n", iBit, Out ); // get the number of items nLits = Vec_IntEntry( vCexStore, iStart++ ); if ( nLits <= 0 ) @@ -515,14 +518,14 @@ int Cec_ManLoadCounterExamples2( Vec_Ptr_t * vInfo, Vec_Int_t * vCexStore, int i for ( k = 0; k < nLits; k++ ) { iLit = Vec_IntEntry( vCexStore, iStart++ ); - pInfo = Vec_PtrEntry( vInfo, Gia_Lit2Var(iLit) ); + pInfo = (unsigned *)Vec_PtrEntry( vInfo, Gia_Lit2Var(iLit) ); if ( Gia_InfoHasBit( pInfo, iBit ) == Gia_LitIsCompl(iLit) ) Gia_InfoXorBit( pInfo, iBit ); } if ( ++iBit == nBits ) break; } -// printf( "added %d bits\n", iBit-1 ); +// Abc_Print( 1, "added %d bits\n", iBit-1 ); return iStart; } @@ -620,7 +623,7 @@ int Gia_ManCheckRefinements( Gia_Man_t * p, Vec_Str_t * vStatus, Vec_Int_t * vOu if ( Gia_ObjHasSameRepr(p, iRepr, iObj) ) Counter++; // if ( Gia_ObjHasSameRepr(p, iRepr, iObj) ) -// printf( "Gia_ManCheckRefinements(): Disproved equivalence (%d,%d) is not refined!\n", iRepr, iObj ); +// Abc_Print( 1, "Gia_ManCheckRefinements(): Disproved equivalence (%d,%d) is not refined!\n", iRepr, iObj ); // if ( Gia_ObjHasSameRepr(p, iRepr, iObj) ) // Cec_ManSimClassRemoveOne( pSim, iObj ); continue; @@ -628,7 +631,7 @@ int Gia_ManCheckRefinements( Gia_Man_t * p, Vec_Str_t * vStatus, Vec_Int_t * vOu if ( status == -1 ) { // if ( !Gia_ObjFailed( p, iObj ) ) -// printf( "Gia_ManCheckRefinements(): Failed equivalence is not marked as failed!\n" ); +// Abc_Print( 1, "Gia_ManCheckRefinements(): Failed equivalence is not marked as failed!\n" ); // Gia_ObjSetFailed( p, iRepr ); // Gia_ObjSetFailed( p, iObj ); // if ( fRings ) @@ -638,7 +641,7 @@ int Gia_ManCheckRefinements( Gia_Man_t * p, Vec_Str_t * vStatus, Vec_Int_t * vOu } } // if ( Counter ) -// printf( "Gia_ManCheckRefinements(): Could not refine %d nodes.\n", Counter ); +// Abc_Print( 1, "Gia_ManCheckRefinements(): Could not refine %d nodes.\n", Counter ); return 1; } @@ -732,10 +735,10 @@ void Cec_ManRefinedClassPrintStats( Gia_Man_t * p, Vec_Str_t * vStatus, int iIte CounterX -= Gia_ManCoNum(p); nLits = Gia_ManCiNum(p) + Gia_ManAndNum(p) - Counter - CounterX; if ( iIter == -1 ) - printf( "BMC : " ); + Abc_Print( 1, "BMC : " ); else - printf( "%3d : ", iIter ); - printf( "c =%8d cl =%7d lit =%8d ", Counter0, Counter, nLits ); + Abc_Print( 1, "%3d : ", iIter ); + Abc_Print( 1, "c =%8d cl =%7d lit =%8d ", Counter0, Counter, nLits ); if ( vStatus ) Vec_StrForEachEntry( vStatus, Entry, i ) { @@ -746,8 +749,8 @@ void Cec_ManRefinedClassPrintStats( Gia_Man_t * p, Vec_Str_t * vStatus, int iIte else if ( Entry == -1 ) nFail++; } - printf( "p =%6d d =%6d f =%6d ", nProve, nDispr, nFail ); - ABC_PRT( "T", Time ); + Abc_Print( 1, "p =%6d d =%6d f =%6d ", nProve, nDispr, nFail ); + Abc_PrintTime( 1, "T", Time ); } /**Function************************************************************* @@ -833,7 +836,7 @@ int Cec_ManLSCorrespondenceClasses( Gia_Man_t * pAig, Cec_ParCor_t * pPars ) { int nIterMax = 100000; int nAddFrames = 1; // additional timeframes to simulate - int fRunBmcFirst = 0; + int fRunBmcFirst = 1; Vec_Str_t * vStatus; Vec_Int_t * vOutputs; Vec_Int_t * vCexStore; @@ -846,7 +849,7 @@ int Cec_ManLSCorrespondenceClasses( Gia_Man_t * pAig, Cec_ParCor_t * pPars ) int clk2, clk = clock(); if ( Gia_ManRegNum(pAig) == 0 ) { - printf( "Cec_ManLatchCorrespondence(): Not a sequential AIG.\n" ); + Abc_Print( 1, "Cec_ManLatchCorrespondence(): Not a sequential AIG.\n" ); return 0; } Gia_ManRandom( 1 ); @@ -861,7 +864,7 @@ int Cec_ManLSCorrespondenceClasses( Gia_Man_t * pAig, Cec_ParCor_t * pPars ) pSim = Cec_ManSimStart( pAig, pParsSim ); if ( pAig->pReprs == NULL ) { - Cec_ManSimClassesPrepare( pSim ); + Cec_ManSimClassesPrepare( pSim, pPars->nLevelMax ); Cec_ManSimClassesRefine( pSim ); } // prepare SAT solving @@ -870,7 +873,7 @@ int Cec_ManLSCorrespondenceClasses( Gia_Man_t * pAig, Cec_ParCor_t * pPars ) pParsSat->fVerbose = pPars->fVerbose; if ( pPars->fVerbose ) { - printf( "Obj = %7d. And = %7d. Conf = %5d. Fr = %d. Lcorr = %d. Ring = %d. CSat = %d.\n", + Abc_Print( 1, "Obj = %7d. And = %7d. Conf = %5d. Fr = %d. Lcorr = %d. Ring = %d. CSat = %d.\n", Gia_ManObjNum(pAig), Gia_ManAndNum(pAig), pPars->nBTLimit, pPars->nFrames, pPars->fLatchCorr, pPars->fUseRings, pPars->fUseCSat ); Cec_ManRefinedClassPrintStats( pAig, NULL, 0, clock() - clk ); @@ -878,9 +881,26 @@ int Cec_ManLSCorrespondenceClasses( Gia_Man_t * pAig, Cec_ParCor_t * pPars ) // check the base case if ( fRunBmcFirst && (!pPars->fLatchCorr || pPars->nFrames > 1) ) Cec_ManLSCorrespondenceBmc( pAig, pPars, 0 ); + if ( pPars->pFunc ) + { + ((int (*)(void *))pPars->pFunc)( pPars->pData ); + ((int (*)(void *))pPars->pFunc)( pPars->pData ); + } + if ( pPars->nStepsMax == 0 ) + { + Abc_Print( 1, "Stopped signal correspondence after BMC.\n" ); + Cec_ManSimStop( pSim ); + return 1; + } // perform refinement of equivalence classes for ( r = 0; r < nIterMax; r++ ) { + if ( pPars->nStepsMax == r ) + { + Cec_ManSimStop( pSim ); + Abc_Print( 1, "Stopped signal correspondence after %d refiment iterations.\n", r ); + return 1; + } clk = clock(); // perform speculative reduction clk2 = clock(); @@ -920,12 +940,14 @@ int Cec_ManLSCorrespondenceClasses( Gia_Man_t * pAig, Cec_ParCor_t * pPars ) Vec_StrFree( vStatus ); Vec_IntFree( vOutputs ); //Gia_ManEquivPrintClasses( pAig, 1, 0 ); + if ( pPars->pFunc ) + ((int (*)(void *))pPars->pFunc)( pPars->pData ); } if ( pPars->fVerbose ) Cec_ManRefinedClassPrintStats( pAig, NULL, r+1, clock() - clk ); // check the overflow if ( r == nIterMax ) - printf( "The refinement was not finished. The result may be incorrect.\n" ); + Abc_Print( 1, "The refinement was not finished. The result may be incorrect.\n" ); Cec_ManSimStop( pSim ); // check the base case if ( !fRunBmcFirst && (!pPars->fLatchCorr || pPars->nFrames > 1) ) @@ -938,9 +960,9 @@ int Cec_ManLSCorrespondenceClasses( Gia_Man_t * pAig, Cec_ParCor_t * pPars ) ABC_PRTP( "Sat ", clkSat, clkTotal ); ABC_PRTP( "Sim ", clkSim, clkTotal ); ABC_PRTP( "Other", clkTotal-clkSat-clkSrm-clkSim, clkTotal ); - ABC_PRT( "TOTAL", clkTotal ); + Abc_PrintTime( 1, "TOTAL", clkTotal ); } - return 0; + return 1; } /**Function************************************************************* @@ -960,7 +982,7 @@ unsigned * Cec_ManComputeInitState( Gia_Man_t * pAig, int nFrames ) unsigned * pInitState; int i, f; Gia_ManRandom( 1 ); -// printf( "Simulating %d timeframes.\n", nFrames ); +// Abc_Print( 1, "Simulating %d timeframes.\n", nFrames ); Gia_ManForEachRo( pAig, pObj, i ) pObj->fMark1 = 0; for ( f = 0; f < nFrames; f++ ) @@ -981,9 +1003,9 @@ unsigned * Cec_ManComputeInitState( Gia_Man_t * pAig, int nFrames ) { if ( pObj->fMark1 ) Gia_InfoSetBit( pInitState, i ); -// printf( "%d", pObj->fMark1 ); +// Abc_Print( 1, "%d", pObj->fMark1 ); } -// printf( "\n" ); +// Abc_Print( 1, "\n" ); Gia_ManCleanMark1( pAig ); return pInitState; } @@ -1007,15 +1029,15 @@ void Cec_ManPrintFlopEquivs( Gia_Man_t * p ) Gia_ManForEachRo( p, pObj, i ) { if ( Gia_ObjIsConst(p, Gia_ObjId(p, pObj)) ) - printf( "Original flop %s is proved equivalent to constant.\n", Vec_PtrEntry(p->vNamesIn, Gia_ObjCioId(pObj)) ); + Abc_Print( 1, "Original flop %s is proved equivalent to constant.\n", Vec_PtrEntry(p->vNamesIn, Gia_ObjCioId(pObj)) ); else if ( (pRepr = Gia_ObjReprObj(p, Gia_ObjId(p, pObj))) ) { if ( Gia_ObjIsCi(pRepr) ) - printf( "Original flop %s is proved equivalent to flop %s.\n", + Abc_Print( 1, "Original flop %s is proved equivalent to flop %s.\n", Vec_PtrEntry( p->vNamesIn, Gia_ObjCioId(pObj) ), Vec_PtrEntry( p->vNamesIn, Gia_ObjCioId(pRepr) ) ); else - printf( "Original flop %s is proved equivalent to internal node %d.\n", + Abc_Print( 1, "Original flop %s is proved equivalent to internal node %d.\n", Vec_PtrEntry( p->vNamesIn, Gia_ObjCioId(pObj) ), Gia_ObjId(p, pRepr) ); } } @@ -1046,7 +1068,7 @@ Gia_Man_t * Cec_ManLSCorrespondence( Gia_Man_t * pAig, Cec_ParCor_t * pPars ) { // compute the cycles AIG pInitState = Cec_ManComputeInitState( pAig, pPars->nPrefix ); - pTemp = Gia_ManDupFlip( pAig, pInitState ); + pTemp = Gia_ManDupFlip( pAig, (int *)pInitState ); ABC_FREE( pInitState ); // compute classes of this AIG RetValue = Cec_ManLSCorrespondenceClasses( pTemp, pPars ); @@ -1086,19 +1108,19 @@ Gia_Man_t * Cec_ManLSCorrespondence( Gia_Man_t * pAig, Cec_ParCor_t * pPars ) // report the results if ( pPars->fVerbose ) { - printf( "NBeg = %d. NEnd = %d. (Gain = %6.2f %%). RBeg = %d. REnd = %d. (Gain = %6.2f %%).\n", + Abc_Print( 1, "NBeg = %d. NEnd = %d. (Gain = %6.2f %%). RBeg = %d. REnd = %d. (Gain = %6.2f %%).\n", Gia_ManAndNum(pAig), Gia_ManAndNum(pNew), 100.0*(Gia_ManAndNum(pAig)-Gia_ManAndNum(pNew))/(Gia_ManAndNum(pAig)?Gia_ManAndNum(pAig):1), Gia_ManRegNum(pAig), Gia_ManRegNum(pNew), 100.0*(Gia_ManRegNum(pAig)-Gia_ManRegNum(pNew))/(Gia_ManRegNum(pAig)?Gia_ManRegNum(pAig):1) ); } if ( pPars->nPrefix && (Gia_ManAndNum(pNew) < Gia_ManAndNum(pAig) || Gia_ManRegNum(pNew) < Gia_ManRegNum(pAig)) ) - printf( "The reduced AIG was produced using %d-th invariants and will not verify.\n", pPars->nPrefix ); + Abc_Print( 1, "The reduced AIG was produced using %d-th invariants and will not verify.\n", pPars->nPrefix ); // print verbose info about equivalences if ( pPars->fVerboseFlops ) { if ( pAig->vNamesIn == NULL ) - printf( "Flop output names are not available. Use command \"&get -n\".\n" ); + Abc_Print( 1, "Flop output names are not available. Use command \"&get -n\".\n" ); else Cec_ManPrintFlopEquivs( pAig ); } @@ -1110,3 +1132,5 @@ Gia_Man_t * Cec_ManLSCorrespondence( Gia_Man_t * pAig, Cec_ParCor_t * pPars ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/cec/cecCorr_updated.c b/src/aig/cec/cecCorr_updated.c index dbe81d81..8ce1bd74 100644 --- a/src/aig/cec/cecCorr_updated.c +++ b/src/aig/cec/cecCorr_updated.c @@ -20,6 +20,9 @@ #include "cecInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -970,7 +973,7 @@ int Cec_ManLSCorrespondenceClasses( Gia_Man_t * pAig, Cec_ParCor_t * pPars ) ABC_PRTP( "Other", clkTotal-clkSat-clkSrm-clkSim, clkTotal ); ABC_PRT( "TOTAL", clkTotal ); } - return 0; + return 1; } /**Function************************************************************* @@ -1020,3 +1023,5 @@ Gia_Man_t * Cec_ManLSCorrespondence( Gia_Man_t * pAig, Cec_ParCor_t * pPars ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/cec/cecInt.h b/src/aig/cec/cecInt.h index 73f108ba..6216eae2 100644 --- a/src/aig/cec/cecInt.h +++ b/src/aig/cec/cecInt.h @@ -21,6 +21,7 @@ #ifndef __CEC_INT_H__ #define __CEC_INT_H__ + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -34,9 +35,10 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -128,8 +130,8 @@ struct Cec_ManSim_t_ void ** pCexes; // counter-examples for each output int iOut; // first failed output int nOuts; // the number of failed outputs - Gia_Cex_t * pCexComb; // counter-example for the first failed output - Gia_Cex_t * pBestState; // the state that led to most of the refinements + Abc_Cex_t * pCexComb; // counter-example for the first failed output + Abc_Cex_t * pBestState; // the state that led to most of the refinements // scoring simulation patterns int * pScores; // counters of refinement for each pattern // temporaries @@ -170,7 +172,7 @@ struct Cec_ManFra_t_ extern void Cec_ManRefinedClassPrintStats( Gia_Man_t * p, Vec_Str_t * vStatus, int iIter, int Time ); /*=== cecClass.c ============================================================*/ extern int Cec_ManSimClassRemoveOne( Cec_ManSim_t * p, int i ); -extern int Cec_ManSimClassesPrepare( Cec_ManSim_t * p ); +extern int Cec_ManSimClassesPrepare( Cec_ManSim_t * p, int LevelMax ); extern int Cec_ManSimClassesRefine( Cec_ManSim_t * p ); extern int Cec_ManSimSimulateRound( Cec_ManSim_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t * vInfoCos ); /*=== cecIso.c ============================================================*/ @@ -192,8 +194,8 @@ extern Vec_Ptr_t * Cec_ManPatCollectPatterns( Cec_ManPat_t * pMan, int extern Vec_Ptr_t * Cec_ManPatPackPatterns( Vec_Int_t * vCexStore, int nInputs, int nRegs, int nWordsInit ); /*=== cecSeq.c ============================================================*/ extern int Cec_ManSeqResimulate( Cec_ManSim_t * p, Vec_Ptr_t * vInfo ); -extern int Cec_ManSeqResimulateInfo( Gia_Man_t * pAig, Vec_Ptr_t * vSimInfo, Gia_Cex_t * pBestState, int fCheckMiter ); -extern void Cec_ManSeqDeriveInfoInitRandom( Vec_Ptr_t * vInfo, Gia_Man_t * pAig, Gia_Cex_t * pCex ); +extern int Cec_ManSeqResimulateInfo( Gia_Man_t * pAig, Vec_Ptr_t * vSimInfo, Abc_Cex_t * pBestState, int fCheckMiter ); +extern void Cec_ManSeqDeriveInfoInitRandom( Vec_Ptr_t * vInfo, Gia_Man_t * pAig, Abc_Cex_t * pCex ); extern int Cec_ManCountNonConstOutputs( Gia_Man_t * pAig ); extern int Cec_ManCheckNonTrivialCands( Gia_Man_t * pAig ); /*=== cecSolve.c ============================================================*/ @@ -209,9 +211,11 @@ extern Vec_Int_t * Cec_ManSatReadCex( Cec_ManSat_t * p ); extern Gia_Man_t * Cec_ManFraSpecReduction( Cec_ManFra_t * p ); extern int Cec_ManFraClassesUpdate( Cec_ManFra_t * p, Cec_ManSim_t * pSim, Cec_ManPat_t * pPat, Gia_Man_t * pNew ); -#ifdef __cplusplus -} -#endif + + +ABC_NAMESPACE_HEADER_END + + #endif diff --git a/src/aig/cec/cecIso.c b/src/aig/cec/cecIso.c index d9aa5240..ec237fe5 100644 --- a/src/aig/cec/cecIso.c +++ b/src/aig/cec/cecIso.c @@ -20,6 +20,9 @@ #include "cecInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -348,13 +351,13 @@ int * Cec_ManDetectIsomorphism( Gia_Man_t * p ) { if ( (Gia_ObjIsHead(p,pIso[i]) && Gia_ObjRepr(p,i)==pIso[i]) || (Gia_ObjIsClass(p,pIso[i]) && Gia_ObjRepr(p,i)==Gia_ObjRepr(p,pIso[i])) ) - printf( "1" ); + Abc_Print( 1, "1" ); else - printf( "0" ); + Abc_Print( 1, "0" ); } */ } - printf( "Computed %d pairs of structurally equivalent nodes.\n", Counter ); + Abc_Print( 1, "Computed %d pairs of structurally equivalent nodes.\n", Counter ); // p->pIso = pIso; // Cec_ManTransformClasses( p ); @@ -368,3 +371,5 @@ int * Cec_ManDetectIsomorphism( Gia_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/cec/cecMan.c b/src/aig/cec/cecMan.c index 70396cca..f03ec701 100644 --- a/src/aig/cec/cecMan.c +++ b/src/aig/cec/cecMan.c @@ -20,6 +20,9 @@ #include "cecInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -70,21 +73,21 @@ Cec_ManSat_t * Cec_ManSatCreate( Gia_Man_t * pAig, Cec_ParSat_t * pPars ) ***********************************************************************/ void Cec_ManSatPrintStats( Cec_ManSat_t * p ) { - printf( "CO = %8d ", Gia_ManCoNum(p->pAig) ); - printf( "AND = %8d ", Gia_ManAndNum(p->pAig) ); - printf( "Conf = %5d ", p->pPars->nBTLimit ); - printf( "MinVar = %5d ", p->pPars->nSatVarMax ); - printf( "MinCalls = %5d\n", p->pPars->nCallsRecycle ); - printf( "Unsat calls %6d (%6.2f %%) Ave conf = %8.1f ", + Abc_Print( 1, "CO = %8d ", Gia_ManCoNum(p->pAig) ); + Abc_Print( 1, "AND = %8d ", Gia_ManAndNum(p->pAig) ); + Abc_Print( 1, "Conf = %5d ", p->pPars->nBTLimit ); + Abc_Print( 1, "MinVar = %5d ", p->pPars->nSatVarMax ); + Abc_Print( 1, "MinCalls = %5d\n", p->pPars->nCallsRecycle ); + Abc_Print( 1, "Unsat calls %6d (%6.2f %%) Ave conf = %8.1f ", p->nSatUnsat, p->nSatTotal? 100.0*p->nSatUnsat/p->nSatTotal : 0.0, p->nSatUnsat? 1.0*p->nConfUnsat/p->nSatUnsat :0.0 ); - ABC_PRTP( "Time", p->timeSatUnsat, p->timeTotal ); - printf( "Sat calls %6d (%6.2f %%) Ave conf = %8.1f ", + Abc_PrintTimeP( 1, "Time", p->timeSatUnsat, p->timeTotal ); + Abc_Print( 1, "Sat calls %6d (%6.2f %%) Ave conf = %8.1f ", p->nSatSat, p->nSatTotal? 100.0*p->nSatSat/p->nSatTotal : 0.0, p->nSatSat? 1.0*p->nConfSat/p->nSatSat : 0.0 ); - ABC_PRTP( "Time", p->timeSatSat, p->timeTotal ); - printf( "Undef calls %6d (%6.2f %%) Ave conf = %8.1f ", + Abc_PrintTimeP( 1, "Time", p->timeSatSat, p->timeTotal ); + Abc_Print( 1, "Undef calls %6d (%6.2f %%) Ave conf = %8.1f ", p->nSatUndec, p->nSatTotal? 100.0*p->nSatUndec/p->nSatTotal : 0.0, p->nSatUndec? 1.0*p->nConfUndec/p->nSatUndec : 0.0 ); - ABC_PRTP( "Time", p->timeSatUndec, p->timeTotal ); - ABC_PRT( "Total time", p->timeTotal ); + Abc_PrintTimeP( 1, "Time", p->timeSatUndec, p->timeTotal ); + Abc_PrintTime( 1, "Total time", p->timeTotal ); } /**Function************************************************************* @@ -146,18 +149,18 @@ Cec_ManPat_t * Cec_ManPatStart() ***********************************************************************/ void Cec_ManPatPrintStats( Cec_ManPat_t * p ) { - printf( "Latest: P = %8d. L = %10d. Lm = %10d. Ave = %6.1f. MEM =%6.2f Mb\n", + Abc_Print( 1, "Latest: P = %8d. L = %10d. Lm = %10d. Ave = %6.1f. MEM =%6.2f Mb\n", p->nPats, p->nPatLits, p->nPatLitsMin, 1.0 * p->nPatLitsMin/p->nPats, 1.0*(Vec_StrSize(p->vStorage)-p->iStart)/(1<<20) ); - printf( "Total: P = %8d. L = %10d. Lm = %10d. Ave = %6.1f. MEM =%6.2f Mb\n", + Abc_Print( 1, "Total: P = %8d. L = %10d. Lm = %10d. Ave = %6.1f. MEM =%6.2f Mb\n", p->nPatsAll, p->nPatLitsAll, p->nPatLitsMinAll, 1.0 * p->nPatLitsMinAll/p->nPatsAll, 1.0*Vec_StrSize(p->vStorage)/(1<<20) ); - ABC_PRTP( "Finding ", p->timeFind, p->timeTotal ); - ABC_PRTP( "Shrinking", p->timeShrink, p->timeTotal ); - ABC_PRTP( "Verifying", p->timeVerify, p->timeTotal ); - ABC_PRTP( "Sorting ", p->timeSort, p->timeTotal ); - ABC_PRTP( "Packing ", p->timePack, p->timeTotal ); - ABC_PRT( "TOTAL ", p->timeTotal ); + Abc_PrintTimeP( 1, "Finding ", p->timeFind, p->timeTotal ); + Abc_PrintTimeP( 1, "Shrinking", p->timeShrink, p->timeTotal ); + Abc_PrintTimeP( 1, "Verifying", p->timeVerify, p->timeTotal ); + Abc_PrintTimeP( 1, "Sorting ", p->timeSort, p->timeTotal ); + Abc_PrintTimeP( 1, "Packing ", p->timePack, p->timeTotal ); + Abc_PrintTime( 1, "TOTAL ", p->timeTotal ); } /**Function************************************************************* @@ -290,3 +293,5 @@ void Cec_ManFraStop( Cec_ManFra_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/cec/cecPat.c b/src/aig/cec/cecPat.c index 8537fe4a..82c12ea9 100644 --- a/src/aig/cec/cecPat.c +++ b/src/aig/cec/cecPat.c @@ -20,6 +20,9 @@ #include "cecInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -296,7 +299,7 @@ void Cec_ManPatVerifyPattern( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vPat Value = Cec_ManPatComputePattern3_rec( p, Gia_ObjFanin0(pObj) ); Value = Gia_XsimNotCond( Value, Gia_ObjFaninC0(pObj) ); if ( Value != GIA_ONE ) - printf( "Cec_ManPatVerifyPattern(): Verification failed.\n" ); + Abc_Print( 1, "Cec_ManPatVerifyPattern(): Verification failed.\n" ); assert( Value == GIA_ONE ); } @@ -412,16 +415,16 @@ int Cec_ManPatCollectTry( Vec_Ptr_t * vInfo, Vec_Ptr_t * vPres, int iBit, int * int i; for ( i = 0; i < nLits; i++ ) { - pInfo = Vec_PtrEntry(vInfo, Gia_Lit2Var(pLits[i])); - pPres = Vec_PtrEntry(vPres, Gia_Lit2Var(pLits[i])); + pInfo = (unsigned *)Vec_PtrEntry(vInfo, Gia_Lit2Var(pLits[i])); + pPres = (unsigned *)Vec_PtrEntry(vPres, Gia_Lit2Var(pLits[i])); if ( Gia_InfoHasBit( pPres, iBit ) && Gia_InfoHasBit( pInfo, iBit ) == Gia_LitIsCompl(pLits[i]) ) return 0; } for ( i = 0; i < nLits; i++ ) { - pInfo = Vec_PtrEntry(vInfo, Gia_Lit2Var(pLits[i])); - pPres = Vec_PtrEntry(vPres, Gia_Lit2Var(pLits[i])); + pInfo = (unsigned *)Vec_PtrEntry(vInfo, Gia_Lit2Var(pLits[i])); + pPres = (unsigned *)Vec_PtrEntry(vPres, Gia_Lit2Var(pLits[i])); Gia_InfoSetBit( pPres, iBit ); if ( Gia_InfoHasBit( pInfo, iBit ) == Gia_LitIsCompl(pLits[i]) ) Gia_InfoXorBit( pInfo, iBit ); @@ -478,7 +481,7 @@ Vec_Ptr_t * Cec_ManPatCollectPatterns( Cec_ManPat_t * pMan, int nInputs, int nW pMan->iStart = iStartOld; if ( pMan->fVerbose ) { - printf( "Total = %5d. Max used = %5d. Full = %5d. Series = %d. ", + Abc_Print( 1, "Total = %5d. Max used = %5d. Full = %5d. Series = %d. ", nPatterns, kMax, nWordsInit*32, pMan->nSeries ); ABC_PRT( "Time", clock() - clk ); Cec_ManPatPrintStats( pMan ); @@ -551,7 +554,7 @@ Vec_Ptr_t * Cec_ManPatPackPatterns( Vec_Int_t * vCexStore, int nInputs, int nReg nBits *= 2; } } -// printf( "packed %d patterns into %d vectors (out of %d)\n", nPatterns, kMax, nBits ); +// Abc_Print( 1, "packed %d patterns into %d vectors (out of %d)\n", nPatterns, kMax, nBits ); Vec_PtrFree( vPres ); Vec_IntFree( vPat ); return vInfo; @@ -562,3 +565,5 @@ Vec_Ptr_t * Cec_ManPatPackPatterns( Vec_Int_t * vCexStore, int nInputs, int nReg //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/cec/cecSeq.c b/src/aig/cec/cecSeq.c index 49f2a018..b91e8523 100644 --- a/src/aig/cec/cecSeq.c +++ b/src/aig/cec/cecSeq.c @@ -20,6 +20,9 @@ #include "cecInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -39,7 +42,7 @@ SeeAlso [] ***********************************************************************/ -void Cec_ManSeqDeriveInfoFromCex( Vec_Ptr_t * vInfo, Gia_Man_t * pAig, Gia_Cex_t * pCex ) +void Cec_ManSeqDeriveInfoFromCex( Vec_Ptr_t * vInfo, Gia_Man_t * pAig, Abc_Cex_t * pCex ) { unsigned * pInfo; int k, i, w, nWords; @@ -56,14 +59,14 @@ void Cec_ManSeqDeriveInfoFromCex( Vec_Ptr_t * vInfo, Gia_Man_t * pAig, Gia_Cex_t */ for ( k = 0; k < Gia_ManRegNum(pAig); k++ ) { - pInfo = Vec_PtrEntry( vInfo, k ); + pInfo = (unsigned *)Vec_PtrEntry( vInfo, k ); for ( w = 0; w < nWords; w++ ) pInfo[w] = 0; } for ( i = pCex->nRegs; i < pCex->nBits; i++ ) { - pInfo = Vec_PtrEntry( vInfo, k++ ); + pInfo = (unsigned *)Vec_PtrEntry( vInfo, k++ ); for ( w = 0; w < nWords; w++ ) pInfo[w] = Gia_ManRandom(0); // set simulation pattern and make sure it is second (first will be erased during simulation) @@ -72,7 +75,7 @@ void Cec_ManSeqDeriveInfoFromCex( Vec_Ptr_t * vInfo, Gia_Man_t * pAig, Gia_Cex_t } for ( ; k < Vec_PtrSize(vInfo); k++ ) { - pInfo = Vec_PtrEntry( vInfo, k ); + pInfo = (unsigned *)Vec_PtrEntry( vInfo, k ); for ( w = 0; w < nWords; w++ ) pInfo[w] = Gia_ManRandom(0); } @@ -89,7 +92,7 @@ void Cec_ManSeqDeriveInfoFromCex( Vec_Ptr_t * vInfo, Gia_Man_t * pAig, Gia_Cex_t SeeAlso [] ***********************************************************************/ -void Cec_ManSeqDeriveInfoInitRandom( Vec_Ptr_t * vInfo, Gia_Man_t * pAig, Gia_Cex_t * pCex ) +void Cec_ManSeqDeriveInfoInitRandom( Vec_Ptr_t * vInfo, Gia_Man_t * pAig, Abc_Cex_t * pCex ) { unsigned * pInfo; int k, w, nWords; @@ -98,14 +101,14 @@ void Cec_ManSeqDeriveInfoInitRandom( Vec_Ptr_t * vInfo, Gia_Man_t * pAig, Gia_Ce assert( Gia_ManRegNum(pAig) <= Vec_PtrSize(vInfo) ); for ( k = 0; k < Gia_ManRegNum(pAig); k++ ) { - pInfo = Vec_PtrEntry( vInfo, k ); + pInfo = (unsigned *)Vec_PtrEntry( vInfo, k ); for ( w = 0; w < nWords; w++ ) pInfo[w] = (pCex && Gia_InfoHasBit(pCex->pData, k))? ~0 : 0; } for ( ; k < Vec_PtrSize(vInfo); k++ ) { - pInfo = Vec_PtrEntry( vInfo, k ); + pInfo = (unsigned *)Vec_PtrEntry( vInfo, k ); for ( w = 0; w < nWords; w++ ) pInfo[w] = Gia_ManRandom( 0 ); } @@ -130,8 +133,8 @@ int Cec_ManSeqResimulate( Cec_ManSim_t * p, Vec_Ptr_t * vInfo ) assert( Vec_PtrSize(vInfo) == Gia_ManRegNum(p->pAig) + Gia_ManPiNum(p->pAig) * p->pPars->nFrames ); for ( k = 0; k < Gia_ManRegNum(p->pAig); k++ ) { - pInfo0 = Vec_PtrEntry( vInfo, k ); - pInfo1 = Vec_PtrEntry( p->vCoSimInfo, Gia_ManPoNum(p->pAig) + k ); + pInfo0 = (unsigned *)Vec_PtrEntry( vInfo, k ); + pInfo1 = (unsigned *)Vec_PtrEntry( p->vCoSimInfo, Gia_ManPoNum(p->pAig) + k ); for ( w = 0; w < p->nWords; w++ ) pInfo1[w] = pInfo0[w]; } @@ -139,15 +142,15 @@ int Cec_ManSeqResimulate( Cec_ManSim_t * p, Vec_Ptr_t * vInfo ) { for ( i = 0; i < Gia_ManPiNum(p->pAig); i++ ) { - pInfo0 = Vec_PtrEntry( vInfo, k++ ); - pInfo1 = Vec_PtrEntry( p->vCiSimInfo, i ); + pInfo0 = (unsigned *)Vec_PtrEntry( vInfo, k++ ); + pInfo1 = (unsigned *)Vec_PtrEntry( p->vCiSimInfo, i ); for ( w = 0; w < p->nWords; w++ ) pInfo1[w] = pInfo0[w]; } for ( i = 0; i < Gia_ManRegNum(p->pAig); i++ ) { - pInfo0 = Vec_PtrEntry( p->vCoSimInfo, Gia_ManPoNum(p->pAig) + i ); - pInfo1 = Vec_PtrEntry( p->vCiSimInfo, Gia_ManPiNum(p->pAig) + i ); + pInfo0 = (unsigned *)Vec_PtrEntry( p->vCoSimInfo, Gia_ManPoNum(p->pAig) + i ); + pInfo1 = (unsigned *)Vec_PtrEntry( p->vCiSimInfo, Gia_ManPiNum(p->pAig) + i ); for ( w = 0; w < p->nWords; w++ ) pInfo1[w] = pInfo0[w]; } @@ -169,7 +172,7 @@ int Cec_ManSeqResimulate( Cec_ManSim_t * p, Vec_Ptr_t * vInfo ) SeeAlso [] ***********************************************************************/ -int Cec_ManSeqResimulateInfo( Gia_Man_t * pAig, Vec_Ptr_t * vSimInfo, Gia_Cex_t * pBestState, int fCheckMiter ) +int Cec_ManSeqResimulateInfo( Gia_Man_t * pAig, Vec_Ptr_t * vSimInfo, Abc_Cex_t * pBestState, int fCheckMiter ) { Cec_ParSim_t ParsSim, * pParsSim = &ParsSim; Cec_ManSim_t * pSim; @@ -200,33 +203,33 @@ int Cec_ManSeqResimulateInfo( Gia_Man_t * pAig, Vec_Ptr_t * vSimInfo, Gia_Cex_t SeeAlso [] ***********************************************************************/ -int Cec_ManSeqResimulateCounter( Gia_Man_t * pAig, Cec_ParSim_t * pPars, Gia_Cex_t * pCex ) +int Cec_ManSeqResimulateCounter( Gia_Man_t * pAig, Cec_ParSim_t * pPars, Abc_Cex_t * pCex ) { Vec_Ptr_t * vSimInfo; int RetValue, clkTotal = clock(); if ( pCex == NULL ) { - printf( "Cec_ManSeqResimulateCounter(): Counter-example is not available.\n" ); + Abc_Print( 1, "Cec_ManSeqResimulateCounter(): Counter-example is not available.\n" ); return -1; } if ( pAig->pReprs == NULL ) { - printf( "Cec_ManSeqResimulateCounter(): Equivalence classes are not available.\n" ); + Abc_Print( 1, "Cec_ManSeqResimulateCounter(): Equivalence classes are not available.\n" ); return -1; } if ( Gia_ManRegNum(pAig) == 0 ) { - printf( "Cec_ManSeqResimulateCounter(): Not a sequential AIG.\n" ); + Abc_Print( 1, "Cec_ManSeqResimulateCounter(): Not a sequential AIG.\n" ); return -1; } // if ( Gia_ManRegNum(pAig) != pCex->nRegs || Gia_ManPiNum(pAig) != pCex->nPis ) if ( Gia_ManPiNum(pAig) != pCex->nPis ) { - printf( "Cec_ManSeqResimulateCounter(): The number of PIs in the AIG and the counter-example differ.\n" ); + Abc_Print( 1, "Cec_ManSeqResimulateCounter(): The number of PIs in the AIG and the counter-example differ.\n" ); return -1; } if ( pPars->fVerbose ) - printf( "Resimulating %d timeframes.\n", pPars->nFrames + pCex->iFrame + 1 ); + Abc_Print( 1, "Resimulating %d timeframes.\n", pPars->nFrames + pCex->iFrame + 1 ); Gia_ManRandom( 1 ); vSimInfo = Vec_PtrAllocSimInfo( Gia_ManRegNum(pAig) + Gia_ManPiNum(pAig) * (pPars->nFrames + pCex->iFrame + 1), 1 ); @@ -240,7 +243,7 @@ int Cec_ManSeqResimulateCounter( Gia_Man_t * pAig, Cec_ParSim_t * pPars, Gia_Cex if ( pPars->fVerbose ) ABC_PRT( "Time", clock() - clkTotal ); if ( RetValue ) - printf( "Cec_ManSeqResimulateCounter(): An output of the miter is asserted!\n" ); + Abc_Print( 1, "Cec_ManSeqResimulateCounter(): An output of the miter is asserted!\n" ); return RetValue; } @@ -320,17 +323,17 @@ int Cec_ManSeqSemiformal( Gia_Man_t * pAig, Cec_ParSmf_t * pPars ) Cec_ParSat_t ParsSat, * pParsSat = &ParsSat; Vec_Ptr_t * vSimInfo; Vec_Str_t * vStatus; - Gia_Cex_t * pState; + Abc_Cex_t * pState; Gia_Man_t * pSrm, * pReduce, * pAux; int r, nPats, RetValue = 0; if ( pAig->pReprs == NULL ) { - printf( "Cec_ManSeqSemiformal(): Equivalence classes are not available.\n" ); + Abc_Print( 1, "Cec_ManSeqSemiformal(): Equivalence classes are not available.\n" ); return -1; } if ( Gia_ManRegNum(pAig) == 0 ) { - printf( "Cec_ManSeqSemiformal(): Not a sequential AIG.\n" ); + Abc_Print( 1, "Cec_ManSeqSemiformal(): Not a sequential AIG.\n" ); return -1; } Gia_ManRandom( 1 ); @@ -344,7 +347,7 @@ int Cec_ManSeqSemiformal( Gia_Man_t * pAig, Cec_ParSmf_t * pPars ) pParsSat->fVerbose = pPars->fVerbose; if ( pParsSat->fVerbose ) { - printf( "Starting: " ); + Abc_Print( 1, "Starting: " ); Gia_ManEquivPrintClasses( pAig, 0, 0 ); } // perform the given number of BMC rounds @@ -353,7 +356,7 @@ int Cec_ManSeqSemiformal( Gia_Man_t * pAig, Cec_ParSmf_t * pPars ) { if ( !Cec_ManCheckNonTrivialCands(pAig) ) { - printf( "Cec_ManSeqSemiformal: There are only trivial equiv candidates left (PO drivers). Quitting.\n" ); + Abc_Print( 1, "Cec_ManSeqSemiformal: There are only trivial equiv candidates left (PO drivers). Quitting.\n" ); break; } // Gia_ManPrintCounterExample( pState ); @@ -362,12 +365,12 @@ int Cec_ManSeqSemiformal( Gia_Man_t * pAig, Cec_ParSmf_t * pPars ) pSrm = Gia_ManSpecReduceInitFrames( pAig, pState, pPars->nFrames, &nFramesReal, pPars->fDualOut, pPars->nMinOutputs ); if ( pSrm == NULL ) { - printf( "Quitting refinement because miter could not be unrolled.\n" ); + Abc_Print( 1, "Quitting refinement because miter could not be unrolled.\n" ); break; } assert( Gia_ManRegNum(pSrm) == 0 && Gia_ManPiNum(pSrm) == (Gia_ManPiNum(pAig) * nFramesReal) ); if ( pPars->fVerbose ) - printf( "Unrolled for %d frames.\n", nFramesReal ); + Abc_Print( 1, "Unrolled for %d frames.\n", nFramesReal ); // allocate room for simulation info vSimInfo = Vec_PtrAllocSimInfo( Gia_ManRegNum(pAig) + Gia_ManPiNum(pAig) * (nFramesReal + nAddFrames), pPars->nWords ); @@ -383,27 +386,27 @@ int Cec_ManSeqSemiformal( Gia_Man_t * pAig, Cec_ParSmf_t * pPars ) pState->iPo = -1; if ( pPars->fVerbose ) { - printf( "BMC = %3d ", nPats ); + Abc_Print( 1, "BMC = %3d ", nPats ); Gia_ManEquivPrintClasses( pAig, 0, 0 ); } // write equivalence classes Gia_WriteAiger( pAig, "gore.aig", 0, 0 ); // reduce the model - pReduce = Gia_ManSpecReduce( pAig, 0, 0 ); + pReduce = Gia_ManSpecReduce( pAig, 0, 0, 0 ); if ( pReduce ) { pReduce = Gia_ManSeqStructSweep( pAux = pReduce, 1, 1, 0 ); Gia_ManStop( pAux ); Gia_WriteAiger( pReduce, "gsrm.aig", 0, 0 ); -// printf( "Speculatively reduced model was written into file \"%s\".\n", "gsrm.aig" ); +// Abc_Print( 1, "Speculatively reduced model was written into file \"%s\".\n", "gsrm.aig" ); // Gia_ManPrintStatsShort( pReduce ); Gia_ManStop( pReduce ); } if ( RetValue ) { - printf( "Cec_ManSeqSemiformal(): An output of the miter is asserted. Refinement stopped.\n" ); + Abc_Print( 1, "Cec_ManSeqSemiformal(): An output of the miter is asserted. Refinement stopped.\n" ); break; } // decide when to stop @@ -417,7 +420,7 @@ int Cec_ManSeqSemiformal( Gia_Man_t * pAig, Cec_ParSmf_t * pPars ) { int nNonConsts = Cec_ManCountNonConstOutputs( pAig ); if ( nNonConsts ) - printf( "The number of POs that are not const-0 candidates = %d.\n", nNonConsts ); + Abc_Print( 1, "The number of POs that are not const-0 candidates = %d.\n", nNonConsts ); } return RetValue; } @@ -432,3 +435,5 @@ int Cec_ManSeqSemiformal( Gia_Man_t * pAig, Cec_ParSmf_t * pPars ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/cec/cecSim.c b/src/aig/cec/cecSim.c index 61610a46..92f8fc2e 100644 --- a/src/aig/cec/cecSim.c +++ b/src/aig/cec/cecSim.c @@ -20,6 +20,9 @@ #include "cecInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -46,3 +49,5 @@ //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/cec/cecSolve.c b/src/aig/cec/cecSolve.c index fa10d222..dc1b88eb 100644 --- a/src/aig/cec/cecSolve.c +++ b/src/aig/cec/cecSolve.c @@ -20,6 +20,9 @@ #include "cecInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -188,7 +191,7 @@ void Cec_AddClausesSuper( Cec_ManSat_t * p, Gia_Obj_t * pNode, Vec_Ptr_t * vSupe pLits = ABC_ALLOC( int, nLits ); // suppose AND-gate is A & B = C // add !A => !C or A + !C - Vec_PtrForEachEntry( vSuper, pFanin, i ) + Vec_PtrForEachEntry( Gia_Obj_t *, vSuper, pFanin, i ) { pLits[0] = toLitCond(Cec_ObjSatNum(p,Gia_Regular(pFanin)), Gia_IsComplement(pFanin)); pLits[1] = toLitCond(Cec_ObjSatNum(p,pNode), 1); @@ -201,7 +204,7 @@ void Cec_AddClausesSuper( Cec_ManSat_t * p, Gia_Obj_t * pNode, Vec_Ptr_t * vSupe assert( RetValue ); } // add A & B => C or !A + !B + C - Vec_PtrForEachEntry( vSuper, pFanin, i ) + Vec_PtrForEachEntry( Gia_Obj_t *, vSuper, pFanin, i ) { pLits[i] = toLitCond(Cec_ObjSatNum(p,Gia_Regular(pFanin)), !Gia_IsComplement(pFanin)); if ( p->pPars->fPolarFlip ) @@ -320,7 +323,7 @@ void Cec_CnfNodeAddToSolver( Cec_ManSat_t * p, Gia_Obj_t * pObj ) vFrontier = Vec_PtrAlloc( 100 ); Cec_ObjAddToFrontier( p, pObj, vFrontier ); // explore nodes in the frontier - Vec_PtrForEachEntry( vFrontier, pNode, i ) + Vec_PtrForEachEntry( Gia_Obj_t *, vFrontier, pNode, i ) { // create the supergate assert( Cec_ObjSatNum(p,pNode) ); @@ -331,14 +334,14 @@ void Cec_CnfNodeAddToSolver( Cec_ManSat_t * p, Gia_Obj_t * pObj ) Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin0( Gia_ObjFanin1(pNode) ) ); Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin1( Gia_ObjFanin0(pNode) ) ); Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin1( Gia_ObjFanin1(pNode) ) ); - Vec_PtrForEachEntry( p->vFanins, pFanin, k ) + Vec_PtrForEachEntry( Gia_Obj_t *, p->vFanins, pFanin, k ) Cec_ObjAddToFrontier( p, Gia_Regular(pFanin), vFrontier ); Cec_AddClausesMux( p, pNode ); } else { Cec_CollectSuper( pNode, fUseMuxes, p->vFanins ); - Vec_PtrForEachEntry( p->vFanins, pFanin, k ) + Vec_PtrForEachEntry( Gia_Obj_t *, p->vFanins, pFanin, k ) Cec_ObjAddToFrontier( p, Gia_Regular(pFanin), vFrontier ); Cec_AddClausesSuper( p, pNode, p->vFanins ); } @@ -366,7 +369,7 @@ void Cec_ManSatSolverRecycle( Cec_ManSat_t * p ) { Gia_Obj_t * pObj; int i; - Vec_PtrForEachEntry( p->vUsedNodes, pObj, i ) + Vec_PtrForEachEntry( Gia_Obj_t *, p->vUsedNodes, pObj, i ) Cec_ObjSetSatNum( p, pObj, 0 ); Vec_PtrClear( p->vUsedNodes ); // memset( p->pSatVars, 0, sizeof(int) * Gia_ManObjNumMax(p->pAigTotal) ); @@ -404,9 +407,9 @@ void Cec_SetActivityFactors_rec( Cec_ManSat_t * p, Gia_Obj_t * pObj, int LevelMi float dActConeBumpMax = 20.0; int iVar; // skip visited variables - if ( Gia_ObjIsTravIdCurrentArray(p->pAig, pObj) ) + if ( Gia_ObjIsTravIdCurrent(p->pAig, pObj) ) return; - Gia_ObjSetTravIdCurrentArray(p->pAig, pObj); + Gia_ObjSetTravIdCurrent(p->pAig, pObj); // add the PI to the list if ( Gia_ObjLevel(p->pAig, pObj) <= LevelMin || Gia_ObjIsCi(pObj) ) return; @@ -440,7 +443,7 @@ int Cec_SetActivityFactors( Cec_ManSat_t * p, Gia_Obj_t * pObj ) // reset the active variables veci_resize(&p->pSat->act_vars, 0); // prepare for traversal - Gia_ManIncrementTravIdArray( p->pAig ); + Gia_ManIncrementTravId( p->pAig ); // determine the min and max level to visit assert( dActConeRatio > 0 && dActConeRatio < 1 ); LevelMax = Gia_ObjLevel(p->pAig,pObj); @@ -491,7 +494,7 @@ int Cec_ManSatCheckNode( Cec_ManSat_t * p, Gia_Obj_t * pObj ) clk2 = clock(); Cec_CnfNodeAddToSolver( p, pObjR ); //ABC_PRT( "cnf", clock() - clk2 ); -//printf( "%d \n", p->pSat->size ); +//Abc_Print( 1, "%d \n", p->pSat->size ); clk2 = clock(); // Cec_SetActivityFactors( p, pObjR ); @@ -529,7 +532,7 @@ p->timeSatUnsat += clock() - clk; assert( RetValue ); p->nSatUnsat++; p->nConfUnsat += p->pSat->stats.conflicts - nConflicts; -//printf( "UNSAT after %d conflicts\n", p->pSat->stats.conflicts - nConflicts ); +//Abc_Print( 1, "UNSAT after %d conflicts\n", p->pSat->stats.conflicts - nConflicts ); return 1; } else if ( RetValue == l_True ) @@ -537,7 +540,7 @@ p->timeSatUnsat += clock() - clk; p->timeSatSat += clock() - clk; p->nSatSat++; p->nConfSat += p->pSat->stats.conflicts - nConflicts; -//printf( "SAT after %d conflicts\n", p->pSat->stats.conflicts - nConflicts ); +//Abc_Print( 1, "SAT after %d conflicts\n", p->pSat->stats.conflicts - nConflicts ); return 0; } else // if ( RetValue == l_Undef ) @@ -545,7 +548,7 @@ p->timeSatSat += clock() - clk; p->timeSatUndec += clock() - clk; p->nSatUndec++; p->nConfUndec += p->pSat->stats.conflicts - nConflicts; -//printf( "UNDEC after %d conflicts\n", p->pSat->stats.conflicts - nConflicts ); +//Abc_Print( 1, "UNDEC after %d conflicts\n", p->pSat->stats.conflicts - nConflicts ); return -1; } } @@ -591,7 +594,7 @@ clk2 = clock(); Cec_CnfNodeAddToSolver( p, pObjR1 ); Cec_CnfNodeAddToSolver( p, pObjR2 ); //ABC_PRT( "cnf", clock() - clk2 ); -//printf( "%d \n", p->pSat->size ); +//Abc_Print( 1, "%d \n", p->pSat->size ); clk2 = clock(); // Cec_SetActivityFactors( p, pObjR1 ); @@ -633,7 +636,7 @@ p->timeSatUnsat += clock() - clk; assert( RetValue ); p->nSatUnsat++; p->nConfUnsat += p->pSat->stats.conflicts - nConflicts; -//printf( "UNSAT after %d conflicts\n", p->pSat->stats.conflicts - nConflicts ); +//Abc_Print( 1, "UNSAT after %d conflicts\n", p->pSat->stats.conflicts - nConflicts ); return 1; } else if ( RetValue == l_True ) @@ -641,7 +644,7 @@ p->timeSatUnsat += clock() - clk; p->timeSatSat += clock() - clk; p->nSatSat++; p->nConfSat += p->pSat->stats.conflicts - nConflicts; -//printf( "SAT after %d conflicts\n", p->pSat->stats.conflicts - nConflicts ); +//Abc_Print( 1, "SAT after %d conflicts\n", p->pSat->stats.conflicts - nConflicts ); return 0; } else // if ( RetValue == l_Undef ) @@ -649,7 +652,7 @@ p->timeSatSat += clock() - clk; p->timeSatUndec += clock() - clk; p->nSatUndec++; p->nConfUndec += p->pSat->stats.conflicts - nConflicts; -//printf( "UNDEC after %d conflicts\n", p->pSat->stats.conflicts - nConflicts ); +//Abc_Print( 1, "UNDEC after %d conflicts\n", p->pSat->stats.conflicts - nConflicts ); return -1; } } @@ -683,7 +686,7 @@ void Cec_ManSatSolve( Cec_ManPat_t * pPat, Gia_Man_t * pAig, Cec_ParSat_t * pPar } Gia_ManSetPhase( pAig ); Gia_ManLevelNum( pAig ); - Gia_ManResetTravIdArray( pAig ); + Gia_ManIncrementTravId( pAig ); p = Cec_ManSatCreate( pAig, pPars ); pProgress = Bar_ProgressStart( stdout, Gia_ManPoNum(pAig) ); Gia_ManForEachCo( pAig, pObj, i ) @@ -705,7 +708,7 @@ clk2 = clock(); Gia_Man_t * pTemp = Gia_ManDupDfsCone( pAig, pObj ); Gia_WriteAiger( pTemp, "gia_hard.aig", 0, 0 ); Gia_ManStop( pTemp ); - printf( "Dumping hard cone into file \"%s\".\n", "gia_hard.aig" ); + Abc_Print( 1, "Dumping hard cone into file \"%s\".\n", "gia_hard.aig" ); } */ if ( status != 0 ) @@ -759,12 +762,12 @@ Vec_Int_t * Cec_ManSatReadCex( Cec_ManSat_t * pSat ) ***********************************************************************/ void Cec_ManSatSolveSeq_rec( Cec_ManSat_t * pSat, Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Ptr_t * vInfo, int iPat, int nRegs ) { - if ( Gia_ObjIsTravIdCurrentArray(p, pObj) ) + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) return; - Gia_ObjSetTravIdCurrentArray(p, pObj); + Gia_ObjSetTravIdCurrent(p, pObj); if ( Gia_ObjIsCi(pObj) ) { - unsigned * pInfo = Vec_PtrEntry( vInfo, nRegs + Gia_ObjCioId(pObj) ); + unsigned * pInfo = (unsigned *)Vec_PtrEntry( vInfo, nRegs + Gia_ObjCioId(pObj) ); if ( Cec_ObjSatVarValue( pSat, pObj ) != Gia_InfoHasBit( pInfo, iPat ) ) Gia_InfoXorBit( pInfo, iPat ); pSat->nCexLits++; @@ -799,7 +802,7 @@ Vec_Str_t * Cec_ManSatSolveSeq( Vec_Ptr_t * vPatts, Gia_Man_t * pAig, Cec_ParSat nPatsInit = nPats = 32 * Vec_PtrReadWordsSimInfo(vPatts); Gia_ManSetPhase( pAig ); Gia_ManLevelNum( pAig ); - Gia_ManResetTravIdArray( pAig ); + Gia_ManIncrementTravId( pAig ); p = Cec_ManSatCreate( pAig, pPars ); vStatus = Vec_StrAlloc( Gia_ManPoNum(pAig) ); pProgress = Bar_ProgressStart( stdout, Gia_ManPoNum(pAig) ); @@ -810,18 +813,18 @@ Vec_Str_t * Cec_ManSatSolveSeq( Vec_Ptr_t * vPatts, Gia_Man_t * pAig, Cec_ParSat { if ( Gia_ObjFaninC0(pObj) ) { -// printf( "Constant 1 output of SRM!!!\n" ); +// Abc_Print( 1, "Constant 1 output of SRM!!!\n" ); Vec_StrPush( vStatus, 0 ); } else { -// printf( "Constant 0 output of SRM!!!\n" ); +// Abc_Print( 1, "Constant 0 output of SRM!!!\n" ); Vec_StrPush( vStatus, 1 ); } continue; } status = Cec_ManSatCheckNode( p, Gia_ObjChild0(pObj) ); -//printf( "output %d status = %d\n", i, status ); +//Abc_Print( 1, "output %d status = %d\n", i, status ); Vec_StrPush( vStatus, (char)status ); if ( status != 0 ) continue; @@ -836,7 +839,7 @@ Vec_Str_t * Cec_ManSatSolveSeq( Vec_Ptr_t * vPatts, Gia_Man_t * pAig, Cec_ParSat if ( iPat % nPatsInit == 0 ) iPat++; // save the pattern - Gia_ManIncrementTravIdArray( pAig ); + Gia_ManIncrementTravId( pAig ); // Vec_IntClear( p->vCex ); Cec_ManSatSolveSeq_rec( p, pAig, Gia_ObjFanin0(pObj), vPatts, iPat++, nRegs ); // Gia_SatVerifyPattern( pAig, pObj, p->vCex, p->vVisits ); @@ -853,7 +856,7 @@ Vec_Str_t * Cec_ManSatSolveSeq( Vec_Ptr_t * vPatts, Gia_Man_t * pAig, Cec_ParSat Bar_ProgressStop( pProgress ); if ( pPars->fVerbose ) Cec_ManSatPrintStats( p ); -// printf( "Total number of cex literals = %d. (Ave = %d)\n", p->nCexLits, p->nCexLits/p->nSatSat ); +// Abc_Print( 1, "Total number of cex literals = %d. (Ave = %d)\n", p->nCexLits, p->nCexLits/p->nSatSat ); Cec_ManSatStop( p ); if ( pnPats ) *pnPats = iPat-1; @@ -900,9 +903,9 @@ void Cec_ManSatAddToStore( Vec_Int_t * vCexStore, Vec_Int_t * vCex, int Out ) ***********************************************************************/ void Cec_ManSatSolveMiter_rec( Cec_ManSat_t * pSat, Gia_Man_t * p, Gia_Obj_t * pObj ) { - if ( Gia_ObjIsTravIdCurrentArray(p, pObj) ) + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) return; - Gia_ObjSetTravIdCurrentArray(p, pObj); + Gia_ObjSetTravIdCurrent(p, pObj); if ( Gia_ObjIsCi(pObj) ) { pSat->nCexLits++; @@ -928,7 +931,7 @@ void Cec_ManSatSolveMiter_rec( Cec_ManSat_t * pSat, Gia_Man_t * p, Gia_Obj_t * p void Cec_ManSavePattern( Cec_ManSat_t * p, Gia_Obj_t * pObj1, Gia_Obj_t * pObj2 ) { Vec_IntClear( p->vCex ); - Gia_ManIncrementTravIdArray( p->pAig ); + Gia_ManIncrementTravId( p->pAig ); Cec_ManSatSolveMiter_rec( p, p->pAig, Gia_Regular(pObj1) ); if ( pObj2 ) Cec_ManSatSolveMiter_rec( p, p->pAig, Gia_Regular(pObj2) ); @@ -957,7 +960,7 @@ Vec_Int_t * Cec_ManSatSolveMiter( Gia_Man_t * pAig, Cec_ParSat_t * pPars, Vec_St // prepare AIG Gia_ManSetPhase( pAig ); Gia_ManLevelNum( pAig ); - Gia_ManResetTravIdArray( pAig ); + Gia_ManIncrementTravId( pAig ); // create resulting data-structures vStatus = Vec_StrAlloc( Gia_ManPoNum(pAig) ); vCexStore = Vec_IntAlloc( 10000 ); @@ -972,13 +975,13 @@ Vec_Int_t * Cec_ManSatSolveMiter( Gia_Man_t * pAig, Cec_ParSat_t * pPars, Vec_St { if ( Gia_ObjFaninC0(pObj) ) { -// printf( "Constant 1 output of SRM!!!\n" ); +// Abc_Print( 1, "Constant 1 output of SRM!!!\n" ); Cec_ManSatAddToStore( vCexStore, p->vCex, i ); // trivial counter-example Vec_StrPush( vStatus, 0 ); } else { -// printf( "Constant 0 output of SRM!!!\n" ); +// Abc_Print( 1, "Constant 0 output of SRM!!!\n" ); Vec_StrPush( vStatus, 1 ); } continue; @@ -994,7 +997,7 @@ Vec_Int_t * Cec_ManSatSolveMiter( Gia_Man_t * pAig, Cec_ParSat_t * pPars, Vec_St continue; assert( status == 0 ); // save the pattern -// Gia_ManIncrementTravIdArray( pAig ); +// Gia_ManIncrementTravId( pAig ); // Cec_ManSatSolveMiter_rec( p, pAig, Gia_ObjFanin0(pObj) ); Cec_ManSavePattern( p, Gia_ObjFanin0(pObj), NULL ); // Gia_SatVerifyPattern( pAig, pObj, p->vCex, p->vVisits ); @@ -1015,3 +1018,5 @@ Vec_Int_t * Cec_ManSatSolveMiter( Gia_Man_t * pAig, Cec_ParSat_t * pPars, Vec_St //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/cec/cecSweep.c b/src/aig/cec/cecSweep.c index 1b68efe0..97f5e36a 100644 --- a/src/aig/cec/cecSweep.c +++ b/src/aig/cec/cecSweep.c @@ -20,6 +20,9 @@ #include "cecInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -162,8 +165,8 @@ void Cec_ManFraCreateInfo( Cec_ManSim_t * p, Vec_Ptr_t * vCiInfo, Vec_Ptr_t * vI int i, w; for ( i = 0; i < Gia_ManCiNum(p->pAig); i++ ) { - pRes0 = Vec_PtrEntry( vCiInfo, i ); - pRes1 = Vec_PtrEntry( vInfo, i ); + pRes0 = (unsigned *)Vec_PtrEntry( vCiInfo, i ); + pRes1 = (unsigned *)Vec_PtrEntry( vInfo, i ); pRes1 += p->nWords * nSeries; for ( w = 0; w < p->nWords; w++ ) pRes0[w] = pRes1[w]; @@ -270,7 +273,7 @@ p->timeSim += clock() - clk; // if ( pObjOld->fMark0 == 0 ) { if ( iRepr == Gia_ObjRepr(p->pAig, iNode) ) - printf( "Cec_ManFraClassesUpdate(): Error! Node is not refined!\n" ); + Abc_Print( 1, "Cec_ManFraClassesUpdate(): Error! Node is not refined!\n" ); p->nAllDisproved++; } } @@ -292,3 +295,5 @@ p->timeSim += clock() - clk; //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/cec/cecSynth.c b/src/aig/cec/cecSynth.c new file mode 100644 index 00000000..52b50a43 --- /dev/null +++ b/src/aig/cec/cecSynth.c @@ -0,0 +1,380 @@ +/**CFile**************************************************************** + + FileName [cecSynth.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Combinational equivalence checking.] + + Synopsis [Partitioned sequential synthesis.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: cecSynth.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "cecInt.h" +#include "giaAig.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Populate sequential synthesis parameters.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec_SeqSynthesisSetDefaultParams( Cec_ParSeq_t * p ) +{ + memset( p, 0, sizeof(Cec_ParSeq_t) ); + p->fUseLcorr = 0; // enables latch correspondence + p->fUseScorr = 0; // enables signal correspondence + p->nBTLimit = 1000; // (scorr/lcorr) conflict limit at a node + p->nFrames = 1; // (scorr only) the number of timeframes + p->nLevelMax = -1; // (scorr only) the max number of levels + p->fConsts = 1; // (scl only) merging constants + p->fEquivs = 1; // (scl only) merging equivalences + p->fUseMiniSat = 0; // enables MiniSat in lcorr/scorr + p->nMinDomSize = 100; // the size of minimum clock domain + p->fVeryVerbose = 0; // verbose stats + p->fVerbose = 0; // verbose stats +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_SeqReadMinDomSize( Cec_ParSeq_t * p ) +{ + return p->nMinDomSize; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_SeqReadVerbose( Cec_ParSeq_t * p ) +{ + return p->fVerbose; +} + +/**Function************************************************************* + + Synopsis [Computes partitioning of registers.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManRegCreatePart( Gia_Man_t * p, Vec_Int_t * vPart, int * pnCountPis, int * pnCountRegs, int ** ppMapBack ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + Vec_Int_t * vNodes, * vRoots; + int i, iOut, nCountPis, nCountRegs; + int * pMapBack; + // collect/mark nodes/PIs in the DFS order from the roots + Gia_ManIncrementTravId( p ); + vRoots = Vec_IntAlloc( Vec_IntSize(vPart) ); + Vec_IntForEachEntry( vPart, iOut, i ) + Vec_IntPush( vRoots, Gia_ObjId(p, Gia_ManCo(p, Gia_ManPoNum(p)+iOut)) ); + vNodes = Gia_ManCollectNodesCis( p, Vec_IntArray(vRoots), Vec_IntSize(vRoots) ); + Vec_IntFree( vRoots ); + // unmark register outputs + Vec_IntForEachEntry( vPart, iOut, i ) + Gia_ObjSetTravIdPrevious( p, Gia_ManCi(p, Gia_ManPiNum(p)+iOut) ); + // count pure PIs + nCountPis = nCountRegs = 0; + Gia_ManForEachPi( p, pObj, i ) + nCountPis += Gia_ObjIsTravIdCurrent(p, pObj); + // count outputs of other registers + Gia_ManForEachRo( p, pObj, i ) + nCountRegs += Gia_ObjIsTravIdCurrent(p, pObj); // should be !Gia_... ??? + if ( pnCountPis ) + *pnCountPis = nCountPis; + if ( pnCountRegs ) + *pnCountRegs = nCountRegs; + // clean old manager + Gia_ManFillValue(p); + Gia_ManConst0(p)->Value = 0; + // create the new manager + pNew = Gia_ManStart( Vec_IntSize(vNodes) ); + // create the PIs + Gia_ManForEachCi( p, pObj, i ) + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + pObj->Value = Gia_ManAppendCi(pNew); + // add variables for the register outputs + // create fake POs to hold the register outputs + Vec_IntForEachEntry( vPart, iOut, i ) + { + pObj = Gia_ManCi(p, Gia_ManPiNum(p)+iOut); + pObj->Value = Gia_ManAppendCi(pNew); + Gia_ManAppendCo( pNew, pObj->Value ); + Gia_ObjSetTravIdCurrent( p, pObj ); // added + } + // create the nodes + Gia_ManForEachObjVec( vNodes, p, pObj, i ) + if ( Gia_ObjIsAnd(pObj) ) + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + // add real POs for the registers + Vec_IntForEachEntry( vPart, iOut, i ) + { + pObj = Gia_ManCo( p, Gia_ManPoNum(p)+iOut ); + Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + } + Gia_ManSetRegNum( pNew, Vec_IntSize(vPart) ); + // create map + if ( ppMapBack ) + { + pMapBack = ABC_FALLOC( int, Gia_ManObjNum(pNew) ); + // map constant nodes + pMapBack[0] = 0; + // logic cones of register outputs + Gia_ManForEachObjVec( vNodes, p, pObj, i ) + { +// pObjNew = Aig_Regular(pObj->pData); +// pMapBack[pObjNew->Id] = pObj->Id; + assert( Gia_Lit2Var(Gia_ObjValue(pObj)) >= 0 ); + assert( Gia_Lit2Var(Gia_ObjValue(pObj)) < Gia_ManObjNum(pNew) ); + pMapBack[ Gia_Lit2Var(Gia_ObjValue(pObj)) ] = Gia_ObjId(p, pObj); + } + // map register outputs + Vec_IntForEachEntry( vPart, iOut, i ) + { + pObj = Gia_ManCi(p, Gia_ManPiNum(p)+iOut); +// pObjNew = pObj->pData; +// pMapBack[pObjNew->Id] = pObj->Id; + assert( Gia_Lit2Var(Gia_ObjValue(pObj)) >= 0 ); + assert( Gia_Lit2Var(Gia_ObjValue(pObj)) < Gia_ManObjNum(pNew) ); + pMapBack[ Gia_Lit2Var(Gia_ObjValue(pObj)) ] = Gia_ObjId(p, pObj); + } + *ppMapBack = pMapBack; + } + Vec_IntFree( vNodes ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Transfers the classes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_TransferMappedClasses( Gia_Man_t * pPart, int * pMapBack, int * pReprs ) +{ + Gia_Obj_t * pObj; + int i, Id1, Id2, nClasses; + if ( pPart->pReprs == NULL ) + return 0; + nClasses = 0; + Gia_ManForEachObj( pPart, pObj, i ) + { + if ( Gia_ObjRepr(pPart, i) == GIA_VOID ) + continue; + assert( i < Gia_ManObjNum(pPart) ); + assert( Gia_ObjRepr(pPart, i) < Gia_ManObjNum(pPart) ); + Id1 = pMapBack[ i ]; + Id2 = pMapBack[ Gia_ObjRepr(pPart, i) ]; + if ( Id1 == Id2 ) + continue; + if ( Id1 < Id2 ) + pReprs[Id2] = Id1; + else + pReprs[Id1] = Id2; + nClasses++; + } + return nClasses; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManFindRepr_rec( int * pReprs, int Id ) +{ + if ( pReprs[Id] == 0 ) + return 0; + if ( pReprs[Id] == ~0 ) + return Id; + return Gia_ManFindRepr_rec( pReprs, pReprs[Id] ); +} + +/**Function************************************************************* + + Synopsis [Normalizes equivalences.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManNormalizeEquivalences( Gia_Man_t * p, int * pReprs ) +{ + int i, iRepr; + assert( p->pReprs == NULL ); + assert( p->pNexts == NULL ); + p->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(p) ); + for ( i = 0; i < Gia_ManObjNum(p); i++ ) + Gia_ObjSetRepr( p, i, GIA_VOID ); + for ( i = 0; i < Gia_ManObjNum(p); i++ ) + { + if ( pReprs[i] == ~0 ) + continue; + iRepr = Gia_ManFindRepr_rec( pReprs, i ); + Gia_ObjSetRepr( p, i, iRepr ); + } + p->pNexts = Gia_ManDeriveNexts( p ); +} + +/**Function************************************************************* + + Synopsis [Partitioned sequential synthesis.] + + Description [Returns AIG annotated with equivalence classes.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_SequentialSynthesisPart( Gia_Man_t * p, Cec_ParSeq_t * pPars ) +{ + int fPrintParts = 0; + char Buffer[100]; + Gia_Man_t * pTemp; + Vec_Ptr_t * vParts = (Vec_Ptr_t *)p->vClockDoms; + Vec_Int_t * vPart; + int * pMapBack, * pReprs; + int i, nCountPis, nCountRegs; + int nClasses, clk = clock(); + + // save parameters + if ( fPrintParts ) + { + // print partitions + Abc_Print( 1, "The following clock domains are used:\n" ); + Vec_PtrForEachEntry( Vec_Int_t *, vParts, vPart, i ) + { + pTemp = Gia_ManRegCreatePart( p, vPart, &nCountPis, &nCountRegs, NULL ); + sprintf( Buffer, "part%03d.aig", i ); + Gia_WriteAiger( pTemp, Buffer, 0, 0 ); + Abc_Print( 1, "part%03d.aig : Reg = %4d. PI = %4d. (True = %4d. Regs = %4d.) And = %5d.\n", + i, Vec_IntSize(vPart), Gia_ManCiNum(pTemp)-Vec_IntSize(vPart), nCountPis, nCountRegs, Gia_ManAndNum(pTemp) ); + Gia_ManStop( pTemp ); + } + } + + // perform sequential synthesis for clock domains + pReprs = ABC_FALLOC( int, Gia_ManObjNum(p) ); + Vec_PtrForEachEntry( Vec_Int_t *, vParts, vPart, i ) + { + pTemp = Gia_ManRegCreatePart( p, vPart, &nCountPis, &nCountRegs, &pMapBack ); + if ( nCountPis > 0 ) + { + if ( pPars->fUseScorr ) + { + Cec_ParCor_t CorPars, * pCorPars = &CorPars; + Cec_ManCorSetDefaultParams( pCorPars ); + pCorPars->nBTLimit = pPars->nBTLimit; + pCorPars->nLevelMax = pPars->nLevelMax; + pCorPars->fVerbose = pPars->fVeryVerbose; + pCorPars->fUseCSat = 1; + Cec_ManLSCorrespondenceClasses( pTemp, pCorPars ); + } + else if ( pPars->fUseLcorr ) + { + Cec_ParCor_t CorPars, * pCorPars = &CorPars; + Cec_ManCorSetDefaultParams( pCorPars ); + pCorPars->fLatchCorr = 1; + pCorPars->nBTLimit = pPars->nBTLimit; + pCorPars->fVerbose = pPars->fVeryVerbose; + pCorPars->fUseCSat = 1; + Cec_ManLSCorrespondenceClasses( pTemp, pCorPars ); + } + else + { +// pNew = Gia_ManSeqStructSweep( pTemp, pPars->fConsts, pPars->fEquivs, pPars->fVerbose ); +// Gia_ManStop( pNew ); + Gia_ManSeqCleanupClasses( pTemp, pPars->fConsts, pPars->fEquivs, pPars->fVerbose ); + } +//Abc_Print( 1, "Part equivalences = %d.\n", Gia_ManEquivCountLitsAll(pTemp) ); + nClasses = Gia_TransferMappedClasses( pTemp, pMapBack, pReprs ); + if ( pPars->fVerbose ) + { + Abc_Print( 1, "%3d : Reg = %4d. PI = %4d. (True = %4d. Regs = %4d.) And = %5d. Cl = %5d.\n", + i, Vec_IntSize(vPart), Gia_ManCiNum(pTemp)-Vec_IntSize(vPart), nCountPis, nCountRegs, Gia_ManAndNum(pTemp), nClasses ); + } + } + Gia_ManStop( pTemp ); + ABC_FREE( pMapBack ); + } + + // generate resulting equivalences + Gia_ManNormalizeEquivalences( p, pReprs ); +//Abc_Print( 1, "Total equivalences = %d.\n", Gia_ManEquivCountLitsAll(p) ); + ABC_FREE( pReprs ); + if ( pPars->fVerbose ) + { + Abc_PrintTime( 1, "Total time", clock() - clk ); + } + return 1; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/cec/module.make b/src/aig/cec/module.make index 35a18cae..42e0cd1b 100644 --- a/src/aig/cec/module.make +++ b/src/aig/cec/module.make @@ -9,4 +9,5 @@ SRC += src/aig/cec/cecCec.c \ src/aig/cec/cecSeq.c \ src/aig/cec/cecSim.c \ src/aig/cec/cecSolve.c \ + src/aig/cec/cecSynth.c \ src/aig/cec/cecSweep.c diff --git a/src/aig/cgt/cgt.h b/src/aig/cgt/cgt.h index 8d18ea80..aa8f9338 100644 --- a/src/aig/cgt/cgt.h +++ b/src/aig/cgt/cgt.h @@ -21,6 +21,7 @@ #ifndef __CGT_H__ #define __CGT_H__ + /* The algorithm implemented in this package is based on the paper: A. Hurst. "Automatic synthesis of clock gating logic with controlled @@ -35,9 +36,10 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -70,9 +72,11 @@ extern void Cgt_SetDefaultParams( Cgt_Par_t * p ); extern Vec_Vec_t * Cgt_ClockGatingCandidates( Aig_Man_t * pAig, Aig_Man_t * pCare, Cgt_Par_t * pPars ); extern Aig_Man_t * Cgt_ClockGating( Aig_Man_t * pAig, Aig_Man_t * pCare, Cgt_Par_t * pPars ); -#ifdef __cplusplus -} -#endif + + +ABC_NAMESPACE_HEADER_END + + #endif diff --git a/src/aig/cgt/cgtAig.c b/src/aig/cgt/cgtAig.c index d411c25a..463c3060 100644 --- a/src/aig/cgt/cgtAig.c +++ b/src/aig/cgt/cgtAig.c @@ -20,6 +20,9 @@ #include "cgtInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -119,7 +122,7 @@ void Cgt_ManDetectFanout( Aig_Man_t * pAig, Aig_Obj_t * pObj, int nOdcMax, Vec_P Cgt_ManDetectFanout_rec( pAig, pObj, nOdcMax, vFanout ); // remove those nodes whose fanout is included k = 0; - Vec_PtrForEachEntry( vFanout, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vFanout, pObj, i ) { // go through the fanouts of this node Aig_ObjForEachFanout( pAig, pObj, pFanout, iFanout, f ) @@ -130,7 +133,7 @@ void Cgt_ManDetectFanout( Aig_Man_t * pAig, Aig_Obj_t * pObj, int nOdcMax, Vec_P Vec_PtrWriteEntry( vFanout, k++, pObj ); } Vec_PtrShrink( vFanout, k ); - Vec_PtrSort( vFanout, Aig_ObjCompareIdIncrease ); + Vec_PtrSort( vFanout, (int (*)(void))Aig_ObjCompareIdIncrease ); assert( Vec_PtrSize(vFanout) > 0 ); } @@ -175,7 +178,7 @@ void Cgt_ManCollectVisited( Aig_Man_t * pAig, Vec_Ptr_t * vFanout, Vec_Ptr_t * v int i; Vec_PtrClear( vVisited ); Aig_ManIncrementTravId( pAig ); - Vec_PtrForEachEntry( vFanout, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vFanout, pObj, i ) Cgt_ManCollectVisited_rec( pAig, pObj, vVisited ); } @@ -215,7 +218,7 @@ Aig_Obj_t * Cgt_ManConstructCareCondition( Cgt_Man_t * p, Aig_Man_t * pNew, Aig_ Cgt_ManDetectFanout( p->pAig, pObjLo, p->pPars->nOdcMax, p->vFanout ); Cgt_ManCollectVisited( p->pAig, p->vFanout, p->vVisited ); // add new variables if the observability condition depends on PI variables - Vec_PtrForEachEntry( p->vVisited, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vVisited, pObj, i ) { assert( Aig_ObjIsNode(pObj) ); if ( Saig_ObjIsPi(p->pAig, Aig_ObjFanin0(pObj)) && Vec_PtrEntry(vCopy0, Aig_ObjFaninId0(pObj)) == NULL ) @@ -232,7 +235,7 @@ Aig_Obj_t * Cgt_ManConstructCareCondition( Cgt_Man_t * p, Aig_Man_t * pNew, Aig_ } } // construct AIGs for the nodes - Vec_PtrForEachEntry( p->vVisited, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vVisited, pObj, i ) { pTemp = Aig_And( pNew, Aig_ObjChild0CopyVec(vCopy0, pObj), Aig_ObjChild1CopyVec(vCopy0, pObj) ); Vec_PtrWriteEntry( vCopy0, Aig_ObjId(pObj), pTemp ); @@ -241,9 +244,9 @@ Aig_Obj_t * Cgt_ManConstructCareCondition( Cgt_Man_t * p, Aig_Man_t * pNew, Aig_ } // construct the care miter pMiter = Aig_ManConst0( pNew ); - Vec_PtrForEachEntry( p->vFanout, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vFanout, pObj, i ) { - pTemp = Aig_Exor( pNew, Vec_PtrEntry(vCopy0, Aig_ObjId(pObj)), Vec_PtrEntry(vCopy1, Aig_ObjId(pObj)) ); + pTemp = Aig_Exor( pNew, (Aig_Obj_t *)Vec_PtrEntry(vCopy0, Aig_ObjId(pObj)), (Aig_Obj_t *)Vec_PtrEntry(vCopy1, Aig_ObjId(pObj)) ); pMiter = Aig_Or( pNew, pMiter, pTemp ); } return pMiter; @@ -300,7 +303,7 @@ Aig_Man_t * Cgt_ManDeriveAigForGating( Cgt_Man_t * p ) Vec_PtrWriteEntry( vCopy0, Aig_ObjId(pObjLo), Aig_ObjChild0Copy(pObjLi) ); Vec_PtrWriteEntry( vCopy1, Aig_ObjId(pObjLo), Aig_ObjChild0Copy(pObjLi) ); // compute the miter - pMiter = Aig_Exor( pNew, pObjLo->pData, Aig_ObjChild0Copy(pObjLi) ); + pMiter = Aig_Exor( pNew, (Aig_Obj_t *)pObjLo->pData, Aig_ObjChild0Copy(pObjLi) ); pMiter = Aig_And( pNew, pMiter, pCare ); pObjLi->pData = Aig_ObjCreatePo( pNew, pMiter ); } @@ -312,7 +315,7 @@ Aig_Man_t * Cgt_ManDeriveAigForGating( Cgt_Man_t * p ) // construct clock-gating miters for each register input Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i ) { - pMiter = Aig_Exor( pNew, pObjLo->pData, Aig_ObjChild0Copy(pObjLi) ); + pMiter = Aig_Exor( pNew, (Aig_Obj_t *)pObjLo->pData, Aig_ObjChild0Copy(pObjLi) ); pObjLi->pData = Aig_ObjCreatePo( pNew, pMiter ); } } @@ -336,19 +339,19 @@ Aig_Obj_t * Cgt_ManConstructCare_rec( Aig_Man_t * pCare, Aig_Obj_t * pObj, Aig_M { Aig_Obj_t * pObj0, * pObj1; if ( Aig_ObjIsTravIdCurrent( pCare, pObj ) ) - return pObj->pData; + return (Aig_Obj_t *)pObj->pData; Aig_ObjSetTravIdCurrent( pCare, pObj ); if ( Aig_ObjIsPi(pObj) ) - return pObj->pData = NULL; + return (Aig_Obj_t *)(pObj->pData = NULL); pObj0 = Cgt_ManConstructCare_rec( pCare, Aig_ObjFanin0(pObj), pNew ); if ( pObj0 == NULL ) - return pObj->pData = NULL; + return (Aig_Obj_t *)(pObj->pData = NULL); pObj1 = Cgt_ManConstructCare_rec( pCare, Aig_ObjFanin1(pObj), pNew ); if ( pObj1 == NULL ) - return pObj->pData = NULL; + return (Aig_Obj_t *)(pObj->pData = NULL); pObj0 = Aig_NotCond( pObj0, Aig_ObjFaninC0(pObj) ); pObj1 = Aig_NotCond( pObj1, Aig_ObjFaninC1(pObj) ); - return pObj->pData = Aig_And( pNew, pObj0, pObj1 ); + return (Aig_Obj_t *)(pObj->pData = Aig_And( pNew, pObj0, pObj1 )); } /**Function************************************************************* @@ -370,16 +373,16 @@ void Cgt_ManConstructCare( Aig_Man_t * pNew, Aig_Man_t * pCare, Vec_Vec_t * vSup // go through the PIs of the partition // label the corresponding PIs of the care set Aig_ManIncrementTravId( pCare ); - Vec_PtrForEachEntry( vLeaves, pLeaf, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vLeaves, pLeaf, i ) { pPi = Aig_ManPi( pCare, Aig_ObjPioNum(pLeaf) ); Aig_ObjSetTravIdCurrent( pCare, pPi ); pPi->pData = pLeaf->pData; } // construct the constraints - Vec_PtrForEachEntry( vLeaves, pLeaf, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vLeaves, pLeaf, i ) { - vOuts = Vec_VecEntry( vSuppsInv, Aig_ObjPioNum(pLeaf) ); + vOuts = (Vec_Int_t *)Vec_VecEntry( vSuppsInv, Aig_ObjPioNum(pLeaf) ); Vec_IntForEachEntry( vOuts, iOut, k ) { pPo = Aig_ManPo( pCare, iOut ); @@ -411,17 +414,17 @@ void Cgt_ManConstructCare( Aig_Man_t * pNew, Aig_Man_t * pCare, Vec_Vec_t * vSup Aig_Obj_t * Cgt_ManDupPartition_rec( Aig_Man_t * pNew, Aig_Man_t * pAig, Aig_Obj_t * pObj, Vec_Ptr_t * vLeaves ) { if ( Aig_ObjIsTravIdCurrent(pAig, pObj) ) - return pObj->pData; + return (Aig_Obj_t *)pObj->pData; Aig_ObjSetTravIdCurrent(pAig, pObj); if ( Aig_ObjIsPi(pObj) ) { pObj->pData = Aig_ObjCreatePi( pNew ); Vec_PtrPush( vLeaves, pObj ); - return pObj->pData; + return (Aig_Obj_t *)pObj->pData; } Cgt_ManDupPartition_rec( pNew, pAig, Aig_ObjFanin0(pObj), vLeaves ); Cgt_ManDupPartition_rec( pNew, pAig, Aig_ObjFanin1(pObj), vLeaves ); - return pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + return (Aig_Obj_t *)(pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) )); } /**Function************************************************************* @@ -469,8 +472,8 @@ Aig_Man_t * Cgt_ManDupPartition( Aig_Man_t * pFrame, int nVarsMin, int nFlopsMin if ( pCare ) Cgt_ManConstructCare( pNew, pCare, vSuppsInv, vLeaves ); // create POs - Vec_PtrForEachEntry( vPos, pObj, i ) - pObj->pData = Aig_ObjCreatePo( pNew, Vec_PtrEntry(vRoots, i) ); + Vec_PtrForEachEntry( Aig_Obj_t *, vPos, pObj, i ) + pObj->pData = (Aig_Obj_t *)Aig_ObjCreatePo( pNew, (Aig_Obj_t *)Vec_PtrEntry(vRoots, i) ); if ( pnOutputs != NULL ) *pnOutputs = Vec_PtrSize( vPos ); Vec_PtrFree( vRoots ); @@ -496,12 +499,12 @@ Aig_Obj_t * Cgt_ManBuildClockGate( Aig_Man_t * pNew, Vec_Ptr_t * vGates ) int i; assert( Vec_PtrSize(vGates) > 0 ); pTotal = Aig_ManConst0(pNew); - Vec_PtrForEachEntry( vGates, pGate, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vGates, pGate, i ) { if ( Aig_Regular(pGate)->pNext ) pGate = Aig_NotCond( Aig_Regular(pGate)->pNext, Aig_IsComplement(pGate) ); else - pGate = Aig_NotCond( Aig_Regular(pGate)->pData, Aig_IsComplement(pGate) ); + pGate = Aig_NotCond( (Aig_Obj_t *)Aig_Regular(pGate)->pData, Aig_IsComplement(pGate) ); pTotal = Aig_Or( pNew, pTotal, pGate ); } return pTotal; @@ -526,7 +529,7 @@ Aig_Man_t * Cgt_ManDeriveGatedAig( Aig_Man_t * pAig, Vec_Vec_t * vGates, int fRe int i, k; Aig_ManCleanNext( pAig ); // label nodes - Vec_VecForEachEntry( vGates, pObj, i, k ) + Vec_VecForEachEntry( Aig_Obj_t *, vGates, pObj, i, k ) { if ( Aig_IsComplement(pObj) ) Aig_Regular(pObj)->fMarkB = 1; @@ -549,12 +552,12 @@ Aig_Man_t * Cgt_ManDeriveGatedAig( Aig_Man_t * pAig, Vec_Vec_t * vGates, int fRe pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); if ( pObj->fMarkA ) { - pObj->pNext = pObj->pData; + pObj->pNext = (Aig_Obj_t *)pObj->pData; pObj->pData = Aig_ManConst0(pNew); } else if ( pObj->fMarkB ) { - pObj->pNext = pObj->pData; + pObj->pNext = (Aig_Obj_t *)pObj->pData; pObj->pData = Aig_ManConst1(pNew); } } @@ -570,14 +573,14 @@ Aig_Man_t * Cgt_ManDeriveGatedAig( Aig_Man_t * pAig, Vec_Vec_t * vGates, int fRe pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) ); Saig_ManForEachLiLo( pAig, pObjLi, pObjLo, i ) { - vOne = Vec_VecEntry( vGates, i ); + vOne = (Vec_Ptr_t *)Vec_VecEntry( vGates, i ); if ( Vec_PtrSize(vOne) == 0 ) pObjNew = Aig_ObjChild0Copy(pObjLi); else { // pGateNew = Aig_NotCond( Aig_Regular(pGate)->pData, Aig_IsComplement(pGate) ); pGateNew = Cgt_ManBuildClockGate( pNew, vOne ); - pObjNew = Aig_Mux( pNew, pGateNew, pObjLo->pData, Aig_ObjChild0Copy(pObjLi) ); + pObjNew = Aig_Mux( pNew, pGateNew, (Aig_Obj_t *)pObjLo->pData, Aig_ObjChild0Copy(pObjLi) ); } pObjLi->pData = Aig_ObjCreatePo( pNew, pObjNew ); } @@ -594,3 +597,5 @@ Aig_Man_t * Cgt_ManDeriveGatedAig( Aig_Man_t * pAig, Vec_Vec_t * vGates, int fRe //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/cgt/cgtCore.c b/src/aig/cgt/cgtCore.c index b213297e..d4229ce6 100644 --- a/src/aig/cgt/cgtCore.c +++ b/src/aig/cgt/cgtCore.c @@ -21,6 +21,9 @@ #include "cgtInt.h" #include "bar.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -68,8 +71,8 @@ int Cgt_SimulationFilter( Cgt_Man_t * p, Aig_Obj_t * pCandPart, Aig_Obj_t * pMit { unsigned * pInfoCand, * pInfoMiter; int w, nWords = Aig_BitWordNum( p->nPatts ); - pInfoCand = Vec_PtrEntry( p->vPatts, Aig_ObjId(Aig_Regular(pCandPart)) ); - pInfoMiter = Vec_PtrEntry( p->vPatts, Aig_ObjId(pMiterPart) ); + pInfoCand = (unsigned *)Vec_PtrEntry( p->vPatts, Aig_ObjId(Aig_Regular(pCandPart)) ); + pInfoMiter = (unsigned *)Vec_PtrEntry( p->vPatts, Aig_ObjId(pMiterPart) ); // C => !M -- true is the same as C & M -- false if ( !Aig_IsComplement(pCandPart) ) { @@ -103,7 +106,7 @@ void Cgt_SimulationRecord( Cgt_Man_t * p ) int i; Aig_ManForEachObj( p->pPart, pObj, i ) if ( sat_solver_var_value( p->pSat, p->pCnf->pVarNums[i] ) ) - Aig_InfoSetBit( Vec_PtrEntry(p->vPatts, i), p->nPatts ); + Aig_InfoSetBit( (unsigned *)Vec_PtrEntry(p->vPatts, i), p->nPatts ); p->nPatts++; if ( p->nPatts == 32 * p->nPattWords ) { @@ -137,14 +140,14 @@ void Cgt_ClockGatingRangeCheck( Cgt_Man_t * p, int iStart, int nOutputs ) pMiter = Saig_ManLi( p->pAig, i ); Cgt_ManDetectCandidates( p->pAig, Aig_ObjFanin0(pMiter), p->pPars->nLevelMax, vNodes ); // go through the candidates of this PO - Vec_PtrForEachEntry( vNodes, pCand, k ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pCand, k ) { // get the corresponding nodes from the frames - pCandFrame = pCand->pData; - pMiterFrame = pMiter->pData; + pCandFrame = (Aig_Obj_t *)pCand->pData; + pMiterFrame = (Aig_Obj_t *)pMiter->pData; // get the corresponding nodes from the part - pCandPart = pCandFrame->pData; - pMiterPart = pMiterFrame->pData; + pCandPart = (Aig_Obj_t *)pCandFrame->pData; + pMiterPart = (Aig_Obj_t *)pMiterFrame->pData; // try direct polarity if ( Cgt_SimulationFilter( p, pCandPart, pMiterPart ) ) { @@ -205,7 +208,7 @@ int Cgt_ClockGatingRange( Cgt_Man_t * p, int iStart ) clk = clock(); p->pPart = Cgt_ManDupPartition( p->pFrame, p->pPars->nVarsMin, p->pPars->nFlopsMin, iStart, p->pCare, p->vSuppsInv, &nOutputs ); p->pCnf = Cnf_DeriveSimple( p->pPart, nOutputs ); - p->pSat = Cnf_DataWriteIntoSolver( p->pCnf, 1, 0 ); + p->pSat = (sat_solver *)Cnf_DataWriteIntoSolver( p->pCnf, 1, 0 ); sat_solver_compress( p->pSat ); p->vPatts = Vec_PtrAllocSimInfo( Aig_ManObjNumMax(p->pPart), p->nPattWords ); Vec_PtrCleanSimInfo( p->vPatts, 0, p->nPattWords ); @@ -314,3 +317,5 @@ Aig_Man_t * Cgt_ClockGating( Aig_Man_t * pAig, Aig_Man_t * pCare, Cgt_Par_t * pP //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/cgt/cgtDecide.c b/src/aig/cgt/cgtDecide.c index 3e79ff73..54a69e95 100644 --- a/src/aig/cgt/cgtDecide.c +++ b/src/aig/cgt/cgtDecide.c @@ -21,6 +21,9 @@ #include "cgtInt.h" #include "sswInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -96,11 +99,11 @@ int Cgt_ManCheckGateComplete( Aig_Man_t * pAig, Vec_Vec_t * vGatesAll, Aig_Obj_t Vec_Ptr_t * vGates; Aig_Obj_t * pObj; int i; - Vec_PtrForEachEntry( vFanout, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vFanout, pObj, i ) { if ( Saig_ObjIsPo(pAig, pObj) ) return 0; - vGates = Vec_VecEntry( vGatesAll, Aig_ObjPioNum(pObj) - Saig_ManPoNum(pAig) ); + vGates = (Vec_Ptr_t *)Vec_VecEntry( vGatesAll, Aig_ObjPioNum(pObj) - Saig_ManPoNum(pAig) ); if ( Vec_PtrFind( vGates, pGate ) == -1 ) return 0; } @@ -125,7 +128,7 @@ Vec_Ptr_t * Cgt_ManCompleteGates( Aig_Man_t * pAig, Vec_Vec_t * vGatesAll, int n int i, k; vFanout = Vec_PtrAlloc( 100 ); vGatesFull = Vec_PtrAlloc( 100 ); - Vec_VecForEachEntry( vGatesAll, pGate, i, k ) + Vec_VecForEachEntry( Aig_Obj_t *, vGatesAll, pGate, i, k ) { pGateR = Aig_Regular(pGate); if ( pGateR->fMarkA ) @@ -136,7 +139,7 @@ Vec_Ptr_t * Cgt_ManCompleteGates( Aig_Man_t * pAig, Vec_Vec_t * vGatesAll, int n Vec_PtrPush( vGatesFull, pGate ); } Vec_PtrFree( vFanout ); - Vec_VecForEachEntry( vGatesAll, pGate, i, k ) + Vec_VecForEachEntry( Aig_Obj_t *, vGatesAll, pGate, i, k ) Aig_Regular(pGate)->fMarkA = 0; return vGatesFull; } @@ -197,8 +200,8 @@ Vec_Vec_t * Cgt_ManDecideSimple( Aig_Man_t * pAig, Vec_Vec_t * vGatesAll, int nO { nHitsMax = 0; pCandBest = NULL; - vCands = Vec_VecEntry( vGatesAll, i ); - Vec_PtrForEachEntry( vCands, pCand, k ) + vCands = (Vec_Ptr_t *)Vec_VecEntry( vGatesAll, i ); + Vec_PtrForEachEntry( Aig_Obj_t *, vCands, pCand, k ) { // check if this is indeed a clock-gate if ( nOdcMax == 0 && !Ssw_SmlCheckXorImplication( pSml, pObjLi, pObjLo, pCand ) ) @@ -260,15 +263,15 @@ Vec_Vec_t * Cgt_ManDecideArea( Aig_Man_t * pAig, Vec_Vec_t * vGatesAll, int nOdc // derive and label complete gates vCompletes = Cgt_ManCompleteGates( pAig, vGatesAll, nOdcMax, fVerbose ); // label complete gates - Vec_PtrForEachEntry( vCompletes, pGate, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vCompletes, pGate, i ) Aig_Regular(pGate)->fMarkA = 1; // select only complete gates vGates = Vec_VecStart( Saig_ManRegNum(pAig) ); - Vec_VecForEachEntry( vGatesAll, pGate, i, k ) + Vec_VecForEachEntry( Aig_Obj_t *, vGatesAll, pGate, i, k ) if ( Aig_Regular(pGate)->fMarkA ) Vec_VecPush( vGates, i, pGate ); // unlabel complete gates - Vec_PtrForEachEntry( vCompletes, pGate, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vCompletes, pGate, i ) Aig_Regular(pGate)->fMarkA = 0; // count the number of gated flops Vec_VecForEachLevel( vGates, vOne, i ) @@ -294,3 +297,5 @@ Vec_Vec_t * Cgt_ManDecideArea( Aig_Man_t * pAig, Vec_Vec_t * vGatesAll, int nOdc //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/cgt/cgtInt.h b/src/aig/cgt/cgtInt.h index 3d9823c3..8cce2381 100644 --- a/src/aig/cgt/cgtInt.h +++ b/src/aig/cgt/cgtInt.h @@ -21,6 +21,7 @@ #ifndef __CGT_INT_H__ #define __CGT_INT_H__ + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -34,9 +35,10 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -106,9 +108,11 @@ extern void Cgt_ManStop( Cgt_Man_t * p ); /*=== cgtSat.c ==========================================================*/ extern int Cgt_CheckImplication( Cgt_Man_t * p, Aig_Obj_t * pGate, Aig_Obj_t * pFlop ); -#ifdef __cplusplus -} -#endif + + +ABC_NAMESPACE_HEADER_END + + #endif diff --git a/src/aig/cgt/cgtMan.c b/src/aig/cgt/cgtMan.c index ddc1c5e0..7744226d 100644 --- a/src/aig/cgt/cgtMan.c +++ b/src/aig/cgt/cgtMan.c @@ -20,6 +20,9 @@ #include "cgtInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -172,3 +175,5 @@ void Cgt_ManStop( Cgt_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/cgt/cgtSat.c b/src/aig/cgt/cgtSat.c index 94168978..0a2a1daa 100644 --- a/src/aig/cgt/cgtSat.c +++ b/src/aig/cgt/cgtSat.c @@ -20,6 +20,9 @@ #include "cgtInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -90,3 +93,5 @@ p->timeSatUndec += clock() - clk; //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/cnf/cnf.h b/src/aig/cnf/cnf.h index f7d1d38c..7c3bf06b 100644 --- a/src/aig/cnf/cnf.h +++ b/src/aig/cnf/cnf.h @@ -21,6 +21,7 @@ #ifndef __CNF_H__ #define __CNF_H__ + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -39,9 +40,10 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -97,7 +99,7 @@ static inline int Cnf_CutLeaveNum( Cnf_Cut_t * pCut ) { return pCut- static inline int * Cnf_CutLeaves( Cnf_Cut_t * pCut ) { return pCut->pFanins; } static inline unsigned * Cnf_CutTruth( Cnf_Cut_t * pCut ) { return (unsigned *)(pCut->pFanins + pCut->nFanins); } -static inline Cnf_Cut_t * Cnf_ObjBestCut( Aig_Obj_t * pObj ) { return pObj->pData; } +static inline Cnf_Cut_t * Cnf_ObjBestCut( Aig_Obj_t * pObj ) { return (Cnf_Cut_t *)pObj->pData; } static inline void Cnf_ObjSetBestCut( Aig_Obj_t * pObj, Cnf_Cut_t * pCut ) { pObj->pData = pCut; } //////////////////////////////////////////////////////////////////////// @@ -121,6 +123,7 @@ static inline void Cnf_ObjSetBestCut( Aig_Obj_t * pObj, Cnf_Cut_t * pCut //////////////////////////////////////////////////////////////////////// /*=== cnfCore.c ========================================================*/ +extern Vec_Int_t * Cnf_DeriveMappingArray( Aig_Man_t * pAig ); extern Cnf_Dat_t * Cnf_Derive( Aig_Man_t * pAig, int nOutputs ); extern Cnf_Man_t * Cnf_ManRead(); extern void Cnf_ClearMemory(); @@ -147,6 +150,7 @@ extern void * Cnf_DataWriteIntoSolver( Cnf_Dat_t * p, int nFrames, int extern int Cnf_DataWriteOrClause( void * pSat, Cnf_Dat_t * pCnf ); extern int Cnf_DataWriteAndClauses( void * p, Cnf_Dat_t * pCnf ); extern void Cnf_DataTranformPolarity( Cnf_Dat_t * pCnf, int fTransformPos ); +extern int Cnf_DataAddXorClause( void * pSat, int iVarA, int iVarB, int iVarC ); /*=== cnfMap.c ========================================================*/ extern void Cnf_DeriveMapping( Cnf_Man_t * p ); extern int Cnf_ManMapForCnf( Cnf_Man_t * p ); @@ -160,14 +164,17 @@ extern Vec_Ptr_t * Cnf_ManScanMapping( Cnf_Man_t * p, int fCollect, int fPre extern Vec_Int_t * Cnf_DataCollectCiSatNums( Cnf_Dat_t * pCnf, Aig_Man_t * p ); extern Vec_Int_t * Cnf_DataCollectCoSatNums( Cnf_Dat_t * pCnf, Aig_Man_t * p ); /*=== cnfWrite.c ========================================================*/ +extern Vec_Int_t * Cnf_ManWriteCnfMapping( Cnf_Man_t * p, Vec_Ptr_t * vMapped ); extern void Cnf_SopConvertToVector( char * pSop, int nCubes, Vec_Int_t * vCover ); extern Cnf_Dat_t * Cnf_ManWriteCnf( Cnf_Man_t * p, Vec_Ptr_t * vMapped, int nOutputs ); extern Cnf_Dat_t * Cnf_DeriveSimple( Aig_Man_t * p, int nOutputs ); extern Cnf_Dat_t * Cnf_DeriveSimpleForRetiming( Aig_Man_t * p ); -#ifdef __cplusplus -} -#endif + + +ABC_NAMESPACE_HEADER_END + + #endif diff --git a/src/aig/cnf/cnfCore.c b/src/aig/cnf/cnfCore.c index 11a7af43..85c971c2 100644 --- a/src/aig/cnf/cnfCore.c +++ b/src/aig/cnf/cnfCore.c @@ -20,6 +20,9 @@ #include "cnf.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -41,6 +44,59 @@ static Cnf_Man_t * s_pManCnf = NULL; SeeAlso [] ***********************************************************************/ +Vec_Int_t * Cnf_DeriveMappingArray( Aig_Man_t * pAig ) +{ + Vec_Int_t * vResult; + Cnf_Man_t * p; + Vec_Ptr_t * vMapped; + Aig_MmFixed_t * pMemCuts; + int clk; + // allocate the CNF manager + if ( s_pManCnf == NULL ) + s_pManCnf = Cnf_ManStart(); + // connect the managers + p = s_pManCnf; + p->pManAig = pAig; + + // generate cuts for all nodes, assign cost, and find best cuts +clk = clock(); + pMemCuts = Dar_ManComputeCuts( pAig, 10, 0 ); +p->timeCuts = clock() - clk; + + // find the mapping +clk = clock(); + Cnf_DeriveMapping( p ); +p->timeMap = clock() - clk; +// Aig_ManScanMapping( p, 1 ); + + // convert it into CNF +clk = clock(); + Cnf_ManTransferCuts( p ); + vMapped = Cnf_ManScanMapping( p, 1, 0 ); + vResult = Cnf_ManWriteCnfMapping( p, vMapped ); + Vec_PtrFree( vMapped ); + Aig_MmFixedStop( pMemCuts, 0 ); +p->timeSave = clock() - clk; + + // reset reference counters + Aig_ManResetRefs( pAig ); +//ABC_PRT( "Cuts ", p->timeCuts ); +//ABC_PRT( "Map ", p->timeMap ); +//ABC_PRT( "Saving ", p->timeSave ); + return vResult; +} + +/**Function************************************************************* + + Synopsis [Converts AIG into the SAT solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ Cnf_Dat_t * Cnf_Derive( Aig_Man_t * pAig, int nOutputs ) { Cnf_Man_t * p; @@ -183,3 +239,5 @@ ABC_PRT( "Ext ", clock() - clk ); //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/cnf/cnfCut.c b/src/aig/cnf/cnfCut.c index 17ab0c78..d41fc1fc 100644 --- a/src/aig/cnf/cnfCut.c +++ b/src/aig/cnf/cnfCut.c @@ -21,6 +21,9 @@ #include "cnf.h" #include "kit.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -369,3 +372,5 @@ Cnf_Cut_t * Cnf_CutCompose( Cnf_Man_t * p, Cnf_Cut_t * pCut, Cnf_Cut_t * pCutFan //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/cnf/cnfData.c b/src/aig/cnf/cnfData.c index 8df93fdb..e4798688 100644 --- a/src/aig/cnf/cnfData.c +++ b/src/aig/cnf/cnfData.c @@ -20,13 +20,16 @@ #include "cnf.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -static char s_Data3[81] = "!#&()*+,-.0123456789:;<=>?ABCDEFGHIJKLMNOPQRSTUVWXYZ[]abcdefghijklmnopqrstuvwxyz|"; +static const char s_Data3[82] = "!#&()*+,-.0123456789:;<=>?ABCDEFGHIJKLMNOPQRSTUVWXYZ[]abcdefghijklmnopqrstuvwxyz|"; -static char * s_Data4[] = { +static const char * s_Data4[] = { "! B a . 8 .B 8a K !K T Ta j 8j Tj s ( + (B +a (. +8 .B( +8a (K +K T( +T j( ", "+j Tj( s+ E !E H Ha E. 8E H. H8 EK EK! HT HTa jE 8jE Hj sH d +d Hd g d. 8d ", "Hd. g8 dK +dK Td gT dj +jd Hjd gs 2 !2 2B a2 5 58 5B 5a 2K 2K! T2 Ta2 5j 58", @@ -4782,3 +4785,5 @@ int Aig_ManDeriveCnfTest2() //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/cnf/cnfMan.c b/src/aig/cnf/cnfMan.c index f8e88b8f..762673ad 100644 --- a/src/aig/cnf/cnfMan.c +++ b/src/aig/cnf/cnfMan.c @@ -22,6 +22,9 @@ #include "satSolver.h" #include "zlib.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -422,7 +425,7 @@ void * Cnf_DataWriteIntoSolver( Cnf_Dat_t * p, int nFrames, int fInit ) ***********************************************************************/ int Cnf_DataWriteOrClause( void * p, Cnf_Dat_t * pCnf ) { - sat_solver * pSat = p; + sat_solver * pSat = (sat_solver *)p; Aig_Obj_t * pObj; int i, * pLits; pLits = ABC_ALLOC( int, Aig_ManPoNum(pCnf->pMan) ); @@ -450,7 +453,7 @@ int Cnf_DataWriteOrClause( void * p, Cnf_Dat_t * pCnf ) ***********************************************************************/ int Cnf_DataWriteAndClauses( void * p, Cnf_Dat_t * pCnf ) { - sat_solver * pSat = p; + sat_solver * pSat = (sat_solver *)p; Aig_Obj_t * pObj; int i, Lit; Aig_ManForEachPo( pCnf->pMan, pObj, i ) @@ -498,8 +501,53 @@ void Cnf_DataTranformPolarity( Cnf_Dat_t * pCnf, int fTransformPos ) ABC_FREE( pVarToPol ); } +/**Function************************************************************* + + Synopsis [Adds constraints for the two-input AND-gate.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cnf_DataAddXorClause( void * pSat, int iVarA, int iVarB, int iVarC ) +{ + lit Lits[3]; + assert( iVarA > 0 && iVarB > 0 && iVarC > 0 ); + + Lits[0] = toLitCond( iVarA, 1 ); + Lits[1] = toLitCond( iVarB, 1 ); + Lits[2] = toLitCond( iVarC, 1 ); + if ( !sat_solver_addclause( (sat_solver *)pSat, Lits, Lits + 3 ) ) + return 0; + + Lits[0] = toLitCond( iVarA, 1 ); + Lits[1] = toLitCond( iVarB, 0 ); + Lits[2] = toLitCond( iVarC, 0 ); + if ( !sat_solver_addclause( (sat_solver *)pSat, Lits, Lits + 3 ) ) + return 0; + + Lits[0] = toLitCond( iVarA, 0 ); + Lits[1] = toLitCond( iVarB, 1 ); + Lits[2] = toLitCond( iVarC, 0 ); + if ( !sat_solver_addclause( (sat_solver *)pSat, Lits, Lits + 3 ) ) + return 0; + + Lits[0] = toLitCond( iVarA, 0 ); + Lits[1] = toLitCond( iVarB, 0 ); + Lits[2] = toLitCond( iVarC, 1 ); + if ( !sat_solver_addclause( (sat_solver *)pSat, Lits, Lits + 3 ) ) + return 0; + + return 1; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/cnf/cnfMap.c b/src/aig/cnf/cnfMap.c index 58c9b803..8907485e 100644 --- a/src/aig/cnf/cnfMap.c +++ b/src/aig/cnf/cnfMap.c @@ -20,6 +20,9 @@ #include "cnf.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -72,7 +75,7 @@ int Cnf_CutSuperAreaFlow( Vec_Ptr_t * vSuper, int * pAreaFlows ) Aig_Obj_t * pLeaf; int i, nAreaFlow; nAreaFlow = 100 * (Vec_PtrSize(vSuper) + 1); - Vec_PtrForEachEntry( vSuper, pLeaf, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vSuper, pLeaf, i ) { pLeaf = Aig_Regular(pLeaf); if ( !Aig_ObjIsNode(pLeaf) ) @@ -355,3 +358,5 @@ int Cnf_ManMapForCnf( Cnf_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/cnf/cnfPost.c b/src/aig/cnf/cnfPost.c index 988275b2..f7491889 100644 --- a/src/aig/cnf/cnfPost.c +++ b/src/aig/cnf/cnfPost.c @@ -20,6 +20,9 @@ #include "cnf.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -143,7 +146,7 @@ void Cnf_ManFreeCuts( Cnf_Man_t * p ) Aig_ManForEachObj( p->pManAig, pObj, i ) if ( pObj->pData ) { - Cnf_CutFree( pObj->pData ); + Cnf_CutFree( (Cnf_Cut_t *)pObj->pData ); pObj->pData = NULL; } } @@ -231,3 +234,5 @@ void Cnf_ManPostprocess( Cnf_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/cnf/cnfUtil.c b/src/aig/cnf/cnfUtil.c index 7da9fb47..236b6bfa 100644 --- a/src/aig/cnf/cnfUtil.c +++ b/src/aig/cnf/cnfUtil.c @@ -20,6 +20,9 @@ #include "cnf.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -56,7 +59,7 @@ int Aig_ManScanMapping_rec( Cnf_Man_t * p, Aig_Obj_t * pObj, Vec_Ptr_t * vMapped Vec_Ptr_t * vSuper = Vec_PtrAlloc( 100 ); Aig_ObjCollectSuper( pObj, vSuper ); aArea = Vec_PtrSize(vSuper) + 1; - Vec_PtrForEachEntry( vSuper, pLeaf, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vSuper, pLeaf, i ) aArea += Aig_ManScanMapping_rec( p, Aig_Regular(pLeaf), vMapped ); Vec_PtrFree( vSuper ); //////////////////////////// @@ -131,7 +134,7 @@ int Cnf_ManScanMapping_rec( Cnf_Man_t * p, Aig_Obj_t * pObj, Vec_Ptr_t * vMapped Vec_Ptr_t * vSuper = Vec_PtrAlloc( 100 ); Aig_ObjCollectSuper( pObj, vSuper ); aArea = Vec_PtrSize(vSuper) + 1; - Vec_PtrForEachEntry( vSuper, pLeaf, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vSuper, pLeaf, i ) aArea += Cnf_ManScanMapping_rec( p, Aig_Regular(pLeaf), vMapped, fPreorder ); Vec_PtrFree( vSuper ); //////////////////////////// @@ -139,7 +142,7 @@ int Cnf_ManScanMapping_rec( Cnf_Man_t * p, Aig_Obj_t * pObj, Vec_Ptr_t * vMapped } else { - pCutBest = pObj->pData; + pCutBest = (Cnf_Cut_t *)pObj->pData; // assert( pCutBest->nFanins > 0 ); assert( pCutBest->Cost < 127 ); aArea = pCutBest->Cost; @@ -231,3 +234,5 @@ Vec_Int_t * Cnf_DataCollectCoSatNums( Cnf_Dat_t * pCnf, Aig_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/cnf/cnfWrite.c b/src/aig/cnf/cnfWrite.c index 638e67da..4f737305 100644 --- a/src/aig/cnf/cnfWrite.c +++ b/src/aig/cnf/cnfWrite.c @@ -20,6 +20,9 @@ #include "cnf.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -30,6 +33,43 @@ /**Function************************************************************* + Synopsis [Derives CNF mapping.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Cnf_ManWriteCnfMapping( Cnf_Man_t * p, Vec_Ptr_t * vMapped ) +{ + Vec_Int_t * vResult; + Aig_Obj_t * pObj; + Cnf_Cut_t * pCut; + int i, k, nOffset; + nOffset = Aig_ManObjNumMax(p->pManAig); + vResult = Vec_IntStart( nOffset ); + Vec_PtrForEachEntry( Aig_Obj_t *, vMapped, pObj, i ) + { + assert( Aig_ObjIsNode(pObj) ); + pCut = Cnf_ObjBestCut( pObj ); + assert( pCut->nFanins < 5 ); + Vec_IntWriteEntry( vResult, Aig_ObjId(pObj), nOffset ); + Vec_IntPush( vResult, *Cnf_CutTruth(pCut) ); + for ( k = 0; k < pCut->nFanins; k++ ) + Vec_IntPush( vResult, pCut->pFanins[k] ); + for ( ; k < 4; k++ ) + Vec_IntPush( vResult, -1 ); + nOffset += 5; + } + return vResult; +} + + + +/**Function************************************************************* + Synopsis [Writes the cover into the array.] Description [] @@ -169,7 +209,7 @@ Cnf_Dat_t * Cnf_ManWriteCnf( Cnf_Man_t * p, Vec_Ptr_t * vMapped, int nOutputs ) // count the number of literals and clauses nLiterals = 1 + Aig_ManPoNum( p->pManAig ) + 3 * nOutputs; nClauses = 1 + Aig_ManPoNum( p->pManAig ) + nOutputs; - Vec_PtrForEachEntry( vMapped, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vMapped, pObj, i ) { assert( Aig_ObjIsNode(pObj) ); pCut = Cnf_ObjBestCut( pObj ); @@ -237,7 +277,7 @@ Cnf_Dat_t * Cnf_ManWriteCnf( Cnf_Man_t * p, Vec_Ptr_t * vMapped, int nOutputs ) } } // assign variables to the internal nodes - Vec_PtrForEachEntry( vMapped, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vMapped, pObj, i ) pCnf->pVarNums[pObj->Id] = Number++; // assign variables to the PIs and constant node Aig_ManForEachPi( p->pManAig, pObj, i ) @@ -249,7 +289,7 @@ Cnf_Dat_t * Cnf_ManWriteCnf( Cnf_Man_t * p, Vec_Ptr_t * vMapped, int nOutputs ) vSopTemp = Vec_IntAlloc( 1 << 16 ); pLits = pCnf->pClauses[0]; pClas = pCnf->pClauses; - Vec_PtrForEachEntry( vMapped, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vMapped, pObj, i ) { pCut = Cnf_ObjBestCut( pObj ); @@ -562,3 +602,5 @@ Cnf_Dat_t * Cnf_DeriveSimpleForRetiming( Aig_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/cnf/cnf_.c b/src/aig/cnf/cnf_.c index 7c9ca499..acf75093 100644 --- a/src/aig/cnf/cnf_.c +++ b/src/aig/cnf/cnf_.c @@ -20,6 +20,9 @@ #include "cnf.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -46,3 +49,5 @@ //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/csw/csw.h b/src/aig/csw/csw.h index 3d704d5f..c1bf7a73 100644 --- a/src/aig/csw/csw.h +++ b/src/aig/csw/csw.h @@ -21,6 +21,7 @@ #ifndef __CSW_H__ #define __CSW_H__ + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -29,9 +30,10 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -53,9 +55,11 @@ extern "C" { /*=== cnfCore.c ========================================================*/ extern Aig_Man_t * Csw_Sweep( Aig_Man_t * pAig, int nCutsMax, int nLeafMax, int fVerbose ); -#ifdef __cplusplus -} -#endif + + +ABC_NAMESPACE_HEADER_END + + #endif diff --git a/src/aig/csw/cswCore.c b/src/aig/csw/cswCore.c index 20893058..e1bdca00 100644 --- a/src/aig/csw/cswCore.c +++ b/src/aig/csw/cswCore.c @@ -20,6 +20,9 @@ #include "cswInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -92,3 +95,5 @@ p->timeOther = p->timeTotal - p->timeCuts - p->timeHash; //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/csw/cswCut.c b/src/aig/csw/cswCut.c index 14cc3e4c..bb6677c2 100644 --- a/src/aig/csw/cswCut.c +++ b/src/aig/csw/cswCut.c @@ -20,6 +20,9 @@ #include "cswInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -78,7 +81,7 @@ static inline float Csw_CutFindCost2( Csw_Man_t * p, Csw_Cut_t * pCut ) /**Function************************************************************* - Synopsis [Returns the next ABC_FREE cut to use.] + Synopsis [Returns the next free cut to use.] Description [] @@ -600,3 +603,5 @@ p->timeHash += clock() - clk; //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/csw/cswInt.h b/src/aig/csw/cswInt.h index 76c673a3..3a06f3f1 100644 --- a/src/aig/csw/cswInt.h +++ b/src/aig/csw/cswInt.h @@ -21,6 +21,7 @@ #ifndef __CSW_INT_H__ #define __CSW_INT_H__ + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -40,9 +41,10 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -145,9 +147,11 @@ extern int Csw_TableCountCuts( Csw_Man_t * p ); extern void Csw_TableCutInsert( Csw_Man_t * p, Csw_Cut_t * pCut ); extern Aig_Obj_t * Csw_TableCutLookup( Csw_Man_t * p, Csw_Cut_t * pCut ); -#ifdef __cplusplus -} -#endif + + +ABC_NAMESPACE_HEADER_END + + #endif diff --git a/src/aig/csw/cswMan.c b/src/aig/csw/cswMan.c index 4225402c..8b6e538b 100644 --- a/src/aig/csw/cswMan.c +++ b/src/aig/csw/cswMan.c @@ -20,6 +20,9 @@ #include "cswInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -123,3 +126,5 @@ void Csw_ManStop( Csw_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/csw/cswTable.c b/src/aig/csw/cswTable.c index 87e36ae1..9bab0a01 100644 --- a/src/aig/csw/cswTable.c +++ b/src/aig/csw/cswTable.c @@ -20,6 +20,9 @@ #include "cswInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -159,3 +162,5 @@ Aig_Obj_t * Csw_TableCutLookup( Csw_Man_t * p, Csw_Cut_t * pCut ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/csw/csw_.c b/src/aig/csw/csw_.c index 1c59f152..c12607d3 100644 --- a/src/aig/csw/csw_.c +++ b/src/aig/csw/csw_.c @@ -20,6 +20,9 @@ #include "cswInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -46,3 +49,5 @@ //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/dar/dar.h b/src/aig/dar/dar.h index 86f43a9e..0a3b5eb7 100644 --- a/src/aig/dar/dar.h +++ b/src/aig/dar/dar.h @@ -21,6 +21,7 @@ #ifndef __DAR_H__ #define __DAR_H__ + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -29,9 +30,10 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -80,6 +82,8 @@ struct Dar_RefPar_t_ /*=== darLib.c ========================================================*/ extern void Dar_LibStart(); extern void Dar_LibStop(); +extern void Dar_LibPrepare( int nSubgraphs ); +extern int Dar_LibReturnClass( unsigned uTruth ); /*=== darBalance.c ========================================================*/ extern Aig_Man_t * Dar_ManBalance( Aig_Man_t * p, int fUpdateLevel ); extern Aig_Man_t * Dar_ManBalanceXor( Aig_Man_t * pAig, int fExor, int fUpdateLevel, int fVerbose ); @@ -98,9 +102,11 @@ extern Aig_Man_t * Dar_ManCompress( Aig_Man_t * pAig, int fBalance, int fUpd extern Aig_Man_t * Dar_ManCompress2( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fFanout, int fPower, int fVerbose ); extern Aig_Man_t * Dar_ManChoice( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fConstruct, int nConfMax, int nLevelMax, int fVerbose ); -#ifdef __cplusplus -} -#endif + + +ABC_NAMESPACE_HEADER_END + + #endif diff --git a/src/aig/dar/darBalance.c b/src/aig/dar/darBalance.c index 35da7fe2..3bfcbdaa 100644 --- a/src/aig/dar/darBalance.c +++ b/src/aig/dar/darBalance.c @@ -21,6 +21,9 @@ #include "darInt.h" #include "tim.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -107,13 +110,13 @@ Vec_Ptr_t * Dar_BalanceCone( Aig_Obj_t * pObj, Vec_Vec_t * vStore, int Level ) if ( Vec_VecSize( vStore ) <= Level ) Vec_VecPush( vStore, Level, 0 ); // get the temporary array of nodes - vNodes = Vec_VecEntry( vStore, Level ); + vNodes = (Vec_Ptr_t *)Vec_VecEntry( vStore, Level ); Vec_PtrClear( vNodes ); // collect the nodes in the implication supergate RetValue = Dar_BalanceCone_rec( pObj, pObj, vNodes ); assert( vNodes->nSize > 1 ); // unmark the visited nodes - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) Aig_Regular(pObj)->fMarkB = 0; // if we found the node and its complement in the same implication supergate, // return empty set of nodes (meaning that we should use constant-0 node) @@ -146,19 +149,19 @@ int Dar_BalanceFindLeft( Vec_Ptr_t * vSuper ) return 0; // set the pointer to the one before the last Current = Vec_PtrSize(vSuper) - 2; - pObjRight = Vec_PtrEntry( vSuper, Current ); + pObjRight = (Aig_Obj_t *)Vec_PtrEntry( vSuper, Current ); // go through the nodes to the left of this one for ( Current--; Current >= 0; Current-- ) { // get the next node on the left - pObjLeft = Vec_PtrEntry( vSuper, Current ); + pObjLeft = (Aig_Obj_t *)Vec_PtrEntry( vSuper, Current ); // if the level of this node is different, quit the loop if ( Aig_ObjLevel(Aig_Regular(pObjLeft)) != Aig_ObjLevel(Aig_Regular(pObjRight)) ) break; } Current++; // get the node, for which the equality holds - pObjLeft = Vec_PtrEntry( vSuper, Current ); + pObjLeft = (Aig_Obj_t *)Vec_PtrEntry( vSuper, Current ); assert( Aig_ObjLevel(Aig_Regular(pObjLeft)) == Aig_ObjLevel(Aig_Regular(pObjRight)) ); return Current; } @@ -185,14 +188,14 @@ void Dar_BalancePermute( Aig_Man_t * p, Vec_Ptr_t * vSuper, int LeftBound, int f if ( LeftBound == RightBound ) return; // get the two last nodes - pObj1 = Vec_PtrEntry( vSuper, RightBound + 1 ); - pObj2 = Vec_PtrEntry( vSuper, RightBound ); + pObj1 = (Aig_Obj_t *)Vec_PtrEntry( vSuper, RightBound + 1 ); + pObj2 = (Aig_Obj_t *)Vec_PtrEntry( vSuper, RightBound ); if ( Aig_Regular(pObj1) == p->pConst1 || Aig_Regular(pObj2) == p->pConst1 || Aig_Regular(pObj1) == Aig_Regular(pObj2) ) return; // find the first node that can be shared for ( i = RightBound; i >= LeftBound; i-- ) { - pObj3 = Vec_PtrEntry( vSuper, i ); + pObj3 = (Aig_Obj_t *)Vec_PtrEntry( vSuper, i ); if ( Aig_Regular(pObj3) == p->pConst1 ) { Vec_PtrWriteEntry( vSuper, i, pObj2 ); @@ -271,8 +274,8 @@ void Dar_BalancePushUniqueOrderByLevel( Vec_Ptr_t * vStore, Aig_Obj_t * pObj ) // find the p of the node for ( i = vStore->nSize-1; i > 0; i-- ) { - pObj1 = vStore->pArray[i ]; - pObj2 = vStore->pArray[i-1]; + pObj1 = (Aig_Obj_t *)vStore->pArray[i ]; + pObj2 = (Aig_Obj_t *)vStore->pArray[i-1]; if ( Aig_ObjLevel(Aig_Regular(pObj1)) <= Aig_ObjLevel(Aig_Regular(pObj2)) ) break; vStore->pArray[i ] = pObj2; @@ -297,7 +300,7 @@ Aig_Obj_t * Dar_BalanceBuildSuper( Aig_Man_t * p, Vec_Ptr_t * vSuper, Aig_Type_t int LeftBound; assert( vSuper->nSize > 1 ); // sort the new nodes by level in the decreasing order - Vec_PtrSort( vSuper, Aig_NodeCompareLevelsDecrease ); + Vec_PtrSort( vSuper, (int (*)(void))Aig_NodeCompareLevelsDecrease ); // balance the nodes while ( vSuper->nSize > 1 ) { @@ -306,11 +309,11 @@ Aig_Obj_t * Dar_BalanceBuildSuper( Aig_Man_t * p, Vec_Ptr_t * vSuper, Aig_Type_t // find the node that can be shared (if no such node, randomize choice) Dar_BalancePermute( p, vSuper, LeftBound, Type == AIG_OBJ_EXOR ); // pull out the last two nodes - pObj1 = Vec_PtrPop(vSuper); - pObj2 = Vec_PtrPop(vSuper); + pObj1 = (Aig_Obj_t *)Vec_PtrPop(vSuper); + pObj2 = (Aig_Obj_t *)Vec_PtrPop(vSuper); Dar_BalancePushUniqueOrderByLevel( vSuper, Aig_Oper(p, pObj1, pObj2, Type) ); } - return Vec_PtrEntry(vSuper, 0); + return (Aig_Obj_t *)Vec_PtrEntry(vSuper, 0); } /**Function************************************************************* @@ -333,20 +336,20 @@ Aig_Obj_t * Dar_Balance_rec( Aig_Man_t * pNew, Aig_Obj_t * pObjOld, Vec_Vec_t * assert( !Aig_ObjIsBuf(pObjOld) ); // return if the result is known if ( pObjOld->pData ) - return pObjOld->pData; + return (Aig_Obj_t *)pObjOld->pData; assert( Aig_ObjIsNode(pObjOld) ); // get the implication supergate vSuper = Dar_BalanceCone( pObjOld, vStore, Level ); // check if supergate contains two nodes in the opposite polarity if ( vSuper->nSize == 0 ) - return pObjOld->pData = Aig_ManConst0(pNew); + return (Aig_Obj_t *)(pObjOld->pData = Aig_ManConst0(pNew)); if ( Vec_PtrSize(vSuper) < 2 ) printf( "Dar_Balance_rec: Internal error!\n" ); // for each old node, derive the new well-balanced node for ( i = 0; i < Vec_PtrSize(vSuper); i++ ) { - pObjNew = Dar_Balance_rec( pNew, Aig_Regular(vSuper->pArray[i]), vStore, Level + 1, fUpdateLevel ); - vSuper->pArray[i] = Aig_NotCond( pObjNew, Aig_IsComplement(vSuper->pArray[i]) ); + pObjNew = Dar_Balance_rec( pNew, Aig_Regular((Aig_Obj_t *)vSuper->pArray[i]), vStore, Level + 1, fUpdateLevel ); + vSuper->pArray[i] = Aig_NotCond( pObjNew, Aig_IsComplement((Aig_Obj_t *)vSuper->pArray[i]) ); } // build the supergate pObjNew = Dar_BalanceBuildSuper( pNew, vSuper, Aig_ObjType(pObjOld), fUpdateLevel ); @@ -366,7 +369,7 @@ Aig_Obj_t * Dar_Balance_rec( Aig_Man_t * pNew, Aig_Obj_t * pObjOld, Vec_Vec_t * } else Aig_Regular(pObjNew)->pHaig = pObjOld->pHaig; - return pObjOld->pData = pObjNew; + return (Aig_Obj_t *)(pObjOld->pData = pObjNew); } /**Function************************************************************* @@ -392,6 +395,7 @@ Aig_Man_t * Dar_ManBalance( Aig_Man_t * p, int fUpdateLevel ) pNew->pName = Aig_UtilStrsav( p->pName ); pNew->pSpec = Aig_UtilStrsav( p->pSpec ); pNew->nAsserts = p->nAsserts; + pNew->nConstrs = p->nConstrs; if ( p->vFlopNums ) pNew->vFlopNums = Vec_IntDup( p->vFlopNums ); // pass the HAIG manager @@ -407,7 +411,7 @@ Aig_Man_t * Dar_ManBalance( Aig_Man_t * p, int fUpdateLevel ) if ( p->pManTime != NULL ) { float arrTime; - Tim_ManIncrementTravId( p->pManTime ); + Tim_ManIncrementTravId( (Tim_Man_t *)p->pManTime ); Aig_ManSetPioNumbers( p ); Aig_ManForEachObj( p, pObj, i ) { @@ -420,7 +424,7 @@ Aig_Man_t * Dar_ManBalance( Aig_Man_t * p, int fUpdateLevel ) pObj->pData = pObjNew; pObjNew->pHaig = pObj->pHaig; // set the arrival time of the new PI - arrTime = Tim_ManGetCiArrival( p->pManTime, Aig_ObjPioNum(pObj) ); + arrTime = Tim_ManGetCiArrival( (Tim_Man_t *)p->pManTime, Aig_ObjPioNum(pObj) ); pObjNew->Level = (int)arrTime; } else if ( Aig_ObjIsPo(pObj) ) @@ -431,7 +435,7 @@ Aig_Man_t * Dar_ManBalance( Aig_Man_t * p, int fUpdateLevel ) pObjNew = Aig_NotCond( pObjNew, Aig_IsComplement(pDriver) ); // save arrival time of the output arrTime = (float)Aig_Regular(pObjNew)->Level; - Tim_ManSetCoArrival( p->pManTime, Aig_ObjPioNum(pObj), arrTime ); + Tim_ManSetCoArrival( (Tim_Man_t *)p->pManTime, Aig_ObjPioNum(pObj), arrTime ); // create PO pObjNew = Aig_ObjCreatePo( pNew, pObjNew ); pObjNew->pHaig = pObj->pHaig; @@ -440,7 +444,7 @@ Aig_Man_t * Dar_ManBalance( Aig_Man_t * p, int fUpdateLevel ) assert( 0 ); } Aig_ManCleanPioNumbers( p ); - pNew->pManTime = Tim_ManDup( p->pManTime, 0 ); + pNew->pManTime = Tim_ManDup( (Tim_Man_t *)p->pManTime, 0 ); } else { @@ -534,12 +538,12 @@ void Dar_BalancePrintStats( Aig_Man_t * p ) continue; Vec_PtrClear( vSuper ); Dar_BalanceCone_rec( pObj, pObj, vSuper ); - Vec_PtrForEachEntry( vSuper, pTemp, k ) + Vec_PtrForEachEntry( Aig_Obj_t *, vSuper, pTemp, k ) pTemp->fMarkB = 0; if ( Vec_PtrSize(vSuper) < 3 ) continue; printf( " %d(", Vec_PtrSize(vSuper) ); - Vec_PtrForEachEntry( vSuper, pTemp, k ) + Vec_PtrForEachEntry( Aig_Obj_t *, vSuper, pTemp, k ) printf( " %d", pTemp->Level ); printf( " )" ); } @@ -554,3 +558,5 @@ void Dar_BalancePrintStats( Aig_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/dar/darCore.c b/src/aig/dar/darCore.c index 83b6e08e..9811757c 100644 --- a/src/aig/dar/darCore.c +++ b/src/aig/dar/darCore.c @@ -20,6 +20,9 @@ #include "darInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -153,7 +156,13 @@ p->timeCuts += clock() - clk; p->GainBest = -1; Required = pAig->vLevelR? Aig_ObjRequiredLevel(pAig, pObj) : ABC_INFINITY; Dar_ObjForEachCut( pObj, pCut, k ) + { + int nLeavesOld = pCut->nLeaves; + if ( pCut->nLeaves == 3 ) + pCut->pLeaves[pCut->nLeaves++] = 0; Dar_LibEval( p, pObj, pCut, Required ); + pCut->nLeaves = nLeavesOld; + } // check the best gain if ( !(p->GainBest > 0 || (p->GainBest == 0 && p->pPars->fUseZeros)) ) { @@ -308,3 +317,5 @@ Aig_MmFixed_t * Dar_ManComputeCuts( Aig_Man_t * pAig, int nCutsMax, int fVerbose //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/dar/darCut.c b/src/aig/dar/darCut.c index 7f7b1b4c..b272b388 100644 --- a/src/aig/dar/darCut.c +++ b/src/aig/dar/darCut.c @@ -20,6 +20,9 @@ #include "darInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -127,7 +130,7 @@ static inline int Dar_CutFindValue( Dar_Man_t * p, Dar_Cut_t * pCut ) /**Function************************************************************* - Synopsis [Returns the next ABC_FREE cut to use.] + Synopsis [Returns the next free cut to use.] Description [Uses the cut with the smallest value.] @@ -628,7 +631,7 @@ void Dar_ManCutsRestart( Dar_Man_t * p, Aig_Obj_t * pRoot ) Aig_Obj_t * pObj; int i; Dar_ObjSetCuts( Aig_ManConst1(p->pAig), NULL ); - Vec_PtrForEachEntry( p->vCutNodes, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vCutNodes, pObj, i ) if ( !Aig_ObjIsNone(pObj) ) Dar_ObjSetCuts( pObj, NULL ); Vec_PtrClear( p->vCutNodes ); @@ -745,3 +748,5 @@ Dar_Cut_t * Dar_ObjComputeCuts_rec( Dar_Man_t * p, Aig_Obj_t * pObj ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/dar/darData.c b/src/aig/dar/darData.c index e644c92b..17963c4a 100644 --- a/src/aig/dar/darData.c +++ b/src/aig/dar/darData.c @@ -20,6 +20,8 @@ #include "darInt.h" +ABC_NAMESPACE_IMPL_START + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -11145,6 +11147,9 @@ Vec_Int_t * Dar_LibReadPrios() #include "abc.h" +ABC_NAMESPACE_IMPL_START + + /**Function************************************************************* Synopsis [Generate arrays.] @@ -11285,3 +11290,5 @@ void Aig_NtkGenerateArrays( Abc_Ntk_t * pNtk ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/dar/darInt.h b/src/aig/dar/darInt.h index 0f2e8894..70831534 100644 --- a/src/aig/dar/darInt.h +++ b/src/aig/dar/darInt.h @@ -21,6 +21,7 @@ #ifndef __DAR_INT_H__ #define __DAR_INT_H__ + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -40,9 +41,10 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -104,7 +106,7 @@ struct Dar_Man_t_ int time2; }; -static inline Dar_Cut_t * Dar_ObjCuts( Aig_Obj_t * pObj ) { return pObj->pData; } +static inline Dar_Cut_t * Dar_ObjCuts( Aig_Obj_t * pObj ) { return (Dar_Cut_t *)pObj->pData; } static inline void Dar_ObjSetCuts( Aig_Obj_t * pObj, Dar_Cut_t * pCuts ) { assert( !Aig_ObjIsNone(pObj) ); pObj->pData = pCuts; } //////////////////////////////////////////////////////////////////////// @@ -144,7 +146,6 @@ extern Vec_Int_t * Dar_LibReadPrios(); /*=== darLib.c ============================================================*/ extern void Dar_LibStart(); extern void Dar_LibStop(); -extern void Dar_LibPrepare( int nSubgraphs ); extern void Dar_LibReturnCanonicals( unsigned * pCanons ); extern void Dar_LibEval( Dar_Man_t * p, Aig_Obj_t * pRoot, Dar_Cut_t * pCut, int Required ); extern Aig_Obj_t * Dar_LibBuildBest( Dar_Man_t * p ); @@ -156,9 +157,11 @@ extern void Dar_ManPrintStats( Dar_Man_t * p ); extern char ** Dar_Permutations( int n ); extern void Dar_Truth4VarNPN( unsigned short ** puCanons, char ** puPhases, char ** puPerms, unsigned char ** puMap ); -#ifdef __cplusplus -} -#endif + + +ABC_NAMESPACE_HEADER_END + + #endif diff --git a/src/aig/dar/darLib.c b/src/aig/dar/darLib.c index 7f9188e0..52fd36b3 100644 --- a/src/aig/dar/darLib.c +++ b/src/aig/dar/darLib.c @@ -19,6 +19,11 @@ ***********************************************************************/ #include "darInt.h" +#include "gia.h" +#include "dar.h" + +ABC_NAMESPACE_IMPL_START + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// @@ -41,7 +46,9 @@ struct Dar_LibObj_t_ // library object (2 words) struct Dar_LibDat_t_ // library object data { + union { Aig_Obj_t * pFunc; // the corresponding AIG node if it exists + int iGunc; }; // the corresponding AIG node if it exists int Level; // level of this node after it is constructured int TravId; // traversal ID of the library object data float dProb; // probability of the node being 1 @@ -184,6 +191,23 @@ void Dar_LibFree( Dar_Lib_t * p ) SeeAlso [] ***********************************************************************/ +int Dar_LibReturnClass( unsigned uTruth ) +{ + return s_DarLib->pMap[uTruth & 0xffff]; +} + + +/**Function************************************************************* + + Synopsis [Returns canonical truth tables.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ void Dar_LibReturnCanonicals( unsigned * pCanons ) { int Visits[222] = {0}; @@ -1005,14 +1029,310 @@ Aig_Obj_t * Dar_LibBuildBest( Dar_Man_t * p ) { int i, Counter = 4; for ( i = 0; i < Vec_PtrSize(p->vLeavesBest); i++ ) - s_DarLib->pDatas[i].pFunc = Vec_PtrEntry( p->vLeavesBest, i ); + s_DarLib->pDatas[i].pFunc = (Aig_Obj_t *)Vec_PtrEntry( p->vLeavesBest, i ); Dar_LibBuildClear_rec( Dar_LibObj(s_DarLib, p->OutBest), &Counter ); return Dar_LibBuildBest_rec( p, Dar_LibObj(s_DarLib, p->OutBest) ); } + + + + +/**Function************************************************************* + + Synopsis [Matches the cut with its canonical form.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Dar2_LibCutMatch( Gia_Man_t * p, Vec_Int_t * vCutLits, unsigned uTruth ) +{ + unsigned uPhase; + char * pPerm; + int i; + assert( Vec_IntSize(vCutLits) == 4 ); + // get the fanin permutation + uPhase = s_DarLib->pPhases[uTruth]; + pPerm = s_DarLib->pPerms4[ (int)s_DarLib->pPerms[uTruth] ]; + // collect fanins with the corresponding permutation/phase + for ( i = 0; i < Vec_IntSize(vCutLits); i++ ) + { +// pFanin = Gia_ManObj( p, pCut->pLeaves[ (int)pPerm[i] ] ); +// pFanin = Gia_ManObj( p, Vec_IntEntry( vCutLits, (int)pPerm[i] ) ); +// pFanin = Gia_ObjFromLit( p, Vec_IntEntry( vCutLits, (int)pPerm[i] ) ); + s_DarLib->pDatas[i].iGunc = Gia_LitNotCond( Vec_IntEntry(vCutLits, (int)pPerm[i]), ((uPhase >> i) & 1) ); + s_DarLib->pDatas[i].Level = Gia_ObjLevel( p, Gia_Regular(Gia_ObjFromLit(p, s_DarLib->pDatas[i].iGunc)) ); + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Assigns numbers to the nodes of one class.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Dar2_LibEvalAssignNums( Gia_Man_t * p, int Class ) +{ + Dar_LibObj_t * pObj; + Dar_LibDat_t * pData, * pData0, * pData1; + int iFanin0, iFanin1, i, iLit; + for ( i = 0; i < s_DarLib->nNodes0[Class]; i++ ) + { + // get one class node, assign its temporary number and set its data + pObj = Dar_LibObj(s_DarLib, s_DarLib->pNodes0[Class][i]); + pObj->Num = 4 + i; + assert( (int)pObj->Num < s_DarLib->nNodes0Max + 4 ); + pData = s_DarLib->pDatas + pObj->Num; + pData->fMffc = 0; + pData->iGunc = -1; + pData->TravId = 0xFFFF; + + // explore the fanins + assert( (int)Dar_LibObj(s_DarLib, pObj->Fan0)->Num < s_DarLib->nNodes0Max + 4 ); + assert( (int)Dar_LibObj(s_DarLib, pObj->Fan1)->Num < s_DarLib->nNodes0Max + 4 ); + pData0 = s_DarLib->pDatas + Dar_LibObj(s_DarLib, pObj->Fan0)->Num; + pData1 = s_DarLib->pDatas + Dar_LibObj(s_DarLib, pObj->Fan1)->Num; + pData->Level = 1 + ABC_MAX(pData0->Level, pData1->Level); + if ( pData0->iGunc == -1 || pData1->iGunc == -1 ) + continue; + iFanin0 = Gia_LitNotCond( pData0->iGunc, pObj->fCompl0 ); + iFanin1 = Gia_LitNotCond( pData1->iGunc, pObj->fCompl1 ); + // compute the resulting literal + if ( iFanin0 == 0 || iFanin1 == 0 || iFanin0 == Gia_LitNot(iFanin1) ) + iLit = 0; + else if ( iFanin0 == 1 || iFanin0 == iFanin1 ) + iLit = iFanin1; + else if ( iFanin1 == 1 ) + iLit = iFanin0; + else + { + iLit = Gia_ManHashLookup( p, Gia_ObjFromLit(p, iFanin0), Gia_ObjFromLit(p, iFanin1) ); + if ( iLit == 0 ) + iLit = -1; + } + pData->iGunc = iLit; + if ( pData->iGunc >= 0 ) + { + // update the level to be more accurate + pData->Level = Gia_ObjLevel( p, Gia_Regular(Gia_ObjFromLit(p, pData->iGunc)) ); + // mark the node if it is part of MFFC +// pData->fMffc = Gia_ObjIsTravIdCurrentArray(p, Gia_Regular(pData->pGunc)); + } + } +} + +/**Function************************************************************* + + Synopsis [Evaluates one cut.] + + Description [Returns the best gain.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Dar2_LibEval_rec( Dar_LibObj_t * pObj, int Out ) +{ + Dar_LibDat_t * pData; + int Area; + pData = s_DarLib->pDatas + pObj->Num; + if ( pData->TravId == Out ) + return 0; + pData->TravId = Out; + if ( pObj->fTerm ) + return 0; + assert( pObj->Num > 3 ); + if ( pData->iGunc >= 0 )//&& !pData->fMffc ) + return 0; + // this is a new node - get a bound on the area of its branches +// nNodesSaved--; + Area = Dar2_LibEval_rec( Dar_LibObj(s_DarLib, pObj->Fan0), Out ); +// if ( Area > nNodesSaved ) +// return 0xff; + Area += Dar2_LibEval_rec( Dar_LibObj(s_DarLib, pObj->Fan1), Out ); +// if ( Area > nNodesSaved ) +// return 0xff; + return Area + 1; +} + +/**Function************************************************************* + + Synopsis [Evaluates one cut.] + + Description [Returns the best gain.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Dar2_LibEval( Gia_Man_t * p, Vec_Int_t * vCutLits, unsigned uTruth, int fKeepLevel, Vec_Int_t * vLeavesBest2 ) +{ + int p_OutBest = -1; + int p_OutNumBest = -1; + int p_LevelBest = 1000000; + int p_GainBest = -1000000; + int p_ClassBest = -1; + int fTraining = 0; + Dar_LibObj_t * pObj; + int Out, k, Class, nNodesSaved, nNodesAdded, nNodesGained, clk; + clk = clock(); + assert( Vec_IntSize(vCutLits) == 4 ); + assert( (uTruth >> 16) == 0 ); + // check if the cut exits and assigns leaves and their levels + if ( !Dar2_LibCutMatch(p, vCutLits, uTruth) ) + return -1; + // mark MFFC of the node +// nNodesSaved = Dar2_LibCutMarkMffc( p->pAig, pRoot, pCut->nLeaves, p->pPars->fPower? &PowerSaved : NULL ); + nNodesSaved = 0; + // evaluate the cut + Class = s_DarLib->pMap[uTruth]; + Dar2_LibEvalAssignNums( p, Class ); + // profile outputs by their savings +// p->nTotalSubgs += s_DarLib->nSubgr0[Class]; +// p->ClassSubgs[Class] += s_DarLib->nSubgr0[Class]; + for ( Out = 0; Out < s_DarLib->nSubgr0[Class]; Out++ ) + { + pObj = Dar_LibObj(s_DarLib, s_DarLib->pSubgr0[Class][Out]); +// nNodesAdded = Dar2_LibEval_rec( pObj, Out, nNodesSaved - !p->pPars->fUseZeros, Required, p->pPars->fPower? &PowerAdded : NULL ); + nNodesAdded = Dar2_LibEval_rec( pObj, Out ); + nNodesGained = nNodesSaved - nNodesAdded; + if ( fKeepLevel ) + { + if ( s_DarLib->pDatas[pObj->Num].Level > p_LevelBest || + (s_DarLib->pDatas[pObj->Num].Level == p_LevelBest && nNodesGained <= p_GainBest) ) + continue; + } + else + { + if ( nNodesGained < p_GainBest || + (nNodesGained == p_GainBest && s_DarLib->pDatas[pObj->Num].Level >= p_LevelBest) ) + continue; + } + // remember this possibility + Vec_IntClear( vLeavesBest2 ); + for ( k = 0; k < Vec_IntSize(vCutLits); k++ ) + Vec_IntPush( vLeavesBest2, s_DarLib->pDatas[k].iGunc ); + p_OutBest = s_DarLib->pSubgr0[Class][Out]; + p_OutNumBest = Out; + p_LevelBest = s_DarLib->pDatas[pObj->Num].Level; + p_GainBest = nNodesGained; + p_ClassBest = Class; +// assert( p_LevelBest <= Required ); + } +//clk = clock() - clk; +//p->ClassTimes[Class] += clk; +//p->timeEval += clk; + assert( p_OutBest != -1 ); + return p_OutBest; +} + +/**Function************************************************************* + + Synopsis [Clears the fields of the nodes used i this cut.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Dar2_LibBuildClear_rec( Dar_LibObj_t * pObj, int * pCounter ) +{ + if ( pObj->fTerm ) + return; + pObj->Num = (*pCounter)++; + s_DarLib->pDatas[ pObj->Num ].iGunc = -1; + Dar2_LibBuildClear_rec( Dar_LibObj(s_DarLib, pObj->Fan0), pCounter ); + Dar2_LibBuildClear_rec( Dar_LibObj(s_DarLib, pObj->Fan1), pCounter ); +} + +/**Function************************************************************* + + Synopsis [Reconstructs the best cut.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Dar2_LibBuildBest_rec( Gia_Man_t * p, Dar_LibObj_t * pObj ) +{ + Gia_Obj_t * pNode; + Dar_LibDat_t * pData; + int iFanin0, iFanin1; + pData = s_DarLib->pDatas + pObj->Num; + if ( pData->iGunc >= 0 ) + return pData->iGunc; + iFanin0 = Dar2_LibBuildBest_rec( p, Dar_LibObj(s_DarLib, pObj->Fan0) ); + iFanin1 = Dar2_LibBuildBest_rec( p, Dar_LibObj(s_DarLib, pObj->Fan1) ); + iFanin0 = Gia_LitNotCond( iFanin0, pObj->fCompl0 ); + iFanin1 = Gia_LitNotCond( iFanin1, pObj->fCompl1 ); + pData->iGunc = Gia_ManHashAnd( p, iFanin0, iFanin1 ); + pNode = Gia_ManObj( p, Gia_Lit2Var(pData->iGunc) ); + if ( Gia_ObjIsAnd( pNode ) ) + Gia_ObjSetAndLevel( p, pNode ); + Gia_ObjSetPhase( pNode ); + return pData->iGunc; +} + +/**Function************************************************************* + + Synopsis [Reconstructs the best cut.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Dar2_LibBuildBest( Gia_Man_t * p, Vec_Int_t * vLeavesBest2, int OutBest ) +{ + int i, iLeaf, Counter = 4; + assert( Vec_IntSize(vLeavesBest2) == 4 ); + Vec_IntForEachEntry( vLeavesBest2, iLeaf, i ) + s_DarLib->pDatas[i].iGunc = iLeaf; + Dar2_LibBuildClear_rec( Dar_LibObj(s_DarLib, OutBest), &Counter ); + return Dar2_LibBuildBest_rec( p, Dar_LibObj(s_DarLib, OutBest) ); +} + +/**Function************************************************************* + + Synopsis [Evaluate and build the new node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Dar_LibEvalBuild( Gia_Man_t * p, Vec_Int_t * vCutLits, unsigned uTruth, int fKeepLevel, Vec_Int_t * vLeavesBest2 ) +{ + int OutBest = Dar2_LibEval( p, vCutLits, uTruth, fKeepLevel, vLeavesBest2 ); + return Dar2_LibBuildBest( p, vLeavesBest2, OutBest ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/dar/darMan.c b/src/aig/dar/darMan.c index b11d3175..59150103 100644 --- a/src/aig/dar/darMan.c +++ b/src/aig/dar/darMan.c @@ -20,6 +20,8 @@ #include "darInt.h" +ABC_NAMESPACE_IMPL_START + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -127,9 +129,46 @@ void Dar_ManPrintStats( Dar_Man_t * p ) } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +#if 0 + +ABC_NAMESPACE_IMPL_END + +#include "kit.h" + +ABC_NAMESPACE_IMPL_START + +void Dar_ManPrintScript() +{ + unsigned pCanons[222]; + int i; + Dar_LibReturnCanonicals( pCanons ); + for ( i = 1; i < 222; i++ ) + { + Kit_DsdNtk_t * pNtk; + pNtk = Kit_DsdDecompose( pCanons + i, 4 ); + printf( " \"" ); + Kit_DsdPrint( stdout, pNtk ); + printf( "\", /* %3d */\n", i ); + Kit_DsdNtkFree( pNtk ); + } +} +#endif //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/dar/darPrec.c b/src/aig/dar/darPrec.c index 85a31dfc..4d164123 100644 --- a/src/aig/dar/darPrec.c +++ b/src/aig/dar/darPrec.c @@ -20,6 +20,9 @@ #include "darInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -130,7 +133,7 @@ void Dar_Permutations_rec( char ** pRes, int nFact, int n, char Array[] ) Description [The number of permutations in the array is n!. The number of entries in each permutation is n. Therefore, the resulting array is a - two-dimentional array of the size: n! x n. To ABC_FREE the resulting array, + two-dimentional array of the size: n! x n. To free the resulting array, call ABC_FREE() on the pointer returned by this procedure.] SideEffects [] @@ -297,14 +300,10 @@ void Dar_Truth4VarNPN( unsigned short ** puCanons, char ** puPhases, char ** puP int i, k; nFuncs = (1 << 16); - uCanons = ABC_ALLOC( unsigned short, nFuncs ); - uPhases = ABC_ALLOC( char, nFuncs ); - uPerms = ABC_ALLOC( char, nFuncs ); - uMap = ABC_ALLOC( unsigned char, nFuncs ); - memset( uCanons, 0, sizeof(unsigned short) * nFuncs ); - memset( uPhases, 0, sizeof(char) * nFuncs ); - memset( uPerms, 0, sizeof(char) * nFuncs ); - memset( uMap, 0, sizeof(unsigned char) * nFuncs ); + uCanons = ABC_CALLOC( unsigned short, nFuncs ); + uPhases = ABC_CALLOC( char, nFuncs ); + uPerms = ABC_CALLOC( char, nFuncs ); + uMap = ABC_CALLOC( unsigned char, nFuncs ); pPerms4 = Dar_Permutations( 4 ); nClasses = 1; @@ -330,11 +329,13 @@ void Dar_Truth4VarNPN( unsigned short ** puCanons, char ** puPhases, char ** puP uCanons[uPerm] = uTruth; uPhases[uPerm] = i; uPerms[uPerm] = k; + uMap[uPerm] = uMap[uTruth]; uPerm = ~uPerm & 0xFFFF; uCanons[uPerm] = uTruth; uPhases[uPerm] = i | 16; uPerms[uPerm] = k; + uMap[uPerm] = uMap[uTruth]; } else assert( uCanons[uPerm] == uTruth ); @@ -348,17 +349,21 @@ void Dar_Truth4VarNPN( unsigned short ** puCanons, char ** puPhases, char ** puP uCanons[uPerm] = uTruth; uPhases[uPerm] = i; uPerms[uPerm] = k; + uMap[uPerm] = uMap[uTruth]; uPerm = ~uPerm & 0xFFFF; uCanons[uPerm] = uTruth; uPhases[uPerm] = i | 16; uPerms[uPerm] = k; + uMap[uPerm] = uMap[uTruth]; } else assert( uCanons[uPerm] == uTruth ); } } } + for ( uTruth = 1; uTruth < 0xffff; uTruth++ ) + assert( uMap[uTruth] != 0 ); uPhases[(1<<16)-1] = 16; assert( nClasses == 222 ); ABC_FREE( pPerms4 ); @@ -385,3 +390,5 @@ void Dar_Truth4VarNPN( unsigned short ** puCanons, char ** puPhases, char ** puP //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/dar/darRefact.c b/src/aig/dar/darRefact.c index 5f6c5520..87e2d0da 100644 --- a/src/aig/dar/darRefact.c +++ b/src/aig/dar/darRefact.c @@ -24,6 +24,9 @@ #include "bdc.h" #include "bdcInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -234,8 +237,8 @@ int Dar_RefactTryGraph( Aig_Man_t * pAig, Aig_Obj_t * pRoot, Vec_Ptr_t * vCut, K Kit_GraphForEachLeaf( pGraph, pNode, i ) { pNode->pFunc = Vec_PtrEntry(vCut, i); - pNode->Level = Aig_Regular(pNode->pFunc)->Level; - assert( Aig_Regular(pNode->pFunc)->Level < (1<<24)-1 ); + pNode->Level = Aig_Regular((Aig_Obj_t *)pNode->pFunc)->Level; + assert( Aig_Regular((Aig_Obj_t *)pNode->pFunc)->Level < (1<<24)-1 ); } //printf( "Trying:\n" ); // compute the AIG size after adding the internal nodes @@ -246,8 +249,8 @@ int Dar_RefactTryGraph( Aig_Man_t * pAig, Aig_Obj_t * pRoot, Vec_Ptr_t * vCut, K pNode0 = Kit_GraphNode( pGraph, pNode->eEdge0.Node ); pNode1 = Kit_GraphNode( pGraph, pNode->eEdge1.Node ); // get the AIG nodes corresponding to the children - pAnd0 = pNode0->pFunc; - pAnd1 = pNode1->pFunc; + pAnd0 = (Aig_Obj_t *)pNode0->pFunc; + pAnd1 = (Aig_Obj_t *)pNode1->pFunc; if ( pAnd0 && pAnd1 ) { // if they are both present, find the resulting node @@ -320,13 +323,13 @@ Aig_Obj_t * Dar_RefactBuildGraph( Aig_Man_t * pAig, Vec_Ptr_t * vCut, Kit_Graph_ pNode->pFunc = Vec_PtrEntry(vCut, i); // check for a literal if ( Kit_GraphIsVar(pGraph) ) - return Aig_NotCond( Kit_GraphVar(pGraph)->pFunc, Kit_GraphIsComplement(pGraph) ); + return Aig_NotCond( (Aig_Obj_t *)Kit_GraphVar(pGraph)->pFunc, Kit_GraphIsComplement(pGraph) ); // build the AIG nodes corresponding to the AND gates of the graph //printf( "Building (current number %d):\n", Aig_ManObjNumMax(pAig) ); Kit_GraphForEachNode( pGraph, pNode, i ) { - pAnd0 = Aig_NotCond( Kit_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl ); - pAnd1 = Aig_NotCond( Kit_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl ); + pAnd0 = Aig_NotCond( (Aig_Obj_t *)Kit_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl ); + pAnd1 = Aig_NotCond( (Aig_Obj_t *)Kit_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl ); pNode->pFunc = Aig_And( pAig, pAnd0, pAnd1 ); /* printf( "Checking " ); @@ -339,7 +342,7 @@ printf( "\n" ); */ } // complement the result if necessary - return Aig_NotCond( pNode->pFunc, Kit_GraphIsComplement(pGraph) ); + return Aig_NotCond( (Aig_Obj_t *)pNode->pFunc, Kit_GraphIsComplement(pGraph) ); } /**Function************************************************************* @@ -473,7 +476,7 @@ int Dar_ObjCutLevelAchieved( Vec_Ptr_t * vCut, int nLevelMin ) { Aig_Obj_t * pObj; int i; - Vec_PtrForEachEntry( vCut, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vCut, pObj, i ) if ( !Aig_ObjIsPi(pObj) && (int)pObj->Level <= nLevelMin ) return 1; return 0; @@ -510,8 +513,8 @@ int Dar_ManRefactor( Aig_Man_t * pAig, Dar_RefPar_t * pPars ) // resynthesize each node once clkStart = clock(); - vCut = Vec_VecEntry( p->vCuts, 0 ); - vCut2 = Vec_VecEntry( p->vCuts, 1 ); + vCut = (Vec_Ptr_t *)Vec_VecEntry( p->vCuts, 0 ); + vCut2 = (Vec_Ptr_t *)Vec_VecEntry( p->vCuts, 1 ); p->nNodesInit = Aig_ManNodeNum(pAig); nNodesOld = Vec_PtrSize( pAig->vObjs ); // pProgress = Bar_ProgressStart( stdout, nNodesOld ); @@ -629,3 +632,5 @@ p->timeOther = p->timeTotal - p->timeCuts - p->timeEval; //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/dar/darResub.c b/src/aig/dar/darResub.c index f819934e..44367207 100644 --- a/src/aig/dar/darResub.c +++ b/src/aig/dar/darResub.c @@ -20,6 +20,9 @@ #include "darInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -46,3 +49,5 @@ //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/dar/darScript.c b/src/aig/dar/darScript.c index 20f3e14a..0332f961 100644 --- a/src/aig/dar/darScript.c +++ b/src/aig/dar/darScript.c @@ -23,12 +23,13 @@ #include "gia.h" #include "giaAig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// - extern void * Tim_ManDup( void * p, int fDiscrete ); - //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -83,10 +84,11 @@ Aig_Man_t * Dar_ManRwsat( Aig_Man_t * pAig, int fBalance, int fVerbose ) pParsRwr->fVerbose = fVerbose; pParsRef->fVerbose = fVerbose; - +//printf( "1" ); pAig = Aig_ManDupDfs( pAig ); if ( fVerbose ) Aig_ManPrintStats( pAig ); +//printf( "2" ); // balance if ( fBalance ) { @@ -96,18 +98,21 @@ Aig_Man_t * Dar_ManRwsat( Aig_Man_t * pAig, int fBalance, int fVerbose ) } //Aig_ManDumpBlif( pAig, "inter.blif", NULL, NULL ); +//printf( "3" ); // rewrite Dar_ManRewrite( pAig, pParsRwr ); pAig = Aig_ManDupDfs( pTemp = pAig ); Aig_ManStop( pTemp ); if ( fVerbose ) Aig_ManPrintStats( pAig ); +//printf( "4" ); // refactor Dar_ManRefactor( pAig, pParsRef ); pAig = Aig_ManDupDfs( pTemp = pAig ); Aig_ManStop( pTemp ); if ( fVerbose ) Aig_ManPrintStats( pAig ); +//printf( "5" ); // balance if ( fBalance ) { @@ -116,12 +121,14 @@ Aig_Man_t * Dar_ManRwsat( Aig_Man_t * pAig, int fBalance, int fVerbose ) if ( fVerbose ) Aig_ManPrintStats( pAig ); } +//printf( "6" ); // rewrite Dar_ManRewrite( pAig, pParsRwr ); pAig = Aig_ManDupDfs( pTemp = pAig ); Aig_ManStop( pTemp ); if ( fVerbose ) Aig_ManPrintStats( pAig ); +//printf( "7" ); return pAig; } @@ -369,7 +376,7 @@ Vec_Ptr_t * Dar_ManChoiceSynthesis( Aig_Man_t * pAig, int fBalance, int fUpdateL Vec_PtrPush( vAigs, pAig ); //Aig_ManPrintStats( pAig ); - pAig = Vec_PtrEntry( vAigs, 1 ); + pAig = (Aig_Man_t *)Vec_PtrEntry( vAigs, 1 ); Aig_ManForEachObj( pAig, pObj, i ) pObj->pHaig = pObj->pNext; @@ -402,7 +409,7 @@ clk = clock(); // (it is also important when constructing choices) if ( !fConstruct ) { - pMan = Vec_PtrPop( vAigs ); + pMan = (Aig_Man_t *)Vec_PtrPop( vAigs ); Vec_PtrPush( vAigs, Vec_PtrEntry(vAigs,0) ); Vec_PtrWriteEntry( vAigs, 0, pMan ); } @@ -416,7 +423,7 @@ clk = clock(); pMan = Aig_ManChoiceConstructive( vAigs, fVerbose ); else pMan = Aig_ManChoicePartitioned( vAigs, 300, nConfMax, nLevelMax, fVerbose ); - Vec_PtrForEachEntry( vAigs, pTemp, i ) + Vec_PtrForEachEntry( Aig_Man_t *, vAigs, pTemp, i ) Aig_ManStop( pTemp ); Vec_PtrFree( vAigs ); if ( fVerbose ) @@ -430,81 +437,6 @@ ABC_PRT( "Choicing time ", clock() - clk ); /**Function************************************************************* - Synopsis [Duplicates the AIG in the DFS order.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Dar_ManChoiceMiter_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) -{ - if ( ~pObj->Value ) - return pObj->Value; - Dar_ManChoiceMiter_rec( pNew, p, Gia_ObjFanin0(pObj) ); - if ( Gia_ObjIsCo(pObj) ) - return pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); - Dar_ManChoiceMiter_rec( pNew, p, Gia_ObjFanin1(pObj) ); - return pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); -} - -/**Function************************************************************* - - Synopsis [Derives the miter of several AIGs for choice computation.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Gia_Man_t * Dar_ManChoiceMiter( Vec_Ptr_t * vGias ) -{ - Gia_Man_t * pNew, * pGia, * pGia0; - int i, k, iNode, nNodes; - // make sure they have equal parameters - assert( Vec_PtrSize(vGias) > 0 ); - pGia0 = Vec_PtrEntry( vGias, 0 ); - Vec_PtrForEachEntry( vGias, pGia, i ) - { - assert( Gia_ManCiNum(pGia) == Gia_ManCiNum(pGia0) ); - assert( Gia_ManCoNum(pGia) == Gia_ManCoNum(pGia0) ); - assert( Gia_ManRegNum(pGia) == Gia_ManRegNum(pGia0) ); - Gia_ManFillValue( pGia ); - Gia_ManConst0(pGia)->Value = 0; - } - // start the new manager - pNew = Gia_ManStart( Vec_PtrSize(vGias) * Gia_ManObjNum(pGia0) ); - pNew->pName = Gia_UtilStrsav( pGia0->pName ); - // create new CIs and assign them to the old manager CIs - for ( k = 0; k < Gia_ManCiNum(pGia0); k++ ) - { - iNode = Gia_ManAppendCi(pNew); - Vec_PtrForEachEntry( vGias, pGia, i ) - Gia_ManCi( pGia, k )->Value = iNode; - } - // create internal nodes - Gia_ManHashAlloc( pNew ); - for ( k = 0; k < Gia_ManCoNum(pGia0); k++ ) - { - Vec_PtrForEachEntry( vGias, pGia, i ) - Dar_ManChoiceMiter_rec( pNew, pGia, Gia_ManCo( pGia, k ) ); - } - Gia_ManHashStop( pNew ); - // check the presence of dangling nodes - nNodes = Gia_ManHasDandling( pNew ); - assert( nNodes == 0 ); - // finalize - Gia_ManSetRegNum( pNew, Gia_ManRegNum(pGia0) ); - return pNew; -} - - -/**Function************************************************************* - Synopsis [Reproduces script "compress".] Description [] @@ -606,9 +538,9 @@ Aig_Man_t * Dar_NewCompress2( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, { // rewrite //Dar_ManRewrite( pAig, pParsRwr ); - pParsRwr->fUpdateLevel = 0; // disable level update +// pParsRwr->fUpdateLevel = 0; // disable level update // this change was requested in July and later disabled Dar_ManRewrite( pAig, pParsRwr ); - pParsRwr->fUpdateLevel = fUpdateLevel; // reenable level update if needed +// pParsRwr->fUpdateLevel = fUpdateLevel; // reenable level update if needed pAig = Aig_ManDupDfs( pTemp = pAig ); Aig_ManStop( pTemp ); @@ -719,21 +651,21 @@ Gia_Man_t * Dar_NewChoiceSynthesis( Aig_Man_t * pAig, int fBalance, int fUpdateL Aig_ManStop( pAig ); // swap around the first and the last - pTemp = Vec_PtrPop( vGias ); + pTemp = (Gia_Man_t *)Vec_PtrPop( vGias ); Vec_PtrPush( vGias, Vec_PtrEntry(vGias,0) ); Vec_PtrWriteEntry( vGias, 0, pTemp ); // Aig_Man_t * pAig; // int i; // printf( "Choicing will be performed with %d AIGs:\n", Vec_PtrSize(p->vAigs) ); -// Vec_PtrForEachEntry( p->vAigs, pAig, i ) +// Vec_PtrForEachEntry( Aig_Man_t *, p->vAigs, pAig, i ) // Aig_ManPrintStats( pAig ); // derive the miter - pGia = Dar_ManChoiceMiter( vGias ); + pGia = Gia_ManChoiceMiter( vGias ); // cleanup - Vec_PtrForEachEntry( vGias, pTemp, i ) + Vec_PtrForEachEntry( Gia_Man_t *, vGias, pTemp, i ) Gia_ManStop( pTemp ); Vec_PtrFree( vGias ); return pGia; @@ -808,7 +740,7 @@ clk = clock(); pMan->pSpec = Aig_UtilStrsav( pTemp->pSpec ); // cleanup - Vec_PtrForEachEntry( vAigs, pTemp, i ) + Vec_PtrForEachEntry( Aig_Man_t *, vAigs, pTemp, i ) Aig_ManStop( pTemp ); Vec_PtrFree( vAigs ); @@ -834,7 +766,7 @@ if ( fVerbose ) ***********************************************************************/ Aig_Man_t * Dar_ManChoiceNewAig( Aig_Man_t * pAig, Dch_Pars_t * pPars ) { - extern Aig_Man_t * Dch_DeriveTotalAig( Vec_Ptr_t * vAigs ); +// extern Aig_Man_t * Dch_DeriveTotalAig( Vec_Ptr_t * vAigs ); extern Aig_Man_t * Dch_ComputeChoices( Aig_Man_t * pAig, Dch_Pars_t * pPars ); int fVerbose = pPars->fVerbose; Aig_Man_t * pMan, * pTemp; @@ -850,14 +782,14 @@ pPars->timeSynth = clock() - clk; // swap the first and last network // this should lead to the primary choice being "better" because of synthesis // (it is also important when constructing choices) - pMan = Vec_PtrPop( vAigs ); + pMan = (Aig_Man_t *)Vec_PtrPop( vAigs ); Vec_PtrPush( vAigs, Vec_PtrEntry(vAigs,0) ); Vec_PtrWriteEntry( vAigs, 0, pMan ); // derive the total AIG pMan = Dch_DeriveTotalAig( vAigs ); // cleanup - Vec_PtrForEachEntry( vAigs, pTemp, i ) + Vec_PtrForEachEntry( Aig_Man_t *, vAigs, pTemp, i ) Aig_ManStop( pTemp ); Vec_PtrFree( vAigs ); @@ -905,7 +837,7 @@ pPars->timeSynth = clock() - clk; Aig_Man_t * Dar_ManChoiceNew( Aig_Man_t * pAig, Dch_Pars_t * pPars ) { extern Aig_Man_t * Cec_ComputeChoices( Gia_Man_t * pGia, Dch_Pars_t * pPars ); - extern Aig_Man_t * Dch_DeriveTotalAig( Vec_Ptr_t * vAigs ); +// extern Aig_Man_t * Dch_DeriveTotalAig( Vec_Ptr_t * vAigs ); extern Aig_Man_t * Dch_ComputeChoices( Aig_Man_t * pAig, Dch_Pars_t * pPars ); int fVerbose = pPars->fVerbose; Aig_Man_t * pMan, * pTemp; @@ -922,7 +854,7 @@ Aig_Man_t * Dar_ManChoiceNew( Aig_Man_t * pAig, Dch_Pars_t * pPars ) // perform synthesis clk = clock(); - pGia = Dar_NewChoiceSynthesis( Aig_ManDupDfs(pAig), 1, 1, pPars->fPower, pPars->fLightSynth, 0 ); + pGia = Dar_NewChoiceSynthesis( Aig_ManDupDfs(pAig), 1, 1, pPars->fPower, pPars->fLightSynth, pPars->fVerbose ); pPars->timeSynth = clock() - clk; // perform choice computation @@ -963,3 +895,5 @@ pPars->timeSynth = clock() - clk; //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/dar/dar_.c b/src/aig/dar/dar_.c index 12fd7d17..323abed2 100644 --- a/src/aig/dar/dar_.c +++ b/src/aig/dar/dar_.c @@ -20,6 +20,9 @@ #include "darInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -46,3 +49,5 @@ //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/dch/dch.h b/src/aig/dch/dch.h index 7271d256..69f340e5 100644 --- a/src/aig/dch/dch.h +++ b/src/aig/dch/dch.h @@ -21,6 +21,7 @@ #ifndef __DCH_H__ #define __DCH_H__ + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -29,9 +30,10 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -65,14 +67,20 @@ struct Dch_Pars_t_ /// FUNCTION DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +/*=== dchAig.c ==========================================================*/ +extern Aig_Man_t * Dch_DeriveTotalAig( Vec_Ptr_t * vAigs ); /*=== dchCore.c ==========================================================*/ extern void Dch_ManSetDefaultParams( Dch_Pars_t * p ); +extern int Dch_ManReadVerbose( Dch_Pars_t * p ); extern Aig_Man_t * Dch_ComputeChoices( Aig_Man_t * pAig, Dch_Pars_t * pPars ); extern void Dch_ComputeEquivalences( Aig_Man_t * pAig, Dch_Pars_t * pPars ); +/*=== dchScript.c ==========================================================*/ +extern Aig_Man_t * Dar_ManChoiceNew( Aig_Man_t * pAig, Dch_Pars_t * pPars ); + + +ABC_NAMESPACE_HEADER_END + -#ifdef __cplusplus -} -#endif #endif diff --git a/src/aig/dch/dchAig.c b/src/aig/dch/dchAig.c index d38a1304..91a00c63 100644 --- a/src/aig/dch/dchAig.c +++ b/src/aig/dch/dchAig.c @@ -20,6 +20,9 @@ #include "dchInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -67,8 +70,8 @@ Aig_Man_t * Dch_DeriveTotalAig( Vec_Ptr_t * vAigs ) assert( Vec_PtrSize(vAigs) > 0 ); // make sure they have the same number of PIs/POs nNodes = 0; - pAig = Vec_PtrEntry( vAigs, 0 ); - Vec_PtrForEachEntry( vAigs, pAig2, i ) + pAig = (Aig_Man_t *)Vec_PtrEntry( vAigs, 0 ); + Vec_PtrForEachEntry( Aig_Man_t *, vAigs, pAig2, i ) { assert( Aig_ManPiNum(pAig) == Aig_ManPiNum(pAig2) ); assert( Aig_ManPoNum(pAig) == Aig_ManPoNum(pAig2) ); @@ -77,19 +80,19 @@ Aig_Man_t * Dch_DeriveTotalAig( Vec_Ptr_t * vAigs ) } // map constant nodes pAigTotal = Aig_ManStart( nNodes ); - Vec_PtrForEachEntry( vAigs, pAig2, k ) + Vec_PtrForEachEntry( Aig_Man_t *, vAigs, pAig2, k ) Aig_ManConst1(pAig2)->pData = Aig_ManConst1(pAigTotal); // map primary inputs Aig_ManForEachPi( pAig, pObj, i ) { pObjPi = Aig_ObjCreatePi( pAigTotal ); - Vec_PtrForEachEntry( vAigs, pAig2, k ) + Vec_PtrForEachEntry( Aig_Man_t *, vAigs, pAig2, k ) Aig_ManPi( pAig2, i )->pData = pObjPi; } // construct the AIG in the order of POs Aig_ManForEachPo( pAig, pObj, i ) { - Vec_PtrForEachEntry( vAigs, pAig2, k ) + Vec_PtrForEachEntry( Aig_Man_t *, vAigs, pAig2, k ) { pObjPo = Aig_ManPo( pAig2, i ); Dch_DeriveTotalAig_rec( pAigTotal, Aig_ObjFanin0(pObjPo) ); @@ -112,3 +115,5 @@ Aig_Man_t * Dch_DeriveTotalAig( Vec_Ptr_t * vAigs ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/dch/dchChoice.c b/src/aig/dch/dchChoice.c index 019f4ec4..c20d2974 100644 --- a/src/aig/dch/dchChoice.c +++ b/src/aig/dch/dchChoice.c @@ -20,6 +20,9 @@ #include "dchInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -204,8 +207,8 @@ void Dch_DeriveChoiceAigNode( Aig_Man_t * pAigNew, Aig_Man_t * pAigOld, Aig_Obj_ if ( pRepr == NULL ) return; // get the corresponding new nodes - pObjNew = Aig_Regular(pObj->pData); - pReprNew = Aig_Regular(pRepr->pData); + pObjNew = Aig_Regular((Aig_Obj_t *)pObj->pData); + pReprNew = Aig_Regular((Aig_Obj_t *)pRepr->pData); if ( pObjNew == pReprNew ) return; // skip the earlier nodes @@ -240,7 +243,7 @@ void Dch_DeriveChoiceAigNode( Aig_Man_t * pAigNew, Aig_Man_t * pAigOld, Aig_Obj_ SeeAlso [] ***********************************************************************/ -Aig_Man_t * Dch_DeriveChoiceAig( Aig_Man_t * pAig ) +Aig_Man_t * Dch_DeriveChoiceAig_old( Aig_Man_t * pAig ) { Aig_Man_t * pChoices, * pTemp; Aig_Obj_t * pObj; @@ -268,8 +271,70 @@ Aig_Man_t * Dch_DeriveChoiceAig( Aig_Man_t * pAig ) return pChoices; } + +/**Function************************************************************* + + Synopsis [Derives the AIG with choices from representatives.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Dch_DeriveChoiceAigInt( Aig_Man_t * pAig ) +{ + Aig_Man_t * pChoices; + Aig_Obj_t * pObj; + int i; + // start recording equivalences + pChoices = Aig_ManStart( Aig_ManObjNumMax(pAig) ); + pChoices->pEquivs = ABC_CALLOC( Aig_Obj_t *, Aig_ManObjNumMax(pAig) ); + pChoices->pReprs = ABC_CALLOC( Aig_Obj_t *, Aig_ManObjNumMax(pAig) ); + // map constants and PIs + Aig_ManCleanData( pAig ); + Aig_ManConst1(pAig)->pData = Aig_ManConst1(pChoices); + Aig_ManForEachPi( pAig, pObj, i ) + pObj->pData = Aig_ObjCreatePi( pChoices ); + // construct choices for the internal nodes + assert( pAig->pReprs != NULL ); + Aig_ManForEachNode( pAig, pObj, i ) + Dch_DeriveChoiceAigNode( pChoices, pAig, pObj ); + Aig_ManForEachPo( pAig, pObj, i ) + Aig_ObjCreatePo( pChoices, Aig_ObjChild0CopyRepr(pChoices, pObj) ); + Dch_DeriveChoiceCountEquivs( pChoices ); + return pChoices; +} + +/**Function************************************************************* + + Synopsis [Derives the AIG with choices from representatives.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Dch_DeriveChoiceAig( Aig_Man_t * pAig ) +{ + Aig_Man_t * pChoices, * pTemp; + pChoices = Dch_DeriveChoiceAigInt( pAig ); +// pChoices = Dch_DeriveChoiceAigInt( pTemp = pChoices ); +// Aig_ManStop( pTemp ); + // there is no need for cleanup + ABC_FREE( pChoices->pReprs ); + pChoices = Aig_ManDupDfs( pTemp = pChoices ); + Aig_ManStop( pTemp ); + return pChoices; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/dch/dchClass.c b/src/aig/dch/dchClass.c index 9f4bd68c..83a3bc2e 100644 --- a/src/aig/dch/dchClass.c +++ b/src/aig/dch/dchClass.c @@ -20,6 +20,9 @@ #include "dchInt.h" +ABC_NAMESPACE_IMPL_START + + /* The candidate equivalence classes are stored as a vector of pointers to the array of pointers to the nodes in each class. @@ -280,10 +283,10 @@ void Dch_ClassesPrintOne( Dch_Cla_t * p, Aig_Obj_t * pRepr ) { Aig_Obj_t * pObj; int i; - printf( "{ " ); + Abc_Print( 1, "{ " ); Dch_ClassForEachNode( p, pRepr, pObj, i ) - printf( "%d(%d,%d) ", pObj->Id, pObj->Level, Aig_SupportSize(p->pAig,pObj) ); - printf( "}\n" ); + Abc_Print( 1, "%d(%d,%d) ", pObj->Id, pObj->Level, Aig_SupportSize(p->pAig,pObj) ); + Abc_Print( 1, "}\n" ); } /**Function************************************************************* @@ -302,21 +305,21 @@ void Dch_ClassesPrint( Dch_Cla_t * p, int fVeryVerbose ) Aig_Obj_t ** ppClass; Aig_Obj_t * pObj; int i; - printf( "Equivalence classes: Const1 = %5d. Class = %5d. Lit = %5d.\n", + Abc_Print( 1, "Equivalence classes: Const1 = %5d. Class = %5d. Lit = %5d.\n", p->nCands1, p->nClasses, p->nLits ); if ( !fVeryVerbose ) return; - printf( "Constants { " ); + Abc_Print( 1, "Constants { " ); Aig_ManForEachObj( p->pAig, pObj, i ) if ( Dch_ObjIsConst1Cand( p->pAig, pObj ) ) - printf( "%d(%d,%d) ", pObj->Id, pObj->Level, Aig_SupportSize(p->pAig,pObj) ); - printf( "}\n" ); + Abc_Print( 1, "%d(%d,%d) ", pObj->Id, pObj->Level, Aig_SupportSize(p->pAig,pObj) ); + Abc_Print( 1, "}\n" ); Dch_ManForEachClass( p, ppClass, i ) { - printf( "%3d (%3d) : ", i, p->pClassSizes[i] ); + Abc_Print( 1, "%3d (%3d) : ", i, p->pClassSizes[i] ); Dch_ClassesPrintOne( p, ppClass[0] ); } - printf( "\n" ); + Abc_Print( 1, "\n" ); } /**Function************************************************************* @@ -456,20 +459,20 @@ int Dch_ClassesRefineOneClass( Dch_Cla_t * p, Aig_Obj_t * pReprOld, int fRecursi return 0; // get the new representative - pReprNew = Vec_PtrEntry( p->vClassNew, 0 ); + pReprNew = (Aig_Obj_t *)Vec_PtrEntry( p->vClassNew, 0 ); assert( Vec_PtrSize(p->vClassOld) > 0 ); assert( Vec_PtrSize(p->vClassNew) > 0 ); // create old class pClassOld = Dch_ObjRemoveClass( p, pReprOld ); - Vec_PtrForEachEntry( p->vClassOld, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vClassOld, pObj, i ) { pClassOld[i] = pObj; Aig_ObjSetRepr( p->pAig, pObj, i? pReprOld : NULL ); } // create new class pClassNew = pClassOld + i; - Vec_PtrForEachEntry( p->vClassNew, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vClassNew, pObj, i ) { pClassNew[i] = pObj; Aig_ObjSetRepr( p->pAig, pObj, i? pReprNew : NULL ); @@ -572,21 +575,21 @@ int Dch_ClassesRefineConst1Group( Dch_Cla_t * p, Vec_Ptr_t * vRoots, int fRecurs return 0; // collect the nodes to be refined Vec_PtrClear( p->vClassNew ); - Vec_PtrForEachEntry( vRoots, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vRoots, pObj, i ) if ( !p->pFuncNodeIsConst( p->pManData, pObj ) ) Vec_PtrPush( p->vClassNew, pObj ); // check if there is a new class if ( Vec_PtrSize(p->vClassNew) == 0 ) return 0; p->nCands1 -= Vec_PtrSize(p->vClassNew); - pReprNew = Vec_PtrEntry( p->vClassNew, 0 ); + pReprNew = (Aig_Obj_t *)Vec_PtrEntry( p->vClassNew, 0 ); Aig_ObjSetRepr( p->pAig, pReprNew, NULL ); if ( Vec_PtrSize(p->vClassNew) == 1 ) return 1; // create a new class composed of these nodes ppClassNew = p->pMemClassesFree; p->pMemClassesFree += Vec_PtrSize(p->vClassNew); - Vec_PtrForEachEntry( p->vClassNew, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vClassNew, pObj, i ) { ppClassNew[i] = pObj; Aig_ObjSetRepr( p->pAig, pObj, i? pReprNew : NULL ); @@ -604,3 +607,5 @@ int Dch_ClassesRefineConst1Group( Dch_Cla_t * p, Vec_Ptr_t * vRoots, int fRecurs //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/dch/dchCnf.c b/src/aig/dch/dchCnf.c index 81fc2f2c..4175a123 100644 --- a/src/aig/dch/dchCnf.c +++ b/src/aig/dch/dchCnf.c @@ -20,6 +20,9 @@ #include "dchInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -169,7 +172,7 @@ void Dch_AddClausesSuper( Dch_Man_t * p, Aig_Obj_t * pNode, Vec_Ptr_t * vSuper ) pLits = ABC_ALLOC( int, nLits ); // suppose AND-gate is A & B = C // add !A => !C or A + !C - Vec_PtrForEachEntry( vSuper, pFanin, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vSuper, pFanin, i ) { pLits[0] = toLitCond(Dch_ObjSatNum(p,Aig_Regular(pFanin)), Aig_IsComplement(pFanin)); pLits[1] = toLitCond(Dch_ObjSatNum(p,pNode), 1); @@ -182,7 +185,7 @@ void Dch_AddClausesSuper( Dch_Man_t * p, Aig_Obj_t * pNode, Vec_Ptr_t * vSuper ) assert( RetValue ); } // add A & B => C or !A + !B + C - Vec_PtrForEachEntry( vSuper, pFanin, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vSuper, pFanin, i ) { pLits[i] = toLitCond(Dch_ObjSatNum(p,Aig_Regular(pFanin)), !Aig_IsComplement(pFanin)); if ( p->pPars->fPolarFlip ) @@ -293,7 +296,7 @@ void Dch_CnfNodeAddToSolver( Dch_Man_t * p, Aig_Obj_t * pObj ) vFrontier = Vec_PtrAlloc( 100 ); Dch_ObjAddToFrontier( p, pObj, vFrontier ); // explore nodes in the frontier - Vec_PtrForEachEntry( vFrontier, pNode, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vFrontier, pNode, i ) { // create the supergate assert( Dch_ObjSatNum(p,pNode) ); @@ -304,14 +307,14 @@ void Dch_CnfNodeAddToSolver( Dch_Man_t * p, Aig_Obj_t * pObj ) Vec_PtrPushUnique( p->vFanins, Aig_ObjFanin0( Aig_ObjFanin1(pNode) ) ); Vec_PtrPushUnique( p->vFanins, Aig_ObjFanin1( Aig_ObjFanin0(pNode) ) ); Vec_PtrPushUnique( p->vFanins, Aig_ObjFanin1( Aig_ObjFanin1(pNode) ) ); - Vec_PtrForEachEntry( p->vFanins, pFanin, k ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vFanins, pFanin, k ) Dch_ObjAddToFrontier( p, Aig_Regular(pFanin), vFrontier ); Dch_AddClausesMux( p, pNode ); } else { Dch_CollectSuper( pNode, fUseMuxes, p->vFanins ); - Vec_PtrForEachEntry( p->vFanins, pFanin, k ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vFanins, pFanin, k ) Dch_ObjAddToFrontier( p, Aig_Regular(pFanin), vFrontier ); Dch_AddClausesSuper( p, pNode, p->vFanins ); } @@ -327,3 +330,5 @@ void Dch_CnfNodeAddToSolver( Dch_Man_t * p, Aig_Obj_t * pObj ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/dch/dchCore.c b/src/aig/dch/dchCore.c index d38d5668..bc78682b 100644 --- a/src/aig/dch/dchCore.c +++ b/src/aig/dch/dchCore.c @@ -20,6 +20,9 @@ #include "dchInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -57,6 +60,22 @@ void Dch_ManSetDefaultParams( Dch_Pars_t * p ) /**Function************************************************************* + Synopsis [Returns verbose parameter.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Dch_ManReadVerbose( Dch_Pars_t * p ) +{ + return p->fVerbose; +} + +/**Function************************************************************* + Synopsis [Performs computation of AIGs with choices.] Description [Takes several AIGs and performs choicing.] @@ -91,7 +110,7 @@ p->timeTotal = clock() - clkTotal; pResult = Dch_DeriveChoiceAig( pAig ); // count the number of representatives if ( pPars->fVerbose ) - printf( "STATS: Reprs = %6d. Equivs = %6d. Choices = %6d.\n", + Abc_Print( 1, "STATS: Reprs = %6d. Equivs = %6d. Choices = %6d.\n", Dch_DeriveChoiceCountReprs( pAig ), Dch_DeriveChoiceCountEquivs( pResult ), Aig_ManChoiceNum( pResult ) ); @@ -135,3 +154,5 @@ p->timeTotal = clock() - clkTotal; //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/dch/dchInt.h b/src/aig/dch/dchInt.h index a419335d..6072d97b 100644 --- a/src/aig/dch/dchInt.h +++ b/src/aig/dch/dchInt.h @@ -21,6 +21,7 @@ #ifndef __DCH_INT_H__ #define __DCH_INT_H__ + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -33,9 +34,10 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -100,7 +102,7 @@ struct Dch_Man_t_ static inline int Dch_ObjSatNum( Dch_Man_t * p, Aig_Obj_t * pObj ) { return p->pSatVars[pObj->Id]; } static inline void Dch_ObjSetSatNum( Dch_Man_t * p, Aig_Obj_t * pObj, int Num ) { p->pSatVars[pObj->Id] = Num; } -static inline Aig_Obj_t * Dch_ObjFraig( Aig_Obj_t * pObj ) { return pObj->pData; } +static inline Aig_Obj_t * Dch_ObjFraig( Aig_Obj_t * pObj ) { return (Aig_Obj_t *)pObj->pData; } static inline void Dch_ObjSetFraig( Aig_Obj_t * pObj, Aig_Obj_t * pNode ) { pObj->pData = pNode; } static inline int Dch_ObjIsConst1Cand( Aig_Man_t * pAig, Aig_Obj_t * pObj ) @@ -118,7 +120,6 @@ static inline void Dch_ObjSetConst1Cand( Aig_Man_t * pAig, Aig_Obj_t * pObj ) //////////////////////////////////////////////////////////////////////// /*=== dchAig.c ===================================================*/ -extern Aig_Man_t * Dch_DeriveTotalAig( Vec_Ptr_t * vAigs ); /*=== dchChoice.c ===================================================*/ extern int Dch_DeriveChoiceCountReprs( Aig_Man_t * pAig ); extern int Dch_DeriveChoiceCountEquivs( Aig_Man_t * pAig ); @@ -155,9 +156,11 @@ extern void Dch_ManResimulateCex2( Dch_Man_t * p, Aig_Obj_t * pObj, Aig /*=== dchSweep.c ===================================================*/ extern void Dch_ManSweep( Dch_Man_t * p ); -#ifdef __cplusplus -} -#endif + + +ABC_NAMESPACE_HEADER_END + + #endif diff --git a/src/aig/dch/dchMan.c b/src/aig/dch/dchMan.c index c8bd8533..dc856309 100644 --- a/src/aig/dch/dchMan.c +++ b/src/aig/dch/dchMan.c @@ -20,6 +20,9 @@ #include "dchInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -74,34 +77,34 @@ Dch_Man_t * Dch_ManCreate( Aig_Man_t * pAig, Dch_Pars_t * pPars ) void Dch_ManPrintStats( Dch_Man_t * p ) { int nNodeNum = Aig_ManNodeNum(p->pAigTotal) / 3; - printf( "Parameters: Sim words = %d. Conf limit = %d. SAT var max = %d.\n", + Abc_Print( 1, "Parameters: Sim words = %d. Conf limit = %d. SAT var max = %d.\n", p->pPars->nWords, p->pPars->nBTLimit, p->pPars->nSatVarMax ); - printf( "AIG nodes : Total = %6d. Dangling = %6d. Main = %6d. (%6.2f %%)\n", + Abc_Print( 1, "AIG nodes : Total = %6d. Dangling = %6d. Main = %6d. (%6.2f %%)\n", Aig_ManNodeNum(p->pAigTotal), Aig_ManNodeNum(p->pAigTotal)-nNodeNum, nNodeNum, 100.0 * nNodeNum/Aig_ManNodeNum(p->pAigTotal) ); - printf( "SAT solver: Vars = %d. Max cone = %d. Recycles = %d.\n", + Abc_Print( 1, "SAT solver: Vars = %d. Max cone = %d. Recycles = %d.\n", p->nSatVars, p->nConeMax, p->nRecycles ); - printf( "SAT calls : All = %6d. Unsat = %6d. Sat = %6d. Fail = %6d.\n", + Abc_Print( 1, "SAT calls : All = %6d. Unsat = %6d. Sat = %6d. Fail = %6d.\n", p->nSatCalls, p->nSatCalls-p->nSatCallsSat-p->nSatFailsReal, p->nSatCallsSat, p->nSatFailsReal ); - printf( "Choices : Lits = %6d. Reprs = %5d. Equivs = %5d. Choices = %5d.\n", + Abc_Print( 1, "Choices : Lits = %6d. Reprs = %5d. Equivs = %5d. Choices = %5d.\n", p->nLits, p->nReprs, p->nEquivs, p->nChoices ); - printf( "Choicing runtime statistics:\n" ); + Abc_Print( 1, "Choicing runtime statistics:\n" ); p->timeOther = p->timeTotal-p->timeSimInit-p->timeSimSat-p->timeSat-p->timeChoice; - ABC_PRTP( "Sim init ", p->timeSimInit, p->timeTotal ); - ABC_PRTP( "Sim SAT ", p->timeSimSat, p->timeTotal ); - ABC_PRTP( "SAT solving", p->timeSat, p->timeTotal ); - ABC_PRTP( " sat ", p->timeSatSat, p->timeTotal ); - ABC_PRTP( " unsat ", p->timeSatUnsat, p->timeTotal ); - ABC_PRTP( " undecided", p->timeSatUndec, p->timeTotal ); - ABC_PRTP( "Choice ", p->timeChoice, p->timeTotal ); - ABC_PRTP( "Other ", p->timeOther, p->timeTotal ); - ABC_PRTP( "TOTAL ", p->timeTotal, p->timeTotal ); + Abc_PrintTimeP( 1, "Sim init ", p->timeSimInit, p->timeTotal ); + Abc_PrintTimeP( 1, "Sim SAT ", p->timeSimSat, p->timeTotal ); + Abc_PrintTimeP( 1, "SAT solving", p->timeSat, p->timeTotal ); + Abc_PrintTimeP( 1, " sat ", p->timeSatSat, p->timeTotal ); + Abc_PrintTimeP( 1, " unsat ", p->timeSatUnsat, p->timeTotal ); + Abc_PrintTimeP( 1, " undecided", p->timeSatUndec, p->timeTotal ); + Abc_PrintTimeP( 1, "Choice ", p->timeChoice, p->timeTotal ); + Abc_PrintTimeP( 1, "Other ", p->timeOther, p->timeTotal ); + Abc_PrintTimeP( 1, "TOTAL ", p->timeTotal, p->timeTotal ); if ( p->pPars->timeSynth ) { - ABC_PRT( "Synthesis ", p->pPars->timeSynth ); + Abc_PrintTime( 1, "Synthesis ", p->pPars->timeSynth ); } } @@ -154,7 +157,7 @@ void Dch_ManSatSolverRecycle( Dch_Man_t * p ) { Aig_Obj_t * pObj; int i; - Vec_PtrForEachEntry( p->vUsedNodes, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vUsedNodes, pObj, i ) Dch_ObjSetSatNum( p, pObj, 0 ); Vec_PtrClear( p->vUsedNodes ); // memset( p->pSatVars, 0, sizeof(int) * Aig_ManObjNumMax(p->pAigTotal) ); @@ -184,3 +187,5 @@ void Dch_ManSatSolverRecycle( Dch_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/dch/dchSat.c b/src/aig/dch/dchSat.c index 6966e635..f5e346ef 100644 --- a/src/aig/dch/dchSat.c +++ b/src/aig/dch/dchSat.c @@ -20,6 +20,9 @@ #include "dchInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -159,3 +162,5 @@ p->timeSatUndec += clock() - clk; //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/dch/dchSim.c b/src/aig/dch/dchSim.c index 44a96970..b2d24761 100644 --- a/src/aig/dch/dchSim.c +++ b/src/aig/dch/dchSim.c @@ -20,13 +20,16 @@ #include "dchInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// static inline unsigned * Dch_ObjSim( Vec_Ptr_t * vSims, Aig_Obj_t * pObj ) { - return Vec_PtrEntry( vSims, pObj->Id ); + return (unsigned *)Vec_PtrEntry( vSims, pObj->Id ); } static inline unsigned Dch_ObjRandomSim() { @@ -82,7 +85,7 @@ int Dch_NodesAreEqualCex( void * p, Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 ) ***********************************************************************/ unsigned Dch_NodeHash( void * p, Aig_Obj_t * pObj ) { - Vec_Ptr_t * vSims = p; + Vec_Ptr_t * vSims = (Vec_Ptr_t *)p; static int s_FPrimes[128] = { 1009, 1049, 1093, 1151, 1201, 1249, 1297, 1361, 1427, 1459, 1499, 1559, 1607, 1657, 1709, 1759, 1823, 1877, 1933, 1997, @@ -130,7 +133,7 @@ unsigned Dch_NodeHash( void * p, Aig_Obj_t * pObj ) ***********************************************************************/ int Dch_NodeIsConst( void * p, Aig_Obj_t * pObj ) { - Vec_Ptr_t * vSims = p; + Vec_Ptr_t * vSims = (Vec_Ptr_t *)p; unsigned * pSim; int k, nWords; nWords = (unsigned *)Vec_PtrEntry(vSims, 1) - (unsigned *)Vec_PtrEntry(vSims, 0); @@ -163,7 +166,7 @@ int Dch_NodeIsConst( void * p, Aig_Obj_t * pObj ) ***********************************************************************/ int Dch_NodesAreEqual( void * p, Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 ) { - Vec_Ptr_t * vSims = p; + Vec_Ptr_t * vSims = (Vec_Ptr_t *)p; unsigned * pSim0, * pSim1; int k, nWords; nWords = (unsigned *)Vec_PtrEntry(vSims, 1) - (unsigned *)Vec_PtrEntry(vSims, 0); @@ -290,3 +293,5 @@ Dch_Cla_t * Dch_CreateCandEquivClasses( Aig_Man_t * pAig, int nWords, int fVerbo //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/dch/dchSimSat.c b/src/aig/dch/dchSimSat.c index 4f31b928..325543d1 100644 --- a/src/aig/dch/dchSimSat.c +++ b/src/aig/dch/dchSimSat.c @@ -20,6 +20,9 @@ #include "dchInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -88,9 +91,9 @@ void Dch_ManCollectTfoCands( Dch_Man_t * p, Aig_Obj_t * pObj1, Aig_Obj_t * pObj2 Aig_ObjSetTravIdCurrent( p->pAigTotal, Aig_ManConst1(p->pAigTotal) ); Dch_ManCollectTfoCands_rec( p, pObj1 ); Dch_ManCollectTfoCands_rec( p, pObj2 ); - Vec_PtrSort( p->vSimRoots, Aig_ObjCompareIdIncrease ); - Vec_PtrSort( p->vSimClasses, Aig_ObjCompareIdIncrease ); - Vec_PtrForEachEntry( p->vSimClasses, pObj, i ) + Vec_PtrSort( p->vSimRoots, (int (*)(void))Aig_ObjCompareIdIncrease ); + Vec_PtrSort( p->vSimClasses, (int (*)(void))Aig_ObjCompareIdIncrease ); + Vec_PtrForEachEntry( Aig_Obj_t *, p->vSimClasses, pObj, i ) pObj->fMarkA = 0; } @@ -185,13 +188,13 @@ void Dch_ManResimulateCex( Dch_Man_t * p, Aig_Obj_t * pObj, Aig_Obj_t * pRepr ) Dch_ManResimulateSolved_rec( p, pRepr ); p->nConeMax = ABC_MAX( p->nConeMax, p->nConeThis ); // resimulate the cone of influence of the other nodes - Vec_PtrForEachEntry( p->vSimRoots, pRoot, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vSimRoots, pRoot, i ) Dch_ManResimulateOther_rec( p, pRoot ); // refine these nodes RetValue1 = Dch_ClassesRefineConst1Group( p->ppClasses, p->vSimRoots, 0 ); // resimulate the cone of influence of the cand classes RetValue2 = 0; - Vec_PtrForEachEntry( p->vSimClasses, pRoot, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vSimClasses, pRoot, i ) { ppClass = Dch_ClassesReadClass( p->ppClasses, pRoot, &nSize ); for ( k = 0; k < nSize; k++ ) @@ -235,7 +238,7 @@ void Dch_ManResimulateCex2( Dch_Man_t * p, Aig_Obj_t * pObj, Aig_Obj_t * pRepr ) Dch_ManResimulateSolved_rec( p, pRepr ); p->nConeMax = ABC_MAX( p->nConeMax, p->nConeThis ); // resimulate the cone of influence of the other nodes - Vec_PtrForEachEntry( p->vSimRoots, pRoot, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vSimRoots, pRoot, i ) Dch_ManResimulateOther_rec( p, pRoot ); // refine this class if ( Dch_ObjIsConst1Cand(p->pAigTotal, pObj) ) @@ -251,3 +254,5 @@ p->timeSimSat += clock() - clk; //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/dch/dchSweep.c b/src/aig/dch/dchSweep.c index afaf7426..4b054be2 100644 --- a/src/aig/dch/dchSweep.c +++ b/src/aig/dch/dchSweep.c @@ -21,6 +21,9 @@ #include "dchInt.h" #include "bar.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -139,3 +142,5 @@ void Dch_ManSweep( Dch_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/deco/deco.h b/src/aig/deco/deco.h index 07afd15c..84f2e25e 100644 --- a/src/aig/deco/deco.h +++ b/src/aig/deco/deco.h @@ -21,6 +21,7 @@ #ifndef __DEC_H__ #define __DEC_H__ + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -29,9 +30,10 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -50,7 +52,8 @@ struct Dec_Node_t_ Dec_Edge_t eEdge0; // the left child of the node Dec_Edge_t eEdge1; // the right child of the node // other info - void * pFunc; // the function of the node (BDD or AIG) + union { int iFunc; // the literal of the node (AIG) + void * pFunc; }; // the function of the node (BDD or AIG) unsigned Level : 14; // the level of this node in the global AIG // printing info unsigned fNodeOr : 1; // marks the original OR node @@ -166,10 +169,13 @@ static inline Dec_Edge_t Dec_IntToEdge( unsigned Edge ) SeeAlso [] ***********************************************************************/ +static inline unsigned Dec_EdgeToInt_( Dec_Edge_t m ) { union { Dec_Edge_t x; unsigned y; } v; v.x = m; return v.y; } +/* static inline unsigned Dec_EdgeToInt_( Dec_Edge_t eEdge ) { return *(unsigned *)&eEdge; } +*/ /**Function************************************************************* @@ -182,10 +188,13 @@ static inline unsigned Dec_EdgeToInt_( Dec_Edge_t eEdge ) SeeAlso [] ***********************************************************************/ +static inline Dec_Edge_t Dec_IntToEdge_( unsigned m ) { union { Dec_Edge_t x; unsigned y; } v; v.y = m; return v.x; } +/* static inline Dec_Edge_t Dec_IntToEdge_( unsigned Edge ) { return *(Dec_Edge_t *)&Edge; } +*/ /**Function************************************************************* @@ -691,9 +700,11 @@ static inline Dec_Edge_t Dec_GraphAddNodeMux( Dec_Graph_t * pGraph, Dec_Edge_t e return eNode; } -#ifdef __cplusplus -} -#endif + + +ABC_NAMESPACE_HEADER_END + + #endif diff --git a/src/aig/fra/fra.h b/src/aig/fra/fra.h index f661d2e5..b046cc47 100644 --- a/src/aig/fra/fra.h +++ b/src/aig/fra/fra.h @@ -21,6 +21,7 @@ #ifndef __FRA_H__ #define __FRA_H__ + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -41,9 +42,10 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -55,7 +57,6 @@ typedef struct Fra_Sec_t_ Fra_Sec_t; typedef struct Fra_Man_t_ Fra_Man_t; typedef struct Fra_Cla_t_ Fra_Cla_t; typedef struct Fra_Sml_t_ Fra_Sml_t; -typedef struct Fra_Cex_t_ Fra_Cex_t; typedef struct Fra_Bmc_t_ Fra_Bmc_t; // FRAIG parameters @@ -180,17 +181,6 @@ struct Fra_Sml_t_ unsigned pData[0]; // simulation data for the nodes }; -// simulation manager -struct Fra_Cex_t_ -{ - int iPo; // the zero-based number of PO, for which verification failed - int iFrame; // the zero-based number of the time-frame, for which verificaiton failed - int nRegs; // the number of registers in the miter - int nPis; // the number of primary inputs in the miter - int nBits; // the number of words of bit data used - unsigned pData[0]; // the cex bit data (the number of bits: nRegs + (iFrame+1) * nPis) -}; - // FRAIG manager struct Fra_Man_t_ { @@ -382,16 +372,18 @@ extern Fra_Sml_t * Fra_SmlStart( Aig_Man_t * pAig, int nPref, int nFrame extern void Fra_SmlStop( Fra_Sml_t * p ); extern Fra_Sml_t * Fra_SmlSimulateSeq( Aig_Man_t * pAig, int nPref, int nFrames, int nWords, int fCheckMiter ); extern Fra_Sml_t * Fra_SmlSimulateComb( Aig_Man_t * pAig, int nWords ); -extern Fra_Cex_t * Fra_SmlGetCounterExample( Fra_Sml_t * p ); -extern Fra_Cex_t * Fra_SmlCopyCounterExample( Aig_Man_t * pAig, Aig_Man_t * pFrames, int * pModel ); -extern void Fra_SmlFreeCounterExample( Fra_Cex_t * p ); -extern Fra_Cex_t * Fra_SmlTrivCounterExample( Aig_Man_t * pAig, int iFrameOut ); -extern int Fra_SmlRunCounterExample( Aig_Man_t * pAig, Fra_Cex_t * p ); -extern int Fra_SmlWriteCounterExample( FILE * pFile, Aig_Man_t * pAig, Fra_Cex_t * p ); - -#ifdef __cplusplus -} -#endif +extern Abc_Cex_t * Fra_SmlGetCounterExample( Fra_Sml_t * p ); +extern Abc_Cex_t * Fra_SmlCopyCounterExample( Aig_Man_t * pAig, Aig_Man_t * pFrames, int * pModel ); +extern void Fra_SmlFreeCounterExample( Abc_Cex_t * p ); +extern Abc_Cex_t * Fra_SmlTrivCounterExample( Aig_Man_t * pAig, int iFrameOut ); +extern int Fra_SmlRunCounterExample( Aig_Man_t * pAig, Abc_Cex_t * p ); +extern int Fra_SmlWriteCounterExample( FILE * pFile, Aig_Man_t * pAig, Abc_Cex_t * p ); +extern Abc_Cex_t * Fra_SmlSimpleCounterExample( Aig_Man_t * pAig, int * pModel, int iFrame, int iPo ); + + +ABC_NAMESPACE_HEADER_END + + #endif diff --git a/src/aig/fra/fraBmc.c b/src/aig/fra/fraBmc.c index 7b08d74d..ae9e4bc5 100644 --- a/src/aig/fra/fraBmc.c +++ b/src/aig/fra/fraBmc.c @@ -20,6 +20,9 @@ #include "fra.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -68,7 +71,7 @@ static inline Aig_Obj_t * Bmc_ObjChild1Frames( Aig_Obj_t * pObj, int i ) { asse ***********************************************************************/ int Fra_BmcNodesAreEqual( Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 ) { - Fra_Man_t * p = pObj0->pData; + Fra_Man_t * p = (Fra_Man_t *)pObj0->pData; Aig_Obj_t * pObjFrames0, * pObjFrames1; Aig_Obj_t * pObjFraig0, * pObjFraig1; int i; @@ -99,7 +102,7 @@ int Fra_BmcNodesAreEqual( Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 ) ***********************************************************************/ int Fra_BmcNodeIsConst( Aig_Obj_t * pObj ) { - Fra_Man_t * p = pObj->pData; + Fra_Man_t * p = (Fra_Man_t *)pObj->pData; return Fra_BmcNodesAreEqual( pObj, Aig_ManConst1(p->pManAig) ); } @@ -421,7 +424,7 @@ void Fra_BmcPerformSimple( Aig_Man_t * pAig, int nFrames, int nBTLimit, int fRew iOutput = Fra_FraigMiterAssertedOutput( pBmc->pAigFraig ); if ( pBmc->pAigFraig->pData ) { - pAig->pSeqModel = Fra_SmlCopyCounterExample( pAig, pBmc->pAigFrames, pBmc->pAigFraig->pData ); + pAig->pSeqModel = Fra_SmlCopyCounterExample( pAig, pBmc->pAigFrames, (int *)pBmc->pAigFraig->pData ); ABC_FREE( pBmc->pAigFraig->pData ); } else if ( iOutput >= 0 ) @@ -444,3 +447,5 @@ void Fra_BmcPerformSimple( Aig_Man_t * pAig, int nFrames, int nBTLimit, int fRew //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/fra/fraCec.c b/src/aig/fra/fraCec.c index b7a78050..037e6c70 100644 --- a/src/aig/fra/fraCec.c +++ b/src/aig/fra/fraCec.c @@ -21,6 +21,9 @@ #include "fra.h" #include "cnf.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -58,7 +61,7 @@ int Fra_FraigSat( Aig_Man_t * pMan, ABC_INT64_T nConfLimit, ABC_INT64_T nInsLimi Cnf_DataTranformPolarity( pCnf, 0 ); // convert into SAT solver - pSat = Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); + pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); if ( pSat == NULL ) { Cnf_DataFree( pCnf ); @@ -128,8 +131,9 @@ int Fra_FraigSat( Aig_Man_t * pMan, ABC_INT64_T nConfLimit, ABC_INT64_T nInsLimi } else assert( 0 ); -// ABC_PRT( "SAT sat_solver time", clock() - clk ); -// printf( "The number of conflicts = %d.\n", (int)pSat->sat_solver_stats.conflicts ); + +// Abc_Print( 1, "The number of conflicts = %6d. ", (int)pSat->stats.conflicts ); +// Abc_PrintTime( 1, "Solving time", clock() - clk ); // if the problem is SAT, get the counterexample if ( status == l_True ) @@ -283,7 +287,7 @@ int Fra_FraigCecPartitioned( Aig_Man_t * pMan1, Aig_Man_t * pMan2, int nConfLimi vParts = Aig_ManMiterPartitioned( pMan1, pMan2, nPartSize, fSmart ); // solve the partitions nOutputs = -1; - Vec_PtrForEachEntry( vParts, pAig, i ) + Vec_PtrForEachEntry( Aig_Man_t *, vParts, pAig, i ) { nOutputs++; if ( fVerbose ) @@ -319,7 +323,7 @@ int Fra_FraigCecPartitioned( Aig_Man_t * pMan1, Aig_Man_t * pMan2, int nConfLimi fflush( stdout ); } // free intermediate results - Vec_PtrForEachEntry( vParts, pAig, i ) + Vec_PtrForEachEntry( Aig_Man_t *, vParts, pAig, i ) Aig_ManStop( pAig ); Vec_PtrFree( vParts ); return RetValue; @@ -395,3 +399,5 @@ ABC_PRT( "Time", clock() - clkTotal ); //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/fra/fraClass.c b/src/aig/fra/fraClass.c index 94cac80a..9b1ad3f2 100644 --- a/src/aig/fra/fraClass.c +++ b/src/aig/fra/fraClass.c @@ -20,6 +20,9 @@ #include "fra.h" +ABC_NAMESPACE_IMPL_START + + /* The candidate equivalence classes are stored as a vector of pointers to the array of pointers to the nodes in each class. @@ -124,7 +127,7 @@ void Fra_ClassesCopyReprs( Fra_Cla_t * p, Vec_Ptr_t * vFailed ) } } if ( vFailed ) - Vec_PtrForEachEntry( vFailed, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vFailed, pObj, i ) p->pAig->pReprs[pObj->Id] = NULL; } @@ -163,7 +166,7 @@ int Fra_ClassesCountLits( Fra_Cla_t * p ) Aig_Obj_t ** pClass; int i, nNodes, nLits = 0; nLits = Vec_PtrSize( p->vClasses1 ); - Vec_PtrForEachEntry( p->vClasses, pClass, i ) + Vec_PtrForEachEntry( Aig_Obj_t **, p->vClasses, pClass, i ) { nNodes = Fra_ClassCount( pClass ); assert( nNodes > 1 ); @@ -187,7 +190,7 @@ int Fra_ClassesCountPairs( Fra_Cla_t * p ) { Aig_Obj_t ** pClass; int i, nNodes, nPairs = 0; - Vec_PtrForEachEntry( p->vClasses, pClass, i ) + Vec_PtrForEachEntry( Aig_Obj_t **, p->vClasses, pClass, i ) { nNodes = Fra_ClassCount( pClass ); assert( nNodes > 1 ); @@ -244,13 +247,13 @@ void Fra_ClassesPrint( Fra_Cla_t * p, int fVeryVerbose ) if ( fVeryVerbose ) { - Vec_PtrForEachEntry( p->vClasses1, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vClasses1, pObj, i ) assert( Fra_ClassObjRepr(pObj) == Aig_ManConst1(p->pAig) ); printf( "Constants { " ); - Vec_PtrForEachEntry( p->vClasses1, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vClasses1, pObj, i ) printf( "%d(%d,%d) ", pObj->Id, pObj->Level, Aig_SupportSize(p->pAig,pObj) ); printf( "}\n" ); - Vec_PtrForEachEntry( p->vClasses, pClass, i ) + Vec_PtrForEachEntry( Aig_Obj_t **, p->vClasses, pClass, i ) { printf( "%3d (%3d) : ", i, Fra_ClassCount(pClass) ); Fra_PrintClass( p, pClass ); @@ -415,15 +418,15 @@ Aig_Obj_t ** Fra_RefineClassOne( Fra_Cla_t * p, Aig_Obj_t ** ppClass ) Vec_PtrPush( p->vClassNew, pObj ); /* printf( "Refining class (" ); - Vec_PtrForEachEntry( p->vClassOld, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vClassOld, pObj, i ) printf( "%d,", pObj->Id ); printf( ") + (" ); - Vec_PtrForEachEntry( p->vClassNew, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vClassNew, pObj, i ) printf( "%d,", pObj->Id ); printf( ")\n" ); */ // put the nodes back into the class memory - Vec_PtrForEachEntry( p->vClassOld, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vClassOld, pObj, i ) { ppClass[i] = pObj; ppClass[Vec_PtrSize(p->vClassOld)+i] = NULL; @@ -431,7 +434,7 @@ Aig_Obj_t ** Fra_RefineClassOne( Fra_Cla_t * p, Aig_Obj_t ** ppClass ) } ppClass += 2*Vec_PtrSize(p->vClassOld); // put the new nodes into the class memory - Vec_PtrForEachEntry( p->vClassNew, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vClassNew, pObj, i ) { ppClass[i] = pObj; ppClass[Vec_PtrSize(p->vClassNew)+i] = NULL; @@ -455,7 +458,7 @@ int Fra_RefineClassLastIter( Fra_Cla_t * p, Vec_Ptr_t * vClasses ) { Aig_Obj_t ** pClass, ** pClass2; int nRefis; - pClass = Vec_PtrEntryLast( vClasses ); + pClass = (Aig_Obj_t **)Vec_PtrEntryLast( vClasses ); for ( nRefis = 0; (pClass2 = Fra_RefineClassOne( p, pClass )); nRefis++ ) { // if the original class is trivial, remove it @@ -495,7 +498,7 @@ int Fra_ClassesRefine( Fra_Cla_t * p ) // refine the classes nRefis = 0; Vec_PtrClear( p->vClassesTemp ); - Vec_PtrForEachEntry( p->vClasses, pClass, i ) + Vec_PtrForEachEntry( Aig_Obj_t **, p->vClasses, pClass, i ) { // add the class to the new array assert( pClass[0] != NULL ); @@ -533,7 +536,7 @@ int Fra_ClassesRefine1( Fra_Cla_t * p, int fRefineNewClass, int * pSkipped ) // collect all the nodes to be refined k = 0; Vec_PtrClear( p->vClassNew ); - Vec_PtrForEachEntry( p->vClasses1, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vClasses1, pObj, i ) { if ( p->pFuncNodeIsConst( pObj ) ) Vec_PtrWriteEntry( p->vClasses1, k++, pObj ); @@ -545,19 +548,19 @@ int Fra_ClassesRefine1( Fra_Cla_t * p, int fRefineNewClass, int * pSkipped ) return 0; /* printf( "Refined const-1 class: {" ); - Vec_PtrForEachEntry( p->vClassNew, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vClassNew, pObj, i ) printf( " %d", pObj->Id ); printf( " }\n" ); */ if ( Vec_PtrSize(p->vClassNew) == 1 ) { - Fra_ClassObjSetRepr( Vec_PtrEntry(p->vClassNew,0), NULL ); + Fra_ClassObjSetRepr( (Aig_Obj_t *)Vec_PtrEntry(p->vClassNew,0), NULL ); return 1; } // create a new class composed of these nodes ppClass = p->pMemClassesFree; p->pMemClassesFree += 2 * Vec_PtrSize(p->vClassNew); - Vec_PtrForEachEntry( p->vClassNew, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vClassNew, pObj, i ) { ppClass[i] = pObj; ppClass[Vec_PtrSize(p->vClassNew)+i] = NULL; @@ -658,7 +661,7 @@ void Fra_ClassesPostprocess( Fra_Cla_t * p ) printf( "Before: Const = %6d. Class = %6d. ", Vec_PtrSize(p->vClasses1), Vec_PtrSize(p->vClasses) ); // remove nodes from classes whose weight is less than WeightMax/Ratio k = 0; - Vec_PtrForEachEntry( p->vClasses1, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vClasses1, pObj, i ) { if ( pWeights[pObj->Id] >= WeightMax/Ratio ) Vec_PtrWriteEntry( p->vClasses1, k++, pObj ); @@ -667,7 +670,7 @@ void Fra_ClassesPostprocess( Fra_Cla_t * p ) } Vec_PtrShrink( p->vClasses1, k ); // in each class, compact the nodes - Vec_PtrForEachEntry( p->vClasses, ppClass, i ) + Vec_PtrForEachEntry( Aig_Obj_t **, p->vClasses, ppClass, i ) { k = 1; for ( c = 1; ppClass[c]; c++ ) @@ -681,7 +684,7 @@ void Fra_ClassesPostprocess( Fra_Cla_t * p ) } // remove classes with only repr k = 0; - Vec_PtrForEachEntry( p->vClasses, ppClass, i ) + Vec_PtrForEachEntry( Aig_Obj_t **, p->vClasses, ppClass, i ) if ( ppClass[1] != NULL ) Vec_PtrWriteEntry( p->vClasses, k++, ppClass ); Vec_PtrShrink( p->vClasses, k ); @@ -705,7 +708,7 @@ void Fra_ClassesSelectRepr( Fra_Cla_t * p ) Aig_Obj_t ** pClass, * pNodeMin; int i, c, cMinSupp, nSuppSizeMin, nSuppSizeCur; // reassign representatives in each class - Vec_PtrForEachEntry( p->vClasses, pClass, i ) + Vec_PtrForEachEntry( Aig_Obj_t **, p->vClasses, pClass, i ) { // collect support sizes and find the min-support node cMinSupp = -1; @@ -855,3 +858,5 @@ printf( "Assert miters = %6d. Output miters = %6d.\n", //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/fra/fraClau.c b/src/aig/fra/fraClau.c index 96d06380..490c73ff 100644 --- a/src/aig/fra/fraClau.c +++ b/src/aig/fra/fraClau.c @@ -22,6 +22,9 @@ #include "cnf.h" #include "satSolver.h" +ABC_NAMESPACE_IMPL_START + + /* This code is inspired by the paper: Aaron Bradley and Zohar Manna, "Checking safety by inductive generalization of counterexamples to @@ -233,7 +236,7 @@ Cla_Man_t * Fra_ClauStart( Aig_Man_t * pMan ) Aig_ObjChild0Flip( Aig_ManPo(pFramesMain, 0) ); // complement the first output pCnfMain = Cnf_DeriveSimple( pFramesMain, 0 ); //Cnf_DataWriteIntoFile( pCnfMain, "temp.cnf", 1 ); - p->pSatMain = Cnf_DataWriteIntoSolver( pCnfMain, 1, 0 ); + p->pSatMain = (sat_solver *)Cnf_DataWriteIntoSolver( pCnfMain, 1, 0 ); /* { int i; @@ -248,7 +251,7 @@ Cla_Man_t * Fra_ClauStart( Aig_Man_t * pMan ) pFramesTest = Aig_ManFrames( pMan, 1, 0, 0, 1, 0, NULL ); assert( Aig_ManPoNum(pFramesTest) == Aig_ManRegNum(pMan) ); pCnfTest = Cnf_DeriveSimple( pFramesTest, Aig_ManRegNum(pMan) ); - p->pSatTest = Cnf_DataWriteIntoSolver( pCnfTest, 1, 0 ); + p->pSatTest = (sat_solver *)Cnf_DataWriteIntoSolver( pCnfTest, 1, 0 ); p->nSatVarsTestBeg = p->nSatVarsTestCur = sat_solver_nvars( p->pSatTest ); // derive one timeframe to be checked for BMC @@ -256,7 +259,7 @@ Cla_Man_t * Fra_ClauStart( Aig_Man_t * pMan ) //Aig_ManShow( pFramesBmc, 0, NULL ); assert( Aig_ManPoNum(pFramesBmc) == Aig_ManRegNum(pMan) ); pCnfBmc = Cnf_DeriveSimple( pFramesBmc, Aig_ManRegNum(pMan) ); - p->pSatBmc = Cnf_DataWriteIntoSolver( pCnfBmc, 1, 0 ); + p->pSatBmc = (sat_solver *)Cnf_DataWriteIntoSolver( pCnfBmc, 1, 0 ); // create variable sets p->vSatVarsMainCs = Fra_ClauSaveInputVars( pFramesMain, pCnfMain, 2 * (Aig_ManPiNum(pMan)-Aig_ManRegNum(pMan)) ); @@ -756,3 +759,5 @@ int Fra_Clau( Aig_Man_t * pMan, int nIters, int fVerbose, int fVeryVerbose ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/fra/fraClaus.c b/src/aig/fra/fraClaus.c index e5fe3f40..90659333 100644 --- a/src/aig/fra/fraClaus.c +++ b/src/aig/fra/fraClaus.c @@ -22,6 +22,9 @@ #include "cnf.h" #include "satSolver.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -818,7 +821,7 @@ clk = clock(); int * pStart; // reset the solver if ( p->pSatMain ) sat_solver_delete( p->pSatMain ); - p->pSatMain = Cnf_DataWriteIntoSolver( p->pCnf, 1, 0 ); + p->pSatMain = (sat_solver *)Cnf_DataWriteIntoSolver( p->pCnf, 1, 0 ); if ( p->pSatMain == NULL ) { printf( "Error: Main solver is unsat.\n" ); @@ -1030,8 +1033,8 @@ void Fra_ClausSimInfoRecord( Clu_Man_t * p, int * pModel ) { if ( pModel[i] == l_True ) { - assert( Aig_InfoHasBit( Vec_PtrEntry(p->vCexes, i), p->nCexes ) == 0 ); - Aig_InfoSetBit( Vec_PtrEntry(p->vCexes, i), p->nCexes ); + assert( Aig_InfoHasBit( (unsigned *)Vec_PtrEntry(p->vCexes, i), p->nCexes ) == 0 ); + Aig_InfoSetBit( (unsigned *)Vec_PtrEntry(p->vCexes, i), p->nCexes ); } } p->nCexes++; @@ -1056,7 +1059,7 @@ int Fra_ClausSimInfoCheck( Clu_Man_t * p, int * pLits, int nLits ) { iVar = lit_var(pLits[i]) - p->nFrames * p->pCnf->nVars; assert( iVar > 0 && iVar < p->pCnf->nVars ); - pSims[i] = Vec_PtrEntry( p->vCexes, iVar ); + pSims[i] = (unsigned *)Vec_PtrEntry( p->vCexes, iVar ); } nWords = p->nCexes / 32; for ( w = 0; w < nWords; w++ ) @@ -1098,7 +1101,7 @@ int Fra_ClausInductiveClauses( Clu_Man_t * p ) // reset the solver if ( p->pSatMain ) sat_solver_delete( p->pSatMain ); - p->pSatMain = Cnf_DataWriteIntoSolver( p->pCnf, p->nFrames+1, 0 ); + p->pSatMain = (sat_solver *)Cnf_DataWriteIntoSolver( p->pCnf, p->nFrames+1, 0 ); if ( p->pSatMain == NULL ) { printf( "Error: Main solver is unsat.\n" ); @@ -1516,7 +1519,7 @@ Aig_Obj_t * Fra_ClausGetLiteral( Clu_Man_t * p, int * pVar2Id, int Lit ) Aig_Obj_t * pLiteral; int NodeId = pVar2Id[ lit_var(Lit) ]; assert( NodeId >= 0 ); - pLiteral = Aig_ManObj( p->pAig, NodeId )->pData; + pLiteral = (Aig_Obj_t *)Aig_ManObj( p->pAig, NodeId )->pData; return Aig_NotCond( pLiteral, lit_sign(Lit) ); } @@ -1705,7 +1708,7 @@ if ( fVerbose ) // check BMC clk = clock(); - p->pSatBmc = Cnf_DataWriteIntoSolver( p->pCnf, p->nPref + p->nFrames, 1 ); + p->pSatBmc = (sat_solver *)Cnf_DataWriteIntoSolver( p->pCnf, p->nPref + p->nFrames, 1 ); if ( p->pSatBmc == NULL ) { printf( "Error: BMC solver is unsat.\n" ); @@ -1725,7 +1728,7 @@ if ( fVerbose ) // start the SAT solver clk = clock(); - p->pSatMain = Cnf_DataWriteIntoSolver( p->pCnf, p->nFrames+1, 0 ); + p->pSatMain = (sat_solver *)Cnf_DataWriteIntoSolver( p->pCnf, p->nFrames+1, 0 ); if ( p->pSatMain == NULL ) { printf( "Error: Main solver is unsat.\n" ); @@ -1867,3 +1870,5 @@ clk = clock(); //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/fra/fraCnf.c b/src/aig/fra/fraCnf.c index 27da3fc5..5021e750 100644 --- a/src/aig/fra/fraCnf.c +++ b/src/aig/fra/fraCnf.c @@ -20,6 +20,9 @@ #include "fra.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -134,7 +137,7 @@ void Fra_AddClausesSuper( Fra_Man_t * p, Aig_Obj_t * pNode, Vec_Ptr_t * vSuper ) pLits = ABC_ALLOC( int, nLits ); // suppose AND-gate is A & B = C // add !A => !C or A + !C - Vec_PtrForEachEntry( vSuper, pFanin, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vSuper, pFanin, i ) { pLits[0] = toLitCond(Fra_ObjSatNum(Aig_Regular(pFanin)), Aig_IsComplement(pFanin)); pLits[1] = toLitCond(Fra_ObjSatNum(pNode), 1); @@ -142,7 +145,7 @@ void Fra_AddClausesSuper( Fra_Man_t * p, Aig_Obj_t * pNode, Vec_Ptr_t * vSuper ) assert( RetValue ); } // add A & B => C or !A + !B + C - Vec_PtrForEachEntry( vSuper, pFanin, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vSuper, pFanin, i ) pLits[i] = toLitCond(Fra_ObjSatNum(Aig_Regular(pFanin)), !Aig_IsComplement(pFanin)); pLits[nLits-1] = toLitCond(Fra_ObjSatNum(pNode), 0); RetValue = sat_solver_addclause( p->pSat, pLits, pLits + nLits ); @@ -246,7 +249,7 @@ void Fra_CnfNodeAddToSolver( Fra_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew ) if ( pOld ) Fra_ObjAddToFrontier( p, pOld, vFrontier ); if ( pNew ) Fra_ObjAddToFrontier( p, pNew, vFrontier ); // explore nodes in the frontier - Vec_PtrForEachEntry( vFrontier, pNode, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vFrontier, pNode, i ) { // create the supergate assert( Fra_ObjSatNum(pNode) ); @@ -258,14 +261,14 @@ void Fra_CnfNodeAddToSolver( Fra_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew ) Vec_PtrPushUnique( vFanins, Aig_ObjFanin0( Aig_ObjFanin1(pNode) ) ); Vec_PtrPushUnique( vFanins, Aig_ObjFanin1( Aig_ObjFanin0(pNode) ) ); Vec_PtrPushUnique( vFanins, Aig_ObjFanin1( Aig_ObjFanin1(pNode) ) ); - Vec_PtrForEachEntry( vFanins, pFanin, k ) + Vec_PtrForEachEntry( Aig_Obj_t *, vFanins, pFanin, k ) Fra_ObjAddToFrontier( p, Aig_Regular(pFanin), vFrontier ); Fra_AddClausesMux( p, pNode ); } else { vFanins = Fra_CollectSuper( pNode, fUseMuxes ); - Vec_PtrForEachEntry( vFanins, pFanin, k ) + Vec_PtrForEachEntry( Aig_Obj_t *, vFanins, pFanin, k ) Fra_ObjAddToFrontier( p, Aig_Regular(pFanin), vFrontier ); Fra_AddClausesSuper( p, pNode, vFanins ); } @@ -282,3 +285,5 @@ void Fra_CnfNodeAddToSolver( Fra_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/fra/fraCore.c b/src/aig/fra/fraCore.c index fad8c7bf..93c16e1e 100644 --- a/src/aig/fra/fraCore.c +++ b/src/aig/fra/fraCore.c @@ -20,6 +20,9 @@ #include "fra.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -198,12 +201,12 @@ void Fra_FraigVerifyCounterEx( Fra_Man_t * p, Vec_Int_t * vCex ) Aig_ManForEachPo( p->pManAig, pObj, i ) pObj->fMarkB = Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj); // check if the classes hold - Vec_PtrForEachEntry( p->pCla->vClasses1, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->pCla->vClasses1, pObj, i ) { if ( pObj->fPhase != pObj->fMarkB ) printf( "The node %d is not constant under cex!\n", pObj->Id ); } - Vec_PtrForEachEntry( p->pCla->vClasses, ppClass, i ) + Vec_PtrForEachEntry( Aig_Obj_t **, p->pCla->vClasses, ppClass, i ) { for ( c = 1; ppClass[c]; c++ ) if ( (ppClass[0]->fPhase ^ ppClass[c]->fPhase) != (ppClass[0]->fMarkB ^ ppClass[c]->fMarkB) ) @@ -483,3 +486,5 @@ Aig_Man_t * Fra_FraigEquivence( Aig_Man_t * pManAig, int nConfMax, int fProve ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/fra/fraHot.c b/src/aig/fra/fraHot.c index c4472121..29c9c33d 100644 --- a/src/aig/fra/fraHot.c +++ b/src/aig/fra/fraHot.c @@ -20,6 +20,9 @@ #include "fra.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -143,8 +146,8 @@ Vec_Int_t * Fra_OneHotCompute( Fra_Man_t * p, Fra_Sml_t * pSim ) continue; assert( i-nTruePis >= 0 ); // Aig_ManForEachLoSeq( pSim->pAig, pObj2, k ) -// Vec_PtrForEachEntryStart( pSim->pAig->vPis, pObj2, k, Aig_ManPiNum(p)-Aig_ManRegNum(p) ) - Vec_PtrForEachEntryStart( pSim->pAig->vPis, pObj2, k, i+1 ) +// Vec_PtrForEachEntryStart( Aig_Obj_t *, pSim->pAig->vPis, pObj2, k, Aig_ManPiNum(p)-Aig_ManRegNum(p) ) + Vec_PtrForEachEntryStart( Aig_Obj_t *, pSim->pAig->vPis, pObj2, k, i+1 ) { if ( fSkipConstEqu && Fra_OneHotNodeIsConst(pSim, pObj2) ) continue; @@ -201,7 +204,7 @@ void Fra_OneHotAssume( Fra_Man_t * p, Vec_Int_t * vOneHots ) pObj2 = Aig_ManPi( p->pManFraig, nPiNum + Fra_LitReg(Out2) ); pLits[0] = toLitCond( Fra_ObjSatNum(pObj1), Fra_LitSign(Out1) ); pLits[1] = toLitCond( Fra_ObjSatNum(pObj2), Fra_LitSign(Out2) ); - // add contraint to solver + // add constraint to solver if ( !sat_solver_addclause( p->pSat, pLits, pLits + 2 ) ) { printf( "Fra_OneHotAssume(): Adding clause makes SAT solver unsat.\n" ); @@ -337,11 +340,11 @@ void Fra_OneHotEstimateCoverage( Fra_Man_t * p, Vec_Int_t * vOneHots ) Aig_ManRandom(1); for ( i = 0; i < nRegs; i++ ) { - pSim1 = Vec_PtrEntry( vSimInfo, i ); + pSim1 = (unsigned *)Vec_PtrEntry( vSimInfo, i ); for ( w = 0; w < nSimWords; w++ ) pSim1[w] = Fra_ObjRandomSim(); } - pSimTot = Vec_PtrEntry( vSimInfo, nRegs ); + pSimTot = (unsigned *)Vec_PtrEntry( vSimInfo, nRegs ); // collect simulation info memset( pSimTot, 0, sizeof(unsigned) * nSimWords ); @@ -355,8 +358,8 @@ void Fra_OneHotEstimateCoverage( Fra_Man_t * p, Vec_Int_t * vOneHots ) //Fra_LitSign(Out1)? '-': '+', Fra_LitReg(Out1), //Fra_LitSign(Out2)? '-': '+', Fra_LitReg(Out2) ); Counter++; - pSim1 = Vec_PtrEntry( vSimInfo, Fra_LitReg(Out1) ); - pSim2 = Vec_PtrEntry( vSimInfo, Fra_LitReg(Out2) ); + pSim1 = (unsigned *)Vec_PtrEntry( vSimInfo, Fra_LitReg(Out1) ); + pSim2 = (unsigned *)Vec_PtrEntry( vSimInfo, Fra_LitReg(Out2) ); if ( Fra_LitSign(Out1) && Fra_LitSign(Out2) ) for ( w = 0; w < nSimWords; w++ ) pSimTot[w] |= pSim1[w] & pSim2[w]; @@ -442,7 +445,7 @@ void Fra_OneHotAddKnownConstraint( Fra_Man_t * p, Vec_Ptr_t * vOnehots ) // these constrants should be added to different timeframes! // (also note that PIs follow first - then registers) // - Vec_PtrForEachEntry( vOnehots, vGroup, k ) + Vec_PtrForEachEntry( Vec_Int_t *, vOnehots, vGroup, k ) { Vec_IntForEachEntry( vGroup, Out1, i ) Vec_IntForEachEntryStart( vGroup, Out2, j, i+1 ) @@ -451,7 +454,7 @@ void Fra_OneHotAddKnownConstraint( Fra_Man_t * p, Vec_Ptr_t * vOnehots ) pObj2 = Aig_ManPi( p->pManFraig, Out2 ); pLits[0] = toLitCond( Fra_ObjSatNum(pObj1), 1 ); pLits[1] = toLitCond( Fra_ObjSatNum(pObj2), 1 ); - // add contraint to solver + // add constraint to solver if ( !sat_solver_addclause( p->pSat, pLits, pLits + 2 ) ) { printf( "Fra_OneHotAddKnownConstraint(): Adding clause makes SAT solver unsat.\n" ); @@ -469,3 +472,5 @@ void Fra_OneHotAddKnownConstraint( Fra_Man_t * p, Vec_Ptr_t * vOnehots ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/fra/fraImp.c b/src/aig/fra/fraImp.c index 716e83d5..34fa87e5 100644 --- a/src/aig/fra/fraImp.c +++ b/src/aig/fra/fraImp.c @@ -20,6 +20,9 @@ #include "fra.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -211,12 +214,12 @@ Vec_Ptr_t * Fra_SmlSortUsingOnes( Fra_Sml_t * p, int fLatchCorr ) // skip nodes participating in the classes // if ( Fra_ClassObjRepr(pObj) ) // continue; - pMemory = Vec_PtrEntry( vNodes, pnBits[i] ); + pMemory = (int *)Vec_PtrEntry( vNodes, pnBits[i] ); pMemory[ pnNodes[pnBits[i]]++ ] = i; } // add 0s in the end nTotal = 0; - Vec_PtrForEachEntry( vNodes, pMemory, i ) + Vec_PtrForEachEntry( int *, vNodes, pMemory, i ) { pMemory[ pnNodes[i]++ ] = 0; nTotal += pnNodes[i]; @@ -335,8 +338,8 @@ Vec_Int_t * Fra_ImpDerive( Fra_Man_t * p, int nImpMaxLimit, int nImpUseLimit, in // count the total number of implications for ( k = nSimWords * 32; k > 0; k-- ) for ( i = k - 1; i > 0; i-- ) - for ( pNodesI = Vec_PtrEntry( vNodes, i ); *pNodesI; pNodesI++ ) - for ( pNodesK = Vec_PtrEntry( vNodes, k ); *pNodesK; pNodesK++ ) + for ( pNodesI = (int *)Vec_PtrEntry( vNodes, i ); *pNodesI; pNodesI++ ) + for ( pNodesK = (int *)Vec_PtrEntry( vNodes, k ); *pNodesK; pNodesK++ ) nImpsTotal++; // compute implications and their costs @@ -347,8 +350,8 @@ Vec_Int_t * Fra_ImpDerive( Fra_Man_t * p, int nImpMaxLimit, int nImpUseLimit, in { // HERE WE ARE MISSING SOME POTENTIAL IMPLICATIONS (with complement!) - for ( pNodesI = Vec_PtrEntry( vNodes, i ); *pNodesI; pNodesI++ ) - for ( pNodesK = Vec_PtrEntry( vNodes, k ); *pNodesK; pNodesK++ ) + for ( pNodesI = (int *)Vec_PtrEntry( vNodes, i ); *pNodesI; pNodesI++ ) + for ( pNodesK = (int *)Vec_PtrEntry( vNodes, k ); *pNodesK; pNodesK++ ) { nImpsTried++; if ( !Sml_NodeCheckImp(pSeq, *pNodesI, *pNodesK) ) @@ -444,7 +447,7 @@ void Fra_ImpAddToSolver( Fra_Man_t * p, Vec_Int_t * vImps, int * pSatVarNums ) Vec_IntWriteEntry( vImps, i, 0 ); break; } - } + } if ( f < p->pPars->nFramesK ) continue; // add constraints in each timeframe @@ -465,7 +468,7 @@ void Fra_ImpAddToSolver( Fra_Man_t * p, Vec_Int_t * vImps, int * pSatVarNums ) // L => R L' v R (complement = L & R') pLits[0] = 2 * Left + !fComplL; pLits[1] = 2 * Right + fComplR; - // add contraint to solver + // add constraint to solver if ( !sat_solver_addclause( pSat, pLits, pLits + 2 ) ) { sat_solver_delete( pSat ); @@ -712,8 +715,8 @@ void Fra_ImpRecordInManager( Fra_Man_t * p, Aig_Man_t * pNew ) pRight = Aig_ManObj( p->pManAig, Fra_ImpRight(Imp) ); // record the implication: L' + R pMiter = Aig_Or( pNew, - Aig_NotCond(pLeft->pData, !pLeft->fPhase), - Aig_NotCond(pRight->pData, pRight->fPhase) ); + Aig_NotCond((Aig_Obj_t *)pLeft->pData, !pLeft->fPhase), + Aig_NotCond((Aig_Obj_t *)pRight->pData, pRight->fPhase) ); Aig_ObjCreatePo( pNew, pMiter ); } pNew->nAsserts = Aig_ManPoNum(pNew) - nPosOld; @@ -724,3 +727,5 @@ void Fra_ImpRecordInManager( Fra_Man_t * p, Aig_Man_t * pNew ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/fra/fraInd.c b/src/aig/fra/fraInd.c index 84b739a4..2f2d8f2d 100644 --- a/src/aig/fra/fraInd.c +++ b/src/aig/fra/fraInd.c @@ -21,6 +21,10 @@ #include "fra.h" #include "cnf.h" #include "dar.h" +#include "saig.h" + +ABC_NAMESPACE_IMPL_START + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// @@ -265,7 +269,7 @@ Aig_Man_t * Fra_FraigInductionPart( Aig_Man_t * pAig, Fra_Ssw_t * pPars ) { // divide large clock domains into separate partitions vResult = Vec_PtrAlloc( 100 ); - Vec_PtrForEachEntry( (Vec_Ptr_t *)pAig->vClockDoms, vPart, i ) + Vec_PtrForEachEntry( Vec_Int_t *, (Vec_Ptr_t *)pAig->vClockDoms, vPart, i ) { if ( nPartSize && Vec_IntSize(vPart) > nPartSize ) Aig_ManPartDivide( vResult, vPart, nPartSize, pPars->nOverSize ); @@ -281,7 +285,7 @@ Aig_Man_t * Fra_FraigInductionPart( Aig_Man_t * pAig, Fra_Ssw_t * pPars ) { // print partitions printf( "Simple partitioning. %d partitions are saved:\n", Vec_PtrSize(vResult) ); - Vec_PtrForEachEntry( vResult, vPart, i ) + Vec_PtrForEachEntry( Vec_Int_t *, vResult, vPart, i ) { sprintf( Buffer, "part%03d.aig", i ); pTemp = Aig_ManRegCreatePart( pAig, vPart, &nCountPis, &nCountRegs, NULL ); @@ -294,7 +298,7 @@ Aig_Man_t * Fra_FraigInductionPart( Aig_Man_t * pAig, Fra_Ssw_t * pPars ) // perform SSW with partitions Aig_ManReprStart( pAig, Aig_ManObjNumMax(pAig) ); - Vec_PtrForEachEntry( vResult, vPart, i ) + Vec_PtrForEachEntry( Vec_Int_t *, vResult, vPart, i ) { pTemp = Aig_ManRegCreatePart( pAig, vPart, &nCountPis, &nCountRegs, &pMapBack ); // create the projection of 1-hot registers @@ -498,7 +502,7 @@ p->timeTrav += clock() - clk2; // Cnf_DataTranformPolarity( pCnf, 0 ); //Cnf_DataWriteIntoFile( pCnf, "temp.cnf", 1 ); - p->pSat = Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); + p->pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); p->nSatVars = pCnf->nVars; assert( p->pSat != NULL ); if ( p->pSat == NULL ) @@ -523,7 +527,7 @@ p->timeTrav += clock() - clk2; if ( pCnf->pVarNums[pObj->Id] == -1 ) continue; Fra_ObjSetSatNum( pObj, pCnf->pVarNums[pObj->Id] ); - Fra_ObjSetFaninVec( pObj, (void *)1 ); + Fra_ObjSetFaninVec( pObj, (Vec_Ptr_t *)1 ); } Cnf_DataFree( pCnf ); @@ -653,7 +657,6 @@ finish: ***********************************************************************/ int Fra_FraigInductionTest( char * pFileName, Fra_Ssw_t * pParams ) { - extern Aig_Man_t * Saig_ManReadBlif( char * pFileName ); FILE * pFile; char * pFilePairs; Aig_Man_t * pMan, * pNew; @@ -678,7 +681,7 @@ int Fra_FraigInductionTest( char * pFileName, Fra_Ssw_t * pParams ) Aig_ManPrintStats( pNew ); } Aig_ManStop( pNew ); - pNum2Id = pMan->pData; + pNum2Id = (int *)pMan->pData; // write the output file pFilePairs = Aig_FileNameGenericAppend( pFileName, ".pairs" ); pFile = fopen( pFilePairs, "w" ); @@ -702,3 +705,5 @@ int Fra_FraigInductionTest( char * pFileName, Fra_Ssw_t * pParams ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/fra/fraIndVer.c b/src/aig/fra/fraIndVer.c index 71faa346..32069cfb 100644 --- a/src/aig/fra/fraIndVer.c +++ b/src/aig/fra/fraIndVer.c @@ -21,6 +21,9 @@ #include "fra.h" #include "cnf.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -72,7 +75,7 @@ int Fra_InvariantVerify( Aig_Man_t * pAig, int nFrames, Vec_Int_t * vClauses, Ve } */ // derive initialized frames for the base case - pSat = Cnf_DataWriteIntoSolver( pCnf, nFrames, 1 ); + pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, nFrames, 1 ); // check clauses in the base case Beg = 0; pStart = Vec_IntArray( vLits ); @@ -93,7 +96,7 @@ int Fra_InvariantVerify( Aig_Man_t * pAig, int nFrames, Vec_Int_t * vClauses, Ve sat_solver_delete( pSat ); // derive initialized frames for the base case - pSat = Cnf_DataWriteIntoSolver( pCnf, nFrames + 1, 0 ); + pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, nFrames + 1, 0 ); assert( pSat->size == 2 * pCnf->nVars ); // add clauses to the first frame Beg = 0; @@ -159,3 +162,5 @@ int Fra_InvariantVerify( Aig_Man_t * pAig, int nFrames, Vec_Int_t * vClauses, Ve //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/fra/fraLcr.c b/src/aig/fra/fraLcr.c index 16912f46..b18a8fcd 100644 --- a/src/aig/fra/fraLcr.c +++ b/src/aig/fra/fraLcr.c @@ -20,6 +20,9 @@ #include "fra.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -197,7 +200,7 @@ void Fra_LcrAigPrepareTwo( Aig_Man_t * pAig, Fra_Man_t * p ) ***********************************************************************/ int Fra_LcrNodesAreEqual( Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 ) { - Fra_Man_t * pTemp = pObj0->pData; + Fra_Man_t * pTemp = (Fra_Man_t *)pObj0->pData; Fra_Lcr_t * pLcr = (Fra_Lcr_t *)pTemp->pBmc; Aig_Man_t * pFraig; Aig_Obj_t * pOut0, * pOut1; @@ -215,7 +218,7 @@ int Fra_LcrNodesAreEqual( Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 ) return 1; } assert( nPart0 == nPart1 ); - pFraig = Vec_PtrEntry( pLcr->vFraigs, nPart0 ); + pFraig = (Aig_Man_t *)Vec_PtrEntry( pLcr->vFraigs, nPart0 ); // get the fraig outputs pOut0 = Aig_ManPo( pFraig, pLcr->pInToOutNum[(long)pObj0->pNext] ); pOut1 = Aig_ManPo( pFraig, pLcr->pInToOutNum[(long)pObj1->pNext] ); @@ -235,7 +238,7 @@ int Fra_LcrNodesAreEqual( Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 ) ***********************************************************************/ int Fra_LcrNodeIsConst( Aig_Obj_t * pObj ) { - Fra_Man_t * pTemp = pObj->pData; + Fra_Man_t * pTemp = (Fra_Man_t *)pObj->pData; Fra_Lcr_t * pLcr = (Fra_Lcr_t *)pTemp->pBmc; Aig_Man_t * pFraig; Aig_Obj_t * pOut; @@ -243,7 +246,7 @@ int Fra_LcrNodeIsConst( Aig_Obj_t * pObj ) assert( Aig_ObjIsPi(pObj) ); // find the partition to which these nodes belong nPart = pLcr->pInToOutPart[(long)pObj->pNext]; - pFraig = Vec_PtrEntry( pLcr->vFraigs, nPart ); + pFraig = (Aig_Man_t *)Vec_PtrEntry( pLcr->vFraigs, nPart ); // get the fraig outputs pOut = Aig_ManPo( pFraig, pLcr->pInToOutNum[(long)pObj->pNext] ); return Aig_ObjFanin0(pOut) == Aig_ManConst1(pFraig); @@ -264,14 +267,14 @@ Aig_Obj_t * Fra_LcrManDup_rec( Aig_Man_t * pNew, Aig_Man_t * p, Aig_Obj_t * pObj { Aig_Obj_t * pObjNew; if ( pObj->pData ) - return pObj->pData; + return (Aig_Obj_t *)pObj->pData; Fra_LcrManDup_rec( pNew, p, Aig_ObjFanin0(pObj) ); if ( Aig_ObjIsBuf(pObj) ) - return pObj->pData = Aig_ObjChild0Copy(pObj); + return (Aig_Obj_t *)(pObj->pData = Aig_ObjChild0Copy(pObj)); Fra_LcrManDup_rec( pNew, p, Aig_ObjFanin1(pObj) ); pObjNew = Aig_Oper( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj), Aig_ObjType(pObj) ); Aig_Regular(pObjNew)->pHaig = pObj->pHaig; - return pObj->pData = pObjNew; + return (Aig_Obj_t *)(pObj->pData = pObjNew); } /**Function************************************************************* @@ -308,7 +311,7 @@ Aig_Man_t * Fra_LcrDeriveAigForPartitioning( Fra_Lcr_t * pLcr ) Aig_ManCleanData( pLcr->pAig ); pNew = Aig_ManStartFrom( pLcr->pAig ); // go over the equivalence classes - Vec_PtrForEachEntry( pLcr->pCla->vClasses, ppClass, i ) + Vec_PtrForEachEntry( Aig_Obj_t **, pLcr->pCla->vClasses, ppClass, i ) { pMiter = Aig_ManConst0(pNew); for ( c = 0; ppClass[c]; c++ ) @@ -321,7 +324,7 @@ Aig_Man_t * Fra_LcrDeriveAigForPartitioning( Fra_Lcr_t * pLcr ) Aig_ObjCreatePo( pNew, pMiter ); } // go over the constant candidates - Vec_PtrForEachEntry( pLcr->pCla->vClasses1, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, pLcr->pCla->vClasses1, pObj, i ) { assert( Aig_ObjIsPi(pObj) ); pObjPo = Aig_ManPo( pLcr->pAig, Offset+(long)pObj->pNext ); @@ -349,14 +352,14 @@ void Fra_LcrRemapPartitions( Vec_Ptr_t * vParts, Fra_Cla_t * pCla, int * pInToOu int Out, Offset, i, k, c; // compute the LO/LI offset Offset = Aig_ManPoNum(pCla->pAig) - Aig_ManPiNum(pCla->pAig); - Vec_PtrForEachEntry( vParts, vOne, i ) + Vec_PtrForEachEntry( Vec_Int_t *, vParts, vOne, i ) { vOneNew = Vec_IntAlloc( Vec_IntSize(vOne) ); Vec_IntForEachEntry( vOne, Out, k ) { if ( Out < Vec_PtrSize(pCla->vClasses) ) { - ppClass = Vec_PtrEntry( pCla->vClasses, Out ); + ppClass = (Aig_Obj_t **)Vec_PtrEntry( pCla->vClasses, Out ); for ( c = 0; ppClass[c]; c++ ) { pInToOutPart[(long)ppClass[c]->pNext] = i; @@ -366,7 +369,7 @@ void Fra_LcrRemapPartitions( Vec_Ptr_t * vParts, Fra_Cla_t * pCla, int * pInToOu } else { - pObjPi = Vec_PtrEntry( pCla->vClasses1, Out - Vec_PtrSize(pCla->vClasses) ); + pObjPi = (Aig_Obj_t *)Vec_PtrEntry( pCla->vClasses1, Out - Vec_PtrSize(pCla->vClasses) ); pInToOutPart[(long)pObjPi->pNext] = i; pInToOutNum[(long)pObjPi->pNext] = Vec_IntSize(vOneNew); Vec_IntPush( vOneNew, Offset+(long)pObjPi->pNext ); @@ -393,7 +396,7 @@ Aig_Obj_t * Fra_LcrCreatePart_rec( Fra_Cla_t * pCla, Aig_Man_t * pNew, Aig_Man_t { assert( !Aig_IsComplement(pObj) ); if ( Aig_ObjIsTravIdCurrent(p, pObj) ) - return pObj->pData; + return (Aig_Obj_t *)pObj->pData; Aig_ObjSetTravIdCurrent(p, pObj); if ( Aig_ObjIsPi(pObj) ) { @@ -404,13 +407,13 @@ Aig_Obj_t * Fra_LcrCreatePart_rec( Fra_Cla_t * pCla, Aig_Man_t * pNew, Aig_Man_t else { pObj->pData = Fra_LcrCreatePart_rec( pCla, pNew, p, pRepr ); - pObj->pData = Aig_NotCond( pObj->pData, pRepr->fPhase ^ pObj->fPhase ); + pObj->pData = Aig_NotCond( (Aig_Obj_t *)pObj->pData, pRepr->fPhase ^ pObj->fPhase ); } - return pObj->pData; + return (Aig_Obj_t *)pObj->pData; } Fra_LcrCreatePart_rec( pCla, pNew, p, Aig_ObjFanin0(pObj) ); Fra_LcrCreatePart_rec( pCla, pNew, p, Aig_ObjFanin1(pObj) ); - return pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + return (Aig_Obj_t *)(pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) )); } /**Function************************************************************* @@ -467,12 +470,12 @@ void Fra_ClassNodesMark( Fra_Lcr_t * p ) // compute the LO/LI offset Offset = Aig_ManPoNum(p->pCla->pAig) - Aig_ManPiNum(p->pCla->pAig); // mark the nodes remaining in the classes - Vec_PtrForEachEntry( p->pCla->vClasses1, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->pCla->vClasses1, pObj, i ) { pObj = Aig_ManPo( p->pCla->pAig, Offset+(long)pObj->pNext ); pObj->fMarkA = 1; } - Vec_PtrForEachEntry( p->pCla->vClasses, ppClass, i ) + Vec_PtrForEachEntry( Aig_Obj_t **, p->pCla->vClasses, ppClass, i ) { for ( c = 0; ppClass[c]; c++ ) { @@ -500,12 +503,12 @@ void Fra_ClassNodesUnmark( Fra_Lcr_t * p ) // compute the LO/LI offset Offset = Aig_ManPoNum(p->pCla->pAig) - Aig_ManPiNum(p->pCla->pAig); // mark the nodes remaining in the classes - Vec_PtrForEachEntry( p->pCla->vClasses1, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->pCla->vClasses1, pObj, i ) { pObj = Aig_ManPo( p->pCla->pAig, Offset+(long)pObj->pNext ); pObj->fMarkA = 0; } - Vec_PtrForEachEntry( p->pCla->vClasses, ppClass, i ) + Vec_PtrForEachEntry( Aig_Obj_t **, p->pCla->vClasses, ppClass, i ) { for ( c = 0; ppClass[c]; c++ ) { @@ -610,12 +613,12 @@ p->timePart += clock() - clk2; // derive AIGs for each partition Fra_ClassNodesMark( p ); Vec_PtrClear( p->vFraigs ); - Vec_PtrForEachEntry( p->vParts, vPart, i ) + Vec_PtrForEachEntry( Vec_Int_t *, p->vParts, vPart, i ) { int clk3 = clock(); if ( TimeLimit != 0.0 && clock() > TimeToStop ) { - Vec_PtrForEachEntry( p->vFraigs, pAigPart, i ) + Vec_PtrForEachEntry( Aig_Man_t *, p->vFraigs, pAigPart, i ) Aig_ManStop( pAigPart ); Aig_ManCleanMarkA( pAig ); Aig_ManCleanMarkB( pAig ); @@ -657,7 +660,7 @@ ABC_PRT( "Time", clock() - clk3 ); if ( Fra_ClassesRefine1( p->pCla, 0, NULL ) ) p->fRefining = 1; // clean the fraigs - Vec_PtrForEachEntry( p->vFraigs, pAigPart, i ) + Vec_PtrForEachEntry( Aig_Man_t *, p->vFraigs, pAigPart, i ) Aig_ManStop( pAigPart ); // repartition if needed @@ -702,3 +705,5 @@ finish: //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/fra/fraMan.c b/src/aig/fra/fraMan.c index 8bdd147d..7e427e72 100644 --- a/src/aig/fra/fraMan.c +++ b/src/aig/fra/fraMan.c @@ -20,6 +20,9 @@ #include "fra.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -307,3 +310,5 @@ void Fra_ManPrint( Fra_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/fra/fraPart.c b/src/aig/fra/fraPart.c index 6dfbd2e9..9556bb51 100644 --- a/src/aig/fra/fraPart.c +++ b/src/aig/fra/fraPart.c @@ -20,6 +20,9 @@ #include "fra.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -63,7 +66,7 @@ ABC_PRT( "Supports", clock() - clk ); // remove last entry Aig_ManForEachPo( p, pObj, i ) { - vSup = Vec_VecEntry( vSupps, i ); + vSup = (Vec_Int_t *)Vec_VecEntry( vSupps, i ); Vec_IntPop( vSup ); // remember support // pObj->pNext = (Aig_Obj_t *)vSup; @@ -74,7 +77,7 @@ clk = clock(); vSuppsIn = Vec_VecStart( Aig_ManPiNum(p) ); Aig_ManForEachPo( p, pObj, i ) { - vSup = Vec_VecEntry( vSupps, i ); + vSup = (Vec_Int_t *)Vec_VecEntry( vSupps, i ); Vec_IntForEachEntry( vSup, Entry, k ) Vec_VecPush( vSuppsIn, Entry, (void *)(ABC_PTRUINT_T)i ); } @@ -91,7 +94,7 @@ clk = clock(); { // Bar_ProgressUpdate( pProgress, i, NULL ); // get old supports - vSup = Vec_VecEntry( vSupps, i ); + vSup = (Vec_Int_t *)Vec_VecEntry( vSupps, i ); if ( Vec_IntSize(vSup) < 2 ) continue; // compute new supports @@ -106,7 +109,7 @@ clk = clock(); // pObj = Aig_ManObj( p, Entry ); // get support of this output // vSup2 = (Vec_Int_t *)pObj->pNext; - vSup2 = Vec_VecEntry( vSupps, k ); + vSup2 = (Vec_Int_t *)Vec_VecEntry( vSupps, k ); // count the number of common vars nCommon = Vec_IntTwoCountCommon(vSup, vSup2); if ( nCommon < 2 ) @@ -197,7 +200,7 @@ ABC_PRT( "Supports", clock() - clk ); // remove last entry Aig_ManForEachPo( p, pObj, i ) { - vSup = Vec_VecEntry( vSupps, i ); + vSup = (Vec_Int_t *)Vec_VecEntry( vSupps, i ); Vec_IntPop( vSup ); // remember support // pObj->pNext = (Aig_Obj_t *)vSup; @@ -210,7 +213,7 @@ clk = clock(); { if ( i == p->nAsserts ) break; - vSup = Vec_VecEntry( vSupps, i ); + vSup = (Vec_Int_t *)Vec_VecEntry( vSupps, i ); Vec_IntForEachEntry( vSup, Entry, k ) Vec_VecPush( vSuppsIn, Entry, (void *)(ABC_PTRUINT_T)i ); } @@ -223,17 +226,17 @@ clk = clock(); { if ( i % 50 != 0 ) continue; - vSup = Vec_VecEntry( vSupps, i ); + vSup = (Vec_Int_t *)Vec_VecEntry( vSupps, i ); memset( pSupp, 0, sizeof(char) * Aig_ManPiNum(p) ); // go through each input of this output Vec_IntForEachEntry( vSup, Entry, k ) { pSupp[Entry] = 1; - vSup2 = Vec_VecEntry( vSuppsIn, Entry ); + vSup2 = (Vec_Int_t *)Vec_VecEntry( vSuppsIn, Entry ); // go though each assert of this input Vec_IntForEachEntry( vSup2, Entry2, m ) { - vSup3 = Vec_VecEntry( vSupps, Entry2 ); + vSup3 = (Vec_Int_t *)Vec_VecEntry( vSupps, Entry2 ); // go through each input of this assert Vec_IntForEachEntry( vSup3, Entry3, n ) { @@ -261,3 +264,5 @@ ABC_PRT( "Extension ", clock() - clk ); //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/fra/fraSat.c b/src/aig/fra/fraSat.c index 039a660f..50503670 100644 --- a/src/aig/fra/fraSat.c +++ b/src/aig/fra/fraSat.c @@ -21,6 +21,9 @@ #include <math.h> #include "fra.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -512,7 +515,7 @@ int Fra_SetActivityFactors_rec( Fra_Man_t * p, Aig_Obj_t * pObj, int LevelMin, i veci_push(&p->pSat->act_vars, Fra_ObjSatNum(pObj)); // explore the fanins vFanins = Fra_ObjFaninVec( pObj ); - Vec_PtrForEachEntry( vFanins, pFanin, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vFanins, pFanin, i ) Counter += Fra_SetActivityFactors_rec( p, Aig_Regular(pFanin), LevelMin, LevelMax ); return 1 + Counter; } @@ -557,3 +560,5 @@ p->timeTrav += clock() - clk; //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/fra/fraSec.c b/src/aig/fra/fraSec.c index ccb3e7b1..1576a70a 100644 --- a/src/aig/fra/fraSec.c +++ b/src/aig/fra/fraSec.c @@ -23,6 +23,10 @@ #include "int.h" #include "ssw.h" #include "saig.h" +#include "bbr.h" + +ABC_NAMESPACE_IMPL_START + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// @@ -63,7 +67,7 @@ void Fra_SecSetDefaultParams( Fra_Sec_t * p ) p->fInterpolation = 1; // enables interpolation p->fInterSeparate = 0; // enables interpolation for each outputs separately p->fReachability = 1; // enables BDD based reachability - p->fReorderImage = 0; // enables variable reordering during image computation + p->fReorderImage = 1; // enables variable reordering during image computation p->fStopOnFirstFail = 1; // enables stopping after first output of a miter has failed to prove p->fUseNewProver = 0; // enables new prover p->fSilent = 0; // disables all output @@ -292,7 +296,7 @@ ABC_PRT( "Time", clock() - clk ); // perform min-area retiming if ( pParSec->fRetimeRegs && pNew->nRegs ) { - extern Aig_Man_t * Saig_ManRetimeMinArea( Aig_Man_t * p, int nMaxIters, int fForwardOnly, int fBackwardOnly, int fInitial, int fVerbose ); +// extern Aig_Man_t * Saig_ManRetimeMinArea( Aig_Man_t * p, int nMaxIters, int fForwardOnly, int fBackwardOnly, int fInitial, int fVerbose ); clk = clock(); pNew->nTruePis = Aig_ManPiNum(pNew) - Aig_ManRegNum(pNew); pNew->nTruePos = Aig_ManPoNum(pNew) - Aig_ManRegNum(pNew); @@ -353,9 +357,9 @@ clk = clock(); Aig_ManSetRegNum( pNew, pNew->nRegs ); // pNew = Ssw_SignalCorrespondence( pTemp = pNew, pPars2 ); if ( Aig_ManRegNum(pNew) > 0 ) - pNew = Ssw_SignalCorrespondence( pTemp = pNew, pPars2 ); + pNew = Ssw_SignalCorrespondence( pTemp = pNew, pPars2 ); else - pNew = Aig_ManDupSimpleDfs( pTemp = pNew ); + pNew = Aig_ManDupSimpleDfs( pTemp = pNew ); if ( pNew == NULL ) { @@ -382,7 +386,7 @@ ABC_PRT( "Time", clock() - clk ); // if ( pParSec->fRetimeFirst && pNew->nRegs ) if ( pNew->nRegs ) { - extern Aig_Man_t * Saig_ManRetimeMinArea( Aig_Man_t * p, int nMaxIters, int fForwardOnly, int fBackwardOnly, int fInitial, int fVerbose ); +// extern Aig_Man_t * Saig_ManRetimeMinArea( Aig_Man_t * p, int nMaxIters, int fForwardOnly, int fBackwardOnly, int fInitial, int fVerbose ); clk = clock(); pNew->nTruePis = Aig_ManPiNum(pNew) - Aig_ManRegNum(pNew); pNew->nTruePos = Aig_ManPoNum(pNew) - Aig_ManRegNum(pNew); @@ -480,7 +484,7 @@ clk = clock(); } else if ( pParSec->fInterSeparate ) { - Ssw_Cex_t * pCex = NULL; + Abc_Cex_t * pCex = NULL; Aig_Man_t * pTemp, * pAux; Aig_Obj_t * pObjPo; int i, Counter = 0; @@ -488,6 +492,8 @@ clk = clock(); { if ( Aig_ObjFanin0(pObjPo) == Aig_ManConst1(pNew) ) continue; + if ( pPars->fVerbose ) + printf( "Solving output %2d (out of %2d):\n", i, Saig_ManPoNum(pNew) ); pTemp = Aig_ManDupOneOutput( pNew, i, 1 ); pTemp = Aig_ManScl( pAux = pTemp, 1, 1, 0 ); Aig_ManStop( pAux ); @@ -537,7 +543,7 @@ clk = clock(); RetValue = Inter_ManPerformInterpolation( pNewOrpos, pPars, &Depth ); if ( pNewOrpos->pSeqModel ) { - Ssw_Cex_t * pCex; + Abc_Cex_t * pCex; pCex = pNew->pSeqModel = pNewOrpos->pSeqModel; pNewOrpos->pSeqModel = NULL; pCex->iPo = Ssw_SmlFindOutputCounterExample( pNew, pNew->pSeqModel ); } @@ -561,10 +567,19 @@ ABC_PRT( "Time", clock() - clk ); // try reachability analysis if ( pParSec->fReachability && RetValue == -1 && Aig_ManRegNum(pNew) > 0 && Aig_ManRegNum(pNew) < pParSec->nBddVarsMax ) { - extern int Aig_ManVerifyUsingBdds( Aig_Man_t * p, int nBddMax, int nIterMax, int fPartition, int fReorder, int fReorderImage, int fVerbose, int fSilent ); + Saig_ParBbr_t Pars, * pPars = &Pars; + Bbr_ManSetDefaultParams( pPars ); + pPars->TimeLimit = 0; + pPars->nBddMax = pParSec->nBddMax; + pPars->nIterMax = pParSec->nBddIterMax; + pPars->fPartition = 1; + pPars->fReorder = 1; + pPars->fReorderImage = 1; + pPars->fVerbose = 0; + pPars->fSilent = pParSec->fSilent; pNew->nTruePis = Aig_ManPiNum(pNew) - Aig_ManRegNum(pNew); pNew->nTruePos = Aig_ManPoNum(pNew) - Aig_ManRegNum(pNew); - RetValue = Aig_ManVerifyUsingBdds( pNew, pParSec->nBddMax, pParSec->nBddIterMax, 1, 1, pParSec->fReorderImage, 0, pParSec->fSilent ); + RetValue = Aig_ManVerifyUsingBdds( pNew, pPars ); } finish: @@ -645,3 +660,5 @@ ABC_PRT( "Time", clock() - clkTotal ); //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/fra/fraSim.c b/src/aig/fra/fraSim.c index 4f164e5c..25c30989 100644 --- a/src/aig/fra/fraSim.c +++ b/src/aig/fra/fraSim.c @@ -20,6 +20,9 @@ #include "fra.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -41,7 +44,7 @@ ***********************************************************************/ int Fra_SmlNodeHash( Aig_Obj_t * pObj, int nTableSize ) { - Fra_Man_t * p = pObj->pData; + Fra_Man_t * p = (Fra_Man_t *)pObj->pData; static int s_FPrimes[128] = { 1009, 1049, 1093, 1151, 1201, 1249, 1297, 1361, 1427, 1459, 1499, 1559, 1607, 1657, 1709, 1759, 1823, 1877, 1933, 1997, @@ -81,7 +84,7 @@ int Fra_SmlNodeHash( Aig_Obj_t * pObj, int nTableSize ) ***********************************************************************/ int Fra_SmlNodeIsConst( Aig_Obj_t * pObj ) { - Fra_Man_t * p = pObj->pData; + Fra_Man_t * p = (Fra_Man_t *)pObj->pData; unsigned * pSims; int i; pSims = Fra_ObjSim(p->pSml, pObj->Id); @@ -104,7 +107,7 @@ int Fra_SmlNodeIsConst( Aig_Obj_t * pObj ) ***********************************************************************/ int Fra_SmlNodesAreEqual( Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 ) { - Fra_Man_t * p = pObj0->pData; + Fra_Man_t * p = (Fra_Man_t *)pObj0->pData; unsigned * pSims0, * pSims1; int i; pSims0 = Fra_ObjSim(p->pSml, pObj0->Id); @@ -885,12 +888,12 @@ Fra_Sml_t * Fra_SmlSimulateSeq( Aig_Man_t * pAig, int nPref, int nFrames, int nW SeeAlso [] ***********************************************************************/ -Fra_Cex_t * Fra_SmlAllocCounterExample( int nRegs, int nRealPis, int nFrames ) +Abc_Cex_t * Fra_SmlAllocCounterExample( int nRegs, int nRealPis, int nFrames ) { - Fra_Cex_t * pCex; + Abc_Cex_t * pCex; int nWords = Aig_BitWordNum( nRegs + nRealPis * nFrames ); - pCex = (Fra_Cex_t *)ABC_ALLOC( char, sizeof(Fra_Cex_t) + sizeof(unsigned) * nWords ); - memset( pCex, 0, sizeof(Fra_Cex_t) + sizeof(unsigned) * nWords ); + pCex = (Abc_Cex_t *)ABC_ALLOC( char, sizeof(Abc_Cex_t) + sizeof(unsigned) * nWords ); + memset( pCex, 0, sizeof(Abc_Cex_t) + sizeof(unsigned) * nWords ); pCex->nRegs = nRegs; pCex->nPis = nRealPis; pCex->nBits = nRegs + nRealPis * nFrames; @@ -908,7 +911,7 @@ Fra_Cex_t * Fra_SmlAllocCounterExample( int nRegs, int nRealPis, int nFrames ) SeeAlso [] ***********************************************************************/ -void Fra_SmlFreeCounterExample( Fra_Cex_t * pCex ) +void Fra_SmlFreeCounterExample( Abc_Cex_t * pCex ) { ABC_FREE( pCex ); } @@ -924,9 +927,9 @@ void Fra_SmlFreeCounterExample( Fra_Cex_t * pCex ) SeeAlso [] ***********************************************************************/ -Fra_Cex_t * Fra_SmlGetCounterExample( Fra_Sml_t * p ) +Abc_Cex_t * Fra_SmlGetCounterExample( Fra_Sml_t * p ) { - Fra_Cex_t * pCex; + Abc_Cex_t * pCex; Aig_Obj_t * pObj; unsigned * pSims; int iPo, iFrame, iBit, i, k; @@ -998,9 +1001,9 @@ Fra_Cex_t * Fra_SmlGetCounterExample( Fra_Sml_t * p ) SeeAlso [] ***********************************************************************/ -Fra_Cex_t * Fra_SmlCopyCounterExample( Aig_Man_t * pAig, Aig_Man_t * pFrames, int * pModel ) +Abc_Cex_t * Fra_SmlCopyCounterExample( Aig_Man_t * pAig, Aig_Man_t * pFrames, int * pModel ) { - Fra_Cex_t * pCex; + Abc_Cex_t * pCex; Aig_Obj_t * pObj; int i, nFrames, nTruePis, nTruePos, iPo, iFrame; // get the number of frames @@ -1058,9 +1061,9 @@ Fra_Cex_t * Fra_SmlCopyCounterExample( Aig_Man_t * pAig, Aig_Man_t * pFrames, in SeeAlso [] ***********************************************************************/ -Fra_Cex_t * Fra_SmlTrivCounterExample( Aig_Man_t * pAig, int iFrameOut ) +Abc_Cex_t * Fra_SmlTrivCounterExample( Aig_Man_t * pAig, int iFrameOut ) { - Fra_Cex_t * pCex; + Abc_Cex_t * pCex; int nTruePis, nTruePos, iPo, iFrame; assert( Aig_ManRegNum(pAig) > 0 ); nTruePis = Aig_ManPiNum(pAig)-Aig_ManRegNum(pAig); @@ -1085,7 +1088,7 @@ Fra_Cex_t * Fra_SmlTrivCounterExample( Aig_Man_t * pAig, int iFrameOut ) SeeAlso [] ***********************************************************************/ -int Fra_SmlRunCounterExample( Aig_Man_t * pAig, Fra_Cex_t * p ) +int Fra_SmlRunCounterExample( Aig_Man_t * pAig, Abc_Cex_t * p ) { Fra_Sml_t * pSml; Aig_Obj_t * pObj; @@ -1113,6 +1116,38 @@ int Fra_SmlRunCounterExample( Aig_Man_t * pAig, Fra_Cex_t * p ) /**Function************************************************************* + Synopsis [Make the trivial counter-example for the trivially asserted output.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Cex_t * Fra_SmlSimpleCounterExample( Aig_Man_t * pAig, int * pModel, int iFrame, int iPo ) +{ + Abc_Cex_t * pCex; + int iBit; + pCex = Fra_SmlAllocCounterExample( Aig_ManRegNum(pAig), Aig_ManPiNum(pAig)-Aig_ManRegNum(pAig), iFrame + 1 ); + pCex->iPo = iPo; + pCex->iFrame = iFrame; + for ( iBit = Aig_ManRegNum(pAig); iBit < pCex->nBits; iBit++ ) + if ( pModel[iBit-Aig_ManRegNum(pAig)] ) + Aig_InfoSetBit( pCex->pData, iBit ); +/* + if ( !Fra_SmlRunCounterExample( pAig, pCex ) ) + { + printf( "Fra_SmlSimpleCounterExample(): Counter-example is invalid.\n" ); +// Fra_SmlFreeCounterExample( pCex ); +// pCex = NULL; + } +*/ + return pCex; +} + +/**Function************************************************************* + Synopsis [Resimulates the counter-example.] Description [] @@ -1122,7 +1157,7 @@ int Fra_SmlRunCounterExample( Aig_Man_t * pAig, Fra_Cex_t * p ) SeeAlso [] ***********************************************************************/ -int Fra_SmlWriteCounterExample( FILE * pFile, Aig_Man_t * pAig, Fra_Cex_t * p ) +int Fra_SmlWriteCounterExample( FILE * pFile, Aig_Man_t * pAig, Abc_Cex_t * p ) { Fra_Sml_t * pSml; Aig_Obj_t * pObj; @@ -1191,3 +1226,5 @@ int Fra_SmlWriteCounterExample( FILE * pFile, Aig_Man_t * pAig, Fra_Cex_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/fra/fra_.c b/src/aig/fra/fra_.c index 2b601587..8e5785ec 100644 --- a/src/aig/fra/fra_.c +++ b/src/aig/fra/fra_.c @@ -20,6 +20,9 @@ #include "fra.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -46,3 +49,5 @@ //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/fsim/fsim.h b/src/aig/fsim/fsim.h index 4e1588a7..fabc5254 100644 --- a/src/aig/fsim/fsim.h +++ b/src/aig/fsim/fsim.h @@ -21,6 +21,7 @@ #ifndef __FSIM_H__ #define __FSIM_H__ + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -29,9 +30,10 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -85,9 +87,11 @@ extern Vec_Int_t * Fsim_ManSwitchSimulate( Aig_Man_t * pAig, Fsim_ParSwitch_t /*=== fsimTsim.c ==========================================================*/ extern Vec_Ptr_t * Fsim_ManTerSimulate( Aig_Man_t * pAig, int fVerbose ); -#ifdef __cplusplus -} -#endif + + +ABC_NAMESPACE_HEADER_END + + #endif diff --git a/src/aig/fsim/fsimCore.c b/src/aig/fsim/fsimCore.c index 2a159cbe..9516f09e 100644 --- a/src/aig/fsim/fsimCore.c +++ b/src/aig/fsim/fsimCore.c @@ -20,6 +20,9 @@ #include "fsimInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -81,3 +84,5 @@ void Fsim_ManSetDefaultParamsSwitch( Fsim_ParSwitch_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/fsim/fsimFront.c b/src/aig/fsim/fsimFront.c index 14906c0b..6169543c 100644 --- a/src/aig/fsim/fsimFront.c +++ b/src/aig/fsim/fsimFront.c @@ -20,6 +20,9 @@ #include "fsimInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -362,3 +365,5 @@ void Fsim_ManFront( Fsim_Man_t * p, int fCompressAig ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/fsim/fsimInt.h b/src/aig/fsim/fsimInt.h index f46a9024..f5dee298 100644 --- a/src/aig/fsim/fsimInt.h +++ b/src/aig/fsim/fsimInt.h @@ -21,6 +21,7 @@ #ifndef __FSIM_INT_H__ #define __FSIM_INT_H__ + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -32,9 +33,10 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -122,9 +124,11 @@ extern Fsim_Man_t * Fsim_ManCreate( Aig_Man_t * pAig ); extern void Fsim_ManDelete( Fsim_Man_t * p ); extern void Fsim_ManTest( Aig_Man_t * pAig ); -#ifdef __cplusplus -} -#endif + + +ABC_NAMESPACE_HEADER_END + + #endif diff --git a/src/aig/fsim/fsimMan.c b/src/aig/fsim/fsimMan.c index 872e1604..ea0cab43 100644 --- a/src/aig/fsim/fsimMan.c +++ b/src/aig/fsim/fsimMan.c @@ -20,6 +20,9 @@ #include "fsimInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -205,3 +208,5 @@ void Fsim_ManTest( Aig_Man_t * pAig ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/fsim/fsimSim.c b/src/aig/fsim/fsimSim.c index 52dedc6d..2da7db15 100644 --- a/src/aig/fsim/fsimSim.c +++ b/src/aig/fsim/fsimSim.c @@ -21,6 +21,9 @@ #include "fsimInt.h" #include "ssw.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -426,9 +429,9 @@ static inline int Fsim_ManCheckPos( Fsim_Man_t * p, int * piPo, int * piPat ) SeeAlso [] ***********************************************************************/ -Ssw_Cex_t * Fsim_ManGenerateCounter( Aig_Man_t * pAig, int iFrame, int iOut, int nWords, int iPat, Vec_Int_t * vCis2Ids ) +Abc_Cex_t * Fsim_ManGenerateCounter( Aig_Man_t * pAig, int iFrame, int iOut, int nWords, int iPat, Vec_Int_t * vCis2Ids ) { - Ssw_Cex_t * p; + Abc_Cex_t * p; unsigned * pData; int f, i, w, iPioId, Counter; p = Ssw_SmlAllocCounterExample( Aig_ManRegNum(pAig), Saig_ManPiNum(pAig), iFrame+1 ); @@ -514,7 +517,7 @@ int Fsim_ManSimulate( Aig_Man_t * pAig, Fsim_ParSim_t * pPars ) p->pDataSimCos = ABC_ALLOC( unsigned, p->nWords * p->nCos ); Fsim_ManSimInfoInit( p ); for ( i = 0; i < pPars->nIters; i++ ) - { + { Fsim_ManSimulateRound( p ); if ( pPars->fVerbose ) { @@ -530,15 +533,14 @@ int Fsim_ManSimulate( Aig_Man_t * pAig, Fsim_ParSim_t * pPars ) break; } if ( (clock() - clkTotal)/CLOCKS_PER_SEC >= pPars->TimeLimit ) - { - printf( "No bug detected after %d frames with time limit %d seconds.\n", i+1, pPars->TimeLimit ); break; - } clk2 = clock(); if ( i < pPars->nIters - 1 ) Fsim_ManSimInfoTransfer( p ); clk2Total += clock() - clk2; } + if ( pAig->pSeqModel == NULL ) + printf( "No bug detected after %d frames with time limit %d seconds.\n", i+1, pPars->TimeLimit ); if ( pPars->fVerbose ) { printf( "Maxcut = %8d. AigMem = %7.2f Mb. SimMem = %7.2f Mb. ", @@ -561,3 +563,5 @@ int Fsim_ManSimulate( Aig_Man_t * pAig, Fsim_ParSim_t * pPars ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/fsim/fsimSwitch.c b/src/aig/fsim/fsimSwitch.c index 97cb612f..3eef2d4c 100644 --- a/src/aig/fsim/fsimSwitch.c +++ b/src/aig/fsim/fsimSwitch.c @@ -20,6 +20,9 @@ #include "fsimInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -33,3 +36,5 @@ //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/fsim/fsimTsim.c b/src/aig/fsim/fsimTsim.c index 0de283e4..e05e6409 100644 --- a/src/aig/fsim/fsimTsim.c +++ b/src/aig/fsim/fsimTsim.c @@ -20,6 +20,9 @@ #include "fsimInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -408,3 +411,5 @@ Vec_Ptr_t * Fsim_ManTerSimulate( Aig_Man_t * pAig, int fVerbose ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/gia.c b/src/aig/gia/gia.c index 4cbb1731..4fb33a9b 100644 --- a/src/aig/gia/gia.c +++ b/src/aig/gia/gia.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -45,3 +48,5 @@ //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index f023366a..3358ca76 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -21,6 +21,7 @@ #ifndef __GIA_H__ #define __GIA_H__ + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -37,9 +38,10 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + #define GIA_NONE 0x1FFFFFFF #define GIA_VOID 0x0FFFFFFF @@ -48,6 +50,10 @@ extern "C" { /// BASIC TYPES /// //////////////////////////////////////////////////////////////////////// +typedef struct Gia_MmFixed_t_ Gia_MmFixed_t; +typedef struct Gia_MmFlex_t_ Gia_MmFlex_t; +typedef struct Gia_MmStep_t_ Gia_MmStep_t; + typedef struct Gia_Rpr_t_ Gia_Rpr_t; struct Gia_Rpr_t_ { @@ -88,18 +94,6 @@ struct Gia_Obj_t_ // - traversal ID of the node during traversal // - reference counter of the node (will not be used in the future) -// sequential counter-example -typedef struct Gia_Cex_t_ Gia_Cex_t; -struct Gia_Cex_t_ -{ - int iPo; // the zero-based number of PO, for which verification failed - int iFrame; // the zero-based number of the time-frame, for which verificaiton failed - int nRegs; // the number of registers in the miter - int nPis; // the number of primary inputs in the miter - int nBits; // the number of words of bit data used - unsigned pData[0]; // the cex bit data (the number of bits: nRegs + (iFrame+1) * nPis) -}; - // new AIG manager typedef struct Gia_Man_t_ Gia_Man_t; struct Gia_Man_t_ @@ -116,8 +110,10 @@ struct Gia_Man_t_ int nHTable; // hash table size int fAddStrash; // performs additional structural hashing int * pRefs; // the reference count - int * pLevels; // levels of the nodes + int * pNodeRefs; // node references + Vec_Int_t * vLevels; // levels of the nodes int nLevels; // the mamixum level + int nConstrs; // the number of constraints int nTravIds; // the current traversal ID int nFront; // frontier size int * pReprsOld; // representatives (for CIs and ANDs) @@ -129,9 +125,11 @@ struct Gia_Man_t_ int * pFanData; // the database to store fanout information int nFansAlloc; // the size of fanout representation int * pMapping; // mapping for each node - Gia_Cex_t * pCexComb; // combinational counter-example - Gia_Cex_t * pCexSeq; // sequential counter-example + Vec_Int_t * vLutConfigs; // LUT configurations + Abc_Cex_t * pCexComb; // combinational counter-example + Abc_Cex_t * pCexSeq; // sequential counter-example int * pCopies; // intermediate copies + Vec_Int_t * vTruths; // used for truth table computation Vec_Int_t * vFlopClasses; // classes of flops for retiming/merging/etc unsigned char* pSwitching; // switching activity for each object Gia_Plc_t * pPlacement; // placement of the objects @@ -139,6 +137,12 @@ struct Gia_Man_t_ int nTravIdsAlloc; // the number of trav IDs allocated Vec_Ptr_t * vNamesIn; // the input names Vec_Ptr_t * vNamesOut; // the output names + Vec_Int_t * vCiNumsOrig; // original names of the CIs + Vec_Int_t * vCoNumsOrig; // original names of the COs + Vec_Vec_t * vClockDoms; // clock domains + Vec_Flt_t * vTiming; // arrival/required/slack + void * pManTime; // the timing manager + void * pLutLib; // LUT library }; @@ -178,26 +182,31 @@ struct Gia_ParSim_t_ int TimeLimit; // time limit in seconds int fCheckMiter; // check if miter outputs are non-zero int fVerbose; // enables verbose output + int iOutFail; // index of the failed output }; extern void Gia_ManSimSetDefaultParams( Gia_ParSim_t * p ); extern int Gia_ManSimSimulate( Gia_Man_t * pAig, Gia_ParSim_t * pPars ); -static inline int Gia_IntAbs( int n ) { return (n < 0)? -n : n; } -static inline int Gia_Float2Int( float Val ) { return *((int *)&Val); } -static inline float Gia_Int2Float( int Num ) { return *((float *)&Num); } -static inline int Gia_Base2Log( unsigned n ) { int r; assert( n >= 0 ); if ( n < 2 ) return n; for ( r = 0, n--; n; n >>= 1, r++ ); return r; } -static inline int Gia_Base10Log( unsigned n ) { int r; assert( n >= 0 ); if ( n < 2 ) return n; for ( r = 0, n--; n; n /= 10, r++ ); return r; } -static inline char * Gia_UtilStrsav( char * s ) { return s ? strcpy(ABC_ALLOC(char, strlen(s)+1), s) : NULL; } -static inline int Gia_BitWordNum( int nBits ) { return (nBits>>5) + ((nBits&31) > 0); } -static inline int Gia_TruthWordNum( int nVars ) { return nVars <= 5 ? 1 : (1 << (nVars - 5)); } -static inline int Gia_InfoHasBit( unsigned * p, int i ) { return (p[(i)>>5] & (1<<((i) & 31))) > 0; } -static inline void Gia_InfoSetBit( unsigned * p, int i ) { p[(i)>>5] |= (1<<((i) & 31)); } -static inline void Gia_InfoXorBit( unsigned * p, int i ) { p[(i)>>5] ^= (1<<((i) & 31)); } -static inline unsigned Gia_InfoMask( int nVar ) { return (~(unsigned)0) >> (32-nVar); } -static inline unsigned Gia_ObjCutSign( unsigned ObjId ) { return (1 << (ObjId & 31)); } -static inline int Gia_WordHasOneBit( unsigned uWord ) { return (uWord & (uWord-1)) == 0; } +static inline int Gia_IntAbs( int n ) { return (n < 0)? -n : n; } +//static inline int Gia_Float2Int( float Val ) { return *((int *)&Val); } +//static inline float Gia_Int2Float( int Num ) { return *((float *)&Num); } +static inline int Gia_Float2Int( float Val ) { union { int x; float y; } v; v.y = Val; return v.x; } +static inline float Gia_Int2Float( int Num ) { union { int x; float y; } v; v.x = Num; return v.y; } +static inline int Gia_Base2Log( unsigned n ) { int r; if ( n < 2 ) return n; for ( r = 0, n--; n; n >>= 1, r++ ); return r; } +static inline int Gia_Base10Log( unsigned n ) { int r; if ( n < 2 ) return n; for ( r = 0, n--; n; n /= 10, r++ ); return r; } +static inline int Gia_Base16Log( unsigned n ) { int r; if ( n < 2 ) return n; for ( r = 0, n--; n; n /= 16, r++ ); return r; } +static inline char * Gia_UtilStrsav( char * s ) { return s ? strcpy(ABC_ALLOC(char, strlen(s)+1), s) : NULL; } +static inline int Gia_BitWordNum( int nBits ) { return (nBits>>5) + ((nBits&31) > 0); } +static inline int Gia_TruthWordNum( int nVars ) { return nVars <= 5 ? 1 : (1 << (nVars - 5)); } +static inline int Gia_InfoHasBit( unsigned * p, int i ) { return (p[(i)>>5] & (1<<((i) & 31))) > 0; } +static inline void Gia_InfoSetBit( unsigned * p, int i ) { p[(i)>>5] |= (1<<((i) & 31)); } +static inline void Gia_InfoXorBit( unsigned * p, int i ) { p[(i)>>5] ^= (1<<((i) & 31)); } +static inline unsigned Gia_InfoMask( int nVar ) { return (~(unsigned)0) >> (32-nVar); } +static inline unsigned Gia_ObjCutSign( unsigned ObjId ) { return (1 << (ObjId & 31)); } +static inline int Gia_WordHasOneBit( unsigned uWord ) { return (uWord & (uWord-1)) == 0; } +static inline int Gia_WordHasOnePair( unsigned uWord ) { return Gia_WordHasOneBit(uWord & (uWord>>1) & 0x55555555); } static inline int Gia_WordCountOnes( unsigned uWord ) { uWord = (uWord & 0x55555555) + ((uWord>>1) & 0x55555555); @@ -206,7 +215,7 @@ static inline int Gia_WordCountOnes( unsigned uWord ) uWord = (uWord & 0x00FF00FF) + ((uWord>>8) & 0x00FF00FF); return (uWord & 0x0000FFFF) + (uWord>>16); } -static inline int Gia_WordFindFirstBit( unsigned uWord ) +static inline int Gia_WordFindFirstBit( unsigned uWord ) { int i; for ( i = 0; i < 32; i++ ) @@ -215,6 +224,46 @@ static inline int Gia_WordFindFirstBit( unsigned uWord ) return -1; } +static inline int Gia_ManTruthIsConst0( unsigned * pIn, int nVars ) +{ + int w; + for ( w = Gia_TruthWordNum(nVars)-1; w >= 0; w-- ) + if ( pIn[w] ) + return 0; + return 1; +} +static inline int Gia_ManTruthIsConst1( unsigned * pIn, int nVars ) +{ + int w; + for ( w = Gia_TruthWordNum(nVars)-1; w >= 0; w-- ) + if ( pIn[w] != ~(unsigned)0 ) + return 0; + return 1; +} +static inline void Gia_ManTruthCopy( unsigned * pOut, unsigned * pIn, int nVars ) +{ + int w; + for ( w = Gia_TruthWordNum(nVars)-1; w >= 0; w-- ) + pOut[w] = pIn[w]; +} +static inline void Gia_ManTruthClear( unsigned * pOut, int nVars ) +{ + int w; + for ( w = Gia_TruthWordNum(nVars)-1; w >= 0; w-- ) + pOut[w] = 0; +} +static inline void Gia_ManTruthFill( unsigned * pOut, int nVars ) +{ + int w; + for ( w = Gia_TruthWordNum(nVars)-1; w >= 0; w-- ) + pOut[w] = ~(unsigned)0; +} +static inline void Gia_ManTruthNot( unsigned * pOut, unsigned * pIn, int nVars ) +{ + int w; + for ( w = Gia_TruthWordNum(nVars)-1; w >= 0; w-- ) + pOut[w] = ~pIn[w]; +} static inline int Gia_Var2Lit( int Var, int fCompl ) { return Var + Var + fCompl; } static inline int Gia_Lit2Var( int Lit ) { return Lit >> 1; } @@ -236,6 +285,7 @@ static inline int Gia_ManRegNum( Gia_Man_t * p ) { return p->nRegs static inline int Gia_ManObjNum( Gia_Man_t * p ) { return p->nObjs; } static inline int Gia_ManAndNum( Gia_Man_t * p ) { return p->nObjs - Vec_IntSize(p->vCis) - Vec_IntSize(p->vCos) - 1; } static inline int Gia_ManCandNum( Gia_Man_t * p ) { return Gia_ManCiNum(p) + Gia_ManAndNum(p); } +static inline int Gia_ManConstrNum( Gia_Man_t * p ) { return p->nConstrs; } static inline Gia_Obj_t * Gia_ManConst0( Gia_Man_t * p ) { return p->pObjs; } static inline Gia_Obj_t * Gia_ManConst1( Gia_Man_t * p ) { return Gia_Not(Gia_ManConst0(p)); } @@ -259,6 +309,8 @@ static inline int Gia_ManObjIsConst0( Gia_Man_t * p, Gia_Obj_t * pObj){ static inline int Gia_ObjId( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( p->pObjs <= pObj && pObj < p->pObjs + p->nObjs ); return pObj - p->pObjs; } static inline int Gia_ObjCioId( Gia_Obj_t * pObj ) { assert( Gia_ObjIsTerm(pObj) ); return pObj->iDiff1; } static inline void Gia_ObjSetCioId( Gia_Obj_t * pObj, int v ) { assert( Gia_ObjIsTerm(pObj) ); pObj->iDiff1 = v; } +static inline int Gia_ObjValue( Gia_Obj_t * pObj ) { return pObj->Value; } +static inline void Gia_ObjSetValue( Gia_Obj_t * pObj, int i ) { pObj->Value = i; } static inline int Gia_ObjPhase( Gia_Obj_t * pObj ) { return pObj->fPhase; } static inline int Gia_ObjPhaseReal( Gia_Obj_t * pObj ) { return Gia_Regular(pObj)->fPhase ^ Gia_IsComplement(pObj); } @@ -302,10 +354,14 @@ static inline Gia_Obj_t * Gia_ObjFromLit( Gia_Man_t * p, int iLit ) { static inline int Gia_ObjToLit( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_Var2Lit( Gia_ObjId(p, Gia_Regular(pObj)), Gia_IsComplement(pObj) ); } static inline int Gia_ObjPhaseRealLit( Gia_Man_t * p, int iLit ) { return Gia_ObjPhaseReal( Gia_ObjFromLit(p, iLit) ); } -static inline int Gia_ObjValue( Gia_Obj_t * pObj ) { return pObj->Value; } -static inline int Gia_ObjLevel( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert(p->pLevels);return p->pLevels[Gia_ObjId(p, pObj)]; } +static inline int Gia_ObjLevel( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Vec_IntGetEntry(p->vLevels, Gia_ObjId(p,pObj)); } +static inline int Gia_ObjLevelId( Gia_Man_t * p, int Id ) { return Vec_IntGetEntry(p->vLevels, Id); } +static inline void Gia_ObjSetLevel( Gia_Man_t * p, Gia_Obj_t * pObj, int l ) { Vec_IntSetEntry(p->vLevels, Gia_ObjId(p,pObj), l); } +static inline void Gia_ObjSetCoLevel( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjIsCo(pObj) ); Gia_ObjSetLevel( p, pObj, Gia_ObjLevel(p,Gia_ObjFanin0(pObj)) ); } +static inline void Gia_ObjSetAndLevel( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjIsAnd(pObj) ); Gia_ObjSetLevel( p, pObj, 1+ABC_MAX(Gia_ObjLevel(p,Gia_ObjFanin0(pObj)),Gia_ObjLevel(p,Gia_ObjFanin1(pObj))) ); } static inline int Gia_ObjRefs( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( p->pRefs); return p->pRefs[Gia_ObjId(p, pObj)]; } +static inline int Gia_ObjRefsId( Gia_Man_t * p, int Id ) { assert( p->pRefs); return p->pRefs[Id]; } static inline int Gia_ObjRefInc( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( p->pRefs); return p->pRefs[Gia_ObjId(p, pObj)]++; } static inline int Gia_ObjRefDec( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( p->pRefs); return --p->pRefs[Gia_ObjId(p, pObj)]; } static inline void Gia_ObjRefFanin0Inc(Gia_Man_t * p, Gia_Obj_t * pObj){ assert( p->pRefs); Gia_ObjRefInc(p, Gia_ObjFanin0(pObj)); } @@ -313,37 +369,35 @@ static inline void Gia_ObjRefFanin1Inc(Gia_Man_t * p, Gia_Obj_t * pObj){ static inline void Gia_ObjRefFanin0Dec(Gia_Man_t * p, Gia_Obj_t * pObj){ assert( p->pRefs); Gia_ObjRefDec(p, Gia_ObjFanin0(pObj)); } static inline void Gia_ObjRefFanin1Dec(Gia_Man_t * p, Gia_Obj_t * pObj){ assert( p->pRefs); Gia_ObjRefDec(p, Gia_ObjFanin1(pObj)); } -static inline void Gia_ManResetTravId( Gia_Man_t * p ) { extern void Gia_ManCleanValue( Gia_Man_t * p ); Gia_ManCleanValue( p ); p->nTravIds = 1; } -static inline void Gia_ManIncrementTravId( Gia_Man_t * p ) { p->nTravIds++; } -static inline void Gia_ObjSetTravId( Gia_Obj_t * pObj, int TravId ) { pObj->Value = TravId; } -static inline void Gia_ObjSetTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * pObj ) { pObj->Value = p->nTravIds; } -static inline void Gia_ObjSetTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { pObj->Value = p->nTravIds - 1; } -static inline int Gia_ObjIsTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * pObj ) { return ((int)pObj->Value == p->nTravIds); } -static inline int Gia_ObjIsTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { return ((int)pObj->Value == p->nTravIds - 1); } - -static inline void Gia_ManResetTravIdArray( Gia_Man_t * p ) -{ - ABC_FREE( p->pTravIds ); - p->nTravIdsAlloc = Gia_ManObjNum(p); - p->pTravIds = ABC_CALLOC( int, p->nTravIdsAlloc ); - p->nTravIds = 1; -} -static inline void Gia_ManIncrementTravIdArray( Gia_Man_t * p ) -{ - while ( p->nTravIdsAlloc < Gia_ManObjNum(p) ) - { - p->nTravIdsAlloc *= 2; - p->pTravIds = ABC_REALLOC( int, p->pTravIds, p->nTravIdsAlloc ); - memset( p->pTravIds + p->nTravIdsAlloc/2, 0, sizeof(int) * p->nTravIdsAlloc/2 ); - } - p->nTravIds++; -} -static inline void Gia_ObjSetTravIdCurrentArray( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); p->pTravIds[Gia_ObjId(p, pObj)] = p->nTravIds; } -static inline void Gia_ObjSetTravIdPreviousArray( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); p->pTravIds[Gia_ObjId(p, pObj)] = p->nTravIds - 1; } -static inline int Gia_ObjIsTravIdCurrentArray( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); return (p->pTravIds[Gia_ObjId(p, pObj)] == p->nTravIds); } -static inline int Gia_ObjIsTravIdPreviousArray( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); return (p->pTravIds[Gia_ObjId(p, pObj)] == p->nTravIds - 1); } -static inline void Gia_ObjSetTravIdCurrentArrayId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); p->pTravIds[Id] = p->nTravIds; } -static inline int Gia_ObjIsTravIdCurrentArrayId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); return (p->pTravIds[Id] == p->nTravIds); } +static inline int Gia_ObjNodeRefs( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( p->pNodeRefs); return p->pNodeRefs[Gia_ObjId(p, pObj)]; } +static inline int Gia_ObjNodeRefsId( Gia_Man_t * p, int Id ) { assert( p->pNodeRefs); return p->pNodeRefs[Id]; } +static inline int Gia_ObjNodeRefIncId( Gia_Man_t * p, int Id ) { assert( p->pNodeRefs); return p->pNodeRefs[Id]++; } +static inline int Gia_ObjNodeRefDecId( Gia_Man_t * p, int Id ) { assert( p->pNodeRefs); return --p->pNodeRefs[Id]; } +static inline int Gia_ObjNodeRefInc( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( p->pNodeRefs); return p->pNodeRefs[Gia_ObjId(p, pObj)]++; } +static inline int Gia_ObjNodeRefDec( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( p->pNodeRefs); return --p->pNodeRefs[Gia_ObjId(p, pObj)]; } + +static inline void Gia_ObjSetTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); p->pTravIds[Gia_ObjId(p, pObj)] = p->nTravIds; } +static inline void Gia_ObjSetTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); p->pTravIds[Gia_ObjId(p, pObj)] = p->nTravIds - 1; } +static inline int Gia_ObjIsTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); return (p->pTravIds[Gia_ObjId(p, pObj)] == p->nTravIds); } +static inline int Gia_ObjIsTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); return (p->pTravIds[Gia_ObjId(p, pObj)] == p->nTravIds - 1); } +static inline void Gia_ObjSetTravIdCurrentId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); p->pTravIds[Id] = p->nTravIds; } +static inline int Gia_ObjIsTravIdCurrentId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); return (p->pTravIds[Id] == p->nTravIds); } + +static inline void Gia_ManTimeClean( Gia_Man_t * p ) { int i; assert( p->vTiming != NULL ); Vec_FltFill(p->vTiming, 3*Gia_ManObjNum(p), 0); for ( i = 0; i < Gia_ManObjNum(p); i++ ) Vec_FltWriteEntry( p->vTiming, 3*i+1, (float)(ABC_INFINITY) ); } +static inline void Gia_ManTimeStart( Gia_Man_t * p ) { assert( p->vTiming == NULL ); p->vTiming = Vec_FltAlloc(0); Gia_ManTimeClean( p ); } +static inline void Gia_ManTimeStop( Gia_Man_t * p ) { assert( p->vTiming != NULL ); Vec_FltFreeP(&p->vTiming); } +static inline float Gia_ObjTimeArrival( Gia_Man_t * p, int Id ) { return Vec_FltEntry(p->vTiming, 3*Id+0); } +static inline float Gia_ObjTimeRequired( Gia_Man_t * p, int Id ) { return Vec_FltEntry(p->vTiming, 3*Id+1); } +static inline float Gia_ObjTimeSlack( Gia_Man_t * p, int Id ) { return Vec_FltEntry(p->vTiming, 3*Id+2); } +static inline float Gia_ObjTimeArrivalObj( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjTimeArrival( p, Gia_ObjId(p, pObj) ); } +static inline float Gia_ObjTimeRequiredObj( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjTimeRequired( p, Gia_ObjId(p, pObj) ); } +static inline float Gia_ObjTimeSlackObj( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjTimeSlack( p, Gia_ObjId(p, pObj) ); } +static inline void Gia_ObjSetTimeArrival( Gia_Man_t * p, int Id, float t ) { Vec_FltWriteEntry( p->vTiming, 3*Id+0, t ); } +static inline void Gia_ObjSetTimeRequired( Gia_Man_t * p, int Id, float t ) { Vec_FltWriteEntry( p->vTiming, 3*Id+1, t ); } +static inline void Gia_ObjSetTimeSlack( Gia_Man_t * p, int Id, float t ) { Vec_FltWriteEntry( p->vTiming, 3*Id+2, t ); } +static inline void Gia_ObjSetTimeArrivalObj( Gia_Man_t * p, Gia_Obj_t * pObj, float t ) { Gia_ObjSetTimeArrival( p, Gia_ObjId(p, pObj), t ); } +static inline void Gia_ObjSetTimeRequiredObj( Gia_Man_t * p, Gia_Obj_t * pObj, float t ) { Gia_ObjSetTimeRequired( p, Gia_ObjId(p, pObj), t ); } +static inline void Gia_ObjSetTimeSlackObj( Gia_Man_t * p, Gia_Obj_t * pObj, float t ) { Gia_ObjSetTimeSlack( p, Gia_ObjId(p, pObj), t ); } // AIG construction extern void Gia_ObjAddFanout( Gia_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pFanout ); @@ -405,6 +459,12 @@ static inline int Gia_ManAppendCo( Gia_Man_t * p, int iLit0 ) Gia_ObjAddFanout( p, Gia_ObjFanin0(pObj), pObj ); return Gia_ObjId( p, pObj ) << 1; } +static inline int Gia_ManAppendMux( Gia_Man_t * p, int iCtrl, int iData1, int iData0 ) +{ + int iTemp0 = Gia_ManAppendAnd( p, Gia_LitNot(iCtrl), iData0 ); + int iTemp1 = Gia_ManAppendAnd( p, iCtrl, iData1 ); + return Gia_LitNotCond( Gia_ManAppendAnd( p, Gia_LitNot(iTemp0), Gia_LitNot(iTemp1) ), 1 ); +} #define GIA_ZER 1 #define GIA_ONE 2 @@ -428,9 +488,10 @@ static inline int Gia_XsimAndCond( int Value0, int fCompl0, int Value1, int fCom } static inline Gia_Obj_t * Gia_ObjReprObj( Gia_Man_t * p, int Id ) { return p->pReprs[Id].iRepr == GIA_VOID ? NULL : Gia_ManObj( p, p->pReprs[Id].iRepr ); } -static inline int Gia_ObjRepr( Gia_Man_t * p, int Id ) { return p->pReprs[Id].iRepr; } -static inline void Gia_ObjSetRepr( Gia_Man_t * p, int Id, int Num ) { p->pReprs[Id].iRepr = Num; } -static inline void Gia_ObjUnsetRepr( Gia_Man_t * p, int Id ) { p->pReprs[Id].iRepr = GIA_VOID; } +static inline int Gia_ObjRepr( Gia_Man_t * p, int Id ) { return p->pReprs[Id].iRepr; } +static inline void Gia_ObjSetRepr( Gia_Man_t * p, int Id, int Num ) { assert( Num == GIA_VOID || Num < Id ); p->pReprs[Id].iRepr = Num; } +static inline void Gia_ObjUnsetRepr( Gia_Man_t * p, int Id ) { p->pReprs[Id].iRepr = GIA_VOID; } +static inline int Gia_ObjHasRepr( Gia_Man_t * p, int Id ) { return p->pReprs[Id].iRepr != GIA_VOID; } static inline int Gia_ObjProved( Gia_Man_t * p, int Id ) { return p->pReprs[Id].fProved; } static inline void Gia_ObjSetProved( Gia_Man_t * p, int Id ) { p->pReprs[Id].fProved = 1; } @@ -474,14 +535,17 @@ static inline void Gia_ClassUndoPair( Gia_Man_t * p, int i ) { a for ( assert(Gia_ObjIsHead(p, i)), iObj = Gia_ObjNext(p, i); iObj; iObj = Gia_ObjNext(p, iObj) ) -static inline int Gia_ObjIsGate( Gia_Man_t * p, int Id ) { return p->pMapping[Id] != 0; } -static inline int Gia_ObjGateSize( Gia_Man_t * p, int Id ) { return p->pMapping[p->pMapping[Id]]; } -static inline int * Gia_ObjGateFanins( Gia_Man_t * p, int Id ) { return p->pMapping + p->pMapping[Id] + 1; } +static inline int Gia_ObjIsLut( Gia_Man_t * p, int Id ) { return p->pMapping[Id] != 0; } +static inline int Gia_ObjLutSize( Gia_Man_t * p, int Id ) { return p->pMapping[p->pMapping[Id]]; } +static inline int * Gia_ObjLutFanins( Gia_Man_t * p, int Id ) { return p->pMapping + p->pMapping[Id] + 1; } +static inline int Gia_ObjLutFanin( Gia_Man_t * p, int Id, int i ) { return Gia_ObjLutFanins(p, Id)[i]; } -#define Gia_ManForEachGate( p, i ) \ - for ( i = 1; i < Gia_ManObjNum(p); i++ ) if ( !Gia_ObjIsGate(p, i) ) {} else -#define Gia_GateForEachFanin( p, i, iFan, k ) \ - for ( k = 0; k < Gia_ObjGateSize(p,i) && ((iFan = Gia_ObjGateFanins(p,i)[k]),1); k++ ) +#define Gia_ManForEachLut( p, i ) \ + for ( i = 1; i < Gia_ManObjNum(p); i++ ) if ( !Gia_ObjIsLut(p, i) ) {} else +#define Gia_LutForEachFanin( p, i, iFan, k ) \ + for ( k = 0; k < Gia_ObjLutSize(p,i) && ((iFan = Gia_ObjLutFanins(p,i)[k]),1); k++ ) +#define Gia_LutForEachFaninObj( p, i, pFanin, k ) \ + for ( k = 0; k < Gia_ObjLutSize(p,i) && ((pFanin = Gia_ManObj(p, Gia_ObjLutFanins(p,i)[k])),1); k++ ) //////////////////////////////////////////////////////////////////////// /// MACRO DEFINITIONS /// @@ -525,9 +589,13 @@ static inline int * Gia_ObjGateFanins( Gia_Man_t * p, int Id ) { re //////////////////////////////////////////////////////////////////////// /*=== giaAiger.c ===========================================================*/ +extern int Gia_FileSize( char * pFileName ); extern Gia_Man_t * Gia_ReadAiger( char * pFileName, int fCheck ); extern void Gia_WriteAiger( Gia_Man_t * p, char * pFileName, int fWriteSymbols, int fCompact ); extern void Gia_DumpAiger( Gia_Man_t * p, char * pFilePrefix, int iFileNum, int nFileNumDigits ); +/*=== giaBidec.c ===========================================================*/ +extern unsigned * Gia_ManConvertAigToTruth( Gia_Man_t * p, Gia_Obj_t * pRoot, Vec_Int_t * vLeaves, Vec_Int_t * vTruth, Vec_Int_t * vVisited ); +extern Gia_Man_t * Gia_ManPerformBidec( Gia_Man_t * p, int fVerbose ); /*=== giaCsatOld.c ============================================================*/ extern Vec_Int_t * Cbs_ManSolveMiter( Gia_Man_t * pGia, int nConfs, Vec_Str_t ** pvStatus, int fVerbose ); /*=== giaCsat.c ============================================================*/ @@ -542,14 +610,17 @@ extern Gia_Man_t * Gia_ManDupCofAll( Gia_Man_t * p, int nFanLim, int fVe /*=== giaDfs.c ============================================================*/ extern void Gia_ManCollectCis( Gia_Man_t * p, int * pNodes, int nNodes, Vec_Int_t * vSupp ); extern void Gia_ManCollectAnds( Gia_Man_t * p, int * pNodes, int nNodes, Vec_Int_t * vNodes ); +extern Vec_Int_t * Gia_ManCollectNodesCis( Gia_Man_t * p, int * pNodes, int nNodes ); extern int Gia_ManSuppSize( Gia_Man_t * p, int * pNodes, int nNodes ); extern int Gia_ManConeSize( Gia_Man_t * p, int * pNodes, int nNodes ); extern Vec_Vec_t * Gia_ManLevelize( Gia_Man_t * p ); +extern Vec_Int_t * Gia_ManOrderReverse( Gia_Man_t * p ); /*=== giaDup.c ============================================================*/ extern Gia_Man_t * Gia_ManDupOrderDfs( Gia_Man_t * p ); +extern Gia_Man_t * Gia_ManDupOrderDfsChoices( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManDupOrderDfsReverse( Gia_Man_t * p ); +extern Gia_Man_t * Gia_ManDupOutputGroup( Gia_Man_t * p, int iOutStart, int iOutStop ); extern Gia_Man_t * Gia_ManDupOrderAiger( Gia_Man_t * p ); - extern Gia_Man_t * Gia_ManDupFlip( Gia_Man_t * p, int * pInitState ); extern Gia_Man_t * Gia_ManDup( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManDupSelf( Gia_Man_t * p ); @@ -562,32 +633,38 @@ extern Gia_Man_t * Gia_ManDupDfsCone( Gia_Man_t * p, Gia_Obj_t * pObj ); extern Gia_Man_t * Gia_ManDupDfsLitArray( Gia_Man_t * p, Vec_Int_t * vLits ); extern Gia_Man_t * Gia_ManDupNormalized( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManDupTrimmed( Gia_Man_t * p, int fTrimCis, int fTrimCos ); +extern Gia_Man_t * Gia_ManDupOntop( Gia_Man_t * p, Gia_Man_t * p2 ); extern Gia_Man_t * Gia_ManDupDfsCiMap( Gia_Man_t * p, int * pCi2Lit, Vec_Int_t * vLits ); extern Gia_Man_t * Gia_ManDupDfsClasses( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManDupTopAnd( Gia_Man_t * p, int fVerbose ); extern Gia_Man_t * Gia_ManMiter( Gia_Man_t * pAig0, Gia_Man_t * pAig1, int fDualOut, int fSeq, int fVerbose ); extern Gia_Man_t * Gia_ManTransformMiter( Gia_Man_t * p ); +extern Gia_Man_t * Gia_ManChoiceMiter( Vec_Ptr_t * vGias ); /*=== giaEnable.c ==========================================================*/ extern void Gia_ManDetectSeqSignals( Gia_Man_t * p, int fSetReset, int fVerbose ); extern Gia_Man_t * Gia_ManUnrollAndCofactor( Gia_Man_t * p, int nFrames, int nFanMax, int fVerbose ); extern Gia_Man_t * Gia_ManRemoveEnables( Gia_Man_t * p ); /*=== giaEquiv.c ==========================================================*/ +extern void Gia_ManEquivFixOutputPairs( Gia_Man_t * p ); extern int Gia_ManCheckTopoOrder( Gia_Man_t * p ); extern int * Gia_ManDeriveNexts( Gia_Man_t * p ); extern void Gia_ManDeriveReprs( Gia_Man_t * p ); extern int Gia_ManEquivCountLits( Gia_Man_t * p ); +extern int Gia_ManEquivCountLitsAll( Gia_Man_t * p ); extern int Gia_ManEquivCountClasses( Gia_Man_t * p ); extern void Gia_ManEquivPrintOne( Gia_Man_t * p, int i, int Counter ); extern void Gia_ManEquivPrintClasses( Gia_Man_t * p, int fVerbose, float Mem ); extern Gia_Man_t * Gia_ManEquivReduce( Gia_Man_t * p, int fUseAll, int fDualOut, int fVerbose ); extern Gia_Man_t * Gia_ManEquivReduceAndRemap( Gia_Man_t * p, int fSeq, int fMiterPairs ); extern int Gia_ManEquivSetColors( Gia_Man_t * p, int fVerbose ); -extern Gia_Man_t * Gia_ManSpecReduce( Gia_Man_t * p, int fDualOut, int fVerbose ); -extern Gia_Man_t * Gia_ManSpecReduceInit( Gia_Man_t * p, Gia_Cex_t * pInit, int nFrames, int fDualOut ); -extern Gia_Man_t * Gia_ManSpecReduceInitFrames( Gia_Man_t * p, Gia_Cex_t * pInit, int nFramesMax, int * pnFrames, int fDualOut, int nMinOutputs ); +extern Gia_Man_t * Gia_ManSpecReduce( Gia_Man_t * p, int fDualOut, int fSynthesis, int fVerbose ); +extern Gia_Man_t * Gia_ManSpecReduceInit( Gia_Man_t * p, Abc_Cex_t * pInit, int nFrames, int fDualOut ); +extern Gia_Man_t * Gia_ManSpecReduceInitFrames( Gia_Man_t * p, Abc_Cex_t * pInit, int nFramesMax, int * pnFrames, int fDualOut, int nMinOutputs ); extern void Gia_ManEquivTransform( Gia_Man_t * p, int fVerbose ); extern void Gia_ManEquivImprove( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManEquivToChoices( Gia_Man_t * p, int nSnapshots ); +extern int Gia_ManCountChoiceNodes( Gia_Man_t * p ); +extern int Gia_ManCountChoices( Gia_Man_t * p ); /*=== giaFanout.c =========================================================*/ extern void Gia_ObjAddFanout( Gia_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pFanout ); extern void Gia_ObjRemoveFanout( Gia_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pFanout ); @@ -611,12 +688,16 @@ extern int Gia_ManHashMux( Gia_Man_t * p, int iCtrl, int iData1, extern int Gia_ManHashAndTry( Gia_Man_t * p, int iLit0, int iLit1 ); extern Gia_Man_t * Gia_ManRehash( Gia_Man_t * p, int fAddStrash ); extern void Gia_ManHashProfile( Gia_Man_t * p ); +extern int Gia_ManHashLookup( Gia_Man_t * p, Gia_Obj_t * p0, Gia_Obj_t * p1 ); +/*=== giaIf.c ===========================================================*/ +extern void Gia_ManPrintNpnClasses( Gia_Man_t * p ); /*=== giaLogic.c ===========================================================*/ extern void Gia_ManTestDistance( Gia_Man_t * p ); extern void Gia_ManSolveProblem( Gia_Man_t * pGia, Emb_Par_t * pPars ); /*=== giaMan.c ===========================================================*/ extern Gia_Man_t * Gia_ManStart( int nObjsMax ); extern void Gia_ManStop( Gia_Man_t * p ); +extern void Gia_ManStopP( Gia_Man_t ** p ); extern void Gia_ManPrintStats( Gia_Man_t * p, int fSwitch ); extern void Gia_ManPrintStatsShort( Gia_Man_t * p ); extern void Gia_ManPrintMiterStatus( Gia_Man_t * p ); @@ -624,8 +705,32 @@ extern void Gia_ManSetRegNum( Gia_Man_t * p, int nRegs ); extern void Gia_ManReportImprovement( Gia_Man_t * p, Gia_Man_t * pNew ); /*=== giaMap.c ===========================================================*/ extern void Gia_ManPrintMappingStats( Gia_Man_t * p ); +extern int Gia_ManLutFaninCount( Gia_Man_t * p ); +extern int Gia_ManLutSizeMax( Gia_Man_t * p ); +extern int Gia_ManLutNum( Gia_Man_t * p ); +extern int Gia_ManLutLevel( Gia_Man_t * p ); +/*=== giaMem.c ===========================================================*/ +extern Gia_MmFixed_t * Gia_MmFixedStart( int nEntrySize, int nEntriesMax ); +extern void Gia_MmFixedStop( Gia_MmFixed_t * p, int fVerbose ); +extern char * Gia_MmFixedEntryFetch( Gia_MmFixed_t * p ); +extern void Gia_MmFixedEntryRecycle( Gia_MmFixed_t * p, char * pEntry ); +extern void Gia_MmFixedRestart( Gia_MmFixed_t * p ); +extern int Gia_MmFixedReadMemUsage( Gia_MmFixed_t * p ); +extern int Gia_MmFixedReadMaxEntriesUsed( Gia_MmFixed_t * p ); +extern Gia_MmFlex_t * Gia_MmFlexStart(); +extern void Gia_MmFlexStop( Gia_MmFlex_t * p, int fVerbose ); +extern char * Gia_MmFlexEntryFetch( Gia_MmFlex_t * p, int nBytes ); +extern void Gia_MmFlexRestart( Gia_MmFlex_t * p ); +extern int Gia_MmFlexReadMemUsage( Gia_MmFlex_t * p ); +extern Gia_MmStep_t * Gia_MmStepStart( int nSteps ); +extern void Gia_MmStepStop( Gia_MmStep_t * p, int fVerbose ); +extern char * Gia_MmStepEntryFetch( Gia_MmStep_t * p, int nBytes ); +extern void Gia_MmStepEntryRecycle( Gia_MmStep_t * p, char * pEntry, int nBytes ); +extern int Gia_MmStepReadMemUsage( Gia_MmStep_t * p ); /*=== giaPat.c ===========================================================*/ extern void Gia_SatVerifyPattern( Gia_Man_t * p, Gia_Obj_t * pRoot, Vec_Int_t * vCex, Vec_Int_t * vVisit ); +/*=== giaReparam.c ===========================================================*/ +extern Gia_Man_t * Gia_ManReparm( Gia_Man_t * p, int fVerbose ); /*=== giaRetime.c ===========================================================*/ extern Gia_Man_t * Gia_ManRetimeForward( Gia_Man_t * p, int nMaxIters, int fVerbose ); /*=== giaSat.c ============================================================*/ @@ -636,10 +741,16 @@ extern int Gia_ManCombMarkUsed( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManCleanup( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManSeqCleanup( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManSeqStructSweep( Gia_Man_t * p, int fConst, int fEquiv, int fVerbose ); +/*=== giaShrink.c ===========================================================*/ +extern Gia_Man_t * Gia_ManPerformMapShrink( Gia_Man_t * p, int fKeepLevel, int fVerbose ); /*=== giaSort.c ============================================================*/ extern int * Gia_SortFloats( float * pArray, int * pPerm, int nSize ); /*=== giaSim.c ============================================================*/ extern int Gia_ManSimSimulate( Gia_Man_t * pAig, Gia_ParSim_t * pPars ); +/*=== giaSpeedup.c ============================================================*/ +extern float Gia_ManDelayTraceLut( Gia_Man_t * p ); +extern float Gia_ManDelayTraceLutPrint( Gia_Man_t * p, int fVerbose ); +extern Gia_Man_t * Gia_ManSpeedup( Gia_Man_t * p, int Percentage, int Degree, int fVerbose, int fVeryVerbose ); /*=== giaSwitch.c ============================================================*/ extern float Gia_ManEvaluateSwitching( Gia_Man_t * p ); extern float Gia_ManComputeSwitching( Gia_Man_t * p, int nFrames, int nPref, int fProbOne ); @@ -649,7 +760,9 @@ extern Gia_Man_t * Gia_ManReduceConst( Gia_Man_t * pAig, int fVerbose ); extern unsigned Gia_ManRandom( int fReset ); extern void Gia_ManRandomInfo( Vec_Ptr_t * vInfo, int iInputStart, int iWordStart, int iWordStop ); extern unsigned int Gia_PrimeCudd( unsigned int p ); +extern char * Gia_TimeStamp(); extern char * Gia_FileNameGenericAppend( char * pBase, char * pSuffix ); +extern void Gia_ManIncrementTravId( Gia_Man_t * p ); extern void Gia_ManSetMark0( Gia_Man_t * p ); extern void Gia_ManCleanMark0( Gia_Man_t * p ); extern void Gia_ManCheckMark0( Gia_Man_t * p ); @@ -657,8 +770,12 @@ extern void Gia_ManSetMark1( Gia_Man_t * p ); extern void Gia_ManCleanMark1( Gia_Man_t * p ); extern void Gia_ManCheckMark1( Gia_Man_t * p ); extern void Gia_ManCleanValue( Gia_Man_t * p ); +extern void Gia_ManCleanLevels( Gia_Man_t * p, int Size ); +extern void Gia_ManCleanTruth( Gia_Man_t * p ); extern void Gia_ManFillValue( Gia_Man_t * p ); +extern void Gia_ObjSetPhase( Gia_Obj_t * pObj ); extern void Gia_ManSetPhase( Gia_Man_t * p ); +extern void Gia_ManSetPhase1( Gia_Man_t * p ); extern void Gia_ManCleanPhase( Gia_Man_t * p ); extern int Gia_ManLevelNum( Gia_Man_t * p ); extern void Gia_ManSetRefs( Gia_Man_t * p ); @@ -670,13 +787,18 @@ extern Vec_Int_t * Gia_ManCollectPoIds( Gia_Man_t * p ); extern int Gia_ObjIsMuxType( Gia_Obj_t * pNode ); extern int Gia_ObjRecognizeExor( Gia_Obj_t * pObj, Gia_Obj_t ** ppFan0, Gia_Obj_t ** ppFan1 ); extern Gia_Obj_t * Gia_ObjRecognizeMux( Gia_Obj_t * pNode, Gia_Obj_t ** ppNodeT, Gia_Obj_t ** ppNodeE ); -extern Gia_Cex_t * Gia_ManAllocCounterExample( int nRegs, int nRealPis, int nFrames ); -extern int Gia_ManVerifyCounterExample( Gia_Man_t * pAig, Gia_Cex_t * p, int fDualOut ); -extern void Gia_ManPrintCounterExample( Gia_Cex_t * p ); +extern Abc_Cex_t * Gia_ManAllocCounterExample( int nRegs, int nRealPis, int nFrames ); +extern Abc_Cex_t * Gia_ManDeriveCexFromArray( Gia_Man_t * pAig, Vec_Int_t * vValues, int nSkip, int iFrame ); +extern Abc_Cex_t * Gia_ManCreateFromComb( int nRegs, int nRealPis, int iPo, int * pModel ); +extern Abc_Cex_t * Gia_ManDupCounterExample( Abc_Cex_t * p, int nRegsNew ); +extern int Gia_ManVerifyCounterExample( Gia_Man_t * pAig, Abc_Cex_t * p, int fDualOut ); +extern void Gia_ManPrintCounterExample( Abc_Cex_t * p ); extern int Gia_NodeMffcSize( Gia_Man_t * p, Gia_Obj_t * pNode ); extern int Gia_ManHasChoices( Gia_Man_t * p ); -extern int Gia_ManHasDandling( Gia_Man_t * p ); -/*=== giaUtil.c ===========================================================*/ +extern int Gia_ManHasDangling( Gia_Man_t * p ); +extern Vec_Int_t * Gia_ManGetDangling( Gia_Man_t * p ); +extern void Gia_ObjPrint( Gia_Man_t * p, Gia_Obj_t * pObj ); +/*=== giaCTas.c ===========================================================*/ typedef struct Tas_Man_t_ Tas_Man_t; extern Tas_Man_t * Tas_ManAlloc( Gia_Man_t * pAig, int nBTLimit ); extern void Tas_ManStop( Tas_Man_t * p ); @@ -686,9 +808,11 @@ extern int Tas_ManSolve( Tas_Man_t * p, Gia_Obj_t * pObj, Gia_Ob extern int Tas_ManSolveArray( Tas_Man_t * p, Vec_Ptr_t * vObjs ); -#ifdef __cplusplus -} -#endif + + +ABC_NAMESPACE_HEADER_END + + #endif diff --git a/src/aig/gia/giaAbs.c b/src/aig/gia/giaAbs.c new file mode 100644 index 00000000..38e010f1 --- /dev/null +++ b/src/aig/gia/giaAbs.c @@ -0,0 +1,553 @@ +/**CFile**************************************************************** + + FileName [giaAbs.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Counter-example-guided abstraction refinement.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaAbs.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" +#include "giaAig.h" +#include "giaAbs.h" +#include "saig.h" + +#ifndef _WIN32 +#include <unistd.h> +#endif + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +extern Vec_Int_t * Saig_ManProofAbstractionFlops( Aig_Man_t * p, Gia_ParAbs_t * pPars ); +extern Vec_Int_t * Saig_ManCexAbstractionFlops( Aig_Man_t * p, Gia_ParAbs_t * pPars ); +extern int Saig_ManCexRefineStep( Aig_Man_t * p, Vec_Int_t * vFlops, Abc_Cex_t * pCex, int fVerbose ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [This procedure sets default parameters.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManAbsSetDefaultParams( Gia_ParAbs_t * p ) +{ + memset( p, 0, sizeof(Gia_ParAbs_t) ); + p->Algo = 0; // algorithm: CBA + p->nFramesMax = 10; // timeframes for PBA + p->nConfMax = 10000; // conflicts for PBA + p->fDynamic = 1; // dynamic unfolding for PBA + p->fConstr = 0; // use constraints + p->nFramesBmc = 250; // timeframes for BMC + p->nConfMaxBmc = 5000; // conflicts for BMC + p->nStableMax = 1000000; // the number of stable frames to quit + p->nRatio = 10; // ratio of flops to quit + p->nBobPar = 1000000; // the number of frames before trying to quit + p->fUseBdds = 0; // use BDDs to refine abstraction + p->fUseDprove = 0; // use 'dprove' to refine abstraction + p->fUseStart = 1; // use starting frame + p->fVerbose = 0; // verbose output + p->fVeryVerbose= 0; // printing additional information + p->Status = -1; // the problem status + p->nFramesDone = -1; // the number of rames covered +} + +/**Function************************************************************* + + Synopsis [Transform flop list into flop map.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_ManFlops2Classes( Gia_Man_t * pGia, Vec_Int_t * vFlops ) +{ + Vec_Int_t * vFlopClasses; + int i, Entry; + vFlopClasses = Vec_IntStart( Gia_ManRegNum(pGia) ); + Vec_IntForEachEntry( vFlops, Entry, i ) + Vec_IntWriteEntry( vFlopClasses, Entry, 1 ); + return vFlopClasses; +} + +/**Function************************************************************* + + Synopsis [Transform flop map into flop list.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_ManClasses2Flops( Vec_Int_t * vFlopClasses ) +{ + Vec_Int_t * vFlops; + int i, Entry; + vFlops = Vec_IntAlloc( 100 ); + Vec_IntForEachEntry( vFlopClasses, Entry, i ) + if ( Entry ) + Vec_IntPush( vFlops, i ); + return vFlops; +} + + +/**Function************************************************************* + + Synopsis [Performs abstraction on the AIG manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManCexAbstraction( Gia_Man_t * p, Vec_Int_t * vFlops ) +{ + Gia_Man_t * pGia; + Aig_Man_t * pNew, * pTemp; + pNew = Gia_ManToAig( p, 0 ); + pNew = Saig_ManDeriveAbstraction( pTemp = pNew, vFlops ); + Aig_ManStop( pTemp ); + pGia = Gia_ManFromAig( pNew ); + pGia->vCiNumsOrig = pNew->vCiNumsOrig; + pNew->vCiNumsOrig = NULL; + Aig_ManStop( pNew ); + return pGia; + +} + +/**Function************************************************************* + + Synopsis [Computes abstracted flops for the manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_ManCexAbstractionFlops( Gia_Man_t * p, Gia_ParAbs_t * pPars ) +{ + Vec_Int_t * vFlops; + Aig_Man_t * pNew; + pNew = Gia_ManToAig( p, 0 ); + vFlops = Saig_ManCexAbstractionFlops( pNew, pPars ); + p->pCexSeq = pNew->pSeqModel; pNew->pSeqModel = NULL; + Aig_ManStop( pNew ); + return vFlops; +} + +/**Function************************************************************* + + Synopsis [Computes abstracted flops for the manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_ManProofAbstractionFlops( Gia_Man_t * p, Gia_ParAbs_t * pPars ) +{ + Vec_Int_t * vFlops; + Aig_Man_t * pNew; + pNew = Gia_ManToAig( p, 0 ); + vFlops = Saig_ManProofAbstractionFlops( pNew, pPars ); + p->pCexSeq = pNew->pSeqModel; pNew->pSeqModel = NULL; + Aig_ManStop( pNew ); + return vFlops; +} + +/**Function************************************************************* + + Synopsis [Starts abstraction by computing latch map.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManCexAbstractionStart( Gia_Man_t * p, Gia_ParAbs_t * pPars ) +{ + Vec_Int_t * vFlops; + if ( p->vFlopClasses != NULL ) + { + printf( "Gia_ManCexAbstractionStart(): Abstraction latch map is present but will be rederived.\n" ); + Vec_IntFreeP( &p->vFlopClasses ); + } + vFlops = Gia_ManCexAbstractionFlops( p, pPars ); + if ( vFlops ) + { + p->vFlopClasses = Gia_ManFlops2Classes( p, vFlops ); + Vec_IntFree( vFlops ); + } +} + +/**Function************************************************************* + + Synopsis [Derives abstraction using the latch map.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManCexAbstractionDerive( Gia_Man_t * pGia ) +{ + Vec_Int_t * vFlops; + Gia_Man_t * pAbs = NULL; + if ( pGia->vFlopClasses == NULL ) + { + printf( "Gia_ManCexAbstractionDerive(): Abstraction latch map is missing.\n" ); + return NULL; + } + vFlops = Gia_ManClasses2Flops( pGia->vFlopClasses ); + pAbs = Gia_ManCexAbstraction( pGia, vFlops ); + Vec_IntFree( vFlops ); + return pAbs; +} + +/**Function************************************************************* + + Synopsis [Refines abstraction using the latch map.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManCexAbstractionRefine( Gia_Man_t * pGia, Abc_Cex_t * pCex, int fVerbose ) +{ + Aig_Man_t * pNew; + Vec_Int_t * vFlops; + if ( pGia->vFlopClasses == NULL ) + { + printf( "Gia_ManCexAbstractionRefine(): Abstraction latch map is missing.\n" ); + return -1; + } + pNew = Gia_ManToAig( pGia, 0 ); + vFlops = Gia_ManClasses2Flops( pGia->vFlopClasses ); + if ( !Saig_ManCexRefineStep( pNew, vFlops, pCex, fVerbose ) ) + { + pGia->pCexSeq = pNew->pSeqModel; pNew->pSeqModel = NULL; + Vec_IntFree( vFlops ); + Aig_ManStop( pNew ); + return 0; + } + Vec_IntFree( pGia->vFlopClasses ); + pGia->vFlopClasses = Gia_ManFlops2Classes( pGia, vFlops ); + Vec_IntFree( vFlops ); + Aig_ManStop( pNew ); + return -1; +} + +/**Function************************************************************* + + Synopsis [Starts abstraction by computing latch map.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManProofAbstractionStart( Gia_Man_t * pGia, Gia_ParAbs_t * pPars ) +{ + Vec_Int_t * vFlops; + if ( pGia->vFlopClasses != NULL ) + { + printf( "Gia_ManProofAbstractionStart(): Abstraction latch map is present but will be rederived.\n" ); + Vec_IntFreeP( &pGia->vFlopClasses ); + } + vFlops = Gia_ManProofAbstractionFlops( pGia, pPars ); + if ( vFlops ) + { + pGia->vFlopClasses = Gia_ManFlops2Classes( pGia, vFlops ); + Vec_IntFree( vFlops ); + } +} + + +/**Function************************************************************* + + Synopsis [Read flop map.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Str_t * Gia_ManReadFile( char * pFileName ) +{ + FILE * pFile; + Vec_Str_t * vStr; + int c; + pFile = fopen( pFileName, "r" ); + if ( pFile == NULL ) + { + printf( "Cannot open file \"%s\".\n", pFileName ); + return NULL; + } + vStr = Vec_StrAlloc( 100 ); + while ( (c = fgetc(pFile)) != EOF ) + Vec_StrPush( vStr, (char)c ); + Vec_StrPush( vStr, '\0' ); + fclose( pFile ); + return vStr; +} + +/**Function************************************************************* + + Synopsis [Read flop map.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_ManReadBinary( char * pFileName, char * pToken ) +{ + Vec_Int_t * vMap = NULL; + Vec_Str_t * vStr; + char * pStr; + int i, Length; + vStr = Gia_ManReadFile( pFileName ); + if ( vStr == NULL ) + return NULL; + pStr = Vec_StrArray( vStr ); + pStr = strstr( pStr, pToken ); + if ( pStr != NULL ) + { + pStr += strlen( pToken ); + vMap = Vec_IntAlloc( 100 ); + Length = strlen( pStr ); + for ( i = 0; i < Length; i++ ) + { + if ( pStr[i] == '0' ) + Vec_IntPush( vMap, 0 ); + else if ( pStr[i] == '1' ) + Vec_IntPush( vMap, 1 ); + if ( ('a' <= pStr[i] && pStr[i] <= 'z') || + ('A' <= pStr[i] && pStr[i] <= 'Z') ) + break; + } + } + Vec_StrFree( vStr ); + return vMap; +} + +/**Function************************************************************* + + Synopsis [Read flop map.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManReadInteger( char * pFileName, char * pToken ) +{ + int Result = -1; + Vec_Str_t * vStr; + char * pStr; + vStr = Gia_ManReadFile( pFileName ); + if ( vStr == NULL ) + return -1; + pStr = Vec_StrArray( vStr ); + pStr = strstr( pStr, pToken ); + if ( pStr != NULL ) + Result = atoi( pStr + strlen(pToken) ); + Vec_StrFree( vStr ); + return Result; +} + + +/**Function************************************************************* + + Synopsis [Starts abstraction by computing latch map.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManCexAbstractionStartNew( Gia_Man_t * pGia, Gia_ParAbs_t * pPars ) +{ + char BufTimeOut[100]; + char BufTimeOutVT[100]; + char Command[1000]; + char * pFileNameIn = "cex_abstr_in_.aig"; + char * pFileNameOut = "cex_abstr_out_.txt"; + FILE * pFile; + Vec_Int_t * vCex; + int RetValue, clk; + if ( pGia->vFlopClasses != NULL ) + { + printf( "Gia_ManCexAbstractionStartNew(): Abstraction latch map is present but will be rederived.\n" ); + Vec_IntFreeP( &pGia->vFlopClasses ); + } + Gia_WriteAiger( pGia, pFileNameIn, 0, 0 ); + sprintf( BufTimeOut, "-timeout=%d", pPars->TimeOut ); + sprintf( BufTimeOutVT, "-vt=%d", pPars->TimeOutVT ); +//ABC switch => cex_abstr switch +//-cba => <input> <output> +//-pba => ,bmc -pba-soft <input> <output> +//-cba-then-pba => -pba-soft <input> <output> +//-cba-with-pba => -pba <input> <output> + if ( pPars->Algo == 0 ) + { + sprintf( Command, "cex_abstr %s %s -depth=%d -stable=%d -confl=%d -bob=%d %s %s %s %s", + pPars->fVerbose? "":"-quiet", + pPars->fVeryVerbose? "-sat-verbosity=1":"", + pPars->nFramesBmc, pPars->nStableMax, pPars->nConfMaxBmc, pPars->nBobPar, + pPars->TimeOut? BufTimeOut : "", + pPars->TimeOutVT? BufTimeOutVT : "", + pFileNameIn, pFileNameOut ); + } + else if ( pPars->Algo == 1 ) + { + sprintf( Command, "cex_abstr %s %s -depth=%d -confl=%d -bob=%d ,bmc -pba-soft %s %s %s %s", + pPars->fVerbose? "":"-quiet", + pPars->fVeryVerbose? "-sat-verbosity=1":"", + pPars->nFramesBmc, pPars->nConfMaxBmc, pPars->nBobPar, + pPars->TimeOut? BufTimeOut : "", + pPars->TimeOutVT? BufTimeOutVT : "", + pFileNameIn, pFileNameOut ); + } + else if ( pPars->Algo == 2 ) + { + sprintf( Command, "cex_abstr %s %s -depth=%d -stable=%d -confl=%d -bob=%d -pba-soft %s %s %s %s", + pPars->fVerbose? "":"-quiet", + pPars->fVeryVerbose? "-sat-verbosity=1":"", + pPars->nFramesBmc, pPars->nStableMax, pPars->nConfMaxBmc, pPars->nBobPar, + pPars->TimeOut? BufTimeOut : "", + pPars->TimeOutVT? BufTimeOutVT : "", + pFileNameIn, pFileNameOut ); + } + else if ( pPars->Algo == 3 ) + { + sprintf( Command, "cex_abstr %s %s -depth=%d -stable=%d -confl=%d -bob=%d -pba %s %s %s %s", + pPars->fVerbose? "":"-quiet", + pPars->fVeryVerbose? "-sat-verbosity=1":"", + pPars->nFramesBmc, pPars->nStableMax, pPars->nConfMaxBmc, pPars->nBobPar, + pPars->TimeOut? BufTimeOut : "", + pPars->TimeOutVT? BufTimeOutVT : "", + pFileNameIn, pFileNameOut ); + } + else + { + printf( "Unnknown option (algo=%d). CBA (algo=0) is assumed.\n", pPars->Algo ); + sprintf( Command, "cex_abstr %s %s -depth=%d -stable=%d -confl=%d -bob=%d %s %s %s %s", + pPars->fVerbose? "":"-quiet", + pPars->fVeryVerbose? "-sat-verbosity=1":"", + pPars->nFramesBmc, pPars->nStableMax, pPars->nConfMaxBmc, pPars->nBobPar, + pPars->TimeOut? BufTimeOut : "", + pPars->TimeOutVT? BufTimeOutVT : "", + pFileNameIn, pFileNameOut ); + } + // run the command + printf( "Executing command line \"%s\"\n", Command ); + clk = clock(); + RetValue = system( Command ); + clk = clock() - clk; +#ifdef WIN32 + _unlink( pFileNameIn ); +#else + unlink( pFileNameIn ); +#endif + if ( RetValue == -1 ) + { + fprintf( stdout, "Command \"%s\" did not succeed.\n", Command ); + return; + } + // check that the input PostScript file is okay + if ( (pFile = fopen( pFileNameOut, "r" )) == NULL ) + { + fprintf( stdout, "Cannot open intermediate file \"%s\".\n", pFileNameOut ); + return; + } + fclose( pFile ); + pPars->nFramesDone = Gia_ManReadInteger( pFileNameOut, "depth:" ); + if ( pPars->nFramesDone == -1 ) + printf( "Gia_ManCexAbstractionStartNew(): Cannot read the number of frames covered by BMC.\n" ); + pGia->vFlopClasses = Gia_ManReadBinary( pFileNameOut, "abstraction:" ); + vCex = Gia_ManReadBinary( pFileNameOut, "counter-example:" ); + if ( vCex ) + { + int nFrames = (Vec_IntSize(vCex) - Gia_ManRegNum(pGia)) / Gia_ManPiNum(pGia); + int nRemain = (Vec_IntSize(vCex) - Gia_ManRegNum(pGia)) % Gia_ManPiNum(pGia); + if ( nRemain != 0 ) + { + printf( "Counter example has a wrong length.\n" ); + } + else + { + printf( "Problem is satisfiable. Found counter-example in frame %d. ", nFrames-1 ); + Abc_PrintTime( 1, "Time", clk ); + pGia->pCexSeq = Gia_ManDeriveCexFromArray( pGia, vCex, 0, nFrames-1 ); + if ( !Gia_ManVerifyCounterExample( pGia, pGia->pCexSeq, 0 ) ) + Abc_Print( 1, "Generated counter-example is INVALID.\n" ); + pPars->Status = 0; + } + Vec_IntFreeP( &vCex ); + } +#ifdef WIN32 + _unlink( pFileNameOut ); +#else + unlink( pFileNameOut ); +#endif +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaAbs.h b/src/aig/gia/giaAbs.h new file mode 100644 index 00000000..090d5dca --- /dev/null +++ b/src/aig/gia/giaAbs.h @@ -0,0 +1,89 @@ +/**CFile**************************************************************** + + FileName [giaAbs.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [External declarations.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaAbs.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#ifndef __GIA_ABS_H__ +#define __GIA_ABS_H__ + + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// PARAMETERS /// +//////////////////////////////////////////////////////////////////////// + + + +ABC_NAMESPACE_HEADER_START + + +//////////////////////////////////////////////////////////////////////// +/// BASIC TYPES /// +//////////////////////////////////////////////////////////////////////// + +// abstraction parameters +typedef struct Gia_ParAbs_t_ Gia_ParAbs_t; +struct Gia_ParAbs_t_ +{ + int Algo; // the algorithm to be used + int nFramesMax; // timeframes for PBA + int nConfMax; // conflicts for PBA + int fDynamic; // dynamic unfolding for PBA + int fConstr; // use constraints + int nFramesBmc; // timeframes for BMC + int nConfMaxBmc; // conflicts for BMC + int nStableMax; // the number of stable frames to quit + int nRatio; // ratio of flops to quit + int TimeOut; // approximate timeout in seconds + int TimeOutVT; // approximate timeout in seconds + int nBobPar; // Bob's parameter + int fUseBdds; // use BDDs to refine abstraction + int fUseDprove; // use 'dprove' to refine abstraction + int fUseStart; // use starting frame + int fVerbose; // verbose output + int fVeryVerbose; // printing additional information + int Status; // the problem status + int nFramesDone; // the number of frames covered +}; + +extern void Gia_ManAbsSetDefaultParams( Gia_ParAbs_t * p ); + +//////////////////////////////////////////////////////////////////////// +/// MACRO DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + + + + +ABC_NAMESPACE_HEADER_END + + + +#endif + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + diff --git a/src/aig/gia/giaAig.c b/src/aig/gia/giaAig.c index fa9030c5..0e004f87 100644 --- a/src/aig/gia/giaAig.c +++ b/src/aig/gia/giaAig.c @@ -19,6 +19,12 @@ ***********************************************************************/ #include "giaAig.h" +#include "fra.h" +#include "dch.h" +#include "dar.h" + +ABC_NAMESPACE_IMPL_START + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// @@ -84,6 +90,7 @@ Gia_Man_t * Gia_ManFromAig( Aig_Man_t * p ) // create the new manager pNew = Gia_ManStart( Aig_ManObjNum(p) ); pNew->pName = Gia_UtilStrsav( p->pName ); + pNew->nConstrs = p->nConstrs; // create room to store equivalences if ( p->pEquivs ) pNew->pNexts = ABC_CALLOC( int, Aig_ManObjNum(p) ); @@ -122,6 +129,7 @@ Gia_Man_t * Gia_ManFromAigSimple( Aig_Man_t * p ) // create the new manager pNew = Gia_ManStart( Aig_ManObjNum(p) ); pNew->pName = Gia_UtilStrsav( p->pName ); + pNew->nConstrs = p->nConstrs; // create the PIs Aig_ManCleanData( p ); Aig_ManForEachObj( p, pObj, i ) @@ -138,8 +146,6 @@ Gia_Man_t * Gia_ManFromAigSimple( Aig_Man_t * p ) assert( 0 ); } Gia_ManSetRegNum( pNew, Aig_ManRegNum(p) ); - if ( pNew->pNexts ) - Gia_ManDeriveReprs( pNew ); return pNew; } @@ -162,6 +168,7 @@ Gia_Man_t * Gia_ManFromAigSwitch( Aig_Man_t * p ) // create the new manager pNew = Gia_ManStart( Aig_ManObjNum(p) ); pNew->pName = Gia_UtilStrsav( p->pName ); + pNew->nConstrs = p->nConstrs; // create the PIs Aig_ManCleanData( p ); Aig_ManConst1(p)->iData = 1; @@ -178,7 +185,7 @@ Gia_Man_t * Gia_ManFromAigSwitch( Aig_Man_t * p ) Aig_ManForEachPo( p, pObj, i ) Gia_ManFromAig_rec( pNew, p, Aig_ObjFanin0(pObj) ); Aig_ManForEachPo( p, pObj, i ) - Gia_ManAppendCo( pNew, Gia_ObjChild0Copy(pObj) ); + pObj->iData = Gia_ManAppendCo( pNew, Gia_ObjChild0Copy(pObj) ); Gia_ManSetRegNum( pNew, Aig_ManRegNum(p) ); return pNew; } @@ -240,6 +247,7 @@ Aig_Man_t * Gia_ManToAig( Gia_Man_t * p, int fChoices ) // create the new manager pNew = Aig_ManStart( Gia_ManAndNum(p) ); pNew->pName = Gia_UtilStrsav( p->pName ); + pNew->nConstrs = p->nConstrs; // pNew->pSpec = Gia_UtilStrsav( p->pName ); // duplicate representation of choice nodes if ( fChoices ) @@ -249,6 +257,10 @@ Aig_Man_t * Gia_ManToAig( Gia_Man_t * p, int fChoices ) ppNodes[0] = Aig_ManConst0(pNew); Gia_ManForEachCi( p, pObj, i ) ppNodes[Gia_ObjId(p, pObj)] = Aig_ObjCreatePi( pNew ); + // transfer level + if ( p->vLevels ) + Gia_ManForEachCi( p, pObj, i ) + Aig_ObjSetLevel( ppNodes[Gia_ObjId(p, pObj)], Gia_ObjLevel(p, pObj) ); // add logic for the POs Gia_ManForEachCo( p, pObj, i ) { @@ -282,6 +294,7 @@ Aig_Man_t * Gia_ManToAigSkip( Gia_Man_t * p, int nOutDelta ) // create the new manager pNew = Aig_ManStart( Gia_ManAndNum(p) ); pNew->pName = Gia_UtilStrsav( p->pName ); + pNew->nConstrs = p->nConstrs; // pNew->pSpec = Gia_UtilStrsav( p->pName ); // create the PIs ppNodes = ABC_CALLOC( Aig_Obj_t *, Gia_ManObjNum(p) ); @@ -312,6 +325,48 @@ Aig_Man_t * Gia_ManToAigSkip( Gia_Man_t * p, int nOutDelta ) SeeAlso [] ***********************************************************************/ +Aig_Man_t * Gia_ManToAigSimple( Gia_Man_t * p ) +{ + Aig_Man_t * pNew; + Aig_Obj_t ** ppNodes; + Gia_Obj_t * pObj; + int i; + ppNodes = ABC_ALLOC( Aig_Obj_t *, Gia_ManObjNum(p) ); + // create the new manager + pNew = Aig_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Gia_UtilStrsav( p->pName ); + pNew->nConstrs = p->nConstrs; + // create the PIs + Gia_ManForEachObj( p, pObj, i ) + { + if ( Gia_ObjIsAnd(pObj) ) + ppNodes[i] = Aig_And( pNew, Gia_ObjChild0Copy2(ppNodes, pObj, Gia_ObjId(p, pObj)), Gia_ObjChild1Copy2(ppNodes, pObj, Gia_ObjId(p, pObj)) ); + else if ( Gia_ObjIsCi(pObj) ) + ppNodes[i] = Aig_ObjCreatePi( pNew ); + else if ( Gia_ObjIsCo(pObj) ) + ppNodes[i] = Aig_ObjCreatePo( pNew, Gia_ObjChild0Copy2(ppNodes, pObj, Gia_ObjId(p, pObj)) ); + else if ( Gia_ObjIsConst0(pObj) ) + ppNodes[i] = Aig_ManConst0(pNew); + else + assert( 0 ); + pObj->Value = Gia_Var2Lit( Aig_ObjId(Aig_Regular(ppNodes[i])), Aig_IsComplement(ppNodes[i]) ); + } + Aig_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + ABC_FREE( ppNodes ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Duplicates AIG in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ Aig_Man_t * Gia_ManCofactorAig( Aig_Man_t * p, int nFrames, int nCofFanLit ) { Aig_Man_t * pMan; @@ -329,41 +384,69 @@ Aig_Man_t * Gia_ManCofactorAig( Aig_Man_t * p, int nFrames, int nCofFanLit ) Synopsis [Transfers representatives from pGia to pAig.] - Description [] + Description [Assumes that pGia was created from pAig.] SideEffects [] SeeAlso [] ***********************************************************************/ -void Gia_ManReprToAigRepr( Aig_Man_t * p, Gia_Man_t * pGia ) +void Gia_ManReprToAigRepr( Aig_Man_t * pAig, Gia_Man_t * pGia ) { Aig_Obj_t * pObj; Gia_Obj_t * pGiaObj, * pGiaRepr; int i; - assert( p->pReprs == NULL ); + assert( pAig->pReprs == NULL ); assert( pGia->pReprs != NULL ); // move pointers from AIG to GIA - Aig_ManForEachObj( p, pObj, i ) + Aig_ManForEachObj( pAig, pObj, i ) { assert( i == 0 || !Gia_LitIsCompl(pObj->iData) ); pGiaObj = Gia_ManObj( pGia, Gia_Lit2Var(pObj->iData) ); pGiaObj->Value = i; } // set the pointers to the nodes in AIG - Aig_ManReprStart( p, Aig_ManObjNumMax(p) ); + Aig_ManReprStart( pAig, Aig_ManObjNumMax(pAig) ); + Gia_ManForEachObj( pGia, pGiaObj, i ) + { + pGiaRepr = Gia_ObjReprObj( pGia, i ); + if ( pGiaRepr == NULL ) + continue; + Aig_ObjCreateRepr( pAig, Aig_ManObj(pAig, pGiaRepr->Value), Aig_ManObj(pAig, pGiaObj->Value) ); + } +} + +/**Function************************************************************* + + Synopsis [Transfers representatives from pGia to pAig.] + + Description [Assumes that pAig was created from pGia.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManReprToAigRepr2( Aig_Man_t * pAig, Gia_Man_t * pGia ) +{ + Gia_Obj_t * pGiaObj, * pGiaRepr; + int i; + assert( pAig->pReprs == NULL ); + assert( pGia->pReprs != NULL ); + // set the pointers to the nodes in AIG + Aig_ManReprStart( pAig, Aig_ManObjNumMax(pAig) ); Gia_ManForEachObj( pGia, pGiaObj, i ) { pGiaRepr = Gia_ObjReprObj( pGia, i ); if ( pGiaRepr == NULL ) continue; - Aig_ObjCreateRepr( p, Aig_ManObj(p, pGiaRepr->Value), Aig_ManObj(p, pGiaObj->Value) ); + Aig_ObjCreateRepr( pAig, Aig_ManObj(pAig, Gia_Lit2Var(pGiaRepr->Value)), Aig_ManObj(pAig, Gia_Lit2Var(pGiaObj->Value)) ); } } /**Function************************************************************* - Synopsis [Applied DC2 to the GIA manager.] + Synopsis [Transfers representatives from pAig to pGia.] Description [] @@ -372,21 +455,159 @@ void Gia_ManReprToAigRepr( Aig_Man_t * p, Gia_Man_t * pGia ) SeeAlso [] ***********************************************************************/ -Gia_Man_t * Gia_ManCompress2( Gia_Man_t * p ) +void Gia_ManReprFromAigRepr( Aig_Man_t * pAig, Gia_Man_t * pGia ) { - extern Aig_Man_t * Dar_ManCompress2( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fFanout, int fPower, int fVerbose ); + Gia_Obj_t * pObjGia; + Aig_Obj_t * pObjAig, * pReprAig; + int i; + assert( pAig->pReprs != NULL ); + assert( pGia->pReprs == NULL ); + assert( Gia_ManObjNum(pGia) - Gia_ManCoNum(pGia) == Aig_ManObjNum(pAig) - Aig_ManPoNum(pAig) ); + pGia->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(pGia) ); + for ( i = 0; i < Gia_ManObjNum(pGia); i++ ) + Gia_ObjSetRepr( pGia, i, GIA_VOID ); + Gia_ManForEachObj( pGia, pObjGia, i ) + { +// Abc_Print( 1, "%d -> %d %d\n", i, Gia_ObjValue(pObjGia), Gia_ObjValue(pObjGia)/2 ); + if ( Gia_ObjIsCo(pObjGia) ) + continue; + assert( i == 0 || !Gia_LitIsCompl(Gia_ObjValue(pObjGia)) ); + pObjAig = Aig_ManObj( pAig, Gia_Lit2Var(Gia_ObjValue(pObjGia)) ); + pObjAig->iData = i; + } + Aig_ManForEachObj( pAig, pObjAig, i ) + { + if ( Aig_ObjIsPo(pObjAig) ) + continue; + if ( pAig->pReprs[i] == NULL ) + continue; + pReprAig = pAig->pReprs[i]; + Gia_ObjSetRepr( pGia, pObjAig->iData, pReprAig->iData ); + } + pGia->pNexts = Gia_ManDeriveNexts( pGia ); +} + +/**Function************************************************************* + + Synopsis [Applies DC2 to the GIA manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManCompress2( Gia_Man_t * p, int fUpdateLevel, int fVerbose ) +{ +// extern Aig_Man_t * Dar_ManCompress2( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fFanout, int fPower, int fVerbose ); Gia_Man_t * pGia; Aig_Man_t * pNew, * pTemp; pNew = Gia_ManToAig( p, 0 ); - pNew = Dar_ManCompress2( pTemp = pNew, 1, 0, 1, 0, 0 ); + pNew = Dar_ManCompress2( pTemp = pNew, 1, fUpdateLevel, 1, 0, fVerbose ); Aig_ManStop( pTemp ); pGia = Gia_ManFromAig( pNew ); Aig_ManStop( pNew ); return pGia; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManPerformDch( Gia_Man_t * p, void * pPars ) +{ + Gia_Man_t * pGia; + Aig_Man_t * pNew; + pNew = Gia_ManToAig( p, 0 ); + pNew = Dar_ManChoiceNew( pNew, (Dch_Pars_t *)pPars ); + pGia = Gia_ManFromAig( pNew ); + Aig_ManStop( pNew ); + return pGia; +} + +/**Function************************************************************* + + Synopsis [Computes equivalences after structural sequential cleanup.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSeqCleanupClasses( Gia_Man_t * p, int fConst, int fEquiv, int fVerbose ) +{ + Aig_Man_t * pNew, * pTemp; + pNew = Gia_ManToAigSimple( p ); + pTemp = Aig_ManScl( pNew, fConst, fEquiv, fVerbose ); + Gia_ManReprFromAigRepr( pNew, p ); + Aig_ManStop( pTemp ); + Aig_ManStop( pNew ); +} + +/**Function************************************************************* + + Synopsis [Solves SAT problem.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManSolveSat( Gia_Man_t * p ) +{ +// extern int Fra_FraigSat( Aig_Man_t * pMan, ABC_INT64_T nConfLimit, ABC_INT64_T nInsLimit, int fFlipBits, int fAndOuts, int fVerbose ); + Aig_Man_t * pNew; + int RetValue, clk = clock(); + pNew = Gia_ManToAig( p, 0 ); + RetValue = Fra_FraigSat( pNew, 10000000, 0, 1, 1, 0 ); + if ( RetValue == 0 ) + { + Gia_Obj_t * pObj; + int i, * pInit = (int *)pNew->pData; + Gia_ManConst0(p)->fMark0 = 0; + Gia_ManForEachPi( p, pObj, i ) + pObj->fMark0 = pInit[i]; + Gia_ManForEachAnd( p, pObj, i ) + pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) & + (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj)); + Gia_ManForEachPo( p, pObj, i ) + pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)); + Gia_ManForEachPo( p, pObj, i ) + if ( pObj->fMark0 != 1 ) + break; + if ( i != Gia_ManPoNum(p) ) + Abc_Print( 1, "Counter-example verification has failed. " ); +// else +// Abc_Print( 1, "Counter-example verification succeeded. " ); + } +/* + else if ( RetValue == 1 ) + Abc_Print( 1, "The SAT problem is unsatisfiable. " ); + else if ( RetValue == -1 ) + Abc_Print( 1, "The SAT problem is undecided. " ); + Abc_PrintTime( 1, "Time", clock() - clk ); +*/ + Aig_ManStop( pNew ); + return RetValue; +} + + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaAig.h b/src/aig/gia/giaAig.h index 8cef5c7e..1c0a24d5 100644 --- a/src/aig/gia/giaAig.h +++ b/src/aig/gia/giaAig.h @@ -21,6 +21,7 @@ #ifndef __GIA_AIG_H__ #define __GIA_AIG_H__ + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -28,6 +29,9 @@ #include "aig.h" #include "gia.h" +ABC_NAMESPACE_HEADER_START + + //////////////////////////////////////////////////////////////////////// /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// @@ -51,12 +55,18 @@ extern Gia_Man_t * Gia_ManFromAigSimple( Aig_Man_t * p ); extern Gia_Man_t * Gia_ManFromAigSwitch( Aig_Man_t * p ); extern Aig_Man_t * Gia_ManToAig( Gia_Man_t * p, int fChoices ); extern Aig_Man_t * Gia_ManToAigSkip( Gia_Man_t * p, int nOutDelta ); -extern void Gia_ManReprToAigRepr( Aig_Man_t * p, Gia_Man_t * pGia ); -extern Gia_Man_t * Gia_ManCompress2( Gia_Man_t * p ); - -#ifdef __cplusplus -} -#endif +extern Aig_Man_t * Gia_ManToAigSimple( Gia_Man_t * p ); +extern void Gia_ManReprToAigRepr( Aig_Man_t * pAig, Gia_Man_t * pGia ); +extern void Gia_ManReprToAigRepr2( Aig_Man_t * pAig, Gia_Man_t * pGia ); +extern void Gia_ManReprFromAigRepr( Aig_Man_t * pAig, Gia_Man_t * pGia ); +extern Gia_Man_t * Gia_ManCompress2( Gia_Man_t * p, int fUpdateLevel, int fVerbose ); +extern Gia_Man_t * Gia_ManPerformDch( Gia_Man_t * p, void * pPars ); +extern Gia_Man_t * Gia_ManAbstraction( Gia_Man_t * p, Vec_Int_t * vFlops ); +extern void Gia_ManSeqCleanupClasses( Gia_Man_t * p, int fConst, int fEquiv, int fVerbose ); +extern int Gia_ManSolveSat( Gia_Man_t * p ); + + +ABC_NAMESPACE_HEADER_END #endif diff --git a/src/aig/gia/giaAiger.c b/src/aig/gia/giaAiger.c index 6c8ace8a..e201cbb9 100644 --- a/src/aig/gia/giaAiger.c +++ b/src/aig/gia/giaAiger.c @@ -21,6 +21,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -41,7 +44,7 @@ SeeAlso [] ***********************************************************************/ -unsigned Gia_ReadAigerDecode( char ** ppPos ) +unsigned Gia_ReadAigerDecode( unsigned char ** ppPos ) { unsigned x = 0, i = 0; unsigned char ch; @@ -61,7 +64,7 @@ unsigned Gia_ReadAigerDecode( char ** ppPos ) SeeAlso [] ***********************************************************************/ -Vec_Int_t * Gia_WriteDecodeLiterals( char ** ppPos, int nEntries ) +Vec_Int_t * Gia_WriteDecodeLiterals( unsigned char ** ppPos, int nEntries ) { Vec_Int_t * vLits; int Lit, LitPrev, Diff, i; @@ -151,30 +154,6 @@ char * Gia_FileNameGeneric( char * FileName ) /**Function************************************************************* - Synopsis [Returns the time stamp.] - - Description [The file should be closed.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -char * Gia_TimeStamp() -{ - static char Buffer[100]; - char * TimeStamp; - time_t ltime; - // get the current time - time( <ime ); - TimeStamp = asctime( localtime( <ime ) ); - TimeStamp[ strlen(TimeStamp) - 1 ] = 0; - strcpy( Buffer, TimeStamp ); - return Buffer; -} - -/**Function************************************************************* - Synopsis [Read integer from the string.] Description [] @@ -203,7 +182,7 @@ int Gia_ReadInt( unsigned char * pPos ) SeeAlso [] ***********************************************************************/ -unsigned Gia_ReadDiffValue( char ** ppPos, int iPrev ) +unsigned Gia_ReadDiffValue( unsigned char ** ppPos, int iPrev ) { int Item = Gia_ReadAigerDecode( ppPos ); if ( Item & 1 ) @@ -371,7 +350,8 @@ Gia_Man_t * Gia_ReadAiger( char * pFileName, int fCheck ) Vec_Int_t * vNodes, * vDrivers;//, * vTerms; int iObj, iNode0, iNode1; int nTotal, nInputs, nOutputs, nLatches, nAnds, nFileSize, i;//, iTerm, nDigits; - char * pContents, * pDrivers, * pSymbols, * pCur, * pName;//, * pType; + unsigned char * pDrivers, * pSymbols, * pCur;//, * pType; + char * pContents, * pName; unsigned uLit0, uLit1, uLit; // read the file into the buffer @@ -391,17 +371,17 @@ Gia_Man_t * Gia_ReadAiger( char * pFileName, int fCheck ) } // read the file type - pCur = pContents; while ( *pCur++ != ' ' ); + pCur = (unsigned char *)pContents; while ( *pCur++ != ' ' ); // read the number of objects - nTotal = atoi( pCur ); while ( *pCur++ != ' ' ); + nTotal = atoi( (char *)pCur ); while ( *pCur++ != ' ' ); // read the number of inputs - nInputs = atoi( pCur ); while ( *pCur++ != ' ' ); + nInputs = atoi( (char *)pCur ); while ( *pCur++ != ' ' ); // read the number of latches - nLatches = atoi( pCur ); while ( *pCur++ != ' ' ); + nLatches = atoi( (char *)pCur ); while ( *pCur++ != ' ' ); // read the number of outputs - nOutputs = atoi( pCur ); while ( *pCur++ != ' ' ); + nOutputs = atoi( (char *)pCur ); while ( *pCur++ != ' ' ); // read the number of nodes - nAnds = atoi( pCur ); while ( *pCur++ != '\n' ); + nAnds = atoi( (char *)pCur ); while ( *pCur++ != '\n' ); // check the parameters if ( nTotal != nInputs + nLatches + nAnds ) { @@ -465,14 +445,14 @@ Gia_Man_t * Gia_ReadAiger( char * pFileName, int fCheck ) pCur = pDrivers; for ( i = 0; i < nLatches; i++ ) { - uLit0 = atoi( pCur ); while ( *pCur++ != '\n' ); + uLit0 = atoi( (char *)pCur ); while ( *pCur++ != '\n' ); iNode0 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), (uLit0 & 1) ); Vec_IntPush( vDrivers, iNode0 ); } // read the PO driver literals for ( i = 0; i < nOutputs; i++ ) { - uLit0 = atoi( pCur ); while ( *pCur++ != '\n' ); + uLit0 = atoi( (char *)pCur ); while ( *pCur++ != '\n' ); iNode0 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), (uLit0 & 1) ); Vec_IntPush( vDrivers, iNode0 ); } @@ -509,7 +489,7 @@ Gia_Man_t * Gia_ReadAiger( char * pFileName, int fCheck ) // check if there are other types of information to read pCur = pSymbols; - if ( pCur + 1 < pContents + nFileSize && *pCur == 'c' ) + if ( (char *)pCur + 1 < pContents + nFileSize && *pCur == 'c' ) { pCur++; if ( *pCur == 'e' ) @@ -539,17 +519,23 @@ Gia_Man_t * Gia_ReadAiger( char * pFileName, int fCheck ) pNew->pPlacement = Gia_ReadPlacement( &pCur, Gia_ManObjNum(pNew) ); } if ( *pCur == 's' ) - { + { pCur++; // read switching activity pNew->pSwitching = Gia_ReadSwitching( &pCur, Gia_ManObjNum(pNew) ); } + if ( *pCur == 'c' ) + { + pCur++; + // read number of constraints + pNew->nConstrs = Gia_ReadInt( pCur ); pCur += 4; + } if ( *pCur == 'n' ) { pCur++; // read model name ABC_FREE( pNew->pName ); - pNew->pName = Gia_UtilStrsav( pCur ); + pNew->pName = Gia_UtilStrsav( (char *)pCur ); } } @@ -710,7 +696,7 @@ unsigned char * Gia_WriteEquivClasses( Gia_Man_t * p, int * pEquivSize ) Gia_ClassForEachObj( p, iRepr, iNode ) nItems++; } - pBuffer = ABC_ALLOC( char, sizeof(int) * (nItems + 1) ); + pBuffer = ABC_ALLOC( unsigned char, sizeof(int) * (nItems + 1) ); // write constant class iPos = Gia_WriteAigerEncode( pBuffer, 4, Gia_Var2Lit(0, 1) ); //printf( "\nRepr = %d ", 0 ); @@ -754,7 +740,7 @@ unsigned char * Gia_WriteEquivClasses( Gia_Man_t * p, int * pEquivSize ) SeeAlso [] ***********************************************************************/ -int Gia_WriteDiffValue( char * pPos, int iPos, int iPrev, int iThis ) +int Gia_WriteDiffValue( unsigned char * pPos, int iPos, int iPrev, int iThis ) { if ( iPrev < iThis ) return Gia_WriteAigerEncode( pPos, iPos, Gia_Var2Lit(iThis - iPrev, 1) ); @@ -779,16 +765,16 @@ unsigned char * Gia_WriteMapping( Gia_Man_t * p, int * pMapSize ) assert( p->pMapping ); // count the number of entries to be written nItems = 0; - Gia_ManForEachGate( p, i ) - nItems += 2 + Gia_ObjGateSize( p, i ); - pBuffer = ABC_ALLOC( char, sizeof(int) * (nItems + 1) ); + Gia_ManForEachLut( p, i ) + nItems += 2 + Gia_ObjLutSize( p, i ); + pBuffer = ABC_ALLOC( unsigned char, sizeof(int) * (nItems + 1) ); // write non-constant classes iPrev = 0; - Gia_ManForEachGate( p, i ) + Gia_ManForEachLut( p, i ) { -//printf( "\nSize = %d ", Gia_ObjGateSize(p, i) ); - iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_ObjGateSize(p, i) ); - Gia_GateForEachFanin( p, i, iFan, k ) +//printf( "\nSize = %d ", Gia_ObjLutSize(p, i) ); + iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_ObjLutSize(p, i) ); + Gia_LutForEachFanin( p, i, iFan, k ) { //printf( "Fan = %d ", iFan ); iPos = Gia_WriteDiffValue( pBuffer, iPos, iPrev, iFan ); @@ -915,8 +901,9 @@ void Gia_WriteAiger( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int // write flop classes if ( p->vFlopClasses ) { - char Buffer[10]; + unsigned char Buffer[10]; int nSize = 4*Gia_ManRegNum(p); + Gia_WriteInt( Buffer, nSize ); fprintf( pFile, "f" ); fwrite( Buffer, 1, 4, pFile ); fwrite( Vec_IntArray(p->vFlopClasses), 1, nSize, pFile ); @@ -933,7 +920,7 @@ void Gia_WriteAiger( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int // write placement if ( p->pPlacement ) { - char Buffer[10]; + unsigned char Buffer[10]; int nSize = 4*Gia_ManObjNum(p); Gia_WriteInt( Buffer, nSize ); fprintf( pFile, "p" ); @@ -943,13 +930,21 @@ void Gia_WriteAiger( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int // write flop classes if ( p->pSwitching ) { - char Buffer[10]; + unsigned char Buffer[10]; int nSize = Gia_ManObjNum(p); Gia_WriteInt( Buffer, nSize ); fprintf( pFile, "s" ); fwrite( Buffer, 1, 4, pFile ); fwrite( p->pSwitching, 1, nSize, pFile ); } + // write constraints + if ( p->nConstrs ) + { + unsigned char Buffer[10]; + Gia_WriteInt( Buffer, p->nConstrs ); + fprintf( pFile, "c" ); + fwrite( Buffer, 1, 4, pFile ); + } // write name if ( p->pName ) fprintf( pFile, "n%s%c", p->pName, '\0' ); @@ -983,3 +978,5 @@ void Gia_DumpAiger( Gia_Man_t * p, char * pFilePrefix, int iFileNum, int nFileNu //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaAiger_new.c b/src/aig/gia/giaAiger_new.c new file mode 100644 index 00000000..67981b26 --- /dev/null +++ b/src/aig/gia/giaAiger_new.c @@ -0,0 +1,1251 @@ +/**CFile**************************************************************** + + FileName [giaAiger.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Procedures to read/write binary AIGER format developed by + Armin Biere, Johannes Kepler University (http://fmv.jku.at/)] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaAiger.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef ABC_UINT64_T word; + +static inline int Gia_ObjObjPhaseDiff( Gia_Man_t * p, int i, int j ) { return Gia_ManObj(p, i)->fPhase ^ Gia_ManObj(p, j)->fPhase; } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Extracts one unsigned AIG edge from the input buffer.] + + Description [This procedure is a slightly modified version of Armin Biere's + procedure "unsigned decode (FILE * file)". ] + + SideEffects [Updates the current reading position.] + + SeeAlso [] + +***********************************************************************/ +unsigned Gia_ReadAigerDecode( char ** ppPos ) +{ + unsigned x = 0, i = 0; + unsigned char ch; + while ((ch = *(*ppPos)++) & 0x80) + x |= (ch & 0x7f) << (7 * i++); + return x | (ch << (7 * i)); +} + +/**Function************************************************************* + + Synopsis [Extracts one signed AIG edge from the input buffer.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ReadAigerDecodeInt( char ** ppPos ) +{ + unsigned Res; + Res = Gia_ReadAigerDecode( ppPos ); + if ( Res & 1 ) + return -((int)(Res >> 1)); + return Res >> 1; +} + +/**Function************************************************************* + + Synopsis [Decodes the encoded array of literals.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_WriteDecodeLiterals( char ** ppPos, int nEntries ) +{ + Vec_Int_t * vLits; + int Lit, LitPrev, Diff, i; + vLits = Vec_IntAlloc( nEntries ); + LitPrev = Gia_ReadAigerDecode( ppPos ); + Vec_IntPush( vLits, LitPrev ); + for ( i = 1; i < nEntries; i++ ) + { +// Diff = Lit - LitPrev; +// Diff = (Lit < LitPrev)? -Diff : Diff; +// Diff = ((2 * Diff) << 1) | (int)(Lit < LitPrev); + Diff = Gia_ReadAigerDecode( ppPos ); + Diff = (Diff & 1)? -(Diff >> 1) : Diff >> 1; + Lit = Diff + LitPrev; + Vec_IntPush( vLits, Lit ); + LitPrev = Lit; + } + return vLits; +} + + +/**Function************************************************************* + + Synopsis [Returns the file size.] + + Description [The file should be closed.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_FixFileName( char * pFileName ) +{ + char * pName; + for ( pName = pFileName; *pName; pName++ ) + if ( *pName == '>' ) + *pName = '\\'; +} + +/**Function************************************************************* + + Synopsis [Returns the file size.] + + Description [The file should be closed.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_FileSize( char * pFileName ) +{ + FILE * pFile; + int nFileSize; + pFile = fopen( pFileName, "r" ); + if ( pFile == NULL ) + { + printf( "Gia_FileSize(): The file is unavailable (absent or open).\n" ); + return 0; + } + fseek( pFile, 0, SEEK_END ); + nFileSize = ftell( pFile ); + fclose( pFile ); + return nFileSize; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Gia_FileNameGeneric( char * FileName ) +{ + char * pDot, * pRes; + pRes = Gia_UtilStrsav( FileName ); + if ( (pDot = strrchr( pRes, '.' )) ) + *pDot = 0; + return pRes; +} + +/**Function************************************************************* + + Synopsis [Write integer into the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ReadInt( unsigned char * pPos ) +{ + int i, Value = 0; + for ( i = 0; i < 4; i++ ) + Value |= ((unsigned)(*pPos++)) << (i << 3); + return Value; +} + +/**Function************************************************************* + + Synopsis [Reads decoded value.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned Gia_ReadDiffValue( char ** ppPos, int iPrev ) +{ + int Item = Gia_ReadAigerDecode( ppPos ); + if ( Item & 1 ) + return iPrev + (Item >> 1); + return iPrev - (Item >> 1); +} + +/**Function************************************************************* + + Synopsis [Read equivalence classes from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Rpr_t * Gia_ReadEquivClasses_old( unsigned char ** ppPos, int nSize ) +{ + Gia_Rpr_t * pReprs; + unsigned char * pStop; + int i, Item, fProved, iRepr, iNode; + pStop = *ppPos; + pStop += Gia_ReadInt( *ppPos ); *ppPos += 4; + pReprs = ABC_CALLOC( Gia_Rpr_t, nSize ); + for ( i = 0; i < nSize; i++ ) + pReprs[i].iRepr = GIA_VOID; + iRepr = iNode = 0; + while ( *ppPos < pStop ) + { + Item = Gia_ReadAigerDecode( ppPos ); + if ( Item & 1 ) + { + iRepr += (Item >> 1); + iNode = iRepr; +//printf( "\nRepr = %d ", iRepr ); + continue; + } + Item >>= 1; + fProved = (Item & 1); + Item >>= 1; + iNode += Item; + pReprs[iNode].fProved = fProved; + pReprs[iNode].iRepr = iRepr; + assert( iRepr < iNode ); +//printf( "Node = %d ", iNode ); + } + return pReprs; +} + +/**Function************************************************************* + + Synopsis [Read equivalence classes from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Rpr_t * Gia_ReadEquivClasses( unsigned char ** ppPos, int nSize, int nAlloc ) +{ + Gia_Rpr_t * pReprs; + unsigned char * pStop; + int i, k, iRepr, iNode, nMembers; + // find place to stop + pStop = *ppPos + nSize; + // prepare equivalence classes + pReprs = ABC_CALLOC( Gia_Rpr_t, nAlloc ); + for ( i = 0; i < nAlloc; i++ ) + pReprs[i].iRepr = GIA_VOID; + // skip the number of classes + Gia_ReadAigerDecode( ppPos ); + // read classes + iRepr = 0; + while ( *ppPos < pStop ) + { + nMembers = Gia_ReadAigerDecode( ppPos ); + iRepr += Gia_ReadAigerDecode( ppPos ); + iNode = iRepr; + for ( k = 1; k < nMembers; k++ ) + { + iNode += Gia_ReadAigerDecode( ppPos ); + pReprs[ Gia_Lit2Var(iNode) ].iRepr = Gia_Lit2Var(iRepr); + assert( Gia_Lit2Var(iRepr) < Gia_Lit2Var(iNode) ); +//if ( !iRepr ) +//printf( "%4d: Reading equiv %d -> %d\n", k, iNode, iRepr ); + } + } + return pReprs; +} + +/**Function************************************************************* + + Synopsis [Read flop classes from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ReadFlopClasses( unsigned char ** ppPos, Vec_Int_t * vClasses, int nSize ) +{ + int nAlloc = Gia_ReadInt( *ppPos ); *ppPos += 4; + assert( nAlloc/4 == nSize ); + assert( Vec_IntSize(vClasses) == nSize ); + memcpy( Vec_IntArray(vClasses), *ppPos, 4*nSize ); + *ppPos += 4 * nSize; +} + +/**Function************************************************************* + + Synopsis [Read equivalence classes from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int * Gia_ReadMapping( unsigned char ** ppPos, int nSize ) +{ + int * pMapping; + unsigned char * pStop; + int k, j, nFanins, nAlloc, iNode = 0, iOffset = nSize; + pStop = *ppPos; + pStop += Gia_ReadInt( *ppPos ); *ppPos += 4; + nAlloc = nSize + pStop - *ppPos; + pMapping = ABC_CALLOC( int, nAlloc ); + while ( *ppPos < pStop ) + { + k = iOffset; + pMapping[k++] = nFanins = Gia_ReadAigerDecode( ppPos ); + for ( j = 0; j <= nFanins; j++ ) + pMapping[k++] = iNode = Gia_ReadDiffValue( ppPos, iNode ); + pMapping[iNode] = iOffset; + iOffset = k; + } + assert( iOffset <= nAlloc ); + return pMapping; +} + +/**Function************************************************************* + + Synopsis [Read switching from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned char * Gia_ReadSwitching( unsigned char ** ppPos, int nSize ) +{ + unsigned char * pSwitching; + int nAlloc = Gia_ReadInt( *ppPos ); *ppPos += 4; + assert( nAlloc == nSize ); + pSwitching = ABC_ALLOC( unsigned char, nSize ); + memcpy( pSwitching, *ppPos, nSize ); + *ppPos += nSize; + return pSwitching; +} + +/**Function************************************************************* + + Synopsis [Read placement from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Plc_t * Gia_ReadPlacement( unsigned char ** ppPos, int nSize ) +{ + Gia_Plc_t * pPlacement; + int nAlloc = Gia_ReadInt( *ppPos ); *ppPos += 4; + assert( nAlloc/4 == nSize ); + pPlacement = ABC_ALLOC( Gia_Plc_t, nSize ); + memcpy( pPlacement, *ppPos, 4*nSize ); + *ppPos += 4 * nSize; + return pPlacement; +} + +/**Function************************************************************* + + Synopsis [Reads char and 64-bit int using little-endian style.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char Gia_ReadBlockHeader( char ** ppCur, word * pWord ) +{ + int i; + char Char = *(*ppCur)++; + *pWord = 0; + for ( i = 0; i < 8; i++ ) + { +// printf( "%d\n", (unsigned char)(*(*ppCur)) ); + *pWord |= ((word)(unsigned char)(*(*ppCur)++)) << (i<<3); + } + return Char; +} + +/**Function************************************************************* + + Synopsis [Reads the AIG in the binary AIGER format.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ReadAiger( char * pFileName, int fCheck ) +{ + FILE * pFile; + Gia_Man_t * pNew; + Vec_Int_t * vLits = NULL; + Vec_Int_t * vNodes, * vDrivers;//, * vTerms; + int iObj, iNode0, iNode1; + int nTotal, nInputs, nOutputs, nLatches, nAnds, nFileSize, i;//, iTerm, nDigits; + char * pContents, * pDrivers, * pSymbols, * pCur, * pName;//, * pType; + unsigned uLit0, uLit1, uLit; + + // read the file into the buffer + Gia_FixFileName( pFileName ); + nFileSize = Gia_FileSize( pFileName ); + pFile = fopen( pFileName, "rb" ); + pContents = ABC_ALLOC( char, nFileSize ); + fread( pContents, nFileSize, 1, pFile ); + fclose( pFile ); + + // check if the input file format is correct + if ( strncmp(pContents, "aig", 3) != 0 || (pContents[3] != ' ' && pContents[3] != '2') ) + { + fprintf( stdout, "Wrong input file format.\n" ); + free( pContents ); + return NULL; + } + + // read the file type + pCur = pContents; while ( *pCur++ != ' ' ); + // read the number of objects + nTotal = atoi( pCur ); while ( *pCur++ != ' ' ); + // read the number of inputs + nInputs = atoi( pCur ); while ( *pCur++ != ' ' ); + // read the number of latches + nLatches = atoi( pCur ); while ( *pCur++ != ' ' ); + // read the number of outputs + nOutputs = atoi( pCur ); while ( *pCur++ != ' ' ); + // read the number of nodes + nAnds = atoi( pCur ); while ( *pCur++ != '\n' ); + // check the parameters + if ( nTotal != nInputs + nLatches + nAnds ) + { + fprintf( stdout, "The paramters are wrong.\n" ); + return NULL; + } + + // allocate the empty AIG + pNew = Gia_ManStart( nTotal + nLatches + nOutputs + 1 ); + pName = Gia_FileNameGeneric( pFileName ); + pNew->pName = Gia_UtilStrsav( pName ); +// pNew->pSpec = Gia_UtilStrsav( pFileName ); + ABC_FREE( pName ); + + // prepare the array of nodes + vNodes = Vec_IntAlloc( 1 + nTotal ); + Vec_IntPush( vNodes, 0 ); + + // create the PIs + for ( i = 0; i < nInputs + nLatches; i++ ) + { + iObj = Gia_ManAppendCi(pNew); + Vec_IntPush( vNodes, iObj ); + } + + // remember the beginning of latch/PO literals + pDrivers = pCur; + if ( pContents[3] == ' ' ) // standard AIGER + { + // scroll to the beginning of the binary data + for ( i = 0; i < nLatches + nOutputs; ) + if ( *pCur++ == '\n' ) + i++; + } + else // modified AIGER + { + vLits = Gia_WriteDecodeLiterals( &pCur, nLatches + nOutputs ); + } + + // create the AND gates + for ( i = 0; i < nAnds; i++ ) + { + uLit = ((i + 1 + nInputs + nLatches) << 1); + uLit1 = uLit - Gia_ReadAigerDecode( &pCur ); + uLit0 = uLit1 - Gia_ReadAigerDecode( &pCur ); +// assert( uLit1 > uLit0 ); + iNode0 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), uLit0 & 1 ); + iNode1 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit1 >> 1), uLit1 & 1 ); + assert( Vec_IntSize(vNodes) == i + 1 + nInputs + nLatches ); +// Vec_IntPush( vNodes, Gia_And(pNew, iNode0, iNode1) ); + Vec_IntPush( vNodes, Gia_ManAppendAnd(pNew, iNode0, iNode1) ); + } + + // remember the place where symbols begin + pSymbols = pCur; + + // read the latch driver literals + vDrivers = Vec_IntAlloc( nLatches + nOutputs ); + if ( pContents[3] == ' ' ) // standard AIGER + { + pCur = pDrivers; + for ( i = 0; i < nLatches; i++ ) + { + uLit0 = atoi( pCur ); while ( *pCur++ != '\n' ); + iNode0 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), (uLit0 & 1) ); + Vec_IntPush( vDrivers, iNode0 ); + } + // read the PO driver literals + for ( i = 0; i < nOutputs; i++ ) + { + uLit0 = atoi( pCur ); while ( *pCur++ != '\n' ); + iNode0 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), (uLit0 & 1) ); + Vec_IntPush( vDrivers, iNode0 ); + } + + } + else + { + // read the latch driver literals + for ( i = 0; i < nLatches; i++ ) + { + uLit0 = Vec_IntEntry( vLits, i ); + iNode0 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), (uLit0 & 1) ); + Vec_IntPush( vDrivers, iNode0 ); + } + // read the PO driver literals + for ( i = 0; i < nOutputs; i++ ) + { + uLit0 = Vec_IntEntry( vLits, i+nLatches ); + iNode0 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), (uLit0 & 1) ); + Vec_IntPush( vDrivers, iNode0 ); + } + Vec_IntFree( vLits ); + } + + // create the POs + for ( i = 0; i < nOutputs; i++ ) + Gia_ManAppendCo( pNew, Vec_IntEntry(vDrivers, nLatches + i) ); + for ( i = 0; i < nLatches; i++ ) + Gia_ManAppendCo( pNew, Vec_IntEntry(vDrivers, i) ); + Vec_IntFree( vDrivers ); + + // create the latches + Gia_ManSetRegNum( pNew, nLatches ); + + // check if there are other types of information to read + pCur = pSymbols; + if ( pCur + 1 < pContents + nFileSize && *pCur == 'c' ) + { + char Char; + word Size; + pCur++; + + // read model name (old style) + if ( *pCur == 'n' ) + { + pCur++; + ABC_FREE( pNew->pName ); + pNew->pName = Gia_UtilStrsav( pCur ); + pCur += (int)(strlen(pNew->pName) + 1); + } + + Char = Gia_ReadBlockHeader( &pCur, &Size ); + if ( Char == '\n' && Size == 0xAC1D0FF1CEC0FFEE ) + { + while ( (Char = Gia_ReadBlockHeader(&pCur, &Size)) ) + { + switch (Char) + { + case 'N': + // read model name + ABC_FREE( pNew->pName ); + pNew->pName = ABC_ALLOC( char, (int)Size + 1 ); + strncpy( pNew->pName, pCur, (int)Size ); + pNew->pName[(int)Size] = '\0'; + pCur += (int)Size; + break; + case '=': + // read equivalence classes + pNew->pReprs = Gia_ReadEquivClasses( &pCur, (int)Size, Gia_ManObjNum(pNew) ); + pNew->pNexts = Gia_ManDeriveNexts( pNew ); + break; + case 'c': + // read number of constraints + pNew->nConstrs = Gia_ReadInt( pCur ); pCur += 4; + break; + default: + printf( "Unrecognized data.\n" ); + break; + } + } + } + else + { + printf( "Extended AIGER reader: Internal signature does not match.\n" ); + } + +/* + if ( *pCur == 'e' ) + { + pCur++; + // read equivalence classes + pNew->pReprs = Gia_ReadEquivClasses( &pCur, Gia_ManObjNum(pNew) ); + pNew->pNexts = Gia_ManDeriveNexts( pNew ); + } + if ( *pCur == 'f' ) + { + pCur++; + // read flop classes + pNew->vFlopClasses = Vec_IntStart( Gia_ManRegNum(pNew) ); + Gia_ReadFlopClasses( &pCur, pNew->vFlopClasses, Gia_ManRegNum(pNew) ); + } + if ( *pCur == 'm' ) + { + pCur++; + // read mapping + pNew->pMapping = Gia_ReadMapping( &pCur, Gia_ManObjNum(pNew) ); + } + if ( *pCur == 'p' ) + { + pCur++; + // read placement + pNew->pPlacement = Gia_ReadPlacement( &pCur, Gia_ManObjNum(pNew) ); + } + if ( *pCur == 's' ) + { + pCur++; + // read switching activity + pNew->pSwitching = Gia_ReadSwitching( &pCur, Gia_ManObjNum(pNew) ); + } + if ( *pCur == 'c' ) + { + pCur++; + // read number of constraints + pNew->nConstrs = Gia_ReadInt( pCur ); pCur += 4; + } + if ( *pCur == 'n' ) + { + pCur++; + // read model name + ABC_FREE( pNew->pName ); + pNew->pName = Gia_UtilStrsav( pCur ); + } +*/ + } + + // skipping the comments + ABC_FREE( pContents ); + Vec_IntFree( vNodes ); +/* + // check the result + if ( fCheck && !Gia_ManCheck( pNew ) ) + { + printf( "Gia_ReadAiger: The network check has failed.\n" ); + Gia_ManStop( pNew ); + return NULL; + } +*/ + return pNew; +} + + +/**Function************************************************************* + + Synopsis [Adds one unsigned AIG edge to the output buffer.] + + Description [This procedure is a slightly modified version of Armin Biere's + procedure "void encode (FILE * file, unsigned x)" ] + + SideEffects [Returns the current writing position.] + + SeeAlso [] + +***********************************************************************/ +int Gia_WriteAigerEncode( unsigned char * pBuffer, int Pos, unsigned x ) +{ + unsigned char ch; + while (x & ~0x7f) + { + ch = (x & 0x7f) | 0x80; + pBuffer[Pos++] = ch; + x >>= 7; + } + ch = x; + pBuffer[Pos++] = ch; + return Pos; +} + +/**Function************************************************************* + + Synopsis [Adds one signed int to the output buffer.] + + Description [] + + SideEffects [Returns the current writing position.] + + SeeAlso [] + +***********************************************************************/ +int Gia_WriteAigerEncodeInt( unsigned char * pBuffer, int Pos, int x ) +{ + if ( x >= 0 ) + return Gia_WriteAigerEncode( pBuffer, Pos, ((unsigned)(x) << 1) ); + return Gia_WriteAigerEncode( pBuffer, Pos, ((unsigned)(-x) << 1) | 1 ); +} + +/**Function************************************************************* + + Synopsis [Create the array of literals to be written.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_WriteAigerLiterals( Gia_Man_t * p ) +{ + Vec_Int_t * vLits; + Gia_Obj_t * pObj; + int i; + vLits = Vec_IntAlloc( Gia_ManPoNum(p) ); + Gia_ManForEachRi( p, pObj, i ) + Vec_IntPush( vLits, Gia_ObjFaninLit0p(p, pObj) ); + Gia_ManForEachPo( p, pObj, i ) + Vec_IntPush( vLits, Gia_ObjFaninLit0p(p, pObj) ); + return vLits; +} + +/**Function************************************************************* + + Synopsis [Creates the binary encoded array of literals.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Str_t * Gia_WriteEncodeLiterals( Vec_Int_t * vLits ) +{ + Vec_Str_t * vBinary; + int Pos = 0, Lit, LitPrev, Diff, i; + vBinary = Vec_StrAlloc( 2 * Vec_IntSize(vLits) ); + LitPrev = Vec_IntEntry( vLits, 0 ); + Pos = Gia_WriteAigerEncode( (unsigned char *)Vec_StrArray(vBinary), Pos, LitPrev ); + Vec_IntForEachEntryStart( vLits, Lit, i, 1 ) + { + Diff = Lit - LitPrev; + Diff = (Lit < LitPrev)? -Diff : Diff; + Diff = (Diff << 1) | (int)(Lit < LitPrev); + Pos = Gia_WriteAigerEncode( (unsigned char *)Vec_StrArray(vBinary), Pos, Diff ); + LitPrev = Lit; + if ( Pos + 10 > vBinary->nCap ) + Vec_StrGrow( vBinary, vBinary->nCap+1 ); + } + vBinary->nSize = Pos; +/* + // verify + { + extern Vec_Int_t * Gia_WriteDecodeLiterals( char ** ppPos, int nEntries ); + char * pPos = Vec_StrArray( vBinary ); + Vec_Int_t * vTemp = Gia_WriteDecodeLiterals( &pPos, Vec_IntSize(vLits) ); + for ( i = 0; i < Vec_IntSize(vLits); i++ ) + { + int Entry1 = Vec_IntEntry(vLits,i); + int Entry2 = Vec_IntEntry(vTemp,i); + assert( Entry1 == Entry2 ); + } + Vec_IntFree( vTemp ); + } +*/ + return vBinary; +} + +/**Function************************************************************* + + Synopsis [Write integer into the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_WriteInt( char * pBuffer, int Value ) +{ + int i; + for ( i = 0; i < 4; i++ ) + pBuffer[i] = (char)(0xff & (Value >> (i<<3))); +} + +/**Function************************************************************* + + Synopsis [Read equivalence classes from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned char * Gia_WriteEquivClasses_old( Gia_Man_t * p, int * pEquivSize ) +{ + unsigned char * pBuffer; + int iRepr, iNode, iPrevRepr, iPrevNode, iLit, nItems, iPos; + assert( p->pReprs && p->pNexts ); + // count the number of entries to be written + nItems = 0; + for ( iRepr = 1; iRepr < Gia_ManObjNum(p); iRepr++ ) + { + nItems += Gia_ObjIsConst( p, iRepr ); + if ( !Gia_ObjIsHead(p, iRepr) ) + continue; + Gia_ClassForEachObj( p, iRepr, iNode ) + nItems++; + } + pBuffer = ABC_ALLOC( char, sizeof(int) * (nItems + 1) ); + // write constant class + iPos = Gia_WriteAigerEncode( pBuffer, 4, Gia_Var2Lit(0, 1) ); + iPrevNode = 0; + for ( iNode = 1; iNode < Gia_ManObjNum(p); iNode++ ) + if ( Gia_ObjIsConst(p, iNode) ) + { + iLit = Gia_Var2Lit( iNode - iPrevNode, Gia_ObjProved(p, iNode) ); + iPrevNode = iNode; + iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_Var2Lit(iLit, 0) ); + } + // write non-constant classes + iPrevRepr = 0; + Gia_ManForEachClass( p, iRepr ) + { + iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_Var2Lit(iRepr - iPrevRepr, 1) ); + iPrevRepr = iPrevNode = iRepr; + Gia_ClassForEachObj1( p, iRepr, iNode ) + { + iLit = Gia_Var2Lit( iNode - iPrevNode, Gia_ObjProved(p, iNode) ); + iPrevNode = iNode; + iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_Var2Lit(iLit, 0) ); + } + } + Gia_WriteInt( pBuffer, iPos ); + *pEquivSize = iPos; + return pBuffer; +} + +/**Function************************************************************* + + Synopsis [Read equivalence classes from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned char * Gia_WriteEquivClasses( Gia_Man_t * p, int * pEquivSize ) +{ + unsigned char * pBuffer; + int k, iNode, iRepr, iPrevLit, iNodeLit, iPrevReprLit, iReprLit; + int nItems, iPos, nClasses, nMembers; + assert( p->pReprs && p->pNexts ); + Gia_ManSetPhase(p); + // count the number of entries to be written + nItems = 0; + nMembers = 0; + nClasses = 0; + for ( iRepr = 1; iRepr < Gia_ManObjNum(p); iRepr++ ) + { + nItems += Gia_ObjIsConst( p, iRepr ); + nMembers += Gia_ObjIsConst( p, iRepr ); + if ( !Gia_ObjIsHead(p, iRepr) ) + continue; + nClasses++; + Gia_ClassForEachObj( p, iRepr, iNode ) + nItems++; + } + nClasses += (nMembers > 0); + // allocate place for data + pBuffer = (unsigned char *)ABC_ALLOC( int, nItems+1 ); + // write the number of classes + iPos = Gia_WriteAigerEncode( pBuffer, 0, nClasses ); + // write constant class + if ( nMembers ) + { + iPos = Gia_WriteAigerEncode( pBuffer, iPos, nMembers+1 ); + iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_Var2Lit(0,0) ); + iPrevLit = Gia_Var2Lit(0,0); + k = 1; + for ( iNode = 1; iNode < Gia_ManObjNum(p); iNode++ ) + if ( Gia_ObjIsConst(p, iNode) ) + { + iNodeLit = Gia_Var2Lit( iNode, Gia_ObjPhase(Gia_ManObj(p, iNode)) ); + iPos = Gia_WriteAigerEncode( pBuffer, iPos, iNodeLit - iPrevLit ); + iPrevLit = iNodeLit; +//printf( "%4d : Writing equiv %d -> %d\n", k++, iNode, 0 ); + } + } + // write non-constant classes + iPrevReprLit = 0; + Gia_ManForEachClass( p, iRepr ) + { + // write number of members + nMembers = 0; + Gia_ClassForEachObj( p, iRepr, iNode ) + nMembers++; + iPos = Gia_WriteAigerEncode( pBuffer, iPos, nMembers ); + // write representative + iReprLit = Gia_Var2Lit( iRepr, Gia_ObjPhase(Gia_ManObj(p, iRepr)) ); + iPos = Gia_WriteAigerEncode( pBuffer, iPos, iReprLit - iPrevReprLit ); + iPrevReprLit = iReprLit; + // write members + iPrevLit = iReprLit; + Gia_ClassForEachObj1( p, iRepr, iNode ) + { + iNodeLit = Gia_Var2Lit( iNode, Gia_ObjPhase(Gia_ManObj(p, iNode)) ); + iPos = Gia_WriteAigerEncode( pBuffer, iPos, iNodeLit - iPrevLit ); + iPrevLit = iNodeLit; +//printf( "Writing equiv %d -> %d\n", iNode, iRepr ); + } + } + *pEquivSize = iPos; + return pBuffer; +} + +/**Function************************************************************* + + Synopsis [Reads decoded value.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_WriteDiffValue( char * pPos, int iPos, int iPrev, int iThis ) +{ + if ( iPrev < iThis ) + return Gia_WriteAigerEncode( pPos, iPos, Gia_Var2Lit(iThis - iPrev, 1) ); + return Gia_WriteAigerEncode( pPos, iPos, Gia_Var2Lit(iPrev - iThis, 0) ); +} + +/**Function************************************************************* + + Synopsis [Read equivalence classes from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned char * Gia_WriteMapping( Gia_Man_t * p, int * pMapSize ) +{ + unsigned char * pBuffer; + int i, k, iPrev, iFan, nItems, iPos = 4; + assert( p->pMapping ); + // count the number of entries to be written + nItems = 0; + Gia_ManForEachLut( p, i ) + nItems += 2 + Gia_ObjLutSize( p, i ); + pBuffer = ABC_ALLOC( char, sizeof(int) * (nItems + 1) ); + // write non-constant classes + iPrev = 0; + Gia_ManForEachLut( p, i ) + { +//printf( "\nSize = %d ", Gia_ObjLutSize(p, i) ); + iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_ObjLutSize(p, i) ); + Gia_LutForEachFanin( p, i, iFan, k ) + { +//printf( "Fan = %d ", iFan ); + iPos = Gia_WriteDiffValue( pBuffer, iPos, iPrev, iFan ); + iPrev = iFan; + } + iPos = Gia_WriteDiffValue( pBuffer, iPos, iPrev, i ); + iPrev = i; +//printf( "Node = %d ", i ); + } +//printf( "\n" ); + Gia_WriteInt( pBuffer, iPos ); + *pMapSize = iPos; + return pBuffer; +} + +/**Function************************************************************* + + Synopsis [Writes char and 64-bit int using little-endian style.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_WriteBlockHeader( FILE * pFile, char Char, word Word ) +{ + int i; + fprintf( pFile, "%c", Char ); + for ( i = 0; i < 8; i++ ) + fprintf( pFile, "%c", (unsigned char)(0xff & (Word >> (i<<3))) ); +} + +/**Function************************************************************* + + Synopsis [Write integer into the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_WriteIntF( FILE * pFile, int Value ) +{ + int i; + for ( i = 0; i < 4; i++ ) + fprintf( pFile, "%c", (char)(0xff & (Value >> (i<<3))) ); +} + +/**Function************************************************************* + + Synopsis [Writes the AIG in the binary AIGER format.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_WriteAiger( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int fCompact ) +{ + FILE * pFile; + Gia_Man_t * p; + Gia_Obj_t * pObj; + int i, nBufferSize, Pos; + unsigned char * pBuffer; + unsigned uLit0, uLit1, uLit; + + if ( Gia_ManCoNum(pInit) == 0 ) + { + printf( "AIG cannot be written because it has no POs.\n" ); + return; + } + + // start the output stream + pFile = fopen( pFileName, "wb" ); + if ( pFile == NULL ) + { + fprintf( stdout, "Gia_WriteAiger(): Cannot open the output file \"%s\".\n", pFileName ); + return; + } + + // create normalized AIG + if ( !Gia_ManIsNormalized(pInit) ) + { +// printf( "Gia_WriteAiger(): Normalizing AIG for writing.\n" ); + p = Gia_ManDupNormalized( pInit ); + } + else + p = pInit; + + // write the header "M I L O A" where M = I + L + A + fprintf( pFile, "aig%s %u %u %u %u %u\n", + fCompact? "2" : "", + Gia_ManCiNum(p) + Gia_ManAndNum(p), + Gia_ManPiNum(p), + Gia_ManRegNum(p), + Gia_ManPoNum(p), + Gia_ManAndNum(p) ); + + if ( !fCompact ) + { + // write latch drivers + Gia_ManForEachRi( p, pObj, i ) + fprintf( pFile, "%u\n", Gia_ObjFaninLit0p(p, pObj) ); + // write PO drivers + Gia_ManForEachPo( p, pObj, i ) + fprintf( pFile, "%u\n", Gia_ObjFaninLit0p(p, pObj) ); + } + else + { + Vec_Int_t * vLits = Gia_WriteAigerLiterals( p ); + Vec_Str_t * vBinary = Gia_WriteEncodeLiterals( vLits ); + fwrite( Vec_StrArray(vBinary), 1, Vec_StrSize(vBinary), pFile ); + Vec_StrFree( vBinary ); + Vec_IntFree( vLits ); + } + + // write the nodes into the buffer + Pos = 0; + nBufferSize = 6 * Gia_ManAndNum(p) + 100; // skeptically assuming 3 chars per one AIG edge + pBuffer = ABC_ALLOC( unsigned char, nBufferSize ); + Gia_ManForEachAnd( p, pObj, i ) + { + uLit = Gia_Var2Lit( i, 0 ); + uLit0 = Gia_ObjFaninLit0( pObj, i ); + uLit1 = Gia_ObjFaninLit1( pObj, i ); + assert( uLit0 < uLit1 ); + Pos = Gia_WriteAigerEncode( pBuffer, Pos, uLit - uLit1 ); + Pos = Gia_WriteAigerEncode( pBuffer, Pos, uLit1 - uLit0 ); + if ( Pos > nBufferSize - 10 ) + { + printf( "Gia_WriteAiger(): AIGER generation has failed because the allocated buffer is too small.\n" ); + fclose( pFile ); + if ( p != pInit ) + Gia_ManStop( p ); + return; + } + } + assert( Pos < nBufferSize ); + + // write the buffer + fwrite( pBuffer, 1, Pos, pFile ); + ABC_FREE( pBuffer ); + + // write the comment + fprintf( pFile, "c" ); + // write signature + Gia_WriteBlockHeader( pFile, '\n', 0xAC1D0FF1CEC0FFEE ); + // write name + if ( p->pName ) + { + Gia_WriteBlockHeader( pFile, 'N', (word)strlen(pInit->pName) ); + fwrite( pInit->pName, 1, strlen(pInit->pName), pFile ); + } + // write equivalences + if ( p->pReprs && p->pNexts ) + { + int nEquivSize; + unsigned char * pEquivs = Gia_WriteEquivClasses( p, &nEquivSize ); + Gia_WriteBlockHeader( pFile, '=', (word)nEquivSize ); + fwrite( pEquivs, 1, nEquivSize, pFile ); + ABC_FREE( pEquivs ); + } +/* + // write flop classes + if ( p->vFlopClasses ) + { + Gia_WriteBlockHeader( pFile, 'f', 4*Gia_ManRegNum(p) ); + fwrite( Vec_IntArray(p->vFlopClasses), 1, 4*Gia_ManRegNum(p), pFile ); + } + // write mapping + if ( p->pMapping ) + { + int nMapSize; + unsigned char * pMaps = Gia_WriteMapping( p, &nMapSize ); + Gia_WriteBlockHeader( pFile, 'm', (word)nMapSize ); + fwrite( pMaps, 1, nMapSize, pFile ); + ABC_FREE( pMaps ); + } + // write placement + if ( p->pPlacement ) + { + Gia_WriteBlockHeader( pFile, 'p', (word)4*Gia_ManObjNum(p) ); + fwrite( p->pPlacement, 1, 4*Gia_ManObjNum(p), pFile ); + } + // write switching activity + if ( p->pSwitching ) + { + Gia_WriteBlockHeader( pFile, 's', (word)Gia_ManObjNum(p) ); + fwrite( p->pSwitching, 1, Gia_ManObjNum(p), pFile ); + } + // write name + if ( p->pName ) + fprintf( pFile, "n%s%c", p->pName, '\0' ); +*/ + // write constraints + if ( p->nConstrs ) + { + Gia_WriteBlockHeader( pFile, 'c', (word)p->nConstrs ); + Gia_WriteIntF( pFile, p->nConstrs ); + } + // write the closing statement + Gia_WriteBlockHeader( pFile, '\0', (word)0 ); + // write comment + fprintf( pFile, "\nThis file was produced by the GIA package in ABC on %s\n", Gia_TimeStamp() ); + fprintf( pFile, "For information about AIGER format, refer to %s\n", "http://fmv.jku.at/aiger" ); + fclose( pFile ); + if ( p != pInit ) + Gia_ManStop( p ); +} + +/**Function************************************************************* + + Synopsis [Writes the AIG in the binary AIGER format.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_DumpAiger( Gia_Man_t * p, char * pFilePrefix, int iFileNum, int nFileNumDigits ) +{ + char Buffer[100]; + sprintf( Buffer, "%s%0*d.aig", pFilePrefix, nFileNumDigits, iFileNum ); + Gia_WriteAiger( p, Buffer, 0, 0 ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaAiger_old.c b/src/aig/gia/giaAiger_old.c new file mode 100644 index 00000000..9a5ba5cd --- /dev/null +++ b/src/aig/gia/giaAiger_old.c @@ -0,0 +1,1255 @@ +/**CFile**************************************************************** + + FileName [giaAiger.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Procedures to read/write binary AIGER format developed by + Armin Biere, Johannes Kepler University (http://fmv.jku.at/)] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaAiger.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef ABC_UINT64_T word; + +static inline int Gia_ObjObjPhaseDiff( Gia_Man_t * p, int i, int j ) { return Gia_ManObj(p, i)->fPhase ^ Gia_ManObj(p, j)->fPhase; } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Extracts one unsigned AIG edge from the input buffer.] + + Description [This procedure is a slightly modified version of Armin Biere's + procedure "unsigned decode (FILE * file)". ] + + SideEffects [Updates the current reading position.] + + SeeAlso [] + +***********************************************************************/ +unsigned Gia_ReadAigerDecode( char ** ppPos ) +{ + unsigned x = 0, i = 0; + unsigned char ch; + while ((ch = *(*ppPos)++) & 0x80) + x |= (ch & 0x7f) << (7 * i++); + return x | (ch << (7 * i)); +} + +/**Function************************************************************* + + Synopsis [Extracts one signed AIG edge from the input buffer.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ReadAigerDecodeInt( char ** ppPos ) +{ + unsigned Res; + Res = Gia_ReadAigerDecode( ppPos ); + if ( Res & 1 ) + return -((int)(Res >> 1)); + return Res >> 1; +} + +/**Function************************************************************* + + Synopsis [Decodes the encoded array of literals.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_WriteDecodeLiterals( char ** ppPos, int nEntries ) +{ + Vec_Int_t * vLits; + int Lit, LitPrev, Diff, i; + vLits = Vec_IntAlloc( nEntries ); + LitPrev = Gia_ReadAigerDecode( ppPos ); + Vec_IntPush( vLits, LitPrev ); + for ( i = 1; i < nEntries; i++ ) + { +// Diff = Lit - LitPrev; +// Diff = (Lit < LitPrev)? -Diff : Diff; +// Diff = ((2 * Diff) << 1) | (int)(Lit < LitPrev); + Diff = Gia_ReadAigerDecode( ppPos ); + Diff = (Diff & 1)? -(Diff >> 1) : Diff >> 1; + Lit = Diff + LitPrev; + Vec_IntPush( vLits, Lit ); + LitPrev = Lit; + } + return vLits; +} + + +/**Function************************************************************* + + Synopsis [Returns the file size.] + + Description [The file should be closed.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_FixFileName( char * pFileName ) +{ + char * pName; + for ( pName = pFileName; *pName; pName++ ) + if ( *pName == '>' ) + *pName = '\\'; +} + +/**Function************************************************************* + + Synopsis [Returns the file size.] + + Description [The file should be closed.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_FileSize( char * pFileName ) +{ + FILE * pFile; + int nFileSize; + pFile = fopen( pFileName, "r" ); + if ( pFile == NULL ) + { + printf( "Gia_FileSize(): The file is unavailable (absent or open).\n" ); + return 0; + } + fseek( pFile, 0, SEEK_END ); + nFileSize = ftell( pFile ); + fclose( pFile ); + return nFileSize; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Gia_FileNameGeneric( char * FileName ) +{ + char * pDot, * pRes; + pRes = Gia_UtilStrsav( FileName ); + if ( (pDot = strrchr( pRes, '.' )) ) + *pDot = 0; + return pRes; +} + +/**Function************************************************************* + + Synopsis [Write integer into the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ReadInt( unsigned char * pPos ) +{ + int i, Value = 0; + for ( i = 0; i < 4; i++ ) + Value |= ((unsigned)(*pPos++)) << (i << 3); + return Value; +} + +/**Function************************************************************* + + Synopsis [Reads decoded value.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned Gia_ReadDiffValue( char ** ppPos, int iPrev ) +{ + int Item = Gia_ReadAigerDecode( ppPos ); + if ( Item & 1 ) + return iPrev + (Item >> 1); + return iPrev - (Item >> 1); +} + +/**Function************************************************************* + + Synopsis [Read equivalence classes from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Rpr_t * Gia_ReadEquivClasses_old( unsigned char ** ppPos, int nSize ) +{ + Gia_Rpr_t * pReprs; + unsigned char * pStop; + int i, Item, fProved, iRepr, iNode; + pStop = *ppPos; + pStop += Gia_ReadInt( *ppPos ); *ppPos += 4; + pReprs = ABC_CALLOC( Gia_Rpr_t, nSize ); + for ( i = 0; i < nSize; i++ ) + pReprs[i].iRepr = GIA_VOID; + iRepr = iNode = 0; + while ( *ppPos < pStop ) + { + Item = Gia_ReadAigerDecode( ppPos ); + if ( Item & 1 ) + { + iRepr += (Item >> 1); + iNode = iRepr; +//printf( "\nRepr = %d ", iRepr ); + continue; + } + Item >>= 1; + fProved = (Item & 1); + Item >>= 1; + iNode += Item; + pReprs[iNode].fProved = fProved; + pReprs[iNode].iRepr = iRepr; + assert( iRepr < iNode ); +//printf( "Node = %d ", iNode ); + } + return pReprs; +} + +/**Function************************************************************* + + Synopsis [Read equivalence classes from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Rpr_t * Gia_ReadEquivClasses( unsigned char ** ppPos, int nSize, int nAlloc ) +{ + Gia_Rpr_t * pReprs; + unsigned char * pStop; + int i, k, iRepr, iNode, nMembers; + // find place to stop + pStop = *ppPos + nSize; + // prepare equivalence classes + pReprs = ABC_CALLOC( Gia_Rpr_t, nAlloc ); + for ( i = 0; i < nAlloc; i++ ) + pReprs[i].iRepr = GIA_VOID; + // skip the number of classes + Gia_ReadAigerDecode( ppPos ); + // read classes + iRepr = iNode = 0; + while ( *ppPos < pStop ) + { + nMembers = Gia_ReadAigerDecode( ppPos ); + iRepr += Gia_ReadAigerDecode( ppPos ) >> 1; + iNode = iRepr; + for ( k = 1; k < nMembers; k++ ) + { + iNode += Gia_ReadAigerDecode( ppPos ) >> 1; + pReprs[ iNode ].iRepr = iRepr; + assert( iRepr < iNode ); +//if ( !iRepr ) +//printf( "%4d: Reading equiv %d -> %d\n", k, iNode, iRepr ); + } + } + return pReprs; +} + +/**Function************************************************************* + + Synopsis [Read flop classes from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ReadFlopClasses( unsigned char ** ppPos, Vec_Int_t * vClasses, int nSize ) +{ + int nAlloc = Gia_ReadInt( *ppPos ); *ppPos += 4; + assert( nAlloc/4 == nSize ); + assert( Vec_IntSize(vClasses) == nSize ); + memcpy( Vec_IntArray(vClasses), *ppPos, 4*nSize ); + *ppPos += 4 * nSize; +} + +/**Function************************************************************* + + Synopsis [Read equivalence classes from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int * Gia_ReadMapping( unsigned char ** ppPos, int nSize ) +{ + int * pMapping; + unsigned char * pStop; + int k, j, nFanins, nAlloc, iNode = 0, iOffset = nSize; + pStop = *ppPos; + pStop += Gia_ReadInt( *ppPos ); *ppPos += 4; + nAlloc = nSize + pStop - *ppPos; + pMapping = ABC_CALLOC( int, nAlloc ); + while ( *ppPos < pStop ) + { + k = iOffset; + pMapping[k++] = nFanins = Gia_ReadAigerDecode( ppPos ); + for ( j = 0; j <= nFanins; j++ ) + pMapping[k++] = iNode = Gia_ReadDiffValue( ppPos, iNode ); + pMapping[iNode] = iOffset; + iOffset = k; + } + assert( iOffset <= nAlloc ); + return pMapping; +} + +/**Function************************************************************* + + Synopsis [Read switching from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned char * Gia_ReadSwitching( unsigned char ** ppPos, int nSize ) +{ + unsigned char * pSwitching; + int nAlloc = Gia_ReadInt( *ppPos ); *ppPos += 4; + assert( nAlloc == nSize ); + pSwitching = ABC_ALLOC( unsigned char, nSize ); + memcpy( pSwitching, *ppPos, nSize ); + *ppPos += nSize; + return pSwitching; +} + +/**Function************************************************************* + + Synopsis [Read placement from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Plc_t * Gia_ReadPlacement( unsigned char ** ppPos, int nSize ) +{ + Gia_Plc_t * pPlacement; + int nAlloc = Gia_ReadInt( *ppPos ); *ppPos += 4; + assert( nAlloc/4 == nSize ); + pPlacement = ABC_ALLOC( Gia_Plc_t, nSize ); + memcpy( pPlacement, *ppPos, 4*nSize ); + *ppPos += 4 * nSize; + return pPlacement; +} + +/**Function************************************************************* + + Synopsis [Reads char and 64-bit int using little-endian style.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char Gia_ReadBlockHeader( char ** ppCur, word * pWord ) +{ + int i; + char Char = *(*ppCur)++; + *pWord = 0; + for ( i = 0; i < 8; i++ ) + { +// printf( "%d\n", (unsigned char)(*(*ppCur)) ); + *pWord |= ((word)(unsigned char)(*(*ppCur)++)) << (i<<3); + } + return Char; +} + +/**Function************************************************************* + + Synopsis [Reads the AIG in the binary AIGER format.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ReadAiger( char * pFileName, int fCheck ) +{ + FILE * pFile; + Gia_Man_t * pNew; + Vec_Int_t * vLits = NULL; + Vec_Int_t * vNodes, * vDrivers;//, * vTerms; + int iObj, iNode0, iNode1; + int nTotal, nInputs, nOutputs, nLatches, nAnds, nFileSize, i;//, iTerm, nDigits; + char * pContents, * pDrivers, * pSymbols, * pCur, * pName;//, * pType; + unsigned uLit0, uLit1, uLit; + + // read the file into the buffer + Gia_FixFileName( pFileName ); + nFileSize = Gia_FileSize( pFileName ); + pFile = fopen( pFileName, "rb" ); + pContents = ABC_ALLOC( char, nFileSize ); + fread( pContents, nFileSize, 1, pFile ); + fclose( pFile ); + + // check if the input file format is correct + if ( strncmp(pContents, "aig", 3) != 0 || (pContents[3] != ' ' && pContents[3] != '2') ) + { + fprintf( stdout, "Wrong input file format.\n" ); + free( pContents ); + return NULL; + } + + // read the file type + pCur = pContents; while ( *pCur++ != ' ' ); + // read the number of objects + nTotal = atoi( pCur ); while ( *pCur++ != ' ' ); + // read the number of inputs + nInputs = atoi( pCur ); while ( *pCur++ != ' ' ); + // read the number of latches + nLatches = atoi( pCur ); while ( *pCur++ != ' ' ); + // read the number of outputs + nOutputs = atoi( pCur ); while ( *pCur++ != ' ' ); + // read the number of nodes + nAnds = atoi( pCur ); while ( *pCur++ != '\n' ); + // check the parameters + if ( nTotal != nInputs + nLatches + nAnds ) + { + fprintf( stdout, "The paramters are wrong.\n" ); + return NULL; + } + + // allocate the empty AIG + pNew = Gia_ManStart( nTotal + nLatches + nOutputs + 1 ); + pName = Gia_FileNameGeneric( pFileName ); + pNew->pName = Gia_UtilStrsav( pName ); +// pNew->pSpec = Gia_UtilStrsav( pFileName ); + ABC_FREE( pName ); + + // prepare the array of nodes + vNodes = Vec_IntAlloc( 1 + nTotal ); + Vec_IntPush( vNodes, 0 ); + + // create the PIs + for ( i = 0; i < nInputs + nLatches; i++ ) + { + iObj = Gia_ManAppendCi(pNew); + Vec_IntPush( vNodes, iObj ); + } + + // remember the beginning of latch/PO literals + pDrivers = pCur; + if ( pContents[3] == ' ' ) // standard AIGER + { + // scroll to the beginning of the binary data + for ( i = 0; i < nLatches + nOutputs; ) + if ( *pCur++ == '\n' ) + i++; + } + else // modified AIGER + { + vLits = Gia_WriteDecodeLiterals( &pCur, nLatches + nOutputs ); + } + + // create the AND gates + for ( i = 0; i < nAnds; i++ ) + { + uLit = ((i + 1 + nInputs + nLatches) << 1); + uLit1 = uLit - Gia_ReadAigerDecode( &pCur ); + uLit0 = uLit1 - Gia_ReadAigerDecode( &pCur ); +// assert( uLit1 > uLit0 ); + iNode0 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), uLit0 & 1 ); + iNode1 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit1 >> 1), uLit1 & 1 ); + assert( Vec_IntSize(vNodes) == i + 1 + nInputs + nLatches ); +// Vec_IntPush( vNodes, Gia_And(pNew, iNode0, iNode1) ); + Vec_IntPush( vNodes, Gia_ManAppendAnd(pNew, iNode0, iNode1) ); + } + + // remember the place where symbols begin + pSymbols = pCur; + + // read the latch driver literals + vDrivers = Vec_IntAlloc( nLatches + nOutputs ); + if ( pContents[3] == ' ' ) // standard AIGER + { + pCur = pDrivers; + for ( i = 0; i < nLatches; i++ ) + { + uLit0 = atoi( pCur ); while ( *pCur++ != '\n' ); + iNode0 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), (uLit0 & 1) ); + Vec_IntPush( vDrivers, iNode0 ); + } + // read the PO driver literals + for ( i = 0; i < nOutputs; i++ ) + { + uLit0 = atoi( pCur ); while ( *pCur++ != '\n' ); + iNode0 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), (uLit0 & 1) ); + Vec_IntPush( vDrivers, iNode0 ); + } + + } + else + { + // read the latch driver literals + for ( i = 0; i < nLatches; i++ ) + { + uLit0 = Vec_IntEntry( vLits, i ); + iNode0 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), (uLit0 & 1) ); + Vec_IntPush( vDrivers, iNode0 ); + } + // read the PO driver literals + for ( i = 0; i < nOutputs; i++ ) + { + uLit0 = Vec_IntEntry( vLits, i+nLatches ); + iNode0 = Gia_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), (uLit0 & 1) ); + Vec_IntPush( vDrivers, iNode0 ); + } + Vec_IntFree( vLits ); + } + + // create the POs + for ( i = 0; i < nOutputs; i++ ) + Gia_ManAppendCo( pNew, Vec_IntEntry(vDrivers, nLatches + i) ); + for ( i = 0; i < nLatches; i++ ) + Gia_ManAppendCo( pNew, Vec_IntEntry(vDrivers, i) ); + Vec_IntFree( vDrivers ); + + // create the latches + Gia_ManSetRegNum( pNew, nLatches ); + + // check if there are other types of information to read + pCur = pSymbols; + if ( pCur + 1 < pContents + nFileSize && *pCur == 'c' ) + { + char Char; + word Size; + pCur++; + + // read model name (old style) + if ( *pCur == 'n' ) + { + pCur++; + ABC_FREE( pNew->pName ); + pNew->pName = Gia_UtilStrsav( pCur ); + pCur += (int)(strlen(pNew->pName) + 1); + } + + Char = Gia_ReadBlockHeader( &pCur, &Size ); + if ( Char == '\n' && Size == 0xAC1D0FF1CEC0FFEE ) + { + while ( (Char = Gia_ReadBlockHeader(&pCur, &Size)) ) + { + switch (Char) + { + case 'N': + // read model name + ABC_FREE( pNew->pName ); + pNew->pName = ABC_ALLOC( char, (int)Size + 1 ); + strncpy( pNew->pName, pCur, (int)Size ); + pNew->pName[(int)Size] = '\0'; + pCur += (int)Size; + break; + case 'n': + // read model name + ABC_FREE( pNew->pName ); + pNew->pName = Gia_UtilStrsav( pCur ); + pCur += (int)(strlen(pNew->pName) + 1); + break; + case '=': + // read equivalence classes + pNew->pReprs = Gia_ReadEquivClasses( &pCur, (int)Size, Gia_ManObjNum(pNew) ); + pNew->pNexts = Gia_ManDeriveNexts( pNew ); + break; + case 'c': + // read number of constraints + pNew->nConstrs = Gia_ReadInt( pCur ); pCur += 4; + break; + default: + printf( "Unrecognized data.\n" ); + break; + } + } + } + else + { + printf( "Extended AIGER reader: Internal signature does not match.\n" ); + } + +/* + if ( *pCur == 'e' ) + { + pCur++; + // read equivalence classes + pNew->pReprs = Gia_ReadEquivClasses( &pCur, Gia_ManObjNum(pNew) ); + pNew->pNexts = Gia_ManDeriveNexts( pNew ); + } + if ( *pCur == 'f' ) + { + pCur++; + // read flop classes + pNew->vFlopClasses = Vec_IntStart( Gia_ManRegNum(pNew) ); + Gia_ReadFlopClasses( &pCur, pNew->vFlopClasses, Gia_ManRegNum(pNew) ); + } + if ( *pCur == 'm' ) + { + pCur++; + // read mapping + pNew->pMapping = Gia_ReadMapping( &pCur, Gia_ManObjNum(pNew) ); + } + if ( *pCur == 'p' ) + { + pCur++; + // read placement + pNew->pPlacement = Gia_ReadPlacement( &pCur, Gia_ManObjNum(pNew) ); + } + if ( *pCur == 's' ) + { + pCur++; + // read switching activity + pNew->pSwitching = Gia_ReadSwitching( &pCur, Gia_ManObjNum(pNew) ); + } + if ( *pCur == 'c' ) + { + pCur++; + // read number of constraints + pNew->nConstrs = Gia_ReadInt( pCur ); pCur += 4; + } + if ( *pCur == 'n' ) + { + pCur++; + // read model name + ABC_FREE( pNew->pName ); + pNew->pName = Gia_UtilStrsav( pCur ); + } +*/ + } + + // skipping the comments + ABC_FREE( pContents ); + Vec_IntFree( vNodes ); +/* + // check the result + if ( fCheck && !Gia_ManCheck( pNew ) ) + { + printf( "Gia_ReadAiger: The network check has failed.\n" ); + Gia_ManStop( pNew ); + return NULL; + } +*/ + return pNew; +} + + +/**Function************************************************************* + + Synopsis [Adds one unsigned AIG edge to the output buffer.] + + Description [This procedure is a slightly modified version of Armin Biere's + procedure "void encode (FILE * file, unsigned x)" ] + + SideEffects [Returns the current writing position.] + + SeeAlso [] + +***********************************************************************/ +int Gia_WriteAigerEncode( unsigned char * pBuffer, int Pos, unsigned x ) +{ + unsigned char ch; + while (x & ~0x7f) + { + ch = (x & 0x7f) | 0x80; + pBuffer[Pos++] = ch; + x >>= 7; + } + ch = x; + pBuffer[Pos++] = ch; + return Pos; +} + +/**Function************************************************************* + + Synopsis [Adds one signed int to the output buffer.] + + Description [] + + SideEffects [Returns the current writing position.] + + SeeAlso [] + +***********************************************************************/ +int Gia_WriteAigerEncodeInt( unsigned char * pBuffer, int Pos, int x ) +{ + if ( x >= 0 ) + return Gia_WriteAigerEncode( pBuffer, Pos, ((unsigned)(x) << 1) ); + return Gia_WriteAigerEncode( pBuffer, Pos, ((unsigned)(-x) << 1) | 1 ); +} + +/**Function************************************************************* + + Synopsis [Create the array of literals to be written.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_WriteAigerLiterals( Gia_Man_t * p ) +{ + Vec_Int_t * vLits; + Gia_Obj_t * pObj; + int i; + vLits = Vec_IntAlloc( Gia_ManPoNum(p) ); + Gia_ManForEachRi( p, pObj, i ) + Vec_IntPush( vLits, Gia_ObjFaninLit0p(p, pObj) ); + Gia_ManForEachPo( p, pObj, i ) + Vec_IntPush( vLits, Gia_ObjFaninLit0p(p, pObj) ); + return vLits; +} + +/**Function************************************************************* + + Synopsis [Creates the binary encoded array of literals.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Str_t * Gia_WriteEncodeLiterals( Vec_Int_t * vLits ) +{ + Vec_Str_t * vBinary; + int Pos = 0, Lit, LitPrev, Diff, i; + vBinary = Vec_StrAlloc( 2 * Vec_IntSize(vLits) ); + LitPrev = Vec_IntEntry( vLits, 0 ); + Pos = Gia_WriteAigerEncode( (unsigned char *)Vec_StrArray(vBinary), Pos, LitPrev ); + Vec_IntForEachEntryStart( vLits, Lit, i, 1 ) + { + Diff = Lit - LitPrev; + Diff = (Lit < LitPrev)? -Diff : Diff; + Diff = (Diff << 1) | (int)(Lit < LitPrev); + Pos = Gia_WriteAigerEncode( (unsigned char *)Vec_StrArray(vBinary), Pos, Diff ); + LitPrev = Lit; + if ( Pos + 10 > vBinary->nCap ) + Vec_StrGrow( vBinary, vBinary->nCap+1 ); + } + vBinary->nSize = Pos; +/* + // verify + { + extern Vec_Int_t * Gia_WriteDecodeLiterals( char ** ppPos, int nEntries ); + char * pPos = Vec_StrArray( vBinary ); + Vec_Int_t * vTemp = Gia_WriteDecodeLiterals( &pPos, Vec_IntSize(vLits) ); + for ( i = 0; i < Vec_IntSize(vLits); i++ ) + { + int Entry1 = Vec_IntEntry(vLits,i); + int Entry2 = Vec_IntEntry(vTemp,i); + assert( Entry1 == Entry2 ); + } + Vec_IntFree( vTemp ); + } +*/ + return vBinary; +} + +/**Function************************************************************* + + Synopsis [Write integer into the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_WriteInt( char * pBuffer, int Value ) +{ + int i; + for ( i = 0; i < 4; i++ ) + pBuffer[i] = (char)(0xff & (Value >> (i<<3))); +} + +/**Function************************************************************* + + Synopsis [Read equivalence classes from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned char * Gia_WriteEquivClasses_old( Gia_Man_t * p, int * pEquivSize ) +{ + unsigned char * pBuffer; + int iRepr, iNode, iPrevRepr, iPrevNode, iLit, nItems, iPos; + assert( p->pReprs && p->pNexts ); + // count the number of entries to be written + nItems = 0; + for ( iRepr = 1; iRepr < Gia_ManObjNum(p); iRepr++ ) + { + nItems += Gia_ObjIsConst( p, iRepr ); + if ( !Gia_ObjIsHead(p, iRepr) ) + continue; + Gia_ClassForEachObj( p, iRepr, iNode ) + nItems++; + } + pBuffer = ABC_ALLOC( char, sizeof(int) * (nItems + 1) ); + // write constant class + iPos = Gia_WriteAigerEncode( pBuffer, 4, Gia_Var2Lit(0, 1) ); + iPrevNode = 0; + for ( iNode = 1; iNode < Gia_ManObjNum(p); iNode++ ) + if ( Gia_ObjIsConst(p, iNode) ) + { + iLit = Gia_Var2Lit( iNode - iPrevNode, Gia_ObjProved(p, iNode) ); + iPrevNode = iNode; + iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_Var2Lit(iLit, 0) ); + } + // write non-constant classes + iPrevRepr = 0; + Gia_ManForEachClass( p, iRepr ) + { + iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_Var2Lit(iRepr - iPrevRepr, 1) ); + iPrevRepr = iPrevNode = iRepr; + Gia_ClassForEachObj1( p, iRepr, iNode ) + { + iLit = Gia_Var2Lit( iNode - iPrevNode, Gia_ObjProved(p, iNode) ); + iPrevNode = iNode; + iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_Var2Lit(iLit, 0) ); + } + } + Gia_WriteInt( pBuffer, iPos ); + *pEquivSize = iPos; + return pBuffer; +} + +/**Function************************************************************* + + Synopsis [Read equivalence classes from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned char * Gia_WriteEquivClasses( Gia_Man_t * p, int * pEquivSize ) +{ + unsigned char * pBuffer; + int k, iRepr, iNode, iPrevRepr, iPrevNode, iLit; + int nItems, iPos, nClasses, nMembers; + assert( p->pReprs && p->pNexts ); + Gia_ManSetPhase(p); + // count the number of entries to be written + nItems = 0; + nMembers = 0; + nClasses = 0; + for ( iRepr = 1; iRepr < Gia_ManObjNum(p); iRepr++ ) + { + nItems += Gia_ObjIsConst( p, iRepr ); + nMembers += Gia_ObjIsConst( p, iRepr ); + if ( !Gia_ObjIsHead(p, iRepr) ) + continue; + nClasses++; + Gia_ClassForEachObj( p, iRepr, iNode ) + nItems++; + } + nClasses += (nMembers > 0); + // allocate place for data + pBuffer = (unsigned char *)ABC_ALLOC( int, nItems+1 ); + // write the number of classes + iPos = Gia_WriteAigerEncode( pBuffer, 0, nClasses ); + // write constant class + if ( nMembers ) + { + iPos = Gia_WriteAigerEncode( pBuffer, iPos, nMembers+1 ); + iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_Var2Lit(0,0) ); + iPrevNode = 0; + k = 1; + for ( iNode = 1; iNode < Gia_ManObjNum(p); iNode++ ) + if ( Gia_ObjIsConst(p, iNode) ) + { + iLit = Gia_Var2Lit( iNode - iPrevNode, Gia_ObjObjPhaseDiff(p, iNode, 0) ); + iPos = Gia_WriteAigerEncode( pBuffer, iPos, iLit ); + iPrevNode = iNode; +//printf( "%4d : Writing equiv %d -> %d\n", k++, iNode, 0 ); + } + } + // write non-constant classes + iPrevRepr = 0; + Gia_ManForEachClass( p, iRepr ) + { + // write number of members + nMembers = 0; + Gia_ClassForEachObj( p, iRepr, iNode ) + nMembers++; + iPos = Gia_WriteAigerEncode( pBuffer, iPos, nMembers ); + // write representatives + iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_Var2Lit(iRepr - iPrevRepr, 0) ); + // write members + iPrevRepr = iPrevNode = iRepr; + Gia_ClassForEachObj1( p, iRepr, iNode ) + { + iLit = Gia_Var2Lit( iNode - iPrevNode, Gia_ObjObjPhaseDiff(p, iNode, iRepr) ); + iPos = Gia_WriteAigerEncode( pBuffer, iPos, iLit ); + iPrevNode = iNode; +//printf( "Writing equiv %d -> %d\n", iNode, iRepr ); + } + } + *pEquivSize = iPos; + return pBuffer; +} + +/**Function************************************************************* + + Synopsis [Reads decoded value.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_WriteDiffValue( char * pPos, int iPos, int iPrev, int iThis ) +{ + if ( iPrev < iThis ) + return Gia_WriteAigerEncode( pPos, iPos, Gia_Var2Lit(iThis - iPrev, 1) ); + return Gia_WriteAigerEncode( pPos, iPos, Gia_Var2Lit(iPrev - iThis, 0) ); +} + +/**Function************************************************************* + + Synopsis [Read equivalence classes from the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned char * Gia_WriteMapping( Gia_Man_t * p, int * pMapSize ) +{ + unsigned char * pBuffer; + int i, k, iPrev, iFan, nItems, iPos = 4; + assert( p->pMapping ); + // count the number of entries to be written + nItems = 0; + Gia_ManForEachLut( p, i ) + nItems += 2 + Gia_ObjLutSize( p, i ); + pBuffer = ABC_ALLOC( char, sizeof(int) * (nItems + 1) ); + // write non-constant classes + iPrev = 0; + Gia_ManForEachLut( p, i ) + { +//printf( "\nSize = %d ", Gia_ObjLutSize(p, i) ); + iPos = Gia_WriteAigerEncode( pBuffer, iPos, Gia_ObjLutSize(p, i) ); + Gia_LutForEachFanin( p, i, iFan, k ) + { +//printf( "Fan = %d ", iFan ); + iPos = Gia_WriteDiffValue( pBuffer, iPos, iPrev, iFan ); + iPrev = iFan; + } + iPos = Gia_WriteDiffValue( pBuffer, iPos, iPrev, i ); + iPrev = i; +//printf( "Node = %d ", i ); + } +//printf( "\n" ); + Gia_WriteInt( pBuffer, iPos ); + *pMapSize = iPos; + return pBuffer; +} + +/**Function************************************************************* + + Synopsis [Writes char and 64-bit int using little-endian style.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_WriteBlockHeader( FILE * pFile, char Char, word Word ) +{ + int i; + fprintf( pFile, "%c", Char ); + for ( i = 0; i < 8; i++ ) + fprintf( pFile, "%c", (unsigned char)(0xff & (Word >> (i<<3))) ); +} + +/**Function************************************************************* + + Synopsis [Write integer into the string.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_WriteIntF( FILE * pFile, int Value ) +{ + int i; + for ( i = 0; i < 4; i++ ) + fprintf( pFile, "%c", (char)(0xff & (Value >> (i<<3))) ); +} + +/**Function************************************************************* + + Synopsis [Writes the AIG in the binary AIGER format.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_WriteAiger( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int fCompact ) +{ + FILE * pFile; + Gia_Man_t * p; + Gia_Obj_t * pObj; + int i, nBufferSize, Pos; + unsigned char * pBuffer; + unsigned uLit0, uLit1, uLit; + + if ( Gia_ManCoNum(pInit) == 0 ) + { + printf( "AIG cannot be written because it has no POs.\n" ); + return; + } + + // start the output stream + pFile = fopen( pFileName, "wb" ); + if ( pFile == NULL ) + { + fprintf( stdout, "Gia_WriteAiger(): Cannot open the output file \"%s\".\n", pFileName ); + return; + } + + // create normalized AIG + if ( !Gia_ManIsNormalized(pInit) ) + { +// printf( "Gia_WriteAiger(): Normalizing AIG for writing.\n" ); + p = Gia_ManDupNormalized( pInit ); + } + else + p = pInit; + + // write the header "M I L O A" where M = I + L + A + fprintf( pFile, "aig%s %u %u %u %u %u\n", + fCompact? "2" : "", + Gia_ManCiNum(p) + Gia_ManAndNum(p), + Gia_ManPiNum(p), + Gia_ManRegNum(p), + Gia_ManPoNum(p), + Gia_ManAndNum(p) ); + + if ( !fCompact ) + { + // write latch drivers + Gia_ManForEachRi( p, pObj, i ) + fprintf( pFile, "%u\n", Gia_ObjFaninLit0p(p, pObj) ); + // write PO drivers + Gia_ManForEachPo( p, pObj, i ) + fprintf( pFile, "%u\n", Gia_ObjFaninLit0p(p, pObj) ); + } + else + { + Vec_Int_t * vLits = Gia_WriteAigerLiterals( p ); + Vec_Str_t * vBinary = Gia_WriteEncodeLiterals( vLits ); + fwrite( Vec_StrArray(vBinary), 1, Vec_StrSize(vBinary), pFile ); + Vec_StrFree( vBinary ); + Vec_IntFree( vLits ); + } + + // write the nodes into the buffer + Pos = 0; + nBufferSize = 6 * Gia_ManAndNum(p) + 100; // skeptically assuming 3 chars per one AIG edge + pBuffer = ABC_ALLOC( unsigned char, nBufferSize ); + Gia_ManForEachAnd( p, pObj, i ) + { + uLit = Gia_Var2Lit( i, 0 ); + uLit0 = Gia_ObjFaninLit0( pObj, i ); + uLit1 = Gia_ObjFaninLit1( pObj, i ); + assert( uLit0 < uLit1 ); + Pos = Gia_WriteAigerEncode( pBuffer, Pos, uLit - uLit1 ); + Pos = Gia_WriteAigerEncode( pBuffer, Pos, uLit1 - uLit0 ); + if ( Pos > nBufferSize - 10 ) + { + printf( "Gia_WriteAiger(): AIGER generation has failed because the allocated buffer is too small.\n" ); + fclose( pFile ); + if ( p != pInit ) + Gia_ManStop( p ); + return; + } + } + assert( Pos < nBufferSize ); + + // write the buffer + fwrite( pBuffer, 1, Pos, pFile ); + ABC_FREE( pBuffer ); + + // write the comment + fprintf( pFile, "c" ); + // write signature + Gia_WriteBlockHeader( pFile, '\n', 0xAC1D0FF1CEC0FFEE ); + // write name + if ( p->pName ) + { + Gia_WriteBlockHeader( pFile, 'N', (word)strlen(pInit->pName) ); + fwrite( pInit->pName, 1, strlen(pInit->pName), pFile ); + } + // write equivalences + if ( p->pReprs && p->pNexts ) + { + int nEquivSize; + unsigned char * pEquivs = Gia_WriteEquivClasses( p, &nEquivSize ); + Gia_WriteBlockHeader( pFile, '=', (word)nEquivSize ); + fwrite( pEquivs, 1, nEquivSize, pFile ); + ABC_FREE( pEquivs ); + } + // write flop classes + if ( p->vFlopClasses ) + { + Gia_WriteBlockHeader( pFile, 'f', 4*Gia_ManRegNum(p) ); + fwrite( Vec_IntArray(p->vFlopClasses), 1, 4*Gia_ManRegNum(p), pFile ); + } +/* + // write mapping + if ( p->pMapping ) + { + int nMapSize; + unsigned char * pMaps = Gia_WriteMapping( p, &nMapSize ); + Gia_WriteBlockHeader( pFile, 'm', (word)nMapSize ); + fwrite( pMaps, 1, nMapSize, pFile ); + ABC_FREE( pMaps ); + } + // write placement + if ( p->pPlacement ) + { + Gia_WriteBlockHeader( pFile, 'p', (word)4*Gia_ManObjNum(p) ); + fwrite( p->pPlacement, 1, 4*Gia_ManObjNum(p), pFile ); + } + // write switching activity + if ( p->pSwitching ) + { + Gia_WriteBlockHeader( pFile, 's', (word)Gia_ManObjNum(p) ); + fwrite( p->pSwitching, 1, Gia_ManObjNum(p), pFile ); + } + // write name + if ( p->pName ) + fprintf( pFile, "n%s%c", p->pName, '\0' ); +*/ + // write constraints + if ( p->nConstrs ) + { + Gia_WriteBlockHeader( pFile, 'c', (word)p->nConstrs ); + Gia_WriteIntF( pFile, p->nConstrs ); + } + // write the closing statement + Gia_WriteBlockHeader( pFile, '\0', (word)0 ); + // write comment + fprintf( pFile, "\nThis file was produced by the GIA package in ABC on %s\n", Gia_TimeStamp() ); + fprintf( pFile, "For information about AIGER format, refer to %s\n", "http://fmv.jku.at/aiger" ); + fclose( pFile ); + if ( p != pInit ) + Gia_ManStop( p ); +} + +/**Function************************************************************* + + Synopsis [Writes the AIG in the binary AIGER format.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_DumpAiger( Gia_Man_t * p, char * pFilePrefix, int iFileNum, int nFileNumDigits ) +{ + char Buffer[100]; + sprintf( Buffer, "%s%0*d.aig", pFilePrefix, nFileNumDigits, iFileNum ); + Gia_WriteAiger( p, Buffer, 0, 0 ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaBidec.c b/src/aig/gia/giaBidec.c new file mode 100644 index 00000000..fc17b582 --- /dev/null +++ b/src/aig/gia/giaBidec.c @@ -0,0 +1,308 @@ +/**CFile**************************************************************** + + FileName [giaBidec.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Application of bi-decomposition to AIG minimization.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaBidec.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" +#include "bdc.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static inline int Bdc_FunObjCopy( Bdc_Fun_t * pObj ) { return Gia_LitNotCond( Bdc_FuncCopyInt(Bdc_Regular(pObj)), Bdc_IsComplement(pObj) ); } +static inline int Bdc_FunFanin0Copy( Bdc_Fun_t * pObj ) { return Bdc_FunObjCopy( Bdc_FuncFanin0(pObj) ); } +static inline int Bdc_FunFanin1Copy( Bdc_Fun_t * pObj ) { return Bdc_FunObjCopy( Bdc_FuncFanin1(pObj) ); } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Computes truth table of the cut.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned * Gia_ManConvertAigToTruth_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vTruth, int nWords, Vec_Int_t * vVisited ) +{ + unsigned * pTruth, * pTruth0, * pTruth1; + int i; + assert( !Gia_IsComplement(pObj) ); + if ( Vec_IntGetEntry(p->vTruths, Gia_ObjId(p, pObj)) != -1 ) + return (unsigned *)Vec_IntEntryP( vTruth, nWords * Vec_IntGetEntry(p->vTruths, Gia_ObjId(p, pObj)) ); + // compute the truth tables of the fanins + pTruth0 = Gia_ManConvertAigToTruth_rec( p, Gia_ObjFanin0(pObj), vTruth, nWords, vVisited ); + pTruth1 = Gia_ManConvertAigToTruth_rec( p, Gia_ObjFanin1(pObj), vTruth, nWords, vVisited ); + // get room for the truth table + pTruth = Vec_IntFetch( vTruth, nWords ); + // create the truth table of the node + if ( !Gia_ObjFaninC0(pObj) && !Gia_ObjFaninC1(pObj) ) + for ( i = 0; i < nWords; i++ ) + pTruth[i] = pTruth0[i] & pTruth1[i]; + else if ( !Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) ) + for ( i = 0; i < nWords; i++ ) + pTruth[i] = pTruth0[i] & ~pTruth1[i]; + else if ( Gia_ObjFaninC0(pObj) && !Gia_ObjFaninC1(pObj) ) + for ( i = 0; i < nWords; i++ ) + pTruth[i] = ~pTruth0[i] & pTruth1[i]; + else // if ( Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) ) + for ( i = 0; i < nWords; i++ ) + pTruth[i] = ~pTruth0[i] & ~pTruth1[i]; + // save the visited node + Vec_IntSetEntry( p->vTruths, Gia_ObjId(p, pObj), Vec_IntSize(vVisited) ); + Vec_IntPush( vVisited, Gia_ObjId(p, pObj) ); + return pTruth; +} + +/**Function************************************************************* + + Synopsis [Computes truth table of the node.] + + Description [Assumes that the structural support is no more than 8 inputs. + Uses array vTruth to store temporary truth tables. The returned pointer should + be used immediately.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned * Gia_ManConvertAigToTruth( Gia_Man_t * p, Gia_Obj_t * pRoot, Vec_Int_t * vLeaves, Vec_Int_t * vTruth, Vec_Int_t * vVisited ) +{ + static unsigned uTruths[8][8] = { // elementary truth tables + { 0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA }, + { 0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC }, + { 0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0 }, + { 0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00 }, + { 0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000 }, + { 0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF }, + { 0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF }, + { 0x00000000,0x00000000,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF } + }; + Gia_Obj_t * pObj; + Vec_Ptr_t * vTtElems = NULL; + unsigned * pTruth;//, * pTruth2; + int i, nWords, nVars; + // get the number of variables and words + nVars = Vec_IntSize( vLeaves ); + nWords = Gia_TruthWordNum( nVars ); + // check the case of a constant + if ( Gia_ObjIsConst0( Gia_Regular(pRoot) ) ) + { + Vec_IntClear( vTruth ); + // get room for the truth table + pTruth = Vec_IntFetch( vTruth, nWords ); + if ( !Gia_IsComplement(pRoot) ) + Gia_ManTruthClear( pTruth, nVars ); + else + Gia_ManTruthFill( pTruth, nVars ); + return pTruth; + } + // if the number of variables is more than 8, allocate truth tables + if ( nVars > 8 ) + vTtElems = Vec_PtrAllocTruthTables( nVars ); + // assign elementary truth tables + Vec_IntClear( vTruth ); + Vec_IntClear( vVisited ); + Gia_ManForEachObjVec( vLeaves, p, pObj, i ) + { + // get room for the truth table + pTruth = Vec_IntFetch( vTruth, nWords ); + // assign elementary variable + if ( vTtElems ) + Gia_ManTruthCopy( pTruth, (unsigned *)Vec_PtrEntry(vTtElems, i), nVars ); + else + Gia_ManTruthCopy( pTruth, uTruths[i], nVars ); + // save the visited node + Vec_IntSetEntry( p->vTruths, Gia_ObjId(p, pObj), Vec_IntSize(vVisited) ); + Vec_IntPush( vVisited, Gia_ObjId(p, pObj) ); + } + if ( vTtElems ) + Vec_PtrFree( vTtElems ); + // clear the marks and compute the truth table +// pTruth2 = Gia_ManConvertAigToTruth_rec( p, Gia_Regular(pRoot), vTruth, nWords, vVisited ); + pTruth = Gia_ManConvertAigToTruth_rec( p, Gia_Regular(pRoot), vTruth, nWords, vVisited ); + // copy the result +// Gia_ManTruthCopy( pTruth, pTruth2, nVars ); + if ( Gia_IsComplement(pRoot) ) + Gia_ManTruthNot( pTruth, pTruth, nVars ); + // clean truth tables + Gia_ManForEachObjVec( vVisited, p, pObj, i ) + Vec_IntSetEntry( p->vTruths, Gia_ObjId(p, pObj), -1 ); + return pTruth; +} + +/**Function************************************************************* + + Synopsis [Resynthesizes nodes using bi-decomposition.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ObjPerformBidec( Bdc_Man_t * pManDec, + Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pRoot, + Vec_Int_t * vLeaves, Vec_Int_t * vTruth, Vec_Int_t * vVisited ) +{ + unsigned * pTruth; + Bdc_Fun_t * pFunc; + Gia_Obj_t * pFanin; + int i, iFan, nVars, nNodes; + // collect leaves of this gate + Vec_IntClear( vLeaves ); + Gia_LutForEachFanin( p, Gia_ObjId(p, pRoot), iFan, i ) + Vec_IntPush( vLeaves, iFan ); + nVars = Vec_IntSize( vLeaves ); + assert( nVars < 16 ); + // derive truth table + pTruth = Gia_ManConvertAigToTruth( p, pRoot, vLeaves, vTruth, vVisited ); +//Extra_PrintBinary( stdout, pTruth, (1<<nVars) ); printf( "\n" ); + if ( Gia_ManTruthIsConst0(pTruth, nVars) ) + { +//printf( "Node %d is const0\n", Gia_ObjId(p, pRoot) ); + return 0; + } + if ( Gia_ManTruthIsConst1(pTruth, nVars) ) + { +//printf( "Node %d is const1\n", Gia_ObjId(p, pRoot) ); + return 1; + } + // decompose truth table + Bdc_ManDecompose( pManDec, pTruth, NULL, nVars, NULL, 1000 ); +/* +if ( Bdc_ManNodeNum(pManDec) == 0 ) + printf( "Node %d has 0 bidec nodes\n", Gia_ObjId(p, pRoot) ); +if ( Kit_TruthSupportSize(pTruth, nVars) != nVars ) +{ + printf( "Node %d has %d fanins and %d supp size\n", Gia_ObjId(p, pRoot), nVars, Kit_TruthSupportSize(pTruth, nVars) ); + Gia_LutForEachFanin( p, Gia_ObjId(p, pRoot), iFan, i ) + { + printf( "%d ", Kit_TruthVarInSupport(pTruth, nVars, i) ); + Gia_ObjPrint( p, Gia_ManObj(p, iFan) ); + } +// Gia_ManPrintStats( p, 0 ); +} +*/ + // convert back into HOP + Bdc_FuncSetCopy( Bdc_ManFunc( pManDec, 0 ), Gia_ManConst1(pNew) ); + Gia_ManForEachObjVec( vLeaves, p, pFanin, i ) + Bdc_FuncSetCopyInt( Bdc_ManFunc( pManDec, i+1 ), Gia_ObjValue(pFanin) ); + nNodes = Bdc_ManNodeNum( pManDec ); + for ( i = nVars + 1; i < nNodes; i++ ) + { + pFunc = Bdc_ManFunc( pManDec, i ); + Bdc_FuncSetCopyInt( pFunc, Gia_ManHashAnd( pNew, Bdc_FunFanin0Copy(pFunc), Bdc_FunFanin1Copy(pFunc) ) ); + } + return Bdc_FunObjCopy( Bdc_ManRoot(pManDec) ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManPerformBidec( Gia_Man_t * p, int fVerbose ) +{ + Bdc_Man_t * pManDec; + Bdc_Par_t Pars = {0}, * pPars = &Pars; + Vec_Int_t * vLeaves, * vTruth, * vVisited; + Gia_Man_t * pNew, * pTemp; + Gia_Obj_t * pObj; + int i, clk = clock(); + pPars->nVarsMax = Gia_ManLutSizeMax( p ); + pPars->fVerbose = fVerbose; + if ( pPars->nVarsMax < 2 ) + { + printf( "Resynthesis is not performed when nodes have less than 2 inputs.\n" ); + return NULL; + } + if ( pPars->nVarsMax > 15 ) + { + printf( "Resynthesis is not performed when nodes have more than 15 inputs.\n" ); + return NULL; + } + vLeaves = Vec_IntAlloc( 0 ); + vTruth = Vec_IntAlloc( (1<<16) ); + vVisited = Vec_IntAlloc( 0 ); + // clean the old manager + Gia_ManCleanTruth( p ); + Gia_ManFillValue( p ); + Gia_ManConst0(p)->Value = 0; + // start the new manager + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Gia_UtilStrsav( p->pName ); + Gia_ManHashAlloc( pNew ); +// Gia_ManCleanLevels( pNew, Gia_ManObjNum(p) ); + pManDec = Bdc_ManAlloc( pPars ); + Gia_ManForEachObj1( p, pObj, i ) + { + if ( Gia_ObjIsCi(pObj) ) // transfer the CI level (is it needed?) + pObj->Value = Gia_ManAppendCi( pNew ); + else if ( Gia_ObjIsCo(pObj) ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + else if ( Gia_ObjIsLut(p, i) ) + pObj->Value = Gia_ObjPerformBidec( pManDec, pNew, p, pObj, vLeaves, vTruth, vVisited ); + } + Bdc_ManFree( pManDec ); + // cleanup the AIG + Gia_ManHashStop( pNew ); + // check the presence of dangling nodes + if ( Gia_ManHasDangling(pNew) ) + { + pNew = Gia_ManCleanup( pTemp = pNew ); + if ( Gia_ManAndNum(pNew) != Gia_ManAndNum(pTemp) ) + printf( "Gia_ManPerformBidec() node count before and after: %6d and %6d.\n", Gia_ManAndNum(pNew), Gia_ManAndNum(pTemp) ); + Gia_ManStop( pTemp ); + } + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + Vec_IntFree( vLeaves ); + Vec_IntFree( vTruth ); + Vec_IntFree( vVisited ); + if ( fVerbose ) + { +// printf( "Total gain in AIG nodes = %d. ", Gia_ManObjNum(p)-Gia_ManObjNum(pNew) ); +// ABC_PRT( "Total runtime", clock() - clk ); + } + return pNew; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaCSat.c b/src/aig/gia/giaCSat.c index e3aca7df..1c5b05fe 100644 --- a/src/aig/gia/giaCSat.c +++ b/src/aig/gia/giaCSat.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //#define gia_assert(exp) ((void)0) //#define gia_assert(exp) (assert(exp)) @@ -627,7 +630,7 @@ static inline void Cbs_ManDeriveReason( Cbs_Man_t * p, int Level ) assert( pQue->pData[pQue->iHead] != NULL ); pQue->iTail = k; // clear the marks - Vec_PtrForEachEntry( p->vTemp, pObj, i ) + Vec_PtrForEachEntry( Gia_Obj_t *, p->vTemp, pObj, i ) pObj->fMark0 = 1; } @@ -1094,3 +1097,5 @@ Vec_Int_t * Cbs_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvSt //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaCSatOld.c b/src/aig/gia/giaCSatOld.c index bd8f061b..983081f0 100644 --- a/src/aig/gia/giaCSatOld.c +++ b/src/aig/gia/giaCSatOld.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -796,3 +799,5 @@ Vec_Int_t * Cbs_ManSolveMiter( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvStat //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaCTas.c b/src/aig/gia/giaCTas.c new file mode 100644 index 00000000..c6aa3fec --- /dev/null +++ b/src/aig/gia/giaCTas.c @@ -0,0 +1,1788 @@ +/**CFile**************************************************************** + + FileName [giaCSat.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [A simple circuit-based solver.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaCSat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +ABC_NAMESPACE_IMPL_START + + +//#define gia_assert(exp) ((void)0) +//#define gia_assert(exp) (assert(exp)) + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Tas_Par_t_ Tas_Par_t; +struct Tas_Par_t_ +{ + // conflict limits + int nBTLimit; // limit on the number of conflicts + int nJustLimit; // limit on the size of justification queue + // current parameters + int nBTThis; // number of conflicts + int nBTThisNc; // number of conflicts + int nJustThis; // max size of the frontier + int nBTTotal; // total number of conflicts + int nJustTotal; // total size of the frontier + // activity + float VarDecay; // variable activity decay + int VarInc; // variable increment + // decision heuristics + int fUseActive; // use most active + int fUseHighest; // use node with the highest ID + int fUseLowest; // use node with the highest ID + int fUseMaxFF; // use node with the largest fanin fanout + // other + int fVerbose; +}; + +typedef struct Tas_Cls_t_ Tas_Cls_t; +struct Tas_Cls_t_ +{ + int iNext[2]; // beginning of the queue + int nLits; // the number of literals + int pLits[0]; // clause literals +}; + +typedef struct Tas_Sto_t_ Tas_Sto_t; +struct Tas_Sto_t_ +{ + int iCur; // current position + int nSize; // allocated size + int * pData; // clause information +}; + +typedef struct Tas_Que_t_ Tas_Que_t; +struct Tas_Que_t_ +{ + int iHead; // beginning of the queue + int iTail; // end of the queue + int nSize; // allocated size + Gia_Obj_t ** pData; // nodes stored in the queue +}; + +struct Tas_Man_t_ +{ + Tas_Par_t Pars; // parameters + Gia_Man_t * pAig; // AIG manager + Tas_Que_t pProp; // propagation queue + Tas_Que_t pJust; // justification queue + Tas_Que_t pClauses; // clause queue + Gia_Obj_t ** pIter; // iterator through clause vars + Vec_Int_t * vLevReas; // levels and decisions + Vec_Int_t * vModel; // satisfying assignment + Vec_Ptr_t * vTemp; // temporary storage + // watched clauses + Tas_Sto_t pStore; // storage for watched clauses + int * pWatches; // watched lists for each literal + Vec_Int_t * vWatchLits; // lits whose watched are assigned + int nClauses; // the counter of clauses + // activity + float * pActivity; // variable activity + Vec_Int_t * vActiveVars; // variables with activity + // SAT calls statistics + int nSatUnsat; // the number of proofs + int nSatSat; // the number of failure + int nSatUndec; // the number of timeouts + int nSatTotal; // the number of calls + // conflicts + int nConfUnsat; // conflicts in unsat problems + int nConfSat; // conflicts in sat problems + int nConfUndec; // conflicts in undec problems + // runtime stats + int timeSatUnsat; // unsat + int timeSatSat; // sat + int timeSatUndec; // undecided + int timeTotal; // total runtime +}; + +static inline int Tas_VarIsAssigned( Gia_Obj_t * pVar ) { return pVar->fMark0; } +static inline void Tas_VarAssign( Gia_Obj_t * pVar ) { assert(!pVar->fMark0); pVar->fMark0 = 1; } +static inline void Tas_VarUnassign( Gia_Obj_t * pVar ) { assert(pVar->fMark0); pVar->fMark0 = 0; pVar->fMark1 = 0; pVar->Value = ~0; } +static inline int Tas_VarValue( Gia_Obj_t * pVar ) { assert(pVar->fMark0); return pVar->fMark1; } +static inline void Tas_VarSetValue( Gia_Obj_t * pVar, int v ) { assert(pVar->fMark0); pVar->fMark1 = v; } +static inline int Tas_VarIsJust( Gia_Obj_t * pVar ) { return Gia_ObjIsAnd(pVar) && !Tas_VarIsAssigned(Gia_ObjFanin0(pVar)) && !Tas_VarIsAssigned(Gia_ObjFanin1(pVar)); } +static inline int Tas_VarFanin0Value( Gia_Obj_t * pVar ) { return !Tas_VarIsAssigned(Gia_ObjFanin0(pVar)) ? 2 : (Tas_VarValue(Gia_ObjFanin0(pVar)) ^ Gia_ObjFaninC0(pVar)); } +static inline int Tas_VarFanin1Value( Gia_Obj_t * pVar ) { return !Tas_VarIsAssigned(Gia_ObjFanin1(pVar)) ? 2 : (Tas_VarValue(Gia_ObjFanin1(pVar)) ^ Gia_ObjFaninC1(pVar)); } +static inline int Tas_VarToLit( Tas_Man_t * p, Gia_Obj_t * pObj ) { assert( Tas_VarIsAssigned(pObj) ); return Gia_Var2Lit( Gia_ObjId(p->pAig, pObj), !Tas_VarValue(pObj) ); } +static inline int Tas_LitIsTrue( Gia_Obj_t * pObj, int Lit ) { assert( Tas_VarIsAssigned(pObj) ); return Tas_VarValue(pObj) != Gia_LitIsCompl(Lit); } + +static inline int Tas_ClsHandle( Tas_Man_t * p, Tas_Cls_t * pClause ) { return ((int *)pClause) - p->pStore.pData; } +static inline Tas_Cls_t * Tas_ClsFromHandle( Tas_Man_t * p, int h ) { return (Tas_Cls_t *)(p->pStore.pData + h); } + +static inline int Tas_VarDecLevel( Tas_Man_t * p, Gia_Obj_t * pVar ) { assert( pVar->Value != ~0 ); return Vec_IntEntry(p->vLevReas, 3*pVar->Value); } +static inline Gia_Obj_t * Tas_VarReason0( Tas_Man_t * p, Gia_Obj_t * pVar ) { assert( pVar->Value != ~0 ); return pVar + Vec_IntEntry(p->vLevReas, 3*pVar->Value+1); } +static inline Gia_Obj_t * Tas_VarReason1( Tas_Man_t * p, Gia_Obj_t * pVar ) { assert( pVar->Value != ~0 ); return pVar + Vec_IntEntry(p->vLevReas, 3*pVar->Value+2); } +static inline int Tas_ClauseDecLevel( Tas_Man_t * p, int hClause ) { return Tas_VarDecLevel( p, p->pClauses.pData[hClause] ); } + +static inline int Tas_VarHasReasonCls( Tas_Man_t * p, Gia_Obj_t * pVar ) { assert( pVar->Value != ~0 ); return Vec_IntEntry(p->vLevReas, 3*pVar->Value+1) == 0 && Vec_IntEntry(p->vLevReas, 3*pVar->Value+2) != 0; } +static inline Tas_Cls_t * Tas_VarReasonCls( Tas_Man_t * p, Gia_Obj_t * pVar ) { assert( pVar->Value != ~0 ); return Tas_ClsFromHandle( p, Vec_IntEntry(p->vLevReas, 3*pVar->Value+2) ); } + +#define Tas_QueForEachEntry( Que, pObj, i ) \ + for ( i = (Que).iHead; (i < (Que).iTail) && ((pObj) = (Que).pData[i]); i++ ) + +#define Tas_ClauseForEachVar( p, hClause, pObj ) \ + for ( (p)->pIter = (p)->pClauses.pData + hClause; (pObj = *pIter); (p)->pIter++ ) +#define Tas_ClauseForEachVar1( p, hClause, pObj ) \ + for ( (p)->pIter = (p)->pClauses.pData+hClause+1; (pObj = *pIter); (p)->pIter++ ) + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Sets default values of the parameters.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Tas_SetDefaultParams( Tas_Par_t * pPars ) +{ + memset( pPars, 0, sizeof(Tas_Par_t) ); + pPars->nBTLimit = 2000; // limit on the number of conflicts + pPars->nJustLimit = 2000; // limit on the size of justification queue + pPars->fUseActive = 0; // use node with the highest activity + pPars->fUseHighest = 1; // use node with the highest ID + pPars->fUseLowest = 0; // use node with the lowest ID + pPars->fUseMaxFF = 0; // use node with the largest fanin fanout + pPars->fVerbose = 1; // print detailed statistics + pPars->VarDecay = (float)0.95; // variable decay + pPars->VarInc = 1.0; // variable increment +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Tas_Man_t * Tas_ManAlloc( Gia_Man_t * pAig, int nBTLimit ) +{ + Tas_Man_t * p; + p = ABC_CALLOC( Tas_Man_t, 1 ); + Tas_SetDefaultParams( &p->Pars ); + p->pAig = pAig; + p->Pars.nBTLimit = nBTLimit; + p->pProp.nSize = p->pJust.nSize = p->pClauses.nSize = 10000; + p->pProp.pData = ABC_ALLOC( Gia_Obj_t *, p->pProp.nSize ); + p->pJust.pData = ABC_ALLOC( Gia_Obj_t *, p->pJust.nSize ); + p->pClauses.pData = ABC_ALLOC( Gia_Obj_t *, p->pClauses.nSize ); + p->pClauses.iHead = p->pClauses.iTail = 1; + p->vModel = Vec_IntAlloc( 1000 ); + p->vLevReas = Vec_IntAlloc( 1000 ); + p->vTemp = Vec_PtrAlloc( 1000 ); + p->pStore.iCur = 16; + p->pStore.nSize = 10000; + p->pStore.pData = ABC_ALLOC( int, p->pStore.nSize ); + p->pWatches = ABC_CALLOC( int, 2 * Gia_ManObjNum(pAig) ); + p->vWatchLits = Vec_IntAlloc( 100 ); + p->pActivity = ABC_CALLOC( float, Gia_ManObjNum(pAig) ); + p->vActiveVars = Vec_IntAlloc( 100 ); + return p; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Tas_ManStop( Tas_Man_t * p ) +{ + Vec_IntFree( p->vActiveVars ); + Vec_IntFree( p->vWatchLits ); + Vec_IntFree( p->vLevReas ); + Vec_IntFree( p->vModel ); + Vec_PtrFree( p->vTemp ); + ABC_FREE( p->pActivity ); + ABC_FREE( p->pWatches ); + ABC_FREE( p->pStore.pData ); + ABC_FREE( p->pClauses.pData ); + ABC_FREE( p->pProp.pData ); + ABC_FREE( p->pJust.pData ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [Returns satisfying assignment.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Tas_ReadModel( Tas_Man_t * p ) +{ + return p->vModel; +} + + + + +/**Function************************************************************* + + Synopsis [Returns 1 if the solver is out of limits.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Tas_ManCheckLimits( Tas_Man_t * p ) +{ + return p->Pars.nJustThis > p->Pars.nJustLimit || p->Pars.nBTThis > p->Pars.nBTLimit; +} + +/**Function************************************************************* + + Synopsis [Saves the satisfying assignment as an array of literals.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Tas_ManSaveModel( Tas_Man_t * p, Vec_Int_t * vCex ) +{ + Gia_Obj_t * pVar; + int i; + Vec_IntClear( vCex ); + p->pProp.iHead = 0; +// printf( "\n" ); + Tas_QueForEachEntry( p->pProp, pVar, i ) + { + if ( Gia_ObjIsCi(pVar) ) +// Vec_IntPush( vCex, Gia_Var2Lit(Gia_ObjId(p->pAig,pVar), !Tas_VarValue(pVar)) ); + Vec_IntPush( vCex, Gia_Var2Lit(Gia_ObjCioId(pVar), !Tas_VarValue(pVar)) ); +/* + printf( "%5d(%d) = ", Gia_ObjId(p->pAig, pVar), Tas_VarValue(pVar) ); + if ( Gia_ObjIsCi(pVar) ) + printf( "pi %d\n", Gia_ObjCioId(pVar) ); + else + { + printf( "%5d %d & ", Gia_ObjFaninId0p(p->pAig, pVar), Gia_ObjFaninC0(pVar) ); + printf( "%5d %d ", Gia_ObjFaninId1p(p->pAig, pVar), Gia_ObjFaninC1(pVar) ); + printf( "\n" ); + } +*/ + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Tas_QueIsEmpty( Tas_Que_t * p ) +{ + return p->iHead == p->iTail; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Tas_QuePush( Tas_Que_t * p, Gia_Obj_t * pObj ) +{ + if ( p->iTail == p->nSize ) + { + p->nSize *= 2; + p->pData = ABC_REALLOC( Gia_Obj_t *, p->pData, p->nSize ); + } + p->pData[p->iTail++] = pObj; +} + +/**Function************************************************************* + + Synopsis [Returns 1 if the object in the queue.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Tas_QueHasNode( Tas_Que_t * p, Gia_Obj_t * pObj ) +{ + Gia_Obj_t * pTemp; + int i; + Tas_QueForEachEntry( *p, pTemp, i ) + if ( pTemp == pObj ) + return 1; + return 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Tas_QueStore( Tas_Que_t * p, int * piHeadOld, int * piTailOld ) +{ + int i; + *piHeadOld = p->iHead; + *piTailOld = p->iTail; + for ( i = *piHeadOld; i < *piTailOld; i++ ) + Tas_QuePush( p, p->pData[i] ); + p->iHead = *piTailOld; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Tas_QueRestore( Tas_Que_t * p, int iHeadOld, int iTailOld ) +{ + p->iHead = iHeadOld; + p->iTail = iTailOld; +} + +/**Function************************************************************* + + Synopsis [Finalized the clause.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Tas_QueFinish( Tas_Que_t * p ) +{ + int iHeadOld = p->iHead; + assert( p->iHead < p->iTail ); + Tas_QuePush( p, NULL ); + p->iHead = p->iTail; + return iHeadOld; +} + + +/**Function************************************************************* + + Synopsis [Max number of fanins fanouts.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Tas_VarFaninFanoutMax( Tas_Man_t * p, Gia_Obj_t * pObj ) +{ + int Count0, Count1; + assert( !Gia_IsComplement(pObj) ); + assert( Gia_ObjIsAnd(pObj) ); + Count0 = Gia_ObjRefs( p->pAig, Gia_ObjFanin0(pObj) ); + Count1 = Gia_ObjRefs( p->pAig, Gia_ObjFanin1(pObj) ); + return ABC_MAX( Count0, Count1 ); +} + + + +/**Function************************************************************* + + Synopsis [Find variable with the highest activity.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Gia_Obj_t * Tas_ManFindActive( Tas_Man_t * p ) +{ + Gia_Obj_t * pObj, * pObjMax = NULL; + float BestCost = 0.0; + int i, ObjId; + Tas_QueForEachEntry( p->pJust, pObj, i ) + { + assert( Gia_ObjIsAnd(pObj) ); + ObjId = Gia_ObjId( p->pAig, pObj ); + if ( pObjMax == NULL || + p->pActivity[Gia_ObjFaninId0(pObj,ObjId)] > BestCost || + (p->pActivity[Gia_ObjFaninId0(pObj,ObjId)] == BestCost && pObjMax < Gia_ObjFanin0(pObj)) ) + { + pObjMax = Gia_ObjFanin0(pObj); + BestCost = p->pActivity[Gia_ObjFaninId0(pObj,ObjId)]; + } + if ( p->pActivity[Gia_ObjFaninId1(pObj,ObjId)] > BestCost || + (p->pActivity[Gia_ObjFaninId1(pObj,ObjId)] == BestCost && pObjMax < Gia_ObjFanin1(pObj)) ) + { + pObjMax = Gia_ObjFanin1(pObj); + BestCost = p->pActivity[Gia_ObjFaninId1(pObj,ObjId)]; + } + } + return pObjMax; +} + +/**Function************************************************************* + + Synopsis [Find variable with the highest activity.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Gia_Obj_t * Tas_ManDecideHighestFanin( Tas_Man_t * p ) +{ + Gia_Obj_t * pObj, * pObjMax = NULL; + int i, ObjId; + Tas_QueForEachEntry( p->pJust, pObj, i ) + { + assert( Gia_ObjIsAnd(pObj) ); + ObjId = Gia_ObjId( p->pAig, pObj ); + if ( pObjMax == NULL || pObjMax < Gia_ObjFanin0(pObj) ) + pObjMax = Gia_ObjFanin0(pObj); + if ( pObjMax < Gia_ObjFanin1(pObj) ) + pObjMax = Gia_ObjFanin1(pObj); + } + return pObjMax; +} + +/**Function************************************************************* + + Synopsis [Find variable with the highest ID.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Gia_Obj_t * Tas_ManDecideHighest( Tas_Man_t * p ) +{ + Gia_Obj_t * pObj, * pObjMax = NULL; + int i; + Tas_QueForEachEntry( p->pJust, pObj, i ) + { +//printf( "%d %6.2f ", Gia_ObjId(p->pAig, pObj), p->pActivity[Gia_ObjId(p->pAig, pObj)] ); + if ( pObjMax == NULL || pObjMax < pObj ) + pObjMax = pObj; + } +//printf( "\n" ); + return pObjMax; +} + +/**Function************************************************************* + + Synopsis [Find variable with the highest ID.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Gia_Obj_t * Tas_ManDecideHighestA( Tas_Man_t * p ) +{ + Gia_Obj_t * pObj, * pObjMax = NULL; + int i; + Tas_QueForEachEntry( p->pJust, pObj, i ) + { + if ( pObjMax == NULL || + p->pActivity[Gia_ObjId(p->pAig, pObjMax)] < p->pActivity[Gia_ObjId(p->pAig, pObj)] ) + pObjMax = pObj; + } + return pObjMax; +} + +/**Function************************************************************* + + Synopsis [Find variable with the lowest ID.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Gia_Obj_t * Tas_ManDecideLowest( Tas_Man_t * p ) +{ + Gia_Obj_t * pObj, * pObjMin = NULL; + int i; + Tas_QueForEachEntry( p->pJust, pObj, i ) + if ( pObjMin == NULL || pObjMin > pObj ) + pObjMin = pObj; + return pObjMin; +} + +/**Function************************************************************* + + Synopsis [Find variable with the maximum number of fanin fanouts.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Gia_Obj_t * Tas_ManDecideMaxFF( Tas_Man_t * p ) +{ + Gia_Obj_t * pObj, * pObjMax = NULL; + int i, iMaxFF = 0, iCurFF; + assert( p->pAig->pRefs != NULL ); + Tas_QueForEachEntry( p->pJust, pObj, i ) + { + iCurFF = Tas_VarFaninFanoutMax( p, pObj ); + assert( iCurFF > 0 ); + if ( iMaxFF < iCurFF ) + { + iMaxFF = iCurFF; + pObjMax = pObj; + } + } + return pObjMax; +} + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Tas_ManCancelUntil( Tas_Man_t * p, int iBound ) +{ + Gia_Obj_t * pVar; + int i; + assert( iBound <= p->pProp.iTail ); + p->pProp.iHead = iBound; + Tas_QueForEachEntry( p->pProp, pVar, i ) + Tas_VarUnassign( pVar ); + p->pProp.iTail = iBound; + Vec_IntShrink( p->vLevReas, 3*iBound ); +} + +int s_Counter2 = 0; +int s_Counter3 = 0; +int s_Counter4 = 0; + +/**Function************************************************************* + + Synopsis [Assigns the variables a value.] + + Description [Returns 1 if conflict; 0 if no conflict.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Tas_ManAssign( Tas_Man_t * p, Gia_Obj_t * pObj, int Level, Gia_Obj_t * pRes0, Gia_Obj_t * pRes1 ) +{ + Gia_Obj_t * pObjR = Gia_Regular(pObj); + assert( Gia_ObjIsCand(pObjR) ); + assert( !Tas_VarIsAssigned(pObjR) ); + Tas_VarAssign( pObjR ); + Tas_VarSetValue( pObjR, !Gia_IsComplement(pObj) ); + assert( pObjR->Value == ~0 ); + pObjR->Value = p->pProp.iTail; + Tas_QuePush( &p->pProp, pObjR ); + Vec_IntPush( p->vLevReas, Level ); + if ( pRes0 == NULL && pRes1 != 0 ) // clause + { + Vec_IntPush( p->vLevReas, 0 ); + Vec_IntPush( p->vLevReas, Tas_ClsHandle( p, (Tas_Cls_t *)pRes1 ) ); + } + else + { + Vec_IntPush( p->vLevReas, pRes0 ? pRes0-pObjR : 0 ); + Vec_IntPush( p->vLevReas, pRes1 ? pRes1-pObjR : 0 ); + } + assert( Vec_IntSize(p->vLevReas) == 3 * p->pProp.iTail ); + s_Counter2++; +} + + +/**Function************************************************************* + + Synopsis [Returns clause size.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Tas_ManClauseSize( Tas_Man_t * p, int hClause ) +{ + Tas_Que_t * pQue = &(p->pClauses); + Gia_Obj_t ** pIter; + for ( pIter = pQue->pData + hClause; *pIter; pIter++ ); + return pIter - pQue->pData - hClause ; +} + +/**Function************************************************************* + + Synopsis [Prints conflict clause.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Tas_ManPrintClause( Tas_Man_t * p, int Level, int hClause ) +{ + Tas_Que_t * pQue = &(p->pClauses); + Gia_Obj_t * pObj; + int i; + assert( Tas_QueIsEmpty( pQue ) ); + printf( "Level %2d : ", Level ); + for ( i = hClause; (pObj = pQue->pData[i]); i++ ) + printf( "%d=%d(%d) ", Gia_ObjId(p->pAig, pObj), Tas_VarValue(pObj), Tas_VarDecLevel(p, pObj) ); + printf( "\n" ); +} + +/**Function************************************************************* + + Synopsis [Prints conflict clause.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Tas_ManPrintClauseNew( Tas_Man_t * p, int Level, int hClause ) +{ + Tas_Que_t * pQue = &(p->pClauses); + Gia_Obj_t * pObj; + int i; + assert( Tas_QueIsEmpty( pQue ) ); + printf( "Level %2d : ", Level ); + for ( i = hClause; (pObj = pQue->pData[i]); i++ ) + printf( "%c%d ", Tas_VarValue(pObj)? '+':'-', Gia_ObjId(p->pAig, pObj) ); + printf( "\n" ); +} + +/**Function************************************************************* + + Synopsis [Returns conflict clause.] + + Description [Performs conflict analysis.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Tas_ManDeriveReason( Tas_Man_t * p, int Level ) +{ + Tas_Que_t * pQue = &(p->pClauses); + Gia_Obj_t * pObj, * pReason; + int i, k, j, iLitLevel, iLitLevel2;//, Id; + assert( pQue->pData[pQue->iHead] == NULL ); + assert( pQue->iHead + 1 < pQue->iTail ); +/* + for ( i = pQue->iHead + 1; i < pQue->iTail; i++ ) + { + pObj = pQue->pData[i]; + assert( pObj->fPhase == 0 ); + } +*/ + // compact literals + Vec_PtrClear( p->vTemp ); + for ( i = k = pQue->iHead + 1; i < pQue->iTail; i++ ) + { + pObj = pQue->pData[i]; + if ( pObj->fPhase ) // unassigned - seen again + continue; + // assigned - seen first time + pObj->fPhase = 1; + Vec_PtrPush( p->vTemp, pObj ); + // bump activity +// Id = Gia_ObjId( p->pAig, pObj ); +// if ( p->pActivity[Id] == 0.0 ) +// Vec_IntPush( p->vActiveVars, Id ); +// p->pActivity[Id] += p->Pars.VarInc; + // check decision level + iLitLevel = Tas_VarDecLevel( p, pObj ); + if ( iLitLevel < Level ) + { + pQue->pData[k++] = pObj; + continue; + } + assert( iLitLevel == Level ); + if ( Tas_VarHasReasonCls( p, pObj ) ) + { + Tas_Cls_t * pCls = Tas_VarReasonCls( p, pObj ); + pReason = Gia_ManObj( p->pAig, Gia_Lit2Var(pCls->pLits[0]) ); + assert( pReason == pObj ); + for ( j = 1; j < pCls->nLits; j++ ) + { + pReason = Gia_ManObj( p->pAig, Gia_Lit2Var(pCls->pLits[j]) ); + iLitLevel2 = Tas_VarDecLevel( p, pReason ); + assert( Tas_VarIsAssigned( pReason ) ); + assert( !Tas_LitIsTrue( pReason, pCls->pLits[j] ) ); + Tas_QuePush( pQue, pReason ); + } + } + else + { + pReason = Tas_VarReason0( p, pObj ); + if ( pReason == pObj ) // no reason + { + assert( pQue->pData[pQue->iHead] == NULL || Level == 0 ); + if ( pQue->pData[pQue->iHead] == NULL ) + pQue->pData[pQue->iHead] = pObj; + else + Tas_QuePush( pQue, pObj ); + continue; + } + Tas_QuePush( pQue, pReason ); + pReason = Tas_VarReason1( p, pObj ); + if ( pReason != pObj ) // second reason + Tas_QuePush( pQue, pReason ); + } + } + assert( pQue->pData[pQue->iHead] != NULL ); + if ( pQue->pData[pQue->iHead] == NULL ) + printf( "Tas_ManDeriveReason(): Failed to derive the clause!!!\n" ); + pQue->iTail = k; + // clear the marks + Vec_PtrForEachEntry( Gia_Obj_t *, p->vTemp, pObj, i ) + pObj->fPhase = 0; +} + +/**Function************************************************************* + + Synopsis [Returns conflict clause.] + + Description [Performs conflict analysis.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Tas_ManAnalyze( Tas_Man_t * p, int Level, Gia_Obj_t * pVar, Gia_Obj_t * pFan0, Gia_Obj_t * pFan1 ) +{ + Tas_Que_t * pQue = &(p->pClauses); + assert( Tas_VarIsAssigned(pVar) ); + assert( Tas_VarIsAssigned(pFan0) ); + assert( pFan1 == NULL || Tas_VarIsAssigned(pFan1) ); + assert( Tas_QueIsEmpty( pQue ) ); + Tas_QuePush( pQue, NULL ); + Tas_QuePush( pQue, pVar ); + Tas_QuePush( pQue, pFan0 ); + if ( pFan1 ) + Tas_QuePush( pQue, pFan1 ); + Tas_ManDeriveReason( p, Level ); + return Tas_QueFinish( pQue ); +} + + +/**Function************************************************************* + + Synopsis [Performs resolution of two clauses.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Tas_ManResolve( Tas_Man_t * p, int Level, int hClause0, int hClause1 ) +{ + Tas_Que_t * pQue = &(p->pClauses); + Gia_Obj_t * pObj; + int i, LevelMax = -1, LevelCur; + assert( pQue->pData[hClause0] != NULL ); + assert( pQue->pData[hClause0] == pQue->pData[hClause1] ); +/* + for ( i = hClause0 + 1; (pObj = pQue->pData[i]); i++ ) + assert( pObj->fPhase == 0 ); + for ( i = hClause1 + 1; (pObj = pQue->pData[i]); i++ ) + assert( pObj->fPhase == 0 ); +*/ + assert( Tas_QueIsEmpty( pQue ) ); + Tas_QuePush( pQue, NULL ); + for ( i = hClause0 + 1; (pObj = pQue->pData[i]); i++ ) + { + if ( pObj->fPhase ) // unassigned - seen again + continue; + // assigned - seen first time + pObj->fPhase = 1; + Tas_QuePush( pQue, pObj ); + LevelCur = Tas_VarDecLevel( p, pObj ); + if ( LevelMax < LevelCur ) + LevelMax = LevelCur; + } + for ( i = hClause1 + 1; (pObj = pQue->pData[i]); i++ ) + { + if ( pObj->fPhase ) // unassigned - seen again + continue; + // assigned - seen first time + pObj->fPhase = 1; + Tas_QuePush( pQue, pObj ); + LevelCur = Tas_VarDecLevel( p, pObj ); + if ( LevelMax < LevelCur ) + LevelMax = LevelCur; + } + for ( i = pQue->iHead + 1; i < pQue->iTail; i++ ) + pQue->pData[i]->fPhase = 0; + Tas_ManDeriveReason( p, LevelMax ); + return Tas_QueFinish( pQue ); +} + + + +/**Function************************************************************* + + Synopsis [Allocates clause of the given size.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Tas_Cls_t * Tas_ManAllocCls( Tas_Man_t * p, int nSize ) +{ + Tas_Cls_t * pCls; + if ( p->pStore.iCur + nSize > p->pStore.nSize ) + { + p->pStore.nSize *= 2; + p->pStore.pData = ABC_REALLOC( int, p->pStore.pData, p->pStore.nSize ); + } + pCls = Tas_ClsFromHandle( p, p->pStore.iCur ); p->pStore.iCur += nSize; + memset( pCls, 0, sizeof(int) * nSize ); + p->nClauses++; + return pCls; +} + +/**Function************************************************************* + + Synopsis [Adds one clause to the watcher list.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Tas_ManWatchClause( Tas_Man_t * p, Tas_Cls_t * pClause, int Lit ) +{ + assert( Gia_Lit2Var(Lit) < Gia_ManObjNum(p->pAig) ); + assert( pClause->nLits >= 2 ); + assert( pClause->pLits[0] == Lit || pClause->pLits[1] == Lit ); + if ( pClause->pLits[0] == Lit ) + pClause->iNext[0] = p->pWatches[Gia_LitNot(Lit)]; + else + pClause->iNext[1] = p->pWatches[Gia_LitNot(Lit)]; + if ( p->pWatches[Gia_LitNot(Lit)] == 0 ) + Vec_IntPush( p->vWatchLits, Gia_LitNot(Lit) ); + p->pWatches[Gia_LitNot(Lit)] = Tas_ClsHandle( p, pClause ); +} + +/**Function************************************************************* + + Synopsis [Creates clause of the given size.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Tas_Cls_t * Tas_ManCreateCls( Tas_Man_t * p, int hClause ) +{ + Tas_Cls_t * pClause; + Tas_Que_t * pQue = &(p->pClauses); + Gia_Obj_t * pObj; + int i, nLits = 0; + assert( Tas_QueIsEmpty( pQue ) ); + assert( pQue->pData[hClause] != NULL ); + for ( i = hClause; (pObj = pQue->pData[i]); i++ ) + nLits++; + if ( nLits == 1 ) + return NULL; + // create this clause + pClause = Tas_ManAllocCls( p, nLits + 3 ); + pClause->nLits = nLits; + for ( i = hClause; (pObj = pQue->pData[i]); i++ ) + { + assert( Tas_VarIsAssigned( pObj ) ); + pClause->pLits[i-hClause] = Gia_LitNot( Tas_VarToLit(p, pObj) ); + } + // add the clause as watched one + if ( nLits >= 2 ) + { + Tas_ManWatchClause( p, pClause, pClause->pLits[0] ); + Tas_ManWatchClause( p, pClause, pClause->pLits[1] ); + } + // increment activity +// p->Pars.VarInc /= p->Pars.VarDecay; + return pClause; +} + +/**Function************************************************************* + + Synopsis [Creates clause of the given size.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Tas_ManCreateFromCls( Tas_Man_t * p, Tas_Cls_t * pCls, int Level ) +{ + Tas_Que_t * pQue = &(p->pClauses); + Gia_Obj_t * pObj; + int i; + assert( Tas_QueIsEmpty( pQue ) ); + Tas_QuePush( pQue, NULL ); + for ( i = 0; i < pCls->nLits; i++ ) + { + pObj = Gia_ManObj( p->pAig, Gia_Lit2Var(pCls->pLits[i]) ); + assert( Tas_VarIsAssigned(pObj) ); + assert( !Tas_LitIsTrue( pObj, pCls->pLits[i] ) ); + Tas_QuePush( pQue, pObj ); + } + Tas_ManDeriveReason( p, Level ); + return Tas_QueFinish( pQue ); +} + +/**Function************************************************************* + + Synopsis [Propagate one assignment.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Tas_ManPropagateWatch( Tas_Man_t * p, int Level, int Lit ) +{ + Gia_Obj_t * pObj; + Tas_Cls_t * pCur; + int * piPrev, iCur, iTemp; + int i, LitF = Gia_LitNot(Lit); + // iterate through the clauses + piPrev = p->pWatches + Lit; + for ( iCur = p->pWatches[Lit]; iCur; iCur = *piPrev ) + { + pCur = Tas_ClsFromHandle( p, iCur ); + // make sure the false literal is in the second literal of the clause + if ( pCur->pLits[0] == LitF ) + { + pCur->pLits[0] = pCur->pLits[1]; + pCur->pLits[1] = LitF; + iTemp = pCur->iNext[0]; + pCur->iNext[0] = pCur->iNext[1]; + pCur->iNext[1] = iTemp; + } + assert( pCur->pLits[1] == LitF ); + + // if the first literal is true, the clause is satisfied +// if ( pCur->pLits[0] == p->pAssigns[Gia_Lit2Var(pCur->pLits[0])] ) + pObj = Gia_ManObj( p->pAig, Gia_Lit2Var(pCur->pLits[0]) ); + if ( Tas_VarIsAssigned(pObj) && Tas_LitIsTrue( pObj, pCur->pLits[0] ) ) + { + piPrev = &pCur->iNext[1]; + continue; + } + + // look for a new literal to watch + for ( i = 2; i < (int)pCur->nLits; i++ ) + { + // skip the case when the literal is false +// if ( Gia_LitNot(pCur->pLits[i]) == p->pAssigns[Gia_Lit2Var(pCur->pLits[i])] ) + pObj = Gia_ManObj( p->pAig, Gia_Lit2Var(pCur->pLits[i]) ); + if ( Tas_VarIsAssigned(pObj) && !Tas_LitIsTrue( pObj, pCur->pLits[i] ) ) + continue; + // the literal is either true or unassigned - watch it + pCur->pLits[1] = pCur->pLits[i]; + pCur->pLits[i] = LitF; + // remove this clause from the watch list of Lit + *piPrev = pCur->iNext[1]; + // add this clause to the watch list of pCur->pLits[i] (now it is pCur->pLits[1]) + Tas_ManWatchClause( p, pCur, pCur->pLits[1] ); + break; + } + if ( i < (int)pCur->nLits ) // found new watch + continue; + + // clause is unit - enqueue new implication + pObj = Gia_ManObj( p->pAig, Gia_Lit2Var(pCur->pLits[0]) ); + if ( !Tas_VarIsAssigned(pObj) ) + { +/* + { + int iLitLevel, iPlace; + for ( i = 1; i < (int)pCur->nLits; i++ ) + { + pObj = Gia_ManObj( p->pAig, Gia_Lit2Var(pCur->pLits[i]) ); + iLitLevel = Tas_VarDecLevel( p, pObj ); + iPlace = pObj->Value; + printf( "Lit = %d. Level = %d. Place = %d.\n", pCur->pLits[i], iLitLevel, iPlace ); + i = i; + } + } +*/ + Tas_ManAssign( p, Gia_ObjFromLit(p->pAig, pCur->pLits[0]), Level, NULL, (Gia_Obj_t *)pCur ); + piPrev = &pCur->iNext[1]; + continue; + } + // conflict detected - return the conflict clause + assert( !Tas_LitIsTrue( pObj, pCur->pLits[0] ) ); + return Tas_ManCreateFromCls( p, pCur, Level ); + } + return 0; +} + + + +/**Function************************************************************* + + Synopsis [Propagates a variable.] + + Description [Returns clause handle if conflict; 0 if no conflict.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Tas_ManPropagateOne( Tas_Man_t * p, Gia_Obj_t * pVar, int Level ) +{ + int Value0, Value1, hClause; + assert( !Gia_IsComplement(pVar) ); + assert( Tas_VarIsAssigned(pVar) ); + s_Counter3++; + if ( (hClause = Tas_ManPropagateWatch( p, Level, Tas_VarToLit(p, pVar) )) ) + return hClause; + if ( Gia_ObjIsCi(pVar) ) + return 0; +/* + if ( pVar->iDiff0 == 570869 && pVar->iDiff1 == 546821 && Level == 3 ) + { + Gia_Obj_t * pFan0 = Gia_ObjFanin0(pVar); + Gia_Obj_t * pFan1 = Gia_ObjFanin1(pVar); + int s = 0; + } +*/ + assert( Gia_ObjIsAnd(pVar) ); + Value0 = Tas_VarFanin0Value(pVar); + Value1 = Tas_VarFanin1Value(pVar); + if ( Tas_VarValue(pVar) ) + { // value is 1 + if ( Value0 == 0 || Value1 == 0 ) // one is 0 + { + if ( Value0 == 0 && Value1 != 0 ) + return Tas_ManAnalyze( p, Level, pVar, Gia_ObjFanin0(pVar), NULL ); + if ( Value0 != 0 && Value1 == 0 ) + return Tas_ManAnalyze( p, Level, pVar, Gia_ObjFanin1(pVar), NULL ); + assert( Value0 == 0 && Value1 == 0 ); + return Tas_ManAnalyze( p, Level, pVar, Gia_ObjFanin0(pVar), Gia_ObjFanin1(pVar) ); + } + if ( Value0 == 2 ) // first is unassigned + Tas_ManAssign( p, Gia_ObjChild0(pVar), Level, pVar, NULL ); + if ( Value1 == 2 ) // first is unassigned + Tas_ManAssign( p, Gia_ObjChild1(pVar), Level, pVar, NULL ); + return 0; + } + // value is 0 + if ( Value0 == 0 || Value1 == 0 ) // one is 0 + return 0; + if ( Value0 == 1 && Value1 == 1 ) // both are 1 + return Tas_ManAnalyze( p, Level, pVar, Gia_ObjFanin0(pVar), Gia_ObjFanin1(pVar) ); + if ( Value0 == 1 || Value1 == 1 ) // one is 1 + { + if ( Value0 == 2 ) // first is unassigned + Tas_ManAssign( p, Gia_Not(Gia_ObjChild0(pVar)), Level, pVar, Gia_ObjFanin1(pVar) ); + if ( Value1 == 2 ) // second is unassigned + Tas_ManAssign( p, Gia_Not(Gia_ObjChild1(pVar)), Level, pVar, Gia_ObjFanin0(pVar) ); + return 0; + } + assert( Tas_VarIsJust(pVar) ); + assert( !Tas_QueHasNode( &p->pJust, pVar ) ); + Tas_QuePush( &p->pJust, pVar ); + return 0; +} + +/**Function************************************************************* + + Synopsis [Propagates a variable.] + + Description [Returns 1 if conflict; 0 if no conflict.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Tas_ManPropagateTwo( Tas_Man_t * p, Gia_Obj_t * pVar, int Level ) +{ + int Value0, Value1; + s_Counter4++; + assert( !Gia_IsComplement(pVar) ); + assert( Gia_ObjIsAnd(pVar) ); + assert( Tas_VarIsAssigned(pVar) ); + assert( !Tas_VarValue(pVar) ); + Value0 = Tas_VarFanin0Value(pVar); + Value1 = Tas_VarFanin1Value(pVar); + // value is 0 + if ( Value0 == 0 || Value1 == 0 ) // one is 0 + return 0; + if ( Value0 == 1 && Value1 == 1 ) // both are 1 + return Tas_ManAnalyze( p, Level, pVar, Gia_ObjFanin0(pVar), Gia_ObjFanin1(pVar) ); + assert( Value0 == 1 || Value1 == 1 ); + if ( Value0 == 2 ) // first is unassigned + Tas_ManAssign( p, Gia_Not(Gia_ObjChild0(pVar)), Level, pVar, Gia_ObjFanin1(pVar) ); + if ( Value1 == 2 ) // first is unassigned + Tas_ManAssign( p, Gia_Not(Gia_ObjChild1(pVar)), Level, pVar, Gia_ObjFanin0(pVar) ); + return 0; +} + +/**Function************************************************************* + + Synopsis [Propagates all variables.] + + Description [Returns 1 if conflict; 0 if no conflict.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Tas_ManPropagate( Tas_Man_t * p, int Level ) +{ + int hClause; + Gia_Obj_t * pVar; + int i, k, nIter = 0; + while ( 1 ) + { +// nIter++; + Tas_QueForEachEntry( p->pProp, pVar, i ) + { + if ( (hClause = Tas_ManPropagateOne( p, pVar, Level )) ) + return hClause; + } + p->pProp.iHead = p->pProp.iTail; + k = p->pJust.iHead; + Tas_QueForEachEntry( p->pJust, pVar, i ) + { + if ( Tas_VarIsJust( pVar ) ) + p->pJust.pData[k++] = pVar; + else if ( (hClause = Tas_ManPropagateTwo( p, pVar, Level )) ) + return hClause; + } + if ( k == p->pJust.iTail ) + break; + p->pJust.iTail = k; + } +// printf( "%d ", nIter ); + return 0; +} + +/**Function************************************************************* + + Synopsis [Solve the problem recursively.] + + Description [Returns learnt clause if unsat, NULL if sat or undecided.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Tas_ManSolve_rec( Tas_Man_t * p, int Level ) +{ + Tas_Que_t * pQue = &(p->pClauses); + Gia_Obj_t * pVar, * pDecVar; + int hClause, hLearn0, hLearn1; + int iPropHead, iJustHead, iJustTail; + // propagate assignments + assert( !Tas_QueIsEmpty(&p->pProp) ); + if ( (hClause = Tas_ManPropagate( p, Level )) ) + { + Tas_ManCreateCls( p, hClause ); + return hClause; + } + // check for satisfying assignment + assert( Tas_QueIsEmpty(&p->pProp) ); + if ( Tas_QueIsEmpty(&p->pJust) ) + return 0; + // quit using resource limits + p->Pars.nJustThis = ABC_MAX( p->Pars.nJustThis, p->pJust.iTail - p->pJust.iHead ); + if ( Tas_ManCheckLimits( p ) ) + return 0; + // remember the state before branching + iPropHead = p->pProp.iHead; + Tas_QueStore( &p->pJust, &iJustHead, &iJustTail ); + // find the decision variable + if ( p->Pars.fUseActive ) + pVar = NULL, pDecVar = Tas_ManFindActive( p ); + else if ( p->Pars.fUseHighest ) +// pVar = NULL, pDecVar = Tas_ManDecideHighestFanin( p ); + pVar = Tas_ManDecideHighest( p ); + else if ( p->Pars.fUseLowest ) + pVar = Tas_ManDecideLowest( p ); + else if ( p->Pars.fUseMaxFF ) + pVar = Tas_ManDecideMaxFF( p ); + else assert( 0 ); + // chose decision variable using fanout count + if ( pVar != NULL ) + { + assert( Tas_VarIsJust( pVar ) ); + if ( Gia_ObjRefs(p->pAig, Gia_ObjFanin0(pVar)) > Gia_ObjRefs(p->pAig, Gia_ObjFanin1(pVar)) ) + pDecVar = Gia_Not(Gia_ObjChild0(pVar)); + else + pDecVar = Gia_Not(Gia_ObjChild1(pVar)); +// pDecVar = Gia_NotCond( pDecVar, Gia_Regular(pDecVar)->fMark1 ^ !Gia_IsComplement(pDecVar) ); + } + // decide on first fanin + Tas_ManAssign( p, pDecVar, Level+1, NULL, NULL ); + if ( !(hLearn0 = Tas_ManSolve_rec( p, Level+1 )) ) + return 0; + if ( pQue->pData[hLearn0] != Gia_Regular(pDecVar) ) + return hLearn0; + Tas_ManCancelUntil( p, iPropHead ); + Tas_QueRestore( &p->pJust, iJustHead, iJustTail ); + // decide on second fanin + Tas_ManAssign( p, Gia_Not(pDecVar), Level+1, NULL, NULL ); + if ( !(hLearn1 = Tas_ManSolve_rec( p, Level+1 )) ) + return 0; + if ( pQue->pData[hLearn1] != Gia_Regular(pDecVar) ) + return hLearn1; + hClause = Tas_ManResolve( p, Level, hLearn0, hLearn1 ); + Tas_ManCreateCls( p, hClause ); +// Tas_ManPrintClauseNew( p, Level, hClause ); +// if ( Level > Tas_ClauseDecLevel(p, hClause) ) +// p->Pars.nBTThisNc++; + p->Pars.nBTThis++; + return hClause; +} + +/**Function************************************************************* + + Synopsis [Looking for a satisfying assignment of the node.] + + Description [Assumes that each node has flag pObj->fMark0 set to 0. + Returns 1 if unsatisfiable, 0 if satisfiable, and -1 if undecided. + The node may be complemented. ] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Tas_ManSolve( Tas_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pObj2 ) +{ + int i, Entry, RetValue = 0; + s_Counter2 = 0; + Vec_IntClear( p->vModel ); + if ( pObj == Gia_ManConst0(p->pAig) || pObj2 == Gia_ManConst0(p->pAig) || pObj == Gia_Not(pObj2) ) + return 1; + if ( pObj == Gia_ManConst1(p->pAig) && (pObj2 == NULL || pObj2 == Gia_ManConst1(p->pAig)) ) + return 0; + assert( !p->pProp.iHead && !p->pProp.iTail ); + assert( !p->pJust.iHead && !p->pJust.iTail ); + assert( p->pClauses.iHead == 1 && p->pClauses.iTail == 1 ); + p->Pars.nBTThis = p->Pars.nJustThis = p->Pars.nBTThisNc = 0; + Tas_ManAssign( p, pObj, 0, NULL, NULL ); + if ( pObj2 && !Tas_VarIsAssigned(Gia_Regular(pObj2)) ) + Tas_ManAssign( p, pObj2, 0, NULL, NULL ); + if ( !Tas_ManSolve_rec(p, 0) && !Tas_ManCheckLimits(p) ) + Tas_ManSaveModel( p, p->vModel ); + else + RetValue = 1; + Tas_ManCancelUntil( p, 0 ); + p->pJust.iHead = p->pJust.iTail = 0; + p->pClauses.iHead = p->pClauses.iTail = 1; + // clauses + if ( p->nClauses > 0 ) + { + p->pStore.iCur = 16; + Vec_IntForEachEntry( p->vWatchLits, Entry, i ) + p->pWatches[Entry] = 0; + Vec_IntClear( p->vWatchLits ); + p->nClauses = 0; + } + // activity + Vec_IntForEachEntry( p->vActiveVars, Entry, i ) + p->pActivity[Entry] = 0.0; + Vec_IntClear( p->vActiveVars ); + // statistics + p->Pars.nBTTotal += p->Pars.nBTThis; + p->Pars.nJustTotal = ABC_MAX( p->Pars.nJustTotal, p->Pars.nJustThis ); + if ( Tas_ManCheckLimits( p ) ) + RetValue = -1; + return RetValue; +} + +/**Function************************************************************* + + Synopsis [Looking for a satisfying assignment of the node.] + + Description [Assumes that each node has flag pObj->fMark0 set to 0. + Returns 1 if unsatisfiable, 0 if satisfiable, and -1 if undecided. + The node may be complemented. ] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Tas_ManSolveArray( Tas_Man_t * p, Vec_Ptr_t * vObjs ) +{ + Gia_Obj_t * pObj; + int i, Entry, RetValue = 0; + s_Counter2 = 0; + s_Counter3 = 0; + s_Counter4 = 0; + Vec_IntClear( p->vModel ); + Vec_PtrForEachEntry( Gia_Obj_t *, vObjs, pObj, i ) + if ( pObj == Gia_ManConst0(p->pAig) ) + return 1; + assert( !p->pProp.iHead && !p->pProp.iTail ); + assert( !p->pJust.iHead && !p->pJust.iTail ); + assert( p->pClauses.iHead == 1 && p->pClauses.iTail == 1 ); + p->Pars.nBTThis = p->Pars.nJustThis = p->Pars.nBTThisNc = 0; + Vec_PtrForEachEntry( Gia_Obj_t *, vObjs, pObj, i ) + if ( pObj != Gia_ManConst1(p->pAig) && !Tas_VarIsAssigned(Gia_Regular(pObj)) ) + Tas_ManAssign( p, pObj, 0, NULL, NULL ); + if ( !Tas_ManSolve_rec(p, 0) && !Tas_ManCheckLimits(p) ) + Tas_ManSaveModel( p, p->vModel ); + else + RetValue = 1; + Tas_ManCancelUntil( p, 0 ); + p->pJust.iHead = p->pJust.iTail = 0; + p->pClauses.iHead = p->pClauses.iTail = 1; + // clauses + if ( p->nClauses > 0 ) + { + p->pStore.iCur = 16; + Vec_IntForEachEntry( p->vWatchLits, Entry, i ) + p->pWatches[Entry] = 0; + Vec_IntClear( p->vWatchLits ); + p->nClauses = 0; + } + // activity + Vec_IntForEachEntry( p->vActiveVars, Entry, i ) + p->pActivity[Entry] = 0.0; + Vec_IntClear( p->vActiveVars ); + // statistics + p->Pars.nBTTotal += p->Pars.nBTThis; + p->Pars.nJustTotal = ABC_MAX( p->Pars.nJustTotal, p->Pars.nJustThis ); + if ( Tas_ManCheckLimits( p ) ) + RetValue = -1; + +// printf( "%d ", Gia_ManObjNum(p->pAig) ); +// printf( "%d ", p->Pars.nBTThis ); +// printf( "%d ", p->Pars.nJustThis ); +// printf( "%d ", s_Counter2 ); +// printf( "%d ", s_Counter3 ); +// printf( "%d ", s_Counter4 ); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [Prints statistics of the manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Tas_ManSatPrintStats( Tas_Man_t * p ) +{ + printf( "CO = %8d ", Gia_ManCoNum(p->pAig) ); + printf( "AND = %8d ", Gia_ManAndNum(p->pAig) ); + printf( "Conf = %6d ", p->Pars.nBTLimit ); + printf( "JustMax = %5d ", p->Pars.nJustLimit ); + printf( "\n" ); + printf( "Unsat calls %6d (%6.2f %%) Ave conf = %8.1f ", + p->nSatUnsat, p->nSatTotal? 100.0*p->nSatUnsat/p->nSatTotal :0.0, p->nSatUnsat? 1.0*p->nConfUnsat/p->nSatUnsat :0.0 ); + ABC_PRTP( "Time", p->timeSatUnsat, p->timeTotal ); + printf( "Sat calls %6d (%6.2f %%) Ave conf = %8.1f ", + p->nSatSat, p->nSatTotal? 100.0*p->nSatSat/p->nSatTotal :0.0, p->nSatSat? 1.0*p->nConfSat/p->nSatSat : 0.0 ); + ABC_PRTP( "Time", p->timeSatSat, p->timeTotal ); + printf( "Undef calls %6d (%6.2f %%) Ave conf = %8.1f ", + p->nSatUndec, p->nSatTotal? 100.0*p->nSatUndec/p->nSatTotal :0.0, p->nSatUndec? 1.0*p->nConfUndec/p->nSatUndec : 0.0 ); + ABC_PRTP( "Time", p->timeSatUndec, p->timeTotal ); + ABC_PRT( "Total time", p->timeTotal ); +} + +/**Function************************************************************* + + Synopsis [Procedure to test the new SAT solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Tas_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvStatus, int fVerbose ) +{ + extern void Gia_ManCollectTest( Gia_Man_t * pAig ); + extern void Cec_ManSatAddToStore( Vec_Int_t * vCexStore, Vec_Int_t * vCex, int Out ); + Tas_Man_t * p; + Vec_Int_t * vCex, * vVisit, * vCexStore; + Vec_Str_t * vStatus; + Gia_Obj_t * pRoot;//, * pRootCopy; +// Gia_Man_t * pAigCopy = Gia_ManDup( pAig ), * pAigTemp; + + int i, status, clk, clkTotal = clock(); + assert( Gia_ManRegNum(pAig) == 0 ); +// Gia_ManCollectTest( pAig ); + // prepare AIG + Gia_ManCreateRefs( pAig ); + Gia_ManCleanMark0( pAig ); + Gia_ManCleanMark1( pAig ); + Gia_ManFillValue( pAig ); // maps nodes into trail ids + Gia_ManCleanPhase( pAig ); // maps nodes into trail ids + // create logic network + p = Tas_ManAlloc( pAig, nConfs ); + p->pAig = pAig; + // create resulting data-structures + vStatus = Vec_StrAlloc( Gia_ManPoNum(pAig) ); + vCexStore = Vec_IntAlloc( 10000 ); + vVisit = Vec_IntAlloc( 100 ); + vCex = Tas_ReadModel( p ); + // solve for each output + Gia_ManForEachCo( pAig, pRoot, i ) + { +// printf( "%d=", i ); + + Vec_IntClear( vCex ); + if ( Gia_ObjIsConst0(Gia_ObjFanin0(pRoot)) ) + { + if ( Gia_ObjFaninC0(pRoot) ) + { +// printf( "Constant 1 output of SRM!!!\n" ); + Cec_ManSatAddToStore( vCexStore, vCex, i ); // trivial counter-example + Vec_StrPush( vStatus, 0 ); + } + else + { +// printf( "Constant 0 output of SRM!!!\n" ); + Vec_StrPush( vStatus, 1 ); + } + continue; + } + clk = clock(); +// p->Pars.fUseActive = 1; + p->Pars.fUseHighest = 1; + p->Pars.fUseLowest = 0; + status = Tas_ManSolve( p, Gia_ObjChild0(pRoot), NULL ); +// printf( "\n" ); +/* + if ( status == -1 ) + { + p->Pars.fUseHighest = 0; + p->Pars.fUseLowest = 1; + status = Tas_ManSolve( p, Gia_ObjChild0(pRoot) ); + } +*/ + Vec_StrPush( vStatus, (char)status ); + if ( status == -1 ) + { +// printf( "Unsolved %d.\n", i ); + + p->nSatUndec++; + p->nConfUndec += p->Pars.nBTThis; + Cec_ManSatAddToStore( vCexStore, NULL, i ); // timeout + p->timeSatUndec += clock() - clk; + continue; + } + +// pRootCopy = Gia_ManCo( pAigCopy, i ); +// pRootCopy->iDiff0 = Gia_ObjId( pAigCopy, pRootCopy ); +// pRootCopy->fCompl0 = 0; + + if ( status == 1 ) + { + p->nSatUnsat++; + p->nConfUnsat += p->Pars.nBTThis; + p->timeSatUnsat += clock() - clk; + continue; + } + p->nSatSat++; + p->nConfSat += p->Pars.nBTThis; +// Gia_SatVerifyPattern( pAig, pRoot, vCex, vVisit ); + Cec_ManSatAddToStore( vCexStore, vCex, i ); + p->timeSatSat += clock() - clk; + +// printf( "%d ", Vec_IntSize(vCex) ); + } +// pAigCopy = Gia_ManCleanup( pAigTemp = pAigCopy ); +// Gia_ManStop( pAigTemp ); +// Gia_DumpAiger( pAigCopy, "test", 0, 2 ); +// Gia_ManStop( pAigCopy ); + + Vec_IntFree( vVisit ); + p->nSatTotal = Gia_ManPoNum(pAig); + p->timeTotal = clock() - clkTotal; + if ( fVerbose ) + Tas_ManSatPrintStats( p ); +// printf( "RecCalls = %8d. RecClause = %8d. RecNonChro = %8d.\n", p->nRecCall, p->nRecClause, p->nRecNonChro ); + Tas_ManStop( p ); + *pvStatus = vStatus; + +// printf( "Total number of cex literals = %d. (Ave = %d)\n", +// Vec_IntSize(vCexStore)-2*p->nSatUndec-2*p->nSatSat, +// (Vec_IntSize(vCexStore)-2*p->nSatUndec-2*p->nSatSat)/p->nSatSat ); + return vCexStore; +} + +/**Function************************************************************* + + Synopsis [Packs patterns into array of simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +*************************************`**********************************/ +int Tas_StorePatternTry( Vec_Ptr_t * vInfo, Vec_Ptr_t * vPres, int iBit, int * pLits, int nLits ) +{ + unsigned * pInfo, * pPres; + int i; + for ( i = 0; i < nLits; i++ ) + { + pInfo = (unsigned *)Vec_PtrEntry(vInfo, Gia_Lit2Var(pLits[i])); + pPres = (unsigned *)Vec_PtrEntry(vPres, Gia_Lit2Var(pLits[i])); + if ( Gia_InfoHasBit( pPres, iBit ) && + Gia_InfoHasBit( pInfo, iBit ) == Gia_LitIsCompl(pLits[i]) ) + return 0; + } + for ( i = 0; i < nLits; i++ ) + { + pInfo = (unsigned *)Vec_PtrEntry(vInfo, Gia_Lit2Var(pLits[i])); + pPres = (unsigned *)Vec_PtrEntry(vPres, Gia_Lit2Var(pLits[i])); + Gia_InfoSetBit( pPres, iBit ); + if ( Gia_InfoHasBit( pInfo, iBit ) == Gia_LitIsCompl(pLits[i]) ) + Gia_InfoXorBit( pInfo, iBit ); + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Procedure to test the new SAT solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Tas_StorePattern( Vec_Ptr_t * vSimInfo, Vec_Ptr_t * vPres, Vec_Int_t * vCex ) +{ + int k; + for ( k = 1; k < 32; k++ ) + if ( Tas_StorePatternTry( vSimInfo, vPres, k, (int *)Vec_IntArray(vCex), Vec_IntSize(vCex) ) ) + break; + return (int)(k < 32); +} + +/**Function************************************************************* + + Synopsis [Procedure to test the new SAT solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Tas_ManSolveMiterNc2( Gia_Man_t * pAig, int nConfs, Gia_Man_t * pAigOld, Vec_Ptr_t * vOldRoots, Vec_Ptr_t * vSimInfo ) +{ + int nPatMax = 1000; + int fVerbose = 1; + extern void Gia_ManCollectTest( Gia_Man_t * pAig ); + extern void Cec_ManSatAddToStore( Vec_Int_t * vCexStore, Vec_Int_t * vCex, int Out ); + Tas_Man_t * p; + Vec_Ptr_t * vPres; + Vec_Int_t * vCex, * vVisit, * vCexStore; + Vec_Str_t * vStatus; + Gia_Obj_t * pRoot, * pOldRoot; + int i, status, clk, clkTotal = clock(); + int Tried = 0, Stored = 0, Step = Gia_ManCoNum(pAig) / nPatMax; + assert( Gia_ManRegNum(pAig) == 0 ); +// Gia_ManCollectTest( pAig ); + // prepare AIG + Gia_ManCreateRefs( pAig ); + Gia_ManCleanMark0( pAig ); + Gia_ManCleanMark1( pAig ); + Gia_ManFillValue( pAig ); // maps nodes into trail ids + Gia_ManCleanPhase( pAig ); // maps nodes into trail ids + // create logic network + p = Tas_ManAlloc( pAig, nConfs ); + p->pAig = pAig; + // create resulting data-structures + vStatus = Vec_StrAlloc( Gia_ManPoNum(pAig) ); + vCexStore = Vec_IntAlloc( 10000 ); + vVisit = Vec_IntAlloc( 100 ); + vCex = Tas_ReadModel( p ); + // solve for each output + vPres = Vec_PtrAllocSimInfo( Gia_ManCiNum(pAig), 1 ); + Vec_PtrCleanSimInfo( vPres, 0, 1 ); + + Gia_ManForEachCo( pAig, pRoot, i ) + { + assert( !Gia_ObjIsConst0(Gia_ObjFanin0(pRoot)) ); + Vec_IntClear( vCex ); + clk = clock(); + p->Pars.fUseHighest = 1; + p->Pars.fUseLowest = 0; + status = Tas_ManSolve( p, Gia_ObjChild0(pRoot), NULL ); + Vec_StrPush( vStatus, (char)status ); + if ( status == -1 ) + { + p->nSatUndec++; + p->nConfUndec += p->Pars.nBTThis; +// Cec_ManSatAddToStore( vCexStore, NULL, i ); // timeout + p->timeSatUndec += clock() - clk; + + i += Step; + continue; + } + if ( status == 1 ) + { + p->nSatUnsat++; + p->nConfUnsat += p->Pars.nBTThis; + p->timeSatUnsat += clock() - clk; + // record proved + pOldRoot = (Gia_Obj_t *)Vec_PtrEntry( vOldRoots, i ); + assert( !Gia_ObjProved( pAigOld, Gia_ObjId(pAigOld, pOldRoot) ) ); + Gia_ObjSetProved( pAigOld, Gia_ObjId(pAigOld, pOldRoot) ); + + i += Step; + continue; + } + p->nSatSat++; + p->nConfSat += p->Pars.nBTThis; +// Gia_SatVerifyPattern( pAig, pRoot, vCex, vVisit ); +// Cec_ManSatAddToStore( vCexStore, vCex, i ); + + // save pattern + Tried++; + Stored += Tas_StorePattern( vSimInfo, vPres, vCex ); + p->timeSatSat += clock() - clk; + i += Step; + } + printf( "Tried = %d Stored = %d\n", Tried, Stored ); + Vec_IntFree( vVisit ); + p->nSatTotal = Gia_ManPoNum(pAig); + p->timeTotal = clock() - clkTotal; + if ( fVerbose ) + Tas_ManSatPrintStats( p ); + Tas_ManStop( p ); + Vec_PtrFree( vPres ); +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaCTas2.c b/src/aig/gia/giaCTas2.c new file mode 100644 index 00000000..855dcdd3 --- /dev/null +++ b/src/aig/gia/giaCTas2.c @@ -0,0 +1,208 @@ +/**CFile**************************************************************** + + FileName [giaCSat2.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Circuit-based SAT solver.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaCSat2.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Tas_Par_t_ Tas_Par_t; +struct Tas_Par_t_ +{ + // conflict limits + int nBTLimit; // limit on the number of conflicts + // current parameters + int nBTThis; // number of conflicts + int nBTTotal; // total number of conflicts + // decision heuristics + int fUseHighest; // use node with the highest ID + // other parameters + int fVerbose; +}; + +typedef struct Tas_Sto_t_ Tas_Sto_t; +struct Tas_Sto_t_ +{ + int iCur; // currently used + int nSize; // allocated size + char * pBuffer; // handles of objects stored in the queue +}; + +typedef struct Tas_Que_t_ Tas_Que_t; +struct Tas_Que_t_ +{ + int iHead; // beginning of the queue + int iTail; // end of the queue + int nSize; // allocated size + int * pData; // handles of objects stored in the queue +}; + +typedef struct Tas_Var_t_ Tas_Var_t; +struct Tas_Var_t_ +{ + unsigned fTerm : 1; // terminal node + unsigned fVal : 1; // current value + unsigned fValOld : 1; // previous value + unsigned fAssign : 1; // assigned status + unsigned fJQueue : 1; // part of J-frontier + unsigned fCompl0 : 1; // complemented attribute + unsigned fCompl1 : 1; // complemented attribute + unsigned fMark0 : 1; // multi-purpose mark + unsigned fMark1 : 1; // multi-purpose mark + unsigned fPhase : 1; // polarity + unsigned Level : 22; // decision level + int Id; // unique ID of this variable + int IdAig; // original ID of this variable + int Reason0; // reason of this variable + int Reason1; // reason of this variable + int Diff0; // difference for the first fanin + int Diff1; // difference for the second fanin + int Watch0; // handle of first watch + int Watch1; // handle of second watch +}; + +typedef struct Tas_Cls_t_ Tas_Cls_t; +struct Tas_Cls_t_ +{ + int Watch0; // next clause to watch + int Watch1; // next clause to watch + int pVars[0]; // variable handles +}; + +typedef struct Tas_Man_t_ Tas_Man_t; +struct Tas_Man_t_ +{ + // user data + Gia_Man_t * pAig; // AIG manager + Tas_Par_t Pars; // parameters + // solver data + Tas_Sto_t * pVars; // variables + Tas_Sto_t * pClauses; // clauses + // state representation + Tas_Que_t pProp; // propagation queue + Tas_Que_t pJust; // justification queue + Vec_Int_t * vModel; // satisfying assignment + Vec_Ptr_t * vTemp; // temporary storage + // SAT calls statistics + int nSatUnsat; // the number of proofs + int nSatSat; // the number of failure + int nSatUndec; // the number of timeouts + int nSatTotal; // the number of calls + // conflicts + int nConfUnsat; // conflicts in unsat problems + int nConfSat; // conflicts in sat problems + int nConfUndec; // conflicts in undec problems + int nConfTotal; // total conflicts + // runtime stats + int timeSatUnsat; // unsat + int timeSatSat; // sat + int timeSatUndec; // undecided + int timeTotal; // total runtime +}; + +static inline int Tas_VarIsAssigned( Tas_Var_t * pVar ) { return pVar->fAssign; } +static inline void Tas_VarAssign( Tas_Var_t * pVar ) { assert(!pVar->fAssign); pVar->fAssign = 1; } +static inline void Tas_VarUnassign( Tas_Var_t * pVar ) { assert(pVar->fAssign); pVar->fAssign = 0; pVar->fVal = 0; } +static inline int Tas_VarValue( Tas_Var_t * pVar ) { assert(pVar->fAssign); return pVar->fVal; } +static inline void Tas_VarSetValue( Tas_Var_t * pVar, int v ) { assert(pVar->fAssign); pVar->fVal = v; } +static inline int Tas_VarIsJust( Tas_Var_t * pVar ) { return Gia_ObjIsAnd(pVar) && !Tas_VarIsAssigned(Gia_ObjFanin0(pVar)) && !Tas_VarIsAssigned(Gia_ObjFanin1(pVar)); } +static inline int Tas_VarFanin0Value( Tas_Var_t * pVar ) { return !Tas_VarIsAssigned(Gia_ObjFanin0(pVar)) ? 2 : (Tas_VarValue(Gia_ObjFanin0(pVar)) ^ Gia_ObjFaninC0(pVar)); } +static inline int Tas_VarFanin1Value( Tas_Var_t * pVar ) { return !Tas_VarIsAssigned(Gia_ObjFanin1(pVar)) ? 2 : (Tas_VarValue(Gia_ObjFanin1(pVar)) ^ Gia_ObjFaninC1(pVar)); } + +static inline int Tas_VarDecLevel( Tas_Man_t * p, Tas_Var_t * pVar ) { assert( pVar->Value != ~0 ); return Vec_IntEntry(p->vLevReas, 3*pVar->Value); } +static inline Tas_Var_t * Tas_VarReason0( Tas_Man_t * p, Tas_Var_t * pVar ) { assert( pVar->Value != ~0 ); return pVar + Vec_IntEntry(p->vLevReas, 3*pVar->Value+1); } +static inline Tas_Var_t * Tas_VarReason1( Tas_Man_t * p, Tas_Var_t * pVar ) { assert( pVar->Value != ~0 ); return pVar + Vec_IntEntry(p->vLevReas, 3*pVar->Value+2); } +static inline int Tas_ClauseDecLevel( Tas_Man_t * p, int hClause ) { return Tas_VarDecLevel( p, p->pClauses.pData[hClause] ); } + +static inline Tas_Var_t * Tas_ManVar( Tas_Man_t * p, int h ) { return (Tas_Var_t *)(p->pVars->pBuffer + h); } +static inline Tas_Cls_t * Tas_ManClause( Tas_Man_t * p, int h ) { return (Tas_Cls_t *)(p->pClauses->pBuffer + h); } + +#define Tas_ClaForEachVar( p, pClause, pVar, i ) \ + for ( pVar = Tas_ManVar(p, pClause->pVars[(i=0)]); pClause->pVars[i]; pVar = (Tas_Var_t *)(((char *)pVar + pClause->pVars[++i])) ) + +#define Tas_QueForEachVar( p, pQue, pVar, i ) \ + for ( pVar = Tas_ManVar(p, pQue->pVars[(i=pQue->iHead)]); i < pQue->iTail; pVar = Tas_ManVar(p, pQue->pVars[i++]) ) + + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Tas_Var_t * Tas_ManCreateVar( Tas_Man_t * p ) +{ + Tas_Var_t * pVar; + if ( p->pVars->iCur + sizeof(Tas_Var_t) > p->pVars->nSize ) + { + p->pVars->nSize *= 2; + p->pVars->pData = ABC_REALLOC( char, p->pVars->pData, p->pVars->nSize ); + } + pVar = p->pVars->pData + p->pVars->iCur; + p->pVars->iCur += sizeof(Tas_Var_t); + memset( pVar, 0, sizeof(Tas_Var_t) ); + pVar->Id = pVar - ((Tas_Var_t *)p->pVars->pData); + return pVar; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Tas_Var_t * Tas_ManObj2Var( Tas_Man_t * p, Gia_Obj_t * pObj ) +{ + Tas_Var_t * pVar; + assert( !Gia_ObjIsComplement(pObj) ); + if ( pObj->Value == 0 ) + { + pVar = Tas_ManCreateVar( p ); + pVar-> + + } + return Tas_ManVar( p, pObj->Value ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaCof.c b/src/aig/gia/giaCof.c index da48c1b0..5a04d9d3 100644 --- a/src/aig/gia/giaCof.c +++ b/src/aig/gia/giaCof.c @@ -21,6 +21,9 @@ #include <math.h> #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -390,7 +393,7 @@ void Cof_ManInsertEntry_rec( Vec_Ptr_t * vNodes, Cof_Obj_t * pNode, int nNodeMax Vec_PtrPush(vNodes, pNode); return; } - pLast = Vec_PtrPop(vNodes); + pLast = (Cof_Obj_t *)Vec_PtrPop(vNodes); if ( Cof_ObjFanoutNum(pLast) < Cof_ObjFanoutNum(pNode) ) { Cof_ManInsertEntry_rec( vNodes, pNode, nNodeMax ); @@ -541,7 +544,7 @@ void Cof_ManPrintHighFanout( Cof_Man_t * p, int nNodes ) Cof_Obj_t * pObj; int i; vNodes = Cof_ManCollectHighFanout( p, nNodes ); - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Cof_Obj_t *, vNodes, pObj, i ) Cof_ManPrintHighFanoutOne( p, pObj ); Vec_PtrFree( vNodes ); } @@ -633,7 +636,7 @@ void Cof_ManPrintFanio( Cof_Man_t * p ) printf( "%15d : ", k ); else { - sprintf( Buffer, "%d - %d", (int)pow(10, k/10) * (k%10), (int)pow(10, k/10) * (k%10+1) - 1 ); + sprintf( Buffer, "%d - %d", (int)pow((double)10, k/10) * (k%10), (int)pow((double)10, k/10) * (k%10+1) - 1 ); printf( "%15s : ", Buffer ); } if ( vFanins->pArray[k] == 0 ) @@ -916,3 +919,5 @@ Gia_Man_t * Gia_ManDupCofAll( Gia_Man_t * p, int nFanLim, int fVerbose ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaConstr.c b/src/aig/gia/giaConstr.c index 14768cc2..60432072 100644 --- a/src/aig/gia/giaConstr.c +++ b/src/aig/gia/giaConstr.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -45,3 +48,5 @@ //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaDfs.c b/src/aig/gia/giaDfs.c index bcc1748f..3b591aee 100644 --- a/src/aig/gia/giaDfs.c +++ b/src/aig/gia/giaDfs.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -136,6 +139,63 @@ void Gia_ManCollectAnds( Gia_Man_t * p, int * pNodes, int nNodes, Vec_Int_t * vN /**Function************************************************************* + Synopsis [Counts the support size of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManCollectNodesCis_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vNodes ) +{ + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return; + Gia_ObjSetTravIdCurrent(p, pObj); + if ( Gia_ObjIsCi(pObj) ) + { + Vec_IntPush( vNodes, Gia_ObjId(p, pObj) ); + return; + } + assert( Gia_ObjIsAnd(pObj) ); + Gia_ManCollectNodesCis_rec( p, Gia_ObjFanin0(pObj), vNodes ); + Gia_ManCollectNodesCis_rec( p, Gia_ObjFanin1(pObj), vNodes ); + Vec_IntPush( vNodes, Gia_ObjId(p, pObj) ); +} + +/**Function************************************************************* + + Synopsis [Collects support nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_ManCollectNodesCis( Gia_Man_t * p, int * pNodes, int nNodes ) +{ + Vec_Int_t * vNodes; + Gia_Obj_t * pObj; + int i; + vNodes = Vec_IntAlloc( 10000 ); + Gia_ManIncrementTravId( p ); + Gia_ObjSetTravIdCurrent( p, Gia_ManConst0(p) ); + for ( i = 0; i < nNodes; i++ ) + { + pObj = Gia_ManObj( p, pNodes[i] ); + if ( Gia_ObjIsCo(pObj) ) + Gia_ManCollectNodesCis_rec( p, Gia_ObjFanin0(pObj), vNodes ); + else + Gia_ManCollectNodesCis_rec( p, pObj, vNodes ); + } + return vNodes; +} + +/**Function************************************************************* + Synopsis [Collects support nodes.] Description [] @@ -151,7 +211,6 @@ void Gia_ManCollectTest( Gia_Man_t * p ) Gia_Obj_t * pObj; int i, iNode, clk = clock(); vNodes = Vec_IntAlloc( 100 ); - Gia_ManResetTravId( p ); Gia_ManIncrementTravId( p ); Gia_ManForEachCo( p, pObj, i ) { @@ -276,7 +335,7 @@ int Gia_ManConeSize( Gia_Man_t * p, int * pNodes, int nNodes ) ***********************************************************************/ Vec_Vec_t * Gia_ManLevelize( Gia_Man_t * p ) -{ +{ Gia_Obj_t * pObj; Vec_Vec_t * vLevels; int nLevels, Level, i; @@ -291,8 +350,49 @@ Vec_Vec_t * Gia_ManLevelize( Gia_Man_t * p ) return vLevels; } +/**Function************************************************************* + + Synopsis [Computes reverse topological order.] + + Description [Assumes that levels are already assigned. + The levels of CO nodes may not be assigned.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_ManOrderReverse( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + Vec_Vec_t * vLevels; + Vec_Ptr_t * vLevel; + Vec_Int_t * vResult; + int i, k; + vLevels = Vec_VecStart( 100 ); + // make sure levels are assigned + Gia_ManForEachAnd( p, pObj, i ) + assert( Gia_ObjLevel(p, pObj) > 0 ); + // add CO nodes based on the level of their fanin + Gia_ManForEachCo( p, pObj, i ) + Vec_VecPush( vLevels, Gia_ObjLevel(p, Gia_ObjFanin0(pObj)), pObj ); + // add other nodes based on their level + Gia_ManForEachObj( p, pObj, i ) + if ( !Gia_ObjIsCo(pObj) ) + Vec_VecPush( vLevels, Gia_ObjLevel(p, pObj), pObj ); + // put the nodes in the reverse topological order + vResult = Vec_IntAlloc( Gia_ManObjNum(p) ); + Vec_VecForEachLevelReverse( vLevels, vLevel, i ) + Vec_PtrForEachEntry( Gia_Obj_t *, vLevel, pObj, k ) + Vec_IntPush( vResult, Gia_ObjId(p, pObj) ); + Vec_VecFree( vLevels ); + return vResult; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index cde19a22..4ded9a78 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -143,6 +146,8 @@ int Gia_ManDupOrderDfs_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) return pObj->Value; if ( Gia_ObjIsCi(pObj) ) return pObj->Value = Gia_ManAppendCi(pNew); +// if ( p->pNexts && Gia_ObjNext(p, Gia_ObjId(p, pObj)) ) +// Gia_ManDupOrderDfs_rec( pNew, p, Gia_ObjNextObj(p, Gia_ObjId(p, pObj)) ); Gia_ManDupOrderDfs_rec( pNew, p, Gia_ObjFanin0(pObj) ); if ( Gia_ObjIsCo(pObj) ) return pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); @@ -193,6 +198,98 @@ Gia_Man_t * Gia_ManDupOrderDfs( Gia_Man_t * p ) SeeAlso [] ***********************************************************************/ +Gia_Man_t * Gia_ManDupOutputGroup( Gia_Man_t * p, int iOutStart, int iOutStop ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + int i; + Gia_ManFillValue( p ); + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Gia_UtilStrsav( p->pName ); + Gia_ManConst0(p)->Value = 0; + for ( i = iOutStart; i < iOutStop; i++ ) + { + pObj = Gia_ManCo( p, i ); + Gia_ManDupOrderDfs_rec( pNew, p, pObj ); + } + return pNew; +} + +/**Function************************************************************* + + Synopsis [Duplicates the AIG in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManDupOrderDfsChoices_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + Gia_Obj_t * pNext; + if ( ~pObj->Value ) + return; + assert( Gia_ObjIsAnd(pObj) ); + pNext = Gia_ObjNextObj( p, Gia_ObjId(p, pObj) ); + if ( pNext ) + Gia_ManDupOrderDfsChoices_rec( pNew, p, pNext ); + Gia_ManDupOrderDfsChoices_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Gia_ManDupOrderDfsChoices_rec( pNew, p, Gia_ObjFanin1(pObj) ); + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + if ( pNext ) + { + pNew->pNexts[Gia_Lit2Var(pObj->Value)] = Gia_Lit2Var( Gia_Lit2Var(pNext->Value) ); + assert( Gia_Lit2Var(pObj->Value) > Gia_Lit2Var(pNext->Value) ); + } +} + +/**Function************************************************************* + + Synopsis [Duplicates AIG while putting objects in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDupOrderDfsChoices( Gia_Man_t * p ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + int i; + assert( p->pReprs && p->pNexts ); + Gia_ManFillValue( p ); + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Gia_UtilStrsav( p->pName ); + pNew->pNexts = ABC_CALLOC( int, Gia_ManObjNum(p) ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi(pNew); + Gia_ManForEachCo( p, pObj, i ) + { + Gia_ManDupOrderDfsChoices_rec( pNew, p, Gia_ObjFanin0(pObj) ); + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + } + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); +// Gia_ManDeriveReprs( pNew ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Duplicates AIG while putting objects in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ Gia_Man_t * Gia_ManDupOrderDfsReverse( Gia_Man_t * p ) { Gia_Man_t * pNew; @@ -274,13 +371,13 @@ Gia_Man_t * Gia_ManDupFlip( Gia_Man_t * p, int * pInitState ) { pObj->Value = Gia_ManAppendCi( pNew ); if ( Gia_ObjCioId(pObj) >= Gia_ManPiNum(p) ) - pObj->Value = Gia_LitNotCond( pObj->Value, Gia_InfoHasBit(pInitState, Gia_ObjCioId(pObj) - Gia_ManPiNum(p)) ); + pObj->Value = Gia_LitNotCond( pObj->Value, Gia_InfoHasBit((unsigned *)pInitState, Gia_ObjCioId(pObj) - Gia_ManPiNum(p)) ); } else if ( Gia_ObjIsCo(pObj) ) { pObj->Value = Gia_ObjFanin0Copy(pObj); if ( Gia_ObjCioId(pObj) >= Gia_ManPoNum(p) ) - pObj->Value = Gia_LitNotCond( pObj->Value, Gia_InfoHasBit(pInitState, Gia_ObjCioId(pObj) - Gia_ManPoNum(p)) ); + pObj->Value = Gia_LitNotCond( pObj->Value, Gia_InfoHasBit((unsigned *)pInitState, Gia_ObjCioId(pObj) - Gia_ManPoNum(p)) ); pObj->Value = Gia_ManAppendCo( pNew, pObj->Value ); } } @@ -318,6 +415,8 @@ Gia_Man_t * Gia_ManDup( Gia_Man_t * p ) pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); } Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + if ( p->pCexSeq ) + pNew->pCexSeq = Gia_ManDupCounterExample( p->pCexSeq, Gia_ManRegNum(p) ); return pNew; } @@ -664,6 +763,8 @@ Gia_Man_t * Gia_ManDupDfs( Gia_Man_t * p ) Gia_ManForEachCo( p, pObj, i ) Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + if ( p->pCexSeq ) + pNew->pCexSeq = Gia_ManDupCounterExample( p->pCexSeq, Gia_ManRegNum(p) ); return pNew; } @@ -719,7 +820,8 @@ Gia_Man_t * Gia_ManDupDfsCone( Gia_Man_t * p, Gia_Obj_t * pRoot ) Gia_ManConst0(p)->Value = 0; Gia_ManForEachCi( p, pObj, i ) pObj->Value = Gia_ManAppendCi(pNew); - Gia_ManDupDfs_rec( pNew, p, pRoot ); + Gia_ManDupDfs_rec( pNew, p, Gia_ObjFanin0(pRoot) ); + Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pRoot) ); Gia_ManSetRegNum( pNew, 0 ); return pNew; } @@ -820,6 +922,49 @@ Gia_Man_t * Gia_ManDupTrimmed( Gia_Man_t * p, int fTrimCis, int fTrimCos ) /**Function************************************************************* + Synopsis [Duplicates AIG in the DFS order while putting CIs first.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDupOntop( Gia_Man_t * p, Gia_Man_t * p2 ) +{ + Gia_Man_t * pTemp, * pNew; + Gia_Obj_t * pObj; + int i; + assert( Gia_ManPoNum(p) == Gia_ManPiNum(p2) ); + assert( Gia_ManRegNum(p) == 0 ); + assert( Gia_ManRegNum(p2) == 0 ); + pNew = Gia_ManStart( Gia_ManObjNum(p)+Gia_ManObjNum(p2) ); + pNew->pName = Gia_UtilStrsav( p->pName ); + Gia_ManHashAlloc( pNew ); + // dup first AIG + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi(pNew); + Gia_ManForEachAnd( p, pObj, i ) + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + // dup second AIG + Gia_ManConst0(p2)->Value = 0; + Gia_ManForEachCo( p, pObj, i ) + Gia_ManPi(p2, i)->Value = Gia_ObjFanin0Copy(pObj); + Gia_ManForEachAnd( p2, pObj, i ) + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + Gia_ManForEachCo( p2, pObj, i ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManHashStop( pNew ); +// Gia_ManPrintStats( pGiaNew, 0 ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + return pNew; +} + +/**Function************************************************************* + Synopsis [Print representatives.] Description [] @@ -1243,8 +1388,84 @@ Gia_Man_t * Gia_ManTransformMiter( Gia_Man_t * p ) return pNew; } +/**Function************************************************************* + + Synopsis [Duplicates the AIG in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManChoiceMiter_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + if ( ~pObj->Value ) + return pObj->Value; + Gia_ManChoiceMiter_rec( pNew, p, Gia_ObjFanin0(pObj) ); + if ( Gia_ObjIsCo(pObj) ) + return pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManChoiceMiter_rec( pNew, p, Gia_ObjFanin1(pObj) ); + return pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Derives the miter of several AIGs for choice computation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManChoiceMiter( Vec_Ptr_t * vGias ) +{ + Gia_Man_t * pNew, * pGia, * pGia0; + int i, k, iNode, nNodes; + // make sure they have equal parameters + assert( Vec_PtrSize(vGias) > 0 ); + pGia0 = (Gia_Man_t *)Vec_PtrEntry( vGias, 0 ); + Vec_PtrForEachEntry( Gia_Man_t *, vGias, pGia, i ) + { + assert( Gia_ManCiNum(pGia) == Gia_ManCiNum(pGia0) ); + assert( Gia_ManCoNum(pGia) == Gia_ManCoNum(pGia0) ); + assert( Gia_ManRegNum(pGia) == Gia_ManRegNum(pGia0) ); + Gia_ManFillValue( pGia ); + Gia_ManConst0(pGia)->Value = 0; + } + // start the new manager + pNew = Gia_ManStart( Vec_PtrSize(vGias) * Gia_ManObjNum(pGia0) ); + pNew->pName = Gia_UtilStrsav( pGia0->pName ); + // create new CIs and assign them to the old manager CIs + for ( k = 0; k < Gia_ManCiNum(pGia0); k++ ) + { + iNode = Gia_ManAppendCi(pNew); + Vec_PtrForEachEntry( Gia_Man_t *, vGias, pGia, i ) + Gia_ManCi( pGia, k )->Value = iNode; + } + // create internal nodes + Gia_ManHashAlloc( pNew ); + for ( k = 0; k < Gia_ManCoNum(pGia0); k++ ) + { + Vec_PtrForEachEntry( Gia_Man_t *, vGias, pGia, i ) + Gia_ManChoiceMiter_rec( pNew, pGia, Gia_ManCo( pGia, k ) ); + } + Gia_ManHashStop( pNew ); + // check the presence of dangling nodes + nNodes = Gia_ManHasDangling( pNew ); + assert( nNodes == 0 ); + // finalize + Gia_ManSetRegNum( pNew, Gia_ManRegNum(pGia0) ); + return pNew; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaEmbed.c b/src/aig/gia/giaEmbed.c index bd14eea9..5c7092a3 100644 --- a/src/aig/gia/giaEmbed.c +++ b/src/aig/gia/giaEmbed.c @@ -20,6 +20,10 @@ #include <math.h> #include "gia.h" +#include "ioa.h" + +ABC_NAMESPACE_IMPL_START + /* The code is based on the paper by D. Harel and Y. Koren, @@ -743,7 +747,7 @@ void Emb_ManPrintFanio( Emb_Man_t * p ) printf( "%15d : ", k ); else { - sprintf( Buffer, "%d - %d", (int)pow(10, k/10) * (k%10), (int)pow(10, k/10) * (k%10+1) - 1 ); + sprintf( Buffer, "%d - %d", (int)pow((double)10, k/10) * (k%10), (int)pow((double)10, k/10) * (k%10+1) - 1 ); printf( "%15s : ", Buffer ); } if ( vFanins->pArray[k] == 0 ) @@ -1692,7 +1696,7 @@ void Emb_ManDumpGnuplot( Emb_Man_t * p, char * pName, int fDumpLarge, int fShowI extern void Gia_ManGnuplotShow( char * pPlotFileName ); // char * pDirectory = "place\\"; char * pDirectory = ""; - extern char * Ioa_TimeStamp(); +// extern char * Ioa_TimeStamp(); FILE * pFile; char Buffer[1000]; Emb_Obj_t * pThis, * pNext; @@ -1865,3 +1869,5 @@ ABC_PRT( "Image dump", clock() - clk ); //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaEnable.c b/src/aig/gia/giaEnable.c index c768bb43..37f0c94f 100644 --- a/src/aig/gia/giaEnable.c +++ b/src/aig/gia/giaEnable.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -620,7 +623,7 @@ Gia_Man_t * Gia_ManRemoveEnables( Gia_Man_t * p ) } Gia_ManForEachRi( p, pObj, i ) { - pData = Vec_PtrEntry(vDatas, i); + pData = (Gia_Obj_t *)Vec_PtrEntry(vDatas, i); if ( pData == NULL ) pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); else @@ -641,3 +644,5 @@ Gia_Man_t * Gia_ManRemoveEnables( Gia_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaEquiv.c b/src/aig/gia/giaEquiv.c index 0f680e31..668bc4a2 100644 --- a/src/aig/gia/giaEquiv.c +++ b/src/aig/gia/giaEquiv.c @@ -19,6 +19,9 @@ ***********************************************************************/ #include "gia.h" +#include "cec.h" + +ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// @@ -221,6 +224,8 @@ int Gia_ManEquivCountLitsAll( Gia_Man_t * p ) int Gia_ManEquivCountClasses( Gia_Man_t * p ) { int i, Counter = 0; + if ( p->pReprs == NULL ) + return 0; for ( i = 1; i < Gia_ManObjNum(p); i++ ) Counter += Gia_ObjIsHead(p, i); return Counter; @@ -448,14 +453,14 @@ Gia_Man_t * Gia_ManEquivReduce( Gia_Man_t * p, int fUseAll, int fDualOut, int fV { printf( "Gia_ManEquivReduce(): Dual-output miter should have even number of POs.\n" ); return NULL; - } + } // check if there are any equivalences defined Gia_ManForEachObj( p, pObj, i ) if ( Gia_ObjReprObj(p, i) != NULL ) break; if ( i == Gia_ManObjNum(p) ) { - printf( "Gia_ManEquivReduce(): There are no equivalences to reduce.\n" ); +// printf( "Gia_ManEquivReduce(): There are no equivalences to reduce.\n" ); return NULL; } /* @@ -815,7 +820,7 @@ void Gia_ManSpecReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, V SeeAlso [] ***********************************************************************/ -Gia_Man_t * Gia_ManSpecReduce( Gia_Man_t * p, int fDualOut, int fVerbose ) +Gia_Man_t * Gia_ManSpecReduce( Gia_Man_t * p, int fDualOut, int fSynthesis, int fVerbose ) { Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj; @@ -858,6 +863,11 @@ Gia_Man_t * Gia_ManSpecReduce( Gia_Man_t * p, int fDualOut, int fVerbose ) Gia_ManSpecBuild( pNew, p, pObj, vXorLits, fDualOut ); Gia_ManForEachCo( p, pObj, i ) Gia_ManSpecReduce_rec( pNew, p, Gia_ObjFanin0(pObj), vXorLits, fDualOut ); + if ( !fSynthesis ) + { + Gia_ManForEachPo( p, pObj, i ) + Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + } Vec_IntForEachEntry( vXorLits, iLitNew, i ) Gia_ManAppendCo( pNew, iLitNew ); if ( Vec_IntSize(vXorLits) == 0 ) @@ -935,7 +945,7 @@ void Gia_ManSpecReduceInit_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pOb SeeAlso [] ***********************************************************************/ -Gia_Man_t * Gia_ManSpecReduceInit( Gia_Man_t * p, Gia_Cex_t * pInit, int nFrames, int fDualOut ) +Gia_Man_t * Gia_ManSpecReduceInit( Gia_Man_t * p, Abc_Cex_t * pInit, int nFrames, int fDualOut ) { Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj, * pObjRi, * pObjRo; @@ -1024,7 +1034,7 @@ Gia_Man_t * Gia_ManSpecReduceInit( Gia_Man_t * p, Gia_Cex_t * pInit, int nFrames SeeAlso [] ***********************************************************************/ -Gia_Man_t * Gia_ManSpecReduceInitFrames( Gia_Man_t * p, Gia_Cex_t * pInit, int nFramesMax, int * pnFrames, int fDualOut, int nMinOutputs ) +Gia_Man_t * Gia_ManSpecReduceInitFrames( Gia_Man_t * p, Abc_Cex_t * pInit, int nFramesMax, int * pnFrames, int fDualOut, int nMinOutputs ) { Gia_Man_t * pFrames; int f, nLits; @@ -1225,7 +1235,7 @@ int Gia_ObjCheckTfi( Gia_Man_t * p, Gia_Obj_t * pOld, Gia_Obj_t * pNode ) assert( !Gia_IsComplement(pNode) ); vVisited = Vec_PtrAlloc( 100 ); RetValue = Gia_ObjCheckTfi_rec( p, pOld, pNode, vVisited ); - Vec_PtrForEachEntry( vVisited, pObj, i ) + Vec_PtrForEachEntry( Gia_Obj_t *, vVisited, pObj, i ) pObj->fMark0 = 0; Vec_PtrFree( vVisited ); return RetValue; @@ -1293,7 +1303,9 @@ void Gia_ManEquivToChoices_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pOb pObjNew = Gia_ManObj( pNew, Gia_Lit2Var(pObj->Value) ); if ( Gia_ObjReprObj( pNew, Gia_ObjId(pNew, pObjNew) ) ) { - assert( Gia_ObjReprObj( pNew, Gia_ObjId(pNew, pObjNew) ) == pReprNew ); +// assert( Gia_ObjReprObj( pNew, Gia_ObjId(pNew, pObjNew) ) == pReprNew ); + if ( Gia_ObjReprObj( pNew, Gia_ObjId(pNew, pObjNew) ) != pReprNew ) + return; pObj->Value = Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) ); return; } @@ -1373,9 +1385,11 @@ void Gia_ManRemoveBadChoices( Gia_Man_t * p ) ***********************************************************************/ Gia_Man_t * Gia_ManEquivToChoices( Gia_Man_t * p, int nSnapshots ) { + Vec_Int_t * vNodes; Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj, * pRepr; int i; +//Gia_ManEquivPrintClasses( p, 0, 0 ); assert( (Gia_ManCoNum(p) % nSnapshots) == 0 ); Gia_ManSetPhase( p ); pNew = Gia_ManStart( Gia_ManObjNum(p) ); @@ -1397,24 +1411,77 @@ Gia_Man_t * Gia_ManEquivToChoices( Gia_Man_t * p, int nSnapshots ) Gia_ManHashAlloc( pNew ); Gia_ManForEachCo( p, pObj, i ) Gia_ManEquivToChoices_rec( pNew, p, Gia_ObjFanin0(pObj) ); + vNodes = Gia_ManGetDangling( p ); + Gia_ManForEachObjVec( vNodes, p, pObj, i ) + Gia_ManEquivToChoices_rec( pNew, p, pObj ); + Vec_IntFree( vNodes ); Gia_ManForEachCo( p, pObj, i ) if ( i % nSnapshots == 0 ) Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); Gia_ManHashStop( pNew ); Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); Gia_ManRemoveBadChoices( pNew ); -// Gia_ManEquivPrintClasses( pNew, 0, 0 ); +//Gia_ManEquivPrintClasses( pNew, 0, 0 ); pNew = Gia_ManCleanup( pTemp = pNew ); Gia_ManStop( pTemp ); -// Gia_ManEquivPrintClasses( pNew, 0, 0 ); +//Gia_ManEquivPrintClasses( pNew, 0, 0 ); return pNew; } +/**Function************************************************************* + + Synopsis [Counts the number of choice nodes] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManCountChoiceNodes( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i, Counter = 0; + if ( p->pReprs == NULL || p->pNexts == NULL ) + return 0; + Gia_ManForEachObj( p, pObj, i ) + Counter += Gia_ObjIsHead( p, i ); + return Counter; +} + +/**Function************************************************************* + + Synopsis [Counts the number of choices] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManCountChoices( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i, Counter = 0; + if ( p->pReprs == NULL || p->pNexts == NULL ) + return 0; + Gia_ManForEachObj( p, pObj, i ) + Counter += (int)(Gia_ObjNext( p, i ) > 0); + return Counter; +} + +ABC_NAMESPACE_IMPL_END + #include "aig.h" #include "saig.h" #include "cec.h" #include "giaAig.h" +ABC_NAMESPACE_IMPL_START + + /**Function************************************************************* Synopsis [Implements iteration during speculation.] @@ -1428,7 +1495,7 @@ Gia_Man_t * Gia_ManEquivToChoices( Gia_Man_t * p, int nSnapshots ) ***********************************************************************/ int Gia_CommandSpecI( Gia_Man_t * pGia, int nFramesInit, int nBTLimitInit, int fStart, int fCheckMiter, int fVerbose ) { - extern int Cec_ManCheckNonTrivialCands( Gia_Man_t * pAig ); +// extern int Cec_ManCheckNonTrivialCands( Gia_Man_t * pAig ); Aig_Man_t * pTemp; Gia_Man_t * pSrm, * pReduce, * pAux; int nIter, nStart = 0; @@ -1460,10 +1527,10 @@ int Gia_CommandSpecI( Gia_Man_t * pGia, int nFramesInit, int nBTLimitInit, int f printf( "Gia_CommandSpecI: There are only trivial equiv candidates left (PO drivers). Quitting.\n" ); break; } - pSrm = Gia_ManSpecReduce( pGia, 0, 0 ); + pSrm = Gia_ManSpecReduce( pGia, 0, 0, 0 ); // bmc2 -F 100 -C 25000 { - Gia_Cex_t * pCex; + Abc_Cex_t * pCex; int nFrames = nFramesInit; // different from default int nNodeDelta = 2000; int nBTLimit = nBTLimitInit; // different from default @@ -1471,7 +1538,7 @@ int Gia_CommandSpecI( Gia_Man_t * pGia, int nFramesInit, int nBTLimitInit, int f pTemp = Gia_ManToAig( pSrm, 0 ); // Aig_ManPrintStats( pTemp ); Gia_ManStop( pSrm ); - Saig_BmcPerform( pTemp, nStart, nFrames, nNodeDelta, 20, nBTLimit, nBTLimitAll, fVerbose, 0 ); + Saig_BmcPerform( pTemp, nStart, nFrames, nNodeDelta, 0, nBTLimit, nBTLimitAll, fVerbose, 0, NULL ); pCex = pTemp->pSeqModel; pTemp->pSeqModel = NULL; Aig_ManStop( pTemp ); if ( pCex == NULL ) @@ -1497,7 +1564,7 @@ int Gia_CommandSpecI( Gia_Man_t * pGia, int nFramesInit, int nBTLimitInit, int f // write equivalence classes Gia_WriteAiger( pGia, "gore.aig", 0, 0 ); // reduce the model - pReduce = Gia_ManSpecReduce( pGia, 0, 0 ); + pReduce = Gia_ManSpecReduce( pGia, 0, 0, 0 ); if ( pReduce ) { pReduce = Gia_ManSeqStructSweep( pAux = pReduce, 1, 1, 0 ); @@ -1516,3 +1583,5 @@ int Gia_CommandSpecI( Gia_Man_t * pGia, int nFramesInit, int nBTLimitInit, int f //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaEra.c b/src/aig/gia/giaEra.c new file mode 100644 index 00000000..ec3e1b1b --- /dev/null +++ b/src/aig/gia/giaEra.c @@ -0,0 +1,561 @@ +/**CFile**************************************************************** + + FileName [giaEra.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Explicit reachability analysis.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaEra.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" +#include "mem.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +// explicit state representation +typedef struct Gia_ObjEra_t_ Gia_ObjEra_t; +struct Gia_ObjEra_t_ +{ + int Num; // ID of this state + int Cond; // input condition + int iPrev; // previous state + int iNext; // next state in the hash table + unsigned pData[0]; // state bits +}; + +// explicit state reachability +typedef struct Gia_ManEra_t_ Gia_ManEra_t; +struct Gia_ManEra_t_ +{ + Gia_Man_t * pAig; // user's AIG manager + int nWordsSim; // 2^(PInum) + int nWordsDat; // Gia_BitWordNum + unsigned * pDataSim; // simulation data + Mem_Fixed_t * pMemory; // memory manager + Vec_Ptr_t * vStates; // reached states + Gia_ObjEra_t * pStateNew; // temporary state + int iCurState; // the current state + Vec_Int_t * vBugTrace; // the sequence of transitions + // hash table for states + int nBins; + unsigned * pBins; +}; + +static inline unsigned * Gia_ManEraData( Gia_ManEra_t * p, int i ) { return p->pDataSim + i * p->nWordsSim; } +static inline Gia_ObjEra_t * Gia_ManEraState( Gia_ManEra_t * p, int i ) { return (Gia_ObjEra_t *)Vec_PtrEntry(p->vStates, i); } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Creates reachability manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_ManEra_t * Gia_ManEraCreate( Gia_Man_t * pAig ) +{ + Vec_Ptr_t * vTruths; + Gia_ManEra_t * p; + unsigned * pTruth, * pSimInfo; + int i; + p = ABC_CALLOC( Gia_ManEra_t, 1 ); + p->pAig = pAig; + p->nWordsSim = Gia_TruthWordNum( Gia_ManPiNum(pAig) ); + p->nWordsDat = Gia_BitWordNum( Gia_ManRegNum(pAig) ); + p->pDataSim = ABC_ALLOC( unsigned, p->nWordsSim*Gia_ManObjNum(pAig) ); + p->pMemory = Mem_FixedStart( sizeof(Gia_ObjEra_t) + sizeof(unsigned) * p->nWordsDat ); + p->vStates = Vec_PtrAlloc( 100000 ); + p->nBins = Gia_PrimeCudd( 100000 ); + p->pBins = ABC_CALLOC( unsigned, p->nBins ); + Vec_PtrPush( p->vStates, NULL ); + // assign primary input values + vTruths = Vec_PtrAllocTruthTables( Gia_ManPiNum(pAig) ); + Vec_PtrForEachEntry( unsigned *, vTruths, pTruth, i ) + { + pSimInfo = Gia_ManEraData( p, Gia_ObjId(pAig, Gia_ManPi(pAig, i)) ); + memcpy( pSimInfo, pTruth, sizeof(unsigned) * p->nWordsSim ); + } + Vec_PtrFree( vTruths ); + // assign constant zero node + pSimInfo = Gia_ManEraData( p, 0 ); + memset( pSimInfo, 0, sizeof(unsigned) * p->nWordsSim ); + return p; +} + +/**Function************************************************************* + + Synopsis [Deletes reachability manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManEraFree( Gia_ManEra_t * p ) +{ + Mem_FixedStop( p->pMemory, 0 ); + Vec_PtrFree( p->vStates ); + if ( p->vBugTrace ) Vec_IntFree( p->vBugTrace ); + ABC_FREE( p->pDataSim ); + ABC_FREE( p->pBins ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [Creates new state.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_ObjEra_t * Gia_ManEraCreateState( Gia_ManEra_t * p ) +{ + Gia_ObjEra_t * pNew; + pNew = (Gia_ObjEra_t *)Mem_FixedEntryFetch( p->pMemory ); + pNew->Num = Vec_PtrSize( p->vStates ); + pNew->iPrev = 0; + Vec_PtrPush( p->vStates, pNew ); + return pNew; +} + + +/**Function************************************************************* + + Synopsis [Computes hash value of the node using its simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManEraStateHash( unsigned * pState, int nWordsSim, int nTableSize ) +{ + static int s_FPrimes[128] = { + 1009, 1049, 1093, 1151, 1201, 1249, 1297, 1361, 1427, 1459, + 1499, 1559, 1607, 1657, 1709, 1759, 1823, 1877, 1933, 1997, + 2039, 2089, 2141, 2213, 2269, 2311, 2371, 2411, 2467, 2543, + 2609, 2663, 2699, 2741, 2797, 2851, 2909, 2969, 3037, 3089, + 3169, 3221, 3299, 3331, 3389, 3461, 3517, 3557, 3613, 3671, + 3719, 3779, 3847, 3907, 3943, 4013, 4073, 4129, 4201, 4243, + 4289, 4363, 4441, 4493, 4549, 4621, 4663, 4729, 4793, 4871, + 4933, 4973, 5021, 5087, 5153, 5227, 5281, 5351, 5417, 5471, + 5519, 5573, 5651, 5693, 5749, 5821, 5861, 5923, 6011, 6073, + 6131, 6199, 6257, 6301, 6353, 6397, 6481, 6563, 6619, 6689, + 6737, 6803, 6863, 6917, 6977, 7027, 7109, 7187, 7237, 7309, + 7393, 7477, 7523, 7561, 7607, 7681, 7727, 7817, 7877, 7933, + 8011, 8039, 8059, 8081, 8093, 8111, 8123, 8147 + }; + unsigned uHash; + int i; + uHash = 0; + for ( i = 0; i < nWordsSim; i++ ) + uHash ^= pState[i] * s_FPrimes[i & 0x7F]; + return uHash % nTableSize; +} + +/**Function************************************************************* + + Synopsis [Returns the place of this state in the table or NULL if it exists.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline unsigned * Gia_ManEraHashFind( Gia_ManEra_t * p, Gia_ObjEra_t * pState ) +{ + Gia_ObjEra_t * pThis; + unsigned * pPlace = p->pBins + Gia_ManEraStateHash( pState->pData, p->nWordsDat, p->nBins ); + for ( pThis = (*pPlace)? Gia_ManEraState(p, *pPlace) : NULL; pThis; + pPlace = (unsigned *)&pThis->iNext, pThis = (*pPlace)? Gia_ManEraState(p, *pPlace) : NULL ) + if ( !memcmp( pState->pData, pThis->pData, sizeof(unsigned) * p->nWordsDat ) ) + return NULL; + return pPlace; +} + +/**Function************************************************************* + + Synopsis [Resizes the hash table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManEraHashResize( Gia_ManEra_t * p ) +{ + Gia_ObjEra_t * pThis; + unsigned * pBinsOld, * piPlace; + int nBinsOld, iNext, Counter, i; + assert( p->pBins != NULL ); + // replace the table + pBinsOld = p->pBins; + nBinsOld = p->nBins; + p->nBins = Gia_PrimeCudd( 3 * p->nBins ); + p->pBins = ABC_CALLOC( unsigned, p->nBins ); + // rehash the entries from the old table + Counter = 0; + for ( i = 0; i < nBinsOld; i++ ) + for ( pThis = (pBinsOld[i]? Gia_ManEraState(p, pBinsOld[i]) : NULL), + iNext = (pThis? pThis->iNext : 0); + pThis; pThis = (iNext? Gia_ManEraState(p, iNext) : NULL), + iNext = (pThis? pThis->iNext : 0) ) + { + assert( pThis->Num ); + pThis->iNext = 0; + piPlace = Gia_ManEraHashFind( p, pThis ); + assert( *piPlace == 0 ); // should not be there + *piPlace = pThis->Num; + Counter++; + } + assert( Counter == Vec_PtrSize( p->vStates ) - 1 ); + ABC_FREE( pBinsOld ); +} + +/**Function************************************************************* + + Synopsis [Initialize register output to the given state.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManInsertState( Gia_ManEra_t * p, Gia_ObjEra_t * pState ) +{ + Gia_Obj_t * pObj; + unsigned * pSimInfo; + int i; + Gia_ManForEachRo( p->pAig, pObj, i ) + { + pSimInfo = Gia_ManEraData( p, Gia_ObjId(p->pAig, pObj) ); + if ( Gia_InfoHasBit(pState->pData, i) ) + memset( pSimInfo, 0xff, sizeof(unsigned) * p->nWordsSim ); + else + memset( pSimInfo, 0, sizeof(unsigned) * p->nWordsSim ); + } +} + +/**Function************************************************************* + + Synopsis [Returns -1 if outputs are not asserted.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_ManOutputAsserted( Gia_ManEra_t * p, Gia_Obj_t * pObj ) +{ + unsigned * pInfo = Gia_ManEraData( p, Gia_ObjId(p->pAig, pObj) ); + int w; + for ( w = 0; w < p->nWordsSim; w++ ) + if ( pInfo[w] ) + return 32*w + Gia_WordFindFirstBit( pInfo[w] ); + return -1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManSimulateCo( Gia_ManEra_t * p, Gia_Obj_t * pObj ) +{ + int Id = Gia_ObjId(p->pAig, pObj); + unsigned * pInfo = Gia_ManEraData( p, Id ); + unsigned * pInfo0 = Gia_ManEraData( p, Gia_ObjFaninId0(pObj, Id) ); + int w; + if ( Gia_ObjFaninC0(pObj) ) + for ( w = p->nWordsSim-1; w >= 0; w-- ) + pInfo[w] = ~pInfo0[w]; + else + for ( w = p->nWordsSim-1; w >= 0; w-- ) + pInfo[w] = pInfo0[w]; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManSimulateNode( Gia_ManEra_t * p, Gia_Obj_t * pObj ) +{ + int Id = Gia_ObjId(p->pAig, pObj); + unsigned * pInfo = Gia_ManEraData( p, Id ); + unsigned * pInfo0 = Gia_ManEraData( p, Gia_ObjFaninId0(pObj, Id) ); + unsigned * pInfo1 = Gia_ManEraData( p, Gia_ObjFaninId1(pObj, Id) ); + int w; + if ( Gia_ObjFaninC0(pObj) ) + { + if ( Gia_ObjFaninC1(pObj) ) + for ( w = p->nWordsSim-1; w >= 0; w-- ) + pInfo[w] = ~(pInfo0[w] | pInfo1[w]); + else + for ( w = p->nWordsSim-1; w >= 0; w-- ) + pInfo[w] = ~pInfo0[w] & pInfo1[w]; + } + else + { + if ( Gia_ObjFaninC1(pObj) ) + for ( w = p->nWordsSim-1; w >= 0; w-- ) + pInfo[w] = pInfo0[w] & ~pInfo1[w]; + else + for ( w = p->nWordsSim-1; w >= 0; w-- ) + pInfo[w] = pInfo0[w] & pInfo1[w]; + } +} + +/**Function************************************************************* + + Synopsis [Performs one iteration of reachability analysis.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManPerformOneIter( Gia_ManEra_t * p ) +{ + Gia_Obj_t * pObj; + int i; + Gia_ManForEachObj1( p->pAig, pObj, i ) + { + if ( Gia_ObjIsAnd(pObj) ) + Gia_ManSimulateNode( p, pObj ); + else if ( Gia_ObjIsCo(pObj) ) + Gia_ManSimulateCo( p, pObj ); + } +} + +/**Function************************************************************* + + Synopsis [Performs one iteration of reachability analysis.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_ManCollectBugTrace( Gia_ManEra_t * p, Gia_ObjEra_t * pState, int iCond ) +{ + Vec_Int_t * vTrace; + vTrace = Vec_IntAlloc( 10 ); + Vec_IntPush( vTrace, iCond ); + for ( ; pState; pState = pState->iPrev ? Gia_ManEraState(p, pState->iPrev) : NULL ) + Vec_IntPush( vTrace, pState->Cond ); + Vec_IntReverseOrder( vTrace ); + return vTrace; +} + +/**Function************************************************************* + + Synopsis [Counts the depth of state transitions leading ot this state.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManCountDepth( Gia_ManEra_t * p ) +{ + Gia_ObjEra_t * pState; + int Counter = 0; + pState = (Gia_ObjEra_t *)Vec_PtrEntryLast( p->vStates ); + if ( pState->iPrev == 0 && Vec_PtrSize(p->vStates) > 3 ) + pState = (Gia_ObjEra_t *)Vec_PtrEntry( p->vStates, Vec_PtrSize(p->vStates) - 2 ); + for ( ; pState; pState = pState->iPrev ? Gia_ManEraState(p, pState->iPrev) : NULL ) + Counter++; + return Counter; +} + +/**Function************************************************************* + + Synopsis [Analized reached states.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManAnalyzeResult( Gia_ManEra_t * p, Gia_ObjEra_t * pState, int fMiter ) +{ + Gia_Obj_t * pObj; + unsigned * pSimInfo, * piPlace; + int i, k, iCond, nMints; + // check if the miter is asserted + if ( fMiter ) + { + Gia_ManForEachPo( p->pAig, pObj, i ) + { + iCond = Gia_ManOutputAsserted( p, pObj ); + if ( iCond >= 0 ) + { + p->vBugTrace = Gia_ManCollectBugTrace( p, pState, iCond ); + return 1; + } + } + } + // collect reached states + nMints = (1 << Gia_ManPiNum(p->pAig)); + for ( k = 0; k < nMints; k++ ) + { + if ( p->pStateNew == NULL ) + p->pStateNew = Gia_ManEraCreateState( p ); + p->pStateNew->pData[p->nWordsDat-1] = 0; + Gia_ManForEachRi( p->pAig, pObj, i ) + { + pSimInfo = Gia_ManEraData( p, Gia_ObjId(p->pAig, pObj) ); + if ( Gia_InfoHasBit(p->pStateNew->pData, i) != Gia_InfoHasBit(pSimInfo, k) ) + Gia_InfoXorBit( p->pStateNew->pData, i ); + } + piPlace = Gia_ManEraHashFind( p, p->pStateNew ); + if ( piPlace == NULL ) + continue; +//printf( "Inserting %d ", Vec_PtrSize(p->vStates) ); +//Extra_PrintBinary( stdout, p->pStateNew->pData, Gia_ManRegNum(p->pAig) ); printf( "\n" ); + assert( *piPlace == 0 ); + *piPlace = p->pStateNew->Num; + p->pStateNew->Cond = k; + p->pStateNew->iPrev = pState->Num; + p->pStateNew->iNext = 0; + p->pStateNew = NULL; + // expand hash table if needed + if ( Vec_PtrSize(p->vStates) > 2 * p->nBins ) + Gia_ManEraHashResize( p ); + } + return 0; +} + +/**Function************************************************************* + + Synopsis [Resizes the hash table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManCollectReachable( Gia_Man_t * pAig, int nStatesMax, int fMiter, int fVerbose ) +{ + Gia_ManEra_t * p; + Gia_ObjEra_t * pState; + int Hash, clk = clock(); + int RetValue = 1; + assert( Gia_ManPiNum(pAig) <= 12 ); + assert( Gia_ManRegNum(pAig) > 0 ); + p = Gia_ManEraCreate( pAig ); + // create init state + pState = Gia_ManEraCreateState( p ); + pState->Cond = 0; + pState->iPrev = 0; + pState->iNext = 0; + memset( pState->pData, 0, sizeof(unsigned) * p->nWordsDat ); + Hash = Gia_ManEraStateHash(pState->pData, p->nWordsDat, p->nBins); + p->pBins[ Hash ] = pState->Num; + // process reachable states + while ( p->iCurState < Vec_PtrSize( p->vStates ) - 1 ) + { + if ( Vec_PtrSize(p->vStates) >= nStatesMax ) + { + printf( "Reached the limit on states traversed (%d). ", nStatesMax ); + RetValue = -1; + break; + } + pState = Gia_ManEraState( p, ++p->iCurState ); + if ( p->iCurState > 1 && pState->iPrev == 0 ) + continue; +//printf( "Extracting %d ", p->iCurState ); +//Extra_PrintBinary( stdout, p->pStateNew->pData, Gia_ManRegNum(p->pAig) ); printf( "\n" ); + Gia_ManInsertState( p, pState ); + Gia_ManPerformOneIter( p ); + if ( Gia_ManAnalyzeResult( p, pState, fMiter ) && fMiter ) + { + RetValue = 0; + printf( "Miter failed in state %d after %d transitions. ", + p->iCurState, Vec_IntSize(p->vBugTrace)-1 ); + break; + } + if ( fVerbose && p->iCurState % 5000 == 0 ) + { + printf( "States =%10d. Reached =%10d. R = %5.3f. Depth =%6d. Mem =%9.2f Mb. ", + p->iCurState, Vec_PtrSize(p->vStates), 1.0*p->iCurState/Vec_PtrSize(p->vStates), Gia_ManCountDepth(p), + (1.0/(1<<20))*(1.0*Vec_PtrSize(p->vStates)*(sizeof(Gia_ObjEra_t) + sizeof(unsigned) * p->nWordsDat) + + 1.0*p->nBins*sizeof(unsigned) + 1.0*p->vStates->nCap * sizeof(void*)) ); + ABC_PRT( "Time", clock() - clk ); + } + } + printf( "Reachability analysis traversed %d states with depth %d. ", p->iCurState-1, Gia_ManCountDepth(p) ); + ABC_PRT( "Time", clock() - clk ); + Gia_ManEraFree( p ); + return RetValue; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaEra2.c b/src/aig/gia/giaEra2.c new file mode 100644 index 00000000..64464832 --- /dev/null +++ b/src/aig/gia/giaEra2.c @@ -0,0 +1,1954 @@ +/**CFile**************************************************************** + + FileName [gia.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: gia.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" +#include "giaAig.h" + +ABC_NAMESPACE_IMPL_START + +/* + Limitations of this package: + - no more than (1<<31)-1 state cubes and internal nodes + - no more than MAX_VARS_NUM state variables + - no more than MAX_CALL_NUM transitions from a state + - cube list rebalancing happens when cube count reaches MAX_CUBE_NUM +*/ + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +#define MAX_CALL_NUM (1000000) // the max number of recursive calls +#define MAX_ITEM_NUM (1<<20) // the number of items on a page +#define MAX_PAGE_NUM (1<<11) // the max number of memory pages +#define MAX_VARS_NUM (1<<14) // the max number of state vars allowed +#define MAX_CUBE_NUM 63 // the max number of cubes before rebalancing + +// pointer to the tree node or state cube +typedef struct Gia_PtrAre_t_ Gia_PtrAre_t; +struct Gia_PtrAre_t_ +{ + unsigned nItem : 20; // item number (related to MAX_ITEM_NUM) + unsigned nPage : 11; // page number (related to MAX_PAGE_NUM) + unsigned fMark : 1; // user mark +}; + +// tree nodes +typedef struct Gia_ObjAre_t_ Gia_ObjAre_t; +struct Gia_ObjAre_t_ +{ + unsigned iVar : 14; // variable (related to MAX_VARS_NUM) + unsigned nStas0 : 6; // cube counter (related to MAX_CUBE_NUM) + unsigned nStas1 : 6; // cube counter (related to MAX_CUBE_NUM) + unsigned nStas2 : 6; // cube counter (related to MAX_CUBE_NUM) + Gia_PtrAre_t F[3]; // branches +}; + +// state cube +typedef struct Gia_StaAre_t_ Gia_StaAre_t; +struct Gia_StaAre_t_ +{ + Gia_PtrAre_t iPrev; // previous state + Gia_PtrAre_t iNext; // next cube in the list + unsigned pData[0]; // state bits +}; + +// explicit state reachability manager +typedef struct Gia_ManAre_t_ Gia_ManAre_t; +struct Gia_ManAre_t_ +{ + Gia_Man_t * pAig; // user's AIG manager + Gia_Man_t * pNew; // temporary AIG manager + unsigned ** ppObjs; // storage for objects (MAX_PAGE_NUM pages) + unsigned ** ppStas; // storage for states (MAX_PAGE_NUM pages) +// unsigned * pfUseless; // to label useless cubes +// int nUselessAlloc; // the number of useless alloced + // internal flags + int fMiter; // stops when a bug is discovered + int fStopped; // set high when reachability is stopped + int fTree; // working in the tree mode + // internal parametesr + int nWords; // the size of bit info in words + int nSize; // the size of state structure in words + int nObjPages; // the number of pages used for objects + int nStaPages; // the number of pages used for states + int nObjs; // the number of objects + int nStas; // the number of states + int iStaCur; // the next state to be explored + Gia_PtrAre_t Root; // root of the tree + Vec_Vec_t * vCiTfos; // storage for nodes in the CI TFOs + Vec_Vec_t * vCiLits; // storage for literals of these nodes + Vec_Int_t * vCubesA; // checked cubes + Vec_Int_t * vCubesB; // unchecked cubes + // deriving counter-example + void * pSat; // SAT solver + Vec_Int_t * vSatNumCis; // SAT variables for CIs + Vec_Int_t * vSatNumCos; // SAT variables for COs + Vec_Int_t * vCofVars; // variables used to cofactor + Vec_Int_t * vAssumps; // temporary storage for assumptions + Gia_StaAre_t * pTarget; // state that needs to be reached + int iOutFail; // the number of the failed output + // statistics + int nChecks; // the number of timea cube was checked + int nEquals; // total number of equal + int nCompares; // the number of compares + int nRecCalls; // the number of rec calls + int nDisjs; // the number of disjoint cube pairs + int nDisjs2; // the number of disjoint cube pairs + int nDisjs3; // the number of disjoint cube pairs + // time + int timeAig; // AIG cofactoring time + int timeCube; // cube checking time +}; + +static inline Gia_PtrAre_t Gia_Int2Ptr( unsigned n ) { return *(Gia_PtrAre_t *)(&n); } +static inline unsigned Gia_Ptr2Int( Gia_PtrAre_t n ) { return (*(int *)(&n)) & 0x7fffffff; } + +static inline int Gia_ObjHasBranch0( Gia_ObjAre_t * q ) { return !q->nStas0 && (q->F[0].nPage || q->F[0].nItem); } +static inline int Gia_ObjHasBranch1( Gia_ObjAre_t * q ) { return !q->nStas1 && (q->F[1].nPage || q->F[1].nItem); } +static inline int Gia_ObjHasBranch2( Gia_ObjAre_t * q ) { return !q->nStas2 && (q->F[2].nPage || q->F[2].nItem); } + +static inline Gia_ObjAre_t * Gia_ManAreObj( Gia_ManAre_t * p, Gia_PtrAre_t n ) { return (Gia_ObjAre_t *)(p->ppObjs[n.nPage] + (n.nItem << 2)); } +static inline Gia_StaAre_t * Gia_ManAreSta( Gia_ManAre_t * p, Gia_PtrAre_t n ) { return (Gia_StaAre_t *)(p->ppStas[n.nPage] + n.nItem * p->nSize); } +static inline Gia_ObjAre_t * Gia_ManAreObjInt( Gia_ManAre_t * p, int n ) { return Gia_ManAreObj( p, Gia_Int2Ptr(n) ); } +static inline Gia_StaAre_t * Gia_ManAreStaInt( Gia_ManAre_t * p, int n ) { return Gia_ManAreSta( p, Gia_Int2Ptr(n) ); } +static inline Gia_ObjAre_t * Gia_ManAreObjLast( Gia_ManAre_t * p ) { return Gia_ManAreObjInt( p, p->nObjs-1 ); } +static inline Gia_StaAre_t * Gia_ManAreStaLast( Gia_ManAre_t * p ) { return Gia_ManAreStaInt( p, p->nStas-1 ); } + +static inline Gia_ObjAre_t * Gia_ObjNextObj0( Gia_ManAre_t * p, Gia_ObjAre_t * q ) { return Gia_ManAreObj( p, q->F[0] ); } +static inline Gia_ObjAre_t * Gia_ObjNextObj1( Gia_ManAre_t * p, Gia_ObjAre_t * q ) { return Gia_ManAreObj( p, q->F[1] ); } +static inline Gia_ObjAre_t * Gia_ObjNextObj2( Gia_ManAre_t * p, Gia_ObjAre_t * q ) { return Gia_ManAreObj( p, q->F[2] ); } + +static inline int Gia_StaHasValue0( Gia_StaAre_t * p, int iReg ) { return Gia_InfoHasBit( p->pData, iReg << 1 ); } +static inline int Gia_StaHasValue1( Gia_StaAre_t * p, int iReg ) { return Gia_InfoHasBit( p->pData, (iReg << 1) + 1 ); } + +static inline void Gia_StaSetValue0( Gia_StaAre_t * p, int iReg ) { Gia_InfoSetBit( p->pData, iReg << 1 ); } +static inline void Gia_StaSetValue1( Gia_StaAre_t * p, int iReg ) { Gia_InfoSetBit( p->pData, (iReg << 1) + 1 ); } + +static inline Gia_StaAre_t * Gia_StaPrev( Gia_ManAre_t * p, Gia_StaAre_t * pS ) { return Gia_ManAreSta(p, pS->iPrev); } +static inline Gia_StaAre_t * Gia_StaNext( Gia_ManAre_t * p, Gia_StaAre_t * pS ) { return Gia_ManAreSta(p, pS->iNext); } +static inline int Gia_StaIsGood( Gia_ManAre_t * p, Gia_StaAre_t * pS ) { return ((unsigned *)pS) != p->ppStas[0]; } + +static inline void Gia_StaSetUnused( Gia_StaAre_t * pS ) { pS->iPrev.fMark = 1; } +static inline int Gia_StaIsUnused( Gia_StaAre_t * pS ) { return pS->iPrev.fMark; } +static inline int Gia_StaIsUsed( Gia_StaAre_t * pS ) { return !pS->iPrev.fMark; } + +#define Gia_ManAreForEachCubeList( p, pList, pCube ) \ + for ( pCube = pList; Gia_StaIsGood(p, pCube); pCube = Gia_StaNext(p, pCube) ) +#define Gia_ManAreForEachCubeList2( p, iList, pCube, iCube ) \ + for ( iCube = Gia_Ptr2Int(iList), pCube = Gia_ManAreSta(p, iList); \ + Gia_StaIsGood(p, pCube); \ + iCube = Gia_Ptr2Int(pCube->iNext), pCube = Gia_StaNext(p, pCube) ) +#define Gia_ManAreForEachCubeStore( p, pCube, i ) \ + for ( i = 1; i < p->nStas && (pCube = Gia_ManAreStaInt(p, i)); i++ ) +#define Gia_ManAreForEachCubeVec( vVec, p, pCube, i ) \ + for ( i = 0; i < Vec_IntSize(vVec) && (pCube = Gia_ManAreStaInt(p, Vec_IntEntry(vVec,i))); i++ ) + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Count state minterms contained in a cube.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManCountMintermsInCube( Gia_StaAre_t * pCube, int nVars, unsigned * pStore ) +{ + unsigned Mint, Mask = 0; + int i, m, nMints, nDashes = 0, Dashes[32]; + // count the number of dashes + for ( i = 0; i < nVars; i++ ) + { + if ( Gia_StaHasValue0( pCube, i ) ) + continue; + if ( Gia_StaHasValue1( pCube, i ) ) + Mask |= (1 << i); + else + Dashes[nDashes++] = i; + } + // fill in the miterms + nMints = (1 << nDashes); + for ( m = 0; m < nMints; m++ ) + { + Mint = Mask; + for ( i = 0; i < nVars; i++ ) + if ( m & (1 << i) ) + Mint |= (1 << Dashes[i]); + Gia_InfoSetBit( pStore, Mint ); + } +} + +/**Function************************************************************* + + Synopsis [Count state minterms contains in the used cubes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManCountMinterms( Gia_ManAre_t * p ) +{ + Gia_StaAre_t * pCube; + unsigned * pMemory; + int i, nMemSize, Counter = 0; + if ( Gia_ManRegNum(p->pAig) > 30 ) + return -1; + nMemSize = Gia_BitWordNum( 1 << Gia_ManRegNum(p->pAig) ); + pMemory = ABC_CALLOC( unsigned, nMemSize ); + Gia_ManAreForEachCubeStore( p, pCube, i ) + if ( Gia_StaIsUsed(pCube) ) + Gia_ManCountMintermsInCube( pCube, Gia_ManRegNum(p->pAig), pMemory ); + for ( i = 0; i < nMemSize; i++ ) + Counter += Gia_WordCountOnes( pMemory[i] ); + ABC_FREE( pMemory ); + return Counter; +} + +/**Function************************************************************* + + Synopsis [Derives the TFO of one CI.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManDeriveCiTfo_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vRes ) +{ + if ( Gia_ObjIsCi(pObj) ) + return pObj->fMark0; + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return pObj->fMark0; + Gia_ObjSetTravIdCurrent(p, pObj); + assert( Gia_ObjIsAnd(pObj) ); + Gia_ManDeriveCiTfo_rec( p, Gia_ObjFanin0(pObj), vRes ); + Gia_ManDeriveCiTfo_rec( p, Gia_ObjFanin1(pObj), vRes ); + pObj->fMark0 = Gia_ObjFanin0(pObj)->fMark0 | Gia_ObjFanin1(pObj)->fMark0; + if ( pObj->fMark0 ) + Vec_IntPush( vRes, Gia_ObjId(p, pObj) ); + return pObj->fMark0; +} + + +/**Function************************************************************* + + Synopsis [Derives the TFO of one CI.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_ManDeriveCiTfoOne( Gia_Man_t * p, Gia_Obj_t * pPivot ) +{ + Vec_Int_t * vRes; + Gia_Obj_t * pObj; + int i; + assert( pPivot->fMark0 == 0 ); + pPivot->fMark0 = 1; + vRes = Vec_IntAlloc( 100 ); + Vec_IntPush( vRes, Gia_ObjId(p, pPivot) ); + Gia_ManIncrementTravId( p ); + Gia_ObjSetTravIdCurrent( p, Gia_ManConst0(p) ); + Gia_ManForEachCo( p, pObj, i ) + { + Gia_ManDeriveCiTfo_rec( p, Gia_ObjFanin0(pObj), vRes ); + if ( Gia_ObjFanin0(pObj)->fMark0 ) + Vec_IntPush( vRes, Gia_ObjId(p, pObj) ); + } + pPivot->fMark0 = 0; + return vRes; +} + +/**Function************************************************************* + + Synopsis [Derives the TFO of each CI.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Vec_t * Gia_ManDeriveCiTfo( Gia_Man_t * p ) +{ + Vec_Ptr_t * vRes; + Gia_Obj_t * pPivot; + int i; + Gia_ManCleanMark0( p ); + Gia_ManIncrementTravId( p ); + vRes = Vec_PtrAlloc( Gia_ManCiNum(p) ); + Gia_ManForEachCi( p, pPivot, i ) + Vec_PtrPush( vRes, Gia_ManDeriveCiTfoOne(p, pPivot) ); + Gia_ManCleanMark0( p ); + return (Vec_Vec_t *)vRes; +} + +/**Function************************************************************* + + Synopsis [Returns 1 if states are equal.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_StaAreEqual( Gia_StaAre_t * p1, Gia_StaAre_t * p2, int nWords ) +{ + int w; + for ( w = 0; w < nWords; w++ ) + if ( p1->pData[w] != p2->pData[w] ) + return 0; + return 1; +} + +/**Function************************************************************* + + Synopsis [Returns 1 if states are disjoint.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_StaAreDisjoint( Gia_StaAre_t * p1, Gia_StaAre_t * p2, int nWords ) +{ + int w; + for ( w = 0; w < nWords; w++ ) + if ( ((p1->pData[w] ^ p2->pData[w]) >> 1) & (p1->pData[w] ^ p2->pData[w]) & 0x55555555 ) + return 1; + return 0; +} + +/**Function************************************************************* + + Synopsis [Returns 1 if cube p1 contains cube p2.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_StaAreContain( Gia_StaAre_t * p1, Gia_StaAre_t * p2, int nWords ) +{ + int w; + for ( w = 0; w < nWords; w++ ) + if ( (p1->pData[w] | p2->pData[w]) != p2->pData[w] ) + return 0; + return 1; +} + +/**Function************************************************************* + + Synopsis [Returns the number of dashes in p1 that are non-dashes in p2.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_StaAreDashNum( Gia_StaAre_t * p1, Gia_StaAre_t * p2, int nWords ) +{ + int w, Counter = 0; + for ( w = 0; w < nWords; w++ ) + Counter += Gia_WordCountOnes( (~(p1->pData[w] ^ (p1->pData[w] >> 1))) & (p2->pData[w] ^ (p2->pData[w] >> 1)) & 0x55555555 ); + return Counter; +} + +/**Function************************************************************* + + Synopsis [Returns the number of a variable for sharping the cube.] + + Description [Counts the number of variables that have dash in p1 and + non-dash in p2. If there is exactly one such variable, returns its index. + Otherwise returns -1.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_StaAreSharpVar( Gia_StaAre_t * p1, Gia_StaAre_t * p2, int nWords ) +{ + unsigned Word; + int w, iVar = -1; + for ( w = 0; w < nWords; w++ ) + { + Word = (~(p1->pData[w] ^ (p1->pData[w] >> 1))) & (p2->pData[w] ^ (p2->pData[w] >> 1)) & 0x55555555; + if ( Word == 0 ) + continue; + if ( !Gia_WordHasOneBit(Word) ) + return -1; + // has exactly one bit + if ( iVar >= 0 ) + return -1; + // the first variable of this type + iVar = 16 * w + Gia_WordFindFirstBit( Word ) / 2; + } + return iVar; +} + +/**Function************************************************************* + + Synopsis [Returns the number of a variable for merging the cubes.] + + Description [If there is exactly one such variable, returns its index. + Otherwise returns -1.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_StaAreDisjointVar( Gia_StaAre_t * p1, Gia_StaAre_t * p2, int nWords ) +{ + unsigned Word; + int w, iVar = -1; + for ( w = 0; w < nWords; w++ ) + { + Word = (p1->pData[w] ^ p2->pData[w]) & ((p1->pData[w] ^ p2->pData[w]) >> 1) & 0x55555555; + if ( Word == 0 ) + continue; + if ( !Gia_WordHasOneBit(Word) ) + return -1; + // has exactly one bit + if ( iVar >= 0 ) + return -1; + // the first variable of this type + iVar = 16 * w + Gia_WordFindFirstBit( Word ) / 2; + } + return iVar; +} + +/**Function************************************************************* + + Synopsis [Creates reachability manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_ManAre_t * Gia_ManAreCreate( Gia_Man_t * pAig ) +{ + Gia_ManAre_t * p; + assert( sizeof(Gia_ObjAre_t) == 16 ); + p = ABC_CALLOC( Gia_ManAre_t, 1 ); + p->pAig = pAig; + p->nWords = Gia_BitWordNum( 2 * Gia_ManRegNum(pAig) ); + p->nSize = sizeof(Gia_StaAre_t)/4 + p->nWords; + p->ppObjs = ABC_CALLOC( unsigned *, MAX_PAGE_NUM ); + p->ppStas = ABC_CALLOC( unsigned *, MAX_PAGE_NUM ); + p->vCiTfos = Gia_ManDeriveCiTfo( pAig ); + p->vCiLits = Vec_VecDupInt( p->vCiTfos ); + p->vCubesA = Vec_IntAlloc( 100 ); + p->vCubesB = Vec_IntAlloc( 100 ); + p->iOutFail = -1; + return p; +} + +/**Function************************************************************* + + Synopsis [Deletes reachability manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManAreFree( Gia_ManAre_t * p ) +{ + int i; + Gia_ManStop( p->pAig ); + if ( p->pNew ) + Gia_ManStop( p->pNew ); + Vec_IntFree( p->vCubesA ); + Vec_IntFree( p->vCubesB ); + Vec_VecFree( p->vCiTfos ); + Vec_VecFree( p->vCiLits ); + for ( i = 0; i < p->nObjPages; i++ ) + ABC_FREE( p->ppObjs[i] ); + ABC_FREE( p->ppObjs ); + for ( i = 0; i < p->nStaPages; i++ ) + ABC_FREE( p->ppStas[i] ); + ABC_FREE( p->ppStas ); +// ABC_FREE( p->pfUseless ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [Returns new object.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Gia_ObjAre_t * Gia_ManAreCreateObj( Gia_ManAre_t * p ) +{ + if ( p->nObjs == p->nObjPages * MAX_ITEM_NUM ) + { + if ( p->nObjPages == MAX_PAGE_NUM ) + { + printf( "ERA manager has run out of memory after allocating 2B internal nodes.\n" ); + return NULL; + } + p->ppObjs[p->nObjPages++] = ABC_CALLOC( unsigned, MAX_ITEM_NUM * 4 ); + if ( p->nObjs == 0 ) + p->nObjs = 1; + } + return Gia_ManAreObjInt( p, p->nObjs++ ); +} + +/**Function************************************************************* + + Synopsis [Returns new state.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Gia_StaAre_t * Gia_ManAreCreateSta( Gia_ManAre_t * p ) +{ + if ( p->nStas == p->nStaPages * MAX_ITEM_NUM ) + { + if ( p->nStaPages == MAX_PAGE_NUM ) + { + printf( "ERA manager has run out of memory after allocating 2B state cubes.\n" ); + return NULL; + } + if ( p->ppStas[p->nStaPages] == NULL ) + p->ppStas[p->nStaPages] = ABC_CALLOC( unsigned, MAX_ITEM_NUM * p->nSize ); + p->nStaPages++; + if ( p->nStas == 0 ) + { + p->nStas = 1; +// p->nUselessAlloc = (1 << 18); +// p->pfUseless = ABC_CALLOC( unsigned, p->nUselessAlloc ); + } +// if ( p->nStas == p->nUselessAlloc * 32 ) +// { +// p->nUselessAlloc *= 2; +// p->pfUseless = ABC_REALLOC( unsigned, p->pfUseless, p->nUselessAlloc ); +// memset( p->pfUseless + p->nUselessAlloc/2, 0, sizeof(unsigned) * p->nUselessAlloc/2 ); +// } + } + return Gia_ManAreStaInt( p, p->nStas++ ); +} + +/**Function************************************************************* + + Synopsis [Recycles new state.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManAreRycycleSta( Gia_ManAre_t * p, Gia_StaAre_t * pSta ) +{ + memset( pSta, 0, p->nSize << 2 ); + if ( pSta == Gia_ManAreStaLast(p) ) + { + p->nStas--; + if ( p->nStas == (p->nStaPages-1) * MAX_ITEM_NUM ) + p->nStaPages--; + } + else + { +// Gia_StaSetUnused( pSta ); + } +} + +/**Function************************************************************* + + Synopsis [Creates new state state from the latch values.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Gia_StaAre_t * Gia_ManAreCreateStaNew( Gia_ManAre_t * p ) +{ + Gia_StaAre_t * pSta; + Gia_Obj_t * pObj; + int i; + pSta = Gia_ManAreCreateSta( p ); + Gia_ManForEachRi( p->pAig, pObj, i ) + { + if ( pObj->Value == 0 ) + Gia_StaSetValue0( pSta, i ); + else if ( pObj->Value == 1 ) + Gia_StaSetValue1( pSta, i ); + } + return pSta; +} + +/**Function************************************************************* + + Synopsis [Creates new state state with latch init values.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Gia_StaAre_t * Gia_ManAreCreateStaInit( Gia_ManAre_t * p ) +{ + Gia_Obj_t * pObj; + int i; + Gia_ManForEachRi( p->pAig, pObj, i ) + pObj->Value = 0; + return Gia_ManAreCreateStaNew( p ); +} + + +/**Function************************************************************* + + Synopsis [Prints the state cube.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManArePrintCube( Gia_ManAre_t * p, Gia_StaAre_t * pSta ) +{ + Gia_Obj_t * pObj; + int i, Count0 = 0, Count1 = 0, Count2 = 0; + printf( "%4d %4d : ", p->iStaCur, p->nStas-1 ); + printf( "Prev %4d ", Gia_Ptr2Int(pSta->iPrev) ); + printf( "%p ", pSta ); + Gia_ManForEachRi( p->pAig, pObj, i ) + { + if ( Gia_StaHasValue0(pSta, i) ) + printf( "0" ), Count0++; + else if ( Gia_StaHasValue1(pSta, i) ) + printf( "1" ), Count1++; + else + printf( "-" ), Count2++; + } + printf( " 0 =%3d", Count0 ); + printf( " 1 =%3d", Count1 ); + printf( " - =%3d", Count2 ); + printf( "\n" ); +} + +/**Function************************************************************* + + Synopsis [Counts the depth of state transitions leading ot this state.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManAreDepth( Gia_ManAre_t * p, int iState ) +{ + Gia_StaAre_t * pSta; + int Counter = 0; + for ( pSta = Gia_ManAreStaInt(p, iState); Gia_StaIsGood(p, pSta); pSta = Gia_StaPrev(p, pSta) ) + Counter++; + return Counter; +} + +/**Function************************************************************* + + Synopsis [Counts the number of cubes in the list.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_ManAreListCountListUsed( Gia_ManAre_t * p, Gia_PtrAre_t Root ) +{ + Gia_StaAre_t * pCube; + int Counter = 0; + Gia_ManAreForEachCubeList( p, Gia_ManAreSta(p, Root), pCube ) + Counter += Gia_StaIsUsed(pCube); + return Counter; +} + +/**Function************************************************************* + + Synopsis [Counts the number of used cubes in the tree.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManAreListCountUsed_rec( Gia_ManAre_t * p, Gia_PtrAre_t Root, int fTree ) +{ + Gia_ObjAre_t * pObj; + if ( !fTree ) + return Gia_ManAreListCountListUsed( p, Root ); + pObj = Gia_ManAreObj(p, Root); + return Gia_ManAreListCountUsed_rec( p, pObj->F[0], Gia_ObjHasBranch0(pObj) ) + + Gia_ManAreListCountUsed_rec( p, pObj->F[1], Gia_ObjHasBranch1(pObj) ) + + Gia_ManAreListCountUsed_rec( p, pObj->F[2], Gia_ObjHasBranch2(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Counts the number of used cubes in the tree.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_ManAreListCountUsed( Gia_ManAre_t * p ) +{ + return Gia_ManAreListCountUsed_rec( p, p->Root, p->fTree ); +} + + +/**Function************************************************************* + + Synopsis [Prints used cubes in the list.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_ManArePrintListUsed( Gia_ManAre_t * p, Gia_PtrAre_t Root ) +{ + Gia_StaAre_t * pCube; + Gia_ManAreForEachCubeList( p, Gia_ManAreSta(p, Root), pCube ) + if ( Gia_StaIsUsed(pCube) ) + Gia_ManArePrintCube( p, pCube ); + return 1; +} + +/**Function************************************************************* + + Synopsis [Prints used cubes in the tree.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManArePrintUsed_rec( Gia_ManAre_t * p, Gia_PtrAre_t Root, int fTree ) +{ + Gia_ObjAre_t * pObj; + if ( !fTree ) + return Gia_ManArePrintListUsed( p, Root ); + pObj = Gia_ManAreObj(p, Root); + return Gia_ManArePrintUsed_rec( p, pObj->F[0], Gia_ObjHasBranch0(pObj) ) + + Gia_ManArePrintUsed_rec( p, pObj->F[1], Gia_ObjHasBranch1(pObj) ) + + Gia_ManArePrintUsed_rec( p, pObj->F[2], Gia_ObjHasBranch2(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Prints used cubes in the tree.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_ManArePrintUsed( Gia_ManAre_t * p ) +{ + return Gia_ManArePrintUsed_rec( p, p->Root, p->fTree ); +} + + +/**Function************************************************************* + + Synopsis [Best var has max weight.] + + Description [Weight is defined as the number of 0/1-lits minus the + absolute value of the diff between the number of 0-lits and 1-lits.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManAreFindBestVar( Gia_ManAre_t * p, Gia_PtrAre_t List ) +{ + Gia_StaAre_t * pCube; + int Count0, Count1, Count2; + int iVarThis, iVarBest = -1, WeightThis, WeightBest = -1; + for ( iVarThis = 0; iVarThis < Gia_ManRegNum(p->pAig); iVarThis++ ) + { + Count0 = Count1 = Count2 = 0; + Gia_ManAreForEachCubeList( p, Gia_ManAreSta(p, List), pCube ) + { + if ( Gia_StaIsUnused(pCube) ) + continue; + if ( Gia_StaHasValue0(pCube, iVarThis) ) + Count0++; + else if ( Gia_StaHasValue1(pCube, iVarThis) ) + Count1++; + else + Count2++; + } +// printf( "%4d : %5d %5d %5d Weight = %5d\n", iVarThis, Count0, Count1, Count2, +// Count0 + Count1 - (Count0 > Count1 ? Count0 - Count1 : Count1 - Count0) ); + if ( (!Count0 && !Count1) || (!Count0 && !Count2) || (!Count1 && !Count2) ) + continue; + WeightThis = Count0 + Count1 - (Count0 > Count1 ? Count0 - Count1 : Count1 - Count0); + if ( WeightBest < WeightThis ) + { + WeightBest = WeightThis; + iVarBest = iVarThis; + } + } + if ( iVarBest == -1 ) + { + Gia_ManArePrintListUsed( p, List ); + printf( "Error: Best variable not found!!!\n" ); + } + assert( iVarBest != -1 ); + return iVarBest; +} + +/**Function************************************************************* + + Synopsis [Rebalances the tree when cubes exceed the limit.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManAreRebalance( Gia_ManAre_t * p, Gia_PtrAre_t * pRoot ) +{ + Gia_ObjAre_t * pNode; + Gia_StaAre_t * pCube; + Gia_PtrAre_t iCube, iNext; + assert( pRoot->nItem || pRoot->nPage ); + pNode = Gia_ManAreCreateObj( p ); + pNode->iVar = Gia_ManAreFindBestVar( p, *pRoot ); + for ( iCube = *pRoot, pCube = Gia_ManAreSta(p, iCube), iNext = pCube->iNext; + Gia_StaIsGood(p, pCube); + iCube = iNext, pCube = Gia_ManAreSta(p, iCube), iNext = pCube->iNext ) + { + if ( Gia_StaIsUnused(pCube) ) + continue; + if ( Gia_StaHasValue0(pCube, pNode->iVar) ) + pCube->iNext = pNode->F[0], pNode->F[0] = iCube, pNode->nStas0++; + else if ( Gia_StaHasValue1(pCube, pNode->iVar) ) + pCube->iNext = pNode->F[1], pNode->F[1] = iCube, pNode->nStas1++; + else + pCube->iNext = pNode->F[2], pNode->F[2] = iCube, pNode->nStas2++; + } + *pRoot = Gia_Int2Ptr(p->nObjs - 1); + assert( pNode == Gia_ManAreObj(p, *pRoot) ); + p->fTree = 1; +} + +/**Function************************************************************* + + Synopsis [Compresses the list by removing unused cubes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManAreCompress( Gia_ManAre_t * p, Gia_PtrAre_t * pRoot ) +{ + Gia_StaAre_t * pCube; + Gia_PtrAre_t iList = *pRoot; + Gia_PtrAre_t iCube, iNext; + assert( pRoot->nItem || pRoot->nPage ); + pRoot->nItem = 0; + pRoot->nPage = 0; + for ( iCube = iList, pCube = Gia_ManAreSta(p, iCube), iNext = pCube->iNext; + Gia_StaIsGood(p, pCube); + iCube = iNext, pCube = Gia_ManAreSta(p, iCube), iNext = pCube->iNext ) + { + if ( Gia_StaIsUnused(pCube) ) + continue; + pCube->iNext = *pRoot; + *pRoot = iCube; + } +} + + +/**Function************************************************************* + + Synopsis [Checks if the state exists in the list.] + + Description [The state may be sharped.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_ManAreCubeCheckList( Gia_ManAre_t * p, Gia_PtrAre_t * pRoot, Gia_StaAre_t * pSta ) +{ + int fVerbose = 0; + Gia_StaAre_t * pCube; + int iVar; +if ( fVerbose ) +{ +printf( "Trying cube: " ); +Gia_ManArePrintCube( p, pSta ); +} + Gia_ManAreForEachCubeList( p, Gia_ManAreSta(p, *pRoot), pCube ) + { + p->nChecks++; + if ( Gia_StaIsUnused( pCube ) ) + continue; + if ( Gia_StaAreDisjoint( pSta, pCube, p->nWords ) ) + continue; + if ( Gia_StaAreContain( pCube, pSta, p->nWords ) ) + { +if ( fVerbose ) +{ +printf( "Contained in " ); +Gia_ManArePrintCube( p, pCube ); +} + Gia_ManAreRycycleSta( p, pSta ); + return 0; + } + if ( Gia_StaAreContain( pSta, pCube, p->nWords ) ) + { +if ( fVerbose ) +{ +printf( "Contains " ); +Gia_ManArePrintCube( p, pCube ); +} + Gia_StaSetUnused( pCube ); + continue; + } + iVar = Gia_StaAreSharpVar( pSta, pCube, p->nWords ); + if ( iVar == -1 ) + continue; +if ( fVerbose ) +{ +printf( "Sharped by " ); +Gia_ManArePrintCube( p, pCube ); +Gia_ManArePrintCube( p, pSta ); +} +// printf( "%d %d\n", Gia_StaAreDashNum( pSta, pCube, p->nWords ), Gia_StaAreSharpVar( pSta, pCube, p->nWords ) ); + assert( !Gia_StaHasValue0(pSta, iVar) && !Gia_StaHasValue1(pSta, iVar) ); + assert( Gia_StaHasValue0(pCube, iVar) ^ Gia_StaHasValue1(pCube, iVar) ); + if ( Gia_StaHasValue0(pCube, iVar) ) + Gia_StaSetValue1( pSta, iVar ); + else + Gia_StaSetValue0( pSta, iVar ); +// return Gia_ManAreCubeCheckList( p, pRoot, pSta ); + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Adds new state to the list.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManAreCubeAddToList( Gia_ManAre_t * p, Gia_PtrAre_t * pRoot, Gia_StaAre_t * pSta ) +{ + int fVerbose = 0; + pSta->iNext = *pRoot; + *pRoot = Gia_Int2Ptr( p->nStas - 1 ); + assert( pSta == Gia_ManAreSta(p, *pRoot) ); +if ( fVerbose ) +{ +printf( "Adding cube: " ); +Gia_ManArePrintCube( p, pSta ); +//printf( "\n" ); +} +} + +/**Function************************************************************* + + Synopsis [Checks if the cube like this exists in the tree.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManAreCubeCheckTree_rec( Gia_ManAre_t * p, Gia_ObjAre_t * pObj, Gia_StaAre_t * pSta ) +{ + int RetValue; + if ( Gia_StaHasValue0(pSta, pObj->iVar) ) + { + if ( Gia_ObjHasBranch0(pObj) ) + RetValue = Gia_ManAreCubeCheckTree_rec( p, Gia_ObjNextObj0(p, pObj), pSta ); + else + RetValue = Gia_ManAreCubeCheckList( p, pObj->F, pSta ); + if ( RetValue == 0 ) + return 0; + } + else if ( Gia_StaHasValue1(pSta, pObj->iVar) ) + { + if ( Gia_ObjHasBranch1(pObj) ) + RetValue = Gia_ManAreCubeCheckTree_rec( p, Gia_ObjNextObj1(p, pObj), pSta ); + else + RetValue = Gia_ManAreCubeCheckList( p, pObj->F + 1, pSta ); + if ( RetValue == 0 ) + return 0; + } + if ( Gia_ObjHasBranch2(pObj) ) + return Gia_ManAreCubeCheckTree_rec( p, Gia_ObjNextObj2(p, pObj), pSta ); + return Gia_ManAreCubeCheckList( p, pObj->F + 2, pSta ); +} + +/**Function************************************************************* + + Synopsis [Adds new cube to the tree.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManAreCubeAddToTree_rec( Gia_ManAre_t * p, Gia_ObjAre_t * pObj, Gia_StaAre_t * pSta ) +{ + if ( Gia_StaHasValue0(pSta, pObj->iVar) ) + { + if ( Gia_ObjHasBranch0(pObj) ) + Gia_ManAreCubeAddToTree_rec( p, Gia_ObjNextObj0(p, pObj), pSta ); + else + { + Gia_ManAreCubeAddToList( p, pObj->F, pSta ); + if ( ++pObj->nStas0 == MAX_CUBE_NUM ) + { + pObj->nStas0 = Gia_ManAreListCountListUsed( p, pObj->F[0] ); + if ( pObj->nStas0 < MAX_CUBE_NUM/2 ) + Gia_ManAreCompress( p, pObj->F ); + else + { + Gia_ManAreRebalance( p, pObj->F ); + pObj->nStas0 = 0; + } + } + } + } + else if ( Gia_StaHasValue1(pSta, pObj->iVar) ) + { + if ( Gia_ObjHasBranch1(pObj) ) + Gia_ManAreCubeAddToTree_rec( p, Gia_ObjNextObj1(p, pObj), pSta ); + else + { + Gia_ManAreCubeAddToList( p, pObj->F+1, pSta ); + if ( ++pObj->nStas1 == MAX_CUBE_NUM ) + { + pObj->nStas1 = Gia_ManAreListCountListUsed( p, pObj->F[1] ); + if ( pObj->nStas1 < MAX_CUBE_NUM/2 ) + Gia_ManAreCompress( p, pObj->F+1 ); + else + { + Gia_ManAreRebalance( p, pObj->F+1 ); + pObj->nStas1 = 0; + } + } + } + } + else + { + if ( Gia_ObjHasBranch2(pObj) ) + Gia_ManAreCubeAddToTree_rec( p, Gia_ObjNextObj2(p, pObj), pSta ); + else + { + Gia_ManAreCubeAddToList( p, pObj->F+2, pSta ); + if ( ++pObj->nStas2 == MAX_CUBE_NUM ) + { + pObj->nStas2 = Gia_ManAreListCountListUsed( p, pObj->F[2] ); + if ( pObj->nStas2 < MAX_CUBE_NUM/2 ) + Gia_ManAreCompress( p, pObj->F+2 ); + else + { + Gia_ManAreRebalance( p, pObj->F+2 ); + pObj->nStas2 = 0; + } + } + } + } +} + + + +/**Function************************************************************* + + Synopsis [Collects overlapping cubes in the list.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_ManAreCubeCollectList( Gia_ManAre_t * p, Gia_PtrAre_t * pRoot, Gia_StaAre_t * pSta ) +{ + Gia_StaAre_t * pCube; + int iCube; + Gia_ManAreForEachCubeList2( p, *pRoot, pCube, iCube ) + { + if ( Gia_StaIsUnused( pCube ) ) + continue; + if ( Gia_StaAreDisjoint( pSta, pCube, p->nWords ) ) + { +/* + int iVar; + p->nDisjs++; + iVar = Gia_StaAreDisjointVar( pSta, pCube, p->nWords ); + if ( iVar >= 0 ) + { + p->nDisjs2++; + if ( iCube > p->iStaCur ) + p->nDisjs3++; + } +*/ + continue; + } +// p->nCompares++; +// p->nEquals += Gia_StaAreEqual( pSta, pCube, p->nWords ); + if ( iCube <= p->iStaCur ) + Vec_IntPush( p->vCubesA, iCube ); + else + Vec_IntPush( p->vCubesB, iCube ); + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Collects overlapping cubes in the tree.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManAreCubeCollectTree_rec( Gia_ManAre_t * p, Gia_ObjAre_t * pObj, Gia_StaAre_t * pSta ) +{ + int RetValue; + if ( Gia_StaHasValue0(pSta, pObj->iVar) ) + { + if ( Gia_ObjHasBranch0(pObj) ) + RetValue = Gia_ManAreCubeCollectTree_rec( p, Gia_ObjNextObj0(p, pObj), pSta ); + else + RetValue = Gia_ManAreCubeCollectList( p, pObj->F, pSta ); + if ( RetValue == 0 ) + return 0; + } + else if ( Gia_StaHasValue1(pSta, pObj->iVar) ) + { + if ( Gia_ObjHasBranch1(pObj) ) + RetValue = Gia_ManAreCubeCollectTree_rec( p, Gia_ObjNextObj1(p, pObj), pSta ); + else + RetValue = Gia_ManAreCubeCollectList( p, pObj->F + 1, pSta ); + if ( RetValue == 0 ) + return 0; + } + if ( Gia_ObjHasBranch2(pObj) ) + return Gia_ManAreCubeCollectTree_rec( p, Gia_ObjNextObj2(p, pObj), pSta ); + return Gia_ManAreCubeCollectList( p, pObj->F + 2, pSta ); +} + +/**Function************************************************************* + + Synopsis [Checks if the cube like this exists in the tree.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManAreCubeCheckTree( Gia_ManAre_t * p, Gia_StaAre_t * pSta ) +{ + Gia_StaAre_t * pCube; + int i, iVar; + assert( p->fTree ); + Vec_IntClear( p->vCubesA ); + Vec_IntClear( p->vCubesB ); + Gia_ManAreCubeCollectTree_rec( p, Gia_ManAreObj(p, p->Root), pSta ); +// if ( p->nStas > 3000 ) +// printf( "%d %d \n", Vec_IntSize(p->vCubesA), Vec_IntSize(p->vCubesB) ); +// Vec_IntSort( p->vCubesA, 0 ); +// Vec_IntSort( p->vCubesB, 0 ); + Gia_ManAreForEachCubeVec( p->vCubesA, p, pCube, i ) + { + if ( Gia_StaIsUnused( pCube ) ) + continue; + if ( Gia_StaAreDisjoint( pSta, pCube, p->nWords ) ) + continue; + if ( Gia_StaAreContain( pCube, pSta, p->nWords ) ) + { + Gia_ManAreRycycleSta( p, pSta ); + return 0; + } + if ( Gia_StaAreContain( pSta, pCube, p->nWords ) ) + { + Gia_StaSetUnused( pCube ); + continue; + } + iVar = Gia_StaAreSharpVar( pSta, pCube, p->nWords ); + if ( iVar == -1 ) + continue; + assert( !Gia_StaHasValue0(pSta, iVar) && !Gia_StaHasValue1(pSta, iVar) ); + assert( Gia_StaHasValue0(pCube, iVar) ^ Gia_StaHasValue1(pCube, iVar) ); + if ( Gia_StaHasValue0(pCube, iVar) ) + Gia_StaSetValue1( pSta, iVar ); + else + Gia_StaSetValue0( pSta, iVar ); + return Gia_ManAreCubeCheckTree( p, pSta ); + } + Gia_ManAreForEachCubeVec( p->vCubesB, p, pCube, i ) + { + if ( Gia_StaIsUnused( pCube ) ) + continue; + if ( Gia_StaAreDisjoint( pSta, pCube, p->nWords ) ) + continue; + if ( Gia_StaAreContain( pCube, pSta, p->nWords ) ) + { + Gia_ManAreRycycleSta( p, pSta ); + return 0; + } + if ( Gia_StaAreContain( pSta, pCube, p->nWords ) ) + { + Gia_StaSetUnused( pCube ); + continue; + } + iVar = Gia_StaAreSharpVar( pSta, pCube, p->nWords ); + if ( iVar == -1 ) + continue; + assert( !Gia_StaHasValue0(pSta, iVar) && !Gia_StaHasValue1(pSta, iVar) ); + assert( Gia_StaHasValue0(pCube, iVar) ^ Gia_StaHasValue1(pCube, iVar) ); + if ( Gia_StaHasValue0(pCube, iVar) ) + Gia_StaSetValue1( pSta, iVar ); + else + Gia_StaSetValue0( pSta, iVar ); + return Gia_ManAreCubeCheckTree( p, pSta ); + } +/* + if ( p->nStas > 3000 ) + { +printf( "Trying cube: " ); +Gia_ManArePrintCube( p, pSta ); + Gia_ManAreForEachCubeVec( p->vCubesA, p, pCube, i ) + { +printf( "aaaaaaaaaaaa %5d ", Vec_IntEntry(p->vCubesA,i) ); +Gia_ManArePrintCube( p, pCube ); + } + Gia_ManAreForEachCubeVec( p->vCubesB, p, pCube, i ) + { +printf( "bbbbbbbbbbbb %5d ", Vec_IntEntry(p->vCubesB,i) ); +Gia_ManArePrintCube( p, pCube ); + } + } +*/ + return 1; +} + +/**Function************************************************************* + + Synopsis [Processes the new cube.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_ManAreCubeProcess( Gia_ManAre_t * p, Gia_StaAre_t * pSta ) +{ + int RetValue; + p->nChecks = 0; + if ( !p->fTree && p->nStas == MAX_CUBE_NUM ) + Gia_ManAreRebalance( p, &p->Root ); + if ( p->fTree ) + { +// RetValue = Gia_ManAreCubeCheckTree_rec( p, Gia_ManAreObj(p, p->Root), pSta ); + RetValue = Gia_ManAreCubeCheckTree( p, pSta ); + if ( RetValue ) + Gia_ManAreCubeAddToTree_rec( p, Gia_ManAreObj(p, p->Root), pSta ); + } + else + { + RetValue = Gia_ManAreCubeCheckList( p, &p->Root, pSta ); + if ( RetValue ) + Gia_ManAreCubeAddToList( p, &p->Root, pSta ); + } +// printf( "%d ", p->nChecks ); + return RetValue; +} + + +/**Function************************************************************* + + Synopsis [Returns the most used CI, or NULL if condition is met.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManAreMostUsedPi_rec( Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return; + Gia_ObjSetTravIdCurrent(p, pObj); + if ( Gia_ObjIsCi(pObj) ) + { + pObj->Value++; + return; + } + assert( Gia_ObjIsAnd(pObj) ); + Gia_ManAreMostUsedPi_rec( p, Gia_ObjFanin0(pObj) ); + Gia_ManAreMostUsedPi_rec( p, Gia_ObjFanin1(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Returns the most used CI, or NULL if condition is met.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Gia_Obj_t * Gia_ManAreMostUsedPi( Gia_ManAre_t * p ) +{ + Gia_Obj_t * pObj, * pObjMax = NULL; + int i; + // clean CI counters + Gia_ManForEachCi( p->pNew, pObj, i ) + pObj->Value = 0; + // traverse from each register output + Gia_ManForEachRi( p->pAig, pObj, i ) + { + if ( pObj->Value <= 1 ) + continue; + Gia_ManIncrementTravId( p->pNew ); + Gia_ManAreMostUsedPi_rec( p->pNew, Gia_ManObj(p->pNew, Gia_Lit2Var(pObj->Value)) ); + } + // check the CI counters + Gia_ManForEachCi( p->pNew, pObj, i ) + if ( pObjMax == NULL || pObjMax->Value < pObj->Value ) + pObjMax = pObj; + // return the result + return pObjMax->Value > 1 ? pObjMax : NULL; +} + +/**Function************************************************************* + + Synopsis [Counts maximum support of primary outputs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManCheckPOs_rec( Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return 0; + Gia_ObjSetTravIdCurrent(p, pObj); + if ( Gia_ObjIsCi(pObj) ) + return 1; + assert( Gia_ObjIsAnd(pObj) ); + return Gia_ManCheckPOs_rec( p, Gia_ObjFanin0(pObj) ) + + Gia_ManCheckPOs_rec( p, Gia_ObjFanin1(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Counts maximum support of primary outputs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_ManCheckPOs( Gia_ManAre_t * p ) +{ + Gia_Obj_t * pObj, * pObjNew; + int i, CountCur, CountMax = 0; + Gia_ManForEachPo( p->pAig, pObj, i ) + { + pObjNew = Gia_ManObj( p->pNew, Gia_Lit2Var(pObj->Value) ); + if ( Gia_ObjIsConst0(pObjNew) ) + CountCur = 0; + else + { + Gia_ManIncrementTravId( p->pNew ); + CountCur = Gia_ManCheckPOs_rec( p->pNew, pObjNew ); + } + CountMax = ABC_MAX( CountMax, CountCur ); + } + return CountMax; +} + +/**Function************************************************************* + + Synopsis [Returns the status of the primary outputs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_ManCheckPOstatus( Gia_ManAre_t * p ) +{ + Gia_Obj_t * pObj, * pObjNew; + int i; + Gia_ManForEachPo( p->pAig, pObj, i ) + { + pObjNew = Gia_ManObj( p->pNew, Gia_Lit2Var(pObj->Value) ); + if ( Gia_ObjIsConst0(pObjNew) ) + { + if ( Gia_LitIsCompl(pObj->Value) ) + { + p->iOutFail = i; + return 1; + } + } + else + { + p->iOutFail = i; +// printf( "To fix later: PO may be assertable.\n" ); + return 1; + } + } + return 0; +} + +/**Function************************************************************* + + Synopsis [Derives next state cubes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManAreDeriveNexts_rec( Gia_ManAre_t * p, Gia_PtrAre_t Sta ) +{ + Gia_Obj_t * pPivot; + Vec_Int_t * vLits, * vTfos; + Gia_Obj_t * pObj; + int i, clk; + if ( ++p->nRecCalls == MAX_CALL_NUM ) + return 0; + if ( (pPivot = Gia_ManAreMostUsedPi(p)) == NULL ) + { + Gia_StaAre_t * pNew; + clk = clock(); + pNew = Gia_ManAreCreateStaNew( p ); + pNew->iPrev = Sta; + p->fStopped = (p->fMiter && (Gia_ManCheckPOstatus(p) & 1)); + if ( p->fStopped ) + { + assert( p->pTarget == NULL ); + p->pTarget = pNew; + return 1; + } + Gia_ManAreCubeProcess( p, pNew ); + p->timeCube += clock() - clk; + return p->fStopped; + } + // remember values in the cone and perform update + vTfos = (Vec_Int_t *)Vec_VecEntry( p->vCiTfos, Gia_ObjCioId(pPivot) ); + vLits = (Vec_Int_t *)Vec_VecEntry( p->vCiLits, Gia_ObjCioId(pPivot) ); + assert( Vec_IntSize(vTfos) == Vec_IntSize(vLits) ); + Gia_ManForEachObjVec( vTfos, p->pAig, pObj, i ) + { + Vec_IntWriteEntry( vLits, i, pObj->Value ); + if ( Gia_ObjIsAnd(pObj) ) + pObj->Value = Gia_ManHashAnd( p->pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + else if ( Gia_ObjIsCo(pObj) ) + pObj->Value = Gia_ObjFanin0Copy(pObj); + else + { + assert( Gia_ObjIsCi(pObj) ); + pObj->Value = 0; + } + } + if ( Gia_ManAreDeriveNexts_rec( p, Sta ) ) + return 1; + // compute different values + Gia_ManForEachObjVec( vTfos, p->pAig, pObj, i ) + { + if ( Gia_ObjIsAnd(pObj) ) + pObj->Value = Gia_ManHashAnd( p->pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + else if ( Gia_ObjIsCo(pObj) ) + pObj->Value = Gia_ObjFanin0Copy(pObj); + else + { + assert( Gia_ObjIsCi(pObj) ); + pObj->Value = 1; + } + } + if ( Gia_ManAreDeriveNexts_rec( p, Sta ) ) + return 1; + // reset the original values + Gia_ManForEachObjVec( vTfos, p->pAig, pObj, i ) + pObj->Value = Vec_IntEntry( vLits, i ); + return 0; +} + +/**Function************************************************************* + + Synopsis [Derives next state cubes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManAreDeriveNexts( Gia_ManAre_t * p, Gia_PtrAre_t Sta ) +{ + Gia_StaAre_t * pSta; + Gia_Obj_t * pObj; + int i, RetValue, clk = clock(); + pSta = Gia_ManAreSta( p, Sta ); + if ( Gia_StaIsUnused(pSta) ) + return 0; + // recycle the manager + if ( p->pNew && Gia_ManObjNum(p->pNew) > 1000000 ) + { + Gia_ManStop( p->pNew ); + p->pNew = NULL; + } + // allocate the manager + if ( p->pNew == NULL ) + { + p->pNew = Gia_ManStart( 10 * Gia_ManObjNum(p->pAig) ); + Gia_ManIncrementTravId( p->pNew ); + Gia_ManHashAlloc( p->pNew ); + Gia_ManConst0(p->pAig)->Value = 0; + Gia_ManForEachCi( p->pAig, pObj, i ) + pObj->Value = Gia_ManAppendCi(p->pNew); + } + Gia_ManForEachRo( p->pAig, pObj, i ) + { + if ( Gia_StaHasValue0( pSta, i ) ) + pObj->Value = 0; + else if ( Gia_StaHasValue1( pSta, i ) ) + pObj->Value = 1; + else // don't-care literal + pObj->Value = Gia_Var2Lit( Gia_ObjId( p->pNew, Gia_ManCi(p->pNew, Gia_ObjCioId(pObj)) ), 0 ); + } + Gia_ManForEachAnd( p->pAig, pObj, i ) + pObj->Value = Gia_ManHashAnd( p->pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + Gia_ManForEachCo( p->pAig, pObj, i ) + pObj->Value = Gia_ObjFanin0Copy(pObj); + + // perform case-splitting + p->nRecCalls = 0; + RetValue = Gia_ManAreDeriveNexts_rec( p, Sta ); + if ( p->nRecCalls >= MAX_CALL_NUM ) + { + printf( "Exceeded the limit on the number of transitions from a state cube (%d).\n", MAX_CALL_NUM ); + p->fStopped = 1; + } +// printf( "%d ", p->nRecCalls ); +//printf( "%d ", Gia_ManObjNum(p->pNew) ); + p->timeAig += clock() - clk; + return RetValue; +} + + +/**Function************************************************************* + + Synopsis [Prints the report] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManArePrintReport( Gia_ManAre_t * p, int Time, int fFinal ) +{ + printf( "States =%10d. Reached =%10d. R = %5.3f. Depth =%6d. Mem =%9.2f Mb. ", + p->iStaCur, p->nStas, 1.0*p->iStaCur/p->nStas, Gia_ManAreDepth(p, p->iStaCur), + (sizeof(Gia_ManAre_t) + 4.0*Gia_ManRegNum(p->pAig) + 8.0*MAX_PAGE_NUM + + 4.0*p->nStaPages*p->nSize*MAX_ITEM_NUM + 16.0*p->nObjPages*MAX_ITEM_NUM)/(1<<20) ); + if ( fFinal ) + { + ABC_PRT( "Time", clock() - Time ); + } + else + { + ABC_PRTr( "Time", clock() - Time ); + } +} + +/**Function************************************************************* + + Synopsis [Performs explicit reachability.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManArePerform( Gia_Man_t * pAig, int nStatesMax, int fMiter, int fVerbose ) +{ +// extern Gia_Man_t * Gia_ManCompress2( Gia_Man_t * p, int fUpdateLevel, int fVerbose ); + extern Abc_Cex_t * Gia_ManAreDeriveCex( Gia_ManAre_t * p, Gia_StaAre_t * pLast ); + Gia_ManAre_t * p; + int clk = clock(); + int RetValue = 1; + if ( Gia_ManRegNum(pAig) > MAX_VARS_NUM ) + { + printf( "Currently can only handle circuit with up to %d registers.\n", MAX_VARS_NUM ); + return -1; + } + ABC_FREE( pAig->pCexSeq ); + p = Gia_ManAreCreate( Gia_ManCompress2(pAig, 0, 0) ); + p->fMiter = fMiter; + Gia_ManAreCubeProcess( p, Gia_ManAreCreateStaInit(p) ); + for ( p->iStaCur = 1; p->iStaCur < p->nStas; p->iStaCur++ ) + { +// printf( "Explored state %d. Total cubes %d.\n", p->iStaCur, p->nStas-1 ); + if ( Gia_ManAreDeriveNexts( p, Gia_Int2Ptr(p->iStaCur) ) || p->nStas > nStatesMax ) + pAig->pCexSeq = Gia_ManAreDeriveCex( p, p->pTarget ); + if ( p->fStopped ) + { + RetValue = -1; + break; + } + if ( fVerbose && p->iStaCur % 5000 == 0 ) + Gia_ManArePrintReport( p, clk, 0 ); + } + Gia_ManArePrintReport( p, clk, 1 ); + printf( "%s after finding %d state cubes (%d not contained) with depth %d. ", + p->fStopped ? "Stopped" : "Completed", + p->nStas, Gia_ManAreListCountUsed(p), + Gia_ManAreDepth(p, p->iStaCur-1) ); + ABC_PRT( "Time", clock() - clk ); + if ( pAig->pCexSeq != NULL ) +// printf( "Miter FAILED in state %d at frame %d (use \"&write_counter\" to dump a witness)\n", + printf( "Miter FAILED in state %d at frame %d (the cex is available for refinement)\n", + p->iStaCur, Gia_ManAreDepth(p, p->iStaCur)-1 ); + if ( fVerbose ) + { + ABC_PRTP( "Cofactoring", p->timeAig - p->timeCube, clock() - clk ); + ABC_PRTP( "Containment", p->timeCube, clock() - clk ); + ABC_PRTP( "Other ", clock() - clk - p->timeAig, clock() - clk ); + ABC_PRTP( "TOTAL ", clock() - clk, clock() - clk ); + } + if ( Gia_ManRegNum(pAig) <= 30 ) + { + clk = clock(); + printf( "The number of unique state minterms in computed state cubes is %d. ", Gia_ManCountMinterms(p) ); + ABC_PRT( "Time", clock() - clk ); + } +// printf( "Compares = %d. Equals = %d. Disj = %d. Disj2 = %d. Disj3 = %d.\n", +// p->nCompares, p->nEquals, p->nDisjs, p->nDisjs2, p->nDisjs3 ); +// Gia_ManAreFindBestVar( p, Gia_ManAreSta(p, p->Root) ); +// Gia_ManArePrintUsed( p ); + Gia_ManAreFree( p ); + // verify + if ( pAig->pCexSeq ) + { + if ( !Gia_ManVerifyCounterExample( pAig, pAig->pCexSeq, 0 ) ) + printf( "Generated counter-example is INVALID. \n" ); + else + printf( "Generated counter-example verified correctly. \n" ); + return 0; + } + return RetValue; +} + +ABC_NAMESPACE_IMPL_END + +#include "giaAig.h" +#include "cnf.h" +#include "satSolver.h" + +ABC_NAMESPACE_IMPL_START + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManAreDeriveCexSatStart( Gia_ManAre_t * p ) +{ + Aig_Man_t * pAig2; + Cnf_Dat_t * pCnf; + assert( p->pSat == NULL ); + pAig2 = Gia_ManToAig( p->pAig, 0 ); + Aig_ManSetRegNum( pAig2, 0 ); + pCnf = Cnf_Derive( pAig2, Gia_ManCoNum(p->pAig) ); + p->pSat = Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); + p->vSatNumCis = Cnf_DataCollectCiSatNums( pCnf, pAig2 ); + p->vSatNumCos = Cnf_DataCollectCoSatNums( pCnf, pAig2 ); + Cnf_DataFree( pCnf ); + Aig_ManStop( pAig2 ); + p->vAssumps = Vec_IntAlloc( 100 ); + p->vCofVars = Vec_IntAlloc( 100 ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManAreDeriveCexSatStop( Gia_ManAre_t * p ) +{ + assert( p->pSat != NULL ); + assert( p->pTarget != NULL ); + sat_solver_delete( (sat_solver *)p->pSat ); + Vec_IntFree( p->vSatNumCis ); + Vec_IntFree( p->vSatNumCos ); + Vec_IntFree( p->vAssumps ); + Vec_IntFree( p->vCofVars ); + p->pTarget = NULL; + p->pSat = NULL; +} + +/**Function************************************************************* + + Synopsis [Computes satisfying assignment in one timeframe.] + + Description [Returns the vector of integers represeting PIO ids + of the primary inputs that should be 1 in the counter-example.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManAreDeriveCexSat( Gia_ManAre_t * p, Gia_StaAre_t * pCur, Gia_StaAre_t * pNext, int iOutFailed ) +{ + int i, status; + // make assuptions + Vec_IntClear( p->vAssumps ); + for ( i = 0; i < Gia_ManRegNum(p->pAig); i++ ) + { + if ( Gia_StaHasValue0(pCur, i) ) + Vec_IntPush( p->vAssumps, Gia_Var2Lit( Vec_IntEntry(p->vSatNumCis, Gia_ManPiNum(p->pAig)+i), 1 ) ); + else if ( Gia_StaHasValue1(pCur, i) ) + Vec_IntPush( p->vAssumps, Gia_Var2Lit( Vec_IntEntry(p->vSatNumCis, Gia_ManPiNum(p->pAig)+i), 0 ) ); + } + if ( pNext ) + for ( i = 0; i < Gia_ManRegNum(p->pAig); i++ ) + { + if ( Gia_StaHasValue0(pNext, i) ) + Vec_IntPush( p->vAssumps, Gia_Var2Lit( Vec_IntEntry(p->vSatNumCos, Gia_ManPoNum(p->pAig)+i), 1 ) ); + else if ( Gia_StaHasValue1(pNext, i) ) + Vec_IntPush( p->vAssumps, Gia_Var2Lit( Vec_IntEntry(p->vSatNumCos, Gia_ManPoNum(p->pAig)+i), 0 ) ); + } + if ( iOutFailed >= 0 ) + { + assert( iOutFailed < Gia_ManPoNum(p->pAig) ); + Vec_IntPush( p->vAssumps, Gia_Var2Lit( Vec_IntEntry(p->vSatNumCos, iOutFailed), 0 ) ); + } + // solve SAT + status = sat_solver_solve( (sat_solver *)p->pSat, (int *)Vec_IntArray(p->vAssumps), (int *)Vec_IntArray(p->vAssumps) + Vec_IntSize(p->vAssumps), + (ABC_INT64_T)1000000, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); + if ( status != l_True ) + { + printf( "SAT problem is not satisfiable. Failure...\n" ); + return; + } + assert( status == l_True ); + // check the model + Vec_IntClear( p->vCofVars ); + for ( i = 0; i < Gia_ManPiNum(p->pAig); i++ ) + { + if ( sat_solver_var_value( (sat_solver *)p->pSat, Vec_IntEntry(p->vSatNumCis, i) ) ) + Vec_IntPush( p->vCofVars, i ); + } + // write the current state + for ( i = 0; i < Gia_ManRegNum(p->pAig); i++ ) + { + if ( Gia_StaHasValue0(pCur, i) ) + assert( sat_solver_var_value( (sat_solver *)p->pSat, Vec_IntEntry(p->vSatNumCis, Gia_ManPiNum(p->pAig)+i) ) == 0 ); + else if ( Gia_StaHasValue1(pCur, i) ) + assert( sat_solver_var_value( (sat_solver *)p->pSat, Vec_IntEntry(p->vSatNumCis, Gia_ManPiNum(p->pAig)+i) ) == 1 ); + // set don't-care value + if ( sat_solver_var_value( (sat_solver *)p->pSat, Vec_IntEntry(p->vSatNumCis, Gia_ManPiNum(p->pAig)+i) ) == 0 ) + Gia_StaSetValue0( pCur, i ); + else + Gia_StaSetValue1( pCur, i ); + } +} + +/**Function************************************************************* + + Synopsis [Returns the status of the cone.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Cex_t * Gia_ManAreDeriveCex( Gia_ManAre_t * p, Gia_StaAre_t * pLast ) +{ + Abc_Cex_t * pCex; + Vec_Ptr_t * vStates; + Gia_StaAre_t * pSta, * pPrev; + int Var, i, v; + assert( p->iOutFail >= 0 ); + Gia_ManAreDeriveCexSatStart( p ); + // compute the trace + vStates = Vec_PtrAlloc( 1000 ); + for ( pSta = pLast; Gia_StaIsGood(p, pSta); pSta = Gia_StaPrev(p, pSta) ) + if ( pSta != pLast ) + Vec_PtrPush( vStates, pSta ); + assert( Vec_PtrSize(vStates) >= 1 ); + // start the counter-example + pCex = Gia_ManAllocCounterExample( Gia_ManRegNum(p->pAig), Gia_ManPiNum(p->pAig), Vec_PtrSize(vStates) ); + pCex->iFrame = Vec_PtrSize(vStates)-1; + pCex->iPo = p->iOutFail; + // compute states + pPrev = NULL; + Vec_PtrForEachEntry( Gia_StaAre_t *, vStates, pSta, i ) + { + Gia_ManAreDeriveCexSat( p, pSta, pPrev, (i == 0) ? p->iOutFail : -1 ); + pPrev = pSta; + // create the counter-example + Vec_IntForEachEntry( p->vCofVars, Var, v ) + { + assert( Var < Gia_ManPiNum(p->pAig) ); + Gia_InfoSetBit( pCex->pData, Gia_ManRegNum(p->pAig) + (Vec_PtrSize(vStates)-1-i) * Gia_ManPiNum(p->pAig) + Var ); + } + } + // free temporary things + Vec_PtrFree( vStates ); + Gia_ManAreDeriveCexSatStop( p ); + return pCex; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaFanout.c b/src/aig/gia/giaFanout.c index b32484af..c3e39405 100644 --- a/src/aig/gia/giaFanout.c +++ b/src/aig/gia/giaFanout.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -195,3 +198,5 @@ void Gia_ObjRemoveFanout( Gia_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pFanout ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaForce.c b/src/aig/gia/giaForce.c index 04c8f2e7..b9135404 100644 --- a/src/aig/gia/giaForce.c +++ b/src/aig/gia/giaForce.c @@ -20,9 +20,12 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + /* The code is based on the paper by F. A. Aloul, I. L. Markov, and K. A. Sakallah. - "FORCE: A Fast and Easy-To-Implement Variable-Ordering Heuristic", Proc. GLSVLSI’03. + "FORCE: A Fast and Easy-To-Implement Variable-Ordering Heuristic", Proc. GLSVLSI�03. http://www.eecs.umich.edu/~imarkov/pubs/conf/glsvlsi03-force.pdf */ @@ -1096,4 +1099,7 @@ Write = 1.81 sec //////////////////////////////////////////////////////////////////////// /// END OF FILE /// -////////////////////////////////////////////////////////////////////////
\ No newline at end of file +//////////////////////////////////////////////////////////////////////// + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaFrames.c b/src/aig/gia/giaFrames.c index c0ea6680..75b17361 100644 --- a/src/aig/gia/giaFrames.c +++ b/src/aig/gia/giaFrames.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -116,7 +119,7 @@ void Gia_ManFraSupports( Gia_ManFra_t * p ) p->vIns = Vec_PtrStart( p->pPars->nFrames ); p->vAnds = Vec_PtrStart( p->pPars->nFrames ); p->vOuts = Vec_PtrStart( p->pPars->nFrames ); - Gia_ManResetTravId( p->pAig ); + Gia_ManIncrementTravId( p->pAig ); for ( f = p->pPars->nFrames - 1; f >= 0; f-- ) { vOuts = Gia_ManCollectPoIds( p->pAig ); @@ -185,9 +188,9 @@ Gia_Man_t * Gia_ManFramesInit( Gia_Man_t * pAig, Gia_ParFra_t * pPars ) Gia_ManConst0(pAig)->Value = 0; for ( f = 0; f < pPars->nFrames; f++ ) { - vIns = Vec_PtrEntry( p->vIns, f ); - vAnds = Vec_PtrEntry( p->vAnds, f ); - vOuts = Vec_PtrEntry( p->vOuts, f ); + vIns = (Vec_Int_t *)Vec_PtrEntry( p->vIns, f ); + vAnds = (Vec_Int_t *)Vec_PtrEntry( p->vAnds, f ); + vOuts = (Vec_Int_t *)Vec_PtrEntry( p->vOuts, f ); if ( pPars->fVerbose ) printf( "Frame %3d : CI = %6d. AND = %6d. CO = %6d.\n", f, Vec_IntSize(vIns), Vec_IntSize(vAnds), Vec_IntSize(vOuts) ); @@ -344,3 +347,5 @@ Gia_Man_t * Gia_ManFrames( Gia_Man_t * pAig, Gia_ParFra_t * pPars ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaFront.c b/src/aig/gia/giaFront.c index b3a3c2d0..6f1ce5a7 100644 --- a/src/aig/gia/giaFront.c +++ b/src/aig/gia/giaFront.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -193,7 +196,7 @@ Gia_Man_t * Gia_ManFront( Gia_Man_t * p ) pFront[iFront] = 0; } assert( pNew->nObjs == p->nObjs ); - assert( nCrossCut == 0 && nCrossCutMax == nCrossCutMaxInit ); + assert( nCrossCut == 0 || nCrossCutMax == nCrossCutMaxInit ); for ( i = 0; i < pNew->nFront; i++ ) assert( pFront[i] == 0 ); ABC_FREE( pFront ); @@ -246,3 +249,5 @@ void Gia_ManFrontTest( Gia_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaGiarf.c b/src/aig/gia/giaGiarf.c new file mode 100644 index 00000000..501f9bb3 --- /dev/null +++ b/src/aig/gia/giaGiarf.c @@ -0,0 +1,1077 @@ +/**CFile**************************************************************** + + FileName [gia.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: gia.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +// combinational simulation manager +typedef struct Hcd_Man_t_ Hcd_Man_t; +struct Hcd_Man_t_ +{ + // parameters + Gia_Man_t * pGia; // the AIG to be used for simulation + int nBTLimit; // internal backtrack limit + int fVerbose; // internal verbose flag + // internal variables + unsigned * pSimInfo; // simulation info for each object + Vec_Ptr_t * vSimInfo; // pointers to the CI simulation info + Vec_Ptr_t * vSimPres; // pointers to the presense of simulation info + // temporaries + Vec_Int_t * vClassOld; // old class numbers + Vec_Int_t * vClassNew; // new class numbers + Vec_Int_t * vClassTemp; // temporary storage + Vec_Int_t * vRefinedC; // refined const reprs +}; + +static inline unsigned Hcd_ObjSim( Hcd_Man_t * p, int Id ) { return p->pSimInfo[Id]; } +static inline unsigned * Hcd_ObjSimP( Hcd_Man_t * p, int Id ) { return p->pSimInfo + Id; } +static inline unsigned Hcd_ObjSetSim( Hcd_Man_t * p, int Id, unsigned n ) { return p->pSimInfo[Id] = n; } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Starts the fraiging manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Hcd_Man_t * Gia_ManEquivStart( Gia_Man_t * pGia, int nBTLimit, int fVerbose ) +{ + Hcd_Man_t * p; + Gia_Obj_t * pObj; + int i; + p = ABC_CALLOC( Hcd_Man_t, 1 ); + p->pGia = pGia; + p->nBTLimit = nBTLimit; + p->fVerbose = fVerbose; + p->pSimInfo = ABC_ALLOC( unsigned, Gia_ManObjNum(pGia) ); + p->vClassOld = Vec_IntAlloc( 100 ); + p->vClassNew = Vec_IntAlloc( 100 ); + p->vClassTemp = Vec_IntAlloc( 100 ); + p->vRefinedC = Vec_IntAlloc( 100 ); + // collect simulation info + p->vSimInfo = Vec_PtrAlloc( 1000 ); + Gia_ManForEachCi( pGia, pObj, i ) + Vec_PtrPush( p->vSimInfo, Hcd_ObjSimP(p, Gia_ObjId(pGia,pObj)) ); + p->vSimPres = Vec_PtrAllocSimInfo( Gia_ManCiNum(pGia), 1 ); + return p; +} + +/**Function************************************************************* + + Synopsis [Starts the fraiging manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManEquivStop( Hcd_Man_t * p ) +{ + Vec_PtrFree( p->vSimInfo ); + Vec_PtrFree( p->vSimPres ); + Vec_IntFree( p->vClassOld ); + Vec_IntFree( p->vClassNew ); + Vec_IntFree( p->vClassTemp ); + Vec_IntFree( p->vRefinedC ); + ABC_FREE( p->pSimInfo ); + ABC_FREE( p ); +} + + +/**Function************************************************************* + + Synopsis [Compared two simulation infos.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Hcd_ManCompareEqual( unsigned s0, unsigned s1 ) +{ + if ( (s0 & 1) == (s1 & 1) ) + return s0 == s1; + else + return s0 ==~s1; +} + +/**Function************************************************************* + + Synopsis [Compares one simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Hcd_ManCompareConst( unsigned s ) +{ + if ( s & 1 ) + return s ==~0; + else + return s == 0; +} + +/**Function************************************************************* + + Synopsis [Creates one equivalence class.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Hcd_ManClassCreate( Gia_Man_t * pGia, Vec_Int_t * vClass ) +{ + int Repr = -1, EntPrev = -1, Ent, i; + assert( Vec_IntSize(vClass) > 0 ); + Vec_IntForEachEntry( vClass, Ent, i ) + { + if ( i == 0 ) + { + Repr = Ent; + Gia_ObjSetRepr( pGia, Ent, -1 ); + EntPrev = Ent; + } + else + { + Gia_ObjSetRepr( pGia, Ent, Repr ); + Gia_ObjSetNext( pGia, EntPrev, Ent ); + EntPrev = Ent; + } + } + Gia_ObjSetNext( pGia, EntPrev, 0 ); +} + +/**Function************************************************************* + + Synopsis [Refines one equivalence class.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Hcd_ManClassClassRemoveOne( Hcd_Man_t * p, int i ) +{ + int iRepr, Ent; + if ( Gia_ObjIsConst(p->pGia, i) ) + { + Gia_ObjSetRepr( p->pGia, i, GIA_VOID ); + return 1; + } + if ( !Gia_ObjIsClass(p->pGia, i) ) + return 0; + assert( Gia_ObjIsClass(p->pGia, i) ); + iRepr = Gia_ObjRepr( p->pGia, i ); + if ( iRepr == GIA_VOID ) + iRepr = i; + // collect nodes + Vec_IntClear( p->vClassOld ); + Vec_IntClear( p->vClassNew ); + Gia_ClassForEachObj( p->pGia, iRepr, Ent ) + { + if ( Ent == i ) + Vec_IntPush( p->vClassNew, Ent ); + else + Vec_IntPush( p->vClassOld, Ent ); + } + assert( Vec_IntSize( p->vClassNew ) == 1 ); + Hcd_ManClassCreate( p->pGia, p->vClassOld ); + Hcd_ManClassCreate( p->pGia, p->vClassNew ); + assert( !Gia_ObjIsClass(p->pGia, i) ); + return 1; +} + +/**Function************************************************************* + + Synopsis [Refines one equivalence class.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Hcd_ManClassRefineOne( Hcd_Man_t * p, int i ) +{ + unsigned Sim0, Sim1; + int Ent; + Vec_IntClear( p->vClassOld ); + Vec_IntClear( p->vClassNew ); + Vec_IntPush( p->vClassOld, i ); + Sim0 = Hcd_ObjSim(p, i); + Gia_ClassForEachObj1( p->pGia, i, Ent ) + { + Sim1 = Hcd_ObjSim(p, Ent); + if ( Hcd_ManCompareEqual( Sim0, Sim1 ) ) + Vec_IntPush( p->vClassOld, Ent ); + else + Vec_IntPush( p->vClassNew, Ent ); + } + if ( Vec_IntSize( p->vClassNew ) == 0 ) + return 0; + Hcd_ManClassCreate( p->pGia, p->vClassOld ); + Hcd_ManClassCreate( p->pGia, p->vClassNew ); + if ( Vec_IntSize(p->vClassNew) > 1 ) + return 1 + Hcd_ManClassRefineOne( p, Vec_IntEntry(p->vClassNew,0) ); + return 1; +} + +/**Function************************************************************* + + Synopsis [Computes hash key of the simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Hcd_ManHashKey( unsigned * pSim, int nWords, int nTableSize ) +{ + static int s_Primes[16] = { + 1291, 1699, 1999, 2357, 2953, 3313, 3907, 4177, + 4831, 5147, 5647, 6343, 6899, 7103, 7873, 8147 }; + unsigned uHash = 0; + int i; + if ( pSim[0] & 1 ) + for ( i = 0; i < nWords; i++ ) + uHash ^= ~pSim[i] * s_Primes[i & 0xf]; + else + for ( i = 0; i < nWords; i++ ) + uHash ^= pSim[i] * s_Primes[i & 0xf]; + return (int)(uHash % nTableSize); + +} + +/**Function************************************************************* + + Synopsis [Rehashes the refined classes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Hcd_ManClassesRehash( Hcd_Man_t * p, Vec_Int_t * vRefined ) +{ + int * pTable, nTableSize, Key, i, k; + nTableSize = Gia_PrimeCudd( 100 + Vec_IntSize(vRefined) / 5 ); + pTable = ABC_CALLOC( int, nTableSize ); + Vec_IntForEachEntry( vRefined, i, k ) + { + assert( !Hcd_ManCompareConst( Hcd_ObjSim(p, i) ) ); + Key = Hcd_ManHashKey( Hcd_ObjSimP(p, i), 1, nTableSize ); + if ( pTable[Key] == 0 ) + Gia_ObjSetRepr( p->pGia, i, GIA_VOID ); + else + { + Gia_ObjSetNext( p->pGia, pTable[Key], i ); + Gia_ObjSetRepr( p->pGia, i, Gia_ObjRepr(p->pGia, pTable[Key]) ); + if ( Gia_ObjRepr(p->pGia, i) == GIA_VOID ) + Gia_ObjSetRepr( p->pGia, i, pTable[Key] ); + } + pTable[Key] = i; + } + ABC_FREE( pTable ); +// Gia_ManEquivPrintClasses( p->pGia, 0, 0.0 ); + // refine classes in the table + Vec_IntForEachEntry( vRefined, i, k ) + { + if ( Gia_ObjIsHead( p->pGia, i ) ) + Hcd_ManClassRefineOne( p, i ); + } + Gia_ManEquivPrintClasses( p->pGia, 0, 0.0 ); +} + +/**Function************************************************************* + + Synopsis [Refines equivalence classes after simulation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Hcd_ManClassesRefine( Hcd_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i; + Vec_IntClear( p->vRefinedC ); + Gia_ManForEachAnd( p->pGia, pObj, i ) + { + if ( Gia_ObjIsTail(p->pGia, i) ) // add check for the class level + { + Hcd_ManClassRefineOne( p, Gia_ObjRepr(p->pGia, i) ); + } + else if ( Gia_ObjIsConst(p->pGia, i) ) + { + if ( !Hcd_ManCompareConst( Hcd_ObjSim(p, i) ) ) + Vec_IntPush( p->vRefinedC, i ); + } + } + Hcd_ManClassesRehash( p, p->vRefinedC ); +} + +/**Function************************************************************* + + Synopsis [Creates equivalence classes for the first time.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Hcd_ManClassesCreate( Hcd_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i; + assert( p->pGia->pReprs == NULL ); + p->pGia->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(p->pGia) ); + p->pGia->pNexts = ABC_CALLOC( int, Gia_ManObjNum(p->pGia) ); + Gia_ManForEachObj( p->pGia, pObj, i ) + Gia_ObjSetRepr( p->pGia, i, Gia_ObjIsAnd(pObj) ? 0 : GIA_VOID ); +} + +/**Function************************************************************* + + Synopsis [Initializes simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Hcd_ManSimulationInit( Hcd_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i; + Gia_ManForEachCi( p->pGia, pObj, i ) + Hcd_ObjSetSim( p, i, (Gia_ManRandom(0) << 1) ); +} + +/**Function************************************************************* + + Synopsis [Performs one round of simple combinational simulation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Hcd_ManSimulateSimple( Hcd_Man_t * p ) +{ + Gia_Obj_t * pObj; + unsigned Res0, Res1; + int i; + Gia_ManForEachAnd( p->pGia, pObj, i ) + { + Res0 = Hcd_ObjSim( p, Gia_ObjFaninId0(pObj, i) ); + Res1 = Hcd_ObjSim( p, Gia_ObjFaninId1(pObj, i) ); + Hcd_ObjSetSim( p, i, (Gia_ObjFaninC0(pObj)? ~Res0: Res0) & + (Gia_ObjFaninC1(pObj)? ~Res1: Res1) ); + } +} + + +/**Function************************************************************* + + Synopsis [Resimulate and refine one equivalence class.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned Gia_Resimulate_rec( Hcd_Man_t * p, int iObj ) +{ + Gia_Obj_t * pObj; + unsigned Res0, Res1; + if ( Gia_ObjIsTravIdCurrentId( p->pGia, iObj ) ) + return Hcd_ObjSim( p, iObj ); + Gia_ObjSetTravIdCurrentId( p->pGia, iObj ); + pObj = Gia_ManObj(p->pGia, iObj); + if ( Gia_ObjIsCi(pObj) ) + return Hcd_ObjSim( p, iObj ); + assert( Gia_ObjIsAnd(pObj) ); + Res0 = Gia_Resimulate_rec( p, Gia_ObjFaninId0(pObj, iObj) ); + Res1 = Gia_Resimulate_rec( p, Gia_ObjFaninId1(pObj, iObj) ); + return Hcd_ObjSetSim( p, iObj, (Gia_ObjFaninC0(pObj)? ~Res0: Res0) & + (Gia_ObjFaninC1(pObj)? ~Res1: Res1) ); +} + +/**Function************************************************************* + + Synopsis [Resimulate and refine one equivalence class.] + + Description [Assumes that the counter-example is assigned at the PIs. + The counter-example should have the first bit set to 0 at each PI.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ResimulateAndRefine( Hcd_Man_t * p, int i ) +{ + int RetValue, iObj; + Gia_ManIncrementTravId( p->pGia ); + Gia_ClassForEachObj( p->pGia, i, iObj ) + Gia_Resimulate_rec( p, iObj ); + RetValue = Hcd_ManClassRefineOne( p, i ); + if ( RetValue == 0 ) + printf( "!!! no refinement !!!\n" ); +// assert( RetValue ); +} + +/**Function************************************************************* + + Synopsis [Returns temporary representative of the node.] + + Description [The temp repr is the first node among the nodes in the class that + (a) precedes the given node, and (b) whose level is lower than the given node.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Gia_Obj_t * Gia_ObjTempRepr( Gia_Man_t * p, int i, int Level ) +{ + int iRepr, iMember; + iRepr = Gia_ObjRepr( p, i ); + if ( !Gia_ObjProved(p, i) ) + return NULL; + if ( Gia_ObjFailed(p, i) ) + return NULL; + if ( iRepr == GIA_VOID ) + return NULL; + if ( iRepr == 0 ) + return Gia_ManConst0( p ); +// if ( p->pLevels[iRepr] < Level ) +// return Gia_ManObj( p, iRepr ); + Gia_ClassForEachObj( p, iRepr, iMember ) + { + if ( Gia_ObjFailed(p, iMember) ) + continue; + if ( iMember >= i ) + return NULL; + if ( Gia_ObjLevelId(p, iMember) < Level ) + return Gia_ManObj( p, iMember ); + } + assert( 0 ); + return NULL; +} + +/**Function************************************************************* + + Synopsis [Generates reduced AIG for the given level.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_GenerateReducedLevel( Gia_Man_t * p, int Level, Vec_Ptr_t ** pvRoots ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj, * pRepr; + Vec_Ptr_t * vRoots; + int i; + vRoots = Vec_PtrAlloc( 100 ); + // copy unmarked nodes + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Gia_UtilStrsav( p->pName ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi(pNew); + Gia_ManHashAlloc( pNew ); + Gia_ManForEachAnd( p, pObj, i ) + { + if ( Gia_ObjLevelId(p, i) > Level ) + continue; + if ( Gia_ObjLevelId(p, i) == Level ) + Vec_PtrPush( vRoots, pObj ); + if ( Gia_ObjLevelId(p, i) < Level && (pRepr = Gia_ObjTempRepr(p, i, Level)) ) + { +// printf( "Substituting %d <--- %d\n", Gia_ObjId(p, pRepr), Gia_ObjId(p, pObj) ); + assert( pRepr < pObj ); + pObj->Value = Gia_LitNotCond( pRepr->Value, Gia_ObjPhase(pRepr) ^ Gia_ObjPhase(pObj) ); + continue; + } + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + } + *pvRoots = vRoots; + // required by SAT solving + Gia_ManCreateRefs( pNew ); + Gia_ManFillValue( pNew ); + Gia_ManIncrementTravId( pNew ); // needed for MiniSat to record cexes +// Gia_ManSetPhase( pNew ); // needed if MiniSat is using polarity -- should not be enabled for TAS because fPhase is used to label + return pNew; +} + +/**Function************************************************************* + + Synopsis [Collects relevant classes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Gia_CollectRelatedClasses( Gia_Man_t * pGia, Vec_Ptr_t * vRoots ) +{ + Vec_Ptr_t * vClasses; + Gia_Obj_t * pRoot, * pRepr; + int i; + vClasses = Vec_PtrAlloc( 100 ); + Gia_ManConst0( pGia )->fMark0 = 1; + Vec_PtrForEachEntry( Gia_Obj_t *, vRoots, pRoot, i ) + { + pRepr = Gia_ObjReprObj( pGia, Gia_ObjId(pGia, pRoot) ); + if ( pRepr == NULL || pRepr->fMark0 ) + continue; + pRepr->fMark0 = 1; + Vec_PtrPush( vClasses, pRepr ); + } + Gia_ManConst0( pGia )->fMark0 = 0; + Vec_PtrForEachEntry( Gia_Obj_t *, vClasses, pRepr, i ) + pRepr->fMark0 = 0; + return vClasses; +} + +/**Function************************************************************* + + Synopsis [Collects class members.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Obj_t * Gia_CollectClassMembers( Gia_Man_t * p, Gia_Obj_t * pRepr, Vec_Ptr_t * vMembers, int Level ) +{ + Gia_Obj_t * pTempRepr = NULL; + int iRepr, iMember; + iRepr = Gia_ObjId( p, pRepr ); + Vec_PtrClear( vMembers ); + Gia_ClassForEachObj( p, iRepr, iMember ) + { + if ( Gia_ObjLevelId(p, iMember) == Level ) + Vec_PtrPush( vMembers, Gia_ManObj( p, iMember ) ); + if ( pTempRepr == NULL && Gia_ObjLevelId(p, iMember) < Level ) + pTempRepr = Gia_ManObj( p, iMember ); + } + return pTempRepr; +} + + +/**Function************************************************************* + + Synopsis [Packs patterns into array of simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +*************************************`**********************************/ +int Gia_GiarfStorePatternTry( Vec_Ptr_t * vInfo, Vec_Ptr_t * vPres, int iBit, int * pLits, int nLits ) +{ + unsigned * pInfo, * pPres; + int i; + for ( i = 0; i < nLits; i++ ) + { + pInfo = (unsigned *)Vec_PtrEntry(vInfo, Gia_Lit2Var(pLits[i])); + pPres = (unsigned *)Vec_PtrEntry(vPres, Gia_Lit2Var(pLits[i])); + if ( Gia_InfoHasBit( pPres, iBit ) && + Gia_InfoHasBit( pInfo, iBit ) == Gia_LitIsCompl(pLits[i]) ) + return 0; + } + for ( i = 0; i < nLits; i++ ) + { + pInfo = (unsigned *)Vec_PtrEntry(vInfo, Gia_Lit2Var(pLits[i])); + pPres = (unsigned *)Vec_PtrEntry(vPres, Gia_Lit2Var(pLits[i])); + Gia_InfoSetBit( pPres, iBit ); + if ( Gia_InfoHasBit( pInfo, iBit ) == Gia_LitIsCompl(pLits[i]) ) + Gia_InfoXorBit( pInfo, iBit ); + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Procedure to test the new SAT solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_GiarfStorePattern( Vec_Ptr_t * vSimInfo, Vec_Ptr_t * vPres, Vec_Int_t * vCex ) +{ + int k; + for ( k = 1; k < 32; k++ ) + if ( Gia_GiarfStorePatternTry( vSimInfo, vPres, k, (int *)Vec_IntArray(vCex), Vec_IntSize(vCex) ) ) + break; + return (int)(k < 32); +} + +/**Function************************************************************* + + Synopsis [Inserts pattern into simulation info for the PIs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_GiarfInsertPattern( Hcd_Man_t * p, Vec_Int_t * vCex, int k ) +{ + Gia_Obj_t * pObj; + unsigned * pInfo; + int Lit, i; + Vec_IntForEachEntry( vCex, Lit, i ) + { + pObj = Gia_ManCi( p->pGia, Gia_Lit2Var(Lit) ); + pInfo = Hcd_ObjSimP( p, Gia_ObjId( p->pGia, pObj ) ); + if ( Gia_InfoHasBit( pInfo, k ) == Gia_LitIsCompl(Lit) ) + Gia_InfoXorBit( pInfo, k ); + } +} + +/**Function************************************************************* + + Synopsis [Inserts pattern into simulation info for the PIs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_GiarfPrintClasses( Gia_Man_t * pGia ) +{ + int nFails = 0; + int nProves = 0; + int nTotal = 0; + int nBoth = 0; + int i; + for ( i = 0; i < Gia_ManObjNum(pGia); i++ ) + { + nFails += Gia_ObjFailed(pGia, i); + nProves += Gia_ObjProved(pGia, i); + nTotal += Gia_ObjReprObj(pGia, i) != NULL; + nBoth += Gia_ObjFailed(pGia, i) && Gia_ObjProved(pGia, i); + } + printf( "nFails = %7d. nProves = %7d. nBoth = %7d. nTotal = %7d.\n", + nFails, nProves, nBoth, nTotal ); +} + +ABC_NAMESPACE_IMPL_END + +#include "cecInt.h" + +ABC_NAMESPACE_IMPL_START + + +/**Function************************************************************* + + Synopsis [Performs computation of AIGs with choices.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ComputeEquivalencesLevel( Hcd_Man_t * p, Gia_Man_t * pGiaLev, Vec_Ptr_t * vOldRoots, int Level, int fUseMiniSat ) +{ + int fUse2Solver = 0; + Cec_ManSat_t * pSat; + Cec_ParSat_t Pars; + Tas_Man_t * pTas; + Vec_Int_t * vCex; + Vec_Ptr_t * vClasses, * vMembers, * vOldRootsNew; + Gia_Obj_t * pRoot, * pMember, * pMemberPrev, * pRepr, * pTempRepr; + int i, k, nIter, iRoot, iRootNew, iMember, iMemberPrev, status, fOneFailed;//, iRepr;//, fTwoMember; + int nSaved = 0, nRecords = 0, nUndec = 0, nClassRefs = 0, nTsat = 0, nMiniSat = 0; + int clk, timeTsat = 0, timeMiniSat = 0, timeSim = 0, timeTotal = clock(); + if ( Vec_PtrSize(vOldRoots) == 0 ) + return 0; + // start SAT solvers + Cec_ManSatSetDefaultParams( &Pars ); + Pars.fPolarFlip = 0; + Pars.nBTLimit = p->nBTLimit; + pSat = Cec_ManSatCreate( pGiaLev, &Pars ); + pTas = Tas_ManAlloc( pGiaLev, p->nBTLimit ); + if ( fUseMiniSat ) + vCex = Cec_ManSatReadCex( pSat ); + else + vCex = Tas_ReadModel( pTas ); + vMembers = Vec_PtrAlloc( 100 ); + Vec_PtrCleanSimInfo( p->vSimPres, 0, 1 ); + // resolve constants + Vec_PtrForEachEntry( Gia_Obj_t *, vOldRoots, pRoot, i ) + { + iRoot = Gia_ObjId( p->pGia, pRoot ); + if ( !Gia_ObjIsConst( p->pGia, iRoot ) ) + continue; + iRootNew = Gia_LitNotCond( pRoot->Value, pRoot->fPhase ); + assert( iRootNew != 1 ); + if ( fUse2Solver ) + { + nTsat++; + clk = clock(); + status = Tas_ManSolve( pTas, Gia_ObjFromLit(pGiaLev, iRootNew), NULL ); + timeTsat += clock() - clk; + if ( status == -1 ) + { + nMiniSat++; + clk = clock(); + status = Cec_ManSatCheckNode( pSat, Gia_ObjFromLit(pGiaLev, iRootNew) ); + timeMiniSat += clock() - clk; + if ( status == 0 ) + { + Cec_ManSavePattern( pSat, Gia_ObjFromLit(pGiaLev, iRootNew), NULL ); + vCex = Cec_ManSatReadCex( pSat ); + } + } + else if ( status == 0 ) + vCex = Tas_ReadModel( pTas ); + } + else if ( fUseMiniSat ) + { + nMiniSat++; + clk = clock(); + status = Cec_ManSatCheckNode( pSat, Gia_ObjFromLit(pGiaLev, iRootNew) ); + timeMiniSat += clock() - clk; + if ( status == 0 ) + Cec_ManSavePattern( pSat, Gia_ObjFromLit(pGiaLev, iRootNew), NULL ); + } + else + { + nTsat++; + clk = clock(); + status = Tas_ManSolve( pTas, Gia_ObjFromLit(pGiaLev, iRootNew), NULL ); + timeTsat += clock() - clk; + } + if ( status == -1 ) // undec + { +// Gia_ObjSetFailed( p->pGia, iRoot ); + nUndec++; +// Hcd_ManClassClassRemoveOne( p, iRoot ); + Gia_ObjSetFailed( p->pGia, iRoot ); + } + else if ( status == 1 ) // unsat + { + Gia_ObjSetProved( p->pGia, iRoot ); +// printf( "proved constant %d\n", iRoot ); + } + else // sat + { +// printf( "Disproved constant %d\n", iRoot ); + Gia_ObjUnsetRepr( p->pGia, iRoot ); // do we need this? + nRecords++; + nSaved += Gia_GiarfStorePattern( p->vSimInfo, p->vSimPres, vCex ); + } + } + + vClasses = Vec_PtrAlloc( 100 ); + vOldRootsNew = Vec_PtrAlloc( 100 ); + for ( nIter = 0; Vec_PtrSize(vOldRoots) > 0; nIter++ ) + { +// printf( "Iter = %d (Size = %d)\n", nIter, Vec_PtrSize(vOldRoots) ); + // resolve equivalences + Vec_PtrClear( vClasses ); + Vec_PtrClear( vOldRootsNew ); + Gia_ManConst0( p->pGia )->fMark0 = 1; + Vec_PtrForEachEntry( Gia_Obj_t *, vOldRoots, pRoot, i ) + { + iRoot = Gia_ObjId( p->pGia, pRoot ); + if ( Gia_ObjIsHead( p->pGia, iRoot ) ) + pRepr = pRoot; + else if ( Gia_ObjIsClass( p->pGia, iRoot ) ) + pRepr = Gia_ObjReprObj( p->pGia, iRoot ); + else + continue; + if ( pRepr->fMark0 ) + continue; + pRepr->fMark0 = 1; + Vec_PtrPush( vClasses, pRepr ); +// iRepr = Gia_ObjId( p->pGia, pRepr ); +// fTwoMember = Gia_ClassIsPair(p->pGia, iRepr) + // derive temp repr and members on this level + pTempRepr = Gia_CollectClassMembers( p->pGia, pRepr, vMembers, Level ); + if ( pTempRepr ) + Vec_PtrPush( vMembers, pTempRepr ); + if ( Vec_PtrSize(vMembers) < 2 ) + continue; + // try proving the members + fOneFailed = 0; + pMemberPrev = (Gia_Obj_t *)Vec_PtrEntryLast( vMembers ); + Vec_PtrForEachEntry( Gia_Obj_t *, vMembers, pMember, k ) + { + iMemberPrev = Gia_LitNotCond( pMemberPrev->Value, pMemberPrev->fPhase ); + iMember = Gia_LitNotCond( pMember->Value, !pMember->fPhase ); + assert( iMemberPrev != iMember ); + if ( fUse2Solver ) + { + nTsat++; + clk = clock(); + status = Tas_ManSolve( pTas, Gia_ObjFromLit(pGiaLev, iMemberPrev), Gia_ObjFromLit(pGiaLev, iMember) ); + timeTsat += clock() - clk; + if ( status == -1 ) + { + nMiniSat++; + clk = clock(); + status = Cec_ManSatCheckNodeTwo( pSat, Gia_ObjFromLit(pGiaLev, iMemberPrev), Gia_ObjFromLit(pGiaLev, iMember) ); + timeMiniSat += clock() - clk; + if ( status == 0 ) + { + Cec_ManSavePattern( pSat, Gia_ObjFromLit(pGiaLev, iMemberPrev), Gia_ObjFromLit(pGiaLev, iMember) ); + vCex = Cec_ManSatReadCex( pSat ); + } + } + else if ( status == 0 ) + vCex = Tas_ReadModel( pTas ); + } + else if ( fUseMiniSat ) + { + nMiniSat++; + clk = clock(); + status = Cec_ManSatCheckNodeTwo( pSat, Gia_ObjFromLit(pGiaLev, iMemberPrev), Gia_ObjFromLit(pGiaLev, iMember) ); + timeMiniSat += clock() - clk; + if ( status == 0 ) + Cec_ManSavePattern( pSat, Gia_ObjFromLit(pGiaLev, iMemberPrev), Gia_ObjFromLit(pGiaLev, iMember) ); + } + else + { + nTsat++; + clk = clock(); + status = Tas_ManSolve( pTas, Gia_ObjFromLit(pGiaLev, iMemberPrev), Gia_ObjFromLit(pGiaLev, iMember) ); + timeTsat += clock() - clk; + } + if ( status == -1 ) // undec + { +// Gia_ObjSetFailed( p->pGia, iRoot ); + nUndec++; + if ( Gia_ObjLevel(p->pGia, pMemberPrev) > Gia_ObjLevel(p->pGia, pMember) ) + { +// Hcd_ManClassClassRemoveOne( p, Gia_ObjId(p->pGia, pMemberPrev) ); + Gia_ObjSetFailed( p->pGia, Gia_ObjId(p->pGia, pMemberPrev) ); + Gia_ObjSetFailed( p->pGia, Gia_ObjId(p->pGia, pMember) ); + } + else + { +// Hcd_ManClassClassRemoveOne( p, Gia_ObjId(p->pGia, pMember) ); + Gia_ObjSetFailed( p->pGia, Gia_ObjId(p->pGia, pMemberPrev) ); + Gia_ObjSetFailed( p->pGia, Gia_ObjId(p->pGia, pMember) ); + } + } + else if ( status == 1 ) // unsat + { +// Gia_ObjSetProved( p->pGia, iRoot ); + } + else // sat + { +// iRepr = Gia_ObjId( p->pGia, pRepr ); +// if ( Gia_ClassIsPair(p->pGia, iRepr) ) +// Gia_ClassUndoPair(p->pGia, iRepr); +// else + { + fOneFailed = 1; + nRecords++; + nSaved += Gia_GiarfStorePattern( p->vSimInfo, p->vSimPres, vCex ); + Gia_GiarfInsertPattern( p, vCex, (k % 31) + 1 ); + } + } + pMemberPrev = pMember; +// if ( fOneFailed ) +// k += Vec_PtrSize(vMembers) / 4; + } + // if fail, quit this class + if ( fOneFailed ) + { + nClassRefs++; + Vec_PtrForEachEntry( Gia_Obj_t *, vMembers, pMember, k ) + if ( pMember != pTempRepr && !Gia_ObjFailed(p->pGia, Gia_ObjId(p->pGia, pMember)) ) + Vec_PtrPush( vOldRootsNew, pMember ); + clk = clock(); + Gia_ResimulateAndRefine( p, Gia_ObjId(p->pGia, pRepr) ); + timeSim += clock() - clk; + } + else + { + Vec_PtrForEachEntry( Gia_Obj_t *, vMembers, pMember, k ) + Gia_ObjSetProved( p->pGia, Gia_ObjId(p->pGia, pMember) ); +/* +// } +// else +// { + printf( "Proved equivalent: " ); + Vec_PtrForEachEntry( Gia_Obj_t *, vMembers, pMember, k ) + printf( "%d(L=%d) ", Gia_ObjId(p->pGia, pMember), p->pGia->pLevels[Gia_ObjId(p->pGia, pMember)] ); + printf( "\n" ); +*/ + } + + } + Vec_PtrClear( vOldRoots ); + Vec_PtrForEachEntry( Gia_Obj_t *, vOldRootsNew, pMember, i ) + Vec_PtrPush( vOldRoots, pMember ); + // clean up + Gia_ManConst0( p->pGia )->fMark0 = 0; + Vec_PtrForEachEntry( Gia_Obj_t *, vClasses, pRepr, i ) + pRepr->fMark0 = 0; + } + Vec_PtrFree( vClasses ); + Vec_PtrFree( vOldRootsNew ); + printf( "nSaved = %d nRecords = %d nUndec = %d nClassRefs = %d nMiniSat = %d nTas = %d\n", + nSaved, nRecords, nUndec, nClassRefs, nMiniSat, nTsat ); + ABC_PRT( "Tas ", timeTsat ); + ABC_PRT( "MiniSat", timeMiniSat ); + ABC_PRT( "Sim ", timeSim ); + ABC_PRT( "Total ", clock() - timeTotal ); + + // resimulate +// clk = clock(); + Hcd_ManSimulateSimple( p ); + Hcd_ManClassesRefine( p ); +// ABC_PRT( "Simulate/refine", clock() - clk ); + + // verify the results + Vec_PtrFree( vMembers ); + Tas_ManStop( pTas ); + Cec_ManSatStop( pSat ); + return nIter; +} + +/**Function************************************************************* + + Synopsis [Performs computation of AIGs with choices.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ComputeEquivalences( Gia_Man_t * pGia, int nBTLimit, int fUseMiniSat, int fVerbose ) +{ + Hcd_Man_t * p; + Vec_Ptr_t * vRoots; + Gia_Man_t * pGiaLev; + int i, Lev, nLevels, nIters, clk; + Gia_ManRandom( 1 ); + Gia_ManSetPhase( pGia ); + nLevels = Gia_ManLevelNum( pGia ); + Gia_ManIncrementTravId( pGia ); + // start the manager + p = Gia_ManEquivStart( pGia, nBTLimit, fVerbose ); + // create trivial classes + Hcd_ManClassesCreate( p ); + // refine + for ( i = 0; i < 3; i++ ) + { + clk = clock(); + Hcd_ManSimulationInit( p ); + Hcd_ManSimulateSimple( p ); + ABC_PRT( "Sim", clock() - clk ); + clk = clock(); + Hcd_ManClassesRefine( p ); + ABC_PRT( "Ref", clock() - clk ); + } + // process in the levelized order + for ( Lev = 1; Lev < nLevels; Lev++ ) + { + clk = clock(); + printf( "LEVEL %3d (out of %3d) ", Lev, nLevels ); + pGiaLev = Gia_GenerateReducedLevel( pGia, Lev, &vRoots ); + nIters = Gia_ComputeEquivalencesLevel( p, pGiaLev, vRoots, Lev, fUseMiniSat ); + Gia_ManStop( pGiaLev ); + Vec_PtrFree( vRoots ); + printf( "Iters = %3d " ); + ABC_PRT( "Time", clock() - clk ); + } + Gia_GiarfPrintClasses( pGia ); + // clean up + Gia_ManEquivStop( p ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaGlitch.c b/src/aig/gia/giaGlitch.c index ed636540..a6e5315a 100644 --- a/src/aig/gia/giaGlitch.c +++ b/src/aig/gia/giaGlitch.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -779,3 +782,5 @@ void Gli_ManSwitchesAndGlitches( Gli_Man_t * p, int nPatterns, float PiTransProb //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaHash.c b/src/aig/gia/giaHash.c index 97326c92..6561ca13 100644 --- a/src/aig/gia/giaHash.c +++ b/src/aig/gia/giaHash.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -66,7 +69,7 @@ static inline int * Gia_ManHashFind( Gia_Man_t * p, int iLit0, int iLit1 ) Gia_Obj_t * pThis; int * pPlace = p->pHTable + Gia_ManHashOne( iLit0, iLit1, p->nHTable ); for ( pThis = (*pPlace)? Gia_ManObj(p, Gia_Lit2Var(*pPlace)) : NULL; pThis; - pPlace = &pThis->Value, pThis = (*pPlace)? Gia_ManObj(p, Gia_Lit2Var(*pPlace)) : NULL ) + pPlace = (int *)&pThis->Value, pThis = (*pPlace)? Gia_ManObj(p, Gia_Lit2Var(*pPlace)) : NULL ) if ( Gia_ObjFaninLit0p(p, pThis) == iLit0 && Gia_ObjFaninLit1p(p, pThis) == iLit1 ) break; return pPlace; @@ -74,6 +77,26 @@ static inline int * Gia_ManHashFind( Gia_Man_t * p, int iLit0, int iLit1 ) /**Function************************************************************* + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManHashLookup( Gia_Man_t * p, Gia_Obj_t * p0, Gia_Obj_t * p1 ) +{ + int iLit0 = Gia_ObjToLit( p, p0 ); + int iLit1 = Gia_ObjToLit( p, p1 ); + if ( iLit0 > iLit1 ) + iLit0 ^= iLit1, iLit1 ^= iLit0, iLit0 ^= iLit1; + return *Gia_ManHashFind( p, iLit0, iLit1 ); +} + +/**Function************************************************************* + Synopsis [Starts the hash table.] Description [] @@ -594,3 +617,5 @@ Gia_Man_t * Gia_ManRehash( Gia_Man_t * p, int fAddStrash ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaHcd.c b/src/aig/gia/giaHcd.c new file mode 100644 index 00000000..454785b9 --- /dev/null +++ b/src/aig/gia/giaHcd.c @@ -0,0 +1,686 @@ +/**CFile**************************************************************** + + FileName [giaHcd.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [New choice computation package.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaHcd.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" +#include "giaAig.h" +#include "aig.h" +#include "dar.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +// choicing parameters +typedef struct Hcd_Pars_t_ Hcd_Pars_t; +struct Hcd_Pars_t_ +{ + int nWords; // the number of simulation words + int nBTLimit; // conflict limit at a node + int nSatVarMax; // the max number of SAT variables + int fSynthesis; // set to 1 to perform synthesis + int fPolarFlip; // uses polarity adjustment + int fSimulateTfo; // uses simulation of TFO classes + int fPower; // uses power-aware rewriting + int fUseGia; // uses GIA package + int fUseCSat; // uses circuit-based solver + int fVerbose; // verbose stats + int timeSynth; // synthesis runtime + int nNodesAhead; // the lookahead in terms of nodes + int nCallsRecycle; // calls to perform before recycling SAT solver +}; + +extern void Gia_ComputeEquivalences( Gia_Man_t * pMiter, int nBTLimit, int fUseMiniSat, int fVerbose ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [This procedure sets default parameters.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Hcd_ManSetDefaultParams( Hcd_Pars_t * p ) +{ + memset( p, 0, sizeof(Hcd_Pars_t) ); + p->nWords = 8; // the number of simulation words + p->nBTLimit = 1000; // conflict limit at a node + p->nSatVarMax = 5000; // the max number of SAT variables + p->fSynthesis = 1; // derives three snapshots + p->fPolarFlip = 1; // uses polarity adjustment + p->fSimulateTfo = 1; // simulate TFO + p->fPower = 0; // power-aware rewriting + p->fVerbose = 0; // verbose stats + p->nNodesAhead = 1000; // the lookahead in terms of nodes + p->nCallsRecycle = 100; // calls to perform before recycling SAT solver +} + + +/**Function************************************************************* + + Synopsis [Reproduces script "compress".] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Hcd_Compress( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fPower, int fVerbose ) +//alias compress2 "b -l; rw -l; rwz -l; b -l; rwz -l; b -l" +{ + Aig_Man_t * pTemp; + + Dar_RwrPar_t ParsRwr, * pParsRwr = &ParsRwr; + Dar_RefPar_t ParsRef, * pParsRef = &ParsRef; + + Dar_ManDefaultRwrParams( pParsRwr ); + Dar_ManDefaultRefParams( pParsRef ); + + pParsRwr->fUpdateLevel = fUpdateLevel; + pParsRef->fUpdateLevel = fUpdateLevel; + + pParsRwr->fPower = fPower; + + pParsRwr->fVerbose = 0;//fVerbose; + pParsRef->fVerbose = 0;//fVerbose; + +// pAig = Aig_ManDupDfs( pAig ); + if ( fVerbose ) Aig_ManPrintStats( pAig ); + + // rewrite + Dar_ManRewrite( pAig, pParsRwr ); + pAig = Aig_ManDupDfs( pTemp = pAig ); + Aig_ManStop( pTemp ); + if ( fVerbose ) Aig_ManPrintStats( pAig ); + + // refactor + Dar_ManRefactor( pAig, pParsRef ); + pAig = Aig_ManDupDfs( pTemp = pAig ); + Aig_ManStop( pTemp ); + if ( fVerbose ) Aig_ManPrintStats( pAig ); + + // balance + if ( fBalance ) + { + pAig = Dar_ManBalance( pTemp = pAig, fUpdateLevel ); + Aig_ManStop( pTemp ); + if ( fVerbose ) Aig_ManPrintStats( pAig ); + } + + pParsRwr->fUseZeros = 1; + pParsRef->fUseZeros = 1; + + // rewrite + Dar_ManRewrite( pAig, pParsRwr ); + pAig = Aig_ManDupDfs( pTemp = pAig ); + Aig_ManStop( pTemp ); + if ( fVerbose ) Aig_ManPrintStats( pAig ); + + return pAig; +} + +/**Function************************************************************* + + Synopsis [Reproduces script "compress2".] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Hcd_Compress2( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fFanout, int fPower, int fVerbose ) +//alias compress2 "b -l; rw -l; rf -l; b -l; rw -l; rwz -l; b -l; rfz -l; rwz -l; b -l" +{ + Aig_Man_t * pTemp; + + Dar_RwrPar_t ParsRwr, * pParsRwr = &ParsRwr; + Dar_RefPar_t ParsRef, * pParsRef = &ParsRef; + + Dar_ManDefaultRwrParams( pParsRwr ); + Dar_ManDefaultRefParams( pParsRef ); + + pParsRwr->fUpdateLevel = fUpdateLevel; + pParsRef->fUpdateLevel = fUpdateLevel; + pParsRwr->fFanout = fFanout; + pParsRwr->fPower = fPower; + + pParsRwr->fVerbose = 0;//fVerbose; + pParsRef->fVerbose = 0;//fVerbose; + +// pAig = Aig_ManDupDfs( pAig ); + if ( fVerbose ) Aig_ManPrintStats( pAig ); + + // rewrite + Dar_ManRewrite( pAig, pParsRwr ); + pAig = Aig_ManDupDfs( pTemp = pAig ); + Aig_ManStop( pTemp ); + if ( fVerbose ) Aig_ManPrintStats( pAig ); + + // refactor + Dar_ManRefactor( pAig, pParsRef ); + pAig = Aig_ManDupDfs( pTemp = pAig ); + Aig_ManStop( pTemp ); + if ( fVerbose ) Aig_ManPrintStats( pAig ); + + // balance +// if ( fBalance ) + { + pAig = Dar_ManBalance( pTemp = pAig, fUpdateLevel ); + Aig_ManStop( pTemp ); + if ( fVerbose ) Aig_ManPrintStats( pAig ); + } + + // rewrite + Dar_ManRewrite( pAig, pParsRwr ); + pAig = Aig_ManDupDfs( pTemp = pAig ); + Aig_ManStop( pTemp ); + if ( fVerbose ) Aig_ManPrintStats( pAig ); + + pParsRwr->fUseZeros = 1; + pParsRef->fUseZeros = 1; + + // rewrite + Dar_ManRewrite( pAig, pParsRwr ); + pAig = Aig_ManDupDfs( pTemp = pAig ); + Aig_ManStop( pTemp ); + if ( fVerbose ) Aig_ManPrintStats( pAig ); + + // balance + if ( fBalance ) + { + pAig = Dar_ManBalance( pTemp = pAig, fUpdateLevel ); + Aig_ManStop( pTemp ); + if ( fVerbose ) Aig_ManPrintStats( pAig ); + } + + // refactor + Dar_ManRefactor( pAig, pParsRef ); + pAig = Aig_ManDupDfs( pTemp = pAig ); + Aig_ManStop( pTemp ); + if ( fVerbose ) Aig_ManPrintStats( pAig ); + + // rewrite + Dar_ManRewrite( pAig, pParsRwr ); + pAig = Aig_ManDupDfs( pTemp = pAig ); + Aig_ManStop( pTemp ); + if ( fVerbose ) Aig_ManPrintStats( pAig ); + + // balance + if ( fBalance ) + { + pAig = Dar_ManBalance( pTemp = pAig, fUpdateLevel ); + Aig_ManStop( pTemp ); + if ( fVerbose ) Aig_ManPrintStats( pAig ); + } + return pAig; +} + +/**Function************************************************************* + + Synopsis [Reproduces script "compress2".] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Hcd_ChoiceSynthesis( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fPower, int fVerbose ) +//alias resyn "b; rw; rwz; b; rwz; b" +//alias resyn2 "b; rw; rf; b; rw; rwz; b; rfz; rwz; b" +{ + Vec_Ptr_t * vGias; + Gia_Man_t * pGia; + + vGias = Vec_PtrAlloc( 3 ); + pGia = Gia_ManFromAig(pAig); + Vec_PtrPush( vGias, pGia ); + + pAig = Hcd_Compress( pAig, fBalance, fUpdateLevel, fPower, fVerbose ); + pGia = Gia_ManFromAig(pAig); + Vec_PtrPush( vGias, pGia ); +//Aig_ManPrintStats( pAig ); + + pAig = Hcd_Compress2( pAig, fBalance, fUpdateLevel, 1, fPower, fVerbose ); + pGia = Gia_ManFromAig(pAig); + Vec_PtrPush( vGias, pGia ); +//Aig_ManPrintStats( pAig ); + + Aig_ManStop( pAig ); + return vGias; +} + + +/**Function************************************************************* + + Synopsis [Duplicates the AIG in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Hcd_ManChoiceMiter_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + if ( ~pObj->Value ) + return pObj->Value; + Hcd_ManChoiceMiter_rec( pNew, p, Gia_ObjFanin0(pObj) ); + if ( Gia_ObjIsCo(pObj) ) + return pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Hcd_ManChoiceMiter_rec( pNew, p, Gia_ObjFanin1(pObj) ); + return pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Derives the miter of several AIGs for choice computation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Hcd_ManChoiceMiter( Vec_Ptr_t * vGias ) +{ + Gia_Man_t * pNew, * pGia, * pGia0; + int i, k, iNode, nNodes; + // make sure they have equal parameters + assert( Vec_PtrSize(vGias) > 0 ); + pGia0 = (Gia_Man_t *)Vec_PtrEntry( vGias, 0 ); + Vec_PtrForEachEntry( Gia_Man_t *, vGias, pGia, i ) + { + assert( Gia_ManCiNum(pGia) == Gia_ManCiNum(pGia0) ); + assert( Gia_ManCoNum(pGia) == Gia_ManCoNum(pGia0) ); + assert( Gia_ManRegNum(pGia) == Gia_ManRegNum(pGia0) ); + Gia_ManFillValue( pGia ); + Gia_ManConst0(pGia)->Value = 0; + } + // start the new manager + pNew = Gia_ManStart( Vec_PtrSize(vGias) * Gia_ManObjNum(pGia0) ); + pNew->pName = Gia_UtilStrsav( pGia0->pName ); + // create new CIs and assign them to the old manager CIs + for ( k = 0; k < Gia_ManCiNum(pGia0); k++ ) + { + iNode = Gia_ManAppendCi(pNew); + Vec_PtrForEachEntry( Gia_Man_t *, vGias, pGia, i ) + Gia_ManCi( pGia, k )->Value = iNode; + } + // create internal nodes + Gia_ManHashAlloc( pNew ); + for ( k = 0; k < Gia_ManCoNum(pGia0); k++ ) + { + Vec_PtrForEachEntry( Gia_Man_t *, vGias, pGia, i ) + Hcd_ManChoiceMiter_rec( pNew, pGia, Gia_ManCo( pGia, k ) ); + } + Gia_ManHashStop( pNew ); + // check the presence of dangling nodes + nNodes = Gia_ManHasDangling( pNew ); + assert( nNodes == 0 ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Returns 1 if pOld is in the TFI of pNode.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Hcd_ObjCheckTfi_rec( Gia_Man_t * p, Gia_Obj_t * pOld, Gia_Obj_t * pNode, Vec_Ptr_t * vVisited ) +{ + // check the trivial cases + if ( pNode == NULL ) + return 0; + if ( Gia_ObjIsCi(pNode) ) + return 0; +// if ( pNode->Id < pOld->Id ) // cannot use because of choices of pNode +// return 0; + if ( pNode == pOld ) + return 1; + // skip the visited node + if ( pNode->fMark0 ) + return 0; + pNode->fMark0 = 1; + Vec_PtrPush( vVisited, pNode ); + // check the children + if ( Hcd_ObjCheckTfi_rec( p, pOld, Gia_ObjFanin0(pNode), vVisited ) ) + return 1; + if ( Hcd_ObjCheckTfi_rec( p, pOld, Gia_ObjFanin1(pNode), vVisited ) ) + return 1; + // check equivalent nodes + return Hcd_ObjCheckTfi_rec( p, pOld, Gia_ObjNextObj(p, Gia_ObjId(p, pNode)), vVisited ); +} + +/**Function************************************************************* + + Synopsis [Returns 1 if pOld is in the TFI of pNode.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Hcd_ObjCheckTfi( Gia_Man_t * p, Gia_Obj_t * pOld, Gia_Obj_t * pNode ) +{ + Vec_Ptr_t * vVisited; + Gia_Obj_t * pObj; + int RetValue, i; + assert( !Gia_IsComplement(pOld) ); + assert( !Gia_IsComplement(pNode) ); + vVisited = Vec_PtrAlloc( 100 ); + RetValue = Hcd_ObjCheckTfi_rec( p, pOld, pNode, vVisited ); + Vec_PtrForEachEntry( Gia_Obj_t *, vVisited, pObj, i ) + pObj->fMark0 = 0; + Vec_PtrFree( vVisited ); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [Adds the next entry while making choices.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Hcd_ManAddNextEntry_rec( Gia_Man_t * p, Gia_Obj_t * pOld, Gia_Obj_t * pNode ) +{ + if ( Gia_ObjNext(p, Gia_ObjId(p, pOld)) == 0 ) + { + Gia_ObjSetNext( p, Gia_ObjId(p, pOld), Gia_ObjId(p, pNode) ); + return; + } + Hcd_ManAddNextEntry_rec( p, Gia_ObjNextObj(p, Gia_ObjId(p, pOld)), pNode ); +} + +/**Function************************************************************* + + Synopsis [Duplicates the AIG in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Hcd_ManEquivToChoices_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + Gia_Obj_t * pRepr, * pReprNew, * pObjNew; + if ( ~pObj->Value ) + return; + if ( (pRepr = Gia_ObjReprObj(p, Gia_ObjId(p, pObj))) ) + { + if ( Gia_ObjIsConst0(pRepr) ) + { + pObj->Value = Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) ); + return; + } + Hcd_ManEquivToChoices_rec( pNew, p, pRepr ); + assert( Gia_ObjIsAnd(pObj) ); + Hcd_ManEquivToChoices_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Hcd_ManEquivToChoices_rec( pNew, p, Gia_ObjFanin1(pObj) ); + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + if ( Gia_LitRegular(pObj->Value) == Gia_LitRegular(pRepr->Value) ) + { + assert( (int)pObj->Value == Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) ) ); + return; + } + if ( pRepr->Value > pObj->Value ) // should never happen with high resource limit + return; + assert( pRepr->Value < pObj->Value ); + pReprNew = Gia_ManObj( pNew, Gia_Lit2Var(pRepr->Value) ); + pObjNew = Gia_ManObj( pNew, Gia_Lit2Var(pObj->Value) ); + if ( Gia_ObjReprObj( pNew, Gia_ObjId(pNew, pObjNew) ) ) + { + assert( Gia_ObjReprObj( pNew, Gia_ObjId(pNew, pObjNew) ) == pReprNew ); + pObj->Value = Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) ); + return; + } + if ( !Hcd_ObjCheckTfi( pNew, pReprNew, pObjNew ) ) + { + assert( Gia_ObjNext(pNew, Gia_ObjId(pNew, pObjNew)) == 0 ); + Gia_ObjSetRepr( pNew, Gia_ObjId(pNew, pObjNew), Gia_ObjId(pNew, pReprNew) ); + Hcd_ManAddNextEntry_rec( pNew, pReprNew, pObjNew ); + } + pObj->Value = Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) ); + return; + } + assert( Gia_ObjIsAnd(pObj) ); + Hcd_ManEquivToChoices_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Hcd_ManEquivToChoices_rec( pNew, p, Gia_ObjFanin1(pObj) ); + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Removes choices, which contain fanouts.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Hcd_ManRemoveBadChoices( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i, iObj, iPrev, Counter = 0; + // mark nodes with fanout + Gia_ManForEachObj( p, pObj, i ) + { + pObj->fMark0 = 0; + if ( Gia_ObjIsAnd(pObj) ) + { + Gia_ObjFanin0(pObj)->fMark0 = 1; + Gia_ObjFanin1(pObj)->fMark0 = 1; + } + else if ( Gia_ObjIsCo(pObj) ) + Gia_ObjFanin0(pObj)->fMark0 = 1; + } + // go through the classes and remove + Gia_ManForEachClass( p, i ) + { + for ( iPrev = i, iObj = Gia_ObjNext(p, i); iObj; iObj = Gia_ObjNext(p, iPrev) ) + { + if ( !Gia_ManObj(p, iObj)->fMark0 ) + { + iPrev = iObj; + continue; + } + Gia_ObjSetRepr( p, iObj, GIA_VOID ); + Gia_ObjSetNext( p, iPrev, Gia_ObjNext(p, iObj) ); + Gia_ObjSetNext( p, iObj, 0 ); + Counter++; + } + } + // remove the marks + Gia_ManCleanMark0( p ); +// printf( "Removed %d bad choices.\n", Counter ); +} + +/**Function************************************************************* + + Synopsis [Reduces AIG using equivalence classes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Hcd_ManEquivToChoices( Gia_Man_t * p, int nSnapshots ) +{ + Gia_Man_t * pNew, * pTemp; + Gia_Obj_t * pObj, * pRepr; + int i; + assert( (Gia_ManCoNum(p) % nSnapshots) == 0 ); + Gia_ManSetPhase( p ); + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Gia_UtilStrsav( p->pName ); + pNew->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(p) ); + pNew->pNexts = ABC_CALLOC( int, Gia_ManObjNum(p) ); + for ( i = 0; i < Gia_ManObjNum(p); i++ ) + Gia_ObjSetRepr( pNew, i, GIA_VOID ); + Gia_ManFillValue( p ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi(pNew); + Gia_ManForEachRo( p, pObj, i ) + if ( (pRepr = Gia_ObjReprObj(p, Gia_ObjId(p, pObj))) ) + { + assert( Gia_ObjIsConst0(pRepr) || Gia_ObjIsRo(p, pRepr) ); + pObj->Value = pRepr->Value; + } + Gia_ManHashAlloc( pNew ); + Gia_ManForEachCo( p, pObj, i ) + Hcd_ManEquivToChoices_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Gia_ManForEachCo( p, pObj, i ) + if ( i % nSnapshots == 0 ) + Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManHashStop( pNew ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + Hcd_ManRemoveBadChoices( pNew ); +// Gia_ManEquivPrintClasses( pNew, 0, 0 ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); +// Gia_ManEquivPrintClasses( pNew, 0, 0 ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Performs computation of AIGs with choices.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Hcd_ComputeChoices( Aig_Man_t * pAig, int nBTLimit, int fSynthesis, int fUseMiniSat, int fVerbose ) +{ + Vec_Ptr_t * vGias; + Gia_Man_t * pGia, * pMiter; + Aig_Man_t * pAigNew; + int i, clk = clock(); + // perform synthesis + if ( fSynthesis ) + { + vGias = Hcd_ChoiceSynthesis( Aig_ManDupDfs(pAig), 1, 1, 0, 0 ); + if ( fVerbose ) + ABC_PRT( "Synthesis time", clock() - clk ); + // create choices + clk = clock(); + pMiter = Hcd_ManChoiceMiter( vGias ); + Vec_PtrForEachEntry( Gia_Man_t *, vGias, pGia, i ) + Gia_ManStop( pGia ); + + Gia_WriteAiger( pMiter, "m3.aig", 0, 0 ); + } + else + { + vGias = Vec_PtrStart( 3 ); + pMiter = Gia_ManFromAig(pAig); + } + // perform choicing + Gia_ComputeEquivalences( pMiter, nBTLimit, fUseMiniSat, fVerbose ); + // derive AIG with choices + pGia = Hcd_ManEquivToChoices( pMiter, Vec_PtrSize(vGias) ); + Gia_ManSetRegNum( pGia, Aig_ManRegNum(pAig) ); + Gia_ManStop( pMiter ); + Vec_PtrFree( vGias ); + if ( fVerbose ) + ABC_PRT( "Choicing time", clock() - clk ); + Gia_ManHasChoices( pGia ); + // transform back + pAigNew = Gia_ManToAig( pGia, 1 ); + Gia_ManStop( pGia ); + + if ( fVerbose ) + { + extern int Dch_DeriveChoiceCountReprs( Aig_Man_t * pAig ); + extern int Dch_DeriveChoiceCountEquivs( Aig_Man_t * pAig ); + printf( "Choices : Reprs = %5d. Equivs = %5d. Choices = %5d.\n", + Dch_DeriveChoiceCountReprs( pAigNew ), + Dch_DeriveChoiceCountEquivs( pAigNew ), + Aig_ManChoiceNum( pAigNew ) ); + } + + return pAigNew; +} + +/**Function************************************************************* + + Synopsis [Performs computation of AIGs with choices.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Hcd_ComputeChoicesTest( Gia_Man_t * pGia, int nBTLimit, int fSynthesis, int fUseMiniSat, int fVerbose ) +{ + Aig_Man_t * pAig, * pAigNew; + pAig = Gia_ManToAig( pGia, 0 ); + pAigNew = Hcd_ComputeChoices( pAig, nBTLimit, fSynthesis, fUseMiniSat, fVerbose ); + Aig_ManStop( pAigNew ); + Aig_ManStop( pAig ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaMap.c b/src/aig/gia/giaIf.c index 72bdb001..a06a6024 100644 --- a/src/aig/gia/giaMap.c +++ b/src/aig/gia/giaIf.c @@ -19,7 +19,12 @@ ***********************************************************************/ #include "gia.h" +#include "aig.h" #include "if.h" +#include "dar.h" + +ABC_NAMESPACE_IMPL_START + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// @@ -95,6 +100,7 @@ If_Man_t * Gia_ManToIf( Gia_Man_t * p, If_Par_t * pPars, Vec_Ptr_t * vAigToIf ) Gia_Obj_t * pNode; int i, clk = clock(); Gia_ManLevelNum( p ); +// assert( p->pReprs == NULL ); /* // set the number of registers (switch activity will be combinational) Gia_ManSetRegNum( p, 0 ); @@ -114,24 +120,25 @@ If_Man_t * Gia_ManToIf( Gia_Man_t * p, If_Par_t * pPars, Vec_Ptr_t * vAigToIf ) pIfMan = If_ManStart( pPars ); // pIfMan->vSwitching = vSwitching2; // load the AIG into the mapper + Gia_ManCreateRefs( p ); Gia_ManForEachObj( p, pNode, i ) { if ( Gia_ObjIsAnd(pNode) ) pIfObj = If_ManCreateAnd( pIfMan, - If_NotCond( Vec_PtrEntry(vAigToIf, Gia_ObjFaninId0(pNode, i)), Gia_ObjFaninC0(pNode) ), - If_NotCond( Vec_PtrEntry(vAigToIf, Gia_ObjFaninId1(pNode, i)), Gia_ObjFaninC1(pNode) ) ); + If_NotCond( (If_Obj_t *)Vec_PtrEntry(vAigToIf, Gia_ObjFaninId0(pNode, i)), Gia_ObjFaninC0(pNode) ), + If_NotCond( (If_Obj_t *)Vec_PtrEntry(vAigToIf, Gia_ObjFaninId1(pNode, i)), Gia_ObjFaninC1(pNode) ) ); else if ( Gia_ObjIsCi(pNode) ) { pIfObj = If_ManCreateCi( pIfMan ); If_ObjSetLevel( pIfObj, Gia_ObjLevel(p,pNode) ); -// printf( "pi=%d ", pIfObj->Level ); +// Abc_Print( 1, "pi=%d ", pIfObj->Level ); if ( pIfMan->nLevelMax < (int)pIfObj->Level ) pIfMan->nLevelMax = (int)pIfObj->Level; } else if ( Gia_ObjIsCo(pNode) ) { - pIfObj = If_ManCreateCo( pIfMan, If_NotCond( Vec_PtrEntry(vAigToIf, Gia_ObjFaninId0(pNode, i)), Gia_ObjFaninC0(pNode) ) ); -// printf( "po=%d ", pIfObj->Level ); + pIfObj = If_ManCreateCo( pIfMan, If_NotCond( (If_Obj_t *)Vec_PtrEntry(vAigToIf, Gia_ObjFaninId0(pNode, i)), Gia_ObjFaninC0(pNode) ) ); +// Abc_Print( 1, "po=%d ", pIfObj->Level ); } else if ( Gia_ObjIsConst0(pNode) ) pIfObj = If_Not(If_ManConst1( pIfMan )); @@ -142,6 +149,18 @@ If_Man_t * Gia_ManToIf( Gia_Man_t * p, If_Par_t * pPars, Vec_Ptr_t * vAigToIf ) Vec_PtrWriteEntry( vAigToIf, i, pIfObj ); // if ( vSwitching2 ) // pSwitching2[pIfObj->Id] = pSwitching[pNode->Id]; + // set up the choice node +/* +// if ( p->pReprs && p->pNexts && Gia_ObjIsHead( p, i ) ) + if ( p->pNexts && Gia_ObjNext(p, i) && Gia_ObjRefsId(p, i) ) + { + int iPrev, iFanin; + pIfMan->nChoices++; + for ( iPrev = i, iFanin = Gia_ObjNext(p, i); iFanin; iPrev = iFanin, iFanin = Gia_ObjNext(p, iFanin) ) + If_ObjSetChoice( Vec_PtrEntry(vAigToIf,iPrev), Vec_PtrEntry(vAigToIf,iFanin) ); + If_ManCreateChoice( pIfMan, Vec_PtrEntry(vAigToIf,i) ); + } +*/ /* // set up the choice node if ( Gia_ObjIsChoice( p, pNode ) ) { @@ -186,7 +205,7 @@ int * Gia_ManFromIf( If_Man_t * pIfMan, Gia_Man_t * p, Vec_Ptr_t * vAigToIf ) vIfToAig = Vec_PtrStart( If_ManObjNum(pIfMan) ); Gia_ManForEachObj( p, pObj, i ) { - pIfObj = Vec_PtrEntry( vAigToIf, i ); + pIfObj = (If_Obj_t *)Vec_PtrEntry( vAigToIf, i ); Vec_PtrWriteEntry( vIfToAig, pIfObj->Id, pObj ); if ( !Gia_ObjIsAnd(pObj) || pIfObj->nRefs == 0 ) continue; @@ -197,7 +216,7 @@ int * Gia_ManFromIf( If_Man_t * pIfMan, Gia_Man_t * p, Vec_Ptr_t * vAigToIf ) iOffset = Gia_ManObjNum(p); Gia_ManForEachObj( p, pObj, i ) { - pIfObj = Vec_PtrEntry( vAigToIf, i ); + pIfObj = (If_Obj_t *)Vec_PtrEntry( vAigToIf, i ); if ( !Gia_ObjIsAnd(pObj) || pIfObj->nRefs == 0 ) continue; pCutBest = If_ObjCutBest( pIfObj ); @@ -208,7 +227,7 @@ int * Gia_ManFromIf( If_Man_t * pIfMan, Gia_Man_t * p, Vec_Ptr_t * vAigToIf ) pMapping[k++] = nLeaves; for ( j = 0; j < nLeaves; j++ ) { - pObjRepr = Vec_PtrEntry( vIfToAig, ppLeaves[j] ); + pObjRepr = (Gia_Obj_t *)Vec_PtrEntry( vIfToAig, ppLeaves[j] ); pMapping[k++] = Gia_ObjId( p, pObjRepr ); } pMapping[k++] = i; @@ -279,23 +298,226 @@ void Gia_ManPrintMappingStats( Gia_Man_t * p ) if ( !p->pMapping ) return; pLevels = ABC_CALLOC( int, Gia_ManObjNum(p) ); - Gia_ManForEachGate( p, i ) + Gia_ManForEachLut( p, i ) { nLuts++; - nFanins += Gia_ObjGateSize(p, i); - nLutSize = ABC_MAX( nLutSize, Gia_ObjGateSize(p, i) ); - Gia_GateForEachFanin( p, i, iFan, k ) + nFanins += Gia_ObjLutSize(p, i); + nLutSize = ABC_MAX( nLutSize, Gia_ObjLutSize(p, i) ); + Gia_LutForEachFanin( p, i, iFan, k ) pLevels[i] = ABC_MAX( pLevels[i], pLevels[iFan] ); pLevels[i]++; LevelMax = ABC_MAX( LevelMax, pLevels[i] ); } ABC_FREE( pLevels ); - printf( "mapping : " ); - printf( "%d=lut =%7d ", nLutSize, nLuts ); - printf( "edge =%8d ", nFanins ); - printf( "lev =%5d ", LevelMax ); - printf( "mem =%5.2f Mb", 4.0*(Gia_ManObjNum(p) + 2*nLuts + nFanins)/(1<<20) ); - printf( "\n" ); + Abc_Print( 1, "mapping (K=%d) : ", nLutSize ); + Abc_Print( 1, "lut =%7d ", nLuts ); + Abc_Print( 1, "edge =%8d ", nFanins ); + Abc_Print( 1, "lev =%5d ", LevelMax ); + Abc_Print( 1, "mem =%5.2f Mb", 4.0*(Gia_ManObjNum(p) + 2*nLuts + nFanins)/(1<<20) ); + Abc_Print( 1, "\n" ); +} + +/**Function************************************************************* + + Synopsis [Prints mapping statistics.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManLutFaninCount( Gia_Man_t * p ) +{ + int i, Counter = 0; + Gia_ManForEachLut( p, i ) + Counter += Gia_ObjLutSize(p, i); + return Counter; +} + +/**Function************************************************************* + + Synopsis [Prints mapping statistics.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManLutSizeMax( Gia_Man_t * p ) +{ + int i, nSizeMax = -1; + Gia_ManForEachLut( p, i ) + nSizeMax = ABC_MAX( nSizeMax, Gia_ObjLutSize(p, i) ); + return nSizeMax; +} + +/**Function************************************************************* + + Synopsis [Prints mapping statistics.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManLutNum( Gia_Man_t * p ) +{ + int i, Counter = 0; + Gia_ManForEachLut( p, i ) + Counter ++; + return Counter; +} + +/**Function************************************************************* + + Synopsis [Prints mapping statistics.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManLutLevel( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i, k, iFan, Level; + int * pLevels = ABC_CALLOC( int, Gia_ManObjNum(p) ); + Gia_ManForEachLut( p, i ) + { + Level = 0; + Gia_LutForEachFanin( p, i, iFan, k ) + if ( Level < pLevels[iFan] ) + Level = pLevels[iFan]; + pLevels[i] = Level + 1; + } + Level = 0; + Gia_ManForEachCo( p, pObj, k ) + if ( Level < pLevels[Gia_ObjFaninId0p(p, pObj)] ) + Level = pLevels[Gia_ObjFaninId0p(p, pObj)]; + ABC_FREE( pLevels ); + return Level; +} + +/**Function************************************************************* + + Synopsis [Assigns levels.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSetRefsMapped( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i, k, iFan; + ABC_FREE( p->pRefs ); + p->pRefs = ABC_CALLOC( int, Gia_ManObjNum(p) ); + Gia_ManForEachCo( p, pObj, i ) + Gia_ObjRefInc( p, Gia_ObjFanin0(pObj) ); + Gia_ManForEachLut( p, i ) + Gia_LutForEachFanin( p, i, iFan, k ) + Gia_ObjRefInc( p, Gia_ManObj(p, iFan) ); +} + +/**Function************************************************************* + + Synopsis [Prints NPN class statistics.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManPrintNpnClasses( Gia_Man_t * p ) +{ + extern char ** Kit_DsdNpn4ClassNames(); + char ** pNames = Kit_DsdNpn4ClassNames(); + Vec_Int_t * vLeaves, * vTruth, * vVisited; + int * pLutClass, ClassCounts[222] = {0}; + int i, k, iFan, Class, OtherClasses, OtherClasses2, nTotal, Counter, Counter2; + unsigned * pTruth; + assert( p->pMapping != NULL ); + assert( Gia_ManLutSizeMax( p ) <= 4 ); + vLeaves = Vec_IntAlloc( 100 ); + vVisited = Vec_IntAlloc( 100 ); + vTruth = Vec_IntAlloc( (1<<16) ); + pLutClass = ABC_CALLOC( int, Gia_ManObjNum(p) ); + Gia_ManCleanTruth( p ); + Gia_ManForEachLut( p, i ) + { + if ( Gia_ObjLutSize(p,i) > 4 ) + continue; + Vec_IntClear( vLeaves ); + Gia_LutForEachFanin( p, i, iFan, k ) + Vec_IntPush( vLeaves, iFan ); + for ( ; k < 4; k++ ) + Vec_IntPush( vLeaves, 0 ); + pTruth = Gia_ManConvertAigToTruth( p, Gia_ManObj(p, i), vLeaves, vTruth, vVisited ); + Class = Dar_LibReturnClass( *pTruth ); + ClassCounts[ Class ]++; + pLutClass[i] = Class; + } + Vec_IntFree( vLeaves ); + Vec_IntFree( vTruth ); + Vec_IntFree( vVisited ); + Vec_IntFreeP( &p->vTruths ); + nTotal = 0; + for ( i = 0; i < 222; i++ ) + nTotal += ClassCounts[i]; + Abc_Print( 1, "NPN CLASS STATISTICS (for %d LUT4 present in the current mapping):\n", nTotal ); + OtherClasses = 0; + for ( i = 0; i < 222; i++ ) + { + if ( ClassCounts[i] == 0 ) + continue; + if ( 100.0 * ClassCounts[i] / (nTotal+1) < 0.1 ) // do not show anything below 0.1 percent + continue; + OtherClasses += ClassCounts[i]; + Abc_Print( 1, "Class %3d : Count = %6d (%7.2f %%) %s\n", + i, ClassCounts[i], 100.0 * ClassCounts[i] / (nTotal+1), pNames[i] ); + } + OtherClasses = nTotal - OtherClasses; + Abc_Print( 1, "Other : Count = %6d (%7.2f %%)\n", + OtherClasses, 100.0 * OtherClasses / (nTotal+1) ); + // count the number of LUTs that have MUX function and two fanins with MUX functions + OtherClasses = OtherClasses2 = 0; + ABC_FREE( p->pRefs ); + Gia_ManSetRefsMapped( p ); + Gia_ManForEachLut( p, i ) + { + if ( pLutClass[i] != 109 ) + continue; + Counter = Counter2 = 0; + Gia_LutForEachFanin( p, i, iFan, k ) + { + Counter += (pLutClass[iFan] == 109); + Counter2 += (pLutClass[iFan] == 109) && (Gia_ObjRefsId(p, iFan) == 1); + } + OtherClasses += (Counter > 1); + OtherClasses2 += (Counter2 > 1); +// Abc_Print( 1, "%d -- ", pLutClass[i] ); +// Gia_LutForEachFanin( p, i, iFan, k ) +// Abc_Print( 1, "%d ", pLutClass[iFan] ); +// Abc_Print( 1, "\n" ); + } + ABC_FREE( p->pRefs ); + Abc_Print( 1, "Approximate number of 4:1 MUX structures: All = %6d (%7.2f %%) MFFC = %6d (%7.2f %%)\n", + OtherClasses, 100.0 * OtherClasses / (nTotal+1), + OtherClasses2, 100.0 * OtherClasses2 / (nTotal+1) ); + ABC_FREE( pLutClass ); } //////////////////////////////////////////////////////////////////////// @@ -303,3 +525,5 @@ void Gia_ManPrintMappingStats( Gia_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaMan.c b/src/aig/gia/giaMan.c index 4547e61c..ed6a5c95 100644 --- a/src/aig/gia/giaMan.c +++ b/src/aig/gia/giaMan.c @@ -19,6 +19,10 @@ ***********************************************************************/ #include "gia.h" +#include "tim.h" + +ABC_NAMESPACE_IMPL_START + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// @@ -66,10 +70,18 @@ Gia_Man_t * Gia_ManStart( int nObjsMax ) ***********************************************************************/ void Gia_ManStop( Gia_Man_t * p ) { + Tim_ManStopP( (Tim_Man_t **)&p->pManTime ); + assert( p->pManTime == NULL ); Vec_PtrFreeFree( p->vNamesIn ); Vec_PtrFreeFree( p->vNamesOut ); - if ( p->vFlopClasses ) - Vec_IntFree( p->vFlopClasses ); + Vec_FltFreeP( &p->vTiming ); + Vec_VecFreeP( &p->vClockDoms ); + Vec_IntFreeP( &p->vLutConfigs ); + Vec_IntFreeP( &p->vCiNumsOrig ); + Vec_IntFreeP( &p->vCoNumsOrig ); + Vec_IntFreeP( &p->vFlopClasses ); + Vec_IntFreeP( &p->vLevels ); + Vec_IntFreeP( &p->vTruths ); Vec_IntFree( p->vCis ); Vec_IntFree( p->vCos ); ABC_FREE( p->pTravIds ); @@ -85,7 +97,7 @@ void Gia_ManStop( Gia_Man_t * p ) ABC_FREE( p->pNexts ); ABC_FREE( p->pName ); ABC_FREE( p->pRefs ); - ABC_FREE( p->pLevels ); + ABC_FREE( p->pNodeRefs ); ABC_FREE( p->pHTable ); ABC_FREE( p->pObjs ); ABC_FREE( p ); @@ -93,6 +105,25 @@ void Gia_ManStop( Gia_Man_t * p ) /**Function************************************************************* + Synopsis [Stops the AIG manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManStopP( Gia_Man_t ** p ) +{ + if ( *p == NULL ) + return; + Gia_ManStop( *p ); + *p = NULL; +} + +/**Function************************************************************* + Synopsis [Prints stats for the AIG.] Description [] @@ -102,7 +133,7 @@ void Gia_ManStop( Gia_Man_t * p ) SeeAlso [] ***********************************************************************/ -void Gia_ManPrintClasses( Gia_Man_t * p ) +void Gia_ManPrintClasses_old( Gia_Man_t * p ) { Gia_Obj_t * pObj; int i; @@ -134,6 +165,44 @@ void Gia_ManPrintClasses( Gia_Man_t * p ) SeeAlso [] ***********************************************************************/ +void Gia_ManPrintClasses( Gia_Man_t * p ) +{ + int i, Class, Counter0, Counter1; + if ( p->vFlopClasses == NULL ) + return; + if ( Vec_IntSize(p->vFlopClasses) != Gia_ManRegNum(p) ) + { + printf( "Gia_ManPrintClasses(): The number of flop map entries differs from the number of flops.\n" ); + return; + } + printf( "Register classes: " ); + // count zero entries + Counter0 = 0; + Vec_IntForEachEntry( p->vFlopClasses, Class, i ) + Counter0 += (Class == 0); + printf( "0=%d ", Counter0 ); + // count one entries + Counter1 = 0; + Vec_IntForEachEntry( p->vFlopClasses, Class, i ) + Counter1 += (Class == 1); + printf( "1=%d ", Counter1 ); + // add comment + if ( Counter0 + Counter1 < Gia_ManRegNum(p) ) + printf( "there are other classes..." ); + printf( "\n" ); +} + +/**Function************************************************************* + + Synopsis [Prints stats for the AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ void Gia_ManPrintPlacement( Gia_Man_t * p ) { int i, nFixed = 0, nUndef = 0; @@ -163,13 +232,15 @@ void Gia_ManPrintStats( Gia_Man_t * p, int fSwitch ) if ( p->pName ) printf( "%-8s : ", p->pName ); printf( "i/o =%7d/%7d", Gia_ManPiNum(p), Gia_ManPoNum(p) ); + if ( Gia_ManConstrNum(p) ) + printf( "(c=%d)", Gia_ManConstrNum(p) ); if ( Gia_ManRegNum(p) ) printf( " ff =%7d", Gia_ManRegNum(p) ); printf( " and =%8d", Gia_ManAndNum(p) ); printf( " lev =%5d", Gia_ManLevelNum(p) ); printf( " cut =%5d", Gia_ManCrossCut(p) ); printf( " mem =%5.2f Mb", 12.0*Gia_ManObjNum(p)/(1<<20) ); - if ( Gia_ManHasDandling(p) ) + if ( Gia_ManHasDangling(p) ) printf( " ch =%5d", Gia_ManEquivCountClasses(p) ); if ( fSwitch ) { @@ -189,7 +260,7 @@ void Gia_ManPrintStats( Gia_Man_t * p, int fSwitch ) if ( p->pPlacement ) Gia_ManPrintPlacement( p ); // print register classes -// Gia_ManPrintClasses( p ); + Gia_ManPrintClasses( p ); } /**Function************************************************************* @@ -309,3 +380,5 @@ void Gia_ManReportImprovement( Gia_Man_t * p, Gia_Man_t * pNew ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaMem.c b/src/aig/gia/giaMem.c new file mode 100644 index 00000000..d77ddfd5 --- /dev/null +++ b/src/aig/gia/giaMem.c @@ -0,0 +1,598 @@ +/**CFile**************************************************************** + + FileName [giaMem.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [AIG package.] + + Synopsis [Memory managers.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - April 28, 2007.] + + Revision [$Id: giaMem.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +struct Gia_MmFixed_t_ +{ + // information about individual entries + int nEntrySize; // the size of one entry + int nEntriesAlloc; // the total number of entries allocated + int nEntriesUsed; // the number of entries in use + int nEntriesMax; // the max number of entries in use + char * pEntriesFree; // the linked list of free entries + + // this is where the memory is stored + int nChunkSize; // the size of one chunk + int nChunksAlloc; // the maximum number of memory chunks + int nChunks; // the current number of memory chunks + char ** pChunks; // the allocated memory + + // statistics + int nMemoryUsed; // memory used in the allocated entries + int nMemoryAlloc; // memory allocated +}; + +struct Gia_MmFlex_t_ +{ + // information about individual entries + int nEntriesUsed; // the number of entries allocated + char * pCurrent; // the current pointer to free memory + char * pEnd; // the first entry outside the free memory + + // this is where the memory is stored + int nChunkSize; // the size of one chunk + int nChunksAlloc; // the maximum number of memory chunks + int nChunks; // the current number of memory chunks + char ** pChunks; // the allocated memory + + // statistics + int nMemoryUsed; // memory used in the allocated entries + int nMemoryAlloc; // memory allocated +}; + +struct Gia_MmStep_t_ +{ + int nMems; // the number of fixed memory managers employed + Gia_MmFixed_t ** pMems; // memory managers: 2^1 words, 2^2 words, etc + int nMapSize; // the size of the memory array + Gia_MmFixed_t ** pMap; // maps the number of bytes into its memory manager + // additional memory chunks + int nChunksAlloc; // the maximum number of memory chunks + int nChunks; // the current number of memory chunks + char ** pChunks; // the allocated memory +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Allocates memory pieces of fixed size.] + + Description [The size of the chunk is computed as the minimum of + 1024 entries and 64K. Can only work with entry size at least 4 byte long.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_MmFixed_t * Gia_MmFixedStart( int nEntrySize, int nEntriesMax ) +{ + Gia_MmFixed_t * p; + + p = ABC_ALLOC( Gia_MmFixed_t, 1 ); + memset( p, 0, sizeof(Gia_MmFixed_t) ); + + p->nEntrySize = nEntrySize; + p->nEntriesAlloc = 0; + p->nEntriesUsed = 0; + p->pEntriesFree = NULL; + + p->nChunkSize = nEntriesMax / 8; + if ( p->nChunkSize < 8 ) + p->nChunkSize = 8; + + p->nChunksAlloc = 64; + p->nChunks = 0; + p->pChunks = ABC_ALLOC( char *, p->nChunksAlloc ); + + p->nMemoryUsed = 0; + p->nMemoryAlloc = 0; + return p; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_MmFixedStop( Gia_MmFixed_t * p, int fVerbose ) +{ + int i; + if ( p == NULL ) + return; + if ( fVerbose ) + { + printf( "Fixed memory manager: Entry = %5d. Chunk = %5d. Chunks used = %5d.\n", + p->nEntrySize, p->nChunkSize, p->nChunks ); + printf( " Entries used = %8d. Entries peak = %8d. Memory used = %8d. Memory alloc = %8d.\n", + p->nEntriesUsed, p->nEntriesMax, p->nEntrySize * p->nEntriesUsed, p->nMemoryAlloc ); + } + for ( i = 0; i < p->nChunks; i++ ) + ABC_FREE( p->pChunks[i] ); + ABC_FREE( p->pChunks ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Gia_MmFixedEntryFetch( Gia_MmFixed_t * p ) +{ + char * pTemp; + int i; + + // check if there are still free entries + if ( p->nEntriesUsed == p->nEntriesAlloc ) + { // need to allocate more entries + assert( p->pEntriesFree == NULL ); + if ( p->nChunks == p->nChunksAlloc ) + { + p->nChunksAlloc *= 2; + p->pChunks = ABC_REALLOC( char *, p->pChunks, p->nChunksAlloc ); + } + p->pEntriesFree = ABC_ALLOC( char, p->nEntrySize * p->nChunkSize ); + p->nMemoryAlloc += p->nEntrySize * p->nChunkSize; + // transform these entries into a linked list + pTemp = p->pEntriesFree; + for ( i = 1; i < p->nChunkSize; i++ ) + { + *((char **)pTemp) = pTemp + p->nEntrySize; + pTemp += p->nEntrySize; + } + // set the last link + *((char **)pTemp) = NULL; + // add the chunk to the chunk storage + p->pChunks[ p->nChunks++ ] = p->pEntriesFree; + // add to the number of entries allocated + p->nEntriesAlloc += p->nChunkSize; + } + // incrememt the counter of used entries + p->nEntriesUsed++; + if ( p->nEntriesMax < p->nEntriesUsed ) + p->nEntriesMax = p->nEntriesUsed; + // return the first entry in the free entry list + pTemp = p->pEntriesFree; + p->pEntriesFree = *((char **)pTemp); + return pTemp; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_MmFixedEntryRecycle( Gia_MmFixed_t * p, char * pEntry ) +{ + // decrement the counter of used entries + p->nEntriesUsed--; + // add the entry to the linked list of free entries + *((char **)pEntry) = p->pEntriesFree; + p->pEntriesFree = pEntry; +} + +/**Function************************************************************* + + Synopsis [] + + Description [Relocates all the memory except the first chunk.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_MmFixedRestart( Gia_MmFixed_t * p ) +{ + int i; + char * pTemp; + if ( p->nChunks == 0 ) + return; + // deallocate all chunks except the first one + for ( i = 1; i < p->nChunks; i++ ) + ABC_FREE( p->pChunks[i] ); + p->nChunks = 1; + // transform these entries into a linked list + pTemp = p->pChunks[0]; + for ( i = 1; i < p->nChunkSize; i++ ) + { + *((char **)pTemp) = pTemp + p->nEntrySize; + pTemp += p->nEntrySize; + } + // set the last link + *((char **)pTemp) = NULL; + // set the free entry list + p->pEntriesFree = p->pChunks[0]; + // set the correct statistics + p->nMemoryAlloc = p->nEntrySize * p->nChunkSize; + p->nMemoryUsed = 0; + p->nEntriesAlloc = p->nChunkSize; + p->nEntriesUsed = 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_MmFixedReadMemUsage( Gia_MmFixed_t * p ) +{ + return p->nMemoryAlloc; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_MmFixedReadMaxEntriesUsed( Gia_MmFixed_t * p ) +{ + return p->nEntriesMax; +} + + + +/**Function************************************************************* + + Synopsis [Allocates entries of flexible size.] + + Description [Can only work with entry size at least 4 byte long.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_MmFlex_t * Gia_MmFlexStart() +{ + Gia_MmFlex_t * p; + + p = ABC_ALLOC( Gia_MmFlex_t, 1 ); + memset( p, 0, sizeof(Gia_MmFlex_t) ); + + p->nEntriesUsed = 0; + p->pCurrent = NULL; + p->pEnd = NULL; + + p->nChunkSize = (1 << 18); + p->nChunksAlloc = 64; + p->nChunks = 0; + p->pChunks = ABC_ALLOC( char *, p->nChunksAlloc ); + + p->nMemoryUsed = 0; + p->nMemoryAlloc = 0; + return p; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_MmFlexStop( Gia_MmFlex_t * p, int fVerbose ) +{ + int i; + if ( p == NULL ) + return; + if ( fVerbose ) + { + printf( "Flexible memory manager: Chunk size = %d. Chunks used = %d.\n", + p->nChunkSize, p->nChunks ); + printf( " Entries used = %d. Memory used = %d. Memory alloc = %d.\n", + p->nEntriesUsed, p->nMemoryUsed, p->nMemoryAlloc ); + } + for ( i = 0; i < p->nChunks; i++ ) + ABC_FREE( p->pChunks[i] ); + ABC_FREE( p->pChunks ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Gia_MmFlexEntryFetch( Gia_MmFlex_t * p, int nBytes ) +{ + char * pTemp; + // check if there are still free entries + if ( p->pCurrent == NULL || p->pCurrent + nBytes > p->pEnd ) + { // need to allocate more entries + if ( p->nChunks == p->nChunksAlloc ) + { + p->nChunksAlloc *= 2; + p->pChunks = ABC_REALLOC( char *, p->pChunks, p->nChunksAlloc ); + } + if ( nBytes > p->nChunkSize ) + { + // resize the chunk size if more memory is requested than it can give + // (ideally, this should never happen) + p->nChunkSize = 2 * nBytes; + } + p->pCurrent = ABC_ALLOC( char, p->nChunkSize ); + p->pEnd = p->pCurrent + p->nChunkSize; + p->nMemoryAlloc += p->nChunkSize; + // add the chunk to the chunk storage + p->pChunks[ p->nChunks++ ] = p->pCurrent; + } + assert( p->pCurrent + nBytes <= p->pEnd ); + // increment the counter of used entries + p->nEntriesUsed++; + // keep track of the memory used + p->nMemoryUsed += nBytes; + // return the next entry + pTemp = p->pCurrent; + p->pCurrent += nBytes; + return pTemp; +} + +/**Function************************************************************* + + Synopsis [] + + Description [Relocates all the memory except the first chunk.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_MmFlexRestart( Gia_MmFlex_t * p ) +{ + int i; + if ( p->nChunks == 0 ) + return; + // deallocate all chunks except the first one + for ( i = 1; i < p->nChunks; i++ ) + ABC_FREE( p->pChunks[i] ); + p->nChunks = 1; + p->nMemoryAlloc = p->nChunkSize; + // transform these entries into a linked list + p->pCurrent = p->pChunks[0]; + p->pEnd = p->pCurrent + p->nChunkSize; + p->nEntriesUsed = 0; + p->nMemoryUsed = 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_MmFlexReadMemUsage( Gia_MmFlex_t * p ) +{ + return p->nMemoryUsed; +} + + + + + +/**Function************************************************************* + + Synopsis [Starts the hierarchical memory manager.] + + Description [This manager can allocate entries of any size. + Iternally they are mapped into the entries with the number of bytes + equal to the power of 2. The smallest entry size is 8 bytes. The + next one is 16 bytes etc. So, if the user requests 6 bytes, he gets + 8 byte entry. If we asks for 25 bytes, he gets 32 byte entry etc. + The input parameters "nSteps" says how many fixed memory managers + are employed internally. Calling this procedure with nSteps equal + to 10 results in 10 hierarchically arranged internal memory managers, + which can allocate up to 4096 (1Kb) entries. Requests for larger + entries are handed over to malloc() and then ABC_FREE()ed.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_MmStep_t * Gia_MmStepStart( int nSteps ) +{ + Gia_MmStep_t * p; + int i, k; + p = ABC_ALLOC( Gia_MmStep_t, 1 ); + memset( p, 0, sizeof(Gia_MmStep_t) ); + p->nMems = nSteps; + // start the fixed memory managers + p->pMems = ABC_ALLOC( Gia_MmFixed_t *, p->nMems ); + for ( i = 0; i < p->nMems; i++ ) + p->pMems[i] = Gia_MmFixedStart( (8<<i), (1<<13) ); + // set up the mapping of the required memory size into the corresponding manager + p->nMapSize = (4<<p->nMems); + p->pMap = ABC_ALLOC( Gia_MmFixed_t *, p->nMapSize+1 ); + p->pMap[0] = NULL; + for ( k = 1; k <= 4; k++ ) + p->pMap[k] = p->pMems[0]; + for ( i = 0; i < p->nMems; i++ ) + for ( k = (4<<i)+1; k <= (8<<i); k++ ) + p->pMap[k] = p->pMems[i]; +//for ( i = 1; i < 100; i ++ ) +//printf( "%10d: size = %10d\n", i, p->pMap[i]->nEntrySize ); + p->nChunksAlloc = 64; + p->nChunks = 0; + p->pChunks = ABC_ALLOC( char *, p->nChunksAlloc ); + return p; +} + +/**Function************************************************************* + + Synopsis [Stops the memory manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_MmStepStop( Gia_MmStep_t * p, int fVerbose ) +{ + int i; + for ( i = 0; i < p->nMems; i++ ) + Gia_MmFixedStop( p->pMems[i], fVerbose ); + if ( p->nChunksAlloc ) + { + for ( i = 0; i < p->nChunks; i++ ) + ABC_FREE( p->pChunks[i] ); + ABC_FREE( p->pChunks ); + } + ABC_FREE( p->pMems ); + ABC_FREE( p->pMap ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [Creates the entry.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Gia_MmStepEntryFetch( Gia_MmStep_t * p, int nBytes ) +{ + if ( nBytes == 0 ) + return NULL; + if ( nBytes > p->nMapSize ) + { + if ( p->nChunks == p->nChunksAlloc ) + { + p->nChunksAlloc *= 2; + p->pChunks = ABC_REALLOC( char *, p->pChunks, p->nChunksAlloc ); + } + p->pChunks[ p->nChunks++ ] = ABC_ALLOC( char, nBytes ); + return p->pChunks[p->nChunks-1]; + } + return Gia_MmFixedEntryFetch( p->pMap[nBytes] ); +} + + +/**Function************************************************************* + + Synopsis [Recycles the entry.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_MmStepEntryRecycle( Gia_MmStep_t * p, char * pEntry, int nBytes ) +{ + if ( nBytes == 0 ) + return; + if ( nBytes > p->nMapSize ) + { +// ABC_FREE( pEntry ); + return; + } + Gia_MmFixedEntryRecycle( p->pMap[nBytes], pEntry ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_MmStepReadMemUsage( Gia_MmStep_t * p ) +{ + int i, nMemTotal = 0; + for ( i = 0; i < p->nMems; i++ ) + nMemTotal += p->pMems[i]->nMemoryAlloc; + return nMemTotal; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaPat.c b/src/aig/gia/giaPat.c index 7968932c..bd43380f 100644 --- a/src/aig/gia/giaPat.c +++ b/src/aig/gia/giaPat.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -127,3 +130,5 @@ void Gia_SatVerifyPattern( Gia_Man_t * p, Gia_Obj_t * pRoot, Vec_Int_t * vCex, V //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaProp.c b/src/aig/gia/giaProp.c index 1d9ed8cf..fee9aa40 100644 --- a/src/aig/gia/giaProp.c +++ b/src/aig/gia/giaProp.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -169,3 +172,5 @@ int Gia_SatPathStart( Gia_Obj_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaReparam.c b/src/aig/gia/giaReparam.c new file mode 100644 index 00000000..e33c1b7e --- /dev/null +++ b/src/aig/gia/giaReparam.c @@ -0,0 +1,201 @@ +/**CFile**************************************************************** + + FileName [gia.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: gia.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" +#include "giaAig.h" +#include "saig.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Specialized duplication.] + + Description [Replaces registers by PIs/POs and PIs by registers.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDupIn2Ff( Gia_Man_t * p ) +{ + Vec_Int_t * vPiOuts; + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + int i; + vPiOuts = Vec_IntAlloc( Gia_ManPiNum(p) ); + pNew = Gia_ManStart( Gia_ManObjNum(p) + 2 * Gia_ManPiNum(p) ); + pNew->pName = Gia_UtilStrsav( p->pName ); + Gia_ManFillValue( p ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachPi( p, pObj, i ) + Vec_IntPush( vPiOuts, Gia_ManAppendCi(pNew) ); + Gia_ManForEachRo( p, pObj, i ) + pObj->Value = Gia_ManAppendCi( pNew ); + Gia_ManForEachPi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi( pNew ); + Gia_ManForEachAnd( p, pObj, i ) + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + Gia_ManForEachPo( p, pObj, i ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManForEachRi( p, pObj, i ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManForEachPi( p, pObj, i ) + Gia_ManAppendCo( pNew, Vec_IntEntry(vPiOuts, i) ); + Gia_ManSetRegNum( pNew, Gia_ManPiNum(p) ); + Vec_IntFree( vPiOuts ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Reverses the above step.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManDupFf2In_rec( Gia_Man_t * pNew, Gia_Obj_t * pObj ) +{ + if ( pObj->Value != ~0 ) + return pObj->Value; + assert( Gia_ObjIsAnd(pObj) ); + Gia_ManDupFf2In_rec( pNew, Gia_ObjFanin0(pObj) ); + Gia_ManDupFf2In_rec( pNew, Gia_ObjFanin1(pObj) ); + return pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Reverses the above step.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDupFf2In( Gia_Man_t * p, int nFlopsOld ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + int i; + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Gia_UtilStrsav( p->pName ); + Gia_ManFillValue( p ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachRo( p, pObj, i ) + pObj->Value = Gia_ManAppendCi( pNew ); + for ( i = Gia_ManPiNum(p) - nFlopsOld; i < Gia_ManPiNum(p); i++ ) + Gia_ManPi(p, i)->Value = Gia_ManAppendCi( pNew ); + Gia_ManForEachPo( p, pObj, i ) + Gia_ManDupFf2In_rec( pNew, Gia_ObjFanin0(pObj) ); + Gia_ManForEachPo( p, pObj, i ) + Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManSetRegNum( pNew, nFlopsOld ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Reparameterized to get rid of useless primary inputs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManReparm( Gia_Man_t * p, int fVerbose ) +{ +// extern Aig_Man_t * Saig_ManRetimeMinArea( Aig_Man_t * p, int nMaxIters, int fForwardOnly, int fBackwardOnly, int fInitial, int fVerbose ); + Aig_Man_t * pMan, * pTemp; + Gia_Man_t * pNew, * pTmp; + int nFlopsOld = Gia_ManRegNum(p); + if ( fVerbose ) + { + printf( "Original AIG:\n" ); + Gia_ManPrintStats( p, 0 ); + } + + // perform input trimming + pNew = Gia_ManDupTrimmed( p, 1, 0 ); + if ( fVerbose ) + { + printf( "After PI trimming:\n" ); + Gia_ManPrintStats( pNew, 0 ); + } + // transform GIA + pNew = Gia_ManDupIn2Ff( pTmp = pNew ); + Gia_ManStop( pTmp ); + if ( fVerbose ) + { + printf( "After PI-2-FF transformation:\n" ); + Gia_ManPrintStats( pNew, 0 ); + } + + // derive AIG + pMan = Gia_ManToAigSimple( pNew ); + Gia_ManStop( pNew ); + // perform min-reg retiming + pMan = Saig_ManRetimeMinArea( pTemp = pMan, 10, 0, 0, 1, 0 ); + Aig_ManStop( pTemp ); + // derive GIA + pNew = Gia_ManFromAigSimple( pMan ); + Aig_ManStop( pMan ); + if ( fVerbose ) + { + printf( "After min-area retiming:\n" ); + Gia_ManPrintStats( pNew, 0 ); + } + + // transform back + pNew = Gia_ManDupFf2In( pTmp = pNew, nFlopsOld ); + Gia_ManStop( pTmp ); + if ( fVerbose ) + { + printf( "After FF-2-PI tranformation:\n" ); + Gia_ManPrintStats( pNew, 0 ); + } + return pNew; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaRetime.c b/src/aig/gia/giaRetime.c index 967b6d01..58029b66 100644 --- a/src/aig/gia/giaRetime.c +++ b/src/aig/gia/giaRetime.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -131,7 +134,7 @@ Gia_Man_t * Gia_ManRetimeDupForward( Gia_Man_t * p, Vec_Ptr_t * vCut ) Gia_ManForEachPi( p, pObj, i ) pObj->Value = Gia_ManAppendCi( pNew ); // create the registers - Vec_PtrForEachEntry( vCut, pObj, i ) + Vec_PtrForEachEntry( Gia_Obj_t *, vCut, pObj, i ) pObj->Value = Gia_LitNotCond( Gia_ManAppendCi(pNew), pObj->fPhase ); // duplicate logic above the cut Gia_ManForEachCo( p, pObj, i ) @@ -146,11 +149,11 @@ Gia_Man_t * Gia_ManRetimeDupForward( Gia_Man_t * p, Vec_Ptr_t * vCut ) Gia_ManForEachRiRo( p, pObjRi, pObjRo, i ) pObjRo->Value = pObjRi->Value; // erase the data values on the internal nodes of the cut - Vec_PtrForEachEntry( vCut, pObj, i ) + Vec_PtrForEachEntry( Gia_Obj_t *, vCut, pObj, i ) if ( Gia_ObjIsAnd(pObj) ) pObj->Value = ~0; // duplicate logic below the cut - Vec_PtrForEachEntry( vCut, pObj, i ) + Vec_PtrForEachEntry( Gia_Obj_t *, vCut, pObj, i ) { Gia_ManRetimeDup_rec( pNew, pObj ); Gia_ManAppendCo( pNew, Gia_LitNotCond( pObj->Value, pObj->fPhase ) ); @@ -192,7 +195,7 @@ Gia_Man_t * Gia_ManRetimeForwardOne( Gia_Man_t * p, int * pnRegFixed, int * pnRe vFlopClasses = Vec_IntAlloc( Gia_ManRegNum(p) ); } // mark the retimable nodes - Gia_ManResetTravId( p ); + Gia_ManIncrementTravId( p ); Gia_ManMarkAutonomous( p ); // mark the retimable registers with the fresh trav ID Gia_ManIncrementTravId( p ); @@ -295,3 +298,5 @@ Gia_Man_t * Gia_ManRetimeForward( Gia_Man_t * p, int nMaxIters, int fVerbose ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaSat.c b/src/aig/gia/giaSat.c index 29ade5c6..c2d70795 100644 --- a/src/aig/gia/giaSat.c +++ b/src/aig/gia/giaSat.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -419,3 +422,5 @@ void Gia_ManSatExperiment( Gia_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaScl.c b/src/aig/gia/giaScl.c index 5ac8e04a..a482d024 100644 --- a/src/aig/gia/giaScl.c +++ b/src/aig/gia/giaScl.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -187,7 +190,7 @@ Gia_Man_t * Gia_ManReduceEquiv( Gia_Man_t * p, int fVerbose ) if ( Gia_ObjFanin0(pObjRi)->Value == 0 ) Gia_ObjFanin0(pObjRi)->Value = 2*nFanins++; pCi2Lit = ABC_FALLOC( unsigned, Gia_ManCiNum(p) ); - pMaps = ABC_FALLOC( unsigned, 2 * nFanins ); + pMaps = ABC_FALLOC( unsigned, 2 * nFanins ); Gia_ManForEachRiRo( p, pObjRi, pObjRo, i ) { iLit = Gia_ObjFanin0Copy( pObjRi ); @@ -215,7 +218,7 @@ Gia_Man_t * Gia_ManReduceEquiv( Gia_Man_t * p, int fVerbose ) // printf( "ReduceEquiv detected %d constant regs and %d equivalent regs.\n", Counter0, Counter ); ABC_FREE( pMaps ); if ( Counter0 || Counter ) - pNew = Gia_ManDupDfsCiMap( p, pCi2Lit, NULL ); + pNew = Gia_ManDupDfsCiMap( p, (int *)pCi2Lit, NULL ); else pNew = p; ABC_FREE( pCi2Lit ); @@ -274,3 +277,5 @@ Gia_Man_t * Gia_ManSeqStructSweep( Gia_Man_t * p, int fConst, int fEquiv, int fV //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaShrink.c b/src/aig/gia/giaShrink.c new file mode 100644 index 00000000..fc9e80d6 --- /dev/null +++ b/src/aig/gia/giaShrink.c @@ -0,0 +1,151 @@ +/**CFile**************************************************************** + + FileName [giaShrink.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Implementation of mapShrink based on ideas of Niklas Een.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaShrink.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" +#include "aig.h" +#include "dar.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +extern int Dar_LibEvalBuild( Gia_Man_t * p, Vec_Int_t * vCut, unsigned uTruth, int fKeepLevel, Vec_Int_t * vLeavesBest ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Performs AIG shrinking using the current mapping.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManPerformMapShrink( Gia_Man_t * p, int fKeepLevel, int fVerbose ) +{ + Vec_Int_t * vLeaves, * vTruth, * vVisited, * vLeavesBest; + Gia_Man_t * pNew, * pTemp; + Gia_Obj_t * pObj, * pFanin; + unsigned * pTruth; + int i, k, iFan, clk = clock(); + int ClassCounts[222] = {0}; + int * pLutClass, Counter = 0; + assert( p->pMapping != NULL ); + if ( Gia_ManLutSizeMax( p ) > 4 ) + { + printf( "Resynthesis is not performed when nodes have more than 4 inputs.\n" ); + return NULL; + } + pLutClass = ABC_CALLOC( int, Gia_ManObjNum(p) ); + vLeaves = Vec_IntAlloc( 0 ); + vTruth = Vec_IntAlloc( (1<<16) ); + vVisited = Vec_IntAlloc( 0 ); + vLeavesBest = Vec_IntAlloc( 4 ); + // prepare the library + Dar_LibPrepare( 5 ); + // clean the old manager + Gia_ManCleanTruth( p ); + Gia_ManSetPhase( p ); + Gia_ManFillValue( p ); + Gia_ManConst0(p)->Value = 0; + // start the new manager + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Gia_UtilStrsav( p->pName ); + Gia_ManHashAlloc( pNew ); + Gia_ManCleanLevels( pNew, Gia_ManObjNum(p) ); + Gia_ManForEachObj1( p, pObj, i ) + { + if ( Gia_ObjIsCi(pObj) ) + { + pObj->Value = Gia_ManAppendCi( pNew ); + Gia_ObjSetLevel( pNew, Gia_ObjFromLit(pNew, Gia_ObjValue(pObj)), Gia_ObjLevel(p, pObj) ); + } + else if ( Gia_ObjIsCo(pObj) ) + { + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + } + else if ( Gia_ObjIsLut(p, i) ) + { + Counter++; + // collect leaves of this gate + Vec_IntClear( vLeaves ); + Gia_LutForEachFanin( p, i, iFan, k ) + Vec_IntPush( vLeaves, iFan ); + for ( ; k < 4; k++ ) + Vec_IntPush( vLeaves, 0 ); + //.compute the truth table + pTruth = Gia_ManConvertAigToTruth( p, pObj, vLeaves, vTruth, vVisited ); + // change from node IDs to their literals + Gia_ManForEachObjVec( vLeaves, p, pFanin, k ) + { + assert( Gia_ObjValue(pFanin) != ~0 ); + Vec_IntWriteEntry( vLeaves, k, Gia_ObjValue(pFanin) ); + } + // derive new structre + if ( Gia_ManTruthIsConst0(pTruth, Vec_IntSize(vLeaves)) ) + pObj->Value = 0; + else if ( Gia_ManTruthIsConst1(pTruth, Vec_IntSize(vLeaves)) ) + pObj->Value = 1; + else + { + pObj->Value = Dar_LibEvalBuild( pNew, vLeaves, 0xffff & *pTruth, fKeepLevel, vLeavesBest ); + pObj->Value = Gia_LitNotCond( pObj->Value, Gia_ObjPhaseRealLit(pNew, pObj->Value) ^ pObj->fPhase ); + } + } + } + // cleanup the AIG + Gia_ManHashStop( pNew ); + // check the presence of dangling nodes + if ( Gia_ManHasDangling(pNew) ) + { + pNew = Gia_ManCleanup( pTemp = pNew ); + if ( Gia_ManAndNum(pNew) != Gia_ManAndNum(pTemp) ) + printf( "Gia_ManPerformMapShrink() node reduction after sweep %6d -> %6d.\n", Gia_ManAndNum(pTemp), Gia_ManAndNum(pNew) ); + Gia_ManStop( pTemp ); + } + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + Vec_IntFree( vLeaves ); + Vec_IntFree( vTruth ); + Vec_IntFree( vVisited ); + Vec_IntFree( vLeavesBest ); + if ( fVerbose ) + { + printf( "Total gain in AIG nodes = %d. ", Gia_ManObjNum(p)-Gia_ManObjNum(pNew) ); + ABC_PRT( "Total runtime", clock() - clk ); + } + ABC_FREE( pLutClass ); + return pNew; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaSim.c b/src/aig/gia/giaSim.c index ae9e304c..68b50fb6 100644 --- a/src/aig/gia/giaSim.c +++ b/src/aig/gia/giaSim.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -65,6 +68,28 @@ void Gia_ManSimSetDefaultParams( Gia_ParSim_t * p ) p->TimeLimit = 60; // time limit in seconds p->fCheckMiter = 0; // check if miter outputs are non-zero p->fVerbose = 0; // enables verbose output + p->iOutFail = -1; // index of the failed output +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSimDelete( Gia_ManSim_t * p ) +{ + Vec_IntFreeP( &p->vCis2Ids ); + Gia_ManStopP( &p->pAig ); + ABC_FREE( p->pDataSim ); + ABC_FREE( p->pDataSimCis ); + ABC_FREE( p->pDataSimCos ); + ABC_FREE( p ); } /**Function************************************************************* @@ -90,10 +115,18 @@ Gia_ManSim_t * Gia_ManSimCreate( Gia_Man_t * pAig, Gia_ParSim_t * pPars ) p->pDataSim = ABC_ALLOC( unsigned, p->nWords * p->pAig->nFront ); p->pDataSimCis = ABC_ALLOC( unsigned, p->nWords * Gia_ManCiNum(p->pAig) ); p->pDataSimCos = ABC_ALLOC( unsigned, p->nWords * Gia_ManCoNum(p->pAig) ); + if ( !p->pDataSim || !p->pDataSimCis || !p->pDataSimCos ) + { + Abc_Print( 1, "Simulator could not allocate %.2f Gb for simulation info.\n", + 4.0 * p->nWords * (p->pAig->nFront + Gia_ManCiNum(p->pAig) + Gia_ManCoNum(p->pAig)) / (1<<30) ); + Gia_ManSimDelete( p ); + return NULL; + } p->vCis2Ids = Vec_IntAlloc( Gia_ManCiNum(p->pAig) ); Vec_IntForEachEntry( pAig->vCis, Entry, i ) Vec_IntPush( p->vCis2Ids, i ); // do we need p->vCis2Ids? - printf( "AIG = %7.2f Mb. Front mem = %7.2f Mb. Other mem = %7.2f Mb.\n", + if ( pPars->fVerbose ) + Abc_Print( 1, "AIG = %7.2f Mb. Front mem = %7.2f Mb. Other mem = %7.2f Mb.\n", 12.0*Gia_ManObjNum(p->pAig)/(1<<20), 4.0*p->nWords*p->pAig->nFront/(1<<20), 4.0*p->nWords*(Gia_ManCiNum(p->pAig) + Gia_ManCoNum(p->pAig))/(1<<20) ); @@ -111,27 +144,6 @@ Gia_ManSim_t * Gia_ManSimCreate( Gia_Man_t * pAig, Gia_ParSim_t * pPars ) SeeAlso [] ***********************************************************************/ -void Gia_ManSimDelete( Gia_ManSim_t * p ) -{ - Vec_IntFree( p->vCis2Ids ); - Gia_ManStop( p->pAig ); - ABC_FREE( p->pDataSim ); - ABC_FREE( p->pDataSimCis ); - ABC_FREE( p->pDataSimCos ); - ABC_FREE( p ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ static inline void Gia_ManSimInfoRandom( Gia_ManSim_t * p, unsigned * pInfo ) { int w; @@ -171,9 +183,9 @@ static inline void Gia_ManSimInfoZero( Gia_ManSim_t * p, unsigned * pInfo ) static inline int Gia_ManSimInfoIsZero( Gia_ManSim_t * p, unsigned * pInfo ) { int w; - for ( w = p->nWords-1; w >= 0; w-- ) + for ( w = 0; w < p->nWords; w++ ) if ( pInfo[w] ) - return 32*(w-1) + Gia_WordFindFirstBit( pInfo[w] ); + return 32*w + Gia_WordFindFirstBit( pInfo[w] ); return -1; } @@ -418,9 +430,9 @@ static inline int Gia_ManCheckPos( Gia_ManSim_t * p, int * piPo, int * piPat ) SeeAlso [] ***********************************************************************/ -Gia_Cex_t * Gia_ManGenerateCounter( Gia_Man_t * pAig, int iFrame, int iOut, int nWords, int iPat, Vec_Int_t * vCis2Ids ) +Abc_Cex_t * Gia_ManGenerateCounter( Gia_Man_t * pAig, int iFrame, int iOut, int nWords, int iPat, Vec_Int_t * vCis2Ids ) { - Gia_Cex_t * p; + Abc_Cex_t * p; unsigned * pData; int f, i, w, iPioId, Counter; p = Gia_ManAllocCounterExample( Gia_ManRegNum(pAig), Gia_ManPiNum(pAig), iFrame+1 ); @@ -468,43 +480,44 @@ int Gia_ManSimSimulate( Gia_Man_t * pAig, Gia_ParSim_t * pPars ) for ( i = 0; i < pPars->nIters; i++ ) { Gia_ManSimulateRound( p ); - if ( pPars->fVerbose ) { - printf( "Frame %4d out of %4d and timeout %3d sec. ", i+1, pPars->nIters, pPars->TimeLimit ); - printf( "Time = %7.2f sec\r", (1.0*clock()-clkTotal)/CLOCKS_PER_SEC ); + Abc_Print( 1, "Frame %4d out of %4d and timeout %3d sec. ", i+1, pPars->nIters, pPars->TimeLimit ); + Abc_Print( 1, "Time = %7.2f sec\r", (1.0*clock()-clkTotal)/CLOCKS_PER_SEC ); } if ( pPars->fCheckMiter && Gia_ManCheckPos( p, &iOut, &iPat ) ) { + pPars->iOutFail = iOut; pAig->pCexSeq = Gia_ManGenerateCounter( pAig, i, iOut, p->nWords, iPat, p->vCis2Ids ); - printf( "Output %d was asserted in frame %d (use \"write_counter\" to dump a witness).\n", iOut, i ); + Abc_Print( 1, "Networks are NOT EQUIVALENT. Output %d was asserted in frame %d. ", iOut, i ); if ( !Gia_ManVerifyCounterExample( pAig, pAig->pCexSeq, 0 ) ) { - printf( "\n" ); - printf( "Generated counter-example is INVALID \n" ); - printf( "\n" ); +// Abc_Print( 1, "\n" ); + Abc_Print( 1, "\nGenerated counter-example is INVALID. " ); +// Abc_Print( 1, "\n" ); } else { - printf( "\n" ); - printf( "Generated counter-example is fine \n" ); - printf( "\n" ); +// Abc_Print( 1, "\n" ); +// if ( pPars->fVerbose ) +// Abc_Print( 1, "\nGenerated counter-example is verified correctly. " ); +// Abc_Print( 1, "\n" ); } RetValue = 1; break; } if ( (clock() - clkTotal)/CLOCKS_PER_SEC >= pPars->TimeLimit ) { - printf( "No bug detected after %d frames with time limit %d seconds. \n", i+1, pPars->TimeLimit ); + i++; break; } - if ( i < pPars->nIters - 1 ) Gia_ManSimInfoTransfer( p ); } Gia_ManSimDelete( p ); - printf( "Simulated %d frames with %d words. ", i, pPars->nWords ); - ABC_PRT( "Time", clock() - clkTotal ); + if ( pAig->pCexSeq == NULL ) + Abc_Print( 1, "No bug detected after simulating %d frames with %d words. ", i, pPars->nWords ); + Abc_PrintTime( 1, "Time", clock() - clkTotal ); return RetValue; } @@ -513,3 +526,5 @@ int Gia_ManSimSimulate( Gia_Man_t * pAig, Gia_ParSim_t * pPars ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaSort.c b/src/aig/gia/giaSort.c index 8574297d..f73e92bb 100644 --- a/src/aig/gia/giaSort.c +++ b/src/aig/gia/giaSort.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -266,3 +269,5 @@ int * Gia_SortFloats( float * pArray, int * pPerm, int nSize ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaSpeedup.c b/src/aig/gia/giaSpeedup.c new file mode 100644 index 00000000..cce0b68d --- /dev/null +++ b/src/aig/gia/giaSpeedup.c @@ -0,0 +1,810 @@ +/**CFile**************************************************************** + + FileName [gia.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: gia.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" +#include "if.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Sorts the pins in the decreasing order of delays.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_LutDelayTraceSortPins( Gia_Man_t * p, int iObj, int * pPinPerm, float * pPinDelays ) +{ + int iFanin, i, j, best_i, temp; + assert( Gia_ObjIsLut(p, iObj) ); + // start the trivial permutation and collect pin delays + Gia_LutForEachFanin( p, iObj, iFanin, i ) + { + pPinPerm[i] = i; + pPinDelays[i] = Gia_ObjTimeArrival(p, iFanin); + } + // selection sort the pins in the decreasible order of delays + // this order will match the increasing order of LUT input pins + for ( i = 0; i < Gia_ObjLutSize(p, iObj)-1; i++ ) + { + best_i = i; + for ( j = i+1; j < Gia_ObjLutSize(p, iObj); j++ ) + if ( pPinDelays[pPinPerm[j]] > pPinDelays[pPinPerm[best_i]] ) + best_i = j; + if ( best_i == i ) + continue; + temp = pPinPerm[i]; + pPinPerm[i] = pPinPerm[best_i]; + pPinPerm[best_i] = temp; + } + // verify + assert( Gia_ObjLutSize(p, iObj) == 0 || pPinPerm[0] < Gia_ObjLutSize(p, iObj) ); + for ( i = 1; i < Gia_ObjLutSize(p, iObj); i++ ) + { + assert( pPinPerm[i] < Gia_ObjLutSize(p, iObj) ); + assert( pPinDelays[pPinPerm[i-1]] >= pPinDelays[pPinPerm[i]] ); + } +} + +/**Function************************************************************* + + Synopsis [Sorts the pins in the decreasing order of delays.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_LutWhereIsPin( Gia_Man_t * p, int iFanout, int iFanin, int * pPinPerm ) +{ + int i; + for ( i = 0; i < Gia_ObjLutSize(p, iFanout); i++ ) + if ( Gia_ObjLutFanin(p, iFanout, pPinPerm[i]) == iFanin ) + return i; + return -1; +} + +/**Function************************************************************* + + Synopsis [Computes the arrival times for the given object.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +float Gia_ObjComputeArrival( Gia_Man_t * p, int iObj, int fUseSorting ) +{ + If_Lib_t * pLutLib = (If_Lib_t *)p->pLutLib; + Gia_Obj_t * pObj = Gia_ManObj( p, iObj ); + int k, iFanin, pPinPerm[32]; + float pPinDelays[32]; + float tArrival, * pDelays; + if ( Gia_ObjIsCi(pObj) ) + return Gia_ObjTimeArrival(p, iObj); + if ( Gia_ObjIsCo(pObj) ) + return Gia_ObjTimeArrival(p, Gia_ObjFaninId0p(p, pObj) ); + assert( Gia_ObjIsLut(p, iObj) ); + tArrival = -TIM_ETERNITY; + if ( pLutLib == NULL ) + { + Gia_LutForEachFanin( p, iObj, iFanin, k ) + if ( tArrival < Gia_ObjTimeArrival(p, iFanin) + 1.0 ) + tArrival = Gia_ObjTimeArrival(p, iFanin) + 1.0; + } + else if ( !pLutLib->fVarPinDelays ) + { + pDelays = pLutLib->pLutDelays[Gia_ObjLutSize(p, iObj)]; + Gia_LutForEachFanin( p, iObj, iFanin, k ) + if ( tArrival < Gia_ObjTimeArrival(p, iFanin) + pDelays[0] ) + tArrival = Gia_ObjTimeArrival(p, iFanin) + pDelays[0]; + } + else + { + pDelays = pLutLib->pLutDelays[Gia_ObjLutSize(p, iObj)]; + if ( fUseSorting ) + { + Gia_LutDelayTraceSortPins( p, iObj, pPinPerm, pPinDelays ); + Gia_LutForEachFanin( p, iObj, iFanin, k ) + if ( tArrival < Gia_ObjTimeArrival( p, Gia_ObjLutFanin(p,iObj,pPinPerm[k])) + pDelays[k] ) + tArrival = Gia_ObjTimeArrival( p, Gia_ObjLutFanin(p,iObj,pPinPerm[k])) + pDelays[k]; + } + else + { + Gia_LutForEachFanin( p, iObj, iFanin, k ) + if ( tArrival < Gia_ObjTimeArrival(p, iFanin) + pDelays[k] ) + tArrival = Gia_ObjTimeArrival(p, iFanin) + pDelays[k]; + } + } + if ( Gia_ObjLutSize(p, iObj) == 0 ) + tArrival = 0.0; + return tArrival; +} + + +/**Function************************************************************* + + Synopsis [Propagates the required times through the given node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +float Gia_ObjPropagateRequired( Gia_Man_t * p, int iObj, int fUseSorting ) +{ + If_Lib_t * pLutLib = (If_Lib_t *)p->pLutLib; + int k, iFanin, pPinPerm[32]; + float pPinDelays[32]; + float tRequired = 0.0; // Suppress "might be used uninitialized" + float * pDelays; + assert( Gia_ObjIsLut(p, iObj) ); + if ( pLutLib == NULL ) + { + tRequired = Gia_ObjTimeRequired( p, iObj) - (float)1.0; + Gia_LutForEachFanin( p, iObj, iFanin, k ) + if ( Gia_ObjTimeRequired(p, iFanin) > tRequired ) + Gia_ObjSetTimeRequired( p, iFanin, tRequired ); + } + else if ( !pLutLib->fVarPinDelays ) + { + pDelays = pLutLib->pLutDelays[Gia_ObjLutSize(p, iObj)]; + tRequired = Gia_ObjTimeRequired(p, iObj) - pDelays[0]; + Gia_LutForEachFanin( p, iObj, iFanin, k ) + if ( Gia_ObjTimeRequired(p, iFanin) > tRequired ) + Gia_ObjSetTimeRequired( p, iFanin, tRequired ); + } + else + { + pDelays = pLutLib->pLutDelays[Gia_ObjLutSize(p, iObj)]; + if ( fUseSorting ) + { + Gia_LutDelayTraceSortPins( p, iObj, pPinPerm, pPinDelays ); + Gia_LutForEachFanin( p, iObj, iFanin, k ) + { + tRequired = Gia_ObjTimeRequired( p, iObj) - pDelays[k]; + if ( Gia_ObjTimeRequired( p, Gia_ObjLutFanin(p, iObj,pPinPerm[k])) > tRequired ) + Gia_ObjSetTimeRequired( p, Gia_ObjLutFanin(p, iObj,pPinPerm[k]), tRequired ); + } + } + else + { + Gia_LutForEachFanin( p, iObj, iFanin, k ) + { + tRequired = Gia_ObjTimeRequired(p, iObj) - pDelays[k]; + if ( Gia_ObjTimeRequired(p, iFanin) > tRequired ) + Gia_ObjSetTimeRequired( p, iFanin, tRequired ); + } + } + } + return tRequired; +} + +/**Function************************************************************* + + Synopsis [Computes the delay trace of the given network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +float Gia_ManDelayTraceLut( Gia_Man_t * p ) +{ + int fUseSorting = 1; + If_Lib_t * pLutLib = (If_Lib_t *)p->pLutLib; + Vec_Int_t * vObjs; + Gia_Obj_t * pObj; + float tArrival, tArrivalCur, tRequired, tSlack; + int i, iObj; + + // get the library + if ( pLutLib && pLutLib->LutMax < Gia_ManLutSizeMax(p) ) + { + printf( "The max LUT size (%d) is less than the max fanin count (%d).\n", + pLutLib->LutMax, Gia_ManLutSizeMax(p) ); + return -TIM_ETERNITY; + } + + // initialize the arrival times + Gia_ManTimeStart( p ); + + // propagate arrival times + if ( p->pManTime ) + Tim_ManIncrementTravId( (Tim_Man_t *)p->pManTime ); + Gia_ManForEachObj( p, pObj, i ) + { + if ( !Gia_ObjIsCi(pObj) && !Gia_ObjIsCo(pObj) && !Gia_ObjIsLut(p, i) ) + continue; + tArrival = Gia_ObjComputeArrival( p, i, fUseSorting ); + if ( Gia_ObjIsCi(pObj) && p->pManTime ) + { + tArrival = Tim_ManGetCiArrival( (Tim_Man_t *)p->pManTime, Gia_ObjCioId(pObj) ); +//printf( "%.3f ", tArrival ); + } + if ( Gia_ObjIsCo(pObj) && p->pManTime ) + Tim_ManSetCoArrival( (Tim_Man_t *)p->pManTime, Gia_ObjCioId(pObj), tArrival ); + Gia_ObjSetTimeArrival( p, i, tArrival ); + } + + // get the latest arrival times + tArrival = -TIM_ETERNITY; + Gia_ManForEachCo( p, pObj, i ) + { + tArrivalCur = Gia_ObjTimeArrivalObj( p, Gia_ObjFanin0(pObj) ); + Gia_ObjSetTimeArrival( p, Gia_ObjId(p,pObj), tArrivalCur ); + if ( tArrival < tArrivalCur ) + tArrival = tArrivalCur; + } + + // initialize the required times + if ( p->pManTime ) + { + Tim_ManIncrementTravId( (Tim_Man_t *)p->pManTime ); + Tim_ManSetCoRequiredAll( (Tim_Man_t *)p->pManTime, tArrival ); + } + else + { + Gia_ManForEachCo( p, pObj, i ) + Gia_ObjSetTimeRequiredObj( p, pObj, tArrival ); + } + + // propagate the required times + vObjs = Gia_ManOrderReverse( p ); + Vec_IntForEachEntry( vObjs, iObj, i ) + { + if ( i == 1137 ) + { + int s = 0; + } + pObj = Gia_ManObj(p, iObj); +//printf( "%d ", Gia_ObjLevel(p, pObj) ); + if ( Gia_ObjIsLut(p, iObj) ) + { + Gia_ObjPropagateRequired( p, iObj, fUseSorting ); + } + else if ( Gia_ObjIsCi(pObj) ) + { + if ( p->pManTime ) + Tim_ManSetCiRequired( (Tim_Man_t *)p->pManTime, Gia_ObjCioId(pObj), Gia_ObjTimeRequired(p, iObj) ); + } + else if ( Gia_ObjIsCo(pObj) ) + { + if ( p->pManTime ) + { + tRequired = Tim_ManGetCoRequired( (Tim_Man_t *)p->pManTime, Gia_ObjCioId(pObj) ); + Gia_ObjSetTimeRequired( p, iObj, tRequired ); + } + if ( Gia_ObjTimeRequired(p, Gia_ObjFaninId0p(p, pObj)) > Gia_ObjTimeRequired(p, iObj) ) + Gia_ObjSetTimeRequired(p, Gia_ObjFaninId0p(p, pObj), Gia_ObjTimeRequired(p, iObj) ); + } + + // set slack for this object + tSlack = Gia_ObjTimeRequired(p, iObj) - Gia_ObjTimeArrival(p, iObj); + assert( tSlack + 0.01 > 0.0 ); + Gia_ObjSetTimeSlack( p, iObj, tSlack < 0.0 ? 0.0 : tSlack ); + } + Vec_IntFree( vObjs ); + return tArrival; +} + +#if 0 + +/**Function************************************************************* + + Synopsis [Computes the required times for the given node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +float Gia_ObjComputeRequired( Gia_Man_t * p, int iObj, int fUseSorting ) +{ + If_Lib_t * pLutLib = p->pLutLib; + int pPinPerm[32]; + float pPinDelays[32]; + Gia_Obj_t * pFanout; + float tRequired, tDelay, * pDelays; + int k, iFanin; + if ( Gia_ObjIsCo(iObj) ) + return Gia_ObjTimeRequired( p, iObj); + tRequired = TIM_ETERNITY; + if ( pLutLib == NULL ) + { + Gia_ObjForEachFanout( iObj, pFanout, k ) + { + tDelay = Gia_ObjIsCo(pFanout)? 0.0 : 1.0; + if ( tRequired > Gia_ObjTimeRequired( p, pFanout) - tDelay ) + tRequired = Gia_ObjTimeRequired( p, pFanout) - tDelay; + } + } + else if ( !pLutLib->fVarPinDelays ) + { + Gia_ObjForEachFanout( iObj, pFanout, k ) + { + pDelays = pLutLib->pLutDelays[Gia_ObjLutSize(p, pFanout)]; + tDelay = Gia_ObjIsCo(pFanout)? 0.0 : pDelays[0]; + if ( tRequired > Gia_ObjTimeRequired( p, pFanout) - tDelay ) + tRequired = Gia_ObjTimeRequired( p, pFanout) - tDelay; + } + } + else + { + if ( fUseSorting ) + { + Gia_ObjForEachFanout( iObj, pFanout, k ) + { + pDelays = pLutLib->pLutDelays[Gia_ObjLutSize(p, pFanout)]; + Gia_LutDelayTraceSortPins( p, pFanout, pPinPerm, pPinDelays ); + iFanin = Gia_LutWhereIsPin( p, pFanout, iObj, pPinPerm ); + assert( Gia_ObjLutFanin( p, pFanout, pPinPerm[iFanin]) == iObj ); + tDelay = Gia_ObjIsCo(pFanout)? 0.0 : pDelays[iFanin]; + if ( tRequired > Gia_ObjTimeRequired( p, pFanout) - tDelay ) + tRequired = Gia_ObjTimeRequired( p, pFanout) - tDelay; + } + } + else + { + Gia_ObjForEachFanout( iObj, pFanout, k ) + { + pDelays = pLutLib->pLutDelays[Gia_ObjLutSize(p, pFanout)]; + iFanin = Gia_ObjFindFanin( p, pFanout, iObj ); + assert( Gia_ObjLutFanin(p, pFanout, iFanin) == iObj ); + tDelay = Gia_ObjIsCo(pFanout)? 0.0 : pDelays[iFanin]; + if ( tRequired > Gia_ObjTimeRequired( p, pFanout) - tDelay ) + tRequired = Gia_ObjTimeRequired( p, pFanout) - tDelay; + } + } + } + return tRequired; +} + +/**Function************************************************************* + + Synopsis [Computes the arrival times for the given node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_LutVerifyTiming( Gia_Man_t * p ) +{ + int iObj; + float tArrival, tRequired; + int i; + Gia_LutForEachObj( p, iObj, i ) + { + if ( Gia_ObjIsCi(iObj) && Gia_ObjFanoutNum(iObj) == 0 ) + continue; + tArrival = Gia_ObjComputeArrival( p, iObj, 1 ); + tRequired = Gia_ObjComputeRequired( p, iObj, 1 ); + if ( !Gia_LutTimeEqual( tArrival, Gia_ObjTimeArrival( p, iObj), (float)0.01 ) ) + printf( "Gia_LutVerifyTiming(): Object %d has different arrival time (%.2f) from computed (%.2f).\n", + iObj->Id, Gia_ObjTimeArrival( p, iObj), tArrival ); + if ( !Gia_LutTimeEqual( tRequired, Gia_ObjTimeRequired( p, iObj), (float)0.01 ) ) + printf( "Gia_LutVerifyTiming(): Object %d has different required time (%.2f) from computed (%.2f).\n", + iObj->Id, Gia_ObjTimeRequired( p, iObj), tRequired ); + } + return 1; +} + +#endif + +/**Function************************************************************* + + Synopsis [Prints the delay trace for the given network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +float Gia_ManDelayTraceLutPrint( Gia_Man_t * p, int fVerbose ) +{ + If_Lib_t * pLutLib = (If_Lib_t *)p->pLutLib; + int i, Nodes, * pCounters; + float tArrival, tDelta, nSteps, Num; + // get the library + if ( pLutLib && pLutLib->LutMax < Gia_ManLutSizeMax(p) ) + { + printf( "The max LUT size (%d) is less than the max fanin count (%d).\n", + pLutLib->LutMax, Gia_ManLutSizeMax(p) ); + return -ABC_INFINITY; + } + // decide how many steps + nSteps = pLutLib ? 20 : Gia_ManLutLevel(p); + pCounters = ABC_ALLOC( int, nSteps + 1 ); + memset( pCounters, 0, sizeof(int)*(nSteps + 1) ); + // perform delay trace + tArrival = Gia_ManDelayTraceLut( p ); + tDelta = tArrival / nSteps; + // count how many nodes have slack in the corresponding intervals + Gia_ManForEachLut( p, i ) + { + if ( Gia_ObjLutSize(p, i) == 0 ) + continue; + Num = Gia_ObjTimeSlack(p, i) / tDelta; + if ( Num > nSteps ) + continue; + assert( Num >=0 && Num <= nSteps ); + pCounters[(int)Num]++; + } + // print the results + if ( fVerbose ) + { + printf( "Max delay = %6.2f. Delay trace using %s model:\n", tArrival, pLutLib? "LUT library" : "unit-delay" ); + Nodes = 0; + for ( i = 0; i < nSteps; i++ ) + { + Nodes += pCounters[i]; + printf( "%3d %s : %5d (%6.2f %%)\n", pLutLib? 5*(i+1) : i+1, + pLutLib? "%":"lev", Nodes, 100.0*Nodes/Gia_ManLutNum(p) ); + } + } + ABC_FREE( pCounters ); + Gia_ManTimeStop( p ); + return tArrival; +} + +/**Function************************************************************* + + Synopsis [Determines timing-critical edges of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned Gia_LutDelayTraceTCEdges( Gia_Man_t * p, int iObj, float tDelta ) +{ + If_Lib_t * pLutLib = (If_Lib_t *)p->pLutLib; + int pPinPerm[32]; + float pPinDelays[32]; + float tRequired, * pDelays; + unsigned uResult = 0; + int k, iFanin; + tRequired = Gia_ObjTimeRequired( p, iObj ); + if ( pLutLib == NULL ) + { + Gia_LutForEachFanin( p, iObj, iFanin, k ) + if ( tRequired < Gia_ObjTimeArrival(p, iFanin) + 1.0 + tDelta ) + uResult |= (1 << k); + } + else if ( !pLutLib->fVarPinDelays ) + { + pDelays = pLutLib->pLutDelays[Gia_ObjLutSize(p, iObj)]; + Gia_LutForEachFanin( p, iObj, iFanin, k ) + if ( tRequired < Gia_ObjTimeArrival(p, iFanin) + pDelays[0] + tDelta ) + uResult |= (1 << k); + } + else + { + pDelays = pLutLib->pLutDelays[Gia_ObjLutSize(p, iObj)]; + Gia_LutDelayTraceSortPins( p, iObj, pPinPerm, pPinDelays ); + Gia_LutForEachFanin( p, iObj, iFanin, k ) + if ( tRequired < Gia_ObjTimeArrival( p, Gia_ObjLutFanin(p, iObj,pPinPerm[k])) + pDelays[k] + tDelta ) + uResult |= (1 << pPinPerm[k]); + } + return uResult; +} + +/**Function************************************************************* + + Synopsis [Adds strashed nodes for one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManSpeedupObj_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vNodes ) +{ + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return 1; + Gia_ObjSetTravIdCurrent( p, pObj ); + if ( Gia_ObjIsCi(pObj) ) + return 0; + assert( Gia_ObjIsAnd(pObj) ); + if ( !Gia_ManSpeedupObj_rec( p, Gia_ObjFanin0(pObj), vNodes ) ) + return 0; + if ( !Gia_ManSpeedupObj_rec( p, Gia_ObjFanin1(pObj), vNodes ) ) + return 0; + Vec_IntPush( vNodes, Gia_ObjId(p, pObj) ); + return 1; +} + +/**Function************************************************************* + + Synopsis [Adds strashed nodes for one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSpeedupObj( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vLeaves, Vec_Int_t * vTimes ) +{ + Vec_Int_t * vNodes; + Gia_Obj_t * pTemp = NULL; + int pCofs[32], nCofs, nSkip, i, k, iResult, iObj; + // mark the leaves + Gia_ManIncrementTravId( p ); + Gia_ObjSetTravIdCurrent( p, Gia_ManConst0(p) ); + Gia_ManForEachObjVec( vLeaves, p, pTemp, i ) + Gia_ObjSetTravIdCurrent( p, pTemp ); + // collect the AIG nodes + vNodes = Vec_IntAlloc( 100 ); + if ( !Gia_ManSpeedupObj_rec( p, pObj, vNodes ) ) + { + printf( "Bad node!!!\n" ); + Vec_IntFree( vNodes ); + return; + } + // derive cofactors + nCofs = (1 << Vec_IntSize(vTimes)); + for ( i = 0; i < nCofs; i++ ) + { + Gia_ManForEachObjVec( vLeaves, p, pTemp, k ) + pTemp->Value = Gia_Var2Lit( Gia_ObjId(p, pTemp), 0 ); + Gia_ManForEachObjVec( vTimes, p, pTemp, k ) + pTemp->Value = ((i & (1<<k)) != 0); + Gia_ManForEachObjVec( vNodes, p, pTemp, k ) + pTemp->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pTemp), Gia_ObjFanin1Copy(pTemp) ); + pCofs[i] = pTemp->Value; + } + Vec_IntFree( vNodes ); + // collect the resulting tree + Gia_ManForEachObjVec( vTimes, p, pTemp, k ) + for ( nSkip = (1<<k), i = 0; i < nCofs; i += 2*nSkip ) + pCofs[i] = Gia_ManHashMux( pNew, Gia_ObjToLit(p,pTemp), pCofs[i+nSkip], pCofs[i] ); + // create choice node (pObj is repr and ppCofs[0] is new) + iObj = Gia_ObjId( p, pObj ); + iResult = Gia_Lit2Var( pCofs[0] ); + if ( iResult <= iObj ) + return; + Gia_ObjSetRepr( pNew, iResult, iObj ); + Gia_ObjSetNext( pNew, iResult, Gia_ObjNext(pNew, iObj) ); + Gia_ObjSetNext( pNew, iObj, iResult ); +} + +/**Function************************************************************* + + Synopsis [Adds choices to speed up the network by the given percentage.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManSpeedup( Gia_Man_t * p, int Percentage, int Degree, int fVerbose, int fVeryVerbose ) +{ + Gia_Man_t * pNew, * pTemp; + Vec_Int_t * vTimeCries, * vTimeFanins; + int iObj, iFanin, iFanin2, nNodesNew; + float tDelta, tArrival; + int i, k, k2, Counter, CounterRes, nTimeCris; + int fUseLutLib = (p->pLutLib != NULL); + void * pTempTim = NULL; + unsigned * puTCEdges; + assert( p->pMapping != NULL ); + if ( !fUseLutLib && p->pManTime ) + { + pTempTim = p->pManTime; + p->pManTime = Tim_ManDup( (Tim_Man_t *)pTempTim, 1 ); + } + // perform delay trace + tArrival = Gia_ManDelayTraceLut( p ); + tDelta = fUseLutLib ? tArrival*Percentage/100.0 : 1.0; + if ( fVerbose ) + { + printf( "Max delay = %.2f. Delta = %.2f. ", tArrival, tDelta ); + printf( "Using %s model. ", fUseLutLib ? "LUT library" : "unit-delay" ); + if ( fUseLutLib ) + printf( "Percentage = %d. ", Percentage ); + printf( "\n" ); + } + // mark the timing critical nodes and edges + puTCEdges = ABC_CALLOC( unsigned, Gia_ManObjNum(p) ); + Gia_ManForEachLut( p, iObj ) + { + if ( Gia_ObjTimeSlack(p, iObj) >= tDelta ) + continue; + puTCEdges[iObj] = Gia_LutDelayTraceTCEdges( p, iObj, tDelta ); + } + if ( fVerbose ) + { + Counter = CounterRes = 0; + Gia_ManForEachLut( p, iObj ) + { + Gia_LutForEachFanin( p, iObj, iFanin, k ) + if ( !Gia_ObjIsCi(Gia_ManObj(p, iFanin)) && Gia_ObjTimeSlack(p, iFanin) < tDelta ) + Counter++; + CounterRes += Gia_WordCountOnes( puTCEdges[iObj] ); + } + printf( "Edges: Total = %7d. 0-slack = %7d. Critical = %7d. Ratio = %4.2f\n", + Gia_ManLutFaninCount(p), Counter, CounterRes, Counter? 1.0*CounterRes/Counter : 0.0 ); + } + + // start the resulting network + pNew = Gia_ManDup( p ); + Gia_ManHashStart( pNew ); + nNodesNew = 1000 + 3 * Gia_ManObjNum(pNew); + pNew->pNexts = ABC_CALLOC( int, nNodesNew ); + pNew->pReprs = ABC_CALLOC( Gia_Rpr_t, nNodesNew ); + for ( i = 0; i < nNodesNew; i++ ) + Gia_ObjSetRepr( pNew, i, GIA_VOID ); + + // collect nodes to be used for resynthesis + Counter = CounterRes = 0; + vTimeCries = Vec_IntAlloc( 16 ); + vTimeFanins = Vec_IntAlloc( 16 ); + Gia_ManForEachLut( p, iObj ) + { + if ( Gia_ObjTimeSlack(p, iObj) >= tDelta ) + continue; + // count the number of non-PI timing-critical nodes + nTimeCris = 0; + Gia_LutForEachFanin( p, iObj, iFanin, k ) + if ( !Gia_ObjIsCi(Gia_ManObj(p, iFanin)) && (puTCEdges[iObj] & (1<<k)) ) + nTimeCris++; + if ( !fVeryVerbose && nTimeCris == 0 ) + continue; + Counter++; + // count the total number of timing critical second-generation nodes + Vec_IntClear( vTimeCries ); + if ( nTimeCris ) + { + Gia_LutForEachFanin( p, iObj, iFanin, k ) + if ( !Gia_ObjIsCi(Gia_ManObj(p, iFanin)) && (puTCEdges[iObj] & (1<<k)) ) + Gia_LutForEachFanin( p, iFanin, iFanin2, k2 ) + if ( puTCEdges[iFanin] & (1<<k2) ) + Vec_IntPushUnique( vTimeCries, iFanin2 ); + } +// if ( !fVeryVerbose && (Vec_IntSize(vTimeCries) == 0 || Vec_IntSize(vTimeCries) > Degree) ) + if ( (Vec_IntSize(vTimeCries) == 0 || Vec_IntSize(vTimeCries) > Degree) ) + continue; + CounterRes++; + // collect second generation nodes + Vec_IntClear( vTimeFanins ); + Gia_LutForEachFanin( p, iObj, iFanin, k ) + { + if ( Gia_ObjIsCi(Gia_ManObj(p, iFanin)) ) + Vec_IntPushUnique( vTimeFanins, iFanin ); + else + Gia_LutForEachFanin( p, iFanin, iFanin2, k2 ) + Vec_IntPushUnique( vTimeFanins, iFanin2 ); + } + // print the results + if ( fVeryVerbose ) + { + printf( "%5d Node %5d : %d %2d %2d ", Counter, iObj, + nTimeCris, Vec_IntSize(vTimeCries), Vec_IntSize(vTimeFanins) ); + Gia_LutForEachFanin( p, iObj, iFanin, k ) + printf( "%d(%.2f)%s ", iFanin, Gia_ObjTimeSlack(p, iFanin), (puTCEdges[iObj] & (1<<k))? "*":"" ); + printf( "\n" ); + } + // add the node to choices + if ( Vec_IntSize(vTimeCries) == 0 || Vec_IntSize(vTimeCries) > Degree ) + continue; + // order the fanins in the increasing order of criticalily + if ( Vec_IntSize(vTimeCries) > 1 ) + { + iFanin = Vec_IntEntry( vTimeCries, 0 ); + iFanin2 = Vec_IntEntry( vTimeCries, 1 ); + if ( Gia_ObjTimeSlack(p, iFanin) < Gia_ObjTimeSlack(p, iFanin2) ) + { + Vec_IntWriteEntry( vTimeCries, 0, iFanin2 ); + Vec_IntWriteEntry( vTimeCries, 1, iFanin ); + } + } + if ( Vec_IntSize(vTimeCries) > 2 ) + { + iFanin = Vec_IntEntry( vTimeCries, 1 ); + iFanin2 = Vec_IntEntry( vTimeCries, 2 ); + if ( Gia_ObjTimeSlack(p, iFanin) < Gia_ObjTimeSlack(p, iFanin2) ) + { + Vec_IntWriteEntry( vTimeCries, 1, iFanin2 ); + Vec_IntWriteEntry( vTimeCries, 2, iFanin ); + } + iFanin = Vec_IntEntry( vTimeCries, 0 ); + iFanin2 = Vec_IntEntry( vTimeCries, 1 ); + if ( Gia_ObjTimeSlack(p, iFanin) < Gia_ObjTimeSlack(p, iFanin2) ) + { + Vec_IntWriteEntry( vTimeCries, 0, iFanin2 ); + Vec_IntWriteEntry( vTimeCries, 1, iFanin ); + } + } + // add choice + Gia_ManSpeedupObj( pNew, p, Gia_ManObj(p,iObj), vTimeFanins, vTimeCries ); + // quit if the number of nodes is large + if ( Gia_ManObjNum(pNew) > nNodesNew - 100 ) + { + printf( "Speedup stopped adding choices because there was too many to add.\n" ); + break; + } + } + Gia_ManTimeStop( p ); + Vec_IntFree( vTimeCries ); + Vec_IntFree( vTimeFanins ); + ABC_FREE( puTCEdges ); + if ( fVerbose ) + printf( "Nodes: Total = %7d. 0-slack = %7d. Workable = %7d. Ratio = %4.2f\n", + Gia_ManLutNum(p), Counter, CounterRes, Counter? 1.0*CounterRes/Counter : 0.0 ); + if ( pTempTim ) + { + Tim_ManStop( (Tim_Man_t *)p->pManTime ); + p->pManTime = pTempTim; + } + // derive AIG with choices +//Gia_ManPrintStats( pNew, 0 ); + pTemp = Gia_ManEquivToChoices( pNew, 1 ); + Gia_ManStop( pNew ); +//Gia_ManPrintStats( pTemp, 0 ); +// pNew = Gia_ManDupOrderDfsChoices( pTemp ); +// Gia_ManStop( pTemp ); +//Gia_ManPrintStats( pNew, 0 ); +// return pNew; + return pTemp; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaSupMin.c b/src/aig/gia/giaSupMin.c new file mode 100644 index 00000000..4abaab0f --- /dev/null +++ b/src/aig/gia/giaSupMin.c @@ -0,0 +1,165 @@ +/**CFile**************************************************************** + + FileName [giaSupMin.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Support minimization for AIGs with don't-cares.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaSupMin.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" +#include "kit.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +// decomposition manager +typedef struct Gia_ManSup_t_ Gia_ManSup_t; +struct Gia_ManSup_t_ +{ + int nVarsMax; // the max number of variables + int nWordsMax; // the max number of words + Vec_Ptr_t * vTruthVars; // elementary truth tables + Vec_Ptr_t * vTruthNodes; // internal truth tables + // current problem + Gia_Man_t * pGia; + int iData; + int iCare; + Vec_Int_t * vConeCare; + Vec_Int_t * vConeData; + unsigned * pTruthIn; + unsigned * pTruthOut; +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Starts Decmetry manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_ManSup_t * Gia_ManSupStart( int nVarsMax ) +{ + Gia_ManSup_t * p; + assert( nVarsMax <= 20 ); + p = ABC_CALLOC( Gia_ManSup_t, 1 ); + p->nVarsMax = nVarsMax; + p->nWordsMax = Kit_TruthWordNum( p->nVarsMax ); + p->vTruthVars = Vec_PtrAllocTruthTables( p->nVarsMax ); + p->vTruthNodes = Vec_PtrAllocSimInfo( 512, p->nWordsMax ); + p->vConeCare = Vec_IntAlloc( 512 ); + p->vConeData = Vec_IntAlloc( 512 ); + p->pTruthIn = ABC_ALLOC( unsigned, p->nWordsMax ); + p->pTruthOut = ABC_ALLOC( unsigned, p->nWordsMax ); + return p; +} + +/**Function************************************************************* + + Synopsis [Stops Decmetry manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSupStop( Gia_ManSup_t * p ) +{ + ABC_FREE( p->pTruthIn ); + ABC_FREE( p->pTruthOut ); + Vec_IntFreeP( &p->vConeCare ); + Vec_IntFreeP( &p->vConeData ); + Vec_PtrFreeP( &p->vTruthVars ); + Vec_PtrFreeP( &p->vTruthNodes ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSupExperimentOne( Gia_ManSup_t * p, Gia_Obj_t * pData, Gia_Obj_t * pCare ) +{ + int iData = Gia_ObjId( p->pGia, Gia_Regular(pData) ); + int iCare = Gia_ObjId( p->pGia, Gia_Regular(pCare) ); + if ( !Gia_ObjIsAnd(Gia_Regular(pCare)) ) + { + Abc_Print( 1, "Enable is not an AND.\n" ); + return; + } + Abc_Print( 1, "DataSupp = %6d. DataCone = %6d. CareSupp = %6d. CareCone = %6d.", + Gia_ManSuppSize( p->pGia, &iData, 1 ), + Gia_ManConeSize( p->pGia, &iData, 1 ), + Gia_ManSuppSize( p->pGia, &iCare, 1 ), + Gia_ManConeSize( p->pGia, &iCare, 1 ) ); + Abc_Print( 1, "\n" ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSupExperiment( Gia_Man_t * pGia, Vec_Int_t * vPairs ) +{ + Gia_ManSup_t * p; + Gia_Obj_t * pData, * pCare; + int i; + p = Gia_ManSupStart( 16 ); + p->pGia = pGia; + assert( Vec_IntSize(vPairs) % 2 == 0 ); + for ( i = 0; i < Vec_IntSize(vPairs)/2; i++ ) + { + Abc_Print( 1, "%6d : ", i ); + pData = Gia_ManPo( pGia, Vec_IntEntry(vPairs, 2*i+0) ); + pCare = Gia_ManPo( pGia, Vec_IntEntry(vPairs, 2*i+1) ); + Gia_ManSupExperimentOne( p, Gia_ObjChild0(pData), Gia_ObjChild0(pCare) ); + } + Gia_ManSupStop( p ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaSwitch.c b/src/aig/gia/giaSwitch.c index 5dac1fbc..bc2f0f67 100644 --- a/src/aig/gia/giaSwitch.c +++ b/src/aig/gia/giaSwitch.c @@ -19,6 +19,10 @@ ***********************************************************************/ #include "giaAig.h" +#include "main.h" + +ABC_NAMESPACE_IMPL_START + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// @@ -597,6 +601,13 @@ Vec_Int_t * Gia_ManSwiSimulate( Gia_Man_t * pAig, Gia_ParSwi_t * pPars ) { Gia_ManForEachObj( pAig, pObj, i ) pSwitching[i] = Gia_ManSwiComputeProbOne( p->pData1[i], pPars->nWords*(pPars->nIters-pPars->nPref) ); + Gia_ManForEachCo( pAig, pObj, i ) + { + if ( Gia_ObjFaninC0(pObj) ) + pSwitching[Gia_ObjId(pAig,pObj)] = (float)1.0-pSwitching[Gia_ObjId(pAig,Gia_ObjFanin0(pObj))]; + else + pSwitching[Gia_ObjId(pAig,pObj)] = pSwitching[Gia_ObjId(pAig,Gia_ObjFanin0(pObj))]; + } } else if ( pPars->fProbTrans ) { @@ -608,6 +619,27 @@ Vec_Int_t * Gia_ManSwiSimulate( Gia_Man_t * pAig, Gia_ParSwi_t * pPars ) Gia_ManForEachObj( pAig, pObj, i ) pSwitching[i] = Gia_ManSwiComputeSwitching( p->pData1[i], pPars->nWords*(pPars->nIters-pPars->nPref) ); } +/* + printf( "PI: " ); + Gia_ManForEachPi( pAig, pObj, i ) + printf( "%d=%d (%f) ", i, p->pData1[Gia_ObjId(pAig,pObj)], pSwitching[Gia_ObjId(pAig,pObj)] ); + printf( "\n" ); + + printf( "LO: " ); + Gia_ManForEachRo( pAig, pObj, i ) + printf( "%d=%d (%f) ", i, p->pData1[Gia_ObjId(pAig,pObj)], pSwitching[Gia_ObjId(pAig,pObj)] ); + printf( "\n" ); + + printf( "PO: " ); + Gia_ManForEachPo( pAig, pObj, i ) + printf( "%d=%d (%f) ", i, p->pData1[Gia_ObjId(pAig,pObj)], pSwitching[Gia_ObjId(pAig,pObj)] ); + printf( "\n" ); + + printf( "LI: " ); + Gia_ManForEachRi( pAig, pObj, i ) + printf( "%d=%d (%f) ", i, p->pData1[Gia_ObjId(pAig,pObj)], pSwitching[Gia_ObjId(pAig,pObj)] ); + printf( "\n" ); +*/ Gia_ManSwiDelete( p ); return vSwitching; @@ -625,7 +657,6 @@ Vec_Int_t * Gia_ManSwiSimulate( Gia_Man_t * pAig, Gia_ParSwi_t * pPars ) ***********************************************************************/ Vec_Int_t * Saig_ManComputeSwitchProbs( Aig_Man_t * pAig, int nFrames, int nPref, int fProbOne ) { - extern char * Abc_FrameReadFlag( char * pFlag ); Gia_ParSwi_t Pars, * pPars = &Pars; Vec_Int_t * vSwitching, * vResult; Gia_Man_t * p; @@ -658,7 +689,11 @@ Vec_Int_t * Saig_ManComputeSwitchProbs( Aig_Man_t * pAig, int nFrames, int nPref // transfer the computed result to the original AIG vResult = Vec_IntStart( Aig_ManObjNumMax(pAig) ); Aig_ManForEachObj( pAig, pObj, i ) + { +// if ( Aig_ObjIsPo(pObj) ) +// printf( "%d=%f\n", i, Aig_Int2Float( Vec_IntEntry(vSwitching, Gia_Lit2Var(pObj->iData)) ) ); Vec_IntWriteEntry( vResult, i, Vec_IntEntry(vSwitching, Gia_Lit2Var(pObj->iData)) ); + } // delete intermediate results Vec_IntFree( vSwitching ); Gia_ManStop( p ); @@ -757,3 +792,5 @@ float Gia_ManComputeSwitching( Gia_Man_t * p, int nFrames, int nPref, int fProbO //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaTsim.c b/src/aig/gia/giaTsim.c index a4cdf88a..e829ff5b 100644 --- a/src/aig/gia/giaTsim.c +++ b/src/aig/gia/giaTsim.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -111,7 +114,7 @@ void Gia_ManTerStatesFree( Vec_Ptr_t * vStates ) { unsigned * pTemp; int i; - Vec_PtrForEachEntry( vStates, pTemp, i ) + Vec_PtrForEachEntry( unsigned *, vStates, pTemp, i ) ABC_FREE( pTemp ); Vec_PtrFree( vStates ); } @@ -505,12 +508,12 @@ void Gia_ManTerStatePrint( unsigned * pState, int nRegs, int iNum ) ***********************************************************************/ void Gia_ManTerAnalyze2( Vec_Ptr_t * vStates, int nRegs ) { - unsigned * pTemp, * pStates = Vec_PtrPop( vStates ); + unsigned * pTemp, * pStates = (unsigned *)Vec_PtrPop( vStates ); int i, w, nZeros, nConsts, nStateWords; // detect constant zero registers nStateWords = Gia_BitWordNum( 2*nRegs ); memset( pStates, 0, sizeof(int) * nStateWords ); - Vec_PtrForEachEntry( vStates, pTemp, i ) + Vec_PtrForEachEntry( unsigned *, vStates, pTemp, i ) for ( w = 0; w < nStateWords; w++ ) pStates[w] |= pTemp[w]; // count the number of zeros @@ -521,7 +524,7 @@ void Gia_ManTerAnalyze2( Vec_Ptr_t * vStates, int nRegs ) printf( "Found %d constant registers.\n", nZeros ); // detect non-ternary registers memset( pStates, 0, sizeof(int) * nStateWords ); - Vec_PtrForEachEntry( vStates, pTemp, i ) + Vec_PtrForEachEntry( unsigned *, vStates, pTemp, i ) for ( w = 0; w < nStateWords; w++ ) pStates[w] |= (~(pTemp[w] ^ (pTemp[w] >> 1)) & 0x55555555); // count the nonternary registers @@ -585,7 +588,7 @@ Vec_Ptr_t * Gia_ManTerTranspose( Gia_ManTer_t * p ) continue; pFlop = Gia_ManTerStateAlloc( nFlopWords ); Vec_PtrPush( vFlops, pFlop ); - Vec_PtrForEachEntry( p->vStates, pState, k ) + Vec_PtrForEachEntry( unsigned *, p->vStates, pState, k ) Gia_ManTerSimInfoSet( pFlop, k, Gia_ManTerSimInfoGet(pState, i) ); //Gia_ManTerStatePrint( pFlop, Vec_PtrSize(p->vStates), i ); } @@ -607,8 +610,8 @@ int Gia_ManFindEqualFlop( Vec_Ptr_t * vFlops, int iFlop, int nFlopWords ) { unsigned * pFlop, * pTemp; int i; - pFlop = Vec_PtrEntry( vFlops, iFlop ); - Vec_PtrForEachEntryStop( vFlops, pTemp, i, iFlop ) + pFlop = (unsigned *)Vec_PtrEntry( vFlops, iFlop ); + Vec_PtrForEachEntryStop( unsigned *, vFlops, pTemp, i, iFlop ) if ( !memcmp( pTemp, pFlop, sizeof(unsigned) * nFlopWords ) ) return i; return -1; @@ -633,7 +636,7 @@ int * Gia_ManTerCreateMap( Gia_ManTer_t * p, int fVerbose ) int i, iRepr, nFlopWords, Counter0 = 0, CounterE = 0; nFlopWords = Gia_BitWordNum( 2*Vec_PtrSize(p->vStates) ); p->vFlops = Gia_ManTerTranspose( p ); - pCi2Lit = ABC_FALLOC( unsigned, Gia_ManCiNum(p->pAig) ); + pCi2Lit = ABC_FALLOC( int, Gia_ManCiNum(p->pAig) ); vMapKtoI = Vec_IntAlloc( 100 ); for ( i = 0; i < Gia_ManRegNum(p->pAig); i++ ) if ( p->pCount0[i] == Vec_PtrSize(p->vStates) ) @@ -678,8 +681,7 @@ Gia_ManTer_t * Gia_ManTerSimulate( Gia_Man_t * pAig, int fVerbose ) if ( 0 ) { printf( "Obj = %8d (%8d). F = %6d. ", - pAig->nObjs, Gia_ManCiNum(pAig) + Gia_ManAndNum(pAig), p->pAig->nFront, - 4.0*Gia_BitWordNum(2 * p->pAig->nFront)/(1<<20) ); + pAig->nObjs, Gia_ManCiNum(pAig) + Gia_ManAndNum(pAig), p->pAig->nFront ); printf( "AIG = %7.2f Mb. F-mem = %7.2f Mb. Other = %7.2f Mb. ", 12.0*Gia_ManObjNum(p->pAig)/(1<<20), 4.0*Gia_BitWordNum(2 * p->pAig->nFront)/(1<<20), @@ -754,3 +756,5 @@ Gia_Man_t * Gia_ManReduceConst( Gia_Man_t * pAig, int fVerbose ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c index 938c6363..002e766d 100644 --- a/src/aig/gia/giaUtil.c +++ b/src/aig/gia/giaUtil.c @@ -20,6 +20,9 @@ #include "gia.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -72,7 +75,7 @@ void Gia_ManRandomInfo( Vec_Ptr_t * vInfo, int iInputStart, int iWordStart, int { unsigned * pInfo; int i, w; - Vec_PtrForEachEntryStart( vInfo, pInfo, i, iInputStart ) + Vec_PtrForEachEntryStart( unsigned *, vInfo, pInfo, i, iInputStart ) for ( w = iWordStart; w < iWordStop; w++ ) pInfo[w] = Gia_ManRandom(0); } @@ -116,6 +119,30 @@ unsigned int Gia_PrimeCudd( unsigned int p ) /**Function************************************************************* + Synopsis [Returns the time stamp.] + + Description [The file should be closed.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Gia_TimeStamp() +{ + static char Buffer[100]; + char * TimeStamp; + time_t ltime; + // get the current time + time( <ime ); + TimeStamp = asctime( localtime( <ime ) ); + TimeStamp[ strlen(TimeStamp) - 1 ] = 0; + strcpy( Buffer, TimeStamp ); + return Buffer; +} + +/**Function************************************************************* + Synopsis [Returns the composite name of the file.] Description [] @@ -140,6 +167,34 @@ char * Gia_FileNameGenericAppend( char * pBase, char * pSuffix ) /**Function************************************************************* + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManIncrementTravId( Gia_Man_t * p ) +{ + if ( p->pTravIds == NULL ) + { + p->nTravIdsAlloc = Gia_ManObjNum(p) + 100; + p->pTravIds = ABC_CALLOC( int, p->nTravIdsAlloc ); + p->nTravIds = 0; + } + while ( p->nTravIdsAlloc < Gia_ManObjNum(p) ) + { + p->nTravIdsAlloc *= 2; + p->pTravIds = ABC_REALLOC( int, p->pTravIds, p->nTravIdsAlloc ); + memset( p->pTravIds + p->nTravIdsAlloc/2, 0, sizeof(int) * p->nTravIdsAlloc/2 ); + } + p->nTravIds++; +} + +/**Function************************************************************* + Synopsis [Sets phases of the internal nodes.] Description [] @@ -290,6 +345,28 @@ void Gia_ManFillValue( Gia_Man_t * p ) /**Function************************************************************* + Synopsis [Sets the phase of one object.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ObjSetPhase( Gia_Obj_t * pObj ) +{ + if ( Gia_ObjIsAnd(pObj) ) + pObj->fPhase = (Gia_ObjPhase(Gia_ObjFanin0(pObj)) ^ Gia_ObjFaninC0(pObj)) & + (Gia_ObjPhase(Gia_ObjFanin1(pObj)) ^ Gia_ObjFaninC1(pObj)); + else if ( Gia_ObjIsCo(pObj) ) + pObj->fPhase = (Gia_ObjPhase(Gia_ObjFanin0(pObj)) ^ Gia_ObjFaninC0(pObj)); + else + pObj->fPhase = 0; +} + +/**Function************************************************************* + Synopsis [Sets phases of the internal nodes.] Description [] @@ -304,15 +381,29 @@ void Gia_ManSetPhase( Gia_Man_t * p ) Gia_Obj_t * pObj; int i; Gia_ManForEachObj( p, pObj, i ) - { - if ( Gia_ObjIsAnd(pObj) ) - pObj->fPhase = (Gia_ObjPhase(Gia_ObjFanin0(pObj)) ^ Gia_ObjFaninC0(pObj)) & - (Gia_ObjPhase(Gia_ObjFanin1(pObj)) ^ Gia_ObjFaninC1(pObj)); - else if ( Gia_ObjIsCo(pObj) ) - pObj->fPhase = (Gia_ObjPhase(Gia_ObjFanin0(pObj)) ^ Gia_ObjFaninC0(pObj)); - else - pObj->fPhase = 0; - } + Gia_ObjSetPhase( pObj ); +} + +/**Function************************************************************* + + Synopsis [Sets phases of the internal nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSetPhase1( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i; + Gia_ManForEachCi( p, pObj, i ) + pObj->fPhase = 1; + Gia_ManForEachObj( p, pObj, i ) + if ( !Gia_ObjIsCi(pObj) ) + Gia_ObjSetPhase( pObj ); } /**Function************************************************************* @@ -336,6 +427,41 @@ void Gia_ManCleanPhase( Gia_Man_t * p ) /**Function************************************************************* + Synopsis [Prepares copies for the model.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManCleanLevels( Gia_Man_t * p, int Size ) +{ + if ( p->vLevels == NULL ) + p->vLevels = Vec_IntAlloc( Size ); + Vec_IntFill( p->vLevels, Size, 0 ); +} +/**Function************************************************************* + + Synopsis [Prepares copies for the model.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManCleanTruth( Gia_Man_t * p ) +{ + if ( p->vTruths == NULL ) + p->vTruths = Vec_IntAlloc( Gia_ManObjNum(p) ); + Vec_IntFill( p->vTruths, Gia_ManObjNum(p), -1 ); +} + +/**Function************************************************************* + Synopsis [Assigns levels.] Description [] @@ -349,24 +475,18 @@ int Gia_ManLevelNum( Gia_Man_t * p ) { Gia_Obj_t * pObj; int i; - if ( p->pLevels ) - return p->nLevels; + Gia_ManCleanLevels( p, Gia_ManObjNum(p) ); p->nLevels = 0; - p->pLevels = ABC_ALLOC( int, p->nObjsAlloc ); Gia_ManForEachObj( p, pObj, i ) if ( Gia_ObjIsAnd(pObj) ) + Gia_ObjSetAndLevel( p, pObj ); + else if ( Gia_ObjIsCo(pObj) ) { - if ( p->pLevels[Gia_ObjFaninId0(pObj, i)] > p->pLevels[Gia_ObjFaninId1(pObj, i)] ) - p->pLevels[i] = 1 + p->pLevels[Gia_ObjFaninId0(pObj, i)]; - else - p->pLevels[i] = 1 + p->pLevels[Gia_ObjFaninId1(pObj, i)]; - if ( p->nLevels < p->pLevels[i] ) - p->nLevels = p->pLevels[i]; + Gia_ObjSetCoLevel( p, pObj ); + p->nLevels = ABC_MAX( p->nLevels, Gia_ObjLevel(p, pObj) ); } - else if ( Gia_ObjIsCo(pObj) ) - p->pLevels[i] = p->pLevels[Gia_ObjFaninId0(pObj, i)]; else - p->pLevels[i] = 0; + Gia_ObjSetLevel( p, pObj, 0 ); return p->nLevels; } @@ -718,18 +838,93 @@ Gia_Obj_t * Gia_ObjRecognizeMux( Gia_Obj_t * pNode, Gia_Obj_t ** ppNodeT, Gia_Ob SeeAlso [] ***********************************************************************/ -Gia_Cex_t * Gia_ManAllocCounterExample( int nRegs, int nRealPis, int nFrames ) +Abc_Cex_t * Gia_ManAllocCounterExample( int nRegs, int nRealPis, int nFrames ) { - Gia_Cex_t * pCex; + Abc_Cex_t * pCex; int nWords = Gia_BitWordNum( nRegs + nRealPis * nFrames ); - pCex = (Gia_Cex_t *)ABC_ALLOC( char, sizeof(Gia_Cex_t) + sizeof(unsigned) * nWords ); - memset( pCex, 0, sizeof(Gia_Cex_t) + sizeof(unsigned) * nWords ); + pCex = (Abc_Cex_t *)ABC_ALLOC( char, sizeof(Abc_Cex_t) + sizeof(unsigned) * nWords ); + memset( pCex, 0, sizeof(Abc_Cex_t) + sizeof(unsigned) * nWords ); pCex->nRegs = nRegs; pCex->nPis = nRealPis; pCex->nBits = nRegs + nRealPis * nFrames; return pCex; } + +/**Function************************************************************* + + Synopsis [Prints the counter-example.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManPrintCex( Abc_Cex_t * p ) +{ + int i, f, k; + for ( k = 0; k < p->nRegs; k++ ) + printf( "%d", Gia_InfoHasBit(p->pData, k) ); + printf( "\n" ); + for ( f = 0; f <= p->iFrame; f++ ) + { + for ( i = 0; i < p->nPis; i++ ) + printf( "%d", Gia_InfoHasBit(p->pData, k++) ); + printf( "\n" ); + } +} + +/**Function************************************************************* + + Synopsis [Derives the counter-example.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Cex_t * Gia_ManDeriveCexFromArray( Gia_Man_t * pAig, Vec_Int_t * vValues, int nSkip, int iFrame ) +{ + Abc_Cex_t * pCex; + int i; + pCex = Gia_ManAllocCounterExample( Gia_ManRegNum(pAig), Gia_ManPiNum(pAig), iFrame+1 ); + assert( Vec_IntSize(vValues) == nSkip + pCex->nBits ); + pCex->iPo = 0; + pCex->iFrame = iFrame; + for ( i = 0; i < pCex->nBits; i++ ) + if ( Vec_IntEntry(vValues, nSkip + i) ) + Gia_InfoSetBit( pCex->pData, i ); + return pCex; +} + +/**Function************************************************************* + + Synopsis [Allocates a counter-example.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Cex_t * Gia_ManCreateFromComb( int nRegs, int nRealPis, int iPo, int * pModel ) +{ + Abc_Cex_t * pCex; + int i; + pCex = Gia_ManAllocCounterExample( nRegs, nRealPis, 1 ); + pCex->iPo = iPo; + pCex->iFrame = 0; + for ( i = pCex->nRegs; i < pCex->nBits; i++ ) + if ( pModel[i-pCex->nRegs] ) + Gia_InfoSetBit( pCex->pData, i ); + return pCex; +} + /**Function************************************************************* Synopsis [Resimulates the counter-example.] @@ -741,10 +936,11 @@ Gia_Cex_t * Gia_ManAllocCounterExample( int nRegs, int nRealPis, int nFrames ) SeeAlso [] ***********************************************************************/ -int Gia_ManVerifyCounterExample( Gia_Man_t * pAig, Gia_Cex_t * p, int fDualOut ) +int Gia_ManVerifyCounterExample( Gia_Man_t * pAig, Abc_Cex_t * p, int fDualOut ) { Gia_Obj_t * pObj, * pObjRi, * pObjRo; int RetValue, i, k, iBit = 0; + Gia_ManCleanMark0(pAig); Gia_ManForEachRo( pAig, pObj, i ) pObj->fMark0 = Gia_InfoHasBit(p->pData, iBit++); for ( i = 0; i <= p->iFrame; i++ ) @@ -770,6 +966,73 @@ int Gia_ManVerifyCounterExample( Gia_Man_t * pAig, Gia_Cex_t * p, int fDualOut ) /**Function************************************************************* + Synopsis [Resimulates the counter-example.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManVerifyCounterExampleAllOuts( Gia_Man_t * pAig, Abc_Cex_t * p ) +{ + Gia_Obj_t * pObj, * pObjRi, * pObjRo; + int RetValue, i, k, iBit = 0; + Gia_ManCleanMark0(pAig); + Gia_ManForEachRo( pAig, pObj, i ) + pObj->fMark0 = Gia_InfoHasBit(p->pData, iBit++); + for ( i = 0; i <= p->iFrame; i++ ) + { + Gia_ManForEachPi( pAig, pObj, k ) + pObj->fMark0 = Gia_InfoHasBit(p->pData, iBit++); + Gia_ManForEachAnd( pAig, pObj, k ) + pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) & + (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj)); + Gia_ManForEachCo( pAig, pObj, k ) + pObj->fMark0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj); + Gia_ManForEachRiRo( pAig, pObjRi, pObjRo, k ) + pObjRo->fMark0 = pObjRi->fMark0; + } + assert( iBit == p->nBits ); + // remember the number of failed output + RetValue = -1; + Gia_ManForEachPo( pAig, pObj, i ) + if ( Gia_ManPo(pAig, i)->fMark0 ) + { + RetValue = i; + break; + } + Gia_ManCleanMark0(pAig); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [Make the trivial counter-example for the trivially asserted output.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Cex_t * Gia_ManDupCounterExample( Abc_Cex_t * p, int nRegsNew ) +{ + Abc_Cex_t * pCex; + int i; + pCex = Gia_ManAllocCounterExample( nRegsNew, p->nPis, p->iFrame+1 ); + pCex->iPo = p->iPo; + pCex->iFrame = p->iFrame; + for ( i = p->nRegs; i < p->nBits; i++ ) + if ( Gia_InfoHasBit(p->pData, i) ) + Gia_InfoSetBit( pCex->pData, pCex->nRegs + i - p->nRegs ); + return pCex; +} + +/**Function************************************************************* + Synopsis [Prints out the counter-example.] Description [] @@ -779,7 +1042,7 @@ int Gia_ManVerifyCounterExample( Gia_Man_t * pAig, Gia_Cex_t * p, int fDualOut ) SeeAlso [] ***********************************************************************/ -void Gia_ManPrintCounterExample( Gia_Cex_t * p ) +void Gia_ManPrintCounterExample( Abc_Cex_t * p ) { int i, f, k; printf( "Counter-example: iPo = %d iFrame = %d nRegs = %d nPis = %d nBits = %d\n", @@ -979,7 +1242,7 @@ int Gia_ManHasChoices( Gia_Man_t * p ) SeeAlso [] ***********************************************************************/ -int Gia_ManHasDandling( Gia_Man_t * p ) +int Gia_ManHasDangling( Gia_Man_t * p ) { Gia_Obj_t * pObj; int i, Counter = 0; @@ -1000,8 +1263,115 @@ int Gia_ManHasDandling( Gia_Man_t * p ) return Counter; } +/**Function************************************************************* + + Synopsis [Returns 1 if AIG has dangling nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_ManGetDangling( Gia_Man_t * p ) +{ + Vec_Int_t * vDangles; + Gia_Obj_t * pObj; + int i; + Gia_ManForEachObj( p, pObj, i ) + { + pObj->fMark0 = 0; + if ( Gia_ObjIsAnd(pObj) ) + { + Gia_ObjFanin0(pObj)->fMark0 = 1; + Gia_ObjFanin1(pObj)->fMark0 = 1; + } + else if ( Gia_ObjIsCo(pObj) ) + Gia_ObjFanin0(pObj)->fMark0 = 1; + } + vDangles = Vec_IntAlloc( 100 ); + Gia_ManForEachAnd( p, pObj, i ) + if ( !pObj->fMark0 ) + Vec_IntPush( vDangles, i ); + Gia_ManCleanMark0( p ); + return vDangles; +} +/**Function************************************************************* + + Synopsis [Verbose printing of the AIG node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ObjPrint( Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + if ( pObj == NULL ) + { + printf( "Object is NULL." ); + return; + } + if ( Gia_IsComplement(pObj) ) + { + printf( "Compl " ); + pObj = Gia_Not(pObj); + } + assert( !Gia_IsComplement(pObj) ); + printf( "Node %4d : ", Gia_ObjId(p, pObj) ); + if ( Gia_ObjIsConst0(pObj) ) + printf( "constant 0" ); + else if ( Gia_ObjIsPi(p, pObj) ) + printf( "PI" ); + else if ( Gia_ObjIsPo(p, pObj) ) + printf( "PO( %4d%s )", Gia_ObjFaninId0p(p, pObj), (Gia_ObjFaninC0(pObj)? "\'" : " ") ); + else if ( Gia_ObjIsCi(pObj) ) + printf( "RI" ); + else if ( Gia_ObjIsCo(pObj) ) + printf( "RO( %4d%s )", Gia_ObjFaninId0p(p, pObj), (Gia_ObjFaninC0(pObj)? "\'" : " ") ); +// else if ( Gia_ObjIsBuf(pObj) ) +// printf( "BUF( %d%s )", Gia_ObjFaninId0p(p, pObj), (Gia_ObjFaninC0(pObj)? "\'" : " ") ); + else + printf( "AND( %4d%s, %4d%s )", + Gia_ObjFaninId0p(p, pObj), (Gia_ObjFaninC0(pObj)? "\'" : " "), + Gia_ObjFaninId1p(p, pObj), (Gia_ObjFaninC1(pObj)? "\'" : " ") ); + if ( p->pRefs ) + printf( " (refs = %3d)", Gia_ObjRefs(p, pObj) ); + printf( "\n" ); +/* + if ( p->pRefs ) + { + Gia_Obj_t * pFanout; + int i; + int iFan = -1; // Suppress "might be used uninitialized" + printf( "\nFanouts:\n" ); + Gia_ObjForEachFanout( p, pObj, pFanout, iFan, i ) + { + printf( " " ); + printf( "Node %4d : ", Gia_ObjId(pFanout) ); + if ( Gia_ObjIsPo(pFanout) ) + printf( "PO( %4d%s )", Gia_ObjFanin0(pFanout)->Id, (Gia_ObjFaninC0(pFanout)? "\'" : " ") ); + else if ( Gia_ObjIsBuf(pFanout) ) + printf( "BUF( %d%s )", Gia_ObjFanin0(pFanout)->Id, (Gia_ObjFaninC0(pFanout)? "\'" : " ") ); + else + printf( "AND( %4d%s, %4d%s )", + Gia_ObjFanin0(pFanout)->Id, (Gia_ObjFaninC0(pFanout)? "\'" : " "), + Gia_ObjFanin1(pFanout)->Id, (Gia_ObjFaninC1(pFanout)? "\'" : " ") ); + printf( "\n" ); + } + return; + } +*/ +} + + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/module.make b/src/aig/gia/module.make index 0245b0f1..fc1c5c73 100644 --- a/src/aig/gia/module.make +++ b/src/aig/gia/module.make @@ -2,6 +2,7 @@ SRC += src/aig/gia/gia.c \ src/aig/gia/giaAbs.c \ src/aig/gia/giaAig.c \ src/aig/gia/giaAiger.c \ + src/aig/gia/giaBidec.c \ src/aig/gia/giaCof.c \ src/aig/gia/giaCSatOld.c \ src/aig/gia/giaCSat.c \ @@ -19,13 +20,18 @@ SRC += src/aig/gia/gia.c \ src/aig/gia/giaFront.c \ src/aig/gia/giaGlitch.c \ src/aig/gia/giaHash.c \ + src/aig/gia/giaIf.c \ src/aig/gia/giaMan.c \ - src/aig/gia/giaMap.c \ + src/aig/gia/giaMem.c \ src/aig/gia/giaPat.c \ + src/aig/gia/giaReparam.c \ src/aig/gia/giaRetime.c \ src/aig/gia/giaScl.c \ + src/aig/gia/giaShrink.c \ src/aig/gia/giaSim.c \ src/aig/gia/giaSort.c \ + src/aig/gia/giaSpeedup.c \ + src/aig/gia/giaSupMin.c \ src/aig/gia/giaSwitch.c \ src/aig/gia/giaTsim.c \ src/aig/gia/giaUtil.c diff --git a/src/aig/hop/cudd2.c b/src/aig/hop/cudd2.c index 11842c39..3ad44e4c 100644 --- a/src/aig/hop/cudd2.c +++ b/src/aig/hop/cudd2.c @@ -21,6 +21,9 @@ #include "hop.h" #include "st.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -353,3 +356,5 @@ void Cudd2_bddEqual( void * pCudd, void * pArg0, void * pArg1, int Result ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/hop/cudd2.h b/src/aig/hop/cudd2.h index 27359b3f..2382b22f 100644 --- a/src/aig/hop/cudd2.h +++ b/src/aig/hop/cudd2.h @@ -21,6 +21,7 @@ #ifndef __CUDD2_H__ #define __CUDD2_H__ + // HA: Added for printing messages #ifndef MSG #define MSG(msg) (printf("%s = \n",(msg))); @@ -34,9 +35,10 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -70,9 +72,11 @@ extern void Cudd2_bddCompose( void * pCudd, void * pArg0, void * pArg1, int v, v extern void Cudd2_bddLeq ( void * pCudd, void * pArg0, void * pArg1, int Result ); extern void Cudd2_bddEqual ( void * pCudd, void * pArg0, void * pArg1, int Result ); -#ifdef __cplusplus -} -#endif + + +ABC_NAMESPACE_HEADER_END + + #endif diff --git a/src/aig/hop/hop.h b/src/aig/hop/hop.h index 15641250..a634f136 100644 --- a/src/aig/hop/hop.h +++ b/src/aig/hop/hop.h @@ -21,6 +21,7 @@ #ifndef __HOP_H__ #define __HOP_H__ + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -37,9 +38,10 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -102,7 +104,7 @@ struct Hop_Man_t_ // memory management Vec_Ptr_t * vChunks; // allocated memory pieces Vec_Ptr_t * vPages; // memory pages used by nodes - Hop_Obj_t * pListFree; // the list of ABC_FREE nodes + Hop_Obj_t * pListFree; // the list of free nodes // timing statistics int time1; int time2; @@ -111,14 +113,15 @@ struct Hop_Man_t_ //////////////////////////////////////////////////////////////////////// /// MACRO DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +extern void Hop_ManAddMemory( Hop_Man_t * p ); static inline int Hop_BitWordNum( int nBits ) { return (nBits>>5) + ((nBits&31) > 0); } static inline int Hop_TruthWordNum( int nVars ) { return nVars <= 5 ? 1 : (1 << (nVars - 5)); } static inline int Hop_InfoHasBit( unsigned * p, int i ) { return (p[(i)>>5] & (1<<((i) & 31))) > 0; } static inline void Hop_InfoSetBit( unsigned * p, int i ) { p[(i)>>5] |= (1<<((i) & 31)); } static inline void Hop_InfoXorBit( unsigned * p, int i ) { p[(i)>>5] ^= (1<<((i) & 31)); } -static inline int Hop_Base2Log( unsigned n ) { int r; assert( n >= 0 ); if ( n < 2 ) return n; for ( r = 0, n--; n; n >>= 1, r++ ); return r; } -static inline int Hop_Base10Log( unsigned n ) { int r; assert( n >= 0 ); if ( n < 2 ) return n; for ( r = 0, n--; n; n /= 10, r++ ); return r; } +static inline int Hop_Base2Log( unsigned n ) { int r; if ( n < 2 ) return n; for ( r = 0, n--; n; n >>= 1, r++ ); return r; } +static inline int Hop_Base10Log( unsigned n ) { int r; if ( n < 2 ) return n; for ( r = 0, n--; n; n /= 10, r++ ); return r; } static inline Hop_Obj_t * Hop_Regular( Hop_Obj_t * p ) { return (Hop_Obj_t *)((ABC_PTRUINT_T)(p) & ~01); } static inline Hop_Obj_t * Hop_Not( Hop_Obj_t * p ) { return (Hop_Obj_t *)((ABC_PTRUINT_T)(p) ^ 01); } @@ -224,7 +227,6 @@ static inline Hop_Obj_t * Hop_ObjCreateGhost( Hop_Man_t * p, Hop_Obj_t * p0, Ho // internal memory manager static inline Hop_Obj_t * Hop_ManFetchMemory( Hop_Man_t * p ) { - extern void Hop_ManAddMemory( Hop_Man_t * p ); Hop_Obj_t * pTemp; if ( p->pListFree == NULL ) Hop_ManAddMemory( p ); @@ -253,10 +255,10 @@ static inline void Hop_ManRecycleMemory( Hop_Man_t * p, Hop_Obj_t * pEntry ) // iterator over the primary inputs #define Hop_ManForEachPi( p, pObj, i ) \ - Vec_PtrForEachEntry( p->vPis, pObj, i ) + Vec_PtrForEachEntry( Hop_Obj_t *, p->vPis, pObj, i ) // iterator over the primary outputs #define Hop_ManForEachPo( p, pObj, i ) \ - Vec_PtrForEachEntry( p->vPos, pObj, i ) + Vec_PtrForEachEntry( Hop_Obj_t *, p->vPos, pObj, i ) // iterator over all objects, including those currently not used #define Hop_ManForEachNode( p, pObj, i ) \ for ( i = 0; i < p->nTableSize; i++ ) \ @@ -334,9 +336,11 @@ extern void Hop_ObjPrintVerbose( Hop_Obj_t * pObj, int fHaig ); extern void Hop_ManPrintVerbose( Hop_Man_t * p, int fHaig ); extern void Hop_ManDumpBlif( Hop_Man_t * p, char * pFileName ); -#ifdef __cplusplus -} -#endif + + +ABC_NAMESPACE_HEADER_END + + #endif diff --git a/src/aig/hop/hopBalance.c b/src/aig/hop/hopBalance.c index 4bc15bb7..9240ffa9 100644 --- a/src/aig/hop/hopBalance.c +++ b/src/aig/hop/hopBalance.c @@ -20,6 +20,9 @@ #include "hop.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -96,27 +99,27 @@ Hop_Obj_t * Hop_NodeBalance_rec( Hop_Man_t * pNew, Hop_Obj_t * pObjOld, Vec_Vec_ assert( !Hop_IsComplement(pObjOld) ); // return if the result is known if ( pObjOld->pData ) - return pObjOld->pData; + return (Hop_Obj_t *)pObjOld->pData; assert( Hop_ObjIsNode(pObjOld) ); // get the implication supergate vSuper = Hop_NodeBalanceCone( pObjOld, vStore, Level ); // check if supergate contains two nodes in the opposite polarity if ( vSuper->nSize == 0 ) - return pObjOld->pData = Hop_ManConst0(pNew); + return (Hop_Obj_t *)(pObjOld->pData = Hop_ManConst0(pNew)); if ( Vec_PtrSize(vSuper) < 2 ) printf( "BUG!\n" ); // for each old node, derive the new well-balanced node for ( i = 0; i < Vec_PtrSize(vSuper); i++ ) { - pObjNew = Hop_NodeBalance_rec( pNew, Hop_Regular(vSuper->pArray[i]), vStore, Level + 1, fUpdateLevel ); - vSuper->pArray[i] = Hop_NotCond( pObjNew, Hop_IsComplement(vSuper->pArray[i]) ); + pObjNew = Hop_NodeBalance_rec( pNew, Hop_Regular((Hop_Obj_t *)vSuper->pArray[i]), vStore, Level + 1, fUpdateLevel ); + vSuper->pArray[i] = Hop_NotCond( pObjNew, Hop_IsComplement((Hop_Obj_t *)vSuper->pArray[i]) ); } // build the supergate pObjNew = Hop_NodeBalanceBuildSuper( pNew, vSuper, Hop_ObjType(pObjOld), fUpdateLevel ); // make sure the balanced node is not assigned // assert( pObjOld->Level >= Hop_Regular(pObjNew)->Level ); assert( pObjOld->pData == NULL ); - return pObjOld->pData = pObjNew; + return (Hop_Obj_t *)(pObjOld->pData = pObjNew); } /**Function************************************************************* @@ -185,13 +188,13 @@ Vec_Ptr_t * Hop_NodeBalanceCone( Hop_Obj_t * pObj, Vec_Vec_t * vStore, int Level if ( Vec_VecSize( vStore ) <= Level ) Vec_VecPush( vStore, Level, 0 ); // get the temporary array of nodes - vNodes = Vec_VecEntry( vStore, Level ); + vNodes = (Vec_Ptr_t *)Vec_VecEntry( vStore, Level ); Vec_PtrClear( vNodes ); // collect the nodes in the implication supergate RetValue = Hop_NodeBalanceCone_rec( pObj, pObj, vNodes ); assert( vNodes->nSize > 1 ); // unmark the visited nodes - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Hop_Obj_t *, vNodes, pObj, i ) Hop_Regular(pObj)->fMarkB = 0; // if we found the node and its complement in the same implication supergate, // return empty set of nodes (meaning that we should use constant-0 node) @@ -238,7 +241,7 @@ Hop_Obj_t * Hop_NodeBalanceBuildSuper( Hop_Man_t * p, Vec_Ptr_t * vSuper, Hop_Ty int LeftBound; assert( vSuper->nSize > 1 ); // sort the new nodes by level in the decreasing order - Vec_PtrSort( vSuper, Hop_NodeCompareLevelsDecrease ); + Vec_PtrSort( vSuper, (int (*)(void))Hop_NodeCompareLevelsDecrease ); // balance the nodes while ( vSuper->nSize > 1 ) { @@ -247,11 +250,11 @@ Hop_Obj_t * Hop_NodeBalanceBuildSuper( Hop_Man_t * p, Vec_Ptr_t * vSuper, Hop_Ty // find the node that can be shared (if no such node, randomize choice) Hop_NodeBalancePermute( p, vSuper, LeftBound, Type == AIG_EXOR ); // pull out the last two nodes - pObj1 = Vec_PtrPop(vSuper); - pObj2 = Vec_PtrPop(vSuper); + pObj1 = (Hop_Obj_t *)Vec_PtrPop(vSuper); + pObj2 = (Hop_Obj_t *)Vec_PtrPop(vSuper); Hop_NodeBalancePushUniqueOrderByLevel( vSuper, Hop_Oper(p, pObj1, pObj2, Type) ); } - return Vec_PtrEntry(vSuper, 0); + return (Hop_Obj_t *)Vec_PtrEntry(vSuper, 0); } /**Function************************************************************* @@ -278,19 +281,19 @@ int Hop_NodeBalanceFindLeft( Vec_Ptr_t * vSuper ) return 0; // set the pointer to the one before the last Current = Vec_PtrSize(vSuper) - 2; - pObjRight = Vec_PtrEntry( vSuper, Current ); + pObjRight = (Hop_Obj_t *)Vec_PtrEntry( vSuper, Current ); // go through the nodes to the left of this one for ( Current--; Current >= 0; Current-- ) { // get the next node on the left - pObjLeft = Vec_PtrEntry( vSuper, Current ); + pObjLeft = (Hop_Obj_t *)Vec_PtrEntry( vSuper, Current ); // if the level of this node is different, quit the loop if ( Hop_ObjLevel(Hop_Regular(pObjLeft)) != Hop_ObjLevel(Hop_Regular(pObjRight)) ) break; } Current++; // get the node, for which the equality holds - pObjLeft = Vec_PtrEntry( vSuper, Current ); + pObjLeft = (Hop_Obj_t *)Vec_PtrEntry( vSuper, Current ); assert( Hop_ObjLevel(Hop_Regular(pObjLeft)) == Hop_ObjLevel(Hop_Regular(pObjRight)) ); return Current; } @@ -317,14 +320,14 @@ void Hop_NodeBalancePermute( Hop_Man_t * p, Vec_Ptr_t * vSuper, int LeftBound, i if ( LeftBound == RightBound ) return; // get the two last nodes - pObj1 = Vec_PtrEntry( vSuper, RightBound + 1 ); - pObj2 = Vec_PtrEntry( vSuper, RightBound ); + pObj1 = (Hop_Obj_t *)Vec_PtrEntry( vSuper, RightBound + 1 ); + pObj2 = (Hop_Obj_t *)Vec_PtrEntry( vSuper, RightBound ); if ( Hop_Regular(pObj1) == p->pConst1 || Hop_Regular(pObj2) == p->pConst1 ) return; // find the first node that can be shared for ( i = RightBound; i >= LeftBound; i-- ) { - pObj3 = Vec_PtrEntry( vSuper, i ); + pObj3 = (Hop_Obj_t *)Vec_PtrEntry( vSuper, i ); if ( Hop_Regular(pObj3) == p->pConst1 ) { Vec_PtrWriteEntry( vSuper, i, pObj2 ); @@ -374,8 +377,8 @@ void Hop_NodeBalancePushUniqueOrderByLevel( Vec_Ptr_t * vStore, Hop_Obj_t * pObj // find the p of the node for ( i = vStore->nSize-1; i > 0; i-- ) { - pObj1 = vStore->pArray[i ]; - pObj2 = vStore->pArray[i-1]; + pObj1 = (Hop_Obj_t *)vStore->pArray[i ]; + pObj2 = (Hop_Obj_t *)vStore->pArray[i-1]; if ( Hop_ObjLevel(Hop_Regular(pObj1)) <= Hop_ObjLevel(Hop_Regular(pObj2)) ) break; vStore->pArray[i ] = pObj2; @@ -389,3 +392,5 @@ void Hop_NodeBalancePushUniqueOrderByLevel( Vec_Ptr_t * vStore, Hop_Obj_t * pObj //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/hop/hopCheck.c b/src/aig/hop/hopCheck.c index 9120906f..174c5523 100644 --- a/src/aig/hop/hopCheck.c +++ b/src/aig/hop/hopCheck.c @@ -20,6 +20,9 @@ #include "hop.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -108,3 +111,5 @@ int Hop_ManCheck( Hop_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/hop/hopDfs.c b/src/aig/hop/hopDfs.c index 27fb1aa6..be1e6c0b 100644 --- a/src/aig/hop/hopDfs.c +++ b/src/aig/hop/hopDfs.c @@ -20,6 +20,9 @@ #include "hop.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -94,7 +97,7 @@ Vec_Ptr_t * Hop_ManDfsNode( Hop_Man_t * p, Hop_Obj_t * pNode ) assert( !Hop_IsComplement(pNode) ); vNodes = Vec_PtrAlloc( 16 ); Hop_ManDfs_rec( pNode, vNodes ); - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Hop_Obj_t *, vNodes, pObj, i ) Hop_ObjClearMarkA(pObj); return vNodes; } @@ -121,7 +124,7 @@ int Hop_ManCountLevels( Hop_Man_t * p ) pObj->pData = NULL; // compute levels in a DFS order vNodes = Hop_ManDfs( p ); - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Hop_Obj_t *, vNodes, pObj, i ) { Level0 = (int)(ABC_PTRUINT_T)Hop_ObjFanin0(pObj)->pData; Level1 = (int)(ABC_PTRUINT_T)Hop_ObjFanin1(pObj)->pData; @@ -335,7 +338,7 @@ Hop_Obj_t * Hop_Transfer( Hop_Man_t * pSour, Hop_Man_t * pDest, Hop_Obj_t * pRoo Hop_Transfer_rec( pDest, Hop_Regular(pRoot) ); // clear the markings Hop_ConeUnmark_rec( Hop_Regular(pRoot) ); - return Hop_NotCond( Hop_Regular(pRoot)->pData, Hop_IsComplement(pRoot) ); + return Hop_NotCond( (Hop_Obj_t *)Hop_Regular(pRoot)->pData, Hop_IsComplement(pRoot) ); } /**Function************************************************************* @@ -389,7 +392,7 @@ Hop_Obj_t * Hop_Compose( Hop_Man_t * p, Hop_Obj_t * pRoot, Hop_Obj_t * pFunc, in Hop_Compose_rec( p, Hop_Regular(pRoot), pFunc, Hop_ManPi(p, iVar) ); // clear the markings Hop_ConeUnmark_rec( Hop_Regular(pRoot) ); - return Hop_NotCond( Hop_Regular(pRoot)->pData, Hop_IsComplement(pRoot) ); + return Hop_NotCond( (Hop_Obj_t *)Hop_Regular(pRoot)->pData, Hop_IsComplement(pRoot) ); } /**Function************************************************************* @@ -457,7 +460,7 @@ Hop_Obj_t * Hop_Remap( Hop_Man_t * p, Hop_Obj_t * pRoot, unsigned uSupp, int nVa Hop_Remap_rec( p, Hop_Regular(pRoot) ); // clear the markings Hop_ConeUnmark_rec( Hop_Regular(pRoot) ); - return Hop_NotCond( Hop_Regular(pRoot)->pData, Hop_IsComplement(pRoot) ); + return Hop_NotCond( (Hop_Obj_t *)Hop_Regular(pRoot)->pData, Hop_IsComplement(pRoot) ); } //////////////////////////////////////////////////////////////////////// @@ -465,3 +468,5 @@ Hop_Obj_t * Hop_Remap( Hop_Man_t * p, Hop_Obj_t * pRoot, unsigned uSupp, int nVa //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/hop/hopMan.c b/src/aig/hop/hopMan.c index bf38a780..84d987bb 100644 --- a/src/aig/hop/hopMan.c +++ b/src/aig/hop/hopMan.c @@ -20,6 +20,9 @@ #include "hop.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -127,7 +130,7 @@ int Hop_ManCleanup( Hop_Man_t * p ) if ( Hop_ObjRefs(pNode) == 0 ) Vec_PtrPush( vObjs, pNode ); // recursively remove dangling nodes - Vec_PtrForEachEntry( vObjs, pNode, i ) + Vec_PtrForEachEntry( Hop_Obj_t *, vObjs, pNode, i ) Hop_ObjDelete_rec( p, pNode ); Vec_PtrFree( vObjs ); return nNodesOld - Hop_ManNodeNum(p); @@ -162,3 +165,5 @@ void Hop_ManPrintStats( Hop_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/hop/hopMem.c b/src/aig/hop/hopMem.c index c6d05865..79de3804 100644 --- a/src/aig/hop/hopMem.c +++ b/src/aig/hop/hopMem.c @@ -20,6 +20,9 @@ #include "hop.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -64,7 +67,7 @@ void Hop_ManStopMemory( Hop_Man_t * p ) { void * pMemory; int i; - Vec_PtrForEachEntry( p->vChunks, pMemory, i ) + Vec_PtrForEachEntry( void *, p->vChunks, pMemory, i ) ABC_FREE( pMemory ); Vec_PtrFree( p->vChunks ); Vec_PtrFree( p->vPages ); @@ -113,3 +116,5 @@ void Hop_ManAddMemory( Hop_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/hop/hopObj.c b/src/aig/hop/hopObj.c index f173248f..4451b3fa 100644 --- a/src/aig/hop/hopObj.c +++ b/src/aig/hop/hopObj.c @@ -20,6 +20,9 @@ #include "hop.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -240,7 +243,7 @@ Hop_Obj_t * Hop_ObjRepr( Hop_Obj_t * pObj ) assert( !Hop_IsComplement(pObj) ); if ( pObj->pData == NULL || pObj->pData == pObj ) return pObj; - return Hop_ObjRepr( pObj->pData ); + return Hop_ObjRepr( (Hop_Obj_t *)pObj->pData ); } /**Function************************************************************* @@ -270,3 +273,5 @@ void Hop_ObjCreateChoice( Hop_Obj_t * pOld, Hop_Obj_t * pNew ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/hop/hopOper.c b/src/aig/hop/hopOper.c index 0ecb8d61..2f5e7650 100644 --- a/src/aig/hop/hopOper.c +++ b/src/aig/hop/hopOper.c @@ -20,6 +20,9 @@ #include "hop.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -298,7 +301,7 @@ Hop_Obj_t * Hop_Miter( Hop_Man_t * p, Vec_Ptr_t * vPairs ) assert( vPairs->nSize % 2 == 0 ); // go through the cubes of the node's SOP for ( i = 0; i < vPairs->nSize; i += 2 ) - vPairs->pArray[i/2] = Hop_Not( Hop_Exor( p, vPairs->pArray[i], vPairs->pArray[i+1] ) ); + vPairs->pArray[i/2] = Hop_Not( Hop_Exor( p, (Hop_Obj_t *)vPairs->pArray[i], (Hop_Obj_t *)vPairs->pArray[i+1] ) ); vPairs->nSize = vPairs->nSize/2; return Hop_Not( Hop_Multi_rec( p, (Hop_Obj_t **)vPairs->pArray, vPairs->nSize, AIG_AND ) ); } @@ -371,3 +374,5 @@ Hop_Obj_t * Hop_CreateExor( Hop_Man_t * p, int nVars ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/hop/hopTable.c b/src/aig/hop/hopTable.c index cfc6add0..8148a125 100644 --- a/src/aig/hop/hopTable.c +++ b/src/aig/hop/hopTable.c @@ -20,6 +20,9 @@ #include "hop.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -260,3 +263,5 @@ unsigned int Cudd_PrimeAig( unsigned int p) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/hop/hopTruth.c b/src/aig/hop/hopTruth.c index 42ded3ed..0b674225 100644 --- a/src/aig/hop/hopTruth.c +++ b/src/aig/hop/hopTruth.c @@ -20,6 +20,9 @@ #include "hop.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -97,7 +100,7 @@ unsigned * Hop_ManConvertAigToTruth_rec2( Hop_Obj_t * pObj, Vec_Int_t * vTruth, int i; assert( !Hop_IsComplement(pObj) ); if ( !Hop_ObjIsNode(pObj) || !Hop_ObjIsMarkA(pObj) ) - return pObj->pData; + return (unsigned *)pObj->pData; // compute the truth tables of the fanins pTruth0 = Hop_ManConvertAigToTruth_rec2( Hop_ObjFanin0(pObj), vTruth, nWords ); pTruth1 = Hop_ManConvertAigToTruth_rec2( Hop_ObjFanin1(pObj), vTruth, nWords ); @@ -220,3 +223,5 @@ unsigned * Hop_ManConvertAigToTruth( Hop_Man_t * p, Hop_Obj_t * pRoot, int nVars //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/hop/hopUtil.c b/src/aig/hop/hopUtil.c index d541ab99..76ed7b17 100644 --- a/src/aig/hop/hopUtil.c +++ b/src/aig/hop/hopUtil.c @@ -20,6 +20,9 @@ #include "hop.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -338,10 +341,10 @@ void Hop_ObjPrintEqn( FILE * pFile, Hop_Obj_t * pObj, Vec_Vec_t * vLevels, int L } // AND case Vec_VecExpand( vLevels, Level ); - vSuper = Vec_VecEntry(vLevels, Level); + vSuper = (Vec_Ptr_t *)Vec_VecEntry(vLevels, Level); Hop_ObjCollectMulti( pObj, vSuper ); fprintf( pFile, "%s", (Level==0? "" : "(") ); - Vec_PtrForEachEntry( vSuper, pFanin, i ) + Vec_PtrForEachEntry( Hop_Obj_t *, vSuper, pFanin, i ) { Hop_ObjPrintEqn( pFile, Hop_NotCond(pFanin, fCompl), vLevels, Level+1 ); if ( i < Vec_PtrSize(vSuper) - 1 ) @@ -387,10 +390,10 @@ void Hop_ObjPrintVerilog( FILE * pFile, Hop_Obj_t * pObj, Vec_Vec_t * vLevels, i if ( Hop_ObjIsExor(pObj) ) { Vec_VecExpand( vLevels, Level ); - vSuper = Vec_VecEntry( vLevels, Level ); + vSuper = (Vec_Ptr_t *)Vec_VecEntry( vLevels, Level ); Hop_ObjCollectMulti( pObj, vSuper ); fprintf( pFile, "%s", (Level==0? "" : "(") ); - Vec_PtrForEachEntry( vSuper, pFanin, i ) + Vec_PtrForEachEntry( Hop_Obj_t *, vSuper, pFanin, i ) { Hop_ObjPrintVerilog( pFile, Hop_NotCond(pFanin, (fCompl && i==0)), vLevels, Level+1 ); if ( i < Vec_PtrSize(vSuper) - 1 ) @@ -425,10 +428,10 @@ void Hop_ObjPrintVerilog( FILE * pFile, Hop_Obj_t * pObj, Vec_Vec_t * vLevels, i } // AND case Vec_VecExpand( vLevels, Level ); - vSuper = Vec_VecEntry(vLevels, Level); + vSuper = (Vec_Ptr_t *)Vec_VecEntry(vLevels, Level); Hop_ObjCollectMulti( pObj, vSuper ); fprintf( pFile, "%s", (Level==0? "" : "(") ); - Vec_PtrForEachEntry( vSuper, pFanin, i ) + Vec_PtrForEachEntry( Hop_Obj_t *, vSuper, pFanin, i ) { Hop_ObjPrintVerilog( pFile, Hop_NotCond(pFanin, fCompl), vLevels, Level+1 ); if ( i < Vec_PtrSize(vSuper) - 1 ) @@ -486,7 +489,7 @@ void Hop_ManPrintVerbose( Hop_Man_t * p, int fHaig ) printf( " %p", pObj ); printf( "\n" ); vNodes = Hop_ManDfs( p ); - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Hop_Obj_t *, vNodes, pObj, i ) Hop_ObjPrintVerbose( pObj, fHaig ), printf( "\n" ); printf( "\n" ); } @@ -521,7 +524,7 @@ void Hop_ManDumpBlif( Hop_Man_t * p, char * pFileName ) pObj->pData = (void *)(ABC_PTRUINT_T)Counter++; Hop_ManForEachPo( p, pObj, i ) pObj->pData = (void *)(ABC_PTRUINT_T)Counter++; - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Hop_Obj_t *, vNodes, pObj, i ) pObj->pData = (void *)(ABC_PTRUINT_T)Counter++; nDigits = Hop_Base10Log( Counter ); // write the file @@ -540,7 +543,7 @@ void Hop_ManDumpBlif( Hop_Man_t * p, char * pFileName ) fprintf( pFile, " n%0*d", nDigits, (int)(ABC_PTRUINT_T)pObj->pData ); fprintf( pFile, "\n" ); // write nodes - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Hop_Obj_t *, vNodes, pObj, i ) { fprintf( pFile, ".names n%0*d n%0*d n%0*d\n", nDigits, (int)(ABC_PTRUINT_T)Hop_ObjFanin0(pObj)->pData, @@ -570,3 +573,5 @@ void Hop_ManDumpBlif( Hop_Man_t * p, char * pFileName ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/hop/hop_.c b/src/aig/hop/hop_.c index 658b8c4e..b2bd8c22 100644 --- a/src/aig/hop/hop_.c +++ b/src/aig/hop/hop_.c @@ -20,6 +20,9 @@ #include "hop.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -46,3 +49,5 @@ //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/int/int.h b/src/aig/int/int.h index 1487b9bf..907691ed 100644 --- a/src/aig/int/int.h +++ b/src/aig/int/int.h @@ -21,6 +21,7 @@ #ifndef __INT_H__ #define __INT_H__ + /* The interpolation algorithm implemented here was introduced in the paper: K. L. McMillan. Interpolation and SAT-based model checking. CAV’03, pp. 1-13. @@ -34,9 +35,10 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -48,6 +50,7 @@ struct Inter_ManParams_t_ { int nBTLimit; // limit on the number of conflicts int nFramesMax; // the max number timeframes to unroll + int nSecLimit; // time limit in seconds int nFramesK; // the number of timeframes to use in induction int fRewrite; // use additional rewriting to simplify timeframes int fTransLoop; // add transition into the init state under new PI var @@ -58,7 +61,9 @@ struct Inter_ManParams_t_ int fUseBias; // bias decisions to global variables int fUseBackward; // perform backward interpolation int fUseSeparate; // solve each output separately + int fDropSatOuts; // replace by 1 the solved outputs int fVerbose; // print verbose statistics + int iFrameMax; // the time frame reached }; //////////////////////////////////////////////////////////////////////// @@ -74,9 +79,11 @@ extern void Inter_ManSetDefaultParams( Inter_ManParams_t * p ); extern int Inter_ManPerformInterpolation( Aig_Man_t * pAig, Inter_ManParams_t * pPars, int * piFrame ); -#ifdef __cplusplus -} -#endif + + +ABC_NAMESPACE_HEADER_END + + #endif diff --git a/src/aig/int/intContain.c b/src/aig/int/intContain.c index 3c16629f..4cc8577e 100644 --- a/src/aig/int/intContain.c +++ b/src/aig/int/intContain.c @@ -21,6 +21,8 @@ #include "intInt.h" #include "fra.h" +ABC_NAMESPACE_IMPL_START + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -219,7 +221,7 @@ int Inter_ManCheckInductiveContainment( Aig_Man_t * pTrans, Aig_Man_t * pInter, // convert to CNF pCnf = Cnf_Derive( pFrames, 0 ); - pSat = Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); + pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); // Cnf_DataFree( pCnf ); // Aig_ManStop( pFrames ); @@ -241,9 +243,13 @@ int Inter_ManCheckInductiveContainment( Aig_Man_t * pTrans, Aig_Man_t * pInter, sat_solver_delete( pSat ); return status == l_False; } +ABC_NAMESPACE_IMPL_END #include "fra.h" +ABC_NAMESPACE_IMPL_START + + /**Function************************************************************* Synopsis [Check if cex satisfies uniqueness constraints.] @@ -326,3 +332,5 @@ int Inter_ManCheckUniqueness( Aig_Man_t * p, sat_solver * pSat, Cnf_Dat_t * pCnf //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/int/intCore.c b/src/aig/int/intCore.c index d1f89c07..c0df48fb 100644 --- a/src/aig/int/intCore.c +++ b/src/aig/int/intCore.c @@ -20,6 +20,9 @@ #include "intInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -44,6 +47,7 @@ void Inter_ManSetDefaultParams( Inter_ManParams_t * p ) memset( p, 0, sizeof(Inter_ManParams_t) ); p->nBTLimit = 10000; // limit on the number of conflicts p->nFramesMax = 40; // the max number timeframes to unroll + p->nSecLimit = 0; // time limit in seconds p->nFramesK = 1; // the number of timeframes to use in induction p->fRewrite = 0; // use additional rewriting to simplify timeframes p->fTransLoop = 1; // add transition into the init state under new PI var @@ -54,7 +58,9 @@ void Inter_ManSetDefaultParams( Inter_ManParams_t * p ) p->fUseBias = 0; // bias decisions to global variables p->fUseBackward = 0; // perform backward interpolation p->fUseSeparate = 0; // solve each output separately + p->fDropSatOuts = 0; // replace by 1 the solved outputs p->fVerbose = 0; // print verbose statistics + p->iFrameMax =-1; } /**Function************************************************************* @@ -77,7 +83,9 @@ int Inter_ManPerformInterpolation( Aig_Man_t * pAig, Inter_ManParams_t * pPars, // sanity checks assert( Saig_ManRegNum(pAig) > 0 ); assert( Saig_ManPiNum(pAig) > 0 ); - assert( Saig_ManPoNum(pAig) == 1 ); + assert( Saig_ManPoNum(pAig)-Saig_ManConstrNum(pAig) == 1 ); + if ( pPars->fVerbose && Saig_ManConstrNum(pAig) ) + printf( "Performing interpolation with %d constraints...\n", Saig_ManConstrNum(pAig) ); /* if ( Inter_ManCheckInitialState(pAig) ) { @@ -179,6 +187,8 @@ p->timeCnf += clock() - clk; i+1, i + 1 + p->nFrames, Aig_ManNodeNum(p->pInter), Aig_ManLevelNum(p->pInter), p->nConfCur ); ABC_PRT( "Time", clock() - clk ); } + // remember the number of timeframes completed + pPars->iFrameMax = i + 1 + p->nFrames; if ( RetValue == 0 ) // found a (spurious?) counter-example { if ( i == 0 ) // real counterexample @@ -187,7 +197,7 @@ p->timeCnf += clock() - clk; printf( "Found a real counterexample in frame %d.\n", p->nFrames ); p->timeTotal = clock() - clkTotal; *piFrame = p->nFrames; - pAig->pSeqModel = Inter_ManGetCounterExample( pAig, p->nFrames+1, pPars->fVerbose ); + pAig->pSeqModel = (Abc_Cex_t *)Inter_ManGetCounterExample( pAig, p->nFrames+1, pPars->fVerbose ); Inter_ManStop( p ); return 0; } @@ -211,6 +221,7 @@ clk = clock(); if ( p->pInterNew ) { p->pInterNew = Dar_ManRwsat( pAigTemp = p->pInterNew, 1, 0 ); +// p->pInterNew = Dar_ManRwsat( pAigTemp = p->pInterNew, 0, 0 ); Aig_ManStop( pAigTemp ); } p->timeRwr += clock() - clk; @@ -251,6 +262,13 @@ p->timeEqu += clock() - clk; Inter_ManStop( p ); return 1; } + if ( pPars->nSecLimit && ((float)pPars->nSecLimit <= (float)(clock()-clkTotal)/(float)(CLOCKS_PER_SEC)) ) + { + printf( "Reached timeout (%d seconds).\n", pPars->nSecLimit ); + p->timeTotal = clock() - clkTotal; + Inter_ManStop( p ); + return -1; + } // save interpolant and convert it into CNF if ( pPars->fTransLoop ) { @@ -286,3 +304,5 @@ p->timeCnf += clock() - clk; //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/int/intCtrex.c b/src/aig/int/intCtrex.c index ddb0bce6..28b1e293 100644 --- a/src/aig/int/intCtrex.c +++ b/src/aig/int/intCtrex.c @@ -21,6 +21,9 @@ #include "intInt.h" #include "ssw.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -92,7 +95,7 @@ Aig_Man_t * Inter_ManFramesBmc( Aig_Man_t * pAig, int nFrames ) void * Inter_ManGetCounterExample( Aig_Man_t * pAig, int nFrames, int fVerbose ) { int nConfLimit = 1000000; - Ssw_Cex_t * pCtrex = NULL; + Abc_Cex_t * pCtrex = NULL; Aig_Man_t * pFrames; sat_solver * pSat; Cnf_Dat_t * pCnf; @@ -107,7 +110,7 @@ void * Inter_ManGetCounterExample( Aig_Man_t * pAig, int nFrames, int fVerbose ) vCiIds = Cnf_DataCollectPiSatNums( pCnf, pFrames ); Aig_ManStop( pFrames ); // convert into SAT solver - pSat = Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); + pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); Cnf_DataFree( pCnf ); if ( pSat == NULL ) { @@ -160,3 +163,5 @@ void * Inter_ManGetCounterExample( Aig_Man_t * pAig, int nFrames, int fVerbose ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/int/intDup.c b/src/aig/int/intDup.c index 4c5b7ab6..800375a9 100644 --- a/src/aig/int/intDup.c +++ b/src/aig/int/intDup.c @@ -20,6 +20,9 @@ #include "intInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -83,12 +86,21 @@ Aig_Man_t * Inter_ManStartDuplicated( Aig_Man_t * p ) Aig_ManForEachPi( p, pObj, i ) pObj->pData = Aig_ObjCreatePi( pNew ); // set registers - pNew->nRegs = p->nRegs; pNew->nTruePis = p->nTruePis; - pNew->nTruePos = 0; + pNew->nTruePos = Saig_ManConstrNum(p); + pNew->nRegs = p->nRegs; // duplicate internal nodes Aig_ManForEachNode( p, pObj, i ) pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + + // create constraint outputs + Saig_ManForEachPo( p, pObj, i ) + { + if ( i < Saig_ManPoNum(p)-Saig_ManConstrNum(p) ) + continue; + Aig_ObjCreatePo( pNew, Aig_Not( Aig_ObjChild0Copy(pObj) ) ); + } + // create register inputs with MUXes Saig_ManForEachLi( p, pObj, i ) Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) ); @@ -130,10 +142,19 @@ Aig_Man_t * Inter_ManStartOneOutput( Aig_Man_t * p, int fAddFirstPo ) // set registers pNew->nRegs = fAddFirstPo? 0 : p->nRegs; pNew->nTruePis = fAddFirstPo? Aig_ManPiNum(p) + 1 : p->nTruePis + 1; - pNew->nTruePos = fAddFirstPo; + pNew->nTruePos = fAddFirstPo + Saig_ManConstrNum(p); // duplicate internal nodes Aig_ManForEachNode( p, pObj, i ) pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + + // create constraint outputs + Saig_ManForEachPo( p, pObj, i ) + { + if ( i < Saig_ManPoNum(p)-Saig_ManConstrNum(p) ) + continue; + Aig_ObjCreatePo( pNew, Aig_Not( Aig_ObjChild0Copy(pObj) ) ); + } + // add the PO if ( fAddFirstPo ) { @@ -145,7 +166,7 @@ Aig_Man_t * Inter_ManStartOneOutput( Aig_Man_t * p, int fAddFirstPo ) // create register inputs with MUXes Saig_ManForEachLiLo( p, pObjLi, pObjLo, i ) { - pObj = Aig_Mux( pNew, pCtrl, pObjLo->pData, Aig_ObjChild0Copy(pObjLi) ); + pObj = Aig_Mux( pNew, pCtrl, (Aig_Obj_t *)pObjLo->pData, Aig_ObjChild0Copy(pObjLi) ); // pObj = Aig_Mux( pNew, pCtrl, Aig_ManConst0(pNew), Aig_ObjChild0Copy(pObjLi) ); Aig_ObjCreatePo( pNew, pObj ); } @@ -159,3 +180,5 @@ Aig_Man_t * Inter_ManStartOneOutput( Aig_Man_t * p, int fAddFirstPo ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/int/intFrames.c b/src/aig/int/intFrames.c index 809cb06b..0fbab6cb 100644 --- a/src/aig/int/intFrames.c +++ b/src/aig/int/intFrames.c @@ -20,6 +20,9 @@ #include "intInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -47,7 +50,7 @@ Aig_Man_t * Inter_ManFramesInter( Aig_Man_t * pAig, int nFrames, int fAddRegOuts Aig_Obj_t * pObj, * pObjLi, * pObjLo; int i, f; assert( Saig_ManRegNum(pAig) > 0 ); - assert( Saig_ManPoNum(pAig) == 1 ); + assert( Saig_ManPoNum(pAig)-Saig_ManConstrNum(pAig) == 1 ); pFrames = Aig_ManStart( Aig_ManNodeNum(pAig) * nFrames ); // map the constant node Aig_ManConst1(pAig)->pData = Aig_ManConst1( pFrames ); @@ -71,6 +74,13 @@ Aig_Man_t * Inter_ManFramesInter( Aig_Man_t * pAig, int nFrames, int fAddRegOuts // add internal nodes of this frame Aig_ManForEachNode( pAig, pObj, i ) pObj->pData = Aig_And( pFrames, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + // add outputs for constraints + Saig_ManForEachPo( pAig, pObj, i ) + { + if ( i < Saig_ManPoNum(pAig)-Saig_ManConstrNum(pAig) ) + continue; + Aig_ObjCreatePo( pFrames, Aig_Not( Aig_ObjChild0Copy(pObj) ) ); + } if ( f == nFrames - 1 ) break; // save register inputs @@ -101,3 +111,5 @@ Aig_Man_t * Inter_ManFramesInter( Aig_Man_t * pAig, int nFrames, int fAddRegOuts //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/int/intInt.h b/src/aig/int/intInt.h index 2d571f09..72079a49 100644 --- a/src/aig/int/intInt.h +++ b/src/aig/int/intInt.h @@ -21,6 +21,7 @@ #ifndef __INT_INT_H__ #define __INT_INT_H__ + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -35,9 +36,10 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -118,9 +120,11 @@ extern int Inter_ManPerformOneStepM114p( Inter_Man_t * p, int fUsePudl extern int Inter_ManCheckInitialState( Aig_Man_t * p ); extern int Inter_ManCheckAllStates( Aig_Man_t * p ); -#ifdef __cplusplus -} -#endif + + +ABC_NAMESPACE_HEADER_END + + #endif diff --git a/src/aig/int/intInter.c b/src/aig/int/intInter.c index 592eedcf..ef32294b 100644 --- a/src/aig/int/intInter.c +++ b/src/aig/int/intInter.c @@ -20,6 +20,9 @@ #include "intInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -138,3 +141,5 @@ void Inter_ManVerifyInterpolant2( Intb_Man_t * pMan, Sto_Man_t * pCnf, Aig_Man_t //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/int/intM114.c b/src/aig/int/intM114.c index 359d5458..c1718eae 100644 --- a/src/aig/int/intM114.c +++ b/src/aig/int/intM114.c @@ -20,6 +20,9 @@ #include "intInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -296,11 +299,11 @@ clk = clock(); */ pManInterA = Inta_ManAlloc(); - p->pInterNew = Inta_ManInterpolate( pManInterA, pSatCnf, p->vVarsAB, 0 ); + p->pInterNew = (Aig_Man_t *)Inta_ManInterpolate( pManInterA, (Sto_Man_t *)pSatCnf, p->vVarsAB, 0 ); Inta_ManFree( pManInterA ); p->timeInt += clock() - clk; - Sto_ManFree( pSatCnf ); + Sto_ManFree( (Sto_Man_t *)pSatCnf ); return RetValue; } @@ -309,3 +312,5 @@ p->timeInt += clock() - clk; //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/int/intM114p.c b/src/aig/int/intM114p.c index 6818fdce..0ad0552f 100644 --- a/src/aig/int/intM114p.c +++ b/src/aig/int/intM114p.c @@ -18,11 +18,13 @@ ***********************************************************************/ -#ifdef ABC_USE_LIBRARIES - #include "intInt.h" #include "m114p.h" +#ifdef ABC_USE_LIBRARIES + +ABC_NAMESPACE_IMPL_START + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -433,6 +435,8 @@ p->timeInt += clock() - clk; /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + #endif diff --git a/src/aig/int/intMan.c b/src/aig/int/intMan.c index 14a79f65..2faef198 100644 --- a/src/aig/int/intMan.c +++ b/src/aig/int/intMan.c @@ -20,6 +20,9 @@ #include "intInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -126,3 +129,5 @@ void Inter_ManStop( Inter_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/int/intUtil.c b/src/aig/int/intUtil.c index c0dc9ddb..0d8beda5 100644 --- a/src/aig/int/intUtil.c +++ b/src/aig/int/intUtil.c @@ -20,6 +20,9 @@ #include "intInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -47,7 +50,7 @@ int Inter_ManCheckInitialState( Aig_Man_t * p ) int status; int clk = clock(); pCnf = Cnf_Derive( p, Saig_ManRegNum(p) ); - pSat = Cnf_DataWriteIntoSolver( pCnf, 1, 1 ); + pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 1 ); Cnf_DataFree( pCnf ); if ( pSat == NULL ) return 0; @@ -75,7 +78,7 @@ int Inter_ManCheckAllStates( Aig_Man_t * p ) int status; int clk = clock(); pCnf = Cnf_Derive( p, Saig_ManRegNum(p) ); - pSat = Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); + pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); Cnf_DataFree( pCnf ); if ( pSat == NULL ) return 1; @@ -90,3 +93,5 @@ int Inter_ManCheckAllStates( Aig_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ioa/ioa.h b/src/aig/ioa/ioa.h index 55d95f6e..46dbda09 100644 --- a/src/aig/ioa/ioa.h +++ b/src/aig/ioa/ioa.h @@ -21,6 +21,7 @@ #ifndef __IOA_H__ #define __IOA_H__ + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -39,9 +40,10 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -60,8 +62,10 @@ extern "C" { //////////////////////////////////////////////////////////////////////// /*=== ioaReadAig.c ========================================================*/ +extern Aig_Man_t * Ioa_ReadAigerFromMemory( char * pContents, int nFileSize, int fCheck ); extern Aig_Man_t * Ioa_ReadAiger( char * pFileName, int fCheck ); /*=== ioaWriteAig.c =======================================================*/ +extern char * Ioa_WriteAigerIntoMemory( Aig_Man_t * pMan, int * pnSize ); extern void Ioa_WriteAiger( Aig_Man_t * pMan, char * pFileName, int fWriteSymbols, int fCompact ); /*=== ioaUtil.c =======================================================*/ extern int Ioa_FileSize( char * pFileName ); @@ -69,9 +73,11 @@ extern char * Ioa_FileNameGeneric( char * FileName ); extern char * Ioa_FileNameGenericAppend( char * pBase, char * pSuffix ); extern char * Ioa_TimeStamp(); -#ifdef __cplusplus -} -#endif + + +ABC_NAMESPACE_HEADER_END + + #endif diff --git a/src/aig/ioa/ioaReadAig.c b/src/aig/ioa/ioaReadAig.c index 6aaa6c64..defaa752 100644 --- a/src/aig/ioa/ioaReadAig.c +++ b/src/aig/ioa/ioaReadAig.c @@ -21,6 +21,9 @@ #include "ioa.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -91,7 +94,7 @@ Vec_Int_t * Ioa_WriteDecodeLiterals( char ** ppPos, int nEntries ) Synopsis [Reads the AIG in from the memory buffer.] Description [The buffer constains the AIG in AIGER format. The size gives - the number of types in the buffer. The buffer is allocated by the user + the number of bytes in the buffer. The buffer is allocated by the user and not deallocated by this procedure.] SideEffects [] @@ -198,8 +201,8 @@ Aig_Man_t * Ioa_ReadAigerFromMemory( char * pContents, int nFileSize, int fCheck uLit1 = uLit - Ioa_ReadAigerDecode( &pCur ); uLit0 = uLit1 - Ioa_ReadAigerDecode( &pCur ); // assert( uLit1 > uLit0 ); - pNode0 = Aig_NotCond( Vec_PtrEntry(vNodes, uLit0 >> 1), uLit0 & 1 ); - pNode1 = Aig_NotCond( Vec_PtrEntry(vNodes, uLit1 >> 1), uLit1 & 1 ); + pNode0 = Aig_NotCond( (Aig_Obj_t *)Vec_PtrEntry(vNodes, uLit0 >> 1), uLit0 & 1 ); + pNode1 = Aig_NotCond( (Aig_Obj_t *)Vec_PtrEntry(vNodes, uLit1 >> 1), uLit1 & 1 ); assert( Vec_PtrSize(vNodes) == i + 1 + nInputs + nLatches ); Vec_PtrPush( vNodes, Aig_And(pNew, pNode0, pNode1) ); } @@ -216,14 +219,14 @@ Aig_Man_t * Ioa_ReadAigerFromMemory( char * pContents, int nFileSize, int fCheck for ( i = 0; i < nLatches; i++ ) { uLit0 = atoi( pCur ); while ( *pCur++ != '\n' ); - pNode0 = Aig_NotCond( Vec_PtrEntry(vNodes, uLit0 >> 1), (uLit0 & 1) );//^ (uLit0 < 2) ); + pNode0 = Aig_NotCond( (Aig_Obj_t *)Vec_PtrEntry(vNodes, uLit0 >> 1), (uLit0 & 1) );//^ (uLit0 < 2) ); Vec_PtrPush( vDrivers, pNode0 ); } // read the PO driver literals for ( i = 0; i < nOutputs; i++ ) { uLit0 = atoi( pCur ); while ( *pCur++ != '\n' ); - pNode0 = Aig_NotCond( Vec_PtrEntry(vNodes, uLit0 >> 1), (uLit0 & 1) );//^ (uLit0 < 2) ); + pNode0 = Aig_NotCond( (Aig_Obj_t *)Vec_PtrEntry(vNodes, uLit0 >> 1), (uLit0 & 1) );//^ (uLit0 < 2) ); Vec_PtrPush( vDrivers, pNode0 ); } @@ -234,14 +237,14 @@ Aig_Man_t * Ioa_ReadAigerFromMemory( char * pContents, int nFileSize, int fCheck for ( i = 0; i < nLatches; i++ ) { uLit0 = Vec_IntEntry( vLits, i ); - pNode0 = Aig_NotCond( Vec_PtrEntry(vNodes, uLit0 >> 1), (uLit0 & 1) );//^ (uLit0 < 2) ); + pNode0 = Aig_NotCond( (Aig_Obj_t *)Vec_PtrEntry(vNodes, uLit0 >> 1), (uLit0 & 1) );//^ (uLit0 < 2) ); Vec_PtrPush( vDrivers, pNode0 ); } // read the PO driver literals for ( i = 0; i < nOutputs; i++ ) { uLit0 = Vec_IntEntry( vLits, i+nLatches ); - pNode0 = Aig_NotCond( Vec_PtrEntry(vNodes, uLit0 >> 1), (uLit0 & 1) );//^ (uLit0 < 2) ); + pNode0 = Aig_NotCond( (Aig_Obj_t *)Vec_PtrEntry(vNodes, uLit0 >> 1), (uLit0 & 1) );//^ (uLit0 < 2) ); Vec_PtrPush( vDrivers, pNode0 ); } Vec_IntFree( vLits ); @@ -249,9 +252,9 @@ Aig_Man_t * Ioa_ReadAigerFromMemory( char * pContents, int nFileSize, int fCheck // create the POs for ( i = 0; i < nOutputs; i++ ) - Aig_ObjCreatePo( pNew, Vec_PtrEntry(vDrivers, nLatches + i) ); + Aig_ObjCreatePo( pNew, (Aig_Obj_t *)Vec_PtrEntry(vDrivers, nLatches + i) ); for ( i = 0; i < nLatches; i++ ) - Aig_ObjCreatePo( pNew, Vec_PtrEntry(vDrivers, i) ); + Aig_ObjCreatePo( pNew, (Aig_Obj_t *)Vec_PtrEntry(vDrivers, i) ); Vec_PtrFree( vDrivers ); /* @@ -403,3 +406,5 @@ Aig_Man_t * Ioa_ReadAiger( char * pFileName, int fCheck ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ioa/ioaUtil.c b/src/aig/ioa/ioaUtil.c index b0e5618b..06034956 100644 --- a/src/aig/ioa/ioaUtil.c +++ b/src/aig/ioa/ioaUtil.c @@ -21,6 +21,9 @@ #include "ioa.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -139,3 +142,5 @@ char * Ioa_TimeStamp() //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ioa/ioaWriteAig.c b/src/aig/ioa/ioaWriteAig.c index 42aa42db..7aa975f2 100644 --- a/src/aig/ioa/ioaWriteAig.c +++ b/src/aig/ioa/ioaWriteAig.c @@ -21,6 +21,9 @@ #include "ioa.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -163,6 +166,35 @@ int Ioa_WriteAigerEncode( unsigned char * pBuffer, int Pos, unsigned x ) /**Function************************************************************* + Synopsis [Adds one unsigned AIG edge to the output buffer.] + + Description [This procedure is a slightly modified version of Armin Biere's + procedure "void encode (FILE * file, unsigned x)" ] + + SideEffects [Returns the current writing position.] + + SeeAlso [] + +***********************************************************************/ +void Ioa_WriteAigerEncodeStr( Vec_Str_t * vStr, unsigned x ) +{ + unsigned char ch; + while (x & ~0x7f) + { + ch = (x & 0x7f) | 0x80; +// putc (ch, file); +// pBuffer[Pos++] = ch; + Vec_StrPush( vStr, ch ); + x >>= 7; + } + ch = x; +// putc (ch, file); +// pBuffer[Pos++] = ch; + Vec_StrPush( vStr, ch ); +} + +/**Function************************************************************* + Synopsis [Create the array of literals to be written.] Description [] @@ -240,6 +272,151 @@ Vec_Str_t * Ioa_WriteEncodeLiterals( Vec_Int_t * vLits ) /**Function************************************************************* + Synopsis [Writes the AIG in into the memory buffer.] + + Description [The resulting buffer constains the AIG in AIGER format. + The returned size (pnSize) gives the number of bytes in the buffer. + The resulting buffer should be deallocated by the user.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Ioa_WriteAigerIntoMemory( Aig_Man_t * pMan, int * pnSize ) +{ + char * pBuffer; + Vec_Str_t * vBuffer; + Aig_Obj_t * pObj, * pDriver; + int nNodes, i, uLit, uLit0, uLit1; + // set the node numbers to be used in the output file + nNodes = 0; + Ioa_ObjSetAigerNum( Aig_ManConst1(pMan), nNodes++ ); + Aig_ManForEachPi( pMan, pObj, i ) + Ioa_ObjSetAigerNum( pObj, nNodes++ ); + Aig_ManForEachNode( pMan, pObj, i ) + Ioa_ObjSetAigerNum( pObj, nNodes++ ); + + // write the header "M I L O A" where M = I + L + A +/* + fprintf( pFile, "aig%s %u %u %u %u %u\n", + fCompact? "2" : "", + Aig_ManPiNum(pMan) + Aig_ManNodeNum(pMan), + Aig_ManPiNum(pMan) - Aig_ManRegNum(pMan), + Aig_ManRegNum(pMan), + Aig_ManPoNum(pMan) - Aig_ManRegNum(pMan), + Aig_ManNodeNum(pMan) ); +*/ + vBuffer = Vec_StrAlloc( 3*Aig_ManObjNum(pMan) ); + Vec_StrPrintStr( vBuffer, "aig " ); + Vec_StrPrintNum( vBuffer, Aig_ManPiNum(pMan) + Aig_ManNodeNum(pMan) ); + Vec_StrPrintStr( vBuffer, " " ); + Vec_StrPrintNum( vBuffer, Aig_ManPiNum(pMan) - Aig_ManRegNum(pMan) ); + Vec_StrPrintStr( vBuffer, " " ); + Vec_StrPrintNum( vBuffer, Aig_ManRegNum(pMan) ); + Vec_StrPrintStr( vBuffer, " " ); + Vec_StrPrintNum( vBuffer, Aig_ManPoNum(pMan) - Aig_ManRegNum(pMan) ); + Vec_StrPrintStr( vBuffer, " " ); + Vec_StrPrintNum( vBuffer, Aig_ManNodeNum(pMan) ); + Vec_StrPrintStr( vBuffer, "\n" ); + + // write latch drivers + Aig_ManForEachLiSeq( pMan, pObj, i ) + { + pDriver = Aig_ObjFanin0(pObj); + uLit = Ioa_ObjMakeLit( Ioa_ObjAigerNum(pDriver), Aig_ObjFaninC0(pObj) ^ (Ioa_ObjAigerNum(pDriver) == 0) ); +// fprintf( pFile, "%u\n", uLit ); + Vec_StrPrintNum( vBuffer, uLit ); + Vec_StrPrintStr( vBuffer, "\n" ); + } + + // write PO drivers + Aig_ManForEachPoSeq( pMan, pObj, i ) + { + pDriver = Aig_ObjFanin0(pObj); + uLit = Ioa_ObjMakeLit( Ioa_ObjAigerNum(pDriver), Aig_ObjFaninC0(pObj) ^ (Ioa_ObjAigerNum(pDriver) == 0) ); +// fprintf( pFile, "%u\n", uLit ); + Vec_StrPrintNum( vBuffer, uLit ); + Vec_StrPrintStr( vBuffer, "\n" ); + } + // write the nodes into the buffer + Aig_ManForEachNode( pMan, pObj, i ) + { + uLit = Ioa_ObjMakeLit( Ioa_ObjAigerNum(pObj), 0 ); + uLit0 = Ioa_ObjMakeLit( Ioa_ObjAigerNum(Aig_ObjFanin0(pObj)), Aig_ObjFaninC0(pObj) ); + uLit1 = Ioa_ObjMakeLit( Ioa_ObjAigerNum(Aig_ObjFanin1(pObj)), Aig_ObjFaninC1(pObj) ); + assert( uLit0 != uLit1 ); + if ( uLit0 > uLit1 ) + { + int Temp = uLit0; + uLit0 = uLit1; + uLit1 = Temp; + } +// Pos = Ioa_WriteAigerEncode( pBuffer, Pos, uLit - uLit1 ); +// Pos = Ioa_WriteAigerEncode( pBuffer, Pos, uLit1 - uLit0 ); + Ioa_WriteAigerEncodeStr( vBuffer, uLit - uLit1 ); + Ioa_WriteAigerEncodeStr( vBuffer, uLit1 - uLit0 ); + } +// fprintf( pFile, "c" ); +// if ( pMan->pName ) +// fprintf( pFile, "n%s%c", pMan->pName, '\0' ); + Vec_StrPrintStr( vBuffer, "c" ); + if ( pMan->pName ) + { + Vec_StrPrintStr( vBuffer, "n" ); + Vec_StrPrintStr( vBuffer, pMan->pName ); + Vec_StrPush( vBuffer, 0 ); + } + // prepare the return values + *pnSize = Vec_StrSize( vBuffer ); + pBuffer = Vec_StrReleaseArray( vBuffer ); + Vec_StrFree( vBuffer ); + return pBuffer; +} + +/**Function************************************************************* + + Synopsis [This procedure is used to test the above procedure.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ioa_WriteAigerBufferTest( Aig_Man_t * pMan, char * pFileName, int fWriteSymbols, int fCompact ) +{ + FILE * pFile; + char * pBuffer; + int nSize; + if ( Aig_ManPoNum(pMan) == 0 ) + { + printf( "AIG cannot be written because it has no POs.\n" ); + return; + } + // start the output stream + pFile = fopen( pFileName, "wb" ); + if ( pFile == NULL ) + { + fprintf( stdout, "Ioa_WriteAiger(): Cannot open the output file \"%s\".\n", pFileName ); + return; + } + // write the buffer + pBuffer = Ioa_WriteAigerIntoMemory( pMan, &nSize ); + fwrite( pBuffer, 1, nSize, pFile ); + ABC_FREE( pBuffer ); + // write the comment +// fprintf( pFile, "c" ); +// if ( pMan->pName ) +// fprintf( pFile, "n%s%c", pMan->pName, '\0' ); + fprintf( pFile, "\nThis file was produced by the IOA package in ABC on %s\n", Ioa_TimeStamp() ); + fprintf( pFile, "For information about AIGER format, refer to %s\n", "http://fmv.jku.at/aiger" ); + fclose( pFile ); +} + +/**Function************************************************************* + Synopsis [Writes the AIG in the binary AIGER format.] Description [] @@ -388,3 +565,5 @@ void Ioa_WriteAiger( Aig_Man_t * pMan, char * pFileName, int fWriteSymbols, int //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ivy/attr.h b/src/aig/ivy/attr.h index ad342ce9..b65906cf 100644 --- a/src/aig/ivy/attr.h +++ b/src/aig/ivy/attr.h @@ -21,6 +21,7 @@ #ifndef __ATTR_H__ #define __ATTR_H__ + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -31,9 +32,10 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -402,9 +404,11 @@ static inline void Attr_ManSetAttrPtr( Attr_Man_t * p, int Id, void * pAttr ) -#ifdef __cplusplus -} -#endif + + +ABC_NAMESPACE_HEADER_END + + #endif diff --git a/src/aig/ivy/ivy.h b/src/aig/ivy/ivy.h index 2c915e5b..870c0906 100644 --- a/src/aig/ivy/ivy.h +++ b/src/aig/ivy/ivy.h @@ -21,6 +21,7 @@ #ifndef __IVY_H__ #define __IVY_H__ + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -33,9 +34,10 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -121,7 +123,7 @@ struct Ivy_Man_t_ // memory management Vec_Ptr_t * vChunks; // allocated memory pieces Vec_Ptr_t * vPages; // memory pages used by nodes - Ivy_Obj_t * pListFree; // the list of ABC_FREE nodes + Ivy_Obj_t * pListFree; // the list of free nodes // timing statistics int time1; int time2; @@ -180,6 +182,8 @@ struct Ivy_Store_t_ #define IVY_MIN(a,b) (((a) < (b))? (a) : (b)) #define IVY_MAX(a,b) (((a) > (b))? (a) : (b)) +extern void Ivy_ManAddMemory( Ivy_Man_t * p ); + static inline int Ivy_BitWordNum( int nBits ) { return (nBits>>5) + ((nBits&31) > 0); } static inline int Ivy_TruthWordNum( int nVars ) { return nVars <= 5 ? 1 : (1 << (nVars - 5)); } static inline int Ivy_InfoHasBit( unsigned * p, int i ) { return (p[(i)>>5] & (1<<((i) & 31))) > 0; } @@ -224,8 +228,8 @@ static inline int Ivy_ManNodeNum( Ivy_Man_t * p ) { return p->nO static inline int Ivy_ManHashObjNum( Ivy_Man_t * p ) { return p->nObjs[IVY_AND]+p->nObjs[IVY_EXOR]+p->nObjs[IVY_LATCH]; } static inline int Ivy_ManGetCost( Ivy_Man_t * p ) { return p->nObjs[IVY_AND]+3*p->nObjs[IVY_EXOR]+8*p->nObjs[IVY_LATCH]; } -static inline Ivy_Type_t Ivy_ObjType( Ivy_Obj_t * pObj ) { return pObj->Type; } -static inline Ivy_Init_t Ivy_ObjInit( Ivy_Obj_t * pObj ) { return pObj->Init; } +static inline Ivy_Type_t Ivy_ObjType( Ivy_Obj_t * pObj ) { return (Ivy_Type_t)pObj->Type; } +static inline Ivy_Init_t Ivy_ObjInit( Ivy_Obj_t * pObj ) { return (Ivy_Init_t)pObj->Init; } static inline int Ivy_ObjIsConst1( Ivy_Obj_t * pObj ) { return pObj->Id == 0; } static inline int Ivy_ObjIsGhost( Ivy_Obj_t * pObj ) { return pObj->Id < 0; } static inline int Ivy_ObjIsNone( Ivy_Obj_t * pObj ) { return pObj->Type == IVY_NONE; } @@ -359,7 +363,6 @@ static Ivy_Init_t Ivy_InitExor( Ivy_Init_t InitA, Ivy_Init_t InitB ) // internal memory manager static inline Ivy_Obj_t * Ivy_ManFetchMemory( Ivy_Man_t * p ) { - extern void Ivy_ManAddMemory( Ivy_Man_t * p ); Ivy_Obj_t * pTemp; if ( p->pListFree == NULL ) Ivy_ManAddMemory( p ); @@ -382,13 +385,13 @@ static inline void Ivy_ManRecycleMemory( Ivy_Man_t * p, Ivy_Obj_t * pEntry ) // iterator over the primary inputs #define Ivy_ManForEachPi( p, pObj, i ) \ - Vec_PtrForEachEntry( p->vPis, pObj, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, p->vPis, pObj, i ) // iterator over the primary outputs #define Ivy_ManForEachPo( p, pObj, i ) \ - Vec_PtrForEachEntry( p->vPos, pObj, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, p->vPos, pObj, i ) // iterator over all objects, including those currently not used #define Ivy_ManForEachObj( p, pObj, i ) \ - Vec_PtrForEachEntry( p->vObjs, pObj, i ) if ( (pObj) == NULL ) {} else + Vec_PtrForEachEntry( Ivy_Obj_t *, p->vObjs, pObj, i ) if ( (pObj) == NULL ) {} else // iterator over the combinational inputs #define Ivy_ManForEachCi( p, pObj, i ) \ Ivy_ManForEachObj( p, pObj, i ) if ( !Ivy_ObjIsCi(pObj) ) {} else @@ -407,7 +410,7 @@ static inline void Ivy_ManRecycleMemory( Ivy_Man_t * p, Ivy_Obj_t * pEntry ) // iterator over the fanouts of an object #define Ivy_ObjForEachFanout( p, pObj, vArray, pFanout, i ) \ for ( i = 0, Ivy_ObjCollectFanouts(p, pObj, vArray); \ - i < Vec_PtrSize(vArray) && ((pFanout) = Vec_PtrEntry(vArray,i)); i++ ) + i < Vec_PtrSize(vArray) && ((pFanout) = (Ivy_Obj_t *)Vec_PtrEntry(vArray,i)); i++ ) //////////////////////////////////////////////////////////////////////// /// FUNCTION DECLARATIONS /// @@ -545,9 +548,11 @@ extern void Ivy_ObjPrintVerbose( Ivy_Man_t * p, Ivy_Obj_t * pObj, int extern void Ivy_ManPrintVerbose( Ivy_Man_t * p, int fHaig ); extern int Ivy_CutTruthPrint( Ivy_Man_t * p, Ivy_Cut_t * pCut, unsigned uTruth ); -#ifdef __cplusplus -} -#endif + + +ABC_NAMESPACE_HEADER_END + + #endif diff --git a/src/aig/ivy/ivyBalance.c b/src/aig/ivy/ivyBalance.c index b5c77e39..4abdf8c3 100644 --- a/src/aig/ivy/ivyBalance.c +++ b/src/aig/ivy/ivyBalance.c @@ -20,6 +20,9 @@ #include "ivy.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -139,8 +142,8 @@ int Ivy_NodeBalance_rec( Ivy_Man_t * pNew, Ivy_Obj_t * pObjOld, Vec_Vec_t * vSto // for each old node, derive the new well-balanced node for ( i = 0; i < vSuper->nSize; i++ ) { - NewNodeId = Ivy_NodeBalance_rec( pNew, Ivy_Regular(vSuper->pArray[i]), vStore, Level + 1, fUpdateLevel ); - NewNodeId = Ivy_EdgeNotCond( NewNodeId, Ivy_IsComplement(vSuper->pArray[i]) ); + NewNodeId = Ivy_NodeBalance_rec( pNew, Ivy_Regular((Ivy_Obj_t *)vSuper->pArray[i]), vStore, Level + 1, fUpdateLevel ); + NewNodeId = Ivy_EdgeNotCond( NewNodeId, Ivy_IsComplement((Ivy_Obj_t *)vSuper->pArray[i]) ); vSuper->pArray[i] = Ivy_EdgeToNode( pNew, NewNodeId ); } // build the supergate @@ -170,7 +173,7 @@ Ivy_Obj_t * Ivy_NodeBalanceBuildSuper( Ivy_Man_t * p, Vec_Ptr_t * vSuper, Ivy_Ty int LeftBound; assert( vSuper->nSize > 1 ); // sort the new nodes by level in the decreasing order - Vec_PtrSort( vSuper, Ivy_NodeCompareLevelsDecrease ); + Vec_PtrSort( vSuper, (int (*)(void))Ivy_NodeCompareLevelsDecrease ); // balance the nodes while ( vSuper->nSize > 1 ) { @@ -179,11 +182,11 @@ Ivy_Obj_t * Ivy_NodeBalanceBuildSuper( Ivy_Man_t * p, Vec_Ptr_t * vSuper, Ivy_Ty // find the node that can be shared (if no such node, randomize choice) Ivy_NodeBalancePermute( p, vSuper, LeftBound, Type == IVY_EXOR ); // pull out the last two nodes - pObj1 = Vec_PtrPop(vSuper); - pObj2 = Vec_PtrPop(vSuper); + pObj1 = (Ivy_Obj_t *)Vec_PtrPop(vSuper); + pObj2 = (Ivy_Obj_t *)Vec_PtrPop(vSuper); Ivy_NodeBalancePushUniqueOrderByLevel( vSuper, Ivy_Oper(p, pObj1, pObj2, Type) ); } - return Vec_PtrEntry(vSuper, 0); + return (Ivy_Obj_t *)Vec_PtrEntry(vSuper, 0); } /**Function************************************************************* @@ -252,13 +255,13 @@ Vec_Ptr_t * Ivy_NodeBalanceCone( Ivy_Obj_t * pObj, Vec_Vec_t * vStore, int Level if ( Vec_VecSize( vStore ) <= Level ) Vec_VecPush( vStore, Level, 0 ); // get the temporary array of nodes - vNodes = Vec_VecEntry( vStore, Level ); + vNodes = (Vec_Ptr_t *)Vec_VecEntry( vStore, Level ); Vec_PtrClear( vNodes ); // collect the nodes in the implication supergate RetValue = Ivy_NodeBalanceCone_rec( pObj, pObj, vNodes ); assert( vNodes->nSize > 1 ); // unmark the visited nodes - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vNodes, pObj, i ) Ivy_Regular(pObj)->fMarkB = 0; // if we found the node and its complement in the same implication supergate, // return empty set of nodes (meaning that we should use constant-0 node) @@ -291,19 +294,19 @@ int Ivy_NodeBalanceFindLeft( Vec_Ptr_t * vSuper ) return 0; // set the pointer to the one before the last Current = Vec_PtrSize(vSuper) - 2; - pObjRight = Vec_PtrEntry( vSuper, Current ); + pObjRight = (Ivy_Obj_t *)Vec_PtrEntry( vSuper, Current ); // go through the nodes to the left of this one for ( Current--; Current >= 0; Current-- ) { // get the next node on the left - pObjLeft = Vec_PtrEntry( vSuper, Current ); + pObjLeft = (Ivy_Obj_t *)Vec_PtrEntry( vSuper, Current ); // if the level of this node is different, quit the loop if ( Ivy_Regular(pObjLeft)->Level != Ivy_Regular(pObjRight)->Level ) break; } Current++; // get the node, for which the equality holds - pObjLeft = Vec_PtrEntry( vSuper, Current ); + pObjLeft = (Ivy_Obj_t *)Vec_PtrEntry( vSuper, Current ); assert( Ivy_Regular(pObjLeft)->Level == Ivy_Regular(pObjRight)->Level ); return Current; } @@ -330,14 +333,14 @@ void Ivy_NodeBalancePermute( Ivy_Man_t * p, Vec_Ptr_t * vSuper, int LeftBound, i if ( LeftBound == RightBound ) return; // get the two last nodes - pObj1 = Vec_PtrEntry( vSuper, RightBound + 1 ); - pObj2 = Vec_PtrEntry( vSuper, RightBound ); + pObj1 = (Ivy_Obj_t *)Vec_PtrEntry( vSuper, RightBound + 1 ); + pObj2 = (Ivy_Obj_t *)Vec_PtrEntry( vSuper, RightBound ); if ( Ivy_Regular(pObj1) == p->pConst1 || Ivy_Regular(pObj2) == p->pConst1 ) return; // find the first node that can be shared for ( i = RightBound; i >= LeftBound; i-- ) { - pObj3 = Vec_PtrEntry( vSuper, i ); + pObj3 = (Ivy_Obj_t *)Vec_PtrEntry( vSuper, i ); if ( Ivy_Regular(pObj3) == p->pConst1 ) { Vec_PtrWriteEntry( vSuper, i, pObj2 ); @@ -387,8 +390,8 @@ void Ivy_NodeBalancePushUniqueOrderByLevel( Vec_Ptr_t * vStore, Ivy_Obj_t * pObj // find the p of the node for ( i = vStore->nSize-1; i > 0; i-- ) { - pObj1 = vStore->pArray[i ]; - pObj2 = vStore->pArray[i-1]; + pObj1 = (Ivy_Obj_t *)vStore->pArray[i ]; + pObj2 = (Ivy_Obj_t *)vStore->pArray[i-1]; if ( Ivy_Regular(pObj1)->Level <= Ivy_Regular(pObj2)->Level ) break; vStore->pArray[i ] = pObj2; @@ -402,3 +405,5 @@ void Ivy_NodeBalancePushUniqueOrderByLevel( Vec_Ptr_t * vStore, Ivy_Obj_t * pObj //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ivy/ivyCanon.c b/src/aig/ivy/ivyCanon.c index db5918de..34ed781f 100644 --- a/src/aig/ivy/ivyCanon.c +++ b/src/aig/ivy/ivyCanon.c @@ -20,6 +20,9 @@ #include "ivy.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -142,3 +145,5 @@ Ivy_Obj_t * Ivy_CanonLatch( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Init_t Init ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ivy/ivyCheck.c b/src/aig/ivy/ivyCheck.c index 55448f19..c924e2d0 100644 --- a/src/aig/ivy/ivyCheck.c +++ b/src/aig/ivy/ivyCheck.c @@ -20,6 +20,9 @@ #include "ivy.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -271,3 +274,5 @@ int Ivy_ManCheckChoices( Ivy_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ivy/ivyCut.c b/src/aig/ivy/ivyCut.c index e3651645..d5a31dee 100644 --- a/src/aig/ivy/ivyCut.c +++ b/src/aig/ivy/ivyCut.c @@ -20,6 +20,9 @@ #include "ivy.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -332,7 +335,7 @@ int Ivy_ManFindBoolCut( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Vec_Ptr_t * vFront, Ve while ( 1 ) { // find the next node to expand on this level - Vec_PtrForEachEntry( vFront, pObj, k ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vFront, pObj, k ) if ( (int)pObj->Level == Lev ) break; if ( k == Vec_PtrSize(vFront) ) @@ -399,11 +402,11 @@ int Ivy_ManFindBoolCut( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Vec_Ptr_t * vFront, Ve if ( pFaninC && !pFaninC->fMarkA && !pFaninC->fMarkB ) Vec_PtrPush( vFront, pFaninC ); // clean the markings - Vec_PtrForEachEntry( vVolume, pObj, k ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vVolume, pObj, k ) pObj->fMarkA = pObj->fMarkB = 0; // mark the nodes on the frontier (including the pivot) - Vec_PtrForEachEntry( vFront, pObj, k ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vFront, pObj, k ) pObj->fMarkA = 1; // cut exists, collect all the nodes on the shortest path to the pivot Vec_PtrClear( vLeaves ); @@ -411,16 +414,16 @@ int Ivy_ManFindBoolCut( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Vec_Ptr_t * vFront, Ve RetValue = Ivy_ManFindBoolCut_rec( p, pRoot, vLeaves, vVolume, pPivot ); assert( RetValue == 1 ); // unmark the nodes on the frontier (including the pivot) - Vec_PtrForEachEntry( vFront, pObj, k ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vFront, pObj, k ) pObj->fMarkA = 0; // mark the nodes in the volume - Vec_PtrForEachEntry( vVolume, pObj, k ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vVolume, pObj, k ) pObj->fMarkA = 1; // expand the cut without increasing its size while ( 1 ) { - Vec_PtrForEachEntry( vLeaves, pObj, k ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vLeaves, pObj, k ) if ( Ivy_ManFindBoolCutCost(pObj) < 2 ) break; if ( k == Vec_PtrSize(vLeaves) ) @@ -448,7 +451,7 @@ int Ivy_ManFindBoolCut( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Vec_Ptr_t * vFront, Ve } } // unmark the nodes in the volume - Vec_PtrForEachEntry( vVolume, pObj, k ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vVolume, pObj, k ) pObj->fMarkA = 0; return 1; } @@ -491,7 +494,7 @@ void Ivy_ManTestCutsBool( Ivy_Man_t * p ) printf( "%d ", Vec_PtrSize(vLeaves) ); /* printf( "( " ); - Vec_PtrForEachEntry( vFront, pTemp, k ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vFront, pTemp, k ) printf( "%d ", Ivy_ObjRefs(Ivy_Regular(pTemp)) ); printf( ")\n" ); */ @@ -988,3 +991,5 @@ void Ivy_ManTestCutsAll( Ivy_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ivy/ivyCutTrav.c b/src/aig/ivy/ivyCutTrav.c index a52bbcf9..3cdca141 100644 --- a/src/aig/ivy/ivyCutTrav.c +++ b/src/aig/ivy/ivyCutTrav.c @@ -20,6 +20,9 @@ #include "ivy.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -70,7 +73,7 @@ Ivy_Store_t * Ivy_NodeFindCutsTravAll( Ivy_Man_t * p, Ivy_Obj_t * pObj, int nLea // set elementary cuts for the leaves nWords = Extra_BitWordNum( nNodes ); - Vec_PtrForEachEntry( vFront, pLeaf, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vFront, pLeaf, i ) { assert( Ivy_ObjTravId(pLeaf) < nNodes ); // get the new bitcut @@ -80,10 +83,10 @@ Ivy_Store_t * Ivy_NodeFindCutsTravAll( Ivy_Man_t * p, Ivy_Obj_t * pObj, int nLea } // compute the cuts for each node - Vec_PtrForEachEntry( vNodes, pLeaf, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vNodes, pLeaf, i ) { // skip the leaves - vCuts = Vec_VecEntry( vBitCuts, Ivy_ObjTravId(pLeaf) ); + vCuts = (Vec_Ptr_t *)Vec_VecEntry( vBitCuts, Ivy_ObjTravId(pLeaf) ); if ( Vec_PtrSize(vCuts) > 0 ) continue; // add elementary cut @@ -91,8 +94,8 @@ Ivy_Store_t * Ivy_NodeFindCutsTravAll( Ivy_Man_t * p, Ivy_Obj_t * pObj, int nLea // set it as the cut of this leaf Vec_VecPush( vBitCuts, Ivy_ObjTravId(pLeaf), pBitCut ); // get the fanin cuts - vCuts0 = Vec_VecEntry( vBitCuts, Ivy_ObjTravId( Ivy_ObjFanin0(pLeaf) ) ); - vCuts1 = Vec_VecEntry( vBitCuts, Ivy_ObjTravId( Ivy_ObjFanin1(pLeaf) ) ); + vCuts0 = (Vec_Ptr_t *)Vec_VecEntry( vBitCuts, Ivy_ObjTravId( Ivy_ObjFanin0(pLeaf) ) ); + vCuts1 = (Vec_Ptr_t *)Vec_VecEntry( vBitCuts, Ivy_ObjTravId( Ivy_ObjFanin1(pLeaf) ) ); assert( Vec_PtrSize(vCuts0) > 0 ); assert( Vec_PtrSize(vCuts1) > 0 ); // merge the cuts @@ -103,8 +106,8 @@ Ivy_Store_t * Ivy_NodeFindCutsTravAll( Ivy_Man_t * p, Ivy_Obj_t * pObj, int nLea pCutStore->nCuts = 0; pCutStore->nCutsMax = IVY_CUT_LIMIT; // collect the cuts of the root node - vCuts = Vec_VecEntry( vBitCuts, Ivy_ObjTravId(pObj) ); - Vec_PtrForEachEntry( vCuts, pBitCut, i ) + vCuts = (Vec_Ptr_t *)Vec_VecEntry( vBitCuts, Ivy_ObjTravId(pObj) ); + Vec_PtrForEachEntry( unsigned *, vCuts, pBitCut, i ) { pCut = pCutStore->pCuts + pCutStore->nCuts++; pCut->nSize = 0; @@ -112,14 +115,14 @@ Ivy_Store_t * Ivy_NodeFindCutsTravAll( Ivy_Man_t * p, Ivy_Obj_t * pObj, int nLea pCut->uHash = 0; for ( k = 0; k < nNodes; k++ ) if ( Extra_TruthHasBit(pBitCut, k) ) - pCut->pArray[ pCut->nSize++ ] = Ivy_ObjId( Vec_PtrEntry(vNodes, k) ); + pCut->pArray[ pCut->nSize++ ] = Ivy_ObjId( (Ivy_Obj_t *)Vec_PtrEntry(vNodes, k) ); assert( pCut->nSize <= nLeaves ); if ( pCutStore->nCuts == pCutStore->nCutsMax ) break; } // clean the travIds - Vec_PtrForEachEntry( vNodes, pLeaf, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vNodes, pLeaf, i ) pLeaf->TravId = 0; return pCutStore; } @@ -228,7 +231,7 @@ void Ivy_NodeComputeVolume( Ivy_Obj_t * pObj, int nNodeLimit, Vec_Ptr_t * vNodes Ivy_NodeComputeVolumeTrav2_rec( pObj, vFront ); // find the fanins that are not marked Vec_PtrClear( vNodes ); - Vec_PtrForEachEntry( vFront, pTemp, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vFront, pTemp, i ) { pFanin = Ivy_ObjFanin0(pTemp); if ( !pFanin->fMarkA ) @@ -246,17 +249,17 @@ void Ivy_NodeComputeVolume( Ivy_Obj_t * pObj, int nNodeLimit, Vec_Ptr_t * vNodes // remember the number of nodes in the frontier nNodes = Vec_PtrSize( vNodes ); // add the remaining nodes - Vec_PtrForEachEntry( vFront, pTemp, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vFront, pTemp, i ) Vec_PtrPush( vNodes, pTemp ); // unmark the nodes - Vec_PtrForEachEntry( vNodes, pTemp, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vNodes, pTemp, i ) { pTemp->fMarkA = 0; pTemp->TravId = i; } // collect the frontier nodes Vec_PtrClear( vFront ); - Vec_PtrForEachEntryStop( vNodes, pTemp, i, nNodes ) + Vec_PtrForEachEntryStop( Ivy_Obj_t *, vNodes, pTemp, i, nNodes ) Vec_PtrPush( vFront, pTemp ); // printf( "%d ", Vec_PtrSize(vNodes) ); } @@ -289,7 +292,7 @@ void Ivy_NodeComputeVolume2( Ivy_Obj_t * pObj, int nNodeLimit, Vec_Ptr_t * vNode do { // get the node to expand pPivot = NULL; - Vec_PtrForEachEntryReverse( vFront, pLeaf, i ) + Vec_PtrForEachEntryReverse( Ivy_Obj_t *, vFront, pLeaf, i ) { if ( (int)pLeaf->Level == LevelMax ) { @@ -326,14 +329,14 @@ void Ivy_NodeComputeVolume2( Ivy_Obj_t * pObj, int nNodeLimit, Vec_Ptr_t * vNode } while ( Vec_PtrSize(vNodes) < nNodeLimit ); // sort nodes by level - Vec_PtrSort( vNodes, Ivy_CompareNodesByLevel ); + Vec_PtrSort( vNodes, (int (*)(void))Ivy_CompareNodesByLevel ); // make sure the nodes are ordered in the increasing number of levels - pFanin = Vec_PtrEntry( vNodes, 0 ); - pPivot = Vec_PtrEntryLast( vNodes ); + pFanin = (Ivy_Obj_t *)Vec_PtrEntry( vNodes, 0 ); + pPivot = (Ivy_Obj_t *)Vec_PtrEntryLast( vNodes ); assert( pFanin->Level <= pPivot->Level ); // clean the marks and remember node numbers in the TravId - Vec_PtrForEachEntry( vNodes, pFanin, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vNodes, pFanin, i ) { pFanin->fMarkA = 0; pFanin->TravId = i; @@ -383,8 +386,8 @@ void Ivy_NodeFindCutsMerge( Vec_Ptr_t * vCuts0, Vec_Ptr_t * vCuts1, Vec_Ptr_t * unsigned * pBitCut, * pBitCut0, * pBitCut1, * pBitCutTest; int i, k, c, w, Counter; // iterate through the cut pairs - Vec_PtrForEachEntry( vCuts0, pBitCut0, i ) - Vec_PtrForEachEntry( vCuts1, pBitCut1, k ) + Vec_PtrForEachEntry( unsigned *, vCuts0, pBitCut0, i ) + Vec_PtrForEachEntry( unsigned *, vCuts1, pBitCut1, k ) { // skip infeasible cuts Counter = 0; @@ -401,7 +404,7 @@ void Ivy_NodeFindCutsMerge( Vec_Ptr_t * vCuts0, Vec_Ptr_t * vCuts1, Vec_Ptr_t * Extra_TruthOrWords( pBitCutTest, pBitCut0, pBitCut1, nWords ); // filter contained cuts; try to find containing cut w = 0; - Vec_PtrForEachEntry( vCuts, pBitCut, c ) + Vec_PtrForEachEntry( unsigned *, vCuts, pBitCut, c ) { if ( Extra_TruthIsImplyWords( pBitCut, pBitCutTest, nWords ) ) break; @@ -471,3 +474,5 @@ void Ivy_ManTestCutsTravAll( Ivy_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ivy/ivyDfs.c b/src/aig/ivy/ivyDfs.c index 9594c0d2..611dd854 100644 --- a/src/aig/ivy/ivyDfs.c +++ b/src/aig/ivy/ivyDfs.c @@ -20,6 +20,9 @@ #include "ivy.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -196,14 +199,14 @@ void Ivy_ManCollectCone( Ivy_Obj_t * pObj, Vec_Ptr_t * vFront, Vec_Ptr_t * vCone assert( !Ivy_IsComplement(pObj) ); assert( Ivy_ObjIsNode(pObj) ); // mark the nodes - Vec_PtrForEachEntry( vFront, pTemp, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vFront, pTemp, i ) Ivy_Regular(pTemp)->fMarkA = 1; assert( pObj->fMarkA == 0 ); // collect the cone Vec_PtrClear( vCone ); Ivy_ManCollectCone_rec( pObj, vCone ); // unmark the nodes - Vec_PtrForEachEntry( vFront, pTemp, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vFront, pTemp, i ) Ivy_Regular(pTemp)->fMarkA = 0; } @@ -255,7 +258,7 @@ Vec_Int_t * Ivy_ManRequiredLevels( Ivy_Man_t * p ) vLevelsR = Vec_IntStart( Ivy_ManObjIdMax(p) + 1 ); // iterate through the nodes in the reverse order vNodes = Ivy_ManLevelize( p ); - Vec_VecForEachEntryReverseReverse( vNodes, pObj, i, k ) + Vec_VecForEachEntryReverseReverse( Ivy_Obj_t *, vNodes, pObj, i, k ) { Level = Vec_IntEntry( vLevelsR, pObj->Id ) + 1 + Ivy_ObjIsExor(pObj); if ( Vec_IntEntry( vLevelsR, Ivy_ObjFaninId0(pObj) ) < Level ) @@ -491,3 +494,5 @@ int Ivy_ManSetLevels( Ivy_Man_t * p, int fHaig ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ivy/ivyDsd.c b/src/aig/ivy/ivyDsd.c index 3b8a2e68..71c4863a 100644 --- a/src/aig/ivy/ivyDsd.c +++ b/src/aig/ivy/ivyDsd.c @@ -20,6 +20,9 @@ #include "ivy.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -50,9 +53,13 @@ struct Ivy_Dec_t_ unsigned Fan5 : 4; // fanin 5 }; -static inline int Ivy_DecToInt( Ivy_Dec_t Node ) { return *((int *)&Node); } -static inline Ivy_Dec_t Ivy_IntToDec( int Node ) { return *((Ivy_Dec_t *)&Node); } -static inline void Ivy_DecClear( Ivy_Dec_t * pNode ) { *((int *)pNode) = 0; } +static inline int Ivy_DecToInt( Ivy_Dec_t m ) { union { Ivy_Dec_t x; int y; } v; v.x = m; return v.y; } +static inline Ivy_Dec_t Ivy_IntToDec( int m ) { union { Ivy_Dec_t x; int y; } v; v.y = m; return v.x; } +static inline void Ivy_DecClear( Ivy_Dec_t * pNode ) { *pNode = Ivy_IntToDec(0); } + +//static inline int Ivy_DecToInt( Ivy_Dec_t Node ) { return *((int *)&Node); } +//static inline Ivy_Dec_t Ivy_IntToDec( int Node ) { return *((Ivy_Dec_t *)&Node); } +//static inline void Ivy_DecClear( Ivy_Dec_t * pNode ) { *((int *)pNode) = 0; } static unsigned s_Masks[6][2] = { @@ -817,3 +824,5 @@ void Ivy_TruthTest5() //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ivy/ivyFanout.c b/src/aig/ivy/ivyFanout.c index 3930186a..9ff4f4bc 100644 --- a/src/aig/ivy/ivyFanout.c +++ b/src/aig/ivy/ivyFanout.c @@ -20,6 +20,9 @@ #include "ivy.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -307,3 +310,5 @@ int Ivy_ObjFanoutNum( Ivy_Man_t * p, Ivy_Obj_t * pObj ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ivy/ivyFastMap.c b/src/aig/ivy/ivyFastMap.c index 0c0102c0..05db377d 100644 --- a/src/aig/ivy/ivyFastMap.c +++ b/src/aig/ivy/ivyFastMap.c @@ -20,6 +20,9 @@ #include "ivy.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -168,7 +171,7 @@ clk = clock(); { Vec_Ptr_t * vNodes; vNodes = Vec_PtrAlloc( 100 ); - Vec_VecForEachEntry( pMan->vLuts, pObj, i, k ) + Vec_VecForEachEntry( Ivy_Obj_t *, pMan->vLuts, pObj, i, k ) Vec_PtrPush( vNodes, pObj ); Ivy_ManShow( pAig, 0, vNodes ); Vec_PtrFree( vNodes ); @@ -189,7 +192,7 @@ clk = clock(); ***********************************************************************/ void Ivy_FastMapStop( Ivy_Man_t * pAig ) { - Ivy_SuppMan_t * p = pAig->pData; + Ivy_SuppMan_t * p = (Ivy_SuppMan_t *)pAig->pData; Vec_VecFree( p->vLuts ); ABC_FREE( p->pMem ); ABC_FREE( p ); @@ -886,7 +889,7 @@ void Ivy_FastMapRequired( Ivy_Man_t * pAig, int Delay, int fSetInter ) vLuts = ((Ivy_SuppMan_t *)pAig->pData)->vLuts; // propagate the required times Vec_VecForEachLevelReverse( vLuts, vNodes, i ) - Vec_PtrForEachEntry( vNodes, pObj, k ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vNodes, pObj, k ) { pSupp = Ivy_ObjSupp( pAig, pObj ); assert( pSupp->nRefs > 0 ); @@ -911,7 +914,7 @@ void Ivy_FastMapRequired( Ivy_Man_t * pAig, int Delay, int fSetInter ) { // set the required times of the intermediate nodes Vec_VecForEachLevelReverse( vLuts, vNodes, i ) - Vec_PtrForEachEntry( vNodes, pObj, k ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vNodes, pObj, k ) { pSupp = Ivy_ObjSupp( pAig, pObj ); Ivy_FastMapRequired_rec( pAig, pObj, pObj, pSupp->DelayR ); @@ -1117,7 +1120,7 @@ int Ivy_FastMapCutCost( Ivy_Man_t * pAig, Vec_Ptr_t * vFront ) Ivy_Supp_t * pSuppF; Ivy_Obj_t * pFanin; int i, Counter = 0; - Vec_PtrForEachEntry( vFront, pFanin, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vFront, pFanin, i ) { pSuppF = Ivy_ObjSupp( pAig, pFanin ); if ( pSuppF->nRefs == 0 ) @@ -1246,7 +1249,7 @@ int Ivy_FastMapNodeFaninCompact0( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, int nLimit { Ivy_Obj_t * pFanin; int i; - Vec_PtrForEachEntry( vFront, pFanin, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vFront, pFanin, i ) { if ( Ivy_ObjIsCi(pFanin) ) continue; @@ -1276,7 +1279,7 @@ int Ivy_FastMapNodeFaninCompact1( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, int nLimit { Ivy_Obj_t * pFanin; int i; - Vec_PtrForEachEntry( vFront, pFanin, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vFront, pFanin, i ) { if ( Ivy_ObjIsCi(pFanin) ) continue; @@ -1304,7 +1307,7 @@ int Ivy_FastMapNodeFaninCompact2( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, int nLimit { Ivy_Obj_t * pFanin; int i; - Vec_PtrForEachEntry( vFront, pFanin, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vFront, pFanin, i ) { if ( Ivy_ObjIsCi(pFanin) ) continue; @@ -1409,7 +1412,7 @@ void Ivy_FastMapNodeUpdate( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, Vec_Ptr_t * vFro Ivy_FastMapNodeDeref( pAig, pObj ); // update the node's cut pSupp->nSize = Vec_PtrSize(vFront); - Vec_PtrForEachEntry( vFront, pFanin, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vFront, pFanin, i ) pSupp->pArray[i] = pFanin->Id; // ref the new cut Ivy_FastMapNodeRef( pAig, pObj ); @@ -1587,3 +1590,5 @@ void Ivy_FastMapNodeRecover4( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, int nLimit, Ve //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ivy/ivyFraig.c b/src/aig/ivy/ivyFraig.c index 68726501..77b64700 100644 --- a/src/aig/ivy/ivyFraig.c +++ b/src/aig/ivy/ivyFraig.c @@ -22,6 +22,8 @@ #include "extra.h" #include "ivy.h" +ABC_NAMESPACE_IMPL_START + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -249,7 +251,7 @@ void Ivy_FraigParamsDefault( Ivy_FraigParams_t * pParams ) ***********************************************************************/ int Ivy_FraigProve( Ivy_Man_t ** ppManAig, void * pPars ) { - Prove_Params_t * pParams = pPars; + Prove_Params_t * pParams = (Prove_Params_t *)pPars; Ivy_FraigParams_t Params, * pIvyParams = &Params; Ivy_Man_t * pManAig, * pManTemp; int RetValue, nIter, clk;//, Counter; @@ -1536,7 +1538,7 @@ void Ivy_FraigSavePattern( Ivy_FraigMan_t * p ) int i; memset( p->pPatWords, 0, sizeof(unsigned) * p->nPatWords ); Ivy_ManForEachPi( p->pManFraig, pObj, i ) -// Vec_PtrForEachEntry( p->vPiVars, pObj, i ) +// Vec_PtrForEachEntry( Ivy_Obj_t *, p->vPiVars, pObj, i ) if ( p->pSat->model.ptr[Ivy_ObjSatNum(pObj)] == l_True ) Ivy_InfoSetBit( p->pPatWords, i ); // Ivy_InfoSetBit( p->pPatWords, pObj->Id - 1 ); @@ -1559,7 +1561,7 @@ void Ivy_FraigSavePattern2( Ivy_FraigMan_t * p ) int i; memset( p->pPatWords, 0, sizeof(unsigned) * p->nPatWords ); // Ivy_ManForEachPi( p->pManFraig, pObj, i ) - Vec_PtrForEachEntry( p->vPiVars, pObj, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, p->vPiVars, pObj, i ) if ( p->pSat->model.ptr[Ivy_ObjSatNum(pObj)] == l_True ) // Ivy_InfoSetBit( p->pPatWords, i ); Ivy_InfoSetBit( p->pPatWords, pObj->Id - 1 ); @@ -1582,7 +1584,7 @@ void Ivy_FraigSavePattern3( Ivy_FraigMan_t * p ) int i; for ( i = 0; i < p->nPatWords; i++ ) p->pPatWords[i] = Ivy_ObjRandomSim(); - Vec_PtrForEachEntry( p->vPiVars, pObj, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, p->vPiVars, pObj, i ) if ( Ivy_InfoHasBit( p->pPatWords, pObj->Id - 1 ) ^ (p->pSat->model.ptr[Ivy_ObjSatNum(pObj)] == l_True) ) Ivy_InfoXorBit( p->pPatWords, pObj->Id - 1 ); } @@ -1820,12 +1822,14 @@ int Ivy_FraigMiterStatus( Ivy_Man_t * pMan ) CountConst0++; continue; } +/* // check if the output is a primary input if ( Ivy_ObjIsPi(Ivy_Regular(pObjNew)) ) { CountNonConst0++; continue; } +*/ // check if the output can be constant 0 if ( Ivy_Regular(pObjNew)->fPhase != (unsigned)Ivy_IsComplement(pObjNew) ) { @@ -2398,7 +2402,7 @@ void Ivy_FraigAddClausesSuper( Ivy_FraigMan_t * p, Ivy_Obj_t * pNode, Vec_Ptr_t pLits = ABC_ALLOC( int, nLits ); // suppose AND-gate is A & B = C // add !A => !C or A + !C - Vec_PtrForEachEntry( vSuper, pFanin, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vSuper, pFanin, i ) { pLits[0] = toLitCond(Ivy_ObjSatNum(Ivy_Regular(pFanin)), Ivy_IsComplement(pFanin)); pLits[1] = toLitCond(Ivy_ObjSatNum(pNode), 1); @@ -2406,7 +2410,7 @@ void Ivy_FraigAddClausesSuper( Ivy_FraigMan_t * p, Ivy_Obj_t * pNode, Vec_Ptr_t assert( RetValue ); } // add A & B => C or !A + !B + C - Vec_PtrForEachEntry( vSuper, pFanin, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vSuper, pFanin, i ) pLits[i] = toLitCond(Ivy_ObjSatNum(Ivy_Regular(pFanin)), !Ivy_IsComplement(pFanin)); pLits[nLits-1] = toLitCond(Ivy_ObjSatNum(pNode), 0); RetValue = sat_solver_addclause( p->pSat, pLits, pLits + nLits ); @@ -2511,7 +2515,7 @@ void Ivy_FraigNodeAddToSolver( Ivy_FraigMan_t * p, Ivy_Obj_t * pOld, Ivy_Obj_t * if ( pOld ) Ivy_FraigObjAddToFrontier( p, pOld, vFrontier ); if ( pNew ) Ivy_FraigObjAddToFrontier( p, pNew, vFrontier ); // explore nodes in the frontier - Vec_PtrForEachEntry( vFrontier, pNode, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vFrontier, pNode, i ) { // create the supergate assert( Ivy_ObjSatNum(pNode) ); @@ -2523,14 +2527,14 @@ void Ivy_FraigNodeAddToSolver( Ivy_FraigMan_t * p, Ivy_Obj_t * pOld, Ivy_Obj_t * Vec_PtrPushUnique( vFanins, Ivy_ObjFanin0( Ivy_ObjFanin1(pNode) ) ); Vec_PtrPushUnique( vFanins, Ivy_ObjFanin1( Ivy_ObjFanin0(pNode) ) ); Vec_PtrPushUnique( vFanins, Ivy_ObjFanin1( Ivy_ObjFanin1(pNode) ) ); - Vec_PtrForEachEntry( vFanins, pFanin, k ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vFanins, pFanin, k ) Ivy_FraigObjAddToFrontier( p, Ivy_Regular(pFanin), vFrontier ); Ivy_FraigAddClausesMux( p, pNode ); } else { vFanins = Ivy_FraigCollectSuper( pNode, fUseMuxes ); - Vec_PtrForEachEntry( vFanins, pFanin, k ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vFanins, pFanin, k ) Ivy_FraigObjAddToFrontier( p, Ivy_Regular(pFanin), vFrontier ); Ivy_FraigAddClausesSuper( p, pNode, vFanins ); } @@ -2572,7 +2576,7 @@ int Ivy_FraigSetActivityFactors_rec( Ivy_FraigMan_t * p, Ivy_Obj_t * pObj, int L veci_push(&p->pSat->act_vars, Ivy_ObjSatNum(pObj)); // explore the fanins vFanins = Ivy_ObjFaninVec( pObj ); - Vec_PtrForEachEntry( vFanins, pFanin, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vFanins, pFanin, i ) Counter += Ivy_FraigSetActivityFactors_rec( p, Ivy_Regular(pFanin), LevelMin, LevelMax ); return 1 + Counter; } @@ -2611,10 +2615,13 @@ p->timeTrav += clock() - clk; return 1; } - +ABC_NAMESPACE_IMPL_END #include "cuddInt.h" +ABC_NAMESPACE_IMPL_START + + /**Function************************************************************* Synopsis [Checks equivalence using BDDs.] @@ -2635,7 +2642,7 @@ DdNode * Ivy_FraigNodesAreEquivBdd_int( DdManager * dd, DdNode * bFunc, Vec_Ptr_ int i, NewSize; // create new frontier vTemp = Vec_PtrAlloc( 100 ); - Vec_PtrForEachEntry( vFront, pObj, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vFront, pObj, i ) { if ( (int)pObj->Level != Level ) { @@ -2664,7 +2671,7 @@ DdNode * Ivy_FraigNodesAreEquivBdd_int( DdManager * dd, DdNode * bFunc, Vec_Ptr_ // collect the permutation NewSize = IVY_MAX(dd->size, Vec_PtrSize(vTemp)); pFuncs = ABC_ALLOC( DdNode *, NewSize ); - Vec_PtrForEachEntry( vFront, pObj, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vFront, pObj, i ) { if ( (int)pObj->Level != Level ) pFuncs[i] = Cudd_bddIthVar( dd, pObj->TravId ); @@ -2685,7 +2692,7 @@ DdNode * Ivy_FraigNodesAreEquivBdd_int( DdManager * dd, DdNode * bFunc, Vec_Ptr_ // create new bFuncNew = Cudd_bddVectorCompose( dd, bFunc, pFuncs ); Cudd_Ref( bFuncNew ); // clean trav Id - Vec_PtrForEachEntry( vTemp, pObj, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vTemp, pObj, i ) { pObj->fMarkB = 0; pObj->TravId = 0; @@ -2739,7 +2746,7 @@ int Ivy_FraigNodesAreEquivBdd( Ivy_Obj_t * pObj1, Ivy_Obj_t * pObj2 ) { // find max level Level = 0; - Vec_PtrForEachEntry( vFront, pObj, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vFront, pObj, i ) if ( Level < (int)pObj->Level ) Level = (int)pObj->Level; if ( Level == 0 ) @@ -2771,3 +2778,5 @@ int Ivy_FraigNodesAreEquivBdd( Ivy_Obj_t * pObj1, Ivy_Obj_t * pObj2 ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ivy/ivyHaig.c b/src/aig/ivy/ivyHaig.c index 87021600..a4fda7d8 100644 --- a/src/aig/ivy/ivyHaig.c +++ b/src/aig/ivy/ivyHaig.c @@ -20,6 +20,9 @@ #include "ivy.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -158,7 +161,7 @@ void Ivy_ManHaigStop( Ivy_Man_t * p ) Ivy_Obj_t * pObj; int i; assert( p->pHaig != NULL ); - Vec_IntFree( p->pHaig->pData ); + Vec_IntFree( (Vec_Int_t *)p->pHaig->pData ); Ivy_ManStop( p->pHaig ); p->pHaig = NULL; // remove dangling pointers to the HAIG objects @@ -189,7 +192,7 @@ void Ivy_ManHaigCreateObj( Ivy_Man_t * p, Ivy_Obj_t * pObj ) // pObj->pEquiv = Ivy_Latch( p->pHaig, Ivy_ObjChild0Equiv(pObj), pObj->Init ); pEquiv0 = Ivy_ObjChild0Equiv(pObj); pEquiv0 = Ivy_NotCond( Ivy_HaigObjRepr(Ivy_Regular(pEquiv0)), Ivy_IsComplement(pEquiv0) ); - pObj->pEquiv = Ivy_Latch( p->pHaig, pEquiv0, pObj->Init ); + pObj->pEquiv = Ivy_Latch( p->pHaig, pEquiv0, (Ivy_Init_t)pObj->Init ); } else if ( Ivy_ObjType(pObj) == IVY_AND ) { @@ -469,7 +472,7 @@ printf( "Collected node %d with fanins %d and %d\n", pObj->Id, Ivy_ObjFanin0(pOb Ivy_ManForEachNodeVec( p, vLatches, pObj, i ) pObj->Init = IVY_INIT_DC; // set the latches of D to be determinate - vLatchesD = p->pData; + vLatchesD = (Vec_Int_t *)p->pData; Ivy_ManForEachNodeVec( p, vLatchesD, pObj, i ) pObj->Init = IVY_INIT_0; @@ -487,21 +490,21 @@ printf( "Collected node %d with fanins %d and %d\n", pObj->Id, Ivy_ObjFanin0(pOb { if ( fVerbose ) printf( "Processing node %d with fanins %d and %d\n", pObj->Id, Ivy_ObjFanin0(pObj)->Id, Ivy_ObjFanin1(pObj)->Id ); - In0 = Ivy_InitNotCond( Ivy_ObjFanin0(pObj)->Init, Ivy_ObjFaninC0(pObj) ); - In1 = Ivy_InitNotCond( Ivy_ObjFanin1(pObj)->Init, Ivy_ObjFaninC1(pObj) ); + In0 = Ivy_InitNotCond( (Ivy_Init_t)Ivy_ObjFanin0(pObj)->Init, Ivy_ObjFaninC0(pObj) ); + In1 = Ivy_InitNotCond( (Ivy_Init_t)Ivy_ObjFanin1(pObj)->Init, Ivy_ObjFaninC1(pObj) ); pObj->Init = Ivy_ManHaigSimulateAnd( In0, In1 ); // simulate the equivalence class if the node is a representative if ( pObj->pEquiv && Ivy_ObjRefs(pObj) > 0 ) { if ( fVerbose ) printf( "Processing choice node %d\n", pObj->Id ); - In0 = pObj->Init; + In0 = (Ivy_Init_t)pObj->Init; assert( !Ivy_IsComplement(pObj->pEquiv) ); for ( pTemp = pObj->pEquiv; pTemp != pObj; pTemp = Ivy_Regular(pTemp->pEquiv) ) { if ( fVerbose ) printf( "Processing secondary node %d\n", pTemp->Id ); - In1 = Ivy_InitNotCond( pTemp->Init, Ivy_IsComplement(pTemp->pEquiv) ); + In1 = Ivy_InitNotCond( (Ivy_Init_t)pTemp->Init, Ivy_IsComplement(pTemp->pEquiv) ); In0 = Ivy_ManHaigSimulateChoice( In0, In1 ); } pObj->Init = In0; @@ -528,3 +531,5 @@ printf( "Using latch %d with fanin %d\n", pObj->Id, Ivy_ObjFanin0(pObj)->Id ); //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ivy/ivyMan.c b/src/aig/ivy/ivyMan.c index 909548d1..6fa34144 100644 --- a/src/aig/ivy/ivyMan.c +++ b/src/aig/ivy/ivyMan.c @@ -20,6 +20,9 @@ #include "ivy.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -333,10 +336,10 @@ int Ivy_ManCleanupSeq( Ivy_Man_t * p ) return 0; } // disconnect the marked objects - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vNodes, pObj, i ) Ivy_ObjDisconnect( p, pObj ); // remove the dangling objects - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vNodes, pObj, i ) { assert( Ivy_ObjIsNode(pObj) || Ivy_ObjIsLatch(pObj) || Ivy_ObjIsBuf(pObj) ); assert( Ivy_ObjRefs(pObj) == 0 ); @@ -416,7 +419,7 @@ int Ivy_ManPropagateBuffers( Ivy_Man_t * p, int fUpdateLevel ) int nSteps; for ( nSteps = 0; Vec_PtrSize(p->vBufs) > 0; nSteps++ ) { - pNode = Vec_PtrEntryLast(p->vBufs); + pNode = (Ivy_Obj_t *)Vec_PtrEntryLast(p->vBufs); while ( Ivy_ObjIsBuf(pNode) ) pNode = Ivy_ObjReadFirstFanout( p, pNode ); // check if this buffer should remain @@ -494,7 +497,7 @@ void Ivy_ManMakeSeq( Ivy_Man_t * p, int nLatches, int * pInits ) for ( i = 0; i < nLatches; i++ ) { // get the latch value - Init = pInits? pInits[i] : IVY_INIT_0; + Init = pInits? (Ivy_Init_t)pInits[i] : IVY_INIT_0; // create latch pObj = Ivy_ManPo( p, Ivy_ManPoNum(p) - nLatches + i ); pLatch = Ivy_Latch( p, Ivy_ObjChild0(pObj), Init ); @@ -545,3 +548,5 @@ void Ivy_ManMakeSeq( Ivy_Man_t * p, int nLatches, int * pInits ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ivy/ivyMem.c b/src/aig/ivy/ivyMem.c index 4ea6d891..d5e6e545 100644 --- a/src/aig/ivy/ivyMem.c +++ b/src/aig/ivy/ivyMem.c @@ -20,6 +20,9 @@ #include "ivy.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -64,7 +67,7 @@ void Ivy_ManStopMemory( Ivy_Man_t * p ) { void * pMemory; int i; - Vec_PtrForEachEntry( p->vChunks, pMemory, i ) + Vec_PtrForEachEntry( void *, p->vChunks, pMemory, i ) ABC_FREE( pMemory ); Vec_PtrFree( p->vChunks ); Vec_PtrFree( p->vPages ); @@ -114,3 +117,5 @@ void Ivy_ManAddMemory( Ivy_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ivy/ivyMulti.c b/src/aig/ivy/ivyMulti.c index 882c2c87..c137a659 100644 --- a/src/aig/ivy/ivyMulti.c +++ b/src/aig/ivy/ivyMulti.c @@ -20,6 +20,9 @@ #include "ivy.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -74,7 +77,7 @@ int Ivy_MultiPlus( Ivy_Man_t * p, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone, Ivy_Ty // set the leaf entries uMaskAll = ((1 << nLeaves) - 1); nEvals = 0; - Vec_PtrForEachEntry( vLeaves, pObj, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vLeaves, pObj, i ) { pEval = pEvals + nEvals; pEval->pArg = pObj; @@ -86,7 +89,7 @@ int Ivy_MultiPlus( Ivy_Man_t * p, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone, Ivy_Ty } // propagate masks through the cone - Vec_PtrForEachEntry( vCone, pObj, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vCone, pObj, i ) { pObj->TravId = nEvals + i; if ( Ivy_ObjIsBuf(pObj) ) @@ -96,7 +99,7 @@ int Ivy_MultiPlus( Ivy_Man_t * p, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone, Ivy_Ty } // set the internal entries - Vec_PtrForEachEntry( vCone, pObj, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vCone, pObj, i ) { if ( i == Vec_PtrSize(vCone) - 1 ) break; @@ -129,7 +132,7 @@ int Ivy_MultiPlus( Ivy_Man_t * p, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone, Ivy_Ty continue; // skip the leaves for ( x = 0; x < nLeaves; x++ ) - if ( pTemp == Ivy_Regular(vLeaves->pArray[x]) ) + if ( pTemp == Ivy_Regular((Ivy_Obj_t *)vLeaves->pArray[x]) ) break; if ( x < nLeaves ) continue; @@ -305,3 +308,5 @@ int Ivy_MultiCover( Ivy_Man_t * p, Ivy_Eva_t * pEvals, int nLeaves, int nEvals, //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ivy/ivyMulti8.c b/src/aig/ivy/ivyMulti8.c index 059d1500..23af0e38 100644 --- a/src/aig/ivy/ivyMulti8.c +++ b/src/aig/ivy/ivyMulti8.c @@ -20,6 +20,9 @@ #include "ivy.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -425,3 +428,5 @@ Ivy_Obj_t * Ivy_Multi2( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ivy/ivyObj.c b/src/aig/ivy/ivyObj.c index 59dda19c..becf69d1 100644 --- a/src/aig/ivy/ivyObj.c +++ b/src/aig/ivy/ivyObj.c @@ -20,6 +20,9 @@ #include "ivy.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -474,3 +477,5 @@ void Ivy_NodeFixBufferFanins( Ivy_Man_t * p, Ivy_Obj_t * pNode, int fUpdateLevel //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ivy/ivyOper.c b/src/aig/ivy/ivyOper.c index 8115ce4f..ea61924d 100644 --- a/src/aig/ivy/ivyOper.c +++ b/src/aig/ivy/ivyOper.c @@ -20,6 +20,9 @@ #include "ivy.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -265,7 +268,7 @@ Ivy_Obj_t * Ivy_Miter( Ivy_Man_t * p, Vec_Ptr_t * vPairs ) assert( vPairs->nSize % 2 == 0 ); // go through the cubes of the node's SOP for ( i = 0; i < vPairs->nSize; i += 2 ) - vPairs->pArray[i/2] = Ivy_Not( Ivy_Exor( p, vPairs->pArray[i], vPairs->pArray[i+1] ) ); + vPairs->pArray[i/2] = Ivy_Not( Ivy_Exor( p, (Ivy_Obj_t *)vPairs->pArray[i], (Ivy_Obj_t *)vPairs->pArray[i+1] ) ); vPairs->nSize = vPairs->nSize/2; return Ivy_Not( Ivy_Multi_rec( p, (Ivy_Obj_t **)vPairs->pArray, vPairs->nSize, IVY_AND ) ); } @@ -291,3 +294,5 @@ Ivy_Obj_t * Ivy_Latch( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Init_t Init ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ivy/ivyResyn.c b/src/aig/ivy/ivyResyn.c index 35ecb122..8d571110 100644 --- a/src/aig/ivy/ivyResyn.c +++ b/src/aig/ivy/ivyResyn.c @@ -20,6 +20,9 @@ #include "ivy.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -194,3 +197,5 @@ if ( fVerbose ) Ivy_ManPrintStats( pMan ); //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ivy/ivyRwr.c b/src/aig/ivy/ivyRwr.c index af425079..b7cb500c 100644 --- a/src/aig/ivy/ivyRwr.c +++ b/src/aig/ivy/ivyRwr.c @@ -22,6 +22,9 @@ #include "deco.h" #include "rwt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -83,14 +86,14 @@ int Ivy_ManRewritePre( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost, int fV nGain = Ivy_NodeRewrite( p, pManRwt, pNode, fUpdateLevel, fUseZeroCost ); if ( nGain > 0 || (nGain == 0 && fUseZeroCost) ) { - Dec_Graph_t * pGraph = Rwt_ManReadDecs(pManRwt); + Dec_Graph_t * pGraph = (Dec_Graph_t *)Rwt_ManReadDecs(pManRwt); int fCompl = Rwt_ManReadCompl(pManRwt); /* { Ivy_Obj_t * pObj; int i; printf( "USING: (" ); - Vec_PtrForEachEntry( Rwt_ManReadLeaves(pManRwt), pObj, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, Rwt_ManReadLeaves(pManRwt), pObj, i ) printf( "%d ", Ivy_ObjFanoutNum(Ivy_Regular(pObj)) ); printf( ") Gain = %d.\n", nGain ); } @@ -208,18 +211,18 @@ p->timeTruth += clock() - clk2; clk2 = clock(); /* printf( "Considering: (" ); - Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, p->vFaninsCur, pFanin, i ) printf( "%d ", Ivy_ObjFanoutNum(Ivy_Regular(pFanin)) ); printf( ")\n" ); */ // mark the fanin boundary - Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, p->vFaninsCur, pFanin, i ) Ivy_ObjRefsInc( Ivy_Regular(pFanin) ); // label MFFC with current ID Ivy_ManIncrementTravId( pMan ); nNodesSaved = Ivy_ObjMffcLabel( pMan, pNode ); // unmark the fanin boundary - Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, p->vFaninsCur, pFanin, i ) Ivy_ObjRefsDec( Ivy_Regular(pFanin) ); p->timeMffc += clock() - clk2; @@ -239,7 +242,7 @@ p->timeEval += clock() - clk2; uTruthBest = uTruth; // collect fanins in the Vec_PtrClear( p->vFanins ); - Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, p->vFaninsCur, pFanin, i ) Vec_PtrPush( p->vFanins, pFanin ); } } @@ -257,7 +260,7 @@ p->timeRes += clock() - clk; else { printf( "Node %d : ", pNode->Id ); - Vec_PtrForEachEntry( p->vFanins, pFanin, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, p->vFanins, pFanin, i ) printf( "%d ", Ivy_Regular(pFanin)->Id ); printf( "a" ); } @@ -272,8 +275,8 @@ p->timeRes += clock() - clk; */ // copy the leaves - Vec_PtrForEachEntry( p->vFanins, pFanin, i ) - Dec_GraphNode(p->pGraph, i)->pFunc = pFanin; + Vec_PtrForEachEntry( Ivy_Obj_t *, p->vFanins, pFanin, i ) + Dec_GraphNode((Dec_Graph_t *)p->pGraph, i)->pFunc = pFanin; p->nScores[p->pMap[uTruthBest]]++; p->nNodesGained += GainBest; @@ -288,7 +291,7 @@ p->timeRes += clock() - clk; printf( "Save = %d. ", nNodesSaveCur ); printf( "Add = %d. ", nNodesSaveCur-GainBest ); printf( "GAIN = %d. ", GainBest ); - printf( "Cone = %d. ", p->pGraph? Dec_GraphNodeNum(p->pGraph) : 0 ); + printf( "Cone = %d. ", p->pGraph? Dec_GraphNodeNum((Dec_Graph_t *)p->pGraph) : 0 ); printf( "Class = %d. ", p->pMap[uTruthBest] ); printf( "\n" ); } @@ -363,16 +366,16 @@ Dec_Graph_t * Rwt_CutEvaluate( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pRoo Rwt_Node_t * pNode, * pFanin; int nNodesAdded, GainBest, i, k; // find the matching class of subgraphs - vSubgraphs = Vec_VecEntry( p->vClasses, p->pMap[uTruth] ); + vSubgraphs = (Vec_Ptr_t *)Vec_VecEntry( p->vClasses, p->pMap[uTruth] ); p->nSubgraphs += vSubgraphs->nSize; // determine the best subgraph GainBest = -1; - Vec_PtrForEachEntry( vSubgraphs, pNode, i ) + Vec_PtrForEachEntry( Rwt_Node_t *, vSubgraphs, pNode, i ) { // get the current graph pGraphCur = (Dec_Graph_t *)pNode->pNext; // copy the leaves - Vec_PtrForEachEntry( vFaninsCur, pFanin, k ) + Vec_PtrForEachEntry( Rwt_Node_t *, vFaninsCur, pFanin, k ) Dec_GraphNode(pGraphCur, k)->pFunc = pFanin; // detect how many unlabeled nodes will be reused nNodesAdded = Ivy_GraphToNetworkCount( pMan, pRoot, pGraphCur, nNodesSaved, LevelMax ); @@ -417,7 +420,7 @@ int Ivy_GraphToNetworkCount( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pGr return 0; // set the levels of the leaves Dec_GraphForEachLeaf( pGraph, pNode, i ) - pNode->Level = Ivy_Regular(pNode->pFunc)->Level; + pNode->Level = Ivy_Regular((Ivy_Obj_t *)pNode->pFunc)->Level; // compute the AIG size after adding the internal nodes Counter = 0; Dec_GraphForEachNode( pGraph, pNode, i ) @@ -426,8 +429,8 @@ int Ivy_GraphToNetworkCount( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pGr pNode0 = Dec_GraphNode( pGraph, pNode->eEdge0.Node ); pNode1 = Dec_GraphNode( pGraph, pNode->eEdge1.Node ); // get the AIG nodes corresponding to the children - pAnd0 = pNode0->pFunc; - pAnd1 = pNode1->pFunc; + pAnd0 = (Ivy_Obj_t *)pNode0->pFunc; + pAnd1 = (Ivy_Obj_t *)pNode1->pFunc; if ( pAnd0 && pAnd1 ) { // if they are both present, find the resulting node @@ -489,16 +492,16 @@ Ivy_Obj_t * Ivy_GraphToNetwork( Ivy_Man_t * p, Dec_Graph_t * pGraph ) return Ivy_NotCond( Ivy_ManConst1(p), Dec_GraphIsComplement(pGraph) ); // check for a literal if ( Dec_GraphIsVar(pGraph) ) - return Ivy_NotCond( Dec_GraphVar(pGraph)->pFunc, Dec_GraphIsComplement(pGraph) ); + return Ivy_NotCond( (Ivy_Obj_t *)Dec_GraphVar(pGraph)->pFunc, Dec_GraphIsComplement(pGraph) ); // build the AIG nodes corresponding to the AND gates of the graph Dec_GraphForEachNode( pGraph, pNode, i ) { - pAnd0 = Ivy_NotCond( Dec_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl ); - pAnd1 = Ivy_NotCond( Dec_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl ); + pAnd0 = Ivy_NotCond( (Ivy_Obj_t *)Dec_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl ); + pAnd1 = Ivy_NotCond( (Ivy_Obj_t *)Dec_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl ); pNode->pFunc = Ivy_And( p, pAnd0, pAnd1 ); } // complement the result if necessary - return Ivy_NotCond( pNode->pFunc, Dec_GraphIsComplement(pGraph) ); + return Ivy_NotCond( (Ivy_Obj_t *)pNode->pFunc, Dec_GraphIsComplement(pGraph) ); } /**Function************************************************************* @@ -561,7 +564,7 @@ void Ivy_GraphUpdateNetwork3( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pG //printf( "Before = %d. ", Ivy_ManNodeNum(p) ); // mark the cut - Vec_PtrForEachEntry( ((Rwt_Man_t *)p->pData)->vFanins, pFanin, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, ((Rwt_Man_t *)p->pData)->vFanins, pFanin, i ) Ivy_ObjRefsInc( Ivy_Regular(pFanin) ); // deref the old cone nRefsOld = pRoot->nRefs; @@ -569,7 +572,7 @@ void Ivy_GraphUpdateNetwork3( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pG Ivy_ObjDelete_rec( p, pRoot, 0 ); pRoot->nRefs = nRefsOld; // unmark the cut - Vec_PtrForEachEntry( ((Rwt_Man_t *)p->pData)->vFanins, pFanin, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, ((Rwt_Man_t *)p->pData)->vFanins, pFanin, i ) Ivy_ObjRefsDec( Ivy_Regular(pFanin) ); //printf( "Deref = %d. ", Ivy_ManNodeNum(p) ); @@ -591,7 +594,7 @@ void Ivy_GraphUpdateNetwork3( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pG //printf( "Replace = %d. ", Ivy_ManNodeNum(p) ); // delete remaining dangling nodes - Vec_PtrForEachEntry( ((Rwt_Man_t *)p->pData)->vFanins, pFanin, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, ((Rwt_Man_t *)p->pData)->vFanins, pFanin, i ) { pFanin = Ivy_Regular(pFanin); if ( !Ivy_ObjIsNone(pFanin) && Ivy_ObjRefs(pFanin) == 0 ) @@ -611,3 +614,5 @@ void Ivy_GraphUpdateNetwork3( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pG //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ivy/ivyRwrAlg.c b/src/aig/ivy/ivyRwrAlg.c index fc48deb0..ce605003 100644 --- a/src/aig/ivy/ivyRwrAlg.c +++ b/src/aig/ivy/ivyRwrAlg.c @@ -20,6 +20,9 @@ #include "ivy.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -136,7 +139,7 @@ Ivy_Obj_t * Ivy_NodeRewriteAlg( Ivy_Obj_t * pObj, Vec_Ptr_t * vFront, Vec_Ptr_t /* printf( "%d ", Vec_PtrSize(vFront) ); printf( "( " ); - Vec_PtrForEachEntry( vFront, pTemp, k ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vFront, pTemp, k ) printf( "%d ", Ivy_ObjRefs(Ivy_Regular(pTemp)) ); printf( ")\n" ); */ @@ -147,7 +150,7 @@ Ivy_Obj_t * Ivy_NodeRewriteAlg( Ivy_Obj_t * pObj, Vec_Ptr_t * vFront, Vec_Ptr_t Ivy_ManCollectCone( pObj, vLeaves, vCone ); // deref nodes in the cone - Vec_PtrForEachEntry( vCone, pTemp, k ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vCone, pTemp, k ) { Ivy_ObjRefsDec( Ivy_ObjFanin0(pTemp) ); Ivy_ObjRefsDec( Ivy_ObjFanin1(pTemp) ); @@ -155,27 +158,27 @@ Ivy_Obj_t * Ivy_NodeRewriteAlg( Ivy_Obj_t * pObj, Vec_Ptr_t * vFront, Vec_Ptr_t } // count the MFFC size - Vec_PtrForEachEntry( vFront, pTemp, k ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vFront, pTemp, k ) Ivy_Regular(pTemp)->fMarkA = 1; nMffc = Ivy_NodeCountMffc( pObj ); - Vec_PtrForEachEntry( vFront, pTemp, k ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vFront, pTemp, k ) Ivy_Regular(pTemp)->fMarkA = 0; if ( fVerbose ) { Counter = 0; - Vec_PtrForEachEntry( vCone, pTemp, k ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vCone, pTemp, k ) Counter += (Ivy_ObjRefs(pTemp) > 0); printf( "%5d : Leaves = %2d. Cone = %2d. ConeRef = %2d. Mffc = %d. Lev = %d. LevR = %d.\n", pObj->Id, Vec_PtrSize(vFront), Vec_PtrSize(vCone), Counter-1, nMffc, Ivy_ObjLevel(pObj), LevelR ); } /* printf( "Leaves:" ); - Vec_PtrForEachEntry( vLeaves, pTemp, k ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vLeaves, pTemp, k ) printf( " %d%s", Ivy_Regular(pTemp)->Id, Ivy_IsComplement(pTemp)? "\'" : "" ); printf( "\n" ); printf( "Cone:\n" ); - Vec_PtrForEachEntry( vCone, pTemp, k ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vCone, pTemp, k ) printf( " %5d = %d%s %d%s\n", pTemp->Id, Ivy_ObjFaninId0(pTemp), Ivy_ObjFaninC0(pTemp)? "\'" : "", Ivy_ObjFaninId1(pTemp), Ivy_ObjFaninC1(pTemp)? "\'" : "" ); @@ -184,7 +187,7 @@ Ivy_Obj_t * Ivy_NodeRewriteAlg( Ivy_Obj_t * pObj, Vec_Ptr_t * vFront, Vec_Ptr_t RetValue = Ivy_MultiPlus( vLeaves, vCone, Ivy_ObjType(pObj), nMffc + fUseZeroCost, vSols ); // ref nodes in the cone - Vec_PtrForEachEntry( vCone, pTemp, k ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vCone, pTemp, k ) { Ivy_ObjRefsInc( Ivy_ObjFanin0(pTemp) ); Ivy_ObjRefsInc( Ivy_ObjFanin1(pTemp) ); @@ -356,7 +359,7 @@ int Ivy_ManFindAlgCut( Ivy_Obj_t * pRoot, Vec_Ptr_t * vFront, Vec_Ptr_t * vLeave Vec_PtrClear( vLeaves ); RetValue = Ivy_ManFindAlgCut_rec( pRoot, Ivy_ObjType(pRoot), vFront, vCone ); // clean the marks - Vec_PtrForEachEntry( vCone, pObj, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vCone, pObj, i ) pObj->fMarkA = pObj->fMarkB = 0; // quit if the same node is found in both polarities if ( RetValue == -1 ) @@ -368,11 +371,11 @@ int Ivy_ManFindAlgCut( Ivy_Obj_t * pRoot, Vec_Ptr_t * vFront, Vec_Ptr_t * vLeave if ( Vec_PtrSize(vFront) <= 2 ) return 1; // sort the entries in increasing order - Vec_PtrSort( vFront, Ivy_ManFindAlgCutCompare ); + Vec_PtrSort( vFront, (int (*)(void))Ivy_ManFindAlgCutCompare ); // remove duplicates from vFront and save the nodes in vLeaves pPrev = Vec_PtrEntry(vFront, 0); Vec_PtrPush( vLeaves, pPrev ); - Vec_PtrForEachEntryStart( vFront, pObj, i, 1 ) + Vec_PtrForEachEntryStart( Ivy_Obj_t *, vFront, pObj, i, 1 ) { // compare current entry and the previous entry if ( pObj == pPrev ) @@ -406,3 +409,5 @@ int Ivy_ManFindAlgCut( Ivy_Obj_t * pRoot, Vec_Ptr_t * vFront, Vec_Ptr_t * vLeave //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ivy/ivySeq.c b/src/aig/ivy/ivySeq.c index 0971a548..69d05463 100644 --- a/src/aig/ivy/ivySeq.c +++ b/src/aig/ivy/ivySeq.c @@ -22,6 +22,9 @@ #include "deco.h" #include "rwt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -93,7 +96,7 @@ int Ivy_ManRewriteSeq( Ivy_Man_t * p, int fUseZeroCost, int fVerbose ) nGain = Ivy_NodeRewriteSeq( p, pManRwt, pNode, fUseZeroCost ); if ( nGain > 0 || (nGain == 0 && fUseZeroCost) ) { - Dec_Graph_t * pGraph = Rwt_ManReadDecs(pManRwt); + Dec_Graph_t * pGraph = (Dec_Graph_t *)Rwt_ManReadDecs(pManRwt); int fCompl = Rwt_ManReadCompl(pManRwt); // complement the FF if needed clk = clock(); @@ -199,7 +202,7 @@ p->timeTruth += clock() - clk2; } clk2 = clock(); // mark the fanin boundary - Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, p->vFaninsCur, pFanin, i ) Ivy_ObjRefsInc( Ivy_Regular(pFanin) ); // label MFFC with current ID Ivy_ManIncrementTravId( pMan ); @@ -208,7 +211,7 @@ clk2 = clock(); // Ivy_ObjForEachFanout( pMan, pNode, vFanout, pFanout, i ) // Ivy_ObjSetTravIdCurrent( pMan, pFanout ); // unmark the fanin boundary - Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, p->vFaninsCur, pFanin, i ) Ivy_ObjRefsDec( Ivy_Regular(pFanin) ); p->timeMffc += clock() - clk2; @@ -231,7 +234,7 @@ p->timeEval += clock() - clk2; uTruthBest = uTruth; // collect fanins in the Vec_PtrClear( p->vFanins ); - Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, p->vFaninsCur, pFanin, i ) Vec_PtrPush( p->vFanins, pFanin ); } } @@ -260,7 +263,7 @@ p->timeRes += clock() - clk; // nMovesS++; // copy the leaves - Ivy_GraphPrepare( p->pGraph, p->pCut, p->vFanins, p->pPerm ); + Ivy_GraphPrepare( (Dec_Graph_t *)p->pGraph, (Ivy_Cut_t *)p->pCut, p->vFanins, p->pPerm ); p->nScores[p->pMap[uTruthBest]]++; p->nNodesGained += GainBest; @@ -286,7 +289,7 @@ p->timeRes += clock() - clk; printf( "Save = %d. ", nNodesSaveCur ); printf( "Add = %d. ", nNodesSaveCur-GainBest ); printf( "GAIN = %d. ", GainBest ); - printf( "Cone = %d. ", p->pGraph? Dec_GraphNodeNum(p->pGraph) : 0 ); + printf( "Cone = %d. ", p->pGraph? Dec_GraphNodeNum((Dec_Graph_t *)p->pGraph) : 0 ); printf( "Class = %d. ", p->pMap[uTruthBest] ); printf( "\n" ); } @@ -313,11 +316,11 @@ Dec_Graph_t * Rwt_CutEvaluateSeq( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * p Rwt_Node_t * pNode; int nNodesAdded, GainBest, i; // find the matching class of subgraphs - vSubgraphs = Vec_VecEntry( p->vClasses, p->pMap[uTruth] ); + vSubgraphs = (Vec_Ptr_t *)Vec_VecEntry( p->vClasses, p->pMap[uTruth] ); p->nSubgraphs += vSubgraphs->nSize; // determine the best subgraph GainBest = -1; - Vec_PtrForEachEntry( vSubgraphs, pNode, i ) + Vec_PtrForEachEntry( Rwt_Node_t *, vSubgraphs, pNode, i ) { // get the current graph pGraphCur = (Dec_Graph_t *)pNode->pNext; @@ -325,7 +328,7 @@ Dec_Graph_t * Rwt_CutEvaluateSeq( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * p // if ( pRoot->Id == 8648 ) // Dec_GraphPrint( stdout, pGraphCur, NULL, NULL ); // copy the leaves -// Vec_PtrForEachEntry( vFaninsCur, pFanin, k ) +// Vec_PtrForEachEntry( Ivy_Obj_t *, vFaninsCur, pFanin, k ) // Dec_GraphNode(pGraphCur, k)->pFunc = pFanin; Ivy_GraphPrepare( pGraphCur, pCut, vFaninsCur, pPerm ); @@ -413,8 +416,8 @@ int Ivy_GraphToNetworkSeqCountSeq( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t pNode0 = Dec_GraphNode( pGraph, pNode->eEdge0.Node ); pNode1 = Dec_GraphNode( pGraph, pNode->eEdge1.Node ); // get the AIG nodes corresponding to the children - pAnd0 = pNode0->pFunc; - pAnd1 = pNode1->pFunc; + pAnd0 = (Ivy_Obj_t *)pNode0->pFunc; + pAnd1 = (Ivy_Obj_t *)pNode1->pFunc; // skip the latches for ( k = 0; pAnd0 && k < (int)pNode->nLat0; k++ ) { @@ -486,14 +489,14 @@ Ivy_Obj_t * Ivy_GraphToNetworkSeq( Ivy_Man_t * p, Dec_Graph_t * pGraph ) pNode = Dec_GraphVar(pGraph); // add the remaining latches for ( k = 0; k < (int)pNode->nLat2; k++ ) - pNode->pFunc = Ivy_Latch( p, pNode->pFunc, IVY_INIT_DC ); - return Ivy_NotCond( pNode->pFunc, Dec_GraphIsComplement(pGraph) ); + pNode->pFunc = Ivy_Latch( p, (Ivy_Obj_t *)pNode->pFunc, IVY_INIT_DC ); + return Ivy_NotCond( (Ivy_Obj_t *)pNode->pFunc, Dec_GraphIsComplement(pGraph) ); } // build the AIG nodes corresponding to the AND gates of the graph Dec_GraphForEachNode( pGraph, pNode, i ) { - pAnd0 = Ivy_NotCond( Dec_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl ); - pAnd1 = Ivy_NotCond( Dec_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl ); + pAnd0 = Ivy_NotCond( (Ivy_Obj_t *)Dec_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl ); + pAnd1 = Ivy_NotCond( (Ivy_Obj_t *)Dec_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl ); // add the latches for ( k = 0; k < (int)pNode->nLat0; k++ ) pAnd0 = Ivy_Latch( p, pAnd0, IVY_INIT_DC ); @@ -504,9 +507,9 @@ Ivy_Obj_t * Ivy_GraphToNetworkSeq( Ivy_Man_t * p, Dec_Graph_t * pGraph ) } // add the remaining latches for ( k = 0; k < (int)pNode->nLat2; k++ ) - pNode->pFunc = Ivy_Latch( p, pNode->pFunc, IVY_INIT_DC ); + pNode->pFunc = Ivy_Latch( p, (Ivy_Obj_t *)pNode->pFunc, IVY_INIT_DC ); // complement the result if necessary - return Ivy_NotCond( pNode->pFunc, Dec_GraphIsComplement(pGraph) ); + return Ivy_NotCond( (Ivy_Obj_t *)pNode->pFunc, Dec_GraphIsComplement(pGraph) ); } /**Function************************************************************* @@ -1135,3 +1138,5 @@ void Ivy_CutComputeAll( Ivy_Man_t * p, int nInputs ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ivy/ivyShow.c b/src/aig/ivy/ivyShow.c index 4fac2709..3aa1e041 100644 --- a/src/aig/ivy/ivyShow.c +++ b/src/aig/ivy/ivyShow.c @@ -20,6 +20,9 @@ #include "ivy.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -94,7 +97,7 @@ void Ivy_WriteDotAig( Ivy_Man_t * pMan, char * pFileName, int fHaig, Vec_Ptr_t * // mark the nodes if ( vBold ) - Vec_PtrForEachEntry( vBold, pNode, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vBold, pNode, i ) pNode->fMarkB = 1; // compute levels @@ -326,7 +329,7 @@ void Ivy_WriteDotAig( Ivy_Man_t * pMan, char * pFileName, int fHaig, Vec_Ptr_t * // unmark nodes if ( vBold ) - Vec_PtrForEachEntry( vBold, pNode, i ) + Vec_PtrForEachEntry( Ivy_Obj_t *, vBold, pNode, i ) pNode->fMarkB = 0; } @@ -336,3 +339,5 @@ void Ivy_WriteDotAig( Ivy_Man_t * pMan, char * pFileName, int fHaig, Vec_Ptr_t * //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ivy/ivyTable.c b/src/aig/ivy/ivyTable.c index fdcc4bfb..0fe5c7ba 100644 --- a/src/aig/ivy/ivyTable.c +++ b/src/aig/ivy/ivyTable.c @@ -20,6 +20,9 @@ #include "ivy.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -299,3 +302,5 @@ unsigned int Cudd_PrimeAig( unsigned int p) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ivy/ivyUtil.c b/src/aig/ivy/ivyUtil.c index ab62a276..4df67517 100644 --- a/src/aig/ivy/ivyUtil.c +++ b/src/aig/ivy/ivyUtil.c @@ -20,6 +20,9 @@ #include "ivy.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -816,3 +819,5 @@ int Ivy_CutTruthPrint( Ivy_Man_t * p, Ivy_Cut_t * pCut, unsigned uTruth ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ivy/ivy_.c b/src/aig/ivy/ivy_.c index 65689689..ccad8a46 100644 --- a/src/aig/ivy/ivy_.c +++ b/src/aig/ivy/ivy_.c @@ -20,6 +20,9 @@ #include "ivy.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -46,3 +49,5 @@ //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/kit/cloud.c b/src/aig/kit/cloud.c index dc57e2b7..fd372970 100644 --- a/src/aig/kit/cloud.c +++ b/src/aig/kit/cloud.c @@ -18,6 +18,9 @@ #include "cloud.h" +ABC_NAMESPACE_IMPL_START + + // the number of operators using cache static int CacheOperNum = 4; @@ -985,3 +988,5 @@ void Cloud_PrintHashTable( CloudManager * dd ) /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/kit/cloud.h b/src/aig/kit/cloud.h index 6f6a1eae..c48b55de 100644 --- a/src/aig/kit/cloud.h +++ b/src/aig/kit/cloud.h @@ -19,15 +19,18 @@ #ifndef __CLOUD_H__ #define __CLOUD_H__ + #include <stdio.h> #include <stdlib.h> #include <assert.h> #include <time.h> + #include "abc_global.h" -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + #ifdef _WIN32 #define inline __inline // compatible with MS VS 6.0 @@ -239,9 +242,11 @@ extern CloudNode * Cloud_bddOr( CloudManager * dd, CloudNode * f, CloudNode * extern void Cloud_PrintInfo( CloudManager * dd ); extern void Cloud_PrintHashTable( CloudManager * dd ); -#ifdef __cplusplus -} -#endif + + +ABC_NAMESPACE_HEADER_END + + #endif diff --git a/src/aig/kit/kit.h b/src/aig/kit/kit.h index 3b564da5..f1075c2f 100644 --- a/src/aig/kit/kit.h +++ b/src/aig/kit/kit.h @@ -21,6 +21,7 @@ #ifndef __KIT_H__ #define __KIT_H__ + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -38,9 +39,10 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -197,8 +199,10 @@ static inline void Kit_SopWriteCube( Kit_Sop_t * cSop, unsigned uCube, i static inline Kit_Edge_t Kit_EdgeCreate( int Node, int fCompl ) { Kit_Edge_t eEdge = { fCompl, Node }; return eEdge; } static inline unsigned Kit_EdgeToInt( Kit_Edge_t eEdge ) { return (eEdge.Node << 1) | eEdge.fCompl; } static inline Kit_Edge_t Kit_IntToEdge( unsigned Edge ) { return Kit_EdgeCreate( Edge >> 1, Edge & 1 ); } -static inline unsigned Kit_EdgeToInt_( Kit_Edge_t eEdge ) { return *(unsigned *)&eEdge; } -static inline Kit_Edge_t Kit_IntToEdge_( unsigned Edge ) { return *(Kit_Edge_t *)&Edge; } +//static inline unsigned Kit_EdgeToInt_( Kit_Edge_t eEdge ) { return *(unsigned *)&eEdge; } +//static inline Kit_Edge_t Kit_IntToEdge_( unsigned Edge ) { return *(Kit_Edge_t *)&Edge; } +static inline unsigned Kit_EdgeToInt_( Kit_Edge_t m ) { union { Kit_Edge_t x; unsigned y; } v; v.x = m; return v.y; } +static inline Kit_Edge_t Kit_IntToEdge_( unsigned m ) { union { Kit_Edge_t x; unsigned y; } v; v.y = m; return v.x; } static inline int Kit_GraphIsConst( Kit_Graph_t * pGraph ) { return pGraph->fConst; } static inline int Kit_GraphIsConst0( Kit_Graph_t * pGraph ) { return pGraph->fConst && pGraph->eRoot.fCompl; } @@ -219,8 +223,12 @@ static inline Kit_Node_t * Kit_GraphNodeFanin0( Kit_Graph_t * pGraph, Kit_Node_t static inline Kit_Node_t * Kit_GraphNodeFanin1( Kit_Graph_t * pGraph, Kit_Node_t * pNode ){ return Kit_GraphNodeIsVar(pGraph, pNode)? NULL : Kit_GraphNode(pGraph, pNode->eEdge1.Node); } static inline int Kit_GraphRootLevel( Kit_Graph_t * pGraph ) { return Kit_GraphNode(pGraph, pGraph->eRoot.Node)->Level; } -static inline int Kit_Float2Int( float Val ) { return *((int *)&Val); } -static inline float Kit_Int2Float( int Num ) { return *((float *)&Num); } +static inline int Kit_SuppIsMinBase( int Supp ) { return (Supp & (Supp+1)) == 0; } + +//static inline int Kit_Float2Int( float Val ) { return *((int *)&Val); } +//static inline float Kit_Int2Float( int Num ) { return *((float *)&Num); } +static inline int Kit_Float2Int( float Val ) { union { int x; float y; } v; v.y = Val; return v.x; } +static inline float Kit_Int2Float( int Num ) { union { int x; float y; } v; v.x = Num; return v.y; } static inline int Kit_BitWordNum( int nBits ) { return nBits/(8*sizeof(unsigned)) + ((nBits%(8*sizeof(unsigned))) > 0); } static inline int Kit_TruthWordNum( int nVars ) { return nVars <= 5 ? 1 : (1 << (nVars - 5)); } static inline unsigned Kit_BitMask( int nBits ) { assert( nBits <= 32 ); return ~((~(unsigned)0) << nBits); } @@ -280,6 +288,14 @@ static inline int Kit_TruthIsEqual( unsigned * pIn0, unsigned * pIn1, int nVars return 0; return 1; } +static inline int Kit_TruthIsEqualWithCare( unsigned * pIn0, unsigned * pIn1, unsigned * pCare, int nVars ) +{ + int w; + for ( w = Kit_TruthWordNum(nVars)-1; w >= 0; w-- ) + if ( (pIn0[w] & pCare[w]) != (pIn1[w] & pCare[w]) ) + return 0; + return 1; +} static inline int Kit_TruthIsOpposite( unsigned * pIn0, unsigned * pIn1, int nVars ) { int w; @@ -423,6 +439,30 @@ static inline void Kit_TruthAndPhase( unsigned * pOut, unsigned * pIn0, unsigned pOut[w] = pIn0[w] & pIn1[w]; } } +static inline void Kit_TruthOrPhase( unsigned * pOut, unsigned * pIn0, unsigned * pIn1, int nVars, int fCompl0, int fCompl1 ) +{ + int w; + if ( fCompl0 && fCompl1 ) + { + for ( w = Kit_TruthWordNum(nVars)-1; w >= 0; w-- ) + pOut[w] = ~(pIn0[w] & pIn1[w]); + } + else if ( fCompl0 && !fCompl1 ) + { + for ( w = Kit_TruthWordNum(nVars)-1; w >= 0; w-- ) + pOut[w] = ~pIn0[w] | pIn1[w]; + } + else if ( !fCompl0 && fCompl1 ) + { + for ( w = Kit_TruthWordNum(nVars)-1; w >= 0; w-- ) + pOut[w] = pIn0[w] | ~pIn1[w]; + } + else // if ( !fCompl0 && !fCompl1 ) + { + for ( w = Kit_TruthWordNum(nVars)-1; w >= 0; w-- ) + pOut[w] = pIn0[w] | pIn1[w]; + } +} static inline void Kit_TruthMux( unsigned * pOut, unsigned * pIn0, unsigned * pIn1, unsigned * pCtrl, int nVars ) { int w; @@ -547,7 +587,10 @@ extern char * Kit_PlaStart( void * p, int nCubes, int nVars ); extern char * Kit_PlaCreateFromIsop( void * p, int nVars, Vec_Int_t * vCover ); extern void Kit_PlaToIsop( char * pSop, Vec_Int_t * vCover ); extern char * Kit_PlaStoreSop( void * p, char * pSop ); -extern ABC_DLL char * Kit_PlaFromTruth( void * p, unsigned * pTruth, int nVars, Vec_Int_t * vCover ); +extern char * Kit_PlaFromTruth( void * p, unsigned * pTruth, int nVars, Vec_Int_t * vCover ); +extern char * Kit_PlaFromTruthNew( unsigned * pTruth, int nVars, Vec_Int_t * vCover, Vec_Str_t * vStr ); +extern ABC_UINT64_T Kit_PlaToTruth6( char * pSop, int nVars ); +extern void Kit_PlaToTruth( char * pSop, int nVars, Vec_Ptr_t * vVars, unsigned * pTemp, unsigned * pTruth ); /*=== kitSop.c ==========================================================*/ extern void Kit_SopCreate( Kit_Sop_t * cResult, Vec_Int_t * vInput, int nVars, Vec_Int_t * vMemory ); extern void Kit_SopCreateInverse( Kit_Sop_t * cResult, Vec_Int_t * vInput, int nVars, Vec_Int_t * vMemory ); @@ -584,6 +627,8 @@ extern void Kit_TruthUniqueNew( unsigned * pRes, unsigned * pTruth, i extern void Kit_TruthMuxVar( unsigned * pOut, unsigned * pCof0, unsigned * pCof1, int nVars, int iVar ); extern void Kit_TruthMuxVarPhase( unsigned * pOut, unsigned * pCof0, unsigned * pCof1, int nVars, int iVar, int fCompl0 ); extern void Kit_TruthChangePhase( unsigned * pTruth, int nVars, int iVar ); +extern int Kit_TruthVarsSymm( unsigned * pTruth, int nVars, int iVar0, int iVar1, unsigned * pCof0, unsigned * pCof1 ); +extern int Kit_TruthVarsAntiSymm( unsigned * pTruth, int nVars, int iVar0, int iVar1, unsigned * pCof0, unsigned * pCof1 ); extern int Kit_TruthMinCofSuppOverlap( unsigned * pTruth, int nVars, int * pVarMin ); extern int Kit_TruthBestCofVar( unsigned * pTruth, int nVars, unsigned * pCof0, unsigned * pCof1 ); extern void Kit_TruthCountOnesInCofs( unsigned * pTruth, int nVars, short * pStore ); @@ -592,10 +637,13 @@ extern void Kit_TruthCountOnesInCofsSlow( unsigned * pTruth, int nVar extern unsigned Kit_TruthHash( unsigned * pIn, int nWords ); extern unsigned Kit_TruthSemiCanonicize( unsigned * pInOut, unsigned * pAux, int nVars, char * pCanonPerm, short * pStore ); extern char * Kit_TruthDumpToFile( unsigned * pTruth, int nVars, int nFile ); +extern void Kit_TruthPrintProfile( unsigned * pTruth, int nVars ); + + + +ABC_NAMESPACE_HEADER_END + -#ifdef __cplusplus -} -#endif #endif diff --git a/src/aig/kit/kitAig.c b/src/aig/kit/kitAig.c index 83012a8c..88f17fc2 100644 --- a/src/aig/kit/kitAig.c +++ b/src/aig/kit/kitAig.c @@ -21,6 +21,9 @@ #include "kit.h" #include "aig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -50,16 +53,16 @@ Aig_Obj_t * Kit_GraphToAigInternal( Aig_Man_t * pMan, Kit_Graph_t * pGraph ) return Aig_NotCond( Aig_ManConst1(pMan), Kit_GraphIsComplement(pGraph) ); // check for a literal if ( Kit_GraphIsVar(pGraph) ) - return Aig_NotCond( Kit_GraphVar(pGraph)->pFunc, Kit_GraphIsComplement(pGraph) ); + return Aig_NotCond( (Aig_Obj_t *)Kit_GraphVar(pGraph)->pFunc, Kit_GraphIsComplement(pGraph) ); // build the AIG nodes corresponding to the AND gates of the graph Kit_GraphForEachNode( pGraph, pNode, i ) { - pAnd0 = Aig_NotCond( Kit_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl ); - pAnd1 = Aig_NotCond( Kit_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl ); + pAnd0 = Aig_NotCond( (Aig_Obj_t *)Kit_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl ); + pAnd1 = Aig_NotCond( (Aig_Obj_t *)Kit_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl ); pNode->pFunc = Aig_And( pMan, pAnd0, pAnd1 ); } // complement the result if necessary - return Aig_NotCond( pNode->pFunc, Kit_GraphIsComplement(pGraph) ); + return Aig_NotCond( (Aig_Obj_t *)pNode->pFunc, Kit_GraphIsComplement(pGraph) ); } /**Function************************************************************* @@ -119,3 +122,5 @@ Aig_Obj_t * Kit_TruthToAig( Aig_Man_t * pMan, Aig_Obj_t ** pFanins, unsigned * p //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/kit/kitBdd.c b/src/aig/kit/kitBdd.c index 75caf949..1b24ac24 100644 --- a/src/aig/kit/kitBdd.c +++ b/src/aig/kit/kitBdd.c @@ -21,6 +21,9 @@ #include "kit.h" #include "extra.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -111,13 +114,13 @@ DdNode * Kit_GraphToBdd( DdManager * dd, Kit_Graph_t * pGraph ) { bFunc0 = Cudd_NotCond( Kit_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl ); bFunc1 = Cudd_NotCond( Kit_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl ); - pNode->pFunc = Cudd_bddAnd( dd, bFunc0, bFunc1 ); Cudd_Ref( pNode->pFunc ); + pNode->pFunc = Cudd_bddAnd( dd, bFunc0, bFunc1 ); Cudd_Ref( (DdNode *)pNode->pFunc ); } // deref the intermediate results - bFunc = pNode->pFunc; Cudd_Ref( bFunc ); + bFunc = (DdNode *)pNode->pFunc; Cudd_Ref( bFunc ); Kit_GraphForEachNode( pGraph, pNode, i ) - Cudd_RecursiveDeref( dd, pNode->pFunc ); + Cudd_RecursiveDeref( dd, (DdNode *)pNode->pFunc ); Cudd_Deref( bFunc ); // complement the result if necessary @@ -229,3 +232,5 @@ int Kit_SopFactorVerify( Vec_Int_t * vCover, Kit_Graph_t * pFForm, int nVars ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/kit/kitCloud.c b/src/aig/kit/kitCloud.c index 525f89f5..dea56749 100644 --- a/src/aig/kit/kitCloud.c +++ b/src/aig/kit/kitCloud.c @@ -20,6 +20,9 @@ #include "kit.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -35,6 +38,9 @@ struct Kit_Mux_t_ unsigned i : 1; // complemented attr of top node }; +static inline int Kit_Mux2Int( Kit_Mux_t m ) { union { Kit_Mux_t x; int y; } v; v.x = m; return v.y; } +static inline Kit_Mux_t Kit_Int2Mux( int m ) { union { Kit_Mux_t x; int y; } v; v.y = m; return v.x; } + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -180,7 +186,7 @@ int Kit_CreateCloud( CloudManager * dd, CloudNode * pFunc, Vec_Int_t * vNodes ) Mux.c = Cloud_IsComplement(dd->ppNodes[i]->e); Mux.i = (i == nNodes - 1)? Cloud_IsComplement(pFunc) : 0; // put the MUX into the array - Vec_IntPush( vNodes, *((int *)&Mux) ); + Vec_IntPush( vNodes, Kit_Mux2Int(Mux) ); } assert( Vec_IntSize(vNodes) == nNodes ); // reset signatures @@ -226,15 +232,15 @@ unsigned * Kit_CloudToTruth( Vec_Int_t * vNodes, int nVars, Vec_Ptr_t * vStore, Kit_Mux_t Mux; int i, Entry; assert( Vec_IntSize(vNodes) <= Vec_PtrSize(vStore) ); - pThis = Vec_PtrEntry( vStore, 0 ); + pThis = (unsigned *)Vec_PtrEntry( vStore, 0 ); Kit_TruthFill( pThis, nVars ); Vec_IntForEachEntryStart( vNodes, Entry, i, 1 ) { - Mux = *((Kit_Mux_t *)&Entry); + Mux = Kit_Int2Mux(Entry); assert( (int)Mux.e < i && (int)Mux.t < i && (int)Mux.v < nVars ); - pFan0 = Vec_PtrEntry( vStore, Mux.e ); - pFan1 = Vec_PtrEntry( vStore, Mux.t ); - pThis = Vec_PtrEntry( vStore, i ); + pFan0 = (unsigned *)Vec_PtrEntry( vStore, Mux.e ); + pFan1 = (unsigned *)Vec_PtrEntry( vStore, Mux.t ); + pThis = (unsigned *)Vec_PtrEntry( vStore, i ); Kit_TruthMuxVarPhase( pThis, pFan0, pFan1, nVars, fInv? Mux.v : nVars-1-Mux.v, Mux.c ); } // complement the result @@ -274,14 +280,14 @@ unsigned * Kit_TruthCompose( CloudManager * dd, unsigned * pTruth, int nVars, // printf( "Failed!\n" ); // compute truth table from the BDD assert( Vec_IntSize(vNodes) <= Vec_PtrSize(vStore) ); - pThis = Vec_PtrEntry( vStore, 0 ); + pThis = (unsigned *)Vec_PtrEntry( vStore, 0 ); Kit_TruthFill( pThis, nVarsAll ); Vec_IntForEachEntryStart( vNodes, Entry, i, 1 ) { - Mux = *((Kit_Mux_t *)&Entry); - pFan0 = Vec_PtrEntry( vStore, Mux.e ); - pFan1 = Vec_PtrEntry( vStore, Mux.t ); - pThis = Vec_PtrEntry( vStore, i ); + Mux = Kit_Int2Mux(Entry); + pFan0 = (unsigned *)Vec_PtrEntry( vStore, Mux.e ); + pFan1 = (unsigned *)Vec_PtrEntry( vStore, Mux.t ); + pThis = (unsigned *)Vec_PtrEntry( vStore, i ); Kit_TruthMuxPhase( pThis, pFan0, pFan1, pInputs[nVars-1-Mux.v], nVarsAll, Mux.c ); } // complement the result @@ -319,7 +325,7 @@ void Kit_TruthCofSupports( Vec_Int_t * vBddDir, Vec_Int_t * vBddInv, int nVars, // compute supports from nodes Vec_IntForEachEntryStart( vBddDir, Entry, i, 1 ) { - Mux = *((Kit_Mux_t *)&Entry); + Mux = Kit_Int2Mux(Entry); Var = nVars - 1 - Mux.v; pFan0 = puSuppAll + nSupps * Mux.e; pFan1 = puSuppAll + nSupps * Mux.t; @@ -344,7 +350,7 @@ void Kit_TruthCofSupports( Vec_Int_t * vBddDir, Vec_Int_t * vBddInv, int nVars, // compute supports from nodes Vec_IntForEachEntryStart( vBddInv, Entry, i, 1 ) { - Mux = *((Kit_Mux_t *)&Entry); + Mux = Kit_Int2Mux(Entry); // Var = nVars - 1 - Mux.v; Var = Mux.v; pFan0 = puSuppAll + nSupps * Mux.e; @@ -368,3 +374,5 @@ void Kit_TruthCofSupports( Vec_Int_t * vBddDir, Vec_Int_t * vBddInv, int nVars, //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/kit/kitDec.c b/src/aig/kit/kitDec.c new file mode 100644 index 00000000..afc7ef6c --- /dev/null +++ b/src/aig/kit/kitDec.c @@ -0,0 +1,343 @@ +/**CFile**************************************************************** + + FileName [kitDec.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Computation kit.] + + Synopsis [Decomposition manager.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - November 18, 2009.] + + Revision [$Id: kitDec.c,v 1.00 2006/12/06 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "kit.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +// decomposition manager +typedef struct Kit_ManDec_t_ Kit_ManDec_t; +struct Kit_ManDec_t_ +{ + int nVarsMax; // the max number of variables + int nWordsMax; // the max number of words + Vec_Ptr_t * vTruthVars; // elementary truth tables + Vec_Ptr_t * vTruthNodes; // internal truth tables + // current problem + int nVarsIn; // the current number of variables + Vec_Int_t * vLutsIn; // LUT truth tables + Vec_Int_t * vSuppIn; // LUT supports + char ATimeIn[64]; // variable arrival times + // extracted information + unsigned * pTruthIn; // computed truth table + unsigned * pTruthOut; // computed truth table + int nVarsOut; // the current number of variables + int nWordsOut; // the current number of words + char Order[32]; // new vars into old vars after supp minimization + // computed information + Vec_Int_t * vLutsOut; // problem decomposition + Vec_Int_t * vSuppOut; // problem decomposition + char ATimeOut[64]; // variable arrival times +}; + +static inline int Kit_DecOuputArrival( int nVars, Vec_Int_t * vLuts, char ATimes[] ) { return ATimes[nVars + Vec_IntSize(vLuts) - 1]; } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Starts Decmetry manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Kit_ManDec_t * Kit_ManDecStart( int nVarsMax ) +{ + Kit_ManDec_t * p; + assert( nVarsMax <= 20 ); + p = ABC_CALLOC( Kit_ManDec_t, 1 ); + p->nVarsMax = nVarsMax; + p->nWordsMax = Kit_TruthWordNum( p->nVarsMax ); + p->vTruthVars = Vec_PtrAllocTruthTables( p->nVarsMax ); + p->vTruthNodes = Vec_PtrAllocSimInfo( 64, p->nWordsMax ); + p->vLutsIn = Vec_IntAlloc( 50 ); + p->vSuppIn = Vec_IntAlloc( 50 ); + p->vLutsOut = Vec_IntAlloc( 50 ); + p->vSuppOut = Vec_IntAlloc( 50 ); + p->pTruthIn = ABC_ALLOC( unsigned, p->nWordsMax ); + p->pTruthOut = ABC_ALLOC( unsigned, p->nWordsMax ); + return p; +} + +/**Function************************************************************* + + Synopsis [Stops Decmetry manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Kit_ManDecStop( Kit_ManDec_t * p ) +{ + ABC_FREE( p->pTruthIn ); + ABC_FREE( p->pTruthOut ); + Vec_IntFreeP( &p->vLutsIn ); + Vec_IntFreeP( &p->vSuppIn ); + Vec_IntFreeP( &p->vLutsOut ); + Vec_IntFreeP( &p->vSuppOut ); + Vec_PtrFreeP( &p->vTruthVars ); + Vec_PtrFreeP( &p->vTruthNodes ); + ABC_FREE( p ); +} + + +/**Function************************************************************* + + Synopsis [Deriving timing information for the decomposed structure.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Kit_DecComputeOuputArrival( int nVars, Vec_Int_t * vSupps, int LutSize, char ATimesIn[], char ATimesOut[] ) +{ + int i, v, iVar, nLuts, Delay; + nLuts = Vec_IntSize(vSupps) / LutSize; + assert( nLuts > 0 ); + assert( Vec_IntSize(vSupps) % LutSize == 0 ); + for ( v = 0; v < nVars; v++ ) + ATimesOut[v] = ATimesIn[v]; + for ( v = 0; v < nLuts; v++ ) + { + Delay = 0; + for ( i = 0; i < LutSize; i++ ) + { + iVar = Vec_IntEntry( vSupps, v * LutSize + i ); + assert( iVar < nVars + v ); + Delay = ABC_MAX( Delay, ATimesOut[iVar] ); + } + ATimesOut[nVars + v] = Delay + 1; + } + return ATimesOut[nVars + nLuts - 1]; +} + +/**Function************************************************************* + + Synopsis [Derives the truth table] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Kit_DecComputeTruthOne( int LutSize, unsigned * pTruthLut, int nVars, unsigned * pTruths[], unsigned * pTemp, unsigned * pRes ) +{ + int i, v; + Kit_TruthClear( pRes, nVars ); + for ( i = 0; i < (1<<LutSize); i++ ) + { + if ( !Kit_TruthHasBit( pTruthLut, i ) ) + continue; + Kit_TruthFill( pTemp, nVars ); + for ( v = 0; v < LutSize; v++ ) + if ( i & (1<<v) ) + Kit_TruthAnd( pTemp, pTemp, pTruths[v], nVars ); + else + Kit_TruthSharp( pTemp, pTemp, pTruths[v], nVars ); + Kit_TruthOr( pRes, pRes, pTemp, nVars ); + } +} + +/**Function************************************************************* + + Synopsis [Derives the truth table] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Kit_DecComputeTruth( Kit_ManDec_t * p, int nVars, Vec_Int_t * vSupps, int LutSize, Vec_Int_t * vLuts, unsigned * pRes ) +{ + unsigned * pResult, * pTruthLuts, * pTruths[17]; + int nTruthLutWords, i, v, iVar, nLuts; + nLuts = Vec_IntSize(vSupps) / LutSize; + pTruthLuts = Vec_IntArray( vLuts ); + nTruthLutWords = Kit_TruthWordNum( LutSize ); + assert( nLuts > 0 ); + assert( Vec_IntSize(vSupps) % LutSize == 0 ); + assert( nLuts * nTruthLutWords == Vec_IntSize(vLuts) ); + for ( v = 0; v < nLuts; v++ ) + { + for ( i = 0; i < LutSize; i++ ) + { + iVar = Vec_IntEntry( vSupps, v * LutSize + i ); + assert( iVar < nVars + v ); + pTruths[i] = (iVar < nVars)? Vec_PtrEntry(p->vTruthVars, iVar) : Vec_PtrEntry(p->vTruthNodes, iVar-nVars); + } + pResult = (v == nLuts - 1) ? pRes : Vec_PtrEntry(p->vTruthNodes, v); + Kit_DecComputeTruthOne( LutSize, pTruthLuts, nVars, pTruths, Vec_PtrEntry(p->vTruthNodes, v+1), pResult ); + pTruthLuts += nTruthLutWords; + } +} + +/**Function************************************************************* + + Synopsis [Derives the truth table] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Kit_DecComputePattern( int nVars, unsigned * pTruth, int LutSize, int Pattern[] ) +{ + int nCofs = (1 << LutSize); + int i, k, nMyu = 0; + assert( LutSize <= 6 ); + assert( LutSize < nVars ); + if ( nVars - LutSize <= 5 ) + { + unsigned uCofs[64]; + int nBits = (1 << (nVars - LutSize)); + for ( i = 0; i < nCofs; i++ ) + uCofs[i] = (pTruth[(i*nBits)/32] >> ((i*nBits)%32)) & ((1<<nBits)-1); + for ( i = 0; i < nCofs; i++ ) + { + for ( k = 0; k < nMyu; k++ ) + if ( uCofs[i] == uCofs[k] ) + { + Pattern[i] = k; + break; + } + if ( k == i ) + Pattern[nMyu++] = i; + } + } + else + { + unsigned * puCofs[64]; + int nWords = (1 << (nVars - LutSize - 5)); + for ( i = 0; i < nCofs; i++ ) + puCofs[i] = pTruth + nWords; + for ( i = 0; i < nCofs; i++ ) + { + for ( k = 0; k < nMyu; k++ ) + if ( Kit_TruthIsEqual( puCofs[i], puCofs[k], nVars - LutSize - 5 ) ) + { + Pattern[i] = k; + break; + } + if ( k == i ) + Pattern[nMyu++] = i; + } + } + return nMyu; +} + +/**Function************************************************************* + + Synopsis [Returns the number of shared variables.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Kit_DecComputeShared_rec( int Pattern[], int Vars[], int nVars, int Shared[], int iVarTry ) +{ + int Pat0[32], Pat1[32], Shared0[5], Shared1[5], VarsNext[5]; + int v, u, iVarsNext, iPat0, iPat1, m, nMints = (1 << nVars); + int nShared0, nShared1, nShared = 0; + for ( v = iVarTry; v < nVars; v++ ) + { + iVarsNext = 0; + for ( u = 0; u < nVars; u++ ) + if ( u == v ) + VarsNext[iVarsNext++] = Vars[u]; + iPat0 = iPat1 = 0; + for ( m = 0; m < nMints; m++ ) + if ( m & (1 << v) ) + Pat1[iPat1++] = m; + else + Pat0[iPat0++] = m; + assert( iPat0 == nMints / 2 ); + assert( iPat1 == nMints / 2 ); + nShared0 = Kit_DecComputeShared_rec( Pat0, VarsNext, nVars-1, Shared0, v + 1 ); + if ( nShared0 == 0 ) + continue; + nShared1 = Kit_DecComputeShared_rec( Pat1, VarsNext, nVars-1, Shared1, v + 1 ); + if ( nShared1 == 0 ) + continue; + Shared[nShared++] = v; + for ( u = 0; u < nShared0; u++ ) + for ( m = 0; m < nShared1; m++ ) + if ( Shared0[u] >= 0 && Shared1[m] >= 0 && Shared0[u] == Shared1[m] ) + { + Shared[nShared++] = Shared0[u]; + Shared0[u] = Shared1[m] = -1; + } + return nShared; + } + return 0; +} + +/**Function************************************************************* + + Synopsis [Returns the number of shared variables.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Kit_DecComputeShared( int Pattern[], int LutSize, int Shared[] ) +{ + int i, Vars[6]; + assert( LutSize <= 6 ); + for ( i = 0; i < LutSize; i++ ) + Vars[i] = i; + return Kit_DecComputeShared_rec( Pattern, Vars, LutSize, Shared, 0 ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/kit/kitDsd.c b/src/aig/kit/kitDsd.c index a85262a9..fbf92e48 100644 --- a/src/aig/kit/kitDsd.c +++ b/src/aig/kit/kitDsd.c @@ -20,6 +20,9 @@ #include "kit.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -268,7 +271,7 @@ void Kit_DsdPrint( FILE * pFile, Kit_DsdNtk_t * pNtk ) if ( Kit_DsdLitIsCompl(pNtk->Root) ) fprintf( pFile, "!" ); Kit_DsdPrint_rec( pFile, pNtk, Kit_DsdLit2Var(pNtk->Root) ); - fprintf( pFile, "\n" ); +// fprintf( pFile, "\n" ); } /**Function************************************************************* @@ -333,7 +336,7 @@ unsigned * Kit_DsdTruthComputeNode_rec( Kit_DsdMan_t * p, Kit_DsdNtk_t * pNtk, i // get the node with this ID pObj = Kit_DsdNtkObj( pNtk, Id ); - pTruthRes = Vec_PtrEntry( p->vTtNodes, Id ); + pTruthRes = (unsigned *)Vec_PtrEntry( p->vTtNodes, Id ); // special case: literal of an internal node if ( pObj == NULL ) @@ -434,7 +437,7 @@ unsigned * Kit_DsdTruthCompute( Kit_DsdMan_t * p, Kit_DsdNtk_t * pNtk ) // assign elementary truth ables assert( pNtk->nVars <= p->nVars ); for ( i = 0; i < (int)pNtk->nVars; i++ ) - Kit_TruthCopy( Vec_PtrEntry(p->vTtNodes, i), Vec_PtrEntry(p->vTtElems, i), p->nVars ); + Kit_TruthCopy( (unsigned *)Vec_PtrEntry(p->vTtNodes, i), (unsigned *)Vec_PtrEntry(p->vTtElems, i), p->nVars ); // compute truth table for each node pTruthRes = Kit_DsdTruthComputeNode_rec( p, pNtk, Kit_DsdLit2Var(pNtk->Root) ); // complement the truth table if needed @@ -463,7 +466,7 @@ unsigned * Kit_DsdTruthComputeNodeOne_rec( Kit_DsdMan_t * p, Kit_DsdNtk_t * pNtk // get the node with this ID pObj = Kit_DsdNtkObj( pNtk, Id ); - pTruthRes = Vec_PtrEntry( p->vTtNodes, Id ); + pTruthRes = (unsigned *)Vec_PtrEntry( p->vTtNodes, Id ); // special case: literal of an internal node if ( pObj == NULL ) @@ -597,7 +600,7 @@ unsigned * Kit_DsdTruthComputeOne( Kit_DsdMan_t * p, Kit_DsdNtk_t * pNtk, unsign // assign elementary truth tables assert( pNtk->nVars <= p->nVars ); for ( i = 0; i < (int)pNtk->nVars; i++ ) - Kit_TruthCopy( Vec_PtrEntry(p->vTtNodes, i), Vec_PtrEntry(p->vTtElems, i), p->nVars ); + Kit_TruthCopy( (unsigned *)Vec_PtrEntry(p->vTtNodes, i), (unsigned *)Vec_PtrEntry(p->vTtElems, i), p->nVars ); // compute truth table for each node pTruthRes = Kit_DsdTruthComputeNodeOne_rec( p, pNtk, Kit_DsdLit2Var(pNtk->Root), uSupp ); // complement the truth table if needed @@ -628,7 +631,7 @@ unsigned * Kit_DsdTruthComputeNodeTwo_rec( Kit_DsdMan_t * p, Kit_DsdNtk_t * pNtk // get the node with this ID pObj = Kit_DsdNtkObj( pNtk, Id ); - pTruthRes = Vec_PtrEntry( p->vTtNodes, Id ); + pTruthRes = (unsigned *)Vec_PtrEntry( p->vTtNodes, Id ); if ( pObj == NULL ) { assert( Id < pNtk->nVars ); @@ -812,7 +815,7 @@ unsigned * Kit_DsdTruthComputeTwo( Kit_DsdMan_t * p, Kit_DsdNtk_t * pNtk, unsign } // assign elementary truth tables for ( i = 0; i < (int)pNtk->nVars; i++ ) - Kit_TruthCopy( Vec_PtrEntry(p->vTtNodes, i), Vec_PtrEntry(p->vTtElems, i), p->nVars ); + Kit_TruthCopy( (unsigned *)Vec_PtrEntry(p->vTtNodes, i), (unsigned *)Vec_PtrEntry(p->vTtElems, i), p->nVars ); // compute truth table for each node pTruthRes = Kit_DsdTruthComputeNodeTwo_rec( p, pNtk, Kit_DsdLit2Var(pNtk->Root), uSupp, iVar, pTruthDec ); // complement the truth table if needed @@ -1125,7 +1128,7 @@ int Kit_DsdExpandNode_rec( Kit_DsdNtk_t * pNew, Kit_DsdNtk_t * p, int iLit ) return iLit; if ( pObj->Type == KIT_DSD_AND ) { - Kit_DsdExpandCollectAnd_rec( p, Kit_DsdLitRegular(iLit), piLitsNew, &nLitsNew ); + Kit_DsdExpandCollectAnd_rec( p, Kit_DsdLitRegular(iLit), piLitsNew, (int *)&nLitsNew ); pObjNew = Kit_DsdObjAlloc( pNew, KIT_DSD_AND, nLitsNew ); for ( i = 0; i < pObjNew->nFans; i++ ) pObjNew->pFans[i] = Kit_DsdExpandNode_rec( pNew, p, piLitsNew[i] ); @@ -1134,7 +1137,7 @@ int Kit_DsdExpandNode_rec( Kit_DsdNtk_t * pNew, Kit_DsdNtk_t * p, int iLit ) if ( pObj->Type == KIT_DSD_XOR ) { int fCompl = Kit_DsdLitIsCompl(iLit); - Kit_DsdExpandCollectXor_rec( p, Kit_DsdLitRegular(iLit), piLitsNew, &nLitsNew ); + Kit_DsdExpandCollectXor_rec( p, Kit_DsdLitRegular(iLit), piLitsNew, (int *)&nLitsNew ); pObjNew = Kit_DsdObjAlloc( pNew, KIT_DSD_XOR, nLitsNew ); for ( i = 0; i < pObjNew->nFans; i++ ) { @@ -2716,8 +2719,252 @@ void Kit_DsdPrintCofactors( unsigned * pTruth, int nVars, int nCofLevel, int fVe ABC_FREE( ppCofs[0][0] ); } + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char ** Kit_DsdNpn4ClassNames() +{ + static const char * pNames[222] = { + "F = 0", /* 0 */ + "F = (!d*(!c*(!b*!a)))", /* 1 */ + "F = (!d*(!c*!b))", /* 2 */ + "F = (!d*(!c*(b+a)))", /* 3 */ + "F = (!d*(!c*!(b*a)))", /* 4 */ + "F = (!d*!c)", /* 5 */ + "F = (!d*16(a,b,c))", /* 6 */ + "F = (!d*17(a,b,c))", /* 7 */ + "F = (!d*18(a,b,c))", /* 8 */ + "F = (!d*19(a,b,c))", /* 9 */ + "F = (!d*CA(!b,!c,a))", /* 10 */ + "F = (!d*(c+!(!b*!a)))", /* 11 */ + "F = (!d*!(c*!(!b*!a)))", /* 12 */ + "F = (!d*(c+b))", /* 13 */ + "F = (!d*3D(a,b,c))", /* 14 */ + "F = (!d*!(c*b))", /* 15 */ + "F = (!d*(c+(b+!a)))", /* 16 */ + "F = (!d*6B(a,b,c))", /* 17 */ + "F = (!d*!(c*!(b+a)))", /* 18 */ + "F = (!d*7E(a,b,c))", /* 19 */ + "F = (!d*!(c*(b*a)))", /* 20 */ + "F = (!d)", /* 21 */ + "F = 0116(a,b,c,d)", /* 22 */ + "F = 0117(a,b,c,d)", /* 23 */ + "F = 0118(a,b,c,d)", /* 24 */ + "F = 0119(a,b,c,d)", /* 25 */ + "F = 011A(a,b,c,d)", /* 26 */ + "F = 011B(a,b,c,d)", /* 27 */ + "F = 29((!b*!a),c,d)", /* 28 */ + "F = 2B((!b*!a),c,d)", /* 29 */ + "F = 012C(a,b,c,d)", /* 30 */ + "F = 012D(a,b,c,d)", /* 31 */ + "F = 012F(a,b,c,d)", /* 32 */ + "F = 013C(a,b,c,d)", /* 33 */ + "F = 013D(a,b,c,d)", /* 34 */ + "F = 013E(a,b,c,d)", /* 35 */ + "F = 013F(a,b,c,d)", /* 36 */ + "F = 0168(a,b,c,d)", /* 37 */ + "F = 0169(a,b,c,d)", /* 38 */ + "F = 016A(a,b,c,d)", /* 39 */ + "F = 016B(a,b,c,d)", /* 40 */ + "F = 016E(a,b,c,d)", /* 41 */ + "F = 016F(a,b,c,d)", /* 42 */ + "F = 017E(a,b,c,d)", /* 43 */ + "F = 017F(a,b,c,d)", /* 44 */ + "F = 0180(a,b,c,d)", /* 45 */ + "F = 0181(a,b,c,d)", /* 46 */ + "F = 0182(a,b,c,d)", /* 47 */ + "F = 0183(a,b,c,d)", /* 48 */ + "F = 0186(a,b,c,d)", /* 49 */ + "F = 0187(a,b,c,d)", /* 50 */ + "F = 0189(a,b,c,d)", /* 51 */ + "F = 018B(a,b,c,d)", /* 52 */ + "F = 018F(a,b,c,d)", /* 53 */ + "F = 0196(a,b,c,d)", /* 54 */ + "F = 0197(a,b,c,d)", /* 55 */ + "F = 0198(a,b,c,d)", /* 56 */ + "F = 0199(a,b,c,d)", /* 57 */ + "F = 019A(a,b,c,d)", /* 58 */ + "F = 019B(a,b,c,d)", /* 59 */ + "F = 019E(a,b,c,d)", /* 60 */ + "F = 019F(a,b,c,d)", /* 61 */ + "F = 42(a,(!c*!b),d)", /* 62 */ + "F = 46(a,(!c*!b),d)", /* 63 */ + "F = 4A(a,(!c*!b),d)", /* 64 */ + "F = CA((!c*!b),!d,a)", /* 65 */ + "F = 01AC(a,b,c,d)", /* 66 */ + "F = 01AD(a,b,c,d)", /* 67 */ + "F = 01AE(a,b,c,d)", /* 68 */ + "F = 01AF(a,b,c,d)", /* 69 */ + "F = 01BC(a,b,c,d)", /* 70 */ + "F = 01BD(a,b,c,d)", /* 71 */ + "F = 01BE(a,b,c,d)", /* 72 */ + "F = 01BF(a,b,c,d)", /* 73 */ + "F = 01E8(a,b,c,d)", /* 74 */ + "F = 01E9(a,b,c,d)", /* 75 */ + "F = 01EA(a,b,c,d)", /* 76 */ + "F = 01EB(a,b,c,d)", /* 77 */ + "F = 25((!b*!a),c,d)", /* 78 */ + "F = !CA(d,c,(!b*!a))", /* 79 */ + "F = (d+!(!c*(!b*!a)))", /* 80 */ + "F = 16(b,c,d)", /* 81 */ + "F = 033D(a,b,c,d)", /* 82 */ + "F = 17(b,c,d)", /* 83 */ + "F = ((!d*!a)+(!c*!b))", /* 84 */ + "F = !(!(!c*!b)*!(!d*!a))", /* 85 */ + "F = 0358(a,b,c,d)", /* 86 */ + "F = 0359(a,b,c,d)", /* 87 */ + "F = 035A(a,b,c,d)", /* 88 */ + "F = 035B(a,b,c,d)", /* 89 */ + "F = 035E(a,b,c,d)", /* 90 */ + "F = 035F(a,b,c,d)", /* 91 */ + "F = 0368(a,b,c,d)", /* 92 */ + "F = 0369(a,b,c,d)", /* 93 */ + "F = 036A(a,b,c,d)", /* 94 */ + "F = 036B(a,b,c,d)", /* 95 */ + "F = 036C(a,b,c,d)", /* 96 */ + "F = 036D(a,b,c,d)", /* 97 */ + "F = 036E(a,b,c,d)", /* 98 */ + "F = 036F(a,b,c,d)", /* 99 */ + "F = 037C(a,b,c,d)", /* 100 */ + "F = 037D(a,b,c,d)", /* 101 */ + "F = 037E(a,b,c,d)", /* 102 */ + "F = 18(b,c,d)", /* 103 */ + "F = 03C1(a,b,c,d)", /* 104 */ + "F = 19(b,c,d)", /* 105 */ + "F = 03C5(a,b,c,d)", /* 106 */ + "F = 03C6(a,b,c,d)", /* 107 */ + "F = 03C7(a,b,c,d)", /* 108 */ + "F = CA(!c,!d,b)", /* 109 */ + "F = 03D4(a,b,c,d)", /* 110 */ + "F = 03D5(a,b,c,d)", /* 111 */ + "F = 03D6(a,b,c,d)", /* 112 */ + "F = 03D7(a,b,c,d)", /* 113 */ + "F = 03D8(a,b,c,d)", /* 114 */ + "F = 03D9(a,b,c,d)", /* 115 */ + "F = 03DB(a,b,c,d)", /* 116 */ + "F = 03DC(a,b,c,d)", /* 117 */ + "F = 03DD(a,b,c,d)", /* 118 */ + "F = 03DE(a,b,c,d)", /* 119 */ + "F = (d+!(!c*!b))", /* 120 */ + "F = ((d+c)*(b+a))", /* 121 */ + "F = 0661(a,b,c,d)", /* 122 */ + "F = 0662(a,b,c,d)", /* 123 */ + "F = 0663(a,b,c,d)", /* 124 */ + "F = (!(d*c)*(b+a))", /* 125 */ + "F = 0667(a,b,c,d)", /* 126 */ + "F = 29((b+a),c,d)", /* 127 */ + "F = 066B(a,b,c,d)", /* 128 */ + "F = 2B((b+a),c,d)", /* 129 */ + "F = 0672(a,b,c,d)", /* 130 */ + "F = 0673(a,b,c,d)", /* 131 */ + "F = 0676(a,b,c,d)", /* 132 */ + "F = 0678(a,b,c,d)", /* 133 */ + "F = 0679(a,b,c,d)", /* 134 */ + "F = 067A(a,b,c,d)", /* 135 */ + "F = 067B(a,b,c,d)", /* 136 */ + "F = 067E(a,b,c,d)", /* 137 */ + "F = 24((b+a),c,d)", /* 138 */ + "F = 0691(a,b,c,d)", /* 139 */ + "F = 0693(a,b,c,d)", /* 140 */ + "F = 26((b+a),c,d)", /* 141 */ + "F = 0697(a,b,c,d)", /* 142 */ + "F = !CA(d,c,(b+a))", /* 143 */ + "F = 06B0(a,b,c,d)", /* 144 */ + "F = 06B1(a,b,c,d)", /* 145 */ + "F = 06B2(a,b,c,d)", /* 146 */ + "F = 06B3(a,b,c,d)", /* 147 */ + "F = 06B4(a,b,c,d)", /* 148 */ + "F = 06B5(a,b,c,d)", /* 149 */ + "F = 06B6(a,b,c,d)", /* 150 */ + "F = 06B7(a,b,c,d)", /* 151 */ + "F = 06B9(a,b,c,d)", /* 152 */ + "F = 06BD(a,b,c,d)", /* 153 */ + "F = 2C((b+a),c,d)", /* 154 */ + "F = 06F1(a,b,c,d)", /* 155 */ + "F = 06F2(a,b,c,d)", /* 156 */ + "F = CA((b+a),!d,c)", /* 157 */ + "F = (d+!(!c*!(b+!a)))", /* 158 */ + "F = 0776(a,b,c,d)", /* 159 */ + "F = 16((b*a),c,d)", /* 160 */ + "F = 0779(a,b,c,d)", /* 161 */ + "F = 077A(a,b,c,d)", /* 162 */ + "F = 077E(a,b,c,d)", /* 163 */ + "F = 07B0(a,b,c,d)", /* 164 */ + "F = 07B1(a,b,c,d)", /* 165 */ + "F = 07B4(a,b,c,d)", /* 166 */ + "F = 07B5(a,b,c,d)", /* 167 */ + "F = 07B6(a,b,c,d)", /* 168 */ + "F = 07BC(a,b,c,d)", /* 169 */ + "F = 07E0(a,b,c,d)", /* 170 */ + "F = 07E1(a,b,c,d)", /* 171 */ + "F = 07E2(a,b,c,d)", /* 172 */ + "F = 07E3(a,b,c,d)", /* 173 */ + "F = 07E6(a,b,c,d)", /* 174 */ + "F = 07E9(a,b,c,d)", /* 175 */ + "F = 1C((b*a),c,d)", /* 176 */ + "F = 07F1(a,b,c,d)", /* 177 */ + "F = 07F2(a,b,c,d)", /* 178 */ + "F = (d+!(!c*!(b*a)))", /* 179 */ + "F = (d+c)", /* 180 */ + "F = 1668(a,b,c,d)", /* 181 */ + "F = 1669(a,b,c,d)", /* 182 */ + "F = 166A(a,b,c,d)", /* 183 */ + "F = 166B(a,b,c,d)", /* 184 */ + "F = 166E(a,b,c,d)", /* 185 */ + "F = 167E(a,b,c,d)", /* 186 */ + "F = 1681(a,b,c,d)", /* 187 */ + "F = 1683(a,b,c,d)", /* 188 */ + "F = 1686(a,b,c,d)", /* 189 */ + "F = 1687(a,b,c,d)", /* 190 */ + "F = 1689(a,b,c,d)", /* 191 */ + "F = 168B(a,b,c,d)", /* 192 */ + "F = 168E(a,b,c,d)", /* 193 */ + "F = 1696(a,b,c,d)", /* 194 */ + "F = 1697(a,b,c,d)", /* 195 */ + "F = 1698(a,b,c,d)", /* 196 */ + "F = 1699(a,b,c,d)", /* 197 */ + "F = 169A(a,b,c,d)", /* 198 */ + "F = 169B(a,b,c,d)", /* 199 */ + "F = 169E(a,b,c,d)", /* 200 */ + "F = 16A9(a,b,c,d)", /* 201 */ + "F = 16AC(a,b,c,d)", /* 202 */ + "F = 16AD(a,b,c,d)", /* 203 */ + "F = 16BC(a,b,c,d)", /* 204 */ + "F = (d+E9(a,b,c))", /* 205 */ + "F = 177E(a,b,c,d)", /* 206 */ + "F = 178E(a,b,c,d)", /* 207 */ + "F = 1796(a,b,c,d)", /* 208 */ + "F = 1798(a,b,c,d)", /* 209 */ + "F = 179A(a,b,c,d)", /* 210 */ + "F = 17AC(a,b,c,d)", /* 211 */ + "F = (d+E8(a,b,c))", /* 212 */ + "F = (d+E7(a,b,c))", /* 213 */ + "F = 19E1(a,b,c,d)", /* 214 */ + "F = 19E3(a,b,c,d)", /* 215 */ + "F = (d+E6(a,b,c))", /* 216 */ + "F = 1BD8(a,b,c,d)", /* 217 */ + "F = (d+CA(b,c,a))", /* 218 */ + "F = (d+(c+(!b*!a)))", /* 219 */ + "F = (d+(c+!b))", /* 220 */ + "F = (d+(c+(b+a)))" /* 221 */ + }; + return (char **)pNames; +} + + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/kit/kitFactor.c b/src/aig/kit/kitFactor.c index 273d4821..3982d7a8 100644 --- a/src/aig/kit/kitFactor.c +++ b/src/aig/kit/kitFactor.c @@ -20,6 +20,9 @@ #include "kit.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -337,3 +340,5 @@ void Kit_FactorTest( unsigned * pTruth, int nVars ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/kit/kitGraph.c b/src/aig/kit/kitGraph.c index 565c000b..f407a93a 100644 --- a/src/aig/kit/kitGraph.c +++ b/src/aig/kit/kitGraph.c @@ -20,6 +20,9 @@ #include "kit.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -395,3 +398,5 @@ int Kit_GraphLeafDepth_rec( Kit_Graph_t * pGraph, Kit_Node_t * pNode, Kit_Node_t /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/kit/kitHop.c b/src/aig/kit/kitHop.c index 044633bc..0dad6295 100644 --- a/src/aig/kit/kitHop.c +++ b/src/aig/kit/kitHop.c @@ -21,6 +21,9 @@ #include "kit.h" #include "hop.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -50,16 +53,16 @@ Hop_Obj_t * Kit_GraphToHopInternal( Hop_Man_t * pMan, Kit_Graph_t * pGraph ) return Hop_NotCond( Hop_ManConst1(pMan), Kit_GraphIsComplement(pGraph) ); // check for a literal if ( Kit_GraphIsVar(pGraph) ) - return Hop_NotCond( Kit_GraphVar(pGraph)->pFunc, Kit_GraphIsComplement(pGraph) ); + return Hop_NotCond( (Hop_Obj_t *)Kit_GraphVar(pGraph)->pFunc, Kit_GraphIsComplement(pGraph) ); // build the AIG nodes corresponding to the AND gates of the graph Kit_GraphForEachNode( pGraph, pNode, i ) { - pAnd0 = Hop_NotCond( Kit_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl ); - pAnd1 = Hop_NotCond( Kit_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl ); + pAnd0 = Hop_NotCond( (Hop_Obj_t *)Kit_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl ); + pAnd1 = Hop_NotCond( (Hop_Obj_t *)Kit_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl ); pNode->pFunc = Hop_And( pMan, pAnd0, pAnd1 ); } // complement the result if necessary - return Hop_NotCond( pNode->pFunc, Kit_GraphIsComplement(pGraph) ); + return Hop_NotCond( (Hop_Obj_t *)pNode->pFunc, Kit_GraphIsComplement(pGraph) ); } /**Function************************************************************* @@ -143,3 +146,5 @@ Hop_Obj_t * Kit_CoverToHop( Hop_Man_t * pMan, Vec_Int_t * vCover, int nVars, Vec //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/kit/kitIsop.c b/src/aig/kit/kitIsop.c index 42fae2ea..18039dc5 100644 --- a/src/aig/kit/kitIsop.c +++ b/src/aig/kit/kitIsop.c @@ -20,6 +20,9 @@ #include "kit.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -323,3 +326,5 @@ unsigned Kit_TruthIsop5_rec( unsigned uOn, unsigned uOnDc, int nVars, Kit_Sop_t //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/kit/kitPla.c b/src/aig/kit/kitPla.c index 776762c2..df6d4e11 100644 --- a/src/aig/kit/kitPla.c +++ b/src/aig/kit/kitPla.c @@ -21,6 +21,9 @@ #include "kit.h" #include "aig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -115,7 +118,9 @@ int Kit_PlaIsInv( char * pSop ) int Kit_PlaGetVarNum( char * pSop ) { char * pCur; - for ( pCur = pSop; *pCur != '\n'; pCur++ ); + for ( pCur = pSop; *pCur != '\n'; pCur++ ) + if ( *pCur == 0 ) + return -1; return pCur - pSop - 2; } @@ -205,7 +210,7 @@ void Kit_PlaComplement( char * pSop ) ***********************************************************************/ char * Kit_PlaStart( void * p, int nCubes, int nVars ) { - Aig_MmFlex_t * pMan = p; + Aig_MmFlex_t * pMan = (Aig_MmFlex_t *)p; char * pSopCover, * pCube; int i, Length; @@ -237,7 +242,7 @@ char * Kit_PlaStart( void * p, int nCubes, int nVars ) ***********************************************************************/ char * Kit_PlaCreateFromIsop( void * p, int nVars, Vec_Int_t * vCover ) { - Aig_MmFlex_t * pMan = p; + Aig_MmFlex_t * pMan = (Aig_MmFlex_t *)p; char * pSop, * pCube; int i, k, Entry, Literal; assert( Vec_IntSize(vCover) > 0 ); @@ -311,7 +316,7 @@ void Kit_PlaToIsop( char * pSop, Vec_Int_t * vCover ) ***********************************************************************/ char * Kit_PlaStoreSop( void * p, char * pSop ) { - Aig_MmFlex_t * pMan = p; + Aig_MmFlex_t * pMan = (Aig_MmFlex_t *)p; char * pStore; pStore = Aig_MmFlexEntryFetch( pMan, strlen(pSop) + 1 ); strcpy( pStore, pSop ); @@ -331,7 +336,7 @@ char * Kit_PlaStoreSop( void * p, char * pSop ) ***********************************************************************/ char * Kit_PlaFromTruth( void * p, unsigned * pTruth, int nVars, Vec_Int_t * vCover ) { - Aig_MmFlex_t * pMan = p; + Aig_MmFlex_t * pMan = (Aig_MmFlex_t *)p; char * pSop; int RetValue; if ( Kit_TruthIsConst0(pTruth, nVars) ) @@ -347,8 +352,184 @@ char * Kit_PlaFromTruth( void * p, unsigned * pTruth, int nVars, Vec_Int_t * vCo } +/**Function************************************************************* + + Synopsis [Creates the cover from the ISOP computed from TT.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Kit_PlaFromIsop( Vec_Str_t * vStr, int nVars, Vec_Int_t * vCover ) +{ + int i, k, Entry, Literal; + assert( Vec_IntSize(vCover) > 0 ); + if ( Vec_IntSize(vCover) == 0 ) + return NULL; + Vec_StrClear( vStr ); + Vec_IntForEachEntry( vCover, Entry, i ) + { + for ( k = 0; k < nVars; k++ ) + { + Literal = 3 & (Entry >> (k << 1)); + if ( Literal == 1 ) + Vec_StrPush( vStr, '0' ); + else if ( Literal == 2 ) + Vec_StrPush( vStr, '1' ); + else if ( Literal == 0 ) + Vec_StrPush( vStr, '-' ); + else + assert( 0 ); + } + Vec_StrPush( vStr, ' ' ); + Vec_StrPush( vStr, '1' ); + Vec_StrPush( vStr, '\n' ); + } + Vec_StrPush( vStr, '\0' ); + return Vec_StrArray( vStr ); +} + +/**Function************************************************************* + + Synopsis [Creates the SOP from TT.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Kit_PlaFromTruthNew( unsigned * pTruth, int nVars, Vec_Int_t * vCover, Vec_Str_t * vStr ) +{ + char * pResult; + // transform truth table into the SOP + int RetValue = Kit_TruthIsop( pTruth, nVars, vCover, 1 ); + assert( RetValue == 0 || RetValue == 1 ); + // check the case of constant cover + if ( Vec_IntSize(vCover) == 0 || (Vec_IntSize(vCover) == 1 && Vec_IntEntry(vCover,0) == 0) ) + { + assert( RetValue == 0 ); + Vec_StrClear( vStr ); + Vec_StrAppend( vStr, (Vec_IntSize(vCover) == 0) ? " 0\n" : " 1\n" ); + Vec_StrPush( vStr, '\0' ); + return Vec_StrArray( vStr ); + } + pResult = Kit_PlaFromIsop( vStr, nVars, vCover ); + if ( RetValue ) + Kit_PlaComplement( pResult ); + if ( nVars < 6 ) + assert( pTruth[0] == (unsigned)Kit_PlaToTruth6(pResult, nVars) ); + else if ( nVars == 6 ) + assert( *((ABC_UINT64_T*)pTruth) == Kit_PlaToTruth6(pResult, nVars) ); + return pResult; +} + +/**Function************************************************************* + + Synopsis [Converts SOP into a truth table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +ABC_UINT64_T Kit_PlaToTruth6( char * pSop, int nVars ) +{ + static ABC_UINT64_T Truth[8] = { + 0xAAAAAAAAAAAAAAAA, + 0xCCCCCCCCCCCCCCCC, + 0xF0F0F0F0F0F0F0F0, + 0xFF00FF00FF00FF00, + 0xFFFF0000FFFF0000, + 0xFFFFFFFF00000000, + 0x0000000000000000, + 0xFFFFFFFFFFFFFFFF + }; + ABC_UINT64_T valueAnd, valueOr = Truth[6]; + int v, lit = 0; + assert( nVars < 7 ); + do { + valueAnd = Truth[7]; + for ( v = 0; v < nVars; v++, lit++ ) + { + if ( pSop[lit] == '1' ) + valueAnd &= Truth[v]; + else if ( pSop[lit] == '0' ) + valueAnd &= ~Truth[v]; + else if ( pSop[lit] != '-' ) + assert( 0 ); + } + valueOr |= valueAnd; + assert( pSop[lit] == ' ' ); + lit++; + lit++; + assert( pSop[lit] == '\n' ); + lit++; + } while ( pSop[lit] ); + if ( Kit_PlaIsComplement(pSop) ) + valueOr = ~valueOr; + return valueOr; +} + +/**Fnction************************************************************* + + Synopsis [Converting SOP into a truth table.] + + Description [The SOP is represented as a C-string, as documented in + file "bblif.h". The truth table is returned as a bit-string composed + of 2^nVars bits. For functions of less than 6 variables, the full + machine word is returned. (The truth table looks as if the function + had 5 variables.) The use of this procedure should be limited to + Boolean functions with no more than 16 inputs.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Kit_PlaToTruth( char * pSop, int nVars, Vec_Ptr_t * vVars, unsigned * pTemp, unsigned * pTruth ) +{ + int v, c, nCubes, fCompl = 0; + assert( pSop != NULL ); + assert( nVars >= 0 ); + if ( strlen(pSop) % (nVars + 3) != 0 ) + { + printf( "Kit_PlaToTruth(): SOP is represented incorrectly.\n" ); + return; + } + // iterate through the cubes + Kit_TruthClear( pTruth, nVars ); + nCubes = strlen(pSop) / (nVars + 3); + for ( c = 0; c < nCubes; c++ ) + { + fCompl = (pSop[nVars+1] == '0'); + Kit_TruthFill( pTemp, nVars ); + // iterate through the literals of the cube + for ( v = 0; v < nVars; v++ ) + if ( pSop[v] == '1' ) + Kit_TruthAnd( pTemp, pTemp, (unsigned *)Vec_PtrEntry(vVars, v), nVars ); + else if ( pSop[v] == '0' ) + Kit_TruthSharp( pTemp, pTemp, (unsigned *)Vec_PtrEntry(vVars, v), nVars ); + // add cube to storage + Kit_TruthOr( pTruth, pTruth, pTemp, nVars ); + // go to the next cube + pSop += (nVars + 3); + } + if ( fCompl ) + Kit_TruthNot( pTruth, pTruth, nVars ); +} + + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/kit/kitSop.c b/src/aig/kit/kitSop.c index 0d1b9e2c..21ea69b8 100644 --- a/src/aig/kit/kitSop.c +++ b/src/aig/kit/kitSop.c @@ -20,6 +20,9 @@ #include "kit.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -510,7 +513,7 @@ void Kit_SopDivisorZeroKernel_rec( Kit_Sop_t * cSop, int nLits ) iLit = Kit_SopWorstLiteral( cSop, nLits ); if ( iLit == -1 ) return; - // derive the cube-ABC_FREE quotient + // derive the cube-free quotient Kit_SopDivideByLiteralQuo( cSop, iLit ); // the same cover Kit_SopMakeCubeFree( cSop ); // the same cover // call recursively @@ -572,3 +575,5 @@ void Kit_SopBestLiteralCover( Kit_Sop_t * cResult, Kit_Sop_t * cSop, unsigned uC //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/kit/kitTruth.c b/src/aig/kit/kitTruth.c index 3f9188c7..56f10ac0 100644 --- a/src/aig/kit/kitTruth.c +++ b/src/aig/kit/kitTruth.c @@ -20,6 +20,9 @@ #include "kit.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -187,7 +190,7 @@ void Kit_TruthStretch( unsigned * pOut, unsigned * pIn, int nVars, int nVarsAll, Description [The input and output truth tables are in pIn/pOut. The current number of variables is nVars. The total number of variables in nVarsAll. The last argument - (Phase) contains shows what variables should remain.] + (Phase) shows what variables should remain.] SideEffects [The input truth table is modified.] @@ -229,7 +232,7 @@ void Kit_TruthShrink( unsigned * pOut, unsigned * pIn, int nVars, int nVarsAll, ***********************************************************************/ void Kit_TruthPermute( unsigned * pOut, unsigned * pIn, int nVars, char * pPerm, int fReturnIn ) { - int * pTemp; + unsigned * pTemp; int i, Temp, fChange, Counter = 0; do { fChange = 0; @@ -404,6 +407,57 @@ void Kit_TruthCofactor0( unsigned * pTruth, int nVars, int iVar ) /**Function************************************************************* + Synopsis [Computes negative cofactor of the function.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Kit_TruthCofactor0Count( unsigned * pTruth, int nVars, int iVar ) +{ + int nWords = Kit_TruthWordNum( nVars ); + int i, k, Step, Counter = 0; + + assert( iVar < nVars ); + switch ( iVar ) + { + case 0: + for ( i = 0; i < nWords; i++ ) + Counter += Kit_WordCountOnes(pTruth[i] & 0x55555555); + return Counter; + case 1: + for ( i = 0; i < nWords; i++ ) + Counter += Kit_WordCountOnes(pTruth[i] & 0x33333333); + return Counter; + case 2: + for ( i = 0; i < nWords; i++ ) + Counter += Kit_WordCountOnes(pTruth[i] & 0x0F0F0F0F); + return Counter; + case 3: + for ( i = 0; i < nWords; i++ ) + Counter += Kit_WordCountOnes(pTruth[i] & 0x00FF00FF); + return Counter; + case 4: + for ( i = 0; i < nWords; i++ ) + Counter += Kit_WordCountOnes(pTruth[i] & 0x0000FFFF); + return Counter; + default: + Step = (1 << (iVar - 5)); + for ( k = 0; k < nWords; k += 2*Step ) + { + for ( i = 0; i < Step; i++ ) + Counter += Kit_WordCountOnes(pTruth[i]); + pTruth += 2*Step; + } + return Counter; + } +} + +/**Function************************************************************* + Synopsis [Computes positive cofactor of the function.] Description [] @@ -598,7 +652,7 @@ int Kit_TruthVarIsVacuous( unsigned * pOnset, unsigned * pOffset, int nVars, int return 1; case 4: for ( i = 0; i < nWords; i++ ) - if ( ((pOnset[i] & (pOffset[i] >> 16)) || (pOffset[i] & (pOnset[i] >> 16))) & 0x0000FFFF ) + if ( ((pOnset[i] & (pOffset[i] >> 16)) | (pOffset[i] & (pOnset[i] >> 16))) & 0x0000FFFF ) return 0; return 1; default: @@ -911,6 +965,77 @@ void Kit_TruthUniqueNew( unsigned * pRes, unsigned * pTruth, int nVars, int iVar /**Function************************************************************* + Synopsis [Returns the number of minterms in the Boolean difference.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Kit_TruthBooleanDiffCount( unsigned * pTruth, int nVars, int iVar ) +{ + int nWords = Kit_TruthWordNum( nVars ); + int i, k, Step, Counter = 0; + + assert( iVar < nVars ); + switch ( iVar ) + { + case 0: + for ( i = 0; i < nWords; i++ ) + Counter += Kit_WordCountOnes( (pTruth[i] ^ (pTruth[i] >> 1)) & 0x55555555 ); + return Counter; + case 1: + for ( i = 0; i < nWords; i++ ) + Counter += Kit_WordCountOnes( (pTruth[i] ^ (pTruth[i] >> 2)) & 0x33333333 ); + return Counter; + case 2: + for ( i = 0; i < nWords; i++ ) + Counter += Kit_WordCountOnes( (pTruth[i] ^ (pTruth[i] >> 4)) & 0x0F0F0F0F ); + return Counter; + case 3: + for ( i = 0; i < nWords; i++ ) + Counter += Kit_WordCountOnes( (pTruth[i] ^ (pTruth[i] >> 8)) & 0x00FF00FF ); + return Counter; + case 4: + for ( i = 0; i < nWords; i++ ) + Counter += Kit_WordCountOnes( (pTruth[i] ^ (pTruth[i] >>16)) & 0x0000FFFF ); + return Counter; + default: + Step = (1 << (iVar - 5)); + for ( k = 0; k < nWords; k += 2*Step ) + { + for ( i = 0; i < Step; i++ ) + Counter += Kit_WordCountOnes( pTruth[i] ^ pTruth[Step+i] ); + pTruth += 2*Step; + } + return Counter; + } +} + +/**Function************************************************************* + + Synopsis [Returns the number of minterms in the Boolean difference.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Kit_TruthXorCount( unsigned * pTruth0, unsigned * pTruth1, int nVars ) +{ + int nWords = Kit_TruthWordNum( nVars ); + int i, Counter = 0; + for ( i = 0; i < nWords; i++ ) + Counter += Kit_WordCountOnes( pTruth0[i] ^ pTruth1[i] ); + return Counter; +} + +/**Function************************************************************* + Synopsis [Universally quantifies the set of variables.] Description [] @@ -1059,20 +1184,29 @@ void Kit_TruthMuxVarPhase( unsigned * pOut, unsigned * pCof0, unsigned * pCof1, SeeAlso [] ***********************************************************************/ -int Kit_TruthVarsSymm( unsigned * pTruth, int nVars, int iVar0, int iVar1 ) +int Kit_TruthVarsSymm( unsigned * pTruth, int nVars, int iVar0, int iVar1, unsigned * pCof0, unsigned * pCof1 ) { - static unsigned uTemp0[16], uTemp1[16]; - assert( nVars <= 9 ); + static unsigned uTemp0[32], uTemp1[32]; + if ( pCof0 == NULL ) + { + assert( nVars <= 10 ); + pCof0 = uTemp0; + } + if ( pCof1 == NULL ) + { + assert( nVars <= 10 ); + pCof1 = uTemp1; + } // compute Cof01 - Kit_TruthCopy( uTemp0, pTruth, nVars ); - Kit_TruthCofactor0( uTemp0, nVars, iVar0 ); - Kit_TruthCofactor1( uTemp0, nVars, iVar1 ); + Kit_TruthCopy( pCof0, pTruth, nVars ); + Kit_TruthCofactor0( pCof0, nVars, iVar0 ); + Kit_TruthCofactor1( pCof0, nVars, iVar1 ); // compute Cof10 - Kit_TruthCopy( uTemp1, pTruth, nVars ); - Kit_TruthCofactor1( uTemp1, nVars, iVar0 ); - Kit_TruthCofactor0( uTemp1, nVars, iVar1 ); + Kit_TruthCopy( pCof1, pTruth, nVars ); + Kit_TruthCofactor1( pCof1, nVars, iVar0 ); + Kit_TruthCofactor0( pCof1, nVars, iVar1 ); // compare - return Kit_TruthIsEqual( uTemp0, uTemp1, nVars ); + return Kit_TruthIsEqual( pCof0, pCof1, nVars ); } /**Function************************************************************* @@ -1086,20 +1220,29 @@ int Kit_TruthVarsSymm( unsigned * pTruth, int nVars, int iVar0, int iVar1 ) SeeAlso [] ***********************************************************************/ -int Kit_TruthVarsAntiSymm( unsigned * pTruth, int nVars, int iVar0, int iVar1 ) +int Kit_TruthVarsAntiSymm( unsigned * pTruth, int nVars, int iVar0, int iVar1, unsigned * pCof0, unsigned * pCof1 ) { - static unsigned uTemp0[16], uTemp1[16]; - assert( nVars <= 9 ); + static unsigned uTemp0[32], uTemp1[32]; + if ( pCof0 == NULL ) + { + assert( nVars <= 10 ); + pCof0 = uTemp0; + } + if ( pCof1 == NULL ) + { + assert( nVars <= 10 ); + pCof1 = uTemp1; + } // compute Cof00 - Kit_TruthCopy( uTemp0, pTruth, nVars ); - Kit_TruthCofactor0( uTemp0, nVars, iVar0 ); - Kit_TruthCofactor0( uTemp0, nVars, iVar1 ); + Kit_TruthCopy( pCof0, pTruth, nVars ); + Kit_TruthCofactor0( pCof0, nVars, iVar0 ); + Kit_TruthCofactor0( pCof0, nVars, iVar1 ); // compute Cof11 - Kit_TruthCopy( uTemp1, pTruth, nVars ); - Kit_TruthCofactor1( uTemp1, nVars, iVar0 ); - Kit_TruthCofactor1( uTemp1, nVars, iVar1 ); + Kit_TruthCopy( pCof1, pTruth, nVars ); + Kit_TruthCofactor1( pCof1, nVars, iVar0 ); + Kit_TruthCofactor1( pCof1, nVars, iVar1 ); // compare - return Kit_TruthIsEqual( uTemp0, uTemp1, nVars ); + return Kit_TruthIsEqual( pCof0, pCof1, nVars ); } /**Function************************************************************* @@ -1691,7 +1834,7 @@ unsigned Kit_TruthSemiCanonicize( unsigned * pInOut, unsigned * pAux, int nVars, SeeAlso [] ***********************************************************************/ -int Kit_TruthCountMinterms( unsigned * pTruth, int nVars, int * pRes, int * pBytes ) +int Kit_TruthCountMinterms( unsigned * pTruth, int nVars, int * pRes, int * pBytesInit ) { // the number of 1s if every byte as well as in the 0-cofactors w.r.t. three variables static unsigned Table[256] = { @@ -1730,6 +1873,7 @@ int Kit_TruthCountMinterms( unsigned * pTruth, int nVars, int * pRes, int * pByt }; unsigned uSum; unsigned char * pTruthC, * pLimit; + int * pBytes = pBytesInit; int i, iVar, Step, nWords, nBytes, nTotal; assert( nVars <= 20 ); @@ -1768,11 +1912,14 @@ int Kit_TruthCountMinterms( unsigned * pTruth, int nVars, int * pRes, int * pByt for ( iVar = 3, Step = 1; Step < nBytes; Step *= 2, iVar++ ) for ( i = 0; i < nBytes; i += Step + Step ) { - pRes[iVar] += pBytes[i]; - pBytes[i] += pBytes[i+Step]; + pRes[iVar] += pBytesInit[i]; + pBytesInit[i] += pBytesInit[i+Step]; } - assert( pBytes[0] == nTotal ); + assert( pBytesInit[0] == nTotal ); assert( iVar == nVars ); + + for ( i = 0; i < nVars; i++ ) + assert( pRes[i] == Kit_TruthCofactor0Count(pTruth, nVars, i) ); return nTotal; } @@ -1866,8 +2013,210 @@ char * Kit_TruthDumpToFile( unsigned * pTruth, int nVars, int nFile ) } +/**Function************************************************************* + + Synopsis [Dumps truth table into a file.] + + Description [Generates script file for reading into ABC.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Kit_TruthPrintProfile_int( unsigned * pTruth, int nVars ) +{ + int Mints[20]; + int Mints0[20]; + int Mints1[20]; + int Unique1[20]; + int Total2[20][20]; + int Unique2[20][20]; + int Common2[20][20]; + int nWords = Kit_TruthWordNum( nVars ); + int * pBytes = ABC_ALLOC( int, nWords * 4 ); + unsigned * pIn = ABC_ALLOC( unsigned, nWords ); + unsigned * pOut = ABC_ALLOC( unsigned, nWords ); + unsigned * pCof00 = ABC_ALLOC( unsigned, nWords ); + unsigned * pCof01 = ABC_ALLOC( unsigned, nWords ); + unsigned * pCof10 = ABC_ALLOC( unsigned, nWords ); + unsigned * pCof11 = ABC_ALLOC( unsigned, nWords ); + unsigned * pTemp; + int nTotalMints, nTotalMints0, nTotalMints1; + int v, u, i, iVar, nMints1; + int Cof00, Cof01, Cof10, Cof11; + int Coz00, Coz01, Coz10, Coz11; + assert( nVars <= 20 ); + assert( nVars >= 6 ); + + nTotalMints = Kit_TruthCountMinterms( pTruth, nVars, Mints, pBytes ); + for ( v = 0; v < nVars; v++ ) + Unique1[v] = Kit_TruthBooleanDiffCount( pTruth, nVars, v ); + + for ( v = 0; v < nVars; v++ ) + for ( u = 0; u < nVars; u++ ) + Total2[v][u] = Unique2[v][u] = Common2[v][u] = -1; + + nMints1 = (1<<(nVars-2)); + for ( v = 0; v < nVars; v++ ) + { + // move this var to be the first + Kit_TruthCopy( pIn, pTruth, nVars ); +// Extra_PrintBinary( stdout, pIn, (1<<nVars) ); printf( "\n" ); + for ( i = v; i < nVars - 1; i++ ) + { + Kit_TruthSwapAdjacentVars( pOut, pIn, nVars, i ); + pTemp = pIn; pIn = pOut; pOut = pTemp; + } +// Extra_PrintBinary( stdout, pIn, (1<<nVars) ); printf( "\n" ); +// printf( "\n" ); + + + // count minterms in both cofactor + nTotalMints0 = Kit_TruthCountMinterms( pIn, nVars-1, Mints0, pBytes ); + nTotalMints1 = Kit_TruthCountMinterms( pIn+nWords/2, nVars-1, Mints1, pBytes ); + assert( nTotalMints == nTotalMints0 + nTotalMints1 ); +/* + for ( u = 0; u < nVars-1; u++ ) + printf( "%2d ", Mints0[u] ); + printf( "\n" ); + + for ( u = 0; u < nVars-1; u++ ) + printf( "%2d ", Mints1[u] ); + printf( "\n" ); +*/ + for ( u = 0; u < nVars-1; u++ ) + { + if ( u < v ) + iVar = u; + else + iVar = u + 1; + assert( v != iVar ); + // get minter counts in the cofactors + Cof00 = Mints0[u]; Coz00 = nMints1 - Cof00; + Cof01 = nTotalMints0-Mints0[u]; Coz01 = nMints1 - Cof01; + Cof10 = Mints1[u]; Coz10 = nMints1 - Cof10; + Cof11 = nTotalMints1-Mints1[u]; Coz11 = nMints1 - Cof11; + + assert( Cof00 >= 0 && Cof00 <= nMints1 ); + assert( Cof01 >= 0 && Cof01 <= nMints1 ); + assert( Cof10 >= 0 && Cof10 <= nMints1 ); + assert( Cof11 >= 0 && Cof11 <= nMints1 ); + + assert( Coz00 >= 0 && Coz00 <= nMints1 ); + assert( Coz01 >= 0 && Coz01 <= nMints1 ); + assert( Coz10 >= 0 && Coz10 <= nMints1 ); + assert( Coz11 >= 0 && Coz11 <= nMints1 ); + + Common2[v][iVar] = Common2[iVar][v] = Cof00 * Coz11 + Coz00 * Cof11 + Cof01 * Coz10 + Coz01 * Cof10; + + Total2[v][iVar] = Total2[iVar][v] = + Cof00 * Coz01 + Coz00 * Cof01 + + Cof00 * Coz10 + Coz00 * Cof10 + + Cof00 * Coz11 + Coz00 * Cof11 + + Cof01 * Coz10 + Coz01 * Cof10 + + Cof01 * Coz11 + Coz01 * Cof11 + + Cof10 * Coz11 + Coz10 * Cof11 ; + + + Kit_TruthCofactor0New( pCof00, pIn, nVars-1, u ); + Kit_TruthCofactor1New( pCof01, pIn, nVars-1, u ); + Kit_TruthCofactor0New( pCof10, pIn+nWords/2, nVars-1, u ); + Kit_TruthCofactor1New( pCof11, pIn+nWords/2, nVars-1, u ); + + Unique2[v][iVar] = Unique2[iVar][v] = + Kit_TruthXorCount( pCof00, pCof01, nVars-1 ) + + Kit_TruthXorCount( pCof00, pCof10, nVars-1 ) + + Kit_TruthXorCount( pCof00, pCof11, nVars-1 ) + + Kit_TruthXorCount( pCof01, pCof10, nVars-1 ) + + Kit_TruthXorCount( pCof01, pCof11, nVars-1 ) + + Kit_TruthXorCount( pCof10, pCof11, nVars-1 ); + } + } + + printf( "\n" ); + printf( " V: " ); + for ( v = 0; v < nVars; v++ ) + printf( "%8c ", v+'a' ); + printf( "\n" ); + + printf( " M: " ); + for ( v = 0; v < nVars; v++ ) + printf( "%8d ", Mints[v] ); + printf( "\n" ); + + printf( " U: " ); + for ( v = 0; v < nVars; v++ ) + printf( "%8d ", Unique1[v] ); + printf( "\n" ); + printf( "\n" ); + + printf( "Unique:\n" ); + for ( i = 0; i < nVars; i++ ) + { + printf( " %2d ", i ); + for ( v = 0; v < nVars; v++ ) + printf( "%8d ", Unique2[i][v] ); + printf( "\n" ); + } + + printf( "Common:\n" ); + for ( i = 0; i < nVars; i++ ) + { + printf( " %2d ", i ); + for ( v = 0; v < nVars; v++ ) + printf( "%8d ", Common2[i][v] ); + printf( "\n" ); + } + + printf( "Total:\n" ); + for ( i = 0; i < nVars; i++ ) + { + printf( " %2d ", i ); + for ( v = 0; v < nVars; v++ ) + printf( "%8d ", Total2[i][v] ); + printf( "\n" ); + } + + ABC_FREE( pIn ); + ABC_FREE( pOut ); + ABC_FREE( pCof00 ); + ABC_FREE( pCof01 ); + ABC_FREE( pCof10 ); + ABC_FREE( pCof11 ); + ABC_FREE( pBytes ); +} + +/**Function************************************************************* + + Synopsis [Dumps truth table into a file.] + + Description [Generates script file for reading into ABC.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Kit_TruthPrintProfile( unsigned * pTruth, int nVars ) +{ + unsigned uTruth[2]; + if ( nVars >= 6 ) + { + Kit_TruthPrintProfile_int( pTruth, nVars ); + return; + } + assert( nVars >= 2 ); + uTruth[0] = pTruth[0]; + uTruth[1] = pTruth[0]; + Kit_TruthPrintProfile( uTruth, 6 ); +} + + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/kit/kit_.c b/src/aig/kit/kit_.c index 5c68ee3c..37be0b49 100644 --- a/src/aig/kit/kit_.c +++ b/src/aig/kit/kit_.c @@ -20,6 +20,9 @@ #include "kit.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -46,3 +49,5 @@ //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/live/liveness.c b/src/aig/live/liveness.c new file mode 100644 index 00000000..e0511556 --- /dev/null +++ b/src/aig/live/liveness.c @@ -0,0 +1,2575 @@ +/**CFile**************************************************************** + + FileName [liveness.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Liveness property checking.] + + Synopsis [Main implementation module.] + + Author [Sayak Ray] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - January 1, 2009.] + + Revision [$Id: liveness.c,v 1.00 2009/01/01 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include <stdio.h> +#include "main.h" +#include "aig.h" +#include "saig.h" +#include <string.h> +#include "mainInt.h" + +ABC_NAMESPACE_IMPL_START + +#define PROPAGATE_NAMES +#define MULTIPLE_LTL_FORMULA +#define ALLOW_SAFETY_PROPERTIES + +#define FULL_BIERE_MODE 0 +#define IGNORE_LIVENESS_KEEP_SAFETY_MODE 1 +#define IGNORE_SAFETY_KEEP_LIVENESS_MODE 2 +#define IGNORE_SAFETY_KEEP_LIVENESS_ONE_LOOP_MODE 3 +#define FULL_BIERE_ONE_LOOP_MODE 4 +//#define DUPLICATE_CKT_DEBUG + +extern Aig_Man_t * Abc_NtkToDar( Abc_Ntk_t * pNtk, int fExors, int fRegisters ); +extern Abc_Ntk_t * Abc_NtkFromAigPhase( Aig_Man_t * pMan ); +//char *strdup(const char *string); + +//****************************************** +//external functions defined in ltl_parser.c +//****************************************** +typedef struct ltlNode_t ltlNode; +extern ltlNode *readLtlFormula( char *formula ); +extern void traverseAbstractSyntaxTree( ltlNode *node ); +extern ltlNode *parseFormulaCreateAST( char *inputFormula ); +extern int isWellFormed( ltlNode *topNode ); +extern int checkSignalNameExistence( Abc_Ntk_t *pNtk, ltlNode *topASTNode ); +extern void populateBoolWithAigNodePtr( Abc_Ntk_t *pNtk, Aig_Man_t *pAigOld, Aig_Man_t *pAigNew, ltlNode *topASTNode ); +extern int checkAllBoolHaveAIGPointer( ltlNode *topASTNode ); +extern void populateAigPointerUnitGF( Aig_Man_t *pAigNew, ltlNode *topASTNode, Vec_Ptr_t *vSignal, Vec_Vec_t *vAigGFMap ); +extern void setAIGNodePtrOfGloballyNode( ltlNode *astNode, Aig_Obj_t *pObjLo ); +extern Aig_Obj_t *buildLogicFromLTLNode( Aig_Man_t *pAig, ltlNode *pLtlNode ); +extern Aig_Obj_t *retriveAIGPointerFromLTLNode( ltlNode *astNode ); +extern void traverseAbstractSyntaxTree_postFix( ltlNode *node ); +//********************************** +//external function declaration ends +//********************************** + + +/******************************************************************* +LAYOUT OF PI VECTOR: + ++------------------------------------------------------------------------------------------------------------------------------------+ +| TRUE ORIGINAL PI (n) | SAVE(PI) (1) | ORIGINAL LO (k) | SAVED(LO) (1) | SHADOW_ORIGINAL LO (k) | LIVENESS LO (l) | FAIRNESS LO (f) | ++------------------------------------------------------------------------------------------------------------------------------------+ +<------------True PI----------------->|<----------------------------LO---------------------------------------------------------------> + +LAYOUT OF PO VECTOR: + ++-----------------------------------------------------------------------------------------------------------+ +| SOLE PO (1) | ORIGINAL LI (k) | SAVED LI (1) | SHADOW_ORIGINAL LI (k) | LIVENESS LI (l) | FAIRNESS LI (f) | ++-----------------------------------------------------------------------------------------------------------+ +<--True PO--->|<--------------------------------------LI----------------------------------------------------> + +********************************************************************/ + + +static int nodeName_starts_with( Abc_Obj_t *pNode, const char *prefix ) +{ + if( strstr( Abc_ObjName( pNode ), prefix ) == Abc_ObjName( pNode ) ) + return 1; + else + return 0; +} + +void printVecPtrOfString( Vec_Ptr_t *vec ) +{ + int i; + + for( i=0; i< Vec_PtrSize( vec ); i++ ) + { + printf("vec[%d] = %s\n", i, (char *)Vec_PtrEntry(vec, i) ); + } +} + +int getPoIndex( Aig_Man_t *pAig, Aig_Obj_t *pPivot ) +{ + int i; + Aig_Obj_t *pObj; + + Saig_ManForEachPo( pAig, pObj, i ) + { + if( pObj == pPivot ) + return i; + } + return -1; +} + +char * retrieveTruePiName( Abc_Ntk_t *pNtkOld, Aig_Man_t *pAigOld, Aig_Man_t *pAigNew, Aig_Obj_t *pObjPivot ) +{ + Aig_Obj_t *pObjOld, *pObj; + Abc_Obj_t *pNode; + int index; + + assert( Saig_ObjIsPi( pAigNew, pObjPivot ) ); + Aig_ManForEachPi( pAigNew, pObj, index ) + if( pObj == pObjPivot ) + break; + assert( index < Aig_ManPiNum( pAigNew ) - Aig_ManRegNum( pAigNew ) ); + if( index == Saig_ManPiNum( pAigNew ) - 1 ) + return "SAVE_BIERE"; + else + { + pObjOld = Aig_ManPi( pAigOld, index ); + pNode = Abc_NtkPi( pNtkOld, index ); + assert( pObjOld->pData == pObjPivot ); + return Abc_ObjName( pNode ); + } +} + +char * retrieveLOName( Abc_Ntk_t *pNtkOld, Aig_Man_t *pAigOld, Aig_Man_t *pAigNew, Aig_Obj_t *pObjPivot, Vec_Ptr_t *vLive, Vec_Ptr_t * vFair ) +{ + Aig_Obj_t *pObjOld, *pObj; + Abc_Obj_t *pNode; + int index, oldIndex, originalLatchNum = Saig_ManRegNum(pAigOld), strMatch, i; + char *dummyStr = (char *)malloc( sizeof(char) * 50 ); + + assert( Saig_ObjIsLo( pAigNew, pObjPivot ) ); + Saig_ManForEachLo( pAigNew, pObj, index ) + if( pObj == pObjPivot ) + break; + if( index < originalLatchNum ) + { + oldIndex = Saig_ManPiNum( pAigOld ) + index; + pObjOld = Aig_ManPi( pAigOld, oldIndex ); + pNode = Abc_NtkCi( pNtkOld, oldIndex ); + assert( pObjOld->pData == pObjPivot ); + return Abc_ObjName( pNode ); + } + else if( index == originalLatchNum ) + return "SAVED_LO"; + else if( index > originalLatchNum && index < 2 * originalLatchNum + 1 ) + { + oldIndex = Saig_ManPiNum( pAigOld ) + index - originalLatchNum - 1; + pObjOld = Aig_ManPi( pAigOld, oldIndex ); + pNode = Abc_NtkCi( pNtkOld, oldIndex ); + sprintf( dummyStr, "%s__%s", Abc_ObjName( pNode ), "SHADOW"); + return dummyStr; + } + else if( index >= 2 * originalLatchNum + 1 && index < 2 * originalLatchNum + 1 + Vec_PtrSize( vLive ) ) + { + oldIndex = index - 2 * originalLatchNum - 1; + strMatch = 0; + dummyStr[0] = '\0'; + Saig_ManForEachPo( pAigOld, pObj, i ) + { + pNode = Abc_NtkPo( pNtkOld, i ); + //if( strstr( Abc_ObjName( pNode ), "assert_fair" ) != NULL ) + if( nodeName_starts_with( pNode, "assert_fair" ) ) + { + if( strMatch == oldIndex ) + { + sprintf( dummyStr, "%s__%s", Abc_ObjName( pNode ), "LIVENESS"); + //return dummyStr; + break; + } + else + strMatch++; + } + } + assert( dummyStr[0] != '\0' ); + return dummyStr; + } + else if( index >= 2 * originalLatchNum + 1 + Vec_PtrSize( vLive ) && index < 2 * originalLatchNum + 1 + Vec_PtrSize( vLive ) + Vec_PtrSize( vFair ) ) + { + oldIndex = index - 2 * originalLatchNum - 1 - Vec_PtrSize( vLive ); + strMatch = 0; + dummyStr[0] = '\0'; + Saig_ManForEachPo( pAigOld, pObj, i ) + { + pNode = Abc_NtkPo( pNtkOld, i ); + //if( strstr( Abc_ObjName( pNode ), "assume_fair" ) != NULL ) + if( nodeName_starts_with( pNode, "assume_fair" ) ) + { + if( strMatch == oldIndex ) + { + sprintf( dummyStr, "%s__%s", Abc_ObjName( pNode ), "FAIRNESS"); + //return dummyStr; + break; + } + else + strMatch++; + } + } + assert( dummyStr[0] != '\0' ); + return dummyStr; + } + else + return "UNKNOWN"; +} + +Vec_Ptr_t *vecPis, *vecPiNames; +Vec_Ptr_t *vecLos, *vecLoNames; + + +int Aig_ManPiCleanupBiere( Aig_Man_t * p ) +{ + int k = 0, nPisOld = Aig_ManPiNum(p); + + p->nObjs[AIG_OBJ_PI] = Vec_PtrSize( p->vPis ); + if ( Aig_ManRegNum(p) ) + p->nTruePis = Aig_ManPiNum(p) - Aig_ManRegNum(p); + + return nPisOld - Aig_ManPiNum(p); +} + + +int Aig_ManPoCleanupBiere( Aig_Man_t * p ) +{ + int k = 0, nPosOld = Aig_ManPoNum(p); + + p->nObjs[AIG_OBJ_PO] = Vec_PtrSize( p->vPos ); + if ( Aig_ManRegNum(p) ) + p->nTruePos = Aig_ManPoNum(p) - Aig_ManRegNum(p); + return nPosOld - Aig_ManPoNum(p); +} + +Aig_Man_t * LivenessToSafetyTransformation( int mode, Abc_Ntk_t * pNtk, Aig_Man_t * p, + Vec_Ptr_t *vLive, Vec_Ptr_t *vFair, Vec_Ptr_t *vAssertSafety, Vec_Ptr_t *vAssumeSafety ) +{ + Aig_Man_t * pNew; + int i, nRegCount; + Aig_Obj_t * pObjSavePi; + Aig_Obj_t *pObjSavedLo, *pObjSavedLi; + Aig_Obj_t *pObj, *pMatch; + Aig_Obj_t *pObjSaveOrSaved, *pObjSaveAndNotSaved, *pObjSavedLoAndEquality; + Aig_Obj_t *pObjShadowLo, *pObjShadowLi, *pObjShadowLiDriver; + Aig_Obj_t *pObjXor, *pObjXnor, *pObjAndAcc; + Aig_Obj_t *pObjLive, *pObjFair, *pObjSafetyGate; + Aig_Obj_t *pObjSafetyPropertyOutput; + Aig_Obj_t *pObjOriginalSafetyPropertyOutput; + Aig_Obj_t *pDriverImage, *pArgument, *collectiveAssertSafety, *collectiveAssumeSafety; + char *nodeName; + int piCopied = 0, liCopied = 0, loCopied = 0, liCreated = 0, loCreated = 0, piVecIndex = 0, liveLatch = 0, fairLatch = 0; + + vecPis = Vec_PtrAlloc( Saig_ManPiNum( p ) + 1); + vecPiNames = Vec_PtrAlloc( Saig_ManPiNum( p ) + 1); + + vecLos = Vec_PtrAlloc( Saig_ManRegNum( p )*2 + 1 + Vec_PtrSize( vLive ) + Vec_PtrSize( vFair ) ); + vecLoNames = Vec_PtrAlloc( Saig_ManRegNum( p )*2 + 1 + Vec_PtrSize( vLive ) + Vec_PtrSize( vFair ) ); + + //**************************************************************** + // Step1: create the new manager + // Note: The new manager is created with "2 * Aig_ManObjNumMax(p)" + // nodes, but this selection is arbitrary - need to be justified + //**************************************************************** + pNew = Aig_ManStart( 2 * Aig_ManObjNumMax(p) ); + pNew->pName = (char *)malloc( strlen( pNtk->pName ) + strlen("_l2s") + 1 ); + sprintf(pNew->pName, "%s_%s", pNtk->pName, "l2s"); + pNew->pSpec = NULL; + + //**************************************************************** + // Step 2: map constant nodes + //**************************************************************** + pObj = Aig_ManConst1( p ); + pObj->pData = Aig_ManConst1( pNew ); + + //**************************************************************** + // Step 3: create true PIs + //**************************************************************** + Saig_ManForEachPi( p, pObj, i ) + { + piCopied++; + pObj->pData = Aig_ObjCreatePi(pNew); + Vec_PtrPush( vecPis, pObj->pData ); + nodeName = Aig_UtilStrsav(Abc_ObjName( Abc_NtkPi( pNtk, i ) )); + Vec_PtrPush( vecPiNames, nodeName ); + } + + //**************************************************************** + // Step 4: create the special Pi corresponding to SAVE + //**************************************************************** + if( mode == FULL_BIERE_MODE || mode == IGNORE_SAFETY_KEEP_LIVENESS_MODE ) + { + pObjSavePi = Aig_ObjCreatePi( pNew ); + nodeName = "SAVE_BIERE", + Vec_PtrPush( vecPiNames, nodeName ); + } + + //**************************************************************** + // Step 5: create register outputs + //**************************************************************** + Saig_ManForEachLo( p, pObj, i ) + { + loCopied++; + pObj->pData = Aig_ObjCreatePi(pNew); + Vec_PtrPush( vecLos, pObj->pData ); + nodeName = Aig_UtilStrsav(Abc_ObjName( Abc_NtkCi( pNtk, Abc_NtkPiNum(pNtk) + i ) )); + Vec_PtrPush( vecLoNames, nodeName ); + } + + //**************************************************************** + // Step 6: create "saved" register output + //**************************************************************** + if( mode == FULL_BIERE_MODE || mode == IGNORE_SAFETY_KEEP_LIVENESS_MODE ) + { + loCreated++; + pObjSavedLo = Aig_ObjCreatePi( pNew ); + Vec_PtrPush( vecLos, pObjSavedLo ); + nodeName = "SAVED_LO"; + Vec_PtrPush( vecLoNames, nodeName ); + } + + //**************************************************************** + // Step 7: create the OR gate and the AND gate directly fed by "SAVE" Pi + //**************************************************************** + if( mode == FULL_BIERE_MODE || mode == IGNORE_SAFETY_KEEP_LIVENESS_MODE ) + { + pObjSaveOrSaved = Aig_Or( pNew, pObjSavePi, pObjSavedLo ); + pObjSaveAndNotSaved = Aig_And( pNew, pObjSavePi, Aig_Not(pObjSavedLo) ); + } + + //******************************************************************** + // Step 8: create internal nodes + //******************************************************************** + Aig_ManForEachNode( p, pObj, i ) + { + pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + } + + + //******************************************************************** + // Step 8.x : create PO for each safety assertions + // NOTE : Here the output is purposely inverted as it will be thrown to + // dprove + //******************************************************************** + if( mode == FULL_BIERE_MODE || mode == IGNORE_LIVENESS_KEEP_SAFETY_MODE ) + { + if( Vec_PtrSize( vAssertSafety ) != 0 && Vec_PtrSize( vAssumeSafety ) == 0 ) + { + pObjAndAcc = Aig_ManConst1( pNew ); + Vec_PtrForEachEntry( Aig_Obj_t *, vAssertSafety, pObj, i ) + { + pArgument = Aig_NotCond( (Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0( pObj ) ); + pObjAndAcc = Aig_And( pNew, pArgument, pObjAndAcc ); + } + pObjOriginalSafetyPropertyOutput = Aig_ObjCreatePo( pNew, Aig_Not(pObjAndAcc) ); + } + else if( Vec_PtrSize( vAssertSafety ) != 0 && Vec_PtrSize( vAssumeSafety ) != 0 ) + { + pObjAndAcc = Aig_ManConst1( pNew ); + Vec_PtrForEachEntry( Aig_Obj_t *, vAssertSafety, pObj, i ) + { + pArgument = Aig_NotCond( (Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0( pObj ) ); + pObjAndAcc = Aig_And( pNew, pArgument, pObjAndAcc ); + } + collectiveAssertSafety = pObjAndAcc; + + pObjAndAcc = Aig_ManConst1( pNew ); + Vec_PtrForEachEntry( Aig_Obj_t *, vAssumeSafety, pObj, i ) + { + pArgument = Aig_NotCond( (Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0( pObj ) ); + pObjAndAcc = Aig_And( pNew, pArgument, pObjAndAcc ); + } + collectiveAssumeSafety = pObjAndAcc; + pObjOriginalSafetyPropertyOutput = Aig_ObjCreatePo( pNew, Aig_And( pNew, Aig_Not(collectiveAssertSafety), collectiveAssumeSafety ) ); + } + else + { + printf("WARNING!! No safety property is found, a new (negated) constant 1 output is created\n"); + pObjOriginalSafetyPropertyOutput = Aig_ObjCreatePo( pNew, Aig_Not( Aig_ManConst1(pNew) ) ); + } + } + + //******************************************************************** + // Step 9: create the safety property output gate for the liveness properties + // discuss with Sat/Alan for an alternative implementation + //******************************************************************** + if( mode == FULL_BIERE_MODE || mode == IGNORE_SAFETY_KEEP_LIVENESS_MODE ) + { + pObjSafetyPropertyOutput = Aig_ObjCreatePo( pNew, (Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData ); + } + + // create register inputs for the original registers + nRegCount = 0; + + Saig_ManForEachLo( p, pObj, i ) + { + pMatch = Saig_ObjLoToLi( p, pObj ); + Aig_ObjCreatePo( pNew, Aig_NotCond((Aig_Obj_t *)Aig_ObjFanin0(pMatch)->pData, Aig_ObjFaninC0( pMatch ) ) ); + nRegCount++; + liCopied++; + } + + // create register input corresponding to the register "saved" + if( mode == FULL_BIERE_MODE || mode == IGNORE_SAFETY_KEEP_LIVENESS_MODE ) + { + #ifndef DUPLICATE_CKT_DEBUG + pObjSavedLi = Aig_ObjCreatePo( pNew, pObjSaveOrSaved ); + nRegCount++; + liCreated++; + + //Changed on October 13, 2009 + //pObjAndAcc = NULL; + pObjAndAcc = Aig_ManConst1( pNew ); + + // create the family of shadow registers, then create the cascade of Xnor and And gates for the comparator + Saig_ManForEachLo( p, pObj, i ) + { + pObjShadowLo = Aig_ObjCreatePi( pNew ); + + #ifdef PROPAGATE_NAMES + Vec_PtrPush( vecLos, pObjShadowLo ); + nodeName = (char *)malloc( strlen( Abc_ObjName( Abc_NtkCi( pNtk, Abc_NtkPiNum(pNtk) + i ) ) ) + 10 ); + sprintf( nodeName, "%s__%s", Abc_ObjName( Abc_NtkCi( pNtk, Abc_NtkPiNum(pNtk) + i ) ), "SHADOW" ); + + Vec_PtrPush( vecLoNames, nodeName ); + #endif + + pObjShadowLiDriver = Aig_Mux( pNew, pObjSaveAndNotSaved, (Aig_Obj_t *)pObj->pData, pObjShadowLo ); + pObjShadowLi = Aig_ObjCreatePo( pNew, pObjShadowLiDriver ); + nRegCount++; + loCreated++; liCreated++; + + pObjXor = Aig_Exor( pNew, (Aig_Obj_t *)pObj->pData, pObjShadowLo ); + pObjXnor = Aig_Not( pObjXor ); + + pObjAndAcc = Aig_And( pNew, pObjXnor, pObjAndAcc ); + } + + // create the AND gate whose output will be the signal "looped" + pObjSavedLoAndEquality = Aig_And( pNew, pObjSavedLo, pObjAndAcc ); + + // create the master AND gate and corresponding AND and OR logic for the liveness properties + pObjAndAcc = Aig_ManConst1( pNew ); + if( vLive == NULL || Vec_PtrSize( vLive ) == 0 ) + { + printf("Circuit without any liveness property\n"); + } + else + { + Vec_PtrForEachEntry( Aig_Obj_t *, vLive, pObj, i ) + { + liveLatch++; + pDriverImage = Aig_NotCond((Aig_Obj_t *)Aig_Regular(Aig_ObjChild0( pObj ))->pData, Aig_ObjFaninC0(pObj)); + pObjShadowLo = Aig_ObjCreatePi( pNew ); + + #ifdef PROPAGATE_NAMES + Vec_PtrPush( vecLos, pObjShadowLo ); + nodeName = (char *)malloc( strlen( Abc_ObjName( Abc_NtkPo( pNtk, getPoIndex( p, pObj ) ) ) ) + 12 ); + sprintf( nodeName, "%s__%s", Abc_ObjName( Abc_NtkPo( pNtk, getPoIndex( p, pObj ) ) ), "LIVENESS" ); + Vec_PtrPush( vecLoNames, nodeName ); + #endif + + pObjShadowLiDriver = Aig_Or( pNew, pObjShadowLo, Aig_And( pNew, pDriverImage, pObjSaveOrSaved ) ); + pObjShadowLi = Aig_ObjCreatePo( pNew, pObjShadowLiDriver ); + nRegCount++; + loCreated++; liCreated++; + + pObjAndAcc = Aig_And( pNew, pObjShadowLo, pObjAndAcc ); + } + } + + pObjLive = pObjAndAcc; + + pObjAndAcc = Aig_ManConst1( pNew ); + if( vFair == NULL || Vec_PtrSize( vFair ) == 0 ) + printf("Circuit without any fairness property\n"); + else + { + Vec_PtrForEachEntry( Aig_Obj_t *, vFair, pObj, i ) + { + fairLatch++; + pDriverImage = Aig_NotCond((Aig_Obj_t *)Aig_Regular(Aig_ObjChild0( pObj ))->pData, Aig_ObjFaninC0(pObj)); + pObjShadowLo = Aig_ObjCreatePi( pNew ); + + #ifdef PROPAGATE_NAMES + Vec_PtrPush( vecLos, pObjShadowLo ); + nodeName = (char *)malloc( strlen( Abc_ObjName( Abc_NtkPo( pNtk, getPoIndex( p, pObj ) ) ) ) + 12 ); + sprintf( nodeName, "%s__%s", Abc_ObjName( Abc_NtkPo( pNtk, getPoIndex( p, pObj ) ) ), "FAIRNESS" ); + Vec_PtrPush( vecLoNames, nodeName ); + #endif + + pObjShadowLiDriver = Aig_Or( pNew, pObjShadowLo, Aig_And( pNew, pDriverImage, pObjSaveOrSaved ) ); + pObjShadowLi = Aig_ObjCreatePo( pNew, pObjShadowLiDriver ); + nRegCount++; + loCreated++; liCreated++; + + pObjAndAcc = Aig_And( pNew, pObjShadowLo, pObjAndAcc ); + } + } + + pObjFair = pObjAndAcc; + + //pObjSafetyGate = Aig_Exor( pNew, Aig_Not(Aig_ManConst1( pNew )), Aig_And( pNew, pObjSavedLoAndEquality, Aig_And( pNew, pObjFair, Aig_Not( pObjLive ) ) ) ); + //Following is the actual Biere translation + pObjSafetyGate = Aig_And( pNew, pObjSavedLoAndEquality, Aig_And( pNew, pObjFair, Aig_Not( pObjLive ) ) ); + + Aig_ObjPatchFanin0( pNew, pObjSafetyPropertyOutput, pObjSafetyGate ); + #endif + } + + Aig_ManSetRegNum( pNew, nRegCount ); + + Aig_ManPiCleanupBiere( pNew ); + Aig_ManPoCleanupBiere( pNew ); + + Aig_ManCleanup( pNew ); + + assert( Aig_ManCheck( pNew ) ); + + if( mode == FULL_BIERE_MODE || mode == IGNORE_SAFETY_KEEP_LIVENESS_MODE ) + { + assert((Aig_Obj_t *)Vec_PtrEntry(pNew->vPos, Saig_ManPoNum(pNew)+Aig_ObjPioNum(pObjSavedLo)-Saig_ManPiNum(p)-1) == pObjSavedLi); + assert( Saig_ManPiNum( p ) + 1 == Saig_ManPiNum( pNew ) ); + assert( Saig_ManRegNum( pNew ) == Saig_ManRegNum( p ) * 2 + 1 + liveLatch + fairLatch ); + } + + return pNew; +} + + + + + +Aig_Man_t * LivenessToSafetyTransformationAbs( int mode, Abc_Ntk_t * pNtk, Aig_Man_t * p, Vec_Int_t *vFlops, + Vec_Ptr_t *vLive, Vec_Ptr_t *vFair, Vec_Ptr_t *vAssertSafety, Vec_Ptr_t *vAssumeSafety ) +{ + Aig_Man_t * pNew; + int i, nRegCount, iEntry; + Aig_Obj_t * pObjSavePi; + Aig_Obj_t *pObjSavedLo, *pObjSavedLi; + Aig_Obj_t *pObj, *pMatch; + Aig_Obj_t *pObjSaveOrSaved, *pObjSaveAndNotSaved, *pObjSavedLoAndEquality; + Aig_Obj_t *pObjShadowLo, *pObjShadowLi, *pObjShadowLiDriver; + Aig_Obj_t *pObjXor, *pObjXnor, *pObjAndAcc; + Aig_Obj_t *pObjLive, *pObjFair, *pObjSafetyGate; + Aig_Obj_t *pObjSafetyPropertyOutput; + Aig_Obj_t *pDriverImage, *pArgument, *collectiveAssertSafety, *collectiveAssumeSafety; + char *nodeName; + int piCopied = 0, liCopied = 0, loCopied = 0, liCreated = 0, loCreated = 0, piVecIndex = 0, liveLatch = 0, fairLatch = 0; + + vecPis = Vec_PtrAlloc( Saig_ManPiNum( p ) + 1); + vecPiNames = Vec_PtrAlloc( Saig_ManPiNum( p ) + 1); + + vecLos = Vec_PtrAlloc( Saig_ManRegNum( p ) + Vec_IntSize( vFlops ) + 1 + Vec_PtrSize( vLive ) + Vec_PtrSize( vFair ) ); + vecLoNames = Vec_PtrAlloc( Saig_ManRegNum( p ) + Vec_IntSize( vFlops ) + 1 + Vec_PtrSize( vLive ) + Vec_PtrSize( vFair ) ); + + //**************************************************************** + // Step1: create the new manager + // Note: The new manager is created with "2 * Aig_ManObjNumMax(p)" + // nodes, but this selection is arbitrary - need to be justified + //**************************************************************** + pNew = Aig_ManStart( 2 * Aig_ManObjNumMax(p) ); + pNew->pName = (char *)malloc( strlen( pNtk->pName ) + strlen("_l2s") + 1 ); + sprintf(pNew->pName, "%s_%s", pNtk->pName, "l2s"); + pNew->pSpec = NULL; + + //**************************************************************** + // Step 2: map constant nodes + //**************************************************************** + pObj = Aig_ManConst1( p ); + pObj->pData = Aig_ManConst1( pNew ); + + //**************************************************************** + // Step 3: create true PIs + //**************************************************************** + Saig_ManForEachPi( p, pObj, i ) + { + piCopied++; + pObj->pData = Aig_ObjCreatePi(pNew); + Vec_PtrPush( vecPis, pObj->pData ); + nodeName = Aig_UtilStrsav(Abc_ObjName( Abc_NtkPi( pNtk, i ) )); + Vec_PtrPush( vecPiNames, nodeName ); + } + + //**************************************************************** + // Step 4: create the special Pi corresponding to SAVE + //**************************************************************** + if( mode == FULL_BIERE_MODE || mode == IGNORE_SAFETY_KEEP_LIVENESS_MODE ) + { + pObjSavePi = Aig_ObjCreatePi( pNew ); + nodeName = "SAVE_BIERE", + Vec_PtrPush( vecPiNames, nodeName ); + } + + //**************************************************************** + // Step 5: create register outputs + //**************************************************************** + Saig_ManForEachLo( p, pObj, i ) + { + loCopied++; + pObj->pData = Aig_ObjCreatePi(pNew); + Vec_PtrPush( vecLos, pObj->pData ); + nodeName = Aig_UtilStrsav(Abc_ObjName( Abc_NtkCi( pNtk, Abc_NtkPiNum(pNtk) + i ) )); + Vec_PtrPush( vecLoNames, nodeName ); + } + + //**************************************************************** + // Step 6: create "saved" register output + //**************************************************************** + if( mode == FULL_BIERE_MODE || mode == IGNORE_SAFETY_KEEP_LIVENESS_MODE ) + { + loCreated++; + pObjSavedLo = Aig_ObjCreatePi( pNew ); + Vec_PtrPush( vecLos, pObjSavedLo ); + nodeName = "SAVED_LO"; + Vec_PtrPush( vecLoNames, nodeName ); + } + + //**************************************************************** + // Step 7: create the OR gate and the AND gate directly fed by "SAVE" Pi + //**************************************************************** + if( mode == FULL_BIERE_MODE || mode == IGNORE_SAFETY_KEEP_LIVENESS_MODE ) + { + pObjSaveOrSaved = Aig_Or( pNew, pObjSavePi, pObjSavedLo ); + pObjSaveAndNotSaved = Aig_And( pNew, pObjSavePi, Aig_Not(pObjSavedLo) ); + } + + //******************************************************************** + // Step 8: create internal nodes + //******************************************************************** + Aig_ManForEachNode( p, pObj, i ) + { + pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + } + + + //******************************************************************** + // Step 8.x : create PO for each safety assertions + // NOTE : Here the output is purposely inverted as it will be thrown to + // dprove + //******************************************************************** + if( mode == FULL_BIERE_MODE || mode == IGNORE_LIVENESS_KEEP_SAFETY_MODE ) + { + if( Vec_PtrSize( vAssertSafety ) != 0 && Vec_PtrSize( vAssumeSafety ) == 0 ) + { + pObjAndAcc = Aig_ManConst1( pNew ); + Vec_PtrForEachEntry( Aig_Obj_t *, vAssertSafety, pObj, i ) + { + pArgument = Aig_NotCond( (Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0( pObj ) ); + pObjAndAcc = Aig_And( pNew, pArgument, pObjAndAcc ); + } + Aig_ObjCreatePo( pNew, Aig_Not(pObjAndAcc) ); + } + else if( Vec_PtrSize( vAssertSafety ) != 0 && Vec_PtrSize( vAssumeSafety ) != 0 ) + { + pObjAndAcc = Aig_ManConst1( pNew ); + Vec_PtrForEachEntry( Aig_Obj_t *, vAssertSafety, pObj, i ) + { + pArgument = Aig_NotCond( (Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0( pObj ) ); + pObjAndAcc = Aig_And( pNew, pArgument, pObjAndAcc ); + } + collectiveAssertSafety = pObjAndAcc; + + pObjAndAcc = Aig_ManConst1( pNew ); + Vec_PtrForEachEntry( Aig_Obj_t *, vAssumeSafety, pObj, i ) + { + pArgument = Aig_NotCond( (Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0( pObj ) ); + pObjAndAcc = Aig_And( pNew, pArgument, pObjAndAcc ); + } + collectiveAssumeSafety = pObjAndAcc; + Aig_ObjCreatePo( pNew, Aig_And( pNew, Aig_Not(collectiveAssertSafety), collectiveAssumeSafety ) ); + } + else + { + printf("WARNING!! No safety property is found, a new (negated) constant 1 output is created\n"); + Aig_ObjCreatePo( pNew, Aig_Not( Aig_ManConst1(pNew) ) ); + } + } + + //******************************************************************** + // Step 9: create the safety property output gate for the liveness properties + // discuss with Sat/Alan for an alternative implementation + //******************************************************************** + if( mode == FULL_BIERE_MODE || mode == IGNORE_SAFETY_KEEP_LIVENESS_MODE ) + { + pObjSafetyPropertyOutput = Aig_ObjCreatePo( pNew, (Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData ); + } + + // create register inputs for the original registers + nRegCount = 0; + + Saig_ManForEachLo( p, pObj, i ) + { + pMatch = Saig_ObjLoToLi( p, pObj ); + Aig_ObjCreatePo( pNew, Aig_NotCond((Aig_Obj_t *)Aig_ObjFanin0(pMatch)->pData, Aig_ObjFaninC0( pMatch ) ) ); + nRegCount++; + liCopied++; + } + + // create register input corresponding to the register "saved" + if( mode == FULL_BIERE_MODE || mode == IGNORE_SAFETY_KEEP_LIVENESS_MODE ) + { + #ifndef DUPLICATE_CKT_DEBUG + pObjSavedLi = Aig_ObjCreatePo( pNew, pObjSaveOrSaved ); + nRegCount++; + liCreated++; + + //Changed on October 13, 2009 + //pObjAndAcc = NULL; + pObjAndAcc = Aig_ManConst1( pNew ); + + // create the family of shadow registers, then create the cascade of Xnor and And gates for the comparator + //Saig_ManForEachLo( p, pObj, i ) + Saig_ManForEachLo( p, pObj, i ) + { + printf("Flop[%d] = %s\n", i, Abc_ObjName( Abc_NtkCi( pNtk, Abc_NtkPiNum(pNtk) + i ) ) ); + } + Vec_IntForEachEntry( vFlops, iEntry, i ) + { + pObjShadowLo = Aig_ObjCreatePi( pNew ); + pObj = Aig_ManLo( p, iEntry ); + + #ifdef PROPAGATE_NAMES + Vec_PtrPush( vecLos, pObjShadowLo ); + nodeName = (char *)malloc( strlen( Abc_ObjName( Abc_NtkCi( pNtk, Abc_NtkPiNum(pNtk) + iEntry ) ) ) + 10 ); + sprintf( nodeName, "%s__%s", Abc_ObjName( Abc_NtkCi( pNtk, Abc_NtkPiNum(pNtk) + iEntry ) ), "SHADOW" ); + printf("Flop copied [%d] = %s\n", iEntry, nodeName ); + Vec_PtrPush( vecLoNames, nodeName ); + #endif + + pObjShadowLiDriver = Aig_Mux( pNew, pObjSaveAndNotSaved, (Aig_Obj_t *)pObj->pData, pObjShadowLo ); + pObjShadowLi = Aig_ObjCreatePo( pNew, pObjShadowLiDriver ); + nRegCount++; + loCreated++; liCreated++; + + pObjXor = Aig_Exor( pNew, (Aig_Obj_t *)pObj->pData, pObjShadowLo ); + pObjXnor = Aig_Not( pObjXor ); + + pObjAndAcc = Aig_And( pNew, pObjXnor, pObjAndAcc ); + } + + // create the AND gate whose output will be the signal "looped" + pObjSavedLoAndEquality = Aig_And( pNew, pObjSavedLo, pObjAndAcc ); + + // create the master AND gate and corresponding AND and OR logic for the liveness properties + pObjAndAcc = Aig_ManConst1( pNew ); + if( vLive == NULL || Vec_PtrSize( vLive ) == 0 ) + { + printf("Circuit without any liveness property\n"); + } + else + { + Vec_PtrForEachEntry( Aig_Obj_t *, vLive, pObj, i ) + { + liveLatch++; + pDriverImage = Aig_NotCond((Aig_Obj_t *)Aig_Regular(Aig_ObjChild0( pObj ))->pData, Aig_ObjFaninC0(pObj)); + pObjShadowLo = Aig_ObjCreatePi( pNew ); + + #ifdef PROPAGATE_NAMES + Vec_PtrPush( vecLos, pObjShadowLo ); + nodeName = (char *)malloc( strlen( Abc_ObjName( Abc_NtkPo( pNtk, getPoIndex( p, pObj ) ) ) ) + 12 ); + sprintf( nodeName, "%s__%s", Abc_ObjName( Abc_NtkPo( pNtk, getPoIndex( p, pObj ) ) ), "LIVENESS" ); + Vec_PtrPush( vecLoNames, nodeName ); + #endif + + pObjShadowLiDriver = Aig_Or( pNew, pObjShadowLo, Aig_And( pNew, pDriverImage, pObjSaveOrSaved ) ); + pObjShadowLi = Aig_ObjCreatePo( pNew, pObjShadowLiDriver ); + nRegCount++; + loCreated++; liCreated++; + + pObjAndAcc = Aig_And( pNew, pObjShadowLo, pObjAndAcc ); + } + } + + pObjLive = pObjAndAcc; + + pObjAndAcc = Aig_ManConst1( pNew ); + if( vFair == NULL || Vec_PtrSize( vFair ) == 0 ) + printf("Circuit without any fairness property\n"); + else + { + Vec_PtrForEachEntry( Aig_Obj_t *, vFair, pObj, i ) + { + fairLatch++; + pDriverImage = Aig_NotCond((Aig_Obj_t *)Aig_Regular(Aig_ObjChild0( pObj ))->pData, Aig_ObjFaninC0(pObj)); + pObjShadowLo = Aig_ObjCreatePi( pNew ); + + #ifdef PROPAGATE_NAMES + Vec_PtrPush( vecLos, pObjShadowLo ); + nodeName = (char *)malloc( strlen( Abc_ObjName( Abc_NtkPo( pNtk, getPoIndex( p, pObj ) ) ) ) + 12 ); + sprintf( nodeName, "%s__%s", Abc_ObjName( Abc_NtkPo( pNtk, getPoIndex( p, pObj ) ) ), "FAIRNESS" ); + Vec_PtrPush( vecLoNames, nodeName ); + #endif + + pObjShadowLiDriver = Aig_Or( pNew, pObjShadowLo, Aig_And( pNew, pDriverImage, pObjSaveOrSaved ) ); + pObjShadowLi = Aig_ObjCreatePo( pNew, pObjShadowLiDriver ); + nRegCount++; + loCreated++; liCreated++; + + pObjAndAcc = Aig_And( pNew, pObjShadowLo, pObjAndAcc ); + } + } + + pObjFair = pObjAndAcc; + + //pObjSafetyGate = Aig_Exor( pNew, Aig_Not(Aig_ManConst1( pNew )), Aig_And( pNew, pObjSavedLoAndEquality, Aig_And( pNew, pObjFair, Aig_Not( pObjLive ) ) ) ); + //Following is the actual Biere translation + pObjSafetyGate = Aig_And( pNew, pObjSavedLoAndEquality, Aig_And( pNew, pObjFair, Aig_Not( pObjLive ) ) ); + + Aig_ObjPatchFanin0( pNew, pObjSafetyPropertyOutput, pObjSafetyGate ); + #endif + } + + Aig_ManSetRegNum( pNew, nRegCount ); + + Aig_ManPiCleanupBiere( pNew ); + Aig_ManPoCleanupBiere( pNew ); + + Aig_ManCleanup( pNew ); + + assert( Aig_ManCheck( pNew ) ); + + if( mode == FULL_BIERE_MODE || mode == IGNORE_SAFETY_KEEP_LIVENESS_MODE ) + { + assert((Aig_Obj_t *)Vec_PtrEntry(pNew->vPos, Saig_ManPoNum(pNew)+Aig_ObjPioNum(pObjSavedLo)-Saig_ManPiNum(p)-1) == pObjSavedLi); + assert( Saig_ManPiNum( p ) + 1 == Saig_ManPiNum( pNew ) ); + assert( Saig_ManRegNum( pNew ) == Saig_ManRegNum( p ) + Vec_IntSize( vFlops ) + 1 + liveLatch + fairLatch ); + } + + return pNew; +} + + + +Aig_Man_t * LivenessToSafetyTransformationOneStepLoop( int mode, Abc_Ntk_t * pNtk, Aig_Man_t * p, + Vec_Ptr_t *vLive, Vec_Ptr_t *vFair, Vec_Ptr_t *vAssertSafety, Vec_Ptr_t *vAssumeSafety ) +{ + Aig_Man_t * pNew; + int i, nRegCount; + Aig_Obj_t * pObjSavePi; + Aig_Obj_t *pObj, *pMatch; + Aig_Obj_t *pObjSavedLoAndEquality; + Aig_Obj_t *pObjXor, *pObjXnor, *pObjAndAcc, *pObjAndAccDummy; + Aig_Obj_t *pObjLive, *pObjFair, *pObjSafetyGate; + Aig_Obj_t *pObjSafetyPropertyOutput; + Aig_Obj_t *pDriverImage; + Aig_Obj_t *pObjCorrespondingLi; + Aig_Obj_t *pArgument; + Aig_Obj_t *collectiveAssertSafety, *collectiveAssumeSafety; + + char *nodeName; + int piCopied = 0, liCopied = 0, loCopied = 0, liCreated = 0, loCreated = 0, piVecIndex = 0; + + if( Aig_ManRegNum( p ) == 0 ) + { + printf("The input AIG contains no register, returning the original AIG as it is\n"); + return p; + } + + vecPis = Vec_PtrAlloc( Saig_ManPiNum( p ) + 1); + vecPiNames = Vec_PtrAlloc( Saig_ManPiNum( p ) + 1); + + vecLos = Vec_PtrAlloc( Saig_ManRegNum( p )*2 + 1 + Vec_PtrSize( vLive ) + Vec_PtrSize( vFair ) ); + vecLoNames = Vec_PtrAlloc( Saig_ManRegNum( p )*2 + 1 + Vec_PtrSize( vLive ) + Vec_PtrSize( vFair ) ); + + //**************************************************************** + // Step1: create the new manager + // Note: The new manager is created with "2 * Aig_ManObjNumMax(p)" + // nodes, but this selection is arbitrary - need to be justified + //**************************************************************** + pNew = Aig_ManStart( 2 * Aig_ManObjNumMax(p) ); + pNew->pName = Aig_UtilStrsav( "live2safe" ); + pNew->pSpec = NULL; + + //**************************************************************** + // Step 2: map constant nodes + //**************************************************************** + pObj = Aig_ManConst1( p ); + pObj->pData = Aig_ManConst1( pNew ); + + //**************************************************************** + // Step 3: create true PIs + //**************************************************************** + Saig_ManForEachPi( p, pObj, i ) + { + piCopied++; + pObj->pData = Aig_ObjCreatePi(pNew); + Vec_PtrPush( vecPis, pObj->pData ); + nodeName = Aig_UtilStrsav(Abc_ObjName( Abc_NtkPi( pNtk, i ) )); + Vec_PtrPush( vecPiNames, nodeName ); + } + + //**************************************************************** + // Step 4: create the special Pi corresponding to SAVE + //**************************************************************** + if( mode == FULL_BIERE_ONE_LOOP_MODE || mode == IGNORE_SAFETY_KEEP_LIVENESS_ONE_LOOP_MODE ) + { + pObjSavePi = Aig_ObjCreatePi( pNew ); + nodeName = "SAVE_BIERE", + Vec_PtrPush( vecPiNames, nodeName ); + } + + //**************************************************************** + // Step 5: create register outputs + //**************************************************************** + Saig_ManForEachLo( p, pObj, i ) + { + loCopied++; + pObj->pData = Aig_ObjCreatePi(pNew); + Vec_PtrPush( vecLos, pObj->pData ); + nodeName = Aig_UtilStrsav(Abc_ObjName( Abc_NtkCi( pNtk, Abc_NtkPiNum(pNtk) + i ) )); + Vec_PtrPush( vecLoNames, nodeName ); + } + + //**************************************************************** + // Step 6: create "saved" register output + //**************************************************************** + +#if 0 + loCreated++; + pObjSavedLo = Aig_ObjCreatePi( pNew ); + Vec_PtrPush( vecLos, pObjSavedLo ); + nodeName = "SAVED_LO"; + Vec_PtrPush( vecLoNames, nodeName ); +#endif + + //**************************************************************** + // Step 7: create the OR gate and the AND gate directly fed by "SAVE" Pi + //**************************************************************** +#if 0 + pObjSaveOrSaved = Aig_Or( pNew, pObjSavePi, pObjSavedLo ); + pObjSaveAndNotSaved = Aig_And( pNew, pObjSavePi, Aig_Not(pObjSavedLo) ); +#endif + + //******************************************************************** + // Step 8: create internal nodes + //******************************************************************** + Aig_ManForEachNode( p, pObj, i ) + { + pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + } + +#if 0 + //******************************************************************** + // Step 8.x : create PO for each safety assertions + //******************************************************************** + Vec_PtrForEachEntry( Aig_Obj_t *, vAssertSafety, pObj, i ) + { + pObj->pData = Aig_ObjCreatePo( pNew, Aig_NotCond(Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0( pObj ) ) ); + } +#endif + + if( mode == FULL_BIERE_ONE_LOOP_MODE || mode == IGNORE_LIVENESS_KEEP_SAFETY_MODE ) + { + if( Vec_PtrSize( vAssertSafety ) != 0 && Vec_PtrSize( vAssumeSafety ) == 0 ) + { + pObjAndAcc = NULL; + Vec_PtrForEachEntry( Aig_Obj_t *, vAssertSafety, pObj, i ) + { + //pObj->pData = Aig_ObjCreatePo( pNew, Aig_NotCond(Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0( pObj ) ) ); + pArgument = Aig_NotCond( (Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0( pObj ) ); + if( pObjAndAcc == NULL ) + pObjAndAcc = pArgument; + else + { + pObjAndAccDummy = pObjAndAcc; + pObjAndAcc = Aig_And( pNew, pArgument, pObjAndAccDummy ); + } + } + Aig_ObjCreatePo( pNew, Aig_Not(pObjAndAcc) ); + } + else if( Vec_PtrSize( vAssertSafety ) != 0 && Vec_PtrSize( vAssumeSafety ) != 0 ) + { + pObjAndAcc = NULL; + Vec_PtrForEachEntry( Aig_Obj_t *, vAssertSafety, pObj, i ) + { + //pObj->pData = Aig_ObjCreatePo( pNew, Aig_NotCond(Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0( pObj ) ) ); + pArgument = Aig_NotCond( (Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0( pObj ) ); + if( pObjAndAcc == NULL ) + pObjAndAcc = pArgument; + else + { + pObjAndAccDummy = pObjAndAcc; + pObjAndAcc = Aig_And( pNew, pArgument, pObjAndAccDummy ); + } + } + collectiveAssertSafety = pObjAndAcc; + pObjAndAcc = NULL; + Vec_PtrForEachEntry( Aig_Obj_t *, vAssumeSafety, pObj, i ) + { + //pObj->pData = Aig_ObjCreatePo( pNew, Aig_NotCond(Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0( pObj ) ) ); + pArgument = Aig_NotCond( (Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0( pObj ) ); + if( pObjAndAcc == NULL ) + pObjAndAcc = pArgument; + else + { + pObjAndAccDummy = pObjAndAcc; + pObjAndAcc = Aig_And( pNew, pArgument, pObjAndAccDummy ); + } + } + collectiveAssumeSafety = pObjAndAcc; + Aig_ObjCreatePo( pNew, Aig_And( pNew, Aig_Not(collectiveAssertSafety), collectiveAssumeSafety ) ); + } + else + printf("No safety property is specified, hence no safety gate is created\n"); + } + + //******************************************************************** + // Step 9: create the safety property output gate + // create the safety property output gate, this will be the sole true PO + // of the whole circuit, discuss with Sat/Alan for an alternative implementation + //******************************************************************** + + if( mode == FULL_BIERE_ONE_LOOP_MODE || mode == IGNORE_SAFETY_KEEP_LIVENESS_ONE_LOOP_MODE ) + { + pObjSafetyPropertyOutput = Aig_ObjCreatePo( pNew, (Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData ); + } + + // create register inputs for the original registers + nRegCount = 0; + + Saig_ManForEachLo( p, pObj, i ) + { + pMatch = Saig_ObjLoToLi( p, pObj ); + //Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pMatch) ); + Aig_ObjCreatePo( pNew, Aig_NotCond((Aig_Obj_t *)Aig_ObjFanin0(pMatch)->pData, Aig_ObjFaninC0( pMatch ) ) ); + nRegCount++; + liCopied++; + } + +#if 0 + // create register input corresponding to the register "saved" + pObjSavedLi = Aig_ObjCreatePo( pNew, pObjSaveOrSaved ); + nRegCount++; + liCreated++;7 +#endif + + pObjAndAcc = NULL; + + //**************************************************************************************************** + //For detection of loop of length 1 we do not need any shadow register, we only need equality detector + //between Lo_j and Li_j and then a cascade of AND gates + //**************************************************************************************************** + + if( mode == FULL_BIERE_ONE_LOOP_MODE || mode == IGNORE_SAFETY_KEEP_LIVENESS_ONE_LOOP_MODE ) + { + Saig_ManForEachLo( p, pObj, i ) + { + pObjCorrespondingLi = Saig_ObjLoToLi( p, pObj ); + + pObjXor = Aig_Exor( pNew, (Aig_Obj_t *)pObj->pData, Aig_NotCond( (Aig_Obj_t *)Aig_ObjFanin0( pObjCorrespondingLi )->pData, Aig_ObjFaninC0( pObjCorrespondingLi ) ) ); + pObjXnor = Aig_Not( pObjXor ); + + if( pObjAndAcc == NULL ) + pObjAndAcc = pObjXnor; + else + { + pObjAndAccDummy = pObjAndAcc; + pObjAndAcc = Aig_And( pNew, pObjXnor, pObjAndAccDummy ); + } + } + + // create the AND gate whose output will be the signal "looped" + pObjSavedLoAndEquality = Aig_And( pNew, pObjSavePi, pObjAndAcc ); + + // create the master AND gate and corresponding AND and OR logic for the liveness properties + pObjAndAcc = NULL; + if( vLive == NULL || Vec_PtrSize( vLive ) == 0 ) + printf("Circuit without any liveness property\n"); + else + { + Vec_PtrForEachEntry( Aig_Obj_t *, vLive, pObj, i ) + { + pDriverImage = Aig_NotCond((Aig_Obj_t *)Aig_Regular(Aig_ObjChild0( pObj ))->pData, Aig_ObjFaninC0(pObj)); + if( pObjAndAcc == NULL ) + pObjAndAcc = pDriverImage; + else + { + pObjAndAccDummy = pObjAndAcc; + pObjAndAcc = Aig_And( pNew, pDriverImage, pObjAndAccDummy ); + } + } + } + + if( pObjAndAcc != NULL ) + pObjLive = pObjAndAcc; + else + pObjLive = Aig_ManConst1( pNew ); + + // create the master AND gate and corresponding AND and OR logic for the fairness properties + pObjAndAcc = NULL; + if( vFair == NULL || Vec_PtrSize( vFair ) == 0 ) + printf("Circuit without any fairness property\n"); + else + { + Vec_PtrForEachEntry( Aig_Obj_t *, vFair, pObj, i ) + { + pDriverImage = Aig_NotCond((Aig_Obj_t *)Aig_Regular(Aig_ObjChild0( pObj ))->pData, Aig_ObjFaninC0(pObj)); + if( pObjAndAcc == NULL ) + pObjAndAcc = pDriverImage; + else + { + pObjAndAccDummy = pObjAndAcc; + pObjAndAcc = Aig_And( pNew, pDriverImage, pObjAndAccDummy ); + } + } + } + + if( pObjAndAcc != NULL ) + pObjFair = pObjAndAcc; + else + pObjFair = Aig_ManConst1( pNew ); + + pObjSafetyGate = Aig_And( pNew, pObjSavedLoAndEquality, Aig_And( pNew, pObjFair, Aig_Not( pObjLive ) ) ); + + Aig_ObjPatchFanin0( pNew, pObjSafetyPropertyOutput, pObjSafetyGate ); + } + + Aig_ManSetRegNum( pNew, nRegCount ); + + //printf("\nSaig_ManPiNum = %d, Reg Num = %d, before everything, before Pi cleanup\n", Vec_PtrSize( pNew->vPis ), pNew->nRegs ); + + Aig_ManPiCleanupBiere( pNew ); + Aig_ManPoCleanupBiere( pNew ); + + Aig_ManCleanup( pNew ); + + assert( Aig_ManCheck( pNew ) ); + + return pNew; +} + + + +Vec_Ptr_t * populateLivenessVector( Abc_Ntk_t *pNtk, Aig_Man_t *pAig ) +{ + Abc_Obj_t * pNode; + int i, liveCounter = 0; + Vec_Ptr_t * vLive; + + vLive = Vec_PtrAlloc( 100 ); + Abc_NtkForEachPo( pNtk, pNode, i ) + //if( strstr( Abc_ObjName( pNode ), "assert_fair") != NULL ) + if( nodeName_starts_with( pNode, "assert_fair" ) ) + { + Vec_PtrPush( vLive, Aig_ManPo( pAig, i ) ); + liveCounter++; + } + printf("Number of liveness property found = %d\n", liveCounter); + return vLive; +} + +Vec_Ptr_t * populateFairnessVector( Abc_Ntk_t *pNtk, Aig_Man_t *pAig ) +{ + Abc_Obj_t * pNode; + int i, fairCounter = 0; + Vec_Ptr_t * vFair; + + vFair = Vec_PtrAlloc( 100 ); + Abc_NtkForEachPo( pNtk, pNode, i ) + //if( strstr( Abc_ObjName( pNode ), "assume_fair") != NULL ) + if( nodeName_starts_with( pNode, "assume_fair" ) ) + { + Vec_PtrPush( vFair, Aig_ManPo( pAig, i ) ); + fairCounter++; + } + printf("Number of fairness property found = %d\n", fairCounter); + return vFair; +} + +Vec_Ptr_t * populateSafetyAssertionVector( Abc_Ntk_t *pNtk, Aig_Man_t *pAig ) +{ + Abc_Obj_t * pNode; + int i, assertSafetyCounter = 0; + Vec_Ptr_t * vAssertSafety; + + vAssertSafety = Vec_PtrAlloc( 100 ); + Abc_NtkForEachPo( pNtk, pNode, i ) + //if( strstr( Abc_ObjName( pNode ), "Assert") != NULL ) + if( nodeName_starts_with( pNode, "assert_safety" ) || nodeName_starts_with( pNode, "Assert" )) + { + Vec_PtrPush( vAssertSafety, Aig_ManPo( pAig, i ) ); + assertSafetyCounter++; + } + printf("Number of safety property found = %d\n", assertSafetyCounter); + return vAssertSafety; +} + +Vec_Ptr_t * populateSafetyAssumptionVector( Abc_Ntk_t *pNtk, Aig_Man_t *pAig ) +{ + Abc_Obj_t * pNode; + int i, assumeSafetyCounter = 0; + Vec_Ptr_t * vAssumeSafety; + + vAssumeSafety = Vec_PtrAlloc( 100 ); + Abc_NtkForEachPo( pNtk, pNode, i ) + //if( strstr( Abc_ObjName( pNode ), "Assert") != NULL ) + if( nodeName_starts_with( pNode, "assume_safety" ) || nodeName_starts_with( pNode, "Assume" )) + { + Vec_PtrPush( vAssumeSafety, Aig_ManPo( pAig, i ) ); + assumeSafetyCounter++; + } + printf("Number of assume_safety property found = %d\n", assumeSafetyCounter); + return vAssumeSafety; +} + +void updateNewNetworkNameManager( Abc_Ntk_t *pNtk, Aig_Man_t *pAig, Vec_Ptr_t *vPiNames, Vec_Ptr_t *vLoNames ) +{ + Aig_Obj_t *pObj; + Abc_Obj_t *pNode; + int i, ntkObjId; + + pNtk->pManName = Nm_ManCreate( Abc_NtkCiNum( pNtk ) ); + + if( vPiNames ) + { + Saig_ManForEachPi( pAig, pObj, i ) + { + ntkObjId = Abc_NtkCi( pNtk, i )->Id; + //printf("Pi %d, Saved Name = %s, id = %d\n", i, Nm_ManStoreIdName( pNtk->pManName, ntkObjId, Aig_ObjType(pObj), Vec_PtrEntry(vPiNames, i), NULL ), ntkObjId); + Nm_ManStoreIdName( pNtk->pManName, ntkObjId, Aig_ObjType(pObj), (char *)Vec_PtrEntry(vPiNames, i), NULL ); + } + } + if( vLoNames ) + { + Saig_ManForEachLo( pAig, pObj, i ) + { + ntkObjId = Abc_NtkCi( pNtk, Saig_ManPiNum( pAig ) + i )->Id; + //printf("Lo %d, Saved name = %s, id = %d\n", i, Nm_ManStoreIdName( pNtk->pManName, ntkObjId, Aig_ObjType(pObj), Vec_PtrEntry(vLoNames, i), NULL ), ntkObjId); + Nm_ManStoreIdName( pNtk->pManName, ntkObjId, Aig_ObjType(pObj), (char *)Vec_PtrEntry(vLoNames, i), NULL ); + } + } + + Abc_NtkForEachPo(pNtk, pNode, i) + { + Abc_ObjAssignName(pNode, "assert_safety_", Abc_ObjName(pNode) ); + } + + // assign latch input names + Abc_NtkForEachLatch(pNtk, pNode, i) + if ( Nm_ManFindNameById(pNtk->pManName, Abc_ObjFanin0(pNode)->Id) == NULL ) + Abc_ObjAssignName( Abc_ObjFanin0(pNode), Abc_ObjName(Abc_ObjFanin0(pNode)), NULL ); +} + + +int Abc_CommandAbcLivenessToSafety( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk, * pNtkTemp, *pNtkNew, *pNtkOld; + Aig_Man_t * pAig, *pAigNew; + int c; + Vec_Ptr_t * vLive, * vFair, *vAssertSafety, *vAssumeSafety; + int directive = -1; + + pNtk = Abc_FrameReadNtk(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + if( argc == 1 ) + { + assert( directive == -1 ); + directive = FULL_BIERE_MODE; + } + else + { + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "1slh" ) ) != EOF ) + { + switch( c ) + { + case '1': + if( directive == -1 ) + directive = FULL_BIERE_ONE_LOOP_MODE; + else + { + assert( directive == IGNORE_LIVENESS_KEEP_SAFETY_MODE || directive == IGNORE_SAFETY_KEEP_LIVENESS_MODE ); + if( directive == IGNORE_LIVENESS_KEEP_SAFETY_MODE ) + directive = IGNORE_LIVENESS_KEEP_SAFETY_MODE; + else + directive = IGNORE_SAFETY_KEEP_LIVENESS_ONE_LOOP_MODE; + } + break; + case 's': + if( directive == -1 ) + directive = IGNORE_SAFETY_KEEP_LIVENESS_MODE; + else + { + if( directive != FULL_BIERE_ONE_LOOP_MODE ) + goto usage; + assert(directive == FULL_BIERE_ONE_LOOP_MODE); + directive = IGNORE_SAFETY_KEEP_LIVENESS_ONE_LOOP_MODE; + } + break; + case 'l': + if( directive == -1 ) + directive = IGNORE_LIVENESS_KEEP_SAFETY_MODE; + else + { + if( directive != FULL_BIERE_ONE_LOOP_MODE ) + goto usage; + assert(directive == FULL_BIERE_ONE_LOOP_MODE); + directive = IGNORE_LIVENESS_KEEP_SAFETY_MODE; + } + break; + case 'h': + goto usage; + default: + goto usage; + } + } + } + + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + if( !Abc_NtkIsStrash( pNtk ) ) + { + printf("The input network was not strashed, strashing....\n"); + pNtkTemp = Abc_NtkStrash( pNtk, 0, 0, 0 ); + pNtkOld = pNtkTemp; + pAig = Abc_NtkToDar( pNtkTemp, 0, 1 ); + vLive = populateLivenessVector( pNtk, pAig ); + vFair = populateFairnessVector( pNtk, pAig ); + vAssertSafety = populateSafetyAssertionVector( pNtk, pAig ); + vAssumeSafety = populateSafetyAssumptionVector( pNtk, pAig ); + } + else + { + pAig = Abc_NtkToDar( pNtk, 0, 1 ); + pNtkOld = pNtk; + vLive = populateLivenessVector( pNtk, pAig ); + vFair = populateFairnessVector( pNtk, pAig ); + vAssertSafety = populateSafetyAssertionVector( pNtk, pAig ); + vAssumeSafety = populateSafetyAssumptionVector( pNtk, pAig ); + } + + switch( directive ) + { + case FULL_BIERE_MODE: + //if( Vec_PtrSize(vLive) == 0 && Vec_PtrSize(vAssertSafety) == 0 ) + //{ + // printf("Input circuit has NO safety and NO liveness property, original network is not disturbed\n"); + // return 1; + //} + //else + //{ + pAigNew = LivenessToSafetyTransformation( FULL_BIERE_MODE, pNtk, pAig, vLive, vFair, vAssertSafety, vAssumeSafety ); + if( Aig_ManRegNum(pAigNew) != 0 ) + printf("A new circuit is produced with\n\t2 POs - one for safety and one for liveness.\n\tone additional input is added (due to Biere's nondeterminism)\n\tshadow flops are not created if the original circuit is combinational\n\tnon-property POs are suppressed\n"); + break; + //} + case FULL_BIERE_ONE_LOOP_MODE: + //if( Vec_PtrSize(vLive) == 0 && Vec_PtrSize(vAssertSafety) == 0 ) + //{ + // printf("Input circuit has NO safety and NO liveness property, original network is not disturbed\n"); + // return 1; + //} + //else + //{ + pAigNew = LivenessToSafetyTransformationOneStepLoop( FULL_BIERE_ONE_LOOP_MODE, pNtk, pAig, vLive, vFair, vAssertSafety, vAssumeSafety ); + if( Aig_ManRegNum(pAigNew) != 0 ) + printf("A new circuit is produced with\n\t2 POs - one for safety and one for liveness.\n\tone additional input is added (due to Biere's nondeterminism)\n\tshadow flops are not created\n\tnon-property POs are suppressed\n"); + break; + //} + case IGNORE_LIVENESS_KEEP_SAFETY_MODE: + //if( Vec_PtrSize(vAssertSafety) == 0 ) + //{ + // printf("Input circuit has NO safety property, original network is not disturbed\n"); + // return 1; + //} + //else + //{ + pAigNew = LivenessToSafetyTransformation( IGNORE_LIVENESS_KEEP_SAFETY_MODE, pNtk, pAig, vLive, vFair, vAssertSafety, vAssumeSafety ); + if( Aig_ManRegNum(pAigNew) != 0 ) + printf("A new circuit is produced with\n\t1 PO - only for safety property; liveness properties are ignored, if any.\n\tno additional input is added (due to Biere's nondeterminism)\n\tshadow flops are not created\n\tnon-property POs are suppressed\n"); + break; + //} + case IGNORE_SAFETY_KEEP_LIVENESS_MODE: + //if( Vec_PtrSize(vLive) == 0 ) + //{ + // printf("Input circuit has NO liveness property, original network is not disturbed\n"); + // return 1; + //} + //else + //{ + pAigNew = LivenessToSafetyTransformation( IGNORE_SAFETY_KEEP_LIVENESS_MODE, pNtk, pAig, vLive, vFair, vAssertSafety, vAssumeSafety ); + if( Aig_ManRegNum(pAigNew) != 0 ) + printf("A new circuit is produced with\n\t1 PO - only for liveness property; safety properties are ignored, if any.\n\tone additional input is added (due to Biere's nondeterminism)\n\tshadow flops are not created if the original circuit is combinational\n\tnon-property POs are suppressed\n"); + break; + //} + case IGNORE_SAFETY_KEEP_LIVENESS_ONE_LOOP_MODE: + //if( Vec_PtrSize(vLive) == 0 ) + //{ + // printf("Input circuit has NO liveness property, original network is not disturbed\n"); + // return 1; + //} + //else + //{ + pAigNew = LivenessToSafetyTransformationOneStepLoop( IGNORE_SAFETY_KEEP_LIVENESS_ONE_LOOP_MODE, pNtk, pAig, vLive, vFair, vAssertSafety, vAssumeSafety ); + if( Aig_ManRegNum(pAigNew) != 0 ) + printf("New circuit is produced ignoring safety outputs!\nOnly liveness and fairness outputs are considered.\nShadow registers are not created\n"); + break; + //} + } + +#if 0 + if( argc == 1 ) + { + pAigNew = LivenessToSafetyTransformation( FULL_BIERE_MODE, pNtk, pAig, vLive, vFair, vAssertSafety, vAssumeSafety ); + if( Aig_ManRegNum(pAigNew) != 0 ) + printf("New circuit is produced considering all safety, liveness and fairness outputs.\nBiere's logic is created\n"); + } + else + { + Extra_UtilGetoptReset(); + c = Extra_UtilGetopt( argc, argv, "1lsh" ); + if( c == '1' ) + { + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + if( !Abc_NtkIsStrash( pNtk ) ) + { + printf("The input network was not strashed, strashing....\n"); + pNtkTemp = Abc_NtkStrash( pNtk, 0, 0, 0 ); + pNtkOld = pNtkTemp; + pAig = Abc_NtkToDar( pNtkTemp, 0, 1 ); + vLive = populateLivenessVector( pNtk, pAig ); + vFair = populateFairnessVector( pNtk, pAig ); + vAssertSafety = populateSafetyAssertionVector( pNtk, pAig ); + vAssumeSafety = populateSafetyAssumptionVector( pNtk, pAig ); + } + else + { + pAig = Abc_NtkToDar( pNtk, 0, 1 ); + pNtkOld = pNtk; + vLive = populateLivenessVector( pNtk, pAig ); + vFair = populateFairnessVector( pNtk, pAig ); + vAssertSafety = populateSafetyAssertionVector( pNtk, pAig ); + vAssumeSafety = populateSafetyAssumptionVector( pNtk, pAig ); + } + pAigNew = LivenessToSafetyTransformationOneStepLoop( pNtk, pAig, vLive, vFair, vAssertSafety, vAssumeSafety ); + } + else if( c == 'l' ) + { + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + if( !Abc_NtkIsStrash( pNtk ) ) + { + printf("The input network was not strashed, strashing....\n"); + pNtkTemp = Abc_NtkStrash( pNtk, 0, 0, 0 ); + pNtkOld = pNtkTemp; + pAig = Abc_NtkToDar( pNtkTemp, 0, 1 ); + vLive = populateLivenessVector( pNtk, pAig ); + vFair = populateFairnessVector( pNtk, pAig ); + vAssertSafety = populateSafetyAssertionVector( pNtk, pAig ); + vAssumeSafety = populateSafetyAssumptionVector( pNtk, pAig ); + } + else + { + pAig = Abc_NtkToDar( pNtk, 0, 1 ); + pNtkOld = pNtk; + vLive = populateLivenessVector( pNtk, pAig ); + vFair = populateFairnessVector( pNtk, pAig ); + vAssertSafety = populateSafetyAssertionVector( pNtk, pAig ); + vAssumeSafety = populateSafetyAssumptionVector( pNtk, pAig ); + } + pAigNew = LivenessToSafetyTransformation( IGNORE_LIVENESS_KEEP_SAFETY_MODE, pNtk, pAig, vLive, vFair, vAssertSafety, vAssumeSafety ); + if( Aig_ManRegNum(pAigNew) != 0 ) + printf("New circuit is produced ignoring liveness outputs!\nOnly safety outputs are kept.\nBiere's logic is not created\n"); + } + else if( c == 's' ) + { + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + + if( !Abc_NtkIsStrash( pNtk ) ) + { + printf("The input network was not strashed, strashing....\n"); + pNtkTemp = Abc_NtkStrash( pNtk, 0, 0, 0 ); + pNtkOld = pNtkTemp; + pAig = Abc_NtkToDar( pNtkTemp, 0, 1 ); + vLive = populateLivenessVector( pNtk, pAig ); + vFair = populateFairnessVector( pNtk, pAig ); + vAssertSafety = populateSafetyAssertionVector( pNtk, pAig ); + vAssumeSafety = populateSafetyAssumptionVector( pNtk, pAig ); + } + else + { + pAig = Abc_NtkToDar( pNtk, 0, 1 ); + pNtkOld = pNtk; + vLive = populateLivenessVector( pNtk, pAig ); + vFair = populateFairnessVector( pNtk, pAig ); + vAssertSafety = populateSafetyAssertionVector( pNtk, pAig ); + vAssumeSafety = populateSafetyAssumptionVector( pNtk, pAig ); + } + pAigNew = LivenessToSafetyTransformation( IGNORE_SAFETY_KEEP_LIVENESS_MODE, pNtk, pAig, vLive, vFair, vAssertSafety, vAssumeSafety ); + if( Aig_ManRegNum(pAigNew) != 0 ) + printf("New circuit is produced ignoring safety outputs!\nOnly liveness and fairness outputs are considered.\nBiere's logic is created\n"); + } + else if( c == 'h' ) + goto usage; + else + goto usage; + } +#endif + +#if 0 + Aig_ManPrintStats( pAigNew ); + printf("\nDetail statistics*************************************\n"); + printf("Number of true primary inputs = %d\n", Saig_ManPiNum( pAigNew )); + printf("Number of true primary outputs = %d\n", Saig_ManPoNum( pAigNew )); + printf("Number of true latch outputs = %d\n", Saig_ManCiNum( pAigNew ) - Saig_ManPiNum( pAigNew )); + printf("Number of true latch inputs = %d\n", Saig_ManCoNum( pAigNew ) - Saig_ManPoNum( pAigNew )); + printf("Numer of registers = %d\n", Saig_ManRegNum( pAigNew ) ); + printf("\n*******************************************************\n"); +#endif + + pNtkNew = Abc_NtkFromAigPhase( pAigNew ); + pNtkNew->pName = Aig_UtilStrsav( pAigNew->pName ); + + if ( !Abc_NtkCheck( pNtkNew ) ) + fprintf( stdout, "Abc_NtkCreateCone(): Network check has failed.\n" ); + + updateNewNetworkNameManager( pNtkNew, pAigNew, vecPiNames, vecLoNames ); + Abc_FrameSetCurrentNetwork( pAbc, pNtkNew ); + +#if 0 +#ifndef DUPLICATE_CKT_DEBUG + Saig_ManForEachPi( pAigNew, pObj, i ) + assert( strcmp( (char *)Vec_PtrEntry(vecPiNames, i), retrieveTruePiName( pNtk, pAig, pAigNew, pObj ) ) == 0 ); + //printf("Name of %d-th Pi = %s, %s\n", i, retrieveTruePiName( pNtk, pAig, pAigNew, pObj ), (char *)Vec_PtrEntry(vecPiNames, i) ); + + Saig_ManForEachLo( pAigNew, pObj, i ) + assert( strcmp( (char *)Vec_PtrEntry(vecLoNames, i), retrieveLOName( pNtk, pAig, pAigNew, pObj, vLive, vFair ) ) == 0 ); +#endif +#endif + + return 0; + +usage: + fprintf( stdout, "usage: l2s [-1lsh]\n" ); + fprintf( stdout, "\t performs Armin Biere's live-to-safe transformation\n" ); + fprintf( stdout, "\t-1 : no shadow logic, presume all loops are self loops\n"); + fprintf( stdout, "\t-l : ignore liveness and fairness outputs\n"); + fprintf( stdout, "\t-s : ignore safety assertions and assumptions\n"); + fprintf( stdout, "\t-h : print command usage\n"); + return 1; +} + +Vec_Int_t * prepareFlopVector( Aig_Man_t * pAig, int vectorLength ) +{ + Vec_Int_t *vFlops; + int i; + + vFlops = Vec_IntAlloc( vectorLength ); + + for( i=0; i<vectorLength; i++ ) + Vec_IntPush( vFlops, i ); + +#if 0 + Vec_IntPush( vFlops, 19 ); + Vec_IntPush( vFlops, 20 ); + Vec_IntPush( vFlops, 23 ); + Vec_IntPush( vFlops, 24 ); + //Vec_IntPush( vFlops, 2 ); + //Vec_IntPush( vFlops, 3 ); + //Vec_IntPush( vFlops, 4 ); + //Vec_IntPush( vFlops, 5 ); + //Vec_IntPush( vFlops, 8 ); + //Vec_IntPush( vFlops, 9 ); + //Vec_IntPush( vFlops, 10 ); + //Vec_IntPush( vFlops, 11 ); + //Vec_IntPush( vFlops, 0 ); + //Vec_IntPush( vFlops, 0 ); +#endif + + return vFlops; +} + +int Abc_CommandAbcLivenessToSafetyAbstraction( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk, * pNtkTemp, *pNtkNew, *pNtkOld; + Aig_Man_t * pAig, *pAigNew; + int c; + Vec_Ptr_t * vLive, * vFair, *vAssertSafety, *vAssumeSafety; + int directive = -1; + Vec_Int_t * vFlops; + + pNtk = Abc_FrameReadNtk(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + if( argc == 1 ) + { + assert( directive == -1 ); + directive = FULL_BIERE_MODE; + } + else + { + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "1slh" ) ) != EOF ) + { + switch( c ) + { + case '1': + if( directive == -1 ) + directive = FULL_BIERE_ONE_LOOP_MODE; + else + { + assert( directive == IGNORE_LIVENESS_KEEP_SAFETY_MODE || directive == IGNORE_SAFETY_KEEP_LIVENESS_MODE ); + if( directive == IGNORE_LIVENESS_KEEP_SAFETY_MODE ) + directive = IGNORE_LIVENESS_KEEP_SAFETY_MODE; + else + directive = IGNORE_SAFETY_KEEP_LIVENESS_ONE_LOOP_MODE; + } + break; + case 's': + if( directive == -1 ) + directive = IGNORE_SAFETY_KEEP_LIVENESS_MODE; + else + { + if( directive != FULL_BIERE_ONE_LOOP_MODE ) + goto usage; + assert(directive == FULL_BIERE_ONE_LOOP_MODE); + directive = IGNORE_SAFETY_KEEP_LIVENESS_ONE_LOOP_MODE; + } + break; + case 'l': + if( directive == -1 ) + directive = IGNORE_LIVENESS_KEEP_SAFETY_MODE; + else + { + if( directive != FULL_BIERE_ONE_LOOP_MODE ) + goto usage; + assert(directive == FULL_BIERE_ONE_LOOP_MODE); + directive = IGNORE_LIVENESS_KEEP_SAFETY_MODE; + } + break; + case 'h': + goto usage; + default: + goto usage; + } + } + } + + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + if( !Abc_NtkIsStrash( pNtk ) ) + { + printf("The input network was not strashed, strashing....\n"); + pNtkTemp = Abc_NtkStrash( pNtk, 0, 0, 0 ); + pNtkOld = pNtkTemp; + pAig = Abc_NtkToDar( pNtkTemp, 0, 1 ); + vLive = populateLivenessVector( pNtk, pAig ); + vFair = populateFairnessVector( pNtk, pAig ); + vAssertSafety = populateSafetyAssertionVector( pNtk, pAig ); + vAssumeSafety = populateSafetyAssumptionVector( pNtk, pAig ); + } + else + { + pAig = Abc_NtkToDar( pNtk, 0, 1 ); + pNtkOld = pNtk; + vLive = populateLivenessVector( pNtk, pAig ); + vFair = populateFairnessVector( pNtk, pAig ); + vAssertSafety = populateSafetyAssertionVector( pNtk, pAig ); + vAssumeSafety = populateSafetyAssumptionVector( pNtk, pAig ); + } + + vFlops = prepareFlopVector( pAig, Aig_ManRegNum(pAig)%2 == 0? Aig_ManRegNum(pAig)/2 : (Aig_ManRegNum(pAig)-1)/2); + + //vFlops = prepareFlopVector( pAig, 100 ); + + switch( directive ) + { + case FULL_BIERE_MODE: + //if( Vec_PtrSize(vLive) == 0 && Vec_PtrSize(vAssertSafety) == 0 ) + //{ + // printf("Input circuit has NO safety and NO liveness property, original network is not disturbed\n"); + // return 1; + //} + //else + //{ + pAigNew = LivenessToSafetyTransformationAbs( FULL_BIERE_MODE, pNtk, pAig, vFlops, vLive, vFair, vAssertSafety, vAssumeSafety ); + if( Aig_ManRegNum(pAigNew) != 0 ) + printf("A new circuit is produced with\n\t2 POs - one for safety and one for liveness.\n\tone additional input is added (due to Biere's nondeterminism)\n\tshadow flops are not created if the original circuit is combinational\n\tnon-property POs are suppressed\n"); + break; + //} + case FULL_BIERE_ONE_LOOP_MODE: + //if( Vec_PtrSize(vLive) == 0 && Vec_PtrSize(vAssertSafety) == 0 ) + //{ + // printf("Input circuit has NO safety and NO liveness property, original network is not disturbed\n"); + // return 1; + //} + //else + //{ + pAigNew = LivenessToSafetyTransformationOneStepLoop( FULL_BIERE_ONE_LOOP_MODE, pNtk, pAig, vLive, vFair, vAssertSafety, vAssumeSafety ); + if( Aig_ManRegNum(pAigNew) != 0 ) + printf("A new circuit is produced with\n\t2 POs - one for safety and one for liveness.\n\tone additional input is added (due to Biere's nondeterminism)\n\tshadow flops are not created\n\tnon-property POs are suppressed\n"); + break; + //} + case IGNORE_LIVENESS_KEEP_SAFETY_MODE: + //if( Vec_PtrSize(vAssertSafety) == 0 ) + //{ + // printf("Input circuit has NO safety property, original network is not disturbed\n"); + // return 1; + //} + //else + //{ + pAigNew = LivenessToSafetyTransformationAbs( IGNORE_LIVENESS_KEEP_SAFETY_MODE, pNtk, pAig, vFlops, vLive, vFair, vAssertSafety, vAssumeSafety ); + if( Aig_ManRegNum(pAigNew) != 0 ) + printf("A new circuit is produced with\n\t1 PO - only for safety property; liveness properties are ignored, if any.\n\tno additional input is added (due to Biere's nondeterminism)\n\tshadow flops are not created\n\tnon-property POs are suppressed\n"); + break; + //} + case IGNORE_SAFETY_KEEP_LIVENESS_MODE: + //if( Vec_PtrSize(vLive) == 0 ) + //{ + // printf("Input circuit has NO liveness property, original network is not disturbed\n"); + // return 1; + //} + //else + //{ + pAigNew = LivenessToSafetyTransformationAbs( IGNORE_SAFETY_KEEP_LIVENESS_MODE, pNtk, pAig, vFlops, vLive, vFair, vAssertSafety, vAssumeSafety ); + if( Aig_ManRegNum(pAigNew) != 0 ) + printf("A new circuit is produced with\n\t1 PO - only for liveness property; safety properties are ignored, if any.\n\tone additional input is added (due to Biere's nondeterminism)\n\tshadow flops are not created if the original circuit is combinational\n\tnon-property POs are suppressed\n"); + break; + //} + case IGNORE_SAFETY_KEEP_LIVENESS_ONE_LOOP_MODE: + //if( Vec_PtrSize(vLive) == 0 ) + //{ + // printf("Input circuit has NO liveness property, original network is not disturbed\n"); + // return 1; + //} + //else + //{ + pAigNew = LivenessToSafetyTransformationOneStepLoop( IGNORE_SAFETY_KEEP_LIVENESS_ONE_LOOP_MODE, pNtk, pAig, vLive, vFair, vAssertSafety, vAssumeSafety ); + if( Aig_ManRegNum(pAigNew) != 0 ) + printf("New circuit is produced ignoring safety outputs!\nOnly liveness and fairness outputs are considered.\nShadow registers are not created\n"); + break; + //} + } + + pNtkNew = Abc_NtkFromAigPhase( pAigNew ); + pNtkNew->pName = Aig_UtilStrsav( pAigNew->pName ); + + if ( !Abc_NtkCheck( pNtkNew ) ) + fprintf( stdout, "Abc_NtkCreateCone(): Network check has failed.\n" ); + + updateNewNetworkNameManager( pNtkNew, pAigNew, vecPiNames,vecLoNames ); + Abc_FrameSetCurrentNetwork( pAbc, pNtkNew ); + +#if 0 +#ifndef DUPLICATE_CKT_DEBUG + Saig_ManForEachPi( pAigNew, pObj, i ) + assert( strcmp( (char *)Vec_PtrEntry(vecPiNames, i), retrieveTruePiName( pNtk, pAig, pAigNew, pObj ) ) == 0 ); + //printf("Name of %d-th Pi = %s, %s\n", i, retrieveTruePiName( pNtk, pAig, pAigNew, pObj ), (char *)Vec_PtrEntry(vecPiNames, i) ); + + Saig_ManForEachLo( pAigNew, pObj, i ) + assert( strcmp( (char *)Vec_PtrEntry(vecLoNames, i), retrieveLOName( pNtk, pAig, pAigNew, pObj, vLive, vFair ) ) == 0 ); +#endif +#endif + + return 0; + +usage: + fprintf( stdout, "usage: l2s [-1lsh]\n" ); + fprintf( stdout, "\t performs Armin Biere's live-to-safe transformation\n" ); + fprintf( stdout, "\t-1 : no shadow logic, presume all loops are self loops\n"); + fprintf( stdout, "\t-l : ignore liveness and fairness outputs\n"); + fprintf( stdout, "\t-s : ignore safety assertions and assumptions\n"); + fprintf( stdout, "\t-h : print command usage\n"); + return 1; +} + +Aig_Man_t * LivenessToSafetyTransformationWithLTL( int mode, Abc_Ntk_t * pNtk, Aig_Man_t * p, + Vec_Ptr_t *vLive, Vec_Ptr_t *vFair, Vec_Ptr_t *vAssertSafety, Vec_Ptr_t *vAssumeSafety, + int *numLtlProcessed, Vec_Ptr_t *ltlBuffer ) +{ + Aig_Man_t * pNew; + int i, ii, iii, nRegCount; + Aig_Obj_t * pObjSavePi; + Aig_Obj_t *pObjSavedLo, *pObjSavedLi; + Aig_Obj_t *pObj, *pMatch; + Aig_Obj_t *pObjSaveOrSaved, *pObjSaveAndNotSaved, *pObjSavedLoAndEquality; + Aig_Obj_t *pObjShadowLo, *pObjShadowLi, *pObjShadowLiDriver; + Aig_Obj_t *pObjXor, *pObjXnor, *pObjAndAcc; + Aig_Obj_t *pObjLive, *pObjSafetyGate; + Aig_Obj_t *pObjSafetyPropertyOutput; + Aig_Obj_t *pObjOriginalSafetyPropertyOutput; + Aig_Obj_t *pDriverImage, *pArgument, *collectiveAssertSafety, *collectiveAssumeSafety; + Aig_Obj_t *pNegatedSafetyConjunction = NULL; + Aig_Obj_t *pObjSafetyAndLiveToSafety; + char *nodeName, *pFormula; + int piCopied = 0, liCopied = 0, loCopied = 0, liCreated = 0, loCreated = 0, piVecIndex = 0, liveLatch = 0, fairLatch = 0; + Vec_Ptr_t *vSignal, *vTopASTNodeArray; + ltlNode *pEnrtyGLOBALLY; + ltlNode *topNodeOfAST, *tempTopASTNode; + Vec_Vec_t *vAigGFMap; + Vec_Ptr_t *vSignalMemory, *vGFFlopMemory, *vPoForLtlProps; + Vec_Ptr_t *vecInputLtlFormulae; + + vecPis = Vec_PtrAlloc( Saig_ManPiNum( p ) + 1); + vecPiNames = Vec_PtrAlloc( Saig_ManPiNum( p ) + 1); + + vecLos = Vec_PtrAlloc( Saig_ManRegNum( p )*2 + 1 + Vec_PtrSize( vLive ) + Vec_PtrSize( vFair ) ); + vecLoNames = Vec_PtrAlloc( Saig_ManRegNum( p )*2 + 1 + Vec_PtrSize( vLive ) + Vec_PtrSize( vFair ) ); + + //**************************************************************** + //step0: Parsing the LTL formula + //**************************************************************** + //Vec_PtrForEachEntry( char *, pNtk->vLtlProperties, pFormula, i ) + // printf("\ninput LTL formula [%d] = %s\n", i, pFormula ); + + +#ifdef MULTIPLE_LTL_FORMULA + + + //*************************************************************************** + //Reading input LTL formulae from Ntk data-structure and creating + //AST for them, Steps involved: + // parsing -> AST creation -> well-formedness check -> signal name check + //*************************************************************************** + + //resetting numLtlProcessed + *numLtlProcessed = 0; + + if( mode == FULL_BIERE_MODE || mode == IGNORE_SAFETY_KEEP_LIVENESS_MODE ) + { + //if( ltlBuffer ) + vecInputLtlFormulae = ltlBuffer; + //vecInputLtlFormulae = pNtk->vLtlProperties; + if( vecInputLtlFormulae ) + { + vTopASTNodeArray = Vec_PtrAlloc( Vec_PtrSize( vecInputLtlFormulae ) ); + printf("\n"); + Vec_PtrForEachEntry( char *, vecInputLtlFormulae, pFormula, i ) + { + tempTopASTNode = parseFormulaCreateAST( pFormula ); + //traverseAbstractSyntaxTree_postFix( tempTopASTNode ); + if( tempTopASTNode ) + { + printf("Formula %d: AST is created, ", i+1); + if( isWellFormed( tempTopASTNode ) ) + printf("Well-formedness check PASSED, "); + else + { + printf("Well-formedness check FAILED!!\n"); + printf("AST will be ignored for formula %d, no extra logic will be added for this formula\n", i+1 ); + //do memory management to free the created AST + continue; + } + if( checkSignalNameExistence( pNtk, tempTopASTNode ) ) + printf("Signal check PASSED\n"); + else + { + printf("Signal check FAILED!!"); + printf("AST will be ignored for formula %d, no extra logic will be added for this formula\n", i+1 ); + //do memory management to free the created AST + continue; + } + Vec_PtrPush( vTopASTNodeArray, tempTopASTNode ); + (*numLtlProcessed)++; + } + else + printf("\nNo AST has been created for formula %d, no extra logic will be added\n", i+1 ); + } + } + printf("\n"); + if( Vec_PtrSize( vTopASTNodeArray ) == 0 ) + { + //printf("\nNo AST has been created for any formula; hence the circuit is left untouched\n"); + printf("\nCurrently aborting, need to take care when Vec_PtrSize( vTopASTNodeArray ) == 0\n"); + exit(0); + } + } + + //**************************************************************** + // Step1: create the new manager + // Note: The new manager is created with "2 * Aig_ManObjNumMax(p)" + // nodes, but this selection is arbitrary - need to be justified + //**************************************************************** + pNew = Aig_ManStart( 2 * Aig_ManObjNumMax(p) ); + pNew->pName = (char *)malloc( strlen( pNtk->pName ) + strlen("_l3s") + 1 ); + sprintf(pNew->pName, "%s_%s", pNtk->pName, "l3s"); + pNew->pSpec = NULL; + + //**************************************************************** + // Step 2: map constant nodes + //**************************************************************** + pObj = Aig_ManConst1( p ); + pObj->pData = Aig_ManConst1( pNew ); + + //**************************************************************** + // Step 3: create true PIs + //**************************************************************** + Saig_ManForEachPi( p, pObj, i ) + { + piCopied++; + pObj->pData = Aig_ObjCreatePi(pNew); + Vec_PtrPush( vecPis, pObj->pData ); + nodeName = Aig_UtilStrsav(Abc_ObjName( Abc_NtkPi( pNtk, i ) )); + Vec_PtrPush( vecPiNames, nodeName ); + } + + //**************************************************************** + // Step 4: create the special Pi corresponding to SAVE + //**************************************************************** + if( mode == FULL_BIERE_MODE || mode == IGNORE_SAFETY_KEEP_LIVENESS_MODE ) + { + pObjSavePi = Aig_ObjCreatePi( pNew ); + nodeName = "SAVE_BIERE", + Vec_PtrPush( vecPiNames, nodeName ); + } + + //**************************************************************** + // Step 5: create register outputs + //**************************************************************** + Saig_ManForEachLo( p, pObj, i ) + { + loCopied++; + pObj->pData = Aig_ObjCreatePi(pNew); + Vec_PtrPush( vecLos, pObj->pData ); + nodeName = Aig_UtilStrsav(Abc_ObjName( Abc_NtkCi( pNtk, Abc_NtkPiNum(pNtk) + i ) )); + Vec_PtrPush( vecLoNames, nodeName ); + } + + //**************************************************************** + // Step 6: create "saved" register output + //**************************************************************** + if( mode == FULL_BIERE_MODE || mode == IGNORE_SAFETY_KEEP_LIVENESS_MODE ) + { + loCreated++; + pObjSavedLo = Aig_ObjCreatePi( pNew ); + Vec_PtrPush( vecLos, pObjSavedLo ); + nodeName = "SAVED_LO"; + Vec_PtrPush( vecLoNames, nodeName ); + } + + //**************************************************************** + // Step 7: create the OR gate and the AND gate directly fed by "SAVE" Pi + //**************************************************************** + if( mode == FULL_BIERE_MODE || mode == IGNORE_SAFETY_KEEP_LIVENESS_MODE ) + { + pObjSaveOrSaved = Aig_Or( pNew, pObjSavePi, pObjSavedLo ); + pObjSaveAndNotSaved = Aig_And( pNew, pObjSavePi, Aig_Not(pObjSavedLo) ); + } + + //******************************************************************** + // Step 8: create internal nodes + //******************************************************************** + Aig_ManForEachNode( p, pObj, i ) + { + pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + } + + + //******************************************************************** + // Step 8.x : create PO for each safety assertions + // NOTE : Here the output is purposely inverted as it will be thrown to + // dprove + //******************************************************************** + assert( pNegatedSafetyConjunction == NULL ); + if( mode == FULL_BIERE_MODE || mode == IGNORE_LIVENESS_KEEP_SAFETY_MODE || mode == IGNORE_SAFETY_KEEP_LIVENESS_MODE) + { + if( Vec_PtrSize( vAssertSafety ) != 0 && Vec_PtrSize( vAssumeSafety ) == 0 ) + { + pObjAndAcc = Aig_ManConst1( pNew ); + Vec_PtrForEachEntry( Aig_Obj_t *, vAssertSafety, pObj, i ) + { + pArgument = Aig_NotCond( (Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0( pObj ) ); + pObjAndAcc = Aig_And( pNew, pArgument, pObjAndAcc ); + } + pNegatedSafetyConjunction = Aig_Not(pObjAndAcc); + if( mode == FULL_BIERE_MODE || mode == IGNORE_LIVENESS_KEEP_SAFETY_MODE ) + pObjOriginalSafetyPropertyOutput = Aig_ObjCreatePo( pNew, Aig_Not(pObjAndAcc) ); + } + else if( Vec_PtrSize( vAssertSafety ) != 0 && Vec_PtrSize( vAssumeSafety ) != 0 ) + { + pObjAndAcc = Aig_ManConst1( pNew ); + Vec_PtrForEachEntry( Aig_Obj_t *, vAssertSafety, pObj, i ) + { + pArgument = Aig_NotCond( (Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0( pObj ) ); + pObjAndAcc = Aig_And( pNew, pArgument, pObjAndAcc ); + } + collectiveAssertSafety = pObjAndAcc; + + pObjAndAcc = Aig_ManConst1( pNew ); + Vec_PtrForEachEntry( Aig_Obj_t *, vAssumeSafety, pObj, i ) + { + pArgument = Aig_NotCond( (Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0( pObj ) ); + pObjAndAcc = Aig_And( pNew, pArgument, pObjAndAcc ); + } + collectiveAssumeSafety = pObjAndAcc; + pNegatedSafetyConjunction = Aig_And( pNew, Aig_Not(collectiveAssertSafety), collectiveAssumeSafety ); + if( mode == FULL_BIERE_MODE || mode == IGNORE_LIVENESS_KEEP_SAFETY_MODE ) + pObjOriginalSafetyPropertyOutput = Aig_ObjCreatePo( pNew, Aig_And( pNew, Aig_Not(collectiveAssertSafety), collectiveAssumeSafety ) ); + } + else + { + printf("WARNING!! No safety property is found, a new (negated) constant 1 output is created\n"); + pNegatedSafetyConjunction = Aig_Not( Aig_ManConst1(pNew) ); + if( mode == FULL_BIERE_MODE || mode == IGNORE_LIVENESS_KEEP_SAFETY_MODE ) + pObjOriginalSafetyPropertyOutput = Aig_ObjCreatePo( pNew, Aig_Not( Aig_ManConst1(pNew) ) ); + } + } + assert( pNegatedSafetyConjunction != NULL ); + + //******************************************************************** + // Step 9: create the safety property output gate for the liveness properties + // discuss with Sat/Alan for an alternative implementation + //******************************************************************** + if( mode == FULL_BIERE_MODE || mode == IGNORE_SAFETY_KEEP_LIVENESS_MODE ) + { + vPoForLtlProps = Vec_PtrAlloc( Vec_PtrSize( vTopASTNodeArray ) ); + if( Vec_PtrSize( vTopASTNodeArray ) ) + { + //no effective AST for any input LTL property + //must do something graceful + } + for( i=0; i<Vec_PtrSize( vTopASTNodeArray ); i++ ) + { + pObjSafetyPropertyOutput = Aig_ObjCreatePo( pNew, (Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData ); + Vec_PtrPush( vPoForLtlProps, pObjSafetyPropertyOutput ); + } + } + + //************************************************************************************* + // Step 10: Placeholder PO's were created for Liveness property outputs in the + // last step. FYI, # of new liveness property outputs = # of LTL properties in the circuit + // It is time for creation of loop LI's and other stuff + // Now creating register inputs for the original flops + //************************************************************************************* + nRegCount = 0; + + Saig_ManForEachLo( p, pObj, i ) + { + pMatch = Saig_ObjLoToLi( p, pObj ); + Aig_ObjCreatePo( pNew, Aig_NotCond((Aig_Obj_t *)Aig_ObjFanin0(pMatch)->pData, Aig_ObjFaninC0( pMatch ) ) ); + nRegCount++; + liCopied++; + } + + //************************************************************************************* + // Step 11: create register input corresponding to the register "saved" + //************************************************************************************* + if( mode == FULL_BIERE_MODE || mode == IGNORE_SAFETY_KEEP_LIVENESS_MODE ) + { + #ifndef DUPLICATE_CKT_DEBUG + pObjSavedLi = Aig_ObjCreatePo( pNew, pObjSaveOrSaved ); + nRegCount++; + liCreated++; + + pObjAndAcc = Aig_ManConst1( pNew ); + + //************************************************************************************* + // Step 11: create the family of shadow registers, then create the cascade of Xnor + // and And gates for the comparator + //************************************************************************************* + Saig_ManForEachLo( p, pObj, i ) + { + //printf("\nKEMON RENDY = %s", Abc_ObjName( Abc_NtkCi( pNtk, Abc_NtkPiNum(pNtk) + i )) ); + //top|route0_target0_queue_with_credit0_queue0 + //top|route0_master0_queue2 + // if( strcmp( Abc_ObjName( Abc_NtkCi( pNtk, Abc_NtkPiNum(pNtk) + i ) ), "top|route0_queue1_num[0]" ) == 0 + // || strcmp( Abc_ObjName( Abc_NtkCi( pNtk, Abc_NtkPiNum(pNtk) + i ) ), "top|route0_queue1_num[1]" ) == 0 || strcmp( Abc_ObjName( Abc_NtkCi( pNtk, Abc_NtkPiNum(pNtk) + i ) ), "top|route0_queue1_num[2]" ) == 0 ) + { + pObjShadowLo = Aig_ObjCreatePi( pNew ); + + #ifdef PROPAGATE_NAMES + Vec_PtrPush( vecLos, pObjShadowLo ); + nodeName = (char *)malloc( strlen( Abc_ObjName( Abc_NtkCi( pNtk, Abc_NtkPiNum(pNtk) + i ) ) ) + 10 ); + sprintf( nodeName, "%s__%s", Abc_ObjName( Abc_NtkCi( pNtk, Abc_NtkPiNum(pNtk) + i ) ), "SHADOW" ); + + Vec_PtrPush( vecLoNames, nodeName ); + #endif + + pObjShadowLiDriver = Aig_Mux( pNew, pObjSaveAndNotSaved, (Aig_Obj_t *)pObj->pData, pObjShadowLo ); + pObjShadowLi = Aig_ObjCreatePo( pNew, pObjShadowLiDriver ); + nRegCount++; + loCreated++; liCreated++; + + pObjXor = Aig_Exor( pNew, (Aig_Obj_t *)pObj->pData, pObjShadowLo ); + pObjXnor = Aig_Not( pObjXor ); + + pObjAndAcc = Aig_And( pNew, pObjXnor, pObjAndAcc ); + } + } + + // create the AND gate whose output will be the signal "looped" + pObjSavedLoAndEquality = Aig_And( pNew, pObjSavedLo, pObjAndAcc ); + + // create the master AND gate and corresponding AND and OR logic for the liveness properties + + //************************************************************************************* + // Step 11: logic for LTL properties:- (looped & ~theta) where theta is the input ltl + // property + // Description of some data-structure: + //------------------------------------------------------------------------------------- + // Name | Type | Purpose + //------------------------------------------------------------------------------------- + // vSignalMemory | Vec_Ptr_t * | A vector across all ASTs of the LTL properties + // | | It remembers if OR+Latch for GF node has already been + // | | created for a particular signal. + // | | + // vGFFlopMemory | Vec_Ptr_t * | A vector across all ASTs of the LTL properties + // | | remembers if OR+Latch of a GF node has already been created + // | | + // vSignal | Vec_Ptr_t * | vector for each AST; contains pointers from GF nodes + // | | to AIG signals + // | | + // vAigGFMap | Vec_Vec_t * | vAigGFMap[ index ] = vector of GF nodes pointing to + // | | the same AIG node; "index" is the index of that + // | | AIG node in the vector vSignal + //************************************************************************************* + + vSignalMemory = Vec_PtrAlloc(10); + vGFFlopMemory = Vec_PtrAlloc(10); + + Vec_PtrForEachEntry( ltlNode *, vTopASTNodeArray, topNodeOfAST, iii ) + { + vSignal = Vec_PtrAlloc( 10 ); + vAigGFMap = Vec_VecAlloc( 10 ); + + //************************************************************************************* + //Step 11a: for the current AST, find out the leaf level Boolean signal pointers from + // the NEW aig. + //************************************************************************************* + populateBoolWithAigNodePtr( pNtk, p, pNew, topNodeOfAST ); + assert( checkAllBoolHaveAIGPointer( topNodeOfAST ) ); + + //************************************************************************************* + //Step 11b: for each GF node, compute the pointer in AIG that it should point to + // In particular, if the subtree below GF is some Boolean crown (including the case + // of simple negation, create new logic and populate the AIG pointer in GF node + // accordingly + //************************************************************************************* + populateAigPointerUnitGF( pNew, topNodeOfAST, vSignal, vAigGFMap ); + + //************************************************************************************* + //Step 11c: everything below GF are computed. Now, it is time to create logic for individual + // GF nodes (i.e. the OR gate and the latch and the Boolean crown of the AST + //************************************************************************************* + Vec_PtrForEachEntry( Aig_Obj_t *, vSignal, pObj, i ) + { + //********************************************************* + // Step 11c.1: if the OR+Latch of the particular signal is + // not already created, create it. It may have already been + // created from another property, so check it before creation + //********************************************************* + if( Vec_PtrFind( vSignalMemory, pObj ) == -1 ) + { + liveLatch++; + + pDriverImage = pObj; + pObjShadowLo = Aig_ObjCreatePi( pNew ); + pObjShadowLiDriver = Aig_Or( pNew, pObjShadowLo, Aig_And( pNew, pDriverImage, pObjSaveOrSaved ) ); + pObjShadowLi = Aig_ObjCreatePo( pNew, pObjShadowLiDriver ); + + nRegCount++; + loCreated++; liCreated++; + + Vec_PtrPush( vSignalMemory, pObj ); + Vec_PtrPush( vGFFlopMemory, pObjShadowLo ); + + #if 1 + #ifdef PROPAGATE_NAMES + Vec_PtrPush( vecLos, pObjShadowLo ); + //nodeName = (char *)malloc( strlen( Abc_ObjName( Abc_NtkPo( pNtk, getPoIndex( p, pObj ) ) ) ) + 12 ); + //sprintf( nodeName, "%s__%s", Abc_ObjName( Abc_NtkPo( pNtk, getPoIndex( p, pObj ) ) ), "LIVENESS" ); + nodeName = (char *)malloc( 20 ); + sprintf( nodeName, "n%d__%s", Aig_ObjId(pObjShadowLo), "GF_flop" ); + Vec_PtrPush( vecLoNames, nodeName ); + #endif + #endif + } + else + pObjShadowLo = (Aig_Obj_t *)Vec_PtrEntry( vGFFlopMemory, Vec_PtrFind( vSignalMemory, pObj ) ); + + Vec_VecForEachEntryLevel( ltlNode *, vAigGFMap, pEnrtyGLOBALLY, ii, i ) + setAIGNodePtrOfGloballyNode( pEnrtyGLOBALLY, pObjShadowLo); + + + //#ifdef PROPAGATE_NAMES + // Vec_PtrPush( vecLos, pObjShadowLo ); + // nodeName = (char *)malloc( strlen( Abc_ObjName( Abc_NtkPo( pNtk, getPoIndex( p, pObj ) ) ) ) + 12 ); + // sprintf( nodeName, "%s__%s", Abc_ObjName( Abc_NtkPo( pNtk, getPoIndex( p, pObj ) ) ), "LIVENESS" ); + // Vec_PtrPush( vecLoNames, nodeName ); + //#endif + + } + + //********************************************************* + //Step 11c.2: creating the Boolean crown + //********************************************************* + buildLogicFromLTLNode( pNew, topNodeOfAST ); + + //********************************************************* + //Step 11c.3: creating logic for (looped & ~theta) and patching + // it with the proper PO + //Note: if ALLOW_SAFETY_PROPERTIES is defined then the final AND + //gate is a conjunction of safety & liveness, i.e. SAFETY & (looped => theta) + //since ABC convention demands a NOT gate at the end, the property logic + //becomes !( SAFETY & (looped => theta) ) = !SAFETY + (looped & !theta) + //********************************************************* + pObjLive = retriveAIGPointerFromLTLNode( topNodeOfAST ); + pObjSafetyGate = Aig_And( pNew, pObjSavedLoAndEquality, Aig_Not(pObjLive) ); + #ifdef ALLOW_SAFETY_PROPERTIES + printf("liveness output is conjoined with safety assertions\n"); + pObjSafetyAndLiveToSafety = Aig_Or( pNew, pObjSafetyGate, pNegatedSafetyConjunction ); + pObjSafetyPropertyOutput = Vec_PtrEntry( vPoForLtlProps, iii ); + Aig_ObjPatchFanin0( pNew, pObjSafetyPropertyOutput, pObjSafetyAndLiveToSafety ); + #else + pObjSafetyPropertyOutput = Vec_PtrEntry( vPoForLtlProps, iii ); + Aig_ObjPatchFanin0( pNew, pObjSafetyPropertyOutput, pObjSafetyGate ); + #endif + //refreshing vSignal and vAigGFMap arrays + Vec_PtrFree( vSignal ); + Vec_VecFree( vAigGFMap ); + } + + #endif + } +#endif + + Aig_ManSetRegNum( pNew, nRegCount ); + + Aig_ManPiCleanupBiere( pNew ); + Aig_ManPoCleanupBiere( pNew ); + + Aig_ManCleanup( pNew ); + + assert( Aig_ManCheck( pNew ) ); + + if( mode == FULL_BIERE_MODE || mode == IGNORE_SAFETY_KEEP_LIVENESS_MODE ) + { + assert((Aig_Obj_t *)Vec_PtrEntry(pNew->vPos, Saig_ManPoNum(pNew)+Aig_ObjPioNum(pObjSavedLo)-Saig_ManPiNum(p)-1) == pObjSavedLi); + assert( Saig_ManPiNum( p ) + 1 == Saig_ManPiNum( pNew ) ); + //assert( Saig_ManRegNum( pNew ) == Saig_ManRegNum( p ) * 2 + 1 + liveLatch + fairLatch ); + } + + + return pNew; +} + +int Abc_CommandAbcLivenessToSafetyWithLTL( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk, * pNtkTemp, *pNtkNew, *pNtkOld; + Aig_Man_t * pAig, *pAigNew; + int c; + Vec_Ptr_t * vLive, * vFair, *vAssertSafety, *vAssumeSafety; + int directive = -1; + char *ltfFormulaString = NULL; + int LTL_FLAG = 0, numOfLtlPropOutput; + Vec_Ptr_t *ltlBuffer; + + pNtk = Abc_FrameReadNtk(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + if( argc == 1 ) + { + assert( directive == -1 ); + directive = FULL_BIERE_MODE; + } + else + { + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "1slhf" ) ) != EOF ) + { + switch( c ) + { + case '1': + if( directive == -1 ) + directive = FULL_BIERE_ONE_LOOP_MODE; + else + { + assert( directive == IGNORE_LIVENESS_KEEP_SAFETY_MODE || directive == IGNORE_SAFETY_KEEP_LIVENESS_MODE ); + if( directive == IGNORE_LIVENESS_KEEP_SAFETY_MODE ) + directive = IGNORE_LIVENESS_KEEP_SAFETY_MODE; + else + directive = IGNORE_SAFETY_KEEP_LIVENESS_ONE_LOOP_MODE; + } + break; + case 's': + if( directive == -1 ) + directive = IGNORE_SAFETY_KEEP_LIVENESS_MODE; + else + { + if( directive != FULL_BIERE_ONE_LOOP_MODE ) + goto usage; + assert(directive == FULL_BIERE_ONE_LOOP_MODE); + directive = IGNORE_SAFETY_KEEP_LIVENESS_ONE_LOOP_MODE; + } + break; + case 'l': + if( directive == -1 ) + directive = IGNORE_LIVENESS_KEEP_SAFETY_MODE; + else + { + if( directive != FULL_BIERE_ONE_LOOP_MODE ) + goto usage; + assert(directive == FULL_BIERE_ONE_LOOP_MODE); + directive = IGNORE_LIVENESS_KEEP_SAFETY_MODE; + } + break; + case 'f': + //assert( argc >= 3 ); + //vecLtlFormula = Vec_PtrAlloc( argc - 2 ); + //if( argc >= 3 ) + //{ + // for( t=3; t<=argc; t++ ) + // { + // printf("argv[%d] = %s\n", t-1, argv[t-1]); + // Vec_PtrPush( vecLtlFormula, argv[t-1] ); + // } + //} + //printf("argv[argc] = %s\n", argv[argc-1]); + //ltfFormulaString = argv[2]; + + //LTL_FLAG = 1; + printf("\nILLEGAL FLAG: aborting....\n"); + exit(0); + break; + case 'h': + goto usage; + default: + goto usage; + } + } + } + + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + if( !Abc_NtkIsStrash( pNtk ) ) + { + printf("The input network was not strashed, strashing....\n"); + pNtkTemp = Abc_NtkStrash( pNtk, 0, 0, 0 ); + pNtkOld = pNtkTemp; + pAig = Abc_NtkToDar( pNtkTemp, 0, 1 ); + vLive = populateLivenessVector( pNtk, pAig ); + vFair = populateFairnessVector( pNtk, pAig ); + vAssertSafety = populateSafetyAssertionVector( pNtk, pAig ); + vAssumeSafety = populateSafetyAssumptionVector( pNtk, pAig ); + } + else + { + pAig = Abc_NtkToDar( pNtk, 0, 1 ); + pNtkOld = pNtk; + vLive = populateLivenessVector( pNtk, pAig ); + vFair = populateFairnessVector( pNtk, pAig ); + vAssertSafety = populateSafetyAssertionVector( pNtk, pAig ); + vAssumeSafety = populateSafetyAssumptionVector( pNtk, pAig ); + } + + if( pAbc->vLTLProperties_global != NULL ) + ltlBuffer = pAbc->vLTLProperties_global; + else + ltlBuffer = NULL; + + switch( directive ) + { + case FULL_BIERE_MODE: + pAigNew = LivenessToSafetyTransformationWithLTL( FULL_BIERE_MODE, pNtk, pAig, vLive, vFair, vAssertSafety, vAssumeSafety, &numOfLtlPropOutput, ltlBuffer ); + if( Aig_ManRegNum(pAigNew) != 0 ) + printf("A new circuit is produced with\n\t%d POs - one for safety and %d for liveness.\n\tone additional input is added (due to Biere's nondeterminism)\n\tshadow flops are not created if the original circuit is combinational\n\tnon-property POs are suppressed\n", numOfLtlPropOutput+1, numOfLtlPropOutput); + break; + + case FULL_BIERE_ONE_LOOP_MODE: + pAigNew = LivenessToSafetyTransformationOneStepLoop( FULL_BIERE_ONE_LOOP_MODE, pNtk, pAig, vLive, vFair, vAssertSafety, vAssumeSafety ); + if( Aig_ManRegNum(pAigNew) != 0 ) + printf("A new circuit is produced with\n\t2 POs - one for safety and one for liveness.\n\tone additional input is added (due to Biere's nondeterminism)\n\tshadow flops are not created\n\tnon-property POs are suppressed\n"); + break; + + case IGNORE_LIVENESS_KEEP_SAFETY_MODE: + pAigNew = LivenessToSafetyTransformationWithLTL( IGNORE_LIVENESS_KEEP_SAFETY_MODE, pNtk, pAig, vLive, vFair, vAssertSafety, vAssumeSafety, &numOfLtlPropOutput, ltlBuffer ); + assert( numOfLtlPropOutput == 0 ); + if( Aig_ManRegNum(pAigNew) != 0 ) + printf("A new circuit is produced with\n\t1 PO - only for safety property; liveness properties are ignored, if any.\n\tno additional input is added (due to Biere's nondeterminism)\n\tshadow flops are not created\n\tnon-property POs are suppressed\n"); + break; + + case IGNORE_SAFETY_KEEP_LIVENESS_MODE: + pAigNew = LivenessToSafetyTransformationWithLTL( IGNORE_SAFETY_KEEP_LIVENESS_MODE, pNtk, pAig, vLive, vFair, vAssertSafety, vAssumeSafety, &numOfLtlPropOutput, ltlBuffer ); + if( Aig_ManRegNum(pAigNew) != 0 ) + printf("A new circuit is produced with\n\t%d PO - only for liveness property; safety properties are ignored, if any.\n\tone additional input is added (due to Biere's nondeterminism)\n\tshadow flops are not created if the original circuit is combinational\n\tnon-property POs are suppressed\n", numOfLtlPropOutput); + break; + + case IGNORE_SAFETY_KEEP_LIVENESS_ONE_LOOP_MODE: + pAigNew = LivenessToSafetyTransformationOneStepLoop( IGNORE_SAFETY_KEEP_LIVENESS_ONE_LOOP_MODE, pNtk, pAig, vLive, vFair, vAssertSafety, vAssumeSafety ); + if( Aig_ManRegNum(pAigNew) != 0 ) + printf("New circuit is produced ignoring safety outputs!\nOnly liveness and fairness outputs are considered.\nShadow registers are not created\n"); + break; + } + +#if 0 + if( argc == 1 ) + { + pAigNew = LivenessToSafetyTransformation( FULL_BIERE_MODE, pNtk, pAig, vLive, vFair, vAssertSafety, vAssumeSafety ); + if( Aig_ManRegNum(pAigNew) != 0 ) + printf("New circuit is produced considering all safety, liveness and fairness outputs.\nBiere's logic is created\n"); + } + else + { + Extra_UtilGetoptReset(); + c = Extra_UtilGetopt( argc, argv, "1lsh" ); + if( c == '1' ) + { + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + if( !Abc_NtkIsStrash( pNtk ) ) + { + printf("The input network was not strashed, strashing....\n"); + pNtkTemp = Abc_NtkStrash( pNtk, 0, 0, 0 ); + pNtkOld = pNtkTemp; + pAig = Abc_NtkToDar( pNtkTemp, 0, 1 ); + vLive = populateLivenessVector( pNtk, pAig ); + vFair = populateFairnessVector( pNtk, pAig ); + vAssertSafety = populateSafetyAssertionVector( pNtk, pAig ); + vAssumeSafety = populateSafetyAssumptionVector( pNtk, pAig ); + } + else + { + pAig = Abc_NtkToDar( pNtk, 0, 1 ); + pNtkOld = pNtk; + vLive = populateLivenessVector( pNtk, pAig ); + vFair = populateFairnessVector( pNtk, pAig ); + vAssertSafety = populateSafetyAssertionVector( pNtk, pAig ); + vAssumeSafety = populateSafetyAssumptionVector( pNtk, pAig ); + } + pAigNew = LivenessToSafetyTransformationOneStepLoop( pNtk, pAig, vLive, vFair, vAssertSafety, vAssumeSafety ); + } + else if( c == 'l' ) + { + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + if( !Abc_NtkIsStrash( pNtk ) ) + { + printf("The input network was not strashed, strashing....\n"); + pNtkTemp = Abc_NtkStrash( pNtk, 0, 0, 0 ); + pNtkOld = pNtkTemp; + pAig = Abc_NtkToDar( pNtkTemp, 0, 1 ); + vLive = populateLivenessVector( pNtk, pAig ); + vFair = populateFairnessVector( pNtk, pAig ); + vAssertSafety = populateSafetyAssertionVector( pNtk, pAig ); + vAssumeSafety = populateSafetyAssumptionVector( pNtk, pAig ); + } + else + { + pAig = Abc_NtkToDar( pNtk, 0, 1 ); + pNtkOld = pNtk; + vLive = populateLivenessVector( pNtk, pAig ); + vFair = populateFairnessVector( pNtk, pAig ); + vAssertSafety = populateSafetyAssertionVector( pNtk, pAig ); + vAssumeSafety = populateSafetyAssumptionVector( pNtk, pAig ); + } + pAigNew = LivenessToSafetyTransformation( IGNORE_LIVENESS_KEEP_SAFETY_MODE, pNtk, pAig, vLive, vFair, vAssertSafety, vAssumeSafety ); + if( Aig_ManRegNum(pAigNew) != 0 ) + printf("New circuit is produced ignoring liveness outputs!\nOnly safety outputs are kept.\nBiere's logic is not created\n"); + } + else if( c == 's' ) + { + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + + if( !Abc_NtkIsStrash( pNtk ) ) + { + printf("The input network was not strashed, strashing....\n"); + pNtkTemp = Abc_NtkStrash( pNtk, 0, 0, 0 ); + pNtkOld = pNtkTemp; + pAig = Abc_NtkToDar( pNtkTemp, 0, 1 ); + vLive = populateLivenessVector( pNtk, pAig ); + vFair = populateFairnessVector( pNtk, pAig ); + vAssertSafety = populateSafetyAssertionVector( pNtk, pAig ); + vAssumeSafety = populateSafetyAssumptionVector( pNtk, pAig ); + } + else + { + pAig = Abc_NtkToDar( pNtk, 0, 1 ); + pNtkOld = pNtk; + vLive = populateLivenessVector( pNtk, pAig ); + vFair = populateFairnessVector( pNtk, pAig ); + vAssertSafety = populateSafetyAssertionVector( pNtk, pAig ); + vAssumeSafety = populateSafetyAssumptionVector( pNtk, pAig ); + } + pAigNew = LivenessToSafetyTransformation( IGNORE_SAFETY_KEEP_LIVENESS_MODE, pNtk, pAig, vLive, vFair, vAssertSafety, vAssumeSafety ); + if( Aig_ManRegNum(pAigNew) != 0 ) + printf("New circuit is produced ignoring safety outputs!\nOnly liveness and fairness outputs are considered.\nBiere's logic is created\n"); + } + else if( c == 'h' ) + goto usage; + else + goto usage; + } +#endif + +#if 0 + Aig_ManPrintStats( pAigNew ); + printf("\nDetail statistics*************************************\n"); + printf("Number of true primary inputs = %d\n", Saig_ManPiNum( pAigNew )); + printf("Number of true primary outputs = %d\n", Saig_ManPoNum( pAigNew )); + printf("Number of true latch outputs = %d\n", Saig_ManCiNum( pAigNew ) - Saig_ManPiNum( pAigNew )); + printf("Number of true latch inputs = %d\n", Saig_ManCoNum( pAigNew ) - Saig_ManPoNum( pAigNew )); + printf("Numer of registers = %d\n", Saig_ManRegNum( pAigNew ) ); + printf("\n*******************************************************\n"); +#endif + + pNtkNew = Abc_NtkFromAigPhase( pAigNew ); + pNtkNew->pName = Aig_UtilStrsav( pAigNew->pName ); + + if ( !Abc_NtkCheck( pNtkNew ) ) + fprintf( stdout, "Abc_NtkCreateCone(): Network check has failed.\n" ); + + updateNewNetworkNameManager( pNtkNew, pAigNew, vecPiNames, vecLoNames ); + Abc_FrameSetCurrentNetwork( pAbc, pNtkNew ); + +#if 0 +#ifndef DUPLICATE_CKT_DEBUG + Saig_ManForEachPi( pAigNew, pObj, i ) + assert( strcmp( (char *)Vec_PtrEntry(vecPiNames, i), retrieveTruePiName( pNtk, pAig, pAigNew, pObj ) ) == 0 ); + //printf("Name of %d-th Pi = %s, %s\n", i, retrieveTruePiName( pNtk, pAig, pAigNew, pObj ), (char *)Vec_PtrEntry(vecPiNames, i) ); + + Saig_ManForEachLo( pAigNew, pObj, i ) + assert( strcmp( (char *)Vec_PtrEntry(vecLoNames, i), retrieveLOName( pNtk, pAig, pAigNew, pObj, vLive, vFair ) ) == 0 ); +#endif +#endif + + return 0; + +usage: + fprintf( stdout, "usage: l3s [-1lsh]\n" ); + fprintf( stdout, "\t performs Armin Biere's live-to-safe transformation\n" ); + fprintf( stdout, "\t-1 : no shadow logic, presume all loops are self loops\n"); + fprintf( stdout, "\t-l : ignore liveness and fairness outputs\n"); + fprintf( stdout, "\t-s : ignore safety assertions and assumptions\n"); + fprintf( stdout, "\t-h : print command usage\n"); + return 1; +} + + +ABC_NAMESPACE_IMPL_END diff --git a/src/aig/live/liveness_old.c b/src/aig/live/liveness_old.c new file mode 100644 index 00000000..b3ddb1fc --- /dev/null +++ b/src/aig/live/liveness_old.c @@ -0,0 +1,1756 @@ +#include <stdio.h> +#include "main.h" +#include "aig.h" +#include "saig.h" +#include <string.h> + +ABC_NAMESPACE_IMPL_START + + +#define PROPAGATE_NAMES + +#define FULL_BIERE_MODE 0 +#define IGNORE_LIVENESS_KEEP_SAFETY_MODE 1 +#define IGNORE_SAFETY_KEEP_LIVENESS_MODE 2 +#define IGNORE_SAFETY_KEEP_LIVENESS_ONE_LOOP_MODE 3 +#define FULL_BIERE_ONE_LOOP_MODE 4 +//#define DUPLICATE_CKT_DEBUG + +extern Aig_Man_t * Abc_NtkToDar( Abc_Ntk_t * pNtk, int fExors, int fRegisters ); +extern Abc_Ntk_t * Abc_NtkFromAigPhase( Aig_Man_t * pMan ); +//char *strdup(const char *string); + + +/******************************************************************* +LAYOUT OF PI VECTOR: + ++------------------------------------------------------------------------------------------------------------------------------------+ +| TRUE ORIGINAL PI (n) | SAVE(PI) (1) | ORIGINAL LO (k) | SAVED(LO) (1) | SHADOW_ORIGINAL LO (k) | LIVENESS LO (l) | FAIRNESS LO (f) | ++------------------------------------------------------------------------------------------------------------------------------------+ +<------------True PI----------------->|<----------------------------LO---------------------------------------------------------------> + +LAYOUT OF PO VECTOR: + ++-----------------------------------------------------------------------------------------------------------+ +| SOLE PO (1) | ORIGINAL LI (k) | SAVED LI (1) | SHADOW_ORIGINAL LI (k) | LIVENESS LI (l) | FAIRNESS LI (f) | ++-----------------------------------------------------------------------------------------------------------+ +<--True PO--->|<--------------------------------------LI----------------------------------------------------> + +********************************************************************/ + + +static int nodeName_starts_with( Abc_Obj_t *pNode, const char *prefix ) +{ + if( strstr( Abc_ObjName( pNode ), prefix ) == Abc_ObjName( pNode ) ) + return 1; + else + return 0; +} + +void printVecPtrOfString( Vec_Ptr_t *vec ) +{ + int i; + + for( i=0; i< Vec_PtrSize( vec ); i++ ) + { + printf("vec[%d] = %s\n", i, (char *)Vec_PtrEntry(vec, i) ); + } +} + +int getPoIndex( Aig_Man_t *pAig, Aig_Obj_t *pPivot ) +{ + int i; + Aig_Obj_t *pObj; + + Saig_ManForEachPo( pAig, pObj, i ) + { + if( pObj == pPivot ) + return i; + } + return -1; +} + +char * retrieveTruePiName( Abc_Ntk_t *pNtkOld, Aig_Man_t *pAigOld, Aig_Man_t *pAigNew, Aig_Obj_t *pObjPivot ) +{ + Aig_Obj_t *pObjOld, *pObj; + Abc_Obj_t *pNode; + int index; + + assert( Saig_ObjIsPi( pAigNew, pObjPivot ) ); + Aig_ManForEachPi( pAigNew, pObj, index ) + if( pObj == pObjPivot ) + break; + assert( index < Aig_ManPiNum( pAigNew ) - Aig_ManRegNum( pAigNew ) ); + if( index == Saig_ManPiNum( pAigNew ) - 1 ) + return "SAVE_BIERE"; + else + { + pObjOld = Aig_ManPi( pAigOld, index ); + pNode = Abc_NtkPi( pNtkOld, index ); + assert( pObjOld->pData == pObjPivot ); + return Abc_ObjName( pNode ); + } +} + +char * retrieveLOName( Abc_Ntk_t *pNtkOld, Aig_Man_t *pAigOld, Aig_Man_t *pAigNew, Aig_Obj_t *pObjPivot, Vec_Ptr_t *vLive, Vec_Ptr_t * vFair ) +{ + Aig_Obj_t *pObjOld, *pObj; + Abc_Obj_t *pNode; + int index, oldIndex, originalLatchNum = Saig_ManRegNum(pAigOld), strMatch, i; + char *dummyStr = (char *)malloc( sizeof(char) * 50 ); + + assert( Saig_ObjIsLo( pAigNew, pObjPivot ) ); + Saig_ManForEachLo( pAigNew, pObj, index ) + if( pObj == pObjPivot ) + break; + if( index < originalLatchNum ) + { + oldIndex = Saig_ManPiNum( pAigOld ) + index; + pObjOld = Aig_ManPi( pAigOld, oldIndex ); + pNode = Abc_NtkCi( pNtkOld, oldIndex ); + assert( pObjOld->pData == pObjPivot ); + return Abc_ObjName( pNode ); + } + else if( index == originalLatchNum ) + return "SAVED_LO"; + else if( index > originalLatchNum && index < 2 * originalLatchNum + 1 ) + { + oldIndex = Saig_ManPiNum( pAigOld ) + index - originalLatchNum - 1; + pObjOld = Aig_ManPi( pAigOld, oldIndex ); + pNode = Abc_NtkCi( pNtkOld, oldIndex ); + sprintf( dummyStr, "%s__%s", Abc_ObjName( pNode ), "SHADOW"); + return dummyStr; + } + else if( index >= 2 * originalLatchNum + 1 && index < 2 * originalLatchNum + 1 + Vec_PtrSize( vLive ) ) + { + oldIndex = index - 2 * originalLatchNum - 1; + strMatch = 0; + dummyStr[0] = '\0'; + Saig_ManForEachPo( pAigOld, pObj, i ) + { + pNode = Abc_NtkPo( pNtkOld, i ); + //if( strstr( Abc_ObjName( pNode ), "assert_fair" ) != NULL ) + if( nodeName_starts_with( pNode, "assert_fair" ) ) + { + if( strMatch == oldIndex ) + { + sprintf( dummyStr, "%s__%s", Abc_ObjName( pNode ), "LIVENESS"); + //return dummyStr; + break; + } + else + strMatch++; + } + } + assert( dummyStr[0] != '\0' ); + return dummyStr; + } + else if( index >= 2 * originalLatchNum + 1 + Vec_PtrSize( vLive ) && index < 2 * originalLatchNum + 1 + Vec_PtrSize( vLive ) + Vec_PtrSize( vFair ) ) + { + oldIndex = index - 2 * originalLatchNum - 1 - Vec_PtrSize( vLive ); + strMatch = 0; + dummyStr[0] = '\0'; + Saig_ManForEachPo( pAigOld, pObj, i ) + { + pNode = Abc_NtkPo( pNtkOld, i ); + //if( strstr( Abc_ObjName( pNode ), "assume_fair" ) != NULL ) + if( nodeName_starts_with( pNode, "assume_fair" ) ) + { + if( strMatch == oldIndex ) + { + sprintf( dummyStr, "%s__%s", Abc_ObjName( pNode ), "FAIRNESS"); + //return dummyStr; + break; + } + else + strMatch++; + } + } + assert( dummyStr[0] != '\0' ); + return dummyStr; + } + else + return "UNKNOWN"; +} + +Vec_Ptr_t *vecPis, *vecPiNames; +Vec_Ptr_t *vecLos, *vecLoNames; + + +int Aig_ManPiCleanupBiere( Aig_Man_t * p ) +{ + int k = 0, nPisOld = Aig_ManPiNum(p); + + p->nObjs[AIG_OBJ_PI] = Vec_PtrSize( p->vPis ); + if ( Aig_ManRegNum(p) ) + p->nTruePis = Aig_ManPiNum(p) - Aig_ManRegNum(p); + + return nPisOld - Aig_ManPiNum(p); +} + + +int Aig_ManPoCleanupBiere( Aig_Man_t * p ) +{ + int k = 0, nPosOld = Aig_ManPoNum(p); + + p->nObjs[AIG_OBJ_PO] = Vec_PtrSize( p->vPos ); + if ( Aig_ManRegNum(p) ) + p->nTruePos = Aig_ManPoNum(p) - Aig_ManRegNum(p); + return nPosOld - Aig_ManPoNum(p); +} + +Aig_Man_t * LivenessToSafetyTransformation( int mode, Abc_Ntk_t * pNtk, Aig_Man_t * p, + Vec_Ptr_t *vLive, Vec_Ptr_t *vFair, Vec_Ptr_t *vAssertSafety, Vec_Ptr_t *vAssumeSafety ) +{ + Aig_Man_t * pNew; + int i, nRegCount; + Aig_Obj_t * pObjSavePi; + Aig_Obj_t *pObjSavedLo, *pObjSavedLi; + Aig_Obj_t *pObj, *pMatch; + Aig_Obj_t *pObjSaveOrSaved, *pObjSaveAndNotSaved, *pObjSavedLoAndEquality; + Aig_Obj_t *pObjShadowLo, *pObjShadowLi, *pObjShadowLiDriver; + Aig_Obj_t *pObjXor, *pObjXnor, *pObjAndAcc; + Aig_Obj_t *pObjLive, *pObjFair, *pObjSafetyGate; + Aig_Obj_t *pObjSafetyPropertyOutput; + Aig_Obj_t *pObjOriginalSafetyPropertyOutput; + Aig_Obj_t *pDriverImage, *pArgument, *collectiveAssertSafety, *collectiveAssumeSafety; + char *nodeName; + int piCopied = 0, liCopied = 0, loCopied = 0, liCreated = 0, loCreated = 0, piVecIndex = 0, liveLatch = 0, fairLatch = 0; + + vecPis = Vec_PtrAlloc( Saig_ManPiNum( p ) + 1); + vecPiNames = Vec_PtrAlloc( Saig_ManPiNum( p ) + 1); + + vecLos = Vec_PtrAlloc( Saig_ManRegNum( p )*2 + 1 + Vec_PtrSize( vLive ) + Vec_PtrSize( vFair ) ); + vecLoNames = Vec_PtrAlloc( Saig_ManRegNum( p )*2 + 1 + Vec_PtrSize( vLive ) + Vec_PtrSize( vFair ) ); + + //**************************************************************** + // Step1: create the new manager + // Note: The new manager is created with "2 * Aig_ManObjNumMax(p)" + // nodes, but this selection is arbitrary - need to be justified + //**************************************************************** + pNew = Aig_ManStart( 2 * Aig_ManObjNumMax(p) ); + pNew->pName = (char *)malloc( strlen( pNtk->pName ) + strlen("_l2s") + 1 ); + sprintf(pNew->pName, "%s_%s", pNtk->pName, "l2s"); + pNew->pSpec = NULL; + + //**************************************************************** + // Step 2: map constant nodes + //**************************************************************** + pObj = Aig_ManConst1( p ); + pObj->pData = Aig_ManConst1( pNew ); + + //**************************************************************** + // Step 3: create true PIs + //**************************************************************** + Saig_ManForEachPi( p, pObj, i ) + { + piCopied++; + pObj->pData = Aig_ObjCreatePi(pNew); + Vec_PtrPush( vecPis, pObj->pData ); + nodeName = Aig_UtilStrsav(Abc_ObjName( Abc_NtkPi( pNtk, i ) )); + Vec_PtrPush( vecPiNames, nodeName ); + } + + //**************************************************************** + // Step 4: create the special Pi corresponding to SAVE + //**************************************************************** + if( mode == FULL_BIERE_MODE || mode == IGNORE_SAFETY_KEEP_LIVENESS_MODE ) + { + pObjSavePi = Aig_ObjCreatePi( pNew ); + nodeName = "SAVE_BIERE", + Vec_PtrPush( vecPiNames, nodeName ); + } + + //**************************************************************** + // Step 5: create register outputs + //**************************************************************** + Saig_ManForEachLo( p, pObj, i ) + { + loCopied++; + pObj->pData = Aig_ObjCreatePi(pNew); + Vec_PtrPush( vecLos, pObj->pData ); + nodeName = Aig_UtilStrsav(Abc_ObjName( Abc_NtkCi( pNtk, Abc_NtkPiNum(pNtk) + i ) )); + Vec_PtrPush( vecLoNames, nodeName ); + } + + //**************************************************************** + // Step 6: create "saved" register output + //**************************************************************** + if( mode == FULL_BIERE_MODE || mode == IGNORE_SAFETY_KEEP_LIVENESS_MODE ) + { + loCreated++; + pObjSavedLo = Aig_ObjCreatePi( pNew ); + Vec_PtrPush( vecLos, pObjSavedLo ); + nodeName = "SAVED_LO"; + Vec_PtrPush( vecLoNames, nodeName ); + } + + //**************************************************************** + // Step 7: create the OR gate and the AND gate directly fed by "SAVE" Pi + //**************************************************************** + if( mode == FULL_BIERE_MODE || mode == IGNORE_SAFETY_KEEP_LIVENESS_MODE ) + { + pObjSaveOrSaved = Aig_Or( pNew, pObjSavePi, pObjSavedLo ); + pObjSaveAndNotSaved = Aig_And( pNew, pObjSavePi, Aig_Not(pObjSavedLo) ); + } + + //******************************************************************** + // Step 8: create internal nodes + //******************************************************************** + Aig_ManForEachNode( p, pObj, i ) + { + pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + } + + + //******************************************************************** + // Step 8.x : create PO for each safety assertions + // NOTE : Here the output is purposely inverted as it will be thrown to + // dprove + //******************************************************************** + if( mode == FULL_BIERE_MODE || mode == IGNORE_LIVENESS_KEEP_SAFETY_MODE ) + { + if( Vec_PtrSize( vAssertSafety ) != 0 && Vec_PtrSize( vAssumeSafety ) == 0 ) + { + pObjAndAcc = Aig_ManConst1( pNew ); + Vec_PtrForEachEntry( Aig_Obj_t *, vAssertSafety, pObj, i ) + { + pArgument = Aig_NotCond( (Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0( pObj ) ); + pObjAndAcc = Aig_And( pNew, pArgument, pObjAndAcc ); + } + pObjOriginalSafetyPropertyOutput = Aig_ObjCreatePo( pNew, Aig_Not(pObjAndAcc) ); + } + else if( Vec_PtrSize( vAssertSafety ) != 0 && Vec_PtrSize( vAssumeSafety ) != 0 ) + { + pObjAndAcc = Aig_ManConst1( pNew ); + Vec_PtrForEachEntry( Aig_Obj_t *, vAssertSafety, pObj, i ) + { + pArgument = Aig_NotCond( (Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0( pObj ) ); + pObjAndAcc = Aig_And( pNew, pArgument, pObjAndAcc ); + } + collectiveAssertSafety = pObjAndAcc; + + pObjAndAcc = Aig_ManConst1( pNew ); + Vec_PtrForEachEntry( Aig_Obj_t *, vAssumeSafety, pObj, i ) + { + pArgument = Aig_NotCond( (Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0( pObj ) ); + pObjAndAcc = Aig_And( pNew, pArgument, pObjAndAcc ); + } + collectiveAssumeSafety = pObjAndAcc; + pObjOriginalSafetyPropertyOutput = Aig_ObjCreatePo( pNew, Aig_And( pNew, Aig_Not(collectiveAssertSafety), collectiveAssumeSafety ) ); + } + else + { + printf("WARNING!! No safety property is found, a new (negated) constant 1 output is created\n"); + pObjOriginalSafetyPropertyOutput = Aig_ObjCreatePo( pNew, Aig_Not( Aig_ManConst1(pNew) ) ); + } + } + + //******************************************************************** + // Step 9: create the safety property output gate for the liveness properties + // discuss with Sat/Alan for an alternative implementation + //******************************************************************** + if( mode == FULL_BIERE_MODE || mode == IGNORE_SAFETY_KEEP_LIVENESS_MODE ) + { + pObjSafetyPropertyOutput = Aig_ObjCreatePo( pNew, (Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData ); + } + + // create register inputs for the original registers + nRegCount = 0; + + Saig_ManForEachLo( p, pObj, i ) + { + pMatch = Saig_ObjLoToLi( p, pObj ); + Aig_ObjCreatePo( pNew, Aig_NotCond((Aig_Obj_t *)Aig_ObjFanin0(pMatch)->pData, Aig_ObjFaninC0( pMatch ) ) ); + nRegCount++; + liCopied++; + } + + // create register input corresponding to the register "saved" + if( mode == FULL_BIERE_MODE || mode == IGNORE_SAFETY_KEEP_LIVENESS_MODE ) + { + #ifndef DUPLICATE_CKT_DEBUG + pObjSavedLi = Aig_ObjCreatePo( pNew, pObjSaveOrSaved ); + nRegCount++; + liCreated++; + + //Changed on October 13, 2009 + //pObjAndAcc = NULL; + pObjAndAcc = Aig_ManConst1( pNew ); + + // create the family of shadow registers, then create the cascade of Xnor and And gates for the comparator + Saig_ManForEachLo( p, pObj, i ) + { + pObjShadowLo = Aig_ObjCreatePi( pNew ); + + #ifdef PROPAGATE_NAMES + Vec_PtrPush( vecLos, pObjShadowLo ); + nodeName = (char *)malloc( strlen( Abc_ObjName( Abc_NtkCi( pNtk, Abc_NtkPiNum(pNtk) + i ) ) ) + 10 ); + sprintf( nodeName, "%s__%s", Abc_ObjName( Abc_NtkCi( pNtk, Abc_NtkPiNum(pNtk) + i ) ), "SHADOW" ); + + Vec_PtrPush( vecLoNames, nodeName ); + #endif + + pObjShadowLiDriver = Aig_Mux( pNew, pObjSaveAndNotSaved, (Aig_Obj_t *)pObj->pData, pObjShadowLo ); + pObjShadowLi = Aig_ObjCreatePo( pNew, pObjShadowLiDriver ); + nRegCount++; + loCreated++; liCreated++; + + pObjXor = Aig_Exor( pNew, (Aig_Obj_t *)pObj->pData, pObjShadowLo ); + pObjXnor = Aig_Not( pObjXor ); + + pObjAndAcc = Aig_And( pNew, pObjXnor, pObjAndAcc ); + } + + // create the AND gate whose output will be the signal "looped" + pObjSavedLoAndEquality = Aig_And( pNew, pObjSavedLo, pObjAndAcc ); + + // create the master AND gate and corresponding AND and OR logic for the liveness properties + pObjAndAcc = Aig_ManConst1( pNew ); + if( vLive == NULL || Vec_PtrSize( vLive ) == 0 ) + { + printf("Circuit without any liveness property\n"); + } + else + { + Vec_PtrForEachEntry( Aig_Obj_t *, vLive, pObj, i ) + { + liveLatch++; + pDriverImage = Aig_NotCond((Aig_Obj_t *)Aig_Regular(Aig_ObjChild0( pObj ))->pData, Aig_ObjFaninC0(pObj)); + pObjShadowLo = Aig_ObjCreatePi( pNew ); + + #ifdef PROPAGATE_NAMES + Vec_PtrPush( vecLos, pObjShadowLo ); + nodeName = (char *)malloc( strlen( Abc_ObjName( Abc_NtkPo( pNtk, getPoIndex( p, pObj ) ) ) ) + 12 ); + sprintf( nodeName, "%s__%s", Abc_ObjName( Abc_NtkPo( pNtk, getPoIndex( p, pObj ) ) ), "LIVENESS" ); + Vec_PtrPush( vecLoNames, nodeName ); + #endif + + pObjShadowLiDriver = Aig_Or( pNew, pObjShadowLo, Aig_And( pNew, pDriverImage, pObjSaveOrSaved ) ); + pObjShadowLi = Aig_ObjCreatePo( pNew, pObjShadowLiDriver ); + nRegCount++; + loCreated++; liCreated++; + + pObjAndAcc = Aig_And( pNew, pObjShadowLo, pObjAndAcc ); + } + } + + pObjLive = pObjAndAcc; + + pObjAndAcc = Aig_ManConst1( pNew ); + if( vFair == NULL || Vec_PtrSize( vFair ) == 0 ) + printf("Circuit without any fairness property\n"); + else + { + Vec_PtrForEachEntry( Aig_Obj_t *, vFair, pObj, i ) + { + fairLatch++; + pDriverImage = Aig_NotCond((Aig_Obj_t *)Aig_Regular(Aig_ObjChild0( pObj ))->pData, Aig_ObjFaninC0(pObj)); + pObjShadowLo = Aig_ObjCreatePi( pNew ); + + #ifdef PROPAGATE_NAMES + Vec_PtrPush( vecLos, pObjShadowLo ); + nodeName = (char *)malloc( strlen( Abc_ObjName( Abc_NtkPo( pNtk, getPoIndex( p, pObj ) ) ) ) + 12 ); + sprintf( nodeName, "%s__%s", Abc_ObjName( Abc_NtkPo( pNtk, getPoIndex( p, pObj ) ) ), "FAIRNESS" ); + Vec_PtrPush( vecLoNames, nodeName ); + #endif + + pObjShadowLiDriver = Aig_Or( pNew, pObjShadowLo, Aig_And( pNew, pDriverImage, pObjSaveOrSaved ) ); + pObjShadowLi = Aig_ObjCreatePo( pNew, pObjShadowLiDriver ); + nRegCount++; + loCreated++; liCreated++; + + pObjAndAcc = Aig_And( pNew, pObjShadowLo, pObjAndAcc ); + } + } + + pObjFair = pObjAndAcc; + + //pObjSafetyGate = Aig_Exor( pNew, Aig_Not(Aig_ManConst1( pNew )), Aig_And( pNew, pObjSavedLoAndEquality, Aig_And( pNew, pObjFair, Aig_Not( pObjLive ) ) ) ); + //Following is the actual Biere translation + pObjSafetyGate = Aig_And( pNew, pObjSavedLoAndEquality, Aig_And( pNew, pObjFair, Aig_Not( pObjLive ) ) ); + + Aig_ObjPatchFanin0( pNew, pObjSafetyPropertyOutput, pObjSafetyGate ); + #endif + } + + Aig_ManSetRegNum( pNew, nRegCount ); + + Aig_ManPiCleanupBiere( pNew ); + Aig_ManPoCleanupBiere( pNew ); + + Aig_ManCleanup( pNew ); + + assert( Aig_ManCheck( pNew ) ); + + if( mode == FULL_BIERE_MODE || mode == IGNORE_SAFETY_KEEP_LIVENESS_MODE ) + { + assert((Aig_Obj_t *)Vec_PtrEntry(pNew->vPos, Saig_ManPoNum(pNew)+Aig_ObjPioNum(pObjSavedLo)-Saig_ManPiNum(p)-1) == pObjSavedLi); + assert( Saig_ManPiNum( p ) + 1 == Saig_ManPiNum( pNew ) ); + assert( Saig_ManRegNum( pNew ) == Saig_ManRegNum( p ) * 2 + 1 + liveLatch + fairLatch ); + } + + return pNew; +} + + + + + +Aig_Man_t * LivenessToSafetyTransformationAbs( int mode, Abc_Ntk_t * pNtk, Aig_Man_t * p, Vec_Int_t *vFlops, + Vec_Ptr_t *vLive, Vec_Ptr_t *vFair, Vec_Ptr_t *vAssertSafety, Vec_Ptr_t *vAssumeSafety ) +{ + Aig_Man_t * pNew; + int i, nRegCount, iEntry; + Aig_Obj_t * pObjSavePi; + Aig_Obj_t *pObjSavedLo, *pObjSavedLi; + Aig_Obj_t *pObj, *pMatch; + Aig_Obj_t *pObjSaveOrSaved, *pObjSaveAndNotSaved, *pObjSavedLoAndEquality; + Aig_Obj_t *pObjShadowLo, *pObjShadowLi, *pObjShadowLiDriver; + Aig_Obj_t *pObjXor, *pObjXnor, *pObjAndAcc; + Aig_Obj_t *pObjLive, *pObjFair, *pObjSafetyGate; + Aig_Obj_t *pObjSafetyPropertyOutput; + Aig_Obj_t *pDriverImage, *pArgument, *collectiveAssertSafety, *collectiveAssumeSafety; + char *nodeName; + int piCopied = 0, liCopied = 0, loCopied = 0, liCreated = 0, loCreated = 0, piVecIndex = 0, liveLatch = 0, fairLatch = 0; + + vecPis = Vec_PtrAlloc( Saig_ManPiNum( p ) + 1); + vecPiNames = Vec_PtrAlloc( Saig_ManPiNum( p ) + 1); + + vecLos = Vec_PtrAlloc( Saig_ManRegNum( p ) + Vec_IntSize( vFlops ) + 1 + Vec_PtrSize( vLive ) + Vec_PtrSize( vFair ) ); + vecLoNames = Vec_PtrAlloc( Saig_ManRegNum( p ) + Vec_IntSize( vFlops ) + 1 + Vec_PtrSize( vLive ) + Vec_PtrSize( vFair ) ); + + //**************************************************************** + // Step1: create the new manager + // Note: The new manager is created with "2 * Aig_ManObjNumMax(p)" + // nodes, but this selection is arbitrary - need to be justified + //**************************************************************** + pNew = Aig_ManStart( 2 * Aig_ManObjNumMax(p) ); + pNew->pName = (char *)malloc( strlen( pNtk->pName ) + strlen("_l2s") + 1 ); + sprintf(pNew->pName, "%s_%s", pNtk->pName, "l2s"); + pNew->pSpec = NULL; + + //**************************************************************** + // Step 2: map constant nodes + //**************************************************************** + pObj = Aig_ManConst1( p ); + pObj->pData = Aig_ManConst1( pNew ); + + //**************************************************************** + // Step 3: create true PIs + //**************************************************************** + Saig_ManForEachPi( p, pObj, i ) + { + piCopied++; + pObj->pData = Aig_ObjCreatePi(pNew); + Vec_PtrPush( vecPis, pObj->pData ); + nodeName = Aig_UtilStrsav(Abc_ObjName( Abc_NtkPi( pNtk, i ) )); + Vec_PtrPush( vecPiNames, nodeName ); + } + + //**************************************************************** + // Step 4: create the special Pi corresponding to SAVE + //**************************************************************** + if( mode == FULL_BIERE_MODE || mode == IGNORE_SAFETY_KEEP_LIVENESS_MODE ) + { + pObjSavePi = Aig_ObjCreatePi( pNew ); + nodeName = "SAVE_BIERE", + Vec_PtrPush( vecPiNames, nodeName ); + } + + //**************************************************************** + // Step 5: create register outputs + //**************************************************************** + Saig_ManForEachLo( p, pObj, i ) + { + loCopied++; + pObj->pData = Aig_ObjCreatePi(pNew); + Vec_PtrPush( vecLos, pObj->pData ); + nodeName = Aig_UtilStrsav(Abc_ObjName( Abc_NtkCi( pNtk, Abc_NtkPiNum(pNtk) + i ) )); + Vec_PtrPush( vecLoNames, nodeName ); + } + + //**************************************************************** + // Step 6: create "saved" register output + //**************************************************************** + if( mode == FULL_BIERE_MODE || mode == IGNORE_SAFETY_KEEP_LIVENESS_MODE ) + { + loCreated++; + pObjSavedLo = Aig_ObjCreatePi( pNew ); + Vec_PtrPush( vecLos, pObjSavedLo ); + nodeName = "SAVED_LO"; + Vec_PtrPush( vecLoNames, nodeName ); + } + + //**************************************************************** + // Step 7: create the OR gate and the AND gate directly fed by "SAVE" Pi + //**************************************************************** + if( mode == FULL_BIERE_MODE || mode == IGNORE_SAFETY_KEEP_LIVENESS_MODE ) + { + pObjSaveOrSaved = Aig_Or( pNew, pObjSavePi, pObjSavedLo ); + pObjSaveAndNotSaved = Aig_And( pNew, pObjSavePi, Aig_Not(pObjSavedLo) ); + } + + //******************************************************************** + // Step 8: create internal nodes + //******************************************************************** + Aig_ManForEachNode( p, pObj, i ) + { + pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + } + + + //******************************************************************** + // Step 8.x : create PO for each safety assertions + // NOTE : Here the output is purposely inverted as it will be thrown to + // dprove + //******************************************************************** + if( mode == FULL_BIERE_MODE || mode == IGNORE_LIVENESS_KEEP_SAFETY_MODE ) + { + if( Vec_PtrSize( vAssertSafety ) != 0 && Vec_PtrSize( vAssumeSafety ) == 0 ) + { + pObjAndAcc = Aig_ManConst1( pNew ); + Vec_PtrForEachEntry( Aig_Obj_t *, vAssertSafety, pObj, i ) + { + pArgument = Aig_NotCond( (Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0( pObj ) ); + pObjAndAcc = Aig_And( pNew, pArgument, pObjAndAcc ); + } + Aig_ObjCreatePo( pNew, Aig_Not(pObjAndAcc) ); + } + else if( Vec_PtrSize( vAssertSafety ) != 0 && Vec_PtrSize( vAssumeSafety ) != 0 ) + { + pObjAndAcc = Aig_ManConst1( pNew ); + Vec_PtrForEachEntry( Aig_Obj_t *, vAssertSafety, pObj, i ) + { + pArgument = Aig_NotCond( (Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0( pObj ) ); + pObjAndAcc = Aig_And( pNew, pArgument, pObjAndAcc ); + } + collectiveAssertSafety = pObjAndAcc; + + pObjAndAcc = Aig_ManConst1( pNew ); + Vec_PtrForEachEntry( Aig_Obj_t *, vAssumeSafety, pObj, i ) + { + pArgument = Aig_NotCond( (Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0( pObj ) ); + pObjAndAcc = Aig_And( pNew, pArgument, pObjAndAcc ); + } + collectiveAssumeSafety = pObjAndAcc; + Aig_ObjCreatePo( pNew, Aig_And( pNew, Aig_Not(collectiveAssertSafety), collectiveAssumeSafety ) ); + } + else + { + printf("WARNING!! No safety property is found, a new (negated) constant 1 output is created\n"); + Aig_ObjCreatePo( pNew, Aig_Not( Aig_ManConst1(pNew) ) ); + } + } + + //******************************************************************** + // Step 9: create the safety property output gate for the liveness properties + // discuss with Sat/Alan for an alternative implementation + //******************************************************************** + if( mode == FULL_BIERE_MODE || mode == IGNORE_SAFETY_KEEP_LIVENESS_MODE ) + { + pObjSafetyPropertyOutput = Aig_ObjCreatePo( pNew, (Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData ); + } + + // create register inputs for the original registers + nRegCount = 0; + + Saig_ManForEachLo( p, pObj, i ) + { + pMatch = Saig_ObjLoToLi( p, pObj ); + Aig_ObjCreatePo( pNew, Aig_NotCond((Aig_Obj_t *)Aig_ObjFanin0(pMatch)->pData, Aig_ObjFaninC0( pMatch ) ) ); + nRegCount++; + liCopied++; + } + + // create register input corresponding to the register "saved" + if( mode == FULL_BIERE_MODE || mode == IGNORE_SAFETY_KEEP_LIVENESS_MODE ) + { + #ifndef DUPLICATE_CKT_DEBUG + pObjSavedLi = Aig_ObjCreatePo( pNew, pObjSaveOrSaved ); + nRegCount++; + liCreated++; + + //Changed on October 13, 2009 + //pObjAndAcc = NULL; + pObjAndAcc = Aig_ManConst1( pNew ); + + // create the family of shadow registers, then create the cascade of Xnor and And gates for the comparator + //Saig_ManForEachLo( p, pObj, i ) + Saig_ManForEachLo( p, pObj, i ) + { + printf("Flop[%d] = %s\n", i, Abc_ObjName( Abc_NtkCi( pNtk, Abc_NtkPiNum(pNtk) + i ) ) ); + } + Vec_IntForEachEntry( vFlops, iEntry, i ) + { + pObjShadowLo = Aig_ObjCreatePi( pNew ); + pObj = Aig_ManLo( p, iEntry ); + + #ifdef PROPAGATE_NAMES + Vec_PtrPush( vecLos, pObjShadowLo ); + nodeName = (char *)malloc( strlen( Abc_ObjName( Abc_NtkCi( pNtk, Abc_NtkPiNum(pNtk) + iEntry ) ) ) + 10 ); + sprintf( nodeName, "%s__%s", Abc_ObjName( Abc_NtkCi( pNtk, Abc_NtkPiNum(pNtk) + iEntry ) ), "SHADOW" ); + printf("Flop copied [%d] = %s\n", iEntry, nodeName ); + Vec_PtrPush( vecLoNames, nodeName ); + #endif + + pObjShadowLiDriver = Aig_Mux( pNew, pObjSaveAndNotSaved, (Aig_Obj_t *)pObj->pData, pObjShadowLo ); + pObjShadowLi = Aig_ObjCreatePo( pNew, pObjShadowLiDriver ); + nRegCount++; + loCreated++; liCreated++; + + pObjXor = Aig_Exor( pNew, (Aig_Obj_t *)pObj->pData, pObjShadowLo ); + pObjXnor = Aig_Not( pObjXor ); + + pObjAndAcc = Aig_And( pNew, pObjXnor, pObjAndAcc ); + } + + // create the AND gate whose output will be the signal "looped" + pObjSavedLoAndEquality = Aig_And( pNew, pObjSavedLo, pObjAndAcc ); + + // create the master AND gate and corresponding AND and OR logic for the liveness properties + pObjAndAcc = Aig_ManConst1( pNew ); + if( vLive == NULL || Vec_PtrSize( vLive ) == 0 ) + { + printf("Circuit without any liveness property\n"); + } + else + { + Vec_PtrForEachEntry( Aig_Obj_t *, vLive, pObj, i ) + { + liveLatch++; + pDriverImage = Aig_NotCond((Aig_Obj_t *)Aig_Regular(Aig_ObjChild0( pObj ))->pData, Aig_ObjFaninC0(pObj)); + pObjShadowLo = Aig_ObjCreatePi( pNew ); + + #ifdef PROPAGATE_NAMES + Vec_PtrPush( vecLos, pObjShadowLo ); + nodeName = (char *)malloc( strlen( Abc_ObjName( Abc_NtkPo( pNtk, getPoIndex( p, pObj ) ) ) ) + 12 ); + sprintf( nodeName, "%s__%s", Abc_ObjName( Abc_NtkPo( pNtk, getPoIndex( p, pObj ) ) ), "LIVENESS" ); + Vec_PtrPush( vecLoNames, nodeName ); + #endif + + pObjShadowLiDriver = Aig_Or( pNew, pObjShadowLo, Aig_And( pNew, pDriverImage, pObjSaveOrSaved ) ); + pObjShadowLi = Aig_ObjCreatePo( pNew, pObjShadowLiDriver ); + nRegCount++; + loCreated++; liCreated++; + + pObjAndAcc = Aig_And( pNew, pObjShadowLo, pObjAndAcc ); + } + } + + pObjLive = pObjAndAcc; + + pObjAndAcc = Aig_ManConst1( pNew ); + if( vFair == NULL || Vec_PtrSize( vFair ) == 0 ) + printf("Circuit without any fairness property\n"); + else + { + Vec_PtrForEachEntry( Aig_Obj_t *, vFair, pObj, i ) + { + fairLatch++; + pDriverImage = Aig_NotCond((Aig_Obj_t *)Aig_Regular(Aig_ObjChild0( pObj ))->pData, Aig_ObjFaninC0(pObj)); + pObjShadowLo = Aig_ObjCreatePi( pNew ); + + #ifdef PROPAGATE_NAMES + Vec_PtrPush( vecLos, pObjShadowLo ); + nodeName = (char *)malloc( strlen( Abc_ObjName( Abc_NtkPo( pNtk, getPoIndex( p, pObj ) ) ) ) + 12 ); + sprintf( nodeName, "%s__%s", Abc_ObjName( Abc_NtkPo( pNtk, getPoIndex( p, pObj ) ) ), "FAIRNESS" ); + Vec_PtrPush( vecLoNames, nodeName ); + #endif + + pObjShadowLiDriver = Aig_Or( pNew, pObjShadowLo, Aig_And( pNew, pDriverImage, pObjSaveOrSaved ) ); + pObjShadowLi = Aig_ObjCreatePo( pNew, pObjShadowLiDriver ); + nRegCount++; + loCreated++; liCreated++; + + pObjAndAcc = Aig_And( pNew, pObjShadowLo, pObjAndAcc ); + } + } + + pObjFair = pObjAndAcc; + + //pObjSafetyGate = Aig_Exor( pNew, Aig_Not(Aig_ManConst1( pNew )), Aig_And( pNew, pObjSavedLoAndEquality, Aig_And( pNew, pObjFair, Aig_Not( pObjLive ) ) ) ); + //Following is the actual Biere translation + pObjSafetyGate = Aig_And( pNew, pObjSavedLoAndEquality, Aig_And( pNew, pObjFair, Aig_Not( pObjLive ) ) ); + + Aig_ObjPatchFanin0( pNew, pObjSafetyPropertyOutput, pObjSafetyGate ); + #endif + } + + Aig_ManSetRegNum( pNew, nRegCount ); + + Aig_ManPiCleanupBiere( pNew ); + Aig_ManPoCleanupBiere( pNew ); + + Aig_ManCleanup( pNew ); + + assert( Aig_ManCheck( pNew ) ); + + if( mode == FULL_BIERE_MODE || mode == IGNORE_SAFETY_KEEP_LIVENESS_MODE ) + { + assert((Aig_Obj_t *)Vec_PtrEntry(pNew->vPos, Saig_ManPoNum(pNew)+Aig_ObjPioNum(pObjSavedLo)-Saig_ManPiNum(p)-1) == pObjSavedLi); + assert( Saig_ManPiNum( p ) + 1 == Saig_ManPiNum( pNew ) ); + assert( Saig_ManRegNum( pNew ) == Saig_ManRegNum( p ) + Vec_IntSize( vFlops ) + 1 + liveLatch + fairLatch ); + } + + return pNew; +} + + + +Aig_Man_t * LivenessToSafetyTransformationOneStepLoop( int mode, Abc_Ntk_t * pNtk, Aig_Man_t * p, + Vec_Ptr_t *vLive, Vec_Ptr_t *vFair, Vec_Ptr_t *vAssertSafety, Vec_Ptr_t *vAssumeSafety ) +{ + Aig_Man_t * pNew; + int i, nRegCount; + Aig_Obj_t * pObjSavePi; + Aig_Obj_t *pObj, *pMatch; + Aig_Obj_t *pObjSavedLoAndEquality; + Aig_Obj_t *pObjXor, *pObjXnor, *pObjAndAcc, *pObjAndAccDummy; + Aig_Obj_t *pObjLive, *pObjFair, *pObjSafetyGate; + Aig_Obj_t *pObjSafetyPropertyOutput; + Aig_Obj_t *pDriverImage; + Aig_Obj_t *pObjCorrespondingLi; + Aig_Obj_t *pArgument; + Aig_Obj_t *collectiveAssertSafety, *collectiveAssumeSafety; + + char *nodeName; + int piCopied = 0, liCopied = 0, loCopied = 0, liCreated = 0, loCreated = 0, piVecIndex = 0; + + if( Aig_ManRegNum( p ) == 0 ) + { + printf("The input AIG contains no register, returning the original AIG as it is\n"); + return p; + } + + vecPis = Vec_PtrAlloc( Saig_ManPiNum( p ) + 1); + vecPiNames = Vec_PtrAlloc( Saig_ManPiNum( p ) + 1); + + vecLos = Vec_PtrAlloc( Saig_ManRegNum( p )*2 + 1 + Vec_PtrSize( vLive ) + Vec_PtrSize( vFair ) ); + vecLoNames = Vec_PtrAlloc( Saig_ManRegNum( p )*2 + 1 + Vec_PtrSize( vLive ) + Vec_PtrSize( vFair ) ); + + //**************************************************************** + // Step1: create the new manager + // Note: The new manager is created with "2 * Aig_ManObjNumMax(p)" + // nodes, but this selection is arbitrary - need to be justified + //**************************************************************** + pNew = Aig_ManStart( 2 * Aig_ManObjNumMax(p) ); + pNew->pName = Aig_UtilStrsav( "live2safe" ); + pNew->pSpec = NULL; + + //**************************************************************** + // Step 2: map constant nodes + //**************************************************************** + pObj = Aig_ManConst1( p ); + pObj->pData = Aig_ManConst1( pNew ); + + //**************************************************************** + // Step 3: create true PIs + //**************************************************************** + Saig_ManForEachPi( p, pObj, i ) + { + piCopied++; + pObj->pData = Aig_ObjCreatePi(pNew); + Vec_PtrPush( vecPis, pObj->pData ); + nodeName = Aig_UtilStrsav(Abc_ObjName( Abc_NtkPi( pNtk, i ) )); + Vec_PtrPush( vecPiNames, nodeName ); + } + + //**************************************************************** + // Step 4: create the special Pi corresponding to SAVE + //**************************************************************** + if( mode == FULL_BIERE_ONE_LOOP_MODE || mode == IGNORE_SAFETY_KEEP_LIVENESS_ONE_LOOP_MODE ) + { + pObjSavePi = Aig_ObjCreatePi( pNew ); + nodeName = "SAVE_BIERE", + Vec_PtrPush( vecPiNames, nodeName ); + } + + //**************************************************************** + // Step 5: create register outputs + //**************************************************************** + Saig_ManForEachLo( p, pObj, i ) + { + loCopied++; + pObj->pData = Aig_ObjCreatePi(pNew); + Vec_PtrPush( vecLos, pObj->pData ); + nodeName = Aig_UtilStrsav(Abc_ObjName( Abc_NtkCi( pNtk, Abc_NtkPiNum(pNtk) + i ) )); + Vec_PtrPush( vecLoNames, nodeName ); + } + + //**************************************************************** + // Step 6: create "saved" register output + //**************************************************************** + +#if 0 + loCreated++; + pObjSavedLo = Aig_ObjCreatePi( pNew ); + Vec_PtrPush( vecLos, pObjSavedLo ); + nodeName = "SAVED_LO"; + Vec_PtrPush( vecLoNames, nodeName ); +#endif + + //**************************************************************** + // Step 7: create the OR gate and the AND gate directly fed by "SAVE" Pi + //**************************************************************** +#if 0 + pObjSaveOrSaved = Aig_Or( pNew, pObjSavePi, pObjSavedLo ); + pObjSaveAndNotSaved = Aig_And( pNew, pObjSavePi, Aig_Not(pObjSavedLo) ); +#endif + + //******************************************************************** + // Step 8: create internal nodes + //******************************************************************** + Aig_ManForEachNode( p, pObj, i ) + { + pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + } + +#if 0 + //******************************************************************** + // Step 8.x : create PO for each safety assertions + //******************************************************************** + Vec_PtrForEachEntry( Aig_Obj_t *, vAssertSafety, pObj, i ) + { + pObj->pData = Aig_ObjCreatePo( pNew, Aig_NotCond(Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0( pObj ) ) ); + } +#endif + + if( mode == FULL_BIERE_ONE_LOOP_MODE || mode == IGNORE_LIVENESS_KEEP_SAFETY_MODE ) + { + if( Vec_PtrSize( vAssertSafety ) != 0 && Vec_PtrSize( vAssumeSafety ) == 0 ) + { + pObjAndAcc = NULL; + Vec_PtrForEachEntry( Aig_Obj_t *, vAssertSafety, pObj, i ) + { + //pObj->pData = Aig_ObjCreatePo( pNew, Aig_NotCond(Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0( pObj ) ) ); + pArgument = Aig_NotCond( (Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0( pObj ) ); + if( pObjAndAcc == NULL ) + pObjAndAcc = pArgument; + else + { + pObjAndAccDummy = pObjAndAcc; + pObjAndAcc = Aig_And( pNew, pArgument, pObjAndAccDummy ); + } + } + Aig_ObjCreatePo( pNew, Aig_Not(pObjAndAcc) ); + } + else if( Vec_PtrSize( vAssertSafety ) != 0 && Vec_PtrSize( vAssumeSafety ) != 0 ) + { + pObjAndAcc = NULL; + Vec_PtrForEachEntry( Aig_Obj_t *, vAssertSafety, pObj, i ) + { + //pObj->pData = Aig_ObjCreatePo( pNew, Aig_NotCond(Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0( pObj ) ) ); + pArgument = Aig_NotCond( (Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0( pObj ) ); + if( pObjAndAcc == NULL ) + pObjAndAcc = pArgument; + else + { + pObjAndAccDummy = pObjAndAcc; + pObjAndAcc = Aig_And( pNew, pArgument, pObjAndAccDummy ); + } + } + collectiveAssertSafety = pObjAndAcc; + pObjAndAcc = NULL; + Vec_PtrForEachEntry( Aig_Obj_t *, vAssumeSafety, pObj, i ) + { + //pObj->pData = Aig_ObjCreatePo( pNew, Aig_NotCond(Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0( pObj ) ) ); + pArgument = Aig_NotCond( (Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0( pObj ) ); + if( pObjAndAcc == NULL ) + pObjAndAcc = pArgument; + else + { + pObjAndAccDummy = pObjAndAcc; + pObjAndAcc = Aig_And( pNew, pArgument, pObjAndAccDummy ); + } + } + collectiveAssumeSafety = pObjAndAcc; + Aig_ObjCreatePo( pNew, Aig_And( pNew, Aig_Not(collectiveAssertSafety), collectiveAssumeSafety ) ); + } + else + printf("No safety property is specified, hence no safety gate is created\n"); + } + + //******************************************************************** + // Step 9: create the safety property output gate + // create the safety property output gate, this will be the sole true PO + // of the whole circuit, discuss with Sat/Alan for an alternative implementation + //******************************************************************** + + if( mode == FULL_BIERE_ONE_LOOP_MODE || mode == IGNORE_SAFETY_KEEP_LIVENESS_ONE_LOOP_MODE ) + { + pObjSafetyPropertyOutput = Aig_ObjCreatePo( pNew, (Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData ); + } + + // create register inputs for the original registers + nRegCount = 0; + + Saig_ManForEachLo( p, pObj, i ) + { + pMatch = Saig_ObjLoToLi( p, pObj ); + //Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pMatch) ); + Aig_ObjCreatePo( pNew, Aig_NotCond((Aig_Obj_t *)Aig_ObjFanin0(pMatch)->pData, Aig_ObjFaninC0( pMatch ) ) ); + nRegCount++; + liCopied++; + } + +#if 0 + // create register input corresponding to the register "saved" + pObjSavedLi = Aig_ObjCreatePo( pNew, pObjSaveOrSaved ); + nRegCount++; + liCreated++;7 +#endif + + pObjAndAcc = NULL; + + //**************************************************************************************************** + //For detection of loop of length 1 we do not need any shadow register, we only need equality detector + //between Lo_j and Li_j and then a cascade of AND gates + //**************************************************************************************************** + + if( mode == FULL_BIERE_ONE_LOOP_MODE || mode == IGNORE_SAFETY_KEEP_LIVENESS_ONE_LOOP_MODE ) + { + Saig_ManForEachLo( p, pObj, i ) + { + pObjCorrespondingLi = Saig_ObjLoToLi( p, pObj ); + + pObjXor = Aig_Exor( pNew, (Aig_Obj_t *)pObj->pData, Aig_NotCond( (Aig_Obj_t *)Aig_ObjFanin0( pObjCorrespondingLi )->pData, Aig_ObjFaninC0( pObjCorrespondingLi ) ) ); + pObjXnor = Aig_Not( pObjXor ); + + if( pObjAndAcc == NULL ) + pObjAndAcc = pObjXnor; + else + { + pObjAndAccDummy = pObjAndAcc; + pObjAndAcc = Aig_And( pNew, pObjXnor, pObjAndAccDummy ); + } + } + + // create the AND gate whose output will be the signal "looped" + pObjSavedLoAndEquality = Aig_And( pNew, pObjSavePi, pObjAndAcc ); + + // create the master AND gate and corresponding AND and OR logic for the liveness properties + pObjAndAcc = NULL; + if( vLive == NULL || Vec_PtrSize( vLive ) == 0 ) + printf("Circuit without any liveness property\n"); + else + { + Vec_PtrForEachEntry( Aig_Obj_t *, vLive, pObj, i ) + { + pDriverImage = Aig_NotCond((Aig_Obj_t *)Aig_Regular(Aig_ObjChild0( pObj ))->pData, Aig_ObjFaninC0(pObj)); + if( pObjAndAcc == NULL ) + pObjAndAcc = pDriverImage; + else + { + pObjAndAccDummy = pObjAndAcc; + pObjAndAcc = Aig_And( pNew, pDriverImage, pObjAndAccDummy ); + } + } + } + + if( pObjAndAcc != NULL ) + pObjLive = pObjAndAcc; + else + pObjLive = Aig_ManConst1( pNew ); + + // create the master AND gate and corresponding AND and OR logic for the fairness properties + pObjAndAcc = NULL; + if( vFair == NULL || Vec_PtrSize( vFair ) == 0 ) + printf("Circuit without any fairness property\n"); + else + { + Vec_PtrForEachEntry( Aig_Obj_t *, vFair, pObj, i ) + { + pDriverImage = Aig_NotCond((Aig_Obj_t *)Aig_Regular(Aig_ObjChild0( pObj ))->pData, Aig_ObjFaninC0(pObj)); + if( pObjAndAcc == NULL ) + pObjAndAcc = pDriverImage; + else + { + pObjAndAccDummy = pObjAndAcc; + pObjAndAcc = Aig_And( pNew, pDriverImage, pObjAndAccDummy ); + } + } + } + + if( pObjAndAcc != NULL ) + pObjFair = pObjAndAcc; + else + pObjFair = Aig_ManConst1( pNew ); + + pObjSafetyGate = Aig_And( pNew, pObjSavedLoAndEquality, Aig_And( pNew, pObjFair, Aig_Not( pObjLive ) ) ); + + Aig_ObjPatchFanin0( pNew, pObjSafetyPropertyOutput, pObjSafetyGate ); + } + + Aig_ManSetRegNum( pNew, nRegCount ); + + //printf("\nSaig_ManPiNum = %d, Reg Num = %d, before everything, before Pi cleanup\n", Vec_PtrSize( pNew->vPis ), pNew->nRegs ); + + Aig_ManPiCleanupBiere( pNew ); + Aig_ManPoCleanupBiere( pNew ); + + Aig_ManCleanup( pNew ); + + assert( Aig_ManCheck( pNew ) ); + + return pNew; +} + + + +Vec_Ptr_t * populateLivenessVector( Abc_Ntk_t *pNtk, Aig_Man_t *pAig ) +{ + Abc_Obj_t * pNode; + int i, liveCounter = 0; + Vec_Ptr_t * vLive; + + vLive = Vec_PtrAlloc( 100 ); + Abc_NtkForEachPo( pNtk, pNode, i ) + //if( strstr( Abc_ObjName( pNode ), "assert_fair") != NULL ) + if( nodeName_starts_with( pNode, "assert_fair" ) ) + { + Vec_PtrPush( vLive, Aig_ManPo( pAig, i ) ); + liveCounter++; + } + printf("Number of liveness property found = %d\n", liveCounter); + return vLive; +} + +Vec_Ptr_t * populateFairnessVector( Abc_Ntk_t *pNtk, Aig_Man_t *pAig ) +{ + Abc_Obj_t * pNode; + int i, fairCounter = 0; + Vec_Ptr_t * vFair; + + vFair = Vec_PtrAlloc( 100 ); + Abc_NtkForEachPo( pNtk, pNode, i ) + //if( strstr( Abc_ObjName( pNode ), "assume_fair") != NULL ) + if( nodeName_starts_with( pNode, "assume_fair" ) ) + { + Vec_PtrPush( vFair, Aig_ManPo( pAig, i ) ); + fairCounter++; + } + printf("Number of fairness property found = %d\n", fairCounter); + return vFair; +} + +Vec_Ptr_t * populateSafetyAssertionVector( Abc_Ntk_t *pNtk, Aig_Man_t *pAig ) +{ + Abc_Obj_t * pNode; + int i, assertSafetyCounter = 0; + Vec_Ptr_t * vAssertSafety; + + vAssertSafety = Vec_PtrAlloc( 100 ); + Abc_NtkForEachPo( pNtk, pNode, i ) + //if( strstr( Abc_ObjName( pNode ), "Assert") != NULL ) + if( nodeName_starts_with( pNode, "assert_safety" ) || nodeName_starts_with( pNode, "Assert" )) + { + Vec_PtrPush( vAssertSafety, Aig_ManPo( pAig, i ) ); + assertSafetyCounter++; + } + printf("Number of safety property found = %d\n", assertSafetyCounter); + return vAssertSafety; +} + +Vec_Ptr_t * populateSafetyAssumptionVector( Abc_Ntk_t *pNtk, Aig_Man_t *pAig ) +{ + Abc_Obj_t * pNode; + int i, assumeSafetyCounter = 0; + Vec_Ptr_t * vAssumeSafety; + + vAssumeSafety = Vec_PtrAlloc( 100 ); + Abc_NtkForEachPo( pNtk, pNode, i ) + //if( strstr( Abc_ObjName( pNode ), "Assert") != NULL ) + if( nodeName_starts_with( pNode, "assume_safety" ) || nodeName_starts_with( pNode, "Assume" )) + { + Vec_PtrPush( vAssumeSafety, Aig_ManPo( pAig, i ) ); + assumeSafetyCounter++; + } + printf("Number of assume_safety property found = %d\n", assumeSafetyCounter); + return vAssumeSafety; +} + +void updateNewNetworkNameManager( Abc_Ntk_t *pNtk, Aig_Man_t *pAig, Vec_Ptr_t *vPiNames, Vec_Ptr_t *vLoNames ) +{ + Aig_Obj_t *pObj; + Abc_Obj_t *pNode; + int i, ntkObjId; + + pNtk->pManName = Nm_ManCreate( Abc_NtkCiNum( pNtk ) ); + + if( vPiNames ) + { + Saig_ManForEachPi( pAig, pObj, i ) + { + ntkObjId = Abc_NtkCi( pNtk, i )->Id; + //printf("Pi %d, Saved Name = %s, id = %d\n", i, Nm_ManStoreIdName( pNtk->pManName, ntkObjId, Aig_ObjType(pObj), Vec_PtrEntry(vPiNames, i), NULL ), ntkObjId); + Nm_ManStoreIdName( pNtk->pManName, ntkObjId, Aig_ObjType(pObj), (char *)Vec_PtrEntry(vPiNames, i), NULL ); + } + } + if( vLoNames ) + { + Saig_ManForEachLo( pAig, pObj, i ) + { + ntkObjId = Abc_NtkCi( pNtk, Saig_ManPiNum( pAig ) + i )->Id; + //printf("Lo %d, Saved name = %s, id = %d\n", i, Nm_ManStoreIdName( pNtk->pManName, ntkObjId, Aig_ObjType(pObj), Vec_PtrEntry(vLoNames, i), NULL ), ntkObjId); + Nm_ManStoreIdName( pNtk->pManName, ntkObjId, Aig_ObjType(pObj), (char *)Vec_PtrEntry(vLoNames, i), NULL ); + } + } + + Abc_NtkForEachPo(pNtk, pNode, i) + { + Abc_ObjAssignName(pNode, "assert_safety_", Abc_ObjName(pNode) ); + } + + // assign latch input names + Abc_NtkForEachLatch(pNtk, pNode, i) + if ( Nm_ManFindNameById(pNtk->pManName, Abc_ObjFanin0(pNode)->Id) == NULL ) + Abc_ObjAssignName( Abc_ObjFanin0(pNode), Abc_ObjName(Abc_ObjFanin0(pNode)), NULL ); +} + + +int Abc_CommandAbcLivenessToSafety( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk, * pNtkTemp, *pNtkNew, *pNtkOld; + Aig_Man_t * pAig, *pAigNew; + int c; + Vec_Ptr_t * vLive, * vFair, *vAssertSafety, *vAssumeSafety; + int directive = -1; + + pNtk = Abc_FrameReadNtk(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + if( argc == 1 ) + { + assert( directive == -1 ); + directive = FULL_BIERE_MODE; + } + else + { + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "1slh" ) ) != EOF ) + { + switch( c ) + { + case '1': + if( directive == -1 ) + directive = FULL_BIERE_ONE_LOOP_MODE; + else + { + assert( directive == IGNORE_LIVENESS_KEEP_SAFETY_MODE || directive == IGNORE_SAFETY_KEEP_LIVENESS_MODE ); + if( directive == IGNORE_LIVENESS_KEEP_SAFETY_MODE ) + directive = IGNORE_LIVENESS_KEEP_SAFETY_MODE; + else + directive = IGNORE_SAFETY_KEEP_LIVENESS_ONE_LOOP_MODE; + } + break; + case 's': + if( directive == -1 ) + directive = IGNORE_SAFETY_KEEP_LIVENESS_MODE; + else + { + if( directive != FULL_BIERE_ONE_LOOP_MODE ) + goto usage; + assert(directive == FULL_BIERE_ONE_LOOP_MODE); + directive = IGNORE_SAFETY_KEEP_LIVENESS_ONE_LOOP_MODE; + } + break; + case 'l': + if( directive == -1 ) + directive = IGNORE_LIVENESS_KEEP_SAFETY_MODE; + else + { + if( directive != FULL_BIERE_ONE_LOOP_MODE ) + goto usage; + assert(directive == FULL_BIERE_ONE_LOOP_MODE); + directive = IGNORE_LIVENESS_KEEP_SAFETY_MODE; + } + break; + case 'h': + goto usage; + default: + goto usage; + } + } + } + + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + if( !Abc_NtkIsStrash( pNtk ) ) + { + printf("The input network was not strashed, strashing....\n"); + pNtkTemp = Abc_NtkStrash( pNtk, 0, 0, 0 ); + pNtkOld = pNtkTemp; + pAig = Abc_NtkToDar( pNtkTemp, 0, 1 ); + vLive = populateLivenessVector( pNtk, pAig ); + vFair = populateFairnessVector( pNtk, pAig ); + vAssertSafety = populateSafetyAssertionVector( pNtk, pAig ); + vAssumeSafety = populateSafetyAssumptionVector( pNtk, pAig ); + } + else + { + pAig = Abc_NtkToDar( pNtk, 0, 1 ); + pNtkOld = pNtk; + vLive = populateLivenessVector( pNtk, pAig ); + vFair = populateFairnessVector( pNtk, pAig ); + vAssertSafety = populateSafetyAssertionVector( pNtk, pAig ); + vAssumeSafety = populateSafetyAssumptionVector( pNtk, pAig ); + } + + switch( directive ) + { + case FULL_BIERE_MODE: + //if( Vec_PtrSize(vLive) == 0 && Vec_PtrSize(vAssertSafety) == 0 ) + //{ + // printf("Input circuit has NO safety and NO liveness property, original network is not disturbed\n"); + // return 1; + //} + //else + //{ + pAigNew = LivenessToSafetyTransformation( FULL_BIERE_MODE, pNtk, pAig, vLive, vFair, vAssertSafety, vAssumeSafety ); + if( Aig_ManRegNum(pAigNew) != 0 ) + printf("A new circuit is produced with\n\t2 POs - one for safety and one for liveness.\n\tone additional input is added (due to Biere's nondeterminism)\n\tshadow flops are not created if the original circuit is combinational\n\tnon-property POs are suppressed\n"); + break; + //} + case FULL_BIERE_ONE_LOOP_MODE: + //if( Vec_PtrSize(vLive) == 0 && Vec_PtrSize(vAssertSafety) == 0 ) + //{ + // printf("Input circuit has NO safety and NO liveness property, original network is not disturbed\n"); + // return 1; + //} + //else + //{ + pAigNew = LivenessToSafetyTransformationOneStepLoop( FULL_BIERE_ONE_LOOP_MODE, pNtk, pAig, vLive, vFair, vAssertSafety, vAssumeSafety ); + if( Aig_ManRegNum(pAigNew) != 0 ) + printf("A new circuit is produced with\n\t2 POs - one for safety and one for liveness.\n\tone additional input is added (due to Biere's nondeterminism)\n\tshadow flops are not created\n\tnon-property POs are suppressed\n"); + break; + //} + case IGNORE_LIVENESS_KEEP_SAFETY_MODE: + //if( Vec_PtrSize(vAssertSafety) == 0 ) + //{ + // printf("Input circuit has NO safety property, original network is not disturbed\n"); + // return 1; + //} + //else + //{ + pAigNew = LivenessToSafetyTransformation( IGNORE_LIVENESS_KEEP_SAFETY_MODE, pNtk, pAig, vLive, vFair, vAssertSafety, vAssumeSafety ); + if( Aig_ManRegNum(pAigNew) != 0 ) + printf("A new circuit is produced with\n\t1 PO - only for safety property; liveness properties are ignored, if any.\n\tno additional input is added (due to Biere's nondeterminism)\n\tshadow flops are not created\n\tnon-property POs are suppressed\n"); + break; + //} + case IGNORE_SAFETY_KEEP_LIVENESS_MODE: + //if( Vec_PtrSize(vLive) == 0 ) + //{ + // printf("Input circuit has NO liveness property, original network is not disturbed\n"); + // return 1; + //} + //else + //{ + pAigNew = LivenessToSafetyTransformation( IGNORE_SAFETY_KEEP_LIVENESS_MODE, pNtk, pAig, vLive, vFair, vAssertSafety, vAssumeSafety ); + if( Aig_ManRegNum(pAigNew) != 0 ) + printf("A new circuit is produced with\n\t1 PO - only for liveness property; safety properties are ignored, if any.\n\tone additional input is added (due to Biere's nondeterminism)\n\tshadow flops are not created if the original circuit is combinational\n\tnon-property POs are suppressed\n"); + break; + //} + case IGNORE_SAFETY_KEEP_LIVENESS_ONE_LOOP_MODE: + //if( Vec_PtrSize(vLive) == 0 ) + //{ + // printf("Input circuit has NO liveness property, original network is not disturbed\n"); + // return 1; + //} + //else + //{ + pAigNew = LivenessToSafetyTransformationOneStepLoop( IGNORE_SAFETY_KEEP_LIVENESS_ONE_LOOP_MODE, pNtk, pAig, vLive, vFair, vAssertSafety, vAssumeSafety ); + if( Aig_ManRegNum(pAigNew) != 0 ) + printf("New circuit is produced ignoring safety outputs!\nOnly liveness and fairness outputs are considered.\nShadow registers are not created\n"); + break; + //} + } + +#if 0 + if( argc == 1 ) + { + pAigNew = LivenessToSafetyTransformation( FULL_BIERE_MODE, pNtk, pAig, vLive, vFair, vAssertSafety, vAssumeSafety ); + if( Aig_ManRegNum(pAigNew) != 0 ) + printf("New circuit is produced considering all safety, liveness and fairness outputs.\nBiere's logic is created\n"); + } + else + { + Extra_UtilGetoptReset(); + c = Extra_UtilGetopt( argc, argv, "1lsh" ); + if( c == '1' ) + { + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + if( !Abc_NtkIsStrash( pNtk ) ) + { + printf("The input network was not strashed, strashing....\n"); + pNtkTemp = Abc_NtkStrash( pNtk, 0, 0, 0 ); + pNtkOld = pNtkTemp; + pAig = Abc_NtkToDar( pNtkTemp, 0, 1 ); + vLive = populateLivenessVector( pNtk, pAig ); + vFair = populateFairnessVector( pNtk, pAig ); + vAssertSafety = populateSafetyAssertionVector( pNtk, pAig ); + vAssumeSafety = populateSafetyAssumptionVector( pNtk, pAig ); + } + else + { + pAig = Abc_NtkToDar( pNtk, 0, 1 ); + pNtkOld = pNtk; + vLive = populateLivenessVector( pNtk, pAig ); + vFair = populateFairnessVector( pNtk, pAig ); + vAssertSafety = populateSafetyAssertionVector( pNtk, pAig ); + vAssumeSafety = populateSafetyAssumptionVector( pNtk, pAig ); + } + pAigNew = LivenessToSafetyTransformationOneStepLoop( pNtk, pAig, vLive, vFair, vAssertSafety, vAssumeSafety ); + } + else if( c == 'l' ) + { + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + if( !Abc_NtkIsStrash( pNtk ) ) + { + printf("The input network was not strashed, strashing....\n"); + pNtkTemp = Abc_NtkStrash( pNtk, 0, 0, 0 ); + pNtkOld = pNtkTemp; + pAig = Abc_NtkToDar( pNtkTemp, 0, 1 ); + vLive = populateLivenessVector( pNtk, pAig ); + vFair = populateFairnessVector( pNtk, pAig ); + vAssertSafety = populateSafetyAssertionVector( pNtk, pAig ); + vAssumeSafety = populateSafetyAssumptionVector( pNtk, pAig ); + } + else + { + pAig = Abc_NtkToDar( pNtk, 0, 1 ); + pNtkOld = pNtk; + vLive = populateLivenessVector( pNtk, pAig ); + vFair = populateFairnessVector( pNtk, pAig ); + vAssertSafety = populateSafetyAssertionVector( pNtk, pAig ); + vAssumeSafety = populateSafetyAssumptionVector( pNtk, pAig ); + } + pAigNew = LivenessToSafetyTransformation( IGNORE_LIVENESS_KEEP_SAFETY_MODE, pNtk, pAig, vLive, vFair, vAssertSafety, vAssumeSafety ); + if( Aig_ManRegNum(pAigNew) != 0 ) + printf("New circuit is produced ignoring liveness outputs!\nOnly safety outputs are kept.\nBiere's logic is not created\n"); + } + else if( c == 's' ) + { + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + + if( !Abc_NtkIsStrash( pNtk ) ) + { + printf("The input network was not strashed, strashing....\n"); + pNtkTemp = Abc_NtkStrash( pNtk, 0, 0, 0 ); + pNtkOld = pNtkTemp; + pAig = Abc_NtkToDar( pNtkTemp, 0, 1 ); + vLive = populateLivenessVector( pNtk, pAig ); + vFair = populateFairnessVector( pNtk, pAig ); + vAssertSafety = populateSafetyAssertionVector( pNtk, pAig ); + vAssumeSafety = populateSafetyAssumptionVector( pNtk, pAig ); + } + else + { + pAig = Abc_NtkToDar( pNtk, 0, 1 ); + pNtkOld = pNtk; + vLive = populateLivenessVector( pNtk, pAig ); + vFair = populateFairnessVector( pNtk, pAig ); + vAssertSafety = populateSafetyAssertionVector( pNtk, pAig ); + vAssumeSafety = populateSafetyAssumptionVector( pNtk, pAig ); + } + pAigNew = LivenessToSafetyTransformation( IGNORE_SAFETY_KEEP_LIVENESS_MODE, pNtk, pAig, vLive, vFair, vAssertSafety, vAssumeSafety ); + if( Aig_ManRegNum(pAigNew) != 0 ) + printf("New circuit is produced ignoring safety outputs!\nOnly liveness and fairness outputs are considered.\nBiere's logic is created\n"); + } + else if( c == 'h' ) + goto usage; + else + goto usage; + } +#endif + +#if 0 + Aig_ManPrintStats( pAigNew ); + printf("\nDetail statistics*************************************\n"); + printf("Number of true primary inputs = %d\n", Saig_ManPiNum( pAigNew )); + printf("Number of true primary outputs = %d\n", Saig_ManPoNum( pAigNew )); + printf("Number of true latch outputs = %d\n", Saig_ManCiNum( pAigNew ) - Saig_ManPiNum( pAigNew )); + printf("Number of true latch inputs = %d\n", Saig_ManCoNum( pAigNew ) - Saig_ManPoNum( pAigNew )); + printf("Numer of registers = %d\n", Saig_ManRegNum( pAigNew ) ); + printf("\n*******************************************************\n"); +#endif + + pNtkNew = Abc_NtkFromAigPhase( pAigNew ); + pNtkNew->pName = Aig_UtilStrsav( pAigNew->pName ); + + if ( !Abc_NtkCheck( pNtkNew ) ) + fprintf( stdout, "Abc_NtkCreateCone(): Network check has failed.\n" ); + + updateNewNetworkNameManager( pNtkNew, pAigNew, vecPiNames, vecLoNames ); + Abc_FrameSetCurrentNetwork( pAbc, pNtkNew ); + +#if 0 +#ifndef DUPLICATE_CKT_DEBUG + Saig_ManForEachPi( pAigNew, pObj, i ) + assert( strcmp( (char *)Vec_PtrEntry(vecPiNames, i), retrieveTruePiName( pNtk, pAig, pAigNew, pObj ) ) == 0 ); + //printf("Name of %d-th Pi = %s, %s\n", i, retrieveTruePiName( pNtk, pAig, pAigNew, pObj ), (char *)Vec_PtrEntry(vecPiNames, i) ); + + Saig_ManForEachLo( pAigNew, pObj, i ) + assert( strcmp( (char *)Vec_PtrEntry(vecLoNames, i), retrieveLOName( pNtk, pAig, pAigNew, pObj, vLive, vFair ) ) == 0 ); +#endif +#endif + + return 0; + +usage: + fprintf( stdout, "usage: l2s [-1lsh]\n" ); + fprintf( stdout, "\t performs Armin Biere's live-to-safe transformation\n" ); + fprintf( stdout, "\t-1 : no shadow logic, presume all loops are self loops\n"); + fprintf( stdout, "\t-l : ignore liveness and fairness outputs\n"); + fprintf( stdout, "\t-s : ignore safety assertions and assumptions\n"); + fprintf( stdout, "\t-h : print command usage\n"); + return 1; +} + +Vec_Int_t * prepareFlopVector( Aig_Man_t * pAig, int vectorLength ) +{ + Vec_Int_t *vFlops; + int i; + + vFlops = Vec_IntAlloc( vectorLength ); + + for( i=0; i<vectorLength; i++ ) + Vec_IntPush( vFlops, i ); + +#if 0 + Vec_IntPush( vFlops, 19 ); + Vec_IntPush( vFlops, 20 ); + Vec_IntPush( vFlops, 23 ); + Vec_IntPush( vFlops, 24 ); + //Vec_IntPush( vFlops, 2 ); + //Vec_IntPush( vFlops, 3 ); + //Vec_IntPush( vFlops, 4 ); + //Vec_IntPush( vFlops, 5 ); + //Vec_IntPush( vFlops, 8 ); + //Vec_IntPush( vFlops, 9 ); + //Vec_IntPush( vFlops, 10 ); + //Vec_IntPush( vFlops, 11 ); + //Vec_IntPush( vFlops, 0 ); + //Vec_IntPush( vFlops, 0 ); +#endif + + return vFlops; +} + +int Abc_CommandAbcLivenessToSafetyAbstraction( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk, * pNtkTemp, *pNtkNew, *pNtkOld; + Aig_Man_t * pAig, *pAigNew; + int c; + Vec_Ptr_t * vLive, * vFair, *vAssertSafety, *vAssumeSafety; + int directive = -1; + Vec_Int_t * vFlops; + + pNtk = Abc_FrameReadNtk(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + if( argc == 1 ) + { + assert( directive == -1 ); + directive = FULL_BIERE_MODE; + } + else + { + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "1slh" ) ) != EOF ) + { + switch( c ) + { + case '1': + if( directive == -1 ) + directive = FULL_BIERE_ONE_LOOP_MODE; + else + { + assert( directive == IGNORE_LIVENESS_KEEP_SAFETY_MODE || directive == IGNORE_SAFETY_KEEP_LIVENESS_MODE ); + if( directive == IGNORE_LIVENESS_KEEP_SAFETY_MODE ) + directive = IGNORE_LIVENESS_KEEP_SAFETY_MODE; + else + directive = IGNORE_SAFETY_KEEP_LIVENESS_ONE_LOOP_MODE; + } + break; + case 's': + if( directive == -1 ) + directive = IGNORE_SAFETY_KEEP_LIVENESS_MODE; + else + { + if( directive != FULL_BIERE_ONE_LOOP_MODE ) + goto usage; + assert(directive == FULL_BIERE_ONE_LOOP_MODE); + directive = IGNORE_SAFETY_KEEP_LIVENESS_ONE_LOOP_MODE; + } + break; + case 'l': + if( directive == -1 ) + directive = IGNORE_LIVENESS_KEEP_SAFETY_MODE; + else + { + if( directive != FULL_BIERE_ONE_LOOP_MODE ) + goto usage; + assert(directive == FULL_BIERE_ONE_LOOP_MODE); + directive = IGNORE_LIVENESS_KEEP_SAFETY_MODE; + } + break; + case 'h': + goto usage; + default: + goto usage; + } + } + } + + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + if( !Abc_NtkIsStrash( pNtk ) ) + { + printf("The input network was not strashed, strashing....\n"); + pNtkTemp = Abc_NtkStrash( pNtk, 0, 0, 0 ); + pNtkOld = pNtkTemp; + pAig = Abc_NtkToDar( pNtkTemp, 0, 1 ); + vLive = populateLivenessVector( pNtk, pAig ); + vFair = populateFairnessVector( pNtk, pAig ); + vAssertSafety = populateSafetyAssertionVector( pNtk, pAig ); + vAssumeSafety = populateSafetyAssumptionVector( pNtk, pAig ); + } + else + { + pAig = Abc_NtkToDar( pNtk, 0, 1 ); + pNtkOld = pNtk; + vLive = populateLivenessVector( pNtk, pAig ); + vFair = populateFairnessVector( pNtk, pAig ); + vAssertSafety = populateSafetyAssertionVector( pNtk, pAig ); + vAssumeSafety = populateSafetyAssumptionVector( pNtk, pAig ); + } + + vFlops = prepareFlopVector( pAig, Aig_ManRegNum(pAig)%2 == 0? Aig_ManRegNum(pAig)/2 : (Aig_ManRegNum(pAig)-1)/2); + + //vFlops = prepareFlopVector( pAig, 100 ); + + switch( directive ) + { + case FULL_BIERE_MODE: + //if( Vec_PtrSize(vLive) == 0 && Vec_PtrSize(vAssertSafety) == 0 ) + //{ + // printf("Input circuit has NO safety and NO liveness property, original network is not disturbed\n"); + // return 1; + //} + //else + //{ + pAigNew = LivenessToSafetyTransformationAbs( FULL_BIERE_MODE, pNtk, pAig, vFlops, vLive, vFair, vAssertSafety, vAssumeSafety ); + if( Aig_ManRegNum(pAigNew) != 0 ) + printf("A new circuit is produced with\n\t2 POs - one for safety and one for liveness.\n\tone additional input is added (due to Biere's nondeterminism)\n\tshadow flops are not created if the original circuit is combinational\n\tnon-property POs are suppressed\n"); + break; + //} + case FULL_BIERE_ONE_LOOP_MODE: + //if( Vec_PtrSize(vLive) == 0 && Vec_PtrSize(vAssertSafety) == 0 ) + //{ + // printf("Input circuit has NO safety and NO liveness property, original network is not disturbed\n"); + // return 1; + //} + //else + //{ + pAigNew = LivenessToSafetyTransformationOneStepLoop( FULL_BIERE_ONE_LOOP_MODE, pNtk, pAig, vLive, vFair, vAssertSafety, vAssumeSafety ); + if( Aig_ManRegNum(pAigNew) != 0 ) + printf("A new circuit is produced with\n\t2 POs - one for safety and one for liveness.\n\tone additional input is added (due to Biere's nondeterminism)\n\tshadow flops are not created\n\tnon-property POs are suppressed\n"); + break; + //} + case IGNORE_LIVENESS_KEEP_SAFETY_MODE: + //if( Vec_PtrSize(vAssertSafety) == 0 ) + //{ + // printf("Input circuit has NO safety property, original network is not disturbed\n"); + // return 1; + //} + //else + //{ + pAigNew = LivenessToSafetyTransformationAbs( IGNORE_LIVENESS_KEEP_SAFETY_MODE, pNtk, pAig, vFlops, vLive, vFair, vAssertSafety, vAssumeSafety ); + if( Aig_ManRegNum(pAigNew) != 0 ) + printf("A new circuit is produced with\n\t1 PO - only for safety property; liveness properties are ignored, if any.\n\tno additional input is added (due to Biere's nondeterminism)\n\tshadow flops are not created\n\tnon-property POs are suppressed\n"); + break; + //} + case IGNORE_SAFETY_KEEP_LIVENESS_MODE: + //if( Vec_PtrSize(vLive) == 0 ) + //{ + // printf("Input circuit has NO liveness property, original network is not disturbed\n"); + // return 1; + //} + //else + //{ + pAigNew = LivenessToSafetyTransformationAbs( IGNORE_SAFETY_KEEP_LIVENESS_MODE, pNtk, pAig, vFlops, vLive, vFair, vAssertSafety, vAssumeSafety ); + if( Aig_ManRegNum(pAigNew) != 0 ) + printf("A new circuit is produced with\n\t1 PO - only for liveness property; safety properties are ignored, if any.\n\tone additional input is added (due to Biere's nondeterminism)\n\tshadow flops are not created if the original circuit is combinational\n\tnon-property POs are suppressed\n"); + break; + //} + case IGNORE_SAFETY_KEEP_LIVENESS_ONE_LOOP_MODE: + //if( Vec_PtrSize(vLive) == 0 ) + //{ + // printf("Input circuit has NO liveness property, original network is not disturbed\n"); + // return 1; + //} + //else + //{ + pAigNew = LivenessToSafetyTransformationOneStepLoop( IGNORE_SAFETY_KEEP_LIVENESS_ONE_LOOP_MODE, pNtk, pAig, vLive, vFair, vAssertSafety, vAssumeSafety ); + if( Aig_ManRegNum(pAigNew) != 0 ) + printf("New circuit is produced ignoring safety outputs!\nOnly liveness and fairness outputs are considered.\nShadow registers are not created\n"); + break; + //} + } + + pNtkNew = Abc_NtkFromAigPhase( pAigNew ); + pNtkNew->pName = Aig_UtilStrsav( pAigNew->pName ); + + if ( !Abc_NtkCheck( pNtkNew ) ) + fprintf( stdout, "Abc_NtkCreateCone(): Network check has failed.\n" ); + + updateNewNetworkNameManager( pNtkNew, pAigNew, vecPiNames,vecLoNames ); + Abc_FrameSetCurrentNetwork( pAbc, pNtkNew ); + +#if 0 +#ifndef DUPLICATE_CKT_DEBUG + Saig_ManForEachPi( pAigNew, pObj, i ) + assert( strcmp( (char *)Vec_PtrEntry(vecPiNames, i), retrieveTruePiName( pNtk, pAig, pAigNew, pObj ) ) == 0 ); + //printf("Name of %d-th Pi = %s, %s\n", i, retrieveTruePiName( pNtk, pAig, pAigNew, pObj ), (char *)Vec_PtrEntry(vecPiNames, i) ); + + Saig_ManForEachLo( pAigNew, pObj, i ) + assert( strcmp( (char *)Vec_PtrEntry(vecLoNames, i), retrieveLOName( pNtk, pAig, pAigNew, pObj, vLive, vFair ) ) == 0 ); +#endif +#endif + + return 0; + +usage: + fprintf( stdout, "usage: l2s [-1lsh]\n" ); + fprintf( stdout, "\t performs Armin Biere's live-to-safe transformation\n" ); + fprintf( stdout, "\t-1 : no shadow logic, presume all loops are self loops\n"); + fprintf( stdout, "\t-l : ignore liveness and fairness outputs\n"); + fprintf( stdout, "\t-s : ignore safety assertions and assumptions\n"); + fprintf( stdout, "\t-h : print command usage\n"); + return 1; +} +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/live/liveness_sim.c b/src/aig/live/liveness_sim.c new file mode 100644 index 00000000..5e494b87 --- /dev/null +++ b/src/aig/live/liveness_sim.c @@ -0,0 +1,848 @@ +/**CFile**************************************************************** + + FileName [liveness_sim.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Liveness property checking.] + + Synopsis [Main implementation module.] + + Author [Sayak Ray] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - January 1, 2009.] + + Revision [$Id: liveness_sim.c,v 1.00 2009/01/01 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include <stdio.h> +#include "main.h" +#include "aig.h" +#include "saig.h" +#include <string.h> + +ABC_NAMESPACE_IMPL_START + + +#define PROPAGATE_NAMES +//#define DUPLICATE_CKT_DEBUG + +extern Aig_Man_t * Abc_NtkToDar( Abc_Ntk_t * pNtk, int fExors, int fRegisters ); +extern Abc_Ntk_t * Abc_NtkFromAigPhase( Aig_Man_t * pMan ); +//char *strdup(const char *string); + + +/******************************************************************* +LAYOUT OF PI VECTOR: + ++------------------------------------------------------------------------------------------------------------------------------------+ +| TRUE ORIGINAL PI (n) | SAVE(PI) (1) | ORIGINAL LO (k) | SAVED(LO) (1) | SHADOW_ORIGINAL LO (k) | LIVENESS LO (l) | FAIRNESS LO (f) | ++------------------------------------------------------------------------------------------------------------------------------------+ +<------------True PI----------------->|<----------------------------LO---------------------------------------------------------------> + +LAYOUT OF PO VECTOR: + ++-----------------------------------------------------------------------------------------------------------+ +| SOLE PO (1) | ORIGINAL LI (k) | SAVED LI (1) | SHADOW_ORIGINAL LI (k) | LIVENESS LI (l) | FAIRNESS LI (f) | ++-----------------------------------------------------------------------------------------------------------+ +<--True PO--->|<--------------------------------------LI----------------------------------------------------> + +********************************************************************/ + +static void printVecPtrOfString( Vec_Ptr_t *vec ) +{ + int i; + + for( i=0; i< Vec_PtrSize( vec ); i++ ) + { + printf("vec[%d] = %s\n", i, (char *)Vec_PtrEntry(vec, i) ); + } +} + +static int getPoIndex( Aig_Man_t *pAig, Aig_Obj_t *pPivot ) +{ + int i; + Aig_Obj_t *pObj; + + Saig_ManForEachPo( pAig, pObj, i ) + { + if( pObj == pPivot ) + return i; + } + return -1; +} + +static char * retrieveTruePiName( Abc_Ntk_t *pNtkOld, Aig_Man_t *pAigOld, Aig_Man_t *pAigNew, Aig_Obj_t *pObjPivot ) +{ + Aig_Obj_t *pObjOld, *pObj; + Abc_Obj_t *pNode; + int index; + + assert( Saig_ObjIsPi( pAigNew, pObjPivot ) ); + Aig_ManForEachPi( pAigNew, pObj, index ) + if( pObj == pObjPivot ) + break; + assert( index < Aig_ManPiNum( pAigNew ) - Aig_ManRegNum( pAigNew ) ); + if( index == Saig_ManPiNum( pAigNew ) - 1 ) + return "SAVE_BIERE"; + else + { + pObjOld = Aig_ManPi( pAigOld, index ); + pNode = Abc_NtkPi( pNtkOld, index ); + assert( pObjOld->pData == pObjPivot ); + return Abc_ObjName( pNode ); + } +} + +static char * retrieveLOName( Abc_Ntk_t *pNtkOld, Aig_Man_t *pAigOld, Aig_Man_t *pAigNew, Aig_Obj_t *pObjPivot, Vec_Ptr_t *vLive, Vec_Ptr_t * vFair ) +{ + Aig_Obj_t *pObjOld, *pObj; + Abc_Obj_t *pNode; + int index, oldIndex, originalLatchNum = Saig_ManRegNum(pAigOld), strMatch, i; + char *dummyStr = (char *)malloc( sizeof(char) * 50 ); + + assert( Saig_ObjIsLo( pAigNew, pObjPivot ) ); + Saig_ManForEachLo( pAigNew, pObj, index ) + if( pObj == pObjPivot ) + break; + if( index < originalLatchNum ) + { + oldIndex = Saig_ManPiNum( pAigOld ) + index; + pObjOld = Aig_ManPi( pAigOld, oldIndex ); + pNode = Abc_NtkCi( pNtkOld, oldIndex ); + assert( pObjOld->pData == pObjPivot ); + return Abc_ObjName( pNode ); + } + else if( index == originalLatchNum ) + return "SAVED_LO"; + else if( index > originalLatchNum && index < 2 * originalLatchNum + 1 ) + { + oldIndex = Saig_ManPiNum( pAigOld ) + index - originalLatchNum - 1; + pObjOld = Aig_ManPi( pAigOld, oldIndex ); + pNode = Abc_NtkCi( pNtkOld, oldIndex ); + sprintf( dummyStr, "%s__%s", Abc_ObjName( pNode ), "SHADOW"); + return dummyStr; + } + else if( index >= 2 * originalLatchNum + 1 && index < 2 * originalLatchNum + 1 + Vec_PtrSize( vLive ) ) + { + oldIndex = index - 2 * originalLatchNum - 1; + strMatch = 0; + Saig_ManForEachPo( pAigOld, pObj, i ) + { + pNode = Abc_NtkPo( pNtkOld, i ); + if( strstr( Abc_ObjName( pNode ), "assert_fair" ) != NULL ) + { + if( strMatch == oldIndex ) + { + sprintf( dummyStr, "%s__%s", Abc_ObjName( pNode ), "LIVENESS"); + return dummyStr; + } + else + strMatch++; + } + } + } + else if( index >= 2 * originalLatchNum + 1 + Vec_PtrSize( vLive ) && index < 2 * originalLatchNum + 1 + Vec_PtrSize( vLive ) + Vec_PtrSize( vFair ) ) + { + oldIndex = index - 2 * originalLatchNum - 1 - Vec_PtrSize( vLive ); + strMatch = 0; + Saig_ManForEachPo( pAigOld, pObj, i ) + { + pNode = Abc_NtkPo( pNtkOld, i ); + if( strstr( Abc_ObjName( pNode ), "assume_fair" ) != NULL ) + { + if( strMatch == oldIndex ) + { + sprintf( dummyStr, "%s__%s", Abc_ObjName( pNode ), "FAIRNESS"); + return dummyStr; + } + else + strMatch++; + } + } + } + else + return "UNKNOWN"; +} + +extern Vec_Ptr_t *vecPis, *vecPiNames; +extern Vec_Ptr_t *vecLos, *vecLoNames; + + +static int Aig_ManPiCleanupBiere( Aig_Man_t * p ) +{ + int k = 0, nPisOld = Aig_ManPiNum(p); + + p->nObjs[AIG_OBJ_PI] = Vec_PtrSize( p->vPis ); + if ( Aig_ManRegNum(p) ) + p->nTruePis = Aig_ManPiNum(p) - Aig_ManRegNum(p); + + return nPisOld - Aig_ManPiNum(p); +} + + +static int Aig_ManPoCleanupBiere( Aig_Man_t * p ) +{ + int k = 0, nPosOld = Aig_ManPoNum(p); + + p->nObjs[AIG_OBJ_PO] = Vec_PtrSize( p->vPos ); + if ( Aig_ManRegNum(p) ) + p->nTruePos = Aig_ManPoNum(p) - Aig_ManRegNum(p); + return nPosOld - Aig_ManPoNum(p); +} + +static Aig_Man_t * LivenessToSafetyTransformationSim( Abc_Ntk_t * pNtk, Aig_Man_t * p, Vec_Ptr_t *vLive, Vec_Ptr_t *vFair ) +{ + Aig_Man_t * pNew; + int i, nRegCount; + Aig_Obj_t * pObjSavePi; + Aig_Obj_t *pObjSavedLo, *pObjSavedLi; + Aig_Obj_t *pObj, *pMatch; + Aig_Obj_t *pObjSaveOrSaved, *pObjSavedLoAndEquality; + Aig_Obj_t *pObjShadowLo, *pObjShadowLi, *pObjShadowLiDriver; + Aig_Obj_t *pObjXor, *pObjXnor, *pObjAndAcc, *pObjAndAccDummy; + Aig_Obj_t *pObjLive, *pObjFair, *pObjSafetyGate; + Aig_Obj_t *pObjSafetyPropertyOutput; + Aig_Obj_t *pDriverImage; + char *nodeName; + int piCopied = 0, liCopied = 0, loCopied = 0, liCreated = 0, loCreated = 0, piVecIndex = 0, liveLatch = 0, fairLatch = 0; + + vecPis = Vec_PtrAlloc( Saig_ManPiNum( p ) + 1); + vecPiNames = Vec_PtrAlloc( Saig_ManPiNum( p ) + 1); + + vecLos = Vec_PtrAlloc( Saig_ManRegNum( p )*2 + 1 + Vec_PtrSize( vLive ) + Vec_PtrSize( vFair ) ); + vecLoNames = Vec_PtrAlloc( Saig_ManRegNum( p )*2 + 1 + Vec_PtrSize( vLive ) + Vec_PtrSize( vFair ) ); + +#ifdef DUPLICATE_CKT_DEBUG + printf("\nCode is compiled in DEBUG mode, the input-output behavior will be the same as the original circuit\n"); + printf("Press any key to continue..."); + scanf("%c", &c); +#endif + + //**************************************************************** + // Step1: create the new manager + // Note: The new manager is created with "2 * Aig_ManObjNumMax(p)" + // nodes, but this selection is arbitrary - need to be justified + //**************************************************************** + pNew = Aig_ManStart( 2 * Aig_ManObjNumMax(p) ); + pNew->pName = Aig_UtilStrsav( "live2safe" ); + pNew->pSpec = NULL; + + //**************************************************************** + // Step 2: map constant nodes + //**************************************************************** + pObj = Aig_ManConst1( p ); + pObj->pData = Aig_ManConst1( pNew ); + + //**************************************************************** + // Step 3: create true PIs + //**************************************************************** + Saig_ManForEachPi( p, pObj, i ) + { + piCopied++; + pObj->pData = Aig_ObjCreatePi(pNew); + Vec_PtrPush( vecPis, pObj->pData ); + nodeName = Aig_UtilStrsav(Abc_ObjName( Abc_NtkPi( pNtk, i ) )); + Vec_PtrPush( vecPiNames, nodeName ); + } + + //**************************************************************** + // Step 4: create the special Pi corresponding to SAVE + //**************************************************************** +#ifndef DUPLICATE_CKT_DEBUG + pObjSavePi = Aig_ObjCreatePi( pNew ); + nodeName = Aig_UtilStrsav("SAVE_BIERE"), + Vec_PtrPush( vecPiNames, nodeName ); +#endif + + //**************************************************************** + // Step 5: create register outputs + //**************************************************************** + Saig_ManForEachLo( p, pObj, i ) + { + loCopied++; + pObj->pData = Aig_ObjCreatePi(pNew); + Vec_PtrPush( vecLos, pObj->pData ); + nodeName = Aig_UtilStrsav(Abc_ObjName( Abc_NtkCi( pNtk, Abc_NtkPiNum(pNtk) + i ) )); + Vec_PtrPush( vecLoNames, nodeName ); + } + + //**************************************************************** + // Step 6: create "saved" register output + //**************************************************************** +#ifndef DUPLICATE_CKT_DEBUG + loCreated++; + pObjSavedLo = Aig_ObjCreatePi( pNew ); + Vec_PtrPush( vecLos, pObjSavedLo ); + nodeName = Aig_UtilStrsav("SAVED_LO"); + Vec_PtrPush( vecLoNames, nodeName ); +#endif + + //**************************************************************** + // Step 7: create the OR gate and the AND gate directly fed by "SAVE" Pi + //**************************************************************** +#ifndef DUPLICATE_CKT_DEBUG + pObjSaveOrSaved = Aig_Or( pNew, pObjSavePi, pObjSavedLo ); + //pObjSaveAndNotSaved = Aig_And( pNew, pObjSavePi, Aig_Not(pObjSavedLo) ); +#endif + + //******************************************************************** + // Step 8: create internal nodes + //******************************************************************** + Aig_ManForEachNode( p, pObj, i ) + { + pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + } + + //******************************************************************** + // Step 9: create the safety property output gate + // create the safety property output gate, this will be the sole true PO + // of the whole circuit, discuss with Sat/Alan for an alternative implementation + //******************************************************************** +#ifndef DUPLICATE_CKT_DEBUG + pObjSafetyPropertyOutput = Aig_ObjCreatePo( pNew, (Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData ); +#endif + + //******************************************************************** + // DEBUG: To recreate the same circuit, at least from the input and output + // behavior, we need to copy the original PO + //******************************************************************** +#ifdef DUPLICATE_CKT_DEBUG + Saig_ManForEachPo( p, pObj, i ) + { + Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) ); + } +#endif + + // create register inputs for the original registers + nRegCount = 0; + + Saig_ManForEachLo( p, pObj, i ) + { + pMatch = Saig_ObjLoToLi( p, pObj ); + //Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pMatch) ); + Aig_ObjCreatePo( pNew, Aig_NotCond((Aig_Obj_t *)Aig_ObjFanin0(pMatch)->pData, Aig_ObjFaninC0( pMatch ) ) ); + nRegCount++; + liCopied++; + } + + // create register input corresponding to the register "saved" +#ifndef DUPLICATE_CKT_DEBUG + pObjSavedLi = Aig_ObjCreatePo( pNew, pObjSaveOrSaved ); + nRegCount++; + liCreated++; + + pObjAndAcc = NULL; + + // create the family of shadow registers, then create the cascade of Xnor and And gates for the comparator + Saig_ManForEachLo( p, pObj, i ) + { + pObjShadowLo = Aig_ObjCreatePi( pNew ); + +#ifdef PROPAGATE_NAMES + Vec_PtrPush( vecLos, pObjShadowLo ); + nodeName = (char *)malloc( strlen( Abc_ObjName( Abc_NtkCi( pNtk, Abc_NtkPiNum(pNtk) + i ) ) ) + 10 ); + sprintf( nodeName, "%s__%s", Abc_ObjName( Abc_NtkCi( pNtk, Abc_NtkPiNum(pNtk) + i ) ), "SHADOW" ); + Vec_PtrPush( vecLoNames, nodeName ); +#endif + + pObjShadowLiDriver = Aig_Mux( pNew, pObjSavePi, (Aig_Obj_t *)pObj->pData, pObjShadowLo ); + pObjShadowLi = Aig_ObjCreatePo( pNew, pObjShadowLiDriver ); + nRegCount++; + loCreated++; liCreated++; + + pObjXor = Aig_Exor( pNew, (Aig_Obj_t *)pObj->pData, pObjShadowLo ); + pObjXnor = Aig_Not( pObjXor ); + if( pObjAndAcc == NULL ) + pObjAndAcc = pObjXnor; + else + { + pObjAndAccDummy = pObjAndAcc; + pObjAndAcc = Aig_And( pNew, pObjXnor, pObjAndAccDummy ); + } + } + + // create the AND gate whose output will be the signal "looped" + pObjSavedLoAndEquality = Aig_And( pNew, pObjSavedLo, pObjAndAcc ); + + // create the master AND gate and corresponding AND and OR logic for the liveness properties + pObjAndAcc = NULL; + if( vLive == NULL || Vec_PtrSize( vLive ) == 0 ) + printf("\nCircuit without any liveness property\n"); + else + { + Vec_PtrForEachEntry( Aig_Obj_t *, vLive, pObj, i ) + { + //assert( Aig_ObjIsNode( Aig_ObjChild0( pObj ) ) ); + //Aig_ObjPrint( pNew, pObj ); + liveLatch++; + pDriverImage = Aig_NotCond((Aig_Obj_t *)Aig_Regular(Aig_ObjChild0( pObj ))->pData, Aig_ObjFaninC0(pObj)); + pObjShadowLo = Aig_ObjCreatePi( pNew ); + +#ifdef PROPAGATE_NAMES + Vec_PtrPush( vecLos, pObjShadowLo ); + nodeName = (char *)malloc( strlen( Abc_ObjName( Abc_NtkPo( pNtk, getPoIndex( p, pObj ) ) ) ) + 12 ); + sprintf( nodeName, "%s__%s", Abc_ObjName( Abc_NtkPo( pNtk, getPoIndex( p, pObj ) ) ), "LIVENESS" ); + Vec_PtrPush( vecLoNames, nodeName ); +#endif + + pObjShadowLiDriver = Aig_Or( pNew, Aig_Mux(pNew, pObjSavePi, Aig_Not(Aig_ManConst1(pNew)), pObjShadowLo), + Aig_And( pNew, pDriverImage, pObjSaveOrSaved ) ); + pObjShadowLi = Aig_ObjCreatePo( pNew, pObjShadowLiDriver ); + nRegCount++; + loCreated++; liCreated++; + + if( pObjAndAcc == NULL ) + pObjAndAcc = pObjShadowLo; + else + { + pObjAndAccDummy = pObjAndAcc; + pObjAndAcc = Aig_And( pNew, pObjShadowLo, pObjAndAccDummy ); + } + } + } + + if( pObjAndAcc != NULL ) + pObjLive = pObjAndAcc; + else + pObjLive = Aig_ManConst1( pNew ); + + // create the master AND gate and corresponding AND and OR logic for the fairness properties + pObjAndAcc = NULL; + if( vFair == NULL || Vec_PtrSize( vFair ) == 0 ) + printf("\nCircuit without any fairness property\n"); + else + { + Vec_PtrForEachEntry( Aig_Obj_t *, vFair, pObj, i ) + { + fairLatch++; + //assert( Aig_ObjIsNode( Aig_ObjChild0( pObj ) ) ); + pDriverImage = Aig_NotCond((Aig_Obj_t *)Aig_Regular(Aig_ObjChild0( pObj ))->pData, Aig_ObjFaninC0(pObj)); + pObjShadowLo = Aig_ObjCreatePi( pNew ); + +#ifdef PROPAGATE_NAMES + Vec_PtrPush( vecLos, pObjShadowLo ); + nodeName = (char *)malloc( strlen( Abc_ObjName( Abc_NtkPo( pNtk, getPoIndex( p, pObj ) ) ) ) + 12 ); + sprintf( nodeName, "%s__%s", Abc_ObjName( Abc_NtkPo( pNtk, getPoIndex( p, pObj ) ) ), "FAIRNESS" ); + Vec_PtrPush( vecLoNames, nodeName ); +#endif + + pObjShadowLiDriver = Aig_Or( pNew, Aig_Mux(pNew, pObjSavePi, Aig_Not(Aig_ManConst1(pNew)), pObjShadowLo), + Aig_And( pNew, pDriverImage, pObjSaveOrSaved ) ); + pObjShadowLi = Aig_ObjCreatePo( pNew, pObjShadowLiDriver ); + nRegCount++; + loCreated++; liCreated++; + + if( pObjAndAcc == NULL ) + pObjAndAcc = pObjShadowLo; + else + { + pObjAndAccDummy = pObjAndAcc; + pObjAndAcc = Aig_And( pNew, pObjShadowLo, pObjAndAccDummy ); + } + } + } + + if( pObjAndAcc != NULL ) + pObjFair = pObjAndAcc; + else + pObjFair = Aig_ManConst1( pNew ); + + //pObjSafetyGate = Aig_Exor( pNew, Aig_Not(Aig_ManConst1( pNew )), Aig_And( pNew, pObjSavedLoAndEquality, Aig_And( pNew, pObjFair, Aig_Not( pObjLive ) ) ) ); + pObjSafetyGate = Aig_And( pNew, pObjSavedLoAndEquality, Aig_And( pNew, pObjFair, Aig_Not( pObjLive ) ) ); + + Aig_ObjPatchFanin0( pNew, pObjSafetyPropertyOutput, pObjSafetyGate ); +#endif + + Aig_ManSetRegNum( pNew, nRegCount ); + + Aig_ManPiCleanupBiere( pNew ); + Aig_ManPoCleanupBiere( pNew ); + + Aig_ManCleanup( pNew ); + assert( Aig_ManCheck( pNew ) ); + +#ifndef DUPLICATE_CKT_DEBUG + assert((Aig_Obj_t *)Vec_PtrEntry(pNew->vPos, Saig_ManPoNum(pNew)+Aig_ObjPioNum(pObjSavedLo)-Saig_ManPiNum(p)-1) == pObjSavedLi); + assert( Saig_ManPoNum( pNew ) == 1 ); + assert( Saig_ManPiNum( p ) + 1 == Saig_ManPiNum( pNew ) ); + assert( Saig_ManRegNum( pNew ) == Saig_ManRegNum( p ) * 2 + 1 + liveLatch + fairLatch ); +#endif + + return pNew; +} + + +static Aig_Man_t * LivenessToSafetyTransformationOneStepLoopSim( Abc_Ntk_t * pNtk, Aig_Man_t * p, Vec_Ptr_t *vLive, Vec_Ptr_t *vFair ) +{ + Aig_Man_t * pNew; + int i, nRegCount; + Aig_Obj_t * pObjSavePi; + Aig_Obj_t *pObj, *pMatch; + Aig_Obj_t *pObjSavedLoAndEquality; + Aig_Obj_t *pObjXor, *pObjXnor, *pObjAndAcc, *pObjAndAccDummy; + Aig_Obj_t *pObjLive, *pObjFair, *pObjSafetyGate; + Aig_Obj_t *pObjSafetyPropertyOutput; + Aig_Obj_t *pDriverImage; + Aig_Obj_t *pObjCorrespondingLi; + + + char *nodeName; + int piCopied = 0, liCopied = 0, loCopied = 0, liCreated = 0, loCreated = 0, piVecIndex = 0; + + vecPis = Vec_PtrAlloc( Saig_ManPiNum( p ) + 1); + vecPiNames = Vec_PtrAlloc( Saig_ManPiNum( p ) + 1); + + vecLos = Vec_PtrAlloc( Saig_ManRegNum( p )*2 + 1 + Vec_PtrSize( vLive ) + Vec_PtrSize( vFair ) ); + vecLoNames = Vec_PtrAlloc( Saig_ManRegNum( p )*2 + 1 + Vec_PtrSize( vLive ) + Vec_PtrSize( vFair ) ); + + //**************************************************************** + // Step1: create the new manager + // Note: The new manager is created with "2 * Aig_ManObjNumMax(p)" + // nodes, but this selection is arbitrary - need to be justified + //**************************************************************** + pNew = Aig_ManStart( 2 * Aig_ManObjNumMax(p) ); + pNew->pName = Aig_UtilStrsav( "live2safe" ); + pNew->pSpec = NULL; + + //**************************************************************** + // Step 2: map constant nodes + //**************************************************************** + pObj = Aig_ManConst1( p ); + pObj->pData = Aig_ManConst1( pNew ); + + //**************************************************************** + // Step 3: create true PIs + //**************************************************************** + Saig_ManForEachPi( p, pObj, i ) + { + piCopied++; + pObj->pData = Aig_ObjCreatePi(pNew); + Vec_PtrPush( vecPis, pObj->pData ); + nodeName = Aig_UtilStrsav(Abc_ObjName( Abc_NtkPi( pNtk, i ) )); + Vec_PtrPush( vecPiNames, nodeName ); + } + + //**************************************************************** + // Step 4: create the special Pi corresponding to SAVE + //**************************************************************** + pObjSavePi = Aig_ObjCreatePi( pNew ); + nodeName = "SAVE_BIERE", + Vec_PtrPush( vecPiNames, nodeName ); + + //**************************************************************** + // Step 5: create register outputs + //**************************************************************** + Saig_ManForEachLo( p, pObj, i ) + { + loCopied++; + pObj->pData = Aig_ObjCreatePi(pNew); + Vec_PtrPush( vecLos, pObj->pData ); + nodeName = Aig_UtilStrsav(Abc_ObjName( Abc_NtkCi( pNtk, Abc_NtkPiNum(pNtk) + i ) )); + Vec_PtrPush( vecLoNames, nodeName ); + } + + //**************************************************************** + // Step 6: create "saved" register output + //**************************************************************** + +#if 0 + loCreated++; + pObjSavedLo = Aig_ObjCreatePi( pNew ); + Vec_PtrPush( vecLos, pObjSavedLo ); + nodeName = "SAVED_LO"; + Vec_PtrPush( vecLoNames, nodeName ); +#endif + + //**************************************************************** + // Step 7: create the OR gate and the AND gate directly fed by "SAVE" Pi + //**************************************************************** +#if 0 + pObjSaveOrSaved = Aig_Or( pNew, pObjSavePi, pObjSavedLo ); + pObjSaveAndNotSaved = Aig_And( pNew, pObjSavePi, Aig_Not(pObjSavedLo) ); +#endif + + //******************************************************************** + // Step 8: create internal nodes + //******************************************************************** + Aig_ManForEachNode( p, pObj, i ) + { + pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + } + + //******************************************************************** + // Step 9: create the safety property output gate + // create the safety property output gate, this will be the sole true PO + // of the whole circuit, discuss with Sat/Alan for an alternative implementation + //******************************************************************** + + pObjSafetyPropertyOutput = Aig_ObjCreatePo( pNew, (Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData ); + + // create register inputs for the original registers + nRegCount = 0; + + Saig_ManForEachLo( p, pObj, i ) + { + pMatch = Saig_ObjLoToLi( p, pObj ); + //Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pMatch) ); + Aig_ObjCreatePo( pNew, Aig_NotCond((Aig_Obj_t *)Aig_ObjFanin0(pMatch)->pData, Aig_ObjFaninC0( pMatch ) ) ); + nRegCount++; + liCopied++; + } + +#if 0 + // create register input corresponding to the register "saved" + pObjSavedLi = Aig_ObjCreatePo( pNew, pObjSaveOrSaved ); + nRegCount++; + liCreated++; +#endif + + pObjAndAcc = NULL; + + //**************************************************************************************************** + //For detection of loop of length 1 we do not need any shadow register, we only need equality detector + //between Lo_j and Li_j and then a cascade of AND gates + //**************************************************************************************************** + + Saig_ManForEachLo( p, pObj, i ) + { + pObjCorrespondingLi = Saig_ObjLoToLi( p, pObj ); + + pObjXor = Aig_Exor( pNew, (Aig_Obj_t *)pObj->pData, Aig_NotCond( (Aig_Obj_t *)Aig_ObjFanin0( pObjCorrespondingLi )->pData, Aig_ObjFaninC0( pObjCorrespondingLi ) ) ); + pObjXnor = Aig_Not( pObjXor ); + + if( pObjAndAcc == NULL ) + pObjAndAcc = pObjXnor; + else + { + pObjAndAccDummy = pObjAndAcc; + pObjAndAcc = Aig_And( pNew, pObjXnor, pObjAndAccDummy ); + } + } + + // create the AND gate whose output will be the signal "looped" + pObjSavedLoAndEquality = Aig_And( pNew, pObjSavePi, pObjAndAcc ); + + // create the master AND gate and corresponding AND and OR logic for the liveness properties + pObjAndAcc = NULL; + if( vLive == NULL || Vec_PtrSize( vLive ) == 0 ) + printf("\nCircuit without any liveness property\n"); + else + { + Vec_PtrForEachEntry( Aig_Obj_t *, vLive, pObj, i ) + { + pDriverImage = Aig_NotCond((Aig_Obj_t *)Aig_Regular(Aig_ObjChild0( pObj ))->pData, Aig_ObjFaninC0(pObj)); + if( pObjAndAcc == NULL ) + pObjAndAcc = pDriverImage; + else + { + pObjAndAccDummy = pObjAndAcc; + pObjAndAcc = Aig_And( pNew, pDriverImage, pObjAndAccDummy ); + } + } + } + + if( pObjAndAcc != NULL ) + pObjLive = pObjAndAcc; + else + pObjLive = Aig_ManConst1( pNew ); + + // create the master AND gate and corresponding AND and OR logic for the fairness properties + pObjAndAcc = NULL; + if( vFair == NULL || Vec_PtrSize( vFair ) == 0 ) + printf("\nCircuit without any fairness property\n"); + else + { + Vec_PtrForEachEntry( Aig_Obj_t *, vFair, pObj, i ) + { + pDriverImage = Aig_NotCond((Aig_Obj_t *)Aig_Regular(Aig_ObjChild0( pObj ))->pData, Aig_ObjFaninC0(pObj)); + if( pObjAndAcc == NULL ) + pObjAndAcc = pDriverImage; + else + { + pObjAndAccDummy = pObjAndAcc; + pObjAndAcc = Aig_And( pNew, pDriverImage, pObjAndAccDummy ); + } + } + } + + if( pObjAndAcc != NULL ) + pObjFair = pObjAndAcc; + else + pObjFair = Aig_ManConst1( pNew ); + + pObjSafetyGate = Aig_And( pNew, pObjSavedLoAndEquality, Aig_And( pNew, pObjFair, Aig_Not( pObjLive ) ) ); + + Aig_ObjPatchFanin0( pNew, pObjSafetyPropertyOutput, pObjSafetyGate ); + + Aig_ManSetRegNum( pNew, nRegCount ); + + printf("\nSaig_ManPiNum = %d, Reg Num = %d, before everything, before Pi cleanup\n", Vec_PtrSize( pNew->vPis ), pNew->nRegs ); + + Aig_ManPiCleanupBiere( pNew ); + Aig_ManPoCleanupBiere( pNew ); + + Aig_ManCleanup( pNew ); + + assert( Aig_ManCheck( pNew ) ); + + return pNew; +} + + + +static Vec_Ptr_t * populateLivenessVector( Abc_Ntk_t *pNtk, Aig_Man_t *pAig ) +{ + Abc_Obj_t * pNode; + int i, liveCounter = 0; + Vec_Ptr_t * vLive; + + vLive = Vec_PtrAlloc( 100 ); + Abc_NtkForEachPo( pNtk, pNode, i ) + if( strstr( Abc_ObjName( pNode ), "assert_fair") != NULL ) + { + Vec_PtrPush( vLive, Aig_ManPo( pAig, i ) ); + liveCounter++; + } + printf("\nNumber of liveness property found = %d\n", liveCounter); + return vLive; +} + +static Vec_Ptr_t * populateFairnessVector( Abc_Ntk_t *pNtk, Aig_Man_t *pAig ) +{ + Abc_Obj_t * pNode; + int i, fairCounter = 0; + Vec_Ptr_t * vFair; + + vFair = Vec_PtrAlloc( 100 ); + Abc_NtkForEachPo( pNtk, pNode, i ) + if( strstr( Abc_ObjName( pNode ), "assume_fair") != NULL ) + { + Vec_PtrPush( vFair, Aig_ManPo( pAig, i ) ); + fairCounter++; + } + printf("\nNumber of fairness property found = %d\n", fairCounter); + return vFair; +} + +static void updateNewNetworkNameManager( Abc_Ntk_t *pNtk, Aig_Man_t *pAig, Vec_Ptr_t *vPiNames, Vec_Ptr_t *vLoNames ) +{ + Aig_Obj_t *pObj; + int i, ntkObjId; + + pNtk->pManName = Nm_ManCreate( Abc_NtkCiNum( pNtk ) ); + + Saig_ManForEachPi( pAig, pObj, i ) + { + ntkObjId = Abc_NtkCi( pNtk, i )->Id; + //printf("Pi %d, Saved Name = %s, id = %d\n", i, Nm_ManStoreIdName( pNtk->pManName, ntkObjId, Aig_ObjType(pObj), Vec_PtrEntry(vPiNames, i), NULL ), ntkObjId); + Nm_ManStoreIdName( pNtk->pManName, ntkObjId, Aig_ObjType(pObj), (char *)Vec_PtrEntry(vPiNames, i), NULL ); + } + Saig_ManForEachLo( pAig, pObj, i ) + { + ntkObjId = Abc_NtkCi( pNtk, Saig_ManPiNum( pAig ) + i )->Id; + //printf("Lo %d, Saved name = %s, id = %d\n", i, Nm_ManStoreIdName( pNtk->pManName, ntkObjId, Aig_ObjType(pObj), Vec_PtrEntry(vLoNames, i), NULL ), ntkObjId); + Nm_ManStoreIdName( pNtk->pManName, ntkObjId, Aig_ObjType(pObj), (char *)Vec_PtrEntry(vLoNames, i), NULL ); + } +} + + +int Abc_CommandAbcLivenessToSafetySim( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk, * pNtkTemp, *pNtkNew, *pNtkOld; + Aig_Man_t * pAig, *pAigNew; + int c; + Vec_Ptr_t * vLive, * vFair; + + pNtk = Abc_FrameReadNtk(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + + if( !Abc_NtkIsStrash( pNtk ) ) + { + printf("\nThe input network was not strashed, strashing....\n"); + pNtkTemp = Abc_NtkStrash( pNtk, 0, 0, 0 ); + pNtkOld = pNtkTemp; + pAig = Abc_NtkToDar( pNtkTemp, 0, 1 ); + vLive = populateLivenessVector( pNtk, pAig ); + vFair = populateFairnessVector( pNtk, pAig ); + } + else + { + pAig = Abc_NtkToDar( pNtk, 0, 1 ); + pNtkOld = pNtk; + vLive = populateLivenessVector( pNtk, pAig ); + vFair = populateFairnessVector( pNtk, pAig ); + } + +#if 0 + Aig_ManPrintStats( pAig ); + printf("\nDetail statistics*************************************\n"); + printf("Number of true primary inputs = %d\n", Saig_ManPiNum( pAig )); + printf("Number of true primary outputs = %d\n", Saig_ManPoNum( pAig )); + printf("Number of true latch outputs = %d\n", Saig_ManCiNum( pAig ) - Saig_ManPiNum( pAig )); + printf("Number of true latch inputs = %d\n", Saig_ManCoNum( pAig ) - Saig_ManPoNum( pAig )); + printf("Numer of registers = %d\n", Saig_ManRegNum( pAig ) ); + printf("\n*******************************************************\n"); +#endif + + c = Extra_UtilGetopt( argc, argv, "1" ); + if( c == '1' ) + pAigNew = LivenessToSafetyTransformationOneStepLoopSim( pNtk, pAig, vLive, vFair ); + else + pAigNew = LivenessToSafetyTransformationSim( pNtk, pAig, vLive, vFair ); + +#if 0 + Aig_ManPrintStats( pAigNew ); + printf("\nDetail statistics*************************************\n"); + printf("Number of true primary inputs = %d\n", Saig_ManPiNum( pAigNew )); + printf("Number of true primary outputs = %d\n", Saig_ManPoNum( pAigNew )); + printf("Number of true latch outputs = %d\n", Saig_ManCiNum( pAigNew ) - Saig_ManPiNum( pAigNew )); + printf("Number of true latch inputs = %d\n", Saig_ManCoNum( pAigNew ) - Saig_ManPoNum( pAigNew )); + printf("Numer of registers = %d\n", Saig_ManRegNum( pAigNew ) ); + printf("\n*******************************************************\n"); +#endif + + pNtkNew = Abc_NtkFromAigPhase( pAigNew ); + + if ( !Abc_NtkCheck( pNtkNew ) ) + fprintf( stdout, "Abc_NtkCreateCone(): Network check has failed.\n" ); + + updateNewNetworkNameManager( pNtkNew, pAigNew, vecPiNames,vecLoNames ); + Abc_FrameSetCurrentNetwork( pAbc, pNtkNew ); + + //Saig_ManForEachPi( pAigNew, pObj, i ) + // printf("Name of %d-th Pi = %s\n", i, retrieveTruePiName( pNtk, pAig, pAigNew, pObj ) ); + + //Saig_ManForEachLo( pAigNew, pObj, i ) + // printf("Name of %d-th Lo = %s\n", i, retrieveLOName( pNtk, pAig, pAigNew, pObj, vLive, vFair ) ); + + //printVecPtrOfString( vecPiNames ); + //printVecPtrOfString( vecLoNames ); + +#if 0 +#ifndef DUPLICATE_CKT_DEBUG + Saig_ManForEachPi( pAigNew, pObj, i ) + assert( strcmp( (char *)Vec_PtrEntry(vecPiNames, i), retrieveTruePiName( pNtk, pAig, pAigNew, pObj ) ) == 0 ); + //printf("Name of %d-th Pi = %s, %s\n", i, retrieveTruePiName( pNtk, pAig, pAigNew, pObj ), (char *)Vec_PtrEntry(vecPiNames, i) ); + + Saig_ManForEachLo( pAigNew, pObj, i ) + assert( strcmp( (char *)Vec_PtrEntry(vecLoNames, i), retrieveLOName( pNtk, pAig, pAigNew, pObj, vLive, vFair ) ) == 0 ); +#endif +#endif + + return 0; + +} +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/live/ltl_parser.c b/src/aig/live/ltl_parser.c new file mode 100644 index 00000000..66d7f72d --- /dev/null +++ b/src/aig/live/ltl_parser.c @@ -0,0 +1,838 @@ +/**CFile**************************************************************** + + FileName [ltl_parser.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Liveness property checking.] + + Synopsis [LTL checker.] + + Author [Sayak Ray] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - January 1, 2009.] + + Revision [$Id: ltl_parser.c,v 1.00 2009/01/01 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include <stdio.h> +#include <string.h> +#include <assert.h> +#include <stdlib.h> +#include <aig.h> +#include <abc.h> +#include <mainInt.h> + +ABC_NAMESPACE_IMPL_START + + +enum ltlToken { AND, OR, NOT, IMPLY, GLOBALLY, EVENTUALLY, NEXT, UNTIL, BOOL }; +enum ltlGrammerToken { OPERAND, LTL, BINOP, UOP }; +typedef enum ltlToken tokenType; +typedef enum ltlGrammerToken ltlGrammerTokenType; + +struct ltlNode_t +{ + tokenType type; + char *name; + Aig_Obj_t *pObj; + struct ltlNode_t *left; + struct ltlNode_t *right; +}; + +typedef struct ltlNode_t ltlNode; + +ltlNode *generateTypedNode( tokenType new_type ) +//void generateTypedNode( ltlNode *new_node, tokenType new_type ) +{ + ltlNode *new_node; + + new_node = (ltlNode *)malloc( sizeof(ltlNode) ); + if( new_node ) + { + new_node->type = new_type; + new_node->pObj = NULL; + new_node->name = NULL; + new_node->left = NULL; + new_node->right = NULL; + } + + return new_node; +} + +Aig_Obj_t *buildLogicFromLTLNode_combinationalOnly( Aig_Man_t *pAig, ltlNode *pLtlNode ); + +static inline int isNotVarNameSymbol( char c ) +{ + return ( c == ' ' || c == '\t' || c == '\n' || c == ':' || c == '\0' ); +} + +void Abc_FrameCopyLTLDataBase( Abc_Frame_t *pAbc, Abc_Ntk_t * pNtk ) +{ + char *pLtlFormula, *tempFormula; + int i; + + if( pAbc->vLTLProperties_global != NULL ) + { +// printf("Deleting exisitng LTL database from the frame\n"); + pAbc->vLTLProperties_global = NULL; + } + pAbc->vLTLProperties_global = Vec_PtrAlloc(Vec_PtrSize(pNtk->vLtlProperties)); + Vec_PtrForEachEntry( char *, pNtk->vLtlProperties, pLtlFormula, i ) + { + tempFormula = (char *)malloc( sizeof(char)*(strlen(pLtlFormula)+1) ); + sprintf( tempFormula, "%s", pLtlFormula ); + Vec_PtrPush( pAbc->vLTLProperties_global, tempFormula ); + } +} + +char *getVarName( char *suffixFormula, int startLoc, int *endLocation ) +{ + int i = startLoc, length; + char *name; + + if( isNotVarNameSymbol( suffixFormula[startLoc] ) ) + return NULL; + + while( !isNotVarNameSymbol( suffixFormula[i] ) ) + i++; + *endLocation = i; + length = i - startLoc; + name = (char *)malloc( sizeof(char) * (length + 1)); + for( i=0; i<length; i++ ) + name[i] = suffixFormula[i+startLoc]; + name[i] = '\0'; + + return name; +} + + +int startOfSuffixString = 0; + +int isUnexpectedEOS( char *formula, int index ) +{ + assert( formula ); + if( index >= (int)strlen( formula ) ) + { + printf("\nInvalid LTL formula: unexpected end of string..." ); + return 1; + } + return 0; +} + +int isTemporalOperator( char *formula, int index ) +{ + if( !(isUnexpectedEOS( formula, index ) || formula[ index ] == 'G' || formula[ index ] == 'F' || formula[ index ] == 'U' || formula[ index ] == 'X') ) + { + printf("\nInvalid LTL formula: expecting temporal operator at the position %d....\n", index); + return 0; + } + return 1; +} + +ltlNode *readLtlFormula( char *formula ) +{ + char ch; + char *varName; + int formulaLength, rememberEnd; + int i = startOfSuffixString; + ltlNode *curr_node, *temp_node_left, *temp_node_right; + char prevChar; + + formulaLength = strlen( formula ); + if( isUnexpectedEOS( formula, startOfSuffixString ) ) + { + printf("\nFAULTING POINT: formula = %s\nstartOfSuffixString = %d, formula[%d] = %c\n\n", formula, startOfSuffixString, startOfSuffixString - 1, formula[startOfSuffixString-1]); + return NULL; + } + + while( i < formulaLength ) + { + ch = formula[i]; + + switch(ch){ + case ' ': + case '\n': + case '\r': + case '\t': + case '\v': + case '\f': + i++; + startOfSuffixString = i; + break; + case ':': + i++; + if( !isTemporalOperator( formula, i ) ) + return NULL; + startOfSuffixString = i; + break; + case 'G': + prevChar = formula[i-1]; + if( prevChar == ':' ) //i.e. 'G' is a temporal operator + { + i++; + startOfSuffixString = i; + temp_node_left = readLtlFormula( formula ); + if( temp_node_left == NULL ) + return NULL; + else + { + curr_node = generateTypedNode(GLOBALLY); + curr_node->left = temp_node_left; + return curr_node; + } + } + else //i.e. 'G' must be starting a variable name + { + varName = getVarName( formula, i, &rememberEnd ); + if( !varName ) + { + printf("\nInvalid LTL formula: expecting valid variable name token...aborting" ); + return NULL; + } + curr_node = generateTypedNode(BOOL); + curr_node->name = varName; + i = rememberEnd; + startOfSuffixString = i; + return curr_node; + } + case 'F': + prevChar = formula[i-1]; + if( prevChar == ':' ) //i.e. 'F' is a temporal operator + { + i++; + startOfSuffixString = i; + temp_node_left = readLtlFormula( formula ); + if( temp_node_left == NULL ) + return NULL; + else + { + curr_node = generateTypedNode(EVENTUALLY); + curr_node->left = temp_node_left; + return curr_node; + } + } + else //i.e. 'F' must be starting a variable name + { + varName = getVarName( formula, i, &rememberEnd ); + if( !varName ) + { + printf("\nInvalid LTL formula: expecting valid variable name token...aborting" ); + return NULL; + } + curr_node = generateTypedNode(BOOL); + curr_node->name = varName; + i = rememberEnd; + startOfSuffixString = i; + return curr_node; + } + case 'X': + prevChar = formula[i-1]; + if( prevChar == ':' ) //i.e. 'X' is a temporal operator + { + i++; + startOfSuffixString = i; + temp_node_left = readLtlFormula( formula ); + if( temp_node_left == NULL ) + return NULL; + else + { + curr_node = generateTypedNode(NEXT); + curr_node->left = temp_node_left; + return curr_node; + } + } + else //i.e. 'X' must be starting a variable name + { + varName = getVarName( formula, i, &rememberEnd ); + if( !varName ) + { + printf("\nInvalid LTL formula: expecting valid variable name token...aborting" ); + return NULL; + } + curr_node = generateTypedNode(BOOL); + curr_node->name = varName; + i = rememberEnd; + startOfSuffixString = i; + return curr_node; + } + case 'U': + prevChar = formula[i-1]; + if( prevChar == ':' ) //i.e. 'X' is a temporal operator + { + i++; + startOfSuffixString = i; + temp_node_left = readLtlFormula( formula ); + if( temp_node_left == NULL ) + return NULL; + temp_node_right = readLtlFormula( formula ); + if( temp_node_right == NULL ) + { + //need to do memory management: if right subtree is NULL then left + //subtree must be freed. + return NULL; + } + curr_node = generateTypedNode(UNTIL); + curr_node->left = temp_node_left; + curr_node->right = temp_node_right; + return curr_node; + } + else //i.e. 'U' must be starting a variable name + { + varName = getVarName( formula, i, &rememberEnd ); + if( !varName ) + { + printf("\nInvalid LTL formula: expecting valid variable name token...aborting" ); + return NULL; + } + curr_node = generateTypedNode(BOOL); + curr_node->name = varName; + i = rememberEnd; + startOfSuffixString = i; + return curr_node; + } + case '+': + i++; + startOfSuffixString = i; + temp_node_left = readLtlFormula( formula ); + if( temp_node_left == NULL ) + return NULL; + temp_node_right = readLtlFormula( formula ); + if( temp_node_right == NULL ) + { + //need to do memory management: if right subtree is NULL then left + //subtree must be freed. + return NULL; + } + curr_node = generateTypedNode(OR); + curr_node->left = temp_node_left; + curr_node->right = temp_node_right; + return curr_node; + case '&': + i++; + startOfSuffixString = i; + temp_node_left = readLtlFormula( formula ); + if( temp_node_left == NULL ) + return NULL; + temp_node_right = readLtlFormula( formula ); + if( temp_node_right == NULL ) + { + //need to do memory management: if right subtree is NULL then left + //subtree must be freed. + return NULL; + } + curr_node = generateTypedNode(AND); + curr_node->left = temp_node_left; + curr_node->right = temp_node_right; + return curr_node; + case '!': + i++; + startOfSuffixString = i; + temp_node_left = readLtlFormula( formula ); + if( temp_node_left == NULL ) + return NULL; + else + { + curr_node = generateTypedNode(NOT); + curr_node->left = temp_node_left; + return curr_node; + } + default: + varName = getVarName( formula, i, &rememberEnd ); + if( !varName ) + { + printf("\nInvalid LTL formula: expecting valid variable name token...aborting" ); + return NULL; + } + curr_node = generateTypedNode(BOOL); + curr_node->name = varName; + i = rememberEnd; + startOfSuffixString = i; + return curr_node; + } + } + return NULL; +} + +void resetGlobalVar() +{ + startOfSuffixString = 0; +} + +ltlNode *parseFormulaCreateAST( char *inputFormula ) +{ + ltlNode *temp; + + temp = readLtlFormula( inputFormula ); + //if( temp == NULL ) + // printf("\nAST creation failed for formula %s", inputFormula ); + resetGlobalVar(); + return temp; +} + +void traverseAbstractSyntaxTree( ltlNode *node ) +{ + switch(node->type){ + case( AND ): + printf("& "); + assert( node->left != NULL ); + assert( node->right != NULL ); + traverseAbstractSyntaxTree( node->left ); + traverseAbstractSyntaxTree( node->right ); + return; + case( OR ): + printf("+ "); + assert( node->left != NULL ); + assert( node->right != NULL ); + traverseAbstractSyntaxTree( node->left ); + traverseAbstractSyntaxTree( node->right ); + return; + case( NOT ): + printf("~ "); + assert( node->left != NULL ); + traverseAbstractSyntaxTree( node->left ); + assert( node->right == NULL ); + return; + case( GLOBALLY ): + printf("G "); + assert( node->left != NULL ); + traverseAbstractSyntaxTree( node->left ); + assert( node->right == NULL ); + return; + case( EVENTUALLY ): + printf("F "); + assert( node->left != NULL ); + traverseAbstractSyntaxTree( node->left ); + assert( node->right == NULL ); + return; + case( NEXT ): + printf("X "); + assert( node->left != NULL ); + traverseAbstractSyntaxTree( node->left ); + assert( node->right == NULL ); + return; + case( UNTIL ): + printf("U "); + assert( node->left != NULL ); + assert( node->right != NULL ); + traverseAbstractSyntaxTree( node->left ); + traverseAbstractSyntaxTree( node->right ); + return; + case( BOOL ): + printf("%s ", node->name); + assert( node->left == NULL ); + assert( node->right == NULL ); + return; + default: + printf("\nUnsupported token type: Exiting execution\n"); + exit(0); + } +} + +void traverseAbstractSyntaxTree_postFix( ltlNode *node ) +{ + switch(node->type){ + case( AND ): + printf("( "); + assert( node->left != NULL ); + assert( node->right != NULL ); + traverseAbstractSyntaxTree_postFix( node->left ); + printf("& "); + traverseAbstractSyntaxTree_postFix( node->right ); + printf(") "); + return; + case( OR ): + printf("( "); + assert( node->left != NULL ); + assert( node->right != NULL ); + traverseAbstractSyntaxTree_postFix( node->left ); + printf("+ "); + traverseAbstractSyntaxTree_postFix( node->right ); + printf(") "); + return; + case( NOT ): + printf("~ "); + assert( node->left != NULL ); + traverseAbstractSyntaxTree_postFix( node->left ); + assert( node->right == NULL ); + return; + case( GLOBALLY ): + printf("G "); + //printf("( "); + assert( node->left != NULL ); + traverseAbstractSyntaxTree_postFix( node->left ); + assert( node->right == NULL ); + //printf(") "); + return; + case( EVENTUALLY ): + printf("F "); + //printf("( "); + assert( node->left != NULL ); + traverseAbstractSyntaxTree_postFix( node->left ); + assert( node->right == NULL ); + //printf(") "); + return; + case( NEXT ): + printf("X "); + assert( node->left != NULL ); + traverseAbstractSyntaxTree_postFix( node->left ); + assert( node->right == NULL ); + return; + case( UNTIL ): + printf("( "); + assert( node->left != NULL ); + assert( node->right != NULL ); + traverseAbstractSyntaxTree_postFix( node->left ); + printf("U "); + traverseAbstractSyntaxTree_postFix( node->right ); + printf(") "); + return; + case( BOOL ): + printf("%s ", node->name); + assert( node->left == NULL ); + assert( node->right == NULL ); + return; + default: + printf("\nUnsupported token type: Exiting execution\n"); + exit(0); + } +} + +void populateAigPointerUnitGF( Aig_Man_t *pAigNew, ltlNode *topASTNode, Vec_Ptr_t *vSignal, Vec_Vec_t *vAigGFMap ) +{ + ltlNode *nextNode, *nextToNextNode; + int serialNumSignal; + + switch( topASTNode->type ){ + case AND: + case OR: + case IMPLY: + populateAigPointerUnitGF( pAigNew, topASTNode->left, vSignal, vAigGFMap ); + populateAigPointerUnitGF( pAigNew, topASTNode->right, vSignal, vAigGFMap ); + return; + case NOT: + populateAigPointerUnitGF( pAigNew, topASTNode->left, vSignal, vAigGFMap ); + return; + case GLOBALLY: + nextNode = topASTNode->left; + assert( nextNode->type = EVENTUALLY ); + nextToNextNode = nextNode->left; + if( nextToNextNode->type == BOOL ) + { + assert( nextToNextNode->pObj ); + serialNumSignal = Vec_PtrFind( vSignal, nextToNextNode->pObj ); + if( serialNumSignal == -1 ) + { + Vec_PtrPush( vSignal, nextToNextNode->pObj ); + serialNumSignal = Vec_PtrFind( vSignal, nextToNextNode->pObj ); + } + //Vec_PtrPush( vGLOBALLY, topASTNode ); + Vec_VecPush( vAigGFMap, serialNumSignal, topASTNode ); + } + else + { + assert( nextToNextNode->pObj == NULL ); + buildLogicFromLTLNode_combinationalOnly( pAigNew, nextToNextNode ); + serialNumSignal = Vec_PtrFind( vSignal, nextToNextNode->pObj ); + if( serialNumSignal == -1 ) + { + Vec_PtrPush( vSignal, nextToNextNode->pObj ); + serialNumSignal = Vec_PtrFind( vSignal, nextToNextNode->pObj ); + } + //Vec_PtrPush( vGLOBALLY, topASTNode ); + Vec_VecPush( vAigGFMap, serialNumSignal, topASTNode ); + } + return; + case BOOL: + return; + default: + printf("\nINVALID situation: aborting...\n"); + exit(0); + } +} + +Aig_Obj_t *buildLogicFromLTLNode_combinationalOnly( Aig_Man_t *pAigNew, ltlNode *pLtlNode ) +{ + Aig_Obj_t *leftAigObj, *rightAigObj; + + if( pLtlNode->pObj != NULL ) + return pLtlNode->pObj; + else + { + assert( pLtlNode->type != BOOL ); + switch( pLtlNode->type ){ + case AND: + assert( pLtlNode->left ); assert( pLtlNode->right ); + leftAigObj = buildLogicFromLTLNode_combinationalOnly( pAigNew, pLtlNode->left ); + rightAigObj = buildLogicFromLTLNode_combinationalOnly( pAigNew, pLtlNode->right ); + assert( leftAigObj ); assert( rightAigObj ); + pLtlNode->pObj = Aig_And( pAigNew, leftAigObj, rightAigObj ); + return pLtlNode->pObj; + case OR: + assert( pLtlNode->left ); assert( pLtlNode->right ); + leftAigObj = buildLogicFromLTLNode_combinationalOnly( pAigNew, pLtlNode->left ); + rightAigObj = buildLogicFromLTLNode_combinationalOnly( pAigNew, pLtlNode->right ); + assert( leftAigObj ); assert( rightAigObj ); + pLtlNode->pObj = Aig_Or( pAigNew, leftAigObj, rightAigObj ); + return pLtlNode->pObj; + case NOT: + assert( pLtlNode->left ); assert( pLtlNode->right == NULL ); + leftAigObj = buildLogicFromLTLNode_combinationalOnly( pAigNew, pLtlNode->left ); + assert( leftAigObj ); + pLtlNode->pObj = Aig_Not( leftAigObj ); + return pLtlNode->pObj; + case GLOBALLY: + case EVENTUALLY: + case NEXT: + case UNTIL: + printf("FORBIDDEN node: ABORTING!!\n"); + exit(0); + default: + printf("\nSerious ERROR: attempting to create AIG node from a temporal node\n"); + exit(0); + } + } +} + +Aig_Obj_t *buildLogicFromLTLNode( Aig_Man_t *pAig, ltlNode *pLtlNode ) +{ + Aig_Obj_t *leftAigObj, *rightAigObj; + + if( pLtlNode->pObj != NULL ) + return pLtlNode->pObj; + else + { + assert( pLtlNode->type != BOOL ); + switch( pLtlNode->type ){ + case AND: + assert( pLtlNode->left ); assert( pLtlNode->right ); + leftAigObj = buildLogicFromLTLNode( pAig, pLtlNode->left ); + rightAigObj = buildLogicFromLTLNode( pAig, pLtlNode->right ); + assert( leftAigObj ); assert( rightAigObj ); + pLtlNode->pObj = Aig_And( pAig, leftAigObj, rightAigObj ); + return pLtlNode->pObj; + case OR: + assert( pLtlNode->left ); assert( pLtlNode->right ); + leftAigObj = buildLogicFromLTLNode( pAig, pLtlNode->left ); + rightAigObj = buildLogicFromLTLNode( pAig, pLtlNode->right ); + assert( leftAigObj ); assert( rightAigObj ); + pLtlNode->pObj = Aig_Or( pAig, leftAigObj, rightAigObj ); + return pLtlNode->pObj; + case NOT: + assert( pLtlNode->left ); assert( pLtlNode->right == NULL ); + leftAigObj = buildLogicFromLTLNode( pAig, pLtlNode->left ); + assert( leftAigObj ); + pLtlNode->pObj = Aig_Not( leftAigObj ); + return pLtlNode->pObj; + case GLOBALLY: + case EVENTUALLY: + case NEXT: + case UNTIL: + printf("\nAttempting to create circuit with missing AIG pointer in a TEMPORAL node: ABORTING!!\n"); + exit(0); + default: + printf("\nSerious ERROR: attempting to create AIG node from a temporal node\n"); + exit(0); + } + } +} + +int isNonTemporalSubformula( ltlNode *topNode ) +{ + switch( topNode->type ){ + case AND: + case OR: + case IMPLY: + return isNonTemporalSubformula( topNode->left) && isNonTemporalSubformula( topNode->right ) ; + case NOT: + assert( topNode->right == NULL ); + return isNonTemporalSubformula( topNode->left ); + case BOOL: + return 1; + default: + return 0; + } +} + +int isWellFormed( ltlNode *topNode ) +{ + ltlNode *nextNode; + + switch( topNode->type ){ + case AND: + case OR: + case IMPLY: + return isWellFormed( topNode->left) && isWellFormed( topNode->right ) ; + case NOT: + assert( topNode->right == NULL ); + return isWellFormed( topNode->left ); + case BOOL: + return 1; + case GLOBALLY: + nextNode = topNode->left; + assert( topNode->right == NULL ); + if( nextNode->type != EVENTUALLY ) + return 0; + else + { + assert( nextNode->right == NULL ); + return isNonTemporalSubformula( nextNode->left ); + } + default: + return 0; + } +} + +int checkBooleanConstant( char *targetName ) +{ + if( strcmp( targetName, "true" ) == 0 ) + return 1; + if( strcmp( targetName, "false" ) == 0 ) + return 0; + return -1; +} + +int checkSignalNameExistence( Abc_Ntk_t *pNtk, ltlNode *topASTNode ) +{ + char *targetName; + Abc_Obj_t * pNode; + int i; + + switch( topASTNode->type ){ + case BOOL: + targetName = topASTNode->name; + //printf("\nTrying to match name %s\n", targetName); + if( checkBooleanConstant( targetName ) != -1 ) + return 1; + Abc_NtkForEachPo( pNtk, pNode, i ) + { + if( strcmp( Abc_ObjName( pNode ), targetName ) == 0 ) + { + //printf("\nVariable name \"%s\" MATCHED\n", targetName); + return 1; + } + } + printf("\nVariable name \"%s\" not found in the PO name list\n", targetName); + return 0; + case AND: + case OR: + case IMPLY: + case UNTIL: + assert( topASTNode->left != NULL ); + assert( topASTNode->right != NULL ); + return checkSignalNameExistence( pNtk, topASTNode->left ) && checkSignalNameExistence( pNtk, topASTNode->right ); + + case NOT: + case NEXT: + case GLOBALLY: + case EVENTUALLY: + assert( topASTNode->left != NULL ); + assert( topASTNode->right == NULL ); + return checkSignalNameExistence( pNtk, topASTNode->left ); + default: + printf("\nUNSUPPORTED LTL NODE TYPE:: Aborting execution\n"); + exit(0); + } +} + +void populateBoolWithAigNodePtr( Abc_Ntk_t *pNtk, Aig_Man_t *pAigOld, Aig_Man_t *pAigNew, ltlNode *topASTNode ) +{ + char *targetName; + Abc_Obj_t * pNode; + int i; + Aig_Obj_t *pObj, *pDriverImage; + + switch( topASTNode->type ){ + case BOOL: + targetName = topASTNode->name; + if( checkBooleanConstant( targetName ) == 1 ) + { + topASTNode->pObj = Aig_ManConst1( pAigNew ); + return; + } + if( checkBooleanConstant( targetName ) == 0 ) + { + topASTNode->pObj = Aig_Not(topASTNode->pObj = Aig_ManConst1( pAigNew )); + return; + } + Abc_NtkForEachPo( pNtk, pNode, i ) + if( strcmp( Abc_ObjName( pNode ), targetName ) == 0 ) + { + pObj = Aig_ManPo( pAigOld, i ); + assert( Aig_ObjIsPo( pObj )); + pDriverImage = Aig_NotCond((Aig_Obj_t *)Aig_Regular(Aig_ObjChild0( pObj ))->pData, Aig_ObjFaninC0(pObj)); + topASTNode->pObj = pDriverImage; + return; + } + assert(0); + case AND: + case OR: + case IMPLY: + case UNTIL: + assert( topASTNode->left != NULL ); + assert( topASTNode->right != NULL ); + populateBoolWithAigNodePtr( pNtk, pAigOld, pAigNew, topASTNode->left ); + populateBoolWithAigNodePtr( pNtk, pAigOld, pAigNew, topASTNode->right ); + return; + case NOT: + case NEXT: + case GLOBALLY: + case EVENTUALLY: + assert( topASTNode->left != NULL ); + assert( topASTNode->right == NULL ); + populateBoolWithAigNodePtr( pNtk, pAigOld, pAigNew, topASTNode->left ); + return; + default: + printf("\nUNSUPPORTED LTL NODE TYPE:: Aborting execution\n"); + exit(0); + } +} + +int checkAllBoolHaveAIGPointer( ltlNode *topASTNode ) +{ + + switch( topASTNode->type ){ + case BOOL: + if( topASTNode->pObj != NULL ) + return 1; + else + { + printf("\nfaulting PODMANDYO topASTNode->name = %s\n", topASTNode->name); + return 0; + } + case AND: + case OR: + case IMPLY: + case UNTIL: + assert( topASTNode->left != NULL ); + assert( topASTNode->right != NULL ); + return checkAllBoolHaveAIGPointer( topASTNode->left ) && checkAllBoolHaveAIGPointer( topASTNode->right ); + + case NOT: + case NEXT: + case GLOBALLY: + case EVENTUALLY: + assert( topASTNode->left != NULL ); + assert( topASTNode->right == NULL ); + return checkAllBoolHaveAIGPointer( topASTNode->left ); + default: + printf("\nUNSUPPORTED LTL NODE TYPE:: Aborting execution\n"); + exit(0); + } +} + +void setAIGNodePtrOfGloballyNode( ltlNode *astNode, Aig_Obj_t *pObjLo ) +{ + astNode->pObj = pObjLo; +} + +Aig_Obj_t *retriveAIGPointerFromLTLNode( ltlNode *astNode ) +{ + return astNode->pObj; +} + + +ABC_NAMESPACE_IMPL_END diff --git a/src/aig/live/module.make b/src/aig/live/module.make new file mode 100644 index 00000000..46a9ed3c --- /dev/null +++ b/src/aig/live/module.make @@ -0,0 +1,3 @@ +SRC += src/aig/live/liveness.c \ + src/aig/live/liveness_sim.c \ + src/aig/live/ltl_parser.c diff --git a/src/aig/nwk2/nwk_.c b/src/aig/llb/llb.c index 81cffbbf..348c0622 100644 --- a/src/aig/nwk2/nwk_.c +++ b/src/aig/llb/llb.c @@ -1,10 +1,10 @@ /**CFile**************************************************************** - FileName [nwk_.c] + FileName [llb.c] SystemName [ABC: Logic synthesis and verification system.] - PackageName [Netlist representation.] + PackageName [BDD based reachability.] Synopsis [] @@ -14,11 +14,14 @@ Date [Ver. 1.0. Started - June 20, 2005.] - Revision [$Id: nwk_.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + Revision [$Id: llb.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] ***********************************************************************/ -#include "nwk.h" +#include "llbInt.h" + +ABC_NAMESPACE_IMPL_START + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// @@ -45,3 +48,5 @@ //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/llb/llb.h b/src/aig/llb/llb.h new file mode 100644 index 00000000..2c8d1c19 --- /dev/null +++ b/src/aig/llb/llb.h @@ -0,0 +1,92 @@ +/**CFile**************************************************************** + + FileName [llb.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [BDD-based reachability.] + + Synopsis [External declarations.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 8, 2010.] + + Revision [$Id: llb.h,v 1.00 2010/05/08 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#ifndef __LLB_H__ +#define __LLB_H__ + + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// PARAMETERS /// +//////////////////////////////////////////////////////////////////////// + + + +ABC_NAMESPACE_HEADER_START + + +//////////////////////////////////////////////////////////////////////// +/// BASIC TYPES /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Gia_ParLlb_t_ Gia_ParLlb_t; +struct Gia_ParLlb_t_ +{ + int nBddMax; // maximum BDD size + int nIterMax; // maximum iteration count + int nClusterMax; // maximum cluster size + int nHintDepth; // the number of times to cofactor + int HintFirst; // the number of first hint to use + int fUseFlow; // use flow computation + int nVolumeMax; // the largest volume + int nVolumeMin; // the smallest volume + int fReorder; // enable dynamic variable reordering + int fIndConstr; // extract inductive constraints + int fUsePivots; // use internal pivot variables + int fCluster; // use partition clustering + int fSchedule; // use cluster scheduling + int fVerbose; // print verbose information + int fVeryVerbose; // print dependency matrices + int fSilent; // do not print any infomation + int fSkipReach; // skip reachability (preparation phase only) + int fSkipOutCheck; // does not check the property output + int TimeLimit; // time limit for one reachability run + int TimeLimitGlo; // time limit for all reachability runs + // internal parameters + int TimeTarget; // the time to stop + int iFrame; // explored up to this frame +}; + +//////////////////////////////////////////////////////////////////////// +/// MACRO DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +/*=== llbCore.c ==========================================================*/ +extern void Llb_ManSetDefaultParams( Gia_ParLlb_t * pPars ); + + + +ABC_NAMESPACE_HEADER_END + + + +#endif + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + diff --git a/src/aig/llb/llbCex.c b/src/aig/llb/llbCex.c new file mode 100644 index 00000000..87059c0c --- /dev/null +++ b/src/aig/llb/llbCex.c @@ -0,0 +1,56 @@ +/**CFile**************************************************************** + + FileName [llbCex.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [BDD based reachability.] + + Synopsis [Deriving counter-example.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: llbCex.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "llbInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Cex_t * Llb_ManDeriveCex( Llb_Man_t * p, DdNode * bInter, int iOutFail, int iIter ) +{ + return NULL; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/llb/llbCluster.c b/src/aig/llb/llbCluster.c new file mode 100644 index 00000000..1d0153ce --- /dev/null +++ b/src/aig/llb/llbCluster.c @@ -0,0 +1,357 @@ +/**CFile**************************************************************** + + FileName [llbCluster.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [BDD based reachability.] + + Synopsis [Clustering algorithm.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: llbCluster.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "llbInt.h" +#include "extra.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Llb_ManComputeCommonQuant( Llb_Mtr_t * p, int iCol1, int iCol2 ) +{ + int iVar, Weight = 0; + for ( iVar = 0; iVar < p->nRows - p->nFfs; iVar++ ) + { + // count each removed variable as 2 + if ( p->pMatrix[iCol1][iVar] == 1 && p->pMatrix[iCol2][iVar] == 1 && p->pRowSums[iVar] == 2 ) + Weight += 2; + // count each added variale as -1 + else if ( (p->pMatrix[iCol1][iVar] == 1 && p->pMatrix[iCol2][iVar] == 0) || + (p->pMatrix[iCol1][iVar] == 0 && p->pMatrix[iCol2][iVar] == 1) ) + Weight--; + } + return Weight; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Llb_ManComputeBestQuant( Llb_Mtr_t * p ) +{ + int i, k, WeightBest = -100000, WeightCur, RetValue = -1; + for ( i = 1; i < p->nCols-1; i++ ) + for ( k = i+1; k < p->nCols-1; k++ ) + { + if ( p->pColSums[i] == 0 || p->pColSums[i] > p->pMan->pPars->nClusterMax ) + continue; + if ( p->pColSums[k] == 0 || p->pColSums[k] > p->pMan->pPars->nClusterMax ) + continue; + + WeightCur = Llb_ManComputeCommonQuant( p, i, k ); + if ( WeightCur <= 0 ) + continue; + if ( WeightBest < WeightCur ) + { + WeightBest = WeightCur; + RetValue = (i << 16) | k; + } + } +// printf( "Choosing best quant Weight %4d\n", WeightCur ); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +float ** Llb_ManComputeQuant( Llb_Mtr_t * p ) +{ + float ** pCosts; + int i, k; + // alloc and clean + pCosts = (float **)Extra_ArrayAlloc( p->nCols, p->nCols, sizeof(float) ); + for ( i = 0; i < p->nCols; i++ ) + for ( k = 0; k < p->nCols; k++ ) + pCosts[i][i] = 0.0; + // fill up + for ( i = 1; i < p->nCols-1; i++ ) + for ( k = i+1; k < p->nCols-1; k++ ) + pCosts[i][k] = pCosts[k][i] = Llb_ManComputeCommonQuant( p, i, k ); + return pCosts; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +float Llb_ManComputeCommonAttr( Llb_Mtr_t * p, int iCol1, int iCol2 ) +{ + int iVar, CountComm = 0, CountDiff = 0; + for ( iVar = 0; iVar < p->nRows - p->nFfs; iVar++ ) + { + if ( p->pMatrix[iCol1][iVar] == 1 && p->pMatrix[iCol2][iVar] == 1 ) + CountComm++; + else if ( p->pMatrix[iCol1][iVar] == 1 || p->pMatrix[iCol2][iVar] == 1 ) + CountDiff++; + } +/* + printf( "Attr cost for %4d and %4d: %4d %4d (%5.2f)\n", + iCol1, iCol2, + CountDiff, CountComm, + -1.0 * CountDiff / ( CountComm + CountDiff ) ); +*/ + return -1.0 * CountDiff / ( CountComm + CountDiff ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Llb_ManComputeBestAttr( Llb_Mtr_t * p ) +{ + float WeightBest = -100000, WeightCur; + int i, k, RetValue = -1; + for ( i = 1; i < p->nCols-1; i++ ) + for ( k = i+1; k < p->nCols-1; k++ ) + { + if ( p->pColSums[i] == 0 || p->pColSums[i] > p->pMan->pPars->nClusterMax ) + continue; + if ( p->pColSums[k] == 0 || p->pColSums[k] > p->pMan->pPars->nClusterMax ) + continue; + WeightCur = Llb_ManComputeCommonAttr( p, i, k ); + if ( WeightBest < WeightCur ) + { + WeightBest = WeightCur; + RetValue = (i << 16) | k; + } + } + return RetValue; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +float ** Llb_ManComputeAttr( Llb_Mtr_t * p ) +{ + float ** pCosts; + int i, k; + // alloc and clean + pCosts = (float **)Extra_ArrayAlloc( p->nCols, p->nCols, sizeof(float) ); + for ( i = 0; i < p->nCols; i++ ) + for ( k = 0; k < p->nCols; k++ ) + pCosts[i][i] = 0.0; + // fill up + for ( i = 1; i < p->nCols-1; i++ ) + for ( k = i+1; k < p->nCols-1; k++ ) + pCosts[i][k] = pCosts[k][i] = Llb_ManComputeCommonAttr( p, i, k ); + return pCosts; +} + + +/**Function************************************************************* + + Synopsis [Returns the number of variables that will be saved.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_MtrCombineSelectedColumns( Llb_Mtr_t * p, int iGrp1, int iGrp2 ) +{ + int iVar; + assert( iGrp1 >= 1 && iGrp1 < p->nCols - 1 ); + assert( iGrp2 >= 1 && iGrp2 < p->nCols - 1 ); + assert( p->pColGrps[iGrp1] != NULL ); + assert( p->pColGrps[iGrp2] != NULL ); + for ( iVar = 0; iVar < p->nRows; iVar++ ) + { + if ( p->pMatrix[iGrp1][iVar] == 1 && p->pMatrix[iGrp2][iVar] == 1 ) + p->pRowSums[iVar]--; + if ( p->pMatrix[iGrp1][iVar] == 0 && p->pMatrix[iGrp2][iVar] == 1 ) + { + p->pMatrix[iGrp1][iVar] = 1; + p->pColSums[iGrp1]++; + } + if ( p->pMatrix[iGrp2][iVar] == 1 ) + p->pMatrix[iGrp2][iVar] = 0; + } + p->pColSums[iGrp2] = 0; +} + + +/**Function************************************************************* + + Synopsis [Combines one pair of columns.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_ManClusterOne( Llb_Mtr_t * p, int iCol1, int iCol2 ) +{ + int fVerbose = 0; + Llb_Grp_t * pGrp; + int iVar; + + if ( fVerbose ) + { + printf( "Combining %d and %d\n", iCol1, iCol2 ); + for ( iVar = 0; iVar < p->nRows; iVar++ ) + { + if ( p->pMatrix[iCol1][iVar] == 0 && p->pMatrix[iCol2][iVar] == 0 ) + continue; + printf( "%3d : %c%c\n", iVar, + p->pMatrix[iCol1][iVar]? '*':' ', + p->pMatrix[iCol2][iVar]? '*':' ' ); + } + } + pGrp = Llb_ManGroupsCombine( p->pColGrps[iCol1], p->pColGrps[iCol2] ); + Llb_MtrCombineSelectedColumns( p, iCol1, iCol2 ); + p->pColGrps[iCol1] = pGrp; + p->pColGrps[iCol2] = NULL; +} + +/**Function************************************************************* + + Synopsis [Removes empty columns.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_ManClusterCompress( Llb_Mtr_t * p ) +{ + int i, k = 0; + for ( i = 0; i < p->nCols; i++ ) + { + if ( p->pColGrps[i] == NULL ) + { + assert( p->pColSums[i] == 0 ); + assert( p->pMatrix[i] != NULL ); + ABC_FREE( p->pMatrix[i] ); + continue; + } + p->pMatrix[k] = p->pMatrix[i]; + p->pColGrps[k] = p->pColGrps[i]; + p->pColSums[k] = p->pColSums[i]; + k++; + } + p->nCols = k; +} + +/**Function************************************************************* + + Synopsis [Combines one pair of columns.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_ManCluster( Llb_Mtr_t * p ) +{ + int RetValue; + do + { + do { + RetValue = Llb_ManComputeBestQuant( p ); + if ( RetValue > 0 ) + Llb_ManClusterOne( p, RetValue >> 16, RetValue & 0xffff ); + } + while ( RetValue > 0 ); + + RetValue = Llb_ManComputeBestAttr( p ); + if ( RetValue > 0 ) + Llb_ManClusterOne( p, RetValue >> 16, RetValue & 0xffff ); + + Llb_MtrVerifyMatrix( p ); + } + while ( RetValue > 0 ); + + Llb_ManClusterCompress( p ); + + Llb_MtrVerifyMatrix( p ); +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/llb/llbConstr.c b/src/aig/llb/llbConstr.c new file mode 100644 index 00000000..eabae3bc --- /dev/null +++ b/src/aig/llb/llbConstr.c @@ -0,0 +1,313 @@ +/**CFile**************************************************************** + + FileName [llbConstr.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [BDD based reachability.] + + Synopsis [Computing inductive constraints.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: llbConstr.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "llbInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Returns the array of constraint candidates.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Llb_ManCountEntries( Vec_Int_t * vCands ) +{ + int i, Entry, Counter = 0; + Vec_IntForEachEntry( vCands, Entry, i ) + Counter += ((Entry == 0) || (Entry == 1)); + return Counter; +} + +/**Function************************************************************* + + Synopsis [Returns the array of constraint candidates.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_ManPrintEntries( Aig_Man_t * p, Vec_Int_t * vCands ) +{ + int i, Entry; + if ( vCands == NULL ) + { + printf( "There is no hints.\n" ); + return; + } + Entry = Llb_ManCountEntries(vCands); + printf( "\n*** Using %d hint%s:\n", Entry, (Entry != 1 ? "s":"") ); + Vec_IntForEachEntry( vCands, Entry, i ) + { + if ( Entry != 0 && Entry != 1 ) + continue; + printf( "%c", Entry ? '+' : '-' ); + printf( "%-6d : ", i ); + Aig_ObjPrint( p, Aig_ManObj(p, i) ); + printf( "\n" ); + } +} + +/**Function************************************************************* + + Synopsis [Dereference BDD nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_ManDerefenceBdds( Aig_Man_t * p, DdManager * dd ) +{ + Aig_Obj_t * pObj; + int i; + Aig_ManForEachObj( p, pObj, i ) + Cudd_RecursiveDeref( dd, (DdNode *)pObj->pData ); +} + +/**Function************************************************************* + + Synopsis [Returns the array of constraint candidates.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * Llb_ManComputeIndCase_rec( Aig_Man_t * p, Aig_Obj_t * pObj, DdManager * dd, Vec_Ptr_t * vBdds ) +{ + DdNode * bBdd0, * bBdd1; + DdNode * bFunc = (DdNode *)Vec_PtrEntry( vBdds, Aig_ObjId(pObj) ); + if ( bFunc != NULL ) + return bFunc; + assert( Aig_ObjIsNode(pObj) ); + bBdd0 = Llb_ManComputeIndCase_rec( p, Aig_ObjFanin0(pObj), dd, vBdds ); + bBdd1 = Llb_ManComputeIndCase_rec( p, Aig_ObjFanin1(pObj), dd, vBdds ); + bBdd0 = Cudd_NotCond( bBdd0, Aig_ObjFaninC0(pObj) ); + bBdd1 = Cudd_NotCond( bBdd1, Aig_ObjFaninC1(pObj) ); + bFunc = Cudd_bddAnd( dd, bBdd0, bBdd1 ); Cudd_Ref( bFunc ); + Vec_PtrWriteEntry( vBdds, Aig_ObjId(pObj), bFunc ); + return bFunc; +} + +/**Function************************************************************* + + Synopsis [Returns the array of constraint candidates.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_ManComputeIndCase( Aig_Man_t * p, DdManager * dd, Vec_Int_t * vNodes ) +{ + Vec_Ptr_t * vBdds; + Aig_Obj_t * pObj; + DdNode * bFunc; + int i, Entry; + vBdds = Vec_PtrStart( Aig_ManObjNumMax(p) ); + bFunc = Cudd_ReadOne(dd); Cudd_Ref( bFunc ); + Vec_PtrWriteEntry( vBdds, Aig_ObjId(Aig_ManConst1(p)), bFunc ); + Saig_ManForEachPi( p, pObj, i ) + { + bFunc = Cudd_bddIthVar( dd, Aig_ManPiNum(p) + i ); Cudd_Ref( bFunc ); + Vec_PtrWriteEntry( vBdds, Aig_ObjId(pObj), bFunc ); + } + Saig_ManForEachLi( p, pObj, i ) + { + bFunc = (DdNode *)pObj->pData; Cudd_Ref( bFunc ); + Vec_PtrWriteEntry( vBdds, Aig_ObjId(Saig_ObjLiToLo(p, pObj)), bFunc ); + } + Vec_IntForEachEntry( vNodes, Entry, i ) + { + if ( Entry != 0 && Entry != 1 ) + continue; + pObj = Aig_ManObj( p, i ); + bFunc = Llb_ManComputeIndCase_rec( p, pObj, dd, vBdds ); + if ( Entry == 0 ) + { +// Extra_bddPrint( dd, Cudd_Not(pObj->pData) ); printf( "\n" ); +// Extra_bddPrint( dd, Cudd_Not(bFunc) ); printf( "\n" ); + if ( !Cudd_bddLeq( dd, Cudd_Not(pObj->pData), Cudd_Not(bFunc) ) ) + Vec_IntWriteEntry( vNodes, i, -1 ); + } + else if ( Entry == 1 ) + { +// Extra_bddPrint( dd, pObj->pData ); printf( "\n" ); +// Extra_bddPrint( dd, bFunc ); printf( "\n" ); + if ( !Cudd_bddLeq( dd, (DdNode *)pObj->pData, bFunc ) ) + Vec_IntWriteEntry( vNodes, i, -1 ); + } + } + Vec_PtrForEachEntry( DdNode *, vBdds, bFunc, i ) + if ( bFunc ) + Cudd_RecursiveDeref( dd, bFunc ); + Vec_PtrFree( vBdds ); +} + +/**Function************************************************************* + + Synopsis [Returns the array of constraint candidates.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Llb_ManComputeBaseCase( Aig_Man_t * p, DdManager * dd ) +{ + Vec_Int_t * vNodes; + Aig_Obj_t * pObj, * pRoot; + int i; + pRoot = Aig_ManPo( p, 0 ); + vNodes = Vec_IntStartFull( Aig_ManObjNumMax(p) ); + Aig_ManForEachObj( p, pObj, i ) + { + if ( !Aig_ObjIsNode(pObj) && !Aig_ObjIsPi(pObj) ) + continue; + if ( Cudd_bddLeq( dd, (DdNode *)pObj->pData, Cudd_Not(pRoot->pData) ) ) + Vec_IntWriteEntry( vNodes, i, 1 ); + else if ( Cudd_bddLeq( dd, Cudd_Not((DdNode *)pObj->pData), Cudd_Not(pRoot->pData) ) ) + Vec_IntWriteEntry( vNodes, i, 0 ); + } + return vNodes; +} + +/**Function************************************************************* + + Synopsis [Constructs global BDDs for each object in the AIG manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdManager * Llb_ManConstructGlobalBdds( Aig_Man_t * p ) +{ + DdManager * dd; + DdNode * bBdd0, * bBdd1; + Aig_Obj_t * pObj; + int i; + dd = Cudd_Init( Aig_ManPiNum(p), 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 ); + Cudd_AutodynEnable( dd, CUDD_REORDER_SYMM_SIFT ); + pObj = Aig_ManConst1(p); + pObj->pData = Cudd_ReadOne(dd); Cudd_Ref( (DdNode *)pObj->pData ); + Aig_ManForEachPi( p, pObj, i ) + { + pObj->pData = Cudd_bddIthVar(dd, i); Cudd_Ref( (DdNode *)pObj->pData ); + } + Aig_ManForEachNode( p, pObj, i ) + { + bBdd0 = Cudd_NotCond( (DdNode *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0(pObj) ); + bBdd1 = Cudd_NotCond( (DdNode *)Aig_ObjFanin1(pObj)->pData, Aig_ObjFaninC1(pObj) ); + pObj->pData = Cudd_bddAnd( dd, bBdd0, bBdd1 ); Cudd_Ref( (DdNode *)pObj->pData ); + } + Aig_ManForEachPo( p, pObj, i ) + { + pObj->pData = Cudd_NotCond( (DdNode *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0(pObj) ); Cudd_Ref( (DdNode *)pObj->pData ); + } + return dd; +} + +/**Function************************************************************* + + Synopsis [Derives inductive constraints.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Llb_ManDeriveConstraints( Aig_Man_t * p ) +{ + DdManager * dd; + Vec_Int_t * vNodes; + if ( Saig_ManPoNum(p) != 1 ) + { + printf( "The AIG has %d property outputs.\n", Saig_ManPoNum(p) ); + return NULL; + } + assert( Saig_ManPoNum(p) == 1 ); + dd = Llb_ManConstructGlobalBdds( p ); + vNodes = Llb_ManComputeBaseCase( p, dd ); + if ( Llb_ManCountEntries(vNodes) > 0 ) + Llb_ManComputeIndCase( p, dd, vNodes ); + if ( Llb_ManCountEntries(vNodes) == 0 ) + Vec_IntFreeP( &vNodes ); + Llb_ManDerefenceBdds( p, dd ); + Extra_StopManager( dd ); + return vNodes; +} + +/**Function************************************************************* + + Synopsis [Tests derived constraints.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_ManConstrTest( Aig_Man_t * p ) +{ + Vec_Int_t * vNodes; + vNodes = Llb_ManDeriveConstraints( p ); + Llb_ManPrintEntries( p, vNodes ); + Vec_IntFreeP( &vNodes ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/llb/llbCore.c b/src/aig/llb/llbCore.c new file mode 100644 index 00000000..562a9800 --- /dev/null +++ b/src/aig/llb/llbCore.c @@ -0,0 +1,219 @@ +/**CFile**************************************************************** + + FileName [llbCore.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [BDD based reachability.] + + Synopsis [Top-level procedure.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: llbCore.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "llbInt.h" +#include "gia.h" +#include "giaAig.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_ManSetDefaultParams( Gia_ParLlb_t * p ) +{ + memset( p, 0, sizeof(Gia_ParLlb_t) ); + p->nBddMax = 1000000; + p->nIterMax = 1000; + p->nClusterMax = 20; + p->nHintDepth = 0; + p->HintFirst = 0; + p->fUseFlow = 0; // use flow + p->nVolumeMax = 100; // max volume + p->nVolumeMin = 30; // min volume + p->fReorder = 1; + p->fIndConstr = 0; + p->fUsePivots = 0; + p->fCluster = 0; + p->fSchedule = 0; + p->fVerbose = 0; + p->fVeryVerbose = 0; + p->fSilent = 0; + p->TimeLimit = 0; +// p->TimeLimit = 0; + p->TimeLimitGlo = 0; + p->TimeTarget = 0; + p->iFrame = -1; +} + + +/**Function************************************************************* + + Synopsis [Prints statistics about MFFCs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_ManPrintAig( Llb_Man_t * p ) +{ + Abc_Print( 1, "pi =%3d ", Saig_ManPiNum(p->pAig) ); + Abc_Print( 1, "po =%3d ", Saig_ManPoNum(p->pAig) ); + Abc_Print( 1, "ff =%3d ", Saig_ManRegNum(p->pAig) ); + Abc_Print( 1, "int =%5d ", Vec_IntSize(p->vVar2Obj)-Aig_ManPiNum(p->pAig)-Saig_ManRegNum(p->pAig) ); + Abc_Print( 1, "var =%5d ", Vec_IntSize(p->vVar2Obj) ); + Abc_Print( 1, "part =%5d ", Vec_PtrSize(p->vGroups)-2 ); + Abc_Print( 1, "and =%5d ", Aig_ManNodeNum(p->pAig) ); + Abc_Print( 1, "lev =%4d ", Aig_ManLevelNum(p->pAig) ); +// Abc_Print( 1, "cut =%4d ", Llb_ManCrossCut(p->pAig) ); + Abc_Print( 1, "\n" ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Llb_ManModelCheckAig( Aig_Man_t * pAigGlo, Gia_ParLlb_t * pPars, Vec_Int_t * vHints, DdManager ** pddGlo ) +{ + Llb_Man_t * p = NULL; + Aig_Man_t * pAig; + int RetValue = -1; + int clk = clock(); + + if ( pPars->fIndConstr ) + { + assert( vHints == NULL ); + vHints = Llb_ManDeriveConstraints( pAigGlo ); + } + + // derive AIG for hints + if ( vHints == NULL ) + pAig = Aig_ManDupSimple( pAigGlo ); + else + { + if ( pPars->fVerbose ) + Llb_ManPrintEntries( pAigGlo, vHints ); + pAig = Aig_ManDupSimpleWithHints( pAigGlo, vHints ); + } + + + if ( pPars->fUseFlow ) + { +// p = Llb_ManStartFlow( pAigGlo, pAig, pPars ); + } + else + { + p = Llb_ManStart( pAigGlo, pAig, pPars ); + if ( pPars->fVerbose ) + { + Llb_ManPrintAig( p ); + printf( "Original matrix: " ); + Llb_MtrPrintMatrixStats( p->pMatrix ); + if ( pPars->fVeryVerbose ) + Llb_MtrPrint( p->pMatrix, 1 ); + } + if ( pPars->fCluster ) + { + Llb_ManCluster( p->pMatrix ); + if ( pPars->fVerbose ) + { + printf( "Matrix after clustering: " ); + Llb_MtrPrintMatrixStats( p->pMatrix ); + if ( pPars->fVeryVerbose ) + Llb_MtrPrint( p->pMatrix, 1 ); + } + } + if ( pPars->fSchedule ) + { + Llb_MtrSchedule( p->pMatrix ); + if ( pPars->fVerbose ) + { + printf( "Matrix after scheduling: " ); + Llb_MtrPrintMatrixStats( p->pMatrix ); + if ( pPars->fVeryVerbose ) + Llb_MtrPrint( p->pMatrix, 1 ); + } + } + } + + if ( !p->pPars->fSkipReach ) + RetValue = Llb_ManReachability( p, vHints, pddGlo ); + Llb_ManStop( p ); + + Abc_PrintTime( 1, "Time", clock() - clk ); + + if ( pPars->fIndConstr ) + Vec_IntFreeP( &vHints ); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Llb_ManModelCheckGia( Gia_Man_t * pGia, Gia_ParLlb_t * pPars ) +{ + Gia_Man_t * pGia2; + Aig_Man_t * pAig; + int RetValue = -1; + pGia2 = Gia_ManDupDfs( pGia ); + pAig = Gia_ManToAigSimple( pGia2 ); + Gia_ManStop( pGia2 ); +//Aig_ManShow( pAig, 0, NULL ); + + if ( pPars->nHintDepth == 0 ) + RetValue = Llb_ManModelCheckAig( pAig, pPars, NULL, NULL ); + else + RetValue = Llb_ManModelCheckAigWithHints( pAig, pPars ); + Aig_ManStop( pAig ); + return RetValue; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/llb/llbFlow.c b/src/aig/llb/llbFlow.c new file mode 100644 index 00000000..55405c09 --- /dev/null +++ b/src/aig/llb/llbFlow.c @@ -0,0 +1,639 @@ +/**CFile**************************************************************** + + FileName [llbFlow.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [BDD based reachability.] + + Synopsis [Flow computation.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: llbFlow.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "llbInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Llb_Flw_t_ Llb_Flw_t; +struct Llb_Flw_t_ +{ + unsigned Source : 1; // source of the graph + unsigned Sink : 1; // sink of the graph + unsigned Flow : 1; // node has flow + unsigned Mark : 1; // visited node + unsigned Id : 14; // ID of the corresponding node + unsigned nFanins : 14; // number of fanins + Llb_Flw_t * Fanins[0]; // fanins +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Llb_Flw_t * Llb_FlwAlloc( Vec_Int_t * vMem, Vec_Ptr_t * vStore, int Id, int nFanins ) +{ + Llb_Flw_t * p; + int nWords = (sizeof(Llb_Flw_t) + nFanins * sizeof(void *)) / sizeof(int); + p = (Llb_Flw_t *)Vec_IntFetch( vMem, nWords ); + memset( p, 1, nWords * sizeof(int) ); + p->Id = Id; + p->nFanins = 0;//nFanins; + Vec_PtrWriteEntry( vStore, Id, p ); + return p; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_FlwAddFanin( Llb_Flw_t * pFrom, Llb_Flw_t * pTo ) +{ + pFrom->Fanins[pFrom->nFanins++] = pTo; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_AigCreateFlw( Aig_Man_t * p, Vec_Int_t ** pvMem, Vec_Ptr_t ** pvTops, Vec_Ptr_t ** pvBots ) +{ + Llb_Flw_t * pFlwTop, * pFlwBot; + Vec_Ptr_t * vTops, * vBots; + Vec_Int_t * vMem; + Aig_Obj_t * pObj; + int i; + vMem = Vec_IntAlloc( Aig_ManObjNumMax(p) * (sizeof(Llb_Flw_t) + sizeof(void *) * 8) ); + vBots = Vec_PtrStart( Aig_ManObjNumMax(p) ); + vTops = Vec_PtrStart( Aig_ManObjNumMax(p) ); + Aig_ManForEachObj( p, pObj, i ) + { + pFlwBot = Llb_FlwAlloc( vMem, vBots, i, Aig_ObjIsPo(pObj) + 2 * Aig_ObjIsNode(pObj) ); + pFlwTop = Llb_FlwAlloc( vMem, vTops, i, Aig_ObjRefs(pObj) + 1 ); + Llb_FlwAddFanin( pFlwBot, pFlwTop ); + Llb_FlwAddFanin( pFlwTop, pFlwBot ); + Llb_FlwAddFanin( pFlwBot, (Llb_Flw_t *)Vec_PtrEntry(vTops, Aig_ObjFaninId0(pObj)) ); + Llb_FlwAddFanin( pFlwBot, (Llb_Flw_t *)Vec_PtrEntry(vTops, Aig_ObjFaninId1(pObj)) ); + Llb_FlwAddFanin( (Llb_Flw_t *)Vec_PtrEntry(vTops, Aig_ObjFaninId0(pObj)), pFlwBot ); + Llb_FlwAddFanin( (Llb_Flw_t *)Vec_PtrEntry(vTops, Aig_ObjFaninId1(pObj)), pFlwBot ); + } + Aig_ManForEachObj( p, pObj, i ) + { + pFlwBot = (Llb_Flw_t *)Vec_PtrEntry( vBots, i ); + pFlwTop = (Llb_Flw_t *)Vec_PtrEntry( vTops, i ); + assert( pFlwBot->nFanins == (unsigned)Aig_ObjIsPo(pObj) + 2 * Aig_ObjIsNode(pObj) ); + assert( pFlwTop->nFanins == (unsigned)Aig_ObjRefs(pObj) + 1 ); + } + *pvMem = vMem; + *pvTops = vTops; + *pvBots = vBots; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_AigCleanMarks( Vec_Ptr_t * vFlw ) +{ + Llb_Flw_t * pFlw; + int i; + Vec_PtrForEachEntry( Llb_Flw_t *, vFlw, pFlw, i ) + pFlw->Mark = 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_AigCleanFlow( Vec_Ptr_t * vFlw ) +{ + Llb_Flw_t * pFlw; + int i; + Vec_PtrForEachEntry( Llb_Flw_t *, vFlw, pFlw, i ) + pFlw->Flow = 0; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Llb_AigCollectCut( Vec_Ptr_t * vNodes, Vec_Ptr_t * vBots, Vec_Ptr_t * vTops ) +{ + Vec_Int_t * vCut; + Llb_Flw_t * pFlwBot, * pFlwTop; + Aig_Obj_t * pObj; + int i; + vCut = Vec_IntAlloc( 100 ); + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) + { + pFlwBot = (Llb_Flw_t *)Vec_PtrEntry( vBots, i ); + pFlwTop = (Llb_Flw_t *)Vec_PtrEntry( vTops, i ); + if ( pFlwBot->Mark && !pFlwTop->Mark ) + Vec_IntPush( vCut, i ); + } + return vCut; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Llb_AigPushFlow_rec( Llb_Flw_t * pFlw, Llb_Flw_t * pFlwPrev, Vec_Ptr_t * vMarked, Vec_Ptr_t * vFlowed ) +{ + int i; + if ( pFlw->Mark ) + return 0; + pFlw->Mark = 1; + Vec_PtrPush( vMarked, pFlw ); + if ( pFlw->Source ) + return 0; + if ( pFlw->Sink ) + { + pFlw->Flow = 1; + Vec_PtrPush( vFlowed, pFlw ); + return 1; + } +// assert( Aig_ObjIsNode(pObj) ); + for ( i = 0; i < (int)pFlw->nFanins; i++ ) + { + if ( pFlw->Fanins[i] == pFlwPrev ) + continue; + if ( Llb_AigPushFlow_rec( pFlw->Fanins[i], pFlw, vMarked, vFlowed ) ) + break; + } + if ( i == (int)pFlw->nFanins ) + return 0; + if ( i == 0 ) + { + pFlw->Flow = 1; + Vec_PtrPush( vFlowed, pFlw ); + } + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Llb_AigPushFlow( Vec_Ptr_t * vFlwBots, Vec_Ptr_t * vMarked, Vec_Ptr_t * vFlowed ) +{ + Llb_Flw_t * pFlw; + int i, Counter = 0; + Vec_PtrForEachEntry( Llb_Flw_t *, vFlwBots, pFlw, i ) + { + pFlw->Mark = 1; + if ( Llb_AigPushFlow_rec( pFlw->Fanins[0], pFlw, vMarked, vFlowed ) ) + { + Counter++; + pFlw->Flow = 1; + Vec_PtrPush( vFlowed, pFlw ); + } + } + return Counter; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Llb_AigFindMinCut( Vec_Ptr_t * vNodes, Vec_Ptr_t * vFlwBots, Vec_Ptr_t * vFlwTop, Vec_Ptr_t * vFlwBots2, Vec_Ptr_t * vFlwTop2 ) +{ + Vec_Int_t * vCut; + Vec_Ptr_t * vMarked, * vFlowed; + int Value; + vMarked = Vec_PtrAlloc( 100 ); + vFlowed = Vec_PtrAlloc( 100 ); + Value = Llb_AigPushFlow( vFlwBots2, vMarked, vFlowed ); + Llb_AigCleanMarks( vMarked ); + Value = Llb_AigPushFlow( vFlwBots2, vMarked, vFlowed ); + assert( Value == 0 ); + vCut = Llb_AigCollectCut( vNodes, vFlwBots, vFlwTop ); + Llb_AigCleanMarks( vMarked ); + Llb_AigCleanFlow( vFlowed ); + return vCut; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Llb_AigCollectFlowTerminals( Aig_Man_t * p, Vec_Ptr_t * vFlws, Vec_Int_t * vCut ) +{ + Vec_Ptr_t * pFlwRes; + Aig_Obj_t * pObj; + int i; + pFlwRes = Vec_PtrAlloc( Vec_IntSize(vCut) ); + Aig_ManForEachNodeVec( p, vCut, pObj, i ) + Vec_PtrPush( pFlwRes, Vec_PtrEntry( vFlws, Aig_ObjId(pObj) ) ); + return pFlwRes; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_AigMarkFlowTerminals( Vec_Ptr_t * vFlws, int fSource, int fSink ) +{ + Llb_Flw_t * pFlw; + int i; + Vec_PtrForEachEntry( Llb_Flw_t *, vFlws, pFlw, i ) + { + pFlw->Source = fSource; + pFlw->Sink = fSink; + } +} + +/**Function************************************************************* + + Synopsis [Collects internal nodes in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_ManCollectNodes_rec( Aig_Man_t * p, Aig_Obj_t * pObj, Vec_Ptr_t * vNodes ) +{ + if ( Aig_ObjIsTravIdCurrent(p, pObj) ) + return; + Aig_ObjSetTravIdCurrent(p, pObj); + assert( Aig_ObjIsNode(pObj) ); + Llb_ManCollectNodes_rec( p, Aig_ObjFanin0(pObj), vNodes ); + Llb_ManCollectNodes_rec( p, Aig_ObjFanin1(pObj), vNodes ); + Vec_PtrPush( vNodes, pObj ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Llb_ManCollectNodes( Aig_Man_t * p, Vec_Int_t * vCut1, Vec_Int_t * vCut2 ) +{ + Vec_Ptr_t * vNodes; + Aig_Obj_t * pObj; + int i; + Aig_ManIncrementTravId( p ); + Aig_ManForEachNodeVec( p, vCut1, pObj, i ) + Aig_ObjSetTravIdCurrent( p, pObj ); + vNodes = Vec_PtrAlloc( Aig_ManObjNumMax(p) ); + Aig_ManForEachNodeVec( p, vCut2, pObj, i ) + Llb_ManCollectNodes_rec( p, pObj, vNodes ); + return vNodes; +} + +/**Function************************************************************* + + Synopsis [Collects internal nodes in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Llb_ManCountNodes_rec( Aig_Man_t * p, Aig_Obj_t * pObj ) +{ + if ( Aig_ObjIsTravIdCurrent(p, pObj) ) + return 0; + Aig_ObjSetTravIdCurrent(p, pObj); + assert( Aig_ObjIsNode(pObj) ); + return 1 + Llb_ManCountNodes_rec( p, Aig_ObjFanin0(pObj) ) + + Llb_ManCountNodes_rec( p, Aig_ObjFanin1(pObj) ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Llb_ManCountNodes( Aig_Man_t * p, Vec_Int_t * vCut1, Vec_Int_t * vCut2 ) +{ + Aig_Obj_t * pObj; + int i, Counter = 0; + Aig_ManIncrementTravId( p ); + Aig_ManForEachNodeVec( p, vCut1, pObj, i ) + Aig_ObjSetTravIdCurrent( p, pObj ); + Aig_ManForEachNodeVec( p, vCut2, pObj, i ) + Counter += Llb_ManCountNodes_rec( p, pObj ); + return Counter; +} + +/**Function************************************************************* + + Synopsis [Computes starting cuts.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Llb_ManComputeCioCut( Aig_Man_t * pAig, int fCollectCos ) +{ + Vec_Int_t * vCut; + Aig_Obj_t * pObj; + int i; + vCut = Vec_IntAlloc( 500 ); + if ( fCollectCos ) + Aig_ManForEachPo( pAig, pObj, i ) + Vec_IntPush( vCut, Aig_ObjId(pObj) ); + else + Aig_ManForEachPi( pAig, pObj, i ) + Vec_IntPush( vCut, Aig_ObjId(pObj) ); + return vCut; +} + +/**Function************************************************************* + + Synopsis [Inserts the new cut into the array.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_ManCutInsert( Aig_Man_t * p, Vec_Ptr_t * vCuts, Vec_Int_t * vVols, int iEntry, Vec_Int_t * vCutNew ) +{ + Vec_Int_t * vCut1, * vCut2; + int Vol1, Vol2; + Vec_PtrInsert( vCuts, iEntry, vCutNew ); + Vec_IntInsert( vVols, iEntry, -1 ); + vCut1 = (Vec_Int_t *)Vec_PtrEntry( vCuts, iEntry ); + vCut2 = (Vec_Int_t *)Vec_PtrEntry( vCuts, iEntry+1 ); + Vol1 = Llb_ManCountNodes( p, vCut1, vCutNew ); + Vol2 = Llb_ManCountNodes( p, vCutNew, vCut2 ); + Vec_IntWriteEntry( vVols, iEntry-1, Vol1 ); + Vec_IntWriteEntry( vVols, iEntry, Vol2 ); +} + +/**Function************************************************************* + + Synopsis [Returns the set of cuts resulting from the flow computation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Llb_ManComputePartitioning( Aig_Man_t * p, int nVolumeMin, int nVolumeMax ) +{ + Vec_Ptr_t * vCuts, * vFlwTops, * vFlwBots; + Vec_Int_t * vVols, * vCut1, * vCut2, * vCut, * vMem; + int nMaxValue, iEntry; + vCuts = Vec_PtrAlloc( 1000 ); + vVols = Vec_IntAlloc( 1000 ); + // prepare flow computation + Llb_AigCreateFlw( p, &vMem, &vFlwTops, &vFlwBots ); + // start with regular cuts + Vec_PtrPush( vCuts, Llb_ManComputeCioCut(p, 0) ); + Vec_PtrPush( vCuts, Llb_ManComputeCioCut(p, 1) ); + Vec_IntPush( vVols, Aig_ManNodeNum(p) ); + // split cuts with the largest volume + while ( (nMaxValue = Vec_IntFindMax(vVols)) > nVolumeMax ) + { + Vec_Ptr_t * vNodes, * vFlwBots2, * vFlwTops2; + iEntry = Vec_IntFind( vVols, nMaxValue ); assert( iEntry >= 0 ); + vCut1 = (Vec_Int_t *)Vec_PtrEntry( vCuts, iEntry ); + vCut2 = (Vec_Int_t *)Vec_PtrEntry( vCuts, iEntry+1 ); + // collect nodes + vNodes = Llb_ManCollectNodes( p, vCut1, vCut1 ); + assert( Vec_PtrSize(vNodes) == nMaxValue ); + assert( Llb_ManCountNodes(p, vCut1, vCut2) == nMaxValue ); + // collect sources and sinks + vFlwBots2 = Llb_AigCollectFlowTerminals( p, vFlwBots, vCut1 ); + vFlwTops2 = Llb_AigCollectFlowTerminals( p, vFlwTops, vCut2 ); + // mark sources and sinks + Llb_AigMarkFlowTerminals( vFlwBots2, 1, 0 ); + Llb_AigMarkFlowTerminals( vFlwTops2, 0, 1 ); + vCut = Llb_AigFindMinCut( vNodes, vFlwBots, vFlwTops, vFlwBots2, vFlwTops2 ); + Llb_AigMarkFlowTerminals( vFlwBots2, 0, 0 ); + Llb_AigMarkFlowTerminals( vFlwTops2, 0, 0 ); + // insert new cut + Llb_ManCutInsert( p, vCuts, vVols, iEntry+1, vCut ); + // deallocate + Vec_PtrFree( vNodes ); + Vec_PtrFree( vFlwBots2 ); + Vec_PtrFree( vFlwTops2 ); + } + Vec_IntFree( vMem ); + Vec_PtrFree( vFlwTops ); + Vec_PtrFree( vFlwBots ); + return vCuts; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Llb_ManMarkPivotNodesFlow( Aig_Man_t * p, Vec_Ptr_t * vCuts ) +{ + Vec_Int_t * vVar2Obj, * vCut; + Aig_Obj_t * pObj; + int i, k; + // mark inputs/outputs + Aig_ManForEachPi( p, pObj, i ) + pObj->fMarkA = 1; + Saig_ManForEachLi( p, pObj, i ) + pObj->fMarkA = 1; + + // mark internal pivot nodes + Vec_PtrForEachEntry( Vec_Int_t *, vCuts, vCut, i ) + Aig_ManForEachNodeVec( p, vCut, pObj, k ) + pObj->fMarkA = 1; + + // assign variable numbers + Aig_ManConst1(p)->fMarkA = 0; + vVar2Obj = Vec_IntAlloc( 100 ); + Aig_ManForEachPi( p, pObj, i ) + Vec_IntPush( vVar2Obj, Aig_ObjId(pObj) ); + Aig_ManForEachNode( p, pObj, i ) + if ( pObj->fMarkA ) + Vec_IntPush( vVar2Obj, Aig_ObjId(pObj) ); + Saig_ManForEachLi( p, pObj, i ) + Vec_IntPush( vVar2Obj, Aig_ObjId(pObj) ); + return vVar2Obj; +} + +/**Function************************************************************* + + Synopsis [Returns the set of cuts resulting from the flow computation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_ManPartitionUsingFlow( Llb_Man_t * p, Vec_Ptr_t * vCuts ) +{ + Vec_Int_t * vCut1, * vCut2; + int i; + vCut1 = (Vec_Int_t *)Vec_PtrEntry( vCuts, 0 ); + Vec_PtrForEachEntryStart( Vec_Int_t *, vCuts, vCut1, i, 1 ) + { + vCut2 = (Vec_Int_t *)Vec_PtrEntry( vCuts, i ); + Llb_ManGroupCreateFromCuts( p, vCut1, vCut2 ); + vCut1 = vCut2; + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Llb_Man_t * Llb_ManStartFlow( Aig_Man_t * pAigGlo, Aig_Man_t * pAig, Gia_ParLlb_t * pPars ) +{ + Vec_Ptr_t * vCuts; + Llb_Man_t * p; + vCuts = Llb_ManComputePartitioning( pAig, pPars->nVolumeMin, pPars->nVolumeMax ); + Aig_ManCleanMarkA( pAig ); + p = ABC_CALLOC( Llb_Man_t, 1 ); + p->pAigGlo = pAigGlo; + p->pPars = pPars; + p->pAig = pAig; + p->vVar2Obj = Llb_ManMarkPivotNodesFlow( p->pAig, vCuts ); + p->vObj2Var = Vec_IntInvert( p->vVar2Obj, -1 ); + Llb_ManPrepareVarMap( p ); + Aig_ManCleanMarkA( pAig ); + Llb_ManPartitionUsingFlow( p, vCuts ); + Vec_VecFreeP( (Vec_Vec_t **)&vCuts ); + return p; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/llb/llbHint.c b/src/aig/llb/llbHint.c new file mode 100644 index 00000000..acc674c8 --- /dev/null +++ b/src/aig/llb/llbHint.c @@ -0,0 +1,226 @@ +/**CFile**************************************************************** + + FileName [llbHint.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [BDD based reachability.] + + Synopsis [Cofactors the circuit w.r.t. the high-fanout variables.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: llbHint.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "llbInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Returns CI index with the largest number of fanouts.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Llb_ManMaxFanoutCi( Aig_Man_t * pAig ) +{ + Aig_Obj_t * pObj; + int i, WeightMax = -ABC_INFINITY, iInput = -1; + Aig_ManForEachPi( pAig, pObj, i ) + if ( WeightMax < Aig_ObjRefs(pObj) ) + { + WeightMax = Aig_ObjRefs(pObj); + iInput = i; + } + assert( iInput >= 0 ); + return iInput; +} + +/**Function************************************************************* + + Synopsis [Derives AIG whose PI is substituted by a constant.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Llb_ManPerformHints( Aig_Man_t * pAig, int nHintDepth ) +{ + Aig_Man_t * pNew, * pTemp; + int i, iInput; + pNew = Aig_ManDupDfs( pAig ); + for ( i = 0; i < nHintDepth; i++ ) + { + iInput = Llb_ManMaxFanoutCi( pNew ); + Abc_Print( 1, "%d %3d\n", i, iInput ); + pNew = Aig_ManDupCof( pTemp = pNew, iInput, 1 ); + Aig_ManStop( pTemp ); + } + return pNew; +} + +/**Function************************************************************* + + Synopsis [Returns CI index with the largest number of fanouts.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Llb_ManCollectHighFanoutObjects( Aig_Man_t * pAig, int nCandMax, int fCisOnly ) +{ + Vec_Int_t * vFanouts, * vResult; + Aig_Obj_t * pObj; + int i, fChanges, PivotValue; +// int Entry; + // collect fanout counts + vFanouts = Vec_IntAlloc( 100 ); + Aig_ManForEachObj( pAig, pObj, i ) + { +// if ( !Aig_ObjIsPi(pObj) && (fCisOnly || !Aig_ObjIsNode(pObj)) ) + if ( !Saig_ObjIsLo(pAig,pObj) && (fCisOnly || !Aig_ObjIsNode(pObj)) ) + continue; + Vec_IntPush( vFanouts, Aig_ObjRefs(pObj) ); + } + Vec_IntSort( vFanouts, 1 ); + // pick the separator + nCandMax = ABC_MIN( nCandMax, Vec_IntSize(vFanouts) - 1 ); + PivotValue = Vec_IntEntry( vFanouts, nCandMax ); + Vec_IntFree( vFanouts ); + // collect obj satisfying the constraints + vResult = Vec_IntAlloc( 100 ); + Aig_ManForEachObj( pAig, pObj, i ) + { +// if ( !Aig_ObjIsPi(pObj) && (fCisOnly || !Aig_ObjIsNode(pObj)) ) + if ( !Saig_ObjIsLo(pAig,pObj) && (fCisOnly || !Aig_ObjIsNode(pObj)) ) + continue; + if ( Aig_ObjRefs(pObj) < PivotValue ) + continue; + Vec_IntPush( vResult, Aig_ObjId(pObj) ); + } + assert( Vec_IntSize(vResult) >= nCandMax ); + // order in the decreasing order of fanouts + do + { + fChanges = 0; + for ( i = 0; i < Vec_IntSize(vResult) - 1; i++ ) + if ( Aig_ObjRefs(Aig_ManObj(pAig, Vec_IntEntry(vResult, i))) < + Aig_ObjRefs(Aig_ManObj(pAig, Vec_IntEntry(vResult, i+1))) ) + { + int Temp = Vec_IntEntry( vResult, i ); + Vec_IntWriteEntry( vResult, i, Vec_IntEntry(vResult, i+1) ); + Vec_IntWriteEntry( vResult, i+1, Temp ); + fChanges = 1; + } + } + while ( fChanges ); +/* + Vec_IntForEachEntry( vResult, Entry, i ) + printf( "%d ", Aig_ObjRefs(Aig_ManObj(pAig, Entry)) ); +printf( "\n" ); +*/ + return vResult; +} + +/**Function************************************************************* + + Synopsis [Derives AIG whose PI is substituted by a constant.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Llb_ManModelCheckAigWithHints( Aig_Man_t * pAigGlo, Gia_ParLlb_t * pPars ) +{ + DdManager * ddGlo = NULL; + Vec_Int_t * vHints; + Vec_Int_t * vHFCands; + int i, Entry, RetValue = -1; + int clk = clock(); + assert( pPars->nHintDepth > 0 ); +/* + // perform reachability without hints + RetValue = Llb_ManModelCheckAig( pAigGlo, pPars, NULL, NULL ); + if ( RetValue >= 0 ) + return RetValue; +*/ + // create hints representation + vHFCands = Llb_ManCollectHighFanoutObjects( pAigGlo, pPars->nHintDepth+pPars->HintFirst, 1 ); + vHints = Vec_IntStartFull( Aig_ManObjNumMax(pAigGlo) ); + // add one hint at a time till the problem is solved + Vec_IntForEachEntryStart( vHFCands, Entry, i, pPars->HintFirst ) + { + Vec_IntWriteEntry( vHints, Entry, 1 ); // change to 1 to start from zero cof!!! + // solve under hints + RetValue = Llb_ManModelCheckAig( pAigGlo, pPars, vHints, &ddGlo ); + if ( RetValue == 0 ) + goto Finish; + if ( RetValue == 1 ) + break; + } + if ( RetValue == -1 ) + goto Finish; + // undo the hints one at a time + for ( ; i >= pPars->HintFirst; i-- ) + { + Entry = Vec_IntEntry( vHFCands, i ); + Vec_IntWriteEntry( vHints, Entry, -1 ); + // solve under relaxed hints + RetValue = Llb_ManModelCheckAig( pAigGlo, pPars, vHints, &ddGlo ); + if ( RetValue == 0 ) + goto Finish; + if ( RetValue == 1 ) + continue; + break; + } +Finish: + if ( ddGlo ) + { + if ( ddGlo->bReached ) + Cudd_RecursiveDeref( ddGlo, ddGlo->bReached ); + Extra_StopManager( ddGlo ); + } + Vec_IntFreeP( &vHFCands ); + Vec_IntFreeP( &vHints ); + if ( pPars->fVerbose ) + Abc_PrintTime( 1, "Total runtime", clock() - clk ); + return RetValue; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/llb/llbInt.h b/src/aig/llb/llbInt.h new file mode 100644 index 00000000..dc448954 --- /dev/null +++ b/src/aig/llb/llbInt.h @@ -0,0 +1,162 @@ +/**CFile**************************************************************** + + FileName [llbInt.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [BDD-based reachability.] + + Synopsis [External declarations.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 8, 2010.] + + Revision [$Id: llbInt.h,v 1.00 2010/05/08 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#ifndef __LLB_INT_H__ +#define __LLB_INT_H__ + + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// + +#include <stdio.h> +#include "aig.h" +#include "saig.h" +#include "cuddInt.h" +#include "extra.h" +#include "llb.h" + +//////////////////////////////////////////////////////////////////////// +/// PARAMETERS /// +//////////////////////////////////////////////////////////////////////// + + + +ABC_NAMESPACE_HEADER_START + + +//////////////////////////////////////////////////////////////////////// +/// BASIC TYPES /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Llb_Man_t_ Llb_Man_t; +typedef struct Llb_Mtr_t_ Llb_Mtr_t; +typedef struct Llb_Grp_t_ Llb_Grp_t; + +struct Llb_Man_t_ +{ + Gia_ParLlb_t * pPars; // parameters + Aig_Man_t * pAigGlo; // initial AIG manager (owned by the caller) + Aig_Man_t * pAig; // derived AIG manager (created in this package) + DdManager * dd; // BDD manager + DdManager * ddG; // BDD manager + Vec_Int_t * vObj2Var; // mapping AIG ObjId into BDD var index + Vec_Int_t * vVar2Obj; // mapping BDD var index into AIG ObjId + Vec_Ptr_t * vGroups; // group Id into group pointer + Llb_Mtr_t * pMatrix; // dependency matrix + // image computation + Vec_Int_t * vVarBegs; // the first group where the var appears + Vec_Int_t * vVarEnds; // the last group where the var appears + // variable mapping + Vec_Int_t * vNs2Glo; // next state variables into global variables + Vec_Int_t * vGlo2Cs; // global variables into current state variables + // flow computation +// Vec_Int_t * vMem; +// Vec_Ptr_t * vTops; +// Vec_Ptr_t * vBots; +// Vec_Ptr_t * vCuts; +}; + +struct Llb_Mtr_t_ +{ + int nPis; // number of primary inputs + int nFfs; // number of flip-flops + int nRows; // number of rows + int nCols; // number of columns + int * pColSums; // sum of values in a column + Llb_Grp_t ** pColGrps; // group structure for each col + int * pRowSums; // sum of values in a row + char ** pMatrix; // dependency matrix + Llb_Man_t * pMan; // manager + // partial product + char * pProdVars; // variables in the partial product + int * pProdNums; // var counts in the remaining partitions +}; + +struct Llb_Grp_t_ +{ + int Id; // group ID + Vec_Ptr_t * vIns; // input AIG objs + Vec_Ptr_t * vOuts; // output AIG objs + Vec_Ptr_t * vNodes; // internal AIG objs + Llb_Man_t * pMan; // manager + Llb_Grp_t * pPrev; // previous group + Llb_Grp_t * pNext; // next group +}; + +//////////////////////////////////////////////////////////////////////// +/// MACRO DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +/*=== llbCex.c =======================================================*/ +extern Abc_Cex_t * Llb_ManDeriveCex( Llb_Man_t * p, DdNode * bInter, int iOutFail, int iIter ); +/*=== llbConstr.c ======================================================*/ +extern Vec_Int_t * Llb_ManDeriveConstraints( Aig_Man_t * p ); +extern void Llb_ManPrintEntries( Aig_Man_t * p, Vec_Int_t * vCands ); +/*=== llbCore.c ======================================================*/ +extern int Llb_ManModelCheckAig( Aig_Man_t * pAigGlo, Gia_ParLlb_t * pPars, Vec_Int_t * vHints, DdManager ** pddGlo ); +/*=== llbCluster.c ======================================================*/ +extern void Llb_ManCluster( Llb_Mtr_t * p ); +/*=== llbFlow.c ======================================================*/ +extern Llb_Man_t * Llb_ManStartFlow( Aig_Man_t * pAigGlo, Aig_Man_t * pAig, Gia_ParLlb_t * pPars ); +/*=== llbHint.c ======================================================*/ +extern int Llb_ManReachabilityWithHints( Llb_Man_t * p ); +extern int Llb_ManModelCheckAigWithHints( Aig_Man_t * pAigGlo, Gia_ParLlb_t * pPars ); +/*=== llbMan.c =======================================================*/ +extern void Llb_ManPrepareVarMap( Llb_Man_t * p ); +extern Llb_Man_t * Llb_ManStart( Aig_Man_t * pAigGlo, Aig_Man_t * pAig, Gia_ParLlb_t * pPars ); +extern void Llb_ManStop( Llb_Man_t * p ); +/*=== llbMatrix.c ====================================================*/ +extern void Llb_MtrVerifyMatrix( Llb_Mtr_t * p ); +extern Llb_Mtr_t * Llb_MtrCreate( Llb_Man_t * p ); +extern void Llb_MtrFree( Llb_Mtr_t * p ); +extern void Llb_MtrPrint( Llb_Mtr_t * p, int fOrder ); +extern void Llb_MtrPrintMatrixStats( Llb_Mtr_t * p ); +/*=== llbPart.c ======================================================*/ +extern Llb_Grp_t * Llb_ManGroupAlloc( Llb_Man_t * pMan ); +extern void Llb_ManGroupStop( Llb_Grp_t * p ); +extern void Llb_ManPrepareGroups( Llb_Man_t * pMan ); +extern Llb_Grp_t * Llb_ManGroupsCombine( Llb_Grp_t * p1, Llb_Grp_t * p2 ); +extern Llb_Grp_t * Llb_ManGroupCreateFromCuts( Llb_Man_t * pMan, Vec_Int_t * vCut1, Vec_Int_t * vCut2 ); +extern void Llb_ManPrepareVarLimits( Llb_Man_t * p ); +/*=== llbPivot.c =====================================================*/ +extern int Llb_ManTracePaths( Aig_Man_t * p, Aig_Obj_t * pPivot ); +extern Vec_Int_t * Llb_ManMarkPivotNodes( Aig_Man_t * p, int fUseInternal ); +/*=== llbReach.c =====================================================*/ +extern int Llb_ManReachability( Llb_Man_t * p, Vec_Int_t * vHints, DdManager ** pddGlo ); +/*=== llbSched.c =====================================================*/ +extern void Llb_MtrSchedule( Llb_Mtr_t * p ); + + + +ABC_NAMESPACE_HEADER_END + + + +#endif + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + diff --git a/src/aig/llb/llbMan.c b/src/aig/llb/llbMan.c new file mode 100644 index 00000000..cd6fd3ff --- /dev/null +++ b/src/aig/llb/llbMan.c @@ -0,0 +1,189 @@ +/**CFile**************************************************************** + + FileName [llbMan.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [BDD based reachability.] + + Synopsis [Reachability manager.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: llbMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "llbInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_ManPrepareVarMap( Llb_Man_t * p ) +{ + Aig_Obj_t * pObjLi, * pObjLo; + int i, iVarLi, iVarLo; + assert( p->vNs2Glo == NULL ); + assert( p->vGlo2Cs == NULL ); + p->vNs2Glo = Vec_IntStartFull( Vec_IntSize(p->vVar2Obj) ); + p->vGlo2Cs = Vec_IntStartFull( Aig_ManRegNum(p->pAig) ); + Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i ) + { + iVarLi = Vec_IntEntry(p->vObj2Var, Aig_ObjId(pObjLi)); + iVarLo = Vec_IntEntry(p->vObj2Var, Aig_ObjId(pObjLo)); + assert( iVarLi >= 0 && iVarLi < Vec_IntSize(p->vVar2Obj) ); + assert( iVarLo >= 0 && iVarLo < Vec_IntSize(p->vVar2Obj) ); + Vec_IntWriteEntry( p->vNs2Glo, iVarLi, i ); + Vec_IntWriteEntry( p->vGlo2Cs, i, iVarLo ); + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_ManPrepareVarLimits( Llb_Man_t * p ) +{ + Llb_Grp_t * pGroup; + Aig_Obj_t * pVar; + int i, k; + assert( p->vVarBegs == NULL ); + assert( p->vVarEnds == NULL ); + p->vVarEnds = Vec_IntStart( Aig_ManObjNumMax(p->pAig) ); + p->vVarBegs = Vec_IntStart( Aig_ManObjNumMax(p->pAig) ); + Vec_IntFill( p->vVarBegs, Aig_ManObjNumMax(p->pAig), p->pMatrix->nCols ); + + for ( i = 0; i < p->pMatrix->nCols; i++ ) + { + pGroup = p->pMatrix->pColGrps[i]; + + Vec_PtrForEachEntry( Aig_Obj_t *, pGroup->vIns, pVar, k ) + if ( Vec_IntEntry(p->vVarBegs, pVar->Id) > i ) + Vec_IntWriteEntry( p->vVarBegs, pVar->Id, i ); + Vec_PtrForEachEntry( Aig_Obj_t *, pGroup->vOuts, pVar, k ) + if ( Vec_IntEntry(p->vVarBegs, pVar->Id) > i ) + Vec_IntWriteEntry( p->vVarBegs, pVar->Id, i ); + + Vec_PtrForEachEntry( Aig_Obj_t *, pGroup->vIns, pVar, k ) + if ( Vec_IntEntry(p->vVarEnds, pVar->Id) < i ) + Vec_IntWriteEntry( p->vVarEnds, pVar->Id, i ); + Vec_PtrForEachEntry( Aig_Obj_t *, pGroup->vOuts, pVar, k ) + if ( Vec_IntEntry(p->vVarEnds, pVar->Id) < i ) + Vec_IntWriteEntry( p->vVarEnds, pVar->Id, i ); + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_ManStop( Llb_Man_t * p ) +{ + Llb_Grp_t * pGrp; + int i; + +// Vec_IntFreeP( &p->vMem ); +// Vec_PtrFreeP( &p->vTops ); +// Vec_PtrFreeP( &p->vBots ); +// Vec_VecFreeP( (Vec_Vec_t **)&p->vCuts ); + + if ( p->pMatrix ) + Llb_MtrFree( p->pMatrix ); + Vec_PtrForEachEntry( Llb_Grp_t *, p->vGroups, pGrp, i ) + Llb_ManGroupStop( pGrp ); + Vec_PtrFreeP( &p->vGroups ); + Vec_IntFreeP( &p->vVar2Obj ); + Vec_IntFreeP( &p->vObj2Var ); + Vec_IntFreeP( &p->vVarBegs ); + Vec_IntFreeP( &p->vVarEnds ); + Vec_IntFreeP( &p->vNs2Glo ); + Vec_IntFreeP( &p->vGlo2Cs ); +// Vec_IntFreeP( &p->vHints ); + if ( p->dd ) + { + Extra_StopManager( p->dd ); + } + if ( p->ddG ) + { + if ( p->ddG->bReached ) + Cudd_RecursiveDeref( p->ddG, p->ddG->bReached ); + Extra_StopManager( p->ddG ); + } + Aig_ManStop( p->pAig ); + ABC_FREE( p ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Llb_Man_t * Llb_ManStart( Aig_Man_t * pAigGlo, Aig_Man_t * pAig, Gia_ParLlb_t * pPars ) +{ + Llb_Man_t * p; + Aig_ManCleanMarkA( pAig ); + p = ABC_CALLOC( Llb_Man_t, 1 ); + p->pAigGlo = pAigGlo; + p->pPars = pPars; + p->pAig = pAig; + p->vVar2Obj = Llb_ManMarkPivotNodes( p->pAig, pPars->fUsePivots ); + p->vObj2Var = Vec_IntInvert( p->vVar2Obj, -1 ); + Llb_ManPrepareVarMap( p ); + Llb_ManPrepareGroups( p ); + Aig_ManCleanMarkA( pAig ); + p->pMatrix = Llb_MtrCreate( p ); + p->pMatrix->pMan = p; + return p; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/llb/llbMatrix.c b/src/aig/llb/llbMatrix.c new file mode 100644 index 00000000..484ee690 --- /dev/null +++ b/src/aig/llb/llbMatrix.c @@ -0,0 +1,430 @@ +/**CFile**************************************************************** + + FileName [llbMatrix.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [BDD based reachability.] + + Synopsis [Partition clustering as a matrix problem.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: llbMatrix.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "llbInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +// 0123 nCols +// +---------------------> +// pi 0 | 111 row0 pRowSums[0] +// pi 1 | 1 11 row1 pRowSums[1] +// pi 2 | 1 11 row2 pRowSums[2] +// CS |1 1 +// CS |1 111 +// CS |111 111 +// int | 11111 +// int | 111 +// int | 111 +// int | 111 +// NS | 11 11 +// NS | 11 1 +// NS | 111 +// nRows | +// v +// cccc pColSums[0] +// oooo pColSums[1] +// llll pColSums[2] +// 0123 pColSums[3] + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Verify columns.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_MtrVerifyRowsAll( Llb_Mtr_t * p ) +{ + int iRow, iCol, Counter; + for ( iCol = 0; iCol < p->nCols; iCol++ ) + { + Counter = 0; + for ( iRow = 0; iRow < p->nRows; iRow++ ) + if ( p->pMatrix[iCol][iRow] == 1 ) + Counter++; + assert( Counter == p->pColSums[iCol] ); + } +} + +/**Function************************************************************* + + Synopsis [Verify columns.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_MtrVerifyColumnsAll( Llb_Mtr_t * p ) +{ + int iRow, iCol, Counter; + for ( iRow = 0; iRow < p->nRows; iRow++ ) + { + Counter = 0; + for ( iCol = 0; iCol < p->nCols; iCol++ ) + if ( p->pMatrix[iCol][iRow] == 1 ) + Counter++; + assert( Counter == p->pRowSums[iRow] ); + } +} + +/**Function************************************************************* + + Synopsis [Verify columns.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_MtrVerifyMatrix( Llb_Mtr_t * p ) +{ + Llb_MtrVerifyRowsAll( p ); + Llb_MtrVerifyColumnsAll( p ); +} + +/**Function************************************************************* + + Synopsis [Sort variables in the order of removal.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int * Llb_MtrFindVarOrder( Llb_Mtr_t * p ) +{ + int * pOrder, * pLast; + int i, k, fChanges, Temp; + pOrder = ABC_CALLOC( int, p->nRows ); + pLast = ABC_CALLOC( int, p->nRows ); + for ( i = 0; i < p->nRows; i++ ) + { + pOrder[i] = i; + for ( k = p->nCols - 1; k >= 0; k-- ) + if ( p->pMatrix[k][i] ) + { + pLast[i] = k; + break; + } + } + do + { + fChanges = 0; + for ( i = 0; i < p->nRows - 1; i++ ) + if ( pLast[i] > pLast[i+1] ) + { + Temp = pOrder[i]; + pOrder[i] = pOrder[i+1]; + pOrder[i+1] = Temp; + + Temp = pLast[i]; + pLast[i] = pLast[i+1]; + pLast[i+1] = Temp; + + fChanges = 1; + } + } + while ( fChanges ); + ABC_FREE( pLast ); + return pOrder; +} + +/**Function************************************************************* + + Synopsis [Returns type of a variable.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Llb_MtrVarName( Llb_Mtr_t * p, int iVar ) +{ + static char Buffer[10]; + if ( iVar < p->nPis ) + strcpy( Buffer, "pi" ); + else if ( iVar < p->nPis + p->nFfs ) + strcpy( Buffer, "CS" ); + else if ( iVar >= p->nRows - p->nFfs ) + strcpy( Buffer, "NS" ); + else + strcpy( Buffer, "int" ); + return Buffer; +} + +/**Function************************************************************* + + Synopsis [Creates one column with vars in the array.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_MtrPrint( Llb_Mtr_t * p, int fOrder ) +{ + int * pOrder = NULL; + int i, iRow, iCol; + if ( fOrder ) + pOrder = Llb_MtrFindVarOrder( p ); + for ( i = 0; i < p->nRows; i++ ) + { + iRow = pOrder ? pOrder[i] : i; + printf( "%3d : ", iRow ); + printf( "%3d ", p->pRowSums[iRow] ); + printf( "%3s ", Llb_MtrVarName(p, iRow) ); + for ( iCol = 0; iCol < p->nCols; iCol++ ) + printf( "%c", p->pMatrix[iCol][iRow] ? '*' : ' ' ); + printf( "\n" ); + } + ABC_FREE( pOrder ); +} + +/**Function************************************************************* + + Synopsis [Verify columns.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_MtrPrintMatrixStats( Llb_Mtr_t * p ) +{ + int iVar, iGrp, iGrp1, iGrp2, Span = 0, nCutSize = 0, nCutSizeMax = 0; + int * pGrp1 = ABC_CALLOC( int, p->nRows ); + int * pGrp2 = ABC_CALLOC( int, p->nRows ); + for ( iVar = 0; iVar < p->nRows; iVar++ ) + { + if ( p->pRowSums[iVar] == 0 ) + continue; + for ( iGrp1 = 0; iGrp1 < p->nCols; iGrp1++ ) + if ( p->pMatrix[iGrp1][iVar] == 1 ) + break; + for ( iGrp2 = p->nCols - 1; iGrp2 >= 0; iGrp2-- ) + if ( p->pMatrix[iGrp2][iVar] == 1 ) + break; + assert( iGrp1 <= iGrp2 ); + pGrp1[iVar] = iGrp1; + pGrp2[iVar] = iGrp2; + Span += iGrp2 - iGrp1; + } + // compute span + for ( iGrp = 0; iGrp < p->nCols; iGrp++ ) + { + for ( iVar = 0; iVar < p->nRows; iVar++ ) + if ( pGrp1[iVar] == iGrp ) + nCutSize++; + if ( nCutSizeMax < nCutSize ) + nCutSizeMax = nCutSize; + for ( iVar = 0; iVar < p->nRows; iVar++ ) + if ( pGrp2[iVar] == iGrp ) + nCutSize--; + } + ABC_FREE( pGrp1 ); + ABC_FREE( pGrp2 ); + printf( "[%4d x %4d] Life-span =%6.2f Max-cut =%5d\n", + p->nCols, p->nRows, 1.0*Span/p->nRows, nCutSizeMax ); + if ( nCutSize ) + Abc_Print( -1, "Cut size is not zero (%d).\n", nCutSize ); +} + + + +/**Function************************************************************* + + Synopsis [Starts the matrix representation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Llb_Mtr_t * Llb_MtrAlloc( int nPis, int nFfs, int nCols, int nRows ) +{ + Llb_Mtr_t * p; + int i; + p = ABC_CALLOC( Llb_Mtr_t, 1 ); + p->nPis = nPis; + p->nFfs = nFfs; + p->nRows = nRows; + p->nCols = nCols; + p->pRowSums = ABC_CALLOC( int, nRows ); + p->pColSums = ABC_CALLOC( int, nCols ); + p->pColGrps = ABC_CALLOC( Llb_Grp_t *, nCols ); + p->pMatrix = ABC_CALLOC( char *, nCols ); + for ( i = 0; i < nCols; i++ ) + p->pMatrix[i] = ABC_CALLOC( char, nRows ); + // partial product + p->pProdVars = ABC_CALLOC( char, nRows ); // variables in the partial product + p->pProdNums = ABC_CALLOC( int, nRows ); // var counts in the remaining partitions + return p; +} + +/**Function************************************************************* + + Synopsis [Stops the matrix representation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_MtrFree( Llb_Mtr_t * p ) +{ + int i; + ABC_FREE( p->pProdVars ); + ABC_FREE( p->pProdNums ); + for ( i = 0; i < p->nCols; i++ ) + ABC_FREE( p->pMatrix[i] ); + ABC_FREE( p->pRowSums ); + ABC_FREE( p->pColSums ); + ABC_FREE( p->pMatrix ); + ABC_FREE( p->pColGrps ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [Creates one column with vars in the array.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_MtrAddColumn( Llb_Mtr_t * p, Llb_Grp_t * pGrp ) +{ + Aig_Obj_t * pVar; + int i, iRow, iCol = pGrp->Id; + assert( iCol >= 0 && iCol < p->nCols ); + p->pColGrps[iCol] = pGrp; + Vec_PtrForEachEntry( Aig_Obj_t *, pGrp->vIns, pVar, i ) + { + iRow = Vec_IntEntry( pGrp->pMan->vObj2Var, Aig_ObjId(pVar) ); + assert( iRow >= 0 && iRow < p->nRows ); + p->pMatrix[iCol][iRow] = 1; + p->pColSums[iCol]++; + p->pRowSums[iRow]++; + } + Vec_PtrForEachEntry( Aig_Obj_t *, pGrp->vOuts, pVar, i ) + { + iRow = Vec_IntEntry( pGrp->pMan->vObj2Var, Aig_ObjId(pVar) ); + assert( iRow >= 0 && iRow < p->nRows ); + p->pMatrix[iCol][iRow] = 1; + p->pColSums[iCol]++; + p->pRowSums[iRow]++; + } +} + +/**Function************************************************************* + + Synopsis [Matrix reduce.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_MtrRemoveSingletonRows( Llb_Mtr_t * p ) +{ + int i, k; + for ( i = 0; i < p->nRows; i++ ) + if ( p->pRowSums[i] < 2 ) + { + p->pRowSums[i] = 0; + for ( k = 0; k < p->nCols; k++ ) + { + if ( p->pMatrix[k][i] == 1 ) + { + p->pMatrix[k][i] = 0; + p->pColSums[k]--; + } + } + } +} + +/**Function************************************************************* + + Synopsis [Matrix reduce.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Llb_Mtr_t * Llb_MtrCreate( Llb_Man_t * p ) +{ + Llb_Mtr_t * pMatrix; + Llb_Grp_t * pGroup; + int i; + pMatrix = Llb_MtrAlloc( Saig_ManPiNum(p->pAig), Saig_ManRegNum(p->pAig), + Vec_PtrSize(p->vGroups), Vec_IntSize(p->vVar2Obj) ); + Vec_PtrForEachEntry( Llb_Grp_t *, p->vGroups, pGroup, i ) + Llb_MtrAddColumn( pMatrix, pGroup ); +// Llb_MtrRemoveSingletonRows( pMatrix ); + return pMatrix; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/llb/llbPart.c b/src/aig/llb/llbPart.c new file mode 100644 index 00000000..41de27d8 --- /dev/null +++ b/src/aig/llb/llbPart.c @@ -0,0 +1,474 @@ +/**CFile**************************************************************** + + FileName [llbPart.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [BDD based reachability.] + + Synopsis [Initial partition computation.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: llbPart.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "llbInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Llb_Grp_t * Llb_ManGroupAlloc( Llb_Man_t * pMan ) +{ + Llb_Grp_t * p; + p = ABC_CALLOC( Llb_Grp_t, 1 ); + p->pMan = pMan; + p->vIns = Vec_PtrAlloc( 8 ); + p->vOuts = Vec_PtrAlloc( 8 ); + p->Id = Vec_PtrSize( pMan->vGroups ); + Vec_PtrPush( pMan->vGroups, p ); + return p; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_ManGroupStop( Llb_Grp_t * p ) +{ + if ( p == NULL ) + return; + Vec_PtrWriteEntry( p->pMan->vGroups, p->Id, NULL ); + Vec_PtrFreeP( &p->vIns ); + Vec_PtrFreeP( &p->vOuts ); + Vec_PtrFreeP( &p->vNodes ); + ABC_FREE( p ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_ManGroupCollect_rec( Aig_Man_t * pAig, Aig_Obj_t * pObj, Vec_Ptr_t * vNodes ) +{ + if ( Aig_ObjIsTravIdCurrent(pAig, pObj) ) + return; + Aig_ObjSetTravIdCurrent(pAig, pObj); + if ( Aig_ObjIsConst1(pObj) ) + return; + if ( Aig_ObjIsPo(pObj) ) + { + Llb_ManGroupCollect_rec( pAig, Aig_ObjFanin0(pObj), vNodes ); + return; + } + assert( Aig_ObjIsAnd(pObj) ); + Llb_ManGroupCollect_rec( pAig, Aig_ObjFanin0(pObj), vNodes ); + Llb_ManGroupCollect_rec( pAig, Aig_ObjFanin1(pObj), vNodes ); + Vec_PtrPush( vNodes, pObj ); +} + +/**Function************************************************************* + + Synopsis [Collects the support of MFFC.] + + Description [Returns the number of internal nodes in the MFFC.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Llb_ManGroupCollect( Llb_Grp_t * pGroup ) +{ + Vec_Ptr_t * vNodes; + Aig_Obj_t * pObj; + int i; + vNodes = Vec_PtrAlloc( 100 ); + Aig_ManIncrementTravId( pGroup->pMan->pAig ); + Vec_PtrForEachEntry( Aig_Obj_t *, pGroup->vIns, pObj, i ) + Aig_ObjSetTravIdCurrent( pGroup->pMan->pAig, pObj ); + Vec_PtrForEachEntry( Aig_Obj_t *, pGroup->vOuts, pObj, i ) + Aig_ObjSetTravIdPrevious( pGroup->pMan->pAig, pObj ); + Vec_PtrForEachEntry( Aig_Obj_t *, pGroup->vOuts, pObj, i ) + Llb_ManGroupCollect_rec( pGroup->pMan->pAig, pObj, vNodes ); + return vNodes; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_ManGroupCreate_rec( Aig_Man_t * pAig, Aig_Obj_t * pObj, Vec_Ptr_t * vSupp ) +{ + if ( Aig_ObjIsTravIdCurrent(pAig, pObj) ) + return; + Aig_ObjSetTravIdCurrent(pAig, pObj); + if ( Aig_ObjIsConst1(pObj) ) + return; + if ( pObj->fMarkA ) + { + Vec_PtrPush( vSupp, pObj ); + return; + } + assert( Aig_ObjIsAnd(pObj) ); + Llb_ManGroupCreate_rec( pAig, Aig_ObjFanin0(pObj), vSupp ); + Llb_ManGroupCreate_rec( pAig, Aig_ObjFanin1(pObj), vSupp ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Llb_Grp_t * Llb_ManGroupCreate( Llb_Man_t * pMan, Aig_Obj_t * pObj ) +{ + Llb_Grp_t * p; + assert( pObj->fMarkA == 1 ); + // derive group + p = Llb_ManGroupAlloc( pMan ); + Vec_PtrPush( p->vOuts, pObj ); + Aig_ManIncrementTravId( pMan->pAig ); + if ( Aig_ObjIsPo(pObj) ) + Llb_ManGroupCreate_rec( pMan->pAig, Aig_ObjFanin0(pObj), p->vIns ); + else + { + Llb_ManGroupCreate_rec( pMan->pAig, Aig_ObjFanin0(pObj), p->vIns ); + Llb_ManGroupCreate_rec( pMan->pAig, Aig_ObjFanin1(pObj), p->vIns ); + } + // derive internal objects + assert( p->vNodes == NULL ); + p->vNodes = Llb_ManGroupCollect( p ); + return p; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Llb_Grp_t * Llb_ManGroupCreateFirst( Llb_Man_t * pMan ) +{ + Llb_Grp_t * p; + Aig_Obj_t * pObj; + int i; + p = Llb_ManGroupAlloc( pMan ); + Saig_ManForEachLo( pMan->pAig, pObj, i ) + Vec_PtrPush( p->vOuts, pObj ); + return p; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Llb_Grp_t * Llb_ManGroupCreateLast( Llb_Man_t * pMan ) +{ + Llb_Grp_t * p; + Aig_Obj_t * pObj; + int i; + p = Llb_ManGroupAlloc( pMan ); + Saig_ManForEachLi( pMan->pAig, pObj, i ) + Vec_PtrPush( p->vIns, pObj ); + return p; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Llb_Grp_t * Llb_ManGroupsCombine( Llb_Grp_t * p1, Llb_Grp_t * p2 ) +{ + Llb_Grp_t * p; + Aig_Obj_t * pObj; + int i; + p = Llb_ManGroupAlloc( p1->pMan ); + // create inputs + Vec_PtrForEachEntry( Aig_Obj_t *, p1->vIns, pObj, i ) + Vec_PtrPush( p->vIns, pObj ); + Vec_PtrForEachEntry( Aig_Obj_t *, p2->vIns, pObj, i ) + Vec_PtrPushUnique( p->vIns, pObj ); + // create outputs + Vec_PtrForEachEntry( Aig_Obj_t *, p1->vOuts, pObj, i ) + Vec_PtrPush( p->vOuts, pObj ); + Vec_PtrForEachEntry( Aig_Obj_t *, p2->vOuts, pObj, i ) + Vec_PtrPushUnique( p->vOuts, pObj ); + + // derive internal objects + assert( p->vNodes == NULL ); + p->vNodes = Llb_ManGroupCollect( p ); + return p; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_ManGroupMarkNodes_rec( Aig_Man_t * p, Aig_Obj_t * pObj ) +{ + if ( Aig_ObjIsTravIdCurrent(p, pObj) ) + return; + if ( Aig_ObjIsTravIdPrevious(p, pObj) ) + { + Aig_ObjSetTravIdCurrent(p, pObj); + return; + } + Aig_ObjSetTravIdCurrent(p, pObj); + assert( Aig_ObjIsNode(pObj) ); + Llb_ManGroupMarkNodes_rec( p, Aig_ObjFanin0(pObj) ); + Llb_ManGroupMarkNodes_rec( p, Aig_ObjFanin1(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Creates group from two cuts derived by the flow computation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Llb_Grp_t * Llb_ManGroupCreateFromCuts( Llb_Man_t * pMan, Vec_Int_t * vCut1, Vec_Int_t * vCut2 ) +{ + Llb_Grp_t * p; + Aig_Obj_t * pObj; + int i; + p = Llb_ManGroupAlloc( pMan ); + + // mark Cut1 + Aig_ManIncrementTravId( pMan->pAig ); + Aig_ManForEachNodeVec( pMan->pAig, vCut1, pObj, i ) + Aig_ObjSetTravIdCurrent( pMan->pAig, pObj ); + // collect unmarked Cut2 + Aig_ManForEachNodeVec( pMan->pAig, vCut2, pObj, i ) + if ( !Aig_ObjIsTravIdCurrent( pMan->pAig, pObj ) ) + Vec_PtrPush( p->vOuts, pObj ); + + // mark nodes reachable from Cut2 + Aig_ManIncrementTravId( pMan->pAig ); + Aig_ManForEachNodeVec( pMan->pAig, vCut2, pObj, i ) + Llb_ManGroupMarkNodes_rec( pMan->pAig, pObj ); + // collect marked Cut1 + Aig_ManForEachNodeVec( pMan->pAig, vCut1, pObj, i ) + if ( Aig_ObjIsTravIdCurrent( pMan->pAig, pObj ) ) + Vec_PtrPush( p->vIns, pObj ); + + // derive internal objects + assert( p->vNodes == NULL ); + p->vNodes = Llb_ManGroupCollect( p ); + return p; +} + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_ManPrepareGroups( Llb_Man_t * pMan ) +{ + Aig_Obj_t * pObj; + int i; + assert( pMan->vGroups == NULL ); + pMan->vGroups = Vec_PtrAlloc( 1000 ); + Llb_ManGroupCreateFirst( pMan ); + Aig_ManForEachNode( pMan->pAig, pObj, i ) + { + if ( pObj->fMarkA ) + Llb_ManGroupCreate( pMan, pObj ); + } + Saig_ManForEachLi( pMan->pAig, pObj, i ) + { + if ( pObj->fMarkA ) + Llb_ManGroupCreate( pMan, pObj ); + } + Llb_ManGroupCreateLast( pMan ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_ManPrintSpan( Llb_Man_t * p ) +{ + Llb_Grp_t * pGroup; + Aig_Obj_t * pVar; + int i, k, Span = 0, SpanMax = 0; + Vec_PtrForEachEntry( Llb_Grp_t *, p->vGroups, pGroup, i ) + { + Vec_PtrForEachEntry( Aig_Obj_t *, pGroup->vIns, pVar, k ) + if ( Vec_IntEntry(p->vVarBegs, pVar->Id) == i ) + Span++; + Vec_PtrForEachEntry( Aig_Obj_t *, pGroup->vOuts, pVar, k ) + if ( Vec_IntEntry(p->vVarBegs, pVar->Id) == i ) + Span++; + + SpanMax = ABC_MAX( SpanMax, Span ); +printf( "%d ", Span ); + + Vec_PtrForEachEntry( Aig_Obj_t *, pGroup->vIns, pVar, k ) + if ( Vec_IntEntry(p->vVarEnds, pVar->Id) == i ) + Span--; + Vec_PtrForEachEntry( Aig_Obj_t *, pGroup->vOuts, pVar, k ) + if ( Vec_IntEntry(p->vVarEnds, pVar->Id) == i ) + Span--; + } +printf( "\n" ); +printf( "Max = %d\n", SpanMax ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Llb_ManGroupHasVar( Llb_Man_t * p, int iGroup, int iVar ) +{ + Llb_Grp_t * pGroup = (Llb_Grp_t *)Vec_PtrEntry( p->vGroups, iGroup ); + Aig_Obj_t * pObj; + int i; + Vec_PtrForEachEntry( Aig_Obj_t *, pGroup->vIns, pObj, i ) + if ( pObj->Id == iVar ) + return 1; + Vec_PtrForEachEntry( Aig_Obj_t *, pGroup->vOuts, pObj, i ) + if ( pObj->Id == iVar ) + return 1; + return 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_ManPrintHisto( Llb_Man_t * p ) +{ + Aig_Obj_t * pObj; + int i, k; + Aig_ManForEachObj( p->pAig, pObj, i ) + { + if ( Vec_IntEntry(p->vObj2Var, i) < 0 ) + continue; + printf( "%3d :", i ); + for ( k = 0; k < Vec_IntEntry(p->vVarBegs, i); k++ ) + printf( " " ); + for ( ; k <= Vec_IntEntry(p->vVarEnds, i); k++ ) + printf( "%c", Llb_ManGroupHasVar(p, k, i)? '*':'-' ); + printf( "\n" ); + } +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/llb/llbPivot.c b/src/aig/llb/llbPivot.c new file mode 100644 index 00000000..6a6fb321 --- /dev/null +++ b/src/aig/llb/llbPivot.c @@ -0,0 +1,254 @@ +/**CFile**************************************************************** + + FileName [llbPivot.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [BDD based reachability.] + + Synopsis [Determining pivot variables.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: llbPivot.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "llbInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Llb_ManTracePaths_rec( Aig_Man_t * p, Aig_Obj_t * pObj, Aig_Obj_t * pPivot ) +{ + Aig_Obj_t * pFanout; + int k, iFan; + if ( Aig_ObjIsTravIdPrevious(p, pObj) ) + return 0; + if ( Aig_ObjIsTravIdCurrent(p, pObj) ) + return 1; + if ( Saig_ObjIsLi(p, pObj) ) + return 0; + if ( Saig_ObjIsPo(p, pObj) ) + return 0; + if ( pObj == pPivot ) + return 1; + assert( Aig_ObjIsCand(pObj) ); + Aig_ObjForEachFanout( p, pObj, pFanout, iFan, k ) + if ( !Llb_ManTracePaths_rec( p, pFanout, pPivot ) ) + { + Aig_ObjSetTravIdPrevious(p, pObj); + return 0; + } + Aig_ObjSetTravIdCurrent(p, pObj); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Llb_ManTracePaths( Aig_Man_t * p, Aig_Obj_t * pPivot ) +{ + Aig_Obj_t * pObj; + int i, Counter = 0; + Aig_ManIncrementTravId( p ); // prev = visited with path to LI (value 0) + Aig_ManIncrementTravId( p ); // cur = visited w/o path to LI (value 1) + Saig_ManForEachLo( p, pObj, i ) + Counter += Llb_ManTracePaths_rec( p, pObj, pPivot ); + return Counter; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_ManTestCuts( Aig_Man_t * p ) +{ + Aig_Obj_t * pObj; + int i, Count; + Aig_ManFanoutStart( p ); + Aig_ManForEachNode( p, pObj, i ) + { + if ( Aig_ObjRefs(pObj) <= 1 ) + continue; + Count = Llb_ManTracePaths( p, pObj ); + printf( "Obj =%5d. Lev =%3d. Fanout =%5d. Count = %3d.\n", + i, Aig_ObjLevel(pObj), Aig_ObjRefs(pObj), Count ); + } + Aig_ManFanoutStop( p ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_ManLabelLiCones_rec( Aig_Man_t * p, Aig_Obj_t * pObj ) +{ + if ( pObj->fMarkB ) + return; + pObj->fMarkB = 1; + assert( Aig_ObjIsNode(pObj) ); + Llb_ManLabelLiCones_rec( p, Aig_ObjFanin0(pObj) ); + Llb_ManLabelLiCones_rec( p, Aig_ObjFanin1(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Determine starting cut-points.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_ManLabelLiCones( Aig_Man_t * p ) +{ + Aig_Obj_t * pObj; + int i; + // mark const and PIs + Aig_ManConst1(p)->fMarkB = 1; + Aig_ManForEachPi( p, pObj, i ) + pObj->fMarkB = 1; + // mark cones + Saig_ManForEachLi( p, pObj, i ) + Llb_ManLabelLiCones_rec( p, Aig_ObjFanin0(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Determine starting cut-points.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_ManMarkInternalPivots( Aig_Man_t * p ) +{ + Vec_Ptr_t * vMuxes; + Aig_Obj_t * pObj; + int i, Counter = 0; + + // remove refs due to MUXes + vMuxes = Aig_ManMuxesCollect( p ); + Aig_ManMuxesDeref( p, vMuxes ); + + // mark nodes feeding into LIs + Aig_ManCleanMarkB( p ); + Llb_ManLabelLiCones( p ); + + // mark internal nodes + Aig_ManFanoutStart( p ); + Aig_ManForEachNode( p, pObj, i ) + if ( pObj->fMarkB && pObj->nRefs > 1 ) + { + if ( Llb_ManTracePaths(p, pObj) > 0 ) + pObj->fMarkA = 1; + Counter++; + } + Aig_ManFanoutStop( p ); +// printf( "TracePath tried = %d.\n", Counter ); + + // mark nodes feeding into LIs + Aig_ManCleanMarkB( p ); + + // add refs due to MUXes + Aig_ManMuxesRef( p, vMuxes ); + Vec_PtrFree( vMuxes ); +} + +/**Function************************************************************* + + Synopsis [Determine starting cut-points.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Llb_ManMarkPivotNodes( Aig_Man_t * p, int fUseInternal ) +{ + Vec_Int_t * vVar2Obj; + Aig_Obj_t * pObj; + int i; + // mark inputs/outputs + Aig_ManForEachPi( p, pObj, i ) + pObj->fMarkA = 1; + Saig_ManForEachLi( p, pObj, i ) + pObj->fMarkA = 1; + + // mark internal pivot nodes + if ( fUseInternal ) + Llb_ManMarkInternalPivots( p ); + + // assign variable numbers + Aig_ManConst1(p)->fMarkA = 0; + vVar2Obj = Vec_IntAlloc( 100 ); + Aig_ManForEachPi( p, pObj, i ) + Vec_IntPush( vVar2Obj, Aig_ObjId(pObj) ); + Aig_ManForEachNode( p, pObj, i ) + if ( pObj->fMarkA ) + Vec_IntPush( vVar2Obj, Aig_ObjId(pObj) ); + Saig_ManForEachLi( p, pObj, i ) + Vec_IntPush( vVar2Obj, Aig_ObjId(pObj) ); + return vVar2Obj; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/llb/llbReach.c b/src/aig/llb/llbReach.c new file mode 100644 index 00000000..7c12a88c --- /dev/null +++ b/src/aig/llb/llbReach.c @@ -0,0 +1,620 @@ +/**CFile**************************************************************** + + FileName [llbReach.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [BDD based reachability.] + + Synopsis [Reachability analysis.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: llbReach.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "llbInt.h" +#include "extra.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Derives global BDD for the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * Llb_ManConstructOutBdd( Aig_Man_t * pAig, Aig_Obj_t * pNode, DdManager * dd ) +{ + DdNode * bBdd0, * bBdd1, * bFunc; + Vec_Ptr_t * vNodes; + Aig_Obj_t * pObj; + int i; + if ( Aig_ObjFanin0(pNode) == Aig_ManConst1(pAig) ) + return Cudd_NotCond( Cudd_ReadOne(dd), Aig_ObjFaninC0(pNode) ); + vNodes = Aig_ManDfsNodes( pAig, &pNode, 1 ); + assert( Vec_PtrSize(vNodes) > 0 ); + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) + { + if ( !Aig_ObjIsNode(pObj) ) + continue; + bBdd0 = Cudd_NotCond( Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0(pObj) ); + bBdd1 = Cudd_NotCond( Aig_ObjFanin1(pObj)->pData, Aig_ObjFaninC1(pObj) ); + pObj->pData = Cudd_bddAnd( dd, bBdd0, bBdd1 ); Cudd_Ref( (DdNode *)pObj->pData ); + } + bFunc = (DdNode *)pObj->pData; Cudd_Ref( bFunc ); + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) + { + if ( !Aig_ObjIsNode(pObj) ) + continue; + Cudd_RecursiveDeref( dd, (DdNode *)pObj->pData ); + } + Vec_PtrFree( vNodes ); + if ( Aig_ObjIsPo(pNode) ) + bFunc = Cudd_NotCond( bFunc, Aig_ObjFaninC0(pNode) ); + Cudd_Deref( bFunc ); + return bFunc; +} + +/**Function************************************************************* + + Synopsis [Derives BDD for the group.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * Llb_ManConstructGroupBdd( Llb_Man_t * p, Llb_Grp_t * pGroup ) +{ + Aig_Obj_t * pObj; + DdNode * bBdd0, * bBdd1, * bRes, * bXor, * bTemp; + int i; + Aig_ManConst1(p->pAig)->pData = Cudd_ReadOne( p->dd ); + Vec_PtrForEachEntry( Aig_Obj_t *, pGroup->vIns, pObj, i ) + pObj->pData = Cudd_bddIthVar( p->dd, Vec_IntEntry(p->vObj2Var, Aig_ObjId(pObj)) ); + Vec_PtrForEachEntry( Aig_Obj_t *, pGroup->vNodes, pObj, i ) + { + bBdd0 = Cudd_NotCond( Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0(pObj) ); + bBdd1 = Cudd_NotCond( Aig_ObjFanin1(pObj)->pData, Aig_ObjFaninC1(pObj) ); + pObj->pData = Cudd_bddAnd( p->dd, bBdd0, bBdd1 ); Cudd_Ref( (DdNode *)pObj->pData ); + } + bRes = Cudd_ReadOne( p->dd ); Cudd_Ref( bRes ); + Vec_PtrForEachEntry( Aig_Obj_t *, pGroup->vOuts, pObj, i ) + { + if ( Aig_ObjIsPo(pObj) ) + bBdd0 = Cudd_NotCond( Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0(pObj) ); + else + bBdd0 = (DdNode *)pObj->pData; + bBdd1 = Cudd_bddIthVar( p->dd, Vec_IntEntry(p->vObj2Var, Aig_ObjId(pObj)) ); + bXor = Cudd_bddXor( p->dd, bBdd0, bBdd1 ); Cudd_Ref( bXor ); + bRes = Cudd_bddAnd( p->dd, bTemp = bRes, Cudd_Not(bXor) ); Cudd_Ref( bRes ); + Cudd_RecursiveDeref( p->dd, bTemp ); + Cudd_RecursiveDeref( p->dd, bXor ); + } + Vec_PtrForEachEntry( Aig_Obj_t *, pGroup->vNodes, pObj, i ) + Cudd_RecursiveDeref( p->dd, (DdNode *)pObj->pData ); + Cudd_Deref( bRes ); + return bRes; +} + +/**Function************************************************************* + + Synopsis [Derives quantification cube.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * Llb_ManConstructQuantCubeIntern( Llb_Man_t * p, Llb_Grp_t * pGroup, int iGrpPlace ) +{ + Aig_Obj_t * pObj; + DdNode * bRes, * bTemp, * bVar; + int i, iGroupFirst, iGroupLast; + bRes = Cudd_ReadOne( p->dd ); Cudd_Ref( bRes ); + Vec_PtrForEachEntry( Aig_Obj_t *, pGroup->vIns, pObj, i ) + { + iGroupFirst = Vec_IntEntry(p->vVarBegs, Aig_ObjId(pObj)); + iGroupLast = Vec_IntEntry(p->vVarEnds, Aig_ObjId(pObj)); + assert( iGroupFirst <= iGroupLast ); + if ( iGroupFirst < iGroupLast ) + continue; + bVar = Cudd_bddIthVar( p->dd, Vec_IntEntry(p->vObj2Var, Aig_ObjId(pObj)) ); + bRes = Cudd_bddAnd( p->dd, bTemp = bRes, bVar ); Cudd_Ref( bRes ); + Cudd_RecursiveDeref( p->dd, bTemp ); + } + Vec_PtrForEachEntry( Aig_Obj_t *, pGroup->vOuts, pObj, i ) + { + iGroupFirst = Vec_IntEntry(p->vVarBegs, Aig_ObjId(pObj)); + iGroupLast = Vec_IntEntry(p->vVarEnds, Aig_ObjId(pObj)); + assert( iGroupFirst <= iGroupLast ); + if ( iGroupFirst < iGroupLast ) + continue; + bVar = Cudd_bddIthVar( p->dd, Vec_IntEntry(p->vObj2Var, Aig_ObjId(pObj)) ); + bRes = Cudd_bddAnd( p->dd, bTemp = bRes, bVar ); Cudd_Ref( bRes ); + Cudd_RecursiveDeref( p->dd, bTemp ); + } + Cudd_Deref( bRes ); + return bRes; +} + +/**Function************************************************************* + + Synopsis [Derives quantification cube.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * Llb_ManConstructQuantCube( Llb_Man_t * p, Llb_Grp_t * pGroup, int iGrpPlace ) +{ + Aig_Obj_t * pObj; + DdNode * bRes, * bTemp, * bVar; + int i, iGroupLast; + bRes = Cudd_ReadOne( p->dd ); Cudd_Ref( bRes ); + Vec_PtrForEachEntry( Aig_Obj_t *, pGroup->vIns, pObj, i ) + { + iGroupLast = Vec_IntEntry(p->vVarEnds, Aig_ObjId(pObj)); + assert( iGroupLast >= iGrpPlace ); + if ( iGroupLast > iGrpPlace ) + continue; + bVar = Cudd_bddIthVar( p->dd, Vec_IntEntry(p->vObj2Var, Aig_ObjId(pObj)) ); + bRes = Cudd_bddAnd( p->dd, bTemp = bRes, bVar ); Cudd_Ref( bRes ); + Cudd_RecursiveDeref( p->dd, bTemp ); + } + Vec_PtrForEachEntry( Aig_Obj_t *, pGroup->vOuts, pObj, i ) + { + iGroupLast = Vec_IntEntry(p->vVarEnds, Aig_ObjId(pObj)); + assert( iGroupLast >= iGrpPlace ); + if ( iGroupLast > iGrpPlace ) + continue; + bVar = Cudd_bddIthVar( p->dd, Vec_IntEntry(p->vObj2Var, Aig_ObjId(pObj)) ); + bRes = Cudd_bddAnd( p->dd, bTemp = bRes, bVar ); Cudd_Ref( bRes ); + Cudd_RecursiveDeref( p->dd, bTemp ); + } + Cudd_Deref( bRes ); + return bRes; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * Llb_ManComputeInitState( Llb_Man_t * p, DdManager * dd ) +{ + Aig_Obj_t * pObj; + DdNode * bRes, * bVar, * bTemp; + int i, iVar; + bRes = Cudd_ReadOne( dd ); Cudd_Ref( bRes ); + Saig_ManForEachLo( p->pAig, pObj, i ) + { + iVar = (dd == p->ddG) ? i : Vec_IntEntry(p->vObj2Var, Aig_ObjId(pObj)); + bVar = Cudd_bddIthVar( dd, iVar ); + bRes = Cudd_bddAnd( dd, bTemp = bRes, Cudd_Not(bVar) ); Cudd_Ref( bRes ); + Cudd_RecursiveDeref( dd, bTemp ); + } + Cudd_Deref( bRes ); + return bRes; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * Llb_ManComputeImage( Llb_Man_t * p, DdNode * bInit ) +{ + int fCheckSupport = 0; + Llb_Grp_t * pGroup; + DdNode * bImage, * bGroup, * bCube, * bTemp; + int i; + bImage = bInit; Cudd_Ref( bImage ); + for ( i = 1; i < p->pMatrix->nCols-1; i++ ) + { + // compute group BDD + pGroup = p->pMatrix->pColGrps[i]; + bGroup = Llb_ManConstructGroupBdd( p, pGroup ); Cudd_Ref( bGroup ); + // quantify variables appearing only in this group + bCube = Llb_ManConstructQuantCubeIntern( p, pGroup, i ); Cudd_Ref( bCube ); + bGroup = Cudd_bddExistAbstract( p->dd, bTemp = bGroup, bCube ); Cudd_Ref( bGroup ); + Cudd_RecursiveDeref( p->dd, bTemp ); + Cudd_RecursiveDeref( p->dd, bCube ); + // perform partial product + bCube = Llb_ManConstructQuantCube( p, pGroup, i ); Cudd_Ref( bCube ); + bImage = Cudd_bddAndAbstract( p->dd, bTemp = bImage, bGroup, bCube ); Cudd_Ref( bImage ); + Cudd_RecursiveDeref( p->dd, bTemp ); + Cudd_RecursiveDeref( p->dd, bGroup ); + Cudd_RecursiveDeref( p->dd, bCube ); + // chech runtime + if ( p->pPars->TimeTarget && clock() >= p->pPars->TimeTarget ) + { + Cudd_RecursiveDeref( p->dd, bImage ); + return NULL; + } + } + + // make sure image depends on next state vars + if ( fCheckSupport ) + { + bCube = Cudd_Support( p->dd, bImage ); Cudd_Ref( bCube ); + for ( bTemp = bCube; bTemp != p->dd->one; bTemp = cuddT(bTemp) ) + { + int ObjId = Vec_IntEntry( p->vVar2Obj, bTemp->index ); + Aig_Obj_t * pObj = Aig_ManObj( p->pAig, ObjId ); + if ( !Saig_ObjIsLi(p->pAig, pObj) ) + printf( "Var %d assigned to obj %d that is not LI\n", bTemp->index, ObjId ); + } + Cudd_RecursiveDeref( p->dd, bCube ); + } + Cudd_Deref( bImage ); + return bImage; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * Llb_ManCreateConstraints( Llb_Man_t * p, Vec_Int_t * vHints, int fUseNsVars ) +{ + DdNode * bConstr, * bFunc, * bTemp; + Aig_Obj_t * pObj; + int i, Entry; + if ( vHints == NULL ) + return Cudd_ReadOne( p->dd ); + assert( Aig_ManPiNum(p->pAig) == Aig_ManPiNum(p->pAigGlo) ); + // assign const and PI nodes to the original AIG + Aig_ManCleanData( p->pAig ); + Aig_ManConst1( p->pAig )->pData = Cudd_ReadOne( p->dd ); + Saig_ManForEachPi( p->pAig, pObj, i ) + pObj->pData = Cudd_bddIthVar( p->dd, Vec_IntEntry(p->vObj2Var,Aig_ObjId(pObj)) ); + Saig_ManForEachLo( p->pAig, pObj, i ) + { + if ( fUseNsVars ) + Entry = Vec_IntEntry( p->vObj2Var, Aig_ObjId(Saig_ObjLoToLi(p->pAig, pObj)) ); + else + Entry = Vec_IntEntry( p->vObj2Var, Aig_ObjId(pObj) ); + pObj->pData = Cudd_bddIthVar( p->dd, Entry ); + } + // transfer them to the global AIG + Aig_ManCleanData( p->pAigGlo ); + Aig_ManConst1( p->pAigGlo )->pData = Cudd_ReadOne( p->dd ); + Aig_ManForEachPi( p->pAigGlo, pObj, i ) + pObj->pData = Aig_ManPi(p->pAig, i)->pData; + // derive consraints + bConstr = Cudd_ReadOne( p->dd ); Cudd_Ref( bConstr ); + Vec_IntForEachEntry( vHints, Entry, i ) + { + if ( Entry != 0 && Entry != 1 ) + continue; + bFunc = Llb_ManConstructOutBdd( p->pAigGlo, Aig_ManObj(p->pAigGlo, i), p->dd ); Cudd_Ref( bFunc ); + bFunc = Cudd_NotCond( bFunc, Entry ); // restrict to not constraint + // make the product + bConstr = Cudd_bddAnd( p->dd, bTemp = bConstr, bFunc ); Cudd_Ref( bConstr ); + Cudd_RecursiveDeref( p->dd, bTemp ); + Cudd_RecursiveDeref( p->dd, bFunc ); + } + Cudd_Deref( bConstr ); + return bConstr; +} + +/**Function************************************************************* + + Synopsis [Perform reachability with hints and returns reached states in ppGlo.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Llb_ManReachability( Llb_Man_t * p, Vec_Int_t * vHints, DdManager ** pddGlo ) +{ + int fCheckOutputs = !p->pPars->fSkipOutCheck; + int fInternalReorder = 0; + int * pNs2Glo = Vec_IntArray( p->vNs2Glo ); + int * pGlo2Cs = Vec_IntArray( p->vGlo2Cs ); + DdNode * bCurrent, * bReached, * bNext, * bTemp, * bCube; + DdNode * bConstrCs, * bConstrNs; + int clk2, clk = clock(), nIters, nBddSize = 0, iOutFail = -1; + int nThreshold = 10000; + + // compute time to stop + if ( p->pPars->TimeLimit ) + p->pPars->TimeTarget = clock() + p->pPars->TimeLimit * CLOCKS_PER_SEC; + else + p->pPars->TimeTarget = 0; + + // define variable limits + Llb_ManPrepareVarLimits( p ); + + // start the managers + assert( p->dd == NULL ); + assert( p->ddG == NULL ); + p->dd = Cudd_Init( Vec_IntSize(p->vVar2Obj), 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 ); + if ( pddGlo && *pddGlo ) + p->ddG = *pddGlo, *pddGlo = NULL; + else + p->ddG = Cudd_Init( Aig_ManRegNum(p->pAig), 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 ); + + if ( p->pPars->fReorder ) + { + Cudd_AutodynEnable( p->dd, CUDD_REORDER_SYMM_SIFT ); + Cudd_AutodynEnable( p->ddG, CUDD_REORDER_SYMM_SIFT ); + } + else + { + Cudd_AutodynDisable( p->dd ); + Cudd_AutodynDisable( p->ddG ); + } + + // derive constraints + bConstrCs = Llb_ManCreateConstraints( p, vHints, 0 ); Cudd_Ref( bConstrCs ); + bConstrNs = Llb_ManCreateConstraints( p, vHints, 1 ); Cudd_Ref( bConstrNs ); +//Extra_bddPrint( p->dd, bConstrCs ); printf( "\n" ); +//Extra_bddPrint( p->dd, bConstrNs ); printf( "\n" ); + + // perform reachability analysis + // compute the starting set of states + if ( p->ddG->bReached ) + { + bReached = p->ddG->bReached; p->ddG->bReached = NULL; + bCurrent = Extra_TransferPermute( p->ddG, p->dd, bReached, pGlo2Cs ); Cudd_Ref( bCurrent ); + } + else + { + bReached = Llb_ManComputeInitState( p, p->ddG ); Cudd_Ref( bReached ); + bCurrent = Llb_ManComputeInitState( p, p->dd ); Cudd_Ref( bCurrent ); + } +//Extra_bddPrintSupport( p->ddG, bReached ); printf( "\n" ); +//Extra_bddPrintSupport( p->dd, bCurrent ); printf( "\n" ); + +//Extra_bddPrintSupport( p->dd, bCurrent ); printf( "\n" ); + for ( nIters = 0; nIters < p->pPars->nIterMax; nIters++ ) + { + clk2 = clock(); + // check the runtime limit + if ( p->pPars->TimeLimit && clock() >= p->pPars->TimeTarget ) + { + if ( !p->pPars->fSilent ) + printf( "Reached timeout during image computation (%d seconds).\n", p->pPars->TimeLimit ); + p->pPars->iFrame = nIters - 1; + Cudd_RecursiveDeref( p->dd, bCurrent ); bCurrent = NULL; + Cudd_RecursiveDeref( p->dd, bConstrCs ); bConstrCs = NULL; + Cudd_RecursiveDeref( p->dd, bConstrNs ); bConstrNs = NULL; + Cudd_RecursiveDeref( p->ddG, bReached ); bReached = NULL; + return -1; + } + + // check outputs + if ( fCheckOutputs ) + { + Aig_Obj_t * pObj; + int i; + Aig_ManConst1( p->pAigGlo )->pData = Cudd_ReadOne( p->dd ); + Aig_ManForEachPi( p->pAig, pObj, i ) + pObj->pData = Cudd_bddIthVar( p->dd, Vec_IntEntry(p->vObj2Var,Aig_ObjId(pObj)) ); + Aig_ManForEachPi( p->pAigGlo, pObj, i ) + pObj->pData = Aig_ManPi(p->pAig, i)->pData; + +//Extra_bddPrintSupport( p->dd, bCurrent ); printf( "\n" ); + for ( iOutFail = 0; iOutFail < Saig_ManPoNum(p->pAig); iOutFail++ ) + { + DdNode * bFunc, * bInter; + bFunc = Llb_ManConstructOutBdd( p->pAigGlo, Aig_ManPo(p->pAigGlo, iOutFail), p->dd ); Cudd_Ref( bFunc ); +//Extra_bddPrint( p->dd, bFunc ); printf( "\n" ); + if ( Cudd_bddLeq( p->dd, bCurrent, Cudd_Not(bFunc) ) ) // no cex + { + Cudd_RecursiveDeref( p->dd, bFunc ); + continue; + } + bInter = Cudd_bddIntersect( p->dd, bCurrent, bFunc ); Cudd_Ref( bInter ); + assert( p->pAig->pSeqModel == NULL ); + p->pAig->pSeqModel = Llb_ManDeriveCex( p, bInter, iOutFail, nIters ); + Cudd_RecursiveDeref( p->dd, bInter ); + Cudd_RecursiveDeref( p->dd, bFunc ); + break; + } + if ( iOutFail < Saig_ManPoNum(p->pAig) ) + { + if ( !p->pPars->fSilent ) + printf( "Output %d was asserted in frame %d (use \"write_counter\" to dump a witness). ", iOutFail, nIters ); + Cudd_RecursiveDeref( p->ddG, bReached ); bReached = NULL; + Cudd_RecursiveDeref( p->dd, bCurrent ); bCurrent = NULL; + p->pPars->iFrame = nIters; + break; + } + } + + // restrict reachable states using constraints + if ( vHints ) + { + bCurrent = Cudd_bddAnd( p->dd, bTemp = bCurrent, bConstrCs ); Cudd_Ref( bCurrent ); + Cudd_RecursiveDeref( p->dd, bTemp ); + } + + // quantify variables appearing only in the init state + bCube = Llb_ManConstructQuantCubeIntern( p, (Llb_Grp_t *)Vec_PtrEntry(p->vGroups,0), 0 ); Cudd_Ref( bCube ); + bCurrent = Cudd_bddExistAbstract( p->dd, bTemp = bCurrent, bCube ); Cudd_Ref( bCurrent ); + Cudd_RecursiveDeref( p->dd, bTemp ); + Cudd_RecursiveDeref( p->dd, bCube ); + + // compute the next states + bNext = Llb_ManComputeImage( p, bCurrent ); + if ( bNext == NULL ) + { + if ( !p->pPars->fSilent ) + printf( "Reached timeout during image computation (%d seconds).\n", p->pPars->TimeLimit ); + p->pPars->iFrame = nIters - 1; + Cudd_RecursiveDeref( p->dd, bCurrent ); bCurrent = NULL; + Cudd_RecursiveDeref( p->dd, bConstrCs ); bConstrCs = NULL; + Cudd_RecursiveDeref( p->dd, bConstrNs ); bConstrNs = NULL; + Cudd_RecursiveDeref( p->ddG, bReached ); bReached = NULL; + return -1; + } + Cudd_Ref( bNext ); + Cudd_RecursiveDeref( p->dd, bCurrent ); bCurrent = NULL; + + // restrict reachable states using constraints + if ( vHints ) + { + bNext = Cudd_bddAnd( p->dd, bTemp = bNext, bConstrNs ); Cudd_Ref( bNext ); + Cudd_RecursiveDeref( p->dd, bTemp ); + } +//Extra_bddPrintSupport( p->dd, bNext ); printf( "\n" ); + + // remap these states into the current state vars + bNext = Extra_TransferPermute( p->dd, p->ddG, bTemp = bNext, pNs2Glo ); Cudd_Ref( bNext ); + Cudd_RecursiveDeref( p->dd, bTemp ); + + // check if there are any new states + if ( Cudd_bddLeq( p->ddG, bNext, bReached ) ) // implication = no new states + { + Cudd_RecursiveDeref( p->ddG, bNext ); bNext = NULL; + break; + } + + // check the BDD size + nBddSize = Cudd_DagSize(bNext); + if ( nBddSize > p->pPars->nBddMax ) + { + Cudd_RecursiveDeref( p->ddG, bNext ); bNext = NULL; + break; + } + + // get the new states + bCurrent = Cudd_bddAnd( p->ddG, bNext, Cudd_Not(bReached) ); Cudd_Ref( bCurrent ); + // minimize the new states with the reached states +// bCurrent = Cudd_bddConstrain( p->ddG, bTemp = bCurrent, Cudd_Not(bReached) ); Cudd_Ref( bCurrent ); +// bCurrent = Cudd_bddRestrict( p->ddG, bTemp = bCurrent, Cudd_Not(bReached) ); Cudd_Ref( bCurrent ); +// Cudd_RecursiveDeref( p->ddG, bTemp ); +//printf( "Initial BDD =%7d. Constrained BDD =%7d.\n", Cudd_DagSize(bTemp), Cudd_DagSize(bCurrent) ); + // remap these states into the current state vars + bCurrent = Extra_TransferPermute( p->ddG, p->dd, bTemp = bCurrent, pGlo2Cs ); Cudd_Ref( bCurrent ); + Cudd_RecursiveDeref( p->ddG, bTemp ); + + // add to the reached states + bReached = Cudd_bddOr( p->ddG, bTemp = bReached, bNext ); Cudd_Ref( bReached ); + Cudd_RecursiveDeref( p->ddG, bTemp ); + Cudd_RecursiveDeref( p->ddG, bNext ); + bNext = NULL; + + if ( p->pPars->fVerbose ) + { + fprintf( stdout, "F =%3d : ", nIters ); + fprintf( stdout, "Image =%6d ", nBddSize ); + fprintf( stdout, "%8d (%4d %3d) ", + Cudd_ReadKeys(p->dd), Cudd_ReadReorderings(p->dd), Cudd_ReadGarbageCollections(p->dd) ); + fprintf( stdout, "Reach =%6d ", Cudd_DagSize(bReached) ); + fprintf( stdout, "%8d (%4d %3d) ", + Cudd_ReadKeys(p->ddG), Cudd_ReadReorderings(p->ddG), Cudd_ReadGarbageCollections(p->ddG) ); + } + if ( fInternalReorder && p->pPars->fReorder && nBddSize > nThreshold ) + { + if ( p->pPars->fVerbose ) + fprintf( stdout, "Reordering... Before = %5d. ", Cudd_DagSize(bReached) ); + Cudd_ReduceHeap( p->dd, CUDD_REORDER_SYMM_SIFT, 100 ); +// Cudd_AutodynDisable( p->dd ); + if ( p->pPars->fVerbose ) + fprintf( stdout, "After = %5d.\r", Cudd_DagSize(bReached) ); + nThreshold *= 2; + } + if ( p->pPars->fVerbose ) +// fprintf( stdout, "\r" ); +// fprintf( stdout, "\n" ); + Abc_PrintTime( 1, "T", clock() - clk2 ); + } + Cudd_RecursiveDeref( p->dd, bConstrCs ); bConstrCs = NULL; + Cudd_RecursiveDeref( p->dd, bConstrNs ); bConstrNs = NULL; + if ( bReached == NULL ) + return 0; // reachable + assert( bCurrent == NULL ); + if ( bCurrent ) + Cudd_RecursiveDeref( p->dd, bCurrent ); + // report the stats + if ( p->pPars->fVerbose ) + { + double nMints = Cudd_CountMinterm(p->ddG, bReached, Saig_ManRegNum(p->pAig) ); + if ( nIters >= p->pPars->nIterMax || nBddSize > p->pPars->nBddMax ) + fprintf( stdout, "Reachability analysis is stopped after %d frames.\n", nIters ); + else + fprintf( stdout, "Reachability analysis completed after %d frames.\n", nIters ); + fprintf( stdout, "Reachable states = %.0f. (Ratio = %.4f %%)\n", nMints, 100.0*nMints/pow(2.0, Saig_ManRegNum(p->pAig)) ); + fflush( stdout ); + } + if ( nIters >= p->pPars->nIterMax || nBddSize > p->pPars->nBddMax ) + { + if ( !p->pPars->fSilent ) + printf( "Verified only for states reachable in %d frames. ", nIters ); + Cudd_RecursiveDeref( p->ddG, bReached ); + return -1; // undecided + } + if ( pddGlo ) + { + assert( p->ddG->bReached == NULL ); + p->ddG->bReached = bReached; bReached = NULL; + assert( *pddGlo == NULL ); + *pddGlo = p->ddG; p->ddG = NULL; + } + else + Cudd_RecursiveDeref( p->ddG, bReached ); + if ( !p->pPars->fSilent ) + printf( "The miter is proved unreachable after %d iterations. ", nIters ); + p->pPars->iFrame = nIters - 1; + return 1; // unreachable +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/llb/llbSched.c b/src/aig/llb/llbSched.c new file mode 100644 index 00000000..0f7b9fab --- /dev/null +++ b/src/aig/llb/llbSched.c @@ -0,0 +1,257 @@ +/**CFile**************************************************************** + + FileName [llb.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [BDD based reachability.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: llb.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "llbInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Swaps two rows.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_MtrSwapColumns( Llb_Mtr_t * p, int iCol1, int iCol2 ) +{ + Llb_Grp_t * pGemp; + char * pTemp; + int iTemp; + assert( iCol1 >= 0 && iCol1 < p->nCols ); + assert( iCol2 >= 0 && iCol2 < p->nCols ); + if ( iCol1 == iCol2 ) + return; + assert( iCol1 != iCol2 ); + // swap col groups + pGemp = p->pColGrps[iCol1]; + p->pColGrps[iCol1] = p->pColGrps[iCol2]; + p->pColGrps[iCol2] = pGemp; + // swap col vectors + pTemp = p->pMatrix[iCol1]; + p->pMatrix[iCol1] = p->pMatrix[iCol2]; + p->pMatrix[iCol2] = pTemp; + // swap col sums + iTemp = p->pColSums[iCol1]; + p->pColSums[iCol1] = p->pColSums[iCol2]; + p->pColSums[iCol2] = iTemp; +} + +/**Function************************************************************* + + Synopsis [Find columns which brings as few vars as possible.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Llb_MtrFindBestColumn( Llb_Mtr_t * p, int iGrpStart ) +{ + int Cost, Cost2, CostBest = ABC_INFINITY, Cost2Best = ABC_INFINITY; + int WeightCur, WeightBest = -ABC_INFINITY, iGrp, iGrpBest = -1; + int k, c, iVar, Counter; + // find partition that reduces partial product as much as possible + for ( iVar = 0; iVar < p->nRows - p->nFfs; iVar++ ) + { + if ( p->pRowSums[iVar] < 2 ) + continue; + // look at present variables that can be quantified + if ( !(p->pProdVars[iVar] == 1 && p->pProdNums[iVar] == 1) ) + continue; + // check that it appears in one partition only + Counter = 0; + for ( c = iGrpStart; c < p->nCols-1; c++ ) + if ( p->pMatrix[c][iVar] == 1 ) + { + iGrp = c; + Counter++; + } + assert( Counter == 1 ); + if ( Counter != 1 ) + Abc_Print( -1, "Llb_MtrFindBestColumn() Internal error!\n" ); + // find weight of this column + WeightCur = 0; + for ( k = 0; k < p->nRows; k++ ) + { + // increase weight if variable k will be quantified from partial product + if ( p->pProdVars[k] == 1 && p->pMatrix[iGrp][k] == 1 && p->pProdNums[k] == 1 ) + WeightCur += 2; + // decrease weight if variable k will be added to partial product + if ( p->pProdVars[k] == 0 && p->pMatrix[iGrp][k] == 1 ) + WeightCur--; + } + if ( WeightCur > 0 && WeightBest < WeightCur ) + { + WeightBest = WeightCur; + iGrpBest = iGrp; + } + } + if ( iGrpBest >= 0 ) + return iGrpBest; + // could not find the group with any vars to quantify + // select the group that contains as few extra variables as possible + // if there is a tie, select variables that appear in less groups than others + for ( iGrp = iGrpStart; iGrp < p->nCols-1; iGrp++ ) + { + Cost = Cost2 = 0; + for ( k = 0; k < p->nRows; k++ ) + if ( p->pProdVars[k] == 0 && p->pMatrix[iGrp][k] == 1 ) + { + Cost++; + Cost2 += p->pProdNums[k]; + } + if ( CostBest > Cost || + (CostBest == Cost && Cost2 > Cost2Best) ) + { + CostBest = Cost; + Cost2Best = Cost2; + iGrpBest = iGrp; + } + } + return iGrpBest; +} + +/**Function************************************************************* + + Synopsis [Returns the number of variables that will be saved.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_MtrUseSelectedColumn( Llb_Mtr_t * p, int iCol ) +{ + int iVar; + assert( iCol >= 1 && iCol < p->nCols - 1 ); + for ( iVar = 0; iVar < p->nRows; iVar++ ) + { + if ( p->pMatrix[iCol][iVar] == 0 ) + continue; + if ( p->pProdVars[iVar] == 1 && p->pProdNums[iVar] == 1 ) + { + p->pProdVars[iVar] = 0; + p->pProdNums[iVar] = 0; + continue; + } + if ( p->pProdVars[iVar] == 0 ) + { + p->pProdVars[iVar] = 1; + p->pProdNums[iVar] = p->pRowSums[iVar]; + } + p->pProdNums[iVar]--; + assert( p->pProdNums[iVar] >= 0 ); + if ( p->pProdNums[iVar] < 0 ) + Abc_Print( -1, "Llb_MtrUseSelectedColumn() Internal error!\n" ); + } +} + +/**Function************************************************************* + + Synopsis [Verify columns.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_MtrVerifyColumns( Llb_Mtr_t * p, int iGrpStart ) +{ + int iVar, iGrp, Counter; + for ( iVar = 0; iVar < p->nRows; iVar++ ) + { + if ( p->pProdVars[iVar] == 0 ) + continue; + Counter = 0; + for ( iGrp = iGrpStart; iGrp < p->nCols; iGrp++ ) + if ( p->pMatrix[iGrp][iVar] == 1 ) + Counter++; + assert( Counter == p->pProdNums[iVar] ); + if ( Counter != p->pProdNums[iVar] ) + Abc_Print( -1, "Llb_MtrVerifyColumns(): Internal error.\n" ); + } +} + +/**Function************************************************************* + + Synopsis [Matrix reduce.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Llb_MtrSchedule( Llb_Mtr_t * p ) +{ + int iGrp, iGrpBest, i; + // start partial product + for ( i = 0; i < p->nRows; i++ ) + { + if ( i >= p->nPis && i < p->nPis + p->nFfs ) + { + p->pProdVars[i] = 1; + p->pProdNums[i] = p->pRowSums[i] - 1; + } + else + { + p->pProdVars[i] = 0; + p->pProdNums[i] = p->pRowSums[i]; + } + } + // order the partitions + Llb_MtrVerifyMatrix( p ); + for ( iGrp = 1; iGrp < p->nCols-1; iGrp++ ) + { + Llb_MtrVerifyColumns( p, iGrp ); + iGrpBest = Llb_MtrFindBestColumn( p, iGrp ); + Llb_MtrUseSelectedColumn( p, iGrpBest ); + Llb_MtrSwapColumns( p, iGrp, iGrpBest ); + } + Llb_MtrVerifyMatrix( p ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/llb/module.make b/src/aig/llb/module.make new file mode 100644 index 00000000..60b6ce07 --- /dev/null +++ b/src/aig/llb/module.make @@ -0,0 +1,11 @@ +SRC += src/aig/llb/llbCex.c \ + src/aig/llb/llbCluster.c \ + src/aig/llb/llbConstr.c \ + src/aig/llb/llbCore.c \ + src/aig/llb/llbHint.c \ + src/aig/llb/llbMan.c \ + src/aig/llb/llbMatrix.c \ + src/aig/llb/llbPart.c \ + src/aig/llb/llbPivot.c \ + src/aig/llb/llbReach.c \ + src/aig/llb/llbSched.c diff --git a/src/aig/mem/mem.c b/src/aig/mem/mem.c index 99d918e9..28d7e86e 100644 --- a/src/aig/mem/mem.c +++ b/src/aig/mem/mem.c @@ -22,9 +22,12 @@ #include <stdlib.h> #include <string.h> #include <assert.h> -#include "abc_global.h" + #include "mem.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -36,7 +39,7 @@ struct Mem_Fixed_t_ int nEntriesAlloc; // the total number of entries allocated int nEntriesUsed; // the number of entries in use int nEntriesMax; // the max number of entries in use - char * pEntriesFree; // the linked list of ABC_FREE entries + char * pEntriesFree; // the linked list of free entries // this is where the memory is stored int nChunkSize; // the size of one chunk @@ -53,8 +56,8 @@ struct Mem_Flex_t_ { // information about individual entries int nEntriesUsed; // the number of entries allocated - char * pCurrent; // the current pointer to ABC_FREE memory - char * pEnd; // the first entry outside the ABC_FREE memory + char * pCurrent; // the current pointer to free memory + char * pEnd; // the first entry outside the free memory // this is where the memory is stored int nChunkSize; // the size of one chunk @@ -164,7 +167,7 @@ char * Mem_FixedEntryFetch( Mem_Fixed_t * p ) char * pTemp; int i; - // check if there are still ABC_FREE entries + // check if there are still free entries if ( p->nEntriesUsed == p->nEntriesAlloc ) { // need to allocate more entries assert( p->pEntriesFree == NULL ); @@ -193,7 +196,7 @@ char * Mem_FixedEntryFetch( Mem_Fixed_t * p ) p->nEntriesUsed++; if ( p->nEntriesMax < p->nEntriesUsed ) p->nEntriesMax = p->nEntriesUsed; - // return the first entry in the ABC_FREE entry list + // return the first entry in the free entry list pTemp = p->pEntriesFree; p->pEntriesFree = *((char **)pTemp); return pTemp; @@ -214,7 +217,7 @@ void Mem_FixedEntryRecycle( Mem_Fixed_t * p, char * pEntry ) { // decrement the counter of used entries p->nEntriesUsed--; - // add the entry to the linked list of ABC_FREE entries + // add the entry to the linked list of free entries *((char **)pEntry) = p->pEntriesFree; p->pEntriesFree = pEntry; } @@ -248,7 +251,7 @@ void Mem_FixedRestart( Mem_Fixed_t * p ) } // set the last link *((char **)pTemp) = NULL; - // set the ABC_FREE entry list + // set the free entry list p->pEntriesFree = p->pChunks[0]; // set the correct statistics p->nMemoryAlloc = p->nEntrySize * p->nChunkSize; @@ -366,7 +369,7 @@ void Mem_FlexStop( Mem_Flex_t * p, int fVerbose ) char * Mem_FlexEntryFetch( Mem_Flex_t * p, int nBytes ) { char * pTemp; - // check if there are still ABC_FREE entries + // check if there are still free entries if ( p->pCurrent == NULL || p->pCurrent + nBytes > p->pEnd ) { // need to allocate more entries if ( p->nChunks == p->nChunksAlloc ) @@ -597,3 +600,5 @@ int Mem_StepReadMemUsage( Mem_Step_t * p ) //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/mem/mem.h b/src/aig/mem/mem.h index d43e5fc3..15cb56fe 100644 --- a/src/aig/mem/mem.h +++ b/src/aig/mem/mem.h @@ -21,9 +21,10 @@ #ifndef __MEM_H__ #define __MEM_H__ -#ifdef __cplusplus -extern "C" { -#endif +#include "abc_global.h" + +ABC_NAMESPACE_HEADER_START + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// @@ -59,9 +60,11 @@ extern char * Mem_StepEntryFetch( Mem_Step_t * p, int nBytes ); extern void Mem_StepEntryRecycle( Mem_Step_t * p, char * pEntry, int nBytes ); extern int Mem_StepReadMemUsage( Mem_Step_t * p ); -#ifdef __cplusplus -} -#endif + + +ABC_NAMESPACE_HEADER_END + + #endif diff --git a/src/aig/mfx/mfx.h b/src/aig/mfx/mfx.h index 09c4f039..9d2c6795 100644 --- a/src/aig/mfx/mfx.h +++ b/src/aig/mfx/mfx.h @@ -21,6 +21,7 @@ #ifndef __MFX_H__ #define __MFX_H__ + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -29,9 +30,10 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -68,10 +70,12 @@ struct Mfx_Par_t_ /*=== mfxCore.c ==========================================================*/ extern void Mfx_ParsDefault( Mfx_Par_t * pPars ); - -#ifdef __cplusplus -} -#endif +extern int Mfx_Perform( Nwk_Man_t * pNtk, Mfx_Par_t * pPars, If_Lib_t * pLutLib ); + + +ABC_NAMESPACE_HEADER_END + + #endif diff --git a/src/aig/mfx/mfxCore.c b/src/aig/mfx/mfxCore.c index e0f6dd82..77f35580 100644 --- a/src/aig/mfx/mfxCore.c +++ b/src/aig/mfx/mfxCore.c @@ -21,6 +21,9 @@ #include "mfxInt.h" #include "bar.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -158,7 +161,7 @@ clk = clock(); p->timeCnf += clock() - clk; // create the SAT problem clk = clock(); - p->pSat = Cnf_DataWriteIntoSolver( p->pCnf, 1, 0 ); + p->pSat = (sat_solver *)Cnf_DataWriteIntoSolver( p->pCnf, 1, 0 ); if ( p->pSat == NULL ) return 0; // solve the SAT problem @@ -217,7 +220,7 @@ Vec_Int_t * Nwk_ManPowerEstimate( Nwk_Man_t * pNtk, int fProbOne ) pSwitching = (float *)vSwitching->pArray; Nwk_ManForEachObj( pNtk, pObjAbc, i ) { - if ( (pObjAig = Aig_Regular(pObjAbc->pCopy)) ) + if ( (pObjAig = Aig_Regular((Aig_Obj_t *)pObjAbc->pCopy)) ) pProbability[pObjAbc->Id] = pSwitching[pObjAig->Id]; } Vec_IntFree( vSwitching ); @@ -339,7 +342,7 @@ int Mfx_Perform( Nwk_Man_t * pNtk, Mfx_Par_t * pPars, If_Lib_t * pLutLib ) p->nTotConfLevel = 0; p->nTimeOutsLevel = 0; clk2 = clock(); - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Nwk_Obj_t *, vNodes, pObj, i ) { if ( p->pPars->nDepthMax && pObj->Level > p->pPars->nDepthMax ) break; @@ -386,3 +389,5 @@ int Mfx_Perform( Nwk_Man_t * pNtk, Mfx_Par_t * pPars, If_Lib_t * pLutLib ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/mfx/mfxDiv.c b/src/aig/mfx/mfxDiv.c index 33f55ecb..35872da2 100644 --- a/src/aig/mfx/mfxDiv.c +++ b/src/aig/mfx/mfxDiv.c @@ -20,6 +20,9 @@ #include "mfxInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -201,7 +204,7 @@ Vec_Ptr_t * Mfx_ComputeDivisors( Mfx_Man_t * p, Nwk_Obj_t * pNode, float tArriva // count the number of PIs nTrueSupp = 0; - Vec_PtrForEachEntry( vCone, pObj, k ) + Vec_PtrForEachEntry( Nwk_Obj_t *, vCone, pObj, k ) nTrueSupp += Nwk_ObjIsCi(pObj); // printf( "%d(%d) ", Vec_PtrSize(p->vSupp), m ); @@ -221,7 +224,7 @@ Vec_Ptr_t * Mfx_ComputeDivisors( Mfx_Man_t * p, Nwk_Obj_t * pNode, float tArriva // start collecting the divisors vDivs = Vec_PtrAlloc( p->pPars->nDivMax ); - Vec_PtrForEachEntry( vCone, pObj, k ) + Vec_PtrForEachEntry( Nwk_Obj_t *, vCone, pObj, k ) { if ( !Nwk_ObjIsTravIdPrevious(pObj) ) continue; @@ -235,7 +238,7 @@ Vec_Ptr_t * Mfx_ComputeDivisors( Mfx_Man_t * p, Nwk_Obj_t * pNode, float tArriva // explore the fanouts of already collected divisors if ( Vec_PtrSize(vDivs) < p->pPars->nDivMax ) - Vec_PtrForEachEntry( vDivs, pObj, k ) + Vec_PtrForEachEntry( Nwk_Obj_t *, vDivs, pObj, k ) { // consider fanouts of this node Nwk_ObjForEachFanout( pObj, pFanout, f ) @@ -262,7 +265,7 @@ Vec_Ptr_t * Mfx_ComputeDivisors( Mfx_Man_t * p, Nwk_Obj_t * pNode, float tArriva if ( m < Nwk_ObjFaninNum(pFanout) ) continue; // make sure this divisor in not among the nodes -// Vec_PtrForEachEntry( p->vNodes, pFanin, m ) +// Vec_PtrForEachEntry( Aig_Obj_t *, p->vNodes, pFanin, m ) // assert( pFanout != pFanin ); // add the node to the divisors Vec_PtrPush( vDivs, pFanout ); @@ -278,7 +281,7 @@ Vec_Ptr_t * Mfx_ComputeDivisors( Mfx_Man_t * p, Nwk_Obj_t * pNode, float tArriva } // sort the divisors by level in the increasing order - Vec_PtrSort( vDivs, Nwk_NodeCompareLevelsIncrease ); + Vec_PtrSort( vDivs, (int (*)(void))Nwk_NodeCompareLevelsIncrease ); // add the fanins of the node Nwk_ObjForEachFanin( pNode, pFanin, k ) @@ -301,3 +304,5 @@ Vec_Ptr_t * Mfx_ComputeDivisors( Mfx_Man_t * p, Nwk_Obj_t * pNode, float tArriva //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/mfx/mfxInt.h b/src/aig/mfx/mfxInt.h index 4263724c..1fcf4e91 100644 --- a/src/aig/mfx/mfxInt.h +++ b/src/aig/mfx/mfxInt.h @@ -21,6 +21,7 @@ #ifndef __MFX_INT_H__ #define __MFX_INT_H__ + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -37,9 +38,10 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + #define MFX_FANIN_MAX 12 @@ -151,9 +153,11 @@ extern double Mfx_ConstraintRatio( Mfx_Man_t * p, Nwk_Obj_t * pNode ); extern Vec_Ptr_t * Mfx_ComputeRoots( Nwk_Obj_t * pNode, int nWinTfoMax, int nFanoutLimit ); -#ifdef __cplusplus -} -#endif + + +ABC_NAMESPACE_HEADER_END + + #endif diff --git a/src/aig/mfx/mfxInter.c b/src/aig/mfx/mfxInter.c index 3e1e3de2..2263398d 100644 --- a/src/aig/mfx/mfxInter.c +++ b/src/aig/mfx/mfxInter.c @@ -21,6 +21,9 @@ #include "mfxInt.h" #include "kit.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -94,7 +97,7 @@ sat_solver * Mfx_CreateSolverResub( Mfx_Man_t * p, int * pCands, int nCands, int // collect the outputs of the divisors Vec_IntClear( p->vProjVars ); - Vec_PtrForEachEntryStart( p->pAigWin->vPos, pObjPo, i, Aig_ManPoNum(p->pAigWin) - Vec_PtrSize(p->vDivs) ) + Vec_PtrForEachEntryStart( Aig_Obj_t *, p->pAigWin->vPos, pObjPo, i, Aig_ManPoNum(p->pAigWin) - Vec_PtrSize(p->vDivs) ) { assert( p->pCnf->pVarNums[pObjPo->Id] >= 0 ); Vec_IntPush( p->vProjVars, p->pCnf->pVarNums[pObjPo->Id] ); @@ -229,7 +232,7 @@ unsigned * Mfx_InterplateTruth( Mfx_Man_t * p, int * pCands, int nCands, int fIn return NULL; } // get the learned clauses - pCnf = sat_solver_store_release( pSat ); + pCnf = (Sto_Man_t *)sat_solver_store_release( pSat ); sat_solver_delete( pSat ); // set the global variables @@ -329,7 +332,7 @@ Hop_Obj_t * Mfx_Interplate( Mfx_Man_t * p, int * pCands, int nCands ) return NULL; } // get the learned clauses - pCnf = sat_solver_store_release( pSat ); + pCnf = (Sto_Man_t *)sat_solver_store_release( pSat ); sat_solver_delete( pSat ); // set the global variables @@ -359,3 +362,5 @@ Hop_Obj_t * Mfx_Interplate( Mfx_Man_t * p, int * pCands, int nCands ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/mfx/mfxMan.c b/src/aig/mfx/mfxMan.c index 2af3d573..9d9994bf 100644 --- a/src/aig/mfx/mfxMan.c +++ b/src/aig/mfx/mfxMan.c @@ -20,6 +20,9 @@ #include "mfxInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -186,3 +189,5 @@ void Mfx_ManStop( Mfx_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/mfx/mfxResub.c b/src/aig/mfx/mfxResub.c index a9ed23a0..83673661 100644 --- a/src/aig/mfx/mfxResub.c +++ b/src/aig/mfx/mfxResub.c @@ -20,6 +20,9 @@ #include "mfxInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -46,7 +49,7 @@ void Mfx_UpdateNetwork( Mfx_Man_t * p, Nwk_Obj_t * pObj, Vec_Ptr_t * vFanins, Ho // create the new node pObjNew = Nwk_ManCreateNode( pObj->pMan, Vec_PtrSize(vFanins), Nwk_ObjFanoutNum(pObj) ); pObjNew->pFunc = pFunc; - Vec_PtrForEachEntry( vFanins, pFanin, k ) + Vec_PtrForEachEntry( Nwk_Obj_t *, vFanins, pFanin, k ) Nwk_ObjAddFanin( pObjNew, pFanin ); // replace the old node by the new node Nwk_ManUpdate( pObj, pObjNew, p->vLevels ); @@ -110,7 +113,7 @@ int Mfx_TryResubOnce( Mfx_Man_t * p, int * pCands, int nCands ) // store the counter-example Vec_IntForEachEntry( p->vProjVars, iVar, i ) { - pData = Vec_PtrEntry( p->vDivCexes, i ); + pData = (unsigned *)Vec_PtrEntry( p->vDivCexes, i ); if ( !sat_solver_var_value( p->pSat, iVar ) ) // remove 0s!!! { assert( Aig_InfoHasBit(pData, p->nCexes) ); @@ -213,7 +216,7 @@ p->timeInt += clock() - clk; printf( "%3d: %2d ", p->nCexes, iVar ); for ( i = 0; i < Vec_PtrSize(p->vDivs); i++ ) { - pData = Vec_PtrEntry( p->vDivCexes, i ); + pData = (unsigned *)Vec_PtrEntry( p->vDivCexes, i ); printf( "%d", Aig_InfoHasBit(pData, p->nCexes-1) ); } printf( "\n" ); @@ -226,12 +229,12 @@ p->timeInt += clock() - clk; { if ( p->pPars->fPower ) { - Nwk_Obj_t * pDiv = Vec_PtrEntry(p->vDivs, iVar); + Nwk_Obj_t * pDiv = (Nwk_Obj_t *)Vec_PtrEntry(p->vDivs, iVar); // only accept the divisor if it is "cool" if ( pProbab[Nwk_ObjId(pDiv)] >= 0.2 ) continue; } - pData = Vec_PtrEntry( p->vDivCexes, iVar ); + pData = (unsigned *)Vec_PtrEntry( p->vDivCexes, iVar ); for ( w = 0; w < nWords; w++ ) if ( pData[w] != ~0 ) break; @@ -356,7 +359,7 @@ p->timeInt += clock() - clk; printf( "%3d: %2d %2d ", p->nCexes, iVar, iVar2 ); for ( i = 0; i < Vec_PtrSize(p->vDivs); i++ ) { - pData = Vec_PtrEntry( p->vDivCexes, i ); + pData = (unsigned *)Vec_PtrEntry( p->vDivCexes, i ); printf( "%d", Aig_InfoHasBit(pData, p->nCexes-1) ); } printf( "\n" ); @@ -368,10 +371,10 @@ p->timeInt += clock() - clk; fBreak = 0; for ( iVar = 1; iVar < Vec_PtrSize(p->vDivs)-Nwk_ObjFaninNum(pNode); iVar++ ) { - pData = Vec_PtrEntry( p->vDivCexes, iVar ); + pData = (unsigned *)Vec_PtrEntry( p->vDivCexes, iVar ); for ( iVar2 = 0; iVar2 < iVar; iVar2++ ) { - pData2 = Vec_PtrEntry( p->vDivCexes, iVar2 ); + pData2 = (unsigned *)Vec_PtrEntry( p->vDivCexes, iVar2 ); for ( w = 0; w < nWords; w++ ) if ( (pData[w] | pData2[w]) != ~0 ) break; @@ -559,3 +562,5 @@ int Mfx_ResubNode2( Mfx_Man_t * p, Nwk_Obj_t * pNode ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/mfx/mfxSat.c b/src/aig/mfx/mfxSat.c index ce8d580b..dc4cd862 100644 --- a/src/aig/mfx/mfxSat.c +++ b/src/aig/mfx/mfxSat.c @@ -20,6 +20,9 @@ #include "mfxInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -90,7 +93,7 @@ int Mfx_SolveSat( Mfx_Man_t * p, Nwk_Obj_t * pNode ) int RetValue, i; // collect projection variables Vec_IntClear( p->vProjVars ); - Vec_PtrForEachEntryStart( p->pAigWin->vPos, pObjPo, i, Aig_ManPoNum(p->pAigWin) - Nwk_ObjFaninNum(pNode) ) + Vec_PtrForEachEntryStart( Aig_Obj_t *, p->pAigWin->vPos, pObjPo, i, Aig_ManPoNum(p->pAigWin) - Nwk_ObjFaninNum(pNode) ) { assert( p->pCnf->pVarNums[pObjPo->Id] >= 0 ); Vec_IntPush( p->vProjVars, p->pCnf->pVarNums[pObjPo->Id] ); @@ -138,3 +141,5 @@ int Mfx_SolveSat( Mfx_Man_t * p, Nwk_Obj_t * pNode ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/mfx/mfxStrash.c b/src/aig/mfx/mfxStrash.c index 5cb6452f..f750523d 100644 --- a/src/aig/mfx/mfxStrash.c +++ b/src/aig/mfx/mfxStrash.c @@ -20,6 +20,9 @@ #include "mfxInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -84,7 +87,7 @@ void Nwk_ConvertHopToAig( Nwk_Obj_t * pObjOld, Aig_Man_t * pMan ) Hop_ManPi(pHopMan, i)->pData = pFanin->pCopy; // construct the AIG Nwk_ConvertHopToAig_rec( Hop_Regular(pRoot), pMan ); - pObjOld->pCopy = (Nwk_Obj_t *)Aig_NotCond( Hop_Regular(pRoot)->pData, Hop_IsComplement(pRoot) ); + pObjOld->pCopy = (Nwk_Obj_t *)Aig_NotCond( (Aig_Obj_t *)Hop_Regular(pRoot)->pData, Hop_IsComplement(pRoot) ); Hop_ConeUnmark_rec( Hop_Regular(pRoot) ); // assign the fanin nodes @@ -92,7 +95,7 @@ void Nwk_ConvertHopToAig( Nwk_Obj_t * pObjOld, Aig_Man_t * pMan ) Hop_ManPi(pHopMan, i)->pData = pFanin->pNext; // construct the AIG Nwk_ConvertHopToAig_rec( Hop_Regular(pRoot), pMan ); - pObjOld->pNext = (Nwk_Obj_t *)Aig_NotCond( Hop_Regular(pRoot)->pData, Hop_IsComplement(pRoot) ); + pObjOld->pNext = (Nwk_Obj_t *)Aig_NotCond( (Aig_Obj_t *)Hop_Regular(pRoot)->pData, Hop_IsComplement(pRoot) ); Hop_ConeUnmark_rec( Hop_Regular(pRoot) ); } @@ -113,19 +116,19 @@ Aig_Obj_t * Mfx_ConstructAig_rec( Mfx_Man_t * p, Nwk_Obj_t * pNode, Aig_Man_t * Nwk_Obj_t * pObj; int i; // assign AIG nodes to the leaves - Vec_PtrForEachEntry( p->vSupp, pObj, i ) + Vec_PtrForEachEntry( Nwk_Obj_t *, p->vSupp, pObj, i ) pObj->pCopy = pObj->pNext = (Nwk_Obj_t *)Aig_ObjCreatePi( pMan ); // strash intermediate nodes Nwk_ManIncrementTravId( pNode->pMan ); - Vec_PtrForEachEntry( p->vNodes, pObj, i ) + Vec_PtrForEachEntry( Nwk_Obj_t *, p->vNodes, pObj, i ) { Nwk_ConvertHopToAig( pObj, pMan ); if ( pObj == pNode ) - pObj->pNext = Aig_Not(pObj->pNext); + pObj->pNext = Aig_Not((Aig_Obj_t *)pObj->pNext); } // create the observability condition pRoot = Aig_ManConst0(pMan); - Vec_PtrForEachEntry( p->vRoots, pObj, i ) + Vec_PtrForEachEntry( Nwk_Obj_t *, p->vRoots, pObj, i ) { pExor = Aig_Exor( pMan, (Aig_Obj_t *)pObj->pCopy, (Aig_Obj_t *)pObj->pNext ); pRoot = Aig_Or( pMan, pRoot, pExor ); @@ -148,19 +151,19 @@ Aig_Obj_t * Mfx_ConstructCare_rec( Aig_Man_t * pCare, Aig_Obj_t * pObj, Aig_Man_ { Aig_Obj_t * pObj0, * pObj1; if ( Aig_ObjIsTravIdCurrent( pCare, pObj ) ) - return pObj->pData; + return (Aig_Obj_t *)pObj->pData; Aig_ObjSetTravIdCurrent( pCare, pObj ); if ( Aig_ObjIsPi(pObj) ) - return pObj->pData = NULL; + return (Aig_Obj_t *)(pObj->pData = NULL); pObj0 = Mfx_ConstructCare_rec( pCare, Aig_ObjFanin0(pObj), pMan ); if ( pObj0 == NULL ) - return pObj->pData = NULL; + return (Aig_Obj_t *)(pObj->pData = NULL); pObj1 = Mfx_ConstructCare_rec( pCare, Aig_ObjFanin1(pObj), pMan ); if ( pObj1 == NULL ) - return pObj->pData = NULL; + return (Aig_Obj_t *)(pObj->pData = NULL); pObj0 = Aig_NotCond( pObj0, Aig_ObjFaninC0(pObj) ); pObj1 = Aig_NotCond( pObj1, Aig_ObjFaninC1(pObj) ); - return pObj->pData = Aig_And( pMan, pObj0, pObj1 ); + return (Aig_Obj_t *)(pObj->pData = Aig_And( pMan, pObj0, pObj1 )); } /**Function************************************************************* @@ -213,16 +216,16 @@ Aig_Man_t * Mfx_ConstructAig( Mfx_Man_t * p, Nwk_Obj_t * pNode ) { // mark the care set Aig_ManIncrementTravId( p->pCare ); - Vec_PtrForEachEntry( p->vSupp, pFanin, i ) + Vec_PtrForEachEntry( Nwk_Obj_t *, p->vSupp, pFanin, i ) { pPi = Aig_ManPi( p->pCare, pFanin->PioId ); Aig_ObjSetTravIdCurrent( p->pCare, pPi ); pPi->pData = pFanin->pCopy; } // construct the constraints - Vec_PtrForEachEntry( p->vSupp, pFanin, i ) + Vec_PtrForEachEntry( Nwk_Obj_t *, p->vSupp, pFanin, i ) { - vOuts = Vec_PtrEntry( p->vSuppsInv, pFanin->PioId ); + vOuts = (Vec_Int_t *)Vec_PtrEntry( p->vSuppsInv, pFanin->PioId ); Vec_IntForEachEntry( vOuts, iOut, k ) { pPo = Aig_ManPo( p->pCare, iOut ); @@ -258,7 +261,7 @@ Aig_Man_t * Mfx_ConstructAig( Mfx_Man_t * p, Nwk_Obj_t * pNode ) pObjAig = (Aig_Obj_t *)pNode->pCopy; Aig_ObjCreatePo( pMan, pObjAig ); // construct the divisors - Vec_PtrForEachEntry( p->vDivs, pFanin, i ) + Vec_PtrForEachEntry( Nwk_Obj_t *, p->vDivs, pFanin, i ) { pObjAig = (Aig_Obj_t *)pFanin->pCopy; Aig_ObjCreatePo( pMan, pObjAig ); @@ -300,7 +303,7 @@ Aig_Man_t * Nwk_AigForConstraints( Mfx_Man_t * p, Nwk_Obj_t * pNode ) pMan = Aig_ManStart( 1000 ); // mark the care set Aig_ManIncrementTravId( p->pCare ); - Vec_PtrForEachEntry( p->vSupp, pFanin, i ) + Vec_PtrForEachEntry( Nwk_Obj_t *, p->vSupp, pFanin, i ) { pPi = Aig_ManPi( p->pCare, pFanin->PioId ); Aig_ObjSetTravIdCurrent( p->pCare, pPi ); @@ -308,9 +311,9 @@ Aig_Man_t * Nwk_AigForConstraints( Mfx_Man_t * p, Nwk_Obj_t * pNode ) } // construct the constraints pObjRoot = Aig_ManConst1(pMan); - Vec_PtrForEachEntry( p->vSupp, pFanin, i ) + Vec_PtrForEachEntry( Nwk_Obj_t *, p->vSupp, pFanin, i ) { - vOuts = Vec_PtrEntry( p->vSuppsInv, pFanin->PioId ); + vOuts = (Vec_Int_t *)Vec_PtrEntry( p->vSuppsInv, pFanin->PioId ); Vec_IntForEachEntry( vOuts, iOut, k ) { pPo = Aig_ManPo( p->pCare, iOut ); @@ -337,3 +340,5 @@ Aig_Man_t * Nwk_AigForConstraints( Mfx_Man_t * p, Nwk_Obj_t * pNode ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/mfx/mfxWin.c b/src/aig/mfx/mfxWin.c index e84a9b90..7cb3c53d 100644 --- a/src/aig/mfx/mfxWin.c +++ b/src/aig/mfx/mfxWin.c @@ -20,6 +20,9 @@ #include "mfxInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -110,3 +113,5 @@ Vec_Ptr_t * Mfx_ComputeRoots( Nwk_Obj_t * pNode, int nWinTfoMax, int nFanoutLimi //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/mfx/mfx_.c b/src/aig/mfx/mfx_.c index 32caf7ff..2682fa42 100644 --- a/src/aig/mfx/mfx_.c +++ b/src/aig/mfx/mfx_.c @@ -20,6 +20,9 @@ #include "mfsInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -45,3 +48,5 @@ //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ntl/ntl.h b/src/aig/ntl/ntl.h index 5407fcf8..c0d701e0 100644 --- a/src/aig/ntl/ntl.h +++ b/src/aig/ntl/ntl.h @@ -21,6 +21,7 @@ #ifndef __NTL_H__ #define __NTL_H__ + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -33,15 +34,12 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif +ABC_NAMESPACE_HEADER_START //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// //////////////////////////////////////////////////////////////////////// -typedef struct Ntl_Man_t_ Ntl_Man_t; typedef struct Ntl_Mod_t_ Ntl_Mod_t; typedef struct Ntl_Reg_t_ Ntl_Reg_t; typedef struct Ntl_Obj_t_ Ntl_Obj_t; @@ -144,7 +142,7 @@ struct Ntl_Obj_t_ unsigned Id : 28; // object ID int nFanins; // the number of fanins int nFanouts; // the number of fanouts -// int Reset; // reset of the flop + int Reset; // reset of the flop union { // functionality Ntl_Mod_t * pImplem; // model (for boxes) char * pSop; // SOP (for logic nodes) @@ -165,7 +163,7 @@ struct Ntl_Net_t_ union { void * pCopy2; // the copy of this object float dTemp; // other data -// int iTemp; // other data + int iTemp; // other data }; Ntl_Obj_t * pDriver; // driver of the net unsigned NetId : 27; // unique ID of the net @@ -254,16 +252,16 @@ static inline int Ntl_ObjIsSeqRoot( Ntl_Obj_t * p ) { return Ntl_O #define Ntl_ManForEachModel( p, pMod, i ) \ for ( i = 0; (i < Vec_PtrSize(p->vModels)) && (((pMod) = (Ntl_Mod_t*)Vec_PtrEntry(p->vModels, i)), 1); i++ ) #define Ntl_ManForEachCiNet( p, pNet, i ) \ - Vec_PtrForEachEntry( p->vCis, pNet, i ) + Vec_PtrForEachEntry( Ntl_Net_t *, p->vCis, pNet, i ) #define Ntl_ManForEachCoNet( p, pNet, i ) \ - Vec_PtrForEachEntry( p->vCos, pNet, i ) + Vec_PtrForEachEntry( Ntl_Net_t *, p->vCos, pNet, i ) #define Ntl_ModelForEachPi( pNwk, pObj, i ) \ for ( i = 0; (i < Vec_PtrSize(pNwk->vPis)) && (((pObj) = (Ntl_Obj_t*)Vec_PtrEntry(pNwk->vPis, i)), 1); i++ ) #define Ntl_ModelForEachPo( pNwk, pObj, i ) \ for ( i = 0; (i < Vec_PtrSize(pNwk->vPos)) && (((pObj) = (Ntl_Obj_t*)Vec_PtrEntry(pNwk->vPos, i)), 1); i++ ) #define Ntl_ModelForEachNet( pNwk, pNet, i ) \ - Vec_PtrForEachEntry( pNwk->vNets, pNet, i ) \ + Vec_PtrForEachEntry( Ntl_Net_t *, pNwk->vNets, pNet, i ) \ if ( pNet == NULL ) {} else #define Ntl_ModelForEachObj( pNwk, pObj, i ) \ for ( i = 0; (i < Vec_PtrSize(pNwk->vObjs)) && (((pObj) = (Ntl_Obj_t*)Vec_PtrEntry(pNwk->vObjs, i)), 1); i++ ) \ @@ -365,7 +363,7 @@ extern ABC_DLL Ntl_Obj_t * Ntl_ModelCreateBox( Ntl_Mod_t * pModel, int nFani extern ABC_DLL Ntl_Obj_t * Ntl_ModelDupObj( Ntl_Mod_t * pModel, Ntl_Obj_t * pOld ); extern ABC_DLL Ntl_Obj_t * Ntl_ModelCreatePiWithName( Ntl_Mod_t * pModel, char * pName ); extern ABC_DLL char * Ntl_ManStoreName( Ntl_Man_t * p, char * pName ); -extern ABC_DLL char * Ntl_ManStoreSop( Aig_MmFlex_t * pMan, char * pSop ); +extern ABC_DLL char * Ntl_ManStoreSop( Aig_MmFlex_t * pMan, const char * pSop ); extern ABC_DLL char * Ntl_ManStoreFileName( Ntl_Man_t * p, char * pFileName ); extern ABC_DLL int Ntl_ManObjWhichFanout( Ntl_Obj_t * pNode, Ntl_Net_t * pFanout ); /*=== ntlSweep.c ==========================================================*/ @@ -387,11 +385,12 @@ extern ABC_DLL Ntl_Mod_t * Ntl_ManFindModel( Ntl_Man_t * p, const char * pNa /*=== ntlTime.c ==========================================================*/ extern ABC_DLL Tim_Man_t * Ntl_ManCreateTiming( Ntl_Man_t * p ); /*=== ntlReadBlif.c ==========================================================*/ -extern ABC_DLL Ntl_Man_t * Ioa_ReadBlif( char * pFileName, int fCheck ); +extern ABC_DLL Ntl_Man_t * Ntl_ManReadBlif( char * pFileName, int fCheck ); /*=== ntlWriteBlif.c ==========================================================*/ -extern ABC_DLL void Ioa_WriteBlif( Ntl_Man_t * p, char * pFileName ); -extern ABC_DLL void Ioa_WriteBlifLogic( Nwk_Man_t * pNtk, Ntl_Man_t * p, char * pFileName ); +extern ABC_DLL void Ntl_ManWriteBlif( Ntl_Man_t * p, char * pFileName ); +extern ABC_DLL void Ntl_WriteBlifLogic( Nwk_Man_t * pNtk, Ntl_Man_t * p, char * pFileName ); /*=== ntlUtil.c ==========================================================*/ +extern ABC_DLL int Ntl_FileIsType( char * pFileName, char * pS1, char * pS2, char * pS3 ); extern ABC_DLL int Ntl_ModelGetFaninMax( Ntl_Mod_t * pRoot ); extern ABC_DLL Ntl_Net_t * Ntl_ModelFindSimpleNet( Ntl_Net_t * pNetCo ); extern ABC_DLL int Ntl_ManCountSimpleCoDrivers( Ntl_Man_t * p ); @@ -413,9 +412,11 @@ extern ABC_DLL int Ntl_ModelCheckNetsAreNotMarked( Ntl_Mod_t * pMode extern ABC_DLL void Ntl_ModelClearNets( Ntl_Mod_t * pModel ); extern ABC_DLL void Ntl_ManRemoveUselessNets( Ntl_Man_t * p ); -#ifdef __cplusplus -} -#endif + + +ABC_NAMESPACE_HEADER_END + + #endif diff --git a/src/aig/ntl/ntlCheck.c b/src/aig/ntl/ntlCheck.c index 82ef388b..7aecf878 100644 --- a/src/aig/ntl/ntlCheck.c +++ b/src/aig/ntl/ntlCheck.c @@ -21,6 +21,9 @@ #include "ntl.h" #include "aig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -319,7 +322,7 @@ void Ntl_ModelFixNonDrivenNets( Ntl_Mod_t * pModel ) if ( Vec_PtrSize(vNets) > 0 ) { printf( "Warning: Constant-0 drivers added to %d non-driven nets in network \"%s\": ", Vec_PtrSize(vNets), pModel->pName ); - Vec_PtrForEachEntry( vNets, pNet, i ) + Vec_PtrForEachEntry( Ntl_Net_t *, vNets, pNet, i ) { printf( "%s%s", (i? ", ": ""), pNet->pName ); if ( i == 3 ) @@ -372,3 +375,5 @@ void Ntl_ModelTransformLatches( Ntl_Mod_t * pModel ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ntl/ntlCore.c b/src/aig/ntl/ntlCore.c index b170cdad..c09bac0f 100644 --- a/src/aig/ntl/ntlCore.c +++ b/src/aig/ntl/ntlCore.c @@ -20,6 +20,10 @@ #include "ntl.h" #include "dch.h" +#include "dar.h" + +ABC_NAMESPACE_IMPL_START + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// @@ -42,10 +46,11 @@ ***********************************************************************/ Aig_Man_t * Ntl_ManPerformChoicing( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fConstruct, int nConfMax, int nLevelMax, int fVerbose ) { - extern Aig_Man_t * Dar_ManBalance( Aig_Man_t * pAig, int fUpdateLevel ); - extern Aig_Man_t * Dar_ManCompress( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fPower, int fVerbose ); - extern Aig_Man_t * Dar_ManChoice( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fConstruct, int nConfMax, int nLevelMax, int fVerbose ); +// extern Aig_Man_t * Dar_ManBalance( Aig_Man_t * pAig, int fUpdateLevel ); +// extern Aig_Man_t * Dar_ManCompress( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fPower, int fVerbose ); +// extern Aig_Man_t * Dar_ManChoice( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fConstruct, int nConfMax, int nLevelMax, int fVerbose ); Aig_Man_t * pTemp; + // perform synthesis //printf( "Pre-synthesis AIG: " ); //Aig_ManPrintStats( pAig ); @@ -54,6 +59,7 @@ Aig_Man_t * Ntl_ManPerformChoicing( Aig_Man_t * pAig, int fBalance, int fUpdateL pTemp = Dar_ManChoice( pAig, fBalance, fUpdateLevel, fConstruct, nConfMax, nLevelMax, fVerbose ); //printf( "Post-synthesis AIG: " ); //Aig_ManPrintStats( pTemp ); + return pTemp; } @@ -70,8 +76,22 @@ Aig_Man_t * Ntl_ManPerformChoicing( Aig_Man_t * pAig, int fBalance, int fUpdateL ***********************************************************************/ Aig_Man_t * Ntl_ManPerformChoicingNew( Aig_Man_t * pAig, Dch_Pars_t * pPars ) { - extern Aig_Man_t * Dar_ManChoiceNew( Aig_Man_t * pAig, Dch_Pars_t * pPars ); - return Dar_ManChoiceNew( pAig, pPars ); +// extern Aig_Man_t * Dar_ManChoiceNew( Aig_Man_t * pAig, Dch_Pars_t * pPars ); + Aig_Man_t * pTemp; +/* + Aig_Obj_t * pObj; + int i; + Aig_ManForEachPi( pAig, pObj, i ) + printf( "%d ", pObj->Level ); + printf( "\n" ); +*/ + pTemp = Dar_ManChoiceNew( pAig, pPars ); +/* + Aig_ManForEachPi( pTemp, pObj, i ) + printf( "%d ", pObj->Level ); + printf( "\n" ); +*/ + return pTemp; } /**Function************************************************************* @@ -128,3 +148,5 @@ int Ntl_ManInsertTestIf( Ntl_Man_t * p, Aig_Man_t * pAig ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ntl/ntlEc.c b/src/aig/ntl/ntlEc.c index 0d41006e..d82ac71e 100644 --- a/src/aig/ntl/ntlEc.c +++ b/src/aig/ntl/ntlEc.c @@ -19,6 +19,10 @@ ***********************************************************************/ #include "ntl.h" +#include "saig.h" + +ABC_NAMESPACE_IMPL_START + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// @@ -273,8 +277,8 @@ void Ntl_ManPrepareCec( char * pFileName1, char * pFileName2, Aig_Man_t ** ppAig { Ntl_Man_t * pMan1, * pMan2; // read the netlists - pMan1 = Ioa_ReadBlif( pFileName1, 1 ); - pMan2 = Ioa_ReadBlif( pFileName2, 1 ); + pMan1 = Ntl_ManReadBlif( pFileName1, 1 ); + pMan2 = Ntl_ManReadBlif( pFileName2, 1 ); if ( !pMan1 || !pMan2 ) { if ( pMan1 ) Ntl_ManFree( pMan1 ); @@ -301,14 +305,14 @@ void Ntl_ManPrepareCec( char * pFileName1, char * pFileName2, Aig_Man_t ** ppAig ***********************************************************************/ Aig_Man_t * Ntl_ManPrepareSec( char * pFileName1, char * pFileName2 ) { - extern Aig_Man_t * Saig_ManCreateMiter( Aig_Man_t * p1, Aig_Man_t * p2, int Oper ); +// extern Aig_Man_t * Saig_ManCreateMiter( Aig_Man_t * p1, Aig_Man_t * p2, int Oper ); Aig_Man_t * pAig1, * pAig2, * pAig; Ntl_Man_t * pMan1, * pMan2; Ntl_Mod_t * pModel1, * pModel2; // read the netlists - pMan1 = Ioa_ReadBlif( pFileName1, 1 ); - pMan2 = Ioa_ReadBlif( pFileName2, 1 ); + pMan1 = Ntl_ManReadBlif( pFileName1, 1 ); + pMan2 = Ntl_ManReadBlif( pFileName2, 1 ); if ( !pMan1 || !pMan2 ) { if ( pMan1 ) Ntl_ManFree( pMan1 ); @@ -366,3 +370,5 @@ Aig_Man_t * Ntl_ManPrepareSec( char * pFileName1, char * pFileName2 ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ntl/ntlExtract.c b/src/aig/ntl/ntlExtract.c index ae278585..a6268b2c 100644 --- a/src/aig/ntl/ntlExtract.c +++ b/src/aig/ntl/ntlExtract.c @@ -22,6 +22,9 @@ #include "dec.h" #include "kit.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -59,9 +62,9 @@ Aig_Obj_t * Ntl_ConvertSopToAigInternal( Aig_Man_t * pMan, Ntl_Obj_t * pNode, ch { pNet = Ntl_ObjFanin( pNode, i ); if ( Value == '1' ) - pAnd = Aig_And( pMan, pAnd, pNet->pCopy ); + pAnd = Aig_And( pMan, pAnd, (Aig_Obj_t *)pNet->pCopy ); else if ( Value == '0' ) - pAnd = Aig_And( pMan, pAnd, Aig_Not(pNet->pCopy) ); + pAnd = Aig_And( pMan, pAnd, Aig_Not((Aig_Obj_t *)pNet->pCopy) ); } // add to the sum of cubes pSum = Aig_Or( pMan, pSum, pAnd ); @@ -93,16 +96,16 @@ Aig_Obj_t * Ntl_GraphToNetworkAig( Aig_Man_t * pMan, Dec_Graph_t * pGraph ) return Aig_NotCond( Aig_ManConst1(pMan), Dec_GraphIsComplement(pGraph) ); // check for a literal if ( Dec_GraphIsVar(pGraph) ) - return Aig_NotCond( Dec_GraphVar(pGraph)->pFunc, Dec_GraphIsComplement(pGraph) ); + return Aig_NotCond( (Aig_Obj_t *)Dec_GraphVar(pGraph)->pFunc, Dec_GraphIsComplement(pGraph) ); // build the AIG nodes corresponding to the AND gates of the graph Dec_GraphForEachNode( pGraph, pNode, i ) { - pAnd0 = Aig_NotCond( Dec_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl ); - pAnd1 = Aig_NotCond( Dec_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl ); + pAnd0 = Aig_NotCond( (Aig_Obj_t *)Dec_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl ); + pAnd1 = Aig_NotCond( (Aig_Obj_t *)Dec_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl ); pNode->pFunc = Aig_And( pMan, pAnd0, pAnd1 ); } // complement the result if necessary - return Aig_NotCond( pNode->pFunc, Dec_GraphIsComplement(pGraph) ); + return Aig_NotCond( (Aig_Obj_t *)pNode->pFunc, Dec_GraphIsComplement(pGraph) ); } /**Function************************************************************* @@ -183,16 +186,16 @@ int Ntl_ManExtract_rec( Ntl_Man_t * p, Ntl_Net_t * pNet ) Vec_IntPush( p->vBox1Cios, Aig_ManPoNum(p->pAig) ); Ntl_ObjForEachFanin( pObj, pNetFanin, i ) { - LevelCur = Aig_ObjLevel( Aig_Regular(pNetFanin->pCopy) ); + LevelCur = Aig_ObjLevel( Aig_Regular((Aig_Obj_t *)pNetFanin->pCopy) ); LevelMax = ABC_MAX( LevelMax, LevelCur ); Vec_PtrPush( p->vCos, pNetFanin ); - Aig_ObjCreatePo( p->pAig, pNetFanin->pCopy ); + Aig_ObjCreatePo( p->pAig, (Aig_Obj_t *)pNetFanin->pCopy ); } Ntl_ObjForEachFanout( pObj, pNetFanin, i ) { Vec_PtrPush( p->vCis, pNetFanin ); pNetFanin->pCopy = Aig_ObjCreatePi( p->pAig ); - Aig_ObjSetLevel( pNetFanin->pCopy, LevelMax + 1 ); + Aig_ObjSetLevel( (Aig_Obj_t *)pNetFanin->pCopy, LevelMax + 1 ); } } Vec_PtrPush( p->vVisNodes, pObj ); @@ -264,7 +267,7 @@ Aig_Man_t * Ntl_ManExtract( Ntl_Man_t * p ) return 0; } Vec_PtrPush( p->vCos, pNet ); - Aig_ObjCreatePo( p->pAig, pNet->pCopy ); + Aig_ObjCreatePo( p->pAig, (Aig_Obj_t *)pNet->pCopy ); } } // visit dangling boxes @@ -306,9 +309,9 @@ Aig_Man_t * Ntl_ManExtract( Ntl_Man_t * p ) SeeAlso [] ***********************************************************************/ -int Ntl_ManCollapseBoxComb_rec( Ntl_Man_t * p, Ntl_Obj_t * pBox, int fSeq ) +int Ntl_ManCollapseBoxComb_rec( Ntl_Man_t * p, Ntl_Obj_t * pBox ) { - extern int Ntl_ManCollapse_rec( Ntl_Man_t * p, Ntl_Net_t * pNet, int fSeq ); + extern int Ntl_ManCollapse_rec( Ntl_Man_t * p, Ntl_Net_t * pNet ); Ntl_Mod_t * pModel = pBox->pImplem; Ntl_Obj_t * pObj; Ntl_Net_t * pNet, * pNetBox; @@ -329,7 +332,7 @@ int Ntl_ManCollapseBoxComb_rec( Ntl_Man_t * p, Ntl_Obj_t * pBox, int fSeq ) Ntl_ModelForEachPo( pModel, pObj, i ) { pNet = Ntl_ObjFanin0(pObj); - if ( !Ntl_ManCollapse_rec( p, pNet, fSeq ) ) + if ( !Ntl_ManCollapse_rec( p, pNet ) ) return 0; pNetBox = Ntl_ObjFanout( pBox, i ); pNetBox->pCopy = pNet->pCopy; @@ -348,9 +351,9 @@ int Ntl_ManCollapseBoxComb_rec( Ntl_Man_t * p, Ntl_Obj_t * pBox, int fSeq ) SeeAlso [] ***********************************************************************/ -int Ntl_ManCollapseBoxSeq1_rec( Ntl_Man_t * p, Ntl_Obj_t * pBox, int fSeq ) +int Ntl_ManCollapseBoxSeq1_rec( Ntl_Man_t * p, Ntl_Obj_t * pBox ) { - extern int Ntl_ManCollapse_rec( Ntl_Man_t * p, Ntl_Net_t * pNet, int fSeq ); + extern int Ntl_ManCollapse_rec( Ntl_Man_t * p, Ntl_Net_t * pNet ); Ntl_Mod_t * pModel = pBox->pImplem; Ntl_Obj_t * pObj; Ntl_Net_t * pNet, * pNetBox; @@ -365,18 +368,18 @@ int Ntl_ManCollapseBoxSeq1_rec( Ntl_Man_t * p, Ntl_Obj_t * pBox, int fSeq ) { pNet = Ntl_ObjFanout0(pObj); pNet->pCopy = Aig_ObjCreatePi( p->pAig ); - if ( fSeq && Ntl_ObjIsInit1( pObj ) ) - pNet->pCopy = Aig_Not(pNet->pCopy); + if ( Ntl_ObjIsInit1( pObj ) ) + pNet->pCopy = Aig_Not((Aig_Obj_t *)pNet->pCopy); pNet->nVisits = 2; // remember the class of this register Vec_IntPush( p->vRegClasses, p->pNal ? pBox->iTemp : pObj->LatchId.regClass ); -// Vec_IntPush( p->vRstClasses, p->pNal ? pBox->Reset : -1 ); + Vec_IntPush( p->vRstClasses, p->pNal ? pBox->Reset : -1 ); } // compute AIG for the internal nodes Ntl_ModelForEachPo( pModel, pObj, i ) { pNet = Ntl_ObjFanin0(pObj); - if ( !Ntl_ManCollapse_rec( p, pNet, fSeq ) ) + if ( !Ntl_ManCollapse_rec( p, pNet ) ) return 0; pNetBox = Ntl_ObjFanout( pBox, i ); pNetBox->pCopy = pNet->pCopy; @@ -395,9 +398,9 @@ int Ntl_ManCollapseBoxSeq1_rec( Ntl_Man_t * p, Ntl_Obj_t * pBox, int fSeq ) SeeAlso [] ***********************************************************************/ -int Ntl_ManCollapseBoxSeq2_rec( Ntl_Man_t * p, Ntl_Obj_t * pBox, int fSeq, int iFirstPi ) +int Ntl_ManCollapseBoxSeq2_rec( Ntl_Man_t * p, Ntl_Obj_t * pBox, int iFirstPi ) { - extern int Ntl_ManCollapse_rec( Ntl_Man_t * p, Ntl_Net_t * pNet, int fSeq ); + extern int Ntl_ManCollapse_rec( Ntl_Man_t * p, Ntl_Net_t * pNet ); Ntl_Mod_t * pModel = pBox->pImplem; Ntl_Obj_t * pObj; Ntl_Net_t * pNet, * pNetBox; @@ -420,20 +423,20 @@ int Ntl_ManCollapseBoxSeq2_rec( Ntl_Man_t * p, Ntl_Obj_t * pBox, int fSeq, int i { pNet = Ntl_ObjFanout0(pObj); pNet->pCopy = Aig_ManPi( p->pAig, iFirstPi++ ); - if ( fSeq && Ntl_ObjIsInit1( pObj ) ) - pNet->pCopy = Aig_Not(pNet->pCopy); + if ( Ntl_ObjIsInit1( pObj ) ) + pNet->pCopy = Aig_Not((Aig_Obj_t *)pNet->pCopy); pNet->nVisits = 2; } // compute AIGs for the registers Ntl_ModelForEachLatch( pModel, pObj, i ) { pNet = Ntl_ObjFanin0(pObj); - if ( !Ntl_ManCollapse_rec( p, pNet, fSeq ) ) + if ( !Ntl_ManCollapse_rec( p, pNet ) ) return 0; - if ( fSeq && Ntl_ObjIsInit1( pObj ) ) - Aig_ObjCreatePo( p->pAig, Aig_Not(pNet->pCopy) ); + if ( Ntl_ObjIsInit1( pObj ) ) + Aig_ObjCreatePo( p->pAig, Aig_Not((Aig_Obj_t *)pNet->pCopy) ); else - Aig_ObjCreatePo( p->pAig, pNet->pCopy ); + Aig_ObjCreatePo( p->pAig, (Aig_Obj_t *)pNet->pCopy ); } return 1; } @@ -449,7 +452,7 @@ int Ntl_ManCollapseBoxSeq2_rec( Ntl_Man_t * p, Ntl_Obj_t * pBox, int fSeq, int i SeeAlso [] ***********************************************************************/ -int Ntl_ManCollapse_rec( Ntl_Man_t * p, Ntl_Net_t * pNet, int fSeq ) +int Ntl_ManCollapse_rec( Ntl_Man_t * p, Ntl_Net_t * pNet ) { Ntl_Obj_t * pObj; Ntl_Net_t * pNetFanin; @@ -467,13 +470,13 @@ int Ntl_ManCollapse_rec( Ntl_Man_t * p, Ntl_Net_t * pNet, int fSeq ) assert( Ntl_ObjIsNode(pObj) || Ntl_ObjIsBox(pObj) ); // visit the input nets of the box Ntl_ObjForEachFanin( pObj, pNetFanin, i ) - if ( !Ntl_ManCollapse_rec( p, pNetFanin, fSeq ) ) + if ( !Ntl_ManCollapse_rec( p, pNetFanin ) ) return 0; // add box inputs/outputs to COs/CIs if ( Ntl_ObjIsBox(pObj) ) { assert( Ntl_BoxIsWhite(pObj) && Ntl_BoxIsComb(pObj) ); - if ( !Ntl_ManCollapseBoxComb_rec( p, pObj, fSeq ) ) + if ( !Ntl_ManCollapseBoxComb_rec( p, pObj ) ) return 0; } if ( Ntl_ObjIsNode(pObj) ) @@ -533,7 +536,7 @@ Aig_Man_t * Ntl_ManCollapse( Ntl_Man_t * p, int fSeq ) if ( !(Ntl_BoxIsSeq(pBox) && Ntl_BoxIsWhite(pBox)) ) continue; Vec_IntPush( p->vBox1Cios, Aig_ManPiNum(p->pAig) ); - Ntl_ManCollapseBoxSeq1_rec( p, pBox, fSeq ); + Ntl_ManCollapseBoxSeq1_rec( p, pBox ); Ntl_ObjForEachFanout( pBox, pNet, k ) pNet->nVisits = 2; } @@ -541,12 +544,12 @@ Aig_Man_t * Ntl_ManCollapse( Ntl_Man_t * p, int fSeq ) // derive the outputs Ntl_ManForEachCoNet( p, pNet, i ) { - if ( !Ntl_ManCollapse_rec( p, pNet, fSeq ) ) + if ( !Ntl_ManCollapse_rec( p, pNet ) ) { printf( "Ntl_ManCollapse(): Error: Combinational loop is detected.\n" ); return 0; } - Aig_ObjCreatePo( p->pAig, pNet->pCopy ); + Aig_ObjCreatePo( p->pAig, (Aig_Obj_t *)pNet->pCopy ); } nTruePos = Aig_ManPoNum(p->pAig); // create outputs of seq boxes @@ -556,12 +559,12 @@ Aig_Man_t * Ntl_ManCollapse( Ntl_Man_t * p, int fSeq ) if ( !(Ntl_BoxIsSeq(pBox) && Ntl_BoxIsWhite(pBox)) ) continue; Ntl_ObjForEachFanin( pBox, pNet, k ) - if ( !Ntl_ManCollapse_rec( p, pNet, fSeq ) ) + if ( !Ntl_ManCollapse_rec( p, pNet ) ) { printf( "Ntl_ManCollapse(): Error: Combinational loop is detected.\n" ); return 0; } - Ntl_ManCollapseBoxSeq2_rec( p, pBox, fSeq, Vec_IntEntry(p->vBox1Cios, iBox++) ); + Ntl_ManCollapseBoxSeq2_rec( p, pBox, Vec_IntEntry(p->vBox1Cios, iBox++) ); } } // make sure registers are added correctly @@ -700,13 +703,13 @@ Nwk_Obj_t * Ntl_ManExtractNwk_rec( Ntl_Man_t * p, Ntl_Net_t * pNet, Nwk_Man_t * Nwk_Obj_t * pNode; int i; if ( pNet->fMark ) - return pNet->pCopy2; + return (Nwk_Obj_t *)pNet->pCopy2; pNet->fMark = 1; pNode = Nwk_ManCreateNode( pNtk, Ntl_ObjFaninNum(pNet->pDriver), (int)(long)pNet->pCopy ); Ntl_ObjForEachFanin( pNet->pDriver, pFaninNet, i ) { Ntl_ManExtractNwk_rec( p, pFaninNet, pNtk, vCover, vMemory ); - Nwk_ObjAddFanin( pNode, pFaninNet->pCopy2 ); + Nwk_ObjAddFanin( pNode, (Nwk_Obj_t *)pFaninNet->pCopy2 ); } if ( Ntl_ObjFaninNum(pNet->pDriver) == 0 || Kit_PlaGetVarNum(pNet->pDriver->pSop) == 0 ) pNode->pFunc = Hop_NotCond( Hop_ManConst1(pNtk->pManHop), Kit_PlaIsConst0(pNet->pDriver->pSop) ); @@ -717,7 +720,7 @@ Nwk_Obj_t * Ntl_ManExtractNwk_rec( Ntl_Man_t * p, Ntl_Net_t * pNet, Nwk_Man_t * if ( Kit_PlaIsComplement(pNet->pDriver->pSop) ) pNode->pFunc = Hop_Not(pNode->pFunc); } - return pNet->pCopy2 = pNode; + return (Nwk_Obj_t *)(pNet->pCopy2 = pNode); } /**Function************************************************************* @@ -780,24 +783,24 @@ Nwk_Man_t * Ntl_ManExtractNwk( Ntl_Man_t * p, Aig_Man_t * pAig, Tim_Man_t * pMan { if ( Aig_ObjIsPi(pAnd) ) { - pNet = pAnd->pData; + pNet = (Ntl_Net_t *)pAnd->pData; pNet->fMark = 1; pNet->pCopy2 = Nwk_ManCreateCi( pNtk, (int)(long)pNet->pCopy ); } else if ( Aig_ObjIsPo(pAnd) ) { - pNet = pAnd->pData; + pNet = (Ntl_Net_t *)pAnd->pData; pNode = Nwk_ManCreateCo( pNtk ); if ( (pNetSimple = Ntl_ModelFindSimpleNet( pNet )) ) { pNetSimple->pCopy2 = Ntl_ManExtractNwk_rec( p, pNetSimple, pNtk, vCover, vMemory ); - Nwk_ObjAddFanin( pNode, pNetSimple->pCopy2 ); + Nwk_ObjAddFanin( pNode, (Nwk_Obj_t *)pNetSimple->pCopy2 ); pNode->fInvert = Kit_PlaIsInv( pNet->pDriver->pSop ); } else { pNet->pCopy2 = Ntl_ManExtractNwk_rec( p, pNet, pNtk, vCover, vMemory ); - Nwk_ObjAddFanin( pNode, pNet->pCopy2 ); + Nwk_ObjAddFanin( pNode, (Nwk_Obj_t *)pNet->pCopy2 ); pNode->fInvert = (Nwk_ObjFanin0(pNode)->pFunc == Hop_ManConst0(pNtk->pManHop)); // fixed on June 7, 2009 } } @@ -818,7 +821,7 @@ Nwk_Man_t * Ntl_ManExtractNwk( Ntl_Man_t * p, Aig_Man_t * pAig, Tim_Man_t * pMan /**Function************************************************************* Synopsis [Extracts logic newtork out of the netlist.] - + Description [] SideEffects [] @@ -831,7 +834,7 @@ Nwk_Man_t * Ntl_ManReadNwk( char * pFileName, Aig_Man_t * pAig, Tim_Man_t * pMan Nwk_Man_t * pNtk; Ntl_Man_t * pNtl; Ntl_Mod_t * pRoot; - pNtl = Ioa_ReadBlif( pFileName, 1 ); + pNtl = Ntl_ManReadBlif( pFileName, 1 ); if ( pNtl == NULL ) { printf( "Ntl_ManReadNwk(): Reading BLIF has failed.\n" ); @@ -870,3 +873,5 @@ Nwk_Man_t * Ntl_ManReadNwk( char * pFileName, Aig_Man_t * pAig, Tim_Man_t * pMan //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ntl/ntlFraig.c b/src/aig/ntl/ntlFraig.c index 1d7ac393..34bc81ec 100644 --- a/src/aig/ntl/ntlFraig.c +++ b/src/aig/ntl/ntlFraig.c @@ -23,6 +23,9 @@ #include "ssw.h" #include "dch.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -66,12 +69,12 @@ void Ntl_ManUpdateNoMergeReprs( Aig_Man_t * pAig, Aig_Obj_t ** pReprs ) if ( pRepresNew != NULL ) continue; // get the net of the representative node - pNet = pRepres->pData; + pNet = (Ntl_Net_t *)pRepres->pData; assert( pRepres->pData != NULL ); if ( Ntl_ObjIsBox(pNet->pDriver) && pNet->pDriver->pImplem->attrNoMerge ) { // the net belongs to the no-merge box - pNetObj = pObj->pData; + pNetObj = (Ntl_Net_t *)pObj->pData; if ( Ntl_ObjIsBox(pNetObj->pDriver) && pNetObj->pDriver->pImplem->attrNoMerge ) continue; // the object's net does not belong to the no-merge box @@ -130,7 +133,7 @@ Aig_Obj_t ** Ntl_ManFraigDeriveClasses( Aig_Man_t * pAig, Ntl_Man_t * pNew, Aig_ // remember pointers to the nets of pNew Aig_ManForEachObj( pAig, pObj, i ) - pObj->pNext = pObj->pData; + pObj->pNext = (Aig_Obj_t *)pObj->pData; // map the AIG managers Aig_ManForEachObj( pAig, pObj, i ) @@ -139,8 +142,8 @@ Aig_Obj_t ** Ntl_ManFraigDeriveClasses( Aig_Man_t * pAig, Ntl_Man_t * pNew, Aig_ pObj->pData = Aig_ManConst1(pAigCol); else if ( !Aig_ObjIsPo(pObj) ) { - pNet = pObj->pData; - pObjCol = Aig_Regular(pNet->pCopy); + pNet = (Ntl_Net_t *)pObj->pData; + pObjCol = Aig_Regular((Aig_Obj_t *)pNet->pCopy); pObj->pData = pObjCol; } } @@ -155,7 +158,7 @@ Aig_Obj_t ** Ntl_ManFraigDeriveClasses( Aig_Man_t * pAig, Ntl_Man_t * pNew, Aig_ { if ( Aig_ObjIsPo(pObj) ) continue; - pObjCol = pObj->pData; + pObjCol = (Aig_Obj_t *)pObj->pData; if ( pObjCol == NULL ) continue; if ( pMapBack[pObjCol->Id] == NULL ) @@ -170,7 +173,7 @@ Aig_Obj_t ** Ntl_ManFraigDeriveClasses( Aig_Man_t * pAig, Ntl_Man_t * pNew, Aig_ if ( Aig_ObjIsPo(pObj) ) continue; // get the collapsed node - pObjCol = pObj->pData; + pObjCol = (Aig_Obj_t *)pObj->pData; if ( pObjCol == NULL ) continue; // get the representative of the collapsed node @@ -230,8 +233,8 @@ void Ntl_ManReduce( Ntl_Man_t * p, Aig_Man_t * pAig ) if ( pObjRepr == NULL ) continue; assert( pObj != pObjRepr ); - pNet = pObj->pData; - pNetRepr = pObjRepr->pData; + pNet = (Ntl_Net_t *)pObj->pData; + pNetRepr = (Ntl_Net_t *)pObjRepr->pData; // consider special cases, when the net should not be reduced if ( Ntl_ObjIsBox(pNet->pDriver) ) { @@ -267,8 +270,8 @@ void Ntl_ManReduce( Ntl_Man_t * p, Aig_Man_t * pAig ) pNetRepr->pCopy = Aig_ManConst1(pAig); } // get the complemented attributes of the nets - fCompl = Aig_IsComplement(pNet->pCopy) ^ Aig_Regular(pNet->pCopy)->fPhase ^ - Aig_IsComplement(pNetRepr->pCopy) ^ Aig_Regular(pNetRepr->pCopy)->fPhase; + fCompl = Aig_IsComplement((Aig_Obj_t *)pNet->pCopy) ^ Aig_Regular((Aig_Obj_t *)pNet->pCopy)->fPhase ^ + Aig_IsComplement((Aig_Obj_t *)pNetRepr->pCopy) ^ Aig_Regular((Aig_Obj_t *)pNetRepr->pCopy)->fPhase; // create interter/buffer driven by the representative net pNode = Ntl_ModelCreateNode( pRoot, 1 ); pNode->pSop = fCompl? Ntl_ManStoreSop( p->pMemSops, "0 1\n" ) : Ntl_ManStoreSop( p->pMemSops, "1 1\n" ); @@ -322,7 +325,7 @@ void Ntl_ManResetComplemented( Ntl_Man_t * p, Aig_Man_t * pAigCol ) { if ( Ntl_ObjIsInit1( pObj ) ) { - pObjCol = Ntl_ObjFanout0(pObj)->pCopy; + pObjCol = (Aig_Obj_t *)Ntl_ObjFanout0(pObj)->pCopy; assert( pObjCol->fPhase == 0 ); pObjCol->fPhase = 1; } @@ -353,7 +356,20 @@ Ntl_Man_t * Ntl_ManFinalize( Ntl_Man_t * pNew, Aig_Man_t * pAig, Aig_Man_t * pAi pAig->nReprsAlloc = Aig_ManObjNumMax(pAig); if ( fVerbose ) printf( "Equivalences: Collapsed = %5d. Extracted = %5d.\n", Aig_ManCountReprs(pAigCol), Aig_ManCountReprs(pAig) ); - +/* +{ + Aig_Obj_t * pObj; + int i; + Aig_ManForEachObj( pAig, pObj, i ) + if ( pAig->pReprs[i] != NULL ) + printf( "%s%d->%s%d ", + (Aig_ObjIsPi(pObj)? "pi": ""), + pObj->Id, + (Aig_ObjIsPi(pAig->pReprs[i])? "pi": ""), + pAig->pReprs[i]->Id ); + printf( "\n" ); +} +*/ // implement equivalence classes and remove dangling nodes Ntl_ManReduce( pNew, pAig ); Ntl_ManSweep( pNew, fVerbose ); @@ -503,7 +519,7 @@ Aig_Man_t * Ntl_ManAigToRst( Ntl_Man_t * pNtl, Aig_Man_t * p ) if ( iRstNum < 0 ) continue; assert( iRstNum < nResets ); - pObj->pData = Aig_And( pNew, pObj->pData, Aig_ManPi(pNew, iRstNum) ); // could be NOT(pi) + pObj->pData = Aig_And( pNew, (Aig_Obj_t *)pObj->pData, Aig_ManPi(pNew, iRstNum) ); // could be NOT(pi) Counter++; } else if ( Aig_ObjIsConst1(pObj) ) @@ -578,7 +594,7 @@ void Ntl_ManRemapClassesScorr( Ntl_Man_t * pNtl, Aig_Man_t * p, Aig_Man_t * pNew // map things back Aig_ManForEachObj( p, pObj, i ) { - pObjNew = pObj->pData; + pObjNew = (Aig_Obj_t *)pObj->pData; assert( pObjNew != NULL && !Aig_IsComplement(pObjNew) ); pObjNew->pData = pObj; } @@ -588,8 +604,8 @@ void Ntl_ManRemapClassesScorr( Ntl_Man_t * pNtl, Aig_Man_t * p, Aig_Man_t * pNew pObjNewRepr = pNew->pReprs[pObjNew->Id]; if ( pObjNewRepr == NULL ) continue; - pObj = pObjNew->pData; - pObjRepr = pObjNewRepr->pData; + pObj = (Aig_Obj_t *)pObjNew->pData; + pObjRepr = (Aig_Obj_t *)pObjNewRepr->pData; assert( Aig_ObjId(pObjRepr) < Aig_ObjId(pObj) ); Aig_ObjCreateRepr( p, pObjRepr, pObj ); } @@ -787,6 +803,8 @@ Ntl_Man_t * Ntl_ManScorr( Ntl_Man_t * p, Ssw_Pars_t * pPars ) } else { + pPars->fVerbose = 1; + pTemp = Ssw_SignalCorrespondence( pAigCol, pPars ); Aig_ManStop( pTemp ); } @@ -872,7 +890,7 @@ void Ntl_ManAttachWhiteBoxes( Ntl_Man_t * p, Aig_Man_t * pAigCol, Aig_Man_t * pA if ( pNet->pCopy == NULL ) continue; // skip the outputs that are not preserved after merging equivalence - if ( Aig_Regular(pNet->pCopy2)->pData == NULL ) + if ( Aig_Regular((Aig_Obj_t *)pNet->pCopy2)->pData == NULL ) continue; break; } @@ -982,3 +1000,5 @@ Ntl_Man_t * Ntl_ManSsw2( Ntl_Man_t * p, Fra_Ssw_t * pPars ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ntl/ntlInsert.c b/src/aig/ntl/ntlInsert.c index 750eb8f7..8b0e3493 100644 --- a/src/aig/ntl/ntlInsert.c +++ b/src/aig/ntl/ntlInsert.c @@ -21,6 +21,9 @@ #include "ntl.h" #include "kit.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -65,7 +68,7 @@ Ntl_Man_t * Ntl_ManInsertMapping( Ntl_Man_t * p, Vec_Ptr_t * vMapping, Aig_Man_t // create a new node for each LUT vCover = Vec_IntAlloc( 1 << 16 ); nDigits = Aig_Base10Log( Vec_PtrSize(vMapping) ); - Vec_PtrForEachEntry( vMapping, pLut, i ) + Vec_PtrForEachEntry( Ntl_Lut_t *, vMapping, pLut, i ) { pNode = Ntl_ModelCreateNode( pRoot, pLut->nFanins ); pNode->pSop = Kit_PlaFromTruth( p->pMemSops, pLut->pTruth, pLut->nFanins, vCover ); @@ -73,7 +76,7 @@ Ntl_Man_t * Ntl_ManInsertMapping( Ntl_Man_t * p, Vec_Ptr_t * vMapping, Aig_Man_t { for ( k = 0; k < pLut->nFanins; k++ ) { - pNet = Vec_PtrEntry( vCopies, pLut->pFanins[k] ); + pNet = (Ntl_Net_t *)Vec_PtrEntry( vCopies, pLut->pFanins[k] ); if ( pNet == NULL ) { printf( "Ntl_ManInsert(): Internal error: Net not found.\n" ); @@ -108,9 +111,9 @@ Ntl_Man_t * Ntl_ManInsertMapping( Ntl_Man_t * p, Vec_Ptr_t * vMapping, Aig_Man_t if ( pNetCo->fMark ) continue; pNetCo->fMark = 1; - pNet = Vec_PtrEntry( vCopies, Aig_Regular(pNetCo->pCopy)->Id ); + pNet = (Ntl_Net_t *)Vec_PtrEntry( vCopies, Aig_Regular((Aig_Obj_t *)pNetCo->pCopy)->Id ); pNode = Ntl_ModelCreateNode( pRoot, 1 ); - pNode->pSop = Aig_IsComplement(pNetCo->pCopy)? Ntl_ManStoreSop( p->pMemSops, "0 1\n" ) : Ntl_ManStoreSop( p->pMemSops, "1 1\n" ); + pNode->pSop = Aig_IsComplement((Aig_Obj_t *)pNetCo->pCopy)? Ntl_ManStoreSop( p->pMemSops, "0 1\n" ) : Ntl_ManStoreSop( p->pMemSops, "1 1\n" ); Ntl_ObjSetFanin( pNode, pNet, 0 ); // update the CO driver net assert( pNetCo->pDriver == NULL ); @@ -187,8 +190,8 @@ Ntl_Man_t * Ntl_ManInsertAig( Ntl_Man_t * p, Aig_Man_t * pAig ) return 0; } pNode = Ntl_ModelCreateNode( pRoot, 2 ); - Ntl_ObjSetFanin( pNode, Aig_ObjFanin0(pObj)->pData, 0 ); - Ntl_ObjSetFanin( pNode, Aig_ObjFanin1(pObj)->pData, 1 ); + Ntl_ObjSetFanin( pNode, (Ntl_Net_t *)Aig_ObjFanin0(pObj)->pData, 0 ); + Ntl_ObjSetFanin( pNode, (Ntl_Net_t *)Aig_ObjFanin1(pObj)->pData, 1 ); if ( Aig_ObjFaninC0(pObj) && Aig_ObjFaninC1(pObj) ) pNode->pSop = Ntl_ManStoreSop( p->pMemSops, "00 1\n" ); else if ( Aig_ObjFaninC0(pObj) && !Aig_ObjFaninC1(pObj) ) @@ -224,7 +227,7 @@ Ntl_Man_t * Ntl_ManInsertAig( Ntl_Man_t * p, Aig_Man_t * pAig ) pObj = Aig_ManPo( pAig, i ); pFanin = Aig_ObjFanin0( pObj ); // get the net driving the driver - pNet = pFanin->pData; + pNet = (Ntl_Net_t *)pFanin->pData; pNode = Ntl_ModelCreateNode( pRoot, 1 ); pNode->pSop = Aig_ObjFaninC0(pObj)? Ntl_ManStoreSop( p->pMemSops, "0 1\n" ) : Ntl_ManStoreSop( p->pMemSops, "1 1\n" ); Ntl_ObjSetFanin( pNode, pNet, 0 ); @@ -317,7 +320,7 @@ Ntl_Man_t * Ntl_ManInsertNtk2( Ntl_Man_t * p, Nwk_Man_t * pNtk ) nDigits = Aig_Base10Log( Nwk_ManNodeNum(pNtk) ); // go through the nodes in the topological order vObjs = Nwk_ManDfs( pNtk ); - Vec_PtrForEachEntry( vObjs, pObj, i ) + Vec_PtrForEachEntry( Nwk_Obj_t *, vObjs, pObj, i ) { if ( !Nwk_ObjIsNode(pObj) ) continue; @@ -351,7 +354,7 @@ Ntl_Man_t * Ntl_ManInsertNtk2( Ntl_Man_t * p, Nwk_Man_t * pNtk ) { Nwk_ObjForEachFanin( pObj, pFanin, k ) { - pNet = pFanin->pCopy; + pNet = (Ntl_Net_t *)pFanin->pCopy; if ( pNet == NULL ) { printf( "Ntl_ManInsertNtk(): Internal error: Net not found.\n" ); @@ -404,7 +407,7 @@ Ntl_Man_t * Ntl_ManInsertNtk2( Ntl_Man_t * p, Nwk_Man_t * pNtk ) pObj = Nwk_ManCo( pNtk, i ); pFanin = Nwk_ObjFanin0( pObj ); // get the net driving this PO - pNet = pFanin->pCopy; + pNet = (Ntl_Net_t *)pFanin->pCopy; if ( pNet == NULL ) // constant net { assert( fWriteConstants ); @@ -500,7 +503,7 @@ Ntl_Man_t * Ntl_ManInsertNtk( Ntl_Man_t * p, Nwk_Man_t * pNtk ) nDigits = Aig_Base10Log( Nwk_ManNodeNum(pNtk) ); // go through the nodes in the topological order vObjs = Nwk_ManDfs( pNtk ); - Vec_PtrForEachEntry( vObjs, pObj, i ) + Vec_PtrForEachEntry( Nwk_Obj_t *, vObjs, pObj, i ) { if ( !Nwk_ObjIsNode(pObj) ) continue; @@ -512,7 +515,7 @@ Ntl_Man_t * Ntl_ManInsertNtk( Ntl_Man_t * p, Nwk_Man_t * pNtk ) { Nwk_ObjForEachFanin( pObj, pFanin, k ) { - pNet = pFanin->pCopy; + pNet = (Ntl_Net_t *)pFanin->pCopy; if ( pNet == NULL ) { printf( "Ntl_ManInsertNtk(): Internal error: Net not found.\n" ); @@ -562,7 +565,7 @@ Ntl_Man_t * Ntl_ManInsertNtk( Ntl_Man_t * p, Nwk_Man_t * pNtk ) pObj = Nwk_ManCo( pNtk, i ); pFanin = Nwk_ObjFanin0( pObj ); // get the net driving this PO - pNet = pFanin->pCopy; + pNet = (Ntl_Net_t *)pFanin->pCopy; if ( Nwk_ObjFanoutNum(pFanin) == 1 && Ntl_ObjIsNode(pNet->pDriver) ) { pNode = pNet->pDriver; @@ -607,3 +610,5 @@ Ntl_Man_t * Ntl_ManInsertNtk( Ntl_Man_t * p, Nwk_Man_t * pNtk ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ntl/ntlMan.c b/src/aig/ntl/ntlMan.c index b5ad7815..45fb7226 100644 --- a/src/aig/ntl/ntlMan.c +++ b/src/aig/ntl/ntlMan.c @@ -20,6 +20,9 @@ #include "ntl.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -108,7 +111,7 @@ Ntl_Man_t * Ntl_ManStartFrom( Ntl_Man_t * pOld ) pNew = Ntl_ManAlloc(); pNew->pName = Ntl_ManStoreFileName( pNew, pOld->pName ); pNew->pSpec = Ntl_ManStoreName( pNew, pOld->pName ); - Vec_PtrForEachEntry( pOld->vModels, pModel, i ) + Vec_PtrForEachEntry( Ntl_Mod_t *, pOld->vModels, pModel, i ) { if ( i == 0 ) { @@ -119,10 +122,10 @@ Ntl_Man_t * Ntl_ManStartFrom( Ntl_Man_t * pOld ) else pModel->pCopy = Ntl_ModelDup( pNew, pModel ); } - Vec_PtrForEachEntry( pOld->vModels, pModel, i ) + Vec_PtrForEachEntry( Ntl_Mod_t *, pOld->vModels, pModel, i ) Ntl_ModelForEachBox( pModel, pBox, k ) { - ((Ntl_Obj_t *)pBox->pCopy)->pImplem = pBox->pImplem->pCopy; + ((Ntl_Obj_t *)pBox->pCopy)->pImplem = (Ntl_Mod_t *)pBox->pImplem->pCopy; ((Ntl_Obj_t *)pBox->pCopy)->iTemp = pBox->iTemp; // ((Ntl_Obj_t *)pBox->pCopy)->Reset = pBox->Reset; } @@ -158,11 +161,11 @@ Ntl_Man_t * Ntl_ManDup( Ntl_Man_t * pOld ) pNew = Ntl_ManAlloc(); pNew->pName = Ntl_ManStoreFileName( pNew, pOld->pName ); pNew->pSpec = Ntl_ManStoreName( pNew, pOld->pName ); - Vec_PtrForEachEntry( pOld->vModels, pModel, i ) + Vec_PtrForEachEntry( Ntl_Mod_t *, pOld->vModels, pModel, i ) pModel->pCopy = Ntl_ModelDup( pNew, pModel ); - Vec_PtrForEachEntry( pOld->vModels, pModel, i ) + Vec_PtrForEachEntry( Ntl_Mod_t *, pOld->vModels, pModel, i ) Ntl_ModelForEachBox( pModel, pBox, k ) - ((Ntl_Obj_t *)pBox->pCopy)->pImplem = pBox->pImplem->pCopy; + ((Ntl_Obj_t *)pBox->pCopy)->pImplem = (Ntl_Mod_t *)pBox->pImplem->pCopy; Ntl_ManForEachCiNet( pOld, pNet, i ) Vec_PtrPush( pNew->vCis, pNet->pCopy ); Ntl_ManForEachCoNet( pOld, pNet, i ) @@ -195,12 +198,12 @@ Ntl_Man_t * Ntl_ManDupCollapseLuts( Ntl_Man_t * pOld ) pNew = Ntl_ManAlloc(); pNew->pName = Ntl_ManStoreFileName( pNew, pOld->pName ); pNew->pSpec = Ntl_ManStoreName( pNew, pOld->pName ); - Vec_PtrForEachEntry( pOld->vModels, pModel, i ) + Vec_PtrForEachEntry( Ntl_Mod_t *, pOld->vModels, pModel, i ) pModel->pCopy = Ntl_ModelDupCollapseLuts( pNew, pModel ); - Vec_PtrForEachEntry( pOld->vModels, pModel, i ) + Vec_PtrForEachEntry( Ntl_Mod_t *, pOld->vModels, pModel, i ) Ntl_ModelForEachBox( pModel, pBox, k ) if ( pBox->pCopy ) - ((Ntl_Obj_t *)pBox->pCopy)->pImplem = pBox->pImplem->pCopy; + ((Ntl_Obj_t *)pBox->pCopy)->pImplem = (Ntl_Mod_t *)pBox->pImplem->pCopy; // Ntl_ManForEachCiNet( pOld, pNet, i ) // Vec_PtrPush( pNew->vCis, pNet->pCopy ); // Ntl_ManForEachCoNet( pOld, pNet, i ) @@ -301,10 +304,16 @@ void Nwk_ManPrintStatsShort( Ntl_Man_t * p, Aig_Man_t * pAig, Nwk_Man_t * pNtk ) Ntl_ModelForEachBox( pRoot, pObj, i ) if ( strcmp(pObj->pImplem->pName, "dff") == 0 ) Counter++; + if ( Counter == 0 ) + { + Ntl_ModelForEachBox( pRoot, pObj, i ) + Counter += (pObj->pImplem->attrWhite && !pObj->pImplem->attrComb); + } printf( "%-15s : ", p->pName ); printf( "pi =%5d ", Ntl_ModelPiNum(pRoot) ); printf( "po =%5d ", Ntl_ModelPoNum(pRoot) ); printf( "ff =%5d ", Counter ); + printf( "box =%6d ", Ntl_ModelBoxNum(pRoot) ); if ( pAig != NULL ) { Counter = Aig_ManChoiceNum( pAig ); @@ -314,7 +323,7 @@ void Nwk_ManPrintStatsShort( Ntl_Man_t * p, Aig_Man_t * pAig, Nwk_Man_t * pNtk ) printf( "aig =%7d ", Aig_ManNodeNum(pAig) ); } if ( pNtk == NULL ) - printf( "Mapping is not available.\n" ); + printf( "No mapping.\n" ); else { printf( "lut =%5d ", Nwk_ManNodeNum(pNtk) ); @@ -509,7 +518,7 @@ void Ntl_ManPrintTypes( Ntl_Man_t * p ) printf( "CLOCK STATISTICS:\n" ); Vec_VecForEachLevel( pModel->vClockFlops, vFlops, i ) { - pNet = Vec_PtrEntry( pModel->vClocks, i ); + pNet = (Ntl_Net_t *)Vec_PtrEntry( pModel->vClocks, i ); printf( "Clock %2d : Name = %30s Flops = %6d.\n", i+1, pNet->pName, Vec_PtrSize(vFlops) ); } } @@ -562,7 +571,7 @@ void Ntl_ManPrintClocks( Ntl_Man_t * p ) printf( "CLOCK STATISTICS:\n" ); Vec_VecForEachLevel( pModel->vClockFlops, vFlops, i ) { - pNet = Vec_PtrEntry( pModel->vClocks, i ); + pNet = (Ntl_Net_t *)Vec_PtrEntry( pModel->vClocks, i ); printf( "Clock %2d : Name = %30s Flops = %6d.\n", i+1, pNet->pName, Vec_PtrSize(vFlops) ); if ( i == 10 ) { @@ -599,7 +608,7 @@ void Ntl_ManPrintResets( Ntl_Man_t * p ) printf( "RESET STATISTICS:\n" ); Vec_VecForEachLevel( pModel->vResetFlops, vFlops, i ) { - pNet = Vec_PtrEntry( pModel->vResets, i ); + pNet = (Ntl_Net_t *)Vec_PtrEntry( pModel->vResets, i ); printf( "Reset %2d : Name = %30s Flops = %6d.\n", i+1, pNet->pName, Vec_PtrSize(vFlops) ); if ( i == 10 ) { @@ -690,7 +699,7 @@ Ntl_Mod_t * Ntl_ModelStartFrom( Ntl_Man_t * pManNew, Ntl_Mod_t * pModelOld ) else if ( pNet->fMark ) { pNet->pCopy = Ntl_ModelFindOrCreateNet( pModelNew, pNet->pName ); - ((Ntl_Net_t *)pNet->pCopy)->pDriver = pNet->pDriver->pCopy; + ((Ntl_Net_t *)pNet->pCopy)->pDriver = (Ntl_Obj_t *)pNet->pDriver->pCopy; } else pNet->pCopy = NULL; @@ -703,14 +712,14 @@ Ntl_Mod_t * Ntl_ModelStartFrom( Ntl_Man_t * pManNew, Ntl_Mod_t * pModelOld ) continue; Ntl_ObjForEachFanin( pObj, pNet, k ) if ( pNet->pCopy != NULL ) - Ntl_ObjSetFanin( pObj->pCopy, pNet->pCopy, k ); + Ntl_ObjSetFanin( (Ntl_Obj_t *)pObj->pCopy, (Ntl_Net_t *)pNet->pCopy, k ); Ntl_ObjForEachFanout( pObj, pNet, k ) if ( pNet->pCopy != NULL ) - Ntl_ObjSetFanout( pObj->pCopy, pNet->pCopy, k ); + Ntl_ObjSetFanout( (Ntl_Obj_t *)pObj->pCopy, (Ntl_Net_t *)pNet->pCopy, k ); if ( Ntl_ObjIsLatch(pObj) ) { ((Ntl_Obj_t *)pObj->pCopy)->LatchId = pObj->LatchId; - ((Ntl_Obj_t *)pObj->pCopy)->pClock = pObj->pClock->pCopy; + ((Ntl_Obj_t *)pObj->pCopy)->pClock = (Ntl_Net_t *)pObj->pClock->pCopy; } } pModelNew->vDelays = pModelOld->vDelays? Vec_IntDup( pModelOld->vDelays ) : NULL; @@ -753,19 +762,19 @@ Ntl_Mod_t * Ntl_ModelDup( Ntl_Man_t * pManNew, Ntl_Mod_t * pModelOld ) assert( !pModelOld->attrWhite ); continue; } - ((Ntl_Net_t *)pNet->pCopy)->pDriver = pNet->pDriver->pCopy; + ((Ntl_Net_t *)pNet->pCopy)->pDriver = (Ntl_Obj_t *)pNet->pDriver->pCopy; assert( pNet->pDriver->pCopy != NULL ); } Ntl_ModelForEachObj( pModelOld, pObj, i ) { Ntl_ObjForEachFanin( pObj, pNet, k ) - Ntl_ObjSetFanin( pObj->pCopy, pNet->pCopy, k ); + Ntl_ObjSetFanin( (Ntl_Obj_t *)pObj->pCopy, (Ntl_Net_t *)pNet->pCopy, k ); Ntl_ObjForEachFanout( pObj, pNet, k ) - Ntl_ObjSetFanout( pObj->pCopy, pNet->pCopy, k ); + Ntl_ObjSetFanout( (Ntl_Obj_t *)pObj->pCopy, (Ntl_Net_t *)pNet->pCopy, k ); if ( Ntl_ObjIsLatch(pObj) ) { ((Ntl_Obj_t *)pObj->pCopy)->LatchId = pObj->LatchId; - ((Ntl_Obj_t *)pObj->pCopy)->pClock = pObj->pClock? pObj->pClock->pCopy : NULL; + ((Ntl_Obj_t *)pObj->pCopy)->pClock = pObj->pClock? (Ntl_Net_t *)pObj->pClock->pCopy : NULL; } if ( Ntl_ObjIsNode(pObj) ) ((Ntl_Obj_t *)pObj->pCopy)->pSop = Ntl_ManStoreSop( pManNew->pMemSops, pObj->pSop ); @@ -821,7 +830,7 @@ Ntl_Mod_t * Ntl_ModelDupCollapseLuts( Ntl_Man_t * pManNew, Ntl_Mod_t * pModelOld } if ( Ntl_ObjIsLutBox(pNet->pDriver) ) continue; - ((Ntl_Net_t *)pNet->pCopy)->pDriver = pNet->pDriver->pCopy; + ((Ntl_Net_t *)pNet->pCopy)->pDriver = (Ntl_Obj_t *)pNet->pDriver->pCopy; assert( pNet->pDriver->pCopy != NULL ); } Ntl_ModelForEachObj( pModelOld, pObj, i ) @@ -848,33 +857,33 @@ Ntl_Mod_t * Ntl_ModelDupCollapseLuts( Ntl_Man_t * pManNew, Ntl_Mod_t * pModelOld continue; sprintf( pNameBuf, "box%d_%s", i, pNet->pName ); pNet->pCopy = Ntl_ModelFindOrCreateNet( pModelNew, pNameBuf ); // change name!!! - ((Ntl_Net_t *)pNet->pCopy)->pDriver = pNet->pDriver->pCopy; + ((Ntl_Net_t *)pNet->pCopy)->pDriver = (Ntl_Obj_t *)pNet->pDriver->pCopy; } // connect nodes Ntl_ModelForEachNode( pModelBox, pObjBox, k ) { Ntl_ObjForEachFanin( pObjBox, pNet, m ) - Ntl_ObjSetFanin( pObjBox->pCopy, pNet->pCopy, m ); + Ntl_ObjSetFanin( (Ntl_Obj_t *)pObjBox->pCopy, (Ntl_Net_t *)pNet->pCopy, m ); Ntl_ObjForEachFanout( pObjBox, pNet, m ) - Ntl_ObjSetFanout( pObjBox->pCopy, pNet->pCopy, m ); + Ntl_ObjSetFanout( (Ntl_Obj_t *)pObjBox->pCopy, (Ntl_Net_t *)pNet->pCopy, m ); ((Ntl_Obj_t *)pObjBox->pCopy)->pSop = Ntl_ManStoreSop( pManNew->pMemSops, pObjBox->pSop ); } // connect the PO nets Ntl_ModelForEachPo( pModelBox, pObjBox, k ) - ((Ntl_Net_t *)Ntl_ObjFanin0(pObjBox)->pCopy)->pDriver = Ntl_ObjFanin0(pObjBox)->pDriver->pCopy; + ((Ntl_Net_t *)Ntl_ObjFanin0(pObjBox)->pCopy)->pDriver = (Ntl_Obj_t *)Ntl_ObjFanin0(pObjBox)->pDriver->pCopy; assert( pObj->pCopy == NULL ); Counter++; } else { Ntl_ObjForEachFanin( pObj, pNet, k ) - Ntl_ObjSetFanin( pObj->pCopy, pNet->pCopy, k ); + Ntl_ObjSetFanin( (Ntl_Obj_t *)pObj->pCopy, (Ntl_Net_t *)pNet->pCopy, k ); Ntl_ObjForEachFanout( pObj, pNet, k ) - Ntl_ObjSetFanout( pObj->pCopy, pNet->pCopy, k ); + Ntl_ObjSetFanout( (Ntl_Obj_t *)pObj->pCopy, (Ntl_Net_t *)pNet->pCopy, k ); if ( Ntl_ObjIsLatch(pObj) ) { ((Ntl_Obj_t *)pObj->pCopy)->LatchId = pObj->LatchId; - ((Ntl_Obj_t *)pObj->pCopy)->pClock = pObj->pClock? pObj->pClock->pCopy : NULL; + ((Ntl_Obj_t *)pObj->pCopy)->pClock = pObj->pClock? (Ntl_Net_t *)pObj->pClock->pCopy : NULL; } if ( Ntl_ObjIsNode(pObj) ) ((Ntl_Obj_t *)pObj->pCopy)->pSop = Ntl_ManStoreSop( pManNew->pMemSops, pObj->pSop ); @@ -1055,3 +1064,5 @@ int Ntl_ModelCountInv( Ntl_Mod_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ntl/ntlMap.c b/src/aig/ntl/ntlMap.c index 10e7dd17..0ce8549d 100644 --- a/src/aig/ntl/ntlMap.c +++ b/src/aig/ntl/ntlMap.c @@ -22,6 +22,9 @@ #include "kit.h" #include "if.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -80,14 +83,14 @@ Vec_Ptr_t * Ntl_MappingFromAig( Aig_Man_t * p ) vMapping = Ntl_MappingAlloc( Aig_ManAndNum(p) + (int)(Aig_ManConst1(p)->nRefs > 0), 2 ); if ( Aig_ManConst1(p)->nRefs > 0 ) { - pLut = Vec_PtrEntry( vMapping, k++ ); + pLut = (Ntl_Lut_t *)Vec_PtrEntry( vMapping, k++ ); pLut->Id = 0; pLut->nFanins = 0; memset( pLut->pTruth, 0xFF, nBytes ); } Aig_ManForEachNode( p, pObj, i ) { - pLut = Vec_PtrEntry( vMapping, k++ ); + pLut = (Ntl_Lut_t *)Vec_PtrEntry( vMapping, k++ ); pLut->Id = pObj->Id; pLut->nFanins = 2; pLut->pFanins[0] = Aig_ObjFaninId0(pObj); @@ -200,7 +203,7 @@ If_Man_t * Ntl_ManToIf( Aig_Man_t * p, If_Par_t * pPars ) pIfMan->nLevelMax = (int)pNode->Level; } else if ( Aig_ObjIsPo(pNode) ) - pNode->pData = If_ManCreateCo( pIfMan, If_NotCond( Aig_ObjFanin0(pNode)->pData, Aig_ObjFaninC0(pNode) ) ); + pNode->pData = If_ManCreateCo( pIfMan, If_NotCond( (If_Obj_t *)Aig_ObjFanin0(pNode)->pData, Aig_ObjFaninC0(pNode) ) ); else if ( Aig_ObjIsConst1(pNode) ) Aig_ManConst1(p)->pData = If_ManConst1( pIfMan ); else // add the node to the mapper @@ -214,7 +217,7 @@ If_Man_t * Ntl_ManToIf( Aig_Man_t * p, If_Par_t * pPars ) // If_ManCreateChoice( pIfMan, (If_Obj_t *)pNode->pData ); // } { - If_Obj_t * pIfObj = pNode->pData; + If_Obj_t * pIfObj = (If_Obj_t *)pNode->pData; assert( !If_IsComplement(pIfObj) ); assert( pIfObj->Id == pNode->Id ); } @@ -255,7 +258,7 @@ Vec_Ptr_t * Ntl_ManFromIf( Aig_Man_t * p, If_Man_t * pMan ) continue; if ( Aig_ObjIsPi(pObj) && pObj->pData == NULL ) continue; - pNode = pObj->pData; + pNode = (If_Obj_t *)pObj->pData; assert( pNode != NULL ); Vec_IntWriteEntry( vIfToAig, pNode->Id, pObj->Id ); } @@ -267,19 +270,19 @@ Vec_Ptr_t * Ntl_ManFromIf( Aig_Man_t * p, If_Man_t * pMan ) nLuts = 0; if ( Aig_ManConst1(p)->nRefs > 0 ) { - pLut = Vec_PtrEntry( vMapping, nLuts++ ); + pLut = (Ntl_Lut_t *)Vec_PtrEntry( vMapping, nLuts++ ); pLut->Id = 0; pLut->nFanins = 0; memset( pLut->pTruth, 0xFF, 4 * nWords ); } - Vec_PtrForEachEntry( vIfMap, pNode, i ) + Vec_PtrForEachEntry( If_Obj_t *, vIfMap, pNode, i ) { // get the best cut pCutBest = If_ObjCutBest(pNode); nLeaves = If_CutLeaveNum( pCutBest ); ppLeaves = If_CutLeaves( pCutBest ); // fill the LUT - pLut = Vec_PtrEntry( vMapping, nLuts++ ); + pLut = (Ntl_Lut_t *)Vec_PtrEntry( vMapping, nLuts++ ); pLut->Id = Vec_IntEntry( vIfToAig, pNode->Id ); pLut->nFanins = nLeaves; If_CutForEachLeaf( pMan, pCutBest, pLeaf, k ) @@ -339,3 +342,5 @@ Vec_Ptr_t * Ntl_MappingIf( Ntl_Man_t * pMan, Aig_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ntl/ntlNames.c b/src/aig/ntl/ntlNames.c new file mode 100644 index 00000000..fa91711d --- /dev/null +++ b/src/aig/ntl/ntlNames.c @@ -0,0 +1,471 @@ +/**CFile**************************************************************** + + FileName [ntlNames.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Netlist representation.] + + Synopsis [Data-structure for storing hiNamrchical object names.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: ntlNames.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "ntl.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +// name object +typedef struct Ntl_ObjNam_t_ Ntl_ObjNam_t; +struct Ntl_ObjNam_t_ +{ + int iPrev; // prefix of this name + int iNext; // the next name in the hash table + char pName[0]; // name characters +}; + +// name manager +typedef struct Ntl_ManNam_t_ Ntl_ManNam_t; +struct Ntl_ManNam_t_ +{ + // info storage for names + char * pStore; // storage for name objects + int nStore; // the size of allocated storage + int iHandle; // the current free handle + int nHandles; // the number of handles + int nRefs; // reference counter for the manager + // hash table for names + int nBins; + unsigned * pBins; + // temporaries + Vec_Str_t * vName; // storage for returned name +}; + +static inline Ntl_ObjNam_t * Ntl_ManNamObj( Ntl_ManNam_t * p, int h ) { assert( !(h & 3) ); return (Ntl_ObjNam_t *)(p->pStore + h); } +static inline int Ntl_ManNamObjHandle( Ntl_ManNam_t * p, Ntl_ObjNam_t * pObj ) { return ((char *)pObj) - p->pStore; } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Creates manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ntl_ManNam_t * Ntl_ManNamStart() +{ + Ntl_ManNam_t * p; + p = ABC_CALLOC( Ntl_ManNam_t, 1 ); + p->nStore = (1 << 20); + p->pStore = ABC_ALLOC( char, p->nStore ); + p->iHandle = 4; + p->nBins = Aig_PrimeCudd( 500000 ); + p->pBins = ABC_CALLOC( unsigned, p->nBins ); + p->vName = Vec_StrAlloc( 1000 ); + return p; +} + +/**Function************************************************************* + + Synopsis [Deletes manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ntl_ManNamStop( Ntl_ManNam_t * p ) +{ + Vec_StrFree( p->vName ); + ABC_FREE( p->pStore ); + ABC_FREE( p->pBins ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [Deletes manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ntl_ManNamReportMemUsage( Ntl_ManNam_t * p ) +{ + return sizeof(Ntl_ManNam_t) + p->nStore + sizeof(int) * p->nBins + sizeof(int) * Vec_StrSize(p->vName); +} + +/**Function************************************************************* + + Synopsis [References the manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ntl_ManNamRef( Ntl_ManNam_t * p ) +{ + p->nRefs++; +} + +/**Function************************************************************* + + Synopsis [Dereferences the manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ntl_ManNamDeref( Ntl_ManNam_t * p ) +{ + if ( --p->nRefs == 0 ) + Ntl_ManNamStop( p ); +} + +/**Function************************************************************* + + Synopsis [Returns object with the given handle.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + + +/**Function************************************************************* + + Synopsis [Computes hash value of the node using its simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ntl_ManNamStrHash( char * pStr, int Length, int nTableSize ) +{ + static int s_FPrimes[128] = { + 1009, 1049, 1093, 1151, 1201, 1249, 1297, 1361, 1427, 1459, + 1499, 1559, 1607, 1657, 1709, 1759, 1823, 1877, 1933, 1997, + 2039, 2089, 2141, 2213, 2269, 2311, 2371, 2411, 2467, 2543, + 2609, 2663, 2699, 2741, 2797, 2851, 2909, 2969, 3037, 3089, + 3169, 3221, 3299, 3331, 3389, 3461, 3517, 3557, 3613, 3671, + 3719, 3779, 3847, 3907, 3943, 4013, 4073, 4129, 4201, 4243, + 4289, 4363, 4441, 4493, 4549, 4621, 4663, 4729, 4793, 4871, + 4933, 4973, 5021, 5087, 5153, 5227, 5281, 5351, 5417, 5471, + 5519, 5573, 5651, 5693, 5749, 5821, 5861, 5923, 6011, 6073, + 6131, 6199, 6257, 6301, 6353, 6397, 6481, 6563, 6619, 6689, + 6737, 6803, 6863, 6917, 6977, 7027, 7109, 7187, 7237, 7309, + 7393, 7477, 7523, 7561, 7607, 7681, 7727, 7817, 7877, 7933, + 8011, 8039, 8059, 8081, 8093, 8111, 8123, 8147 + }; + unsigned uHash; + int i; + uHash = 0; + for ( i = 0; i < Length; i++ ) + if ( i & 1 ) + uHash *= pStr[i] * s_FPrimes[i & 0x7F]; + else + uHash ^= pStr[i] * s_FPrimes[i & 0x7F]; + return uHash % nTableSize; +} + + +/**Function************************************************************* + + Synopsis [Compares two strings to be equal.] + + Description [Returns 1 if the strings match.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ntl_ManNamStrCompare_rec( Ntl_ManNam_t * p, char * pStr, int Length, Ntl_ObjNam_t * pThis ) +{ + Ntl_ObjNam_t * pNext = (pThis->iPrev)? Ntl_ManNamObj(p, pThis->iPrev) : NULL; + int LengthNew = strlen(pThis->pName); + if ( !strncmp( pThis->pName, pStr + Length - LengthNew, LengthNew ) ) + return 0; + if ( pNext == NULL ) + return 1; + return Ntl_ManNamStrCompare_rec( p, pStr, Length - LengthNew, pNext ); +} + + +/**Function************************************************************* + + Synopsis [Returns the place of this state in the table or NULL if it exists.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline unsigned * Ntl_ManNamStrHashFind( Ntl_ManNam_t * p, char * pStr, int Length, int * pHandle ) +{ + Ntl_ObjNam_t * pThis; + unsigned * pPlace = p->pBins + Ntl_ManNamStrHash( pStr, Length, p->nBins ); + for ( pThis = (*pPlace)? Ntl_ManNamObj(p, *pPlace) : NULL; pThis; + pPlace = (unsigned *)&pThis->iNext, pThis = (*pPlace)? Ntl_ManNamObj(p, *pPlace) : NULL ) + if ( !Ntl_ManNamStrCompare_rec( p, pStr, Length, pThis ) ) + { + *pHandle = Ntl_ManNamObjHandle( p, pThis ); + return NULL; + } + *pHandle = -1; + return pPlace; +} + +/**Function************************************************************* + + Synopsis [Resizes the hash table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ntl_ManNamStrHashResize( Ntl_ManNam_t * p ) +{ + Ntl_ObjNam_t * pThis; + unsigned * pBinsOld, * piPlace; + int nBinsOld, iNext, iHandle, Counter, i; + assert( p->pBins != NULL ); + // replace the table + pBinsOld = p->pBins; + nBinsOld = p->nBins; + p->nBins = Aig_PrimeCudd( 3 * p->nBins ); + p->pBins = ABC_CALLOC( unsigned, p->nBins ); + // rehash the entries from the old table + Counter = 0; + for ( i = 0; i < nBinsOld; i++ ) + for ( pThis = (pBinsOld[i]? Ntl_ManNamObj(p, pBinsOld[i]) : NULL), + iNext = (pThis? pThis->iNext : 0); + pThis; pThis = (iNext? Ntl_ManNamObj(p, iNext) : NULL), + iNext = (pThis? pThis->iNext : 0) ) + { + pThis->iNext = 0; + piPlace = Ntl_ManNamStrHashFind( p, pThis->pName, strlen(pThis->pName), &iHandle ); + assert( *piPlace == 0 ); // should not be there + *piPlace = Ntl_ManNamObjHandle( p, pThis ); + Counter++; + } + assert( Counter == p->nHandles ); + ABC_FREE( pBinsOld ); +} + +/**Function************************************************************* + + Synopsis [Returns the handle of a new object to represent the name.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ntl_ManNamStrGrow_rec( Ntl_ManNam_t * p, char * pStr, int Length, unsigned * piPlace ) +{ + Ntl_ObjNam_t * pThis; + char * pStrNew; + int Separ, LengthNew; + int iHandle; + assert( Length > 0 ); + // find the separator symbol + for ( Separ = Length - 2; Separ >= 0 && pStr[Separ] != '/'; Separ-- ); + pStrNew = (Separ == -1) ? pStr : pStr + Separ + 1; + LengthNew = Length - (pStrNew - pStr); + // realloc memory if needed + if ( p->iHandle + (int)sizeof(Ntl_ObjNam_t) + LengthNew+5 > p->nStore ) + { + int OffSet; + if ( (char *)piPlace > p->pStore && (char *)piPlace < p->pStore + p->nStore ) + OffSet = (char *)piPlace - p->pStore; + else + OffSet = -1; + p->nStore *= 2; + p->pStore = ABC_REALLOC( char, p->pStore, p->nStore ); + if ( OffSet >= 0 ) + piPlace = (unsigned *)(p->pStore + OffSet); + } + // new entry is created + p->nHandles++; + *piPlace = p->iHandle; + pThis = Ntl_ManNamObj( p, p->iHandle ); + p->iHandle += sizeof(Ntl_ObjNam_t) + 4 * Aig_BitWordNum( 8*(LengthNew+1) ); + pThis->iNext = 0; + pThis->iPrev = 0; + strncpy( pThis->pName, pStrNew, LengthNew ); + pThis->pName[LengthNew] = 0; + // expand hash table if needed +// if ( p->nHandles > 2 * p->nBins ) +// Ntl_ManNamStrHashResize( p ); + // create previous object if needed + if ( Separ >= 0 ) + { + assert( pStr[Separ] == '/' ); + Separ++; + piPlace = Ntl_ManNamStrHashFind( p, pStr, Separ, &iHandle ); + if ( piPlace != NULL ) + iHandle = Ntl_ManNamStrGrow_rec( p, pStr, Separ, piPlace ); + pThis->iPrev = iHandle; + } + return Ntl_ManNamObjHandle( p, pThis ); +} + +/**Function************************************************************* + + Synopsis [Finds or adds the given name to storage.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ntl_ManNamStrFind( Ntl_ManNam_t * p, char * pStr ) +{ + int iHandle; + Ntl_ManNamStrHashFind( p, pStr, strlen(pStr), &iHandle ); + return iHandle; +} + +/**Function************************************************************* + + Synopsis [Finds or adds the given name to storage.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned Ntl_ManNamStrFindOrAdd( Ntl_ManNam_t * p, char * pStr ) +{ + unsigned * piPlace; + int iHandle, Length = strlen(pStr); + assert( Length > 0 ); + piPlace = Ntl_ManNamStrHashFind( p, pStr, Length, &iHandle ); + if ( piPlace == NULL ) + return iHandle; + assert( *piPlace == 0 ); + return Ntl_ManNamStrGrow_rec( p, pStr, Length, piPlace ); +} + +/**Function************************************************************* + + Synopsis [Returns name from handle.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Ntl_ManNamStr( Ntl_ManNam_t * p, int h ) +{ + Ntl_ObjNam_t * pObj; + int k; + assert( h && h < p->iHandle ); + Vec_StrClear( p->vName ); + for ( pObj = Ntl_ManNamObj( p, h ); pObj; pObj = pObj->iPrev ? Ntl_ManNamObj(p, pObj->iPrev) : NULL ) + for ( k = strlen(pObj->pName) - 1; k >= 0; k-- ) + Vec_StrPush( p->vName, pObj->pName[k] ); + Vec_StrReverseOrder( p->vName ); + Vec_StrPush( p->vName, 0 ); + return Vec_StrArray( p->vName ); +} + +/**Function************************************************************* + + Synopsis [Testing procedure for the manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ntl_ManNamTest( Ntl_Man_t * pNtl ) +{ + Ntl_ManNam_t * p; + Ntl_Mod_t * pRoot; + Ntl_Net_t * pNet; + int Memory; + int i, iHandle; + int clk = clock(); + + p = Ntl_ManNamStart(); +printf( "a" ); + Memory = 0; + pRoot = Ntl_ManRootModel( pNtl ); + Ntl_ModelForEachNet( pRoot, pNet, i ) + { + Memory += strlen(pNet->pName) + 1; + iHandle = Ntl_ManNamStrFindOrAdd( p, pNet->pName ); + +// printf( "Before = %s\n", pNet->pName ); +// printf( "After = %s\n", Ntl_ManNamStr(p, iHandle) ); + } + printf( "Net =%7d. Handle =%8d. ", Vec_PtrSize(pRoot->vNets), p->nHandles ); + printf( "Mem old = %7.2f Mb. Mem new = %7.2f Mb.\n", + 1.0 * Memory / (1 << 20), 1.0 * Ntl_ManNamReportMemUsage(p) / (1 << 20) ); + ABC_PRT( "Time", clock() - clk ); +printf( "b" ); + + Ntl_ManNamStop( p ); +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ntl/ntlObj.c b/src/aig/ntl/ntlObj.c index 1915d650..209974aa 100644 --- a/src/aig/ntl/ntlObj.c +++ b/src/aig/ntl/ntlObj.c @@ -20,6 +20,9 @@ #include "ntl.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -160,7 +163,7 @@ Ntl_Obj_t * Ntl_ModelCreateBox( Ntl_Mod_t * pModel, int nFanins, int nFanouts ) p->Type = NTL_OBJ_BOX; p->nFanins = nFanins; p->nFanouts = nFanouts; -// p->Reset = -1; + p->Reset = -1; pModel->nObjs[NTL_OBJ_BOX]++; return p; } @@ -246,7 +249,7 @@ char * Ntl_ManStoreName( Ntl_Man_t * p, char * pName ) SeeAlso [] ***********************************************************************/ -char * Ntl_ManStoreSop( Aig_MmFlex_t * pMan, char * pSop ) +char * Ntl_ManStoreSop( Aig_MmFlex_t * pMan, const char * pSop ) { char * pStore; pStore = Aig_MmFlexEntryFetch( pMan, strlen(pSop) + 1 ); @@ -312,3 +315,5 @@ int Ntl_ManObjWhichFanout( Ntl_Obj_t * pNode, Ntl_Net_t * pFanout ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ntl/ntlReadBlif.c b/src/aig/ntl/ntlReadBlif.c index 2e8a8096..103f8540 100644 --- a/src/aig/ntl/ntlReadBlif.c +++ b/src/aig/ntl/ntlReadBlif.c @@ -24,14 +24,17 @@ #include "bzlib.h" #include "zlib.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -typedef struct Ioa_ReadMod_t_ Ioa_ReadMod_t; // parsing model -typedef struct Ioa_ReadMan_t_ Ioa_ReadMan_t; // parsing manager +typedef struct Ntl_ReadMod_t_ Ntl_ReadMod_t; // parsing model +typedef struct Ntl_ReadMan_t_ Ntl_ReadMan_t; // parsing manager -struct Ioa_ReadMod_t_ +struct Ntl_ReadMod_t_ { // file lines char * pFirst; // .model line @@ -53,10 +56,10 @@ struct Ioa_ReadMod_t_ // the resulting network Ntl_Mod_t * pNtk; // the parent manager - Ioa_ReadMan_t * pMan; + Ntl_ReadMan_t * pMan; }; -struct Ioa_ReadMan_t_ +struct Ntl_ReadMan_t_ { // general info about file char * pFileName; // the name of the file @@ -66,7 +69,7 @@ struct Ioa_ReadMan_t_ Ntl_Man_t * pDesign; // the design under construction // intermediate storage for models Vec_Ptr_t * vModels; // vector of models - Ioa_ReadMod_t * pLatest; // the current model + Ntl_ReadMod_t * pLatest; // the current model // current processing info Vec_Ptr_t * vTokens; // the current tokens Vec_Ptr_t * vTokens2; // the current tokens @@ -79,28 +82,28 @@ struct Ioa_ReadMan_t_ }; // static functions -static Ioa_ReadMan_t * Ioa_ReadAlloc(); -static void Ioa_ReadFree( Ioa_ReadMan_t * p ); -static Ioa_ReadMod_t * Ioa_ReadModAlloc(); -static void Ioa_ReadModFree( Ioa_ReadMod_t * p ); -static char * Ioa_ReadLoadFile( char * pFileName ); -static char * Ioa_ReadLoadFileBz2( char * pFileName ); -static char * Ioa_ReadLoadFileGz( char * pFileName ); -static void Ioa_ReadReadPreparse( Ioa_ReadMan_t * p ); -static int Ioa_ReadReadInterfaces( Ioa_ReadMan_t * p ); -static Ntl_Man_t * Ioa_ReadParse( Ioa_ReadMan_t * p ); -static int Ioa_ReadParseLineModel( Ioa_ReadMod_t * p, char * pLine ); -static int Ioa_ReadParseLineAttrib( Ioa_ReadMod_t * p, char * pLine ); -static int Ioa_ReadParseLineInputs( Ioa_ReadMod_t * p, char * pLine ); -static int Ioa_ReadParseLineOutputs( Ioa_ReadMod_t * p, char * pLine ); -static int Ioa_ReadParseLineLatch( Ioa_ReadMod_t * p, char * pLine ); -static int Ioa_ReadParseLineSubckt( Ioa_ReadMod_t * p, char * pLine ); -static int Ioa_ReadParseLineDelay( Ioa_ReadMod_t * p, char * pLine ); -static int Ioa_ReadParseLineTimes( Ioa_ReadMod_t * p, char * pLine, int fOutput ); -static int Ioa_ReadParseLineNamesBlif( Ioa_ReadMod_t * p, char * pLine ); - -static int Ioa_ReadCharIsSpace( char s ) { return s == ' ' || s == '\t' || s == '\r' || s == '\n'; } -static int Ioa_ReadCharIsSopSymb( char s ) { return s == '0' || s == '1' || s == '-' || s == '\r' || s == '\n'; } +static Ntl_ReadMan_t * Ntl_ReadAlloc(); +static void Ntl_ReadFree( Ntl_ReadMan_t * p ); +static Ntl_ReadMod_t * Ntl_ReadModAlloc(); +static void Ntl_ReadModFree( Ntl_ReadMod_t * p ); +static char * Ntl_ReadLoadFile( char * pFileName ); +static char * Ntl_ReadLoadFileBz2( char * pFileName ); +static char * Ntl_ReadLoadFileGz( char * pFileName ); +static void Ntl_ReadReadPreparse( Ntl_ReadMan_t * p ); +static int Ntl_ReadReadInterfaces( Ntl_ReadMan_t * p ); +static Ntl_Man_t * Ntl_ReadParse( Ntl_ReadMan_t * p ); +static int Ntl_ReadParseLineModel( Ntl_ReadMod_t * p, char * pLine ); +static int Ntl_ReadParseLineAttrib( Ntl_ReadMod_t * p, char * pLine ); +static int Ntl_ReadParseLineInputs( Ntl_ReadMod_t * p, char * pLine ); +static int Ntl_ReadParseLineOutputs( Ntl_ReadMod_t * p, char * pLine ); +static int Ntl_ReadParseLineLatch( Ntl_ReadMod_t * p, char * pLine ); +static int Ntl_ReadParseLineSubckt( Ntl_ReadMod_t * p, char * pLine ); +static int Ntl_ReadParseLineDelay( Ntl_ReadMod_t * p, char * pLine ); +static int Ntl_ReadParseLineTimes( Ntl_ReadMod_t * p, char * pLine, int fOutput ); +static int Ntl_ReadParseLineNamesBlif( Ntl_ReadMod_t * p, char * pLine ); + +static int Ntl_ReadCharIsSpace( char s ) { return s == ' ' || s == '\t' || s == '\r' || s == '\n'; } +static int Ntl_ReadCharIsSopSymb( char s ) { return s == '0' || s == '1' || s == '-' || s == '\r' || s == '\n'; } //////////////////////////////////////////////////////////////////////// @@ -118,61 +121,64 @@ static int Ioa_ReadCharIsSopSymb( char s ) { return s == '0' || s SeeAlso [] ***********************************************************************/ -Ntl_Man_t * Ioa_ReadBlif( char * pFileName, int fCheck ) +Ntl_Man_t * Ntl_ManReadBlif( char * pFileName, int fCheck ) { FILE * pFile; - Ioa_ReadMan_t * p; + Ntl_ReadMan_t * p; Ntl_Man_t * pDesign; -// int nNodes; - + if ( !Ntl_FileIsType(pFileName, ".blif", ".blif.gz", ".blif.bz2") ) + { + printf( "Wrong file format\n" ); + return NULL; + } // check that the file is available pFile = fopen( pFileName, "rb" ); if ( pFile == NULL ) { - printf( "Ioa_ReadBlif(): The file is unavailable (absent or open).\n" ); + printf( "Ntl_ManReadBlif(): The file is unavailable (absent or open).\n" ); return 0; } fclose( pFile ); // start the file reader - p = Ioa_ReadAlloc(); + p = Ntl_ReadAlloc(); p->pFileName = pFileName; if ( !strncmp(pFileName+strlen(pFileName)-4,".bz2",4) ) - p->pBuffer = Ioa_ReadLoadFileBz2( pFileName ); + p->pBuffer = Ntl_ReadLoadFileBz2( pFileName ); else if ( !strncmp(pFileName+strlen(pFileName)-3,".gz",3) ) - p->pBuffer = Ioa_ReadLoadFileGz( pFileName ); + p->pBuffer = Ntl_ReadLoadFileGz( pFileName ); else - p->pBuffer = Ioa_ReadLoadFile( pFileName ); + p->pBuffer = Ntl_ReadLoadFile( pFileName ); if ( p->pBuffer == NULL ) { - Ioa_ReadFree( p ); + Ntl_ReadFree( p ); return NULL; } // set the design name - p->pDesign = Ntl_ManAlloc( pFileName ); + p->pDesign = Ntl_ManAlloc(); p->pDesign->pName = Ntl_ManStoreFileName( p->pDesign, pFileName ); p->pDesign->pSpec = Ntl_ManStoreName( p->pDesign, pFileName ); // prepare the file for parsing - Ioa_ReadReadPreparse( p ); + Ntl_ReadReadPreparse( p ); // parse interfaces of each network - if ( !Ioa_ReadReadInterfaces( p ) ) + if ( !Ntl_ReadReadInterfaces( p ) ) { if ( p->sError[0] ) fprintf( stdout, "%s\n", p->sError ); - Ioa_ReadFree( p ); + Ntl_ReadFree( p ); return NULL; } // construct the network - pDesign = Ioa_ReadParse( p ); + pDesign = Ntl_ReadParse( p ); if ( p->sError[0] ) fprintf( stdout, "%s\n", p->sError ); if ( pDesign == NULL ) { - Ioa_ReadFree( p ); + Ntl_ReadFree( p ); return NULL; } p->pDesign = NULL; - Ioa_ReadFree( p ); + Ntl_ReadFree( p ); // pDesign should be linked to all models of the design // make sure that everything is okay with the network structure @@ -180,7 +186,7 @@ Ntl_Man_t * Ioa_ReadBlif( char * pFileName, int fCheck ) { if ( !Ntl_ManCheck( pDesign ) ) { - printf( "Ioa_ReadBlif: The check has failed for design %s.\n", pDesign->pName ); + printf( "Ntl_ReadBlif: The check has failed for design %s.\n", pDesign->pName ); Ntl_ManFree( pDesign ); return NULL; } @@ -189,7 +195,7 @@ Ntl_Man_t * Ioa_ReadBlif( char * pFileName, int fCheck ) // transform the design by removing the CO drivers // if ( (nNodes = Ntl_ManReconnectCoDrivers(pDesign)) ) // printf( "The design was transformed by removing %d buf/inv CO drivers.\n", nNodes ); -//Ioa_WriteBlif( pDesign, "_temp_.blif" ); +//Ntl_ManWriteBlif( pDesign, "_temp_.blif" ); /* { Aig_Man_t * p = Ntl_ManCollapseSeq( pDesign ); @@ -210,11 +216,11 @@ Ntl_Man_t * Ioa_ReadBlif( char * pFileName, int fCheck ) SeeAlso [] ***********************************************************************/ -static Ioa_ReadMan_t * Ioa_ReadAlloc() +static Ntl_ReadMan_t * Ntl_ReadAlloc() { - Ioa_ReadMan_t * p; - p = ABC_ALLOC( Ioa_ReadMan_t, 1 ); - memset( p, 0, sizeof(Ioa_ReadMan_t) ); + Ntl_ReadMan_t * p; + p = ABC_ALLOC( Ntl_ReadMan_t, 1 ); + memset( p, 0, sizeof(Ntl_ReadMan_t) ); p->vLines = Vec_PtrAlloc( 512 ); p->vModels = Vec_PtrAlloc( 512 ); p->vTokens = Vec_PtrAlloc( 512 ); @@ -234,9 +240,9 @@ static Ioa_ReadMan_t * Ioa_ReadAlloc() SeeAlso [] ***********************************************************************/ -static void Ioa_ReadFree( Ioa_ReadMan_t * p ) +static void Ntl_ReadFree( Ntl_ReadMan_t * p ) { - Ioa_ReadMod_t * pMod; + Ntl_ReadMod_t * pMod; int i; if ( p->pDesign ) Ntl_ManFree( p->pDesign ); @@ -246,8 +252,8 @@ static void Ioa_ReadFree( Ioa_ReadMan_t * p ) Vec_PtrFree( p->vLines ); if ( p->vModels ) { - Vec_PtrForEachEntry( p->vModels, pMod, i ) - Ioa_ReadModFree( pMod ); + Vec_PtrForEachEntry( Ntl_ReadMod_t *, p->vModels, pMod, i ) + Ntl_ReadModFree( pMod ); Vec_PtrFree( p->vModels ); } Vec_PtrFree( p->vTokens ); @@ -267,11 +273,11 @@ static void Ioa_ReadFree( Ioa_ReadMan_t * p ) SeeAlso [] ***********************************************************************/ -static Ioa_ReadMod_t * Ioa_ReadModAlloc() +static Ntl_ReadMod_t * Ntl_ReadModAlloc() { - Ioa_ReadMod_t * p; - p = ABC_ALLOC( Ioa_ReadMod_t, 1 ); - memset( p, 0, sizeof(Ioa_ReadMod_t) ); + Ntl_ReadMod_t * p; + p = ABC_ALLOC( Ntl_ReadMod_t, 1 ); + memset( p, 0, sizeof(Ntl_ReadMod_t) ); p->vInputs = Vec_PtrAlloc( 8 ); p->vOutputs = Vec_PtrAlloc( 8 ); p->vLatches = Vec_PtrAlloc( 8 ); @@ -294,7 +300,7 @@ static Ioa_ReadMod_t * Ioa_ReadModAlloc() SeeAlso [] ***********************************************************************/ -static void Ioa_ReadModFree( Ioa_ReadMod_t * p ) +static void Ntl_ReadModFree( Ntl_ReadMod_t * p ) { Vec_PtrFree( p->vInputs ); Vec_PtrFree( p->vOutputs ); @@ -320,7 +326,7 @@ static void Ioa_ReadModFree( Ioa_ReadMod_t * p ) SeeAlso [] ***********************************************************************/ -static int Ioa_ReadCountChars( char * pLine, char Char ) +static int Ntl_ReadCountChars( char * pLine, char Char ) { char * pCur; int Counter = 0; @@ -341,7 +347,7 @@ static int Ioa_ReadCountChars( char * pLine, char Char ) SeeAlso [] ***********************************************************************/ -static void Ioa_ReadCollectTokens( Vec_Ptr_t * vTokens, char * pInput, char * pOutput ) +static void Ntl_ReadCollectTokens( Vec_Ptr_t * vTokens, char * pInput, char * pOutput ) { char * pCur; Vec_PtrClear( vTokens ); @@ -365,15 +371,15 @@ static void Ioa_ReadCollectTokens( Vec_Ptr_t * vTokens, char * pInput, char * pO SeeAlso [] ***********************************************************************/ -static void Ioa_ReadSplitIntoTokens( Vec_Ptr_t * vTokens, char * pLine, char Stop ) +static void Ntl_ReadSplitIntoTokens( Vec_Ptr_t * vTokens, char * pLine, char Stop ) { char * pCur; // clear spaces for ( pCur = pLine; *pCur != Stop; pCur++ ) - if ( Ioa_ReadCharIsSpace(*pCur) ) + if ( Ntl_ReadCharIsSpace(*pCur) ) *pCur = 0; // collect tokens - Ioa_ReadCollectTokens( vTokens, pLine, pCur ); + Ntl_ReadCollectTokens( vTokens, pLine, pCur ); } /**Function************************************************************* @@ -387,15 +393,15 @@ static void Ioa_ReadSplitIntoTokens( Vec_Ptr_t * vTokens, char * pLine, char Sto SeeAlso [] ***********************************************************************/ -static void Ioa_ReadSplitIntoTokensAndClear( Vec_Ptr_t * vTokens, char * pLine, char Stop, char Char ) +static void Ntl_ReadSplitIntoTokensAndClear( Vec_Ptr_t * vTokens, char * pLine, char Stop, char Char ) { char * pCur; // clear spaces for ( pCur = pLine; *pCur != Stop; pCur++ ) - if ( Ioa_ReadCharIsSpace(*pCur) || *pCur == Char ) + if ( Ntl_ReadCharIsSpace(*pCur) || *pCur == Char ) *pCur = 0; // collect tokens - Ioa_ReadCollectTokens( vTokens, pLine, pCur ); + Ntl_ReadCollectTokens( vTokens, pLine, pCur ); } /**Function************************************************************* @@ -409,11 +415,11 @@ static void Ioa_ReadSplitIntoTokensAndClear( Vec_Ptr_t * vTokens, char * pLine, SeeAlso [] ***********************************************************************/ -static int Ioa_ReadGetLine( Ioa_ReadMan_t * p, char * pToken ) +static int Ntl_ReadGetLine( Ntl_ReadMan_t * p, char * pToken ) { char * pLine; int i; - Vec_PtrForEachEntry( p->vLines, pLine, i ) + Vec_PtrForEachEntry( char *, p->vLines, pLine, i ) if ( pToken < pLine ) return i; return -1; @@ -430,7 +436,7 @@ static int Ioa_ReadGetLine( Ioa_ReadMan_t * p, char * pToken ) SeeAlso [] ***********************************************************************/ -static char * Ioa_ReadLoadFile( char * pFileName ) +static char * Ntl_ReadLoadFile( char * pFileName ) { FILE * pFile; int nFileSize; @@ -438,14 +444,14 @@ static char * Ioa_ReadLoadFile( char * pFileName ) pFile = fopen( pFileName, "rb" ); if ( pFile == NULL ) { - printf( "Ioa_ReadLoadFile(): The file is unavailable (absent or open).\n" ); + printf( "Ntl_ReadLoadFile(): The file is unavailable (absent or open).\n" ); return NULL; } fseek( pFile, 0, SEEK_END ); nFileSize = ftell( pFile ); if ( nFileSize == 0 ) { - printf( "Ioa_ReadLoadFile(): The file is empty.\n" ); + printf( "Ntl_ReadLoadFile(): The file is empty.\n" ); return NULL; } pContents = ABC_ALLOC( char, nFileSize + 10 ); @@ -475,7 +481,7 @@ typedef struct buflist { struct buflist * next; } buflist; -static char * Ioa_ReadLoadFileBz2( char * pFileName ) +static char * Ntl_ReadLoadFileBz2( char * pFileName ) { FILE * pFile; int nFileSize = 0; @@ -488,12 +494,12 @@ static char * Ioa_ReadLoadFileBz2( char * pFileName ) pFile = fopen( pFileName, "rb" ); if ( pFile == NULL ) { - printf( "Ioa_ReadLoadFileBz2(): The file is unavailable (absent or open).\n" ); + printf( "Ntl_ReadLoadFileBz2(): The file is unavailable (absent or open).\n" ); return NULL; } b = BZ2_bzReadOpen(&bzError,pFile,0,0,NULL,0); if (bzError != BZ_OK) { - printf( "Ioa_ReadLoadFileBz2(): BZ2_bzReadOpen() failed with error %d.\n",bzError ); + printf( "Ntl_ReadLoadFileBz2(): BZ2_bzReadOpen() failed with error %d.\n",bzError ); return NULL; } do { @@ -525,7 +531,7 @@ static char * Ioa_ReadLoadFileBz2( char * pFileName ) nFileSize = ftell( pFile ); if ( nFileSize == 0 ) { - printf( "Ioa_ReadLoadFileBz2(): The file is empty.\n" ); + printf( "Ntl_ReadLoadFileBz2(): The file is empty.\n" ); return NULL; } pContents = ABC_ALLOC( char, nFileSize + 10 ); @@ -533,7 +539,7 @@ static char * Ioa_ReadLoadFileBz2( char * pFileName ) fread( pContents, nFileSize, 1, pFile ); } else { // Some other error. - printf( "Ioa_ReadLoadFileBz2(): Unable to read the compressed BLIF.\n" ); + printf( "Ntl_ReadLoadFileBz2(): Unable to read the compressed BLIF.\n" ); return NULL; } fclose( pFile ); @@ -554,13 +560,13 @@ static char * Ioa_ReadLoadFileBz2( char * pFileName ) SeeAlso [] ***********************************************************************/ -static char * Ioa_ReadLoadFileGz( char * pFileName ) +static char * Ntl_ReadLoadFileGz( char * pFileName ) { const int READ_BLOCK_SIZE = 100000; FILE * pFile; char * pContents; int amtRead, readBlock, nFileSize = READ_BLOCK_SIZE; - pFile = gzopen( pFileName, "rb" ); // if pFileName doesn't end in ".gz" then this acts as a passthrough to fopen + pFile = (FILE *)gzopen( pFileName, "rb" ); // if pFileName doesn't end in ".gz" then this acts as a passthrough to fopen pContents = ABC_ALLOC( char, nFileSize ); readBlock = 0; while ((amtRead = gzread(pFile, pContents + readBlock * READ_BLOCK_SIZE, READ_BLOCK_SIZE)) == READ_BLOCK_SIZE) { @@ -593,7 +599,7 @@ static char * Ioa_ReadLoadFileGz( char * pFileName ) SeeAlso [] ***********************************************************************/ -static void Ioa_ReadReadPreparse( Ioa_ReadMan_t * p ) +static void Ntl_ReadReadPreparse( Ntl_ReadMan_t * p ) { char * pCur, * pPrev; int i, fComment = 0; @@ -617,13 +623,13 @@ static void Ioa_ReadReadPreparse( Ioa_ReadMan_t * p ) } // unfold the line extensions and sort lines by directive - Vec_PtrForEachEntry( p->vLines, pCur, i ) + Vec_PtrForEachEntry( char *, p->vLines, pCur, i ) { if ( *pCur == 0 ) continue; // find previous non-space character for ( pPrev = pCur - 2; pPrev >= p->pBuffer; pPrev-- ) - if ( !Ioa_ReadCharIsSpace(*pPrev) ) + if ( !Ntl_ReadCharIsSpace(*pPrev) ) break; // if it is the line extender, overwrite it with spaces if ( pPrev >= p->pBuffer && *pPrev == '\\' ) @@ -634,7 +640,7 @@ static void Ioa_ReadReadPreparse( Ioa_ReadMan_t * p ) continue; } // skip spaces at the beginning of the line - while ( Ioa_ReadCharIsSpace(*pCur++) ); + while ( Ntl_ReadCharIsSpace(*pCur++) ); // parse directives if ( *(pCur-1) != '.' ) continue; @@ -672,14 +678,14 @@ static void Ioa_ReadReadPreparse( Ioa_ReadMan_t * p ) p->pLatest->fBlackBox = 1; else if ( !strncmp(pCur, "model", 5) ) { - p->pLatest = Ioa_ReadModAlloc(); + p->pLatest = Ntl_ReadModAlloc(); p->pLatest->pFirst = pCur; p->pLatest->pMan = p; } else if ( !strncmp(pCur, "attrib", 6) ) { if ( p->pLatest->pAttrib != NULL ) - fprintf( stdout, "Line %d: Skipping second .attrib line for this model.\n", Ioa_ReadGetLine(p, pCur) ); + fprintf( stdout, "Line %d: Skipping second .attrib line for this model.\n", Ntl_ReadGetLine(p, pCur) ); else p->pLatest->pAttrib = pCur; } @@ -691,7 +697,7 @@ static void Ioa_ReadReadPreparse( Ioa_ReadMan_t * p ) } else if ( !strncmp(pCur, "exdc", 4) ) { - fprintf( stdout, "Line %d: Skipping EXDC network.\n", Ioa_ReadGetLine(p, pCur) ); + fprintf( stdout, "Line %d: Skipping EXDC network.\n", Ntl_ReadGetLine(p, pCur) ); break; } else if ( !strncmp(pCur, "no_merge", 8) ) @@ -703,7 +709,7 @@ static void Ioa_ReadReadPreparse( Ioa_ReadMan_t * p ) pCur--; if ( pCur[strlen(pCur)-1] == '\r' ) pCur[strlen(pCur)-1] = 0; - fprintf( stdout, "Line %d: Skipping line \"%s\".\n", Ioa_ReadGetLine(p, pCur), pCur ); + fprintf( stdout, "Line %d: Skipping line \"%s\".\n", Ntl_ReadGetLine(p, pCur), pCur ); } } } @@ -719,41 +725,41 @@ static void Ioa_ReadReadPreparse( Ioa_ReadMan_t * p ) SeeAlso [] ***********************************************************************/ -static int Ioa_ReadReadInterfaces( Ioa_ReadMan_t * p ) +static int Ntl_ReadReadInterfaces( Ntl_ReadMan_t * p ) { - Ioa_ReadMod_t * pMod; + Ntl_ReadMod_t * pMod; char * pLine; int i, k; // iterate through the models - Vec_PtrForEachEntry( p->vModels, pMod, i ) + Vec_PtrForEachEntry( Ntl_ReadMod_t *, p->vModels, pMod, i ) { // parse the model - if ( !Ioa_ReadParseLineModel( pMod, pMod->pFirst ) ) + if ( !Ntl_ReadParseLineModel( pMod, pMod->pFirst ) ) return 0; // parse the model attributes - if ( pMod->pAttrib && !Ioa_ReadParseLineAttrib( pMod, pMod->pAttrib ) ) + if ( pMod->pAttrib && !Ntl_ReadParseLineAttrib( pMod, pMod->pAttrib ) ) return 0; // parse no-merge if ( pMod->fNoMerge ) pMod->pNtk->attrNoMerge = 1; // parse the inputs - Vec_PtrForEachEntry( pMod->vInputs, pLine, k ) - if ( !Ioa_ReadParseLineInputs( pMod, pLine ) ) + Vec_PtrForEachEntry( char *, pMod->vInputs, pLine, k ) + if ( !Ntl_ReadParseLineInputs( pMod, pLine ) ) return 0; // parse the outputs - Vec_PtrForEachEntry( pMod->vOutputs, pLine, k ) - if ( !Ioa_ReadParseLineOutputs( pMod, pLine ) ) + Vec_PtrForEachEntry( char *, pMod->vOutputs, pLine, k ) + if ( !Ntl_ReadParseLineOutputs( pMod, pLine ) ) return 0; // parse the delay info Ntl_ModelSetPioNumbers( pMod->pNtk ); - Vec_PtrForEachEntry( pMod->vDelays, pLine, k ) - if ( !Ioa_ReadParseLineDelay( pMod, pLine ) ) + Vec_PtrForEachEntry( char *, pMod->vDelays, pLine, k ) + if ( !Ntl_ReadParseLineDelay( pMod, pLine ) ) return 0; - Vec_PtrForEachEntry( pMod->vTimeInputs, pLine, k ) - if ( !Ioa_ReadParseLineTimes( pMod, pLine, 0 ) ) + Vec_PtrForEachEntry( char *, pMod->vTimeInputs, pLine, k ) + if ( !Ntl_ReadParseLineTimes( pMod, pLine, 0 ) ) return 0; - Vec_PtrForEachEntry( pMod->vTimeOutputs, pLine, k ) - if ( !Ioa_ReadParseLineTimes( pMod, pLine, 1 ) ) + Vec_PtrForEachEntry( char *, pMod->vTimeOutputs, pLine, k ) + if ( !Ntl_ReadParseLineTimes( pMod, pLine, 1 ) ) return 0; // report timing line stats if ( pMod->fInArr && pMod->fInReq ) @@ -780,26 +786,26 @@ static int Ioa_ReadReadInterfaces( Ioa_ReadMan_t * p ) SeeAlso [] ***********************************************************************/ -static Ntl_Man_t * Ioa_ReadParse( Ioa_ReadMan_t * p ) +static Ntl_Man_t * Ntl_ReadParse( Ntl_ReadMan_t * p ) { Ntl_Man_t * pDesign; - Ioa_ReadMod_t * pMod; + Ntl_ReadMod_t * pMod; char * pLine; int i, k; // iterate through the models - Vec_PtrForEachEntry( p->vModels, pMod, i ) + Vec_PtrForEachEntry( Ntl_ReadMod_t *, p->vModels, pMod, i ) { // parse the latches - Vec_PtrForEachEntry( pMod->vLatches, pLine, k ) - if ( !Ioa_ReadParseLineLatch( pMod, pLine ) ) + Vec_PtrForEachEntry( char *, pMod->vLatches, pLine, k ) + if ( !Ntl_ReadParseLineLatch( pMod, pLine ) ) return NULL; // parse the nodes - Vec_PtrForEachEntry( pMod->vNames, pLine, k ) - if ( !Ioa_ReadParseLineNamesBlif( pMod, pLine ) ) + Vec_PtrForEachEntry( char *, pMod->vNames, pLine, k ) + if ( !Ntl_ReadParseLineNamesBlif( pMod, pLine ) ) return NULL; // parse the subcircuits - Vec_PtrForEachEntry( pMod->vSubckts, pLine, k ) - if ( !Ioa_ReadParseLineSubckt( pMod, pLine ) ) + Vec_PtrForEachEntry( char *, pMod->vSubckts, pLine, k ) + if ( !Ntl_ReadParseLineSubckt( pMod, pLine ) ) return NULL; // finalize the network Ntl_ModelFixNonDrivenNets( pMod->pNtk ); @@ -807,7 +813,7 @@ static Ntl_Man_t * Ioa_ReadParse( Ioa_ReadMan_t * p ) if ( i == 0 ) return NULL; // update the design name - pMod = Vec_PtrEntry( p->vModels, 0 ); + pMod = (Ntl_ReadMod_t *)Vec_PtrEntry( p->vModels, 0 ); if ( Ntl_ModelLatchNum(pMod->pNtk) > 0 ) Ntl_ModelTransformLatches( pMod->pNtk ); p->pDesign->pName = Ntl_ManStoreName( p->pDesign, pMod->pNtk->pName ); @@ -828,22 +834,22 @@ static Ntl_Man_t * Ioa_ReadParse( Ioa_ReadMan_t * p ) SeeAlso [] ***********************************************************************/ -static int Ioa_ReadParseLineModel( Ioa_ReadMod_t * p, char * pLine ) +static int Ntl_ReadParseLineModel( Ntl_ReadMod_t * p, char * pLine ) { Vec_Ptr_t * vTokens = p->pMan->vTokens; char * pToken; - Ioa_ReadSplitIntoTokens( vTokens, pLine, '\0' ); - pToken = Vec_PtrEntry( vTokens, 0 ); + Ntl_ReadSplitIntoTokens( vTokens, pLine, '\0' ); + pToken = (char *)Vec_PtrEntry( vTokens, 0 ); assert( !strcmp(pToken, "model") ); if ( Vec_PtrSize(vTokens) != 2 ) { - sprintf( p->pMan->sError, "Line %d: The number of entries (%d) in .model line is different from two.", Ioa_ReadGetLine(p->pMan, pToken), Vec_PtrSize(vTokens) ); + sprintf( p->pMan->sError, "Line %d: The number of entries (%d) in .model line is different from two.", Ntl_ReadGetLine(p->pMan, pToken), Vec_PtrSize(vTokens) ); return 0; } - p->pNtk = Ntl_ModelAlloc( p->pMan->pDesign, Vec_PtrEntry(vTokens, 1) ); + p->pNtk = Ntl_ModelAlloc( p->pMan->pDesign, (char *)Vec_PtrEntry(vTokens, 1) ); if ( p->pNtk == NULL ) { - sprintf( p->pMan->sError, "Line %d: Model %s already exists.", Ioa_ReadGetLine(p->pMan, pToken), (char*)Vec_PtrEntry(vTokens, 1) ); + sprintf( p->pMan->sError, "Line %d: Model %s already exists.", Ntl_ReadGetLine(p->pMan, pToken), (char*)Vec_PtrEntry(vTokens, 1) ); return 0; } return 1; @@ -860,17 +866,17 @@ static int Ioa_ReadParseLineModel( Ioa_ReadMod_t * p, char * pLine ) SeeAlso [] ***********************************************************************/ -static int Ioa_ReadParseLineAttrib( Ioa_ReadMod_t * p, char * pLine ) +static int Ntl_ReadParseLineAttrib( Ntl_ReadMod_t * p, char * pLine ) { Vec_Ptr_t * vTokens = p->pMan->vTokens; char * pToken; int i; - Ioa_ReadSplitIntoTokens( vTokens, pLine, '\0' ); - pToken = Vec_PtrEntry( vTokens, 0 ); + Ntl_ReadSplitIntoTokens( vTokens, pLine, '\0' ); + pToken = (char *)Vec_PtrEntry( vTokens, 0 ); assert( !strncmp(pToken, "attrib", 6) ); - Vec_PtrForEachEntryStart( vTokens, pToken, i, 1 ) + Vec_PtrForEachEntryStart( char *, vTokens, pToken, i, 1 ) { - pToken = Vec_PtrEntry( vTokens, i ); + pToken = (char *)Vec_PtrEntry( vTokens, i ); if ( strcmp( pToken, "white" ) == 0 ) p->pNtk->attrWhite = 1; else if ( strcmp( pToken, "black" ) == 0 ) @@ -889,7 +895,7 @@ static int Ioa_ReadParseLineAttrib( Ioa_ReadMod_t * p, char * pLine ) p->pNtk->attrKeep = 0; else { - sprintf( p->pMan->sError, "Line %d: Unknown attribute (%s) in the .attrib line of model %s.", Ioa_ReadGetLine(p->pMan, pToken), pToken, p->pNtk->pName ); + sprintf( p->pMan->sError, "Line %d: Unknown attribute (%s) in the .attrib line of model %s.", Ntl_ReadGetLine(p->pMan, pToken), pToken, p->pNtk->pName ); return 0; } } @@ -907,23 +913,23 @@ static int Ioa_ReadParseLineAttrib( Ioa_ReadMod_t * p, char * pLine ) SeeAlso [] ***********************************************************************/ -static int Ioa_ReadParseLineInputs( Ioa_ReadMod_t * p, char * pLine ) +static int Ntl_ReadParseLineInputs( Ntl_ReadMod_t * p, char * pLine ) { Ntl_Net_t * pNet; Ntl_Obj_t * pObj; Vec_Ptr_t * vTokens = p->pMan->vTokens; char * pToken; int i; - Ioa_ReadSplitIntoTokens( vTokens, pLine, '\0' ); - pToken = Vec_PtrEntry(vTokens, 0); + Ntl_ReadSplitIntoTokens( vTokens, pLine, '\0' ); + pToken = (char *)Vec_PtrEntry(vTokens, 0); assert( !strcmp(pToken, "inputs") ); - Vec_PtrForEachEntryStart( vTokens, pToken, i, 1 ) + Vec_PtrForEachEntryStart( char *, vTokens, pToken, i, 1 ) { pObj = Ntl_ModelCreatePi( p->pNtk ); pNet = Ntl_ModelFindOrCreateNet( p->pNtk, pToken ); if ( !Ntl_ModelSetNetDriver( pObj, pNet ) ) { - sprintf( p->pMan->sError, "Line %d: Net %s already has a driver.", Ioa_ReadGetLine(p->pMan, pToken), pNet->pName ); + sprintf( p->pMan->sError, "Line %d: Net %s already has a driver.", Ntl_ReadGetLine(p->pMan, pToken), pNet->pName ); return 0; } } @@ -941,17 +947,17 @@ static int Ioa_ReadParseLineInputs( Ioa_ReadMod_t * p, char * pLine ) SeeAlso [] ***********************************************************************/ -static int Ioa_ReadParseLineOutputs( Ioa_ReadMod_t * p, char * pLine ) +static int Ntl_ReadParseLineOutputs( Ntl_ReadMod_t * p, char * pLine ) { Ntl_Net_t * pNet; Ntl_Obj_t * pObj; Vec_Ptr_t * vTokens = p->pMan->vTokens; char * pToken; int i; - Ioa_ReadSplitIntoTokens( vTokens, pLine, '\0' ); - pToken = Vec_PtrEntry(vTokens, 0); + Ntl_ReadSplitIntoTokens( vTokens, pLine, '\0' ); + pToken = (char *)Vec_PtrEntry(vTokens, 0); assert( !strcmp(pToken, "outputs") ); - Vec_PtrForEachEntryStart( vTokens, pToken, i, 1 ) + Vec_PtrForEachEntryStart( char *, vTokens, pToken, i, 1 ) { pNet = Ntl_ModelFindOrCreateNet( p->pNtk, pToken ); pObj = Ntl_ModelCreatePo( p->pNtk, pNet ); @@ -971,46 +977,47 @@ static int Ioa_ReadParseLineOutputs( Ioa_ReadMod_t * p, char * pLine ) SeeAlso [] ***********************************************************************/ -static int Ioa_ReadParseLineLatch( Ioa_ReadMod_t * p, char * pLine ) +static int Ntl_ReadParseLineLatch( Ntl_ReadMod_t * p, char * pLine ) { Vec_Ptr_t * vTokens = p->pMan->vTokens; Ntl_Net_t * pNetLi, * pNetLo; Ntl_Obj_t * pObj; char * pToken, * pNameLi, * pNameLo; - Ioa_ReadSplitIntoTokens( vTokens, pLine, '\0' ); - pToken = Vec_PtrEntry(vTokens,0); + Ntl_ReadSplitIntoTokens( vTokens, pLine, '\0' ); + pToken = (char *)Vec_PtrEntry(vTokens,0); assert( !strcmp(pToken, "latch") ); if ( Vec_PtrSize(vTokens) < 3 ) { - sprintf( p->pMan->sError, "Line %d: Latch does not have input name and output name.", Ioa_ReadGetLine(p->pMan, pToken) ); + sprintf( p->pMan->sError, "Line %d: Latch does not have input name and output name.", Ntl_ReadGetLine(p->pMan, pToken) ); return 0; } // create latch - pNameLi = Vec_PtrEntry( vTokens, 1 ); - pNameLo = Vec_PtrEntry( vTokens, 2 ); + pNameLi = (char *)Vec_PtrEntry( vTokens, 1 ); + pNameLo = (char *)Vec_PtrEntry( vTokens, 2 ); pNetLi = Ntl_ModelFindOrCreateNet( p->pNtk, pNameLi ); pNetLo = Ntl_ModelFindOrCreateNet( p->pNtk, pNameLo ); pObj = Ntl_ModelCreateLatch( p->pNtk ); pObj->pFanio[0] = pNetLi; if ( !Ntl_ModelSetNetDriver( pObj, pNetLo ) ) { - sprintf( p->pMan->sError, "Line %d: Net %s already has a driver.", Ioa_ReadGetLine(p->pMan, pToken), pNetLo->pName ); + sprintf( p->pMan->sError, "Line %d: Net %s already has a driver.", Ntl_ReadGetLine(p->pMan, pToken), pNetLo->pName ); return 0; } // get initial value if ( Vec_PtrSize(vTokens) > 3 ) - pObj->LatchId.regInit = atoi( Vec_PtrEntry(vTokens,Vec_PtrSize(vTokens)-1) ); + pObj->LatchId.regInit = atoi( (char *)Vec_PtrEntry(vTokens,Vec_PtrSize(vTokens)-1) ); else pObj->LatchId.regInit = 2; if ( pObj->LatchId.regInit < 0 || pObj->LatchId.regInit > 2 ) { - sprintf( p->pMan->sError, "Line %d: Initial state of the latch is incorrect \"%s\".", Ioa_ReadGetLine(p->pMan, pToken), (char*)Vec_PtrEntry(vTokens,3) ); + sprintf( p->pMan->sError, "Line %d: Initial state of the latch is incorrect \"%s\".", Ntl_ReadGetLine(p->pMan, pToken), (char*)Vec_PtrEntry(vTokens,3) ); return 0; } // get the register class - if ( Vec_PtrSize(vTokens) == 6 ) +// if ( Vec_PtrSize(vTokens) == 6 ) + if ( Vec_PtrSize(vTokens) == 5 || Vec_PtrSize(vTokens) == 6 ) { - pToken = Vec_PtrEntry(vTokens,3); + pToken = (char *)Vec_PtrEntry(vTokens,3); if ( strcmp( pToken, "fe" ) == 0 ) pObj->LatchId.regType = 1; else if ( strcmp( pToken, "re" ) == 0 ) @@ -1025,19 +1032,20 @@ static int Ioa_ReadParseLineLatch( Ioa_ReadMod_t * p, char * pLine ) pObj->LatchId.regClass = atoi(pToken); else { - sprintf( p->pMan->sError, "Line %d: Type/class of the latch is incorrect \"%s\".", Ioa_ReadGetLine(p->pMan, pToken), pToken ); + sprintf( p->pMan->sError, "Line %d: Type/class of the latch is incorrect \"%s\".", Ntl_ReadGetLine(p->pMan, pToken), pToken ); return 0; } } if ( pObj->LatchId.regClass < 0 || pObj->LatchId.regClass > (1<<24) ) { - sprintf( p->pMan->sError, "Line %d: Class of the latch is incorrect \"%s\".", Ioa_ReadGetLine(p->pMan, pToken), (char*)Vec_PtrEntry(vTokens,3) ); + sprintf( p->pMan->sError, "Line %d: Class of the latch is incorrect \"%s\".", Ntl_ReadGetLine(p->pMan, pToken), (char*)Vec_PtrEntry(vTokens,3) ); return 0; } // get the clock - if ( Vec_PtrSize(vTokens) == 5 || Vec_PtrSize(vTokens) == 6 ) +// if ( Vec_PtrSize(vTokens) == 5 || Vec_PtrSize(vTokens) == 6 ) + if ( Vec_PtrSize(vTokens) == 6 ) { - pToken = Vec_PtrEntry(vTokens,Vec_PtrSize(vTokens)-2); + pToken = (char *)Vec_PtrEntry(vTokens,Vec_PtrSize(vTokens)-2); pNetLi = Ntl_ModelFindOrCreateNet( p->pNtk, pToken ); pObj->pClock = pNetLi; } @@ -1055,7 +1063,7 @@ static int Ioa_ReadParseLineLatch( Ioa_ReadMod_t * p, char * pLine ) SeeAlso [] ***********************************************************************/ -static int Ioa_ReadParseLineSubckt( Ioa_ReadMod_t * p, char * pLine ) +static int Ntl_ReadParseLineSubckt( Ntl_ReadMod_t * p, char * pLine ) { Vec_Ptr_t * vTokens = p->pMan->vTokens; Ntl_Mod_t * pModel; @@ -1065,17 +1073,17 @@ static int Ioa_ReadParseLineSubckt( Ioa_ReadMod_t * p, char * pLine ) int nEquals, i, k; // split the line into tokens - nEquals = Ioa_ReadCountChars( pLine, '=' ); - Ioa_ReadSplitIntoTokensAndClear( vTokens, pLine, '\0', '=' ); - pToken = Vec_PtrEntry(vTokens,0); + nEquals = Ntl_ReadCountChars( pLine, '=' ); + Ntl_ReadSplitIntoTokensAndClear( vTokens, pLine, '\0', '=' ); + pToken = (char *)Vec_PtrEntry(vTokens,0); assert( !strcmp(pToken, "subckt") ); // get the model for this box - pName = Vec_PtrEntry(vTokens,1); + pName = (char *)Vec_PtrEntry(vTokens,1); pModel = Ntl_ManFindModel( p->pMan->pDesign, pName ); if ( pModel == NULL ) { - sprintf( p->pMan->sError, "Line %d: Cannot find the model for subcircuit %s.", Ioa_ReadGetLine(p->pMan, pToken), pName ); + sprintf( p->pMan->sError, "Line %d: Cannot find the model for subcircuit %s.", Ntl_ReadGetLine(p->pMan, pToken), pName ); return 0; } /* @@ -1087,9 +1095,9 @@ static int Ioa_ReadParseLineSubckt( Ioa_ReadMod_t * p, char * pLine ) pToken = Vec_PtrEntry( vTokens, Vec_PtrSize(vTokens) - 1 ); for ( ; *pToken; pToken++ ); for ( ; *pToken == 0; pToken++ ); - Ioa_ReadSplitIntoTokensAndClear( vTokens2, pToken, '\0', '=' ); + Ntl_ReadSplitIntoTokensAndClear( vTokens2, pToken, '\0', '=' ); // assert( Vec_PtrSize( vTokens2 ) == 2 ); - Vec_PtrForEachEntry( vTokens2, pToken, i ) + Vec_PtrForEachEntry( char *, vTokens2, pToken, i ) Vec_PtrPush( vTokens, pToken ); nEquals += Vec_PtrSize(vTokens2)/2; Vec_PtrFree( vTokens2 ); @@ -1099,7 +1107,7 @@ static int Ioa_ReadParseLineSubckt( Ioa_ReadMod_t * p, char * pLine ) if ( nEquals != Ntl_ModelPiNum(pModel) + Ntl_ModelPoNum(pModel) ) { sprintf( p->pMan->sError, "Line %d: The number of ports (%d) in .subckt %s differs from the sum of PIs and POs of the model (%d).", - Ioa_ReadGetLine(p->pMan, pToken), nEquals, pName, Ntl_ModelPiNum(pModel) + Ntl_ModelPoNum(pModel) ); + Ntl_ReadGetLine(p->pMan, pToken), nEquals, pName, Ntl_ModelPiNum(pModel) + Ntl_ModelPoNum(pModel) ); return 0; } @@ -1119,7 +1127,7 @@ static int Ioa_ReadParseLineSubckt( Ioa_ReadMod_t * p, char * pLine ) if ( k == nEquals ) { sprintf( p->pMan->sError, "Line %d: Cannot find PI \"%s\" of the model \"%s\" as a formal input of the subcircuit.", - Ioa_ReadGetLine(p->pMan, pToken), pName, pModel->pName ); + Ntl_ReadGetLine(p->pMan, pToken), pName, pModel->pName ); return 0; } // create the BI with the actual name @@ -1136,7 +1144,7 @@ static int Ioa_ReadParseLineSubckt( Ioa_ReadMod_t * p, char * pLine ) if ( k == nEquals ) { sprintf( p->pMan->sError, "Line %d: Cannot find PO \"%s\" of the model \"%s\" as a formal output of the subcircuit.", - Ioa_ReadGetLine(p->pMan, pToken), pName, pModel->pName ); + Ntl_ReadGetLine(p->pMan, pToken), pName, pModel->pName ); return 0; } // create the BI with the actual name @@ -1157,54 +1165,54 @@ static int Ioa_ReadParseLineSubckt( Ioa_ReadMod_t * p, char * pLine ) SeeAlso [] ***********************************************************************/ -static int Ioa_ReadParseLineDelay( Ioa_ReadMod_t * p, char * pLine ) +static int Ntl_ReadParseLineDelay( Ntl_ReadMod_t * p, char * pLine ) { Vec_Ptr_t * vTokens = p->pMan->vTokens; int RetValue1, RetValue2, Number1, Number2, Temp; char * pToken, * pTokenNum; float Delay; assert( sizeof(float) == sizeof(int) ); - Ioa_ReadSplitIntoTokens( vTokens, pLine, '\0' ); - pToken = Vec_PtrEntry(vTokens,0); + Ntl_ReadSplitIntoTokens( vTokens, pLine, '\0' ); + pToken = (char *)Vec_PtrEntry(vTokens,0); assert( !strcmp(pToken, "delay") ); if ( Vec_PtrSize(vTokens) < 2 && Vec_PtrSize(vTokens) > 4 ) { - sprintf( p->pMan->sError, "Line %d: Delay line does not have a valid number of parameters (1, 2, or 3).", Ioa_ReadGetLine(p->pMan, pToken) ); + sprintf( p->pMan->sError, "Line %d: Delay line does not have a valid number of parameters (1, 2, or 3).", Ntl_ReadGetLine(p->pMan, pToken) ); return 0; } // find the delay number - pTokenNum = Vec_PtrEntryLast(vTokens); + pTokenNum = (char *)Vec_PtrEntryLast(vTokens); Delay = atof( pTokenNum ); if ( Delay == 0.0 && pTokenNum[0] != '0' ) { - sprintf( p->pMan->sError, "Line %d: Delay value (%s) appears to be invalid.", Ioa_ReadGetLine(p->pMan, pToken), (char*)Vec_PtrEntryLast(vTokens) ); + sprintf( p->pMan->sError, "Line %d: Delay value (%s) appears to be invalid.", Ntl_ReadGetLine(p->pMan, pToken), (char*)Vec_PtrEntryLast(vTokens) ); return 0; } // find the PI/PO numbers RetValue1 = 0; Number1 = -1; if ( Vec_PtrSize(vTokens) > 2 ) { - RetValue1 = Ntl_ModelFindPioNumber( p->pNtk, 0, 0, Vec_PtrEntry(vTokens, 1), &Number1 ); + RetValue1 = Ntl_ModelFindPioNumber( p->pNtk, 0, 0, (char *)Vec_PtrEntry(vTokens, 1), &Number1 ); if ( RetValue1 == 0 ) { - sprintf( p->pMan->sError, "Line %d: Cannot find signal \"%s\" among PIs/POs.", Ioa_ReadGetLine(p->pMan, pToken), (char*)Vec_PtrEntry(vTokens, 1) ); + sprintf( p->pMan->sError, "Line %d: Cannot find signal \"%s\" among PIs/POs.", Ntl_ReadGetLine(p->pMan, pToken), (char*)Vec_PtrEntry(vTokens, 1) ); return 0; } } RetValue2 = 0; Number2 = -1; if ( Vec_PtrSize(vTokens) > 3 ) { - RetValue2 = Ntl_ModelFindPioNumber( p->pNtk, 0, 0, Vec_PtrEntry(vTokens, 2), &Number2 ); + RetValue2 = Ntl_ModelFindPioNumber( p->pNtk, 0, 0, (char *)Vec_PtrEntry(vTokens, 2), &Number2 ); if ( RetValue2 == 0 ) { - sprintf( p->pMan->sError, "Line %d: Cannot find signal \"%s\" among PIs/POs.", Ioa_ReadGetLine(p->pMan, pToken), (char*)Vec_PtrEntry(vTokens, 2) ); + sprintf( p->pMan->sError, "Line %d: Cannot find signal \"%s\" among PIs/POs.", Ntl_ReadGetLine(p->pMan, pToken), (char*)Vec_PtrEntry(vTokens, 2) ); return 0; } } if ( RetValue1 == RetValue2 && RetValue1 ) { sprintf( p->pMan->sError, "Line %d: Both signals \"%s\" and \"%s\" listed appear to be PIs or POs.", - Ioa_ReadGetLine(p->pMan, pToken), (char*)Vec_PtrEntry(vTokens, 1), (char*)Vec_PtrEntry(vTokens, 2) ); + Ntl_ReadGetLine(p->pMan, pToken), (char*)Vec_PtrEntry(vTokens, 1), (char*)Vec_PtrEntry(vTokens, 2) ); return 0; } if ( RetValue2 < RetValue1 ) @@ -1234,26 +1242,26 @@ static int Ioa_ReadParseLineDelay( Ioa_ReadMod_t * p, char * pLine ) SeeAlso [] ***********************************************************************/ -static int Ioa_ReadParseLineTimes( Ioa_ReadMod_t * p, char * pLine, int fOutput ) +static int Ntl_ReadParseLineTimes( Ntl_ReadMod_t * p, char * pLine, int fOutput ) { Vec_Ptr_t * vTokens = p->pMan->vTokens; int RetValue, Number = -1; char * pToken, * pTokenNum; float Delay; assert( sizeof(float) == sizeof(int) ); - Ioa_ReadSplitIntoTokens( vTokens, pLine, '\0' ); - pToken = Vec_PtrEntry(vTokens,0); + Ntl_ReadSplitIntoTokens( vTokens, pLine, '\0' ); + pToken = (char *)Vec_PtrEntry(vTokens,0); if ( fOutput ) assert( !strncmp(pToken, "output_", 7) ); else assert( !strncmp(pToken, "input_", 6) ); if ( Vec_PtrSize(vTokens) != 2 && Vec_PtrSize(vTokens) != 3 ) { - sprintf( p->pMan->sError, "Line %d: Delay line does not have a valid number of parameters (2 or 3).", Ioa_ReadGetLine(p->pMan, pToken) ); + sprintf( p->pMan->sError, "Line %d: Delay line does not have a valid number of parameters (2 or 3).", Ntl_ReadGetLine(p->pMan, pToken) ); return 0; } // find the delay number - pTokenNum = Vec_PtrEntryLast(vTokens); + pTokenNum = (char *)Vec_PtrEntryLast(vTokens); if ( !strcmp( pTokenNum, "-inf" ) ) Delay = -TIM_ETERNITY; else if ( !strcmp( pTokenNum, "inf" ) ) @@ -1262,7 +1270,7 @@ static int Ioa_ReadParseLineTimes( Ioa_ReadMod_t * p, char * pLine, int fOutput Delay = atof( pTokenNum ); if ( Delay == 0.0 && pTokenNum[0] != '0' ) { - sprintf( p->pMan->sError, "Line %d: Delay value (%s) appears to be invalid.", Ioa_ReadGetLine(p->pMan, pToken), (char*)Vec_PtrEntryLast(vTokens) ); + sprintf( p->pMan->sError, "Line %d: Delay value (%s) appears to be invalid.", Ntl_ReadGetLine(p->pMan, pToken), (char*)Vec_PtrEntryLast(vTokens) ); return 0; } // find the PI/PO numbers @@ -1270,10 +1278,10 @@ static int Ioa_ReadParseLineTimes( Ioa_ReadMod_t * p, char * pLine, int fOutput { if ( Vec_PtrSize(vTokens) == 3 ) { - RetValue = Ntl_ModelFindPioNumber( p->pNtk, 0, 1, Vec_PtrEntry(vTokens, 1), &Number ); + RetValue = Ntl_ModelFindPioNumber( p->pNtk, 0, 1, (char *)Vec_PtrEntry(vTokens, 1), &Number ); if ( RetValue == 0 ) { - sprintf( p->pMan->sError, "Line %d: Cannot find signal \"%s\" among POs.", Ioa_ReadGetLine(p->pMan, pToken), (char*)Vec_PtrEntry(vTokens, 1) ); + sprintf( p->pMan->sError, "Line %d: Cannot find signal \"%s\" among POs.", Ntl_ReadGetLine(p->pMan, pToken), (char*)Vec_PtrEntry(vTokens, 1) ); return 0; } } @@ -1287,10 +1295,10 @@ static int Ioa_ReadParseLineTimes( Ioa_ReadMod_t * p, char * pLine, int fOutput { if ( Vec_PtrSize(vTokens) == 3 ) { - RetValue = Ntl_ModelFindPioNumber( p->pNtk, 1, 0, Vec_PtrEntry(vTokens, 1), &Number ); + RetValue = Ntl_ModelFindPioNumber( p->pNtk, 1, 0, (char *)Vec_PtrEntry(vTokens, 1), &Number ); if ( RetValue == 0 ) { - sprintf( p->pMan->sError, "Line %d: Cannot find signal \"%s\" among PIs.", Ioa_ReadGetLine(p->pMan, pToken), (char*)Vec_PtrEntry(vTokens, 1) ); + sprintf( p->pMan->sError, "Line %d: Cannot find signal \"%s\" among PIs.", Ntl_ReadGetLine(p->pMan, pToken), (char*)Vec_PtrEntry(vTokens, 1) ); return 0; } } @@ -1315,7 +1323,7 @@ static int Ioa_ReadParseLineTimes( Ioa_ReadMod_t * p, char * pLine, int fOutput SeeAlso [] ***********************************************************************/ -static char * Ioa_ReadParseTableBlif( Ioa_ReadMod_t * p, char * pTable, int nFanins ) +static char * Ntl_ReadParseTableBlif( Ntl_ReadMod_t * p, char * pTable, int nFanins ) { Vec_Ptr_t * vTokens = p->pMan->vTokens; Vec_Str_t * vFunc = p->pMan->vFunc; @@ -1325,52 +1333,52 @@ static char * Ioa_ReadParseTableBlif( Ioa_ReadMod_t * p, char * pTable, int nFan p->pMan->nTablesRead++; // get the tokens - Ioa_ReadSplitIntoTokens( vTokens, pTable, '.' ); + Ntl_ReadSplitIntoTokens( vTokens, pTable, '.' ); if ( Vec_PtrSize(vTokens) == 0 ) return Ntl_ManStoreSop( p->pMan->pDesign->pMemSops, " 0\n" ); if ( Vec_PtrSize(vTokens) == 1 ) { - pOutput = Vec_PtrEntry( vTokens, 0 ); + pOutput = (char *)Vec_PtrEntry( vTokens, 0 ); if ( *pOutput == '\"' ) return Ntl_ManStoreSop( p->pMan->pDesign->pMemSops, pOutput ); if ( ((pOutput[0] - '0') & 0x8E) || pOutput[1] ) { - sprintf( p->pMan->sError, "Line %d: Constant table has wrong output value \"%s\".", Ioa_ReadGetLine(p->pMan, pOutput), pOutput ); + sprintf( p->pMan->sError, "Line %d: Constant table has wrong output value \"%s\".", Ntl_ReadGetLine(p->pMan, pOutput), pOutput ); return NULL; } return Ntl_ManStoreSop( p->pMan->pDesign->pMemSops, (pOutput[0] == '0') ? " 0\n" : " 1\n" ); } - pProduct = Vec_PtrEntry( vTokens, 0 ); + pProduct = (char *)Vec_PtrEntry( vTokens, 0 ); if ( Vec_PtrSize(vTokens) % 2 == 1 ) { - sprintf( p->pMan->sError, "Line %d: Table has odd number of tokens (%d).", Ioa_ReadGetLine(p->pMan, pProduct), Vec_PtrSize(vTokens) ); + sprintf( p->pMan->sError, "Line %d: Table has odd number of tokens (%d).", Ntl_ReadGetLine(p->pMan, pProduct), Vec_PtrSize(vTokens) ); return NULL; } // parse the table Vec_StrClear( vFunc ); for ( i = 0; i < Vec_PtrSize(vTokens)/2; i++ ) { - pProduct = Vec_PtrEntry( vTokens, 2*i + 0 ); - pOutput = Vec_PtrEntry( vTokens, 2*i + 1 ); + pProduct = (char *)Vec_PtrEntry( vTokens, 2*i + 0 ); + pOutput = (char *)Vec_PtrEntry( vTokens, 2*i + 1 ); if ( strlen(pProduct) != (unsigned)nFanins ) { - sprintf( p->pMan->sError, "Line %d: Cube \"%s\" has size different from the fanin count (%d).", Ioa_ReadGetLine(p->pMan, pProduct), pProduct, nFanins ); + sprintf( p->pMan->sError, "Line %d: Cube \"%s\" has size different from the fanin count (%d).", Ntl_ReadGetLine(p->pMan, pProduct), pProduct, nFanins ); return NULL; } if ( ((pOutput[0] - '0') & 0x8E) || pOutput[1] ) { - sprintf( p->pMan->sError, "Line %d: Output value \"%s\" is incorrect.", Ioa_ReadGetLine(p->pMan, pProduct), pOutput ); + sprintf( p->pMan->sError, "Line %d: Output value \"%s\" is incorrect.", Ntl_ReadGetLine(p->pMan, pProduct), pOutput ); return NULL; } if ( Polarity == -1 ) Polarity = pOutput[0] - '0'; else if ( Polarity != pOutput[0] - '0' ) { - sprintf( p->pMan->sError, "Line %d: Output value \"%s\" differs from the value in the first line of the table (%d).", Ioa_ReadGetLine(p->pMan, pProduct), pOutput, Polarity ); + sprintf( p->pMan->sError, "Line %d: Output value \"%s\" differs from the value in the first line of the table (%d).", Ntl_ReadGetLine(p->pMan, pProduct), pOutput, Polarity ); return NULL; } // parse one product - Vec_StrAppend( vFunc, pProduct ); + Vec_StrPrintStr( vFunc, pProduct ); Vec_StrPush( vFunc, ' ' ); Vec_StrPush( vFunc, pOutput[0] ); Vec_StrPush( vFunc, '\n' ); @@ -1390,36 +1398,36 @@ static char * Ioa_ReadParseTableBlif( Ioa_ReadMod_t * p, char * pTable, int nFan SeeAlso [] ***********************************************************************/ -static int Ioa_ReadParseLineNamesBlif( Ioa_ReadMod_t * p, char * pLine ) +static int Ntl_ReadParseLineNamesBlif( Ntl_ReadMod_t * p, char * pLine ) { Vec_Ptr_t * vTokens = p->pMan->vTokens; Ntl_Obj_t * pNode; Ntl_Net_t * pNetOut, * pNetIn; char * pNameOut, * pNameIn; int i; - Ioa_ReadSplitIntoTokens( vTokens, pLine, '\0' ); + Ntl_ReadSplitIntoTokens( vTokens, pLine, '\0' ); // parse the mapped node // if ( !strcmp(Vec_PtrEntry(vTokens,0), "gate") ) -// return Ioa_ReadParseLineGateBlif( p, vTokens ); +// return Ntl_ReadParseLineGateBlif( p, vTokens ); // parse the regular name line - assert( !strcmp(Vec_PtrEntry(vTokens,0), "names") ); - pNameOut = Vec_PtrEntryLast( vTokens ); + assert( !strcmp((char *)Vec_PtrEntry(vTokens,0), "names") ); + pNameOut = (char *)Vec_PtrEntryLast( vTokens ); pNetOut = Ntl_ModelFindOrCreateNet( p->pNtk, pNameOut ); // create fanins pNode = Ntl_ModelCreateNode( p->pNtk, Vec_PtrSize(vTokens) - 2 ); for ( i = 0; i < Vec_PtrSize(vTokens) - 2; i++ ) { - pNameIn = Vec_PtrEntry(vTokens, i+1); + pNameIn = (char *)Vec_PtrEntry(vTokens, i+1); pNetIn = Ntl_ModelFindOrCreateNet( p->pNtk, pNameIn ); Ntl_ObjSetFanin( pNode, pNetIn, i ); } if ( !Ntl_ModelSetNetDriver( pNode, pNetOut ) ) { - sprintf( p->pMan->sError, "Line %d: Signal \"%s\" is defined more than once.", Ioa_ReadGetLine(p->pMan, pNameOut), pNameOut ); + sprintf( p->pMan->sError, "Line %d: Signal \"%s\" is defined more than once.", Ntl_ReadGetLine(p->pMan, pNameOut), pNameOut ); return 0; } // parse the table of this node - pNode->pSop = Ioa_ReadParseTableBlif( p, pNameOut + strlen(pNameOut), pNode->nFanins ); + pNode->pSop = Ntl_ReadParseTableBlif( p, pNameOut + strlen(pNameOut), pNode->nFanins ); if ( pNode->pSop == NULL ) return 0; pNode->pSop = Ntl_ManStoreSop( p->pNtk->pMan->pMemSops, pNode->pSop ); @@ -1432,3 +1440,5 @@ static int Ioa_ReadParseLineNamesBlif( Ioa_ReadMod_t * p, char * pLine ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ntl/ntlSweep.c b/src/aig/ntl/ntlSweep.c index b2c700fb..29e40f30 100644 --- a/src/aig/ntl/ntlSweep.c +++ b/src/aig/ntl/ntlSweep.c @@ -20,6 +20,9 @@ #include "ntl.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -207,3 +210,5 @@ int Ntl_ManSweep( Ntl_Man_t * p, int fVerbose ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ntl/ntlTable.c b/src/aig/ntl/ntlTable.c index 0b87c8be..23207081 100644 --- a/src/aig/ntl/ntlTable.c +++ b/src/aig/ntl/ntlTable.c @@ -20,6 +20,9 @@ #include "ntl.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -55,7 +58,9 @@ static unsigned Ntl_HashString( const char * pName, int TableSize ) Ntl_Net_t * Ntl_ModelCreateNet( Ntl_Mod_t * p, const char * pName ) { Ntl_Net_t * pNet; - pNet = (Ntl_Net_t *)Aig_MmFlexEntryFetch( p->pMan->pMemObjs, sizeof(Ntl_Net_t) + strlen(pName) + 1 ); + int nSize = sizeof(Ntl_Net_t) + strlen(pName) + 1; + nSize = (nSize / sizeof(char*) + ((nSize % sizeof(char*)) > 0)) * sizeof(char*); // added by Saurabh on Sep 3, 2009 + pNet = (Ntl_Net_t *)Aig_MmFlexEntryFetch( p->pMan->pMemObjs, nSize ); memset( pNet, 0, sizeof(Ntl_Net_t) ); strcpy( pNet->pName, pName ); pNet->NetId = Vec_PtrSize( p->vNets ); @@ -362,7 +367,7 @@ int Ntl_ModelFindPioNumber( Ntl_Mod_t * p, int fPiOnly, int fPoOnly, const char } if ( fPoOnly ) { - pTerm = pNet->pCopy; + pTerm = (Ntl_Obj_t *)pNet->pCopy; if ( pTerm && Ntl_ObjIsPo(pTerm) ) { *pNumber = pTerm->iTemp; @@ -370,7 +375,7 @@ int Ntl_ModelFindPioNumber( Ntl_Mod_t * p, int fPiOnly, int fPoOnly, const char } return 0; } - pTerm = pNet->pCopy; + pTerm = (Ntl_Obj_t *)pNet->pCopy; if ( pTerm && Ntl_ObjIsPo(pTerm) ) { *pNumber = pTerm->iTemp; @@ -545,3 +550,5 @@ Ntl_Mod_t * Ntl_ManFindModel( Ntl_Man_t * p, const char * pName ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ntl/ntlTime.c b/src/aig/ntl/ntlTime.c index f9fadaa8..7a531482 100644 --- a/src/aig/ntl/ntlTime.c +++ b/src/aig/ntl/ntlTime.c @@ -20,6 +20,9 @@ #include "ntl.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -217,7 +220,7 @@ Tim_Man_t * Ntl_ManCreateTiming( Ntl_Man_t * p ) // set up the boxes iBox = 0; curPi = p->iLastCi; - Vec_PtrForEachEntry( p->vVisNodes, pObj, i ) + Vec_PtrForEachEntry( Ntl_Obj_t *, p->vVisNodes, pObj, i ) { if ( !Ntl_ObjIsBox(pObj) ) continue; @@ -238,3 +241,5 @@ Tim_Man_t * Ntl_ManCreateTiming( Ntl_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ntl/ntlUtil.c b/src/aig/ntl/ntlUtil.c index 0bd86247..c3c6fd49 100644 --- a/src/aig/ntl/ntlUtil.c +++ b/src/aig/ntl/ntlUtil.c @@ -20,6 +20,9 @@ #include "ntl.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -30,6 +33,32 @@ /**Function************************************************************* + Synopsis [Returns one if the file has a given extension.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ntl_FileIsType( char * pFileName, char * pS1, char * pS2, char * pS3 ) +{ + int lenS, lenF = strlen(pFileName); + lenS = pS1 ? strlen(pS1) : 0; + if ( lenS && lenF > lenS && !strncmp( pFileName+lenF-lenS, pS1, lenS ) ) + return 1; + lenS = pS2 ? strlen(pS2) : 0; + if ( lenS && lenF > lenS && !strncmp( pFileName+lenF-lenS, pS2, lenS ) ) + return 1; + lenS = pS3 ? strlen(pS3) : 0; + if ( lenS && lenF > lenS && !strncmp( pFileName+lenF-lenS, pS3, lenS ) ) + return 1; + return 0; +} + +/**Function************************************************************* + Synopsis [Reads the maximum number of fanins.] Description [] @@ -419,7 +448,7 @@ Vec_Vec_t * Ntl_ManTransformRegClasses( Ntl_Man_t * pMan, int nSizeMax, int fVer if ( fVerbose ) { printf( "The number of selected register clases = %d.\n", Vec_PtrSize(vParts) ); - Vec_PtrForEachEntry( vParts, vPart, i ) + Vec_PtrForEachEntry( Vec_Int_t *, vParts, vPart, i ) printf( "(%d, %d) ", i, Vec_IntSize(vPart) ); printf( "\n" ); } @@ -704,3 +733,5 @@ void Ntl_ManRemoveUselessNets( Ntl_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ntl/ntlWriteBlif.c b/src/aig/ntl/ntlWriteBlif.c index e6e4cbdd..f9b2781f 100644 --- a/src/aig/ntl/ntlWriteBlif.c +++ b/src/aig/ntl/ntlWriteBlif.c @@ -27,6 +27,9 @@ #include "bzlib.h" #include "zlib.h" +ABC_NAMESPACE_IMPL_START + + #ifdef _WIN32 #define vsnprintf _vsnprintf #endif @@ -50,7 +53,7 @@ SeeAlso [] ***********************************************************************/ -void Ioa_WriteBlifModel( FILE * pFile, Ntl_Mod_t * pModel, int fMain ) +void Ntl_ManWriteBlifModel( FILE * pFile, Ntl_Mod_t * pModel, int fMain ) { Ntl_Obj_t * pObj; Ntl_Net_t * pNet; @@ -195,7 +198,7 @@ void Ioa_WriteBlifModel( FILE * pFile, Ntl_Mod_t * pModel, int fMain ) SeeAlso [] ***********************************************************************/ -void Ioa_WriteBlif_old( Ntl_Man_t * p, char * pFileName ) +void Ntl_ManWriteBlif_old( Ntl_Man_t * p, char * pFileName ) { FILE * pFile; Ntl_Mod_t * pModel; @@ -204,13 +207,13 @@ void Ioa_WriteBlif_old( Ntl_Man_t * p, char * pFileName ) pFile = fopen( pFileName, "w" ); if ( pFile == NULL ) { - fprintf( stdout, "Ioa_WriteBlif(): Cannot open the output file \"%s\".\n", pFileName ); + fprintf( stdout, "Ntl_ManWriteBlif(): Cannot open the output file \"%s\".\n", pFileName ); return; } - fprintf( pFile, "# Benchmark \"%s\" written by ABC-8 on %s\n", p->pName, Ioa_TimeStamp() ); + fprintf( pFile, "# Benchmark \"%s\" written by ABC-8 on %s\n", p->pName, Aig_TimeStamp() ); // write the models Ntl_ManForEachModel( p, pModel, i ) - Ioa_WriteBlifModel( pFile, pModel, i==0 ); + Ntl_ManWriteBlifModel( pFile, pModel, i==0 ); // close the file fclose( pFile ); } @@ -226,11 +229,11 @@ void Ioa_WriteBlif_old( Ntl_Man_t * p, char * pFileName ) SeeAlso [] ***********************************************************************/ -void Ioa_WriteBlifLogic( Nwk_Man_t * pNtk, Ntl_Man_t * p, char * pFileName ) +void Ntl_ManWriteBlifLogic( Nwk_Man_t * pNtk, Ntl_Man_t * p, char * pFileName ) { Ntl_Man_t * pNew; pNew = Ntl_ManInsertNtk( p, pNtk ); - Ioa_WriteBlif( pNew, pFileName ); + Ntl_ManWriteBlif( pNew, pFileName ); Ntl_ManFree( pNew ); } @@ -277,7 +280,7 @@ int fprintfBz2(bz2file * b, char * fmt, ...) { } BZ2_bzWrite( &bzError, b->b, b->buf, b->nBytes ); if (bzError == BZ_IO_ERROR) { - fprintf( stdout, "Ioa_WriteBlif(): I/O error writing to compressed stream.\n" ); + fprintf( stdout, "Ntl_ManWriteBlif(): I/O error writing to compressed stream.\n" ); return -1; } return b->nBytes; @@ -302,7 +305,7 @@ int fprintfBz2(bz2file * b, char * fmt, ...) { SeeAlso [] ***********************************************************************/ -void Ioa_WriteBlifModelGz( gzFile pFile, Ntl_Mod_t * pModel, int fMain ) +void Ntl_ManWriteBlifModelGz( gzFile pFile, Ntl_Mod_t * pModel, int fMain ) { Ntl_Obj_t * pObj; Ntl_Net_t * pNet; @@ -447,7 +450,7 @@ void Ioa_WriteBlifModelGz( gzFile pFile, Ntl_Mod_t * pModel, int fMain ) SeeAlso [] ***********************************************************************/ -void Ioa_WriteBlifGz( Ntl_Man_t * p, char * pFileName ) +void Ntl_ManWriteBlifGz( Ntl_Man_t * p, char * pFileName ) { Ntl_Mod_t * pModel; int i; @@ -457,14 +460,14 @@ void Ioa_WriteBlifGz( Ntl_Man_t * p, char * pFileName ) pFile = gzopen( pFileName, "wb" ); // if pFileName doesn't end in ".gz" then this acts as a passthrough to fopen if ( pFile == NULL ) { - fprintf( stdout, "Ioa_WriteBlif(): Cannot open the output file \"%s\".\n", pFileName ); + fprintf( stdout, "Ntl_ManWriteBlif(): Cannot open the output file \"%s\".\n", pFileName ); return; } - gzprintf( pFile, "# Benchmark \"%s\" written by ABC-8 on %s\n", p->pName, Ioa_TimeStamp() ); + gzprintf( pFile, "# Benchmark \"%s\" written by ABC-8 on %s\n", p->pName, Aig_TimeStamp() ); // write the models Ntl_ManForEachModel( p, pModel, i ) - Ioa_WriteBlifModelGz( pFile, pModel, i==0 ); + Ntl_ManWriteBlifModelGz( pFile, pModel, i==0 ); // close the file gzclose( pFile ); } @@ -481,7 +484,7 @@ void Ioa_WriteBlifGz( Ntl_Man_t * p, char * pFileName ) SeeAlso [] ***********************************************************************/ -void Ioa_WriteBlifModelBz2( bz2file * b, Ntl_Mod_t * pModel, int fMain ) +void Ntl_ManWriteBlifModelBz2( bz2file * b, Ntl_Mod_t * pModel, int fMain ) { Ntl_Obj_t * pObj; Ntl_Net_t * pNet; @@ -626,12 +629,12 @@ void Ioa_WriteBlifModelBz2( bz2file * b, Ntl_Mod_t * pModel, int fMain ) SeeAlso [] ***********************************************************************/ -void Ioa_WriteBlif( Ntl_Man_t * p, char * pFileName ) +void Ntl_ManWriteBlif( Ntl_Man_t * p, char * pFileName ) { Ntl_Mod_t * pModel; int i, bzError; bz2file b; - if ( p->pNal && strncmp(pFileName+strlen(pFileName)-5,".blif",5) ) + if ( p->pNal && !Ntl_FileIsType(pFileName, ".blif", ".blif.gz", ".blif.bz2") ) { p->pNalW( p, pFileName ); return; @@ -639,7 +642,7 @@ void Ioa_WriteBlif( Ntl_Man_t * p, char * pFileName ) // write the GZ file if (!strncmp(pFileName+strlen(pFileName)-3,".gz",3)) { - Ioa_WriteBlifGz( p, pFileName ); + Ntl_ManWriteBlifGz( p, pFileName ); return; } @@ -651,7 +654,7 @@ void Ioa_WriteBlif( Ntl_Man_t * p, char * pFileName ) b.f = fopen( pFileName, "wb" ); if ( b.f == NULL ) { - fprintf( stdout, "Ioa_WriteBlif(): Cannot open the output file \"%s\".\n", pFileName ); + fprintf( stdout, "Ntl_ManWriteBlif(): Cannot open the output file \"%s\".\n", pFileName ); ABC_FREE(b.buf); return; } @@ -659,22 +662,22 @@ void Ioa_WriteBlif( Ntl_Man_t * p, char * pFileName ) b.b = BZ2_bzWriteOpen( &bzError, b.f, 9, 0, 0 ); if ( bzError != BZ_OK ) { BZ2_bzWriteClose( &bzError, b.b, 0, NULL, NULL ); - fprintf( stdout, "Ioa_WriteBlif(): Cannot start compressed stream.\n" ); + fprintf( stdout, "Ntl_ManWriteBlif(): Cannot start compressed stream.\n" ); fclose( b.f ); ABC_FREE(b.buf); return; } } - fprintfBz2( &b, "# Benchmark \"%s\" written by ABC-8 on %s\n", p->pName, Ioa_TimeStamp() ); + fprintfBz2( &b, "# Benchmark \"%s\" written by ABC-8 on %s\n", p->pName, Aig_TimeStamp() ); // write the models Ntl_ManForEachModel( p, pModel, i ) - Ioa_WriteBlifModelBz2( &b, pModel, i==0 ); + Ntl_ManWriteBlifModelBz2( &b, pModel, i==0 ); // close the file if (b.b) { BZ2_bzWriteClose( &bzError, b.b, 0, NULL, NULL ); if (bzError == BZ_IO_ERROR) { - fprintf( stdout, "Ioa_WriteBlif(): I/O error closing compressed stream.\n" ); + fprintf( stdout, "Ntl_ManWriteBlif(): I/O error closing compressed stream.\n" ); fclose( b.f ); ABC_FREE(b.buf); return; @@ -690,3 +693,5 @@ void Ioa_WriteBlif( Ntl_Man_t * p, char * pFileName ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ntl/ntl_.c b/src/aig/ntl/ntl_.c index 4b3ad684..9b0b1d0a 100644 --- a/src/aig/ntl/ntl_.c +++ b/src/aig/ntl/ntl_.c @@ -20,6 +20,9 @@ #include "ntl.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -45,3 +48,5 @@ //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ntl/ntlnwk.h b/src/aig/ntl/ntlnwk.h new file mode 100644 index 00000000..0b07f243 --- /dev/null +++ b/src/aig/ntl/ntlnwk.h @@ -0,0 +1,113 @@ +/**CFile**************************************************************** + + FileName [ntlnwk.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Netlist and network representation.] + + Synopsis [External declarations.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: ntlnwk.h,v 1.3 2008/10/24 14:18:44 mjarvin Exp $] + +***********************************************************************/ + +#ifndef __NTLNWK_H__ +#define __NTLNWK_H__ + + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// PARAMETERS /// +//////////////////////////////////////////////////////////////////////// + +ABC_NAMESPACE_HEADER_START + + +//////////////////////////////////////////////////////////////////////// +/// BASIC TYPES /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Ntl_Man_t_ Ntl_Man_t; +typedef struct Nwk_Man_t_ Nwk_Man_t; + +//////////////////////////////////////////////////////////////////////// +/// MACRO DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// INLINED FUNCTIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// ITERATORS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +extern ABC_DLL Ntl_Man_t * Ntl_ManReadBlif( char * pFileName, int fCheck ); +extern ABC_DLL void Ntl_ManWriteBlif( Ntl_Man_t * p, char * pFileName ); + +extern ABC_DLL Tim_Man_t * Ntl_ManReadTimeMan( Ntl_Man_t * p ); +extern ABC_DLL Ntl_Man_t * Ntl_ManDup( Ntl_Man_t * p ); +extern ABC_DLL void Ntl_ManFree( Ntl_Man_t * p ); +extern ABC_DLL int Ntl_ManIsComb( Ntl_Man_t * p ); +extern ABC_DLL void Ntl_ManPrintStats( Ntl_Man_t * p ); +extern ABC_DLL int Ntl_ManSweep( Ntl_Man_t * p, int fVerbose ); +extern ABC_DLL Ntl_Man_t * Ntl_ManInsertNtk( Ntl_Man_t * p, Nwk_Man_t * pNtk ); +extern ABC_DLL Ntl_Man_t * Ntl_ManInsertAig( Ntl_Man_t * p, Aig_Man_t * pAig ); +extern ABC_DLL Aig_Man_t * Ntl_ManExtract( Ntl_Man_t * p ); +extern ABC_DLL Aig_Man_t * Ntl_ManCollapse( Ntl_Man_t * p, int fSeq ); +extern ABC_DLL Aig_Man_t * Ntl_ManCollapseSeq( Ntl_Man_t * p, int nMinDomSize, int fVerbose ); +extern ABC_DLL Ntl_Man_t * Ntl_ManDupCollapseLuts( Ntl_Man_t * p ); +extern ABC_DLL Ntl_Man_t * Ntl_ManFraig( Ntl_Man_t * p, int nPartSize, int nConfLimit, int nLevelMax, int fUseCSat, int fVerbose ); +extern ABC_DLL void Ntl_ManPrepareCecMans( Ntl_Man_t * pMan1, Ntl_Man_t * pMan2, Aig_Man_t ** ppAig1, Aig_Man_t ** ppAig2 ); +extern ABC_DLL Vec_Ptr_t * Ntl_ManCollectCiNames( Ntl_Man_t * p ); +extern ABC_DLL Vec_Ptr_t * Ntl_ManCollectCoNames( Ntl_Man_t * p ); +extern ABC_DLL Ntl_Man_t * Ntl_ManScl( Ntl_Man_t * p, int fLatchConst, int fLatchEqual, int fVerbose ); +extern ABC_DLL Ntl_Man_t * Ntl_ManLcorr( Ntl_Man_t * p, int nConfMax, int fScorrGia, int fUseCSat, int fVerbose ); +extern ABC_DLL Ntl_Man_t * Ntl_ManSsw( Ntl_Man_t * p, Fra_Ssw_t * pPars ); +extern ABC_DLL Ntl_Man_t * Ntl_ManScorr( Ntl_Man_t * p, Ssw_Pars_t * pPars ); +extern ABC_DLL void Ntl_ManTransformInitValues( Ntl_Man_t * p ); + +extern ABC_DLL void Ntl_ManPrepareCec( char * pFileName1, char * pFileName2, Aig_Man_t ** ppMan1, Aig_Man_t ** ppMan2 ); +extern ABC_DLL Aig_Man_t * Ntl_ManPrepareSec( char * pFileName1, char * pFileName2 ); + +extern ABC_DLL Nwk_Man_t * Ntl_ManExtractNwk( Ntl_Man_t * p, Aig_Man_t * pAig, Tim_Man_t * pManTime ); +extern ABC_DLL Nwk_Man_t * Ntl_ManReadNwk( char * pFileName, Aig_Man_t * pAig, Tim_Man_t * pManTime ); +extern ABC_DLL void Nwk_ManPrintStats( Nwk_Man_t * p, If_Lib_t * pLutLib, int fSaveBest, int fDumpResult, int fPower, Ntl_Man_t * pNtl ); +extern ABC_DLL void Nwk_ManPrintStatsShort( Ntl_Man_t * p, Aig_Man_t * pAig, Nwk_Man_t * pNtk ); +extern ABC_DLL void Nwk_ManPrintFanioNew( Nwk_Man_t * p ); +extern ABC_DLL Nwk_Man_t * Nwk_MappingIf( Aig_Man_t * p, Tim_Man_t * pManTime, If_Par_t * pPars ); +extern ABC_DLL void Nwk_ManSetIfParsDefault( If_Par_t * pPars ); +extern ABC_DLL void Nwk_ManBidecResyn( Nwk_Man_t * p, int fVerbose ); +extern ABC_DLL Aig_Man_t * Nwk_ManSpeedup( Nwk_Man_t * p, int fUseLutLib, int Percentage, int Degree, int fVerbose, int fVeryVerbose ); +extern ABC_DLL Aig_Man_t * Nwk_ManStrash( Nwk_Man_t * p ); +extern ABC_DLL Vec_Int_t * Nwk_ManLutMerge( Nwk_Man_t * p, void * pPars ); +extern ABC_DLL int Nwk_ManCheck( Nwk_Man_t * p ); +extern ABC_DLL void Nwk_ManDumpBlif( Nwk_Man_t * p, char * pFileName, Vec_Ptr_t * vCiNames, Vec_Ptr_t * vCoNames ); +extern ABC_DLL void Nwk_ManFree( Nwk_Man_t * p ); + + + +ABC_NAMESPACE_HEADER_END + + + +#endif + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + diff --git a/src/aig/nwk/nwk.h b/src/aig/nwk/nwk.h index c8cc91cb..acbcbf4a 100644 --- a/src/aig/nwk/nwk.h +++ b/src/aig/nwk/nwk.h @@ -20,6 +20,7 @@ #ifndef __NWK_H__ #define __NWK_H__ + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// @@ -31,19 +32,20 @@ #include "if.h" #include "bdc.h" +#include "fra.h" +#include "ssw.h" +#include "ntlnwk.h" + //////////////////////////////////////////////////////////////////////// /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif +ABC_NAMESPACE_HEADER_START //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// //////////////////////////////////////////////////////////////////////// -typedef struct Nwk_Man_t_ Nwk_Man_t; typedef struct Nwk_Obj_t_ Nwk_Obj_t; // object types @@ -175,23 +177,23 @@ static inline int Nwk_ManTimeMore( float f1, float f2, float Eps ) { r //////////////////////////////////////////////////////////////////////// #define Nwk_ManForEachCi( p, pObj, i ) \ - Vec_PtrForEachEntry( p->vCis, pObj, i ) + Vec_PtrForEachEntry( Nwk_Obj_t *, p->vCis, pObj, i ) #define Nwk_ManForEachCo( p, pObj, i ) \ - Vec_PtrForEachEntry( p->vCos, pObj, i ) + Vec_PtrForEachEntry( Nwk_Obj_t *, p->vCos, pObj, i ) #define Nwk_ManForEachPi( p, pObj, i ) \ - Vec_PtrForEachEntry( p->vCis, pObj, i ) \ + Vec_PtrForEachEntry( Nwk_Obj_t *, p->vCis, pObj, i ) \ if ( !Nwk_ObjIsPi(pObj) ) {} else #define Nwk_ManForEachPo( p, pObj, i ) \ - Vec_PtrForEachEntry( p->vCos, pObj, i ) \ + Vec_PtrForEachEntry( Nwk_Obj_t *, p->vCos, pObj, i ) \ if ( !Nwk_ObjIsPo(pObj) ) {} else #define Nwk_ManForEachObj( p, pObj, i ) \ - for ( i = 0; (i < Vec_PtrSize(p->vObjs)) && (((pObj) = Vec_PtrEntry(p->vObjs, i)), 1); i++ ) \ + for ( i = 0; (i < Vec_PtrSize(p->vObjs)) && (((pObj) = (Nwk_Obj_t *)Vec_PtrEntry(p->vObjs, i)), 1); i++ ) \ if ( pObj == NULL ) {} else #define Nwk_ManForEachNode( p, pObj, i ) \ - for ( i = 0; (i < Vec_PtrSize(p->vObjs)) && (((pObj) = Vec_PtrEntry(p->vObjs, i)), 1); i++ ) \ + for ( i = 0; (i < Vec_PtrSize(p->vObjs)) && (((pObj) = (Nwk_Obj_t *)Vec_PtrEntry(p->vObjs, i)), 1); i++ ) \ if ( (pObj) == NULL || !Nwk_ObjIsNode(pObj) ) {} else #define Nwk_ManForEachLatch( p, pObj, i ) \ - for ( i = 0; (i < Vec_PtrSize(p->vObjs)) && (((pObj) = Vec_PtrEntry(p->vObjs, i)), 1); i++ ) \ + for ( i = 0; (i < Vec_PtrSize(p->vObjs)) && (((pObj) = (Nwk_Obj_t *)Vec_PtrEntry(p->vObjs, i)), 1); i++ ) \ if ( (pObj) == NULL || !Nwk_ObjIsLatch(pObj) ) {} else #define Nwk_ObjForEachFanin( pObj, pFanin, i ) \ @@ -201,13 +203,13 @@ static inline int Nwk_ManTimeMore( float f1, float f2, float Eps ) { r // sequential iterators #define Nwk_ManForEachPiSeq( p, pObj, i ) \ - Vec_PtrForEachEntryStop( p->vCis, pObj, i, (p)->nTruePis ) + Vec_PtrForEachEntryStop( Nwk_Obj_t *, p->vCis, pObj, i, (p)->nTruePis ) #define Nwk_ManForEachPoSeq( p, pObj, i ) \ - Vec_PtrForEachEntryStop( p->vCos, pObj, i, (p)->nTruePos ) + Vec_PtrForEachEntryStop( Nwk_Obj_t *, p->vCos, pObj, i, (p)->nTruePos ) #define Nwk_ManForEachLoSeq( p, pObj, i ) \ - for ( i = 0; (i < (p)->nLatches) && (((pObj) = Vec_PtrEntry(p->vCis, i+(p)->nTruePis)), 1); i++ ) + for ( i = 0; (i < (p)->nLatches) && (((pObj) = (Nwk_Obj_t *)Vec_PtrEntry(p->vCis, i+(p)->nTruePis)), 1); i++ ) #define Nwk_ManForEachLiSeq( p, pObj, i ) \ - for ( i = 0; (i < (p)->nLatches) && (((pObj) = Vec_PtrEntry(p->vCos, i+(p)->nTruePos)), 1); i++ ) + for ( i = 0; (i < (p)->nLatches) && (((pObj) = (Nwk_Obj_t *)Vec_PtrEntry(p->vCos, i+(p)->nTruePos)), 1); i++ ) #define Nwk_ManForEachLiLoSeq( p, pObjLi, pObjLo, i ) \ for ( i = 0; (i < (p)->nLatches) && (((pObjLi) = Nwk_ManCo(p, i+(p)->nTruePos)), 1) \ && (((pObjLo) = Nwk_ManCi(p, i+(p)->nTruePis)), 1); i++ ) @@ -253,7 +255,7 @@ extern ABC_DLL Vec_Ptr_t * Nwk_ManRetimeCutBackward( Nwk_Man_t * pMan, int n extern ABC_DLL Nwk_Man_t * Nwk_ManAlloc(); extern ABC_DLL void Nwk_ManFree( Nwk_Man_t * p ); extern ABC_DLL float Nwl_ManComputeTotalSwitching( Nwk_Man_t * pNtk ); -extern ABC_DLL void Nwk_ManPrintStats( Nwk_Man_t * p, If_Lib_t * pLutLib, int fSaveBest, int fDumpResult, int fPower, void * pNtl ); +extern ABC_DLL void Nwk_ManPrintStats( Nwk_Man_t * p, If_Lib_t * pLutLib, int fSaveBest, int fDumpResult, int fPower, Ntl_Man_t * pNtl ); /*=== nwkMap.c ============================================================*/ extern ABC_DLL Nwk_Man_t * Nwk_MappingIf( Aig_Man_t * p, Tim_Man_t * pManTime, If_Par_t * pPars ); /*=== nwkObj.c ============================================================*/ @@ -291,9 +293,11 @@ extern ABC_DLL void Nwk_ManCleanMarks( Nwk_Man_t * pNtk ); extern ABC_DLL void Nwk_ManMinimumBase( Nwk_Man_t * pNtk, int fVerbose ); extern ABC_DLL void Nwk_ManRemoveDupFanins( Nwk_Man_t * pNtk, int fVerbose ); -#ifdef __cplusplus -} -#endif + + +ABC_NAMESPACE_HEADER_END + + #endif diff --git a/src/aig/nwk/nwkAig.c b/src/aig/nwk/nwkAig.c index 7421348a..54e84237 100644 --- a/src/aig/nwk/nwkAig.c +++ b/src/aig/nwk/nwkAig.c @@ -20,6 +20,9 @@ #include "nwk.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -57,13 +60,13 @@ Nwk_Man_t * Nwk_ManDeriveFromAig( Aig_Man_t * p ) Aig_ManForEachNode( p, pObj, i ) { pObj->pData = Nwk_ManCreateNode( pNtk, 2, pObj->nRefs ); - Nwk_ObjAddFanin( pObj->pData, Aig_ObjFanin0(pObj)->pData ); - Nwk_ObjAddFanin( pObj->pData, Aig_ObjFanin1(pObj)->pData ); + Nwk_ObjAddFanin( (Nwk_Obj_t *)pObj->pData, (Nwk_Obj_t *)Aig_ObjFanin0(pObj)->pData ); + Nwk_ObjAddFanin( (Nwk_Obj_t *)pObj->pData, (Nwk_Obj_t *)Aig_ObjFanin1(pObj)->pData ); } Aig_ManForEachPo( p, pObj, i ) { pObj->pData = Nwk_ManCreateCo( pNtk ); - Nwk_ObjAddFanin( pObj->pData, Aig_ObjFanin0(pObj)->pData ); + Nwk_ObjAddFanin( (Nwk_Obj_t *)pObj->pData, (Nwk_Obj_t *)Aig_ObjFanin0(pObj)->pData ); } return pNtk; } @@ -93,7 +96,7 @@ Vec_Ptr_t * Nwk_ManDeriveRetimingCut( Aig_Man_t * p, int fForward, int fVerbose vNodes = Nwk_ManRetimeCutBackward( pNtk, Aig_ManRegNum(p), fVerbose ); Aig_ManForEachObj( p, pObj, i ) ((Nwk_Obj_t *)pObj->pData)->pCopy = pObj; - Vec_PtrForEachEntry( vNodes, pNode, i ) + Vec_PtrForEachEntry( Nwk_Obj_t *, vNodes, pNode, i ) Vec_PtrWriteEntry( vNodes, i, pNode->pCopy ); Nwk_ManFree( pNtk ); assert( Vec_PtrSize(vNodes) <= Aig_ManRegNum(p) ); @@ -105,3 +108,5 @@ Vec_Ptr_t * Nwk_ManDeriveRetimingCut( Aig_Man_t * p, int fForward, int fVerbose //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/nwk/nwkBidec.c b/src/aig/nwk/nwkBidec.c index 13abf81f..567b904b 100644 --- a/src/aig/nwk/nwkBidec.c +++ b/src/aig/nwk/nwkBidec.c @@ -20,6 +20,9 @@ #include "nwk.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -44,7 +47,7 @@ static inline void Extra_TruthSharp( unsigned * pOut, unsigned * pIn0, unsigned pOut[w] = pIn0[w] & ~pIn1[w]; } -static inline Hop_Obj_t * Bdc_FunCopyHop( Bdc_Fun_t * pObj ) { return Hop_NotCond( Bdc_FuncCopy(Bdc_Regular(pObj)), Bdc_IsComplement(pObj) ); } +static inline Hop_Obj_t * Bdc_FunCopyHop( Bdc_Fun_t * pObj ) { return Hop_NotCond( (Hop_Obj_t *)Bdc_FuncCopy(Bdc_Regular(pObj)), Bdc_IsComplement(pObj) ); } //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -170,3 +173,5 @@ void Nwk_ManBidecResyn( Nwk_Man_t * pNtk, int fVerbose ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/nwk/nwkCheck.c b/src/aig/nwk/nwkCheck.c index f20d61f2..24a0d513 100644 --- a/src/aig/nwk/nwkCheck.c +++ b/src/aig/nwk/nwkCheck.c @@ -20,6 +20,9 @@ #include "nwk.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -69,3 +72,5 @@ int Nwk_ManCheck( Nwk_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/nwk/nwkDfs.c b/src/aig/nwk/nwkDfs.c index ec4ad440..59752c59 100644 --- a/src/aig/nwk/nwkDfs.c +++ b/src/aig/nwk/nwkDfs.c @@ -20,6 +20,9 @@ #include "nwk.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -657,3 +660,5 @@ int Nwk_ObjMffcLabel( Nwk_Obj_t * pNode ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/nwk/nwkFanio.c b/src/aig/nwk/nwkFanio.c index daea19d5..2a12f5bf 100644 --- a/src/aig/nwk/nwkFanio.c +++ b/src/aig/nwk/nwkFanio.c @@ -20,6 +20,9 @@ #include "nwk.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -279,7 +282,7 @@ void Nwk_ObjTransferFanout( Nwk_Obj_t * pNodeFrom, Nwk_Obj_t * pNodeTo ) nFanoutsOld = Nwk_ObjFanoutNum(pNodeTo); Nwk_ObjCollectFanouts( pNodeFrom, vFanouts ); // patch the fanin of each of them - Vec_PtrForEachEntry( vFanouts, pTemp, i ) + Vec_PtrForEachEntry( Nwk_Obj_t *, vFanouts, pTemp, i ) Nwk_ObjPatchFanin( pTemp, pNodeFrom, pNodeTo ); assert( Nwk_ObjFanoutNum(pNodeFrom) == 0 ); assert( Nwk_ObjFanoutNum(pNodeTo) == nFanoutsOld + Vec_PtrSize(vFanouts) ); @@ -313,3 +316,5 @@ void Nwk_ObjReplace( Nwk_Obj_t * pNodeOld, Nwk_Obj_t * pNodeNew ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/nwk/nwkFlow.c b/src/aig/nwk/nwkFlow.c index 5efd0233..3961e5c2 100644 --- a/src/aig/nwk/nwkFlow.c +++ b/src/aig/nwk/nwkFlow.c @@ -20,6 +20,9 @@ #include "nwk.h" +ABC_NAMESPACE_IMPL_START + + /* This code is based on the papers: A. Hurst, A. Mishchenko, and R. Brayton, "Fast minimum-register retiming @@ -33,7 +36,7 @@ //////////////////////////////////////////////////////////////////////// // predecessors -static inline Nwk_Obj_t * Nwk_ObjPred( Nwk_Obj_t * pObj ) { return pObj->pCopy; } +static inline Nwk_Obj_t * Nwk_ObjPred( Nwk_Obj_t * pObj ) { return (Nwk_Obj_t *)pObj->pCopy; } static inline int Nwk_ObjSetPred( Nwk_Obj_t * pObj, Nwk_Obj_t * p ) { pObj->pCopy = p; return 1; } // sink static inline int Nwk_ObjIsSink( Nwk_Obj_t * pObj ) { return pObj->MarkA; } @@ -393,7 +396,7 @@ int Nwk_ManRetimeVerifyCutForward( Nwk_Man_t * pMan, Vec_Ptr_t * vNodes ) Nwk_Obj_t * pObj; int i; // mark the nodes - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Nwk_Obj_t *, vNodes, pObj, i ) { assert( pObj->MarkA == 0 ); pObj->MarkA = 1; @@ -404,7 +407,7 @@ int Nwk_ManRetimeVerifyCutForward( Nwk_Man_t * pMan, Vec_Ptr_t * vNodes ) if ( !Nwk_ManVerifyCut_rec( pObj ) ) printf( "Nwk_ManRetimeVerifyCutForward(): Internal cut verification failed.\n" ); // unmark the nodes - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Nwk_Obj_t *, vNodes, pObj, i ) pObj->MarkA = 0; return 1; } @@ -599,3 +602,5 @@ Vec_Ptr_t * Nwk_ManRetimeCutBackward( Nwk_Man_t * pMan, int nLatches, int fVerbo //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/nwk/nwkFlow_depth.c b/src/aig/nwk/nwkFlow_depth.c index a457631c..6c2e7eb9 100644 --- a/src/aig/nwk/nwkFlow_depth.c +++ b/src/aig/nwk/nwkFlow_depth.c @@ -20,6 +20,9 @@ #include "nwk.h" +ABC_NAMESPACE_IMPL_START + + /* This code is based on the papers: A. Hurst, A. Mishchenko, and R. Brayton, "Fast minimum-register retiming @@ -414,7 +417,7 @@ int Nwk_ManRetimeVerifyCutForward( Nwk_Man_t * pMan, Vec_Ptr_t * vNodes ) Nwk_Obj_t * pObj; int i; // mark the nodes - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Nwk_Obj_t *, vNodes, pObj, i ) { assert( pObj->MarkA == 0 ); pObj->MarkA = 1; @@ -425,7 +428,7 @@ int Nwk_ManRetimeVerifyCutForward( Nwk_Man_t * pMan, Vec_Ptr_t * vNodes ) if ( !Nwk_ManVerifyCut_rec( pObj ) ) printf( "Nwk_ManRetimeVerifyCutForward(): Internal cut verification failed.\n" ); // unmark the nodes - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Nwk_Obj_t *, vNodes, pObj, i ) pObj->MarkA = 0; return 1; } @@ -624,3 +627,5 @@ Vec_Ptr_t * Nwk_ManRetimeCutBackward( Nwk_Man_t * pMan, int nLatches, int fVerbo //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/nwk/nwkMan.c b/src/aig/nwk/nwkMan.c index 8f971871..2e2a3e56 100644 --- a/src/aig/nwk/nwkMan.c +++ b/src/aig/nwk/nwkMan.c @@ -20,6 +20,9 @@ #include "nwk.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -117,7 +120,7 @@ void Nwk_ManPrintLutSizes( Nwk_Man_t * p, If_Lib_t * pLutLib ) ***********************************************************************/ int Nwk_ManCompareAndSaveBest( Nwk_Man_t * pNtk, void * pNtl ) { - extern void Ioa_WriteBlifLogic( Nwk_Man_t * pNtk, void * pNtl, char * pFileName ); +// extern void Ntl_WriteBlifLogic( Nwk_Man_t * pNtk, void * pNtl, char * pFileName ); extern void Nwk_ManDumpBlif( Nwk_Man_t * pNtk, char * pFileName, Vec_Ptr_t * vPiNames, Vec_Ptr_t * vPoNames ); static struct ParStruct { char * pName; // name of the best saved network @@ -154,7 +157,7 @@ int Nwk_ManCompareAndSaveBest( Nwk_Man_t * pNtk, void * pNtl ) ParsBest.nPis = ParsNew.nPis; ParsBest.nPos = ParsNew.nPos; // write the network -// Ioa_WriteBlifLogic( pNtk, pNtl, "best.blif" ); +// Ntl_WriteBlifLogic( pNtk, pNtl, "best.blif" ); // Nwk_ManDumpBlif( pNtk, "best_map.blif", NULL, NULL ); return 1; } @@ -209,14 +212,14 @@ float Nwl_ManComputeTotalSwitching( Nwk_Man_t * pNtk ) pSwitching = (float *)vSwitching->pArray; Nwk_ManForEachObj( pNtk, pObjAbc, i ) { - if ( (pObjAig = Aig_Regular(pObjAbc->pCopy)) ) + if ( (pObjAig = Aig_Regular((Aig_Obj_t *)pObjAbc->pCopy)) ) Result += Nwk_ObjFanoutNum(pObjAbc) * pSwitching[pObjAig->Id]; } Vec_IntFree( vSwitching ); Aig_ManStop( pAig ); return Result; } - + /**Function************************************************************* Synopsis [Prints stats of the manager.] @@ -228,18 +231,18 @@ float Nwl_ManComputeTotalSwitching( Nwk_Man_t * pNtk ) SeeAlso [] ***********************************************************************/ -void Nwk_ManPrintStats( Nwk_Man_t * pNtk, If_Lib_t * pLutLib, int fSaveBest, int fDumpResult, int fPower, void * pNtl ) +void Nwk_ManPrintStats( Nwk_Man_t * pNtk, If_Lib_t * pLutLib, int fSaveBest, int fDumpResult, int fPower, Ntl_Man_t * pNtl ) { - extern int Ntl_ManLatchNum( void * p ); - extern void Ioa_WriteBlifLogic( Nwk_Man_t * pNtk, void * pNtl, char * pFileName ); +// extern int Ntl_ManLatchNum( Ntl_Man_t * p ); +// extern void Ntl_ManWriteBlifLogic( Nwk_Man_t * pNtk, void * pNtl, char * pFileName ); if ( fSaveBest ) Nwk_ManCompareAndSaveBest( pNtk, pNtl ); if ( fDumpResult ) { char Buffer[1000] = {0}; - char * pNameGen = pNtk->pSpec? Nwk_FileNameGeneric( pNtk->pSpec ) : "nameless_"; + const char * pNameGen = pNtk->pSpec? Nwk_FileNameGeneric( pNtk->pSpec ) : "nameless_"; sprintf( Buffer, "%s_dump.blif", pNameGen ); - Ioa_WriteBlifLogic( pNtk, pNtl, Buffer ); +// Ntl_ManWriteBlifLogic( pNtk, pNtl, Buffer ); // sprintf( Buffer, "%s_dump_map.blif", pNameGen ); // Nwk_ManDumpBlif( pNtk, Buffer, NULL, NULL ); if ( pNtk->pSpec ) ABC_FREE( pNameGen ); @@ -251,7 +254,7 @@ void Nwk_ManPrintStats( Nwk_Man_t * pNtk, If_Lib_t * pLutLib, int fSaveBest, int printf( "po = %5d ", Nwk_ManPoNum(pNtk) ); printf( "ci = %5d ", Nwk_ManCiNum(pNtk) ); printf( "co = %5d ", Nwk_ManCoNum(pNtk) ); - printf( "lat = %5d ", Ntl_ManLatchNum(pNtl) ); +// printf( "lat = %5d ", Ntl_ManLatchNum(pNtl) ); printf( "node = %5d ", Nwk_ManNodeNum(pNtk) ); printf( "edge = %5d ", Nwk_ManGetTotalFanins(pNtk) ); printf( "aig = %6d ", Nwk_ManGetAigNodeNum(pNtk) ); @@ -271,3 +274,5 @@ void Nwk_ManPrintStats( Nwk_Man_t * pNtk, If_Lib_t * pLutLib, int fSaveBest, int //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/nwk/nwkMap.c b/src/aig/nwk/nwkMap.c index 5812358b..22f25dbc 100644 --- a/src/aig/nwk/nwkMap.c +++ b/src/aig/nwk/nwkMap.c @@ -21,6 +21,9 @@ #include "nwk.h" #include "if.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -126,21 +129,24 @@ If_Man_t * Nwk_ManToIf( Aig_Man_t * p, If_Par_t * pPars, Vec_Ptr_t * vAigToIf ) Aig_ManForEachObj( p, pNode, i ) { if ( Aig_ObjIsAnd(pNode) ) + { pIfObj = If_ManCreateAnd( pIfMan, - If_NotCond( Aig_ObjFanin0(pNode)->pData, Aig_ObjFaninC0(pNode) ), - If_NotCond( Aig_ObjFanin1(pNode)->pData, Aig_ObjFaninC1(pNode) ) ); + If_NotCond( (If_Obj_t *)Aig_ObjFanin0(pNode)->pData, Aig_ObjFaninC0(pNode) ), + If_NotCond( (If_Obj_t *)Aig_ObjFanin1(pNode)->pData, Aig_ObjFaninC1(pNode) ) ); +// printf( "no%d=%d\n ", If_ObjId(pIfObj), If_ObjLevel(pIfObj) ); + } else if ( Aig_ObjIsPi(pNode) ) { pIfObj = If_ManCreateCi( pIfMan ); If_ObjSetLevel( pIfObj, Aig_ObjLevel(pNode) ); -// printf( "pi=%d ", pIfObj->Level ); +// printf( "pi%d=%d\n ", If_ObjId(pIfObj), If_ObjLevel(pIfObj) ); if ( pIfMan->nLevelMax < (int)pIfObj->Level ) pIfMan->nLevelMax = (int)pIfObj->Level; } else if ( Aig_ObjIsPo(pNode) ) { - pIfObj = If_ManCreateCo( pIfMan, If_NotCond( Aig_ObjFanin0(pNode)->pData, Aig_ObjFaninC0(pNode) ) ); -// printf( "po=%d ", pIfObj->Level ); + pIfObj = If_ManCreateCo( pIfMan, If_NotCond( (If_Obj_t *)Aig_ObjFanin0(pNode)->pData, Aig_ObjFaninC0(pNode) ) ); +// printf( "po%d=%d\n ", If_ObjId(pIfObj), If_ObjLevel(pIfObj) ); } else if ( Aig_ObjIsConst1(pNode) ) pIfObj = If_ManConst1( pIfMan ); @@ -157,8 +163,8 @@ If_Man_t * Nwk_ManToIf( Aig_Man_t * p, If_Par_t * pPars, Vec_Ptr_t * vAigToIf ) { pIfMan->nChoices++; for ( pPrev = pNode, pFanin = Aig_ObjEquiv(p, pNode); pFanin; pPrev = pFanin, pFanin = Aig_ObjEquiv(p, pFanin) ) - If_ObjSetChoice( pPrev->pData, pFanin->pData ); - If_ManCreateChoice( pIfMan, pNode->pData ); + If_ObjSetChoice( (If_Obj_t *)pPrev->pData, (If_Obj_t *)pFanin->pData ); + If_ManCreateChoice( pIfMan, (If_Obj_t *)pNode->pData ); } // assert( If_ObjLevel(pIfObj) == Aig_ObjLevel(pNode) ); } @@ -188,14 +194,14 @@ Hop_Obj_t * Nwk_NodeIfToHop2_rec( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Obj pCut = If_ObjCutBest(pIfObj); // if the cut is visited, return the result if ( If_CutData(pCut) ) - return If_CutData(pCut); + return (Hop_Obj_t *)If_CutData(pCut); // mark the node as visited Vec_PtrPush( vVisited, pCut ); // insert the worst case If_CutSetData( pCut, (void *)1 ); // skip in case of primary input if ( If_ObjIsCi(pIfObj) ) - return If_CutData(pCut); + return (Hop_Obj_t *)If_CutData(pCut); // compute the functions of the children for ( pTemp = pIfObj; pTemp; pTemp = pTemp->pEquiv ) { @@ -212,7 +218,7 @@ Hop_Obj_t * Nwk_NodeIfToHop2_rec( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Obj If_CutSetData( pCut, gFunc ); break; } - return If_CutData(pCut); + return (Hop_Obj_t *)If_CutData(pCut); } /**Function************************************************************* @@ -250,7 +256,7 @@ Hop_Obj_t * Nwk_NodeIfToHop( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Obj_t * // clean the cuts If_CutForEachLeaf( pIfMan, pCut, pLeaf, i ) If_CutSetData( If_ObjCutBest(pLeaf), NULL ); - Vec_PtrForEachEntry( pIfMan->vTemp, pCut, i ) + Vec_PtrForEachEntry( If_Cut_t *, pIfMan->vTemp, pCut, i ) If_CutSetData( pCut, NULL ); return gFunc; } @@ -284,7 +290,7 @@ Nwk_Man_t * Nwk_ManFromIf( If_Man_t * pIfMan, Aig_Man_t * p, Vec_Ptr_t * vAigToI vIfToAig = Vec_PtrStart( If_ManObjNum(pIfMan) ); Aig_ManForEachObj( p, pObj, i ) { - pIfObj = Vec_PtrEntry( vAigToIf, i ); + pIfObj = (If_Obj_t *)Vec_PtrEntry( vAigToIf, i ); Vec_PtrWriteEntry( vIfToAig, pIfObj->Id, pObj ); } // construct the network @@ -296,7 +302,7 @@ Nwk_Man_t * Nwk_ManFromIf( If_Man_t * pIfMan, Aig_Man_t * p, Vec_Ptr_t * vAigToI // pNtk->nTruePos = Nwk_ManCoNum(pNtk) - pNtk->nLatches; Aig_ManForEachObj( p, pObj, i ) { - pIfObj = Vec_PtrEntry( vAigToIf, i ); + pIfObj = (If_Obj_t *)Vec_PtrEntry( vAigToIf, i ); if ( pIfObj->nRefs == 0 && !If_ObjIsTerm(pIfObj) ) continue; if ( Aig_ObjIsNode(pObj) ) @@ -308,8 +314,8 @@ Nwk_Man_t * Nwk_ManFromIf( If_Man_t * pIfMan, Aig_Man_t * p, Vec_Ptr_t * vAigToI pObjNew = Nwk_ManCreateNode( pNtk, nLeaves, pIfObj->nRefs ); for ( k = 0; k < nLeaves; k++ ) { - pObjRepr = Vec_PtrEntry( vIfToAig, ppLeaves[k] ); - Nwk_ObjAddFanin( pObjNew, pObjRepr->pData ); + pObjRepr = (Aig_Obj_t *)Vec_PtrEntry( vIfToAig, ppLeaves[k] ); + Nwk_ObjAddFanin( pObjNew, (Nwk_Obj_t *)pObjRepr->pData ); } // get the functionality pObjNew->pFunc = Nwk_NodeIfToHop( pNtk->pManHop, pIfMan, pIfObj ); @@ -320,7 +326,7 @@ Nwk_Man_t * Nwk_ManFromIf( If_Man_t * pIfMan, Aig_Man_t * p, Vec_Ptr_t * vAigToI { pObjNew = Nwk_ManCreateCo( pNtk ); pObjNew->fInvert = Aig_ObjFaninC0(pObj); - Nwk_ObjAddFanin( pObjNew, Aig_ObjFanin0(pObj)->pData ); + Nwk_ObjAddFanin( pObjNew, (Nwk_Obj_t *)Aig_ObjFanin0(pObj)->pData ); //printf( "%d ", pObjNew->Id ); } else if ( Aig_ObjIsConst1(pObj) ) @@ -365,6 +371,7 @@ Nwk_Man_t * Nwk_MappingIf( Aig_Man_t * p, Tim_Man_t * pManTime, If_Par_t * pPars if ( pIfMan == NULL ) return NULL; pIfMan->pManTim = Tim_ManDup( pManTime, 0 ); + pIfMan->pPars->fCutMin = 0; // is not compatible with deriving result if ( !If_ManPerformMapping( pIfMan ) ) { If_ManStop( pIfMan ); @@ -385,3 +392,5 @@ Nwk_Man_t * Nwk_MappingIf( Aig_Man_t * p, Tim_Man_t * pManTime, If_Par_t * pPars //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/nwk/nwkMerge.c b/src/aig/nwk/nwkMerge.c index bc7826e1..9a4f2f8c 100644 --- a/src/aig/nwk/nwkMerge.c +++ b/src/aig/nwk/nwkMerge.c @@ -21,6 +21,9 @@ #include "nwk.h" #include "nwkMerge.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -787,7 +790,7 @@ void Nwk_ManCollectCircle( Vec_Ptr_t * vStart, Vec_Ptr_t * vNext, int nFanMax ) Nwk_Obj_t * pObj, * pNext; int i, k; Vec_PtrClear( vNext ); - Vec_PtrForEachEntry( vStart, pObj, i ) + Vec_PtrForEachEntry( Nwk_Obj_t *, vStart, pObj, i ) { Nwk_ObjForEachFanin( pObj, pNext, k ) { @@ -845,7 +848,7 @@ void Nwk_ManCollectNonOverlapCands( Nwk_Obj_t * pLut, Vec_Ptr_t * vStart, Vec_Pt vStart = vNext; vNext = vTemp; // collect the nodes in vStart - Vec_PtrForEachEntry( vStart, pObj, k ) + Vec_PtrForEachEntry( Nwk_Obj_t *, vStart, pObj, k ) Vec_PtrPush( vCands, pObj ); } @@ -867,7 +870,7 @@ void Nwk_ManCollectNonOverlapCands( Nwk_Obj_t * pLut, Vec_Ptr_t * vStart, Vec_Pt // - they have no more than the given number of fanins // - they have no more than the given diff in delay k = 0; - Vec_PtrForEachEntry( vCands, pObj, i ) + Vec_PtrForEachEntry( Nwk_Obj_t *, vCands, pObj, i ) { if ( Nwk_ObjIsTravIdCurrent(pObj) ) continue; @@ -963,8 +966,9 @@ void Nwk_ManCollectOverlapCands( Nwk_Obj_t * pLut, Vec_Ptr_t * vCands, Nwk_LMPar SeeAlso [] ***********************************************************************/ -Vec_Int_t * Nwk_ManLutMerge( Nwk_Man_t * pNtk, Nwk_LMPars_t * pPars ) +Vec_Int_t * Nwk_ManLutMerge( Nwk_Man_t * pNtk, void * pParsInit ) { + Nwk_LMPars_t * pPars = (Nwk_LMPars_t *)pParsInit; Nwk_Grf_t * p; Vec_Int_t * vResult; Vec_Ptr_t * vStart, * vNext, * vCands1, * vCands2; @@ -992,9 +996,9 @@ Vec_Int_t * Nwk_ManLutMerge( Nwk_Man_t * pNtk, Nwk_LMPars_t * pPars ) continue; nCands += Vec_PtrSize(vCands1) + Vec_PtrSize(vCands2); // save candidates - Vec_PtrForEachEntry( vCands1, pCand, k ) + Vec_PtrForEachEntry( Nwk_Obj_t *, vCands1, pCand, k ) Nwk_ManGraphHashEdge( p, Nwk_ObjId(pLut), Nwk_ObjId(pCand) ); - Vec_PtrForEachEntry( vCands2, pCand, k ) + Vec_PtrForEachEntry( Nwk_Obj_t *, vCands2, pCand, k ) Nwk_ManGraphHashEdge( p, Nwk_ObjId(pLut), Nwk_ObjId(pCand) ); // print statistics about this node if ( pPars->fVeryVerbose ) @@ -1036,3 +1040,5 @@ Vec_Int_t * Nwk_ManLutMerge( Nwk_Man_t * pNtk, Nwk_LMPars_t * pPars ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/nwk/nwkMerge.h b/src/aig/nwk/nwkMerge.h index ab39ec39..f6be760f 100644 --- a/src/aig/nwk/nwkMerge.h +++ b/src/aig/nwk/nwkMerge.h @@ -21,6 +21,7 @@ #ifndef __NWK_MERGE_H__ #define __NWK_MERGE_H__ + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -29,9 +30,10 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + #define NWK_MAX_LIST 16 @@ -137,9 +139,11 @@ extern ABC_DLL void Nwk_ManGraphHashEdge( Nwk_Grf_t * p, int iLut1, int extern ABC_DLL void Nwk_ManGraphSolve( Nwk_Grf_t * p ); extern ABC_DLL int Nwk_ManLutMergeGraphTest( char * pFileName ); -#ifdef __cplusplus -} -#endif + + +ABC_NAMESPACE_HEADER_END + + #endif diff --git a/src/aig/nwk/nwkObj.c b/src/aig/nwk/nwkObj.c index 58587f07..e5930087 100644 --- a/src/aig/nwk/nwkObj.c +++ b/src/aig/nwk/nwkObj.c @@ -20,6 +20,9 @@ #include "nwk.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -157,7 +160,7 @@ void Nwk_ManDeleteNode( Nwk_Obj_t * pObj ) assert( Nwk_ObjFanoutNum(pObj) == 0 ); // delete fanins Nwk_ObjCollectFanins( pObj, vNodes ); - Vec_PtrForEachEntry( vNodes, pTemp, i ) + Vec_PtrForEachEntry( Nwk_Obj_t *, vNodes, pTemp, i ) Nwk_ObjDeleteFanin( pObj, pTemp ); // remove from the list of objects Vec_PtrWriteEntry( pObj->pMan->vObjs, pObj->Id, NULL ); @@ -186,7 +189,7 @@ void Nwk_ManDeleteNode_rec( Nwk_Obj_t * pObj ) vNodes = Vec_PtrAlloc( 100 ); Nwk_ObjCollectFanins( pObj, vNodes ); Nwk_ManDeleteNode( pObj ); - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Nwk_Obj_t *, vNodes, pObj, i ) if ( Nwk_ObjIsNode(pObj) && Nwk_ObjFanoutNum(pObj) == 0 ) Nwk_ManDeleteNode_rec( pObj ); Vec_PtrFree( vNodes ); @@ -197,3 +200,5 @@ void Nwk_ManDeleteNode_rec( Nwk_Obj_t * pObj ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/nwk/nwkSpeedup.c b/src/aig/nwk/nwkSpeedup.c index 54e4d414..335d50f8 100644 --- a/src/aig/nwk/nwkSpeedup.c +++ b/src/aig/nwk/nwkSpeedup.c @@ -20,6 +20,9 @@ #include "nwk.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -74,9 +77,9 @@ void Aig_ManSpeedupNode( Nwk_Man_t * pNtk, Aig_Man_t * pAig, Nwk_Obj_t * pNode, int nCofs, i, k, nSkip; // quit of regulars are the same - Vec_PtrForEachEntry( vLeaves, pObj, i ) - Vec_PtrForEachEntry( vLeaves, pObj2, k ) - if ( i != k && Aig_Regular(pObj->pCopy) == Aig_Regular(pObj2->pCopy) ) + Vec_PtrForEachEntry( Nwk_Obj_t *, vLeaves, pObj, i ) + Vec_PtrForEachEntry( Nwk_Obj_t *, vLeaves, pObj2, k ) + if ( i != k && Aig_Regular((Aig_Obj_t *)pObj->pCopy) == Aig_Regular((Aig_Obj_t *)pObj2->pCopy) ) { // printf( "Identical after structural hashing!!!\n" ); return; @@ -86,13 +89,13 @@ void Aig_ManSpeedupNode( Nwk_Man_t * pNtk, Aig_Man_t * pAig, Nwk_Obj_t * pNode, vNodes = Vec_PtrAlloc( 100 ); Aig_ManIncrementTravId( pAig ); Aig_ObjSetTravIdCurrent( pAig, Aig_ManConst1(pAig) ); - Vec_PtrForEachEntry( vLeaves, pObj, i ) + Vec_PtrForEachEntry( Nwk_Obj_t *, vLeaves, pObj, i ) { - pAnd = pObj->pCopy; + pAnd = (Aig_Obj_t *)pObj->pCopy; Aig_ObjSetTravIdCurrent( pAig, Aig_Regular(pAnd) ); } // traverse from the root node - pAnd = pNode->pCopy; + pAnd = (Aig_Obj_t *)pNode->pCopy; if ( !Aig_ManSpeedupNode_rec( pAig, Aig_Regular(pAnd), vNodes ) ) { // printf( "Bad node!!!\n" ); @@ -104,21 +107,21 @@ void Aig_ManSpeedupNode( Nwk_Man_t * pNtk, Aig_Man_t * pAig, Nwk_Obj_t * pNode, nCofs = (1 << Vec_PtrSize(vTimes)); for ( i = 0; i < nCofs; i++ ) { - Vec_PtrForEachEntry( vLeaves, pObj, k ) + Vec_PtrForEachEntry( Nwk_Obj_t *, vLeaves, pObj, k ) { - pAnd = pObj->pCopy; + pAnd = (Aig_Obj_t *)pObj->pCopy; Aig_Regular(pAnd)->pData = Aig_Regular(pAnd); } - Vec_PtrForEachEntry( vTimes, pObj, k ) + Vec_PtrForEachEntry( Nwk_Obj_t *, vTimes, pObj, k ) { - pAnd = pObj->pCopy; + pAnd = (Aig_Obj_t *)pObj->pCopy; Aig_Regular(pAnd)->pData = Aig_NotCond( Aig_ManConst1(pAig), ((i & (1<<k)) == 0) ); } - Vec_PtrForEachEntry( vNodes, pTemp, k ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pTemp, k ) pTemp->pData = Aig_And( pAig, Aig_ObjChild0Copy(pTemp), Aig_ObjChild1Copy(pTemp) ); // save the result - pAnd = pNode->pCopy; - ppCofs[i] = Aig_NotCond( Aig_Regular(pAnd)->pData, Aig_IsComplement(pAnd) ); + pAnd = (Aig_Obj_t *)pNode->pCopy; + ppCofs[i] = Aig_NotCond( (Aig_Obj_t *)Aig_Regular(pAnd)->pData, Aig_IsComplement(pAnd) ); } Vec_PtrFree( vNodes ); @@ -126,16 +129,16 @@ void Aig_ManSpeedupNode( Nwk_Man_t * pNtk, Aig_Man_t * pAig, Nwk_Obj_t * pNode, //Nwk_ObjAddFanin( Nwk_ManCreatePo(pAig), ppCofs[1] ); // collect the resulting tree - Vec_PtrForEachEntry( vTimes, pObj, k ) + Vec_PtrForEachEntry( Nwk_Obj_t *, vTimes, pObj, k ) for ( nSkip = (1<<k), i = 0; i < nCofs; i += 2*nSkip ) { - pAnd = pObj->pCopy; + pAnd = (Aig_Obj_t *)pObj->pCopy; ppCofs[i] = Aig_Mux( pAig, Aig_Regular(pAnd), ppCofs[i+nSkip], ppCofs[i] ); } //Nwk_ObjAddFanin( Nwk_ManCreatePo(pAig), ppCofs[0] ); // create choice node - pAnd = Aig_Regular(pNode->pCopy); // repr + pAnd = Aig_Regular((Aig_Obj_t *)pNode->pCopy); // repr pTemp = Aig_Regular(ppCofs[0]); // new if ( Aig_ObjEquiv(pAig, pAnd) == NULL && Aig_ObjEquiv(pAig, pTemp) == NULL && !Aig_ObjCheckTfi(pAig, pTemp, pAnd) ) pAig->pEquivs[pAnd->Id] = pTemp; @@ -204,12 +207,20 @@ Aig_Man_t * Nwk_ManSpeedup( Nwk_Man_t * pNtk, int fUseLutLib, int Percentage, in Nwk_Obj_t * pNode, * pFanin, * pFanin2; Aig_Obj_t * pAnd; If_Lib_t * pTempLib = pNtk->pLutLib; + Tim_Man_t * pTempTim = NULL; float tDelta, tArrival; int i, k, k2, Counter, CounterRes, nTimeCris; unsigned * puTCEdges; // perform delay trace if ( !fUseLutLib ) + { pNtk->pLutLib = NULL; + if ( pNtk->pManTime ) + { + pTempTim = pNtk->pManTime; + pNtk->pManTime = Tim_ManDup( pTempTim, 1 ); + } + } tArrival = Nwk_ManDelayTraceLut( pNtk ); tDelta = fUseLutLib ? tArrival*Percentage/100.0 : 1.0; if ( fVerbose ) @@ -302,8 +313,8 @@ Aig_Man_t * Nwk_ManSpeedup( Nwk_Man_t * pNtk, int fUseLutLib, int Percentage, in // order the fanins in the increasing order of criticalily if ( Vec_PtrSize(vTimeCries) > 1 ) { - pFanin = Vec_PtrEntry( vTimeCries, 0 ); - pFanin2 = Vec_PtrEntry( vTimeCries, 1 ); + pFanin = (Nwk_Obj_t *)Vec_PtrEntry( vTimeCries, 0 ); + pFanin2 = (Nwk_Obj_t *)Vec_PtrEntry( vTimeCries, 1 ); if ( Nwk_ObjSlack(pFanin) < Nwk_ObjSlack(pFanin2) ) { Vec_PtrWriteEntry( vTimeCries, 0, pFanin2 ); @@ -312,15 +323,15 @@ Aig_Man_t * Nwk_ManSpeedup( Nwk_Man_t * pNtk, int fUseLutLib, int Percentage, in } if ( Vec_PtrSize(vTimeCries) > 2 ) { - pFanin = Vec_PtrEntry( vTimeCries, 1 ); - pFanin2 = Vec_PtrEntry( vTimeCries, 2 ); + pFanin = (Nwk_Obj_t *)Vec_PtrEntry( vTimeCries, 1 ); + pFanin2 = (Nwk_Obj_t *)Vec_PtrEntry( vTimeCries, 2 ); if ( Nwk_ObjSlack(pFanin) < Nwk_ObjSlack(pFanin2) ) { Vec_PtrWriteEntry( vTimeCries, 1, pFanin2 ); Vec_PtrWriteEntry( vTimeCries, 2, pFanin ); } - pFanin = Vec_PtrEntry( vTimeCries, 0 ); - pFanin2 = Vec_PtrEntry( vTimeCries, 1 ); + pFanin = (Nwk_Obj_t *)Vec_PtrEntry( vTimeCries, 0 ); + pFanin2 = (Nwk_Obj_t *)Vec_PtrEntry( vTimeCries, 1 ); if ( Nwk_ObjSlack(pFanin) < Nwk_ObjSlack(pFanin2) ) { Vec_PtrWriteEntry( vTimeCries, 0, pFanin2 ); @@ -348,6 +359,11 @@ Aig_Man_t * Nwk_ManSpeedup( Nwk_Man_t * pNtk, int fUseLutLib, int Percentage, in // put back the library if ( !fUseLutLib ) pNtk->pLutLib = pTempLib; + if ( pTempTim ) + { + Tim_ManStop( pNtk->pManTime ); + pNtk->pManTime = pTempTim; + } // reconstruct the network pAig = Aig_ManDupDfs( pTemp = pAig ); @@ -362,3 +378,5 @@ Aig_Man_t * Nwk_ManSpeedup( Nwk_Man_t * pNtk, int fUseLutLib, int Percentage, in //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/nwk/nwkStrash.c b/src/aig/nwk/nwkStrash.c index 6c2a3677..54f1f027 100644 --- a/src/aig/nwk/nwkStrash.c +++ b/src/aig/nwk/nwkStrash.c @@ -20,6 +20,9 @@ #include "nwk.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -79,7 +82,7 @@ Aig_Obj_t * Nwk_ManStrashNode( Aig_Man_t * p, Nwk_Obj_t * pObj ) Nwk_ManStrashNode_rec( p, Hop_Regular(pRoot) ); Hop_ConeUnmark_rec( Hop_Regular(pRoot) ); // return the final node - return Aig_NotCond( Hop_Regular(pRoot)->pData, Hop_IsComplement(pRoot) ); + return Aig_NotCond( (Aig_Obj_t *)Hop_Regular(pRoot)->pData, Hop_IsComplement(pRoot) ); } /**Function************************************************************* @@ -103,25 +106,25 @@ Aig_Man_t * Nwk_ManStrash( Nwk_Man_t * pNtk ) pMan = Aig_ManStart( Nwk_ManGetAigNodeNum(pNtk) ); pMan->pName = Aig_UtilStrsav( pNtk->pName ); pMan->pSpec = Aig_UtilStrsav( pNtk->pSpec ); - pMan->pManTime = Tim_ManDup( pNtk->pManTime, 1 ); - Tim_ManIncrementTravId( pMan->pManTime ); + pMan->pManTime = Tim_ManDup( (Tim_Man_t *)pNtk->pManTime, 1 ); + Tim_ManIncrementTravId( (Tim_Man_t *)pMan->pManTime ); Nwk_ManForEachObj( pNtk, pObj, i ) pObj->pCopy = NULL; // Nwk_ManForEachObj( pNtk, pObj, i ) vObjs = Nwk_ManDfs( pNtk ); - Vec_PtrForEachEntry( vObjs, pObj, i ) + Vec_PtrForEachEntry( Nwk_Obj_t *, vObjs, pObj, i ) { if ( Nwk_ObjIsCi(pObj) ) { pObjNew = Aig_ObjCreatePi(pMan); - Level = Tim_ManGetCiArrival( pMan->pManTime, pObj->PioId ); + Level = Tim_ManGetCiArrival( (Tim_Man_t *)pMan->pManTime, pObj->PioId ); Aig_ObjSetLevel( pObjNew, Level ); } else if ( Nwk_ObjIsCo(pObj) ) { - pObjNew = Aig_ObjCreatePo( pMan, Aig_NotCond(Nwk_ObjFanin0(pObj)->pCopy, pObj->fInvert) ); + pObjNew = Aig_ObjCreatePo( pMan, Aig_NotCond((Aig_Obj_t *)Nwk_ObjFanin0(pObj)->pCopy, pObj->fInvert) ); Level = Aig_ObjLevel( pObjNew ); - Tim_ManSetCoArrival( pMan->pManTime, pObj->PioId, (float)Level ); + Tim_ManSetCoArrival( (Tim_Man_t *)pMan->pManTime, pObj->PioId, (float)Level ); } else if ( Nwk_ObjIsNode(pObj) ) { @@ -142,3 +145,5 @@ Aig_Man_t * Nwk_ManStrash( Nwk_Man_t * pNtk ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/nwk/nwkTiming.c b/src/aig/nwk/nwkTiming.c index 5c53038c..53591ee8 100644 --- a/src/aig/nwk/nwkTiming.c +++ b/src/aig/nwk/nwkTiming.c @@ -20,6 +20,9 @@ #include "nwk.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -349,13 +352,13 @@ float Nwk_ManDelayTraceLut( Nwk_Man_t * pNtk ) Tim_ManIncrementTravId( pNtk->pManTime ); // Nwk_ManForEachObj( pNtk, pObj, i ) vObjs = Nwk_ManDfs( pNtk ); - Vec_PtrForEachEntry( vObjs, pObj, i ) + Vec_PtrForEachEntry( Nwk_Obj_t *, vObjs, pObj, i ) { tArrival = Nwk_NodeComputeArrival( pObj, fUseSorting ); - if ( Nwk_ObjIsCo(pObj) && pNtk->pManTime ) - Tim_ManSetCoArrival( pNtk->pManTime, pObj->PioId, tArrival ); if ( Nwk_ObjIsCi(pObj) && pNtk->pManTime ) tArrival = Tim_ManGetCiArrival( pNtk->pManTime, pObj->PioId ); + if ( Nwk_ObjIsCo(pObj) && pNtk->pManTime ) + Tim_ManSetCoArrival( pNtk->pManTime, pObj->PioId, tArrival ); Nwk_ObjSetArrival( pObj, tArrival ); } Vec_PtrFree( vObjs ); @@ -379,7 +382,7 @@ float Nwk_ManDelayTraceLut( Nwk_Man_t * pNtk ) } // propagate the required times - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Nwk_Obj_t *, vNodes, pObj, i ) { if ( Nwk_ObjIsNode(pObj) ) { @@ -518,8 +521,8 @@ void Nwk_NodeUpdateAddToQueue( Vec_Ptr_t * vQueue, Nwk_Obj_t * pObj, int iCurren Vec_PtrPush( vQueue, pObj ); for ( i = Vec_PtrSize(vQueue) - 1; i > iCurrent + 1; i-- ) { - pTemp1 = vQueue->pArray[i]; - pTemp2 = vQueue->pArray[i-1]; + pTemp1 = (Nwk_Obj_t *)vQueue->pArray[i]; + pTemp2 = (Nwk_Obj_t *)vQueue->pArray[i-1]; if ( fArrival ) { if ( Nwk_ObjLevel(pTemp2) <= Nwk_ObjLevel(pTemp1) ) @@ -536,8 +539,8 @@ void Nwk_NodeUpdateAddToQueue( Vec_Ptr_t * vQueue, Nwk_Obj_t * pObj, int iCurren // verification for ( i = iCurrent + 1; i < Vec_PtrSize(vQueue) - 1; i++ ) { - pTemp1 = vQueue->pArray[i]; - pTemp2 = vQueue->pArray[i+1]; + pTemp1 = (Nwk_Obj_t *)vQueue->pArray[i]; + pTemp2 = (Nwk_Obj_t *)vQueue->pArray[i+1]; if ( fArrival ) assert( Nwk_ObjLevel(pTemp1) <= Nwk_ObjLevel(pTemp2) ); else @@ -575,7 +578,7 @@ void Nwk_NodeUpdateArrival( Nwk_Obj_t * pObj ) // process objects if ( pManTime ) Tim_ManIncrementTravId( pManTime ); - Vec_PtrForEachEntry( vQueue, pTemp, iCur ) + Vec_PtrForEachEntry( Nwk_Obj_t *, vQueue, pTemp, iCur ) { pTemp->MarkA = 0; tArrival = Nwk_NodeComputeArrival( pTemp, 1 ); @@ -659,7 +662,7 @@ void Nwk_NodeUpdateRequired( Nwk_Obj_t * pObj ) // process objects if ( pManTime ) Tim_ManIncrementTravId( pManTime ); - Vec_PtrForEachEntry( vQueue, pTemp, iCur ) + Vec_PtrForEachEntry( Nwk_Obj_t *, vQueue, pTemp, iCur ) { pTemp->MarkA = 0; tRequired = Nwk_NodeComputeRequired( pTemp, 1 ); @@ -773,7 +776,7 @@ void Nwk_ManUpdateLevel( Nwk_Obj_t * pObj ) Vec_PtrPush( vQueue, pObj ); pObj->MarkA = 1; // process objects - Vec_PtrForEachEntry( vQueue, pTemp, iCur ) + Vec_PtrForEachEntry( Nwk_Obj_t *, vQueue, pTemp, iCur ) { pTemp->MarkA = 0; LevelNew = Nwk_ObjLevelNew( pTemp ); @@ -887,3 +890,5 @@ void Nwk_ManUpdate( Nwk_Obj_t * pObj, Nwk_Obj_t * pObjNew, Vec_Vec_t * vLevels ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/nwk/nwkUtil.c b/src/aig/nwk/nwkUtil.c index 9fc292ea..a1948031 100644 --- a/src/aig/nwk/nwkUtil.c +++ b/src/aig/nwk/nwkUtil.c @@ -18,9 +18,12 @@ ***********************************************************************/ +#include <math.h> #include "nwk.h" #include "kit.h" -#include <math.h> + +ABC_NAMESPACE_IMPL_START + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// @@ -295,7 +298,7 @@ void Nwk_ManDumpBlif( Nwk_Man_t * pNtk, char * pFileName, Vec_Ptr_t * vPiNames, vTruth = Vec_IntAlloc( 1 << 16 ); vCover = Vec_IntAlloc( 1 << 16 ); vNodes = Nwk_ManDfs( pNtk ); - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Nwk_Obj_t *, vNodes, pObj, i ) { if ( !Nwk_ObjIsNode(pObj) ) continue; @@ -425,7 +428,7 @@ void Nwk_ManPrintFanioNew( Nwk_Man_t * pNtk ) printf( "%15d : ", k ); else { - sprintf( Buffer, "%d - %d", (int)pow(10, k/10) * (k%10), (int)pow(10, k/10) * (k%10+1) - 1 ); + sprintf( Buffer, "%d - %d", (int)pow((double)10, k/10) * (k%10), (int)pow((double)10, k/10) * (k%10+1) - 1 ); printf( "%15s : ", Buffer ); } if ( vFanins->pArray[k] == 0 ) @@ -636,3 +639,5 @@ void Nwk_ManRemoveDupFanins( Nwk_Man_t * pNtk, int fVerbose ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/nwk/nwk_.c b/src/aig/nwk/nwk_.c index 81cffbbf..882b077c 100644 --- a/src/aig/nwk/nwk_.c +++ b/src/aig/nwk/nwk_.c @@ -20,6 +20,9 @@ #include "nwk.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -45,3 +48,5 @@ //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/nwk2/module.make b/src/aig/nwk2/module.make deleted file mode 100644 index 226a68ef..00000000 --- a/src/aig/nwk2/module.make +++ /dev/null @@ -1,7 +0,0 @@ -SRC += src/aig/nwk/nwkCheck.c \ - src/aig/nwk/nwkDfs.c \ - src/aig/nwk/nwkFanio.c \ - src/aig/nwk/nwkMan.c \ - src/aig/nwk/nwkMerge.c \ - src/aig/nwk/nwkObj.c \ - src/aig/nwk/nwkUtil.c diff --git a/src/aig/nwk2/nwk.h b/src/aig/nwk2/nwk.h deleted file mode 100644 index 36d483fc..00000000 --- a/src/aig/nwk2/nwk.h +++ /dev/null @@ -1,278 +0,0 @@ -/**CFile**************************************************************** - - FileName [nwk.h] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Logic network representation.] - - Synopsis [External declarations.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: nwk.h,v 1.1 2008/05/14 22:13:09 wudenni Exp $] - -***********************************************************************/ - -#ifndef __NWK_H__ -#define __NWK_H__ - -//////////////////////////////////////////////////////////////////////// -/// INCLUDES /// -//////////////////////////////////////////////////////////////////////// - -#include "aig.h" -#include "hop.h" -#include "tim.h" - -//////////////////////////////////////////////////////////////////////// -/// PARAMETERS /// -//////////////////////////////////////////////////////////////////////// - -#ifdef __cplusplus -extern "C" { -#endif - -//////////////////////////////////////////////////////////////////////// -/// BASIC TYPES /// -//////////////////////////////////////////////////////////////////////// - -typedef struct Nwk_Man_t_ Nwk_Man_t; -typedef struct Nwk_Obj_t_ Nwk_Obj_t; - -// object types -typedef enum { - NWK_OBJ_NONE, // 0: non-existant object - NWK_OBJ_CI, // 1: combinational input - NWK_OBJ_CO, // 2: combinational output - NWK_OBJ_NODE, // 3: logic node - NWK_OBJ_LATCH, // 4: register - NWK_OBJ_VOID // 5: unused object -} Nwk_Type_t; - -struct Nwk_Man_t_ -{ - // models of this design - char * pName; // the name of this design - char * pSpec; // the name of input file - // node representation - Vec_Ptr_t * vCis; // the primary inputs of the extracted part - Vec_Ptr_t * vCos; // the primary outputs of the extracted part - Vec_Ptr_t * vObjs; // the objects in the topological order - int nObjs[NWK_OBJ_VOID]; // counter of objects of each type - int nFanioPlus; // the number of extra fanins/fanouts alloc by default - // functionality, timing, memory, etc - Hop_Man_t * pManHop; // the functionality representation - Tim_Man_t * pManTime; // the timing manager -// If_Lib_t * pLutLib; // the LUT library - Aig_MmFlex_t * pMemObjs; // memory for objects - Vec_Ptr_t * vTemp; // array used for incremental updates - int nTravIds; // the counter of traversal IDs - int nRealloced; // the number of realloced nodes - // sequential information - int nLatches; // the total number of latches - int nTruePis; // the number of true primary inputs - int nTruePos; // the number of true primary outputs -}; - -struct Nwk_Obj_t_ -{ - Nwk_Man_t * pMan; // the manager - Hop_Obj_t * pFunc; // functionality - void * pCopy; // temporary pointer - union { - void * pNext; // temporary pointer - int iTemp; // temporary number - }; - // node information - unsigned Type : 3; // object type - unsigned fInvert : 1; // complemented attribute - unsigned MarkA : 1; // temporary mark - unsigned MarkB : 1; // temporary mark - unsigned MarkC : 1; // temporary mark - unsigned PioId : 25; // number of this node in the PI/PO list - int Id; // unique ID - int TravId; // traversal ID - // timing information - int Level; // the topological level - float tArrival; // the arrival time - float tRequired; // the required time - float tSlack; // the slack - // fanin/fanout representation - int nFanins; // the number of fanins - int nFanouts; // the number of fanouts - int nFanioAlloc; // the number of allocated fanins/fanouts - Nwk_Obj_t ** pFanio; // fanins/fanouts -}; - -//////////////////////////////////////////////////////////////////////// -/// MACRO DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - - -//////////////////////////////////////////////////////////////////////// -/// INLINED FUNCTIONS /// -//////////////////////////////////////////////////////////////////////// - -static inline int Nwk_ManCiNum( Nwk_Man_t * p ) { return p->nObjs[NWK_OBJ_CI]; } -static inline int Nwk_ManCoNum( Nwk_Man_t * p ) { return p->nObjs[NWK_OBJ_CO]; } -static inline int Nwk_ManNodeNum( Nwk_Man_t * p ) { return p->nObjs[NWK_OBJ_NODE]; } -static inline int Nwk_ManLatchNum( Nwk_Man_t * p ) { return p->nObjs[NWK_OBJ_LATCH]; } -static inline int Nwk_ManObjNumMax( Nwk_Man_t * p ) { return Vec_PtrSize(p->vObjs); } - -static inline Nwk_Obj_t * Nwk_ManCi( Nwk_Man_t * p, int i ) { return (Nwk_Obj_t *)Vec_PtrEntry( p->vCis, i ); } -static inline Nwk_Obj_t * Nwk_ManCo( Nwk_Man_t * p, int i ) { return (Nwk_Obj_t *)Vec_PtrEntry( p->vCos, i ); } -static inline Nwk_Obj_t * Nwk_ManObj( Nwk_Man_t * p, int i ) { return (Nwk_Obj_t *)Vec_PtrEntry( p->vObjs, i ); } - -static inline int Nwk_ObjId( Nwk_Obj_t * p ) { return p->Id; } -static inline int Nwk_ObjPioNum( Nwk_Obj_t * p ) { return p->PioId; } -static inline int Nwk_ObjFaninNum( Nwk_Obj_t * p ) { return p->nFanins; } -static inline int Nwk_ObjFanoutNum( Nwk_Obj_t * p ) { return p->nFanouts; } - -static inline Nwk_Obj_t * Nwk_ObjFanin0( Nwk_Obj_t * p ) { return p->pFanio[0]; } -static inline Nwk_Obj_t * Nwk_ObjFanout0( Nwk_Obj_t * p ) { return p->pFanio[p->nFanins]; } -static inline Nwk_Obj_t * Nwk_ObjFanin( Nwk_Obj_t * p, int i ) { return p->pFanio[i]; } -static inline Nwk_Obj_t * Nwk_ObjFanout( Nwk_Obj_t * p, int i ) { return p->pFanio[p->nFanins+1]; } - -static inline int Nwk_ObjIsNone( Nwk_Obj_t * p ) { return p->Type == NWK_OBJ_NONE; } -static inline int Nwk_ObjIsCi( Nwk_Obj_t * p ) { return p->Type == NWK_OBJ_CI; } -static inline int Nwk_ObjIsCo( Nwk_Obj_t * p ) { return p->Type == NWK_OBJ_CO; } -static inline int Nwk_ObjIsNode( Nwk_Obj_t * p ) { return p->Type == NWK_OBJ_NODE; } -static inline int Nwk_ObjIsLatch( Nwk_Obj_t * p ) { return p->Type == NWK_OBJ_LATCH; } -static inline int Nwk_ObjIsPi( Nwk_Obj_t * p ) { return Nwk_ObjIsCi(p) && (p->pMan->pManTime == NULL || Tim_ManBoxForCi(p->pMan->pManTime, p->PioId) == -1); } -static inline int Nwk_ObjIsPo( Nwk_Obj_t * p ) { return Nwk_ObjIsCo(p) && (p->pMan->pManTime == NULL || Tim_ManBoxForCo(p->pMan->pManTime, p->PioId) == -1); } -static inline int Nwk_ObjIsLi( Nwk_Obj_t * p ) { return p->pMan->nTruePos && Nwk_ObjIsCo(p) && (int)p->PioId >= p->pMan->nTruePos; } -static inline int Nwk_ObjIsLo( Nwk_Obj_t * p ) { return p->pMan->nTruePis && Nwk_ObjIsCi(p) && (int)p->PioId >= p->pMan->nTruePis; } - -static inline float Nwk_ObjArrival( Nwk_Obj_t * pObj ) { return pObj->tArrival; } -static inline float Nwk_ObjRequired( Nwk_Obj_t * pObj ) { return pObj->tRequired; } -static inline float Nwk_ObjSlack( Nwk_Obj_t * pObj ) { return pObj->tSlack; } -static inline void Nwk_ObjSetArrival( Nwk_Obj_t * pObj, float Time ) { pObj->tArrival = Time; } -static inline void Nwk_ObjSetRequired( Nwk_Obj_t * pObj, float Time ) { pObj->tRequired = Time; } -static inline void Nwk_ObjSetSlack( Nwk_Obj_t * pObj, float Time ) { pObj->tSlack = Time; } - -static inline int Nwk_ObjLevel( Nwk_Obj_t * pObj ) { return pObj->Level; } -static inline void Nwk_ObjSetLevel( Nwk_Obj_t * pObj, int Level ) { pObj->Level = Level; } - -static inline void Nwk_ObjSetTravId( Nwk_Obj_t * pObj, int TravId ) { pObj->TravId = TravId; } -static inline void Nwk_ObjSetTravIdCurrent( Nwk_Obj_t * pObj ) { pObj->TravId = pObj->pMan->nTravIds; } -static inline void Nwk_ObjSetTravIdPrevious( Nwk_Obj_t * pObj ) { pObj->TravId = pObj->pMan->nTravIds - 1; } -static inline int Nwk_ObjIsTravIdCurrent( Nwk_Obj_t * pObj ) { return pObj->TravId == pObj->pMan->nTravIds; } -static inline int Nwk_ObjIsTravIdPrevious( Nwk_Obj_t * pObj ) { return pObj->TravId == pObj->pMan->nTravIds - 1; } - -static inline int Nwk_ManTimeEqual( float f1, float f2, float Eps ) { return (f1 < f2 + Eps) && (f2 < f1 + Eps); } -static inline int Nwk_ManTimeLess( float f1, float f2, float Eps ) { return (f1 < f2 + Eps); } -static inline int Nwk_ManTimeMore( float f1, float f2, float Eps ) { return (f1 + Eps > f2); } - -//////////////////////////////////////////////////////////////////////// -/// ITERATORS /// -//////////////////////////////////////////////////////////////////////// - -#define Nwk_ManForEachCi( p, pObj, i ) \ - Vec_PtrForEachEntry( p->vCis, pObj, i ) -#define Nwk_ManForEachCo( p, pObj, i ) \ - Vec_PtrForEachEntry( p->vCos, pObj, i ) -#define Nwk_ManForEachPi( p, pObj, i ) \ - Vec_PtrForEachEntry( p->vCis, pObj, i ) \ - if ( !Nwk_ObjIsPi(pObj) ) {} else -#define Nwk_ManForEachPo( p, pObj, i ) \ - Vec_PtrForEachEntry( p->vCos, pObj, i ) \ - if ( !Nwk_ObjIsPo(pObj) ) {} else -#define Nwk_ManForEachObj( p, pObj, i ) \ - for ( i = 0; (i < Vec_PtrSize(p->vObjs)) && (((pObj) = Vec_PtrEntry(p->vObjs, i)), 1); i++ ) \ - if ( pObj == NULL ) {} else -#define Nwk_ManForEachNode( p, pObj, i ) \ - for ( i = 0; (i < Vec_PtrSize(p->vObjs)) && (((pObj) = Vec_PtrEntry(p->vObjs, i)), 1); i++ ) \ - if ( (pObj) == NULL || !Nwk_ObjIsNode(pObj) ) {} else -#define Nwk_ManForEachLatch( p, pObj, i ) \ - for ( i = 0; (i < Vec_PtrSize(p->vObjs)) && (((pObj) = Vec_PtrEntry(p->vObjs, i)), 1); i++ ) \ - if ( (pObj) == NULL || !Nwk_ObjIsLatch(pObj) ) {} else - -#define Nwk_ObjForEachFanin( pObj, pFanin, i ) \ - for ( i = 0; (i < (int)(pObj)->nFanins) && ((pFanin) = (pObj)->pFanio[i]); i++ ) -#define Nwk_ObjForEachFanout( pObj, pFanout, i ) \ - for ( i = 0; (i < (int)(pObj)->nFanouts) && ((pFanout) = (pObj)->pFanio[(pObj)->nFanins+i]); i++ ) - -// sequential iterators -#define Nwk_ManForEachPiSeq( p, pObj, i ) \ - Vec_PtrForEachEntryStop( p->vCis, pObj, i, (p)->nTruePis ) -#define Nwk_ManForEachPoSeq( p, pObj, i ) \ - Vec_PtrForEachEntryStop( p->vCos, pObj, i, (p)->nTruePos ) -#define Nwk_ManForEachLoSeq( p, pObj, i ) \ - for ( i = 0; (i < (p)->nLatches) && (((pObj) = Vec_PtrEntry(p->vCis, i+(p)->nTruePis)), 1); i++ ) -#define Nwk_ManForEachLiSeq( p, pObj, i ) \ - for ( i = 0; (i < (p)->nLatches) && (((pObj) = Vec_PtrEntry(p->vCos, i+(p)->nTruePos)), 1); i++ ) -#define Nwk_ManForEachLiLoSeq( p, pObjLi, pObjLo, i ) \ - for ( i = 0; (i < (p)->nLatches) && (((pObjLi) = Nwk_ManCo(p, i+(p)->nTruePos)), 1) \ - && (((pObjLo) = Nwk_ManCi(p, i+(p)->nTruePis)), 1); i++ ) - - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -/*=== nwkCheck.c ==========================================================*/ -extern int Nwk_ManCheck( Nwk_Man_t * p ); -/*=== nwkDfs.c ==========================================================*/ -extern int Nwk_ManVerifyTopoOrder( Nwk_Man_t * pNtk ); -extern int Nwk_ManLevelBackup( Nwk_Man_t * pNtk ); -extern int Nwk_ManLevel( Nwk_Man_t * pNtk ); -extern int Nwk_ManLevelMax( Nwk_Man_t * pNtk ); -extern Vec_Vec_t * Nwk_ManLevelize( Nwk_Man_t * pNtk ); -extern Vec_Ptr_t * Nwk_ManDfs( Nwk_Man_t * pNtk ); -extern Vec_Ptr_t * Nwk_ManDfsNodes( Nwk_Man_t * pNtk, Nwk_Obj_t ** ppNodes, int nNodes ); -extern Vec_Ptr_t * Nwk_ManDfsReverse( Nwk_Man_t * pNtk ); -extern Vec_Ptr_t * Nwk_ManSupportNodes( Nwk_Man_t * pNtk, Nwk_Obj_t ** ppNodes, int nNodes ); -extern void Nwk_ManSupportSum( Nwk_Man_t * pNtk ); -extern int Nwk_ObjMffcLabel( Nwk_Obj_t * pNode ); -/*=== nwkFanio.c ==========================================================*/ -extern void Nwk_ObjCollectFanins( Nwk_Obj_t * pNode, Vec_Ptr_t * vNodes ); -extern void Nwk_ObjCollectFanouts( Nwk_Obj_t * pNode, Vec_Ptr_t * vNodes ); -extern int Nwk_ObjFindFanin( Nwk_Obj_t * pObj, Nwk_Obj_t * pFanin ); -extern int Nwk_ObjFindFanout( Nwk_Obj_t * pObj, Nwk_Obj_t * pFanout ); -extern void Nwk_ObjAddFanin( Nwk_Obj_t * pObj, Nwk_Obj_t * pFanin ); -extern void Nwk_ObjDeleteFanin( Nwk_Obj_t * pObj, Nwk_Obj_t * pFanin ); -extern void Nwk_ObjPatchFanin( Nwk_Obj_t * pObj, Nwk_Obj_t * pFaninOld, Nwk_Obj_t * pFaninNew ); -extern void Nwk_ObjTransferFanout( Nwk_Obj_t * pNodeFrom, Nwk_Obj_t * pNodeTo ); -extern void Nwk_ObjReplace( Nwk_Obj_t * pNodeOld, Nwk_Obj_t * pNodeNew ); -/*=== nwkMan.c ============================================================*/ -extern Nwk_Man_t * Nwk_ManAlloc(); -extern void Nwk_ManFree( Nwk_Man_t * p ); -//extern void Nwk_ManPrintStats( Nwk_Man_t * p, If_Lib_t * pLutLib, int fSaveBest, int fDumpResult, int fPower, void * pNtl ); -/*=== nwkObj.c ============================================================*/ -extern Nwk_Obj_t * Nwk_ManCreateCi( Nwk_Man_t * pMan, int nFanouts ); -extern Nwk_Obj_t * Nwk_ManCreateCo( Nwk_Man_t * pMan ); -extern Nwk_Obj_t * Nwk_ManCreateNode( Nwk_Man_t * pMan, int nFanins, int nFanouts ); -extern Nwk_Obj_t * Nwk_ManCreateBox( Nwk_Man_t * pMan, int nFanins, int nFanouts ); -extern Nwk_Obj_t * Nwk_ManCreateLatch( Nwk_Man_t * pMan ); -extern void Nwk_ManDeleteNode( Nwk_Obj_t * pObj ); -extern void Nwk_ManDeleteNode_rec( Nwk_Obj_t * pObj ); -/*=== nwkUtil.c ============================================================*/ -extern void Nwk_ManIncrementTravId( Nwk_Man_t * pNtk ); -extern int Nwk_ManGetFaninMax( Nwk_Man_t * pNtk ); -extern int Nwk_ManGetTotalFanins( Nwk_Man_t * pNtk ); -extern int Nwk_ManPiNum( Nwk_Man_t * pNtk ); -extern int Nwk_ManPoNum( Nwk_Man_t * pNtk ); -extern int Nwk_ManGetAigNodeNum( Nwk_Man_t * pNtk ); -extern int Nwk_NodeCompareLevelsIncrease( Nwk_Obj_t ** pp1, Nwk_Obj_t ** pp2 ); -extern int Nwk_NodeCompareLevelsDecrease( Nwk_Obj_t ** pp1, Nwk_Obj_t ** pp2 ); -extern void Nwk_ObjPrint( Nwk_Obj_t * pObj ); -extern void Nwk_ManDumpBlif( Nwk_Man_t * pNtk, char * pFileName, Vec_Ptr_t * vCiNames, Vec_Ptr_t * vCoNames ); -extern void Nwk_ManPrintFanioNew( Nwk_Man_t * pNtk ); -extern void Nwk_ManCleanMarks( Nwk_Man_t * pNtk ); -extern void Nwk_ManMinimumBase( Nwk_Man_t * pNtk, int fVerbose ); - -#ifdef __cplusplus -} -#endif - -#endif - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - diff --git a/src/aig/nwk2/nwkCheck.c b/src/aig/nwk2/nwkCheck.c deleted file mode 100644 index 6922e439..00000000 --- a/src/aig/nwk2/nwkCheck.c +++ /dev/null @@ -1,73 +0,0 @@ -/**CFile**************************************************************** - - FileName [nwkCheck.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Logic network representation.] - - Synopsis [Consistency checking procedures.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: nwkCheck.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "nwk.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Checking the logic network for consistency.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Nwk_ManCheck( Nwk_Man_t * p ) -{ - Nwk_Obj_t * pObj; - int i, k, m; - // check if the nodes have duplicated fanins - Nwk_ManForEachNode( p, pObj, i ) - { - for ( k = 0; k < pObj->nFanins; k++ ) - for ( m = k + 1; m < pObj->nFanins; m++ ) - if ( pObj->pFanio[k] == pObj->pFanio[m] ) - printf( "Node %d has duplicated fanin %d.\n", pObj->Id, pObj->pFanio[k]->Id ); - } -/* - // check if all nodes are in the correct fanin/fanout relationship - Nwk_ManForEachObj( p, pObj, i ) - { - Nwk_ObjForEachFanin( pObj, pNext, k ) - if ( Nwk_ObjFindFanout( pNext, pObj ) == -1 ) - printf( "Nwk_ManCheck(): Object %d has fanin %d which does not have a corresponding fanout.\n", pObj->Id, pNext->Id ); - Nwk_ObjForEachFanout( pObj, pNext, k ) - if ( Nwk_ObjFindFanin( pNext, pObj ) == -1 ) - printf( "Nwk_ManCheck(): Object %d has fanout %d which does not have a corresponding fanin.\n", pObj->Id, pNext->Id ); - } -*/ - return 1; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/nwk2/nwkDfs.c b/src/aig/nwk2/nwkDfs.c deleted file mode 100644 index c1c77349..00000000 --- a/src/aig/nwk2/nwkDfs.c +++ /dev/null @@ -1,659 +0,0 @@ -/**CFile**************************************************************** - - FileName [nwkDfs.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Logic network representation.] - - Synopsis [DFS traversals.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: nwkDfs.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "nwk.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Verifies that the objects are in a topo order.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Nwk_ManVerifyTopoOrder( Nwk_Man_t * pNtk ) -{ - Nwk_Obj_t * pObj, * pNext; - int i, k, iBox, iTerm1, nTerms; - Nwk_ManIncrementTravId( pNtk ); - Nwk_ManForEachObj( pNtk, pObj, i ) - { - if ( Nwk_ObjIsNode(pObj) || Nwk_ObjIsCo(pObj) ) - { - Nwk_ObjForEachFanin( pObj, pNext, k ) - { - if ( !Nwk_ObjIsTravIdCurrent(pNext) ) - { - printf( "Node %d has fanin %d that is not in a topological order.\n", pObj->Id, pNext->Id ); - return 0; - } - } - } - else if ( Nwk_ObjIsCi(pObj) ) - { - if ( pNtk->pManTime ) - { - iBox = Tim_ManBoxForCi( pNtk->pManTime, pObj->PioId ); - if ( iBox >= 0 ) // this is not a true PI - { - iTerm1 = Tim_ManBoxInputFirst( pNtk->pManTime, iBox ); - nTerms = Tim_ManBoxInputNum( pNtk->pManTime, iBox ); - for ( k = 0; k < nTerms; k++ ) - { - pNext = Nwk_ManCo( pNtk, iTerm1 + k ); - if ( !Nwk_ObjIsTravIdCurrent(pNext) ) - { - printf( "Box %d has input %d that is not in a topological order.\n", iBox, pNext->Id ); - return 0; - } - } - } - } - } - else - assert( 0 ); - Nwk_ObjSetTravIdCurrent( pObj ); - } - return 1; -} - -/**Function************************************************************* - - Synopsis [Computes the number of logic levels not counting PIs/POs.] - - Description [Assumes that white boxes have unit level.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Nwk_ManLevelBackup( Nwk_Man_t * pNtk ) -{ - Tim_Man_t * pManTimeUnit; - Nwk_Obj_t * pObj, * pFanin; - int i, k, LevelMax, Level; - assert( Nwk_ManVerifyTopoOrder(pNtk) ); - // clean the levels - Nwk_ManForEachObj( pNtk, pObj, i ) - Nwk_ObjSetLevel( pObj, 0 ); - // perform level computation - LevelMax = 0; - pManTimeUnit = pNtk->pManTime ? Tim_ManDupUnit( pNtk->pManTime ) : NULL; - if ( pManTimeUnit ) - Tim_ManIncrementTravId( pManTimeUnit ); - Nwk_ManForEachObj( pNtk, pObj, i ) - { - if ( Nwk_ObjIsCi(pObj) ) - { - Level = pManTimeUnit? (int)Tim_ManGetCiArrival( pManTimeUnit, pObj->PioId ) : 0; - Nwk_ObjSetLevel( pObj, Level ); - } - else if ( Nwk_ObjIsCo(pObj) ) - { - Level = Nwk_ObjLevel( Nwk_ObjFanin0(pObj) ); - if ( pManTimeUnit ) - Tim_ManSetCoArrival( pManTimeUnit, pObj->PioId, (float)Level ); - Nwk_ObjSetLevel( pObj, Level ); - if ( LevelMax < Nwk_ObjLevel(pObj) ) - LevelMax = Nwk_ObjLevel(pObj); - } - else if ( Nwk_ObjIsNode(pObj) ) - { - Level = 0; - Nwk_ObjForEachFanin( pObj, pFanin, k ) - if ( Level < Nwk_ObjLevel(pFanin) ) - Level = Nwk_ObjLevel(pFanin); - Nwk_ObjSetLevel( pObj, Level + 1 ); - } - else - assert( 0 ); - } - // set the old timing manager - if ( pManTimeUnit ) - Tim_ManStop( pManTimeUnit ); - return LevelMax; -} - -/**Function************************************************************* - - Synopsis [Computes the number of logic levels not counting PIs/POs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Nwk_ManLevel_rec( Nwk_Obj_t * pObj ) -{ - Tim_Man_t * pManTime = pObj->pMan->pManTime; - Nwk_Obj_t * pNext; - int i, iBox, iTerm1, nTerms, LevelMax = 0; - if ( Nwk_ObjIsTravIdCurrent( pObj ) ) - return; - Nwk_ObjSetTravIdCurrent( pObj ); - if ( Nwk_ObjIsCi(pObj) ) - { - if ( pManTime ) - { - iBox = Tim_ManBoxForCi( pManTime, pObj->PioId ); - if ( iBox >= 0 ) // this is not a true PI - { - iTerm1 = Tim_ManBoxInputFirst( pManTime, iBox ); - nTerms = Tim_ManBoxInputNum( pManTime, iBox ); - for ( i = 0; i < nTerms; i++ ) - { - pNext = Nwk_ManCo(pObj->pMan, iTerm1 + i); - Nwk_ManLevel_rec( pNext ); - if ( LevelMax < Nwk_ObjLevel(pNext) ) - LevelMax = Nwk_ObjLevel(pNext); - } - LevelMax++; - } - } - } - else if ( Nwk_ObjIsNode(pObj) || Nwk_ObjIsCo(pObj) ) - { - Nwk_ObjForEachFanin( pObj, pNext, i ) - { - Nwk_ManLevel_rec( pNext ); - if ( LevelMax < Nwk_ObjLevel(pNext) ) - LevelMax = Nwk_ObjLevel(pNext); - } - if ( Nwk_ObjIsNode(pObj) && Nwk_ObjFaninNum(pObj) > 0 ) - LevelMax++; - } - else - assert( 0 ); - Nwk_ObjSetLevel( pObj, LevelMax ); -} - -/**Function************************************************************* - - Synopsis [Computes the number of logic levels not counting PIs/POs.] - - Description [Does not assume that the objects are in a topo order.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Nwk_ManLevel( Nwk_Man_t * pNtk ) -{ - Nwk_Obj_t * pObj; - int i, LevelMax = 0; - Nwk_ManForEachObj( pNtk, pObj, i ) - Nwk_ObjSetLevel( pObj, 0 ); - Nwk_ManIncrementTravId( pNtk ); - Nwk_ManForEachPo( pNtk, pObj, i ) - { - Nwk_ManLevel_rec( pObj ); - if ( LevelMax < Nwk_ObjLevel(pObj) ) - LevelMax = Nwk_ObjLevel(pObj); - } - Nwk_ManForEachCi( pNtk, pObj, i ) - { - Nwk_ManLevel_rec( pObj ); - if ( LevelMax < Nwk_ObjLevel(pObj) ) - LevelMax = Nwk_ObjLevel(pObj); - } - return LevelMax; -} - -/**Function************************************************************* - - Synopsis [Computes the number of logic levels not counting PIs/POs.] - - Description [Does not assume that the objects are in a topo order.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Nwk_ManLevelMax( Nwk_Man_t * pNtk ) -{ - Nwk_Obj_t * pObj; - int i, LevelMax = 0; - Nwk_ManForEachPo( pNtk, pObj, i ) - if ( LevelMax < Nwk_ObjLevel(pObj) ) - LevelMax = Nwk_ObjLevel(pObj); - return LevelMax; -} - -/**Function************************************************************* - - Synopsis [Returns the array of objects in the AIG manager ordered by level.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Vec_t * Nwk_ManLevelize( Nwk_Man_t * pNtk ) -{ - Nwk_Obj_t * pObj; - Vec_Vec_t * vLevels; - int nLevels, i; -// assert( Nwk_ManVerifyLevel(pNtk) ); - nLevels = Nwk_ManLevelMax( pNtk ); - vLevels = Vec_VecStart( nLevels + 1 ); - Nwk_ManForEachNode( pNtk, pObj, i ) - { - assert( Nwk_ObjLevel(pObj) <= nLevels ); - Vec_VecPush( vLevels, Nwk_ObjLevel(pObj), pObj ); - } - return vLevels; -} - - - -/**Function************************************************************* - - Synopsis [Performs DFS for one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Nwk_ManDfs_rec( Nwk_Obj_t * pObj, Vec_Ptr_t * vNodes ) -{ - Nwk_Obj_t * pNext; - int i; - if ( Nwk_ObjIsTravIdCurrent( pObj ) ) - return; - Nwk_ObjSetTravIdCurrent( pObj ); - Nwk_ObjForEachFanin( pObj, pNext, i ) - Nwk_ManDfs_rec( pNext, vNodes ); - Vec_PtrPush( vNodes, pObj ); -} - -/**Function************************************************************* - - Synopsis [Returns the DFS ordered array of all objects except latches.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Nwk_ManDfs( Nwk_Man_t * pNtk ) -{ - Vec_Ptr_t * vNodes; - Nwk_Obj_t * pObj; - int i; - Nwk_ManIncrementTravId( pNtk ); - vNodes = Vec_PtrAlloc( 100 ); - Nwk_ManForEachObj( pNtk, pObj, i ) - { - if ( Nwk_ObjIsCi(pObj) ) - { - Nwk_ObjSetTravIdCurrent( pObj ); - Vec_PtrPush( vNodes, pObj ); - } - else if ( Nwk_ObjIsCo(pObj) ) - Nwk_ManDfs_rec( pObj, vNodes ); - } - return vNodes; -} - -/**Function************************************************************* - - Synopsis [Performs DFS for one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Nwk_ManDfsNodes_rec( Nwk_Obj_t * pObj, Vec_Ptr_t * vNodes ) -{ - Nwk_Obj_t * pNext; - int i; - if ( Nwk_ObjIsTravIdCurrent( pObj ) ) - return; - Nwk_ObjSetTravIdCurrent( pObj ); - if ( Nwk_ObjIsCi(pObj) ) - return; - assert( Nwk_ObjIsNode(pObj) ); - Nwk_ObjForEachFanin( pObj, pNext, i ) - Nwk_ManDfsNodes_rec( pNext, vNodes ); - Vec_PtrPush( vNodes, pObj ); -} - -/**Function************************************************************* - - Synopsis [Returns the set of internal nodes rooted in the given nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Nwk_ManDfsNodes( Nwk_Man_t * pNtk, Nwk_Obj_t ** ppNodes, int nNodes ) -{ - Vec_Ptr_t * vNodes; - int i; - // set the traversal ID - Nwk_ManIncrementTravId( pNtk ); - // start the array of nodes - vNodes = Vec_PtrAlloc( 100 ); - // go through the PO nodes and call for each of them - for ( i = 0; i < nNodes; i++ ) - if ( Nwk_ObjIsCo(ppNodes[i]) ) - Nwk_ManDfsNodes_rec( Nwk_ObjFanin0(ppNodes[i]), vNodes ); - else - Nwk_ManDfsNodes_rec( ppNodes[i], vNodes ); - return vNodes; -} - -/**Function************************************************************* - - Synopsis [Performs DFS for one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Nwk_ManDfsReverse_rec( Nwk_Obj_t * pObj, Vec_Ptr_t * vNodes ) -{ - Nwk_Obj_t * pNext; - int i, iBox, iTerm1, nTerms; - if ( Nwk_ObjIsTravIdCurrent( pObj ) ) - return; - Nwk_ObjSetTravIdCurrent( pObj ); - if ( Nwk_ObjIsCo(pObj) ) - { - if ( pObj->pMan->pManTime ) - { - iBox = Tim_ManBoxForCo( pObj->pMan->pManTime, pObj->PioId ); - if ( iBox >= 0 ) // this is not a true PO - { - iTerm1 = Tim_ManBoxOutputFirst( pObj->pMan->pManTime, iBox ); - nTerms = Tim_ManBoxOutputNum( pObj->pMan->pManTime, iBox ); - for ( i = 0; i < nTerms; i++ ) - { - pNext = Nwk_ManCi(pObj->pMan, iTerm1 + i); - Nwk_ManDfsReverse_rec( pNext, vNodes ); - } - } - } - } - else if ( Nwk_ObjIsNode(pObj) || Nwk_ObjIsCi(pObj) ) - { - Nwk_ObjForEachFanout( pObj, pNext, i ) - Nwk_ManDfsReverse_rec( pNext, vNodes ); - } - else - assert( 0 ); - Vec_PtrPush( vNodes, pObj ); -} - -/**Function************************************************************* - - Synopsis [Returns the DFS ordered array of all objects except latches.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Nwk_ManDfsReverse( Nwk_Man_t * pNtk ) -{ - Vec_Ptr_t * vNodes; - Nwk_Obj_t * pObj; - int i; - Nwk_ManIncrementTravId( pNtk ); - vNodes = Vec_PtrAlloc( 100 ); - Nwk_ManForEachPi( pNtk, pObj, i ) - Nwk_ManDfsReverse_rec( pObj, vNodes ); - // add nodes without fanins - Nwk_ManForEachNode( pNtk, pObj, i ) - if ( Nwk_ObjFaninNum(pObj) == 0 && !Nwk_ObjIsTravIdCurrent(pObj) ) - Vec_PtrPush( vNodes, pObj ); - return vNodes; -} - -/**Function************************************************************* - - Synopsis [Performs DFS for one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Nwk_ManSupportNodes_rec( Nwk_Obj_t * pNode, Vec_Ptr_t * vNodes ) -{ - Nwk_Obj_t * pFanin; - int i; - // if this node is already visited, skip - if ( Nwk_ObjIsTravIdCurrent( pNode ) ) - return; - // mark the node as visited - Nwk_ObjSetTravIdCurrent( pNode ); - // collect the CI - if ( Nwk_ObjIsCi(pNode) ) - { - Vec_PtrPush( vNodes, pNode ); - return; - } - assert( Nwk_ObjIsNode( pNode ) ); - // visit the transitive fanin of the node - Nwk_ObjForEachFanin( pNode, pFanin, i ) - Nwk_ManSupportNodes_rec( pFanin, vNodes ); -} - -/**Function************************************************************* - - Synopsis [Returns the set of CI nodes in the support of the given nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Nwk_ManSupportNodes( Nwk_Man_t * pNtk, Nwk_Obj_t ** ppNodes, int nNodes ) -{ - Vec_Ptr_t * vNodes; - int i; - // set the traversal ID - Nwk_ManIncrementTravId( pNtk ); - // start the array of nodes - vNodes = Vec_PtrAlloc( 100 ); - // go through the PO nodes and call for each of them - for ( i = 0; i < nNodes; i++ ) - if ( Nwk_ObjIsCo(ppNodes[i]) ) - Nwk_ManSupportNodes_rec( Nwk_ObjFanin0(ppNodes[i]), vNodes ); - else - Nwk_ManSupportNodes_rec( ppNodes[i], vNodes ); - return vNodes; -} - -/**Function************************************************************* - - Synopsis [Computes the sum total of supports of all outputs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Nwk_ManSupportSum( Nwk_Man_t * pNtk ) -{ - Vec_Ptr_t * vSupp; - Nwk_Obj_t * pObj; - int i, nTotalSupps = 0; - Nwk_ManForEachCo( pNtk, pObj, i ) - { - vSupp = Nwk_ManSupportNodes( pNtk, &pObj, 1 ); - nTotalSupps += Vec_PtrSize( vSupp ); - Vec_PtrFree( vSupp ); - } - printf( "Total supports = %d.\n", nTotalSupps ); -} - - -/**Function************************************************************* - - Synopsis [Dereferences the node's MFFC.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Nwk_ObjDeref_rec( Nwk_Obj_t * pNode ) -{ - Nwk_Obj_t * pFanin; - int i, Counter = 1; - if ( Nwk_ObjIsCi(pNode) ) - return 0; - Nwk_ObjForEachFanin( pNode, pFanin, i ) - { - assert( pFanin->nFanouts > 0 ); - if ( --pFanin->nFanouts == 0 ) - Counter += Nwk_ObjDeref_rec( pFanin ); - } - return Counter; -} - -/**Function************************************************************* - - Synopsis [References the node's MFFC.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Nwk_ObjRef_rec( Nwk_Obj_t * pNode ) -{ - Nwk_Obj_t * pFanin; - int i, Counter = 1; - if ( Nwk_ObjIsCi(pNode) ) - return 0; - Nwk_ObjForEachFanin( pNode, pFanin, i ) - { - if ( pFanin->nFanouts++ == 0 ) - Counter += Nwk_ObjRef_rec( pFanin ); - } - return Counter; -} - -/**Function************************************************************* - - Synopsis [Collects the internal and boundary nodes in the derefed MFFC.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Nwk_ObjMffcLabel_rec( Nwk_Obj_t * pNode, int fTopmost ) -{ - Nwk_Obj_t * pFanin; - int i; - // add to the new support nodes - if ( !fTopmost && (Nwk_ObjIsCi(pNode) || pNode->nFanouts > 0) ) - return; - // skip visited nodes - if ( Nwk_ObjIsTravIdCurrent(pNode) ) - return; - Nwk_ObjSetTravIdCurrent(pNode); - // recur on the children - Nwk_ObjForEachFanin( pNode, pFanin, i ) - Nwk_ObjMffcLabel_rec( pFanin, 0 ); - // collect the internal node -// printf( "%d ", pNode->Id ); -} - -/**Function************************************************************* - - Synopsis [Collects the internal nodes of the MFFC limited by cut.] - - Description [] - - SideEffects [Increments the trav ID and marks visited nodes.] - - SeeAlso [] - -***********************************************************************/ -int Nwk_ObjMffcLabel( Nwk_Obj_t * pNode ) -{ - int Count1, Count2; - // dereference the node - Count1 = Nwk_ObjDeref_rec( pNode ); - // collect the nodes inside the MFFC - Nwk_ManIncrementTravId( pNode->pMan ); - Nwk_ObjMffcLabel_rec( pNode, 1 ); - // reference it back - Count2 = Nwk_ObjRef_rec( pNode ); - assert( Count1 == Count2 ); - return Count1; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/nwk2/nwkFanio.c b/src/aig/nwk2/nwkFanio.c deleted file mode 100644 index 30037a83..00000000 --- a/src/aig/nwk2/nwkFanio.c +++ /dev/null @@ -1,309 +0,0 @@ -/**CFile**************************************************************** - - FileName [nwkFanio.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Logic network representation.] - - Synopsis [Manipulation of fanins/fanouts.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: nwkFanio.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "nwk.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Collects fanins of the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Nwk_ObjCollectFanins( Nwk_Obj_t * pNode, Vec_Ptr_t * vNodes ) -{ - Nwk_Obj_t * pFanin; - int i; - Vec_PtrClear(vNodes); - Nwk_ObjForEachFanin( pNode, pFanin, i ) - Vec_PtrPush( vNodes, pFanin ); -} - -/**Function************************************************************* - - Synopsis [Collects fanouts of the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Nwk_ObjCollectFanouts( Nwk_Obj_t * pNode, Vec_Ptr_t * vNodes ) -{ - Nwk_Obj_t * pFanout; - int i; - Vec_PtrClear(vNodes); - Nwk_ObjForEachFanout( pNode, pFanout, i ) - Vec_PtrPush( vNodes, pFanout ); -} - -/**Function************************************************************* - - Synopsis [Returns the number of the fanin of the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Nwk_ObjFindFanin( Nwk_Obj_t * pObj, Nwk_Obj_t * pFanin ) -{ - Nwk_Obj_t * pTemp; - int i; - Nwk_ObjForEachFanin( pObj, pTemp, i ) - if ( pTemp == pFanin ) - return i; - return -1; -} - -/**Function************************************************************* - - Synopsis [Returns the number of the fanout of the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Nwk_ObjFindFanout( Nwk_Obj_t * pObj, Nwk_Obj_t * pFanout ) -{ - Nwk_Obj_t * pTemp; - int i; - Nwk_ObjForEachFanout( pObj, pTemp, i ) - if ( pTemp == pFanout ) - return i; - return -1; -} - -/**Function************************************************************* - - Synopsis [Returns 1 if the node has to be reallocated.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Nwk_ObjReallocIsNeeded( Nwk_Obj_t * pObj ) -{ - return pObj->nFanins + pObj->nFanouts == pObj->nFanioAlloc; -} - -/**Function************************************************************* - - Synopsis [Reallocates the object.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static Nwk_Obj_t * Nwk_ManReallocNode( Nwk_Obj_t * pObj ) -{ - Nwk_Obj_t ** pFanioOld = pObj->pFanio; - assert( Nwk_ObjReallocIsNeeded(pObj) ); - pObj->pFanio = (Nwk_Obj_t **)Aig_MmFlexEntryFetch( pObj->pMan->pMemObjs, 2 * pObj->nFanioAlloc * sizeof(Nwk_Obj_t *) ); - memmove( pObj->pFanio, pFanioOld, pObj->nFanioAlloc * sizeof(Nwk_Obj_t *) ); - pObj->nFanioAlloc *= 2; - pObj->pMan->nRealloced++; - return NULL; -} - -/**Function************************************************************* - - Synopsis [Creates fanout/fanin relationship between the nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Nwk_ObjAddFanin( Nwk_Obj_t * pObj, Nwk_Obj_t * pFanin ) -{ - int i; - assert( pObj->pMan == pFanin->pMan ); - assert( pObj->Id >= 0 && pFanin->Id >= 0 ); - if ( Nwk_ObjReallocIsNeeded(pObj) ) - Nwk_ManReallocNode( pObj ); - if ( Nwk_ObjReallocIsNeeded(pFanin) ) - Nwk_ManReallocNode( pFanin ); - for ( i = pObj->nFanins + pObj->nFanouts; i > pObj->nFanins; i-- ) - pObj->pFanio[i] = pObj->pFanio[i-1]; - pObj->pFanio[pObj->nFanins++] = pFanin; - pFanin->pFanio[pFanin->nFanins + pFanin->nFanouts++] = pObj; - pObj->Level = ABC_MAX( pObj->Level, pFanin->Level + Nwk_ObjIsNode(pObj) ); -} - -/**Function************************************************************* - - Synopsis [Removes fanout/fanin relationship between the nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Nwk_ObjDeleteFanin( Nwk_Obj_t * pObj, Nwk_Obj_t * pFanin ) -{ - int i, k, Limit; - // remove pFanin from the fanin list of pObj - Limit = pObj->nFanins + pObj->nFanouts; - for ( k = i = 0; i < Limit; i++ ) - if ( pObj->pFanio[i] != pFanin ) - pObj->pFanio[k++] = pObj->pFanio[i]; - assert( i == k + 1 ); // if it fails, likely because of duplicated fanin - pObj->nFanins--; - // remove pObj from the fanout list of pFanin - Limit = pFanin->nFanins + pFanin->nFanouts; - for ( k = i = pFanin->nFanins; i < Limit; i++ ) - if ( pFanin->pFanio[i] != pObj ) - pFanin->pFanio[k++] = pFanin->pFanio[i]; - assert( i == k + 1 ); // if it fails, likely because of duplicated fanout - pFanin->nFanouts--; -} - -/**Function************************************************************* - - Synopsis [Replaces a fanin of the node.] - - Description [The node is pObj. An old fanin of this node (pFaninOld) has to be - replaced by a new fanin (pFaninNew). Assumes that the node and the old fanin - are not complemented. The new fanin can be complemented. In this case, the - polarity of the new fanin will change, compared to the polarity of the old fanin.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Nwk_ObjPatchFanin( Nwk_Obj_t * pObj, Nwk_Obj_t * pFaninOld, Nwk_Obj_t * pFaninNew ) -{ - int i, k, iFanin, Limit; - assert( pFaninOld != pFaninNew ); - assert( pObj != pFaninOld ); - assert( pObj != pFaninNew ); - assert( pObj->pMan == pFaninOld->pMan ); - assert( pObj->pMan == pFaninNew->pMan ); - // update the fanin - iFanin = Nwk_ObjFindFanin( pObj, pFaninOld ); - if ( iFanin == -1 ) - { - printf( "Nwk_ObjPatchFanin(); Error! Node %d is not among", pFaninOld->Id ); - printf( " the fanins of node %d...\n", pObj->Id ); - return; - } - pObj->pFanio[iFanin] = pFaninNew; - // remove pObj from the fanout list of pFaninOld - Limit = pFaninOld->nFanins + pFaninOld->nFanouts; - for ( k = i = pFaninOld->nFanins; i < Limit; i++ ) - if ( pFaninOld->pFanio[i] != pObj ) - pFaninOld->pFanio[k++] = pFaninOld->pFanio[i]; - pFaninOld->nFanouts--; - // add pObj to the fanout list of pFaninNew - if ( Nwk_ObjReallocIsNeeded(pFaninNew) ) - Nwk_ManReallocNode( pFaninNew ); - pFaninNew->pFanio[pFaninNew->nFanins + pFaninNew->nFanouts++] = pObj; -} - - -/**Function************************************************************* - - Synopsis [Transfers fanout from the old node to the new node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Nwk_ObjTransferFanout( Nwk_Obj_t * pNodeFrom, Nwk_Obj_t * pNodeTo ) -{ - Vec_Ptr_t * vFanouts = pNodeFrom->pMan->vTemp; - Nwk_Obj_t * pTemp; - int nFanoutsOld, i; - assert( !Nwk_ObjIsCo(pNodeFrom) && !Nwk_ObjIsCo(pNodeTo) ); - assert( pNodeFrom->pMan == pNodeTo->pMan ); - assert( pNodeFrom != pNodeTo ); - assert( Nwk_ObjFanoutNum(pNodeFrom) > 0 ); - // get the fanouts of the old node - nFanoutsOld = Nwk_ObjFanoutNum(pNodeTo); - Nwk_ObjCollectFanouts( pNodeFrom, vFanouts ); - // patch the fanin of each of them - Vec_PtrForEachEntry( vFanouts, pTemp, i ) - Nwk_ObjPatchFanin( pTemp, pNodeFrom, pNodeTo ); - assert( Nwk_ObjFanoutNum(pNodeFrom) == 0 ); - assert( Nwk_ObjFanoutNum(pNodeTo) == nFanoutsOld + Vec_PtrSize(vFanouts) ); -} - -/**Function************************************************************* - - Synopsis [Replaces the node by a new node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Nwk_ObjReplace( Nwk_Obj_t * pNodeOld, Nwk_Obj_t * pNodeNew ) -{ - assert( pNodeOld->pMan == pNodeNew->pMan ); - assert( pNodeOld != pNodeNew ); - assert( Nwk_ObjFanoutNum(pNodeOld) > 0 ); - // transfer the fanouts to the old node - Nwk_ObjTransferFanout( pNodeOld, pNodeNew ); - // remove the old node - Nwk_ManDeleteNode_rec( pNodeOld ); -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/nwk2/nwkMan.c b/src/aig/nwk2/nwkMan.c deleted file mode 100644 index cd73f866..00000000 --- a/src/aig/nwk2/nwkMan.c +++ /dev/null @@ -1,239 +0,0 @@ -/**CFile**************************************************************** - - FileName [nwkMan.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Logic network representation.] - - Synopsis [Network manager.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: nwkMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "nwk.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Allocates the manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Nwk_Man_t * Nwk_ManAlloc() -{ - Nwk_Man_t * p; - p = ALLOC( Nwk_Man_t, 1 ); - memset( p, 0, sizeof(Nwk_Man_t) ); - p->vCis = Vec_PtrAlloc( 1000 ); - p->vCos = Vec_PtrAlloc( 1000 ); - p->vObjs = Vec_PtrAlloc( 1000 ); - p->vTemp = Vec_PtrAlloc( 1000 ); - p->nFanioPlus = 2; - p->pMemObjs = Aig_MmFlexStart(); - p->pManHop = Hop_ManStart(); - return p; -} - -/**Function************************************************************* - - Synopsis [Deallocates the manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Nwk_ManFree( Nwk_Man_t * p ) -{ -// printf( "The number of realloced nodes = %d.\n", p->nRealloced ); - if ( p->pName ) free( p->pName ); - if ( p->pSpec ) free( p->pSpec ); - if ( p->vCis ) Vec_PtrFree( p->vCis ); - if ( p->vCos ) Vec_PtrFree( p->vCos ); - if ( p->vObjs ) Vec_PtrFree( p->vObjs ); - if ( p->vTemp ) Vec_PtrFree( p->vTemp ); - if ( p->pManTime ) Tim_ManStop( p->pManTime ); - if ( p->pMemObjs ) Aig_MmFlexStop( p->pMemObjs, 0 ); - if ( p->pManHop ) Hop_ManStop( p->pManHop ); - free( p ); -} - -/**Function************************************************************* - - Synopsis [Prints stats of the manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -/* -void Nwk_ManPrintLutSizes( Nwk_Man_t * p, If_Lib_t * pLutLib ) -{ - Nwk_Obj_t * pObj; - int i, Counters[256] = {0}; - Nwk_ManForEachNode( p, pObj, i ) - Counters[Nwk_ObjFaninNum(pObj)]++; - printf( "LUTs by size: " ); - for ( i = 0; i <= pLutLib->LutMax; i++ ) - printf( "%d:%d ", i, Counters[i] ); -} -*/ - -/**Function************************************************************* - - Synopsis [If the network is best, saves it in "best.blif" and returns 1.] - - Description [If the networks are incomparable, saves the new network, - returns its parameters in the internal parameter structure, and returns 1. - If the new network is not a logic network, quits without saving and returns 0.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Nwk_ManCompareAndSaveBest( Nwk_Man_t * pNtk, void * pNtl ) -{ - extern void Ioa_WriteBlifLogic( Nwk_Man_t * pNtk, void * pNtl, char * pFileName ); - extern void Nwk_ManDumpBlif( Nwk_Man_t * pNtk, char * pFileName, Vec_Ptr_t * vPiNames, Vec_Ptr_t * vPoNames ); - static struct ParStruct { - char * pName; // name of the best saved network - int Depth; // depth of the best saved network - int Flops; // flops in the best saved network - int Nodes; // nodes in the best saved network - int nPis; // the number of primary inputs - int nPos; // the number of primary outputs - } ParsNew, ParsBest = { 0 }; - // free storage for the name - if ( pNtk == NULL ) - { - FREE( ParsBest.pName ); - return 0; - } - // get the parameters - ParsNew.Depth = Nwk_ManLevel( pNtk ); - ParsNew.Flops = Nwk_ManLatchNum( pNtk ); - ParsNew.Nodes = Nwk_ManNodeNum( pNtk ); - ParsNew.nPis = Nwk_ManPiNum( pNtk ); - ParsNew.nPos = Nwk_ManPoNum( pNtk ); - // reset the parameters if the network has the same name - if ( ParsBest.pName == NULL || - strcmp(ParsBest.pName, pNtk->pName) || - ParsBest.Depth > ParsNew.Depth || - (ParsBest.Depth == ParsNew.Depth && ParsBest.Flops > ParsNew.Flops) || - (ParsBest.Depth == ParsNew.Depth && ParsBest.Flops == ParsNew.Flops && ParsBest.Nodes > ParsNew.Nodes) ) - { - FREE( ParsBest.pName ); - ParsBest.pName = Aig_UtilStrsav( pNtk->pName ); - ParsBest.Depth = ParsNew.Depth; - ParsBest.Flops = ParsNew.Flops; - ParsBest.Nodes = ParsNew.Nodes; - ParsBest.nPis = ParsNew.nPis; - ParsBest.nPos = ParsNew.nPos; - // write the network -// Ioa_WriteBlifLogic( pNtk, pNtl, "best.blif" ); -// Nwk_ManDumpBlif( pNtk, "best_map.blif", NULL, NULL ); - return 1; - } - return 0; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -char * Nwk_FileNameGeneric( char * FileName ) -{ - char * pDot, * pRes; - pRes = Aig_UtilStrsav( FileName ); - if ( (pDot = strrchr( pRes, '.' )) ) - *pDot = 0; - return pRes; -} - -/**Function************************************************************* - - Synopsis [Prints stats of the manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -/* -void Nwk_ManPrintStats( Nwk_Man_t * pNtk, If_Lib_t * pLutLib, int fSaveBest, int fDumpResult, int fPower, void * pNtl ) -{ - extern int Ntl_ManLatchNum( void * p ); - extern void Ioa_WriteBlifLogic( Nwk_Man_t * pNtk, void * pNtl, char * pFileName ); - if ( fSaveBest ) - Nwk_ManCompareAndSaveBest( pNtk, pNtl ); - if ( fDumpResult ) - { - char Buffer[1000] = {0}; - char * pNameGen = pNtk->pSpec? Nwk_FileNameGeneric( pNtk->pSpec ) : "nameless_"; - sprintf( Buffer, "%s_dump.blif", pNameGen ); - Ioa_WriteBlifLogic( pNtk, pNtl, Buffer ); -// sprintf( Buffer, "%s_dump_map.blif", pNameGen ); -// Nwk_ManDumpBlif( pNtk, Buffer, NULL, NULL ); - if ( pNtk->pSpec ) free( pNameGen ); - } - - pNtk->pLutLib = pLutLib; - printf( "%-15s : ", pNtk->pName ); - printf( "pi = %5d ", Nwk_ManPiNum(pNtk) ); - printf( "po = %5d ", Nwk_ManPoNum(pNtk) ); - printf( "ci = %5d ", Nwk_ManCiNum(pNtk) ); - printf( "co = %5d ", Nwk_ManCoNum(pNtk) ); - printf( "lat = %5d ", Ntl_ManLatchNum(pNtl) ); - printf( "node = %5d ", Nwk_ManNodeNum(pNtk) ); - printf( "edge = %5d ", Nwk_ManGetTotalFanins(pNtk) ); - printf( "aig = %6d ", Nwk_ManGetAigNodeNum(pNtk) ); - printf( "lev = %3d ", Nwk_ManLevel(pNtk) ); -// printf( "lev2 = %3d ", Nwk_ManLevelBackup(pNtk) ); - printf( "delay = %5.2f ", Nwk_ManDelayTraceLut(pNtk) ); - Nwk_ManPrintLutSizes( pNtk, pLutLib ); - printf( "\n" ); -// Nwk_ManDelayTracePrint( pNtk, pLutLib ); - fflush( stdout ); -} -*/ - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/nwk2/nwkMerge.c b/src/aig/nwk2/nwkMerge.c deleted file mode 100644 index 1a5255d3..00000000 --- a/src/aig/nwk2/nwkMerge.c +++ /dev/null @@ -1,993 +0,0 @@ -/**CFile**************************************************************** - - FileName [nwkMerge.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Netlist representation.] - - Synopsis [LUT merging algorithm.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: nwkMerge.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "nwk.h" -#include "nwkMerge.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Allocates the graph.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Nwk_Grf_t * Nwk_ManGraphAlloc( int nVertsMax ) -{ - Nwk_Grf_t * p; - p = ALLOC( Nwk_Grf_t, 1 ); - memset( p, 0, sizeof(Nwk_Grf_t) ); - p->nVertsMax = nVertsMax; - p->nEdgeHash = Aig_PrimeCudd( 3 * nVertsMax ); - p->pEdgeHash = CALLOC( Nwk_Edg_t *, p->nEdgeHash ); - p->pMemEdges = Aig_MmFixedStart( sizeof(Nwk_Edg_t), p->nEdgeHash ); - p->vPairs = Vec_IntAlloc( 1000 ); - return p; -} - -/**Function************************************************************* - - Synopsis [Deallocates the graph.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Nwk_ManGraphFree( Nwk_Grf_t * p ) -{ - if ( p->vPairs ) Vec_IntFree( p->vPairs ); - if ( p->pMemEdges ) Aig_MmFixedStop( p->pMemEdges, 0 ); - if ( p->pMemVerts ) Aig_MmFlexStop( p->pMemVerts, 0 ); - FREE( p->pVerts ); - FREE( p->pEdgeHash ); - FREE( p->pMapLut2Id ); - FREE( p->pMapId2Lut ); - free( p ); -} - -/**Function************************************************************* - - Synopsis [Prepares the graph for solving the problem.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Nwk_ManGraphReportMemoryUsage( Nwk_Grf_t * p ) -{ - p->nMemBytes1 = - sizeof(Nwk_Grf_t) + - sizeof(void *) * p->nEdgeHash + - sizeof(int) * (p->nObjs + p->nVertsMax) + - sizeof(Nwk_Edg_t) * p->nEdges; - p->nMemBytes2 = - sizeof(Nwk_Vrt_t) * p->nVerts + - sizeof(int) * 2 * p->nEdges; - printf( "Memory usage stats: Preprocessing = %.2f Mb. Solving = %.2f Mb.\n", - 1.0 * p->nMemBytes1 / (1<<20), 1.0 * p->nMemBytes2 / (1<<20) ); -} - - -/**Function************************************************************* - - Synopsis [Finds or adds the edge to the graph.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Nwk_ManGraphHashEdge( Nwk_Grf_t * p, int iLut1, int iLut2 ) -{ - Nwk_Edg_t * pEntry; - unsigned Key; - if ( iLut1 == iLut2 ) - return; - if ( iLut1 > iLut2 ) - { - Key = iLut1; - iLut1 = iLut2; - iLut2 = Key; - } - assert( iLut1 < iLut2 ); - if ( p->nObjs < iLut2 ) - p->nObjs = iLut2; - Key = (unsigned)(741457 * iLut1 + 4256249 * iLut2) % p->nEdgeHash; - for ( pEntry = p->pEdgeHash[Key]; pEntry; pEntry = pEntry->pNext ) - if ( pEntry->iNode1 == iLut1 && pEntry->iNode2 == iLut2 ) - return; - pEntry = (Nwk_Edg_t *)Aig_MmFixedEntryFetch( p->pMemEdges ); - pEntry->iNode1 = iLut1; - pEntry->iNode2 = iLut2; - pEntry->pNext = p->pEdgeHash[Key]; - p->pEdgeHash[Key] = pEntry; - p->nEdges++; -} - -/**Function************************************************************* - - Synopsis [Adds one entry to the list.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Nwk_ManGraphListAdd( Nwk_Grf_t * p, int * pList, Nwk_Vrt_t * pVertex ) -{ - if ( *pList ) - { - Nwk_Vrt_t * pHead; - pHead = p->pVerts[*pList]; - pVertex->iPrev = 0; - pVertex->iNext = pHead->Id; - pHead->iPrev = pVertex->Id; - } - *pList = pVertex->Id; -} - -/**Function************************************************************* - - Synopsis [Deletes one entry from the list.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Nwk_ManGraphListDelete( Nwk_Grf_t * p, int * pList, Nwk_Vrt_t * pVertex ) -{ - assert( *pList ); - if ( pVertex->iPrev ) - { -// assert( p->pVerts[pVertex->iPrev]->iNext == pVertex->Id ); - p->pVerts[pVertex->iPrev]->iNext = pVertex->iNext; - } - if ( pVertex->iNext ) - { -// assert( p->pVerts[pVertex->iNext]->iPrev == pVertex->Id ); - p->pVerts[pVertex->iNext]->iPrev = pVertex->iPrev; - } - if ( *pList == pVertex->Id ) - *pList = pVertex->iNext; - pVertex->iPrev = pVertex->iNext = 0; -} - -/**Function************************************************************* - - Synopsis [Inserts the edge into one of the linked lists.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Nwk_ManGraphListInsert( Nwk_Grf_t * p, Nwk_Vrt_t * pVertex ) -{ - Nwk_Vrt_t * pNext; - assert( pVertex->nEdges > 0 ); - - if ( pVertex->nEdges == 1 ) - { - pNext = p->pVerts[ pVertex->pEdges[0] ]; - if ( pNext->nEdges >= NWK_MAX_LIST ) - Nwk_ManGraphListAdd( p, p->pLists1 + NWK_MAX_LIST, pVertex ); - else - Nwk_ManGraphListAdd( p, p->pLists1 + pNext->nEdges, pVertex ); - } - else - { - if ( pVertex->nEdges >= NWK_MAX_LIST ) - Nwk_ManGraphListAdd( p, p->pLists2 + NWK_MAX_LIST, pVertex ); - else - Nwk_ManGraphListAdd( p, p->pLists2 + pVertex->nEdges, pVertex ); - } -} - -/**Function************************************************************* - - Synopsis [Extracts the edge from one of the linked lists.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Nwk_ManGraphListExtract( Nwk_Grf_t * p, Nwk_Vrt_t * pVertex ) -{ - Nwk_Vrt_t * pNext; - assert( pVertex->nEdges > 0 ); - - if ( pVertex->nEdges == 1 ) - { - pNext = p->pVerts[ pVertex->pEdges[0] ]; - if ( pNext->nEdges >= NWK_MAX_LIST ) - Nwk_ManGraphListDelete( p, p->pLists1 + NWK_MAX_LIST, pVertex ); - else - Nwk_ManGraphListDelete( p, p->pLists1 + pNext->nEdges, pVertex ); - } - else - { - if ( pVertex->nEdges >= NWK_MAX_LIST ) - Nwk_ManGraphListDelete( p, p->pLists2 + NWK_MAX_LIST, pVertex ); - else - Nwk_ManGraphListDelete( p, p->pLists2 + pVertex->nEdges, pVertex ); - } -} - -/**Function************************************************************* - - Synopsis [Prepares the graph for solving the problem.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Nwk_ManGraphPrepare( Nwk_Grf_t * p ) -{ - Nwk_Edg_t * pEntry; - Nwk_Vrt_t * pVertex; - int * pnEdges, nBytes, i; - // allocate memory for the present objects - p->pMapLut2Id = ALLOC( int, p->nObjs+1 ); - p->pMapId2Lut = ALLOC( int, p->nVertsMax+1 ); - memset( p->pMapLut2Id, 0xff, sizeof(int) * (p->nObjs+1) ); - memset( p->pMapId2Lut, 0xff, sizeof(int) * (p->nVertsMax+1) ); - // mark present objects - Nwk_GraphForEachEdge( p, pEntry, i ) - { - assert( pEntry->iNode1 <= p->nObjs ); - assert( pEntry->iNode2 <= p->nObjs ); - p->pMapLut2Id[ pEntry->iNode1 ] = 0; - p->pMapLut2Id[ pEntry->iNode2 ] = 0; - } - // map objects - p->nVerts = 0; - for ( i = 0; i <= p->nObjs; i++ ) - { - if ( p->pMapLut2Id[i] == 0 ) - { - p->pMapLut2Id[i] = ++p->nVerts; - p->pMapId2Lut[p->nVerts] = i; - } - } - // count the edges and mark present objects - pnEdges = CALLOC( int, p->nVerts+1 ); - Nwk_GraphForEachEdge( p, pEntry, i ) - { - // translate into vertices - assert( pEntry->iNode1 <= p->nObjs ); - assert( pEntry->iNode2 <= p->nObjs ); - pEntry->iNode1 = p->pMapLut2Id[pEntry->iNode1]; - pEntry->iNode2 = p->pMapLut2Id[pEntry->iNode2]; - // count the edges - assert( pEntry->iNode1 <= p->nVerts ); - assert( pEntry->iNode2 <= p->nVerts ); - pnEdges[pEntry->iNode1]++; - pnEdges[pEntry->iNode2]++; - } - // allocate the real graph - p->pMemVerts = Aig_MmFlexStart(); - p->pVerts = ALLOC( Nwk_Vrt_t *, p->nVerts + 1 ); - p->pVerts[0] = NULL; - for ( i = 1; i <= p->nVerts; i++ ) - { - assert( pnEdges[i] > 0 ); - nBytes = sizeof(Nwk_Vrt_t) + sizeof(int) * pnEdges[i]; - p->pVerts[i] = (Nwk_Vrt_t *)Aig_MmFlexEntryFetch( p->pMemVerts, nBytes ); - memset( p->pVerts[i], 0, nBytes ); - p->pVerts[i]->Id = i; - } - // add edges to the real graph - Nwk_GraphForEachEdge( p, pEntry, i ) - { - pVertex = p->pVerts[pEntry->iNode1]; - pVertex->pEdges[ pVertex->nEdges++ ] = pEntry->iNode2; - pVertex = p->pVerts[pEntry->iNode2]; - pVertex->pEdges[ pVertex->nEdges++ ] = pEntry->iNode1; - } - // put vertices into the data structure - for ( i = 1; i <= p->nVerts; i++ ) - { - assert( p->pVerts[i]->nEdges == pnEdges[i] ); - Nwk_ManGraphListInsert( p, p->pVerts[i] ); - } - // clean up - Aig_MmFixedStop( p->pMemEdges, 0 ); p->pMemEdges = NULL; - FREE( p->pEdgeHash ); -// p->nEdgeHash = 0; - free( pnEdges ); -} - -/**Function************************************************************* - - Synopsis [Updates the problem after pulling out one edge.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Nwk_ManGraphCheckLists( Nwk_Grf_t * p ) -{ - Nwk_Vrt_t * pVertex, * pNext; - int i, j; - assert( p->pLists1[0] == 0 ); - for ( i = 1; i <= NWK_MAX_LIST; i++ ) - if ( p->pLists1[i] ) - { - pVertex = p->pVerts[ p->pLists1[i] ]; - assert( pVertex->nEdges == 1 ); - pNext = p->pVerts[ pVertex->pEdges[0] ]; - assert( pNext->nEdges == i || pNext->nEdges > NWK_MAX_LIST ); - } - // find the next vertext to extract - assert( p->pLists2[0] == 0 ); - assert( p->pLists2[1] == 0 ); - for ( j = 2; j <= NWK_MAX_LIST; j++ ) - if ( p->pLists2[j] ) - { - pVertex = p->pVerts[ p->pLists2[j] ]; - assert( pVertex->nEdges == j || pVertex->nEdges > NWK_MAX_LIST ); - } -} - -/**Function************************************************************* - - Synopsis [Extracts the edge from one of the linked lists.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Nwk_ManGraphVertexRemoveEdge( Nwk_Vrt_t * pThis, Nwk_Vrt_t * pNext ) -{ - int k; - for ( k = 0; k < pThis->nEdges; k++ ) - if ( pThis->pEdges[k] == pNext->Id ) - break; - assert( k < pThis->nEdges ); - pThis->nEdges--; - for ( ; k < pThis->nEdges; k++ ) - pThis->pEdges[k] = pThis->pEdges[k+1]; -} - -/**Function************************************************************* - - Synopsis [Updates the problem after pulling out one edge.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Nwk_ManGraphUpdate( Nwk_Grf_t * p, Nwk_Vrt_t * pVertex, Nwk_Vrt_t * pNext ) -{ - Nwk_Vrt_t * pChanged, * pOther; - int i, k; -// Nwk_ManGraphCheckLists( p ); - Nwk_ManGraphListExtract( p, pVertex ); - Nwk_ManGraphListExtract( p, pNext ); - // update neihbors of pVertex - Nwk_VertexForEachAdjacent( p, pVertex, pChanged, i ) - { - if ( pChanged == pNext ) - continue; - Nwk_ManGraphListExtract( p, pChanged ); - // move those that use this one - if ( pChanged->nEdges > 1 ) - Nwk_VertexForEachAdjacent( p, pChanged, pOther, k ) - { - if ( pOther == pVertex || pOther->nEdges > 1 ) - continue; - assert( pOther->nEdges == 1 ); - Nwk_ManGraphListExtract( p, pOther ); - pChanged->nEdges--; - Nwk_ManGraphListInsert( p, pOther ); - pChanged->nEdges++; - } - // remove the edge - Nwk_ManGraphVertexRemoveEdge( pChanged, pVertex ); - // add the changed vertex back - if ( pChanged->nEdges > 0 ) - Nwk_ManGraphListInsert( p, pChanged ); - } - // update neihbors of pNext - Nwk_VertexForEachAdjacent( p, pNext, pChanged, i ) - { - if ( pChanged == pVertex ) - continue; - Nwk_ManGraphListExtract( p, pChanged ); - // move those that use this one - if ( pChanged->nEdges > 1 ) - Nwk_VertexForEachAdjacent( p, pChanged, pOther, k ) - { - if ( pOther == pNext || pOther->nEdges > 1 ) - continue; - assert( pOther->nEdges == 1 ); - Nwk_ManGraphListExtract( p, pOther ); - pChanged->nEdges--; - Nwk_ManGraphListInsert( p, pOther ); - pChanged->nEdges++; - } - // remove the edge - Nwk_ManGraphVertexRemoveEdge( pChanged, pNext ); - // add the changed vertex back - if ( pChanged->nEdges > 0 ) - Nwk_ManGraphListInsert( p, pChanged ); - } - // add to the result - if ( pVertex->Id < pNext->Id ) - { - Vec_IntPush( p->vPairs, p->pMapId2Lut[pVertex->Id] ); - Vec_IntPush( p->vPairs, p->pMapId2Lut[pNext->Id] ); - } - else - { - Vec_IntPush( p->vPairs, p->pMapId2Lut[pNext->Id] ); - Vec_IntPush( p->vPairs, p->pMapId2Lut[pVertex->Id] ); - } -// Nwk_ManGraphCheckLists( p ); -} - -/**Function************************************************************* - - Synopsis [Counts the number of entries in the list.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Nwk_ManGraphListLength( Nwk_Grf_t * p, int List ) -{ - Nwk_Vrt_t * pThis; - int fVerbose = 0; - int Counter = 0; - Nwk_ListForEachVertex( p, List, pThis ) - { - if ( fVerbose && Counter < 20 ) - printf( "%d ", p->pVerts[pThis->pEdges[0]]->nEdges ); - Counter++; - } - if ( fVerbose ) - printf( "\n" ); - return Counter; -} - -/**Function************************************************************* - - Synopsis [Returns the adjacent vertex with the mininum number of edges.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Nwk_Vrt_t * Nwk_ManGraphListFindMinEdge( Nwk_Grf_t * p, Nwk_Vrt_t * pVert ) -{ - Nwk_Vrt_t * pThis, * pMinCost = NULL; - int k; - Nwk_VertexForEachAdjacent( p, pVert, pThis, k ) - { - if ( pMinCost == NULL || pMinCost->nEdges > pThis->nEdges ) - pMinCost = pThis; - } - return pMinCost; -} - -/**Function************************************************************* - - Synopsis [Finds the best vertext in the list.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Nwk_Vrt_t * Nwk_ManGraphListFindMin( Nwk_Grf_t * p, int List ) -{ - Nwk_Vrt_t * pThis, * pMinCost = NULL; - int k, Counter = 10000, BestCost = 1000000; - Nwk_ListForEachVertex( p, List, pThis ) - { - for ( k = 0; k < pThis->nEdges; k++ ) - { - if ( pMinCost == NULL || BestCost > p->pVerts[pThis->pEdges[k]]->nEdges ) - { - BestCost = p->pVerts[pThis->pEdges[k]]->nEdges; - pMinCost = pThis; - } - } - if ( --Counter == 0 ) - break; - } - return pMinCost; -} - -/**Function************************************************************* - - Synopsis [Solves the problem by extracting one edge at a time.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Nwk_ManGraphSolve( Nwk_Grf_t * p ) -{ - Nwk_Vrt_t * pVertex, * pNext; - int i, j; - Nwk_ManGraphPrepare( p ); - while ( 1 ) - { - // find the next vertex to extract - assert( p->pLists1[0] == 0 ); - for ( i = 1; i <= NWK_MAX_LIST; i++ ) - if ( p->pLists1[i] ) - { -// printf( "%d ", i ); -// printf( "ListA = %2d. Length = %5d.\n", i, Nwk_ManGraphListLength(p,p->pLists1[i]) ); - pVertex = p->pVerts[ p->pLists1[i] ]; - assert( pVertex->nEdges == 1 ); - pNext = p->pVerts[ pVertex->pEdges[0] ]; - Nwk_ManGraphUpdate( p, pVertex, pNext ); - break; - } - if ( i < NWK_MAX_LIST + 1 ) - continue; - // find the next vertex to extract - assert( p->pLists2[0] == 0 ); - assert( p->pLists2[1] == 0 ); - for ( j = 2; j <= NWK_MAX_LIST; j++ ) - if ( p->pLists2[j] ) - { -// printf( "***%d ", j ); -// printf( "ListB = %2d. Length = %5d.\n", j, Nwk_ManGraphListLength(p,p->pLists2[j]) ); - pVertex = Nwk_ManGraphListFindMin( p, p->pLists2[j] ); - assert( pVertex->nEdges == j || j == NWK_MAX_LIST ); - pNext = Nwk_ManGraphListFindMinEdge( p, pVertex ); - Nwk_ManGraphUpdate( p, pVertex, pNext ); - break; - } - if ( j == NWK_MAX_LIST + 1 ) - break; - } -} - -/**Function************************************************************* - - Synopsis [Reads graph from file.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Nwk_Grf_t * Nwk_ManLutMergeReadGraph( char * pFileName ) -{ - Nwk_Grf_t * p; - FILE * pFile; - char Buffer[100]; - int nNodes, nEdges, iNode1, iNode2; - pFile = fopen( pFileName, "r" ); - fscanf( pFile, "%s %d", Buffer, &nNodes ); - fscanf( pFile, "%s %d", Buffer, &nEdges ); - p = Nwk_ManGraphAlloc( nNodes ); - while ( fscanf( pFile, "%s %d %d", Buffer, &iNode1, &iNode2 ) == 3 ) - Nwk_ManGraphHashEdge( p, iNode1, iNode2 ); - assert( p->nEdges == nEdges ); - fclose( pFile ); - return p; -} - -/**Function************************************************************* - - Synopsis [Solves the graph coming from file.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Nwk_ManLutMergeGraphTest( char * pFileName ) -{ - int nPairs; - Nwk_Grf_t * p; - int clk = clock(); - p = Nwk_ManLutMergeReadGraph( pFileName ); - PRT( "Reading", clock() - clk ); - clk = clock(); - Nwk_ManGraphSolve( p ); - printf( "GRAPH: Nodes = %6d. Edges = %6d. Pairs = %6d. ", - p->nVerts, p->nEdges, Vec_IntSize(p->vPairs)/2 ); - PRT( "Solving", clock() - clk ); - nPairs = Vec_IntSize(p->vPairs)/2; - Nwk_ManGraphReportMemoryUsage( p ); - Nwk_ManGraphFree( p ); - return nPairs; -} - - - - -/**Function************************************************************* - - Synopsis [Marks the fanins of the node with the current trav ID.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Nwk_ManMarkFanins_rec( Nwk_Obj_t * pLut, int nLevMin ) -{ - Nwk_Obj_t * pNext; - int i; - if ( !Nwk_ObjIsNode(pLut) ) - return; - if ( Nwk_ObjIsTravIdCurrent( pLut ) ) - return; - Nwk_ObjSetTravIdCurrent( pLut ); - if ( Nwk_ObjLevel(pLut) < nLevMin ) - return; - Nwk_ObjForEachFanin( pLut, pNext, i ) - Nwk_ManMarkFanins_rec( pNext, nLevMin ); -} - -/**Function************************************************************* - - Synopsis [Marks the fanouts of the node with the current trav ID.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Nwk_ManMarkFanouts_rec( Nwk_Obj_t * pLut, int nLevMax, int nFanMax ) -{ - Nwk_Obj_t * pNext; - int i; - if ( !Nwk_ObjIsNode(pLut) ) - return; - if ( Nwk_ObjIsTravIdCurrent( pLut ) ) - return; - Nwk_ObjSetTravIdCurrent( pLut ); - if ( Nwk_ObjLevel(pLut) > nLevMax ) - return; - if ( Nwk_ObjFanoutNum(pLut) > nFanMax ) - return; - Nwk_ObjForEachFanout( pLut, pNext, i ) - Nwk_ManMarkFanouts_rec( pNext, nLevMax, nFanMax ); -} - -/**Function************************************************************* - - Synopsis [Collects the circle of nodes around the given set.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Nwk_ManCollectCircle( Vec_Ptr_t * vStart, Vec_Ptr_t * vNext, int nFanMax ) -{ - Nwk_Obj_t * pObj, * pNext; - int i, k; - Vec_PtrClear( vNext ); - Vec_PtrForEachEntry( vStart, pObj, i ) - { - Nwk_ObjForEachFanin( pObj, pNext, k ) - { - if ( !Nwk_ObjIsNode(pNext) ) - continue; - if ( Nwk_ObjIsTravIdCurrent( pNext ) ) - continue; - Nwk_ObjSetTravIdCurrent( pNext ); - Vec_PtrPush( vNext, pNext ); - } - Nwk_ObjForEachFanout( pObj, pNext, k ) - { - if ( !Nwk_ObjIsNode(pNext) ) - continue; - if ( Nwk_ObjIsTravIdCurrent( pNext ) ) - continue; - Nwk_ObjSetTravIdCurrent( pNext ); - if ( Nwk_ObjFanoutNum(pNext) > nFanMax ) - continue; - Vec_PtrPush( vNext, pNext ); - } - } -} - -/**Function************************************************************* - - Synopsis [Collects the circle of nodes removes from the given one.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Nwk_ManCollectNonOverlapCands( Nwk_Obj_t * pLut, Vec_Ptr_t * vStart, Vec_Ptr_t * vNext, Vec_Ptr_t * vCands, Nwk_LMPars_t * pPars ) -{ - Vec_Ptr_t * vTemp; - Nwk_Obj_t * pObj; - int i, k; - Vec_PtrClear( vCands ); - if ( pPars->nMaxSuppSize - Nwk_ObjFaninNum(pLut) <= 1 ) - return; - - // collect nodes removed by this distance - assert( pPars->nMaxDistance > 0 ); - Vec_PtrClear( vStart ); - Vec_PtrPush( vStart, pLut ); - Nwk_ManIncrementTravId( pLut->pMan ); - Nwk_ObjSetTravIdCurrent( pLut ); - for ( i = 1; i <= pPars->nMaxDistance; i++ ) - { - Nwk_ManCollectCircle( vStart, vNext, pPars->nMaxFanout ); - vTemp = vStart; - vStart = vNext; - vNext = vTemp; - // collect the nodes in vStart - Vec_PtrForEachEntry( vStart, pObj, k ) - Vec_PtrPush( vCands, pObj ); - } - - // mark the TFI/TFO nodes - Nwk_ManIncrementTravId( pLut->pMan ); - if ( pPars->fUseTfiTfo ) - Nwk_ObjSetTravIdCurrent( pLut ); - else - { - Nwk_ObjSetTravIdPrevious( pLut ); - Nwk_ManMarkFanins_rec( pLut, Nwk_ObjLevel(pLut) - pPars->nMaxDistance ); - Nwk_ObjSetTravIdPrevious( pLut ); - Nwk_ManMarkFanouts_rec( pLut, Nwk_ObjLevel(pLut) + pPars->nMaxDistance, pPars->nMaxFanout ); - } - - // collect nodes satisfying the following conditions: - // - they are close enough in terms of distance - // - they are not in the TFI/TFO of the LUT - // - they have no more than the given number of fanins - // - they have no more than the given diff in delay - k = 0; - Vec_PtrForEachEntry( vCands, pObj, i ) - { - if ( Nwk_ObjIsTravIdCurrent(pObj) ) - continue; - if ( Nwk_ObjFaninNum(pLut) + Nwk_ObjFaninNum(pObj) > pPars->nMaxSuppSize ) - continue; - if ( Nwk_ObjLevel(pLut) - Nwk_ObjLevel(pObj) > pPars->nMaxLevelDiff || - Nwk_ObjLevel(pObj) - Nwk_ObjLevel(pLut) > pPars->nMaxLevelDiff ) - continue; - Vec_PtrWriteEntry( vCands, k++, pObj ); - } - Vec_PtrShrink( vCands, k ); -} - - -/**Function************************************************************* - - Synopsis [Count the total number of fanins.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Nwk_ManCountTotalFanins( Nwk_Obj_t * pLut, Nwk_Obj_t * pCand ) -{ - Nwk_Obj_t * pFanin; - int i, nCounter = Nwk_ObjFaninNum(pLut); - Nwk_ObjForEachFanin( pCand, pFanin, i ) - nCounter += !pFanin->MarkC; - return nCounter; -} - -/**Function************************************************************* - - Synopsis [Collects overlapping candidates.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Nwl_ManCollectOverlapCands( Nwk_Obj_t * pLut, Vec_Ptr_t * vCands, Nwk_LMPars_t * pPars ) -{ - Nwk_Obj_t * pFanin, * pObj; - int i, k; - // mark fanins of pLut - Nwk_ObjForEachFanin( pLut, pFanin, i ) - pFanin->MarkC = 1; - // collect the matching fanouts of each fanin of the node - Vec_PtrClear( vCands ); - Nwk_ManIncrementTravId( pLut->pMan ); - Nwk_ObjSetTravIdCurrent( pLut ); - Nwk_ObjForEachFanin( pLut, pFanin, i ) - { - if ( !Nwk_ObjIsNode(pFanin) ) - continue; - if ( Nwk_ObjFanoutNum(pFanin) > pPars->nMaxFanout ) - continue; - Nwk_ObjForEachFanout( pFanin, pObj, k ) - { - if ( !Nwk_ObjIsNode(pObj) ) - continue; - if ( Nwk_ObjIsTravIdCurrent( pObj ) ) - continue; - Nwk_ObjSetTravIdCurrent( pObj ); - // check the difference in delay - if ( Nwk_ObjLevel(pLut) - Nwk_ObjLevel(pObj) > pPars->nMaxLevelDiff || - Nwk_ObjLevel(pObj) - Nwk_ObjLevel(pLut) > pPars->nMaxLevelDiff ) - continue; - // check the total number of fanins of the node - if ( Nwk_ManCountTotalFanins(pLut, pObj) > pPars->nMaxSuppSize ) - continue; - Vec_PtrPush( vCands, pObj ); - } - } - // unmark fanins of pLut - Nwk_ObjForEachFanin( pLut, pFanin, i ) - pFanin->MarkC = 0; -} - -/**Function************************************************************* - - Synopsis [Performs LUT merging with parameters.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Nwk_ManLutMerge( Nwk_Man_t * pNtk, Nwk_LMPars_t * pPars ) -{ - Nwk_Grf_t * p; - Vec_Int_t * vResult; - Vec_Ptr_t * vStart, * vNext, * vCands1, * vCands2; - Nwk_Obj_t * pLut, * pCand; - int i, k, nVertsMax, nCands, clk = clock(); - // count the number of vertices - nVertsMax = 0; - Nwk_ManForEachNode( pNtk, pLut, i ) - nVertsMax += (int)(Nwk_ObjFaninNum(pLut) <= pPars->nMaxLutSize); - p = Nwk_ManGraphAlloc( nVertsMax ); - // create graph - vStart = Vec_PtrAlloc( 1000 ); - vNext = Vec_PtrAlloc( 1000 ); - vCands1 = Vec_PtrAlloc( 1000 ); - vCands2 = Vec_PtrAlloc( 1000 ); - nCands = 0; - Nwk_ManForEachNode( pNtk, pLut, i ) - { - if ( Nwk_ObjFaninNum(pLut) > pPars->nMaxLutSize ) - continue; - Nwl_ManCollectOverlapCands( pLut, vCands1, pPars ); - if ( pPars->fUseDiffSupp ) - Nwk_ManCollectNonOverlapCands( pLut, vStart, vNext, vCands2, pPars ); - if ( Vec_PtrSize(vCands1) == 0 && Vec_PtrSize(vCands2) == 0 ) - continue; - nCands += Vec_PtrSize(vCands1) + Vec_PtrSize(vCands2); - // save candidates - Vec_PtrForEachEntry( vCands1, pCand, k ) - Nwk_ManGraphHashEdge( p, Nwk_ObjId(pLut), Nwk_ObjId(pCand) ); - Vec_PtrForEachEntry( vCands2, pCand, k ) - Nwk_ManGraphHashEdge( p, Nwk_ObjId(pLut), Nwk_ObjId(pCand) ); - // print statistics about this node - if ( pPars->fVeryVerbose ) - printf( "Node %6d : Fanins = %d. Fanouts = %3d. Cand1 = %3d. Cand2 = %3d.\n", - Nwk_ObjId(pLut), Nwk_ObjFaninNum(pLut), Nwk_ObjFaninNum(pLut), - Vec_PtrSize(vCands1), Vec_PtrSize(vCands2) ); - } - Vec_PtrFree( vStart ); - Vec_PtrFree( vNext ); - Vec_PtrFree( vCands1 ); - Vec_PtrFree( vCands2 ); - if ( pPars->fVerbose ) - { - printf( "Mergable LUTs = %6d. Total cands = %6d. ", p->nVertsMax, nCands ); - PRT( "Deriving graph", clock() - clk ); - } - // solve the graph problem - clk = clock(); - Nwk_ManGraphSolve( p ); - if ( pPars->fVerbose ) - { - printf( "GRAPH: Nodes = %6d. Edges = %6d. Pairs = %6d. ", - p->nVerts, p->nEdges, Vec_IntSize(p->vPairs)/2 ); - PRT( "Solving", clock() - clk ); - Nwk_ManGraphReportMemoryUsage( p ); - } - vResult = p->vPairs; p->vPairs = NULL; - Nwk_ManGraphFree( p ); - return vResult; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/nwk2/nwkMerge.h b/src/aig/nwk2/nwkMerge.h deleted file mode 100644 index f5697f6e..00000000 --- a/src/aig/nwk2/nwkMerge.h +++ /dev/null @@ -1,149 +0,0 @@ -/**CFile**************************************************************** - - FileName [nwkMerge.h] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Logic network representation.] - - Synopsis [External declarations.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: nwkMerge.h,v 1.1 2008/05/14 22:13:09 wudenni Exp $] - -***********************************************************************/ - -#ifndef __NWK_MERGE_H__ -#define __NWK_MERGE_H__ - -//////////////////////////////////////////////////////////////////////// -/// INCLUDES /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// PARAMETERS /// -//////////////////////////////////////////////////////////////////////// - -#ifdef __cplusplus -extern "C" { -#endif - -#define NWK_MAX_LIST 16 - -//////////////////////////////////////////////////////////////////////// -/// BASIC TYPES /// -//////////////////////////////////////////////////////////////////////// - -// the LUT merging parameters -typedef struct Nwk_LMPars_t_ Nwk_LMPars_t; -struct Nwk_LMPars_t_ -{ - int nMaxLutSize; // the max LUT size for merging (N=5) - int nMaxSuppSize; // the max total support size after merging (S=5) - int nMaxDistance; // the max number of nodes separating LUTs - int nMaxLevelDiff; // the max difference in levels - int nMaxFanout; // the max number of fanouts to traverse - int fUseDiffSupp; // enables the use of nodes with different support - int fUseTfiTfo; // enables the use of TFO/TFO nodes as candidates - int fVeryVerbose; // enables additional verbose output - int fVerbose; // enables verbose output -}; - -// edge of the graph -typedef struct Nwk_Edg_t_ Nwk_Edg_t; -struct Nwk_Edg_t_ -{ - int iNode1; // the first node - int iNode2; // the second node - Nwk_Edg_t * pNext; // the next edge -}; - -// vertex of the graph -typedef struct Nwk_Vrt_t_ Nwk_Vrt_t; -struct Nwk_Vrt_t_ -{ - int Id; // the vertex number - int iPrev; // the previous vertex in the list - int iNext; // the next vertex in the list - int nEdges; // the number of edges - int pEdges[0]; // the array of edges -}; - -// the connectivity graph -typedef struct Nwk_Grf_t_ Nwk_Grf_t; -struct Nwk_Grf_t_ -{ - // preliminary graph representation - int nObjs; // the number of objects - int nVertsMax; // the upper bound on the number of vertices - int nEdgeHash; // an approximate number of edges - Nwk_Edg_t ** pEdgeHash; // hash table for edges - Aig_MmFixed_t * pMemEdges; // memory for edges - // graph representation - int nEdges; // the number of edges - int nVerts; // the number of vertices - Nwk_Vrt_t ** pVerts; // the array of vertices - Aig_MmFlex_t * pMemVerts; // memory for vertices - // intermediate data - int pLists1[NWK_MAX_LIST+1]; // lists of nodes with one edge - int pLists2[NWK_MAX_LIST+1]; // lists of nodes with more than one edge - // the results of matching - Vec_Int_t * vPairs; // pairs matched in the graph - // object mappings - int * pMapLut2Id; // LUT numbers into vertex IDs - int * pMapId2Lut; // vertex IDs into LUT numbers - // other things - int nMemBytes1; // memory usage in bytes - int nMemBytes2; // memory usage in bytes -}; - -//////////////////////////////////////////////////////////////////////// -/// MACRO DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -#define Nwk_GraphForEachEdge( p, pEdge, k ) \ - for ( k = 0; k < p->nEdgeHash; k++ ) \ - for ( pEdge = p->pEdgeHash[k]; pEdge; pEdge = pEdge->pNext ) - -#define Nwk_ListForEachVertex( p, List, pVrt ) \ - for ( pVrt = List? p->pVerts[List] : NULL; pVrt; \ - pVrt = pVrt->iNext? p->pVerts[pVrt->iNext] : NULL ) - -#define Nwk_VertexForEachAdjacent( p, pVrt, pNext, k ) \ - for ( k = 0; (k < pVrt->nEdges) && (((pNext) = p->pVerts[pVrt->pEdges[k]]), 1); k++ ) - -//////////////////////////////////////////////////////////////////////// -/// INLINED FUNCTIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// ITERATORS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -/*=== nwkMerge.c ==========================================================*/ -extern Nwk_Grf_t * Nwk_ManGraphAlloc( int nVertsMax ); -extern void Nwk_ManGraphFree( Nwk_Grf_t * p ); -extern void Nwk_ManGraphReportMemoryUsage( Nwk_Grf_t * p ); -extern void Nwk_ManGraphHashEdge( Nwk_Grf_t * p, int iLut1, int iLut2 ); -extern void Nwk_ManGraphSolve( Nwk_Grf_t * p ); -extern int Nwk_ManLutMergeGraphTest( char * pFileName ); - -#ifdef __cplusplus -} -#endif - -#endif - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - diff --git a/src/aig/nwk2/nwkObj.c b/src/aig/nwk2/nwkObj.c deleted file mode 100644 index 58587f07..00000000 --- a/src/aig/nwk2/nwkObj.c +++ /dev/null @@ -1,199 +0,0 @@ -/**CFile**************************************************************** - - FileName [nwkObj.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Logic network representation.] - - Synopsis [Manipulation of objects.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: nwkObj.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "nwk.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Creates an object.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Nwk_Obj_t * Nwk_ManCreateObj( Nwk_Man_t * p, int nFanins, int nFanouts ) -{ - Nwk_Obj_t * pObj; - pObj = (Nwk_Obj_t *)Aig_MmFlexEntryFetch( p->pMemObjs, sizeof(Nwk_Obj_t) + (nFanins + nFanouts + p->nFanioPlus) * sizeof(Nwk_Obj_t *) ); - memset( pObj, 0, sizeof(Nwk_Obj_t) ); - pObj->pFanio = (Nwk_Obj_t **)((char *)pObj + sizeof(Nwk_Obj_t)); - pObj->Id = Vec_PtrSize( p->vObjs ); - Vec_PtrPush( p->vObjs, pObj ); - pObj->pMan = p; - pObj->nFanioAlloc = nFanins + nFanouts + p->nFanioPlus; - return pObj; -} - - -/**Function************************************************************* - - Synopsis [Creates a primary input.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Nwk_Obj_t * Nwk_ManCreateCi( Nwk_Man_t * p, int nFanouts ) -{ - Nwk_Obj_t * pObj; - pObj = Nwk_ManCreateObj( p, 1, nFanouts ); - pObj->PioId = Vec_PtrSize( p->vCis ); - Vec_PtrPush( p->vCis, pObj ); - pObj->Type = NWK_OBJ_CI; - p->nObjs[NWK_OBJ_CI]++; - return pObj; -} - -/**Function************************************************************* - - Synopsis [Creates a primary output.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Nwk_Obj_t * Nwk_ManCreateCo( Nwk_Man_t * p ) -{ - Nwk_Obj_t * pObj; - pObj = Nwk_ManCreateObj( p, 1, 1 ); - pObj->PioId = Vec_PtrSize( p->vCos ); - Vec_PtrPush( p->vCos, pObj ); - pObj->Type = NWK_OBJ_CO; - p->nObjs[NWK_OBJ_CO]++; - return pObj; -} - -/**Function************************************************************* - - Synopsis [Creates a latch.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Nwk_Obj_t * Nwk_ManCreateLatch( Nwk_Man_t * p ) -{ - Nwk_Obj_t * pObj; - pObj = Nwk_ManCreateObj( p, 1, 1 ); - pObj->Type = NWK_OBJ_LATCH; - p->nObjs[NWK_OBJ_LATCH]++; - return pObj; -} - -/**Function************************************************************* - - Synopsis [Creates a node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Nwk_Obj_t * Nwk_ManCreateNode( Nwk_Man_t * p, int nFanins, int nFanouts ) -{ - Nwk_Obj_t * pObj; - pObj = Nwk_ManCreateObj( p, nFanins, nFanouts ); - pObj->Type = NWK_OBJ_NODE; - p->nObjs[NWK_OBJ_NODE]++; - return pObj; -} - - -/**Function************************************************************* - - Synopsis [Deletes the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Nwk_ManDeleteNode( Nwk_Obj_t * pObj ) -{ - Vec_Ptr_t * vNodes = pObj->pMan->vTemp; - Nwk_Obj_t * pTemp; - int i; - assert( Nwk_ObjFanoutNum(pObj) == 0 ); - // delete fanins - Nwk_ObjCollectFanins( pObj, vNodes ); - Vec_PtrForEachEntry( vNodes, pTemp, i ) - Nwk_ObjDeleteFanin( pObj, pTemp ); - // remove from the list of objects - Vec_PtrWriteEntry( pObj->pMan->vObjs, pObj->Id, NULL ); - pObj->pMan->nObjs[pObj->Type]--; - memset( pObj, 0, sizeof(Nwk_Obj_t) ); - pObj->Id = -1; -} - -/**Function************************************************************* - - Synopsis [Deletes the node and MFFC of the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Nwk_ManDeleteNode_rec( Nwk_Obj_t * pObj ) -{ - Vec_Ptr_t * vNodes; - int i; - assert( !Nwk_ObjIsCi(pObj) ); - assert( Nwk_ObjFanoutNum(pObj) == 0 ); - vNodes = Vec_PtrAlloc( 100 ); - Nwk_ObjCollectFanins( pObj, vNodes ); - Nwk_ManDeleteNode( pObj ); - Vec_PtrForEachEntry( vNodes, pObj, i ) - if ( Nwk_ObjIsNode(pObj) && Nwk_ObjFanoutNum(pObj) == 0 ) - Nwk_ManDeleteNode_rec( pObj ); - Vec_PtrFree( vNodes ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/nwk2/nwkUtil.c b/src/aig/nwk2/nwkUtil.c deleted file mode 100644 index 5473e628..00000000 --- a/src/aig/nwk2/nwkUtil.c +++ /dev/null @@ -1,515 +0,0 @@ -/**CFile**************************************************************** - - FileName [nwkUtil.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Logic network representation.] - - Synopsis [Various utilities.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: nwkUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "nwk.h" -#include "kit.h" -#include <math.h> - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Increments the current traversal ID of the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Nwk_ManIncrementTravId( Nwk_Man_t * pNtk ) -{ - Nwk_Obj_t * pObj; - int i; - if ( pNtk->nTravIds >= (1<<26)-1 ) - { - pNtk->nTravIds = 0; - Nwk_ManForEachObj( pNtk, pObj, i ) - pObj->TravId = 0; - } - pNtk->nTravIds++; -} - -/**Function************************************************************* - - Synopsis [Reads the maximum number of fanins of a node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Nwk_ManGetFaninMax( Nwk_Man_t * pNtk ) -{ - Nwk_Obj_t * pNode; - int i, nFaninsMax = 0; - Nwk_ManForEachNode( pNtk, pNode, i ) - { - if ( nFaninsMax < Nwk_ObjFaninNum(pNode) ) - nFaninsMax = Nwk_ObjFaninNum(pNode); - } - return nFaninsMax; -} - -/**Function************************************************************* - - Synopsis [Reads the total number of all fanins.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Nwk_ManGetTotalFanins( Nwk_Man_t * pNtk ) -{ - Nwk_Obj_t * pNode; - int i, nFanins = 0; - Nwk_ManForEachNode( pNtk, pNode, i ) - nFanins += Nwk_ObjFaninNum(pNode); - return nFanins; -} - - -/**Function************************************************************* - - Synopsis [Returns the number of true PIs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Nwk_ManPiNum( Nwk_Man_t * pNtk ) -{ - Nwk_Obj_t * pNode; - int i, Counter = 0; - Nwk_ManForEachCi( pNtk, pNode, i ) - Counter += Nwk_ObjIsPi( pNode ); - return Counter; -} - -/**Function************************************************************* - - Synopsis [Returns the number of true POs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Nwk_ManPoNum( Nwk_Man_t * pNtk ) -{ - Nwk_Obj_t * pNode; - int i, Counter = 0; - Nwk_ManForEachCo( pNtk, pNode, i ) - Counter += Nwk_ObjIsPo( pNode ); - return Counter; -} - -/**Function************************************************************* - - Synopsis [Reads the number of AIG nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Nwk_ManGetAigNodeNum( Nwk_Man_t * pNtk ) -{ - Nwk_Obj_t * pNode; - int i, nNodes = 0; - Nwk_ManForEachNode( pNtk, pNode, i ) - { - if ( pNode->pFunc == NULL ) - { - printf( "Nwk_ManGetAigNodeNum(): Local AIG of node %d is not assigned.\n", pNode->Id ); - continue; - } - if ( Nwk_ObjFaninNum(pNode) < 2 ) - continue; - nNodes += Hop_DagSize( pNode->pFunc ); - } - return nNodes; -} - -/**Function************************************************************* - - Synopsis [Procedure used for sorting the nodes in increasing order of levels.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Nwk_NodeCompareLevelsIncrease( Nwk_Obj_t ** pp1, Nwk_Obj_t ** pp2 ) -{ - int Diff = (*pp1)->Level - (*pp2)->Level; - if ( Diff < 0 ) - return -1; - if ( Diff > 0 ) - return 1; - return 0; -} - -/**Function************************************************************* - - Synopsis [Procedure used for sorting the nodes in decreasing order of levels.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Nwk_NodeCompareLevelsDecrease( Nwk_Obj_t ** pp1, Nwk_Obj_t ** pp2 ) -{ - int Diff = (*pp1)->Level - (*pp2)->Level; - if ( Diff > 0 ) - return -1; - if ( Diff < 0 ) - return 1; - return 0; -} - -/**Function************************************************************* - - Synopsis [Prints the objects.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Nwk_ObjPrint( Nwk_Obj_t * pObj ) -{ - Nwk_Obj_t * pNext; - int i; - printf( "ObjId = %5d. ", pObj->Id ); - if ( Nwk_ObjIsPi(pObj) ) - printf( "PI" ); - if ( Nwk_ObjIsPo(pObj) ) - printf( "PO" ); - if ( Nwk_ObjIsNode(pObj) ) - printf( "Node" ); - printf( " Fanins = " ); - Nwk_ObjForEachFanin( pObj, pNext, i ) - printf( "%d ", pNext->Id ); - printf( " Fanouts = " ); - Nwk_ObjForEachFanout( pObj, pNext, i ) - printf( "%d ", pNext->Id ); - printf( "\n" ); -} - -/**Function************************************************************* - - Synopsis [Dumps the BLIF file for the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Nwk_ManDumpBlif( Nwk_Man_t * pNtk, char * pFileName, Vec_Ptr_t * vPiNames, Vec_Ptr_t * vPoNames ) -{ - FILE * pFile; - Vec_Ptr_t * vNodes; - Vec_Int_t * vTruth; - Vec_Int_t * vCover; - Nwk_Obj_t * pObj, * pFanin; - Aig_MmFlex_t * pMem; - char * pSop = NULL; - unsigned * pTruth; - int i, k, nDigits; - if ( Nwk_ManPoNum(pNtk) == 0 ) - { - printf( "Nwk_ManDumpBlif(): Network does not have POs.\n" ); - return; - } - // collect nodes in the DFS order - nDigits = Aig_Base10Log( Nwk_ManObjNumMax(pNtk) ); - // write the file - pFile = fopen( pFileName, "w" ); - fprintf( pFile, "# BLIF file written by procedure Nwk_ManDumpBlif()\n" ); -// fprintf( pFile, "# http://www.eecs.berkeley.edu/~alanmi/abc/\n" ); - fprintf( pFile, ".model %s\n", pNtk->pName ); - // write PIs - fprintf( pFile, ".inputs" ); - Nwk_ManForEachCi( pNtk, pObj, i ) - if ( vPiNames ) - fprintf( pFile, " %s", (char*)Vec_PtrEntry(vPiNames, i) ); - else - fprintf( pFile, " n%0*d", nDigits, pObj->Id ); - fprintf( pFile, "\n" ); - // write POs - fprintf( pFile, ".outputs" ); - Nwk_ManForEachCo( pNtk, pObj, i ) - if ( vPoNames ) - fprintf( pFile, " %s", (char*)Vec_PtrEntry(vPoNames, i) ); - else - fprintf( pFile, " n%0*d", nDigits, pObj->Id ); - fprintf( pFile, "\n" ); - // write nodes - pMem = Aig_MmFlexStart(); - vTruth = Vec_IntAlloc( 1 << 16 ); - vCover = Vec_IntAlloc( 1 << 16 ); - vNodes = Nwk_ManDfs( pNtk ); - Vec_PtrForEachEntry( vNodes, pObj, i ) - { - if ( !Nwk_ObjIsNode(pObj) ) - continue; - // derive SOP for the AIG - pTruth = Hop_ManConvertAigToTruth( pNtk->pManHop, Hop_Regular(pObj->pFunc), Nwk_ObjFaninNum(pObj), vTruth, 0 ); - if ( Hop_IsComplement(pObj->pFunc) ) - Kit_TruthNot( pTruth, pTruth, Nwk_ObjFaninNum(pObj) ); - pSop = Kit_PlaFromTruth( pMem, pTruth, Nwk_ObjFaninNum(pObj), vCover ); - // write the node - fprintf( pFile, ".names" ); - if ( !Kit_TruthIsConst0(pTruth, Nwk_ObjFaninNum(pObj)) && !Kit_TruthIsConst1(pTruth, Nwk_ObjFaninNum(pObj)) ) - { - Nwk_ObjForEachFanin( pObj, pFanin, k ) - if ( vPiNames && Nwk_ObjIsPi(pFanin) ) - fprintf( pFile, " %s", (char*)Vec_PtrEntry(vPiNames, Nwk_ObjPioNum(pFanin)) ); - else - fprintf( pFile, " n%0*d", nDigits, pFanin->Id ); - } - fprintf( pFile, " n%0*d\n", nDigits, pObj->Id ); - // write the function - fprintf( pFile, "%s", pSop ); - } - Vec_IntFree( vCover ); - Vec_IntFree( vTruth ); - Vec_PtrFree( vNodes ); - Aig_MmFlexStop( pMem, 0 ); - // write POs - Nwk_ManForEachCo( pNtk, pObj, i ) - { - fprintf( pFile, ".names" ); - if ( vPiNames && Nwk_ObjIsPi(Nwk_ObjFanin0(pObj)) ) - fprintf( pFile, " %s", (char*)Vec_PtrEntry(vPiNames, Nwk_ObjPioNum(Nwk_ObjFanin0(pObj))) ); - else - fprintf( pFile, " n%0*d", nDigits, Nwk_ObjFanin0(pObj)->Id ); - if ( vPoNames ) - fprintf( pFile, " %s\n", (char*)Vec_PtrEntry(vPoNames, Nwk_ObjPioNum(pObj)) ); - else - fprintf( pFile, " n%0*d\n", nDigits, pObj->Id ); - fprintf( pFile, "%d 1\n", !pObj->fInvert ); - } - fprintf( pFile, ".end\n\n" ); - fclose( pFile ); -} - -/**Function************************************************************* - - Synopsis [Prints the distribution of fanins/fanouts in the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Nwk_ManPrintFanioNew( Nwk_Man_t * pNtk ) -{ - char Buffer[100]; - Nwk_Obj_t * pNode; - Vec_Int_t * vFanins, * vFanouts; - int nFanins, nFanouts, nFaninsMax, nFanoutsMax, nFaninsAll, nFanoutsAll; - int i, k, nSizeMax; - - // determine the largest fanin and fanout - nFaninsMax = nFanoutsMax = 0; - nFaninsAll = nFanoutsAll = 0; - Nwk_ManForEachNode( pNtk, pNode, i ) - { - nFanins = Nwk_ObjFaninNum(pNode); - nFanouts = Nwk_ObjFanoutNum(pNode); - nFaninsAll += nFanins; - nFanoutsAll += nFanouts; - nFaninsMax = ABC_MAX( nFaninsMax, nFanins ); - nFanoutsMax = ABC_MAX( nFanoutsMax, nFanouts ); - } - - // allocate storage for fanin/fanout numbers - nSizeMax = ABC_MAX( 10 * (Aig_Base10Log(nFaninsMax) + 1), 10 * (Aig_Base10Log(nFanoutsMax) + 1) ); - vFanins = Vec_IntStart( nSizeMax ); - vFanouts = Vec_IntStart( nSizeMax ); - - // count the number of fanins and fanouts - Nwk_ManForEachNode( pNtk, pNode, i ) - { - nFanins = Nwk_ObjFaninNum(pNode); - nFanouts = Nwk_ObjFanoutNum(pNode); -// nFanouts = Nwk_NodeMffcSize(pNode); - - if ( nFanins < 10 ) - Vec_IntAddToEntry( vFanins, nFanins, 1 ); - else if ( nFanins < 100 ) - Vec_IntAddToEntry( vFanins, 10 + nFanins/10, 1 ); - else if ( nFanins < 1000 ) - Vec_IntAddToEntry( vFanins, 20 + nFanins/100, 1 ); - else if ( nFanins < 10000 ) - Vec_IntAddToEntry( vFanins, 30 + nFanins/1000, 1 ); - else if ( nFanins < 100000 ) - Vec_IntAddToEntry( vFanins, 40 + nFanins/10000, 1 ); - else if ( nFanins < 1000000 ) - Vec_IntAddToEntry( vFanins, 50 + nFanins/100000, 1 ); - else if ( nFanins < 10000000 ) - Vec_IntAddToEntry( vFanins, 60 + nFanins/1000000, 1 ); - - if ( nFanouts < 10 ) - Vec_IntAddToEntry( vFanouts, nFanouts, 1 ); - else if ( nFanouts < 100 ) - Vec_IntAddToEntry( vFanouts, 10 + nFanouts/10, 1 ); - else if ( nFanouts < 1000 ) - Vec_IntAddToEntry( vFanouts, 20 + nFanouts/100, 1 ); - else if ( nFanouts < 10000 ) - Vec_IntAddToEntry( vFanouts, 30 + nFanouts/1000, 1 ); - else if ( nFanouts < 100000 ) - Vec_IntAddToEntry( vFanouts, 40 + nFanouts/10000, 1 ); - else if ( nFanouts < 1000000 ) - Vec_IntAddToEntry( vFanouts, 50 + nFanouts/100000, 1 ); - else if ( nFanouts < 10000000 ) - Vec_IntAddToEntry( vFanouts, 60 + nFanouts/1000000, 1 ); - } - - printf( "The distribution of fanins and fanouts in the network:\n" ); - printf( " Number Nodes with fanin Nodes with fanout\n" ); - for ( k = 0; k < nSizeMax; k++ ) - { - if ( vFanins->pArray[k] == 0 && vFanouts->pArray[k] == 0 ) - continue; - if ( k < 10 ) - printf( "%15d : ", k ); - else - { - sprintf( Buffer, "%d - %d", (int)pow(10, k/10) * (k%10), (int)pow(10, k/10) * (k%10+1) - 1 ); - printf( "%15s : ", Buffer ); - } - if ( vFanins->pArray[k] == 0 ) - printf( " " ); - else - printf( "%12d ", vFanins->pArray[k] ); - printf( " " ); - if ( vFanouts->pArray[k] == 0 ) - printf( " " ); - else - printf( "%12d ", vFanouts->pArray[k] ); - printf( "\n" ); - } - Vec_IntFree( vFanins ); - Vec_IntFree( vFanouts ); - - printf( "Fanins: Max = %d. Ave = %.2f. Fanouts: Max = %d. Ave = %.2f.\n", - nFaninsMax, 1.0*nFaninsAll/Nwk_ManNodeNum(pNtk), - nFanoutsMax, 1.0*nFanoutsAll/Nwk_ManNodeNum(pNtk) ); -} - -/**Function************************************************************* - - Synopsis [Cleans the temporary marks of the nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Nwk_ManCleanMarks( Nwk_Man_t * pMan ) -{ - Nwk_Obj_t * pObj; - int i; - Nwk_ManForEachObj( pMan, pObj, i ) - pObj->MarkA = pObj->MarkB = 0; -} - -/**Function************************************************************* - - Synopsis [Minimizes the support of all nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Nwk_ManMinimumBase( Nwk_Man_t * pNtk, int fVerbose ) -{ - unsigned * pTruth; - Vec_Int_t * vTruth; - Nwk_Obj_t * pObj, * pFanin, * pObjNew; - int uSupp, nSuppSize, i, k, Counter = 0; - vTruth = Vec_IntAlloc( 1 << 16 ); - Nwk_ManForEachNode( pNtk, pObj, i ) - { - pTruth = Hop_ManConvertAigToTruth( pNtk->pManHop, Hop_Regular(pObj->pFunc), Nwk_ObjFaninNum(pObj), vTruth, 0 ); - nSuppSize = Kit_TruthSupportSize(pTruth, Nwk_ObjFaninNum(pObj)); - if ( nSuppSize == Nwk_ObjFaninNum(pObj) ) - continue; - Counter++; - uSupp = Kit_TruthSupport( pTruth, Nwk_ObjFaninNum(pObj) ); - // create new node with the given support - pObjNew = Nwk_ManCreateNode( pNtk, nSuppSize, Nwk_ObjFanoutNum(pObj) ); - Nwk_ObjForEachFanin( pObj, pFanin, k ) - if ( uSupp & (1 << k) ) - Nwk_ObjAddFanin( pObjNew, pFanin ); - pObjNew->pFunc = Hop_Remap( pNtk->pManHop, pObj->pFunc, uSupp, Nwk_ObjFaninNum(pObj) ); - if ( fVerbose ) - printf( "Reducing node %d fanins from %d to %d.\n", - pObj->Id, Nwk_ObjFaninNum(pObj), Nwk_ObjFaninNum(pObjNew) ); - Nwk_ObjReplace( pObj, pObjNew ); - } - if ( fVerbose && Counter ) - printf( "Support minimization reduced support of %d nodes.\n", Counter ); - Vec_IntFree( vTruth ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/rwt/rwt.h b/src/aig/rwt/rwt.h index 9efdc421..5410c9de 100644 --- a/src/aig/rwt/rwt.h +++ b/src/aig/rwt/rwt.h @@ -21,21 +21,28 @@ #ifndef __RWT_H__ #define __RWT_H__ + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// -#include "mem.h" -#include "extra.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + #include "vec.h" +#include "extra.h" +#include "mem.h" //////////////////////////////////////////////////////////////////////// /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -144,9 +151,11 @@ extern char * Rwt_ManGetPractical( Rwt_Man_t * p ); extern Rwt_Node_t * Rwt_ManAddVar( Rwt_Man_t * p, unsigned uTruth, int fPrecompute ); extern void Rwt_ManIncTravId( Rwt_Man_t * p ); -#ifdef __cplusplus -} -#endif + + +ABC_NAMESPACE_HEADER_END + + #endif diff --git a/src/aig/rwt/rwtDec.c b/src/aig/rwt/rwtDec.c index 2f183913..a26e474d 100644 --- a/src/aig/rwt/rwtDec.c +++ b/src/aig/rwt/rwtDec.c @@ -21,6 +21,9 @@ #include "rwt.h" #include "deco.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -66,7 +69,7 @@ void Rwt_ManPreprocess( Rwt_Man_t * p ) } } // compute decomposition forms for each node and verify them - Vec_VecForEachEntry( p->vClasses, pNode, i, k ) + Vec_VecForEachEntry( Rwt_Node_t *, p->vClasses, pNode, i, k ) { pGraph = Rwt_NodePreprocess( p, pNode ); pNode->pNext = (Rwt_Node_t *)pGraph; @@ -148,3 +151,5 @@ Dec_Edge_t Rwt_TravCollect_rec( Rwt_Man_t * p, Rwt_Node_t * pNode, Dec_Graph_t * //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/rwt/rwtMan.c b/src/aig/rwt/rwtMan.c index 87074e6e..12caa87f 100644 --- a/src/aig/rwt/rwtMan.c +++ b/src/aig/rwt/rwtMan.c @@ -21,6 +21,9 @@ #include "rwt.h" #include "deco.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -149,7 +152,7 @@ void Rwt_ManStop( Rwt_Man_t * p ) { Rwt_Node_t * pNode; int i, k; - Vec_VecForEachEntry( p->vClasses, pNode, i, k ) + Vec_VecForEachEntry( Rwt_Node_t *, p->vClasses, pNode, i, k ) Dec_GraphFree( (Dec_Graph_t *)pNode->pNext ); } if ( p->vClasses ) Vec_VecFree( p->vClasses ); @@ -356,3 +359,5 @@ void Rwt_Precompute() //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/rwt/rwtUtil.c b/src/aig/rwt/rwtUtil.c index b0b653bd..6cdaf657 100644 --- a/src/aig/rwt/rwtUtil.c +++ b/src/aig/rwt/rwtUtil.c @@ -20,287 +20,14 @@ #include "rwt.h" -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -// precomputed data -#ifdef _WIN32 -unsigned short s_RwtPracticalClasses[]; -unsigned short s_RwtAigSubgraphs[]; -#else -static unsigned short s_RwtPracticalClasses[]; -static unsigned short s_RwtAigSubgraphs[]; -#endif - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Adds the node to the end of the list.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rwt_ListAddToTail( Rwt_Node_t ** ppList, Rwt_Node_t * pNode ) -{ - Rwt_Node_t * pTemp; - // find the last one - for ( pTemp = *ppList; pTemp; pTemp = pTemp->pNext ) - ppList = &pTemp->pNext; - // attach at the end - *ppList = pNode; -} - -/**Function************************************************************* - - Synopsis [Adds one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Rwt_Node_t * Rwt_ManAddVar( Rwt_Man_t * p, unsigned uTruth, int fPrecompute ) -{ - Rwt_Node_t * pNew; - pNew = (Rwt_Node_t *)Mem_FixedEntryFetch( p->pMmNode ); - pNew->Id = p->vForest->nSize; - pNew->TravId = 0; - pNew->uTruth = uTruth; - pNew->Level = 0; - pNew->Volume = 0; - pNew->fUsed = 1; - pNew->fExor = 0; - pNew->p0 = NULL; - pNew->p1 = NULL; - pNew->pNext = NULL; - Vec_PtrPush( p->vForest, pNew ); - if ( fPrecompute ) - Rwt_ListAddToTail( p->pTable + uTruth, pNew ); - return pNew; -} - -/**Function************************************************************* - - Synopsis [Adds one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Rwt_Node_t * Rwt_ManAddNode( Rwt_Man_t * p, Rwt_Node_t * p0, Rwt_Node_t * p1, int fExor, int Level, int Volume ) -{ - Rwt_Node_t * pNew; - unsigned uTruth; - // compute truth table, leve, volume - p->nConsidered++; - if ( fExor ) - uTruth = (p0->uTruth ^ p1->uTruth); - else - uTruth = (Rwt_IsComplement(p0)? ~Rwt_Regular(p0)->uTruth : Rwt_Regular(p0)->uTruth) & - (Rwt_IsComplement(p1)? ~Rwt_Regular(p1)->uTruth : Rwt_Regular(p1)->uTruth) & 0xFFFF; - // create the new node - pNew = (Rwt_Node_t *)Mem_FixedEntryFetch( p->pMmNode ); - pNew->Id = p->vForest->nSize; - pNew->TravId = 0; - pNew->uTruth = uTruth; - pNew->Level = Level; - pNew->Volume = Volume; - pNew->fUsed = 0; - pNew->fExor = fExor; - pNew->p0 = p0; - pNew->p1 = p1; - pNew->pNext = NULL; - Vec_PtrPush( p->vForest, pNew ); - // do not add if the node is not essential - if ( uTruth != p->puCanons[uTruth] ) - return pNew; - - // add to the list - p->nAdded++; - if ( p->pTable[uTruth] == NULL ) - p->nClasses++; - Rwt_ListAddToTail( p->pTable + uTruth, pNew ); - return pNew; -} - -/**Function************************************************************* - - Synopsis [Adds one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rwt_Trav_rec( Rwt_Man_t * p, Rwt_Node_t * pNode, int * pVolume ) -{ - if ( pNode->fUsed || pNode->TravId == p->nTravIds ) - return; - pNode->TravId = p->nTravIds; - (*pVolume)++; - if ( pNode->fExor ) - (*pVolume)++; - Rwt_Trav_rec( p, Rwt_Regular(pNode->p0), pVolume ); - Rwt_Trav_rec( p, Rwt_Regular(pNode->p1), pVolume ); -} - -/**Function************************************************************* - - Synopsis [Adds one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rwt_ManIncTravId( Rwt_Man_t * p ) -{ - Rwt_Node_t * pNode; - int i; - if ( p->nTravIds++ < 0x8FFFFFFF ) - return; - Vec_PtrForEachEntry( p->vForest, pNode, i ) - pNode->TravId = 0; - p->nTravIds = 1; -} - -/**Function************************************************************* - - Synopsis [Adds one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Rwt_ManNodeVolume( Rwt_Man_t * p, Rwt_Node_t * p0, Rwt_Node_t * p1 ) -{ - int Volume = 0; - Rwt_ManIncTravId( p ); - Rwt_Trav_rec( p, p0, &Volume ); - Rwt_Trav_rec( p, p1, &Volume ); - return Volume; -} - -/**Function************************************************************* - - Synopsis [Loads data.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rwt_ManLoadFromArray( Rwt_Man_t * p, int fVerbose ) -{ - unsigned short * pArray = s_RwtAigSubgraphs; - Rwt_Node_t * p0, * p1; - unsigned Entry0, Entry1; - int Level, Volume, nEntries, fExor; - int i, clk = clock(); - - // reconstruct the forest - for ( i = 0; ; i++ ) - { - Entry0 = pArray[2*i + 0]; - Entry1 = pArray[2*i + 1]; - if ( Entry0 == 0 && Entry1 == 0 ) - break; - // get EXOR flag - fExor = (Entry0 & 1); - Entry0 >>= 1; - // get the nodes - p0 = p->vForest->pArray[Entry0 >> 1]; - p1 = p->vForest->pArray[Entry1 >> 1]; - // compute the level and volume of the new nodes - Level = 1 + RWT_MAX( p0->Level, p1->Level ); - Volume = 1 + Rwt_ManNodeVolume( p, p0, p1 ); - // set the complemented attributes - p0 = Rwt_NotCond( p0, (Entry0 & 1) ); - p1 = Rwt_NotCond( p1, (Entry1 & 1) ); - // add the node -// Rwt_ManTryNode( p, p0, p1, Level, Volume ); - Rwt_ManAddNode( p, p0, p1, fExor, Level, Volume + fExor ); - } - nEntries = i - 1; - if ( fVerbose ) - { - printf( "The number of classes = %d. Canonical nodes = %d.\n", p->nClasses, p->nAdded ); - printf( "The number of nodes loaded = %d. ", nEntries ); ABC_PRT( "Loading", clock() - clk ); - } -} - -/**Function************************************************************* - - Synopsis [Create practical classes.] - - Description [] - - SideEffects [] +ABC_NAMESPACE_IMPL_START - SeeAlso [] - -***********************************************************************/ -char * Rwt_ManGetPractical( Rwt_Man_t * p ) -{ - char * pPractical; - int i; - pPractical = ABC_ALLOC( char, p->nFuncs ); - memset( pPractical, 0, sizeof(char) * p->nFuncs ); - pPractical[0] = 1; - for ( i = 1; ; i++ ) - { - if ( s_RwtPracticalClasses[i] == 0 ) - break; - pPractical[ s_RwtPracticalClasses[i] ] = 1; - } - return pPractical; -} //////////////////////////////////////////////////////////////////////// -/// END OF FILE /// +/// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -// the following 135 practical NPN classes of 4-variable functions were computed -// by considering all 4-input cuts appearing in IWLS, MCNC, and ISCAS benchmarks -static unsigned short s_RwtPracticalClasses[] = -{ - 0x0000, 0x0001, 0x0003, 0x0006, 0x0007, 0x000f, 0x0016, 0x0017, 0x0018, 0x0019, 0x001b, - 0x001e, 0x001f, 0x003c, 0x003d, 0x003f, 0x0069, 0x006b, 0x006f, 0x007e, 0x007f, 0x00ff, - 0x0116, 0x0118, 0x0119, 0x011a, 0x011b, 0x011e, 0x011f, 0x012c, 0x012d, 0x012f, 0x013c, - 0x013d, 0x013e, 0x013f, 0x0168, 0x0169, 0x016f, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, - 0x0186, 0x0189, 0x018b, 0x018f, 0x0198, 0x0199, 0x019b, 0x01a8, 0x01a9, 0x01aa, 0x01ab, - 0x01ac, 0x01ad, 0x01ae, 0x01af, 0x01bf, 0x01e9, 0x01ea, 0x01eb, 0x01ee, 0x01ef, 0x01fe, - 0x033c, 0x033d, 0x033f, 0x0356, 0x0357, 0x0358, 0x0359, 0x035a, 0x035b, 0x035f, 0x0368, - 0x0369, 0x036c, 0x036e, 0x037d, 0x03c0, 0x03c1, 0x03c3, 0x03c7, 0x03cf, 0x03d4, 0x03d5, - 0x03d7, 0x03d8, 0x03d9, 0x03dc, 0x03dd, 0x03de, 0x03fc, 0x0660, 0x0661, 0x0666, 0x0669, - 0x066f, 0x0676, 0x067e, 0x0690, 0x0696, 0x0697, 0x069f, 0x06b1, 0x06b6, 0x06f0, 0x06f2, - 0x06f6, 0x06f9, 0x0776, 0x0778, 0x07b0, 0x07b1, 0x07b4, 0x07bc, 0x07f0, 0x07f2, 0x07f8, - 0x0ff0, 0x1683, 0x1696, 0x1698, 0x169e, 0x16e9, 0x178e, 0x17e8, 0x18e7, 0x19e6, 0x1be4, - 0x1ee1, 0x3cc3, 0x6996, 0x0000 -}; - +// precomputed data static unsigned short s_RwtAigSubgraphs[] = { 0x0008,0x0002, 0x000a,0x0002, 0x0008,0x0003, 0x000a,0x0003, 0x0009,0x0002, @@ -663,3 +390,273 @@ static unsigned short s_RwtAigSubgraphs[] = }; +static unsigned short s_RwtPracticalClasses[] = +{ + 0x0000, 0x0001, 0x0003, 0x0006, 0x0007, 0x000f, 0x0016, 0x0017, 0x0018, 0x0019, 0x001b, + 0x001e, 0x001f, 0x003c, 0x003d, 0x003f, 0x0069, 0x006b, 0x006f, 0x007e, 0x007f, 0x00ff, + 0x0116, 0x0118, 0x0119, 0x011a, 0x011b, 0x011e, 0x011f, 0x012c, 0x012d, 0x012f, 0x013c, + 0x013d, 0x013e, 0x013f, 0x0168, 0x0169, 0x016f, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, + 0x0186, 0x0189, 0x018b, 0x018f, 0x0198, 0x0199, 0x019b, 0x01a8, 0x01a9, 0x01aa, 0x01ab, + 0x01ac, 0x01ad, 0x01ae, 0x01af, 0x01bf, 0x01e9, 0x01ea, 0x01eb, 0x01ee, 0x01ef, 0x01fe, + 0x033c, 0x033d, 0x033f, 0x0356, 0x0357, 0x0358, 0x0359, 0x035a, 0x035b, 0x035f, 0x0368, + 0x0369, 0x036c, 0x036e, 0x037d, 0x03c0, 0x03c1, 0x03c3, 0x03c7, 0x03cf, 0x03d4, 0x03d5, + 0x03d7, 0x03d8, 0x03d9, 0x03dc, 0x03dd, 0x03de, 0x03fc, 0x0660, 0x0661, 0x0666, 0x0669, + 0x066f, 0x0676, 0x067e, 0x0690, 0x0696, 0x0697, 0x069f, 0x06b1, 0x06b6, 0x06f0, 0x06f2, + 0x06f6, 0x06f9, 0x0776, 0x0778, 0x07b0, 0x07b1, 0x07b4, 0x07bc, 0x07f0, 0x07f2, 0x07f8, + 0x0ff0, 0x1683, 0x1696, 0x1698, 0x169e, 0x16e9, 0x178e, 0x17e8, 0x18e7, 0x19e6, 0x1be4, + 0x1ee1, 0x3cc3, 0x6996, 0x0000 +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Adds the node to the end of the list.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Rwt_ListAddToTail( Rwt_Node_t ** ppList, Rwt_Node_t * pNode ) +{ + Rwt_Node_t * pTemp; + // find the last one + for ( pTemp = *ppList; pTemp; pTemp = pTemp->pNext ) + ppList = &pTemp->pNext; + // attach at the end + *ppList = pNode; +} + +/**Function************************************************************* + + Synopsis [Adds one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Rwt_Node_t * Rwt_ManAddVar( Rwt_Man_t * p, unsigned uTruth, int fPrecompute ) +{ + Rwt_Node_t * pNew; + pNew = (Rwt_Node_t *)Mem_FixedEntryFetch( p->pMmNode ); + pNew->Id = p->vForest->nSize; + pNew->TravId = 0; + pNew->uTruth = uTruth; + pNew->Level = 0; + pNew->Volume = 0; + pNew->fUsed = 1; + pNew->fExor = 0; + pNew->p0 = NULL; + pNew->p1 = NULL; + pNew->pNext = NULL; + Vec_PtrPush( p->vForest, pNew ); + if ( fPrecompute ) + Rwt_ListAddToTail( p->pTable + uTruth, pNew ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Adds one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Rwt_Node_t * Rwt_ManAddNode( Rwt_Man_t * p, Rwt_Node_t * p0, Rwt_Node_t * p1, int fExor, int Level, int Volume ) +{ + Rwt_Node_t * pNew; + unsigned uTruth; + // compute truth table, leve, volume + p->nConsidered++; + if ( fExor ) + uTruth = (p0->uTruth ^ p1->uTruth); + else + uTruth = (Rwt_IsComplement(p0)? ~Rwt_Regular(p0)->uTruth : Rwt_Regular(p0)->uTruth) & + (Rwt_IsComplement(p1)? ~Rwt_Regular(p1)->uTruth : Rwt_Regular(p1)->uTruth) & 0xFFFF; + // create the new node + pNew = (Rwt_Node_t *)Mem_FixedEntryFetch( p->pMmNode ); + pNew->Id = p->vForest->nSize; + pNew->TravId = 0; + pNew->uTruth = uTruth; + pNew->Level = Level; + pNew->Volume = Volume; + pNew->fUsed = 0; + pNew->fExor = fExor; + pNew->p0 = p0; + pNew->p1 = p1; + pNew->pNext = NULL; + Vec_PtrPush( p->vForest, pNew ); + // do not add if the node is not essential + if ( uTruth != p->puCanons[uTruth] ) + return pNew; + + // add to the list + p->nAdded++; + if ( p->pTable[uTruth] == NULL ) + p->nClasses++; + Rwt_ListAddToTail( p->pTable + uTruth, pNew ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Adds one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Rwt_Trav_rec( Rwt_Man_t * p, Rwt_Node_t * pNode, int * pVolume ) +{ + if ( pNode->fUsed || pNode->TravId == p->nTravIds ) + return; + pNode->TravId = p->nTravIds; + (*pVolume)++; + if ( pNode->fExor ) + (*pVolume)++; + Rwt_Trav_rec( p, Rwt_Regular(pNode->p0), pVolume ); + Rwt_Trav_rec( p, Rwt_Regular(pNode->p1), pVolume ); +} + +/**Function************************************************************* + + Synopsis [Adds one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Rwt_ManIncTravId( Rwt_Man_t * p ) +{ + Rwt_Node_t * pNode; + int i; + if ( p->nTravIds++ < 0x8FFFFFFF ) + return; + Vec_PtrForEachEntry( Rwt_Node_t *, p->vForest, pNode, i ) + pNode->TravId = 0; + p->nTravIds = 1; +} + +/**Function************************************************************* + + Synopsis [Adds one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Rwt_ManNodeVolume( Rwt_Man_t * p, Rwt_Node_t * p0, Rwt_Node_t * p1 ) +{ + int Volume = 0; + Rwt_ManIncTravId( p ); + Rwt_Trav_rec( p, p0, &Volume ); + Rwt_Trav_rec( p, p1, &Volume ); + return Volume; +} + +/**Function************************************************************* + + Synopsis [Loads data.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Rwt_ManLoadFromArray( Rwt_Man_t * p, int fVerbose ) +{ + unsigned short * pArray = s_RwtAigSubgraphs; + Rwt_Node_t * p0, * p1; + unsigned Entry0, Entry1; + int Level, Volume, nEntries, fExor; + int i, clk = clock(); + + // reconstruct the forest + for ( i = 0; ; i++ ) + { + Entry0 = pArray[2*i + 0]; + Entry1 = pArray[2*i + 1]; + if ( Entry0 == 0 && Entry1 == 0 ) + break; + // get EXOR flag + fExor = (Entry0 & 1); + Entry0 >>= 1; + // get the nodes + p0 = (Rwt_Node_t *)p->vForest->pArray[Entry0 >> 1]; + p1 = (Rwt_Node_t *)p->vForest->pArray[Entry1 >> 1]; + // compute the level and volume of the new nodes + Level = 1 + RWT_MAX( p0->Level, p1->Level ); + Volume = 1 + Rwt_ManNodeVolume( p, p0, p1 ); + // set the complemented attributes + p0 = Rwt_NotCond( p0, (Entry0 & 1) ); + p1 = Rwt_NotCond( p1, (Entry1 & 1) ); + // add the node +// Rwt_ManTryNode( p, p0, p1, Level, Volume ); + Rwt_ManAddNode( p, p0, p1, fExor, Level, Volume + fExor ); + } + nEntries = i - 1; + if ( fVerbose ) + { + printf( "The number of classes = %d. Canonical nodes = %d.\n", p->nClasses, p->nAdded ); + printf( "The number of nodes loaded = %d. ", nEntries ); ABC_PRT( "Loading", clock() - clk ); + } +} + +/**Function************************************************************* + + Synopsis [Create practical classes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Rwt_ManGetPractical( Rwt_Man_t * p ) +{ + char * pPractical; + int i; + pPractical = ABC_ALLOC( char, p->nFuncs ); + memset( pPractical, 0, sizeof(char) * p->nFuncs ); + pPractical[0] = 1; + for ( i = 1; ; i++ ) + { + if ( s_RwtPracticalClasses[i] == 0 ) + break; + pPractical[ s_RwtPracticalClasses[i] ] = 1; + } + return pPractical; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + +// the following 135 practical NPN classes of 4-variable functions were computed +// by considering all 4-input cuts appearing in IWLS, MCNC, and ISCAS benchmarks +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/module.make b/src/aig/saig/module.make index e583bcfe..88935121 100644 --- a/src/aig/saig/module.make +++ b/src/aig/saig/module.make @@ -1,12 +1,17 @@ SRC += src/aig/saig/saigAbs.c \ + src/aig/saig/saigAbs2.c \ src/aig/saig/saigBmc.c \ src/aig/saig/saigBmc2.c \ + src/aig/saig/saigBmc3.c \ src/aig/saig/saigCone.c \ + src/aig/saig/saigConstr.c \ + src/aig/saig/saigConstr2.c \ src/aig/saig/saigDup.c \ src/aig/saig/saigHaig.c \ src/aig/saig/saigInd.c \ src/aig/saig/saigIoa.c \ src/aig/saig/saigMiter.c \ + src/aig/saig/saigPba.c \ src/aig/saig/saigPhase.c \ src/aig/saig/saigRetFwd.c \ src/aig/saig/saigRetMin.c \ diff --git a/src/aig/saig/saig.h b/src/aig/saig/saig.h index f72a3074..fc85d52a 100644 --- a/src/aig/saig/saig.h +++ b/src/aig/saig/saig.h @@ -21,6 +21,7 @@ #ifndef __SAIG_H__ #define __SAIG_H__ + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -32,9 +33,10 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -43,26 +45,57 @@ extern "C" { typedef struct Sec_MtrStatus_t_ Sec_MtrStatus_t; struct Sec_MtrStatus_t_ { - int nInputs; // the total number of inputs - int nNodes; // the total number of nodes - int nOutputs; // the total number of outputs - int nUnsat; // the number of UNSAT outputs - int nSat; // the number of SAT outputs - int nUndec; // the number of undecided outputs - int iOut; // the satisfied output + int nInputs; // the total number of inputs + int nNodes; // the total number of nodes + int nOutputs; // the total number of outputs + int nUnsat; // the number of UNSAT outputs + int nSat; // the number of SAT outputs + int nUndec; // the number of undecided outputs + int iOut; // the satisfied output +}; + +typedef struct Saig_ParBmc_t_ Saig_ParBmc_t; +struct Saig_ParBmc_t_ +{ + int nStart; // starting timeframe + int nFramesMax; // maximum number of timeframes + int nConfLimit; // maximum number of conflicts at a node + int nTimeOut; // approximate timeout in seconds + int fSolveAll; // does not stop at the first SAT output + int fDropSatOuts; // replace sat outputs by constant 0 + int fVerbose; // verbose + int iFrame; // explored up to this frame + int nFailOuts; // the number of failed outputs +}; + +typedef struct Saig_ParBbr_t_ Saig_ParBbr_t; +struct Saig_ParBbr_t_ +{ + int TimeLimit; + int nBddMax; + int nIterMax; + int fPartition; + int fReorder; + int fReorderImage; + int fVerbose; + int fSilent; + int fSkipOutCheck;// skip output checking + int iFrame; // explored up to this frame }; + //////////////////////////////////////////////////////////////////////// /// MACRO DEFINITIONS /// //////////////////////////////////////////////////////////////////////// -static inline int Saig_ManPiNum( Aig_Man_t * p ) { return p->nTruePis; } -static inline int Saig_ManPoNum( Aig_Man_t * p ) { return p->nTruePos; } -static inline int Saig_ManCiNum( Aig_Man_t * p ) { return p->nTruePis + p->nRegs; } -static inline int Saig_ManCoNum( Aig_Man_t * p ) { return p->nTruePos + p->nRegs; } -static inline int Saig_ManRegNum( Aig_Man_t * p ) { return p->nRegs; } -static inline Aig_Obj_t * Saig_ManLo( Aig_Man_t * p, int i ) { return (Aig_Obj_t *)Vec_PtrEntry(p->vPis, Saig_ManPiNum(p)+i); } -static inline Aig_Obj_t * Saig_ManLi( Aig_Man_t * p, int i ) { return (Aig_Obj_t *)Vec_PtrEntry(p->vPos, Saig_ManPoNum(p)+i); } +static inline int Saig_ManPiNum( Aig_Man_t * p ) { return p->nTruePis; } +static inline int Saig_ManPoNum( Aig_Man_t * p ) { return p->nTruePos; } +static inline int Saig_ManCiNum( Aig_Man_t * p ) { return p->nTruePis + p->nRegs; } +static inline int Saig_ManCoNum( Aig_Man_t * p ) { return p->nTruePos + p->nRegs; } +static inline int Saig_ManRegNum( Aig_Man_t * p ) { return p->nRegs; } +static inline int Saig_ManConstrNum( Aig_Man_t * p ) { return p->nConstrs; } +static inline Aig_Obj_t * Saig_ManLo( Aig_Man_t * p, int i ) { return (Aig_Obj_t *)Vec_PtrEntry(p->vPis, Saig_ManPiNum(p)+i); } +static inline Aig_Obj_t * Saig_ManLi( Aig_Man_t * p, int i ) { return (Aig_Obj_t *)Vec_PtrEntry(p->vPos, Saig_ManPoNum(p)+i); } static inline int Saig_ObjIsPi( Aig_Man_t * p, Aig_Obj_t * pObj ) { return Aig_ObjIsPi(pObj) && Aig_ObjPioNum(pObj) < Saig_ManPiNum(p); } static inline int Saig_ObjIsPo( Aig_Man_t * p, Aig_Obj_t * pObj ) { return Aig_ObjIsPo(pObj) && Aig_ObjPioNum(pObj) < Saig_ManPoNum(p); } @@ -73,14 +106,14 @@ static inline Aig_Obj_t * Saig_ObjLiToLo( Aig_Man_t * p, Aig_Obj_t * pObj ) { // iterator over the primary inputs/outputs #define Saig_ManForEachPi( p, pObj, i ) \ - Vec_PtrForEachEntryStop( p->vPis, pObj, i, Saig_ManPiNum(p) ) + Vec_PtrForEachEntryStop( Aig_Obj_t *, p->vPis, pObj, i, Saig_ManPiNum(p) ) #define Saig_ManForEachPo( p, pObj, i ) \ - Vec_PtrForEachEntryStop( p->vPos, pObj, i, Saig_ManPoNum(p) ) + Vec_PtrForEachEntryStop( Aig_Obj_t *, p->vPos, pObj, i, Saig_ManPoNum(p) ) // iterator over the latch inputs/outputs #define Saig_ManForEachLo( p, pObj, i ) \ - for ( i = 0; (i < Saig_ManRegNum(p)) && (((pObj) = Vec_PtrEntry(p->vPis, i+Saig_ManPiNum(p))), 1); i++ ) + for ( i = 0; (i < Saig_ManRegNum(p)) && (((pObj) = (Aig_Obj_t *)Vec_PtrEntry(p->vPis, i+Saig_ManPiNum(p))), 1); i++ ) #define Saig_ManForEachLi( p, pObj, i ) \ - for ( i = 0; (i < Saig_ManRegNum(p)) && (((pObj) = Vec_PtrEntry(p->vPos, i+Saig_ManPoNum(p))), 1); i++ ) + for ( i = 0; (i < Saig_ManRegNum(p)) && (((pObj) = (Aig_Obj_t *)Vec_PtrEntry(p->vPos, i+Saig_ManPoNum(p))), 1); i++ ) // iterator over the latch input and outputs #define Saig_ManForEachLiLo( p, pObjLi, pObjLo, i ) \ for ( i = 0; (i < Saig_ManRegNum(p)) && (((pObjLi) = Saig_ManLi(p, i)), 1) \ @@ -89,21 +122,36 @@ static inline Aig_Obj_t * Saig_ObjLiToLo( Aig_Man_t * p, Aig_Obj_t * pObj ) { //////////////////////////////////////////////////////////////////////// /// FUNCTION DECLARATIONS /// //////////////////////////////////////////////////////////////////////// - + /*=== sswAbs.c ==========================================================*/ +extern Aig_Man_t * Saig_ManCexAbstraction( Aig_Man_t * p, Gia_ParAbs_t * pPars ); +/*=== sswAbs2.c ==========================================================*/ +extern Aig_Man_t * Saig_ManConCexAbstraction( Aig_Man_t * p, Gia_ParAbs_t * pPars ); +/*=== sswPba.c ==========================================================*/ extern Aig_Man_t * Saig_ManProofAbstraction( Aig_Man_t * p, Gia_ParAbs_t * pPars ); /*=== saigBmc.c ==========================================================*/ extern int Saig_ManBmcSimple( Aig_Man_t * pAig, int nFrames, int nSizeMax, int nBTLimit, int fRewrite, int fVerbose, int * piFrame, int nCofFanLit ); -extern void Saig_BmcPerform( Aig_Man_t * pAig, int nStart, int nFramesMax, int nNodesMax, int nTimeOut, int nConfMaxOne, int nConfMaxAll, int fVerbose, int fVerbOverwrite ); +extern int Saig_BmcPerform( Aig_Man_t * pAig, int nStart, int nFramesMax, int nNodesMax, int nTimeOut, int nConfMaxOne, int nConfMaxAll, int fVerbose, int fVerbOverwrite, int * piFrames ); +/*=== saigBmc3.c ==========================================================*/ +extern void Saig_ParBmcSetDefaultParams( Saig_ParBmc_t * p ); +extern int Saig_ManBmcScalable( Aig_Man_t * pAig, Saig_ParBmc_t * pPars ); /*=== saigCone.c ==========================================================*/ extern void Saig_ManPrintCones( Aig_Man_t * p ); +/*=== saigConstr.c ==========================================================*/ +extern Aig_Man_t * Saig_ManDupUnfoldConstrs( Aig_Man_t * pAig ); +extern Aig_Man_t * Saig_ManDupFoldConstrs( Aig_Man_t * pAig, Vec_Int_t * vConstrs ); +extern int Saig_ManDetectConstrTest( Aig_Man_t * p ); +extern void Saig_ManDetectConstrFuncTest( Aig_Man_t * p, int nFrames, int nConfs, int nProps, int fOldAlgo, int fVerbose ); +/*=== saigConstr2.c ==========================================================*/ +extern Aig_Man_t * Saig_ManDupFoldConstrsFunc( Aig_Man_t * pAig, int fCompl, int fVerbose ); +extern Aig_Man_t * Saig_ManDupUnfoldConstrsFunc( Aig_Man_t * pAig, int nFrames, int nConfs, int nProps, int fOldAlgo, int fVerbose ); /*=== saigDup.c ==========================================================*/ extern Aig_Man_t * Said_ManDupOrpos( Aig_Man_t * p ); -extern Aig_Man_t * Saig_ManAbstraction( Aig_Man_t * pAig, Vec_Int_t * vFlops ); +extern Aig_Man_t * Saig_ManDeriveAbstraction( Aig_Man_t * pAig, Vec_Int_t * vFlops ); /*=== saigHaig.c ==========================================================*/ extern Aig_Man_t * Saig_ManHaigRecord( Aig_Man_t * p, int nIters, int nSteps, int fRetimingOnly, int fAddBugs, int fUseCnf, int fVerbose ); /*=== saigInd.c ==========================================================*/ -extern int Saig_ManInduction( Aig_Man_t * p, int nFramesMax, int nConfMax, int fVerbose ); +extern int Saig_ManInduction( Aig_Man_t * p, int nFramesMax, int nConfMax, int fUnique, int fUniqueAll, int fVerbose, int fVeryVerbose ); /*=== saigIoa.c ==========================================================*/ extern void Saig_ManDumpBlif( Aig_Man_t * p, char * pFileName ); extern Aig_Man_t * Saig_ManReadBlif( char * pFileName ); @@ -115,6 +163,7 @@ extern Aig_Man_t * Saig_ManDualRail( Aig_Man_t * p, int fMiter ); extern Aig_Man_t * Saig_ManCreateMiterTwo( Aig_Man_t * pOld, Aig_Man_t * pNew, int nFrames ); extern int Saig_ManDemiterSimple( Aig_Man_t * p, Aig_Man_t ** ppAig0, Aig_Man_t ** ppAig1 ); extern int Saig_ManDemiterSimpleDiff( Aig_Man_t * p, Aig_Man_t ** ppAig0, Aig_Man_t ** ppAig1 ); +extern int Ssw_SecSpecialMiter( Aig_Man_t * p0, Aig_Man_t * p1, int nFrames, int fVerbose ); /*=== saigPhase.c ==========================================================*/ extern Aig_Man_t * Saig_ManPhaseAbstract( Aig_Man_t * p, Vec_Int_t * vInits, int nFrames, int nPref, int fIgnore, int fPrint, int fVerbose ); /*=== saigRetFwd.c ==========================================================*/ @@ -128,8 +177,8 @@ extern int Saig_ManRetimeSteps( Aig_Man_t * p, int nSteps, int fFo /*=== saigScl.c ==========================================================*/ extern void Saig_ManReportUselessRegisters( Aig_Man_t * pAig ); /*=== saigSimExt.c ==========================================================*/ -//extern Vec_Int_t * Saig_ManExtendCounterExample( Aig_Man_t * p, int iFirstPi, Ssw_Cex_t * pCex, Vec_Ptr_t * vSimInfo ); -//extern Vec_Int_t * Saig_ManExtendCounterExampleTest( Aig_Man_t * p, int iFirstPi, Ssw_Cex_t * pCex ); +extern Vec_Int_t * Saig_ManExtendCounterExample( Aig_Man_t * p, int iFirstPi, Abc_Cex_t * pCex, Vec_Ptr_t * vSimInfo, int fVerbose ); +extern Vec_Int_t * Saig_ManExtendCounterExampleTest( Aig_Man_t * p, int iFirstPi, Abc_Cex_t * pCex, int fVerbose ); /*=== saigSimMv.c ==========================================================*/ extern int Saig_MvManSimulate( Aig_Man_t * pAig, int fVerbose ); /*=== saigStrSim.c ==========================================================*/ @@ -145,9 +194,11 @@ extern Aig_Man_t * Saig_ManWindowExtract( Aig_Man_t * p, Aig_Obj_t * pObj, extern Aig_Man_t * Saig_ManWindowInsert( Aig_Man_t * p, Aig_Obj_t * pObj, int nDist, Aig_Man_t * pWnd ); extern Aig_Obj_t * Saig_ManFindPivot( Aig_Man_t * p ); -#ifdef __cplusplus -} -#endif + + +ABC_NAMESPACE_HEADER_END + + #endif diff --git a/src/aig/saig/saigAbs.c b/src/aig/saig/saigAbs.c index 2fac60f5..194add25 100644 --- a/src/aig/saig/saigAbs.c +++ b/src/aig/saig/saigAbs.c @@ -6,7 +6,7 @@ PackageName [Sequential AIG package.] - Synopsis [Proof-based abstraction.] + Synopsis [Counter-example-based abstraction.] Author [Alan Mishchenko] @@ -19,110 +19,24 @@ ***********************************************************************/ #include "saig.h" - -#include "cnf.h" -#include "satSolver.h" -#include "satStore.h" #include "ssw.h" -#include "ioa.h" #include "fra.h" +#include "bbr.h" + +ABC_NAMESPACE_IMPL_START + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -static inline char Saig_AbsVisited( Vec_Str_t * p, int nObjs, Aig_Obj_t * pObj, int i ) { return Vec_StrGetEntry( p, nObjs*i+pObj->Id ); } -static inline void Saig_AbsSetVisited( Vec_Str_t * p, int nObjs, Aig_Obj_t * pObj, int i ) { Vec_StrSetEntry( p, nObjs*i+pObj->Id, (char)1 ); } - //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* - Synopsis [Finds the set of clauses involved in the UNSAT core.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Saig_AbsSolverUnsatCore( sat_solver * pSat, int nConfMax, int fVerbose ) -{ - Vec_Int_t * vCore; - void * pSatCnf; - Intp_Man_t * pManProof; - int RetValue, clk = clock(); - // solve the problem - RetValue = sat_solver_solve( pSat, NULL, NULL, (ABC_INT64_T)nConfMax, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); - if ( RetValue == l_Undef ) - { - printf( "Conflict limit is reached.\n" ); - return NULL; - } - if ( RetValue == l_True ) - { - printf( "The BMC problem is SAT.\n" ); - return NULL; - } - if ( fVerbose ) - { - printf( "SAT solver returned UNSAT after %d conflicts. ", pSat->stats.conflicts ); - ABC_PRT( "Time", clock() - clk ); - } - assert( RetValue == l_False ); - pSatCnf = sat_solver_store_release( pSat ); - // derive the UNSAT core - clk = clock(); - pManProof = Intp_ManAlloc(); - vCore = Intp_ManUnsatCore( pManProof, pSatCnf, 0 ); - Intp_ManFree( pManProof ); - Sto_ManFree( pSatCnf ); - if ( fVerbose ) - { - printf( "SAT core contains %d clauses (out of %d). ", Vec_IntSize(vCore), pSat->stats.clauses ); - ABC_PRT( "Time", clock() - clk ); - } - return vCore; -} - - -/**Function************************************************************* - - Synopsis [Mark visited nodes recursively.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Saig_AbsMarkVisited_rec( Aig_Man_t * p, Vec_Str_t * vObj2Visit, Aig_Obj_t * pObj, int i ) -{ - if ( Saig_AbsVisited( vObj2Visit, Aig_ManObjNumMax(p), pObj, i ) ) - return 1; - Saig_AbsSetVisited( vObj2Visit, Aig_ManObjNumMax(p), pObj, i ); - if ( Saig_ObjIsPi( p, pObj ) ) - return 1; - if ( Saig_ObjIsLo( p, pObj ) ) - { - if ( i == 0 ) - return 1; - return Saig_AbsMarkVisited_rec( p, vObj2Visit, Saig_ObjLoToLi(p, pObj), i-1 ); - } - if ( Aig_ObjIsPo( pObj ) ) - return Saig_AbsMarkVisited_rec( p, vObj2Visit, Aig_ObjFanin0(pObj), i ); - Saig_AbsMarkVisited_rec( p, vObj2Visit, Aig_ObjFanin0(pObj), i ); - Saig_AbsMarkVisited_rec( p, vObj2Visit, Aig_ObjFanin1(pObj), i ); - return 1; -} - -/**Function************************************************************* - - Synopsis [Mark visited nodes.] + Synopsis [Collects internal nodes in the DFS order.] Description [] @@ -131,47 +45,29 @@ int Saig_AbsMarkVisited_rec( Aig_Man_t * p, Vec_Str_t * vObj2Visit, Aig_Obj_t * SeeAlso [] ***********************************************************************/ -Vec_Str_t * Saig_AbsMarkVisited( Aig_Man_t * p, int nFramesMax ) +int Saig_ManFindFirstFlop_rec( Aig_Man_t * p, Aig_Obj_t * pObj ) { - Vec_Str_t * vObj2Visit; - Aig_Obj_t * pObj; - int i, f; - vObj2Visit = Vec_StrStart( Aig_ManObjNumMax(p) * nFramesMax ); -// Saig_ManForEachLo( p, pObj, i ) -// Saig_AbsSetVisited( vObj2Visit, Aig_ManObjNumMax(p), pObj, 0 ); - for ( f = 0; f < nFramesMax; f++ ) + int RetValue; + if ( Aig_ObjIsTravIdCurrent(p, pObj) ) + return -1; + Aig_ObjSetTravIdCurrent(p, pObj); + if ( Saig_ObjIsPi(p, pObj) ) + return -1; + if ( Saig_ObjIsLo(p, pObj) ) { - Saig_AbsSetVisited( vObj2Visit, Aig_ManObjNumMax(p), Aig_ManConst1(p), f ); - Saig_ManForEachPo( p, pObj, i ) - Saig_AbsMarkVisited_rec( p, vObj2Visit, pObj, f ); + assert( Aig_ObjPioNum(pObj) >= Saig_ManPiNum(p) ); + return Aig_ObjPioNum(pObj)-Saig_ManPiNum(p); } - return vObj2Visit; -} - -/**Function************************************************************* - - Synopsis [Performs the actual construction of the output.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Obj_t * Saig_AbsCreateFrames_rec( Aig_Man_t * pFrame, Aig_Obj_t * pObj ) -{ - if ( pObj->pData ) - return pObj->pData; assert( Aig_ObjIsNode(pObj) ); - Saig_AbsCreateFrames_rec( pFrame, Aig_ObjFanin0(pObj) ); - Saig_AbsCreateFrames_rec( pFrame, Aig_ObjFanin1(pObj) ); - return pObj->pData = Aig_And( pFrame, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + RetValue = Saig_ManFindFirstFlop_rec( p, Aig_ObjFanin0(pObj) ); + if ( RetValue >= 0 ) + return RetValue; + return Saig_ManFindFirstFlop_rec( p, Aig_ObjFanin1(pObj) ); } /**Function************************************************************* - Synopsis [Derives a vector of AIG managers, one for each frame.] + Synopsis [Returns the index of the flop that appears in the support.] Description [] @@ -180,462 +76,12 @@ Aig_Obj_t * Saig_AbsCreateFrames_rec( Aig_Man_t * pFrame, Aig_Obj_t * pObj ) SeeAlso [] ***********************************************************************/ -Vec_Ptr_t * Saig_AbsCreateFrames( Aig_Man_t * p, int nFramesMax, int fVerbose ) +int Saig_ManFindFirstFlop( Aig_Man_t * p ) { - Vec_Ptr_t * vFrames, * vLoObjs, * vLiObjs; - Vec_Str_t * vObj2Visit; - Aig_Man_t * pFrame; - Aig_Obj_t * pObj; - int f, i; - vObj2Visit = Saig_AbsMarkVisited( p, nFramesMax ); - vFrames = Vec_PtrAlloc( nFramesMax ); - vLoObjs = Vec_PtrAlloc( 100 ); - vLiObjs = Vec_PtrAlloc( 100 ); - for ( f = 0; f < nFramesMax; f++ ) - { - Aig_ManCleanData( p ); - pFrame = Aig_ManStart( 1000 ); - Aig_ManConst1(p)->pData = Aig_ManConst1(pFrame); - // create PIs - Vec_PtrClear( vLoObjs ); - Vec_PtrClear( vLiObjs ); - Aig_ManForEachPi( p, pObj, i ) - { - if ( Saig_AbsVisited( vObj2Visit, Aig_ManObjNumMax(p), pObj, f ) ) - { - pObj->pData = Aig_ObjCreatePi(pFrame); - if ( i >= Saig_ManPiNum(p) ) - Vec_PtrPush( vLoObjs, pObj ); - } - } - // remember the number of (implicit) registers in this frame - pFrame->nAsserts = Vec_PtrSize(vLoObjs); - // create POs - Aig_ManForEachPo( p, pObj, i ) - { - if ( Saig_AbsVisited( vObj2Visit, Aig_ManObjNumMax(p), pObj, f ) ) - { - Saig_AbsCreateFrames_rec( pFrame, Aig_ObjFanin0(pObj) ); - pObj->pData = Aig_ObjCreatePo( pFrame, Aig_ObjChild0Copy(pObj) ); - if ( i >= Saig_ManPoNum(p) ) - Vec_PtrPush( vLiObjs, pObj ); - } - } -// Vec_PtrPush( vFrames, Cnf_Derive(pFrame, Aig_ManPoNum(pFrame)) ); - Vec_PtrPush( vFrames, Cnf_DeriveSimple(pFrame, Aig_ManPoNum(pFrame)) ); - // set the new PIs to point to the corresponding registers - Aig_ManCleanData( pFrame ); - Vec_PtrForEachEntry( vLoObjs, pObj, i ) - ((Aig_Obj_t *)pObj->pData)->pData = pObj; - Vec_PtrForEachEntry( vLiObjs, pObj, i ) - ((Aig_Obj_t *)pObj->pData)->pData = pObj; - if ( fVerbose ) - printf( "%3d : PI =%8d. PO =%8d. Flop =%8d. Node =%8d.\n", - f, Aig_ManPiNum(pFrame), Aig_ManPoNum(pFrame), pFrame->nAsserts, Aig_ManNodeNum(pFrame) ); - } - Vec_PtrFree( vLoObjs ); - Vec_PtrFree( vLiObjs ); - Vec_StrFree( vObj2Visit ); - return vFrames; -} - -/**Function************************************************************* + Aig_ManIncrementTravId( p ); + Aig_ObjSetTravIdCurrent( p, Aig_ManConst1(p) ); + return Saig_ManFindFirstFlop_rec( p, Aig_ObjFanin0(Aig_ManPo(p, 0)) ); - Synopsis [Derives a vector of AIG managers, one for each frame.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -sat_solver * Saig_AbsCreateSolverDyn( Aig_Man_t * p, Vec_Ptr_t * vFrames ) -{ - sat_solver * pSat; - Cnf_Dat_t * pCnf, * pCnfPrev; - Vec_Int_t * vPoLits; - Aig_Obj_t * pObjPo, * pObjLi, * pObjLo; - int f, i, Lit, Lits[2], iVarOld, iVarNew, nSatVars, nRegisters; - // start array of output literals - vPoLits = Vec_IntAlloc( 100 ); - // count the number of CNF variables - nSatVars = 0; - Vec_PtrForEachEntry( vFrames, pCnf, f ) - nSatVars += pCnf->nVars; - - // create the SAT solver - pSat = sat_solver_new(); - sat_solver_store_alloc( pSat ); - sat_solver_setnvars( pSat, nSatVars ); - - // add clauses for the timeframes - nSatVars = 0; -// Vec_PtrForEachEntryReverse( vFrames, pCnf, f ) - Vec_PtrForEachEntry( vFrames, pCnf, f ) - { - // lift clauses of this CNF - Cnf_DataLift( pCnf, nSatVars ); - nSatVars += pCnf->nVars; - // copy clauses into the manager - for ( i = 0; i < pCnf->nClauses; i++ ) - { - if ( !sat_solver_addclause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1] ) ) - { - printf( "The BMC problem is trivially UNSAT.\n" ); - sat_solver_delete( pSat ); - Vec_IntFree( vPoLits ); - return NULL; - } - } - // remember output literal - Aig_ManForEachPo( pCnf->pMan, pObjPo, i ) - { - if ( i == Saig_ManPoNum(p) ) - break; - Vec_IntPush( vPoLits, toLit(pCnf->pVarNums[pObjPo->Id]) ); - } - } - - // add auxiliary clauses (output, connectors, initial) - // add output clause - if ( !sat_solver_addclause( pSat, Vec_IntArray(vPoLits), Vec_IntArray(vPoLits) + Vec_IntSize(vPoLits) ) ) - { - printf( "SAT solver is not created correctly.\n" ); - assert( 0 ); - } - Vec_IntFree( vPoLits ); - - // add connecting clauses - pCnfPrev = Vec_PtrEntry( vFrames, 0 ); - Vec_PtrForEachEntryStart( vFrames, pCnf, f, 1 ) - { - nRegisters = pCnf->pMan->nAsserts; - assert( nRegisters <= Aig_ManPoNum(pCnfPrev->pMan) ); - assert( nRegisters <= Aig_ManPiNum(pCnf->pMan) ); - for ( i = 0; i < nRegisters; i++ ) - { - pObjLi = Aig_ManPo( pCnfPrev->pMan, Aig_ManPoNum(pCnfPrev->pMan) - nRegisters + i ); - pObjLo = Aig_ManPi( pCnf->pMan, Aig_ManPiNum(pCnf->pMan) - nRegisters + i ); - // get variable numbers - iVarOld = pCnfPrev->pVarNums[pObjLi->Id]; - iVarNew = pCnf->pVarNums[pObjLo->Id]; - // add clauses connecting existing variables - Lits[0] = toLitCond( iVarOld, 0 ); - Lits[1] = toLitCond( iVarNew, 1 ); - if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) ) - assert( 0 ); - Lits[0] = toLitCond( iVarOld, 1 ); - Lits[1] = toLitCond( iVarNew, 0 ); - if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) ) - assert( 0 ); - } - pCnfPrev = pCnf; - } - // add unit clauses - pCnf = Vec_PtrEntry( vFrames, 0 ); - nRegisters = pCnf->pMan->nAsserts; - for ( i = 0; i < nRegisters; i++ ) - { - pObjLo = Aig_ManPi( pCnf->pMan, Aig_ManPiNum(pCnf->pMan) - nRegisters + i ); - assert( pCnf->pVarNums[pObjLo->Id] >= 0 ); - Lit = toLitCond( pCnf->pVarNums[pObjLo->Id], 1 ); - if ( !sat_solver_addclause( pSat, &Lit, &Lit+1 ) ) - assert( 0 ); - } - sat_solver_store_mark_roots( pSat ); - return pSat; -} - - -/**Function************************************************************* - - Synopsis [Creates SAT solver for BMC.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -sat_solver * Saig_AbsCreateSolver( Cnf_Dat_t * pCnf, int nFrames ) -{ - sat_solver * pSat; - Vec_Int_t * vPoLits; - Aig_Obj_t * pObjPo, * pObjLi, * pObjLo; - int f, i, Lit, Lits[2], iVarOld, iVarNew; - // start array of output literals - vPoLits = Vec_IntAlloc( nFrames * Saig_ManPoNum(pCnf->pMan) ); - // create the SAT solver - pSat = sat_solver_new(); - sat_solver_store_alloc( pSat ); - sat_solver_setnvars( pSat, pCnf->nVars * nFrames ); - - // add clauses for the timeframes - for ( f = 0; f < nFrames; f++ ) - { - for ( i = 0; i < pCnf->nClauses; i++ ) - { - if ( !sat_solver_addclause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1] ) ) - { - printf( "The BMC problem is trivially UNSAT.\n" ); - sat_solver_delete( pSat ); - Vec_IntFree( vPoLits ); - return NULL; - } - } - // remember output literal - Saig_ManForEachPo( pCnf->pMan, pObjPo, i ) - Vec_IntPush( vPoLits, toLit(pCnf->pVarNums[pObjPo->Id]) ); - // lift CNF to the next frame - Cnf_DataLift( pCnf, pCnf->nVars ); - } - // put CNF back to the original level - Cnf_DataLift( pCnf, - pCnf->nVars * nFrames ); - - // add auxiliary clauses (output, connectors, initial) - // add output clause - if ( !sat_solver_addclause( pSat, Vec_IntArray(vPoLits), Vec_IntArray(vPoLits) + Vec_IntSize(vPoLits) ) ) - assert( 0 ); - Vec_IntFree( vPoLits ); - // add connecting clauses - for ( f = 0; f < nFrames; f++ ) - { - // connect to the previous timeframe - if ( f > 0 ) - { - Saig_ManForEachLiLo( pCnf->pMan, pObjLi, pObjLo, i ) - { - iVarOld = pCnf->pVarNums[pObjLi->Id] - pCnf->nVars; - iVarNew = pCnf->pVarNums[pObjLo->Id]; - // add clauses connecting existing variables - Lits[0] = toLitCond( iVarOld, 0 ); - Lits[1] = toLitCond( iVarNew, 1 ); - if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) ) - assert( 0 ); - Lits[0] = toLitCond( iVarOld, 1 ); - Lits[1] = toLitCond( iVarNew, 0 ); - if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) ) - assert( 0 ); - } - } - // lift CNF to the next frame - Cnf_DataLift( pCnf, pCnf->nVars ); - } - // put CNF back to the original level - Cnf_DataLift( pCnf, - pCnf->nVars * nFrames ); - // add unit clauses - Saig_ManForEachLo( pCnf->pMan, pObjLo, i ) - { - assert( pCnf->pVarNums[pObjLo->Id] >= 0 ); - Lit = toLitCond( pCnf->pVarNums[pObjLo->Id], 1 ); - if ( !sat_solver_addclause( pSat, &Lit, &Lit+1 ) ) - assert( 0 ); - } - sat_solver_store_mark_roots( pSat ); - return pSat; -} - -/**Function************************************************************* - - Synopsis [Performs proof-based abstraction using BMC of the given depth.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Saig_AbsCollectRegistersDyn( Aig_Man_t * p, Vec_Ptr_t * vFrames, Vec_Int_t * vCore ) -{ - Aig_Obj_t * pObj; - Cnf_Dat_t * pCnf; - Vec_Int_t * vFlops; - int * pVars, * pFlops; - int i, f, iClause, iReg, * piLit, nSatVars, nSatClauses; - // count the number of CNF variables - nSatVars = 0; - Vec_PtrForEachEntry( vFrames, pCnf, f ) - nSatVars += pCnf->nVars; - // mark register variables - pVars = ABC_ALLOC( int, nSatVars ); - for ( i = 0; i < nSatVars; i++ ) - pVars[i] = -1; - Vec_PtrForEachEntry( vFrames, pCnf, f ) - { - Aig_ManForEachPi( pCnf->pMan, pObj, i ) - { - assert( pCnf->pVarNums[pObj->Id] >= 0 ); - assert( pCnf->pVarNums[pObj->Id] < nSatVars ); - if ( pObj->pData == NULL ) - continue; - iReg = Aig_ObjPioNum(pObj->pData) - Saig_ManPiNum(p); - assert( iReg >= 0 && iReg < Aig_ManRegNum(p) ); - pVars[ pCnf->pVarNums[pObj->Id] ] = iReg; - } - Aig_ManForEachPo( pCnf->pMan, pObj, i ) - { - assert( pCnf->pVarNums[pObj->Id] >= 0 ); - assert( pCnf->pVarNums[pObj->Id] < nSatVars ); - if ( pObj->pData == NULL ) - continue; - iReg = Aig_ObjPioNum(pObj->pData) - Saig_ManPoNum(p); - assert( iReg >= 0 && iReg < Aig_ManRegNum(p) ); - pVars[ pCnf->pVarNums[pObj->Id] ] = iReg; - } - } - // mark used registers - pFlops = ABC_CALLOC( int, Aig_ManRegNum(p) ); - Vec_IntForEachEntry( vCore, iClause, i ) - { - nSatClauses = 0; - Vec_PtrForEachEntry( vFrames, pCnf, f ) - { - if ( iClause < nSatClauses + pCnf->nClauses ) - break; - nSatClauses += pCnf->nClauses; - } - if ( f == Vec_PtrSize(vFrames) ) - continue; - iClause = iClause - nSatClauses; - assert( iClause >= 0 ); - assert( iClause < pCnf->nClauses ); - // consider the clause - for ( piLit = pCnf->pClauses[iClause]; piLit < pCnf->pClauses[iClause+1]; piLit++ ) - { - iReg = pVars[ lit_var(*piLit) ]; - if ( iReg >= 0 ) - pFlops[iReg] = 1; - } - } - // collect registers - vFlops = Vec_IntAlloc( Aig_ManRegNum(p) ); - for ( i = 0; i < Aig_ManRegNum(p); i++ ) - if ( pFlops[i] ) - Vec_IntPush( vFlops, i ); - ABC_FREE( pFlops ); - ABC_FREE( pVars ); - return vFlops; -} - -/**Function************************************************************* - - Synopsis [Performs proof-based abstraction using BMC of the given depth.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Saig_AbsCollectRegisters( Cnf_Dat_t * pCnf, int nFrames, Vec_Int_t * vCore ) -{ - Aig_Obj_t * pObj; - Vec_Int_t * vFlops; - int * pVars, * pFlops; - int i, iClause, iReg, * piLit; - // mark register variables - pVars = ABC_ALLOC( int, pCnf->nVars ); - for ( i = 0; i < pCnf->nVars; i++ ) - pVars[i] = -1; - Saig_ManForEachLi( pCnf->pMan, pObj, i ) - pVars[ pCnf->pVarNums[pObj->Id] ] = i; - Saig_ManForEachLo( pCnf->pMan, pObj, i ) - pVars[ pCnf->pVarNums[pObj->Id] ] = i; - // mark used registers - pFlops = ABC_CALLOC( int, Aig_ManRegNum(pCnf->pMan) ); - Vec_IntForEachEntry( vCore, iClause, i ) - { - // skip auxiliary clauses - if ( iClause >= pCnf->nClauses * nFrames ) - continue; - // consider the clause - iClause = iClause % pCnf->nClauses; - for ( piLit = pCnf->pClauses[iClause]; piLit < pCnf->pClauses[iClause+1]; piLit++ ) - { - iReg = pVars[ lit_var(*piLit) ]; - if ( iReg >= 0 ) - pFlops[iReg] = 1; - } - } - // collect registers - vFlops = Vec_IntAlloc( Aig_ManRegNum(pCnf->pMan) ); - for ( i = 0; i < Aig_ManRegNum(pCnf->pMan); i++ ) - if ( pFlops[i] ) - Vec_IntPush( vFlops, i ); - ABC_FREE( pFlops ); - ABC_FREE( pVars ); - return vFlops; -} - -/**Function************************************************************* - - Synopsis [Performs proof-based abstraction using BMC of the given depth.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Saig_AbsFreeCnfs( Vec_Ptr_t * vFrames ) -{ - Cnf_Dat_t * pCnf; - int i; - Vec_PtrForEachEntry( vFrames, pCnf, i ) - { - Aig_ManStop( pCnf->pMan ); - Cnf_DataFree( pCnf ); - } - Vec_PtrFree( vFrames ); -} - -/**Function************************************************************* - - Synopsis [Performs proof-based abstraction using BMC of the given depth.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Saig_AbsExtendOneStep( Aig_Man_t * p, Vec_Int_t * vFlops ) -{ - Vec_Ptr_t * vFlopPtrs, * vSupp; - Aig_Obj_t * pObj; - int i, Entry; - // collect latch inputs - vFlopPtrs = Vec_PtrAlloc( 1000 ); - Vec_IntForEachEntry( vFlops, Entry, i ) - { - Vec_PtrPush( vFlopPtrs, Saig_ManLi(p, Entry) ); - pObj = Saig_ManLo(p, Entry); - pObj->fMarkA = 1; - } - // collect latch outputs - vSupp = Vec_PtrAlloc( 1000 ); - Aig_SupportNodes( p, (Aig_Obj_t **)Vec_PtrArray(vFlopPtrs), Vec_PtrSize(vFlopPtrs), vSupp ); - Vec_PtrFree( vFlopPtrs ); - // mark influencing flops - Vec_PtrForEachEntry( vSupp, pObj, i ) - pObj->fMarkA = 1; - Vec_PtrFree( vSupp ); - // reload flops - Vec_IntClear( vFlops ); - Aig_ManForEachPi( p, pObj, i ) - { - if ( pObj->fMarkA == 0 ) - continue; - pObj->fMarkA = 0; - if ( Aig_ObjPioNum(pObj)-Saig_ManPiNum(p) >= 0 ) - Vec_IntPush( vFlops, Aig_ObjPioNum(pObj)-Saig_ManPiNum(p) ); - } } /**Function************************************************************* @@ -649,11 +95,15 @@ void Saig_AbsExtendOneStep( Aig_Man_t * p, Vec_Int_t * vFlops ) SeeAlso [] ***********************************************************************/ -Ssw_Cex_t * Saig_ManCexShrink( Aig_Man_t * p, Aig_Man_t * pAbs, Ssw_Cex_t * pCexAbs ) +Abc_Cex_t * Saig_ManCexRemap( Aig_Man_t * p, Aig_Man_t * pAbs, Abc_Cex_t * pCexAbs ) { - Ssw_Cex_t * pCex; + Abc_Cex_t * pCex; Aig_Obj_t * pObj; int i, f; + if ( !Ssw_SmlRunCounterExample( pAbs, pCexAbs ) ) + printf( "Saig_ManCexRemap(): The intial counter-example is invalid.\n" ); + else + printf( "Saig_ManCexRemap(): The intial counter-example is correct.\n" ); // start the counter-example pCex = Ssw_SmlAllocCounterExample( Aig_ManRegNum(p), Saig_ManPiNum(p), pCexAbs->iFrame+1 ); pCex->iFrame = pCexAbs->iFrame; @@ -672,7 +122,7 @@ Ssw_Cex_t * Saig_ManCexShrink( Aig_Man_t * p, Aig_Man_t * pAbs, Ssw_Cex_t * pCex // verify the counter example if ( !Ssw_SmlRunCounterExample( p, pCex ) ) { - printf( "Saig_ManCexShrink(): Counter-example is invalid.\n" ); + printf( "Saig_ManCexRemap(): Counter-example is invalid.\n" ); Ssw_SmlFreeCounterExample( pCex ); pCex = NULL; } @@ -695,7 +145,7 @@ Ssw_Cex_t * Saig_ManCexShrink( Aig_Man_t * p, Aig_Man_t * pAbs, Ssw_Cex_t * pCex SeeAlso [] ***********************************************************************/ -int Saig_ManFirstFlopPi( Aig_Man_t * p, Aig_Man_t * pAbs ) +int Saig_ManCexFirstFlopPi( Aig_Man_t * p, Aig_Man_t * pAbs ) { Aig_Obj_t * pObj; int i; @@ -710,7 +160,7 @@ int Saig_ManFirstFlopPi( Aig_Man_t * p, Aig_Man_t * pAbs ) /**Function************************************************************* - Synopsis [Performs proof-based abstraction using BMC of the given depth.] + Synopsis [Refines abstraction using one step.] Description [] @@ -719,15 +169,12 @@ int Saig_ManFirstFlopPi( Aig_Man_t * p, Aig_Man_t * pAbs ) SeeAlso [] ***********************************************************************/ -Aig_Man_t * Saig_ManProofRefine( Aig_Man_t * p, Aig_Man_t * pAbs, Vec_Int_t * vFlops, int nFrames, int nConfMaxOne, int fUseBdds, int fUseDprove, int * pnUseStart, int fVerbose ) +Aig_Man_t * Saig_ManCexRefine( Aig_Man_t * p, Aig_Man_t * pAbs, Vec_Int_t * vFlops, int nFrames, int nConfMaxOne, int fUseBdds, int fUseDprove, int fVerbose, int * pnUseStart, int * piRetValue, int * pnFrames ) { - extern void Saig_BmcPerform( Aig_Man_t * pAig, int nStart, int nFramesMax, int nNodesMax, int nTimeOut, int nConfMaxOne, int nConfMaxAll, int fVerbose, int fVerbOverwrite ); - extern Vec_Int_t * Saig_ManExtendCounterExampleTest( Aig_Man_t * p, int iFirstPi, void * pCex, int fVerbose ); - extern int Aig_ManVerifyUsingBdds( Aig_Man_t * p, int nBddMax, int nIterMax, int fPartition, int fReorder, int fReorderImage, int fVerbose, int fSilent ); - - Vec_Int_t * vFlopsNew;//, * vPiToReg; -// Aig_Obj_t * pObj; - int i, Entry;//, iFlop; + extern int Saig_BmcPerform( Aig_Man_t * pAig, int nStart, int nFramesMax, int nNodesMax, int nTimeOut, int nConfMaxOne, int nConfMaxAll, int fVerbose, int fVerbOverwrite, int * piFrames ); + Vec_Int_t * vFlopsNew; + int i, Entry; + *piRetValue = -1; if ( fUseDprove && Aig_ManRegNum(pAbs) > 0 ) { Fra_Sec_t SecPar, * pSecPar = &SecPar; @@ -738,66 +185,92 @@ Aig_Man_t * Saig_ManProofRefine( Aig_Man_t * p, Aig_Man_t * pAbs, Vec_Int_t * vF } else if ( fUseBdds && (Aig_ManRegNum(pAbs) > 0 && Aig_ManRegNum(pAbs) <= 80) ) { - int nBddMax = 1000000; - int nIterMax = nFrames; - int fPartition = 1; - int fReorder = 1; - int fReorderImage = 1; - Aig_ManVerifyUsingBdds( pAbs, nBddMax, nIterMax, fPartition, fReorder, fReorderImage, fVerbose, 0 ); + Saig_ParBbr_t Pars, * pPars = &Pars; + Bbr_ManSetDefaultParams( pPars ); + pPars->TimeLimit = 0; + pPars->nBddMax = 1000000; + pPars->nIterMax = nFrames; + pPars->fPartition = 1; + pPars->fReorder = 1; + pPars->fReorderImage = 1; + pPars->fVerbose = fVerbose; + pPars->fSilent = 0; + Aig_ManVerifyUsingBdds( pAbs, pPars ); } else - Saig_BmcPerform( pAbs, pnUseStart? *pnUseStart: 0, nFrames, 2000, 20, nConfMaxOne, 1000000, fVerbose, 0 ); + { + Saig_BmcPerform( pAbs, pnUseStart? *pnUseStart: 0, nFrames, 2000, 0, nConfMaxOne, 0, fVerbose, 0, pnFrames ); + } if ( pAbs->pSeqModel == NULL ) return NULL; if ( pnUseStart ) - *pnUseStart = ((Fra_Cex_t *)pAbs->pSeqModel)->iFrame; -// vFlopsNew = Saig_ManExtendCounterExampleTest( pAbs, Saig_ManPiNum(p), pAbs->pSeqModel, fVerbose ); - vFlopsNew = Saig_ManExtendCounterExampleTest( pAbs, Saig_ManFirstFlopPi(p, pAbs), pAbs->pSeqModel, fVerbose ); + *pnUseStart = pAbs->pSeqModel->iFrame; + vFlopsNew = Saig_ManExtendCounterExampleTest( pAbs, Saig_ManCexFirstFlopPi(p, pAbs), pAbs->pSeqModel, fVerbose ); + if ( vFlopsNew == NULL ) + return NULL; if ( Vec_IntSize(vFlopsNew) == 0 ) { printf( "Discovered a true counter-example!\n" ); - p->pSeqModel = Saig_ManCexShrink( p, pAbs, pAbs->pSeqModel ); + p->pSeqModel = Saig_ManCexRemap( p, pAbs, pAbs->pSeqModel ); Vec_IntFree( vFlopsNew ); + *piRetValue = 0; return NULL; } + // vFlopsNew contains PI numbers that should be kept in pAbs if ( fVerbose ) printf( "Adding %d registers to the abstraction.\n", Vec_IntSize(vFlopsNew) ); - // vFlopsNew contains PI number that should be kept in pAbs -/* - // for each additional PI, collect the number of a register it stands for - Vec_IntForEachEntry( vFlops, Entry, i ) - { - pObj = Saig_ManLo( p, Entry ); - pObj->fMarkA = 1; - } - vPiToReg = Vec_IntAlloc( 1000 ); - Aig_ManForEachPi( p, pObj, i ) - { - if ( pObj->fMarkA ) - { - pObj->fMarkA = 0; - continue; - } - if ( i < Saig_ManPiNum(p) ) - Vec_IntPush( vPiToReg, -1 ); - else - Vec_IntPush( vPiToReg, Aig_ObjPioNum(pObj)-Saig_ManPiNum(p) ); - } - // collect registers + // add to the abstraction Vec_IntForEachEntry( vFlopsNew, Entry, i ) { - iFlop = Vec_IntEntry( vPiToReg, Entry ); - assert( iFlop >= 0 ); - assert( iFlop < Aig_ManRegNum(p) ); - Vec_IntPush( vFlops, iFlop ); + Entry = Vec_IntEntry(pAbs->vCiNumsOrig, Entry); + assert( Entry >= Saig_ManPiNum(p) ); + assert( Entry < Aig_ManPiNum(p) ); + Vec_IntPush( vFlops, Entry-Saig_ManPiNum(p) ); } - Vec_IntFree( vPiToReg ); Vec_IntFree( vFlopsNew ); Vec_IntSort( vFlops, 0 ); Vec_IntForEachEntryStart( vFlops, Entry, i, 1 ) assert( Vec_IntEntry(vFlops, i-1) != Entry ); -*/ + + return Saig_ManDeriveAbstraction( p, vFlops ); +} + +/**Function************************************************************* + + Synopsis [Refines abstraction using one step.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_ManCexRefineStep( Aig_Man_t * p, Vec_Int_t * vFlops, Abc_Cex_t * pCex, int fVerbose ) +{ + Aig_Man_t * pAbs; + Vec_Int_t * vFlopsNew; + int i, Entry; + pAbs = Saig_ManDeriveAbstraction( p, vFlops ); + vFlopsNew = Saig_ManExtendCounterExampleTest( pAbs, Saig_ManCexFirstFlopPi(p, pAbs), pCex, fVerbose ); + if ( vFlopsNew == NULL ) + { + Aig_ManStop( pAbs ); + return 0; + } + if ( Vec_IntSize(vFlopsNew) == 0 ) + { + printf( "Refinement did not happen. Discovered a true counter-example.\n" ); + printf( "Remapping counter-example from %d to %d primary inputs.\n", Aig_ManPiNum(pAbs), Aig_ManPiNum(p) ); + p->pSeqModel = Saig_ManCexRemap( p, pAbs, pCex ); + Vec_IntFree( vFlopsNew ); + Aig_ManStop( pAbs ); + return 0; + } + if ( fVerbose ) + printf( "Adding %d registers to the abstraction.\n", Vec_IntSize(vFlopsNew) ); + // vFlopsNew contains PI number that should be kept in pAbs // add to the abstraction Vec_IntForEachEntry( vFlopsNew, Entry, i ) { @@ -807,17 +280,13 @@ Aig_Man_t * Saig_ManProofRefine( Aig_Man_t * p, Aig_Man_t * pAbs, Vec_Int_t * vF Vec_IntPush( vFlops, Entry-Saig_ManPiNum(p) ); } Vec_IntFree( vFlopsNew ); - - Vec_IntSort( vFlops, 0 ); - Vec_IntForEachEntryStart( vFlops, Entry, i, 1 ) - assert( Vec_IntEntry(vFlops, i-1) != Entry ); - - return Saig_ManAbstraction( p, vFlops ); + Aig_ManStop( pAbs ); + return 1; } /**Function************************************************************* - Synopsis [Performs proof-based abstraction using BMC of the given depth.] + Synopsis [Computes the flops to remain after abstraction.] Description [] @@ -826,138 +295,67 @@ Aig_Man_t * Saig_ManProofRefine( Aig_Man_t * p, Aig_Man_t * pAbs, Vec_Int_t * vF SeeAlso [] ***********************************************************************/ -Vec_Int_t * Saig_ManProofAbstraction_int( Aig_Man_t * p, Gia_ParAbs_t * pPars ) +Vec_Int_t * Saig_ManCexAbstractionFlops( Aig_Man_t * p, Gia_ParAbs_t * pPars ) { - Aig_Man_t * pResult, * pTemp; - Cnf_Dat_t * pCnf; - Vec_Ptr_t * vFrames; - sat_solver * pSat; - Vec_Int_t * vCore; + int nUseStart = 0; + Aig_Man_t * pAbs, * pTemp; Vec_Int_t * vFlops; - int Iter, clk = clock(), clk2 = clock(); + int Iter, clk = clock(), clk2 = clock();//, iFlop; assert( Aig_ManRegNum(p) > 0 ); + if ( pPars->fVerbose ) + printf( "Performing counter-example-based refinement.\n" ); Aig_ManSetPioNumbers( p ); - - if ( pPars->fSkipProof ) - { -// assert( 0 ); - if ( pPars->fVerbose ) - printf( "Performing counter-example-based refinement.\n" ); -// vFlops = Vec_IntStartNatural( 100 ); -// Vec_IntPush( vFlops, 0 ); - vFlops = Vec_IntStartNatural( 1 ); - } - else - { - if ( pPars->fVerbose ) - printf( "Performing proof-based abstraction with %d frames and %d max conflicts.\n", pPars->nFramesMax, pPars->nConfMax ); - if ( pPars->fDynamic ) - { - // create CNF for the frames - vFrames = Saig_AbsCreateFrames( p, pPars->nFramesMax, pPars->fVerbose ); - // create dynamic solver - pSat = Saig_AbsCreateSolverDyn( p, vFrames ); - } - else - { - // create CNF for the AIG - pCnf = Cnf_DeriveSimple( p, Aig_ManPoNum(p) ); - // create SAT solver for the unrolled AIG - pSat = Saig_AbsCreateSolver( pCnf, pPars->nFramesMax ); - } - if ( pPars->fVerbose ) - { - printf( "SAT solver: Vars = %7d. Clauses = %7d. ", pSat->size, pSat->stats.clauses ); - ABC_PRT( "Time", clock() - clk2 ); - } - // compute UNSAT core - vCore = Saig_AbsSolverUnsatCore( pSat, pPars->nConfMax, pPars->fVerbose ); - sat_solver_delete( pSat ); - if ( vCore == NULL ) - { - Saig_AbsFreeCnfs( vFrames ); - return NULL; - } - // collect registers - if ( pPars->fDynamic ) - { - vFlops = Saig_AbsCollectRegistersDyn( p, vFrames, vCore ); - Saig_AbsFreeCnfs( vFrames ); - } - else - { - vFlops = Saig_AbsCollectRegisters( pCnf, pPars->nFramesMax, vCore ); - Cnf_DataFree( pCnf ); - } - Vec_IntFree( vCore ); - if ( pPars->fVerbose ) - { - printf( "The number of relevant registers is %d (out of %d). ", Vec_IntSize(vFlops), Aig_ManRegNum(p) ); - ABC_PRT( "Time", clock() - clk ); - } - } + vFlops = Vec_IntStartNatural( 1 ); /* - // extend the abstraction - if ( fExtend ) - { - if ( fVerbose ) - printf( "Support extended from %d flops to", Vec_IntSize(vFlops) ); - Saig_AbsExtendOneStep( p, vFlops ); - if ( fVerbose ) - printf( " %d flops.\n", Vec_IntSize(vFlops) ); - } + iFlop = Saig_ManFindFirstFlop( p ); + assert( iFlop >= 0 ); + vFlops = Vec_IntAlloc( 1 ); + Vec_IntPush( vFlops, iFlop ); */ // create the resulting AIG - pResult = Saig_ManAbstraction( p, vFlops ); - - if ( pPars->fExtend ) + pAbs = Saig_ManDeriveAbstraction( p, vFlops ); + if ( !pPars->fVerbose ) { - int nUseStart = 0; - if ( !pPars->fVerbose ) + printf( "Init : " ); + Aig_ManPrintStats( pAbs ); + } + printf( "Refining abstraction...\n" ); + for ( Iter = 0; ; Iter++ ) + { + pTemp = Saig_ManCexRefine( p, pAbs, vFlops, pPars->nFramesBmc, pPars->nConfMaxBmc, pPars->fUseBdds, pPars->fUseDprove, pPars->fVerbose, pPars->fUseStart?&nUseStart:NULL, &pPars->Status, &pPars->nFramesDone ); + if ( pTemp == NULL ) { - printf( "Init : " ); - Aig_ManPrintStats( pResult ); + ABC_FREE( p->pSeqModel ); + p->pSeqModel = pAbs->pSeqModel; + pAbs->pSeqModel = NULL; + Aig_ManStop( pAbs ); + break; } - printf( "Refining abstraction...\n" ); - for ( Iter = 0; ; Iter++ ) - { - pTemp = Saig_ManProofRefine( p, pResult, vFlops, pPars->nFramesBmc, pPars->nConfMaxBmc, pPars->fUseBdds, pPars->fUseDprove, pPars->fUseStart?&nUseStart:NULL, pPars->fVerbose ); - if ( pTemp == NULL ) - break; - Aig_ManStop( pResult ); - pResult = pTemp; - printf( "ITER %4d : ", Iter ); - if ( !pPars->fVerbose ) - Aig_ManPrintStats( pResult ); -// else -// printf( " -----------------------------------------------------\n" ); - // output the intermediate result of abstraction - Ioa_WriteAiger( pResult, "gabs.aig", 0, 0 ); + Aig_ManStop( pAbs ); + pAbs = pTemp; + printf( "ITER %4d : ", Iter ); + if ( !pPars->fVerbose ) + Aig_ManPrintStats( pAbs ); + // output the intermediate result of abstraction + Ioa_WriteAiger( pAbs, "gabs.aig", 0, 0 ); // printf( "Intermediate abstracted model was written into file \"%s\".\n", "gabs.aig" ); - // check if the ratio is reached - if ( 100.0*(Aig_ManRegNum(p)-Aig_ManRegNum(pTemp))/Aig_ManRegNum(p) < 1.0*pPars->nRatio ) - { - printf( "Refinements is stopped because flop reduction is less than %d%%\n", pPars->nRatio ); - Aig_ManStop( pResult ); - pResult = NULL; - break; - } + // check if the ratio is reached + if ( 100.0*(Aig_ManRegNum(p)-Aig_ManRegNum(pAbs))/Aig_ManRegNum(p) < 1.0*pPars->nRatio ) + { + printf( "Refinements is stopped because flop reduction is less than %d%%\n", pPars->nRatio ); + Aig_ManStop( pAbs ); + pAbs = NULL; + Vec_IntFree( vFlops ); + vFlops = NULL; + break; } } - // write the final result - if ( pResult ) - Aig_ManStop( pResult ); - else - { - Vec_IntFree( vFlops ); - vFlops = NULL; - } return vFlops; } /**Function************************************************************* - Synopsis [Performs proof-based abstraction using BMC of the given depth.] + Synopsis [Performs counter-example-based abstraction.] Description [] @@ -966,15 +364,15 @@ Vec_Int_t * Saig_ManProofAbstraction_int( Aig_Man_t * p, Gia_ParAbs_t * pPars ) SeeAlso [] ***********************************************************************/ -Aig_Man_t * Saig_ManProofAbstraction( Aig_Man_t * p, Gia_ParAbs_t * pPars ) +Aig_Man_t * Saig_ManCexAbstraction( Aig_Man_t * p, Gia_ParAbs_t * pPars ) { Vec_Int_t * vFlops; Aig_Man_t * pAbs = NULL; - vFlops = Saig_ManProofAbstraction_int( p, pPars ); + vFlops = Saig_ManCexAbstractionFlops( p, pPars ); // write the final result if ( vFlops ) { - pAbs = Saig_ManAbstraction( p, vFlops ); + pAbs = Saig_ManDeriveAbstraction( p, vFlops ); Ioa_WriteAiger( pAbs, "gabs.aig", 0, 0 ); printf( "Final abstracted model was written into file \"%s\".\n", "gabs.aig" ); Vec_IntFree( vFlops ); @@ -987,3 +385,5 @@ Aig_Man_t * Saig_ManProofAbstraction( Aig_Man_t * p, Gia_ParAbs_t * pPars ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigAbs2.c b/src/aig/saig/saigAbs2.c new file mode 100644 index 00000000..a4d0f973 --- /dev/null +++ b/src/aig/saig/saigAbs2.c @@ -0,0 +1,237 @@ +/**CFile**************************************************************** + + FileName [saigAbs.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Sequential AIG package.] + + Synopsis [Counter-example-based abstraction with constraints.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: saigAbs.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "saig.h" +#include "ssw.h" +#include "fra.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +extern int Saig_ManFindFirstFlop( Aig_Man_t * p ); +extern Aig_Man_t * Saig_ManCexRefine( Aig_Man_t * p, Aig_Man_t * pAbs, Vec_Int_t * vFlops, + int nFrames, int nConfMaxOne, int fUseBdds, int fUseDprove, int fVerbose, int * pnUseStart, + int * piRetValue, int * pnFrames ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Returns the array of constraint numbers that are violated.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Saig_ManFindViolatedConstrs( Aig_Man_t * p, Abc_Cex_t * pCexAbs ) +{ + Vec_Int_t * vFailed; + Aig_Obj_t * pObj, * pObjRi, * pObjRo; + int * pPoMap, i, k, iBit; + pPoMap = ABC_CALLOC( int, Saig_ManPoNum(p) ); + Aig_ManCleanMarkA(p); + Saig_ManForEachLo( p, pObj, i ) + pObj->fMarkA = 0; + assert( pCexAbs->nBits == pCexAbs->nRegs + (pCexAbs->iFrame + 1) * pCexAbs->nPis ); + for ( i = 0; i <= pCexAbs->iFrame; i++ ) + { + iBit = pCexAbs->nRegs + i * pCexAbs->nPis; + Saig_ManForEachPi( p, pObj, k ) + pObj->fMarkA = Aig_InfoHasBit(pCexAbs->pData, iBit++); + Aig_ManForEachNode( p, pObj, k ) + pObj->fMarkA = (Aig_ObjFanin0(pObj)->fMarkA ^ Aig_ObjFaninC0(pObj)) & + (Aig_ObjFanin1(pObj)->fMarkA ^ Aig_ObjFaninC1(pObj)); + Aig_ManForEachPo( p, pObj, k ) + pObj->fMarkA = Aig_ObjFanin0(pObj)->fMarkA ^ Aig_ObjFaninC0(pObj); + Saig_ManForEachPo( p, pObj, k ) + pPoMap[k] |= pObj->fMarkA; + Saig_ManForEachLiLo( p, pObjRi, pObjRo, k ) + pObjRo->fMarkA = pObjRi->fMarkA; + } + Aig_ManCleanMarkA(p); + // collect numbers of failed constraints + vFailed = Vec_IntAlloc( Saig_ManPoNum(p) ); + Saig_ManForEachPo( p, pObj, k ) + if ( pPoMap[k] ) + Vec_IntPush( vFailed, k ); + ABC_FREE( pPoMap ); + return vFailed; +} + +/**Function************************************************************* + + Synopsis [Computes the flops to remain after abstraction.] + + Description [Updates the set of included constraints.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Saig_ManConCexAbstractionFlops( Aig_Man_t * pInit, Gia_ParAbs_t * pPars, Vec_Int_t * vConstrs ) +{ + int nUseStart = 0; + Aig_Man_t * pCur, * pAbs, * pTemp; + Vec_Int_t * vFlops, * vFlopsCopy, * vConstrsToAdd; + int i, Entry, iFlop, Iter, clk = clock(), clk2 = clock(); + assert( Aig_ManRegNum(pInit) > 0 ); + if ( pPars->fVerbose ) + printf( "Performing counter-example-based refinement with constraints.\n" ); +// Aig_ManSetPioNumbers( p ); + // create constrained AIG + pCur = Saig_ManDupFoldConstrs( pInit, vConstrs ); + assert( Saig_ManPoNum(pCur) == 1 ); + printf( "cur>>> " ); Aig_ManPrintStats( pCur ); + // start the flop map + iFlop = Saig_ManFindFirstFlop( pCur ); + assert( iFlop >= 0 ); +// vFlops = Vec_IntStartNatural( 1 ); + vFlops = Vec_IntAlloc( 1 ); + Vec_IntPush( vFlops, iFlop ); + // create the abstraction + pAbs = Saig_ManDeriveAbstraction( pCur, vFlops ); + printf( "abs>>> " ); Aig_ManPrintStats( pAbs ); + if ( !pPars->fVerbose ) + { + printf( "Init : " ); + Aig_ManPrintStats( pAbs ); + } + printf( "Refining abstraction...\n" ); + for ( Iter = 0; ; Iter++ ) + { + while ( 1 ) + { + vFlopsCopy = Vec_IntDup( vFlops ); + pTemp = Saig_ManCexRefine( pCur, pAbs, vFlops, pPars->nFramesBmc, pPars->nConfMaxBmc, pPars->fUseBdds, pPars->fUseDprove, pPars->fVerbose, pPars->fUseStart?&nUseStart:NULL, &pPars->Status, &pPars->nFramesDone ); + if ( pTemp == NULL ) + { + Vec_IntFree( vFlopsCopy ); + break; + } + vConstrsToAdd = Saig_ManFindViolatedConstrs( pInit, pAbs->pSeqModel ); + if ( Vec_IntSize(vConstrsToAdd) == 0 ) + { + Vec_IntFree( vConstrsToAdd ); + Vec_IntFree( vFlopsCopy ); + break; + } + // add the constraints to the base set + Vec_IntForEachEntry( vConstrsToAdd, Entry, i ) + { +// assert( Vec_IntFind(vConstrs, Entry) == -1 ); + Vec_IntPushUnique( vConstrs, Entry ); + } + printf( "Adding %3d constraints. The total is %3d (out of %3d).\n", + Vec_IntSize(vConstrsToAdd), Vec_IntSize(vConstrs), Saig_ManPoNum(pInit)-1 ); + Vec_IntFree( vConstrsToAdd ); + // update the current one + Aig_ManStop( pCur ); + pCur = Saig_ManDupFoldConstrs( pInit, vConstrs ); + printf( "cur>>> " ); Aig_ManPrintStats( pCur ); + // update the flop map + Vec_IntFree( vFlops ); + vFlops = vFlopsCopy; +// Vec_IntFree( vFlopsCopy ); +// vFlops = vFlops; + // update abstraction + Aig_ManStop( pAbs ); + pAbs = Saig_ManDeriveAbstraction( pCur, vFlops ); + printf( "abs>>> " ); Aig_ManPrintStats( pAbs ); + } + Aig_ManStop( pAbs ); + if ( pTemp == NULL ) + break; + pAbs = pTemp; + printf( "ITER %4d : ", Iter ); + if ( !pPars->fVerbose ) + Aig_ManPrintStats( pAbs ); + // output the intermediate result of abstraction + Ioa_WriteAiger( pAbs, "gabs.aig", 0, 0 ); +// printf( "Intermediate abstracted model was written into file \"%s\".\n", "gabs.aig" ); + // check if the ratio is reached + if ( 100.0*(Aig_ManRegNum(pCur)-Aig_ManRegNum(pAbs))/Aig_ManRegNum(pCur) < 1.0*pPars->nRatio ) + { + printf( "Refinements is stopped because flop reduction is less than %d%%\n", pPars->nRatio ); + Aig_ManStop( pAbs ); + pAbs = NULL; + Vec_IntFree( vFlops ); + vFlops = NULL; + break; + } + } + ABC_FREE( pInit->pSeqModel ); + pInit->pSeqModel = pCur->pSeqModel; + pCur->pSeqModel = NULL; + Aig_ManStop( pCur ); + return vFlops; +} + +/**Function************************************************************* + + Synopsis [Performs counter-example-based abstraction.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Saig_ManConCexAbstraction( Aig_Man_t * p, Gia_ParAbs_t * pPars ) +{ + Vec_Int_t * vFlops, * vConstrs; + Aig_Man_t * pCur, * pAbs = NULL; + assert( Saig_ManPoNum(p) > 1 ); // should contain constraint outputs + // start included constraints + vConstrs = Vec_IntAlloc( 100 ); + // perform refinement + vFlops = Saig_ManConCexAbstractionFlops( p, pPars, vConstrs ); + // write the final result + if ( vFlops ) + { + pCur = Saig_ManDupFoldConstrs( p, vConstrs ); + pAbs = Saig_ManDeriveAbstraction( pCur, vFlops ); + Aig_ManStop( pCur ); + + Ioa_WriteAiger( pAbs, "gabs.aig", 0, 0 ); + printf( "Final abstracted model was written into file \"%s\".\n", "gabs.aig" ); + Vec_IntFree( vFlops ); + } + Vec_IntFree( vConstrs ); + return pAbs; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigBmc.c b/src/aig/saig/saigBmc.c index ac1cbe5b..8aa3af80 100644 --- a/src/aig/saig/saigBmc.c +++ b/src/aig/saig/saigBmc.c @@ -19,375 +19,72 @@ ***********************************************************************/ #include "saig.h" +#include "fra.h" #include "cnf.h" #include "satStore.h" -#include "ssw.h" + +ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -#define AIG_VISITED ((Aig_Obj_t *)(ABC_PTRUINT_T)1) - -typedef struct Saig_Bmc_t_ Saig_Bmc_t; -struct Saig_Bmc_t_ -{ - // parameters - int nFramesMax; // the max number of timeframes to consider - int nNodesMax; // the max number of nodes to add - int nConfMaxOne; // the max number of conflicts at a target - int nConfMaxAll; // the max number of conflicts for all targets - int fVerbose; // enables verbose output - // AIG managers - Aig_Man_t * pAig; // the user's AIG manager - Aig_Man_t * pFrm; // Frames manager - Vec_Ptr_t * vVisited; // nodes visited in Frames - // node mapping - int nObjs; // the largest number of an AIG object - Vec_Ptr_t * vAig2Frm; // mapping of AIG nodees into Frames nodes -// Vec_Str_t * vAig2Frm2; // mapping of AIG nodees into Frames nodes - // SAT solver - sat_solver * pSat; // SAT solver - int nSatVars; // the number of used SAT variables - Vec_Int_t * vObj2Var; // mapping of frames objects in CNF variables - // subproblems - Vec_Ptr_t * vTargets; // targets to be solved in this interval - int iFramePrev; // previous frame - int iFrameLast; // last frame - int iOutputLast; // last output - int iFrameFail; // failed frame - int iOutputFail; // failed output -}; - -static inline int Saig_BmcSatNum( Saig_Bmc_t * p, Aig_Obj_t * pObj ) { return Vec_IntGetEntry( p->vObj2Var, pObj->Id ); } -static inline void Saig_BmcSetSatNum( Saig_Bmc_t * p, Aig_Obj_t * pObj, int Num ) { Vec_IntSetEntry(p->vObj2Var, pObj->Id, Num); } - -static inline Aig_Obj_t * Saig_BmcObjFrame( Saig_Bmc_t * p, Aig_Obj_t * pObj, int i ) { return Vec_PtrGetEntry( p->vAig2Frm, p->nObjs*i+pObj->Id ); } -static inline void Saig_BmcObjSetFrame( Saig_Bmc_t * p, Aig_Obj_t * pObj, int i, Aig_Obj_t * pNode ) { Vec_PtrSetEntry( p->vAig2Frm, p->nObjs*i+pObj->Id, pNode ); } - -static inline Aig_Obj_t * Saig_BmcObjChild0( Saig_Bmc_t * p, Aig_Obj_t * pObj, int i ) { assert( !Aig_IsComplement(pObj) ); return Aig_NotCond(Saig_BmcObjFrame(p, Aig_ObjFanin0(pObj), i), Aig_ObjFaninC0(pObj)); } -static inline Aig_Obj_t * Saig_BmcObjChild1( Saig_Bmc_t * p, Aig_Obj_t * pObj, int i ) { assert( !Aig_IsComplement(pObj) ); return Aig_NotCond(Saig_BmcObjFrame(p, Aig_ObjFanin1(pObj), i), Aig_ObjFaninC1(pObj)); } - //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// -#define ABS_ZER 1 -#define ABS_ONE 2 -#define ABS_UND 3 - -static inline int Abs_ManSimInfoNot( int Value ) -{ - if ( Value == ABS_ZER ) - return ABS_ONE; - if ( Value == ABS_ONE ) - return ABS_ZER; - return ABS_UND; -} - -static inline int Abs_ManSimInfoAnd( int Value0, int Value1 ) -{ - if ( Value0 == ABS_ZER || Value1 == ABS_ZER ) - return ABS_ZER; - if ( Value0 == ABS_ONE && Value1 == ABS_ONE ) - return ABS_ONE; - return ABS_UND; -} - -static inline int Abs_ManSimInfoGet( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame ) -{ - unsigned * pInfo = Vec_PtrEntry( vSimInfo, iFrame ); - return 3 & (pInfo[Aig_ObjId(pObj) >> 4] >> ((Aig_ObjId(pObj) & 15) << 1)); -} - -static inline void Abs_ManSimInfoSet( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame, int Value ) -{ - unsigned * pInfo = Vec_PtrEntry( vSimInfo, iFrame ); - assert( Value >= ABS_ZER && Value <= ABS_UND ); - Value ^= Abs_ManSimInfoGet( vSimInfo, pObj, iFrame ); - pInfo[Aig_ObjId(pObj) >> 4] ^= (Value << ((Aig_ObjId(pObj) & 15) << 1)); -} - /**Function************************************************************* - Synopsis [Performs ternary simulation for one node.] + Synopsis [Create timeframes of the manager for BMC.] - Description [] + Description [The resulting manager is combinational. POs correspond to \ + the property outputs in each time-frame.] SideEffects [] SeeAlso [] ***********************************************************************/ -int Abs_ManExtendOneEval_rec( Vec_Ptr_t * vSimInfo, Aig_Man_t * p, Aig_Obj_t * pObj, int iFrame ) +Aig_Man_t * Saig_ManFramesBmc( Aig_Man_t * pAig, int nFrames ) { - int Value0, Value1, Value; - Value = Abs_ManSimInfoGet( vSimInfo, pObj, iFrame ); - if ( Value ) - return Value; - if ( Aig_ObjIsPi(pObj) ) - { - assert( Saig_ObjIsLo(p, pObj) ); - Value = Abs_ManExtendOneEval_rec( vSimInfo, p, Saig_ObjLoToLi(p, pObj), iFrame-1 ); - Abs_ManSimInfoSet( vSimInfo, pObj, iFrame, Value ); - return Value; - } - Value0 = Abs_ManExtendOneEval_rec( vSimInfo, p, Aig_ObjFanin0(pObj), iFrame ); - if ( Aig_ObjFaninC0(pObj) ) - Value0 = Abs_ManSimInfoNot( Value0 ); - if ( Aig_ObjIsPo(pObj) ) - { - Abs_ManSimInfoSet( vSimInfo, pObj, iFrame, Value0 ); - return Value0; - } - assert( Aig_ObjIsNode(pObj) ); - if ( Value0 == ABS_ZER ) - Value = ABS_ZER; - else - { - Value1 = Abs_ManExtendOneEval_rec( vSimInfo, p, Aig_ObjFanin1(pObj), iFrame ); - if ( Aig_ObjFaninC1(pObj) ) - Value1 = Abs_ManSimInfoNot( Value1 ); - Value = Abs_ManSimInfoAnd( Value0, Value1 ); - } - Abs_ManSimInfoSet( vSimInfo, pObj, iFrame, Value ); - assert( Value ); - return Value; -} - -/**Function************************************************************* - - Synopsis [Performs ternary simulation for one design.] - - Description [The returned array contains the result of ternary - simulation for all the frames where the output could be proved 0.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Abs_ManTernarySimulate( Aig_Man_t * p, int nFramesMax, int fVerbose ) -{ - Vec_Ptr_t * vSimInfo; - Aig_Obj_t * pObj; - int i, f, nFramesLimit, nFrameWords; - int clk = clock(); - assert( Aig_ManRegNum(p) > 0 ); - // the maximum number of frames will be determined to use at most 200Mb of RAM - nFramesLimit = 1 + (200000000 * 4)/Aig_ManObjNum(p); - nFramesLimit = ABC_MIN( nFramesLimit, nFramesMax ); - nFrameWords = Aig_BitWordNum( 2 * Aig_ManObjNum(p) ); - // allocate simulation info - vSimInfo = Vec_PtrAlloc( nFramesLimit ); - for ( f = 0; f < nFramesLimit; f++ ) - { - Vec_PtrPush( vSimInfo, ABC_CALLOC(unsigned, nFrameWords) ); - if ( f == 0 ) - { - Saig_ManForEachLo( p, pObj, i ) - Abs_ManSimInfoSet( vSimInfo, pObj, 0, ABS_ZER ); - } - Abs_ManSimInfoSet( vSimInfo, Aig_ManConst1(p), f, ABS_ONE ); - Saig_ManForEachPi( p, pObj, i ) - Abs_ManSimInfoSet( vSimInfo, pObj, f, ABS_UND ); - Saig_ManForEachPo( p, pObj, i ) - Abs_ManExtendOneEval_rec( vSimInfo, p, pObj, f ); - // check if simulation has derived at least one fail or unknown - Saig_ManForEachPo( p, pObj, i ) - if ( Abs_ManSimInfoGet(vSimInfo, pObj, f) != ABS_ZER ) - { - if ( fVerbose ) - { - printf( "Ternary sim found non-zero output in frame %d. Used %5.2f Mb. ", - f, 0.25 * (f+1) * Aig_ManObjNum(p) / (1<<20) ); - ABC_PRT( "Time", clock() - clk ); - } - return vSimInfo; - } - } - if ( fVerbose ) - { - printf( "Ternary sim proved all outputs in the first %d frames. Used %5.2f Mb. ", - nFramesLimit, 0.25 * nFramesLimit * Aig_ManObjNum(p) / (1<<20) ); - ABC_PRT( "Time", clock() - clk ); - } - return vSimInfo; -} - -/**Function************************************************************* - - Synopsis [Free the array of simulation info.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abs_ManFreeAray( Vec_Ptr_t * p ) -{ - void * pTemp; - int i; - Vec_PtrForEachEntry( p, pTemp, i ) - ABC_FREE( pTemp ); - Vec_PtrFree( p ); -} - - -/**Function************************************************************* - - Synopsis [Create manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Saig_Bmc_t * Saig_BmcManStart( Aig_Man_t * pAig, int nFramesMax, int nNodesMax, int nConfMaxOne, int nConfMaxAll, int fVerbose ) -{ - Saig_Bmc_t * p; - Aig_Obj_t * pObj; - int i, Lit; -// assert( Aig_ManRegNum(pAig) > 0 ); - p = (Saig_Bmc_t *)ABC_ALLOC( char, sizeof(Saig_Bmc_t) ); - memset( p, 0, sizeof(Saig_Bmc_t) ); - // set parameters - p->nFramesMax = nFramesMax; - p->nNodesMax = nNodesMax; - p->nConfMaxOne = nConfMaxOne; - p->nConfMaxAll = nConfMaxAll; - p->fVerbose = fVerbose; - p->pAig = pAig; - p->nObjs = Aig_ManObjNumMax(pAig); - // create node and variable mappings - p->vAig2Frm = Vec_PtrAlloc( 0 ); - Vec_PtrFill( p->vAig2Frm, 5 * p->nObjs, NULL ); - p->vObj2Var = Vec_IntAlloc( 0 ); - Vec_IntFill( p->vObj2Var, 5 * p->nObjs, 0 ); - // start the AIG manager and map primary inputs - p->pFrm = Aig_ManStart( 5 * p->nObjs ); + Aig_Man_t * pFrames; + Aig_Obj_t * pObj, * pObjLi, * pObjLo; + int i, f; + assert( Saig_ManRegNum(pAig) > 0 ); + pFrames = Aig_ManStart( Aig_ManNodeNum(pAig) * nFrames ); + // map the constant node + Aig_ManConst1(pAig)->pData = Aig_ManConst1( pFrames ); + // create variables for register outputs Saig_ManForEachLo( pAig, pObj, i ) - Saig_BmcObjSetFrame( p, pObj, 0, Aig_ManConst0(p->pFrm) ); - // create SAT solver - p->nSatVars = 1; - p->pSat = sat_solver_new(); - sat_solver_setnvars( p->pSat, 2000 ); - Lit = toLit( p->nSatVars ); - sat_solver_addclause( p->pSat, &Lit, &Lit + 1 ); - Saig_BmcSetSatNum( p, Aig_ManConst1(p->pFrm), p->nSatVars++ ); - // other data structures - p->vTargets = Vec_PtrAlloc( 0 ); - p->vVisited = Vec_PtrAlloc( 0 ); - p->iOutputFail = -1; - p->iFrameFail = -1; - return p; -} - -/**Function************************************************************* - - Synopsis [Delete manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Saig_BmcManStop( Saig_Bmc_t * p ) -{ -// Aig_Obj_t * pObj; -// int i, f, Counter = 0; -// int i, Counter = 0; -// for ( i = 0; i < p->vAig2Frm2->nSize; i++ ) -// Counter += (p->vAig2Frm2->pArray[i] != 0); -// for ( i = 0; i < p->vAig2Frm->nSize; i++ ) -// Counter += (p->vAig2Frm->pArray[i] != NULL); -// printf( "Objs = %d. Nodes = %d. Frames = %d. Used = %d. Non-empty = %d.\n", -// p->nObjs, Aig_ManNodeNum(p->pAig), p->iFrameLast, p->vAig2Frm->nSize, Counter ); - -/* - Aig_ManForEachObj( p->pAig, pObj, i ) - { - int Last = -1; - for ( f = 0; f <= p->iFrameLast; f++ ) - if ( Saig_BmcObjFrame( p, pObj, f ) ) - Last = f; - if ( i % 50 == 0 ) - printf( "%d ", Last ); - } - printf( "\n" ); -*/ - - Aig_ManStop( p->pFrm ); - Vec_PtrFree( p->vAig2Frm ); -// Vec_StrFree( p->vAig2Frm2 ); - Vec_IntFree( p->vObj2Var ); - sat_solver_delete( p->pSat ); - Vec_PtrFree( p->vTargets ); - Vec_PtrFree( p->vVisited ); - ABC_FREE( p ); -} - -/**Function************************************************************* - - Synopsis [Explores the possibility of constructing the output.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Obj_t * Saig_BmcIntervalExplore_rec( Saig_Bmc_t * p, Aig_Obj_t * pObj, int i ) -{ - Aig_Obj_t * pRes, * p0, * p1, * pConst1 = Aig_ManConst1(p->pAig); - pRes = Saig_BmcObjFrame( p, pObj, i ); - if ( pRes != NULL ) - return pRes; - if ( Saig_ObjIsPi( p->pAig, pObj ) ) - pRes = AIG_VISITED; - else if ( Saig_ObjIsLo( p->pAig, pObj ) ) - pRes = Saig_BmcIntervalExplore_rec( p, Saig_ObjLoToLi(p->pAig, pObj), i-1 ); - else if ( Aig_ObjIsPo( pObj ) ) - { - pRes = Saig_BmcIntervalExplore_rec( p, Aig_ObjFanin0(pObj), i ); - if ( pRes != AIG_VISITED ) - pRes = Saig_BmcObjChild0( p, pObj, i ); - } - else + pObj->pData = Aig_ManConst0( pFrames ); + // add timeframes + for ( f = 0; f < nFrames; f++ ) { - p0 = Saig_BmcIntervalExplore_rec( p, Aig_ObjFanin0(pObj), i ); - if ( p0 != AIG_VISITED ) - p0 = Saig_BmcObjChild0( p, pObj, i ); - p1 = Saig_BmcIntervalExplore_rec( p, Aig_ObjFanin1(pObj), i ); - if ( p1 != AIG_VISITED ) - p1 = Saig_BmcObjChild1( p, pObj, i ); - - if ( p0 == Aig_Not(p1) ) - pRes = Aig_ManConst0(p->pFrm); - else if ( Aig_Regular(p0) == pConst1 ) - pRes = (p0 == pConst1) ? p1 : Aig_ManConst0(p->pFrm); - else if ( Aig_Regular(p1) == pConst1 ) - pRes = (p1 == pConst1) ? p0 : Aig_ManConst0(p->pFrm); - else - pRes = AIG_VISITED; - - if ( pRes != AIG_VISITED && !Aig_ObjIsConst1(Aig_Regular(pRes)) ) - pRes = AIG_VISITED; + // create PI nodes for this frame + Saig_ManForEachPi( pAig, pObj, i ) + pObj->pData = Aig_ObjCreatePi( pFrames ); + // add internal nodes of this frame + Aig_ManForEachNode( pAig, pObj, i ) + pObj->pData = Aig_And( pFrames, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + // create POs for this frame + Saig_ManForEachPo( pAig, pObj, i ) + Aig_ObjCreatePo( pFrames, Aig_ObjChild0Copy(pObj) ); + if ( f == nFrames - 1 ) + break; + // save register inputs + Saig_ManForEachLi( pAig, pObj, i ) + pObj->pData = Aig_ObjChild0Copy(pObj); + // transfer to register outputs + Saig_ManForEachLiLo( pAig, pObjLi, pObjLo, i ) + pObjLo->pData = pObjLi->pData; } - Saig_BmcObjSetFrame( p, pObj, i, pRes ); - return pRes; + Aig_ManCleanup( pFrames ); + return pFrames; } /**Function************************************************************* - Synopsis [Performs the actual construction of the output.] + Synopsis [Returns the number of internal nodes that are not counted yet.] Description [] @@ -396,271 +93,88 @@ Aig_Obj_t * Saig_BmcIntervalExplore_rec( Saig_Bmc_t * p, Aig_Obj_t * pObj, int i SeeAlso [] ***********************************************************************/ -Aig_Obj_t * Saig_BmcIntervalConstruct_rec( Saig_Bmc_t * p, Aig_Obj_t * pObj, int i, Vec_Ptr_t * vVisited ) +int Saig_ManFramesCount_rec( Aig_Man_t * p, Aig_Obj_t * pObj ) { - Aig_Obj_t * pRes; - pRes = Saig_BmcObjFrame( p, pObj, i ); - if ( pRes != NULL ) - return pRes; - if ( Saig_ObjIsPi( p->pAig, pObj ) ) - pRes = Aig_ObjCreatePi(p->pFrm); - else if ( Saig_ObjIsLo( p->pAig, pObj ) ) - pRes = Saig_BmcIntervalConstruct_rec( p, Saig_ObjLoToLi(p->pAig, pObj), i-1, vVisited ); - else if ( Aig_ObjIsPo( pObj ) ) - { - Saig_BmcIntervalConstruct_rec( p, Aig_ObjFanin0(pObj), i, vVisited ); - pRes = Saig_BmcObjChild0( p, pObj, i ); - } - else - { - Saig_BmcIntervalConstruct_rec( p, Aig_ObjFanin0(pObj), i, vVisited ); - if ( Saig_BmcObjChild0(p, pObj, i) == Aig_ManConst0(p->pFrm) ) - pRes = Aig_ManConst0(p->pFrm); - else - { - Saig_BmcIntervalConstruct_rec( p, Aig_ObjFanin1(pObj), i, vVisited ); - pRes = Aig_And( p->pFrm, Saig_BmcObjChild0(p, pObj, i), Saig_BmcObjChild1(p, pObj, i) ); - } - } - assert( pRes != NULL ); - Saig_BmcObjSetFrame( p, pObj, i, pRes ); - Vec_PtrPush( vVisited, pObj ); - Vec_PtrPush( vVisited, (void *)i ); - return pRes; + if ( !Aig_ObjIsNode(pObj) ) + return 0; + if ( Aig_ObjIsTravIdCurrent(p, pObj) ) + return 0; + Aig_ObjSetTravIdCurrent(p, pObj); + return 1 + Saig_ManFramesCount_rec( p, Aig_ObjFanin0(pObj) ) + + Saig_ManFramesCount_rec( p, Aig_ObjFanin1(pObj) ); } /**Function************************************************************* - Synopsis [Adds new AIG nodes to the frames.] + Synopsis [Create timeframes of the manager for BMC.] - Description [] + Description [The resulting manager is combinational. POs correspond to + the property outputs in each time-frame. + The unrolling is stopped as soon as the number of nodes in the frames + exceeds the given maximum size.] SideEffects [] SeeAlso [] ***********************************************************************/ -void Saig_BmcInterval( Saig_Bmc_t * p ) +Aig_Man_t * Saig_ManFramesBmcLimit( Aig_Man_t * pAig, int nFrames, int nSizeMax ) { - Aig_Obj_t * pTarget; - Aig_Obj_t * pObj, * pRes; - int i, iFrame, Counter; - int nNodes = Aig_ManObjNum( p->pFrm ); - Vec_PtrClear( p->vTargets ); - p->iFramePrev = p->iFrameLast; - for ( ; p->iFrameLast < p->nFramesMax; p->iFrameLast++, p->iOutputLast = 0 ) + Aig_Man_t * pFrames; + Aig_Obj_t * pObj, * pObjLi, * pObjLo, * pObjPo; + int i, f, Counter = 0; + assert( Saig_ManRegNum(pAig) > 0 ); + pFrames = Aig_ManStart( nSizeMax ); + Aig_ManIncrementTravId( pFrames ); + // map the constant node + Aig_ManConst1(pAig)->pData = Aig_ManConst1( pFrames ); + // create variables for register outputs + Saig_ManForEachLo( pAig, pObj, i ) + pObj->pData = Aig_ManConst0( pFrames ); + // add timeframes + Counter = 0; + for ( f = 0; f < nFrames; f++ ) { - if ( p->iOutputLast == 0 ) + // create PI nodes for this frame + Saig_ManForEachPi( pAig, pObj, i ) + pObj->pData = Aig_ObjCreatePi( pFrames ); + // add internal nodes of this frame + Aig_ManForEachNode( pAig, pObj, i ) + pObj->pData = Aig_And( pFrames, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + // create POs for this frame + Saig_ManForEachPo( pAig, pObj, i ) { - Saig_BmcObjSetFrame( p, Aig_ManConst1(p->pAig), p->iFrameLast, Aig_ManConst1(p->pFrm) ); + pObjPo = Aig_ObjCreatePo( pFrames, Aig_ObjChild0Copy(pObj) ); + Counter += Saig_ManFramesCount_rec( pFrames, Aig_ObjFanin0(pObjPo) ); } - for ( ; p->iOutputLast < Saig_ManPoNum(p->pAig); p->iOutputLast++ ) - { - if ( Aig_ManObjNum(p->pFrm) >= nNodes + p->nNodesMax ) - return; -// Saig_BmcIntervalExplore_rec( p, Aig_ManPo(p->pAig, p->iOutputLast), p->iFrameLast ); - Vec_PtrClear( p->vVisited ); - pTarget = Saig_BmcIntervalConstruct_rec( p, Aig_ManPo(p->pAig, p->iOutputLast), p->iFrameLast, p->vVisited ); - Vec_PtrPush( p->vTargets, pTarget ); - Aig_ObjCreatePo( p->pFrm, pTarget ); - Aig_ManCleanup( p->pFrm ); - // check if the node is gone - Counter = 0; - Vec_PtrForEachEntry( p->vVisited, pObj, i ) - { - iFrame = (int)(ABC_PTRINT_T)Vec_PtrEntry( p->vVisited, 1+i++ ); - pRes = Saig_BmcObjFrame( p, pObj, iFrame ); - if ( Aig_ObjIsNone( Aig_Regular(pRes) ) ) - { - Saig_BmcObjSetFrame( p, pObj, iFrame, NULL ); - Counter++; - } - } -// printf( "%d ", Counter ); - } - } -} - -/**Function************************************************************* - - Synopsis [Performs the actual construction of the output.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Obj_t * Saig_BmcIntervalToAig_rec( Saig_Bmc_t * p, Aig_Man_t * pNew, Aig_Obj_t * pObj ) -{ - if ( pObj->pData ) - return pObj->pData; - Vec_PtrPush( p->vVisited, pObj ); - if ( Saig_BmcSatNum(p, pObj) || Aig_ObjIsPi(pObj) ) - return pObj->pData = Aig_ObjCreatePi(pNew); - Saig_BmcIntervalToAig_rec( p, pNew, Aig_ObjFanin0(pObj) ); - Saig_BmcIntervalToAig_rec( p, pNew, Aig_ObjFanin1(pObj) ); - assert( pObj->pData == NULL ); - return pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); -} - -/**Function************************************************************* - - Synopsis [Creates AIG of the newly added nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Man_t * Saig_BmcIntervalToAig( Saig_Bmc_t * p ) -{ - Aig_Man_t * pNew; - Aig_Obj_t * pObj, * pObjNew; - int i; - Aig_ManForEachObj( p->pFrm, pObj, i ) - assert( pObj->pData == NULL ); - - pNew = Aig_ManStart( p->nNodesMax ); - Aig_ManConst1(p->pFrm)->pData = Aig_ManConst1(pNew); - Vec_PtrClear( p->vVisited ); - Vec_PtrPush( p->vVisited, Aig_ManConst1(p->pFrm) ); - Vec_PtrForEachEntry( p->vTargets, pObj, i ) - { -// assert( !Aig_ObjIsConst1(Aig_Regular(pObj)) ); - pObjNew = Saig_BmcIntervalToAig_rec( p, pNew, Aig_Regular(pObj) ); - assert( !Aig_IsComplement(pObjNew) ); - Aig_ObjCreatePo( pNew, pObjNew ); - } - return pNew; -} - -/**Function************************************************************* - - Synopsis [Derives CNF for the newly added nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Saig_BmcLoadCnf( Saig_Bmc_t * p, Cnf_Dat_t * pCnf ) -{ - Aig_Obj_t * pObj, * pObjNew; - int i, Lits[2], VarNumOld, VarNumNew; - Vec_PtrForEachEntry( p->vVisited, pObj, i ) - { - // get the new variable of this node - pObjNew = pObj->pData; - pObj->pData = NULL; - VarNumNew = pCnf->pVarNums[ pObjNew->Id ]; - if ( VarNumNew == -1 ) - continue; - // get the old variable of this node - VarNumOld = Saig_BmcSatNum( p, pObj ); - if ( VarNumOld == 0 ) + if ( Counter >= nSizeMax ) { - Saig_BmcSetSatNum( p, pObj, VarNumNew ); - continue; + Aig_ManCleanup( pFrames ); + return pFrames; } - // add clauses connecting existing variables - Lits[0] = toLitCond( VarNumOld, 0 ); - Lits[1] = toLitCond( VarNumNew, 1 ); - if ( !sat_solver_addclause( p->pSat, Lits, Lits+2 ) ) - assert( 0 ); - Lits[0] = toLitCond( VarNumOld, 1 ); - Lits[1] = toLitCond( VarNumNew, 0 ); - if ( !sat_solver_addclause( p->pSat, Lits, Lits+2 ) ) - assert( 0 ); - } - // add CNF to the SAT solver - for ( i = 0; i < pCnf->nClauses; i++ ) - if ( !sat_solver_addclause( p->pSat, pCnf->pClauses[i], pCnf->pClauses[i+1] ) ) + if ( f == nFrames - 1 ) break; - if ( i < pCnf->nClauses ) - printf( "SAT solver became UNSAT after adding clauses.\n" ); -} - -/**Function************************************************************* - - Synopsis [Solves targets with the given resource limit.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Saig_BmcDeriveFailed( Saig_Bmc_t * p, int iTargetFail ) -{ - int k; - p->iOutputFail = p->iOutputLast; - p->iFrameFail = p->iFrameLast; - for ( k = Vec_PtrSize(p->vTargets); k > iTargetFail; k-- ) - { - if ( p->iOutputFail == 0 ) - { - p->iOutputFail = Saig_ManPoNum(p->pAig); - p->iFrameFail--; - } - p->iOutputFail--; + // save register inputs + Saig_ManForEachLi( pAig, pObj, i ) + pObj->pData = Aig_ObjChild0Copy(pObj); + // transfer to register outputs + Saig_ManForEachLiLo( pAig, pObjLi, pObjLo, i ) + pObjLo->pData = pObjLi->pData; } + Aig_ManCleanup( pFrames ); + return pFrames; } -/**Function************************************************************* +ABC_NAMESPACE_IMPL_END - Synopsis [Solves targets with the given resource limit.] +#include "utilMem.h" - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ssw_Cex_t * Saig_BmcGenerateCounterExample( Saig_Bmc_t * p ) -{ - Ssw_Cex_t * pCex; - Aig_Obj_t * pObj, * pObjFrm; - int i, f, iVarNum; - // start the counter-example - pCex = Ssw_SmlAllocCounterExample( Aig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), p->iFrameFail+1 ); - pCex->iFrame = p->iFrameFail; - pCex->iPo = p->iOutputFail; - // copy the bit data - for ( f = 0; f <= p->iFrameFail; f++ ) - { - Saig_ManForEachPi( p->pAig, pObj, i ) - { - pObjFrm = Saig_BmcObjFrame( p, pObj, f ); - if ( pObjFrm == NULL ) - continue; - iVarNum = Saig_BmcSatNum( p, pObjFrm ); - if ( iVarNum == 0 ) - continue; - if ( sat_solver_var_value( p->pSat, iVarNum ) ) - Aig_InfoSetBit( pCex->pData, pCex->nRegs + Saig_ManPiNum(p->pAig) * f + i ); - } - } - // verify the counter example - if ( !Ssw_SmlRunCounterExample( p->pAig, pCex ) ) - { - printf( "Saig_BmcGenerateCounterExample(): Counter-example is invalid.\n" ); - Ssw_SmlFreeCounterExample( pCex ); - pCex = NULL; - } - return pCex; -} +ABC_NAMESPACE_IMPL_START + /**Function************************************************************* - Synopsis [Solves targets with the given resource limit.] + Synopsis [Performs BMC for the given AIG.] Description [] @@ -669,157 +183,156 @@ Ssw_Cex_t * Saig_BmcGenerateCounterExample( Saig_Bmc_t * p ) SeeAlso [] ***********************************************************************/ -int Saig_BmcSolveTargets( Saig_Bmc_t * p, int nStart, int * pnOutsSolved ) +int Saig_ManBmcSimple( Aig_Man_t * pAig, int nFrames, int nSizeMax, int nConfLimit, int fRewrite, int fVerbose, int * piFrame, int nCofFanLit ) { + extern Aig_Man_t * Gia_ManCofactorAig( Aig_Man_t * p, int nFrames, int nCofFanLit ); + sat_solver * pSat; + Cnf_Dat_t * pCnf; + Aig_Man_t * pFrames, * pAigTemp; Aig_Obj_t * pObj; - int i, VarNum, Lit, RetValue; - assert( Vec_PtrSize(p->vTargets) > 0 ); - if ( p->pSat->qtail != p->pSat->qhead ) + int status, clk, Lit, i, RetValue = -1; + + // derive the timeframes + clk = clock(); + if ( nCofFanLit ) { - RetValue = sat_solver_simplify(p->pSat); - assert( RetValue != 0 ); + pFrames = Gia_ManCofactorAig( pAig, nFrames, nCofFanLit ); + if ( pFrames == NULL ) + return -1; } - Vec_PtrForEachEntry( p->vTargets, pObj, i ) + else if ( nSizeMax > 0 ) { - if ( ((*pnOutsSolved)++ / Saig_ManPoNum(p->pAig)) < nStart ) - continue; - if ( p->pSat->stats.conflicts > p->nConfMaxAll ) - return l_Undef; - VarNum = Saig_BmcSatNum( p, Aig_Regular(pObj) ); - Lit = toLitCond( VarNum, Aig_IsComplement(pObj) ); - RetValue = sat_solver_solve( p->pSat, &Lit, &Lit + 1, (ABC_INT64_T)p->nConfMaxOne, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); - if ( RetValue == l_False ) // unsat - continue; - if ( RetValue == l_Undef ) // undecided - return l_Undef; - // generate counter-example - Saig_BmcDeriveFailed( p, i ); - p->pAig->pSeqModel = Saig_BmcGenerateCounterExample( p ); - - { -// extern Vec_Int_t * Saig_ManExtendCounterExampleTest( Aig_Man_t * p, int iFirstPi, void * pCex ); -// Saig_ManExtendCounterExampleTest( p->pAig, 0, p->pAig->pSeqModel ); - } - return l_True; + pFrames = Saig_ManFramesBmcLimit( pAig, nFrames, nSizeMax ); + nFrames = Aig_ManPoNum(pFrames) / Saig_ManPoNum(pAig) + ((Aig_ManPoNum(pFrames) % Saig_ManPoNum(pAig)) > 0); } - return l_False; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Saig_BmcAddTargetsAsPos( Saig_Bmc_t * p ) -{ - Aig_Obj_t * pObj; - int i; - Vec_PtrForEachEntry( p->vTargets, pObj, i ) - Aig_ObjCreatePo( p->pFrm, pObj ); - Aig_ManPrintStats( p->pFrm ); - Aig_ManCleanup( p->pFrm ); - Aig_ManPrintStats( p->pFrm ); -} - -/**Function************************************************************* - - Synopsis [Performs BMC with the given parameters.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Saig_BmcPerform( Aig_Man_t * pAig, int nStart, int nFramesMax, int nNodesMax, int nTimeOut, int nConfMaxOne, int nConfMaxAll, int fVerbose, int fVerbOverwrite ) -{ - Saig_Bmc_t * p; - Aig_Man_t * pNew; - Cnf_Dat_t * pCnf; - int nOutsSolved = 0; - int Iter, RetValue, clk = clock(), clk2; -/* - Vec_Ptr_t * vSimInfo; - vSimInfo = Abs_ManTernarySimulate( pAig, nFramesMax, fVerbose ); - Abs_ManFreeAray( vSimInfo ); -*/ - p = Saig_BmcManStart( pAig, nFramesMax, nNodesMax, nConfMaxOne, nConfMaxAll, fVerbose ); + else + pFrames = Saig_ManFramesBmc( pAig, nFrames ); + if ( piFrame ) + *piFrame = nFrames; if ( fVerbose ) { printf( "AIG: PI/PO/Reg = %d/%d/%d. Node = %6d. Lev = %5d.\n", Saig_ManPiNum(pAig), Saig_ManPoNum(pAig), Saig_ManRegNum(pAig), Aig_ManNodeNum(pAig), Aig_ManLevelNum(pAig) ); - printf( "Params: FramesMax = %d. NodesDelta = %d. ConfMaxOne = %d. ConfMaxAll = %d.\n", - nFramesMax, nNodesMax, nConfMaxOne, nConfMaxAll ); - } - - for ( Iter = 0; ; Iter++ ) + printf( "Time-frames (%d): PI/PO = %d/%d. Node = %6d. Lev = %5d. ", + nFrames, Aig_ManPiNum(pFrames), Aig_ManPoNum(pFrames), + Aig_ManNodeNum(pFrames), Aig_ManLevelNum(pFrames) ); + ABC_PRT( "Time", clock() - clk ); + fflush( stdout ); + } + // rewrite the timeframes + if ( fRewrite ) { - clk2 = clock(); - // add new logic interval to frames - Saig_BmcInterval( p ); -// Saig_BmcAddTargetsAsPos( p ); - if ( Vec_PtrSize(p->vTargets) == 0 ) - break; - // convert logic slice into new AIG - pNew = Saig_BmcIntervalToAig( p ); - // derive CNF for the new AIG - pCnf = Cnf_Derive( pNew, Aig_ManPoNum(pNew) ); - Cnf_DataLift( pCnf, p->nSatVars ); - p->nSatVars += pCnf->nVars; - // add this CNF to the solver - Saig_BmcLoadCnf( p, pCnf ); - Cnf_DataFree( pCnf ); - Aig_ManStop( pNew ); - // solve the targets - RetValue = Saig_BmcSolveTargets( p, nStart, &nOutsSolved ); + clk = clock(); +// pFrames = Dar_ManBalance( pAigTemp = pFrames, 0 ); + pFrames = Dar_ManRwsat( pAigTemp = pFrames, 1, 0 ); + Aig_ManStop( pAigTemp ); if ( fVerbose ) { - printf( "%3d : F = %3d. O =%4d. And = %7d. Var = %7d. Conf = %7d. ", - Iter, p->iFrameLast, p->iOutputLast, Aig_ManNodeNum(p->pFrm), p->nSatVars, (int)p->pSat->stats.conflicts ); - ABC_PRT( "Time", clock() - clk2 ); + printf( "Time-frames after rewriting: Node = %6d. Lev = %5d. ", + Aig_ManNodeNum(pFrames), Aig_ManLevelNum(pFrames) ); + ABC_PRT( "Time", clock() - clk ); + fflush( stdout ); } - if ( RetValue != l_False ) - break; } - if ( RetValue == l_True ) + // create the SAT solver + clk = clock(); + pCnf = Cnf_Derive( pFrames, Aig_ManPoNum(pFrames) ); +//if ( s_fInterrupt ) +//return -1; + pSat = sat_solver_new(); + sat_solver_setnvars( pSat, pCnf->nVars ); + for ( i = 0; i < pCnf->nClauses; i++ ) { - assert( p->iFrameFail * Saig_ManPoNum(p->pAig) + p->iOutputFail + 1 == nOutsSolved ); - printf( "Output %d was asserted in frame %d (use \"write_counter\" to dump a witness). ", - p->iOutputFail, p->iFrameFail ); + if ( !sat_solver_addclause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1] ) ) + assert( 0 ); } - else // if ( RetValue == l_False || RetValue == l_Undef ) - printf( "No output was asserted in %d frames. ", p->iFramePrev-1 ); - if ( fVerbOverwrite ) + if ( fVerbose ) { - ABC_PRTr( "Time", clock() - clk ); + printf( "CNF: Variables = %6d. Clauses = %7d. Literals = %8d. ", pCnf->nVars, pCnf->nClauses, pCnf->nLiterals ); + ABC_PRT( "Time", clock() - clk ); + fflush( stdout ); } - else + status = sat_solver_simplify(pSat); + if ( status == 0 ) { - ABC_PRT( "Time", clock() - clk ); + if ( fVerbose ) + { + printf( "The BMC problem is trivially UNSAT\n" ); + fflush( stdout ); + } } - if ( RetValue != l_True ) + else { - if ( p->iFrameLast >= p->nFramesMax ) - printf( "Reached limit on the number of timeframes (%d).\n", p->nFramesMax ); - else if ( p->pSat->stats.conflicts > p->nConfMaxAll ) - printf( "Reached global conflict limit (%d).\n", p->nConfMaxAll ); - else - printf( "Reached local conflict limit (%d).\n", p->nConfMaxOne ); + int clkPart = clock(); + Aig_ManForEachPo( pFrames, pObj, i ) + { +//if ( s_fInterrupt ) +//return -1; + Lit = toLitCond( pCnf->pVarNums[pObj->Id], 0 ); + if ( fVerbose ) + { + printf( "Solving output %2d of frame %3d ... \r", + i % Saig_ManPoNum(pAig), i / Saig_ManPoNum(pAig) ); + } + clk = clock(); + status = sat_solver_solve( pSat, &Lit, &Lit + 1, (ABC_INT64_T)nConfLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); + if ( fVerbose && (i % Saig_ManPoNum(pAig) == Saig_ManPoNum(pAig) - 1) ) + { + printf( "Solved %2d outputs of frame %3d. ", + Saig_ManPoNum(pAig), i / Saig_ManPoNum(pAig) ); + printf( "Conf =%8.0f. Imp =%11.0f. ", (double)pSat->stats.conflicts, (double)pSat->stats.propagations ); + ABC_PRT( "T", clock() - clkPart ); + clkPart = clock(); + fflush( stdout ); + } + if ( status == l_False ) + { +/* + Lit = lit_neg( Lit ); + RetValue = sat_solver_addclause( pSat, &Lit, &Lit + 1 ); + assert( RetValue ); + if ( pSat->qtail != pSat->qhead ) + { + RetValue = sat_solver_simplify(pSat); + assert( RetValue ); + } +*/ + } + else if ( status == l_True ) + { +// extern void * Fra_SmlCopyCounterExample( Aig_Man_t * pAig, Aig_Man_t * pFrames, int * pModel ); + Vec_Int_t * vCiIds = Cnf_DataCollectPiSatNums( pCnf, pFrames ); + int * pModel = Sat_SolverGetModel( pSat, vCiIds->pArray, vCiIds->nSize ); + pModel[Aig_ManPiNum(pFrames)] = pObj->Id; + pAig->pSeqModel = (Abc_Cex_t *)Fra_SmlCopyCounterExample( pAig, pFrames, pModel ); + ABC_FREE( pModel ); + Vec_IntFree( vCiIds ); + + if ( piFrame ) + *piFrame = i / Saig_ManPoNum(pAig); + RetValue = 0; + break; + } + else + { + if ( piFrame ) + *piFrame = i / Saig_ManPoNum(pAig); + RetValue = -1; + break; + } + } } - Saig_BmcManStop( p ); + sat_solver_delete( pSat ); + Cnf_DataFree( pCnf ); + Aig_ManStop( pFrames ); + return RetValue; } - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigBmc2.c b/src/aig/saig/saigBmc2.c index 240168e6..c7129c67 100644 --- a/src/aig/saig/saigBmc2.c +++ b/src/aig/saig/saigBmc2.c @@ -21,67 +21,207 @@ #include "saig.h" #include "cnf.h" #include "satStore.h" +#include "ssw.h" + +ABC_NAMESPACE_IMPL_START + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +#define AIG_VISITED ((Aig_Obj_t *)(ABC_PTRUINT_T)1) + +typedef struct Saig_Bmc_t_ Saig_Bmc_t; +struct Saig_Bmc_t_ +{ + // parameters + int nFramesMax; // the max number of timeframes to consider + int nNodesMax; // the max number of nodes to add + int nConfMaxOne; // the max number of conflicts at a target + int nConfMaxAll; // the max number of conflicts for all targets + int fVerbose; // enables verbose output + // AIG managers + Aig_Man_t * pAig; // the user's AIG manager + Aig_Man_t * pFrm; // Frames manager + Vec_Ptr_t * vVisited; // nodes visited in Frames + // node mapping + int nObjs; // the largest number of an AIG object + Vec_Ptr_t * vAig2Frm; // mapping of AIG nodees into Frames nodes +// Vec_Str_t * vAig2Frm2; // mapping of AIG nodees into Frames nodes + // SAT solver + sat_solver * pSat; // SAT solver + int nSatVars; // the number of used SAT variables + Vec_Int_t * vObj2Var; // mapping of frames objects in CNF variables + int nStitchVars; + // subproblems + Vec_Ptr_t * vTargets; // targets to be solved in this interval + int iFramePrev; // previous frame + int iFrameLast; // last frame + int iOutputLast; // last output + int iFrameFail; // failed frame + int iOutputFail; // failed output +}; + +static inline int Saig_BmcSatNum( Saig_Bmc_t * p, Aig_Obj_t * pObj ) { return Vec_IntGetEntry( p->vObj2Var, pObj->Id ); } +static inline void Saig_BmcSetSatNum( Saig_Bmc_t * p, Aig_Obj_t * pObj, int Num ) { Vec_IntSetEntry(p->vObj2Var, pObj->Id, Num); } + +static inline Aig_Obj_t * Saig_BmcObjFrame( Saig_Bmc_t * p, Aig_Obj_t * pObj, int i ) { return (Aig_Obj_t *)Vec_PtrGetEntry( p->vAig2Frm, p->nObjs*i+pObj->Id ); } +static inline void Saig_BmcObjSetFrame( Saig_Bmc_t * p, Aig_Obj_t * pObj, int i, Aig_Obj_t * pNode ) { Vec_PtrSetEntry( p->vAig2Frm, p->nObjs*i+pObj->Id, pNode ); } + +static inline Aig_Obj_t * Saig_BmcObjChild0( Saig_Bmc_t * p, Aig_Obj_t * pObj, int i ) { assert( !Aig_IsComplement(pObj) ); return Aig_NotCond(Saig_BmcObjFrame(p, Aig_ObjFanin0(pObj), i), Aig_ObjFaninC0(pObj)); } +static inline Aig_Obj_t * Saig_BmcObjChild1( Saig_Bmc_t * p, Aig_Obj_t * pObj, int i ) { assert( !Aig_IsComplement(pObj) ); return Aig_NotCond(Saig_BmcObjFrame(p, Aig_ObjFanin1(pObj), i), Aig_ObjFaninC1(pObj)); } + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +#define ABS_ZER 1 +#define ABS_ONE 2 +#define ABS_UND 3 + +static inline int Abs_ManSimInfoNot( int Value ) +{ + if ( Value == ABS_ZER ) + return ABS_ONE; + if ( Value == ABS_ONE ) + return ABS_ZER; + return ABS_UND; +} + +static inline int Abs_ManSimInfoAnd( int Value0, int Value1 ) +{ + if ( Value0 == ABS_ZER || Value1 == ABS_ZER ) + return ABS_ZER; + if ( Value0 == ABS_ONE && Value1 == ABS_ONE ) + return ABS_ONE; + return ABS_UND; +} + +static inline int Abs_ManSimInfoGet( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame ) +{ + unsigned * pInfo = (unsigned *)Vec_PtrEntry( vSimInfo, iFrame ); + return 3 & (pInfo[Aig_ObjId(pObj) >> 4] >> ((Aig_ObjId(pObj) & 15) << 1)); +} + +static inline void Abs_ManSimInfoSet( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame, int Value ) +{ + unsigned * pInfo = (unsigned *)Vec_PtrEntry( vSimInfo, iFrame ); + assert( Value >= ABS_ZER && Value <= ABS_UND ); + Value ^= Abs_ManSimInfoGet( vSimInfo, pObj, iFrame ); + pInfo[Aig_ObjId(pObj) >> 4] ^= (Value << ((Aig_ObjId(pObj) & 15) << 1)); +} + /**Function************************************************************* - Synopsis [Create timeframes of the manager for BMC.] + Synopsis [Performs ternary simulation for one node.] - Description [The resulting manager is combinational. POs correspond to \ - the property outputs in each time-frame.] + Description [] SideEffects [] SeeAlso [] ***********************************************************************/ -Aig_Man_t * Saig_ManFramesBmc( Aig_Man_t * pAig, int nFrames ) +int Abs_ManExtendOneEval_rec( Vec_Ptr_t * vSimInfo, Aig_Man_t * p, Aig_Obj_t * pObj, int iFrame ) { - Aig_Man_t * pFrames; - Aig_Obj_t * pObj, * pObjLi, * pObjLo; - int i, f; - assert( Saig_ManRegNum(pAig) > 0 ); - pFrames = Aig_ManStart( Aig_ManNodeNum(pAig) * nFrames ); - // map the constant node - Aig_ManConst1(pAig)->pData = Aig_ManConst1( pFrames ); - // create variables for register outputs - Saig_ManForEachLo( pAig, pObj, i ) - pObj->pData = Aig_ManConst0( pFrames ); - // add timeframes - for ( f = 0; f < nFrames; f++ ) + int Value0, Value1, Value; + Value = Abs_ManSimInfoGet( vSimInfo, pObj, iFrame ); + if ( Value ) + return Value; + if ( Aig_ObjIsPi(pObj) ) { - // create PI nodes for this frame - Saig_ManForEachPi( pAig, pObj, i ) - pObj->pData = Aig_ObjCreatePi( pFrames ); - // add internal nodes of this frame - Aig_ManForEachNode( pAig, pObj, i ) - pObj->pData = Aig_And( pFrames, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); - // create POs for this frame - Saig_ManForEachPo( pAig, pObj, i ) - Aig_ObjCreatePo( pFrames, Aig_ObjChild0Copy(pObj) ); - if ( f == nFrames - 1 ) - break; - // save register inputs - Saig_ManForEachLi( pAig, pObj, i ) - pObj->pData = Aig_ObjChild0Copy(pObj); - // transfer to register outputs - Saig_ManForEachLiLo( pAig, pObjLi, pObjLo, i ) - pObjLo->pData = pObjLi->pData; + assert( Saig_ObjIsLo(p, pObj) ); + Value = Abs_ManExtendOneEval_rec( vSimInfo, p, Saig_ObjLoToLi(p, pObj), iFrame-1 ); + Abs_ManSimInfoSet( vSimInfo, pObj, iFrame, Value ); + return Value; + } + Value0 = Abs_ManExtendOneEval_rec( vSimInfo, p, Aig_ObjFanin0(pObj), iFrame ); + if ( Aig_ObjFaninC0(pObj) ) + Value0 = Abs_ManSimInfoNot( Value0 ); + if ( Aig_ObjIsPo(pObj) ) + { + Abs_ManSimInfoSet( vSimInfo, pObj, iFrame, Value0 ); + return Value0; } - Aig_ManCleanup( pFrames ); - return pFrames; + assert( Aig_ObjIsNode(pObj) ); + if ( Value0 == ABS_ZER ) + Value = ABS_ZER; + else + { + Value1 = Abs_ManExtendOneEval_rec( vSimInfo, p, Aig_ObjFanin1(pObj), iFrame ); + if ( Aig_ObjFaninC1(pObj) ) + Value1 = Abs_ManSimInfoNot( Value1 ); + Value = Abs_ManSimInfoAnd( Value0, Value1 ); + } + Abs_ManSimInfoSet( vSimInfo, pObj, iFrame, Value ); + assert( Value ); + return Value; } /**Function************************************************************* - Synopsis [Returns the number of internal nodes that are not counted yet.] + Synopsis [Performs ternary simulation for one design.] + + Description [The returned array contains the result of ternary + simulation for all the frames where the output could be proved 0.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Abs_ManTernarySimulate( Aig_Man_t * p, int nFramesMax, int fVerbose ) +{ + Vec_Ptr_t * vSimInfo; + Aig_Obj_t * pObj; + int i, f, nFramesLimit, nFrameWords; + int clk = clock(); + assert( Aig_ManRegNum(p) > 0 ); + // the maximum number of frames will be determined to use at most 200Mb of RAM + nFramesLimit = 1 + (200000000 * 4)/Aig_ManObjNum(p); + nFramesLimit = ABC_MIN( nFramesLimit, nFramesMax ); + nFrameWords = Aig_BitWordNum( 2 * Aig_ManObjNum(p) ); + // allocate simulation info + vSimInfo = Vec_PtrAlloc( nFramesLimit ); + for ( f = 0; f < nFramesLimit; f++ ) + { + Vec_PtrPush( vSimInfo, ABC_CALLOC(unsigned, nFrameWords) ); + if ( f == 0 ) + { + Saig_ManForEachLo( p, pObj, i ) + Abs_ManSimInfoSet( vSimInfo, pObj, 0, ABS_ZER ); + } + Abs_ManSimInfoSet( vSimInfo, Aig_ManConst1(p), f, ABS_ONE ); + Saig_ManForEachPi( p, pObj, i ) + Abs_ManSimInfoSet( vSimInfo, pObj, f, ABS_UND ); + Saig_ManForEachPo( p, pObj, i ) + Abs_ManExtendOneEval_rec( vSimInfo, p, pObj, f ); + // check if simulation has derived at least one fail or unknown + Saig_ManForEachPo( p, pObj, i ) + if ( Abs_ManSimInfoGet(vSimInfo, pObj, f) != ABS_ZER ) + { + if ( fVerbose ) + { + printf( "Ternary sim found non-zero output in frame %d. Used %5.2f Mb. ", + f, 0.25 * (f+1) * Aig_ManObjNum(p) / (1<<20) ); + ABC_PRT( "Time", clock() - clk ); + } + return vSimInfo; + } + } + if ( fVerbose ) + { + printf( "Ternary sim proved all outputs in the first %d frames. Used %5.2f Mb. ", + nFramesLimit, 0.25 * nFramesLimit * Aig_ManObjNum(p) / (1<<20) ); + ABC_PRT( "Time", clock() - clk ); + } + return vSimInfo; +} + +/**Function************************************************************* + + Synopsis [Free the array of simulation info.] Description [] @@ -90,83 +230,444 @@ Aig_Man_t * Saig_ManFramesBmc( Aig_Man_t * pAig, int nFrames ) SeeAlso [] ***********************************************************************/ -int Saig_ManFramesCount_rec( Aig_Man_t * p, Aig_Obj_t * pObj ) +void Abs_ManFreeAray( Vec_Ptr_t * p ) { - if ( !Aig_ObjIsNode(pObj) ) - return 0; - if ( Aig_ObjIsTravIdCurrent(p, pObj) ) - return 0; - Aig_ObjSetTravIdCurrent(p, pObj); - return 1 + Saig_ManFramesCount_rec( p, Aig_ObjFanin0(pObj) ) + - Saig_ManFramesCount_rec( p, Aig_ObjFanin1(pObj) ); + void * pTemp; + int i; + Vec_PtrForEachEntry( void *, p, pTemp, i ) + ABC_FREE( pTemp ); + Vec_PtrFree( p ); } + /**Function************************************************************* - Synopsis [Create timeframes of the manager for BMC.] + Synopsis [Create manager.] - Description [The resulting manager is combinational. POs correspond to - the property outputs in each time-frame. - The unrolling is stopped as soon as the number of nodes in the frames - exceeds the given maximum size.] + Description [] SideEffects [] SeeAlso [] ***********************************************************************/ -Aig_Man_t * Saig_ManFramesBmcLimit( Aig_Man_t * pAig, int nFrames, int nSizeMax ) +Saig_Bmc_t * Saig_BmcManStart( Aig_Man_t * pAig, int nFramesMax, int nNodesMax, int nConfMaxOne, int nConfMaxAll, int fVerbose ) { - Aig_Man_t * pFrames; - Aig_Obj_t * pObj, * pObjLi, * pObjLo, * pObjPo; - int i, f, Counter = 0; - assert( Saig_ManRegNum(pAig) > 0 ); - pFrames = Aig_ManStart( nSizeMax ); - Aig_ManIncrementTravId( pFrames ); - // map the constant node - Aig_ManConst1(pAig)->pData = Aig_ManConst1( pFrames ); - // create variables for register outputs + Saig_Bmc_t * p; + Aig_Obj_t * pObj; + int i, Lit; +// assert( Aig_ManRegNum(pAig) > 0 ); + p = (Saig_Bmc_t *)ABC_ALLOC( char, sizeof(Saig_Bmc_t) ); + memset( p, 0, sizeof(Saig_Bmc_t) ); + // set parameters + p->nFramesMax = nFramesMax; + p->nNodesMax = nNodesMax; + p->nConfMaxOne = nConfMaxOne; + p->nConfMaxAll = nConfMaxAll; + p->fVerbose = fVerbose; + p->pAig = pAig; + p->nObjs = Aig_ManObjNumMax(pAig); + // create node and variable mappings + p->vAig2Frm = Vec_PtrAlloc( 0 ); + Vec_PtrFill( p->vAig2Frm, 5 * p->nObjs, NULL ); + p->vObj2Var = Vec_IntAlloc( 0 ); + Vec_IntFill( p->vObj2Var, 5 * p->nObjs, 0 ); + // start the AIG manager and map primary inputs + p->pFrm = Aig_ManStart( 5 * p->nObjs ); Saig_ManForEachLo( pAig, pObj, i ) - pObj->pData = Aig_ManConst0( pFrames ); - // add timeframes - Counter = 0; - for ( f = 0; f < nFrames; f++ ) + Saig_BmcObjSetFrame( p, pObj, 0, Aig_ManConst0(p->pFrm) ); + // create SAT solver + p->nSatVars = 1; + p->pSat = sat_solver_new(); + sat_solver_setnvars( p->pSat, 2000 ); + Lit = toLit( p->nSatVars ); + sat_solver_addclause( p->pSat, &Lit, &Lit + 1 ); + Saig_BmcSetSatNum( p, Aig_ManConst1(p->pFrm), p->nSatVars++ ); + // other data structures + p->vTargets = Vec_PtrAlloc( 0 ); + p->vVisited = Vec_PtrAlloc( 0 ); + p->iOutputFail = -1; + p->iFrameFail = -1; + return p; +} + +/**Function************************************************************* + + Synopsis [Delete manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_BmcManStop( Saig_Bmc_t * p ) +{ +// Aig_Obj_t * pObj; +// int i, f, Counter = 0; +// int i, Counter = 0; +// for ( i = 0; i < p->vAig2Frm2->nSize; i++ ) +// Counter += (p->vAig2Frm2->pArray[i] != 0); +// for ( i = 0; i < p->vAig2Frm->nSize; i++ ) +// Counter += (p->vAig2Frm->pArray[i] != NULL); +// printf( "Objs = %d. Nodes = %d. Frames = %d. Used = %d. Non-empty = %d.\n", +// p->nObjs, Aig_ManNodeNum(p->pAig), p->iFrameLast, p->vAig2Frm->nSize, Counter ); + +/* + Aig_ManForEachObj( p->pAig, pObj, i ) { - // create PI nodes for this frame - Saig_ManForEachPi( pAig, pObj, i ) - pObj->pData = Aig_ObjCreatePi( pFrames ); - // add internal nodes of this frame - Aig_ManForEachNode( pAig, pObj, i ) - pObj->pData = Aig_And( pFrames, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); - // create POs for this frame - Saig_ManForEachPo( pAig, pObj, i ) + int Last = -1; + for ( f = 0; f <= p->iFrameLast; f++ ) + if ( Saig_BmcObjFrame( p, pObj, f ) ) + Last = f; + if ( i % 50 == 0 ) + printf( "%d ", Last ); + } + printf( "\n" ); +*/ + + Aig_ManStop( p->pFrm ); + Vec_PtrFree( p->vAig2Frm ); +// Vec_StrFree( p->vAig2Frm2 ); + Vec_IntFree( p->vObj2Var ); + sat_solver_delete( p->pSat ); + Vec_PtrFree( p->vTargets ); + Vec_PtrFree( p->vVisited ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [Explores the possibility of constructing the output.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Saig_BmcIntervalExplore_rec( Saig_Bmc_t * p, Aig_Obj_t * pObj, int i ) +{ + Aig_Obj_t * pRes, * p0, * p1, * pConst1 = Aig_ManConst1(p->pAig); + pRes = Saig_BmcObjFrame( p, pObj, i ); + if ( pRes != NULL ) + return pRes; + if ( Saig_ObjIsPi( p->pAig, pObj ) ) + pRes = AIG_VISITED; + else if ( Saig_ObjIsLo( p->pAig, pObj ) ) + pRes = Saig_BmcIntervalExplore_rec( p, Saig_ObjLoToLi(p->pAig, pObj), i-1 ); + else if ( Aig_ObjIsPo( pObj ) ) + { + pRes = Saig_BmcIntervalExplore_rec( p, Aig_ObjFanin0(pObj), i ); + if ( pRes != AIG_VISITED ) + pRes = Saig_BmcObjChild0( p, pObj, i ); + } + else + { + p0 = Saig_BmcIntervalExplore_rec( p, Aig_ObjFanin0(pObj), i ); + if ( p0 != AIG_VISITED ) + p0 = Saig_BmcObjChild0( p, pObj, i ); + p1 = Saig_BmcIntervalExplore_rec( p, Aig_ObjFanin1(pObj), i ); + if ( p1 != AIG_VISITED ) + p1 = Saig_BmcObjChild1( p, pObj, i ); + + if ( p0 == Aig_Not(p1) ) + pRes = Aig_ManConst0(p->pFrm); + else if ( Aig_Regular(p0) == pConst1 ) + pRes = (p0 == pConst1) ? p1 : Aig_ManConst0(p->pFrm); + else if ( Aig_Regular(p1) == pConst1 ) + pRes = (p1 == pConst1) ? p0 : Aig_ManConst0(p->pFrm); + else + pRes = AIG_VISITED; + + if ( pRes != AIG_VISITED && !Aig_ObjIsConst1(Aig_Regular(pRes)) ) + pRes = AIG_VISITED; + } + Saig_BmcObjSetFrame( p, pObj, i, pRes ); + return pRes; +} + +/**Function************************************************************* + + Synopsis [Performs the actual construction of the output.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Saig_BmcIntervalConstruct_rec( Saig_Bmc_t * p, Aig_Obj_t * pObj, int i, Vec_Ptr_t * vVisited ) +{ + Aig_Obj_t * pRes; + pRes = Saig_BmcObjFrame( p, pObj, i ); + if ( pRes != NULL ) + return pRes; + if ( Saig_ObjIsPi( p->pAig, pObj ) ) + pRes = Aig_ObjCreatePi(p->pFrm); + else if ( Saig_ObjIsLo( p->pAig, pObj ) ) + pRes = Saig_BmcIntervalConstruct_rec( p, Saig_ObjLoToLi(p->pAig, pObj), i-1, vVisited ); + else if ( Aig_ObjIsPo( pObj ) ) + { + Saig_BmcIntervalConstruct_rec( p, Aig_ObjFanin0(pObj), i, vVisited ); + pRes = Saig_BmcObjChild0( p, pObj, i ); + } + else + { + Saig_BmcIntervalConstruct_rec( p, Aig_ObjFanin0(pObj), i, vVisited ); + if ( Saig_BmcObjChild0(p, pObj, i) == Aig_ManConst0(p->pFrm) ) + pRes = Aig_ManConst0(p->pFrm); + else + { + Saig_BmcIntervalConstruct_rec( p, Aig_ObjFanin1(pObj), i, vVisited ); + pRes = Aig_And( p->pFrm, Saig_BmcObjChild0(p, pObj, i), Saig_BmcObjChild1(p, pObj, i) ); + } + } + assert( pRes != NULL ); + Saig_BmcObjSetFrame( p, pObj, i, pRes ); + Vec_PtrPush( vVisited, pObj ); + Vec_PtrPush( vVisited, (void *)(ABC_PTRINT_T)i ); + return pRes; +} + +/**Function************************************************************* + + Synopsis [Adds new AIG nodes to the frames.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_BmcInterval( Saig_Bmc_t * p ) +{ + Aig_Obj_t * pTarget; + Aig_Obj_t * pObj, * pRes; + int i, iFrame, Counter; + int nNodes = Aig_ManObjNum( p->pFrm ); + Vec_PtrClear( p->vTargets ); + p->iFramePrev = p->iFrameLast; + for ( ; p->iFrameLast < p->nFramesMax; p->iFrameLast++, p->iOutputLast = 0 ) + { + if ( p->iOutputLast == 0 ) { - pObjPo = Aig_ObjCreatePo( pFrames, Aig_ObjChild0Copy(pObj) ); - Counter += Saig_ManFramesCount_rec( pFrames, Aig_ObjFanin0(pObjPo) ); + Saig_BmcObjSetFrame( p, Aig_ManConst1(p->pAig), p->iFrameLast, Aig_ManConst1(p->pFrm) ); } - if ( Counter >= nSizeMax ) + for ( ; p->iOutputLast < Saig_ManPoNum(p->pAig); p->iOutputLast++ ) { - Aig_ManCleanup( pFrames ); - return pFrames; + if ( Aig_ManObjNum(p->pFrm) >= nNodes + p->nNodesMax ) + return; +// Saig_BmcIntervalExplore_rec( p, Aig_ManPo(p->pAig, p->iOutputLast), p->iFrameLast ); + Vec_PtrClear( p->vVisited ); + pTarget = Saig_BmcIntervalConstruct_rec( p, Aig_ManPo(p->pAig, p->iOutputLast), p->iFrameLast, p->vVisited ); + Vec_PtrPush( p->vTargets, pTarget ); + Aig_ObjCreatePo( p->pFrm, pTarget ); + Aig_ManCleanup( p->pFrm ); + // check if the node is gone + Counter = 0; + Vec_PtrForEachEntry( Aig_Obj_t *, p->vVisited, pObj, i ) + { + iFrame = (int)(ABC_PTRINT_T)Vec_PtrEntry( p->vVisited, 1+i++ ); + pRes = Saig_BmcObjFrame( p, pObj, iFrame ); + if ( Aig_ObjIsNone( Aig_Regular(pRes) ) ) + { + Saig_BmcObjSetFrame( p, pObj, iFrame, NULL ); + Counter++; + } + } +// printf( "%d ", Counter ); } - if ( f == nFrames - 1 ) + } +} + +/**Function************************************************************* + + Synopsis [Performs the actual construction of the output.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Saig_BmcIntervalToAig_rec( Saig_Bmc_t * p, Aig_Man_t * pNew, Aig_Obj_t * pObj ) +{ + if ( pObj->pData ) + return (Aig_Obj_t *)pObj->pData; + Vec_PtrPush( p->vVisited, pObj ); + if ( Saig_BmcSatNum(p, pObj) || Aig_ObjIsPi(pObj) ) + { + p->nStitchVars += !Aig_ObjIsPi(pObj); + return (Aig_Obj_t *)(pObj->pData = Aig_ObjCreatePi(pNew)); + } + Saig_BmcIntervalToAig_rec( p, pNew, Aig_ObjFanin0(pObj) ); + Saig_BmcIntervalToAig_rec( p, pNew, Aig_ObjFanin1(pObj) ); + assert( pObj->pData == NULL ); + return (Aig_Obj_t *)(pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) )); +} + +/**Function************************************************************* + + Synopsis [Creates AIG of the newly added nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Saig_BmcIntervalToAig( Saig_Bmc_t * p ) +{ + Aig_Man_t * pNew; + Aig_Obj_t * pObj, * pObjNew; + int i; + Aig_ManForEachObj( p->pFrm, pObj, i ) + assert( pObj->pData == NULL ); + + pNew = Aig_ManStart( p->nNodesMax ); + Aig_ManConst1(p->pFrm)->pData = Aig_ManConst1(pNew); + Vec_PtrClear( p->vVisited ); + Vec_PtrPush( p->vVisited, Aig_ManConst1(p->pFrm) ); + Vec_PtrForEachEntry( Aig_Obj_t *, p->vTargets, pObj, i ) + { +// assert( !Aig_ObjIsConst1(Aig_Regular(pObj)) ); + pObjNew = Saig_BmcIntervalToAig_rec( p, pNew, Aig_Regular(pObj) ); + assert( !Aig_IsComplement(pObjNew) ); + Aig_ObjCreatePo( pNew, pObjNew ); + } + return pNew; +} + +/**Function************************************************************* + + Synopsis [Derives CNF for the newly added nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_BmcLoadCnf( Saig_Bmc_t * p, Cnf_Dat_t * pCnf ) +{ + Aig_Obj_t * pObj, * pObjNew; + int i, Lits[2], VarNumOld, VarNumNew; + Vec_PtrForEachEntry( Aig_Obj_t *, p->vVisited, pObj, i ) + { + // get the new variable of this node + pObjNew = (Aig_Obj_t *)pObj->pData; + pObj->pData = NULL; + VarNumNew = pCnf->pVarNums[ pObjNew->Id ]; + if ( VarNumNew == -1 ) + continue; + // get the old variable of this node + VarNumOld = Saig_BmcSatNum( p, pObj ); + if ( VarNumOld == 0 ) + { + Saig_BmcSetSatNum( p, pObj, VarNumNew ); + continue; + } + // add clauses connecting existing variables + Lits[0] = toLitCond( VarNumOld, 0 ); + Lits[1] = toLitCond( VarNumNew, 1 ); + if ( !sat_solver_addclause( p->pSat, Lits, Lits+2 ) ) + assert( 0 ); + Lits[0] = toLitCond( VarNumOld, 1 ); + Lits[1] = toLitCond( VarNumNew, 0 ); + if ( !sat_solver_addclause( p->pSat, Lits, Lits+2 ) ) + assert( 0 ); + } + // add CNF to the SAT solver + for ( i = 0; i < pCnf->nClauses; i++ ) + if ( !sat_solver_addclause( p->pSat, pCnf->pClauses[i], pCnf->pClauses[i+1] ) ) break; - // save register inputs - Saig_ManForEachLi( pAig, pObj, i ) - pObj->pData = Aig_ObjChild0Copy(pObj); - // transfer to register outputs - Saig_ManForEachLiLo( pAig, pObjLi, pObjLo, i ) - pObjLo->pData = pObjLi->pData; + if ( i < pCnf->nClauses ) + printf( "SAT solver became UNSAT after adding clauses.\n" ); +} + +/**Function************************************************************* + + Synopsis [Solves targets with the given resource limit.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_BmcDeriveFailed( Saig_Bmc_t * p, int iTargetFail ) +{ + int k; + p->iOutputFail = p->iOutputLast; + p->iFrameFail = p->iFrameLast; + for ( k = Vec_PtrSize(p->vTargets); k > iTargetFail; k-- ) + { + if ( p->iOutputFail == 0 ) + { + p->iOutputFail = Saig_ManPoNum(p->pAig); + p->iFrameFail--; + } + p->iOutputFail--; } - Aig_ManCleanup( pFrames ); - return pFrames; } -#include "utilMem.h" +/**Function************************************************************* + + Synopsis [Solves targets with the given resource limit.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Cex_t * Saig_BmcGenerateCounterExample( Saig_Bmc_t * p ) +{ + Abc_Cex_t * pCex; + Aig_Obj_t * pObj, * pObjFrm; + int i, f, iVarNum; + // start the counter-example + pCex = Ssw_SmlAllocCounterExample( Aig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), p->iFrameFail+1 ); + pCex->iFrame = p->iFrameFail; + pCex->iPo = p->iOutputFail; + // copy the bit data + for ( f = 0; f <= p->iFrameFail; f++ ) + { + Saig_ManForEachPi( p->pAig, pObj, i ) + { + pObjFrm = Saig_BmcObjFrame( p, pObj, f ); + if ( pObjFrm == NULL ) + continue; + iVarNum = Saig_BmcSatNum( p, pObjFrm ); + if ( iVarNum == 0 ) + continue; + if ( sat_solver_var_value( p->pSat, iVarNum ) ) + Aig_InfoSetBit( pCex->pData, pCex->nRegs + Saig_ManPiNum(p->pAig) * f + i ); + } + } + // verify the counter example + if ( !Ssw_SmlRunCounterExample( p->pAig, pCex ) ) + { + printf( "Saig_BmcGenerateCounterExample(): Counter-example is invalid.\n" ); + Ssw_SmlFreeCounterExample( pCex ); + pCex = NULL; + } + return pCex; +} /**Function************************************************************* - Synopsis [Performs BMC for the given AIG.] + Synopsis [Solves targets with the given resource limit.] Description [] @@ -175,154 +676,178 @@ Aig_Man_t * Saig_ManFramesBmcLimit( Aig_Man_t * pAig, int nFrames, int nSizeMax SeeAlso [] ***********************************************************************/ -int Saig_ManBmcSimple( Aig_Man_t * pAig, int nFrames, int nSizeMax, int nConfLimit, int fRewrite, int fVerbose, int * piFrame, int nCofFanLit ) +int Saig_BmcSolveTargets( Saig_Bmc_t * p, int nStart, int * pnOutsSolved ) { - extern Aig_Man_t * Gia_ManCofactorAig( Aig_Man_t * p, int nFrames, int nCofFanLit ); - sat_solver * pSat; - Cnf_Dat_t * pCnf; - Aig_Man_t * pFrames, * pAigTemp; Aig_Obj_t * pObj; - int status, clk, Lit, i, RetValue = 1; - - // derive the timeframes - clk = clock(); - if ( nCofFanLit ) + int i, VarNum, Lit, RetValue; + assert( Vec_PtrSize(p->vTargets) > 0 ); + if ( p->pSat->qtail != p->pSat->qhead ) { - pFrames = Gia_ManCofactorAig( pAig, nFrames, nCofFanLit ); - if ( pFrames == NULL ) - return -1; + RetValue = sat_solver_simplify(p->pSat); + assert( RetValue != 0 ); } - else if ( nSizeMax > 0 ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vTargets, pObj, i ) { - pFrames = Saig_ManFramesBmcLimit( pAig, nFrames, nSizeMax ); - nFrames = Aig_ManPoNum(pFrames) / Saig_ManPoNum(pAig) + ((Aig_ManPoNum(pFrames) % Saig_ManPoNum(pAig)) > 0); + if ( ((*pnOutsSolved)++ / Saig_ManPoNum(p->pAig)) < nStart ) + continue; + if ( p->nConfMaxAll && p->pSat->stats.conflicts > p->nConfMaxAll ) + return l_Undef; + VarNum = Saig_BmcSatNum( p, Aig_Regular(pObj) ); + Lit = toLitCond( VarNum, Aig_IsComplement(pObj) ); + RetValue = sat_solver_solve( p->pSat, &Lit, &Lit + 1, (ABC_INT64_T)p->nConfMaxOne, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); + if ( RetValue == l_False ) // unsat + continue; + if ( RetValue == l_Undef ) // undecided + return l_Undef; + // generate counter-example + Saig_BmcDeriveFailed( p, i ); + p->pAig->pSeqModel = Saig_BmcGenerateCounterExample( p ); + + { +// extern Vec_Int_t * Saig_ManExtendCounterExampleTest( Aig_Man_t * p, int iFirstPi, void * pCex ); +// Saig_ManExtendCounterExampleTest( p->pAig, 0, p->pAig->pSeqModel ); + } + return l_True; } - else - pFrames = Saig_ManFramesBmc( pAig, nFrames ); - if ( piFrame ) - *piFrame = nFrames; + return l_False; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_BmcAddTargetsAsPos( Saig_Bmc_t * p ) +{ + Aig_Obj_t * pObj; + int i; + Vec_PtrForEachEntry( Aig_Obj_t *, p->vTargets, pObj, i ) + Aig_ObjCreatePo( p->pFrm, pObj ); + Aig_ManPrintStats( p->pFrm ); + Aig_ManCleanup( p->pFrm ); + Aig_ManPrintStats( p->pFrm ); +} + +/**Function************************************************************* + + Synopsis [Performs BMC with the given parameters.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_BmcPerform( Aig_Man_t * pAig, int nStart, int nFramesMax, int nNodesMax, int nTimeOut, int nConfMaxOne, int nConfMaxAll, int fVerbose, int fVerbOverwrite, int * piFrames ) +{ + Saig_Bmc_t * p; + Aig_Man_t * pNew; + Cnf_Dat_t * pCnf; + int nOutsSolved = 0; + int Iter, RetValue, clk = clock(), clk2, clkTotal = clock(); + int Status = -1; +/* + Vec_Ptr_t * vSimInfo; + vSimInfo = Abs_ManTernarySimulate( pAig, nFramesMax, fVerbose ); + Abs_ManFreeAray( vSimInfo ); +*/ + p = Saig_BmcManStart( pAig, nFramesMax, nNodesMax, nConfMaxOne, nConfMaxAll, fVerbose ); if ( fVerbose ) { printf( "AIG: PI/PO/Reg = %d/%d/%d. Node = %6d. Lev = %5d.\n", Saig_ManPiNum(pAig), Saig_ManPoNum(pAig), Saig_ManRegNum(pAig), Aig_ManNodeNum(pAig), Aig_ManLevelNum(pAig) ); - printf( "Time-frames (%d): PI/PO = %d/%d. Node = %6d. Lev = %5d. ", - nFrames, Aig_ManPiNum(pFrames), Aig_ManPoNum(pFrames), - Aig_ManNodeNum(pFrames), Aig_ManLevelNum(pFrames) ); - ABC_PRT( "Time", clock() - clk ); - fflush( stdout ); - } - // rewrite the timeframes - if ( fRewrite ) + printf( "Params: FramesMax = %d. NodesDelta = %d. ConfMaxOne = %d. ConfMaxAll = %d.\n", + nFramesMax, nNodesMax, nConfMaxOne, nConfMaxAll ); + } + + for ( Iter = 0; ; Iter++ ) { - clk = clock(); -// pFrames = Dar_ManBalance( pAigTemp = pFrames, 0 ); - pFrames = Dar_ManRwsat( pAigTemp = pFrames, 1, 0 ); - Aig_ManStop( pAigTemp ); + clk2 = clock(); + // add new logic interval to frames + Saig_BmcInterval( p ); +// Saig_BmcAddTargetsAsPos( p ); + if ( Vec_PtrSize(p->vTargets) == 0 ) + break; + // convert logic slice into new AIG + pNew = Saig_BmcIntervalToAig( p ); +//printf( "StitchVars = %d.\n", p->nStitchVars ); + // derive CNF for the new AIG + pCnf = Cnf_Derive( pNew, Aig_ManPoNum(pNew) ); + Cnf_DataLift( pCnf, p->nSatVars ); + p->nSatVars += pCnf->nVars; + // add this CNF to the solver + Saig_BmcLoadCnf( p, pCnf ); + Cnf_DataFree( pCnf ); + Aig_ManStop( pNew ); + // solve the targets + RetValue = Saig_BmcSolveTargets( p, nStart, &nOutsSolved ); if ( fVerbose ) { - printf( "Time-frames after rewriting: Node = %6d. Lev = %5d. ", - Aig_ManNodeNum(pFrames), Aig_ManLevelNum(pFrames) ); - ABC_PRT( "Time", clock() - clk ); - fflush( stdout ); + printf( "%3d : F = %3d. O =%4d. And = %7d. Var = %7d. Conf = %7d. ", + Iter, p->iFrameLast, p->iOutputLast, Aig_ManNodeNum(p->pFrm), p->nSatVars, (int)p->pSat->stats.conflicts ); + ABC_PRT( "Time", clock() - clk2 ); + } + if ( RetValue != l_False ) + break; + // check the timeout + if ( nTimeOut && ((float)nTimeOut <= (float)(clock()-clkTotal)/(float)(CLOCKS_PER_SEC)) ) + { + printf( "Reached timeout (%d seconds).\n", nTimeOut ); + Saig_BmcManStop( p ); + if ( piFrames ) + *piFrames = p->iFrameLast-1; + return Status; } } - // create the SAT solver - clk = clock(); - pCnf = Cnf_Derive( pFrames, Aig_ManPoNum(pFrames) ); -//if ( s_fInterrupt ) -//return -1; - pSat = sat_solver_new(); - sat_solver_setnvars( pSat, pCnf->nVars ); - for ( i = 0; i < pCnf->nClauses; i++ ) + if ( RetValue == l_True ) { - if ( !sat_solver_addclause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1] ) ) - assert( 0 ); + assert( p->iFrameFail * Saig_ManPoNum(p->pAig) + p->iOutputFail + 1 == nOutsSolved ); + printf( "Output %d was asserted in frame %d (use \"write_counter\" to dump a witness). ", + p->iOutputFail, p->iFrameFail ); + Status = 0; + if ( piFrames ) + *piFrames = p->iFrameFail; } - if ( fVerbose ) + else // if ( RetValue == l_False || RetValue == l_Undef ) { - printf( "CNF: Variables = %6d. Clauses = %7d. Literals = %8d. ", pCnf->nVars, pCnf->nClauses, pCnf->nLiterals ); - ABC_PRT( "Time", clock() - clk ); - fflush( stdout ); + printf( "No output was asserted in %d frames. ", p->iFramePrev-1 ); + if ( piFrames ) + *piFrames = p->iFramePrev-1; } - status = sat_solver_simplify(pSat); - if ( status == 0 ) + if ( fVerbOverwrite ) { - if ( fVerbose ) - { - printf( "The BMC problem is trivially UNSAT\n" ); - fflush( stdout ); - } + ABC_PRTr( "Time", clock() - clk ); } else { - int clkPart = clock(); - Aig_ManForEachPo( pFrames, pObj, i ) - { -//if ( s_fInterrupt ) -//return -1; - Lit = toLitCond( pCnf->pVarNums[pObj->Id], 0 ); - if ( fVerbose ) - { - printf( "Solving output %2d of frame %3d ... \r", - i % Saig_ManPoNum(pAig), i / Saig_ManPoNum(pAig) ); - } - clk = clock(); - status = sat_solver_solve( pSat, &Lit, &Lit + 1, (ABC_INT64_T)nConfLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); - if ( fVerbose && (i % Saig_ManPoNum(pAig) == Saig_ManPoNum(pAig) - 1) ) - { - printf( "Solved %2d outputs of frame %3d. ", - Saig_ManPoNum(pAig), i / Saig_ManPoNum(pAig) ); - printf( "Conf =%8.0f. Imp =%11.0f. ", (double)pSat->stats.conflicts, (double)pSat->stats.propagations ); - ABC_PRT( "T", clock() - clkPart ); - clkPart = clock(); - fflush( stdout ); - } - if ( status == l_False ) - { -/* - Lit = lit_neg( Lit ); - RetValue = sat_solver_addclause( pSat, &Lit, &Lit + 1 ); - assert( RetValue ); - if ( pSat->qtail != pSat->qhead ) - { - RetValue = sat_solver_simplify(pSat); - assert( RetValue ); - } -*/ - } - else if ( status == l_True ) - { - extern void * Fra_SmlCopyCounterExample( Aig_Man_t * pAig, Aig_Man_t * pFrames, int * pModel ); - Vec_Int_t * vCiIds = Cnf_DataCollectPiSatNums( pCnf, pFrames ); - int * pModel = Sat_SolverGetModel( pSat, vCiIds->pArray, vCiIds->nSize ); - pModel[Aig_ManPiNum(pFrames)] = pObj->Id; - pAig->pSeqModel = Fra_SmlCopyCounterExample( pAig, pFrames, pModel ); - ABC_FREE( pModel ); - Vec_IntFree( vCiIds ); - -// if ( piFrame ) -// *piFrame = i / Saig_ManPoNum(pAig); - RetValue = 0; - break; - } - else - { - if ( piFrame ) - *piFrame = i / Saig_ManPoNum(pAig); - RetValue = -1; - break; - } - } + ABC_PRT( "Time", clock() - clk ); } - sat_solver_delete( pSat ); - Cnf_DataFree( pCnf ); - Aig_ManStop( pFrames ); - return RetValue; + if ( RetValue != l_True ) + { + if ( p->iFrameLast >= p->nFramesMax ) + printf( "Reached limit on the number of timeframes (%d).\n", p->nFramesMax ); + else if ( p->pSat->stats.conflicts > p->nConfMaxAll ) + printf( "Reached global conflict limit (%d).\n", p->nConfMaxAll ); + else + printf( "Reached local conflict limit (%d).\n", p->nConfMaxOne ); + } + Saig_BmcManStop( p ); + return Status; } + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigBmc3.c b/src/aig/saig/saigBmc3.c new file mode 100644 index 00000000..a75297f7 --- /dev/null +++ b/src/aig/saig/saigBmc3.c @@ -0,0 +1,1227 @@ +/**CFile**************************************************************** + + FileName [saigBmc3.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Sequential AIG package.] + + Synopsis [Simple BMC package.] + + Author [Alan Mishchenko in collaboration with Niklas Een.] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: saigBmc3.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "saig.h" +#include "fra.h" +#include "cnf.h" +#include "satStore.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Gia_ManBmc_t_ Gia_ManBmc_t; +struct Gia_ManBmc_t_ +{ + // input/output data + Saig_ParBmc_t * pPars; // parameters + Aig_Man_t * pAig; // user AIG + Vec_Ptr_t * vCexes; // counter-examples + // intermediate data + Vec_Int_t * vMapping; // mapping + Vec_Vec_t * vSects; // sections + Vec_Int_t * vId2Num; // number of each node + Vec_Int_t * vVisited; // visited nodes + // SAT variables + Vec_Int_t * vPiVars; // SAT vars for the PIs + Vec_Ptr_t * vId2Var; // SAT vars for each object + // SAT solver + sat_solver * pSat; // SAT solver + int nSatVars; // SAT variables + int nObjNums; // SAT objects + int nBufNum; // the number of simple nodes + int nDupNum; // the number of simple nodes + char * pSopSizes, ** pSops; // CNF representation +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +#define SAIG_TER_ZER 1 +#define SAIG_TER_ONE 2 +#define SAIG_TER_UND 3 + +static inline int Saig_ManBmcSimInfoNot( int Value ) +{ + if ( Value == SAIG_TER_ZER ) + return SAIG_TER_ONE; + if ( Value == SAIG_TER_ONE ) + return SAIG_TER_ZER; + return SAIG_TER_UND; +} + +static inline int Saig_ManBmcSimInfoAnd( int Value0, int Value1 ) +{ + if ( Value0 == SAIG_TER_ZER || Value1 == SAIG_TER_ZER ) + return SAIG_TER_ZER; + if ( Value0 == SAIG_TER_ONE && Value1 == SAIG_TER_ONE ) + return SAIG_TER_ONE; + return SAIG_TER_UND; +} + +static inline int Saig_ManBmcSimInfoGet( unsigned * pInfo, Aig_Obj_t * pObj ) +{ + return 3 & (pInfo[Aig_ObjId(pObj) >> 4] >> ((Aig_ObjId(pObj) & 15) << 1)); +} + +static inline void Saig_ManBmcSimInfoSet( unsigned * pInfo, Aig_Obj_t * pObj, int Value ) +{ + assert( Value >= SAIG_TER_ZER && Value <= SAIG_TER_UND ); + Value ^= Saig_ManBmcSimInfoGet( pInfo, pObj ); + pInfo[Aig_ObjId(pObj) >> 4] ^= (Value << ((Aig_ObjId(pObj) & 15) << 1)); +} + +/**Function************************************************************* + + Synopsis [Returns the number of LIs with binary ternary info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_ManBmcTerSimCount01( Aig_Man_t * p, unsigned * pInfo ) +{ + Aig_Obj_t * pObj; + int i, Counter = 0; + if ( pInfo == NULL ) + return Saig_ManRegNum(p); + Saig_ManForEachLi( p, pObj, i ) + if ( !Aig_ObjIsConst1(Aig_ObjFanin0(pObj)) ) + Counter += (Saig_ManBmcSimInfoGet(pInfo, pObj) != SAIG_TER_UND); + return Counter; +} + +/**Function************************************************************* + + Synopsis [Performs ternary simulation of one frame.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned * Saig_ManBmcTerSimOne( Aig_Man_t * p, unsigned * pPrev ) +{ + Aig_Obj_t * pObj, * pObjLi; + unsigned * pInfo; + int i, Val0, Val1; + pInfo = ABC_CALLOC( unsigned, Aig_BitWordNum(2 * Aig_ManObjNumMax(p)) ); + Saig_ManBmcSimInfoSet( pInfo, Aig_ManConst1(p), SAIG_TER_ONE ); + Saig_ManForEachPi( p, pObj, i ) + Saig_ManBmcSimInfoSet( pInfo, pObj, SAIG_TER_UND ); + if ( pPrev == NULL ) + { + Saig_ManForEachLo( p, pObj, i ) + Saig_ManBmcSimInfoSet( pInfo, pObj, SAIG_TER_ZER ); + } + else + { + Saig_ManForEachLiLo( p, pObjLi, pObj, i ) + Saig_ManBmcSimInfoSet( pInfo, pObj, Saig_ManBmcSimInfoGet(pPrev, pObjLi) ); + } + Aig_ManForEachNode( p, pObj, i ) + { + Val0 = Saig_ManBmcSimInfoGet( pInfo, Aig_ObjFanin0(pObj) ); + Val1 = Saig_ManBmcSimInfoGet( pInfo, Aig_ObjFanin1(pObj) ); + if ( Aig_ObjFaninC0(pObj) ) + Val0 = Saig_ManBmcSimInfoNot( Val0 ); + if ( Aig_ObjFaninC1(pObj) ) + Val1 = Saig_ManBmcSimInfoNot( Val1 ); + Saig_ManBmcSimInfoSet( pInfo, pObj, Saig_ManBmcSimInfoAnd(Val0, Val1) ); + } + Aig_ManForEachPo( p, pObj, i ) + { + Val0 = Saig_ManBmcSimInfoGet( pInfo, Aig_ObjFanin0(pObj) ); + if ( Aig_ObjFaninC0(pObj) ) + Val0 = Saig_ManBmcSimInfoNot( Val0 ); + Saig_ManBmcSimInfoSet( pInfo, pObj, Val0 ); + } + return pInfo; +} + +/**Function************************************************************* + + Synopsis [Collects internal nodes and PIs in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Saig_ManBmcTerSim( Aig_Man_t * p ) +{ + Vec_Ptr_t * vInfos; + unsigned * pInfo = NULL; + int i, TerPrev = ABC_INFINITY, TerCur, CountIncrease = 0; + vInfos = Vec_PtrAlloc( 100 ); + for ( i = 0; i < 1000 && CountIncrease < 5 && TerPrev > 0; i++ ) + { + TerCur = Saig_ManBmcTerSimCount01( p, pInfo ); + if ( TerCur >= TerPrev ) + CountIncrease++; + TerPrev = TerCur; + pInfo = Saig_ManBmcTerSimOne( p, pInfo ); + Vec_PtrPush( vInfos, pInfo ); + } + return vInfos; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_ManBmcTerSimTest( Aig_Man_t * p ) +{ + Vec_Ptr_t * vInfos; + unsigned * pInfo; + int i; + vInfos = Saig_ManBmcTerSim( p ); + Vec_PtrForEachEntry( unsigned *, vInfos, pInfo, i ) + printf( "%d=%d ", i, Saig_ManBmcTerSimCount01(p, pInfo) ); + printf( "\n" ); + Vec_PtrFreeFree( vInfos ); +} + + + +/**Function************************************************************* + + Synopsis [Collects internal nodes in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_ManBmcDfs_rec( Aig_Man_t * p, Aig_Obj_t * pObj, Vec_Ptr_t * vNodes ) +{ + assert( !Aig_IsComplement(pObj) ); + if ( Aig_ObjIsTravIdCurrent(p, pObj) ) + return; + Aig_ObjSetTravIdCurrent(p, pObj); + if ( Aig_ObjIsNode(pObj) ) + { + Saig_ManBmcDfs_rec( p, Aig_ObjFanin0(pObj), vNodes ); + Saig_ManBmcDfs_rec( p, Aig_ObjFanin1(pObj), vNodes ); + } + Vec_PtrPush( vNodes, pObj ); +} + +/**Function************************************************************* + + Synopsis [Collects internal nodes and PIs in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Saig_ManBmcDfsNodes( Aig_Man_t * p, Vec_Ptr_t * vRoots ) +{ + Vec_Ptr_t * vNodes; + Aig_Obj_t * pObj; + int i; + vNodes = Vec_PtrAlloc( 100 ); + Vec_PtrForEachEntry( Aig_Obj_t *, vRoots, pObj, i ) + Saig_ManBmcDfs_rec( p, Aig_ObjFanin0(pObj), vNodes ); + return vNodes; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Vec_t * Saig_ManBmcSections( Aig_Man_t * p ) +{ + Vec_Ptr_t * vSects, * vRoots, * vCone; + Aig_Obj_t * pObj, * pObjPo; + int i; + Aig_ManIncrementTravId( p ); + Aig_ObjSetTravIdCurrent( p, Aig_ManConst1(p) ); + // start the roots + vRoots = Vec_PtrAlloc( 1000 ); + Saig_ManForEachPo( p, pObjPo, i ) + { + Aig_ObjSetTravIdCurrent( p, pObjPo ); + Vec_PtrPush( vRoots, pObjPo ); + } + // compute the cones + vSects = Vec_PtrAlloc( 20 ); + while ( Vec_PtrSize(vRoots) > 0 ) + { + vCone = Saig_ManBmcDfsNodes( p, vRoots ); + Vec_PtrPush( vSects, vCone ); + // get the next set of roots + Vec_PtrClear( vRoots ); + Vec_PtrForEachEntry( Aig_Obj_t *, vCone, pObj, i ) + { + if ( !Saig_ObjIsLo(p, pObj) ) + continue; + pObjPo = Saig_ObjLoToLi( p, pObj ); + if ( Aig_ObjIsTravIdCurrent(p, pObjPo) ) + continue; + Aig_ObjSetTravIdCurrent( p, pObjPo ); + Vec_PtrPush( vRoots, pObjPo ); + } + } + Vec_PtrFree( vRoots ); + return (Vec_Vec_t *)vSects; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_ManBmcSectionsTest( Aig_Man_t * p ) +{ + Vec_Vec_t * vSects; + Vec_Ptr_t * vOne; + int i; + vSects = Saig_ManBmcSections( p ); + Vec_VecForEachLevel( vSects, vOne, i ) + printf( "%d=%d ", i, Vec_PtrSize(vOne) ); + printf( "\n" ); + Vec_VecFree( vSects ); +} + + + +/**Function************************************************************* + + Synopsis [Collects the supergate.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_ManBmcSupergate_rec( Aig_Obj_t * pObj, Vec_Ptr_t * vSuper ) +{ + // if the new node is complemented or a PI, another gate begins + if ( Aig_IsComplement(pObj) || Aig_ObjIsPi(pObj) ) // || (Aig_ObjRefs(pObj) > 1) ) + { + Vec_PtrPushUnique( vSuper, Aig_Regular(pObj) ); + return; + } + // go through the branches + Saig_ManBmcSupergate_rec( Aig_ObjChild0(pObj), vSuper ); + Saig_ManBmcSupergate_rec( Aig_ObjChild1(pObj), vSuper ); +} + +/**Function************************************************************* + + Synopsis [Collect the topmost supergate.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Saig_ManBmcSupergate( Aig_Man_t * p, int iPo ) +{ + Vec_Ptr_t * vSuper; + Aig_Obj_t * pObj; + vSuper = Vec_PtrAlloc( 10 ); + pObj = Aig_ManPo( p, iPo ); + pObj = Aig_ObjChild0( pObj ); + if ( !Aig_IsComplement(pObj) ) + { + Vec_PtrPush( vSuper, pObj ); + return vSuper; + } + pObj = Aig_Regular( pObj ); + if ( !Aig_ObjIsNode(pObj) ) + { + Vec_PtrPush( vSuper, pObj ); + return vSuper; + } + Saig_ManBmcSupergate_rec( Aig_ObjChild0(pObj), vSuper ); + Saig_ManBmcSupergate_rec( Aig_ObjChild1(pObj), vSuper ); + return vSuper; +} + +/**Function************************************************************* + + Synopsis [Returns the number of nodes with ref counter more than 1.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_ManBmcCountRefed( Aig_Man_t * p, Vec_Ptr_t * vSuper ) +{ + Aig_Obj_t * pObj; + int i, Counter = 0; + Vec_PtrForEachEntry( Aig_Obj_t *, vSuper, pObj, i ) + { + assert( !Aig_IsComplement(pObj) ); + Counter += (Aig_ObjRefs(pObj) > 1); + } + return Counter; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_ManBmcSupergateTest( Aig_Man_t * p ) +{ + Vec_Ptr_t * vSuper; + Aig_Obj_t * pObj; + int i; + printf( "Supergates: " ); + Saig_ManForEachPo( p, pObj, i ) + { + vSuper = Saig_ManBmcSupergate( p, i ); + printf( "%d=%d(%d) ", i, Vec_PtrSize(vSuper), Saig_ManBmcCountRefed(p, vSuper) ); + Vec_PtrFree( vSuper ); + } + printf( "\n" ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_ManBmcWriteBlif( Aig_Man_t * p, Vec_Int_t * vMapping, char * pFileName ) +{ + FILE * pFile; + char * pSopSizes, ** pSops; + Aig_Obj_t * pObj; + char Vals[4]; + int i, k, b, iFan, iTruth, * pData; + pFile = fopen( pFileName, "w" ); + if ( pFile == NULL ) + { + printf( "Cannot open file %s\n", pFileName ); + return; + } + fprintf( pFile, ".model test\n" ); + fprintf( pFile, ".inputs" ); + Aig_ManForEachPi( p, pObj, i ) + fprintf( pFile, " n%d", Aig_ObjId(pObj) ); + fprintf( pFile, "\n" ); + fprintf( pFile, ".outputs" ); + Aig_ManForEachPo( p, pObj, i ) + fprintf( pFile, " n%d", Aig_ObjId(pObj) ); + fprintf( pFile, "\n" ); + fprintf( pFile, ".names" ); + fprintf( pFile, " n%d\n", Aig_ObjId(Aig_ManConst1(p)) ); + fprintf( pFile, " 1\n" ); + + Cnf_ReadMsops( &pSopSizes, &pSops ); + Aig_ManForEachNode( p, pObj, i ) + { + if ( Vec_IntEntry(vMapping, i) == 0 ) + continue; + pData = Vec_IntEntryP( vMapping, Vec_IntEntry(vMapping, i) ); + fprintf( pFile, ".names" ); + for ( iFan = 0; iFan < 4; iFan++ ) + if ( pData[iFan+1] >= 0 ) + fprintf( pFile, " n%d", pData[iFan+1] ); + else + break; + fprintf( pFile, " n%d\n", i ); + // write SOP + iTruth = pData[0] & 0xffff; + for ( k = 0; k < pSopSizes[iTruth]; k++ ) + { + int Lit = pSops[iTruth][k]; + for ( b = 3; b >= 0; b-- ) + { + if ( Lit % 3 == 0 ) + Vals[b] = '0'; + else if ( Lit % 3 == 1 ) + Vals[b] = '1'; + else + Vals[b] = '-'; + Lit = Lit / 3; + } + for ( b = 0; b < iFan; b++ ) + fprintf( pFile, "%c", Vals[b] ); + fprintf( pFile, " 1\n" ); + } + } + free( pSopSizes ); + free( pSops[1] ); + free( pSops ); + + Aig_ManForEachPo( p, pObj, i ) + { + fprintf( pFile, ".names" ); + fprintf( pFile, " n%d", Aig_ObjId(Aig_ObjFanin0(pObj)) ); + fprintf( pFile, " n%d\n", Aig_ObjId(pObj) ); + fprintf( pFile, "%d 1\n", !Aig_ObjFaninC0(pObj) ); + } + fprintf( pFile, ".end\n" ); + fclose( pFile ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_ManBmcMappingTest( Aig_Man_t * p ) +{ + Vec_Int_t * vMapping; + vMapping = Cnf_DeriveMappingArray( p ); + Saig_ManBmcWriteBlif( p, vMapping, "test.blif" ); + Vec_IntFree( vMapping ); +} + + + + + + + +/**Function************************************************************* + + Synopsis [Create manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_ManBmc_t * Saig_Bmc3ManStart( Aig_Man_t * pAig ) +{ + Gia_ManBmc_t * p; + Aig_Obj_t * pObj; + int i; + assert( Aig_ManRegNum(pAig) > 0 ); + p = ABC_CALLOC( Gia_ManBmc_t, 1 ); + p->pAig = pAig; + // create mapping + p->vMapping = Cnf_DeriveMappingArray( pAig ); + // create sections + p->vSects = Saig_ManBmcSections( pAig ); + // map object IDs into their numbers and section numbers + p->nObjNums = 0; + p->vId2Num = Vec_IntStartFull( Aig_ManObjNumMax(pAig) ); + Vec_IntWriteEntry( p->vId2Num, Aig_ObjId(Aig_ManConst1(pAig)), p->nObjNums++ ); + Aig_ManForEachPi( pAig, pObj, i ) + Vec_IntWriteEntry( p->vId2Num, Aig_ObjId(pObj), p->nObjNums++ ); + Aig_ManForEachNode( pAig, pObj, i ) + if ( Vec_IntEntry(p->vMapping, Aig_ObjId(pObj)) > 0 ) + Vec_IntWriteEntry( p->vId2Num, Aig_ObjId(pObj), p->nObjNums++ ); + Aig_ManForEachPo( pAig, pObj, i ) + Vec_IntWriteEntry( p->vId2Num, Aig_ObjId(pObj), p->nObjNums++ ); + p->vPiVars = Vec_IntAlloc( 1000 ); + p->vId2Var = Vec_PtrAlloc( 100 ); + p->vVisited = Vec_IntAlloc( 1000 ); + // create solver + p->nSatVars = 1; + p->pSat = sat_solver_new(); + sat_solver_setnvars( p->pSat, 1000 ); + Cnf_ReadMsops( &p->pSopSizes, &p->pSops ); + return p; +} + +/**Function************************************************************* + + Synopsis [Delete manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_Bmc3ManStop( Gia_ManBmc_t * p ) +{ + if ( p->vCexes ) + { + assert( p->pAig->pSeqModelVec == NULL ); + p->pAig->pSeqModelVec = p->vCexes; + p->vCexes = NULL; + } +// Vec_PtrFreeFree( p->vCexes ); + Vec_IntFree( p->vMapping ); + Vec_VecFree( p->vSects ); + Vec_IntFree( p->vId2Num ); + Vec_IntFree( p->vPiVars ); + Vec_IntFree( p->vVisited ); + Vec_VecFree( (Vec_Vec_t *)p->vId2Var ); + sat_solver_delete( p->pSat ); + free( p->pSopSizes ); + free( p->pSops[1] ); + free( p->pSops ); + free( p ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int * Saig_ManBmcMapping( Gia_ManBmc_t * p, Aig_Obj_t * pObj ) +{ + if ( Vec_IntEntry(p->vMapping, Aig_ObjId(pObj)) == 0 ) + return NULL; + return Vec_IntEntryP( p->vMapping, Vec_IntEntry(p->vMapping, Aig_ObjId(pObj)) ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Saig_ManBmcLiteral( Gia_ManBmc_t * p, Aig_Obj_t * pObj, int iFrame ) +{ + Vec_Int_t * vFrame; + int ObjNum; + assert( !Aig_ObjIsNode(pObj) || Saig_ManBmcMapping(p, pObj) ); + ObjNum = Vec_IntEntry( p->vId2Num, Aig_ObjId(pObj) ); + assert( ObjNum >= 0 ); + vFrame = (Vec_Int_t *)Vec_PtrEntry( p->vId2Var, iFrame ); + assert( vFrame != NULL ); + return Vec_IntEntry( vFrame, ObjNum ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Saig_ManBmcSetLiteral( Gia_ManBmc_t * p, Aig_Obj_t * pObj, int iFrame, int iLit ) +{ + Vec_Int_t * vFrame; + int ObjNum; + assert( !Aig_ObjIsNode(pObj) || Saig_ManBmcMapping(p, pObj) ); + ObjNum = Vec_IntEntry( p->vId2Num, Aig_ObjId(pObj) ); + vFrame = (Vec_Int_t *)Vec_PtrEntry( p->vId2Var, iFrame ); + Vec_IntWriteEntry( vFrame, ObjNum, iLit ); + if ( iLit == ABC_INFINITY || iLit == ABC_INFINITY+1 ) + { + Vec_IntPush( p->vVisited, Aig_ObjId(pObj) ); + Vec_IntPush( p->vVisited, iFrame ); + } + else if ( iLit != ~0 && Saig_ObjIsPi(p->pAig, pObj) ) // save PI SAT var num + Vec_IntWriteEntry( p->vPiVars, iFrame*Saig_ManPiNum(p->pAig)+Aig_ObjPioNum(pObj), lit_var(iLit) ); + return iLit; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Saig_ManBmcCof0( int t, int v ) +{ + static int s_Truth[4] = { 0xAAAA, 0xCCCC, 0xF0F0, 0xFF00 }; + return 0xffff & ((t & ~s_Truth[v]) | ((t & ~s_Truth[v]) << (1<<v))); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Saig_ManBmcCof1( int t, int v ) +{ + static int s_Truth[4] = { 0xAAAA, 0xCCCC, 0xF0F0, 0xFF00 }; + return 0xffff & ((t & s_Truth[v]) | ((t & s_Truth[v]) >> (1<<v))); +} + +/**Function************************************************************* + + Synopsis [Derives CNF for one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Saig_ManBmcDeriveTruth( int uTruth, int Lits[] ) +{ + int v; + for ( v = 0; v < 4; v++ ) + if ( Lits[v] == 0 ) + { + uTruth = Saig_ManBmcCof0(uTruth, v); + Lits[v] = -1; + } + else if ( Lits[v] == 1 ) + { + uTruth = Saig_ManBmcCof1(uTruth, v); + Lits[v] = -1; + } + for ( v = 0; v < 4; v++ ) + if ( Lits[v] == -1 ) + assert( Saig_ManBmcCof0(uTruth, v) == Saig_ManBmcCof1(uTruth, v) ); + return uTruth; +} + +/* +void Cnf_SopConvertToVector( char * pSop, int nCubes, Vec_Int_t * vCover ) +{ + int Lits[4], Cube, iCube, i, b; + Vec_IntClear( vCover ); + for ( i = 0; i < nCubes; i++ ) + { + Cube = pSop[i]; + for ( b = 0; b < 4; b++ ) + { + if ( Cube % 3 == 0 ) + Lits[b] = 1; + else if ( Cube % 3 == 1 ) + Lits[b] = 2; + else + Lits[b] = 0; + Cube = Cube / 3; + } + iCube = 0; + for ( b = 0; b < 4; b++ ) + iCube = (iCube << 2) | Lits[b]; + Vec_IntPush( vCover, iCube ); + } +} + + Vec_IntForEachEntry( vCover, Cube, k ) + { + *pClas++ = pLits; + *pLits++ = 2 * OutVar; + pLits += Cnf_IsopWriteCube( Cube, pCut->nFanins, pVars, pLits ); + } + + +int Cnf_IsopWriteCube( int Cube, int nVars, int * pVars, int * pLiterals ) +{ + int nLits = nVars, b; + for ( b = 0; b < nVars; b++ ) + { + if ( (Cube & 3) == 1 ) // value 0 --> write positive literal + *pLiterals++ = 2 * pVars[b]; + else if ( (Cube & 3) == 2 ) // value 1 --> write negative literal + *pLiterals++ = 2 * pVars[b] + 1; + else + nLits--; + Cube >>= 2; + } + return nLits; +} + + iTruth = pData[0] & 0xffff; + for ( k = 0; k < pSopSizes[iTruth]; k++ ) + { + int Lit = pSops[iTruth][k]; + for ( b = 3; b >= 0; b-- ) + { + if ( Lit % 3 == 0 ) + Vals[b] = '0'; + else if ( Lit % 3 == 1 ) + Vals[b] = '1'; + else + Vals[b] = '-'; + Lit = Lit / 3; + } + for ( b = 0; b < iFan; b++ ) + fprintf( pFile, "%c", Vals[b] ); + fprintf( pFile, " 1\n" ); + } +*/ + +/**Function************************************************************* + + Synopsis [Derives CNF for one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Saig_ManBmcAddClauses( Gia_ManBmc_t * p, int uTruth, int Lits[], int iLitOut ) +{ + int i, k, b, CutLit, nClaLits, ClaLits[5]; + assert( uTruth > 0 && uTruth < 0xffff ); + // write positive/negative polarity + for ( i = 0; i < 2; i++ ) + { + if ( i ) + uTruth = 0xffff & ~uTruth; +// Extra_PrintBinary( stdout, &uTruth, 16 ); printf( "\n" ); + for ( k = 0; k < p->pSopSizes[uTruth]; k++ ) + { + nClaLits = 0; + ClaLits[nClaLits++] = i ? lit_neg(iLitOut) : iLitOut; + CutLit = p->pSops[uTruth][k]; + for ( b = 3; b >= 0; b-- ) + { + if ( CutLit % 3 == 0 ) // value 0 --> write positive literal + { + assert( Lits[b] > 1 ); + ClaLits[nClaLits++] = Lits[b]; + } + else if ( CutLit % 3 == 1 ) // value 1 --> write negative literal + { + assert( Lits[b] > 1 ); + ClaLits[nClaLits++] = lit_neg(Lits[b]); + } + CutLit = CutLit / 3; + } + +// for ( b = 0; b < nClaLits; b++ ) +// printf( "%d ", ClaLits[b] ); +// printf( "\n" ); + + if ( !sat_solver_addclause( p->pSat, ClaLits, ClaLits+nClaLits ) ) + assert( 0 ); + } + } +} + +/**Function************************************************************* + + Synopsis [Derives CNF for one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_ManBmcCreateCnf_rec( Gia_ManBmc_t * p, Aig_Obj_t * pObj, int iFrame, int fAddClauses ) +{ + int * pMapping, i, iLit, Lits[4], uTruth; + iLit = Saig_ManBmcLiteral( p, pObj, iFrame ); + if ( iLit != ~0 ) + return iLit; + assert( iFrame >= 0 ); + if ( Aig_ObjIsPi(pObj) ) + { + if ( Saig_ObjIsPi(p->pAig, pObj) ) + iLit = fAddClauses ? toLit( p->nSatVars++ ) : ABC_INFINITY; + else + iLit = Saig_ManBmcCreateCnf_rec( p, Saig_ObjLoToLi(p->pAig, pObj), iFrame-1, fAddClauses ); + return Saig_ManBmcSetLiteral( p, pObj, iFrame, iLit ); + } + if ( Aig_ObjIsPo(pObj) ) + { + iLit = Saig_ManBmcCreateCnf_rec( p, Aig_ObjFanin0(pObj), iFrame, fAddClauses ); + if ( Aig_ObjFaninC0(pObj) ) + iLit = lit_neg(iLit); + return Saig_ManBmcSetLiteral( p, pObj, iFrame, iLit ); + } + assert( Aig_ObjIsNode(pObj) ); + pMapping = Saig_ManBmcMapping( p, pObj ); + for ( i = 0; i < 4; i++ ) + if ( pMapping[i+1] == -1 ) + Lits[i] = -1; + else + Lits[i] = Saig_ManBmcCreateCnf_rec( p, Aig_ManObj(p->pAig, pMapping[i+1]), iFrame, fAddClauses ); + // derive new truth table +//uTruth = 0xffff & (unsigned)pMapping[0]; +//printf( "Truth : " ); +//Extra_PrintBinary( stdout, &uTruth, 16 ); printf( "\n" ); + uTruth = Saig_ManBmcDeriveTruth( 0xffff & (unsigned)pMapping[0], Lits ); + if ( uTruth == 0 || uTruth == 0xffff ) + { + iLit = (uTruth == 0xffff); + return Saig_ManBmcSetLiteral( p, pObj, iFrame, iLit ); + } + // create CNF + if ( fAddClauses ) + { + iLit = toLit( p->nSatVars++ ); + Saig_ManBmcAddClauses( p, uTruth, Lits, iLit ); + + if ( uTruth == 0xAAAA || (0xffff & ~uTruth) == 0xAAAA || + uTruth == 0xCCCC || (0xffff & ~uTruth) == 0xCCCC || + uTruth == 0xF0F0 || (0xffff & ~uTruth) == 0xF0F0 || + uTruth == 0xFF00 || (0xffff & ~uTruth) == 0xFF00 ) + p->nBufNum++; + + if ( (Lits[0] > 1 && (Lits[0] == Lits[1] || Lits[0] == Lits[2] || Lits[0] == Lits[3])) || + (Lits[1] > 1 && (Lits[1] == Lits[2] || Lits[1] == Lits[2])) || + (Lits[2] > 1 && (Lits[2] == Lits[3])) ) + p->nDupNum++; + + } + else + { + iLit = ABC_INFINITY; + } + return Saig_ManBmcSetLiteral( p, pObj, iFrame, iLit ); +} + +/**Function************************************************************* + + Synopsis [Derives CNF for one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_ManBmcCreateCnf( Gia_ManBmc_t * p, Aig_Obj_t * pObj, int iFrame ) +{ + int i, iLit, Entry, iFrameOld, Value; + Vec_IntClear( p->vVisited ); + iLit = Saig_ManBmcCreateCnf_rec( p, pObj, iFrame, 0 ); + Vec_IntForEachEntry( p->vVisited, Entry, i ) + { + iFrameOld = Vec_IntEntry( p->vVisited, ++i ); + Value = Saig_ManBmcLiteral( p, Aig_ManObj(p->pAig, Entry), iFrameOld ); +// assert( Value == 0 || Value == 1 || Value == ABC_INFINITY || Value == ABC_INFINITY+1 ); + assert( Value == ABC_INFINITY || Value == ABC_INFINITY+1 ); + if ( !(Value == ABC_INFINITY || Value == ABC_INFINITY+1) ) + printf( "Internal error!\n" ); +// if ( Value == 0 || Value == 1 ) +// continue; + Saig_ManBmcSetLiteral( p, Aig_ManObj(p->pAig, Entry), iFrameOld, ~0 ); + } + if ( iLit < 2 ) + return iLit; + return Saig_ManBmcCreateCnf_rec( p, pObj, iFrame, 1 ); +} + + + +/**Function************************************************************* + + Synopsis [This procedure sets default parameters.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_ParBmcSetDefaultParams( Saig_ParBmc_t * p ) +{ + memset( p, 0, sizeof(Saig_ParBmc_t) ); + p->nStart = 0; // maximum number of timeframes + p->nFramesMax = 2000; // maximum number of timeframes + p->nConfLimit = 2000; // maximum number of conflicts at a node + p->nTimeOut = 0; // approximate timeout in seconds + p->fSolveAll = 0; // stops on the first SAT instance + p->fDropSatOuts = 0; // replace sat outputs by constant 0 + p->fVerbose = 0; // verbose + p->iFrame = -1; // explored up to this frame + p->nFailOuts = 0; // the number of failed outputs +} + +/**Function************************************************************* + + Synopsis [Bounded model checking engine.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_ManBmcScalable( Aig_Man_t * pAig, Saig_ParBmc_t * pPars ) +{ + Gia_ManBmc_t * p; + Aig_Obj_t * pObj; + int RetValue = -1, fFirst = 1; + int i, f, Lit, status, clk, clk2, clkOther = 0, clkTotal = clock(); + if ( pPars->fVerbose && Aig_ManConstrNum(pAig) > 0 ) + printf( "Performing BMC with constraints...\n" ); + p = Saig_Bmc3ManStart( pAig ); + p->pPars = pPars; + if ( pPars->fVerbose ) + { + printf( "AIG: PI/PO/Reg = %d/%d/%d. Node = %6d. Lev = %5d. Map = %6d. Sect =%3d.\n", + Saig_ManPiNum(pAig), Saig_ManPoNum(pAig), Saig_ManRegNum(pAig), + Aig_ManNodeNum(pAig), Aig_ManLevelNum(pAig), (Vec_IntSize(p->vMapping)-Aig_ManObjNumMax(pAig))/5, Vec_VecSize(p->vSects) ); + printf( "Params: Start = %d. FramesMax = %d. ConfLimit = %d. TimeOut = %d. SolveAll = %d.\n", + pPars->nStart, pPars->nFramesMax, pPars->nConfLimit, pPars->nTimeOut, pPars->fSolveAll ); + } + for ( f = 0; f < pPars->nFramesMax; f++ ) + { + pPars->iFrame = f; + // resize the array + Vec_IntFillExtra( p->vPiVars, (f+1)*Saig_ManPiNum(p->pAig), 0 ); + // map nodes of this section + Vec_PtrPush( p->vId2Var, Vec_IntStartFull(p->nObjNums) ); +/* + if ( f > 2*Vec_VecSize(p->vSects) ) + { + int iFrameOld = f - 2*Vec_VecSize( p->vSects ); + void * pMemory = Vec_IntReleaseArray( Vec_PtrEntry(p->vId2Var, iFrameOld) ); + ABC_FREE( pMemory ); + } +*/ + // prepare some nodes + Saig_ManBmcSetLiteral( p, Aig_ManConst1(pAig), f, 1 ); + if ( f == 0 ) + Saig_ManForEachLo( p->pAig, pObj, i ) + Saig_ManBmcSetLiteral( p, pObj, 0, 0 ); + // add the constraints for this frame + Saig_ManForEachPo( pAig, pObj, i ) + { + if ( i < Saig_ManPoNum(pAig) - Saig_ManConstrNum(pAig) ) + continue; +clk2 = clock(); + Lit = Saig_ManBmcCreateCnf( p, pObj, f ); + Lit = lit_neg( Lit ); +clkOther += clock() - clk2; + status = sat_solver_addclause( p->pSat, &Lit, &Lit + 1 ); + if ( status == 0 ) + { + printf( "SAT problem became UNSAT after adding constraints in frame %d.\n", f ); + Saig_Bmc3ManStop( p ); + return 1; + } + } + // solve SAT + clk = clock(); + Saig_ManForEachPo( pAig, pObj, i ) + { + if ( i >= Saig_ManPoNum(pAig) - Saig_ManConstrNum(pAig) ) + break; + // skip solved outputs + if ( p->vCexes && Vec_PtrEntry(p->vCexes, i) ) + continue; + // add constraints for this output +clk2 = clock(); + Lit = Saig_ManBmcCreateCnf( p, pObj, f ); +clkOther += clock() - clk2; + if ( Lit == 0 ) + continue; + if ( Lit == 1 ) + { + extern Abc_Cex_t * Fra_SmlTrivCounterExample( Aig_Man_t * pAig, int iFrameOut ); + Abc_Cex_t * pCex = Fra_SmlTrivCounterExample( pAig, f*Saig_ManPoNum(pAig)+i ); + printf( "Output %d is trivially SAT in frame %d.\n", i, f ); + if ( !pPars->fSolveAll ) + { + ABC_FREE( pAig->pSeqModel ); + pAig->pSeqModel = pCex; + Saig_Bmc3ManStop( p ); + return 0; + } + pPars->nFailOuts++; + if ( p->vCexes == NULL ) + p->vCexes = Vec_PtrStart( Saig_ManPoNum(pAig) ); + Vec_PtrWriteEntry( p->vCexes, i, pCex ); + continue; + } + // solve this output + sat_solver_compress( p->pSat ); + status = sat_solver_solve( p->pSat, &Lit, &Lit + 1, (ABC_INT64_T)pPars->nConfLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); + if ( status == l_False ) + {/* + Lit = lit_neg( Lit ); + status = sat_solver_addclause( p->pSat, &Lit, &Lit + 1 ); + assert( status ); + sat_solver_compress( p->pSat ); + */ + } + else if ( status == l_True ) + { +// extern void * Fra_SmlSimpleCounterExample( Aig_Man_t * p, int * pModel, int iFrame, int iPo ); + int * pModel = Sat_SolverGetModel( p->pSat, Vec_IntArray(p->vPiVars), Vec_IntSize(p->vPiVars) ); + Abc_Cex_t * pCex = Fra_SmlSimpleCounterExample( pAig, pModel, f, i ); + ABC_FREE( pModel ); + fFirst = 0; + if ( !pPars->fSolveAll ) + { +//ABC_PRT( "CNF generation runtime", clkOther ); + if ( pPars->fVerbose ) + { + printf( "%3d : ", f ); + printf( "Var =%8.0f. ", (double)p->nSatVars ); + printf( "Cla =%9.0f. ", (double)p->pSat->stats.clauses ); + printf( "Conf =%7.0f. ",(double)p->pSat->stats.conflicts ); + printf( "Imp =%10.0f. ", (double)p->pSat->stats.propagations ); + ABC_PRT( "Time", clock() - clk ); + ABC_PRM( "Id2Var", (f+1)*p->nObjNums*4 ); + ABC_PRM( "SAT", 42 * p->pSat->size + 16 * (int)p->pSat->stats.clauses + 4 * (int)p->pSat->stats.clauses_literals ); + printf( "Simples = %6d. ", p->nBufNum ); +// printf( "Dups = %6d. ", p->nDupNum ); + printf( "\n" ); + fflush( stdout ); + } + ABC_FREE( pAig->pSeqModel ); + pAig->pSeqModel = pCex; + Saig_Bmc3ManStop( p ); + return 0; + } + pPars->nFailOuts++; + printf( "Output %d was asserted in frame %d (use \"write_counter\" to dump a witness).\n", i, f ); + if ( p->vCexes == NULL ) + p->vCexes = Vec_PtrStart( Saig_ManPoNum(pAig) ); + Vec_PtrWriteEntry( p->vCexes, i, pCex ); + } + else + { + assert( status == l_Undef ); + Saig_Bmc3ManStop( p ); + return RetValue; + } + if ( pPars->nTimeOut && ((float)pPars->nTimeOut <= (float)(clock()-clkTotal)/(float)(CLOCKS_PER_SEC)) ) + { + printf( "Reached timeout (%d seconds).\n", pPars->nTimeOut ); + Saig_Bmc3ManStop( p ); + return RetValue; + } + } + if ( pPars->fVerbose ) + { + if ( fFirst == 1 && f > 0 && p->pSat->stats.conflicts > 1 ) + { + fFirst = 0; +// printf( "Outputs of frames up to %d are trivially UNSAT.\n", f ); + } + printf( "%3d : ", f ); + printf( "Var =%8.0f. ", (double)p->nSatVars ); + printf( "Cla =%9.0f. ", (double)p->pSat->stats.clauses ); + printf( "Conf =%7.0f. ",(double)p->pSat->stats.conflicts ); + printf( "Imp =%10.0f. ", (double)p->pSat->stats.propagations ); + ABC_PRT( "Time", clock() - clk ); +// ABC_PRM( "Id2Var", (f+1)*p->nObjNums*4 ); +// ABC_PRM( "SAT", 42 * p->pSat->size + 16 * (int)p->pSat->stats.clauses + 4 * (int)p->pSat->stats.clauses_literals ); +// printf( "Simples = %6d. ", p->nBufNum ); +// printf( "Dups = %6d. ", p->nDupNum ); +// printf( "\n" ); + fflush( stdout ); + } + } +//ABC_PRT( "CNF generation runtime", clkOther ); + if ( pPars->fVerbose ) + { + ABC_PRM( "Id2Var", (f+1)*p->nObjNums*4 ); + ABC_PRM( "SAT", 48 * p->pSat->size + 16 * (int)p->pSat->stats.clauses + 4 * (int)p->pSat->stats.clauses_literals ); + printf( "Simples = %6d. ", p->nBufNum ); +// printf( "Dups = %6d. ", p->nDupNum ); + printf( "\n" ); + } + Saig_Bmc3ManStop( p ); + return RetValue; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigCone.c b/src/aig/saig/saigCone.c index 7ca077c8..2b0da5c9 100644 --- a/src/aig/saig/saigCone.c +++ b/src/aig/saig/saigCone.c @@ -20,6 +20,9 @@ #include "saig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -78,7 +81,7 @@ Vec_Ptr_t * Saig_ManSupport( Aig_Man_t * p, Vec_Ptr_t * vNodes ) int i; vSupp = Vec_PtrAlloc( 100 ); Aig_ManIncrementTravId( p ); - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) { assert( Aig_ObjIsPo(pObj) ); Saig_ManSupport_rec( p, Aig_ObjFanin0(pObj), vSupp ); @@ -115,7 +118,7 @@ void Saig_ManPrintConeOne( Aig_Man_t * p, Aig_Obj_t * pObj ) { // classify current into those new, prev, and older nCurNew = nCurPrev = nCurOld = 0; - Vec_PtrForEachEntry( vCur, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vCur, pObj, i ) { if ( Vec_PtrFind(vTotal, pObj) == -1 ) { @@ -174,3 +177,5 @@ void Saig_ManPrintCones( Aig_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigConstr.c b/src/aig/saig/saigConstr.c new file mode 100644 index 00000000..b4024634 --- /dev/null +++ b/src/aig/saig/saigConstr.c @@ -0,0 +1,384 @@ +/**CFile**************************************************************** + + FileName [saigConstr.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Sequential AIG package.] + + Synopsis [Structural constraint detection.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: saigConstr.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "saig.h" +#include "cnf.h" +#include "satSolver.h" +#include "kit.h" +#include "ioa.h" + +ABC_NAMESPACE_IMPL_START + + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static int Saig_ManDetectConstr( Aig_Man_t * p, Vec_Ptr_t ** pvOuts, Vec_Ptr_t ** pvCons ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Duplicates the AIG while unfolding constraints.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Saig_ManDupUnfoldConstrs( Aig_Man_t * pAig ) +{ + Vec_Ptr_t * vOuts, * vCons; + Aig_Man_t * pAigNew; + Aig_Obj_t * pMiter, * pObj; + int i, RetValue; + RetValue = Saig_ManDetectConstr( pAig, &vOuts, &vCons ); + if ( RetValue == 0 ) + return Aig_ManDupDfs( pAig ); + // start the new manager + pAigNew = Aig_ManStart( Aig_ManNodeNum(pAig) ); + pAigNew->pName = Aig_UtilStrsav( pAig->pName ); + // map the constant node + Aig_ManConst1(pAig)->pData = Aig_ManConst1( pAigNew ); + // create variables for PIs + Aig_ManForEachPi( pAig, pObj, i ) + pObj->pData = Aig_ObjCreatePi( pAigNew ); + // add internal nodes of this frame + Aig_ManForEachNode( pAig, pObj, i ) + pObj->pData = Aig_And( pAigNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + // AND the outputs + pMiter = Aig_ManConst1( pAigNew ); + Vec_PtrForEachEntry( Aig_Obj_t *, vOuts, pObj, i ) + pMiter = Aig_And( pAigNew, pMiter, Aig_Not(Aig_ObjRealCopy(pObj)) ); + Aig_ObjCreatePo( pAigNew, pMiter ); + // add constraints + pAigNew->nConstrs = Vec_PtrSize(vCons); + Vec_PtrForEachEntry( Aig_Obj_t *, vCons, pObj, i ) + Aig_ObjCreatePo( pAigNew, Aig_ObjRealCopy(pObj) ); + // transfer to register outputs + Saig_ManForEachLi( pAig, pObj, i ) + Aig_ObjCreatePo( pAigNew, Aig_ObjChild0Copy(pObj) ); + Vec_PtrFreeP( &vOuts ); + Vec_PtrFreeP( &vCons ); + + Aig_ManSetRegNum( pAigNew, Aig_ManRegNum(pAig) ); + Aig_ManCleanup( pAigNew ); + Aig_ManSeqCleanup( pAigNew ); + return pAigNew; +} + +/**Function************************************************************* + + Synopsis [Duplicates the AIG while folding in the constraints.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Saig_ManDupFoldConstrs( Aig_Man_t * pAig, Vec_Int_t * vConstrs ) +{ + Aig_Man_t * pAigNew; + Aig_Obj_t * pMiter, * pFlopOut, * pFlopIn, * pObj; + int Entry, i; + assert( Saig_ManRegNum(pAig) > 0 ); + // start the new manager + pAigNew = Aig_ManStart( Aig_ManNodeNum(pAig) ); + pAigNew->pName = Aig_UtilStrsav( pAig->pName ); + // map the constant node + Aig_ManConst1(pAig)->pData = Aig_ManConst1( pAigNew ); + // create variables for PIs + Aig_ManForEachPi( pAig, pObj, i ) + pObj->pData = Aig_ObjCreatePi( pAigNew ); + // add internal nodes of this frame + Aig_ManForEachNode( pAig, pObj, i ) + pObj->pData = Aig_And( pAigNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + + // OR the constraint outputs + pMiter = Aig_ManConst0( pAigNew ); + Vec_IntForEachEntry( vConstrs, Entry, i ) + { + assert( Entry > 0 && Entry < Saig_ManPoNum(pAig) ); + pObj = Aig_ManPo( pAig, Entry ); + pMiter = Aig_Or( pAigNew, pMiter, Aig_ObjChild0Copy(pObj) ); + } + // create additional flop + pFlopOut = Aig_ObjCreatePi( pAigNew ); + pFlopIn = Aig_Or( pAigNew, pMiter, pFlopOut ); + + // create primary output + Saig_ManForEachPo( pAig, pObj, i ) + { + pMiter = Aig_And( pAigNew, Aig_ObjChild0Copy(pObj), Aig_Not(pFlopIn) ); + Aig_ObjCreatePo( pAigNew, pMiter ); + } + + // transfer to register outputs + Saig_ManForEachLi( pAig, pObj, i ) + Aig_ObjCreatePo( pAigNew, Aig_ObjChild0Copy(pObj) ); + // create additional flop + Aig_ObjCreatePo( pAigNew, pFlopIn ); + + Aig_ManSetRegNum( pAigNew, Aig_ManRegNum(pAig)+1 ); + Aig_ManCleanup( pAigNew ); + Aig_ManSeqCleanup( pAigNew ); + return pAigNew; +} + + +/**Function************************************************************* + + Synopsis [Tests the above two procedures.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_ManFoldConstrTest( Aig_Man_t * pAig ) +{ + Aig_Man_t * pAig1, * pAig2; + Vec_Int_t * vConstrs; + // unfold constraints + pAig1 = Saig_ManDupUnfoldConstrs( pAig ); + // create the constraint list + vConstrs = Vec_IntStartNatural( Saig_ManPoNum(pAig1) ); + Vec_IntRemove( vConstrs, 0 ); + // fold constraints back + pAig2 = Saig_ManDupFoldConstrs( pAig1, vConstrs ); + Vec_IntFree( vConstrs ); + // compare the two AIGs + Ioa_WriteAiger( pAig2, "test.aig", 0, 0 ); + Aig_ManStop( pAig1 ); + Aig_ManStop( pAig2 ); +} + + + + +/**Function************************************************************* + + Synopsis [Collects the supergate.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_DetectConstrCollectSuper_rec( Aig_Obj_t * pObj, Vec_Ptr_t * vSuper ) +{ + // if the new node is complemented or a PI, another gate begins + if ( Aig_IsComplement(pObj) || !Aig_ObjIsNode(pObj) )//|| (Aig_ObjRefs(pObj) > 1) ) + { + Vec_PtrPushUnique( vSuper, Aig_Not(pObj) ); + return; + } + // go through the branches + Saig_DetectConstrCollectSuper_rec( Aig_ObjChild0(pObj), vSuper ); + Saig_DetectConstrCollectSuper_rec( Aig_ObjChild1(pObj), vSuper ); +} + +/**Function************************************************************* + + Synopsis [Collects the supergate.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Saig_DetectConstrCollectSuper( Aig_Obj_t * pObj ) +{ + Vec_Ptr_t * vSuper; + assert( !Aig_IsComplement(pObj) ); + assert( Aig_ObjIsAnd(pObj) ); + vSuper = Vec_PtrAlloc( 4 ); + Saig_DetectConstrCollectSuper_rec( Aig_ObjChild0(pObj), vSuper ); + Saig_DetectConstrCollectSuper_rec( Aig_ObjChild1(pObj), vSuper ); + return vSuper; +} + +/**Function************************************************************* + + Synopsis [Returns NULL if not contained, or array with unique entries.] + + Description [Returns NULL if vSuper2 is not contained in vSuper. Otherwise + returns the array of entries in vSuper that are not found in vSuper2.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Saig_ManDetectConstrCheckCont( Vec_Ptr_t * vSuper, Vec_Ptr_t * vSuper2 ) +{ + Vec_Ptr_t * vUnique; + Aig_Obj_t * pObj, * pObj2; + int i; + Vec_PtrForEachEntry( Aig_Obj_t *, vSuper2, pObj2, i ) + if ( Vec_PtrFind( vSuper, pObj2 ) == -1 ) + return 0; + vUnique = Vec_PtrAlloc( 100 ); + Vec_PtrForEachEntry( Aig_Obj_t *, vSuper, pObj, i ) + if ( Vec_PtrFind( vSuper2, pObj ) == -1 ) + Vec_PtrPush( vUnique, pObj ); + return vUnique; +} + +/**Function************************************************************* + + Synopsis [Detects constraints using structural methods.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_ManDetectConstr( Aig_Man_t * p, Vec_Ptr_t ** pvOuts, Vec_Ptr_t ** pvCons ) +{ + Vec_Ptr_t * vSuper, * vSuper2, * vUnique; + Aig_Obj_t * pObj, * pObj2, * pFlop; + int i, nFlops, RetValue; + *pvOuts = NULL; + *pvCons = NULL; + if ( Saig_ManPoNum(p) != 1 ) + { + printf( "The number of POs is other than 1.\n" ); + return 0; + } + pObj = Aig_ObjChild0( Aig_ManPo(p, 0) ); + if ( Aig_IsComplement(pObj) || !Aig_ObjIsNode(pObj) ) + { + printf( "The output is not an AND.\n" ); + return 0; + } + vSuper = Saig_DetectConstrCollectSuper( pObj ); + assert( Vec_PtrSize(vSuper) >= 2 ); + nFlops = 0; + Vec_PtrForEachEntry( Aig_Obj_t *, vSuper, pObj, i ) + nFlops += Saig_ObjIsLo( p, Aig_Regular(pObj) ); + if ( nFlops == 0 ) + { + printf( "There is no flop outputs.\n" ); + Vec_PtrFree( vSuper ); + return 0; + } + // try flops + vUnique = NULL; + Vec_PtrForEachEntry( Aig_Obj_t *, vSuper, pObj, i ) + { + pFlop = Aig_Regular( pObj ); + if ( !Saig_ObjIsLo(p, pFlop) ) + continue; + pFlop = Saig_ObjLoToLi( p, pFlop ); + pObj2 = Aig_ObjChild0( pFlop ); + if ( !Aig_IsComplement(pObj2) || !Aig_ObjIsNode(Aig_Regular(pObj2)) ) + continue; + vSuper2 = Saig_DetectConstrCollectSuper( Aig_Regular(pObj2) ); + // every node in vSuper2 should appear in vSuper + vUnique = Saig_ManDetectConstrCheckCont( vSuper, vSuper2 ); + if ( vUnique != NULL ) + { +/// assert( !Aig_IsComplement(pObj) ); + // assert( Vec_PtrFind( vSuper2, pObj ) >= 0 ); + if ( Aig_IsComplement(pObj) ) + { + printf( "Special flop input is complemented.\n" ); + Vec_PtrFreeP( &vUnique ); + Vec_PtrFree( vSuper2 ); + break; + } + if ( Vec_PtrFind( vSuper2, pObj ) == -1 ) + { + printf( "Cannot find special flop about the inputs of OR gate.\n" ); + Vec_PtrFreeP( &vUnique ); + Vec_PtrFree( vSuper2 ); + break; + } + // remove the flop output + Vec_PtrRemove( vSuper2, pObj ); + break; + } + Vec_PtrFree( vSuper2 ); + } + Vec_PtrFree( vSuper ); + if ( vUnique == NULL ) + { + printf( "There is no structural constraints.\n" ); + return 0; + } + // vUnique contains unique entries + // vSuper2 contains the supergate + printf( "Structural analysis found %d original properties and %d constraints.\n", + Vec_PtrSize(vUnique), Vec_PtrSize(vSuper2) ); + // remember the number of constraints + RetValue = Vec_PtrSize(vSuper2); + // make the AND of properties +// Vec_PtrFree( vUnique ); +// Vec_PtrFree( vSuper2 ); + *pvOuts = vUnique; + *pvCons = vSuper2; + return RetValue; +} + + +/**Function************************************************************* + + Synopsis [Experiment with the above procedure.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_ManDetectConstrTest( Aig_Man_t * p ) +{ + Vec_Ptr_t * vOuts, * vCons; + int RetValue = Saig_ManDetectConstr( p, &vOuts, &vCons ); + Vec_PtrFreeP( &vOuts ); + Vec_PtrFreeP( &vCons ); + return RetValue; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigConstr2.c b/src/aig/saig/saigConstr2.c new file mode 100644 index 00000000..a5a575fd --- /dev/null +++ b/src/aig/saig/saigConstr2.c @@ -0,0 +1,1001 @@ +/**CFile**************************************************************** + + FileName [saigConstr2.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Sequential AIG package.] + + Synopsis [Functional constraint detection.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: saigConstr2.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "saig.h" +#include "cnf.h" +#include "satSolver.h" +#include "kit.h" +#include "bar.h" + +ABC_NAMESPACE_IMPL_START + + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static inline Aig_Obj_t * Aig_ObjFrames( Aig_Obj_t ** pObjMap, int nFs, Aig_Obj_t * pObj, int i ) { return pObjMap[nFs*pObj->Id + i]; } +static inline void Aig_ObjSetFrames( Aig_Obj_t ** pObjMap, int nFs, Aig_Obj_t * pObj, int i, Aig_Obj_t * pNode ) { pObjMap[nFs*pObj->Id + i] = pNode; } + +static inline Aig_Obj_t * Aig_ObjChild0Frames( Aig_Obj_t ** pObjMap, int nFs, Aig_Obj_t * pObj, int i ) { return Aig_ObjFanin0(pObj)? Aig_NotCond(Aig_ObjFrames(pObjMap,nFs,Aig_ObjFanin0(pObj),i), Aig_ObjFaninC0(pObj)) : NULL; } +static inline Aig_Obj_t * Aig_ObjChild1Frames( Aig_Obj_t ** pObjMap, int nFs, Aig_Obj_t * pObj, int i ) { return Aig_ObjFanin1(pObj)? Aig_NotCond(Aig_ObjFrames(pObjMap,nFs,Aig_ObjFanin1(pObj),i), Aig_ObjFaninC1(pObj)) : NULL; } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Returns the probability of POs being 1 under rand seq sim.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ssw_ManProfileConstraints( Aig_Man_t * p, int nWords, int nFrames, int fVerbose ) +{ + Vec_Ptr_t * vInfo; + Vec_Int_t * vProbs, * vProbs2; + Aig_Obj_t * pObj, * pObjLi; + unsigned * pInfo, * pInfo0, * pInfo1, * pInfoMask, * pInfoMask2; + int i, w, f, RetValue = 1, clk = clock(); + if ( fVerbose ) + printf( "Simulating %d nodes and %d flops for %d frames with %d words... ", + Aig_ManNodeNum(p), Aig_ManRegNum(p), nFrames, nWords ); + Aig_ManRandom( 1 ); + vInfo = Vec_PtrAllocSimInfo( Aig_ManObjNumMax(p)+2, nWords ); + Vec_PtrCleanSimInfo( vInfo, 0, nWords ); + vProbs = Vec_IntStart( Saig_ManPoNum(p) ); + vProbs2 = Vec_IntStart( Saig_ManPoNum(p) ); + // start the constant + pInfo = (unsigned *)Vec_PtrEntry( vInfo, Aig_ObjId(Aig_ManConst1(p)) ); + for ( w = 0; w < nWords; w++ ) + pInfo[w] = ~0; + // start the flop inputs + Saig_ManForEachLi( p, pObj, i ) + { + pInfo = (unsigned *)Vec_PtrEntry( vInfo, Aig_ObjId(pObj) ); + for ( w = 0; w < nWords; w++ ) + pInfo[w] = 0; + } + // get the info mask + pInfoMask = (unsigned *)Vec_PtrEntry( vInfo, Aig_ManObjNumMax(p) ); // PO failed + pInfoMask2 = (unsigned *)Vec_PtrEntry( vInfo, Aig_ManObjNumMax(p)+1 ); // constr failed + for ( f = 0; f < nFrames; f++ ) + { + // assign primary inputs + Saig_ManForEachPi( p, pObj, i ) + { + pInfo = (unsigned *)Vec_PtrEntry( vInfo, Aig_ObjId(pObj) ); + for ( w = 0; w < nWords; w++ ) + pInfo[w] = Aig_ManRandom( 0 ); + } + // move the flop values + Saig_ManForEachLiLo( p, pObjLi, pObj, i ) + { + pInfo = (unsigned *)Vec_PtrEntry( vInfo, Aig_ObjId(pObj) ); + pInfo0 = (unsigned *)Vec_PtrEntry( vInfo, Aig_ObjId(pObjLi) ); + for ( w = 0; w < nWords; w++ ) + pInfo[w] = pInfo0[w]; + } + // simulate the nodes + Aig_ManForEachNode( p, pObj, i ) + { + pInfo = (unsigned *)Vec_PtrEntry( vInfo, Aig_ObjId(pObj) ); + pInfo0 = (unsigned *)Vec_PtrEntry( vInfo, Aig_ObjFaninId0(pObj) ); + pInfo1 = (unsigned *)Vec_PtrEntry( vInfo, Aig_ObjFaninId1(pObj) ); + if ( Aig_ObjFaninC0(pObj) ) + { + if ( Aig_ObjFaninC1(pObj) ) + for ( w = 0; w < nWords; w++ ) + pInfo[w] = ~(pInfo0[w] | pInfo1[w]); + else + for ( w = 0; w < nWords; w++ ) + pInfo[w] = ~pInfo0[w] & pInfo1[w]; + } + else + { + if ( Aig_ObjFaninC1(pObj) ) + for ( w = 0; w < nWords; w++ ) + pInfo[w] = pInfo0[w] & ~pInfo1[w]; + else + for ( w = 0; w < nWords; w++ ) + pInfo[w] = pInfo0[w] & pInfo1[w]; + } + } + // clean the mask + for ( w = 0; w < nWords; w++ ) + pInfoMask[w] = pInfoMask2[w] = 0; + // simulate the primary outputs + Aig_ManForEachPo( p, pObj, i ) + { + pInfo = (unsigned *)Vec_PtrEntry( vInfo, Aig_ObjId(pObj) ); + pInfo0 = (unsigned *)Vec_PtrEntry( vInfo, Aig_ObjFaninId0(pObj) ); + if ( i < Saig_ManPoNum(p)-Saig_ManConstrNum(p) || i >= Saig_ManPoNum(p) ) + { + if ( Aig_ObjFaninC0(pObj) ) + { + for ( w = 0; w < nWords; w++ ) + pInfo[w] = ~pInfo0[w]; + } + else + { + for ( w = 0; w < nWords; w++ ) + pInfo[w] = pInfo0[w]; + } + } + else + { + if ( Aig_ObjFaninC0(pObj) ) + { + for ( w = 0; w < nWords; w++ ) + pInfo[w] |= ~pInfo0[w]; + } + else + { + for ( w = 0; w < nWords; w++ ) + pInfo[w] |= pInfo0[w]; + } + } + // collect patterns when one of the outputs fails + if ( i < Saig_ManPoNum(p)-Saig_ManConstrNum(p) ) + { + for ( w = 0; w < nWords; w++ ) + pInfoMask[w] |= pInfo[w]; + } + else if ( i < Saig_ManPoNum(p) ) + { + for ( w = 0; w < nWords; w++ ) + pInfoMask2[w] |= pInfo[w]; + } + } + // compare the PO values (mask=1 => out=0) or UNSAT(mask=1 & out=1) + Saig_ManForEachPo( p, pObj, i ) + { + pInfo = (unsigned *)Vec_PtrEntry( vInfo, Aig_ObjId(pObj) ); + for ( w = 0; w < nWords; w++ ) + Vec_IntAddToEntry( vProbs, i, Aig_WordCountOnes(pInfo[w]) ); + if ( i < Saig_ManPoNum(p)-Saig_ManConstrNum(p) ) + { + // chek the output + for ( w = 0; w < nWords; w++ ) + if ( pInfo[w] & ~pInfoMask2[w] ) + break; + if ( w == nWords ) + continue; + printf( "Primary output %d fails on some input patterns.\n", i ); + } + else + { + // collect patterns that block the POs + for ( w = 0; w < nWords; w++ ) + Vec_IntAddToEntry( vProbs2, i, Aig_WordCountOnes(pInfo[w] & pInfoMask[w]) ); + } + } + } + if ( fVerbose ) + Abc_PrintTime( 1, "T", clock() - clk ); + // print the state + if ( fVerbose ) + { + Saig_ManForEachPo( p, pObj, i ) + { + if ( i < Saig_ManPoNum(p) - Saig_ManConstrNum(p) ) + printf( "Primary output : ", i ); + else + printf( "Constraint %3d : ", i-(Saig_ManPoNum(p) - Saig_ManConstrNum(p)) ); + printf( "ProbOne = %f ", (float)Vec_IntEntry(vProbs, i)/(32*nWords*nFrames) ); + printf( "ProbOneC = %f ", (float)Vec_IntEntry(vProbs2, i)/(32*nWords*nFrames) ); + printf( "AllZeroValue = %d ", Aig_ObjPhase(pObj) ); + printf( "\n" ); + } + } + + // print the states + Vec_PtrFree( vInfo ); + Vec_IntFree( vProbs ); + Vec_IntFree( vProbs2 ); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [Creates COI of the property output.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Saig_ManCreateIndMiter( Aig_Man_t * pAig, Vec_Vec_t * vCands ) +{ + int nFrames = 2; + Vec_Ptr_t * vNodes; + Aig_Man_t * pFrames; + Aig_Obj_t * pObj, * pObjLi, * pObjLo, * pObjNew; + Aig_Obj_t ** pObjMap; + int i, f, k; + + // create mapping for the frames nodes + pObjMap = ABC_CALLOC( Aig_Obj_t *, nFrames * Aig_ManObjNumMax(pAig) ); + + // start the fraig package + pFrames = Aig_ManStart( Aig_ManObjNumMax(pAig) * nFrames ); + pFrames->pName = Aig_UtilStrsav( pAig->pName ); + pFrames->pSpec = Aig_UtilStrsav( pAig->pSpec ); + // map constant nodes + for ( f = 0; f < nFrames; f++ ) + Aig_ObjSetFrames( pObjMap, nFrames, Aig_ManConst1(pAig), f, Aig_ManConst1(pFrames) ); + // create PI nodes for the frames + for ( f = 0; f < nFrames; f++ ) + Aig_ManForEachPiSeq( pAig, pObj, i ) + Aig_ObjSetFrames( pObjMap, nFrames, pObj, f, Aig_ObjCreatePi(pFrames) ); + // set initial state for the latches + Aig_ManForEachLoSeq( pAig, pObj, i ) + Aig_ObjSetFrames( pObjMap, nFrames, pObj, 0, Aig_ObjCreatePi(pFrames) ); + + // add timeframes + for ( f = 0; f < nFrames; f++ ) + { + // add internal nodes of this frame + Aig_ManForEachNode( pAig, pObj, i ) + { + pObjNew = Aig_And( pFrames, Aig_ObjChild0Frames(pObjMap,nFrames,pObj,f), Aig_ObjChild1Frames(pObjMap,nFrames,pObj,f) ); + Aig_ObjSetFrames( pObjMap, nFrames, pObj, f, pObjNew ); + } + // set the latch inputs and copy them into the latch outputs of the next frame + Aig_ManForEachLiLoSeq( pAig, pObjLi, pObjLo, i ) + { + pObjNew = Aig_ObjChild0Frames(pObjMap,nFrames,pObjLi,f); + if ( f < nFrames - 1 ) + Aig_ObjSetFrames( pObjMap, nFrames, pObjLo, f+1, pObjNew ); + } + } + + // go through the candidates + Vec_VecForEachLevel( vCands, vNodes, i ) + { + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, k ) + { + Aig_Obj_t * pObjR = Aig_Regular(pObj); + Aig_Obj_t * pNode0 = pObjMap[nFrames*Aig_ObjId(pObjR)+0]; + Aig_Obj_t * pNode1 = pObjMap[nFrames*Aig_ObjId(pObjR)+1]; + Aig_Obj_t * pFan0 = Aig_NotCond( pNode0, Aig_IsComplement(pObj) ); + Aig_Obj_t * pFan1 = Aig_NotCond( pNode1, !Aig_IsComplement(pObj) ); + Aig_Obj_t * pMiter = Aig_And( pFrames, pFan0, pFan1 ); + Aig_ObjCreatePo( pFrames, pMiter ); + } + } + Aig_ManCleanup( pFrames ); + ABC_FREE( pObjMap ); + +//Aig_ManShow( pAig, 0, NULL ); +//Aig_ManShow( pFrames, 0, NULL ); + return pFrames; +} + +/**Function************************************************************* + + Synopsis [Performs inductive check for one of the constraints.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_ManFilterUsingIndOne_new( Aig_Man_t * p, Aig_Man_t * pFrame, sat_solver * pSat, Cnf_Dat_t * pCnf, int nConfs, int nProps, int Counter ) +{ + Aig_Obj_t * pObj; + int Lit, status; + pObj = Aig_ManPo( pFrame, Counter ); + Lit = toLitCond( pCnf->pVarNums[Aig_ObjId(pObj)], 0 ); + status = sat_solver_solve( pSat, &Lit, &Lit + 1, (ABC_INT64_T)nConfs, 0, 0, 0 ); + if ( status == l_False ) + return 1; + if ( status == l_Undef ) + { +// printf( "Solver returned undecided.\n" ); + return 0; + } + assert( status == l_True ); + return 0; +} + +/**Function************************************************************* + + Synopsis [Detects constraints functionally.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_ManFilterUsingInd( Aig_Man_t * p, Vec_Vec_t * vCands, int nConfs, int nProps, int fVerbose ) +{ + Vec_Ptr_t * vNodes; + Aig_Man_t * pFrames; + sat_solver * pSat; + Cnf_Dat_t * pCnf; + Aig_Obj_t * pObj; + int i, k, k2, Counter; +/* + Vec_VecForEachLevel( vCands, vNodes, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, k ) + printf( "%d ", Aig_ObjId(Aig_Regular(pObj)) ); + printf( "\n" ); +*/ + // create timeframes +// pFrames = Saig_ManUnrollInd( p ); + pFrames = Saig_ManCreateIndMiter( p, vCands ); + assert( Aig_ManPoNum(pFrames) == Vec_VecSizeSize(vCands) ); + // start the SAT solver + pCnf = Cnf_DeriveSimple( pFrames, Aig_ManPoNum(pFrames) ); + pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); + // check candidates + if ( fVerbose ) + printf( "Filtered cands: " ); + Counter = 0; + Vec_VecForEachLevel( vCands, vNodes, i ) + { + k2 = 0; + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, k ) + { + if ( Saig_ManFilterUsingIndOne_new( p, pFrames, pSat, pCnf, nConfs, nProps, Counter++ ) ) +// if ( Saig_ManFilterUsingIndOne_old( p, pSat, pCnf, nConfs, pObj ) ) + { + Vec_PtrWriteEntry( vNodes, k2++, pObj ); + if ( fVerbose ) + printf( "%d:%s%d ", i, Aig_IsComplement(pObj)? "!":"", Aig_ObjId(Aig_Regular(pObj)) ); + } + } + Vec_PtrShrink( vNodes, k2 ); + } + if ( fVerbose ) + printf( "\n" ); + // clean up + Cnf_DataFree( pCnf ); + sat_solver_delete( pSat ); + if ( fVerbose ) + Aig_ManPrintStats( pFrames ); + Aig_ManStop( pFrames ); +} + + + + +/**Function************************************************************* + + Synopsis [Creates COI of the property output.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Saig_ManUnrollCOI_( Aig_Man_t * p, int nFrames ) +{ + Aig_Man_t * pFrames; + Aig_Obj_t ** pObjMap; + int i; +//Aig_Man_t * Aig_ManFrames( Aig_Man_t * pAig, int nFrames, int fInit, int fOuts, int fRegs, int fEnlarge, Aig_Obj_t *** ppObjMap ) + pFrames = Aig_ManFrames( p, nFrames, 0, 1, 1, 0, &pObjMap ); + for ( i = 0; i < nFrames * Aig_ManObjNumMax(p); i++ ) + if ( pObjMap[i] && Aig_ObjIsNone( Aig_Regular(pObjMap[i]) ) ) + pObjMap[i] = NULL; + assert( p->pObjCopies == NULL ); + p->pObjCopies = pObjMap; + return pFrames; +} + +/**Function************************************************************* + + Synopsis [Creates COI of the property output.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Saig_ManUnrollCOI( Aig_Man_t * pAig, int nFrames ) +{ + Aig_Man_t * pFrames; + Aig_Obj_t * pObj, * pObjLi, * pObjLo, * pObjNew; + Aig_Obj_t ** pObjMap; + int i, f; + // create mapping for the frames nodes + pObjMap = ABC_CALLOC( Aig_Obj_t *, nFrames * Aig_ManObjNumMax(pAig) ); + // start the fraig package + pFrames = Aig_ManStart( Aig_ManObjNumMax(pAig) * nFrames ); + pFrames->pName = Aig_UtilStrsav( pAig->pName ); + pFrames->pSpec = Aig_UtilStrsav( pAig->pSpec ); + // map constant nodes + for ( f = 0; f < nFrames; f++ ) + Aig_ObjSetFrames( pObjMap, nFrames, Aig_ManConst1(pAig), f, Aig_ManConst1(pFrames) ); + // create PI nodes for the frames + for ( f = 0; f < nFrames; f++ ) + Aig_ManForEachPiSeq( pAig, pObj, i ) + Aig_ObjSetFrames( pObjMap, nFrames, pObj, f, Aig_ObjCreatePi(pFrames) ); + // set initial state for the latches + Aig_ManForEachLoSeq( pAig, pObj, i ) + Aig_ObjSetFrames( pObjMap, nFrames, pObj, 0, Aig_ObjCreatePi(pFrames) ); + // add timeframes + for ( f = 0; f < nFrames; f++ ) + { + Aig_ManForEachNode( pAig, pObj, i ) + { + pObjNew = Aig_And( pFrames, Aig_ObjChild0Frames(pObjMap,nFrames,pObj,f), Aig_ObjChild1Frames(pObjMap,nFrames,pObj,f) ); + Aig_ObjSetFrames( pObjMap, nFrames, pObj, f, pObjNew ); + } + // set the latch inputs and copy them into the latch outputs of the next frame + Aig_ManForEachLiLoSeq( pAig, pObjLi, pObjLo, i ) + { + pObjNew = Aig_ObjChild0Frames(pObjMap,nFrames,pObjLi,f); + if ( f < nFrames - 1 ) + Aig_ObjSetFrames( pObjMap, nFrames, pObjLo, f+1, pObjNew ); + } + } + // create the only output + for ( f = nFrames-1; f < nFrames; f++ ) + { + Aig_ManForEachPoSeq( pAig, pObj, i ) + { + pObjNew = Aig_ObjCreatePo( pFrames, Aig_ObjChild0Frames(pObjMap,nFrames,pObj,f) ); + Aig_ObjSetFrames( pObjMap, nFrames, pObj, f, pObjNew ); + } + } + // created lots of dangling nodes - no sweeping! + //Aig_ManCleanup( pFrames ); + assert( pAig->pObjCopies == NULL ); + pAig->pObjCopies = pObjMap; + return pFrames; +} + + +/**Function************************************************************* + + Synopsis [Collects and saves values of the SAT variables.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_CollectSatValues( sat_solver * pSat, Cnf_Dat_t * pCnf, Vec_Ptr_t * vInfo, int * piPat ) +{ + Aig_Obj_t * pObj; + unsigned * pInfo; + int i; + Aig_ManForEachObj( pCnf->pMan, pObj, i ) + { + if ( !Aig_ObjIsNode(pObj) && !Aig_ObjIsPi(pObj) ) + continue; + assert( pCnf->pVarNums[i] > 0 ); + pInfo = (unsigned *)Vec_PtrEntry( vInfo, i ); + if ( Aig_InfoHasBit(pInfo, *piPat) != sat_solver_var_value(pSat, pCnf->pVarNums[i]) ) + Aig_InfoXorBit(pInfo, *piPat); + } +} + +/**Function************************************************************* + + Synopsis [Runs the SAT test for the node in one polarity.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_DetectTryPolarity( sat_solver * pSat, int nConfs, int nProps, Cnf_Dat_t * pCnf, Aig_Obj_t * pObj, int iPol, Vec_Ptr_t * vInfo, int * piPat, int fVerbose ) +{ + Aig_Obj_t * pOut = Aig_ManPo( pCnf->pMan, 0 ); + int status, Lits[2]; +// ABC_INT64_T nOldConfs = pSat->stats.conflicts; +// ABC_INT64_T nOldImps = pSat->stats.propagations; + Lits[0] = toLitCond( pCnf->pVarNums[Aig_ObjId(pOut)], 0 ); + Lits[1] = toLitCond( pCnf->pVarNums[Aig_ObjId(pObj)], !iPol ); + status = sat_solver_solve( pSat, Lits, Lits + 2, (ABC_INT64_T)nConfs, (ABC_INT64_T)nProps, 0, 0 ); + if ( status == l_False ) + { +// printf( "u%d(%d) ", (int)(pSat->stats.conflicts-nOldConfs), (int)(pSat->stats.propagations-nOldImps) ); + return 1; + } + if ( status == l_Undef ) + { +// printf( "Solver returned undecided.\n" ); + return 0; + } +// printf( "s%d(%d) ", (int)(pSat->stats.conflicts-nOldConfs), (int)(pSat->stats.propagations-nOldImps) ); + assert( status == l_True ); + Saig_CollectSatValues( pSat, pCnf, vInfo, piPat ); + (*piPat)++; + if ( *piPat == Vec_PtrReadWordsSimInfo(vInfo) * 32 ) + { + if ( fVerbose ) + printf( "Warning: Reached the limit on the number of patterns.\n" ); + *piPat = 0; + } + return 0; +} + +/**Function************************************************************* + + Synopsis [Returns the number of variables implied by the output.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Vec_t * Ssw_ManFindDirectImplications( Aig_Man_t * p, int nFrames, int nConfs, int nProps, int fVerbose ) +{ + Vec_Vec_t * vCands = NULL; + Vec_Ptr_t * vNodes; + Cnf_Dat_t * pCnf; + sat_solver * pSat; + Aig_Man_t * pFrames; + Aig_Obj_t * pObj, * pRepr, * pReprR; + int i, f, k, value; + vCands = Vec_VecAlloc( nFrames ); + + // perform unrolling + pFrames = Saig_ManUnrollCOI( p, nFrames ); + assert( Aig_ManPoNum(pFrames) == 1 ); + // start the SAT solver + pCnf = Cnf_DeriveSimple( pFrames, 0 ); + pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); + if ( pSat != NULL ) + { + Aig_ManIncrementTravId( p ); + for ( f = 0; f < nFrames; f++ ) + { + Aig_ManForEachObj( p, pObj, i ) + { + if ( !Aig_ObjIsCand(pObj) ) + continue; + if ( Aig_ObjIsTravIdCurrent(p, pObj) ) + continue; + // get the node from timeframes + pRepr = p->pObjCopies[nFrames*i + nFrames-1-f]; + pReprR = Aig_Regular(pRepr); + if ( pCnf->pVarNums[Aig_ObjId(pReprR)] < 0 ) + continue; + value = pSat->assigns[ pCnf->pVarNums[Aig_ObjId(pReprR)] ]; + if ( value == l_Undef ) + continue; + // label this node as taken + Aig_ObjSetTravIdCurrent(p, pObj); + if ( Saig_ObjIsLo(p, pObj) ) + Aig_ObjSetTravIdCurrent( p, Aig_ObjFanin0(Saig_ObjLoToLi(p, pObj)) ); + // remember the node + Vec_VecPush( vCands, f, Aig_NotCond( pObj, (value == l_True) ^ Aig_IsComplement(pRepr) ) ); + // printf( "%s%d ", (value == l_False)? "":"!", i ); + } + } + // printf( "\n" ); + sat_solver_delete( pSat ); + } + Aig_ManStop( pFrames ); + Cnf_DataFree( pCnf ); + + if ( fVerbose ) + { + printf( "Found %3d candidates.\n", Vec_VecSizeSize(vCands) ); + Vec_VecForEachLevel( vCands, vNodes, k ) + { + printf( "Level %d. Cands =%d ", k, Vec_PtrSize(vNodes) ); +// Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) +// printf( "%d:%s%d ", k, Aig_IsComplement(pObj)? "!":"", Aig_ObjId(Aig_Regular(pObj)) ); + printf( "\n" ); + } + } + + ABC_FREE( p->pObjCopies ); + Saig_ManFilterUsingInd( p, vCands, nConfs, nProps, fVerbose ); + if ( Vec_VecSizeSize(vCands) ) + printf( "Found %3d constraints after filtering.\n", Vec_VecSizeSize(vCands) ); + if ( fVerbose ) + { + Vec_VecForEachLevel( vCands, vNodes, k ) + { + printf( "Level %d. Constr =%d ", k, Vec_PtrSize(vNodes) ); +// Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) +// printf( "%d:%s%d ", k, Aig_IsComplement(pObj)? "!":"", Aig_ObjId(Aig_Regular(pObj)) ); + printf( "\n" ); + } + } + + return vCands; +} + + +/**Function************************************************************* + + Synopsis [Detects constraints functionally.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Vec_t * Saig_ManDetectConstrFunc( Aig_Man_t * p, int nFrames, int nConfs, int nProps, int fVerbose ) +{ + int iPat = 0, nWordsAlloc = 16; + Bar_Progress_t * pProgress = NULL; + Vec_Vec_t * vCands = NULL; + Vec_Ptr_t * vInfo, * vNodes; + Aig_Obj_t * pObj, * pRepr, * pObjNew; + Aig_Man_t * pFrames; + sat_solver * pSat; + Cnf_Dat_t * pCnf; + unsigned * pInfo; + int i, j, k, Lit, status, nCands = 0; + assert( Saig_ManPoNum(p) == 1 ); + if ( Saig_ManPoNum(p) != 1 ) + { + printf( "The number of outputs is different from 1.\n" ); + return NULL; + } +//printf( "Implications = %d.\n", Ssw_ManCountImplications(p, nFrames) ); + + // perform unrolling + pFrames = Saig_ManUnrollCOI( p, nFrames ); + assert( Aig_ManPoNum(pFrames) == 1 ); + if ( fVerbose ) + { + printf( "Detecting constraints with %d frames, %d conflicts, and %d propagations.\n", nFrames, nConfs, nProps ); + printf( "Frames: " ); + Aig_ManPrintStats( pFrames ); + } +// Aig_ManShow( pFrames, 0, NULL ); + + // start the SAT solver + pCnf = Cnf_DeriveSimple( pFrames, Aig_ManPoNum(pFrames) ); + pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); +//printf( "Implications = %d.\n", pSat->qhead ); + + // solve the original problem + Lit = toLitCond( pCnf->pVarNums[Aig_ObjId(Aig_ManPo(pFrames,0))], 0 ); + status = sat_solver_solve( pSat, &Lit, &Lit + 1, (ABC_INT64_T)nConfs, 0, 0, 0 ); + if ( status == l_False ) + { + printf( "The problem is trivially UNSAT (inductive with k=%d).\n", nFrames-1 ); + Cnf_DataFree( pCnf ); + sat_solver_delete( pSat ); + Aig_ManStop( pFrames ); + return NULL; + } + if ( status == l_Undef ) + { + printf( "Solver could not solve the original problem.\n" ); + Cnf_DataFree( pCnf ); + sat_solver_delete( pSat ); + Aig_ManStop( pFrames ); + return NULL; + } + assert( status == l_True ); + + // create simulation info + vInfo = Vec_PtrAllocSimInfo( Aig_ManObjNumMax(pFrames), nWordsAlloc ); + Vec_PtrCleanSimInfo( vInfo, 0, nWordsAlloc ); + Saig_CollectSatValues( pSat, pCnf, vInfo, &iPat ); + Aig_ManForEachObj( pFrames, pObj, i ) + { + pInfo = (unsigned *)Vec_PtrEntry( vInfo, i ); + if ( pInfo[0] & 1 ) + memset( (char*)pInfo, 0xff, 4*nWordsAlloc ); + } +// Aig_ManShow( pFrames, 0, NULL ); +// Aig_ManShow( p, 0, NULL ); + + // consider the nodes for ci=>!Out and label when it holds + pProgress = Bar_ProgressStart( stdout, Aig_ManObjNumMax(pFrames) ); + Aig_ManCleanMarkAB( pFrames ); + Aig_ManForEachObj( pFrames, pObj, i ) + { + if ( !Aig_ObjIsNode(pObj) && !Aig_ObjIsPi(pObj) ) + continue; + Bar_ProgressUpdate( pProgress, i, NULL ); + // check if the node is available in both polarities + pInfo = (unsigned *)Vec_PtrEntry( vInfo, i ); + for ( k = 0; k < nWordsAlloc; k++ ) + if ( pInfo[k] != ~0 ) + break; + if ( k == nWordsAlloc ) + { + if ( Saig_DetectTryPolarity(pSat, nConfs, nProps, pCnf, pObj, 0, vInfo, &iPat, fVerbose) ) // !pObj is a constr + { + pObj->fMarkA = 1, nCands++; +// printf( "!%d ", Aig_ObjId(pObj) ); + } + continue; + } + for ( k = 0; k < nWordsAlloc; k++ ) + if ( pInfo[k] != 0 ) + break; + if ( k == nWordsAlloc ) + { + if ( Saig_DetectTryPolarity(pSat, nConfs, nProps, pCnf, pObj, 1, vInfo, &iPat, fVerbose) ) // pObj is a constr + { + pObj->fMarkB = 1, nCands++; +// printf( "%d ", Aig_ObjId(pObj) ); + } + continue; + } + } + Bar_ProgressStop( pProgress ); + if ( nCands ) + { + +// printf( "\n" ); + if ( fVerbose ) + printf( "Found %3d classes of candidates.\n", nCands ); + vCands = Vec_VecAlloc( nFrames ); + for ( k = 0; k < nFrames; k++ ) + { + Aig_ManForEachObj( p, pObj, i ) + { + if ( !Aig_ObjIsNode(pObj) && !Aig_ObjIsPi(pObj) ) + continue; + pRepr = p->pObjCopies[nFrames*i + nFrames-1-k]; +// pRepr = p->pObjCopies[nFrames*i + k]; + if ( pRepr == NULL ) + continue; + if ( Aig_Regular(pRepr)->fMarkA ) // !pObj is a constr + { + pObjNew = Aig_NotCond(pObj, !Aig_IsComplement(pRepr)); + + for ( j = 0; j < k; j++ ) + if ( Vec_PtrFind( (Vec_Ptr_t *)Vec_VecEntry(vCands, j), pObjNew ) >= 0 ) + break; + if ( j == k ) + Vec_VecPush( vCands, k, pObjNew ); +// printf( "%d->!%d ", Aig_ObjId(Aig_Regular(pRepr)), Aig_ObjId(pObj) ); + } + else if ( Aig_Regular(pRepr)->fMarkB ) // pObj is a constr + { + pObjNew = Aig_NotCond(pObj, Aig_IsComplement(pRepr)); + + for ( j = 0; j < k; j++ ) + if ( Vec_PtrFind( (Vec_Ptr_t *)Vec_VecEntry(vCands, j), pObjNew ) >= 0 ) + break; + if ( j == k ) + Vec_VecPush( vCands, k, pObjNew ); +// printf( "%d->%d ", Aig_ObjId(Aig_Regular(pRepr)), Aig_ObjId(pObj) ); + } + } + } + +// printf( "\n" ); + if ( fVerbose ) + { + printf( "Found %3d candidates.\n", Vec_VecSizeSize(vCands) ); + Vec_VecForEachLevel( vCands, vNodes, k ) + { + printf( "Level %d. Cands =%d ", k, Vec_PtrSize(vNodes) ); +// Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) +// printf( "%d:%s%d ", k, Aig_IsComplement(pObj)? "!":"", Aig_ObjId(Aig_Regular(pObj)) ); + printf( "\n" ); + } + } + + ABC_FREE( p->pObjCopies ); + Saig_ManFilterUsingInd( p, vCands, nConfs, nProps, fVerbose ); + if ( Vec_VecSizeSize(vCands) ) + printf( "Found %3d constraints after filtering.\n", Vec_VecSizeSize(vCands) ); + if ( fVerbose ) + { + Vec_VecForEachLevel( vCands, vNodes, k ) + { + printf( "Level %d. Constr =%d ", k, Vec_PtrSize(vNodes) ); +// Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) +// printf( "%d:%s%d ", k, Aig_IsComplement(pObj)? "!":"", Aig_ObjId(Aig_Regular(pObj)) ); + printf( "\n" ); + } + } + } + Vec_PtrFree( vInfo ); + Cnf_DataFree( pCnf ); + sat_solver_delete( pSat ); + Aig_ManCleanMarkAB( pFrames ); + Aig_ManStop( pFrames ); + return vCands; +} + +/**Function************************************************************* + + Synopsis [Experimental procedure.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_ManDetectConstrFuncTest( Aig_Man_t * p, int nFrames, int nConfs, int nProps, int fOldAlgo, int fVerbose ) +{ + Vec_Vec_t * vCands; + if ( fOldAlgo ) + vCands = Saig_ManDetectConstrFunc( p, nFrames, nConfs, nProps, fVerbose ); + else + vCands = Ssw_ManFindDirectImplications( p, nFrames, nConfs, nProps, fVerbose ); + Vec_VecFreeP( &vCands ); +} + +/**Function************************************************************* + + Synopsis [Duplicates the AIG while unfolding constraints.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Saig_ManDupUnfoldConstrsFunc( Aig_Man_t * pAig, int nFrames, int nConfs, int nProps, int fOldAlgo, int fVerbose ) +{ + Aig_Man_t * pNew; + Vec_Vec_t * vCands; + Vec_Ptr_t * vNodes, * vNewFlops; + Aig_Obj_t * pObj; + int i, j, k, nNewFlops; + if ( fOldAlgo ) + vCands = Saig_ManDetectConstrFunc( pAig, nFrames, nConfs, nProps, fVerbose ); + else + vCands = Ssw_ManFindDirectImplications( pAig, nFrames, nConfs, nProps, fVerbose ); + if ( vCands == NULL || Vec_VecSizeSize(vCands) == 0 ) + { + Vec_VecFreeP( &vCands ); + return Aig_ManDupDfs( pAig ); + } + // create new manager + pNew = Aig_ManDupWithoutPos( pAig ); + pNew->nConstrs = pAig->nConstrs + Vec_VecSizeSize(vCands); + // add normal POs + Saig_ManForEachPo( pAig, pObj, i ) + Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) ); + // create constraint outputs + vNewFlops = Vec_PtrAlloc( 100 ); + Vec_VecForEachLevel( vCands, vNodes, i ) + { + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, k ) + { + Vec_PtrPush( vNewFlops, Aig_ObjRealCopy(pObj) ); + for ( j = 0; j < i; j++ ) + Vec_PtrPush( vNewFlops, Aig_ObjCreatePi(pNew) ); + Aig_ObjCreatePo( pNew, (Aig_Obj_t *)Vec_PtrPop(vNewFlops) ); + } + } + // add latch outputs + Saig_ManForEachLi( pAig, pObj, i ) + Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) ); + // add new latch outputs + nNewFlops = 0; + Vec_VecForEachLevel( vCands, vNodes, i ) + { + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, k ) + { + for ( j = 0; j < i; j++ ) + Aig_ObjCreatePo( pNew, (Aig_Obj_t *)Vec_PtrEntry(vNewFlops, nNewFlops++) ); + } + } + assert( nNewFlops == Vec_PtrSize(vNewFlops) ); + Aig_ManSetRegNum( pNew, Aig_ManRegNum(pAig) + nNewFlops ); + Vec_VecFreeP( &vCands ); + Vec_PtrFree( vNewFlops ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Duplicates the AIG while unfolding constraints.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Saig_ManDupFoldConstrsFunc( Aig_Man_t * pAig, int fCompl, int fVerbose ) +{ + Aig_Man_t * pAigNew; + Aig_Obj_t * pMiter, * pFlopOut, * pFlopIn, * pObj; + int i; + assert( Saig_ManRegNum(pAig) > 0 ); + if ( Aig_ManConstrNum(pAig) == 0 ) + return Aig_ManDupDfs( pAig ); + assert( Aig_ManConstrNum(pAig) < Saig_ManPoNum(pAig) ); + // start the new manager + pAigNew = Aig_ManStart( Aig_ManNodeNum(pAig) ); + pAigNew->pName = Aig_UtilStrsav( pAig->pName ); + pAigNew->pSpec = Aig_UtilStrsav( pAig->pSpec ); + // map the constant node + Aig_ManConst1(pAig)->pData = Aig_ManConst1( pAigNew ); + // create variables for PIs + Aig_ManForEachPi( pAig, pObj, i ) + pObj->pData = Aig_ObjCreatePi( pAigNew ); + // add internal nodes of this frame + Aig_ManForEachNode( pAig, pObj, i ) + pObj->pData = Aig_And( pAigNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + + // OR the constraint outputs + pMiter = Aig_ManConst0( pAigNew ); + Saig_ManForEachPo( pAig, pObj, i ) + { + if ( i < Saig_ManPoNum(pAig)-Aig_ManConstrNum(pAig) ) + continue; + pMiter = Aig_Or( pAigNew, pMiter, Aig_NotCond( Aig_ObjChild0Copy(pObj), fCompl ) ); + } + // create additional flop + pFlopOut = Aig_ObjCreatePi( pAigNew ); + pFlopIn = Aig_Or( pAigNew, pMiter, pFlopOut ); + + // create primary output + Saig_ManForEachPo( pAig, pObj, i ) + { + if ( i >= Saig_ManPoNum(pAig)-Aig_ManConstrNum(pAig) ) + continue; + pMiter = Aig_And( pAigNew, Aig_ObjChild0Copy(pObj), Aig_Not(pFlopIn) ); + Aig_ObjCreatePo( pAigNew, pMiter ); + } + + // transfer to register outputs + Saig_ManForEachLi( pAig, pObj, i ) + Aig_ObjCreatePo( pAigNew, Aig_ObjChild0Copy(pObj) ); + // create additional flop + Aig_ObjCreatePo( pAigNew, pFlopIn ); + + Aig_ManSetRegNum( pAigNew, Aig_ManRegNum(pAig)+1 ); + Aig_ManCleanup( pAigNew ); + Aig_ManSeqCleanup( pAigNew ); + return pAigNew; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigDup.c b/src/aig/saig/saigDup.c index e261fca1..268540da 100644 --- a/src/aig/saig/saigDup.c +++ b/src/aig/saig/saigDup.c @@ -20,6 +20,9 @@ #include "saig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -44,9 +47,15 @@ Aig_Man_t * Said_ManDupOrpos( Aig_Man_t * pAig ) Aig_Man_t * pAigNew; Aig_Obj_t * pObj, * pMiter; int i; + if ( pAig->nConstrs > 0 ) + { + printf( "The AIG manager should have no constraints.\n" ); + return NULL; + } // start the new manager pAigNew = Aig_ManStart( Aig_ManNodeNum(pAig) ); pAigNew->pName = Aig_UtilStrsav( pAig->pName ); + pAigNew->nConstrs = pAig->nConstrs; // map the constant node Aig_ManConst1(pAig)->pData = Aig_ManConst1( pAigNew ); // create variables for PIs @@ -82,10 +91,10 @@ Aig_Man_t * Said_ManDupOrpos( Aig_Man_t * pAig ) Aig_Obj_t * Saig_ManAbstractionDfs_rec( Aig_Man_t * pNew, Aig_Obj_t * pObj ) { if ( pObj->pData ) - return pObj->pData; + return (Aig_Obj_t *)pObj->pData; Saig_ManAbstractionDfs_rec( pNew, Aig_ObjFanin0(pObj) ); Saig_ManAbstractionDfs_rec( pNew, Aig_ObjFanin1(pObj) ); - return pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + return (Aig_Obj_t *)(pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) )); } /**Function************************************************************* @@ -112,6 +121,7 @@ Aig_Man_t * Saig_ManTrimPis( Aig_Man_t * p ) // start the new manager pNew = Aig_ManStart( Aig_ManObjNum(p) ); pNew->pName = Aig_UtilStrsav( p->pName ); + pNew->nConstrs = p->nConstrs; // start mapping of the CI numbers pNew->vCiNumsOrig = Vec_IntAlloc( Aig_ManPiNum(p) ); // map const and primary inputs @@ -142,9 +152,9 @@ Aig_Man_t * Saig_ManTrimPis( Aig_Man_t * p ) SeeAlso [] ***********************************************************************/ -Aig_Man_t * Saig_ManAbstraction( Aig_Man_t * p, Vec_Int_t * vFlops ) +Aig_Man_t * Saig_ManDeriveAbstraction( Aig_Man_t * p, Vec_Int_t * vFlops ) { - Aig_Man_t * pNew, * pTemp; + Aig_Man_t * pNew;//, * pTemp; Aig_Obj_t * pObj, * pObjLi, * pObjLo; int i, Entry; Aig_ManCleanData( p ); @@ -200,8 +210,8 @@ Aig_Man_t * Saig_ManAbstraction( Aig_Man_t * p, Vec_Int_t * vFlops ) Aig_ManSetRegNum( pNew, Vec_IntSize(vFlops) ); Aig_ManSeqCleanup( pNew ); // remove PIs without fanout - pNew = Saig_ManTrimPis( pTemp = pNew ); - Aig_ManStop( pTemp ); +// pNew = Saig_ManTrimPis( pTemp = pNew ); +// Aig_ManStop( pTemp ); return pNew; } @@ -210,3 +220,5 @@ Aig_Man_t * Saig_ManAbstraction( Aig_Man_t * p, Vec_Int_t * vFlops ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigHaig.c b/src/aig/saig/saigHaig.c index 1c7aa025..3ea0a2c6 100644 --- a/src/aig/saig/saigHaig.c +++ b/src/aig/saig/saigHaig.c @@ -22,6 +22,9 @@ #include "satSolver.h" #include "cnf.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -51,9 +54,9 @@ void Aig_ManHaigSpeculate( Aig_Man_t * pFrames, Aig_Obj_t * pObj ) return; // assert( pObjRepr->Id < pObj->Id ); // get the new node - pObjNew = pObj->pData; + pObjNew = (Aig_Obj_t *)pObj->pData; // get the new node of the representative - pObjReprNew = pObjRepr->pData; + pObjReprNew = (Aig_Obj_t *)pObjRepr->pData; // if this is the same node, no need to add constraints assert( pObjNew != NULL && pObjReprNew != NULL ); if ( Aig_Regular(pObjNew) == Aig_Regular(pObjReprNew) ) @@ -233,7 +236,7 @@ clk = clock(); // Saig_ManDumpBlif( pHaig, "haig_temp.blif" ); // Saig_ManDumpBlif( pFrames, "haig_temp_frames.blif" ); // create the SAT solver to be used for this problem - pSat = Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); + pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); if ( pSat == NULL ) { printf( "Aig_ManHaigVerify(): Computed CNF is not valid.\n" ); @@ -422,7 +425,7 @@ clk = clock(); // printf( "\n" ); // create the SAT solver to be used for this problem - pSat = Cnf_DataWriteIntoSolver( pCnf, nFrames, 0 ); + pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, nFrames, 0 ); //Sat_SolverWriteDimacs( pSat, "1.cnf", NULL, NULL, 0 ); if ( pSat == NULL ) { @@ -586,7 +589,7 @@ Aig_Man_t * Saig_ManHaigDump( Aig_Man_t * pHaig ) } printf( "Added %d property outputs.\n", Vec_IntSize(pHaig->vEquPairs)/2 ); // add the registers - Vec_PtrForEachEntry( vTemp, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vTemp, pObj, i ) Vec_PtrPush( pHaig->vPos, pObj ); Vec_PtrFree( vTemp ); assert( pHaig->nObjs[AIG_OBJ_PO] == Vec_PtrSize(pHaig->vPos) ); @@ -630,7 +633,7 @@ clk = clock(); // create its history AIG pNew->pManHaig = Aig_ManDupSimple( pNew ); Aig_ManForEachObj( pNew, pObj, i ) - pObj->pHaig = pObj->pData; + pObj->pHaig = (Aig_Obj_t *)pObj->pData; // remove structural hashing table Aig_TableClear( pNew->pManHaig ); pNew->pManHaig->vEquPairs = Vec_IntAlloc( 10000 ); @@ -725,3 +728,5 @@ clkSynth = clock() - clk; //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigInd.c b/src/aig/saig/saigInd.c index 1c26e5df..e22adba2 100644 --- a/src/aig/saig/saigInd.c +++ b/src/aig/saig/saigInd.c @@ -22,6 +22,9 @@ #include "cnf.h" #include "satSolver.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -32,7 +35,51 @@ /**Function************************************************************* - Synopsis [Performs localization by unrolling timeframes backward.] + Synopsis [Returns 1 if two state are equal.] + + Description [Array vState contains indexes of CNF variables for each + flop in the first N time frames (0 < i < k, i < N, k < N).] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_ManStatesAreEqual( sat_solver * pSat, Vec_Int_t * vState, int nRegs, int i, int k ) +{ + int * pStateI = (int *)Vec_IntArray(vState) + nRegs * i; + int * pStateK = (int *)Vec_IntArray(vState) + nRegs * k; + int v; + assert( i && k && i < k ); + assert( nRegs * k <= Vec_IntSize(vState) ); + // check if the states are available + for ( v = 0; v < nRegs; v++ ) + if ( pStateI[v] >= 0 && pStateK[v] == -1 ) + return 0; +/* + printf( "\nchecking uniqueness\n" ); + printf( "%3d : ", i ); + for ( v = 0; v < nRegs; v++ ) + printf( "%d", sat_solver_var_value(pSat, pStateI[v]) ); + printf( "\n" ); + + printf( "%3d : ", k ); + for ( v = 0; v < nRegs; v++ ) + printf( "%d", sat_solver_var_value(pSat, pStateK[v]) ); + printf( "\n" ); +*/ + for ( v = 0; v < nRegs; v++ ) + if ( pStateI[v] >= 0 ) + { + if ( sat_solver_var_value(pSat, pStateI[v]) != sat_solver_var_value(pSat, pStateK[v]) ) + return 0; + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Add uniqueness constraint.] Description [] @@ -41,21 +88,78 @@ SeeAlso [] ***********************************************************************/ -int Saig_ManInduction( Aig_Man_t * p, int nFramesMax, int nConfMax, int fVerbose ) +void Saig_ManAddUniqueness( sat_solver * pSat, Vec_Int_t * vState, int nRegs, int i, int k, int * pnSatVarNum, int * pnClauses ) +{ + int * pStateI = (int *)Vec_IntArray(vState) + nRegs * i; + int * pStateK = (int *)Vec_IntArray(vState) + nRegs * k; + int v, iVars, nSatVarsOld, RetValue, * pClause; + assert( i && k && i < k ); + assert( nRegs * k <= Vec_IntSize(vState) ); + // check if the states are available + for ( v = 0; v < nRegs; v++ ) + if ( pStateI[v] >= 0 && pStateK[v] == -1 ) + { +// printf( "Cannot constrain an incomplete state.\n" ); + return; + } + // add XORs + nSatVarsOld = *pnSatVarNum; + for ( v = 0; v < nRegs; v++ ) + if ( pStateI[v] >= 0 ) + { + *pnClauses += 4; + RetValue = Cnf_DataAddXorClause( pSat, pStateI[v], pStateK[v], (*pnSatVarNum)++ ); + if ( RetValue == 0 ) + { + printf( "SAT solver became UNSAT.\n" ); + return; + } + } + // add OR clause + (*pnClauses)++; + iVars = 0; + pClause = ABC_ALLOC( int, nRegs ); + for ( v = nSatVarsOld; v < *pnSatVarNum; v++ ) + pClause[iVars++] = toLitCond( v, 0 ); + assert( iVars <= nRegs ); + RetValue = sat_solver_addclause( pSat, pClause, pClause + iVars ); + ABC_FREE( pClause ); + if ( RetValue == 0 ) + { + printf( "SAT solver became UNSAT.\n" ); + return; + } +} + +/**Function************************************************************* + + Synopsis [Performs induction by unrolling timeframes backward.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_ManInduction( Aig_Man_t * p, int nFramesMax, int nConfMax, int fUnique, int fUniqueAll, int fVerbose, int fVeryVerbose ) { sat_solver * pSat; Aig_Man_t * pAigPart; Cnf_Dat_t * pCnfPart; - Vec_Int_t * vTopVarNums; + Vec_Int_t * vTopVarNums, * vState; Vec_Ptr_t * vTop, * vBot; Aig_Obj_t * pObjPi, * pObjPiCopy, * pObjPo; - int i, f, clk, Lits[2], status, RetValue, nSatVarNum, nConfPrev; + int i, k, f, clk, Lits[2], status, RetValue, nSatVarNum, nConfPrev; + int nOldSize, iReg, iLast, fAdded, nConstrs = 0, nClauses = 0; + assert( fUnique == 0 || fUniqueAll == 0 ); assert( Saig_ManPoNum(p) == 1 ); Aig_ManSetPioNumbers( p ); // start the top by including the PO vBot = Vec_PtrAlloc( 100 ); vTop = Vec_PtrAlloc( 100 ); + vState = Vec_IntAlloc( 1000 ); Vec_PtrPush( vTop, Aig_ManPo(p, 0) ); // start the array of CNF variables vTopVarNums = Vec_IntAlloc( 100 ); @@ -67,7 +171,7 @@ int Saig_ManInduction( Aig_Man_t * p, int nFramesMax, int nConfMax, int fVerbose RetValue = -1; nSatVarNum = 0; if ( fVerbose ) - printf( "Localization parameters: FramesMax = %5d. ConflictMax = %6d.\n", nFramesMax, nConfMax ); + printf( "Induction parameters: FramesMax = %5d. ConflictMax = %6d.\n", nFramesMax, nConfMax ); for ( f = 0; ; f++ ) { if ( f > 0 ) @@ -84,6 +188,7 @@ int Saig_ManInduction( Aig_Man_t * p, int nFramesMax, int nConfMax, int fVerbose pCnfPart = Cnf_Derive( pAigPart, Aig_ManPoNum(pAigPart) ); Cnf_DataLift( pCnfPart, nSatVarNum ); nSatVarNum += pCnfPart->nVars; + nClauses += pCnfPart->nClauses; // stitch variables of top and bot assert( Aig_ManPoNum(pAigPart)-1 == Vec_IntSize(vTopVarNums) ); @@ -98,6 +203,7 @@ int Saig_ManInduction( Aig_Man_t * p, int nFramesMax, int nConfMax, int fVerbose Lits[0] = toLitCond( pCnfPart->pVarNums[pObjPo->Id], f>0 ); if ( !sat_solver_addclause( pSat, Lits, Lits+1 ) ) assert( 0 ); + nClauses++; continue; } Lits[0] = toLitCond( Vec_IntEntry(vTopVarNums, i-1), 0 ); @@ -108,6 +214,7 @@ int Saig_ManInduction( Aig_Man_t * p, int nFramesMax, int nConfMax, int fVerbose Lits[1] = toLitCond( pCnfPart->pVarNums[pObjPo->Id], 0 ); if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) ) assert( 0 ); + nClauses += 2; } // add CNF to the SAT solver for ( i = 0; i < pCnfPart->nClauses; i++ ) @@ -119,14 +226,50 @@ int Saig_ManInduction( Aig_Man_t * p, int nFramesMax, int nConfMax, int fVerbose RetValue = 1; break; } + + // create new set of POs to derive new top + Vec_PtrClear( vTop ); + Vec_PtrPush( vTop, Aig_ManPo(p, 0) ); + Vec_IntClear( vTopVarNums ); + nOldSize = Vec_IntSize(vState); + Vec_IntFillExtra( vState, nOldSize + Aig_ManRegNum(p), -1 ); + Vec_PtrForEachEntry( Aig_Obj_t *, vBot, pObjPi, i ) + { + assert( Aig_ObjIsPi(pObjPi) ); + if ( Saig_ObjIsLo(p, pObjPi) ) + { + pObjPiCopy = (Aig_Obj_t *)pObjPi->pData; + assert( pObjPiCopy != NULL ); + Vec_PtrPush( vTop, Saig_ObjLoToLi(p, pObjPi) ); + Vec_IntPush( vTopVarNums, pCnfPart->pVarNums[pObjPiCopy->Id] ); + + iReg = pObjPi->PioNum - Saig_ManPiNum(p); + assert( iReg >= 0 && iReg < Aig_ManRegNum(p) ); + Vec_IntWriteEntry( vState, nOldSize+iReg, pCnfPart->pVarNums[pObjPiCopy->Id] ); + } + } + iLast = Vec_IntSize(vState)/Aig_ManRegNum(p); + if ( fUniqueAll ) + { + for ( i = 1; i < iLast-1; i++ ) + { + nConstrs++; + Saig_ManAddUniqueness( pSat, vState, Aig_ManRegNum(p), i, iLast-1, &nSatVarNum, &nClauses ); + if ( fVeryVerbose ) + printf( "added constaint for %3d and %3d\n", i, iLast-1 ); + } + } + +nextrun: + fAdded = 0; // run the SAT solver nConfPrev = pSat->stats.conflicts; status = sat_solver_solve( pSat, NULL, NULL, (ABC_INT64_T)nConfMax, 0, 0, 0 ); if ( fVerbose ) { - printf( "%3d : PI = %5d. PO = %5d. AIG = %5d. Var = %6d. Conf = %6d. ", - f+1, Aig_ManPiNum(pAigPart), Aig_ManPoNum(pAigPart), Aig_ManNodeNum(pAigPart), - nSatVarNum, pSat->stats.conflicts-nConfPrev ); + printf( "%4d : PI =%5d. PO =%5d. AIG =%5d. Var =%7d. Clau =%7d. Conf =%7d. ", + f, Aig_ManPiNum(pAigPart), Aig_ManPoNum(pAigPart), Aig_ManNodeNum(pAigPart), + nSatVarNum, nClauses, pSat->stats.conflicts-nConfPrev ); ABC_PRT( "Time", clock() - clk ); } if ( status == l_Undef ) @@ -137,26 +280,49 @@ int Saig_ManInduction( Aig_Man_t * p, int nFramesMax, int nConfMax, int fVerbose break; } assert( status == l_True ); + // the problem is SAT - add more clauses + if ( fVeryVerbose ) + { + Vec_IntForEachEntry( vState, iReg, i ) + { + if ( i && (i % Aig_ManRegNum(p)) == 0 ) + printf( "\n" ); + if ( (i % Aig_ManRegNum(p)) == 0 ) + printf( "%3d : ", i/Aig_ManRegNum(p) ); + printf( "%c", (iReg >= 0) ? ('0' + sat_solver_var_value(pSat, iReg)) : 'x' ); + } + printf( "\n" ); + } if ( f == nFramesMax - 1 ) break; - // the problem is SAT - add more clauses - // create new set of POs to derive new top - Vec_PtrClear( vTop ); - Vec_PtrPush( vTop, Aig_ManPo(p, 0) ); - Vec_IntClear( vTopVarNums ); - Vec_PtrForEachEntry( vBot, pObjPi, i ) + if ( fUnique ) { - assert( Aig_ObjIsPi(pObjPi) ); - if ( Saig_ObjIsLo(p, pObjPi) ) + for ( i = 1; i < iLast; i++ ) + for ( k = i+1; k < iLast; k++ ) { - pObjPiCopy = pObjPi->pData; - assert( pObjPiCopy != NULL ); - Vec_PtrPush( vTop, Saig_ObjLoToLi(p, pObjPi) ); - Vec_IntPush( vTopVarNums, pCnfPart->pVarNums[pObjPiCopy->Id] ); + if ( !Saig_ManStatesAreEqual( pSat, vState, Aig_ManRegNum(p), i, k ) ) + continue; + nConstrs++; + fAdded = 1; + Saig_ManAddUniqueness( pSat, vState, Aig_ManRegNum(p), i, k, &nSatVarNum, &nClauses ); + if ( fVeryVerbose ) + printf( "added constaint for %3d and %3d\n", i, k ); } } + if ( fAdded ) + { +// if ( fVeryVerbose ) +// printf( "Trying a new run.\n" ); + goto nextrun; + } + } + if ( fVerbose ) + { + if ( fUnique || fUniqueAll ) + printf( "Completed %d interations and added %d uniqueness constraints.\n", f+1, nConstrs ); + else + printf( "Completed %d interations.\n", f+1 ); } -// printf( "Completed %d interations.\n", f+1 ); // cleanup sat_solver_delete( pSat ); Aig_ManStop( pAigPart ); @@ -164,11 +330,15 @@ int Saig_ManInduction( Aig_Man_t * p, int nFramesMax, int nConfMax, int fVerbose Vec_IntFree( vTopVarNums ); Vec_PtrFree( vTop ); Vec_PtrFree( vBot ); + Vec_IntFree( vState ); return RetValue; } + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigIoa.c b/src/aig/saig/saigIoa.c index d049489e..c84c37f3 100644 --- a/src/aig/saig/saigIoa.c +++ b/src/aig/saig/saigIoa.c @@ -18,8 +18,12 @@ ***********************************************************************/ +#include <math.h> #include "saig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -346,7 +350,7 @@ Aig_Man_t * Saig_ManReadBlif( char * pFileName ) // allocate mapping if ( pNum2Id == NULL ) { - extern double pow( double x, double y ); +// extern double pow( double x, double y ); int Size = (int)pow(10.0, (double)(strlen(pToken) - 1)); pNum2Id = ABC_CALLOC( int, Size ); } @@ -397,3 +401,5 @@ Aig_Man_t * Saig_ManReadBlif( char * pFileName ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigMiter.c b/src/aig/saig/saigMiter.c index 0a9f230b..b470333d 100644 --- a/src/aig/saig/saigMiter.c +++ b/src/aig/saig/saigMiter.c @@ -19,6 +19,10 @@ ***********************************************************************/ #include "saig.h" +#include "fra.h" + +ABC_NAMESPACE_IMPL_START + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// @@ -210,10 +214,10 @@ void Saig_AndDualRail( Aig_Man_t * pNew, Aig_Obj_t * pObj, Aig_Obj_t ** ppData, { Aig_Obj_t * pFanin0 = Aig_ObjFanin0(pObj); Aig_Obj_t * pFanin1 = Aig_ObjFanin1(pObj); - Aig_Obj_t * p0Data = Aig_ObjFaninC0(pObj)? pFanin0->pNext : pFanin0->pData; - Aig_Obj_t * p0Next = Aig_ObjFaninC0(pObj)? pFanin0->pData : pFanin0->pNext; - Aig_Obj_t * p1Data = Aig_ObjFaninC1(pObj)? pFanin1->pNext : pFanin1->pData; - Aig_Obj_t * p1Next = Aig_ObjFaninC1(pObj)? pFanin1->pData : pFanin1->pNext; + Aig_Obj_t * p0Data = Aig_ObjFaninC0(pObj)? pFanin0->pNext : (Aig_Obj_t *)pFanin0->pData; + Aig_Obj_t * p0Next = Aig_ObjFaninC0(pObj)? (Aig_Obj_t *)pFanin0->pData : pFanin0->pNext; + Aig_Obj_t * p1Data = Aig_ObjFaninC1(pObj)? pFanin1->pNext : (Aig_Obj_t *)pFanin1->pData; + Aig_Obj_t * p1Next = Aig_ObjFaninC1(pObj)? (Aig_Obj_t *)pFanin1->pData : pFanin1->pNext; *ppData = Aig_Or( pNew, Aig_And(pNew, p0Data, Aig_Not(p0Next)), Aig_And(pNew, p1Data, Aig_Not(p1Next)) ); @@ -262,20 +266,20 @@ Aig_Man_t * Saig_ManDualRail( Aig_Man_t * p, int fMiter ) Saig_ManForEachLo( p, pObj, i ) { pMiter = Aig_And( pNew, pMiter, - Aig_Or(pNew, pObj->pData, pObj->pNext) ); + Aig_Or(pNew, (Aig_Obj_t *)pObj->pData, pObj->pNext) ); } Aig_ObjCreatePo( pNew, pMiter ); Saig_ManForEachLi( p, pObj, i ) { if ( !Aig_ObjFaninC0(pObj) ) { - Aig_ObjCreatePo( pNew, Aig_ObjFanin0(pObj)->pData ); + Aig_ObjCreatePo( pNew, (Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData ); Aig_ObjCreatePo( pNew, Aig_ObjFanin0(pObj)->pNext ); } else { Aig_ObjCreatePo( pNew, Aig_ObjFanin0(pObj)->pNext ); - Aig_ObjCreatePo( pNew, Aig_ObjFanin0(pObj)->pData ); + Aig_ObjCreatePo( pNew, (Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData ); } } } @@ -285,13 +289,13 @@ Aig_Man_t * Saig_ManDualRail( Aig_Man_t * p, int fMiter ) { if ( !Aig_ObjFaninC0(pObj) ) { - Aig_ObjCreatePo( pNew, Aig_ObjFanin0(pObj)->pData ); + Aig_ObjCreatePo( pNew, (Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData ); Aig_ObjCreatePo( pNew, Aig_ObjFanin0(pObj)->pNext ); } else { Aig_ObjCreatePo( pNew, Aig_ObjFanin0(pObj)->pNext ); - Aig_ObjCreatePo( pNew, Aig_ObjFanin0(pObj)->pData ); + Aig_ObjCreatePo( pNew, (Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData ); } } } @@ -396,7 +400,7 @@ Aig_Man_t * Aig_ManDupNodesAll( Aig_Man_t * p, Vec_Ptr_t * vSet ) pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); // Saig_ManForEachPo( p, pObj, i ) // pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) ); - Vec_PtrForEachEntry( vSet, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vSet, pObj, i ) Aig_ObjCreatePo( pNew, Aig_NotCond((Aig_Obj_t *)Aig_Regular(pObj)->pData, Aig_IsComplement(pObj)) ); Saig_ManForEachLi( p, pObj, i ) pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) ); @@ -447,7 +451,7 @@ Aig_Man_t * Aig_ManDupNodesHalf( Aig_Man_t * p, Vec_Ptr_t * vSet, int iPart ) pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); // Saig_ManForEachPo( p, pObj, i ) // pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) ); - Vec_PtrForEachEntry( vSet, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vSet, pObj, i ) Aig_ObjCreatePo( pNew, Aig_NotCond((Aig_Obj_t *)Aig_Regular(pObj)->pData, Aig_IsComplement(pObj)) ); if ( iPart == 0 ) { @@ -712,8 +716,8 @@ int Saig_ManDemiter( Aig_Man_t * p, Aig_Man_t ** ppAig0, Aig_Man_t ** ppAig1 ) vSet0 = Vec_PtrAlloc( Saig_ManPoNum(p) ); vSet1 = Vec_PtrAlloc( Saig_ManPoNum(p) ); // get the first pair of outputs - pObj0 = Vec_PtrEntry( vPairs, 0 ); - pObj1 = Vec_PtrEntry( vPairs, 1 ); + pObj0 = (Aig_Obj_t *)Vec_PtrEntry( vPairs, 0 ); + pObj1 = (Aig_Obj_t *)Vec_PtrEntry( vPairs, 1 ); // label registers reachable from the outputs Aig_ManIncrementTravId( p ); Saig_ManDemiterLabel_rec( p, Aig_Regular(pObj0), 0 ); @@ -724,8 +728,8 @@ int Saig_ManDemiter( Aig_Man_t * p, Aig_Man_t ** ppAig0, Aig_Man_t ** ppAig1 ) // find where each output belongs for ( i = 2; i < Vec_PtrSize(vPairs); i += 2 ) { - pObj0 = Vec_PtrEntry( vPairs, i ); - pObj1 = Vec_PtrEntry( vPairs, i+1 ); + pObj0 = (Aig_Obj_t *)Vec_PtrEntry( vPairs, i ); + pObj1 = (Aig_Obj_t *)Vec_PtrEntry( vPairs, i+1 ); Aig_ManIncrementTravId( p ); pFlop0 = Saig_ManGetLabeledRegister_rec( p, Aig_Regular(pObj0) ); @@ -862,7 +866,7 @@ int Ssw_SecCexResimulate( Aig_Man_t * p, int * pModel, int * pnOutputs ) ***********************************************************************/ int Ssw_SecSpecial( Aig_Man_t * pPart0, Aig_Man_t * pPart1, int nFrames, int fVerbose ) { - extern int Fra_FraigCec( Aig_Man_t ** ppAig, int nConfLimit, int fVerbose ); +// extern int Fra_FraigCec( Aig_Man_t ** ppAig, int nConfLimit, int fVerbose ); int iOut, nOuts; Aig_Man_t * pMiterCec; int RetValue, clkTotal = clock(); @@ -905,7 +909,7 @@ ABC_PRT( "Time", clock() - clkTotal ); printf( "Counter-example is not available.\n" ); else { - iOut = Ssw_SecCexResimulate( pMiterCec, pMiterCec->pData, &nOuts ); + iOut = Ssw_SecCexResimulate( pMiterCec, (int *)pMiterCec->pData, &nOuts ); if ( iOut == -1 ) printf( "Counter-example verification has failed.\n" ); else @@ -993,3 +997,5 @@ int Ssw_SecSpecialMiter( Aig_Man_t * p0, Aig_Man_t * p1, int nFrames, int fVerbo //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigPba.c b/src/aig/saig/saigPba.c new file mode 100644 index 00000000..65b39fc0 --- /dev/null +++ b/src/aig/saig/saigPba.c @@ -0,0 +1,752 @@ +/**CFile**************************************************************** + + FileName [saigPba.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Sequential AIG package.] + + Synopsis [Proof-based abstraction.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: saigPba.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "saig.h" + +#include "cnf.h" +#include "satSolver.h" +#include "satStore.h" +#include "ssw.h" +#include "ioa.h" +#include "fra.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static inline char Saig_AbsVisited( Vec_Str_t * p, int nObjs, Aig_Obj_t * pObj, int i ) { return Vec_StrGetEntry( p, nObjs*i+pObj->Id ); } +static inline void Saig_AbsSetVisited( Vec_Str_t * p, int nObjs, Aig_Obj_t * pObj, int i ) { Vec_StrSetEntry( p, nObjs*i+pObj->Id, (char)1 ); } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Finds the set of clauses involved in the UNSAT core.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Saig_AbsSolverUnsatCore( sat_solver * pSat, int nConfMax, int fVerbose, int * piRetValue ) +{ + Vec_Int_t * vCore; + void * pSatCnf; + Intp_Man_t * pManProof; + int RetValue, clk = clock(); + *piRetValue = -1; + // solve the problem + RetValue = sat_solver_solve( pSat, NULL, NULL, (ABC_INT64_T)nConfMax, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); + if ( RetValue == l_Undef ) + { + printf( "Conflict limit is reached.\n" ); + return NULL; + } + if ( RetValue == l_True ) + { + printf( "The BMC problem is SAT.\n" ); + *piRetValue = 0; + return NULL; + } + if ( fVerbose ) + { + printf( "SAT solver returned UNSAT after %d conflicts. ", pSat->stats.conflicts ); + ABC_PRT( "Time", clock() - clk ); + } + assert( RetValue == l_False ); + pSatCnf = sat_solver_store_release( pSat ); + // derive the UNSAT core + clk = clock(); + pManProof = Intp_ManAlloc(); + vCore = (Vec_Int_t *)Intp_ManUnsatCore( pManProof, (Sto_Man_t *)pSatCnf, 0 ); + Intp_ManFree( pManProof ); + Sto_ManFree( (Sto_Man_t *)pSatCnf ); + if ( fVerbose ) + { + printf( "SAT core contains %d clauses (out of %d). ", Vec_IntSize(vCore), pSat->stats.clauses ); + ABC_PRT( "Time", clock() - clk ); + } + return vCore; +} + + +/**Function************************************************************* + + Synopsis [Mark visited nodes recursively.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_AbsMarkVisited_rec( Aig_Man_t * p, Vec_Str_t * vObj2Visit, Aig_Obj_t * pObj, int i ) +{ + if ( Saig_AbsVisited( vObj2Visit, Aig_ManObjNumMax(p), pObj, i ) ) + return 1; + Saig_AbsSetVisited( vObj2Visit, Aig_ManObjNumMax(p), pObj, i ); + if ( Saig_ObjIsPi( p, pObj ) ) + return 1; + if ( Saig_ObjIsLo( p, pObj ) ) + { + if ( i == 0 ) + return 1; + return Saig_AbsMarkVisited_rec( p, vObj2Visit, Saig_ObjLoToLi(p, pObj), i-1 ); + } + if ( Aig_ObjIsPo( pObj ) ) + return Saig_AbsMarkVisited_rec( p, vObj2Visit, Aig_ObjFanin0(pObj), i ); + Saig_AbsMarkVisited_rec( p, vObj2Visit, Aig_ObjFanin0(pObj), i ); + Saig_AbsMarkVisited_rec( p, vObj2Visit, Aig_ObjFanin1(pObj), i ); + return 1; +} + +/**Function************************************************************* + + Synopsis [Mark visited nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Str_t * Saig_AbsMarkVisited( Aig_Man_t * p, int nFramesMax ) +{ + Vec_Str_t * vObj2Visit; + Aig_Obj_t * pObj; + int i, f; + vObj2Visit = Vec_StrStart( Aig_ManObjNumMax(p) * nFramesMax ); +// Saig_ManForEachLo( p, pObj, i ) +// Saig_AbsSetVisited( vObj2Visit, Aig_ManObjNumMax(p), pObj, 0 ); + for ( f = 0; f < nFramesMax; f++ ) + { + Saig_AbsSetVisited( vObj2Visit, Aig_ManObjNumMax(p), Aig_ManConst1(p), f ); + Saig_ManForEachPo( p, pObj, i ) + Saig_AbsMarkVisited_rec( p, vObj2Visit, pObj, f ); + } + return vObj2Visit; +} + +/**Function************************************************************* + + Synopsis [Performs the actual construction of the output.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Saig_AbsCreateFrames_rec( Aig_Man_t * pFrame, Aig_Obj_t * pObj ) +{ + if ( pObj->pData ) + return (Aig_Obj_t *)pObj->pData; + assert( Aig_ObjIsNode(pObj) ); + Saig_AbsCreateFrames_rec( pFrame, Aig_ObjFanin0(pObj) ); + Saig_AbsCreateFrames_rec( pFrame, Aig_ObjFanin1(pObj) ); + return (Aig_Obj_t *)(pObj->pData = Aig_And( pFrame, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) )); +} + +/**Function************************************************************* + + Synopsis [Derives a vector of AIG managers, one for each frame.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Saig_AbsCreateFrames( Aig_Man_t * p, int nFramesMax, int fVerbose ) +{ + Vec_Ptr_t * vFrames, * vLoObjs, * vLiObjs; + Vec_Str_t * vObj2Visit; + Aig_Man_t * pFrame; + Aig_Obj_t * pObj; + int f, i; + vObj2Visit = Saig_AbsMarkVisited( p, nFramesMax ); + vFrames = Vec_PtrAlloc( nFramesMax ); + vLoObjs = Vec_PtrAlloc( 100 ); + vLiObjs = Vec_PtrAlloc( 100 ); + for ( f = 0; f < nFramesMax; f++ ) + { + Aig_ManCleanData( p ); + pFrame = Aig_ManStart( 1000 ); + Aig_ManConst1(p)->pData = Aig_ManConst1(pFrame); + // create PIs + Vec_PtrClear( vLoObjs ); + Vec_PtrClear( vLiObjs ); + Aig_ManForEachPi( p, pObj, i ) + { + if ( Saig_AbsVisited( vObj2Visit, Aig_ManObjNumMax(p), pObj, f ) ) + { + pObj->pData = Aig_ObjCreatePi(pFrame); + if ( i >= Saig_ManPiNum(p) ) + Vec_PtrPush( vLoObjs, pObj ); + } + } + // remember the number of (implicit) registers in this frame + pFrame->nAsserts = Vec_PtrSize(vLoObjs); + // create POs + Aig_ManForEachPo( p, pObj, i ) + { + if ( Saig_AbsVisited( vObj2Visit, Aig_ManObjNumMax(p), pObj, f ) ) + { + Saig_AbsCreateFrames_rec( pFrame, Aig_ObjFanin0(pObj) ); + pObj->pData = Aig_ObjCreatePo( pFrame, Aig_ObjChild0Copy(pObj) ); + if ( i >= Saig_ManPoNum(p) ) + Vec_PtrPush( vLiObjs, pObj ); + } + } +// Vec_PtrPush( vFrames, Cnf_Derive(pFrame, Aig_ManPoNum(pFrame)) ); + Vec_PtrPush( vFrames, Cnf_DeriveSimple(pFrame, Aig_ManPoNum(pFrame)) ); + // set the new PIs to point to the corresponding registers + Aig_ManCleanData( pFrame ); + Vec_PtrForEachEntry( Aig_Obj_t *, vLoObjs, pObj, i ) + ((Aig_Obj_t *)pObj->pData)->pData = pObj; + Vec_PtrForEachEntry( Aig_Obj_t *, vLiObjs, pObj, i ) + ((Aig_Obj_t *)pObj->pData)->pData = pObj; + if ( fVerbose ) + printf( "%3d : PI =%8d. PO =%8d. Flop =%8d. Node =%8d.\n", + f, Aig_ManPiNum(pFrame), Aig_ManPoNum(pFrame), pFrame->nAsserts, Aig_ManNodeNum(pFrame) ); + } + Vec_PtrFree( vLoObjs ); + Vec_PtrFree( vLiObjs ); + Vec_StrFree( vObj2Visit ); + return vFrames; +} + +/**Function************************************************************* + + Synopsis [Derives a vector of AIG managers, one for each frame.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +sat_solver * Saig_AbsCreateSolverDyn( Aig_Man_t * p, Vec_Ptr_t * vFrames ) +{ + sat_solver * pSat; + Cnf_Dat_t * pCnf, * pCnfPrev; + Vec_Int_t * vPoLits; + Aig_Obj_t * pObjPo, * pObjLi, * pObjLo; + int f, i, Lit, Lits[2], iVarOld, iVarNew, nSatVars, nRegisters; + // start array of output literals + vPoLits = Vec_IntAlloc( 100 ); + // count the number of CNF variables + nSatVars = 0; + Vec_PtrForEachEntry( Cnf_Dat_t *, vFrames, pCnf, f ) + nSatVars += pCnf->nVars; + + // create the SAT solver + pSat = sat_solver_new(); + sat_solver_store_alloc( pSat ); + sat_solver_setnvars( pSat, nSatVars ); + + // add clauses for the timeframes + nSatVars = 0; +// Vec_PtrForEachEntryReverse( Cnf_Dat_t *, vFrames, pCnf, f ) + Vec_PtrForEachEntry( Cnf_Dat_t *, vFrames, pCnf, f ) + { + // lift clauses of this CNF + Cnf_DataLift( pCnf, nSatVars ); + nSatVars += pCnf->nVars; + // copy clauses into the manager + for ( i = 0; i < pCnf->nClauses; i++ ) + { + if ( !sat_solver_addclause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1] ) ) + { + printf( "The BMC problem is trivially UNSAT.\n" ); + sat_solver_delete( pSat ); + Vec_IntFree( vPoLits ); + return NULL; + } + } + // remember output literal + Aig_ManForEachPo( pCnf->pMan, pObjPo, i ) + { + if ( i == Saig_ManPoNum(p) ) + break; + Vec_IntPush( vPoLits, toLit(pCnf->pVarNums[pObjPo->Id]) ); + } + } + + // add auxiliary clauses (output, connectors, initial) + // add output clause + if ( !sat_solver_addclause( pSat, Vec_IntArray(vPoLits), Vec_IntArray(vPoLits) + Vec_IntSize(vPoLits) ) ) + { + printf( "SAT solver is not created correctly.\n" ); + assert( 0 ); + } + Vec_IntFree( vPoLits ); + + // add connecting clauses + pCnfPrev = (Cnf_Dat_t *)Vec_PtrEntry( vFrames, 0 ); + Vec_PtrForEachEntryStart( Cnf_Dat_t *, vFrames, pCnf, f, 1 ) + { + nRegisters = pCnf->pMan->nAsserts; + assert( nRegisters <= Aig_ManPoNum(pCnfPrev->pMan) ); + assert( nRegisters <= Aig_ManPiNum(pCnf->pMan) ); + for ( i = 0; i < nRegisters; i++ ) + { + pObjLi = Aig_ManPo( pCnfPrev->pMan, Aig_ManPoNum(pCnfPrev->pMan) - nRegisters + i ); + pObjLo = Aig_ManPi( pCnf->pMan, Aig_ManPiNum(pCnf->pMan) - nRegisters + i ); + // get variable numbers + iVarOld = pCnfPrev->pVarNums[pObjLi->Id]; + iVarNew = pCnf->pVarNums[pObjLo->Id]; + // add clauses connecting existing variables + Lits[0] = toLitCond( iVarOld, 0 ); + Lits[1] = toLitCond( iVarNew, 1 ); + if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) ) + assert( 0 ); + Lits[0] = toLitCond( iVarOld, 1 ); + Lits[1] = toLitCond( iVarNew, 0 ); + if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) ) + assert( 0 ); + } + pCnfPrev = pCnf; + } + // add unit clauses + pCnf = (Cnf_Dat_t *)Vec_PtrEntry( vFrames, 0 ); + nRegisters = pCnf->pMan->nAsserts; + for ( i = 0; i < nRegisters; i++ ) + { + pObjLo = Aig_ManPi( pCnf->pMan, Aig_ManPiNum(pCnf->pMan) - nRegisters + i ); + assert( pCnf->pVarNums[pObjLo->Id] >= 0 ); + Lit = toLitCond( pCnf->pVarNums[pObjLo->Id], 1 ); + if ( !sat_solver_addclause( pSat, &Lit, &Lit+1 ) ) + assert( 0 ); + } + sat_solver_store_mark_roots( pSat ); + return pSat; +} + + +/**Function************************************************************* + + Synopsis [Creates SAT solver for BMC.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +sat_solver * Saig_AbsCreateSolver( Cnf_Dat_t * pCnf, int nFrames ) +{ + sat_solver * pSat; + Vec_Int_t * vPoLits; + Aig_Obj_t * pObjPo, * pObjLi, * pObjLo; + int f, i, Lit, Lits[2], iVarOld, iVarNew; + // start array of output literals + vPoLits = Vec_IntAlloc( nFrames * Saig_ManPoNum(pCnf->pMan) ); + // create the SAT solver + pSat = sat_solver_new(); + sat_solver_store_alloc( pSat ); + sat_solver_setnvars( pSat, pCnf->nVars * nFrames ); + + // add clauses for the timeframes + for ( f = 0; f < nFrames; f++ ) + { + for ( i = 0; i < pCnf->nClauses; i++ ) + { + if ( !sat_solver_addclause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1] ) ) + { + printf( "The BMC problem is trivially UNSAT.\n" ); + sat_solver_delete( pSat ); + Vec_IntFree( vPoLits ); + return NULL; + } + } + // remember output literal + Saig_ManForEachPo( pCnf->pMan, pObjPo, i ) + Vec_IntPush( vPoLits, toLit(pCnf->pVarNums[pObjPo->Id]) ); + // lift CNF to the next frame + Cnf_DataLift( pCnf, pCnf->nVars ); + } + // put CNF back to the original level + Cnf_DataLift( pCnf, - pCnf->nVars * nFrames ); + + // add auxiliary clauses (output, connectors, initial) + // add output clause + if ( !sat_solver_addclause( pSat, Vec_IntArray(vPoLits), Vec_IntArray(vPoLits) + Vec_IntSize(vPoLits) ) ) + assert( 0 ); + Vec_IntFree( vPoLits ); + // add connecting clauses + for ( f = 0; f < nFrames; f++ ) + { + // connect to the previous timeframe + if ( f > 0 ) + { + Saig_ManForEachLiLo( pCnf->pMan, pObjLi, pObjLo, i ) + { + iVarOld = pCnf->pVarNums[pObjLi->Id] - pCnf->nVars; + iVarNew = pCnf->pVarNums[pObjLo->Id]; + // add clauses connecting existing variables + Lits[0] = toLitCond( iVarOld, 0 ); + Lits[1] = toLitCond( iVarNew, 1 ); + if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) ) + assert( 0 ); + Lits[0] = toLitCond( iVarOld, 1 ); + Lits[1] = toLitCond( iVarNew, 0 ); + if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) ) + assert( 0 ); + } + } + // lift CNF to the next frame + Cnf_DataLift( pCnf, pCnf->nVars ); + } + // put CNF back to the original level + Cnf_DataLift( pCnf, - pCnf->nVars * nFrames ); + // add unit clauses + Saig_ManForEachLo( pCnf->pMan, pObjLo, i ) + { + assert( pCnf->pVarNums[pObjLo->Id] >= 0 ); + Lit = toLitCond( pCnf->pVarNums[pObjLo->Id], 1 ); + if ( !sat_solver_addclause( pSat, &Lit, &Lit+1 ) ) + assert( 0 ); + } + sat_solver_store_mark_roots( pSat ); + return pSat; +} + +/**Function************************************************************* + + Synopsis [Performs proof-based abstraction using BMC of the given depth.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Saig_AbsCollectRegistersDyn( Aig_Man_t * p, Vec_Ptr_t * vFrames, Vec_Int_t * vCore ) +{ + Aig_Obj_t * pObj; + Cnf_Dat_t * pCnf; + Vec_Int_t * vFlops; + int * pVars, * pFlops; + int i, f, iClause, iReg, * piLit, nSatVars, nSatClauses; + // count the number of CNF variables + nSatVars = 0; + Vec_PtrForEachEntry( Cnf_Dat_t *, vFrames, pCnf, f ) + nSatVars += pCnf->nVars; + // mark register variables + pVars = ABC_ALLOC( int, nSatVars ); + for ( i = 0; i < nSatVars; i++ ) + pVars[i] = -1; + Vec_PtrForEachEntry( Cnf_Dat_t *, vFrames, pCnf, f ) + { + Aig_ManForEachPi( pCnf->pMan, pObj, i ) + { + assert( pCnf->pVarNums[pObj->Id] >= 0 ); + assert( pCnf->pVarNums[pObj->Id] < nSatVars ); + if ( pObj->pData == NULL ) + continue; + iReg = Aig_ObjPioNum((Aig_Obj_t *)pObj->pData) - Saig_ManPiNum(p); + assert( iReg >= 0 && iReg < Aig_ManRegNum(p) ); + pVars[ pCnf->pVarNums[pObj->Id] ] = iReg; + } + Aig_ManForEachPo( pCnf->pMan, pObj, i ) + { + assert( pCnf->pVarNums[pObj->Id] >= 0 ); + assert( pCnf->pVarNums[pObj->Id] < nSatVars ); + if ( pObj->pData == NULL ) + continue; + iReg = Aig_ObjPioNum((Aig_Obj_t *)pObj->pData) - Saig_ManPoNum(p); + assert( iReg >= 0 && iReg < Aig_ManRegNum(p) ); + pVars[ pCnf->pVarNums[pObj->Id] ] = iReg; + } + } + // mark used registers + pFlops = ABC_CALLOC( int, Aig_ManRegNum(p) ); + Vec_IntForEachEntry( vCore, iClause, i ) + { + nSatClauses = 0; + Vec_PtrForEachEntry( Cnf_Dat_t *, vFrames, pCnf, f ) + { + if ( iClause < nSatClauses + pCnf->nClauses ) + break; + nSatClauses += pCnf->nClauses; + } + if ( f == Vec_PtrSize(vFrames) ) + continue; + iClause = iClause - nSatClauses; + assert( iClause >= 0 ); + assert( iClause < pCnf->nClauses ); + // consider the clause + for ( piLit = pCnf->pClauses[iClause]; piLit < pCnf->pClauses[iClause+1]; piLit++ ) + { + iReg = pVars[ lit_var(*piLit) ]; + if ( iReg >= 0 ) + pFlops[iReg] = 1; + } + } + // collect registers + vFlops = Vec_IntAlloc( Aig_ManRegNum(p) ); + for ( i = 0; i < Aig_ManRegNum(p); i++ ) + if ( pFlops[i] ) + Vec_IntPush( vFlops, i ); + ABC_FREE( pFlops ); + ABC_FREE( pVars ); + return vFlops; +} + +/**Function************************************************************* + + Synopsis [Performs proof-based abstraction using BMC of the given depth.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Saig_AbsCollectRegisters( Cnf_Dat_t * pCnf, int nFrames, Vec_Int_t * vCore ) +{ + Aig_Obj_t * pObj; + Vec_Int_t * vFlops; + int * pVars, * pFlops; + int i, iClause, iReg, * piLit; + // mark register variables + pVars = ABC_ALLOC( int, pCnf->nVars ); + for ( i = 0; i < pCnf->nVars; i++ ) + pVars[i] = -1; + Saig_ManForEachLi( pCnf->pMan, pObj, i ) + pVars[ pCnf->pVarNums[pObj->Id] ] = i; + Saig_ManForEachLo( pCnf->pMan, pObj, i ) + pVars[ pCnf->pVarNums[pObj->Id] ] = i; + // mark used registers + pFlops = ABC_CALLOC( int, Aig_ManRegNum(pCnf->pMan) ); + Vec_IntForEachEntry( vCore, iClause, i ) + { + // skip auxiliary clauses + if ( iClause >= pCnf->nClauses * nFrames ) + continue; + // consider the clause + iClause = iClause % pCnf->nClauses; + for ( piLit = pCnf->pClauses[iClause]; piLit < pCnf->pClauses[iClause+1]; piLit++ ) + { + iReg = pVars[ lit_var(*piLit) ]; + if ( iReg >= 0 ) + pFlops[iReg] = 1; + } + } + // collect registers + vFlops = Vec_IntAlloc( Aig_ManRegNum(pCnf->pMan) ); + for ( i = 0; i < Aig_ManRegNum(pCnf->pMan); i++ ) + if ( pFlops[i] ) + Vec_IntPush( vFlops, i ); + ABC_FREE( pFlops ); + ABC_FREE( pVars ); + return vFlops; +} + +/**Function************************************************************* + + Synopsis [Performs proof-based abstraction using BMC of the given depth.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_AbsFreeCnfs( Vec_Ptr_t * vFrames ) +{ + Cnf_Dat_t * pCnf; + int i; + Vec_PtrForEachEntry( Cnf_Dat_t *, vFrames, pCnf, i ) + { + Aig_ManStop( pCnf->pMan ); + Cnf_DataFree( pCnf ); + } + Vec_PtrFree( vFrames ); +} + +/**Function************************************************************* + + Synopsis [Performs proof-based abstraction using BMC of the given depth.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_AbsExtendOneStep( Aig_Man_t * p, Vec_Int_t * vFlops ) +{ + Vec_Ptr_t * vFlopPtrs, * vSupp; + Aig_Obj_t * pObj; + int i, Entry; + // collect latch inputs + vFlopPtrs = Vec_PtrAlloc( 1000 ); + Vec_IntForEachEntry( vFlops, Entry, i ) + { + Vec_PtrPush( vFlopPtrs, Saig_ManLi(p, Entry) ); + pObj = Saig_ManLo(p, Entry); + pObj->fMarkA = 1; + } + // collect latch outputs + vSupp = Vec_PtrAlloc( 1000 ); + Aig_SupportNodes( p, (Aig_Obj_t **)Vec_PtrArray(vFlopPtrs), Vec_PtrSize(vFlopPtrs), vSupp ); + Vec_PtrFree( vFlopPtrs ); + // mark influencing flops + Vec_PtrForEachEntry( Aig_Obj_t *, vSupp, pObj, i ) + pObj->fMarkA = 1; + Vec_PtrFree( vSupp ); + // reload flops + Vec_IntClear( vFlops ); + Aig_ManForEachPi( p, pObj, i ) + { + if ( pObj->fMarkA == 0 ) + continue; + pObj->fMarkA = 0; + if ( Aig_ObjPioNum(pObj)-Saig_ManPiNum(p) >= 0 ) + Vec_IntPush( vFlops, Aig_ObjPioNum(pObj)-Saig_ManPiNum(p) ); + } +} + + +/**Function************************************************************* + + Synopsis [Performs proof-based abstraction using BMC of the given depth.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Saig_ManProofAbstractionFlops( Aig_Man_t * p, Gia_ParAbs_t * pPars ) +{ + Vec_Int_t * vFlops; + sat_solver * pSat; + Vec_Ptr_t * vFrames = NULL; + Vec_Int_t * vCore; + Cnf_Dat_t * pCnf = NULL; + int clk = clock(), clk2 = clock(); + if ( pPars->fVerbose ) + printf( "Performing proof-based abstraction with %d frames and %d max conflicts.\n", pPars->nFramesMax, pPars->nConfMax ); + assert( Aig_ManRegNum(p) > 0 ); + Aig_ManSetPioNumbers( p ); + if ( pPars->fDynamic ) + { + // create CNF for the frames + vFrames = Saig_AbsCreateFrames( p, pPars->nFramesMax, pPars->fVerbose ); + // create dynamic solver + pSat = Saig_AbsCreateSolverDyn( p, vFrames ); + } + else + { + // create CNF for the AIG + pCnf = Cnf_DeriveSimple( p, Aig_ManPoNum(p) ); + // create SAT solver for the unrolled AIG + pSat = Saig_AbsCreateSolver( pCnf, pPars->nFramesMax ); + } + if ( pPars->fVerbose ) + { + printf( "SAT solver: Vars = %7d. Clauses = %7d. ", pSat->size, pSat->stats.clauses ); + ABC_PRT( "Time", clock() - clk2 ); + } + // compute UNSAT core + vCore = Saig_AbsSolverUnsatCore( pSat, pPars->nConfMax, pPars->fVerbose, &pPars->Status ); + sat_solver_delete( pSat ); + if ( vCore == NULL ) + { + if ( vFrames ) + Saig_AbsFreeCnfs( vFrames ); + return NULL; + } + pPars->nFramesDone = pPars->nFramesMax; + // collect registers + if ( pPars->fDynamic ) + { + vFlops = Saig_AbsCollectRegistersDyn( p, vFrames, vCore ); + Saig_AbsFreeCnfs( vFrames ); + } + else + { + vFlops = Saig_AbsCollectRegisters( pCnf, pPars->nFramesMax, vCore ); + Cnf_DataFree( pCnf ); + } + Vec_IntFree( vCore ); + if ( pPars->fVerbose ) + { + printf( "The number of relevant registers is %d (out of %d). ", Vec_IntSize(vFlops), Aig_ManRegNum(p) ); + ABC_PRT( "Time", clock() - clk ); + } + return vFlops; +} + +/**Function************************************************************* + + Synopsis [Performs proof-based abstraction using BMC of the given depth.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Saig_ManProofAbstraction( Aig_Man_t * p, Gia_ParAbs_t * pPars ) +{ + Vec_Int_t * vFlops; + Aig_Man_t * pAbs = NULL; + vFlops = Saig_ManProofAbstractionFlops( p, pPars ); + // write the final result + if ( vFlops ) + { + pAbs = Saig_ManDeriveAbstraction( p, vFlops ); + Ioa_WriteAiger( pAbs, "gabs.aig", 0, 0 ); + printf( "Final abstracted model was written into file \"%s\".\n", "gabs.aig" ); + Vec_IntFree( vFlops ); + } + return pAbs; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigPhase.c b/src/aig/saig/saigPhase.c index c67949b5..340910d0 100644 --- a/src/aig/saig/saigPhase.c +++ b/src/aig/saig/saigPhase.c @@ -20,6 +20,9 @@ #include "saig.h" +ABC_NAMESPACE_IMPL_START + + /* The algorithm is described in the paper: Per Bjesse and Jim Kukula, "Automatic Phase Abstraction for Formal Verification", ICCAD 2005 @@ -228,7 +231,7 @@ int Saig_TsiCountNonXValuedRegisters( Saig_Tsim_t * p, int nWords, int nPref ) p->vNonXRegs = Vec_IntAlloc( 10 ); for ( i = 0; i < nRegs; i++ ) { - Vec_PtrForEachEntryStart( p->vStates, pState, k, nPref ) + Vec_PtrForEachEntryStart( unsigned *, p->vStates, pState, k, nPref ) { Value = (Aig_InfoHasBit( pState, 2 * i + 1 ) << 1) | Aig_InfoHasBit( pState, 2 * i ); assert( Value != 0 ); @@ -261,7 +264,7 @@ void Saig_TsiPrintTraces( Saig_Tsim_t * p, int nWords, int nPrefix ) return; for ( i = 0; i < nRegs; i++ ) { - Vec_PtrForEachEntry( p->vStates, pState, k ) + Vec_PtrForEachEntry( unsigned *, p->vStates, pState, k ) { Value = (Aig_InfoHasBit( pState, 2 * i + 1 ) << 1) | Aig_InfoHasBit( pState, 2 * i ); if ( Value == SAIG_XVSX ) @@ -273,7 +276,7 @@ void Saig_TsiPrintTraces( Saig_Tsim_t * p, int nWords, int nPrefix ) continue; // print trace printf( "%5d : %5d %5d ", Counter, i, Saig_ManLo(p->pAig, i)->Id ); - Vec_PtrForEachEntryStop( p->vStates, pState, k, Vec_PtrSize(p->vStates)-1 ) + Vec_PtrForEachEntryStop( unsigned *, p->vStates, pState, k, Vec_PtrSize(p->vStates)-1 ) { Value = (Aig_InfoHasBit( pState, 2 * i + 1 ) << 1) | Aig_InfoHasBit( pState, 2 * i ); if ( Value == SAIG_XVS0 ) @@ -310,7 +313,7 @@ int Saig_TsiComputePrefix( Saig_Tsim_t * p, unsigned * pState, int nWords ) for ( pEntry = p->pBins[Hash]; pEntry; pEntry = Saig_TsiNext(pEntry, nWords) ) if ( !memcmp( pEntry, pState, sizeof(unsigned) * nWords ) ) { - Vec_PtrForEachEntry( p->vStates, pPrev, i ) + Vec_PtrForEachEntry( unsigned *, p->vStates, pPrev, i ) { if ( pPrev == pEntry ) return i; @@ -449,7 +452,7 @@ void Saig_TsiStateOrAll( Saig_Tsim_t * pTsi, unsigned * pState ) { unsigned * pPrev; int i, k; - Vec_PtrForEachEntry( pTsi->vStates, pPrev, i ) + Vec_PtrForEachEntry( unsigned *, pTsi->vStates, pPrev, i ) { for ( k = 0; k < pTsi->nWords; k++ ) pState[k] |= pPrev[k]; @@ -616,9 +619,9 @@ int Saig_ManFindRegisters( Saig_Tsim_t * pTsi, int nFrames, int fIgnore, int fVe for ( k = 0; k < nTests; k++ ) { if ( k < pTsi->nPrefix + pTsi->nCycle ) - pState = Vec_PtrEntry( pTsi->vStates, k ); + pState = (unsigned *)Vec_PtrEntry( pTsi->vStates, k ); else - pState = Vec_PtrEntry( pTsi->vStates, k - pTsi->nCycle ); + pState = (unsigned *)Vec_PtrEntry( pTsi->vStates, k - pTsi->nCycle ); Value = (Aig_InfoHasBit( pState, 2 * Reg + 1 ) << 1) | Aig_InfoHasBit( pState, 2 * Reg ); assert( Value == SAIG_XVS0 || Value == SAIG_XVS1 ); if ( k < nFrames || (fIgnore && k == nFrames) ) @@ -721,7 +724,7 @@ Aig_Man_t * Saig_ManPerformAbstraction( Saig_Tsim_t * pTsi, int nFrames, int fVe Vec_IntForEachEntry( pTsi->vNonXRegs, Reg, i ) { pObj = Saig_ManLo( pAig, Reg ); - pState = Vec_PtrEntry( pTsi->vStates, f ); + pState = (unsigned *)Vec_PtrEntry( pTsi->vStates, f ); Value = (Aig_InfoHasBit( pState, 2 * Reg + 1 ) << 1) | Aig_InfoHasBit( pState, 2 * Reg ); assert( Value == SAIG_XVS0 || Value == SAIG_XVS1 ); pObjNew = (Value == SAIG_XVS1)? Aig_ManConst1(pFrames) : Aig_ManConst0(pFrames); @@ -766,6 +769,37 @@ Aig_Man_t * Saig_ManPerformAbstraction( Saig_Tsim_t * pTsi, int nFrames, int fVe return pFrames; } + +/**Function************************************************************* + + Synopsis [Performs automated phase abstraction.] + + Description [Takes the AIG manager and the array of initial states.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_ManPhaseFrameNum( Aig_Man_t * p, Vec_Int_t * vInits ) +{ + Saig_Tsim_t * pTsi; + int nFrames, nPrefix; + assert( Saig_ManRegNum(p) ); + assert( Saig_ManPiNum(p) ); + assert( Saig_ManPoNum(p) ); + // perform terminary simulation + pTsi = Saig_ManReachableTernary( p, vInits, 0 ); + if ( pTsi == NULL ) + return 1; + // derive information + nPrefix = Saig_TsiComputePrefix( pTsi, (unsigned *)Vec_PtrEntryLast(pTsi->vStates), pTsi->nWords ); + nFrames = Vec_PtrSize(pTsi->vStates) - 1 - nPrefix; + Saig_TsiStop( pTsi ); + // potentially, may need to reduce nFrames if nPrefix is less than nFrames + return nFrames; +} + /**Function************************************************************* Synopsis [Performs automated phase abstraction.] @@ -789,7 +823,7 @@ Aig_Man_t * Saig_ManPhaseAbstract( Aig_Man_t * p, Vec_Int_t * vInits, int nFrame if ( pTsi == NULL ) return NULL; // derive information - pTsi->nPrefix = Saig_TsiComputePrefix( pTsi, Vec_PtrEntryLast(pTsi->vStates), pTsi->nWords ); + pTsi->nPrefix = Saig_TsiComputePrefix( pTsi, (unsigned *)Vec_PtrEntryLast(pTsi->vStates), pTsi->nWords ); pTsi->nCycle = Vec_PtrSize(pTsi->vStates) - 1 - pTsi->nPrefix; pTsi->nNonXRegs = Saig_TsiCountNonXValuedRegisters(pTsi, pTsi->nWords, ABC_MIN(pTsi->nPrefix,nPref)); // print statistics @@ -845,7 +879,7 @@ Aig_Man_t * Saig_ManPhaseAbstractAuto( Aig_Man_t * p, int fVerbose ) if ( pTsi == NULL ) return NULL; // derive information - pTsi->nPrefix = Saig_TsiComputePrefix( pTsi, Vec_PtrEntryLast(pTsi->vStates), pTsi->nWords ); + pTsi->nPrefix = Saig_TsiComputePrefix( pTsi, (unsigned *)Vec_PtrEntryLast(pTsi->vStates), pTsi->nWords ); pTsi->nCycle = Vec_PtrSize(pTsi->vStates) - 1 - pTsi->nPrefix; pTsi->nNonXRegs = Saig_TsiCountNonXValuedRegisters(pTsi, pTsi->nWords, 0); // print statistics @@ -903,3 +937,5 @@ Aig_Man_t * Saig_ManPhaseAbstractAuto( Aig_Man_t * p, int fVerbose ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigRetFwd.c b/src/aig/saig/saigRetFwd.c index 8178d26e..94d08aaf 100644 --- a/src/aig/saig/saigRetFwd.c +++ b/src/aig/saig/saigRetFwd.c @@ -20,6 +20,9 @@ #include "saig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -240,3 +243,5 @@ Aig_Man_t * Saig_ManRetimeForward( Aig_Man_t * p, int nMaxIters, int fVerbose ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigRetMin.c b/src/aig/saig/saigRetMin.c index b9204f44..cce7dcc6 100644 --- a/src/aig/saig/saigRetMin.c +++ b/src/aig/saig/saigRetMin.c @@ -20,16 +20,18 @@ #include "saig.h" +#include "nwk.h" #include "cnf.h" #include "satSolver.h" #include "satStore.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -extern Vec_Ptr_t * Nwk_ManDeriveRetimingCut( Aig_Man_t * p, int fForward, int fVerbose ); - //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -55,7 +57,7 @@ Vec_Int_t * Saig_ManRetimeInitState( Aig_Man_t * p ) int i, RetValue, * pModel; // solve the SAT problem pCnf = Cnf_DeriveSimpleForRetiming( p ); - pSat = Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); + pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); if ( pSat == NULL ) { Cnf_DataFree( pCnf ); @@ -126,9 +128,9 @@ int Saig_ManRetimeUnsatCore( Aig_Man_t * p, int fVerbose ) sat_solver_delete( pSat ); // derive the UNSAT core pManProof = Intp_ManAlloc(); - vCore = Intp_ManUnsatCore( pManProof, pSatCnf, fVeryVerbose ); + vCore = (Vec_Int_t *)Intp_ManUnsatCore( pManProof, (Sto_Man_t *)pSatCnf, fVeryVerbose ); Intp_ManFree( pManProof ); - Sto_ManFree( pSatCnf ); + Sto_ManFree( (Sto_Man_t *)pSatCnf ); // derive the set of variables on which the core depends // collect the variable numbers nVars = 0; @@ -216,7 +218,7 @@ int Saig_ManRetimeCountCut( Aig_Man_t * p, Vec_Ptr_t * vCut ) int i, RetValue; // mark the cones Aig_ManIncrementTravId( p ); - Vec_PtrForEachEntry( vCut, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vCut, pObj, i ) Saig_ManMarkCone_rec( p, pObj ); // collect the new cut vNodes = Vec_PtrAlloc( 1000 ); @@ -237,7 +239,7 @@ int Saig_ManRetimeCountCut( Aig_Man_t * p, Vec_Ptr_t * vCut ) pFanin->fMarkA = 1; } } - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) pObj->fMarkA = 0; RetValue = Vec_PtrSize( vNodes ); Vec_PtrFree( vNodes ); @@ -296,7 +298,7 @@ Aig_Man_t * Saig_ManRetimeDupForward( Aig_Man_t * p, Vec_Ptr_t * vCut ) Saig_ManForEachPi( p, pObj, i ) pObj->pData = Aig_ObjCreatePi( pNew ); // create the registers - Vec_PtrForEachEntry( vCut, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vCut, pObj, i ) pObj->pData = Aig_NotCond( Aig_ObjCreatePi(pNew), pObj->fPhase ); // duplicate logic above the cut Aig_ManForEachPo( p, pObj, i ) @@ -311,14 +313,14 @@ Aig_Man_t * Saig_ManRetimeDupForward( Aig_Man_t * p, Vec_Ptr_t * vCut ) Saig_ManForEachLiLo( p, pObjLi, pObjLo, i ) pObjLo->pData = pObjLi->pData; // erase the data values on the internal nodes of the cut - Vec_PtrForEachEntry( vCut, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vCut, pObj, i ) if ( Aig_ObjIsNode(pObj) ) pObj->pData = NULL; // duplicate logic below the cut - Vec_PtrForEachEntry( vCut, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vCut, pObj, i ) { Saig_ManRetimeDup_rec( pNew, pObj ); - Aig_ObjCreatePo( pNew, Aig_NotCond(pObj->pData, pObj->fPhase) ); + Aig_ObjCreatePo( pNew, Aig_NotCond((Aig_Obj_t *)pObj->pData, pObj->fPhase) ); } Aig_ManCleanup( pNew ); return pNew; @@ -355,7 +357,7 @@ Aig_Man_t * Saig_ManRetimeDupBackward( Aig_Man_t * p, Vec_Ptr_t * vCut, Vec_Int_ Saig_ManForEachPi( p, pObj, i ) pObj->pData = Aig_ObjCreatePi( pNew ); // create the registers - Vec_PtrForEachEntry( vCut, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vCut, pObj, i ) pObj->pData = Aig_NotCond( Aig_ObjCreatePi(pNew), vInit?Vec_IntEntry(vInit,i):0 ); // duplicate logic above the cut and remember values Saig_ManForEachLi( p, pObj, i ) @@ -367,7 +369,7 @@ Aig_Man_t * Saig_ManRetimeDupBackward( Aig_Man_t * p, Vec_Ptr_t * vCut, Vec_Int_ Saig_ManForEachLiLo( p, pObjLi, pObjLo, i ) pObjLo->pData = pObjLi->pData; // erase the data values on the internal nodes of the cut - Vec_PtrForEachEntry( vCut, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vCut, pObj, i ) if ( Aig_ObjIsNode(pObj) ) pObj->pData = NULL; // replicate the data on the constant node and the PIs @@ -381,10 +383,10 @@ Aig_Man_t * Saig_ManRetimeDupBackward( Aig_Man_t * p, Vec_Ptr_t * vCut, Vec_Int_ Saig_ManRetimeDup_rec( pNew, Aig_ObjFanin0(pObj) ); Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) ); } - Vec_PtrForEachEntry( vCut, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vCut, pObj, i ) { Saig_ManRetimeDup_rec( pNew, pObj ); - Aig_ObjCreatePo( pNew, Aig_NotCond(pObj->pData, vInit?Vec_IntEntry(vInit,i):0) ); + Aig_ObjCreatePo( pNew, Aig_NotCond((Aig_Obj_t *)pObj->pData, vInit?Vec_IntEntry(vInit,i):0) ); } Aig_ManCleanup( pNew ); return pNew; @@ -414,7 +416,7 @@ Aig_Man_t * Saig_ManRetimeDupInitState( Aig_Man_t * p, Vec_Ptr_t * vCut ) Aig_ManCleanData( p ); Aig_ManConst1(p)->pData = Aig_ManConst1(pNew); // create the registers - Vec_PtrForEachEntry( vCut, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vCut, pObj, i ) pObj->pData = Aig_ObjCreatePi(pNew); // duplicate logic above the cut and create POs Saig_ManForEachLi( p, pObj, i ) @@ -503,7 +505,7 @@ int Saig_ManHideBadRegs( Aig_Man_t * p, Vec_Ptr_t * vBadRegs ) nTruePo = Aig_ManPoNum(p) - Aig_ManRegNum(p); assert( nTruePi == p->nTruePis ); assert( nTruePo == p->nTruePos ); - Vec_PtrForEachEntry( vBadRegs, pObjLi, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vBadRegs, pObjLi, i ) { Vec_PtrWriteEntry( vPisNew, nTruePi++, pObjLi->pData ); Vec_PtrWriteEntry( vPosNew, nTruePo++, pObjLi ); @@ -699,3 +701,5 @@ Aig_Man_t * Saig_ManRetimeMinArea( Aig_Man_t * p, int nMaxIters, int fForwardOnl //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigRetStep.c b/src/aig/saig/saigRetStep.c index e2502761..aa1ae8a4 100644 --- a/src/aig/saig/saigRetStep.c +++ b/src/aig/saig/saigRetStep.c @@ -20,6 +20,9 @@ #include "saig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -229,3 +232,5 @@ int Saig_ManRetimeSteps( Aig_Man_t * p, int nSteps, int fForward, int fAddBugs ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigScl.c b/src/aig/saig/saigScl.c index 6d55943a..4b0a3102 100644 --- a/src/aig/saig/saigScl.c +++ b/src/aig/saig/saigScl.c @@ -20,6 +20,9 @@ #include "saig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -108,3 +111,5 @@ int Saig_ManReportComplements( Aig_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigSimExt.c b/src/aig/saig/saigSimExt.c index 22d5d6b8..9828d17e 100644 --- a/src/aig/saig/saigSimExt.c +++ b/src/aig/saig/saigSimExt.c @@ -21,6 +21,9 @@ #include "saig.h" #include "ssw.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -49,13 +52,13 @@ static inline int Saig_ManSimInfoAnd( int Value0, int Value1 ) static inline int Saig_ManSimInfoGet( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame ) { - unsigned * pInfo = Vec_PtrEntry( vSimInfo, Aig_ObjId(pObj) ); + unsigned * pInfo = (unsigned *)Vec_PtrEntry( vSimInfo, Aig_ObjId(pObj) ); return 3 & (pInfo[iFrame >> 4] >> ((iFrame & 15) << 1)); } static inline void Saig_ManSimInfoSet( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame, int Value ) { - unsigned * pInfo = Vec_PtrEntry( vSimInfo, Aig_ObjId(pObj) ); + unsigned * pInfo = (unsigned *)Vec_PtrEntry( vSimInfo, Aig_ObjId(pObj) ); assert( Value >= SAIG_ZER && Value <= SAIG_UND ); Value ^= Saig_ManSimInfoGet( vSimInfo, pObj, iFrame ); pInfo[iFrame >> 4] ^= (Value << ((iFrame & 15) << 1)); @@ -107,7 +110,7 @@ int Saig_ManExtendOneEval( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame ) SeeAlso [] ***********************************************************************/ -int Saig_ManSimDataInit( Aig_Man_t * p, Ssw_Cex_t * pCex, Vec_Ptr_t * vSimInfo, Vec_Int_t * vRes ) +int Saig_ManSimDataInit( Aig_Man_t * p, Abc_Cex_t * pCex, Vec_Ptr_t * vSimInfo, Vec_Int_t * vRes ) { Aig_Obj_t * pObj, * pObjLi, * pObjLo; int i, f, Entry, iBit = 0; @@ -146,7 +149,7 @@ int Saig_ManSimDataInit( Aig_Man_t * p, Ssw_Cex_t * pCex, Vec_Ptr_t * vSimInfo, SeeAlso [] ***********************************************************************/ -int Saig_ManExtendOne( Aig_Man_t * p, Ssw_Cex_t * pCex, Vec_Ptr_t * vSimInfo, +int Saig_ManExtendOne( Aig_Man_t * p, Abc_Cex_t * pCex, Vec_Ptr_t * vSimInfo, int iPi, int iFrame, Vec_Int_t * vUndo, Vec_Int_t * vVis, Vec_Int_t * vVis2 ) { Aig_Obj_t * pFanout, * pObj = Aig_ManPi(p, iPi); @@ -247,7 +250,7 @@ void Saig_ManExtendUndo( Aig_Man_t * p, Vec_Ptr_t * vSimInfo, Vec_Int_t * vUndo SeeAlso [] ***********************************************************************/ -Vec_Int_t * Saig_ManExtendCounterExample( Aig_Man_t * p, int iFirstFlopPi, Ssw_Cex_t * pCex, Vec_Ptr_t * vSimInfo, int fVerbose ) +Vec_Int_t * Saig_ManExtendCounterExample0( Aig_Man_t * p, int iFirstFlopPi, Abc_Cex_t * pCex, Vec_Ptr_t * vSimInfo, int fVerbose ) { Vec_Int_t * vRes, * vResInv, * vUndo, * vVis, * vVis2; int i, f, Value; @@ -297,14 +300,244 @@ Vec_Int_t * Saig_ManExtendCounterExample( Aig_Man_t * p, int iFirstFlopPi, Ssw_C SeeAlso [] ***********************************************************************/ -Vec_Int_t * Saig_ManExtendCounterExampleTest( Aig_Man_t * p, int iFirstFlopPi, Ssw_Cex_t * pCex, int fVerbose ) +Vec_Int_t * Saig_ManExtendCounterExample1( Aig_Man_t * p, int iFirstFlopPi, Abc_Cex_t * pCex, Vec_Ptr_t * vSimInfo, int fVerbose ) +{ + Vec_Int_t * vRes, * vResInv, * vUndo, * vVis, * vVis2; + int i, f, Value; +// assert( Aig_ManRegNum(p) > 0 ); + assert( (unsigned *)Vec_PtrEntry(vSimInfo,1) - (unsigned *)Vec_PtrEntry(vSimInfo,0) >= Aig_BitWordNum(2*(pCex->iFrame+1)) ); + // start simulation data + Value = Saig_ManSimDataInit( p, pCex, vSimInfo, NULL ); + assert( Value == SAIG_ONE ); + // select the result + vRes = Vec_IntAlloc( 1000 ); + vResInv = Vec_IntAlloc( 1000 ); + vVis = Vec_IntAlloc( 1000 ); + vVis2 = Vec_IntAlloc( 1000 ); + vUndo = Vec_IntAlloc( 1000 ); + for ( i = Saig_ManPiNum(p) - 1; i >= iFirstFlopPi; i-- ) + { + Vec_IntClear( vUndo ); + for ( f = pCex->iFrame; f >= 0; f-- ) + if ( !Saig_ManExtendOne( p, pCex, vSimInfo, i, f, vUndo, vVis, vVis2 ) ) + { + Saig_ManExtendUndo( p, vSimInfo, vUndo ); + break; + } + if ( f >= 0 ) + Vec_IntPush( vRes, i ); + else + Vec_IntPush( vResInv, i ); + } + Vec_IntFree( vVis ); + Vec_IntFree( vVis2 ); + Vec_IntFree( vUndo ); + // resimulate to make sure it is valid + Value = Saig_ManSimDataInit( p, pCex, vSimInfo, vResInv ); + assert( Value == SAIG_ONE ); + Vec_IntFree( vResInv ); + return vRes; +} + +/**Function************************************************************* + + Synopsis [Returns the array of PIs for flops that should not be absracted.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Saig_ManExtendCounterExample2( Aig_Man_t * p, int iFirstFlopPi, Abc_Cex_t * pCex, Vec_Ptr_t * vSimInfo, int fVerbose ) +{ + Vec_Int_t * vRes, * vResInv, * vUndo, * vVis, * vVis2; + int i, f, Value; +// assert( Aig_ManRegNum(p) > 0 ); + assert( (unsigned *)Vec_PtrEntry(vSimInfo,1) - (unsigned *)Vec_PtrEntry(vSimInfo,0) >= Aig_BitWordNum(2*(pCex->iFrame+1)) ); + // start simulation data + Value = Saig_ManSimDataInit( p, pCex, vSimInfo, NULL ); + assert( Value == SAIG_ONE ); + // select the result + vRes = Vec_IntAlloc( 1000 ); + vResInv = Vec_IntAlloc( 1000 ); + vVis = Vec_IntAlloc( 1000 ); + vVis2 = Vec_IntAlloc( 1000 ); + vUndo = Vec_IntAlloc( 1000 ); + for ( i = iFirstFlopPi; i < Saig_ManPiNum(p); i++ ) + { + if ( i % 2 == 0 ) + continue; + Vec_IntClear( vUndo ); + for ( f = pCex->iFrame; f >= 0; f-- ) + if ( !Saig_ManExtendOne( p, pCex, vSimInfo, i, f, vUndo, vVis, vVis2 ) ) + { + Saig_ManExtendUndo( p, vSimInfo, vUndo ); + break; + } + if ( f >= 0 ) + Vec_IntPush( vRes, i ); + else + Vec_IntPush( vResInv, i ); + } + for ( i = iFirstFlopPi; i < Saig_ManPiNum(p); i++ ) + { + if ( i % 2 == 1 ) + continue; + Vec_IntClear( vUndo ); + for ( f = pCex->iFrame; f >= 0; f-- ) + if ( !Saig_ManExtendOne( p, pCex, vSimInfo, i, f, vUndo, vVis, vVis2 ) ) + { + Saig_ManExtendUndo( p, vSimInfo, vUndo ); + break; + } + if ( f >= 0 ) + Vec_IntPush( vRes, i ); + else + Vec_IntPush( vResInv, i ); + } + Vec_IntFree( vVis ); + Vec_IntFree( vVis2 ); + Vec_IntFree( vUndo ); + // resimulate to make sure it is valid + Value = Saig_ManSimDataInit( p, pCex, vSimInfo, vResInv ); + assert( Value == SAIG_ONE ); + Vec_IntFree( vResInv ); + return vRes; +} + +/**Function************************************************************* + + Synopsis [Returns the array of PIs for flops that should not be absracted.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Saig_ManExtendCounterExample3( Aig_Man_t * p, int iFirstFlopPi, Abc_Cex_t * pCex, Vec_Ptr_t * vSimInfo, int fVerbose ) +{ + Vec_Int_t * vRes, * vResInv, * vUndo, * vVis, * vVis2; + int i, f, Value; +// assert( Aig_ManRegNum(p) > 0 ); + assert( (unsigned *)Vec_PtrEntry(vSimInfo,1) - (unsigned *)Vec_PtrEntry(vSimInfo,0) >= Aig_BitWordNum(2*(pCex->iFrame+1)) ); + // start simulation data + Value = Saig_ManSimDataInit( p, pCex, vSimInfo, NULL ); + assert( Value == SAIG_ONE ); + // select the result + vRes = Vec_IntAlloc( 1000 ); + vResInv = Vec_IntAlloc( 1000 ); + vVis = Vec_IntAlloc( 1000 ); + vVis2 = Vec_IntAlloc( 1000 ); + vUndo = Vec_IntAlloc( 1000 ); + for ( i = Saig_ManPiNum(p) - 1; i >= iFirstFlopPi; i-- ) + { + if ( i % 2 == 0 ) + continue; + Vec_IntClear( vUndo ); + for ( f = pCex->iFrame; f >= 0; f-- ) + if ( !Saig_ManExtendOne( p, pCex, vSimInfo, i, f, vUndo, vVis, vVis2 ) ) + { + Saig_ManExtendUndo( p, vSimInfo, vUndo ); + break; + } + if ( f >= 0 ) + Vec_IntPush( vRes, i ); + else + Vec_IntPush( vResInv, i ); + } + for ( i = Saig_ManPiNum(p) - 1; i >= iFirstFlopPi; i-- ) + { + if ( i % 2 == 1 ) + continue; + Vec_IntClear( vUndo ); + for ( f = pCex->iFrame; f >= 0; f-- ) + if ( !Saig_ManExtendOne( p, pCex, vSimInfo, i, f, vUndo, vVis, vVis2 ) ) + { + Saig_ManExtendUndo( p, vSimInfo, vUndo ); + break; + } + if ( f >= 0 ) + Vec_IntPush( vRes, i ); + else + Vec_IntPush( vResInv, i ); + } + Vec_IntFree( vVis ); + Vec_IntFree( vVis2 ); + Vec_IntFree( vUndo ); + // resimulate to make sure it is valid + Value = Saig_ManSimDataInit( p, pCex, vSimInfo, vResInv ); + assert( Value == SAIG_ONE ); + Vec_IntFree( vResInv ); + return vRes; +} + +/**Function************************************************************* + + Synopsis [Returns the array of PIs for flops that should not be absracted.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Saig_ManExtendCounterExample( Aig_Man_t * p, int iFirstFlopPi, Abc_Cex_t * pCex, Vec_Ptr_t * vSimInfo, int fVerbose ) +{ + Vec_Int_t * vRes0 = Saig_ManExtendCounterExample0( p, iFirstFlopPi, pCex, vSimInfo, fVerbose ); + Vec_Int_t * vRes1 = Saig_ManExtendCounterExample1( p, iFirstFlopPi, pCex, vSimInfo, fVerbose ); + Vec_Int_t * vRes2 = Saig_ManExtendCounterExample2( p, iFirstFlopPi, pCex, vSimInfo, fVerbose ); + Vec_Int_t * vRes3 = Saig_ManExtendCounterExample3( p, iFirstFlopPi, pCex, vSimInfo, fVerbose ); + Vec_Int_t * vRes = vRes0; +// if ( fVerbose ) + printf( "Removable flops: Order0 =%3d. Order1 =%3d. Order2 =%3d. Order3 =%3d.\n", + Vec_IntSize(vRes0), Vec_IntSize(vRes1), Vec_IntSize(vRes2), Vec_IntSize(vRes3) ); + if ( Vec_IntSize(vRes1) < Vec_IntSize(vRes) ) + vRes = vRes1; + if ( Vec_IntSize(vRes2) < Vec_IntSize(vRes) ) + vRes = vRes2; + if ( Vec_IntSize(vRes3) < Vec_IntSize(vRes) ) + vRes = vRes3; + vRes = Vec_IntDup( vRes ); + Vec_IntFree( vRes0 ); + Vec_IntFree( vRes1 ); + Vec_IntFree( vRes2 ); + Vec_IntFree( vRes3 ); + return vRes; +} + +/**Function************************************************************* + + Synopsis [Returns the array of PIs for flops that should not be absracted.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Saig_ManExtendCounterExampleTest( Aig_Man_t * p, int iFirstFlopPi, Abc_Cex_t * pCex, int fVerbose ) { Vec_Int_t * vRes; Vec_Ptr_t * vSimInfo; int clk; + if ( Saig_ManPiNum(p) != pCex->nPis ) + { + printf( "Saig_ManExtendCounterExampleTest(): The PI count of AIG (%d) does not match that of cex (%d).\n", + Aig_ManPiNum(p), pCex->nPis ); + return NULL; + } Aig_ManFanoutStart( p ); vSimInfo = Vec_PtrAllocSimInfo( Aig_ManObjNumMax(p), Aig_BitWordNum(2*(pCex->iFrame+1)) ); + Vec_PtrCleanSimInfo( vSimInfo, 0, Aig_BitWordNum(2*(pCex->iFrame+1)) ); + clk = clock(); +// vRes = Saig_ManExtendCounterExample0( p, iFirstFlopPi, pCex, vSimInfo, fVerbose ); vRes = Saig_ManExtendCounterExample( p, iFirstFlopPi, pCex, vSimInfo, fVerbose ); if ( fVerbose ) { @@ -314,8 +547,6 @@ ABC_PRT( "Time", clock() - clk ); Vec_PtrFree( vSimInfo ); Aig_ManFanoutStop( p ); return vRes; -// Vec_IntFree( vRes ); -// return NULL; } //////////////////////////////////////////////////////////////////////// @@ -323,3 +554,5 @@ ABC_PRT( "Time", clock() - clk ); //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigSimFast.c b/src/aig/saig/saigSimFast.c index 05f77f8a..1840eaa7 100644 --- a/src/aig/saig/saigSimFast.c +++ b/src/aig/saig/saigSimFast.c @@ -20,6 +20,11 @@ #include "saig.h" +#include "main.h" + +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -247,7 +252,7 @@ static inline unsigned Faig_SimulateTransferShift( unsigned uOld, unsigned uNew ***********************************************************************/ int * Faig_ManSimulateFrames( Faig_Man_t * p, int nFrames, int nPref, int fTrans ) { - int * pNumOnes = ABC_CALLOC( unsigned, p->nObjs ); + int * pNumOnes = ABC_CALLOC( int, p->nObjs ); unsigned * pSimInfo = ABC_ALLOC( unsigned, p->nObjs ); int f, i; //printf( "Allocating %7.2f Mb.\n", 1.0 * 4 * p->nObjs/(1<<20) ); @@ -338,7 +343,6 @@ float Faig_ManComputeProbOne( int nOnes, int nSimWords ) ***********************************************************************/ Vec_Int_t * Faig_ManComputeSwitchProbs4( Aig_Man_t * p, int nFrames, int nPref, int fProbOne ) { - extern char * Abc_FrameReadFlag( char * pFlag ); int fTrans = 1; Faig_Man_t * pAig; Vec_Int_t * vSwitching; @@ -442,3 +446,5 @@ Vec_Int_t * Saig_ManComputeSwitchProb3s( Aig_Man_t * p, int nFrames, int nPref, //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigSimMv.c b/src/aig/saig/saigSimMv.c index a3fdaf93..90c6cb33 100644 --- a/src/aig/saig/saigSimMv.c +++ b/src/aig/saig/saigSimMv.c @@ -20,6 +20,9 @@ #include "saig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -61,7 +64,7 @@ struct Saig_MvMan_t_ Saig_MvObj_t * pAigOld; // AIG objects Vec_Ptr_t * vFlops; // collected flops Vec_Ptr_t * vTired; // collected flops - int * pTStates; // hash table for states + unsigned * pTStates; // hash table for states int nTStatesSize; // hash table size Aig_MmFixed_t * pMemStates; // memory for states Vec_Ptr_t * vStates; // reached states @@ -213,7 +216,7 @@ Saig_MvMan_t * Saig_MvManStart( Aig_Man_t * pAig ) // compacted AIG p->pAigOld = Saig_ManCreateReducedAig( pAig, &p->vFlops ); p->nTStatesSize = Aig_PrimeCudd( p->nStatesMax ); - p->pTStates = ABC_CALLOC( int, p->nTStatesSize ); + p->pTStates = ABC_CALLOC( unsigned, p->nTStatesSize ); p->pMemStates = Aig_MmFixedStart( sizeof(int) * (p->nFlops+1), p->nStatesMax ); p->vStates = Vec_PtrAlloc( p->nStatesMax ); Vec_PtrPush( p->vStates, NULL ); @@ -422,7 +425,7 @@ printf( "%d = %d%s * %d%s --> %d\n", pEntry - p->pAigOld, assert( 0 ); } Vec_PtrClear( p->vTired ); - Vec_PtrForEachEntry( p->vFlops, pEntry, i ) + Vec_PtrForEachEntry( Saig_MvObj_t *, p->vFlops, pEntry, i ) { NewValue = Saig_MvSimulateValue0(p->pAigOld, pEntry); if ( NewValue != (int)pEntry->Value ) @@ -451,7 +454,7 @@ printf( "\n" ); SeeAlso [] ***********************************************************************/ -int Saig_MvSimHash( int * pState, int nFlops, int TableSize ) +int Saig_MvSimHash( unsigned * pState, int nFlops, int TableSize ) { static int s_SPrimes[128] = { 1009, 1049, 1093, 1151, 1201, 1249, 1297, 1361, 1427, 1459, @@ -486,12 +489,12 @@ int Saig_MvSimHash( int * pState, int nFlops, int TableSize ) SeeAlso [] ***********************************************************************/ -static inline int * Saig_MvSimTableFind( Saig_MvMan_t * p, int * pState ) +static inline unsigned * Saig_MvSimTableFind( Saig_MvMan_t * p, unsigned * pState ) { - int * pEntry; - int * pPlace = p->pTStates + Saig_MvSimHash( pState+1, p->nFlops, p->nTStatesSize ); - for ( pEntry = (*pPlace)? Vec_PtrEntry(p->vStates, *pPlace) : NULL; pEntry; - pPlace = pEntry, pEntry = (*pPlace)? Vec_PtrEntry(p->vStates, *pPlace) : NULL ) + unsigned * pEntry; + unsigned * pPlace = p->pTStates + Saig_MvSimHash( pState+1, p->nFlops, p->nTStatesSize ); + for ( pEntry = (*pPlace)? (unsigned *)Vec_PtrEntry(p->vStates, *pPlace) : NULL; pEntry; + pPlace = pEntry, pEntry = (*pPlace)? (unsigned *)Vec_PtrEntry(p->vStates, *pPlace) : NULL ) if ( memcmp( pEntry+1, pState+1, sizeof(int)*p->nFlops ) == 0 ) break; return pPlace; @@ -511,12 +514,13 @@ static inline int * Saig_MvSimTableFind( Saig_MvMan_t * p, int * pState ) int Saig_MvSaveState( Saig_MvMan_t * p, int * piReg ) { Saig_MvObj_t * pEntry; - int i, k, * pState, * pPlace, nMaxUndefs = 0; + unsigned * pState, * pPlace; + int i, k, nMaxUndefs = 0; int iTimesOld, iTimesNew; *piReg = -1; - pState = (int *)Aig_MmFixedEntryFetch( p->pMemStates ); + pState = (unsigned *)Aig_MmFixedEntryFetch( p->pMemStates ); pState[0] = 0; - Vec_PtrForEachEntry( p->vFlops, pEntry, i ) + Vec_PtrForEachEntry( Saig_MvObj_t *, p->vFlops, pEntry, i ) { iTimesOld = p->nRegsValues[i]; // count the number of different def values @@ -585,21 +589,22 @@ int Saig_MvSaveState( Saig_MvMan_t * p, int * piReg ) void Saig_MvManPostProcess( Saig_MvMan_t * p, int iState ) { Saig_MvObj_t * pEntry; - int i, k, j, nTotal = 0, * pState, Counter = 0, iFlop; + unsigned * pState; + int i, k, j, nTotal = 0, Counter = 0, iFlop; Vec_Int_t * vUniques = Vec_IntAlloc( 100 ); Vec_Int_t * vCounter = Vec_IntAlloc( 100 ); // count registers that never became undef - Vec_PtrForEachEntry( p->vFlops, pEntry, i ) + Vec_PtrForEachEntry( Saig_MvObj_t *, p->vFlops, pEntry, i ) if ( p->pRegsUndef[i] == 0 ) nTotal++; printf( "The number of registers that never became undef = %d. (Total = %d.)\n", nTotal, p->nFlops ); - Vec_PtrForEachEntry( p->vFlops, pEntry, i ) + Vec_PtrForEachEntry( Saig_MvObj_t *, p->vFlops, pEntry, i ) { if ( p->pRegsUndef[i] ) continue; Vec_IntForEachEntry( vUniques, iFlop, k ) { - Vec_PtrForEachEntryStart( p->vStates, pState, j, 1 ) + Vec_PtrForEachEntryStart( unsigned *, p->vStates, pState, j, 1 ) if ( pState[iFlop+1] != pState[i+1] ) break; if ( j == Vec_PtrSize(p->vStates) ) @@ -625,7 +630,7 @@ void Saig_MvManPostProcess( Saig_MvMan_t * p, int iState ) printf( "%d ", p->pRegsValues[iFlop][k] ); printf( "\n" ); */ - Vec_PtrForEachEntryStart( p->vStates, pState, k, 1 ) + Vec_PtrForEachEntryStart( unsigned *, p->vStates, pState, k, 1 ) { if ( k == iState+1 ) printf( " # " ); @@ -664,7 +669,7 @@ int Saig_MvManSimulate( Aig_Man_t * pAig, int fVerbose ) ABC_PRT( "Constructing the problem", clock() - clk ); clk = clock(); // initiliaze registers - Vec_PtrForEachEntry( p->vFlops, pEntry, i ) + Vec_PtrForEachEntry( Saig_MvObj_t *, p->vFlops, pEntry, i ) { pEntry->Value = Saig_MvConst0(); if ( pEntry->iFan0 == 1 ) @@ -706,7 +711,7 @@ ABC_PRT( "Constructing the problem", clock() - clk ); printf( "Retiring flop %d.\n", iRegMax ); */ // printf( "Retiring %d flops.\n", Vec_PtrSize(p->vTired) ); - Vec_PtrForEachEntry( p->vTired, pEntry, k ) + Vec_PtrForEachEntry( Saig_MvObj_t *, p->vTired, pEntry, k ) pEntry->Value = Saig_MvUndef(); } } @@ -724,3 +729,5 @@ ABC_PRT( "Multi-value simulation", clock() - clk ); //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigSimSeq.c b/src/aig/saig/saigSimSeq.c index c527b152..37bb12b5 100644 --- a/src/aig/saig/saigSimSeq.c +++ b/src/aig/saig/saigSimSeq.c @@ -21,6 +21,9 @@ #include "saig.h" #include "ssw.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -52,7 +55,7 @@ struct Raig_Man_t_ int nWordsAlloc; // the number of allocated entries int nMems; // the number of used entries int nMemsMax; // the max number of used entries - int MemFree; // next ABC_FREE entry + int MemFree; // next free entry }; static inline int Raig_Var2Lit( int Var, int fCompl ) { return Var + Var + fCompl; } @@ -228,7 +231,7 @@ unsigned * Raig_ManSimRef( Raig_Man_t * p, int i ) assert( p->pSims[i] == 0 ); if ( p->MemFree == 0 ) { - int * pPlace, Ent; + unsigned * pPlace, Ent; if ( p->nWordsAlloc == 0 ) { assert( p->pMems == NULL ); @@ -238,9 +241,9 @@ unsigned * Raig_ManSimRef( Raig_Man_t * p, int i ) p->nWordsAlloc *= 2; p->pMems = ABC_REALLOC( unsigned, p->pMems, p->nWordsAlloc ); memset( p->pMems, 0xff, sizeof(unsigned) * (p->nWords + 1) ); - pPlace = &p->MemFree; + pPlace = (unsigned *)&p->MemFree; for ( Ent = p->nMems * (p->nWords + 1); - Ent + p->nWords + 1 < p->nWordsAlloc; + Ent + p->nWords + 1 < (unsigned)p->nWordsAlloc; Ent += p->nWords + 1 ) { *pPlace = Ent; @@ -410,9 +413,9 @@ int Raig_ManSimulateRound( Raig_Man_t * p, int fMiter, int fFirst, int * piPat ) SeeAlso [] ***********************************************************************/ -Ssw_Cex_t * Raig_ManGenerateCounter( Aig_Man_t * pAig, int iFrame, int iOut, int nWords, int iPat, Vec_Int_t * vCis2Ids ) +Abc_Cex_t * Raig_ManGenerateCounter( Aig_Man_t * pAig, int iFrame, int iOut, int nWords, int iPat, Vec_Int_t * vCis2Ids ) { - Ssw_Cex_t * p; + Abc_Cex_t * p; unsigned * pData; int f, i, w, iPioId, Counter; p = Ssw_SmlAllocCounterExample( Aig_ManRegNum(pAig), Saig_ManPiNum(pAig), iFrame+1 ); @@ -511,3 +514,5 @@ int Raig_ManSimulate( Aig_Man_t * pAig, int nWords, int nIters, int TimeLimit, i //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigStrSim.c b/src/aig/saig/saigStrSim.c index 9e50c9b6..1d69630f 100644 --- a/src/aig/saig/saigStrSim.c +++ b/src/aig/saig/saigStrSim.c @@ -21,6 +21,9 @@ #include "saig.h" #include "ssw.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -66,7 +69,7 @@ unsigned Saig_StrSimHash( Aig_Obj_t * pObj ) unsigned uHash = 0; int i; assert( SAIG_WORDS <= 128 ); - pSims = pObj->pData; + pSims = (unsigned *)pObj->pData; for ( i = 0; i < SAIG_WORDS; i++ ) uHash ^= pSims[i] * s_SPrimes[i & 0x7F]; return uHash; @@ -85,8 +88,8 @@ unsigned Saig_StrSimHash( Aig_Obj_t * pObj ) ***********************************************************************/ int Saig_StrSimIsEqual( Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 ) { - unsigned * pSims0 = pObj0->pData; - unsigned * pSims1 = pObj1->pData; + unsigned * pSims0 = (unsigned *)pObj0->pData; + unsigned * pSims1 = (unsigned *)pObj1->pData; int i; for ( i = 0; i < SAIG_WORDS; i++ ) if ( pSims0[i] != pSims1[i] ) @@ -107,7 +110,7 @@ int Saig_StrSimIsEqual( Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 ) ***********************************************************************/ int Saig_StrSimIsZero( Aig_Obj_t * pObj ) { - unsigned * pSims = pObj->pData; + unsigned * pSims = (unsigned *)pObj->pData; int i; for ( i = 0; i < SAIG_WORDS; i++ ) if ( pSims[i] != 0 ) @@ -128,7 +131,7 @@ int Saig_StrSimIsZero( Aig_Obj_t * pObj ) ***********************************************************************/ int Saig_StrSimIsOne( Aig_Obj_t * pObj ) { - unsigned * pSims = pObj->pData; + unsigned * pSims = (unsigned *)pObj->pData; int i; for ( i = 0; i < SAIG_WORDS; i++ ) if ( pSims[i] != ~0 ) @@ -149,7 +152,7 @@ int Saig_StrSimIsOne( Aig_Obj_t * pObj ) ***********************************************************************/ void Saig_StrSimAssignRandom( Aig_Obj_t * pObj ) { - unsigned * pSims = pObj->pData; + unsigned * pSims = (unsigned *)pObj->pData; int i; for ( i = 0; i < SAIG_WORDS; i++ ) pSims[i] = Aig_ManRandom(0); @@ -168,7 +171,7 @@ void Saig_StrSimAssignRandom( Aig_Obj_t * pObj ) ***********************************************************************/ void Saig_StrSimAssignOne( Aig_Obj_t * pObj ) { - unsigned * pSims = pObj->pData; + unsigned * pSims = (unsigned *)pObj->pData; int i; for ( i = 0; i < SAIG_WORDS; i++ ) pSims[i] = ~0; @@ -187,7 +190,7 @@ void Saig_StrSimAssignOne( Aig_Obj_t * pObj ) ***********************************************************************/ void Saig_StrSimAssignZeroInit( Aig_Obj_t * pObj ) { - unsigned * pSims = pObj->pData; + unsigned * pSims = (unsigned *)pObj->pData; pSims[0] = 0; } @@ -204,9 +207,9 @@ void Saig_StrSimAssignZeroInit( Aig_Obj_t * pObj ) ***********************************************************************/ void Saig_StrSimulateNode( Aig_Obj_t * pObj, int i ) { - unsigned * pSims = pObj->pData; - unsigned * pSims0 = Aig_ObjFanin0(pObj)->pData; - unsigned * pSims1 = Aig_ObjFanin1(pObj)->pData; + unsigned * pSims = (unsigned *)pObj->pData; + unsigned * pSims0 = (unsigned *)Aig_ObjFanin0(pObj)->pData; + unsigned * pSims1 = (unsigned *)Aig_ObjFanin1(pObj)->pData; if ( Aig_ObjFaninC0(pObj) && Aig_ObjFaninC1(pObj) ) pSims[i] = ~(pSims0[i] | pSims1[i]); else if ( Aig_ObjFaninC0(pObj) && !Aig_ObjFaninC1(pObj) ) @@ -230,8 +233,8 @@ void Saig_StrSimulateNode( Aig_Obj_t * pObj, int i ) ***********************************************************************/ void Saig_StrSimSaveOutput( Aig_Obj_t * pObj, int i ) { - unsigned * pSims = pObj->pData; - unsigned * pSims0 = Aig_ObjFanin0(pObj)->pData; + unsigned * pSims = (unsigned *)pObj->pData; + unsigned * pSims0 = (unsigned *)Aig_ObjFanin0(pObj)->pData; if ( Aig_ObjFaninC0(pObj) ) pSims[i] = ~pSims0[i]; else @@ -251,8 +254,8 @@ void Saig_StrSimSaveOutput( Aig_Obj_t * pObj, int i ) ***********************************************************************/ void Saig_StrSimTransfer( Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 ) { - unsigned * pSims0 = pObj0->pData; - unsigned * pSims1 = pObj1->pData; + unsigned * pSims0 = (unsigned *)pObj0->pData; + unsigned * pSims1 = (unsigned *)pObj1->pData; int i; for ( i = 0; i < SAIG_WORDS; i++ ) pSims1[i] = pSims0[i]; @@ -271,8 +274,8 @@ void Saig_StrSimTransfer( Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 ) ***********************************************************************/ void Saig_StrSimTransferNext( Aig_Obj_t * pObj0, Aig_Obj_t * pObj1, int i ) { - unsigned * pSims0 = pObj0->pData; - unsigned * pSims1 = pObj1->pData; + unsigned * pSims0 = (unsigned *)pObj0->pData; + unsigned * pSims1 = (unsigned *)pObj1->pData; assert( i < SAIG_WORDS - 1 ); pSims1[i+1] = pSims0[i]; } @@ -520,7 +523,7 @@ void Saig_StrSimPrepareAig( Aig_Man_t * p ) // allocate simulation info p->pData2 = Vec_PtrAllocSimInfo( Aig_ManObjNumMax(p), SAIG_WORDS ); Aig_ManForEachObj( p, pObj, i ) - pObj->pData = Vec_PtrEntry( p->pData2, i ); + pObj->pData = Vec_PtrEntry( (Vec_Ptr_t *)p->pData2, i ); // set simulation info for constant1 and register outputs Saig_StrSimAssignOne( Aig_ManConst1(p) ); Saig_ManForEachLo( p, pObj, i ) @@ -821,7 +824,7 @@ void Ssw_StrSimMatchingExtend( Aig_Man_t * p0, Aig_Man_t * p1, int nDist, int fV { Ssw_StrSimMatchingExtendOne( p0, vNodes0 ); Ssw_StrSimMatchingExtendOne( p1, vNodes1 ); - Vec_PtrForEachEntry( vNodes0, pNext0, k ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes0, pNext0, k ) { pNext1 = Aig_ObjRepr( p0, pNext0 ); if ( pNext1 == NULL ) @@ -832,7 +835,7 @@ void Ssw_StrSimMatchingExtend( Aig_Man_t * p0, Aig_Man_t * p1, int nDist, int fV Aig_ObjSetRepr( p0, pNext0, NULL ); Aig_ObjSetRepr( p1, pNext1, NULL ); } - Vec_PtrForEachEntry( vNodes1, pNext1, k ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes1, pNext1, k ) { pNext0 = Aig_ObjRepr( p1, pNext1 ); if ( pNext0 == NULL ) @@ -932,8 +935,8 @@ Vec_Int_t * Saig_StrSimPerformMatching( Aig_Man_t * p0, Aig_Man_t * p1, int nDis break; } // cleanup - Vec_PtrFree( pPart0->pData2 ); pPart0->pData2 = NULL; - Vec_PtrFree( pPart1->pData2 ); pPart1->pData2 = NULL; + Vec_PtrFree( (Vec_Ptr_t *)pPart0->pData2 ); pPart0->pData2 = NULL; + Vec_PtrFree( (Vec_Ptr_t *)pPart1->pData2 ); pPart1->pData2 = NULL; // extend the islands Aig_ManFanoutStart( pPart0 ); Aig_ManFanoutStart( pPart1 ); @@ -969,3 +972,5 @@ Vec_Int_t * Saig_StrSimPerformMatching( Aig_Man_t * p0, Aig_Man_t * p1, int nDis //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigSwitch.c b/src/aig/saig/saigSwitch.c index 122483d2..bbad9be4 100644 --- a/src/aig/saig/saigSwitch.c +++ b/src/aig/saig/saigSwitch.c @@ -20,6 +20,11 @@ #include "saig.h" +#include "main.h" + +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -260,7 +265,6 @@ float Saig_ManComputeProbOnePlus( int nOnes, int nSimWords, int fCompl ) ***********************************************************************/ Vec_Int_t * Saig_ManComputeSwitchProb4s( Aig_Man_t * p, int nFrames, int nPref, int fProbOne ) { - extern char * Abc_FrameReadFlag( char * pFlag ); Saig_SimObj_t * pAig, * pEntry; Vec_Int_t * vSwitching; float * pSwitching; @@ -564,3 +568,5 @@ Aig_CMan_t * Aig_CManCreate( Aig_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigSynch.c b/src/aig/saig/saigSynch.c index b29fcb9b..00f7517e 100644 --- a/src/aig/saig/saigSynch.c +++ b/src/aig/saig/saigSynch.c @@ -20,6 +20,9 @@ #include "saig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -75,7 +78,7 @@ void Saig_SynchSetConstant1( Aig_Man_t * pAig, Vec_Ptr_t * vSimInfo, int nWords unsigned * pSim; int w; pObj = Aig_ManConst1( pAig ); - pSim = Vec_PtrEntry( vSimInfo, pObj->Id ); + pSim = (unsigned *)Vec_PtrEntry( vSimInfo, pObj->Id ); for ( w = 0; w < nWords; w++ ) pSim[w] = 0x55555555; } @@ -98,7 +101,7 @@ void Saig_SynchInitRegsTernary( Aig_Man_t * pAig, Vec_Ptr_t * vSimInfo, int nWor int i, w; Saig_ManForEachLo( pAig, pObj, i ) { - pSim = Vec_PtrEntry( vSimInfo, pObj->Id ); + pSim = (unsigned *)Vec_PtrEntry( vSimInfo, pObj->Id ); for ( w = 0; w < nWords; w++ ) pSim[w] = 0xffffffff; } @@ -122,7 +125,7 @@ void Saig_SynchInitRegsBinary( Aig_Man_t * pAig, Vec_Ptr_t * vSimInfo, int nWord int i, w; Saig_ManForEachLo( pAig, pObj, i ) { - pSim = Vec_PtrEntry( vSimInfo, pObj->Id ); + pSim = (unsigned *)Vec_PtrEntry( vSimInfo, pObj->Id ); for ( w = 0; w < nWords; w++ ) pSim[w] = Saig_SynchTernary( pObj->fMarkA ); } @@ -146,7 +149,7 @@ void Saig_SynchInitPisRandom( Aig_Man_t * pAig, Vec_Ptr_t * vSimInfo, int nWords int i, w; Saig_ManForEachPi( pAig, pObj, i ) { - pSim = Vec_PtrEntry( vSimInfo, pObj->Id ); + pSim = (unsigned *)Vec_PtrEntry( vSimInfo, pObj->Id ); for ( w = 0; w < nWords; w++ ) pSim[w] = Saig_SynchRandomBinary(); } @@ -170,7 +173,7 @@ void Saig_SynchInitPisGiven( Aig_Man_t * pAig, Vec_Ptr_t * vSimInfo, int nWords, int i, w; Saig_ManForEachPi( pAig, pObj, i ) { - pSim = Vec_PtrEntry( vSimInfo, pObj->Id ); + pSim = (unsigned *)Vec_PtrEntry( vSimInfo, pObj->Id ); for ( w = 0; w < nWords; w++ ) pSim[w] = Saig_SynchTernary( pValues[i] ); } @@ -195,9 +198,9 @@ void Saig_SynchTernarySimulate( Aig_Man_t * pAig, Vec_Ptr_t * vSimInfo, int nWor // simulate nodes Aig_ManForEachNode( pAig, pObj, i ) { - pSim = Vec_PtrEntry( vSimInfo, pObj->Id ); - pSim0 = Vec_PtrEntry( vSimInfo, Aig_ObjFaninId0(pObj) ); - pSim1 = Vec_PtrEntry( vSimInfo, Aig_ObjFaninId1(pObj) ); + pSim = (unsigned *)Vec_PtrEntry( vSimInfo, pObj->Id ); + pSim0 = (unsigned *)Vec_PtrEntry( vSimInfo, Aig_ObjFaninId0(pObj) ); + pSim1 = (unsigned *)Vec_PtrEntry( vSimInfo, Aig_ObjFaninId1(pObj) ); if ( Aig_ObjFaninC0(pObj) && Aig_ObjFaninC1(pObj) ) { for ( w = 0; w < nWords; w++ ) @@ -222,8 +225,8 @@ void Saig_SynchTernarySimulate( Aig_Man_t * pAig, Vec_Ptr_t * vSimInfo, int nWor // transfer values to register inputs Saig_ManForEachLi( pAig, pObj, i ) { - pSim = Vec_PtrEntry( vSimInfo, pObj->Id ); - pSim0 = Vec_PtrEntry( vSimInfo, Aig_ObjFaninId0(pObj) ); + pSim = (unsigned *)Vec_PtrEntry( vSimInfo, pObj->Id ); + pSim0 = (unsigned *)Vec_PtrEntry( vSimInfo, Aig_ObjFaninId0(pObj) ); if ( Aig_ObjFaninC0(pObj) ) { for ( w = 0; w < nWords; w++ ) @@ -255,8 +258,8 @@ void Saig_SynchTernaryTransferState( Aig_Man_t * pAig, Vec_Ptr_t * vSimInfo, int int i, w; Saig_ManForEachLiLo( pAig, pObjLi, pObjLo, i ) { - pSim0 = Vec_PtrEntry( vSimInfo, pObjLi->Id ); - pSim1 = Vec_PtrEntry( vSimInfo, pObjLo->Id ); + pSim0 = (unsigned *)Vec_PtrEntry( vSimInfo, pObjLi->Id ); + pSim1 = (unsigned *)Vec_PtrEntry( vSimInfo, pObjLo->Id ); for ( w = 0; w < nWords; w++ ) pSim1[w] = pSim0[w]; } @@ -283,7 +286,7 @@ int Saig_SynchCountX( Aig_Man_t * pAig, Vec_Ptr_t * vSimInfo, int nWords, int * pCounters = ABC_CALLOC( int, nWords * 16 ); Saig_ManForEachLi( pAig, pObj, i ) { - pSim = Vec_PtrEntry( vSimInfo, pObj->Id ); + pSim = (unsigned *)Vec_PtrEntry( vSimInfo, pObj->Id ); for ( w = 0; w < nWords; w++ ) for ( b = 0; b < 16; b++ ) if ( ((pSim[w] >> (b << 1)) & 3) == 3 ) @@ -324,7 +327,7 @@ int Saig_SynchSavePattern( Aig_Man_t * pAig, Vec_Ptr_t * vSimInfo, int nWords, i assert( iPat < 16 * nWords ); Saig_ManForEachPi( pAig, pObj, i ) { - pSim = Vec_PtrEntry( vSimInfo, pObj->Id ); + pSim = (unsigned *)Vec_PtrEntry( vSimInfo, pObj->Id ); Value = (pSim[iPat>>4] >> ((iPat&0xf) << 1)) & 3; Vec_StrPush( vSequence, (char)Value ); // printf( "%d ", Value ); @@ -333,11 +336,11 @@ int Saig_SynchSavePattern( Aig_Man_t * pAig, Vec_Ptr_t * vSimInfo, int nWords, i Counter = 0; Saig_ManForEachLiLo( pAig, pObjLi, pObjLo, i ) { - pSim = Vec_PtrEntry( vSimInfo, pObjLi->Id ); + pSim = (unsigned *)Vec_PtrEntry( vSimInfo, pObjLi->Id ); Value = (pSim[iPat>>4] >> ((iPat&0xf) << 1)) & 3; Counter += (Value == 3); // save patern in the same register - pSim = Vec_PtrEntry( vSimInfo, pObjLo->Id ); + pSim = (unsigned *)Vec_PtrEntry( vSimInfo, pObjLo->Id ); for ( w = 0; w < nWords; w++ ) pSim[w] = Saig_SynchTernary( Value ); } @@ -377,7 +380,7 @@ int Saig_SynchSequenceRun( Aig_Man_t * pAig, Vec_Ptr_t * vSimInfo, Vec_Str_t * v Counter = 0; Saig_ManForEachLo( pAig, pObj, i ) { - pSim = Vec_PtrEntry( vSimInfo, pObj->Id ); + pSim = (unsigned *)Vec_PtrEntry( vSimInfo, pObj->Id ); Value = pSim[0] & 3; assert( Value != 2 ); Counter += (Value == 3); @@ -656,3 +659,5 @@ Aig_Man_t * Saig_Synchronize( Aig_Man_t * pAig1, Aig_Man_t * pAig2, int nWords, //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigTrans.c b/src/aig/saig/saigTrans.c index a92d9369..09639e27 100644 --- a/src/aig/saig/saigTrans.c +++ b/src/aig/saig/saigTrans.c @@ -19,6 +19,10 @@ ***********************************************************************/ #include "saig.h" +#include "fra.h" + +ABC_NAMESPACE_IMPL_START + /* A similar approach is presented in the his paper: @@ -59,7 +63,7 @@ static inline void Saig_ManStartMap1( Aig_Man_t * p, int nFrames ) static inline void Saig_ManStopMap1( Aig_Man_t * p ) { assert( p->pData != NULL ); - Vec_IntFree( p->pData ); + Vec_IntFree( (Vec_Int_t *)p->pData ); p->pData = NULL; } static inline int Saig_ManHasMap1( Aig_Man_t * p ) @@ -68,7 +72,7 @@ static inline int Saig_ManHasMap1( Aig_Man_t * p ) } static inline void Saig_ManSetMap1( Aig_Man_t * p, Aig_Obj_t * pOld, int f1, Aig_Obj_t * pNew ) { - Vec_Int_t * vMap = p->pData; + Vec_Int_t * vMap = (Vec_Int_t *)p->pData; int nOffset = f1 * Aig_ManObjNumMax(p) + pOld->Id; assert( !Aig_IsComplement(pOld) ); assert( !Aig_IsComplement(pNew) ); @@ -76,7 +80,7 @@ static inline void Saig_ManSetMap1( Aig_Man_t * p, Aig_Obj_t * pOld, int f1, Aig } static inline int Saig_ManGetMap1( Aig_Man_t * p, Aig_Obj_t * pOld, int f1 ) { - Vec_Int_t * vMap = p->pData; + Vec_Int_t * vMap = (Vec_Int_t *)p->pData; int nOffset = f1 * Aig_ManObjNumMax(p) + pOld->Id; return Vec_IntEntry( vMap, nOffset ); } @@ -106,7 +110,7 @@ static inline void Saig_ManStartMap2( Aig_Man_t * p, int nFrames ) static inline void Saig_ManStopMap2( Aig_Man_t * p ) { assert( p->pData2 != NULL ); - Vec_IntFree( p->pData2 ); + Vec_IntFree( (Vec_Int_t *)p->pData2 ); p->pData2 = NULL; } static inline int Saig_ManHasMap2( Aig_Man_t * p ) @@ -115,7 +119,7 @@ static inline int Saig_ManHasMap2( Aig_Man_t * p ) } static inline void Saig_ManSetMap2( Aig_Man_t * p, Aig_Obj_t * pOld, int f1, Aig_Obj_t * pNew, int f2 ) { - Vec_Int_t * vMap = p->pData2; + Vec_Int_t * vMap = (Vec_Int_t *)p->pData2; int nOffset = f1 * Aig_ManObjNumMax(p) + pOld->Id; assert( !Aig_IsComplement(pOld) ); assert( !Aig_IsComplement(pNew) ); @@ -124,7 +128,7 @@ static inline void Saig_ManSetMap2( Aig_Man_t * p, Aig_Obj_t * pOld, int f1, Aig } static inline int Saig_ManGetMap2( Aig_Man_t * p, Aig_Obj_t * pOld, int f1, int * pf2 ) { - Vec_Int_t * vMap = p->pData2; + Vec_Int_t * vMap = (Vec_Int_t *)p->pData2; int nOffset = f1 * Aig_ManObjNumMax(p) + pOld->Id; *pf2 = Vec_IntEntry( vMap, 2*nOffset + 1 ); return Vec_IntEntry( vMap, 2*nOffset ); @@ -222,7 +226,7 @@ Aig_Man_t * Saig_ManFramesNonInitial( Aig_Man_t * pAig, int nFrames ) Aig_ManForEachObj( pAig, pObj, i ) { assert( pObj->pData != NULL ); - Saig_ManSetMap1( pAig, pObj, f, Aig_Regular(pObj->pData) ); + Saig_ManSetMap1( pAig, pObj, f, Aig_Regular((Aig_Obj_t *)pObj->pData) ); } // quit if the last frame if ( f == nFrames - 1 ) @@ -233,7 +237,7 @@ Aig_Man_t * Saig_ManFramesNonInitial( Aig_Man_t * pAig, int nFrames ) } // remember register outputs Saig_ManForEachLiLo( pAig, pObjLi, pObjLo, i ) - Aig_ObjCreatePo( pFrames, pObjLi->pData ); + Aig_ObjCreatePo( pFrames, (Aig_Obj_t *)pObjLi->pData ); Aig_ManCleanup( pFrames ); return pFrames; } @@ -266,7 +270,7 @@ Aig_Man_t * Saig_ManFramesInitialMapped( Aig_Man_t * pAig, int nFrames, int nFra Saig_ManForEachLo( pAig, pObj, i ) { pObj->pData = Aig_ManConst0( pFrames ); - Saig_ManSetMap1( pAig, pObj, 0, Aig_Regular(pObj->pData) ); + Saig_ManSetMap1( pAig, pObj, 0, Aig_Regular((Aig_Obj_t *)pObj->pData) ); } } else @@ -279,7 +283,7 @@ Aig_Man_t * Saig_ManFramesInitialMapped( Aig_Man_t * pAig, int nFrames, int nFra Saig_ManForEachLo( pAig, pObj, i ) { pObj->pData = Aig_ObjCreatePi( pFrames ); - Saig_ManSetMap1( pAig, pObj, 0, Aig_Regular(pObj->pData) ); + Saig_ManSetMap1( pAig, pObj, 0, Aig_Regular((Aig_Obj_t *)pObj->pData) ); } } // add timeframes @@ -288,7 +292,7 @@ Aig_Man_t * Saig_ManFramesInitialMapped( Aig_Man_t * pAig, int nFrames, int nFra // map the constant node pObj = Aig_ManConst1(pAig); pObj->pData = Aig_ManConst1( pFrames ); - Saig_ManSetMap1( pAig, pObj, f, Aig_Regular(pObj->pData) ); + Saig_ManSetMap1( pAig, pObj, f, Aig_Regular((Aig_Obj_t *)pObj->pData) ); // create PI nodes for this frame Saig_ManForEachPi( pAig, pObj, i ) { @@ -296,13 +300,13 @@ Aig_Man_t * Saig_ManFramesInitialMapped( Aig_Man_t * pAig, int nFrames, int nFra pObj->pData = Aig_ObjCreatePi( pFrames ); else pObj->pData = Aig_ManPi( pFrames, f * Saig_ManPiNum(pAig) + i ); - Saig_ManSetMap1( pAig, pObj, f, Aig_Regular(pObj->pData) ); + Saig_ManSetMap1( pAig, pObj, f, Aig_Regular((Aig_Obj_t *)pObj->pData) ); } // add internal nodes of this frame Aig_ManForEachNode( pAig, pObj, i ) { pObj->pData = Aig_And( pFrames, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); - Saig_ManSetMap1( pAig, pObj, f, Aig_Regular(pObj->pData) ); + Saig_ManSetMap1( pAig, pObj, f, Aig_Regular((Aig_Obj_t *)pObj->pData) ); if ( !Saig_ManHasMap2(pAig) ) continue; if ( f < nFrames ) @@ -322,19 +326,19 @@ Aig_Man_t * Saig_ManFramesInitialMapped( Aig_Man_t * pAig, int nFrames, int nFra iNum1 = Saig_ManGetMap1( pAig, Aig_ManObj(pAig, iNum2), iFrame2 ); pRepr = Aig_ManObj( pFrames, iNum1 ); // compare the phases of these nodes - pObj->pData = Aig_NotCond( pRepr, pRepr->fPhase ^ Aig_ObjPhaseReal(pObj->pData) ); + pObj->pData = Aig_NotCond( pRepr, pRepr->fPhase ^ Aig_ObjPhaseReal((Aig_Obj_t *)pObj->pData) ); } // create POs for this frame Saig_ManForEachPo( pAig, pObj, i ) { pObj->pData = Aig_ObjCreatePo( pFrames, Aig_ObjChild0Copy(pObj) ); - Saig_ManSetMap1( pAig, pObj, f, Aig_Regular(pObj->pData) ); + Saig_ManSetMap1( pAig, pObj, f, Aig_Regular((Aig_Obj_t *)pObj->pData) ); } // save register inputs Saig_ManForEachLi( pAig, pObj, i ) { pObj->pData = Aig_ObjChild0Copy(pObj); - Saig_ManSetMap1( pAig, pObj, f, Aig_Regular(pObj->pData) ); + Saig_ManSetMap1( pAig, pObj, f, Aig_Regular((Aig_Obj_t *)pObj->pData) ); } // quit if the last frame if ( f == nFramesMax - 1 ) @@ -344,14 +348,14 @@ Aig_Man_t * Saig_ManFramesInitialMapped( Aig_Man_t * pAig, int nFrames, int nFra { pObjLo->pData = pObjLi->pData; if ( !fInit ) - Saig_ManSetMap1( pAig, pObjLo, f+1, Aig_Regular(pObjLo->pData) ); + Saig_ManSetMap1( pAig, pObjLo, f+1, Aig_Regular((Aig_Obj_t *)pObjLo->pData) ); } } if ( !fInit ) { // create registers Saig_ManForEachLiLo( pAig, pObjLi, pObjLo, i ) - Aig_ObjCreatePo( pFrames, pObjLi->pData ); + Aig_ObjCreatePo( pFrames, (Aig_Obj_t *)pObjLi->pData ); // set register number Aig_ManSetRegNum( pFrames, pAig->nRegs ); } @@ -373,7 +377,7 @@ Aig_Man_t * Saig_ManFramesInitialMapped( Aig_Man_t * pAig, int nFrames, int nFra ***********************************************************************/ Aig_Man_t * Saig_ManTimeframeSimplify( Aig_Man_t * pAig, int nFrames, int nFramesMax, int fInit, int fVerbose ) { - extern Aig_Man_t * Fra_FraigEquivence( Aig_Man_t * pManAig, int nConfMax, int fProve ); +// extern Aig_Man_t * Fra_FraigEquivence( Aig_Man_t * pManAig, int nConfMax, int fProve ); Aig_Man_t * pFrames, * pFraig, * pRes1, * pRes2; int clk; // create uninitialized timeframes with map1 @@ -420,3 +424,5 @@ ABC_PRT( "Normal", clock() - clk ); //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saigWnd.c b/src/aig/saig/saigWnd.c index 10202f1b..eeacb44e 100644 --- a/src/aig/saig/saigWnd.c +++ b/src/aig/saig/saigWnd.c @@ -20,6 +20,9 @@ #include "saig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -103,7 +106,7 @@ Vec_Ptr_t * Saig_ManWindowOutline( Aig_Man_t * p, Aig_Obj_t * pObj, int nDist ) vNodes = Vec_PtrAlloc( 1000 ); Aig_ManIncrementTravId( p ); Saig_ManWindowOutline_rec( p, pObj, nDist, vNodes, pDists ); - Vec_PtrSort( vNodes, Aig_ObjCompareIdIncrease ); + Vec_PtrSort( vNodes, (int (*)(void))Aig_ObjCompareIdIncrease ); // make sure LI/LO are labeled/unlabeled mutually Saig_ManForEachLiLo( p, pObjLi, pObjLo, i ) assert( Aig_ObjIsTravIdCurrent(p, pObjLi) == @@ -150,7 +153,7 @@ Vec_Ptr_t * Saig_ManWindowCollectPis( Aig_Man_t * p, Vec_Ptr_t * vNodes ) Aig_Obj_t * pObj, * pMatch, * pFanin; int i; vNodesPi = Vec_PtrAlloc( 1000 ); - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) { if ( Saig_ObjIsPi(p, pObj) ) { @@ -197,7 +200,7 @@ Vec_Ptr_t * Saig_ManWindowCollectPos( Aig_Man_t * p, Vec_Ptr_t * vNodes, Vec_Ptr vNodesPo = Vec_PtrAlloc( 1000 ); if ( pvPointers ) *pvPointers = Vec_PtrAlloc( 1000 ); - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) { if ( (pPointer = Saig_ObjHasUnlabeledFanout(p, pObj)) ) { @@ -236,29 +239,29 @@ Aig_Man_t * Saig_ManWindowExtractNodes( Aig_Man_t * p, Vec_Ptr_t * vNodes ) pObj->pData = Aig_ManConst1( pNew ); // create real PIs vNodesPi = Saig_ManWindowCollectPis( p, vNodes ); - Vec_PtrForEachEntry( vNodesPi, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodesPi, pObj, i ) pObj->pData = Aig_ObjCreatePi(pNew); Vec_PtrFree( vNodesPi ); // create register outputs - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) { if ( Saig_ObjIsLo(p, pObj) ) pObj->pData = Aig_ObjCreatePi(pNew); } // create internal nodes - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) { if ( Aig_ObjIsNode(pObj) ) pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); } // create POs vNodesPo = Saig_ManWindowCollectPos( p, vNodes, NULL ); - Vec_PtrForEachEntry( vNodesPo, pObj, i ) - Aig_ObjCreatePo( pNew, pObj->pData ); + Vec_PtrForEachEntry( Aig_Obj_t *, vNodesPo, pObj, i ) + Aig_ObjCreatePo( pNew, (Aig_Obj_t *)pObj->pData ); Vec_PtrFree( vNodesPo ); // create register inputs nRegCount = 0; - Vec_PtrForEachEntry( vNodes, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) { if ( Saig_ObjIsLo(p, pObj) ) { @@ -292,7 +295,7 @@ void Saig_ManWindowInsertBig_rec( Aig_Man_t * pNew, Aig_Obj_t * pObjBig, Aig_Obj_t * pMatch; if ( pObjBig->pData ) return; - if ( (pMatch = Vec_PtrEntry( vBigNode2SmallPo, pObjBig->Id )) ) + if ( (pMatch = (Aig_Obj_t *)Vec_PtrEntry( vBigNode2SmallPo, pObjBig->Id )) ) { Saig_ManWindowInsertSmall_rec( pNew, Aig_ObjFanin0(pMatch), vBigNode2SmallPo, vSmallPi2BigNode ); pObjBig->pData = Aig_ObjChild0Copy(pMatch); @@ -321,7 +324,7 @@ void Saig_ManWindowInsertSmall_rec( Aig_Man_t * pNew, Aig_Obj_t * pObjSmall, Aig_Obj_t * pMatch; if ( pObjSmall->pData ) return; - if ( (pMatch = Vec_PtrEntry( vSmallPi2BigNode, pObjSmall->Id )) ) + if ( (pMatch = (Aig_Obj_t *)Vec_PtrEntry( vSmallPi2BigNode, pObjSmall->Id )) ) { Saig_ManWindowInsertBig_rec( pNew, pMatch, vBigNode2SmallPo, vSmallPi2BigNode ); pObjSmall->pData = pMatch->pData; @@ -355,7 +358,7 @@ Aig_Man_t * Saig_ManWindowInsertNodes( Aig_Man_t * p, Vec_Ptr_t * vNodes, Aig_Ma // set mapping of small PIs into big nodes vSmallPi2BigNode = Vec_PtrStart( Aig_ManObjNumMax(pWnd) ); vNodesPi = Saig_ManWindowCollectPis( p, vNodes ); - Vec_PtrForEachEntry( vNodesPi, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodesPi, pObj, i ) Vec_PtrWriteEntry( vSmallPi2BigNode, Aig_ManPi(pWnd, i)->Id, pObj ); assert( i == Saig_ManPiNum(pWnd) ); Vec_PtrFree( vNodesPi ); @@ -363,7 +366,7 @@ Aig_Man_t * Saig_ManWindowInsertNodes( Aig_Man_t * p, Vec_Ptr_t * vNodes, Aig_Ma // set mapping of big nodes into small POs vBigNode2SmallPo = Vec_PtrStart( Aig_ManObjNumMax(p) ); vNodesPo = Saig_ManWindowCollectPos( p, vNodes, NULL ); - Vec_PtrForEachEntry( vNodesPo, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodesPo, pObj, i ) Vec_PtrWriteEntry( vBigNode2SmallPo, pObj->Id, Aig_ManPo(pWnd, i) ); assert( i == Saig_ManPoNum(pWnd) ); Vec_PtrFree( vNodesPo ); @@ -589,7 +592,7 @@ void Saig_ManWindowCreatePis( Aig_Man_t * pNew, Aig_Man_t * p0, Aig_Man_t * p1, { Aig_Obj_t * pObj, * pMatch, * pFanin; int i, Counter = 0; - Vec_PtrForEachEntry( vNodes0, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes0, pObj, i ) { if ( Saig_ObjIsLo(p0, pObj) ) { @@ -667,7 +670,7 @@ void Saig_ManWindowCreatePos( Aig_Man_t * pNew, Aig_Man_t * p0, Aig_Man_t * p1 ) Aig_ObjIsTravIdCurrent(p1, pFanin1) ); if ( Aig_ObjIsTravIdCurrent(p0, pFanin0) ) { - pMiter = Aig_Exor( pNew, pFanin0->pData, pFanin1->pData ); + pMiter = Aig_Exor( pNew, (Aig_Obj_t *)pFanin0->pData, (Aig_Obj_t *)pFanin1->pData ); Aig_ObjCreatePo( pNew, pMiter ); } } @@ -681,7 +684,7 @@ void Saig_ManWindowCreatePos( Aig_Man_t * pNew, Aig_Man_t * p0, Aig_Man_t * p1 ) Aig_ObjIsTravIdCurrent(p1, pFanin1) ); if ( Aig_ObjIsTravIdCurrent(p0, pFanin0) ) { - pMiter = Aig_Exor( pNew, pFanin0->pData, pFanin1->pData ); + pMiter = Aig_Exor( pNew, (Aig_Obj_t *)pFanin0->pData, (Aig_Obj_t *)pFanin1->pData ); Aig_ObjCreatePo( pNew, pMiter ); } @@ -691,7 +694,7 @@ void Saig_ManWindowCreatePos( Aig_Man_t * pNew, Aig_Man_t * p0, Aig_Man_t * p1 ) Aig_ObjIsTravIdCurrent(p1, pFanin1) ); if ( Aig_ObjIsTravIdCurrent(p0, pFanin0) ) { - pMiter = Aig_Exor( pNew, pFanin0->pData, pFanin1->pData ); + pMiter = Aig_Exor( pNew, (Aig_Obj_t *)pFanin0->pData, (Aig_Obj_t *)pFanin1->pData ); Aig_ObjCreatePo( pNew, pMiter ); } } @@ -753,23 +756,23 @@ Aig_Man_t * Saig_ManWindowExtractMiter( Aig_Man_t * p0, Aig_Man_t * p1 ) Saig_ManWindowCreatePis( pNew, p0, p1, vNodes0 ); Saig_ManWindowCreatePis( pNew, p1, p0, vNodes1 ); // create register outputs - Vec_PtrForEachEntry( vNodes0, pObj0, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes0, pObj0, i ) { if ( Saig_ObjIsLo(p0, pObj0) ) pObj0->pData = Aig_ObjCreatePi(pNew); } - Vec_PtrForEachEntry( vNodes1, pObj1, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes1, pObj1, i ) { if ( Saig_ObjIsLo(p1, pObj1) ) pObj1->pData = Aig_ObjCreatePi(pNew); } // create internal nodes - Vec_PtrForEachEntry( vNodes0, pObj0, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes0, pObj0, i ) { if ( Aig_ObjIsNode(pObj0) ) pObj0->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj0), Aig_ObjChild1Copy(pObj0) ); } - Vec_PtrForEachEntry( vNodes1, pObj1, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes1, pObj1, i ) { if ( Aig_ObjIsNode(pObj1) ) pObj1->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj1), Aig_ObjChild1Copy(pObj1) ); @@ -779,7 +782,7 @@ Aig_Man_t * Saig_ManWindowExtractMiter( Aig_Man_t * p0, Aig_Man_t * p1 ) // Saig_ManWindowCreatePos( pNew, p1, p0 ); // create register inputs nRegCount = 0; - Vec_PtrForEachEntry( vNodes0, pObj0, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes0, pObj0, i ) { if ( Saig_ObjIsLo(p0, pObj0) ) { @@ -788,7 +791,7 @@ Aig_Man_t * Saig_ManWindowExtractMiter( Aig_Man_t * p0, Aig_Man_t * p1 ) nRegCount++; } } - Vec_PtrForEachEntry( vNodes1, pObj1, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes1, pObj1, i ) { if ( Saig_ObjIsLo(p1, pObj1) ) { @@ -807,3 +810,5 @@ Aig_Man_t * Saig_ManWindowExtractMiter( Aig_Man_t * p0, Aig_Man_t * p1 ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/saig/saig_.c b/src/aig/saig/saig_.c index 255639e6..f0f293fd 100644 --- a/src/aig/saig/saig_.c +++ b/src/aig/saig/saig_.c @@ -20,6 +20,9 @@ #include "saig.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -45,3 +48,5 @@ //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ssw/module.make b/src/aig/ssw/module.make index 1e79c955..9d93fb93 100644 --- a/src/aig/ssw/module.make +++ b/src/aig/ssw/module.make @@ -2,8 +2,10 @@ SRC += src/aig/ssw/sswAig.c \ src/aig/ssw/sswBmc.c \ src/aig/ssw/sswClass.c \ src/aig/ssw/sswCnf.c \ + src/aig/ssw/sswConstr.c \ src/aig/ssw/sswCore.c \ src/aig/ssw/sswDyn.c \ + src/aig/ssw/sswFilter.c \ src/aig/ssw/sswIslands.c \ src/aig/ssw/sswLcorr.c \ src/aig/ssw/sswMan.c \ diff --git a/src/aig/ssw/ssw.h b/src/aig/ssw/ssw.h index c2a33ee4..207ebea9 100644 --- a/src/aig/ssw/ssw.h +++ b/src/aig/ssw/ssw.h @@ -21,6 +21,7 @@ #ifndef __SSW_H__ #define __SSW_H__ + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -29,9 +30,7 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif +ABC_NAMESPACE_HEADER_START //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -45,7 +44,8 @@ struct Ssw_Pars_t_ int nOverSize; // size of the overlap between partitions int nFramesK; // the induction depth int nFramesAddSim; // the number of additional frames to simulate - int nConstrs; // treat the last nConstrs POs as seq constraints + int fConstrs; // treat the last nConstrs POs as seq constraints + int fMergeFull; // enables full merge when constraints are used int nMaxLevs; // the max number of levels of nodes to consider int nBTLimit; // conflict limit at a node int nBTLimitGlobal;// conflict limit for multiple runs @@ -53,10 +53,13 @@ struct Ssw_Pars_t_ int nItersStop; // stop after the given number of iterations int fDumpSRInit; // dumps speculative reduction int nResimDelta; // the number of nodes to resimulate + int nStepsMax; // (scorr only) the max number of induction steps + int TimeLimit; // time out in seconds int fPolarFlip; // uses polarity adjustment int fLatchCorr; // perform register correspondence + int fOutputCorr; // perform 'PO correspondence' int fSemiFormal; // enable semiformal filtering - int fUniqueness; // enable uniqueness constraints +// int fUniqueness; // enable uniqueness constraints int fDynamic; // enable dynamic addition of constraints int fLocalSim; // enable local simulation simulation int fPartSigCorr; // uses partial signal correspondence @@ -75,18 +78,9 @@ struct Ssw_Pars_t_ // internal parameters int nIters; // the number of iterations performed int nConflicts; // the total number of conflicts performed -}; - -// sequential counter-example -typedef struct Ssw_Cex_t_ Ssw_Cex_t; -struct Ssw_Cex_t_ -{ - int iPo; // the zero-based number of PO, for which verification failed - int iFrame; // the zero-based number of the time-frame, for which verificaiton failed - int nRegs; // the number of registers in the miter - int nPis; // the number of primary inputs in the miter - int nBits; // the number of words of bit data used - unsigned pData[0]; // the cex bit data (the number of bits: nRegs + (iFrame+1) * nPis) + // callback + void * pData; + void * pFunc; }; typedef struct Ssw_Sml_t_ Ssw_Sml_t; // sequential simulation manager @@ -101,6 +95,8 @@ typedef struct Ssw_Sml_t_ Ssw_Sml_t; // sequential simulation manager /*=== sswBmc.c ==========================================================*/ extern int Ssw_BmcDynamic( Aig_Man_t * pAig, int nFramesMax, int nConfLimit, int fVerbose, int * piFrame ); +/*=== sswConstr.c ==========================================================*/ +extern int Ssw_ManSetConstrPhases( Aig_Man_t * p, int nFrames, Vec_Int_t ** pvInits ); /*=== sswCore.c ==========================================================*/ extern void Ssw_ManSetDefaultParams( Ssw_Pars_t * p ); extern void Ssw_ManSetDefaultParamsLcorr( Ssw_Pars_t * p ); @@ -110,7 +106,6 @@ extern Aig_Man_t * Ssw_LatchCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPa extern int Ssw_SecWithSimilarityPairs( Aig_Man_t * p0, Aig_Man_t * p1, Vec_Int_t * vPairs, Ssw_Pars_t * pPars ); extern int Ssw_SecWithSimilarity( Aig_Man_t * p0, Aig_Man_t * p1, Ssw_Pars_t * pPars ); /*=== sswMiter.c ===================================================*/ -extern int Ssw_SecSpecialMiter( Aig_Man_t * p0, Aig_Man_t * p1, int nFrames, int fVerbose ); /*=== sswPart.c ==========================================================*/ extern Aig_Man_t * Ssw_SignalCorrespondencePart( Aig_Man_t * pAig, Ssw_Pars_t * pPars ); /*=== sswPairs.c ===================================================*/ @@ -127,15 +122,17 @@ extern int Ssw_SmlNumFrames( Ssw_Sml_t * p ); extern int Ssw_SmlNumWordsTotal( Ssw_Sml_t * p ); extern unsigned * Ssw_SmlSimInfo( Ssw_Sml_t * p, Aig_Obj_t * pObj ); extern int Ssw_SmlObjsAreEqualWord( Ssw_Sml_t * p, Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 ); -extern Ssw_Cex_t * Ssw_SmlAllocCounterExample( int nRegs, int nRealPis, int nFrames ); -extern void Ssw_SmlFreeCounterExample( Ssw_Cex_t * pCex ); -extern int Ssw_SmlRunCounterExample( Aig_Man_t * pAig, Ssw_Cex_t * p ); -extern int Ssw_SmlFindOutputCounterExample( Aig_Man_t * pAig, Ssw_Cex_t * p ); -extern Ssw_Cex_t * Ssw_SmlDupCounterExample( Ssw_Cex_t * p, int nRegsNew ); - -#ifdef __cplusplus -} -#endif +extern Abc_Cex_t * Ssw_SmlAllocCounterExample( int nRegs, int nRealPis, int nFrames ); +extern void Ssw_SmlFreeCounterExample( Abc_Cex_t * pCex ); +extern int Ssw_SmlRunCounterExample( Aig_Man_t * pAig, Abc_Cex_t * p ); +extern int Ssw_SmlFindOutputCounterExample( Aig_Man_t * pAig, Abc_Cex_t * p ); +extern Abc_Cex_t * Ssw_SmlDupCounterExample( Abc_Cex_t * p, int nRegsNew ); + + + +ABC_NAMESPACE_HEADER_END + + #endif diff --git a/src/aig/ssw/sswAig.c b/src/aig/ssw/sswAig.c index 62e93d2d..f3174470 100644 --- a/src/aig/ssw/sswAig.c +++ b/src/aig/ssw/sswAig.c @@ -20,6 +20,9 @@ #include "sswInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -142,7 +145,7 @@ Aig_Man_t * Ssw_FramesWithClasses( Ssw_Man_t * p ) { Aig_Man_t * pFrames; Aig_Obj_t * pObj, * pObjLi, * pObjLo, * pObjNew; - int i, f; + int i, f, iLits; assert( p->pFrames == NULL ); assert( Aig_ManRegNum(p->pAig) > 0 ); assert( Aig_ManRegNum(p->pAig) < Aig_ManPiNum(p->pAig) ); @@ -154,12 +157,17 @@ Aig_Man_t * Ssw_FramesWithClasses( Ssw_Man_t * p ) Saig_ManForEachLo( p->pAig, pObj, i ) Ssw_ObjSetFrame( p, pObj, 0, Aig_ObjCreatePi(pFrames) ); // add timeframes + iLits = 0; for ( f = 0; f < p->pPars->nFramesK; f++ ) { // map constants and PIs Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), f, Aig_ManConst1(pFrames) ); Saig_ManForEachPi( p->pAig, pObj, i ) - Ssw_ObjSetFrame( p, pObj, f, Aig_ObjCreatePi(pFrames) ); + { + pObjNew = Aig_ObjCreatePi(pFrames); + pObjNew->fPhase = (p->vInits != NULL) && Vec_IntEntry(p->vInits, iLits++); + Ssw_ObjSetFrame( p, pObj, f, pObjNew ); + } // set the constraints on the latch outputs Saig_ManForEachLo( p->pAig, pObj, i ) Ssw_FramesConstrainNode( p, pFrames, p->pAig, pObj, f, 1 ); @@ -170,10 +178,14 @@ Aig_Man_t * Ssw_FramesWithClasses( Ssw_Man_t * p ) Ssw_ObjSetFrame( p, pObj, f, pObjNew ); Ssw_FramesConstrainNode( p, pFrames, p->pAig, pObj, f, 1 ); } + // transfer to the primary outputs + Aig_ManForEachPo( p->pAig, pObj, i ) + Ssw_ObjSetFrame( p, pObj, f, Ssw_ObjChild0Fra(p, pObj,f) ); // transfer latch input to the latch outputs Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i ) - Ssw_ObjSetFrame( p, pObjLo, f+1, Ssw_ObjChild0Fra(p, pObjLi,f) ); + Ssw_ObjSetFrame( p, pObjLo, f+1, Ssw_ObjFrame(p, pObjLi,f) ); } + assert( p->vInits == NULL || Vec_IntSize(p->vInits) == iLits + Saig_ManPiNum(p->pAig) ); // add the POs for the latch outputs of the last frame Saig_ManForEachLo( p->pAig, pObj, i ) Aig_ObjCreatePo( pFrames, Ssw_ObjFrame( p, pObj, p->pPars->nFramesK ) ); @@ -186,8 +198,6 @@ Aig_Man_t * Ssw_FramesWithClasses( Ssw_Man_t * p ) return pFrames; } - - /**Function************************************************************* Synopsis [Prepares the inductive case with speculative reduction.] @@ -245,3 +255,5 @@ Aig_Man_t * Ssw_SpeculativeReduction( Ssw_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ssw/sswBmc.c b/src/aig/ssw/sswBmc.c index 86d04424..aba32304 100644 --- a/src/aig/ssw/sswBmc.c +++ b/src/aig/ssw/sswBmc.c @@ -20,6 +20,9 @@ #include "sswInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -84,9 +87,9 @@ Aig_Obj_t * Ssw_BmcUnroll_rec( Ssw_Frm_t * pFrm, Aig_Obj_t * pObj, int f ) SeeAlso [] ***********************************************************************/ -Ssw_Cex_t * Ssw_BmcGetCounterExample( Ssw_Frm_t * pFrm, Ssw_Sat_t * pSat, int iPo, int iFrame ) +Abc_Cex_t * Ssw_BmcGetCounterExample( Ssw_Frm_t * pFrm, Ssw_Sat_t * pSat, int iPo, int iFrame ) { - Ssw_Cex_t * pCex; + Abc_Cex_t * pCex; Aig_Obj_t * pObj, * pObjFrames; int f, i, nShift; assert( Saig_ManRegNum(pFrm->pAig) > 0 ); @@ -217,3 +220,5 @@ int Ssw_BmcDynamic( Aig_Man_t * pAig, int nFramesMax, int nConfLimit, int fVerbo //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ssw/sswClass.c b/src/aig/ssw/sswClass.c index ce6ebf85..7fd2a21b 100644 --- a/src/aig/ssw/sswClass.c +++ b/src/aig/ssw/sswClass.c @@ -20,6 +20,9 @@ #include "sswInt.h" +ABC_NAMESPACE_IMPL_START + + /* The candidate equivalence classes are stored as a vector of pointers to the array of pointers to the nodes in each class. @@ -144,8 +147,8 @@ Ssw_Cla_t * Ssw_ClassesStart( Aig_Man_t * pAig ) p->vClassOld = Vec_PtrAlloc( 100 ); p->vClassNew = Vec_PtrAlloc( 100 ); p->vRefined = Vec_PtrAlloc( 1000 ); - assert( pAig->pReprs == NULL ); - Aig_ManReprStart( pAig, Aig_ManObjNumMax(pAig) ); + if ( pAig->pReprs == NULL ) + Aig_ManReprStart( pAig, Aig_ManObjNumMax(pAig) ); return p; } @@ -412,7 +415,7 @@ void Ssw_ClassesPrint( Ssw_Cla_t * p, int fVeryVerbose ) Aig_Obj_t ** ppClass; Aig_Obj_t * pObj; int i; - printf( "Equivalence classes: Const1 = %5d. Class = %5d. Lit = %5d.\n", + printf( "Equiv classes: Const1 = %5d. Class = %5d. Lit = %5d.\n", p->nCands1, p->nClasses, p->nCands1+p->nLits ); if ( !fVeryVerbose ) return; @@ -508,7 +511,7 @@ int Ssw_ClassesPrepareRehash( Ssw_Cla_t * p, Vec_Ptr_t * vCands ) // sort through the candidates nEntries = 0; p->nCands1 = 0; - Vec_PtrForEachEntry( vCands, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vCands, pObj, i ) { assert( p->pClassSizes[pObj->Id] == 0 ); Aig_ObjSetRepr( p->pAig, pObj, NULL ); @@ -547,7 +550,7 @@ int Ssw_ClassesPrepareRehash( Ssw_Cla_t * p, Vec_Ptr_t * vCands ) // copy the entries into storage in the topological order nEntries2 = 0; - Vec_PtrForEachEntry( vCands, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vCands, pObj, i ) { nNodes = p->pClassSizes[pObj->Id]; // skip the nodes that are not representatives of non-trivial classes @@ -587,7 +590,7 @@ int Ssw_ClassesPrepareRehash( Ssw_Cla_t * p, Vec_Ptr_t * vCands ) SeeAlso [] ***********************************************************************/ -Ssw_Cla_t * Ssw_ClassesPrepare( Aig_Man_t * pAig, int nFramesK, int fLatchCorr, int nMaxLevs, int fVerbose ) +Ssw_Cla_t * Ssw_ClassesPrepare( Aig_Man_t * pAig, int nFramesK, int fLatchCorr, int fOutputCorr, int nMaxLevs, int fVerbose ) { // int nFrames = 4; // int nWords = 1; @@ -622,7 +625,7 @@ if ( fVerbose ) // set comparison procedures clk = clock(); - Ssw_ClassesSetData( p, pSml, Ssw_SmlObjHashWord, Ssw_SmlObjIsConstWord, Ssw_SmlObjsAreEqualWord ); + Ssw_ClassesSetData( p, pSml, (unsigned(*)(void *,Aig_Obj_t *))Ssw_SmlObjHashWord, (int(*)(void *,Aig_Obj_t *))Ssw_SmlObjIsConstWord, (int(*)(void *,Aig_Obj_t *,Aig_Obj_t *))Ssw_SmlObjsAreEqualWord ); // collect nodes to be considered as candidates vCands = Vec_PtrAlloc( 1000 ); @@ -643,6 +646,22 @@ clk = clock(); } Vec_PtrPush( vCands, pObj ); } + + // this change will consider all PO drivers + if ( fOutputCorr ) + { + Vec_PtrClear( vCands ); + Aig_ManForEachObj( p->pAig, pObj, i ) + pObj->fMarkB = 0; + Saig_ManForEachPo( p->pAig, pObj, i ) + if ( Aig_ObjIsCand(Aig_ObjFanin0(pObj)) ) + Aig_ObjFanin0(pObj)->fMarkB = 1; + Aig_ManForEachObj( p->pAig, pObj, i ) + if ( pObj->fMarkB ) + Vec_PtrPush( vCands, pObj ); + Aig_ManForEachObj( p->pAig, pObj, i ) + pObj->fMarkB = 0; + } // allocate room for classes p->pMemClasses = ABC_ALLOC( Aig_Obj_t *, Vec_PtrSize(vCands) ); @@ -741,6 +760,69 @@ Ssw_Cla_t * Ssw_ClassesPrepareSimple( Aig_Man_t * pAig, int fLatchCorr, int nMax SeeAlso [] ***********************************************************************/ +Ssw_Cla_t * Ssw_ClassesPrepareFromReprs( Aig_Man_t * pAig ) +{ + Ssw_Cla_t * p; + Aig_Obj_t * pObj, * pRepr; + int * pClassSizes, nEntries, i; + // start the classes + p = Ssw_ClassesStart( pAig ); + // allocate memory for classes + p->pMemClasses = ABC_CALLOC( Aig_Obj_t *, Aig_ManObjNumMax(pAig) ); + // count classes + p->nCands1 = 0; + Aig_ManForEachObj( pAig, pObj, i ) + { + if ( Ssw_ObjIsConst1Cand(pAig, pObj) ) + { + p->nCands1++; + continue; + } + if ( (pRepr = Aig_ObjRepr(pAig, pObj)) ) + { + if ( p->pClassSizes[pRepr->Id]++ == 0 ) + p->pClassSizes[pRepr->Id]++; + } + } + // add nodes + nEntries = 0; + p->nClasses = 0; + pClassSizes = ABC_CALLOC( int, Aig_ManObjNumMax(pAig) ); + Aig_ManForEachObj( pAig, pObj, i ) + { + if ( p->pClassSizes[i] ) + { + p->pId2Class[i] = p->pMemClasses + nEntries; + nEntries += p->pClassSizes[i]; + p->pId2Class[i][pClassSizes[i]++] = pObj; + p->nClasses++; + continue; + } + if ( Ssw_ObjIsConst1Cand(pAig, pObj) ) + continue; + if ( (pRepr = Aig_ObjRepr(pAig, pObj)) ) + p->pId2Class[pRepr->Id][pClassSizes[pRepr->Id]++] = pObj; + } + p->pMemClassesFree = p->pMemClasses + nEntries; + p->nLits = nEntries - p->nClasses; + assert( memcmp(pClassSizes, p->pClassSizes, sizeof(int)*Aig_ManObjNumMax(pAig)) == 0 ); + ABC_FREE( pClassSizes ); +// printf( "After converting:\n" ); +// Ssw_ClassesPrint( p, 0 ); + return p; +} + +/**Function************************************************************* + + Synopsis [Creates initial simulation classes.] + + Description [Assumes that simulation info is assigned.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ Ssw_Cla_t * Ssw_ClassesPrepareTargets( Aig_Man_t * pAig ) { Ssw_Cla_t * p; @@ -902,20 +984,20 @@ int Ssw_ClassesRefineOneClass( Ssw_Cla_t * p, Aig_Obj_t * pReprOld, int fRecursi // Vec_PtrPush( p->vRefined, pObj ); // get the new representative - pReprNew = Vec_PtrEntry( p->vClassNew, 0 ); + pReprNew = (Aig_Obj_t *)Vec_PtrEntry( p->vClassNew, 0 ); assert( Vec_PtrSize(p->vClassOld) > 0 ); assert( Vec_PtrSize(p->vClassNew) > 0 ); // create old class pClassOld = Ssw_ObjRemoveClass( p, pReprOld ); - Vec_PtrForEachEntry( p->vClassOld, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vClassOld, pObj, i ) { pClassOld[i] = pObj; Aig_ObjSetRepr( p->pAig, pObj, i? pReprOld : NULL ); } // create new class pClassNew = pClassOld + i; - Vec_PtrForEachEntry( p->vClassNew, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vClassNew, pObj, i ) { pClassNew[i] = pObj; Aig_ObjSetRepr( p->pAig, pObj, i? pReprNew : NULL ); @@ -972,21 +1054,21 @@ int Ssw_ClassesRefineConst1Group( Ssw_Cla_t * p, Vec_Ptr_t * vRoots, int fRecurs return 0; // collect the nodes to be refined Vec_PtrClear( p->vClassNew ); - Vec_PtrForEachEntry( vRoots, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vRoots, pObj, i ) if ( !p->pFuncNodeIsConst( p->pManData, pObj ) ) Vec_PtrPush( p->vClassNew, pObj ); // check if there is a new class if ( Vec_PtrSize(p->vClassNew) == 0 ) return 0; p->nCands1 -= Vec_PtrSize(p->vClassNew); - pReprNew = Vec_PtrEntry( p->vClassNew, 0 ); + pReprNew = (Aig_Obj_t *)Vec_PtrEntry( p->vClassNew, 0 ); Aig_ObjSetRepr( p->pAig, pReprNew, NULL ); if ( Vec_PtrSize(p->vClassNew) == 1 ) return 1; // create a new class composed of these nodes ppClassNew = p->pMemClassesFree; p->pMemClassesFree += Vec_PtrSize(p->vClassNew); - Vec_PtrForEachEntry( p->vClassNew, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vClassNew, pObj, i ) { ppClassNew[i] = pObj; Aig_ObjSetRepr( p->pAig, pObj, i? pReprNew : NULL ); @@ -1029,14 +1111,14 @@ int Ssw_ClassesRefineConst1( Ssw_Cla_t * p, int fRecursive ) if ( Vec_PtrSize(p->vClassNew) == 0 ) return 0; p->nCands1 -= Vec_PtrSize(p->vClassNew); - pReprNew = Vec_PtrEntry( p->vClassNew, 0 ); + pReprNew = (Aig_Obj_t *)Vec_PtrEntry( p->vClassNew, 0 ); Aig_ObjSetRepr( p->pAig, pReprNew, NULL ); if ( Vec_PtrSize(p->vClassNew) == 1 ) return 1; // create a new class composed of these nodes ppClassNew = p->pMemClassesFree; p->pMemClassesFree += Vec_PtrSize(p->vClassNew); - Vec_PtrForEachEntry( p->vClassNew, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vClassNew, pObj, i ) { ppClassNew[i] = pObj; Aig_ObjSetRepr( p->pAig, pObj, i? pReprNew : NULL ); @@ -1054,3 +1136,5 @@ int Ssw_ClassesRefineConst1( Ssw_Cla_t * p, int fRecursive ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ssw/sswCnf.c b/src/aig/ssw/sswCnf.c index 73fa0b02..1970c62f 100644 --- a/src/aig/ssw/sswCnf.c +++ b/src/aig/ssw/sswCnf.c @@ -20,6 +20,9 @@ #include "sswInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -228,7 +231,7 @@ void Ssw_AddClausesSuper( Ssw_Sat_t * p, Aig_Obj_t * pNode, Vec_Ptr_t * vSuper ) pLits = ABC_ALLOC( int, nLits ); // suppose AND-gate is A & B = C // add !A => !C or A + !C - Vec_PtrForEachEntry( vSuper, pFanin, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vSuper, pFanin, i ) { pLits[0] = toLitCond(Ssw_ObjSatNum(p,Aig_Regular(pFanin)), Aig_IsComplement(pFanin)); pLits[1] = toLitCond(Ssw_ObjSatNum(p,pNode), 1); @@ -241,7 +244,7 @@ void Ssw_AddClausesSuper( Ssw_Sat_t * p, Aig_Obj_t * pNode, Vec_Ptr_t * vSuper ) assert( RetValue ); } // add A & B => C or !A + !B + C - Vec_PtrForEachEntry( vSuper, pFanin, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vSuper, pFanin, i ) { pLits[i] = toLitCond(Ssw_ObjSatNum(p,Aig_Regular(pFanin)), !Aig_IsComplement(pFanin)); if ( p->fPolarFlip ) @@ -357,7 +360,7 @@ void Ssw_CnfNodeAddToSolver( Ssw_Sat_t * p, Aig_Obj_t * pObj ) vFrontier = Vec_PtrAlloc( 100 ); Ssw_ObjAddToFrontier( p, pObj, vFrontier ); // explore nodes in the frontier - Vec_PtrForEachEntry( vFrontier, pNode, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vFrontier, pNode, i ) { // create the supergate assert( Ssw_ObjSatNum(p,pNode) ); @@ -368,14 +371,14 @@ void Ssw_CnfNodeAddToSolver( Ssw_Sat_t * p, Aig_Obj_t * pObj ) Vec_PtrPushUnique( p->vFanins, Aig_ObjFanin0( Aig_ObjFanin1(pNode) ) ); Vec_PtrPushUnique( p->vFanins, Aig_ObjFanin1( Aig_ObjFanin0(pNode) ) ); Vec_PtrPushUnique( p->vFanins, Aig_ObjFanin1( Aig_ObjFanin1(pNode) ) ); - Vec_PtrForEachEntry( p->vFanins, pFanin, k ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vFanins, pFanin, k ) Ssw_ObjAddToFrontier( p, Aig_Regular(pFanin), vFrontier ); Ssw_AddClausesMux( p, pNode ); } else { Ssw_CollectSuper( pNode, fUseMuxes, p->vFanins ); - Vec_PtrForEachEntry( p->vFanins, pFanin, k ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vFanins, pFanin, k ) Ssw_ObjAddToFrontier( p, Aig_Regular(pFanin), vFrontier ); Ssw_AddClausesSuper( p, pNode, p->vFanins ); } @@ -421,3 +424,5 @@ int Ssw_CnfGetNodeValue( Ssw_Sat_t * p, Aig_Obj_t * pObj ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ssw/sswConstr.c b/src/aig/ssw/sswConstr.c new file mode 100644 index 00000000..e233f133 --- /dev/null +++ b/src/aig/ssw/sswConstr.c @@ -0,0 +1,635 @@ +/**CFile**************************************************************** + + FileName [sswConstr.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Inductive prover with constraints.] + + Synopsis [One round of SAT sweeping.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - September 1, 2008.] + + Revision [$Id: sswConstr.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "sswInt.h" +#include "cnf.h" +#include "bar.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Constructs initialized timeframes with constraints as POs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Ssw_FramesWithConstraints( Aig_Man_t * p, int nFrames ) +{ + Aig_Man_t * pFrames; + Aig_Obj_t * pObj, * pObjLi, * pObjLo; + int i, f; + assert( Saig_ManConstrNum(p) > 0 ); + assert( Aig_ManRegNum(p) > 0 ); + assert( Aig_ManRegNum(p) < Aig_ManPiNum(p) ); + // start the fraig package + pFrames = Aig_ManStart( Aig_ManObjNumMax(p) * nFrames ); + // create latches for the first frame + Saig_ManForEachLo( p, pObj, i ) + Aig_ObjSetCopy( pObj, Aig_ManConst0(pFrames) ); + // add timeframes + for ( f = 0; f < nFrames; f++ ) + { + // map constants and PIs + Aig_ObjSetCopy( Aig_ManConst1(p), Aig_ManConst1(pFrames) ); + Saig_ManForEachPi( p, pObj, i ) + Aig_ObjSetCopy( pObj, Aig_ObjCreatePi(pFrames) ); + // add internal nodes of this frame + Aig_ManForEachNode( p, pObj, i ) + Aig_ObjSetCopy( pObj, Aig_And( pFrames, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ) ); + // transfer to the primary output + Aig_ManForEachPo( p, pObj, i ) + Aig_ObjSetCopy( pObj, Aig_ObjChild0Copy(pObj) ); + // create constraint outputs + Saig_ManForEachPo( p, pObj, i ) + { + if ( i < Saig_ManPoNum(p) - Saig_ManConstrNum(p) ) + continue; + Aig_ObjCreatePo( pFrames, Aig_Not( Aig_ObjCopy(pObj) ) ); + } + // transfer latch inputs to the latch outputs + Saig_ManForEachLiLo( p, pObjLi, pObjLo, i ) + Aig_ObjSetCopy( pObjLo, Aig_ObjCopy(pObjLi) ); + } + // remove dangling nodes + Aig_ManCleanup( pFrames ); + return pFrames; +} + +/**Function************************************************************* + + Synopsis [Finds one satisfiable assignment of the timeframes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ssw_ManSetConstrPhases( Aig_Man_t * p, int nFrames, Vec_Int_t ** pvInits ) +{ + Aig_Man_t * pFrames; + sat_solver * pSat; + Cnf_Dat_t * pCnf; + Aig_Obj_t * pObj; + int i, RetValue; + if ( pvInits ) + *pvInits = NULL; + assert( p->nConstrs > 0 ); + // derive the timeframes + pFrames = Ssw_FramesWithConstraints( p, nFrames ); + // create CNF + pCnf = Cnf_Derive( pFrames, 0 ); + // create SAT solver + pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); + if ( pSat == NULL ) + { + Cnf_DataFree( pCnf ); + Aig_ManStop( pFrames ); + return 1; + } + // solve + RetValue = sat_solver_solve( pSat, NULL, NULL, + (ABC_INT64_T)1000000, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); + if ( RetValue == l_True && pvInits ) + { + *pvInits = Vec_IntAlloc( 1000 ); + Aig_ManForEachPi( pFrames, pObj, i ) + Vec_IntPush( *pvInits, sat_solver_var_value(pSat, pCnf->pVarNums[Aig_ObjId(pObj)]) ); + +// Aig_ManForEachPi( pFrames, pObj, i ) +// printf( "%d", Vec_IntEntry(*pvInits, i) ); +// printf( "\n" ); + } + sat_solver_delete( pSat ); + Cnf_DataFree( pCnf ); + Aig_ManStop( pFrames ); + if ( RetValue == l_False ) + return 1; + if ( RetValue == l_True ) + return 0; + return -1; +} + +/**Function************************************************************* + + Synopsis [Performs fraiging for one node.] + + Description [Returns the fraiged node.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ssw_ManSetConstrPhases_( Aig_Man_t * p, int nFrames, Vec_Int_t ** pvInits ) +{ + Vec_Int_t * vLits; + sat_solver * pSat; + Cnf_Dat_t * pCnf; + Aig_Obj_t * pObj; + int i, f, iVar, RetValue, nRegs; + if ( pvInits ) + *pvInits = NULL; + assert( p->nConstrs > 0 ); + // create CNF + nRegs = p->nRegs; p->nRegs = 0; + pCnf = Cnf_Derive( p, Aig_ManPoNum(p) ); + p->nRegs = nRegs; + // create SAT solver + pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, nFrames, 0 ); + assert( pSat->size == nFrames * pCnf->nVars ); + // collect constraint literals + vLits = Vec_IntAlloc( 100 ); + Saig_ManForEachLo( p, pObj, i ) + { + assert( pCnf->pVarNums[Aig_ObjId(pObj)] >= 0 ); + Vec_IntPush( vLits, toLitCond(pCnf->pVarNums[Aig_ObjId(pObj)], 1) ); + } + for ( f = 0; f < nFrames; f++ ) + { + Saig_ManForEachPo( p, pObj, i ) + { + if ( i < Saig_ManPoNum(p) - Saig_ManConstrNum(p) ) + continue; + assert( pCnf->pVarNums[Aig_ObjId(pObj)] >= 0 ); + iVar = pCnf->pVarNums[Aig_ObjId(pObj)] + pCnf->nVars*f; + Vec_IntPush( vLits, toLitCond(iVar, 1) ); + } + } + RetValue = sat_solver_solve( pSat, (int *)Vec_IntArray(vLits), + (int *)Vec_IntArray(vLits) + Vec_IntSize(vLits), + (ABC_INT64_T)1000000, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); + if ( RetValue == l_True && pvInits ) + { + *pvInits = Vec_IntAlloc( 1000 ); + for ( f = 0; f < nFrames; f++ ) + { + Saig_ManForEachPi( p, pObj, i ) + { + iVar = pCnf->pVarNums[Aig_ObjId(pObj)] + pCnf->nVars*f; + Vec_IntPush( *pvInits, sat_solver_var_value(pSat, iVar) ); + } + } + } + sat_solver_delete( pSat ); + Vec_IntFree( vLits ); + Cnf_DataFree( pCnf ); + if ( RetValue == l_False ) + return 1; + if ( RetValue == l_True ) + return 0; + return -1; +} + +/**Function************************************************************* + + Synopsis [Performs fraiging for one node.] + + Description [Returns the fraiged node.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ssw_ManPrintPolarity( Aig_Man_t * p ) +{ + Aig_Obj_t * pObj; + int i; + Aig_ManForEachObj( p, pObj, i ) + printf( "%d", pObj->fPhase ); + printf( "\n" ); +} + +/**Function************************************************************* + + Synopsis [Performs fraiging for one node.] + + Description [Returns the fraiged node.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ssw_ManRefineByConstrSim( Ssw_Man_t * p ) +{ + Aig_Obj_t * pObj, * pObjLi; + int f, i, iLits, RetValue1, RetValue2; + int nFrames = Vec_IntSize(p->vInits) / Saig_ManPiNum(p->pAig); + assert( Vec_IntSize(p->vInits) % Saig_ManPiNum(p->pAig) == 0 ); + // assign register outputs + Saig_ManForEachLi( p->pAig, pObj, i ) + pObj->fMarkB = 0; + // simulate the timeframes + iLits = 0; + for ( f = 0; f < nFrames; f++ ) + { + // set the PI simulation information + Aig_ManConst1(p->pAig)->fMarkB = 1; + Saig_ManForEachPi( p->pAig, pObj, i ) + pObj->fMarkB = Vec_IntEntry( p->vInits, iLits++ ); + Saig_ManForEachLiLo( p->pAig, pObjLi, pObj, i ) + pObj->fMarkB = pObjLi->fMarkB; + // simulate internal nodes + Aig_ManForEachNode( p->pAig, pObj, i ) + pObj->fMarkB = ( Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj) ) + & ( Aig_ObjFanin1(pObj)->fMarkB ^ Aig_ObjFaninC1(pObj) ); + // assign the COs + Aig_ManForEachPo( p->pAig, pObj, i ) + pObj->fMarkB = ( Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj) ); + // check the outputs + Saig_ManForEachPo( p->pAig, pObj, i ) + { + if ( i < Saig_ManPoNum(p->pAig) - Saig_ManConstrNum(p->pAig) ) + { + if ( pObj->fMarkB ) + printf( "output %d failed in frame %d.\n", i, f ); + } + else + { + if ( pObj->fMarkB ) + printf( "constraint %d failed in frame %d.\n", i, f ); + } + } + // transfer + if ( f == 0 ) + { // copy markB into phase + Aig_ManForEachObj( p->pAig, pObj, i ) + pObj->fPhase = pObj->fMarkB; + } + else + { // refine classes + RetValue1 = Ssw_ClassesRefineConst1( p->ppClasses, 0 ); + RetValue2 = Ssw_ClassesRefine( p->ppClasses, 0 ); + } + } + assert( iLits == Vec_IntSize(p->vInits) ); +} + + +/**Function************************************************************* + + Synopsis [Performs fraiging for one node.] + + Description [Returns the fraiged node.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ssw_ManSweepNodeConstr( Ssw_Man_t * p, Aig_Obj_t * pObj, int f, int fBmc ) +{ + Aig_Obj_t * pObjRepr, * pObjFraig, * pObjFraig2, * pObjReprFraig; + int RetValue; + // get representative of this class + pObjRepr = Aig_ObjRepr( p->pAig, pObj ); + if ( pObjRepr == NULL ) + return 0; + // get the fraiged node + pObjFraig = Ssw_ObjFrame( p, pObj, f ); + // get the fraiged representative + pObjReprFraig = Ssw_ObjFrame( p, pObjRepr, f ); + // check if constant 0 pattern distinquishes these nodes + assert( pObjFraig != NULL && pObjReprFraig != NULL ); + assert( (pObj->fPhase == pObjRepr->fPhase) == (Aig_ObjPhaseReal(pObjFraig) == Aig_ObjPhaseReal(pObjReprFraig)) ); + // if the fraiged nodes are the same, return + if ( Aig_Regular(pObjFraig) == Aig_Regular(pObjReprFraig) ) + return 0; + // call equivalence checking + if ( Aig_Regular(pObjFraig) != Aig_ManConst1(p->pFrames) ) + RetValue = Ssw_NodesAreEquiv( p, Aig_Regular(pObjReprFraig), Aig_Regular(pObjFraig) ); + else + RetValue = Ssw_NodesAreEquiv( p, Aig_Regular(pObjFraig), Aig_Regular(pObjReprFraig) ); + if ( RetValue == 1 ) // proved equivalent + { + pObjFraig2 = Aig_NotCond( pObjReprFraig, pObj->fPhase ^ pObjRepr->fPhase ); + Ssw_ObjSetFrame( p, pObj, f, pObjFraig2 ); + return 0; + } + if ( RetValue == -1 ) // timed out + { + Ssw_ClassesRemoveNode( p->ppClasses, pObj ); + return 1; + } + // disproved equivalence + Ssw_SmlSavePatternAig( p, f ); + Ssw_ManResimulateBit( p, pObj, pObjRepr ); + assert( Aig_ObjRepr( p->pAig, pObj ) != pObjRepr ); + if ( Aig_ObjRepr( p->pAig, pObj ) == pObjRepr ) + { + printf( "Ssw_ManSweepNodeConstr(): Failed to refine representative.\n" ); + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Performs fraiging for the internal nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Ssw_ManSweepBmcConstr_rec( Ssw_Man_t * p, Aig_Obj_t * pObj, int f ) +{ + Aig_Obj_t * pObjNew, * pObjLi; + pObjNew = Ssw_ObjFrame( p, pObj, f ); + if ( pObjNew ) + return pObjNew; + assert( !Saig_ObjIsPi(p->pAig, pObj) ); + if ( Saig_ObjIsLo(p->pAig, pObj) ) + { + assert( f > 0 ); + pObjLi = Saig_ObjLoToLi( p->pAig, pObj ); + pObjNew = Ssw_ManSweepBmcConstr_rec( p, Aig_ObjFanin0(pObjLi), f-1 ); + pObjNew = Aig_NotCond( pObjNew, Aig_ObjFaninC0(pObjLi) ); + } + else + { + assert( Aig_ObjIsNode(pObj) ); + Ssw_ManSweepBmcConstr_rec( p, Aig_ObjFanin0(pObj), f ); + Ssw_ManSweepBmcConstr_rec( p, Aig_ObjFanin1(pObj), f ); + pObjNew = Aig_And( p->pFrames, Ssw_ObjChild0Fra(p, pObj, f), Ssw_ObjChild1Fra(p, pObj, f) ); + } + Ssw_ObjSetFrame( p, pObj, f, pObjNew ); + assert( pObjNew != NULL ); + return pObjNew; +} + +/**Function************************************************************* + + Synopsis [Performs fraiging for the internal nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ssw_ManSweepBmcConstr( Ssw_Man_t * p ) +{ + Bar_Progress_t * pProgress = NULL; + Aig_Obj_t * pObj, * pObjNew, * pObjLi, * pObjLo; + int i, f, iLits, clk; +clk = clock(); + + // start initialized timeframes + p->pFrames = Aig_ManStart( Aig_ManObjNumMax(p->pAig) * p->pPars->nFramesK ); + Saig_ManForEachLo( p->pAig, pObj, i ) + Ssw_ObjSetFrame( p, pObj, 0, Aig_ManConst0(p->pFrames) ); + + // build the constraint outputs + iLits = 0; + for ( f = 0; f < p->pPars->nFramesK; f++ ) + { + // map constants and PIs + Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), f, Aig_ManConst1(p->pFrames) ); + Saig_ManForEachPi( p->pAig, pObj, i ) + { + pObjNew = Aig_ObjCreatePi(p->pFrames); + pObjNew->fPhase = Vec_IntEntry( p->vInits, iLits++ ); + Ssw_ObjSetFrame( p, pObj, f, pObjNew ); + } + // build the constraint cones + Saig_ManForEachPo( p->pAig, pObj, i ) + { + if ( i < Saig_ManPoNum(p->pAig) - Saig_ManConstrNum(p->pAig) ) + continue; + pObjNew = Ssw_ManSweepBmcConstr_rec( p, Aig_ObjFanin0(pObj), f ); + pObjNew = Aig_NotCond( pObjNew, Aig_ObjFaninC0(pObj) ); + if ( Aig_Regular(pObjNew) == Aig_ManConst1(p->pFrames) ) + { + assert( Aig_IsComplement(pObjNew) ); + continue; + } + Ssw_NodesAreConstrained( p, pObjNew, Aig_ManConst0(p->pFrames) ); + } + } + assert( Vec_IntSize(p->vInits) == iLits + Saig_ManPiNum(p->pAig) ); + + // sweep internal nodes + p->fRefined = 0; + if ( p->pPars->fVerbose ) + pProgress = Bar_ProgressStart( stdout, Aig_ManObjNumMax(p->pAig) * p->pPars->nFramesK ); + for ( f = 0; f < p->pPars->nFramesK; f++ ) + { + // sweep internal nodes + Aig_ManForEachNode( p->pAig, pObj, i ) + { + if ( p->pPars->fVerbose ) + Bar_ProgressUpdate( pProgress, Aig_ManObjNumMax(p->pAig) * f + i, NULL ); + pObjNew = Aig_And( p->pFrames, Ssw_ObjChild0Fra(p, pObj, f), Ssw_ObjChild1Fra(p, pObj, f) ); + Ssw_ObjSetFrame( p, pObj, f, pObjNew ); + p->fRefined |= Ssw_ManSweepNodeConstr( p, pObj, f, 1 ); + } + // quit if this is the last timeframe + if ( f == p->pPars->nFramesK - 1 ) + break; + // transfer latch input to the latch outputs + Aig_ManForEachPo( p->pAig, pObj, i ) + Ssw_ObjSetFrame( p, pObj, f, Ssw_ObjChild0Fra(p, pObj, f) ); + // build logic cones for register outputs + Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i ) + { + pObjNew = Ssw_ObjFrame( p, pObjLi, f ); + Ssw_ObjSetFrame( p, pObjLo, f+1, pObjNew ); + Ssw_CnfNodeAddToSolver( p->pMSat, Aig_Regular(pObjNew) );// + } + } + if ( p->pPars->fVerbose ) + Bar_ProgressStop( pProgress ); + + // cleanup +// Ssw_ClassesCheck( p->ppClasses ); +p->timeBmc += clock() - clk; + return p->fRefined; +} + + + + +/**Function************************************************************* + + Synopsis [Performs fraiging for the internal nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Ssw_FramesWithClasses_rec( Ssw_Man_t * p, Aig_Obj_t * pObj, int f ) +{ + Aig_Obj_t * pObjNew, * pObjLi; + pObjNew = Ssw_ObjFrame( p, pObj, f ); + if ( pObjNew ) + return pObjNew; + assert( !Saig_ObjIsPi(p->pAig, pObj) ); + if ( Saig_ObjIsLo(p->pAig, pObj) ) + { + assert( f > 0 ); + pObjLi = Saig_ObjLoToLi( p->pAig, pObj ); + pObjNew = Ssw_FramesWithClasses_rec( p, Aig_ObjFanin0(pObjLi), f-1 ); + pObjNew = Aig_NotCond( pObjNew, Aig_ObjFaninC0(pObjLi) ); + } + else + { + assert( Aig_ObjIsNode(pObj) ); + Ssw_FramesWithClasses_rec( p, Aig_ObjFanin0(pObj), f ); + Ssw_FramesWithClasses_rec( p, Aig_ObjFanin1(pObj), f ); + pObjNew = Aig_And( p->pFrames, Ssw_ObjChild0Fra(p, pObj, f), Ssw_ObjChild1Fra(p, pObj, f) ); + } + Ssw_ObjSetFrame( p, pObj, f, pObjNew ); + assert( pObjNew != NULL ); + return pObjNew; +} + + +/**Function************************************************************* + + Synopsis [Performs fraiging for the internal nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ssw_ManSweepConstr( Ssw_Man_t * p ) +{ + Bar_Progress_t * pProgress = NULL; + Aig_Obj_t * pObj, * pObj2, * pObjNew; + int nConstrPairs, clk, i, f, iLits; +//Ssw_ManPrintPolarity( p->pAig ); + + // perform speculative reduction +clk = clock(); + // create timeframes + p->pFrames = Ssw_FramesWithClasses( p ); + // add constants + nConstrPairs = Aig_ManPoNum(p->pFrames)-Aig_ManRegNum(p->pAig); + assert( (nConstrPairs & 1) == 0 ); + for ( i = 0; i < nConstrPairs; i += 2 ) + { + pObj = Aig_ManPo( p->pFrames, i ); + pObj2 = Aig_ManPo( p->pFrames, i+1 ); + Ssw_NodesAreConstrained( p, Aig_ObjChild0(pObj), Aig_ObjChild0(pObj2) ); + } + // build logic cones for register inputs + for ( i = 0; i < Aig_ManRegNum(p->pAig); i++ ) + { + pObj = Aig_ManPo( p->pFrames, nConstrPairs + i ); + Ssw_CnfNodeAddToSolver( p->pMSat, Aig_ObjFanin0(pObj) );// + } + + // map constants and PIs of the last frame + f = p->pPars->nFramesK; +// iLits = 0; + iLits = f * Saig_ManPiNum(p->pAig); + Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), f, Aig_ManConst1(p->pFrames) ); + Saig_ManForEachPi( p->pAig, pObj, i ) + { + pObjNew = Aig_ObjCreatePi(p->pFrames); + pObjNew->fPhase = (p->vInits != NULL) && Vec_IntEntry(p->vInits, iLits++); + Ssw_ObjSetFrame( p, pObj, f, pObjNew ); + } + assert( Vec_IntSize(p->vInits) == iLits ); +p->timeReduce += clock() - clk; + + // add constraints to all timeframes + for ( f = 0; f <= p->pPars->nFramesK; f++ ) + { + Saig_ManForEachPo( p->pAig, pObj, i ) + { + if ( i < Saig_ManPoNum(p->pAig) - Saig_ManConstrNum(p->pAig) ) + continue; + Ssw_FramesWithClasses_rec( p, Aig_ObjFanin0(pObj), f ); +// if ( Aig_Regular(Ssw_ObjChild0Fra(p,pObj,f)) == Aig_ManConst1(p->pFrames) ) + if ( Ssw_ObjChild0Fra(p,pObj,f) == Aig_ManConst0(p->pFrames) ) + continue; + assert( Ssw_ObjChild0Fra(p,pObj,f) != Aig_ManConst1(p->pFrames) ); + if ( Ssw_ObjChild0Fra(p,pObj,f) == Aig_ManConst1(p->pFrames) ) + { + printf( "Polarity violation.\n" ); + continue; + } + Ssw_NodesAreConstrained( p, Ssw_ObjChild0Fra(p,pObj,f), Aig_ManConst0(p->pFrames) ); + } + } + f = p->pPars->nFramesK; + // clean the solver + sat_solver_simplify( p->pMSat->pSat ); + + + // sweep internal nodes + p->fRefined = 0; + Ssw_ClassesClearRefined( p->ppClasses ); + if ( p->pPars->fVerbose ) + pProgress = Bar_ProgressStart( stdout, Aig_ManObjNumMax(p->pAig) ); + Aig_ManForEachObj( p->pAig, pObj, i ) + { + if ( p->pPars->fVerbose ) + Bar_ProgressUpdate( pProgress, i, NULL ); + if ( Saig_ObjIsLo(p->pAig, pObj) ) + p->fRefined |= Ssw_ManSweepNodeConstr( p, pObj, f, 0 ); + else if ( Aig_ObjIsNode(pObj) ) + { + pObjNew = Aig_And( p->pFrames, Ssw_ObjChild0Fra(p, pObj, f), Ssw_ObjChild1Fra(p, pObj, f) ); + Ssw_ObjSetFrame( p, pObj, f, pObjNew ); + p->fRefined |= Ssw_ManSweepNodeConstr( p, pObj, f, 0 ); + } + } + if ( p->pPars->fVerbose ) + Bar_ProgressStop( pProgress ); + // cleanup +// Ssw_ClassesCheck( p->ppClasses ); + return p->fRefined; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ssw/sswCore.c b/src/aig/ssw/sswCore.c index 6cb84800..c277d76e 100644 --- a/src/aig/ssw/sswCore.c +++ b/src/aig/ssw/sswCore.c @@ -20,6 +20,9 @@ #include "sswInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -46,16 +49,18 @@ void Ssw_ManSetDefaultParams( Ssw_Pars_t * p ) p->nOverSize = 0; // size of the overlap between partitions p->nFramesK = 1; // the induction depth p->nFramesAddSim = 2; // additional frames to simulate - p->nConstrs = 0; // treat the last nConstrs POs as seq constraints + p->fConstrs = 0; // treat the last nConstrs POs as seq constraints + p->fMergeFull = 0; // enables full merge when constraints are used p->nBTLimit = 1000; // conflict limit at a node p->nBTLimitGlobal = 5000000; // conflict limit for all runs p->nMinDomSize = 100; // min clock domain considered for optimization p->nItersStop = -1; // stop after the given number of iterations p->nResimDelta = 1000; // the internal of nodes to resimulate + p->nStepsMax = -1; // (scorr only) the max number of induction steps p->fPolarFlip = 0; // uses polarity adjustment p->fLatchCorr = 0; // performs register correspondence + p->fOutputCorr = 0; // perform 'PO correspondence' p->fSemiFormal = 0; // enable semiformal filtering - p->fUniqueness = 0; // enable uniqueness constraints p->fDynamic = 0; // dynamic partitioning p->fLocalSim = 0; // local simulation p->fVerbose = 0; // verbose stats @@ -90,6 +95,130 @@ void Ssw_ManSetDefaultParamsLcorr( Ssw_Pars_t * p ) /**Function************************************************************* + Synopsis [Reports improvements for property cones.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ssw_ReportConeReductions( Ssw_Man_t * p, Aig_Man_t * pAigInit, Aig_Man_t * pAigStop ) +{ + Aig_Man_t * pAig1, * pAig2, * pAux; + pAig1 = Aig_ManDupOneOutput( pAigInit, 0, 1 ); + pAig1 = Aig_ManScl( pAux = pAig1, 1, 1, 0 ); + Aig_ManStop( pAux ); + pAig2 = Aig_ManDupOneOutput( pAigStop, 0, 1 ); + pAig2 = Aig_ManScl( pAux = pAig2, 1, 1, 0 ); + Aig_ManStop( pAux ); + + p->nNodesBegC = Aig_ManNodeNum(pAig1); + p->nNodesEndC = Aig_ManNodeNum(pAig2); + p->nRegsBegC = Aig_ManRegNum(pAig1); + p->nRegsEndC = Aig_ManRegNum(pAig2); + + Aig_ManStop( pAig1 ); + Aig_ManStop( pAig2 ); +} + +/**Function************************************************************* + + Synopsis [Reports one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ssw_ReportOneOutput( Aig_Man_t * p, Aig_Obj_t * pObj ) +{ + if ( pObj == Aig_ManConst1(p) ) + printf( "1" ); + else if ( pObj == Aig_ManConst0(p) ) + printf( "0" ); + else + printf( "X" ); +} + +/**Function************************************************************* + + Synopsis [Reports improvements for property cones.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ssw_ReportOutputs( Aig_Man_t * pAig ) +{ + Aig_Obj_t * pObj; + int i; + Saig_ManForEachPo( pAig, pObj, i ) + { + if ( i < Saig_ManPoNum(pAig)-Saig_ManConstrNum(pAig) ) + printf( "o" ); + else + printf( "c" ); + Ssw_ReportOneOutput( pAig, Aig_ObjChild0(pObj) ); + } + printf( "\n" ); +} + +/**Function************************************************************* + + Synopsis [Remove from-equivs that are in the cone of constraints.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ssw_ManUpdateEquivs( Ssw_Man_t * p, Aig_Man_t * pAig, int fVerbose ) +{ + Vec_Ptr_t * vCones; + Aig_Obj_t ** pArray; + Aig_Obj_t * pObj; + int i, nTotal = 0, nRemoved = 0; + // collect the nodes in the cone of constraints + pArray = (Aig_Obj_t **)Vec_PtrArray(pAig->vPos); + pArray += Saig_ManPoNum(pAig) - Saig_ManConstrNum(pAig); + vCones = Aig_ManDfsNodes( pAig, pArray, Saig_ManConstrNum(pAig) ); + // remove all the node that are equiv to something and are in the cones + Aig_ManForEachObj( pAig, pObj, i ) + { + if ( !Aig_ObjIsPi(pObj) && !Aig_ObjIsNode(pObj) ) + continue; + if ( pAig->pReprs[i] != NULL ) + nTotal++; + if ( !Aig_ObjIsTravIdCurrent(pAig, pObj) ) + continue; + if ( pAig->pReprs[i] ) + { + if ( p->pPars->fConstrs && !p->pPars->fMergeFull ) + { + pAig->pReprs[i] = NULL; + nRemoved++; + } + } + } + // collect statistics + p->nConesTotal = Aig_ManPiNum(pAig) + Aig_ManNodeNum(pAig); + p->nConesConstr = Vec_PtrSize(vCones); + p->nEquivsTotal = nTotal; + p->nEquivsConstr = nRemoved; + Vec_PtrFree( vCones ); +} + +/**Function************************************************************* + Synopsis [Performs computation of signal correspondence with constraints.] Description [] @@ -118,9 +247,10 @@ Aig_Man_t * Ssw_SignalCorrespondenceRefine( Ssw_Man_t * p ) if ( !p->pPars->fLatchCorr ) { p->pMSat = Ssw_SatStart( 0 ); - Ssw_ManSweepBmc( p ); - if ( p->pPars->nFramesK > 1 && p->pPars->fUniqueness ) - Ssw_UniqueRegisterPairInfo( p ); + if ( p->pPars->fConstrs ) + Ssw_ManSweepBmcConstr( p ); + else + Ssw_ManSweepBmc( p ); Ssw_SatStop( p->pMSat ); p->pMSat = NULL; Ssw_ManCleanup( p ); @@ -142,10 +272,25 @@ Aig_Man_t * Ssw_SignalCorrespondenceRefine( Ssw_Man_t * p ) Aig_ManStop( pSRed ); } */ + if ( p->pPars->pFunc ) + { + ((int (*)(void *))p->pPars->pFunc)( p->pPars->pData ); + ((int (*)(void *))p->pPars->pFunc)( p->pPars->pData ); + } + if ( p->pPars->nStepsMax == 0 ) + { + printf( "Stopped signal correspondence after BMC.\n" ); + goto finalize; + } // refine classes using induction nSatProof = nSatCallsSat = nRecycles = nSatFailsReal = nUniques = 0; for ( nIter = 0; ; nIter++ ) { + if ( p->pPars->nStepsMax == nIter ) + { + printf( "Stopped signal correspondence after %d refiment iterations.\n", nIter ); + goto finalize; + } if ( p->pPars->nItersStop >= 0 && p->pPars->nItersStop == nIter ) { Aig_Man_t * pSRed = Ssw_SpeculativeReduction( p ); @@ -174,19 +319,20 @@ clk = clock(); } else { - if ( p->pPars->fDynamic ) + if ( p->pPars->fConstrs ) + RetValue = Ssw_ManSweepConstr( p ); + else if ( p->pPars->fDynamic ) RetValue = Ssw_ManSweepDyn( p ); else RetValue = Ssw_ManSweep( p ); + p->pPars->nConflicts += p->pMSat->pSat->stats.conflicts; if ( p->pPars->fVerbose ) { printf( "%3d : C =%7d. Cl =%7d. LR =%6d. NR =%6d. ", nIter, Ssw_ClassesCand1Num(p->ppClasses), Ssw_ClassesClassNum(p->ppClasses), p->nConstrReduced, Aig_ManNodeNum(p->pFrames) ); - if ( p->pPars->fUniqueness ) - printf( "U =%4d. ", p->nUniques-nUniques ); - else if ( p->pPars->fDynamic ) + if ( p->pPars->fDynamic ) { printf( "Cex =%5d. ", p->nSatCallsSat-nSatCallsSat ); printf( "R =%4d. ", p->nRecycles-nRecycles ); @@ -211,9 +357,15 @@ clk = clock(); Ssw_ManCleanup( p ); if ( !RetValue ) break; + if ( p->pPars->pFunc ) + ((int (*)(void *))p->pPars->pFunc)( p->pPars->pData ); } + +finalize: p->pPars->nIters = nIter + 1; p->timeTotal = clock() - clkTotal; + + Ssw_ManUpdateEquivs( p, p->pAig, p->pPars->fVerbose ); pAigNew = Aig_ManDupRepr( p->pAig, 0 ); Aig_ManSeqCleanup( pAigNew ); //Ssw_ClassesPrint( p->ppClasses, 1 ); @@ -221,6 +373,9 @@ p->timeTotal = clock() - clkTotal; p->nLitsEnd = Ssw_ClassesLitNum( p->ppClasses ); p->nNodesEnd = Aig_ManNodeNum(pAigNew); p->nRegsEnd = Aig_ManRegNum(pAigNew); + // cleanup + Aig_ManSetPhase( p->pAig ); + Aig_ManCleanMarkB( p->pAig ); return pAigNew; } @@ -255,13 +410,6 @@ Aig_Man_t * Ssw_SignalCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars ) return Aig_ManDupOrdered(pAig); } // check and update parameters - if ( pPars->fUniqueness ) - { - pPars->nFramesAddSim = 0; - if ( pPars->nFramesK != 2 ) - printf( "Setting K = 2 for uniqueness constraints to work.\n" ); - pPars->nFramesK = 2; - } if ( pPars->fLatchCorrOpt ) { pPars->fLatchCorr = 1; @@ -291,15 +439,31 @@ Aig_Man_t * Ssw_SignalCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars ) return Cec_SignalCorrespondence( pAig, pPars->nBTLimit, pPars->fUseCSat ); } } - + // start the induction manager p = Ssw_ManCreate( pAig, pPars ); // compute candidate equivalence classes // p->pPars->nConstrs = 1; - if ( p->pPars->nConstrs == 0 ) + if ( p->pPars->fConstrs ) + { + // create trivial equivalence classes with all nodes being candidates for constant 1 + p->ppClasses = Ssw_ClassesPrepareSimple( pAig, pPars->fLatchCorr, pPars->nMaxLevs ); + Ssw_ClassesSetData( p->ppClasses, NULL, NULL, Ssw_SmlObjIsConstBit, Ssw_SmlObjsAreEqualBit ); + // derive phase bits to satisfy the constraints + if ( Ssw_ManSetConstrPhases( pAig, p->pPars->nFramesK + 1, &p->vInits ) != 0 ) + { + printf( "Ssw_SignalCorrespondence(): The init state does not satisfy the constraints!\n" ); + p->pPars->fVerbose = 0; + Ssw_ManStop( p ); + return NULL; + } + // perform simulation of the first timeframes + Ssw_ManRefineByConstrSim( p ); + } + else { // perform one round of seq simulation and generate candidate equivalence classes - p->ppClasses = Ssw_ClassesPrepare( pAig, pPars->nFramesK, pPars->fLatchCorr, pPars->nMaxLevs, pPars->fVerbose ); + p->ppClasses = Ssw_ClassesPrepare( pAig, pPars->nFramesK, pPars->fLatchCorr, pPars->fOutputCorr, pPars->nMaxLevs, pPars->fVerbose ); // p->ppClasses = Ssw_ClassesPrepareTargets( pAig ); if ( pPars->fLatchCorrOpt ) p->pSml = Ssw_SmlStart( pAig, 0, 2, 1 ); @@ -307,21 +471,16 @@ Aig_Man_t * Ssw_SignalCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars ) p->pSml = Ssw_SmlStart( pAig, 0, p->nFrames + p->pPars->nFramesAddSim, 1 ); else p->pSml = Ssw_SmlStart( pAig, 0, 1 + p->pPars->nFramesAddSim, 1 ); - Ssw_ClassesSetData( p->ppClasses, p->pSml, Ssw_SmlObjHashWord, Ssw_SmlObjIsConstWord, Ssw_SmlObjsAreEqualWord ); - } - else - { - // create trivial equivalence classes with all nodes being candidates for constant 1 - p->ppClasses = Ssw_ClassesPrepareSimple( pAig, pPars->fLatchCorr, pPars->nMaxLevs ); - Ssw_ClassesSetData( p->ppClasses, NULL, NULL, Ssw_SmlObjIsConstBit, Ssw_SmlObjsAreEqualBit ); + Ssw_ClassesSetData( p->ppClasses, p->pSml, (unsigned(*)(void *,Aig_Obj_t *))Ssw_SmlObjHashWord, (int(*)(void *,Aig_Obj_t *))Ssw_SmlObjIsConstWord, (int(*)(void *,Aig_Obj_t *,Aig_Obj_t *))Ssw_SmlObjsAreEqualWord ); } + // allocate storage if ( p->pPars->fLocalSim ) p->pVisited = ABC_CALLOC( int, Ssw_SmlNumFrames( p->pSml ) * Aig_ManObjNumMax(p->pAig) ); // perform refinement of classes pAigNew = Ssw_SignalCorrespondenceRefine( p ); - if ( pPars->fUniqueness ) - printf( "Uniqueness constraints = %3d. Prevented counter-examples = %3d.\n", - p->nUniquesAdded, p->nUniquesUseful ); +// Ssw_ReportOutputs( pAigNew ); + if ( pPars->fConstrs && pPars->fVerbose ) + Ssw_ReportConeReductions( p, pAig, pAigNew ); // cleanup Ssw_ManStop( p ); return pAigNew; @@ -340,10 +499,14 @@ Aig_Man_t * Ssw_SignalCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars ) ***********************************************************************/ Aig_Man_t * Ssw_LatchCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars ) { + Aig_Man_t * pRes; Ssw_Pars_t Pars; if ( pPars == NULL ) Ssw_ManSetDefaultParamsLcorr( pPars = &Pars ); - return Ssw_SignalCorrespondence( pAig, pPars ); + pRes = Ssw_SignalCorrespondence( pAig, pPars ); +// if ( pPars->fConstrs && pPars->fVerbose ) +// Ssw_ReportConeReductions( pAig, pRes ); + return pRes; } @@ -352,3 +515,5 @@ Aig_Man_t * Ssw_LatchCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ssw/sswDyn.c b/src/aig/ssw/sswDyn.c index 04e66f09..7e8edc66 100644 --- a/src/aig/ssw/sswDyn.c +++ b/src/aig/ssw/sswDyn.c @@ -21,6 +21,9 @@ #include "sswInt.h" #include "bar.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -153,7 +156,7 @@ void Ssw_ManLoadSolver( Ssw_Man_t * p, Aig_Obj_t * pRepr, Aig_Obj_t * pObj ) Ssw_ManCollectPis_rec( pRepr, p->vNewLos ); Ssw_ManCollectPis_rec( pObj, p->vNewLos ); // add logic cones for register outputs - Vec_PtrForEachEntry( p->vNewLos, pTemp, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vNewLos, pTemp, i ) { pObj0 = Aig_Regular( Ssw_ObjFrame( p, pTemp, p->pPars->nFramesK ) ); Ssw_CnfNodeAddToSolver( p->pMSat, pObj0 ); @@ -172,7 +175,7 @@ void Ssw_ManLoadSolver( Ssw_Man_t * p, Aig_Obj_t * pRepr, Aig_Obj_t * pObj ) // collect the related constraint POs Vec_IntClear( p->vNewPos ); - Vec_PtrForEachEntry( p->vNewLos, pTemp, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vNewLos, pTemp, i ) Ssw_ManCollectPos_rec( p, pTemp, p->vNewPos ); // check if the corresponding pairs are added Vec_IntForEachEntry( p->vNewPos, iConstr, i ) @@ -222,7 +225,7 @@ void Ssw_ManSweepTransferDyn( Ssw_Man_t * p ) } assert( !Aig_IsComplement(pObjFraig) ); assert( Aig_ObjIsPi(pObjFraig) ); - pInfo = Vec_PtrEntry( p->vSimInfo, Aig_ObjPioNum(pObjFraig) ); + pInfo = (unsigned *)Vec_PtrEntry( p->vSimInfo, Aig_ObjPioNum(pObjFraig) ); Ssw_SmlObjSetWord( p->pSml, pObj, pInfo[0], 0, 0 ); } // set random simulation info for the second frame @@ -233,7 +236,7 @@ void Ssw_ManSweepTransferDyn( Ssw_Man_t * p ) pObjFraig = Ssw_ObjFrame( p, pObj, f ); assert( !Aig_IsComplement(pObjFraig) ); assert( Aig_ObjIsPi(pObjFraig) ); - pInfo = Vec_PtrEntry( p->vSimInfo, Aig_ObjPioNum(pObjFraig) ); + pInfo = (unsigned *)Vec_PtrEntry( p->vSimInfo, Aig_ObjPioNum(pObjFraig) ); Ssw_SmlObjSetWord( p->pSml, pObj, pInfo[0], 0, f ); } } @@ -327,10 +330,10 @@ int Ssw_ManSweepResimulateDynLocal( Ssw_Man_t * p, int f ) // Aig_ManIncrementTravId( p->pAig ); // Aig_ObjIsTravIdCurrent( p->pAig, Aig_ManConst1(p->pAig) ); p->nVisCounter++; - Vec_PtrForEachEntry( p->vResimConsts, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vResimConsts, pObj, i ) Ssw_SmlSimulateOneDyn_rec( p->pSml, pObj, p->nFrames-1, p->pVisited, p->nVisCounter ); // resimulate the cone of influence of the cand classes - Vec_PtrForEachEntry( p->vResimClasses, pRepr, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vResimClasses, pRepr, i ) { ppClass = Ssw_ClassesReadClass( p->ppClasses, pRepr, &nSize ); for ( k = 0; k < nSize; k++ ) @@ -343,7 +346,7 @@ int Ssw_ManSweepResimulateDynLocal( Ssw_Man_t * p, int f ) // refine these nodes RetValue1 = Ssw_ClassesRefineConst1Group( p->ppClasses, p->vResimConsts, 1 ); RetValue2 = 0; - Vec_PtrForEachEntry( p->vResimClasses, pRepr, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vResimClasses, pRepr, i ) RetValue2 += Ssw_ClassesRefineOneClass( p->ppClasses, pRepr, 1 ); // prepare simulation info for the next round @@ -482,3 +485,5 @@ p->timeReduce += clock() - clk; //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ssw/sswFilter.c b/src/aig/ssw/sswFilter.c new file mode 100644 index 00000000..a0c0934a --- /dev/null +++ b/src/aig/ssw/sswFilter.c @@ -0,0 +1,492 @@ +/**CFile**************************************************************** + + FileName [sswConstr.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Inductive prover with constraints.] + + Synopsis [One round of SAT sweeping.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - September 1, 2008.] + + Revision [$Id: sswConstr.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "sswInt.h" +#include "giaAig.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Performs fraiging for one node.] + + Description [Returns the fraiged node.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ssw_ManRefineByFilterSim( Ssw_Man_t * p, int nFrames ) +{ + Aig_Obj_t * pObj, * pObjLi; + int f, i, RetValue1, RetValue2; + assert( nFrames > 0 ); + // assign register outputs + Saig_ManForEachLi( p->pAig, pObj, i ) + pObj->fMarkB = Aig_InfoHasBit( p->pPatWords, Saig_ManPiNum(p->pAig) + i ); + // simulate the timeframes + for ( f = 0; f < nFrames; f++ ) + { + // set the PI simulation information + Aig_ManConst1(p->pAig)->fMarkB = 1; + Saig_ManForEachPi( p->pAig, pObj, i ) + pObj->fMarkB = 0; + Saig_ManForEachLiLo( p->pAig, pObjLi, pObj, i ) + pObj->fMarkB = pObjLi->fMarkB; + // simulate internal nodes + Aig_ManForEachNode( p->pAig, pObj, i ) + pObj->fMarkB = ( Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj) ) + & ( Aig_ObjFanin1(pObj)->fMarkB ^ Aig_ObjFaninC1(pObj) ); + // assign the COs + Aig_ManForEachPo( p->pAig, pObj, i ) + pObj->fMarkB = ( Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj) ); + // transfer + if ( f == 0 ) + { // copy markB into phase + Aig_ManForEachObj( p->pAig, pObj, i ) + pObj->fPhase = pObj->fMarkB; + } + else + { // refine classes + RetValue1 = Ssw_ClassesRefineConst1( p->ppClasses, 0 ); + RetValue2 = Ssw_ClassesRefine( p->ppClasses, 0 ); + } + } +} + + +/**Function************************************************************* + + Synopsis [Performs fraiging for one node.] + + Description [Returns the fraiged node.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ssw_ManRollForward( Ssw_Man_t * p, int nFrames ) +{ + Aig_Obj_t * pObj, * pObjLi; + int f, i; + assert( nFrames > 0 ); + // assign register outputs + Saig_ManForEachLi( p->pAig, pObj, i ) + pObj->fMarkB = Aig_InfoHasBit( p->pPatWords, Saig_ManPiNum(p->pAig) + i ); + // simulate the timeframes + for ( f = 0; f < nFrames; f++ ) + { + // set the PI simulation information + Aig_ManConst1(p->pAig)->fMarkB = 1; + Saig_ManForEachPi( p->pAig, pObj, i ) + pObj->fMarkB = Aig_ManRandom(0) & 1; + Saig_ManForEachLiLo( p->pAig, pObjLi, pObj, i ) + pObj->fMarkB = pObjLi->fMarkB; + // simulate internal nodes + Aig_ManForEachNode( p->pAig, pObj, i ) + pObj->fMarkB = ( Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj) ) + & ( Aig_ObjFanin1(pObj)->fMarkB ^ Aig_ObjFaninC1(pObj) ); + // assign the COs + Aig_ManForEachPo( p->pAig, pObj, i ) + pObj->fMarkB = ( Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj) ); + } + // record the new pattern + Saig_ManForEachLi( p->pAig, pObj, i ) + if ( pObj->fMarkB ^ Aig_InfoHasBit(p->pPatWords, Saig_ManPiNum(p->pAig) + i) ) + Aig_InfoXorBit( p->pPatWords, Saig_ManPiNum(p->pAig) + i ); +} + +/**Function************************************************************* + + Synopsis [Performs fraiging for one node.] + + Description [Returns the fraiged node.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ssw_ManFindStartingState( Ssw_Man_t * p, Abc_Cex_t * pCex ) +{ + Aig_Obj_t * pObj, * pObjLi; + int f, i, iBit; + // assign register outputs + Saig_ManForEachLi( p->pAig, pObj, i ) + pObj->fMarkB = 0; + // simulate the timeframes + iBit = pCex->nRegs; + for ( f = 0; f <= pCex->iFrame; f++ ) + { + // set the PI simulation information + Aig_ManConst1(p->pAig)->fMarkB = 1; + Saig_ManForEachPi( p->pAig, pObj, i ) + pObj->fMarkB = Aig_InfoHasBit( pCex->pData, iBit++ ); + Saig_ManForEachLiLo( p->pAig, pObjLi, pObj, i ) + pObj->fMarkB = pObjLi->fMarkB; + // simulate internal nodes + Aig_ManForEachNode( p->pAig, pObj, i ) + pObj->fMarkB = ( Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj) ) + & ( Aig_ObjFanin1(pObj)->fMarkB ^ Aig_ObjFaninC1(pObj) ); + // assign the COs + Aig_ManForEachPo( p->pAig, pObj, i ) + pObj->fMarkB = ( Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj) ); + } + assert( iBit == pCex->nBits ); + // check that the output failed as expected -- cannot check because it is not an SRM! +// pObj = Aig_ManPo( p->pAig, pCex->iPo ); +// if ( pObj->fMarkB != 1 ) +// printf( "The counter-example does not refine the output.\n" ); + // record the new pattern + Saig_ManForEachLo( p->pAig, pObj, i ) + if ( pObj->fMarkB ^ Aig_InfoHasBit(p->pPatWords, Saig_ManPiNum(p->pAig) + i) ) + Aig_InfoXorBit( p->pPatWords, Saig_ManPiNum(p->pAig) + i ); +} + +/**Function************************************************************* + + Synopsis [Performs fraiging for one node.] + + Description [Returns the fraiged node.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ssw_ManSweepNodeFilter( Ssw_Man_t * p, Aig_Obj_t * pObj, int f ) +{ + Aig_Obj_t * pObjRepr, * pObjFraig, * pObjFraig2, * pObjReprFraig; + int RetValue; + // get representative of this class + pObjRepr = Aig_ObjRepr( p->pAig, pObj ); + if ( pObjRepr == NULL ) + return 0; + // get the fraiged node + pObjFraig = Ssw_ObjFrame( p, pObj, f ); + // get the fraiged representative + pObjReprFraig = Ssw_ObjFrame( p, pObjRepr, f ); + // check if constant 0 pattern distinquishes these nodes + assert( pObjFraig != NULL && pObjReprFraig != NULL ); + assert( (pObj->fPhase == pObjRepr->fPhase) == (Aig_ObjPhaseReal(pObjFraig) == Aig_ObjPhaseReal(pObjReprFraig)) ); + // if the fraiged nodes are the same, return + if ( Aig_Regular(pObjFraig) == Aig_Regular(pObjReprFraig) ) + return 0; + // call equivalence checking + if ( Aig_Regular(pObjFraig) != Aig_ManConst1(p->pFrames) ) + RetValue = Ssw_NodesAreEquiv( p, Aig_Regular(pObjReprFraig), Aig_Regular(pObjFraig) ); + else + RetValue = Ssw_NodesAreEquiv( p, Aig_Regular(pObjFraig), Aig_Regular(pObjReprFraig) ); + if ( RetValue == 1 ) // proved equivalent + { + pObjFraig2 = Aig_NotCond( pObjReprFraig, pObj->fPhase ^ pObjRepr->fPhase ); + Ssw_ObjSetFrame( p, pObj, f, pObjFraig2 ); + return 0; + } + if ( RetValue == -1 ) // timed out + { +// Ssw_ClassesRemoveNode( p->ppClasses, pObj ); + return 1; + } + // disproved equivalence + Ssw_SmlSavePatternAig( p, f ); + Ssw_ManResimulateBit( p, pObj, pObjRepr ); + assert( Aig_ObjRepr( p->pAig, pObj ) != pObjRepr ); + if ( Aig_ObjRepr( p->pAig, pObj ) == pObjRepr ) + { + printf( "Ssw_ManSweepNodeFilter(): Failed to refine representative.\n" ); + } + return 0; +} + +/**Function************************************************************* + + Synopsis [Performs fraiging for the internal nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Ssw_ManSweepBmcFilter_rec( Ssw_Man_t * p, Aig_Obj_t * pObj, int f ) +{ + Aig_Obj_t * pObjNew, * pObjLi; + pObjNew = Ssw_ObjFrame( p, pObj, f ); + if ( pObjNew ) + return pObjNew; + assert( !Saig_ObjIsPi(p->pAig, pObj) ); + if ( Saig_ObjIsLo(p->pAig, pObj) ) + { + assert( f > 0 ); + pObjLi = Saig_ObjLoToLi( p->pAig, pObj ); + pObjNew = Ssw_ManSweepBmcFilter_rec( p, Aig_ObjFanin0(pObjLi), f-1 ); + pObjNew = Aig_NotCond( pObjNew, Aig_ObjFaninC0(pObjLi) ); + } + else + { + assert( Aig_ObjIsNode(pObj) ); + Ssw_ManSweepBmcFilter_rec( p, Aig_ObjFanin0(pObj), f ); + Ssw_ManSweepBmcFilter_rec( p, Aig_ObjFanin1(pObj), f ); + pObjNew = Aig_And( p->pFrames, Ssw_ObjChild0Fra(p, pObj, f), Ssw_ObjChild1Fra(p, pObj, f) ); + } + Ssw_ObjSetFrame( p, pObj, f, pObjNew ); + assert( pObjNew != NULL ); + return pObjNew; +} + +/**Function************************************************************* + + Synopsis [Filter equivalence classes of nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ssw_ManSweepBmcFilter( Ssw_Man_t * p, int TimeLimit ) +{ + Aig_Obj_t * pObj, * pObjNew, * pObjLi, * pObjLo; + int f, f1, i, clkTotal = clock(); + // start initialized timeframes + p->pFrames = Aig_ManStart( Aig_ManObjNumMax(p->pAig) * p->pPars->nFramesK ); + Saig_ManForEachLo( p->pAig, pObj, i ) + { + if ( Aig_InfoHasBit( p->pPatWords, Saig_ManPiNum(p->pAig) + i ) ) + { + Ssw_ObjSetFrame( p, pObj, 0, Aig_ManConst1(p->pFrames) ); +//printf( "1" ); + } + else + { + Ssw_ObjSetFrame( p, pObj, 0, Aig_ManConst0(p->pFrames) ); +//printf( "0" ); + } + } +//printf( "\n" ); + + // sweep internal nodes + for ( f = 0; f < p->pPars->nFramesK; f++ ) + { + // realloc mapping of timeframes + if ( f == p->nFrames-1 ) + { + Aig_Obj_t ** pNodeToFrames; + pNodeToFrames = ABC_CALLOC( Aig_Obj_t *, Aig_ManObjNumMax(p->pAig) * 2 * p->nFrames ); + for ( f1 = 0; f1 < p->nFrames; f1++ ) + { + Aig_ManForEachObj( p->pAig, pObj, i ) + pNodeToFrames[2*p->nFrames*pObj->Id + f1] = Ssw_ObjFrame( p, pObj, f1 ); + } + ABC_FREE( p->pNodeToFrames ); + p->pNodeToFrames = pNodeToFrames; + p->nFrames *= 2; + } + // map constants and PIs + Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), f, Aig_ManConst1(p->pFrames) ); + Saig_ManForEachPi( p->pAig, pObj, i ) + { + pObjNew = Aig_ObjCreatePi(p->pFrames); + Ssw_ObjSetFrame( p, pObj, f, pObjNew ); + } + // sweep internal nodes + Aig_ManForEachNode( p->pAig, pObj, i ) + { + pObjNew = Aig_And( p->pFrames, Ssw_ObjChild0Fra(p, pObj, f), Ssw_ObjChild1Fra(p, pObj, f) ); + Ssw_ObjSetFrame( p, pObj, f, pObjNew ); + if ( Ssw_ManSweepNodeFilter( p, pObj, f ) ) + break; + } + // printout + if ( p->pPars->fVerbose ) + { + printf( "Frame %4d : ", f ); + Ssw_ClassesPrint( p->ppClasses, 0 ); + } + if ( i < Vec_PtrSize(p->pAig->vObjs) ) + { + if ( p->pPars->fVerbose ) + printf( "Exceeded the resource limits (%d conflicts). Quitting...\n", p->pPars->nBTLimit ); + break; + } + // quit if this is the last timeframe + if ( f == p->pPars->nFramesK - 1 ) + { + if ( p->pPars->fVerbose ) + printf( "Exceeded the time frame limit (%d time frames). Quitting...\n", p->pPars->nFramesK ); + break; + } + // check timeout + if ( TimeLimit && ((float)TimeLimit <= (float)(clock()-clkTotal)/(float)(CLOCKS_PER_SEC)) ) + break; + // transfer latch input to the latch outputs + Aig_ManForEachPo( p->pAig, pObj, i ) + Ssw_ObjSetFrame( p, pObj, f, Ssw_ObjChild0Fra(p, pObj, f) ); + // build logic cones for register outputs + Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i ) + { + pObjNew = Ssw_ObjFrame( p, pObjLi, f ); + Ssw_ObjSetFrame( p, pObjLo, f+1, pObjNew ); + Ssw_CnfNodeAddToSolver( p->pMSat, Aig_Regular(pObjNew) );// + } + } + // verify +// Ssw_ClassesCheck( p->ppClasses ); + return 1; +} + +/**Function************************************************************* + + Synopsis [Filter equivalence classes of nodes.] + + Description [Unrolls at most nFramesMax frames. Works with nConfMax + conflicts until the first undefined SAT call. Verbose prints the message.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ssw_SignalFilter( Aig_Man_t * pAig, int nFramesMax, int nConfMax, int nRounds, int TimeLimit, int TimeLimit2, Abc_Cex_t * pCex, int fVerbose ) +{ + Ssw_Pars_t Pars, * pPars = &Pars; + Ssw_Man_t * p; + int r, TimeLimitPart, clkTotal = clock(); + assert( Aig_ManRegNum(pAig) > 0 ); + assert( Aig_ManConstrNum(pAig) == 0 ); + // consider the case of empty AIG + if ( Aig_ManNodeNum(pAig) == 0 ) + return; + // reset random numbers + Aig_ManRandom( 1 ); + // if parameters are not given, create them + Ssw_ManSetDefaultParams( pPars = &Pars ); + pPars->nFramesK = 3; //nFramesMax; + pPars->nBTLimit = nConfMax; + pPars->TimeLimit = TimeLimit; + pPars->fVerbose = fVerbose; + // start the induction manager + p = Ssw_ManCreate( pAig, pPars ); + pPars->nFramesK = nFramesMax; + // create trivial equivalence classes with all nodes being candidates for constant 1 + if ( pAig->pReprs == NULL ) + p->ppClasses = Ssw_ClassesPrepareSimple( pAig, 0, 0 ); + else + p->ppClasses = Ssw_ClassesPrepareFromReprs( pAig ); + Ssw_ClassesSetData( p->ppClasses, NULL, NULL, Ssw_SmlObjIsConstBit, Ssw_SmlObjsAreEqualBit ); + assert( p->vInits == NULL ); + // compute starting state if needed + if ( pCex ) + Ssw_ManFindStartingState( p, pCex ); + // refine classes using BMC + for ( r = 0; r < nRounds; r++ ) + { + if ( p->pPars->fVerbose ) + printf( "Round %3d:\n", r ); + // start filtering equivalence classes + Ssw_ManRefineByFilterSim( p, p->pPars->nFramesK ); + if ( Ssw_ClassesCand1Num(p->ppClasses) == 0 && Ssw_ClassesClassNum(p->ppClasses) == 0 ) + { + printf( "All equivalences are refined away.\n" ); + break; + } + // printout + if ( p->pPars->fVerbose ) + { + printf( "Initial : " ); + Ssw_ClassesPrint( p->ppClasses, 0 ); + } + p->pMSat = Ssw_SatStart( 0 ); + TimeLimitPart = TimeLimit ? TimeLimit - (int)((float)(clock()-clkTotal)/(float)(CLOCKS_PER_SEC)) : 0; + if ( TimeLimit2 ) + { + if ( TimeLimitPart ) + TimeLimitPart = ABC_MIN( TimeLimitPart, TimeLimit2 ); + else + TimeLimitPart = TimeLimit2; + } + Ssw_ManSweepBmcFilter( p, TimeLimitPart ); + Ssw_SatStop( p->pMSat ); + p->pMSat = NULL; + Ssw_ManCleanup( p ); + // simulate pattern forward + Ssw_ManRollForward( p, p->pPars->nFramesK ); + // check timeout + if ( TimeLimit && ((float)TimeLimit <= (float)(clock()-clkTotal)/(float)(CLOCKS_PER_SEC)) ) + { + printf( "Reached timeout (%d seconds).\n", TimeLimit ); + break; + } + } + // cleanup + Aig_ManSetPhase( p->pAig ); + Aig_ManCleanMarkB( p->pAig ); + // cleanup + pPars->fVerbose = 0; + Ssw_ManStop( p ); +} + +/**Function************************************************************* + + Synopsis [Filter equivalence classes of nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ssw_SignalFilterGia( Gia_Man_t * p, int nFramesMax, int nConfMax, int nRounds, int TimeLimit, int TimeLimit2, Abc_Cex_t * pCex, int fVerbose ) +{ + Aig_Man_t * pAig; + pAig = Gia_ManToAigSimple( p ); + if ( p->pReprs != NULL ) + { + Gia_ManReprToAigRepr2( pAig, p ); + ABC_FREE( p->pReprs ); + ABC_FREE( p->pNexts ); + } + Ssw_SignalFilter( pAig, nFramesMax, nConfMax, nRounds, TimeLimit, TimeLimit2, pCex, fVerbose ); + Gia_ManReprFromAigRepr( pAig, p ); + Aig_ManStop( pAig ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ssw/sswInt.h b/src/aig/ssw/sswInt.h index 269bdad7..e3a9a341 100644 --- a/src/aig/ssw/sswInt.h +++ b/src/aig/ssw/sswInt.h @@ -21,6 +21,7 @@ #ifndef __SSW_INT_H__ #define __SSW_INT_H__ + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -33,9 +34,10 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -93,6 +95,7 @@ struct Ssw_Man_t_ int iNodeLast; // the last node considered Vec_Ptr_t * vResimConsts; // resimulation constants Vec_Ptr_t * vResimClasses; // resimulation classes + Vec_Int_t * vInits; // the init values of primary inputs under constraints // counter example storage int nPatWords; // the number of words in the counter example unsigned * pPatWords; // the counter example @@ -113,6 +116,15 @@ struct Ssw_Man_t_ int nNodesEnd; int nRegsBeg; int nRegsEnd; + // equiv statistis + int nConesTotal; + int nConesConstr; + int nEquivsTotal; + int nEquivsConstr; + int nNodesBegC; + int nNodesEndC; + int nRegsBegC; + int nRegsEndC; // runtime stats int timeBmc; // bounded model checking int timeReduce; // speculative reduction @@ -172,7 +184,7 @@ static inline void Ssw_ObjSetFrame( Ssw_Man_t * p, Aig_Obj_t * pObj, int static inline Aig_Obj_t * Ssw_ObjChild0Fra( Ssw_Man_t * p, Aig_Obj_t * pObj, int i ) { assert( !Aig_IsComplement(pObj) ); return Aig_ObjFanin0(pObj)? Aig_NotCond(Ssw_ObjFrame(p, Aig_ObjFanin0(pObj), i), Aig_ObjFaninC0(pObj)) : NULL; } static inline Aig_Obj_t * Ssw_ObjChild1Fra( Ssw_Man_t * p, Aig_Obj_t * pObj, int i ) { assert( !Aig_IsComplement(pObj) ); return Aig_ObjFanin1(pObj)? Aig_NotCond(Ssw_ObjFrame(p, Aig_ObjFanin1(pObj), i), Aig_ObjFaninC1(pObj)) : NULL; } -static inline Aig_Obj_t * Ssw_ObjFrame_( Ssw_Frm_t * p, Aig_Obj_t * pObj, int i ) { return Vec_PtrGetEntry( p->vAig2Frm, p->nObjs*i+pObj->Id ); } +static inline Aig_Obj_t * Ssw_ObjFrame_( Ssw_Frm_t * p, Aig_Obj_t * pObj, int i ) { return (Aig_Obj_t *)Vec_PtrGetEntry( p->vAig2Frm, p->nObjs*i+pObj->Id ); } static inline void Ssw_ObjSetFrame_( Ssw_Frm_t * p, Aig_Obj_t * pObj, int i, Aig_Obj_t * pNode ) { Vec_PtrSetEntry( p->vAig2Frm, p->nObjs*i+pObj->Id, pNode ); } static inline Aig_Obj_t * Ssw_ObjChild0Fra_( Ssw_Frm_t * p, Aig_Obj_t * pObj, int i ) { assert( !Aig_IsComplement(pObj) ); return Aig_ObjFanin0(pObj)? Aig_NotCond(Ssw_ObjFrame_(p, Aig_ObjFanin0(pObj), i), Aig_ObjFaninC0(pObj)) : NULL; } @@ -206,8 +218,9 @@ extern void Ssw_ClassesCollectClass( Ssw_Cla_t * p, Aig_Obj_t * pRepr, extern void Ssw_ClassesCheck( Ssw_Cla_t * p ); extern void Ssw_ClassesPrint( Ssw_Cla_t * p, int fVeryVerbose ); extern void Ssw_ClassesRemoveNode( Ssw_Cla_t * p, Aig_Obj_t * pObj ); -extern Ssw_Cla_t * Ssw_ClassesPrepare( Aig_Man_t * pAig, int nFramesK, int fLatchCorr, int nMaxLevs, int fVerbose ); +extern Ssw_Cla_t * Ssw_ClassesPrepare( Aig_Man_t * pAig, int nFramesK, int fLatchCorr, int fOutputCorr, int nMaxLevs, int fVerbose ); extern Ssw_Cla_t * Ssw_ClassesPrepareSimple( Aig_Man_t * pAig, int fLatchCorr, int nMaxLevs ); +extern Ssw_Cla_t * Ssw_ClassesPrepareFromReprs( Aig_Man_t * pAig ); extern Ssw_Cla_t * Ssw_ClassesPrepareTargets( Aig_Man_t * pAig ); extern Ssw_Cla_t * Ssw_ClassesPreparePairs( Aig_Man_t * pAig, Vec_Int_t ** pvClasses ); extern Ssw_Cla_t * Ssw_ClassesPreparePairsSimple( Aig_Man_t * pMiter, Vec_Int_t * vPairs ); @@ -220,6 +233,10 @@ extern Ssw_Sat_t * Ssw_SatStart( int fPolarFlip ); extern void Ssw_SatStop( Ssw_Sat_t * p ); extern void Ssw_CnfNodeAddToSolver( Ssw_Sat_t * p, Aig_Obj_t * pObj ); extern int Ssw_CnfGetNodeValue( Ssw_Sat_t * p, Aig_Obj_t * pObjFraig ); +/*=== sswConstr.c ===================================================*/ +extern int Ssw_ManSweepBmcConstr( Ssw_Man_t * p ); +extern int Ssw_ManSweepConstr( Ssw_Man_t * p ); +extern void Ssw_ManRefineByConstrSim( Ssw_Man_t * p ); /*=== sswCore.c ===================================================*/ extern Aig_Man_t * Ssw_SignalCorrespondenceRefine( Ssw_Man_t * p ); /*=== sswDyn.c ===================================================*/ @@ -231,10 +248,10 @@ extern int Ssw_ManSweepLatch( Ssw_Man_t * p ); extern Ssw_Man_t * Ssw_ManCreate( Aig_Man_t * pAig, Ssw_Pars_t * pPars ); extern void Ssw_ManCleanup( Ssw_Man_t * p ); extern void Ssw_ManStop( Ssw_Man_t * p ); -extern void Ssw_ManStartSolver( Ssw_Man_t * p ); /*=== sswSat.c ===================================================*/ extern int Ssw_NodesAreEquiv( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew ); extern int Ssw_NodesAreConstrained( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew ); +extern int Ssw_NodeIsConstrained( Ssw_Man_t * p, Aig_Obj_t * pPoObj ); /*=== sswSemi.c ===================================================*/ extern int Ssw_FilterUsingSemi( Ssw_Man_t * pMan, int fCheckTargets, int nConfMax, int fVerbose ); /*=== sswSim.c ===================================================*/ @@ -259,6 +276,7 @@ extern void Ssw_ManResimulateBit( Ssw_Man_t * p, Aig_Obj_t * pObj, Aig_ extern void Ssw_ManResimulateWord( Ssw_Man_t * p, Aig_Obj_t * pCand, Aig_Obj_t * pRepr, int f ); /*=== sswSweep.c ===================================================*/ extern int Ssw_ManGetSatVarValue( Ssw_Man_t * p, Aig_Obj_t * pObj, int f ); +extern void Ssw_SmlSavePatternAig( Ssw_Man_t * p, int f ); extern int Ssw_ManSweepNode( Ssw_Man_t * p, Aig_Obj_t * pObj, int f, int fBmc ); extern int Ssw_ManSweepBmc( Ssw_Man_t * p ); extern int Ssw_ManSweep( Ssw_Man_t * p ); @@ -267,9 +285,11 @@ extern void Ssw_UniqueRegisterPairInfo( Ssw_Man_t * p ); extern int Ssw_ManUniqueOne( Ssw_Man_t * p, Aig_Obj_t * pRepr, Aig_Obj_t * pObj, int fVerbose ); extern int Ssw_ManUniqueAddConstraint( Ssw_Man_t * p, Vec_Ptr_t * vCommon, int f1, int f2 ); -#ifdef __cplusplus -} -#endif + + +ABC_NAMESPACE_HEADER_END + + #endif diff --git a/src/aig/ssw/sswIslands.c b/src/aig/ssw/sswIslands.c index 8913116c..d1ebe4bc 100644 --- a/src/aig/ssw/sswIslands.c +++ b/src/aig/ssw/sswIslands.c @@ -20,6 +20,9 @@ #include "sswInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -99,7 +102,7 @@ void Ssw_MatchingStart( Aig_Man_t * p0, Aig_Man_t * p1, Vec_Int_t * vPairs ) { if ( pObj0->pData == NULL ) continue; - pObj1 = pObj0->pData; + pObj1 = (Aig_Obj_t *)pObj0->pData; if ( !Saig_ObjIsLo(p1, pObj1) ) printf( "Mismatch between LO pairs.\n" ); } @@ -107,7 +110,7 @@ void Ssw_MatchingStart( Aig_Man_t * p0, Aig_Man_t * p1, Vec_Int_t * vPairs ) { if ( pObj1->pData == NULL ) continue; - pObj0 = pObj1->pData; + pObj0 = (Aig_Obj_t *)pObj1->pData; if ( !Saig_ObjIsLo(p0, pObj0) ) printf( "Mismatch between LO pairs.\n" ); } @@ -234,9 +237,9 @@ void Ssw_MatchingExtend( Aig_Man_t * p0, Aig_Man_t * p1, int nDist, int fVerbose { Ssw_MatchingExtendOne( p0, vNodes0 ); Ssw_MatchingExtendOne( p1, vNodes1 ); - Vec_PtrForEachEntry( vNodes0, pNext0, k ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes0, pNext0, k ) { - pNext1 = pNext0->pData; + pNext1 = (Aig_Obj_t *)pNext0->pData; if ( pNext1 == NULL ) continue; assert( pNext1->pData == pNext0 ); @@ -245,9 +248,9 @@ void Ssw_MatchingExtend( Aig_Man_t * p0, Aig_Man_t * p1, int nDist, int fVerbose pNext0->pData = NULL; pNext1->pData = NULL; } - Vec_PtrForEachEntry( vNodes1, pNext0, k ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNodes1, pNext0, k ) { - pNext1 = pNext0->pData; + pNext1 = (Aig_Obj_t *)pNext0->pData; if ( pNext1 == NULL ) continue; assert( pNext1->pData == pNext0 ); @@ -307,7 +310,7 @@ void Ssw_MatchingComplete( Aig_Man_t * p0, Aig_Man_t * p1 ) pObj1->pData = pObj0; } // create register outputs in p0 that are absent in p1 - Vec_PtrForEachEntry( vNewLis, pObj0Li, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vNewLis, pObj0Li, i ) Aig_ObjCreatePo( p1, Aig_ObjChild0Copy(pObj0Li) ); // increment the number of registers Aig_ManSetRegNum( p1, Aig_ManRegNum(p1) + Vec_PtrSize(vNewLis) ); @@ -342,7 +345,7 @@ Vec_Int_t * Ssw_MatchingPairs( Aig_Man_t * p0, Aig_Man_t * p1 ) { if ( Aig_ObjIsPo(pObj0) ) continue; - pObj1 = pObj0->pData; + pObj1 = (Aig_Obj_t *)pObj0->pData; Vec_IntPush( vPairsNew, pObj0->Id ); Vec_IntPush( vPairsNew, pObj1->Id ); } @@ -379,11 +382,11 @@ Vec_Int_t * Ssw_MatchingMiter( Aig_Man_t * pMiter, Aig_Man_t * p0, Aig_Man_t * p assert( pObj1->pData != NULL ); if ( pObj0->pData == pObj1->pData ) continue; - if ( Aig_ObjIsNone(pObj0->pData) || Aig_ObjIsNone(pObj1->pData) ) + if ( Aig_ObjIsNone((Aig_Obj_t *)pObj0->pData) || Aig_ObjIsNone((Aig_Obj_t *)pObj1->pData) ) continue; // get the miter nodes - pObj0 = pObj0->pData; - pObj1 = pObj1->pData; + pObj0 = (Aig_Obj_t *)pObj0->pData; + pObj1 = (Aig_Obj_t *)pObj1->pData; assert( !Aig_IsComplement(pObj0) ); assert( !Aig_IsComplement(pObj1) ); assert( Aig_ObjType(pObj0) == Aig_ObjType(pObj1) ); @@ -435,7 +438,7 @@ Aig_Man_t * Ssw_SecWithSimilaritySweep( Aig_Man_t * p0, Aig_Man_t * p1, Vec_Int_ if ( p->pPars->fPartSigCorr ) p->ppClasses = Ssw_ClassesPreparePairsSimple( pMiter, vPairsMiter ); else - p->ppClasses = Ssw_ClassesPrepare( pMiter, pPars->nFramesK, pPars->fLatchCorr, pPars->nMaxLevs, pPars->fVerbose ); + p->ppClasses = Ssw_ClassesPrepare( pMiter, pPars->nFramesK, pPars->fLatchCorr, pPars->fOutputCorr, pPars->nMaxLevs, pPars->fVerbose ); if ( p->pPars->fDumpSRInit ) { if ( p->pPars->fPartSigCorr ) @@ -449,7 +452,7 @@ Aig_Man_t * Ssw_SecWithSimilaritySweep( Aig_Man_t * p0, Aig_Man_t * p1, Vec_Int_ printf( "Dumping speculative miter is possible only for partial signal correspondence (switch \"-c\").\n" ); } p->pSml = Ssw_SmlStart( pMiter, 0, 1 + p->pPars->nFramesAddSim, 1 ); - Ssw_ClassesSetData( p->ppClasses, p->pSml, Ssw_SmlObjHashWord, Ssw_SmlObjIsConstWord, Ssw_SmlObjsAreEqualWord ); + Ssw_ClassesSetData( p->ppClasses, p->pSml, (unsigned(*)(void *,Aig_Obj_t *))Ssw_SmlObjHashWord, (int(*)(void *,Aig_Obj_t *))Ssw_SmlObjIsConstWord, (int(*)(void *,Aig_Obj_t *,Aig_Obj_t *))Ssw_SmlObjsAreEqualWord ); // perform refinement of classes pAigNew = Ssw_SignalCorrespondenceRefine( p ); // cleanup @@ -591,3 +594,5 @@ int Ssw_SecWithSimilarity( Aig_Man_t * p0, Aig_Man_t * p1, Ssw_Pars_t * pPars ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ssw/sswLcorr.c b/src/aig/ssw/sswLcorr.c index fb36c31d..7cd94727 100644 --- a/src/aig/ssw/sswLcorr.c +++ b/src/aig/ssw/sswLcorr.c @@ -21,6 +21,9 @@ #include "sswInt.h" //#include "bar.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -56,7 +59,7 @@ void Ssw_ManSweepTransfer( Ssw_Man_t * p ) } assert( !Aig_IsComplement(pObjFraig) ); assert( Aig_ObjIsPi(pObjFraig) ); - pInfo = Vec_PtrEntry( p->vSimInfo, Aig_ObjPioNum(pObjFraig) ); + pInfo = (unsigned *)Vec_PtrEntry( p->vSimInfo, Aig_ObjPioNum(pObjFraig) ); Ssw_SmlObjSetWord( p->pSml, pObj, pInfo[0], 0, 0 ); } } @@ -106,14 +109,14 @@ void Ssw_SmlAddPattern( Ssw_Man_t * p, Aig_Obj_t * pRepr, Aig_Obj_t * pCand ) Aig_Obj_t * pObj; unsigned * pInfo; int i, nVarNum, Value; - Vec_PtrForEachEntry( p->pMSat->vUsedPis, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->pMSat->vUsedPis, pObj, i ) { nVarNum = Ssw_ObjSatNum( p->pMSat, pObj ); assert( nVarNum > 0 ); Value = sat_solver_var_value( p->pMSat->pSat, nVarNum ); if ( Value == 0 ) continue; - pInfo = Vec_PtrEntry( p->vSimInfo, Aig_ObjPioNum(pObj) ); + pInfo = (unsigned *)Vec_PtrEntry( p->vSimInfo, Aig_ObjPioNum(pObj) ); Aig_InfoSetBit( pInfo, p->nPatterns ); } } @@ -284,7 +287,7 @@ int Ssw_ManSweepLatch( Ssw_Man_t * p ) if ( Vec_PtrSize(vClass) == 0 ) continue; // try to prove equivalences in this class - Vec_PtrForEachEntry( vClass, pTemp, k ) + Vec_PtrForEachEntry( Aig_Obj_t *, vClass, pTemp, k ) if ( Aig_ObjRepr(p->pAig, pTemp) == pObj ) { Ssw_ManSweepLatchOne( p, pObj, pTemp ); @@ -329,3 +332,5 @@ int Ssw_ManSweepLatch( Ssw_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ssw/sswMan.c b/src/aig/ssw/sswMan.c index 90cc9028..0f1317e1 100644 --- a/src/aig/ssw/sswMan.c +++ b/src/aig/ssw/sswMan.c @@ -20,6 +20,9 @@ #include "sswInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -57,13 +60,12 @@ Ssw_Man_t * Ssw_ManCreate( Aig_Man_t * pAig, Ssw_Pars_t * pPars ) p->iOutputLit = -1; // allocate storage for sim pattern p->nPatWords = Aig_BitWordNum( Saig_ManPiNum(pAig) * p->nFrames + Saig_ManRegNum(pAig) ); - p->pPatWords = ABC_ALLOC( unsigned, p->nPatWords ); + p->pPatWords = ABC_CALLOC( unsigned, p->nPatWords ); // other p->vNewLos = Vec_PtrAlloc( 100 ); p->vNewPos = Vec_IntAlloc( 100 ); p->vResimConsts = Vec_PtrAlloc( 100 ); p->vResimClasses = Vec_PtrAlloc( 100 ); - // p->pPars->fVerbose = 1; return p; } @@ -104,10 +106,10 @@ void Ssw_ManPrintStats( Ssw_Man_t * p ) double nMemory = 1.0*Aig_ManObjNumMax(p->pAig)*p->nFrames*(2*sizeof(int)+2*sizeof(void*))/(1<<20); printf( "Parameters: F = %d. AddF = %d. C-lim = %d. Constr = %d. MaxLev = %d. Mem = %0.2f Mb.\n", - p->pPars->nFramesK, p->pPars->nFramesAddSim, p->pPars->nBTLimit, p->pPars->nConstrs, p->pPars->nMaxLevs, nMemory ); + p->pPars->nFramesK, p->pPars->nFramesAddSim, p->pPars->nBTLimit, Saig_ManConstrNum(p->pAig), p->pPars->nMaxLevs, nMemory ); printf( "AIG : PI = %d. PO = %d. Latch = %d. Node = %d. Ave SAT vars = %d.\n", Saig_ManPiNum(p->pAig), Saig_ManPoNum(p->pAig), Saig_ManRegNum(p->pAig), Aig_ManNodeNum(p->pAig), - 0/p->pPars->nIters ); + 0/(p->pPars->nIters+1) ); printf( "SAT calls : Proof = %d. Cex = %d. Fail = %d. Lits proved = %d.\n", p->nSatProof, p->nSatCallsSat, p->nSatFailsReal, Ssw_ManCountEquivs(p) ); printf( "SAT solver: Vars max = %d. Calls max = %d. Recycles = %d. Sim rounds = %d.\n", @@ -127,6 +129,19 @@ void Ssw_ManPrintStats( Ssw_Man_t * p ) ABC_PRTP( " undecided", p->timeSatUndec, p->timeTotal ); ABC_PRTP( "Other ", p->timeOther, p->timeTotal ); ABC_PRTP( "TOTAL ", p->timeTotal, p->timeTotal ); + + // report the reductions + if ( p->pAig->nConstrs ) + { + printf( "Statistics reflecting the use of constraints:\n" ); + printf( "Total cones = %6d. Constraint cones = %6d. (%6.2f %%)\n", + p->nConesTotal, p->nConesConstr, 100.0*p->nConesConstr/p->nConesTotal ); + printf( "Total equivs = %6d. Removed equivs = %6d. (%6.2f %%)\n", + p->nEquivsTotal, p->nEquivsConstr, 100.0*p->nEquivsConstr/p->nEquivsTotal ); + printf( "NBeg = %d. NEnd = %d. (Gain = %6.2f %%). RBeg = %d. REnd = %d. (Gain = %6.2f %%).\n", + p->nNodesBegC, p->nNodesEndC, 100.0*(p->nNodesBegC-p->nNodesEndC)/(p->nNodesBegC?p->nNodesBegC:1), + p->nRegsBegC, p->nRegsEndC, 100.0*(p->nRegsBegC-p->nRegsEndC)/(p->nRegsBegC?p->nRegsBegC:1) ); + } } /**Function************************************************************* @@ -174,7 +189,7 @@ void Ssw_ManCleanup( Ssw_Man_t * p ) void Ssw_ManStop( Ssw_Man_t * p ) { ABC_FREE( p->pVisited ); - if ( p->pPars->fVerbose ) + if ( p->pPars->fVerbose )//&& p->pPars->nStepsMax == -1 ) Ssw_ManPrintStats( p ); if ( p->ppClasses ) Ssw_ClassesStop( p->ppClasses ); @@ -182,6 +197,8 @@ void Ssw_ManStop( Ssw_Man_t * p ) Ssw_SmlStop( p->pSml ); if ( p->vDiffPairs ) Vec_IntFree( p->vDiffPairs ); + if ( p->vInits ) + Vec_IntFree( p->vInits ); Vec_PtrFree( p->vResimConsts ); Vec_PtrFree( p->vResimClasses ); Vec_PtrFree( p->vNewLos ); @@ -197,3 +214,5 @@ void Ssw_ManStop( Ssw_Man_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ssw/sswPairs.c b/src/aig/ssw/sswPairs.c index 3c079922..0aba942f 100644 --- a/src/aig/ssw/sswPairs.c +++ b/src/aig/ssw/sswPairs.c @@ -20,6 +20,9 @@ #include "sswInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -113,8 +116,8 @@ Vec_Int_t * Ssw_TransferSignalPairs( Aig_Man_t * pMiter, Aig_Man_t * pAig1, Aig_ { pObj1 = Aig_ManObj( pAig1, Vec_IntEntry(vIds1, i) ); pObj2 = Aig_ManObj( pAig2, Vec_IntEntry(vIds2, i) ); - pObj1m = Aig_Regular(pObj1->pData); - pObj2m = Aig_Regular(pObj2->pData); + pObj1m = Aig_Regular((Aig_Obj_t *)pObj1->pData); + pObj2m = Aig_Regular((Aig_Obj_t *)pObj2->pData); assert( pObj1m && pObj2m ); if ( pObj1m == pObj2m ) continue; @@ -290,7 +293,7 @@ Aig_Man_t * Ssw_SignalCorrespondenceWithPairs( Aig_Man_t * pAig1, Aig_Man_t * pA // create equivalence classes using these IDs p->ppClasses = Ssw_ClassesPreparePairs( pMiter, pvClasses ); p->pSml = Ssw_SmlStart( pMiter, 0, p->nFrames + p->pPars->nFramesAddSim, 1 ); - Ssw_ClassesSetData( p->ppClasses, p->pSml, Ssw_SmlObjHashWord, Ssw_SmlObjIsConstWord, Ssw_SmlObjsAreEqualWord ); + Ssw_ClassesSetData( p->ppClasses, p->pSml, (unsigned(*)(void *,Aig_Obj_t *))Ssw_SmlObjHashWord, (int(*)(void *,Aig_Obj_t *))Ssw_SmlObjIsConstWord, (int(*)(void *,Aig_Obj_t *,Aig_Obj_t *))Ssw_SmlObjsAreEqualWord ); // perform refinement of classes pAigNew = Ssw_SignalCorrespondenceRefine( p ); // cleanup @@ -326,7 +329,7 @@ Aig_Man_t * Ssw_SignalCorrespondeceTestPairs( Aig_Man_t * pAig ) vIds2 = Vec_IntAlloc( Aig_ManObjNumMax(pAig) ); Aig_ManForEachObj( pAig, pObj, i ) { - pRepr = Aig_Regular(pObj->pData); + pRepr = Aig_Regular((Aig_Obj_t *)pObj->pData); if ( pRepr == NULL ) continue; if ( Aig_ManObj(pAigNew, pRepr->Id) == NULL ) @@ -470,3 +473,5 @@ int Ssw_SecGeneralMiter( Aig_Man_t * pMiter, Ssw_Pars_t * pPars ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ssw/sswPart.c b/src/aig/ssw/sswPart.c index f481b457..8a0e69da 100644 --- a/src/aig/ssw/sswPart.c +++ b/src/aig/ssw/sswPart.c @@ -19,6 +19,10 @@ ***********************************************************************/ #include "sswInt.h" +#include "ioa.h" + +ABC_NAMESPACE_IMPL_START + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// @@ -50,16 +54,20 @@ Aig_Man_t * Ssw_SignalCorrespondencePart( Aig_Man_t * pAig, Ssw_Pars_t * pPars ) int i, nCountPis, nCountRegs; int nClasses, nPartSize, fVerbose; int clk = clock(); - + if ( pPars->fConstrs ) + { + printf( "Cannot use partitioned computation with constraints.\n" ); + return NULL; + } // save parameters nPartSize = pPars->nPartSize; pPars->nPartSize = 0; - fVerbose = pPars->fVerbose; pPars->fVerbose = 0; + fVerbose = pPars->fVerbose; pPars->fVerbose = 0; // generate partitions if ( pAig->vClockDoms ) { // divide large clock domains into separate partitions vResult = Vec_PtrAlloc( 100 ); - Vec_PtrForEachEntry( (Vec_Ptr_t *)pAig->vClockDoms, vPart, i ) + Vec_PtrForEachEntry( Vec_Int_t *, (Vec_Ptr_t *)pAig->vClockDoms, vPart, i ) { if ( nPartSize && Vec_IntSize(vPart) > nPartSize ) Aig_ManPartDivide( vResult, vPart, nPartSize, pPars->nOverSize ); @@ -75,9 +83,9 @@ Aig_Man_t * Ssw_SignalCorrespondencePart( Aig_Man_t * pAig, Ssw_Pars_t * pPars ) { // print partitions printf( "Simple partitioning. %d partitions are saved:\n", Vec_PtrSize(vResult) ); - Vec_PtrForEachEntry( vResult, vPart, i ) + Vec_PtrForEachEntry( Vec_Int_t *, vResult, vPart, i ) { - extern void Ioa_WriteAiger( Aig_Man_t * pMan, char * pFileName, int fWriteSymbols, int fCompact ); +// extern void Ioa_WriteAiger( Aig_Man_t * pMan, char * pFileName, int fWriteSymbols, int fCompact ); sprintf( Buffer, "part%03d.aig", i ); pTemp = Aig_ManRegCreatePart( pAig, vPart, &nCountPis, &nCountRegs, NULL ); Ioa_WriteAiger( pTemp, Buffer, 0, 0 ); @@ -89,7 +97,7 @@ Aig_Man_t * Ssw_SignalCorrespondencePart( Aig_Man_t * pAig, Ssw_Pars_t * pPars ) // perform SSW with partitions Aig_ManReprStart( pAig, Aig_ManObjNumMax(pAig) ); - Vec_PtrForEachEntry( vResult, vPart, i ) + Vec_PtrForEachEntry( Vec_Int_t *, vResult, vPart, i ) { pTemp = Aig_ManRegCreatePart( pAig, vPart, &nCountPis, &nCountRegs, &pMapBack ); Aig_ManSetRegNum( pTemp, pTemp->nRegs ); @@ -129,3 +137,5 @@ Aig_Man_t * Ssw_SignalCorrespondencePart( Aig_Man_t * pAig, Ssw_Pars_t * pPars ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ssw/sswSat.c b/src/aig/ssw/sswSat.c index 21c5c1f1..7d371cac 100644 --- a/src/aig/ssw/sswSat.c +++ b/src/aig/ssw/sswSat.c @@ -20,6 +20,9 @@ #include "sswInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -50,9 +53,6 @@ int Ssw_NodesAreEquiv( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew ) assert( !Aig_IsComplement(pOld) ); assert( !Aig_IsComplement(pNew) ); assert( pOld != pNew ); - -// if ( p->pSat == NULL ) -// Ssw_ManStartSolver( p ); assert( p->pMSat != NULL ); // if the nodes do not have SAT variables, allocate them @@ -199,7 +199,7 @@ int Ssw_NodesAreConstrained( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew ) // sanity checks assert( Aig_Regular(pOld) != Aig_Regular(pNew) ); - assert( Aig_ObjPhaseReal(pOld) == Aig_ObjPhaseReal(pNew) ); + assert( p->pPars->fConstrs || Aig_ObjPhaseReal(pOld) == Aig_ObjPhaseReal(pNew) ); // move constant to the old node if ( Aig_Regular(pNew) == Aig_ManConst1(p->pFrames) ) @@ -216,9 +216,6 @@ int Ssw_NodesAreConstrained( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew ) pOld = Aig_Regular(pOld); pNew = Aig_Not(pNew); } - -// if ( p->pSat == NULL ) -// Ssw_ManStartSolver( p ); assert( p->pMSat != NULL ); // if the nodes do not have SAT variables, allocate them @@ -274,8 +271,36 @@ int Ssw_NodesAreConstrained( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew ) return 1; } +/**Function************************************************************* + + Synopsis [Constrains one node in the SAT solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ssw_NodeIsConstrained( Ssw_Man_t * p, Aig_Obj_t * pPoObj ) +{ + int RetValue, Lit; + Ssw_CnfNodeAddToSolver( p->pMSat, Aig_ObjFanin0(pPoObj) ); + // add constraint A = 1 ----> A + Lit = toLitCond( Ssw_ObjSatNum(p->pMSat,Aig_ObjFanin0(pPoObj)), !Aig_ObjFaninC0(pPoObj) ); + if ( p->pPars->fPolarFlip ) + { + if ( Aig_ObjFanin0(pPoObj)->fPhase ) Lit = lit_neg( Lit ); + } + RetValue = sat_solver_addclause( p->pMSat->pSat, &Lit, &Lit + 1 ); + assert( RetValue ); + return 1; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ssw/sswSemi.c b/src/aig/ssw/sswSemi.c index 1d578291..dfb2fb0f 100644 --- a/src/aig/ssw/sswSemi.c +++ b/src/aig/ssw/sswSemi.c @@ -20,6 +20,9 @@ #include "sswInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -127,7 +130,7 @@ int Ssw_SemCheckTargets( Ssw_Sem_t * p ) { Aig_Obj_t * pObj; int i; - Vec_PtrForEachEntry( p->vTargets, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vTargets, pObj, i ) if ( !Ssw_ObjIsConst1Cand(p->pMan->pAig, pObj) ) return 1; return 0; @@ -153,7 +156,7 @@ void Ssw_ManFilterBmcSavePattern( Ssw_Sem_t * p ) return; Saig_ManForEachLo( p->pMan->pAig, pObj, i ) { - pInfo = Vec_PtrEntry( p->vPatterns, i ); + pInfo = (unsigned *)Vec_PtrEntry( p->vPatterns, i ); if ( Aig_InfoHasBit( p->pMan->pPatWords, Saig_ManPiNum(p->pMan->pAig) + i ) ) Aig_InfoSetBit( pInfo, p->nPatterns ); } @@ -183,7 +186,7 @@ clk = clock(); p->pFrames = Aig_ManStart( Aig_ManObjNumMax(p->pAig) * 3 ); Saig_ManForEachLo( p->pAig, pObj, i ) { - pInfo = Vec_PtrEntry( pBmc->vPatterns, i ); + pInfo = (unsigned *)Vec_PtrEntry( pBmc->vPatterns, i ); pObjNew = Aig_NotCond( Aig_ManConst1(p->pFrames), !Aig_InfoHasBit(pInfo, iPat) ); Ssw_ObjSetFrame( p, pObj, 0, pObjNew ); } @@ -315,3 +318,5 @@ clk = clock(); //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ssw/sswSim.c b/src/aig/ssw/sswSim.c index cf5270dd..37bf5717 100644 --- a/src/aig/ssw/sswSim.c +++ b/src/aig/ssw/sswSim.c @@ -20,6 +20,9 @@ #include "sswInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -349,7 +352,7 @@ int Ssw_SmlNodeCountOnesRealVec( Ssw_Sml_t * p, Vec_Ptr_t * vObjs ) for ( i = 0; i < p->nWordsTotal; i++ ) { uWord = 0; - Vec_PtrForEachEntry( vObjs, pObj, k ) + Vec_PtrForEachEntry( Aig_Obj_t *, vObjs, pObj, k ) { pSims = Ssw_ObjSim(p, Aig_Regular(pObj)->Id); if ( Aig_Regular(pObj)->fPhase ^ Aig_IsComplement(pObj) ) @@ -858,7 +861,7 @@ void Ssw_SmlInitialize( Ssw_Sml_t * p, int fInit ) if ( fInit ) { assert( Aig_ManRegNum(p->pAig) > 0 ); - assert( Aig_ManRegNum(p->pAig) < Aig_ManPiNum(p->pAig) ); + assert( Aig_ManRegNum(p->pAig) <= Aig_ManPiNum(p->pAig) ); // assign random info for primary inputs Saig_ManForEachPi( p->pAig, pObj, i ) Ssw_SmlAssignRandom( p, pObj ); @@ -1240,12 +1243,12 @@ unsigned * Ssw_SmlSimInfo( Ssw_Sml_t * p, Aig_Obj_t * pObj ) SeeAlso [] ***********************************************************************/ -Ssw_Cex_t * Ssw_SmlAllocCounterExample( int nRegs, int nRealPis, int nFrames ) +Abc_Cex_t * Ssw_SmlAllocCounterExample( int nRegs, int nRealPis, int nFrames ) { - Ssw_Cex_t * pCex; + Abc_Cex_t * pCex; int nWords = Aig_BitWordNum( nRegs + nRealPis * nFrames ); - pCex = (Ssw_Cex_t *)ABC_ALLOC( char, sizeof(Ssw_Cex_t) + sizeof(unsigned) * nWords ); - memset( pCex, 0, sizeof(Ssw_Cex_t) + sizeof(unsigned) * nWords ); + pCex = (Abc_Cex_t *)ABC_ALLOC( char, sizeof(Abc_Cex_t) + sizeof(unsigned) * nWords ); + memset( pCex, 0, sizeof(Abc_Cex_t) + sizeof(unsigned) * nWords ); pCex->nRegs = nRegs; pCex->nPis = nRealPis; pCex->nBits = nRegs + nRealPis * nFrames; @@ -1263,7 +1266,7 @@ Ssw_Cex_t * Ssw_SmlAllocCounterExample( int nRegs, int nRealPis, int nFrames ) SeeAlso [] ***********************************************************************/ -void Ssw_SmlFreeCounterExample( Ssw_Cex_t * pCex ) +void Ssw_SmlFreeCounterExample( Abc_Cex_t * pCex ) { ABC_FREE( pCex ); } @@ -1279,11 +1282,15 @@ void Ssw_SmlFreeCounterExample( Ssw_Cex_t * pCex ) SeeAlso [] ***********************************************************************/ -int Ssw_SmlRunCounterExample( Aig_Man_t * pAig, Ssw_Cex_t * p ) +int Ssw_SmlRunCounterExample( Aig_Man_t * pAig, Abc_Cex_t * p ) { Ssw_Sml_t * pSml; Aig_Obj_t * pObj; int RetValue, i, k, iBit; + if ( Saig_ManPiNum(pAig) != p->nPis ) + return 0; +// if ( Saig_ManRegNum(pAig) != p->nRegs ) +// return 0; // assert( Aig_ManRegNum(pAig) > 0 ); // assert( Aig_ManRegNum(pAig) < Aig_ManPiNum(pAig) ); // start a new sequential simulator @@ -1293,10 +1300,11 @@ int Ssw_SmlRunCounterExample( Aig_Man_t * pAig, Ssw_Cex_t * p ) Saig_ManForEachLo( pAig, pObj, i ) Ssw_SmlObjAssignConst( pSml, pObj, Aig_InfoHasBit(p->pData, iBit++), 0 ); // assign simulation info for the primary inputs + iBit = Saig_ManRegNum(pAig); for ( i = 0; i <= p->iFrame; i++ ) Saig_ManForEachPi( pAig, pObj, k ) Ssw_SmlObjAssignConst( pSml, pObj, Aig_InfoHasBit(p->pData, iBit++), i ); - assert( iBit == p->nBits ); +// assert( iBit == p->nBits ); // run random simulation Ssw_SmlSimulateOne( pSml ); // check if the given output has failed @@ -1316,7 +1324,7 @@ int Ssw_SmlRunCounterExample( Aig_Man_t * pAig, Ssw_Cex_t * p ) SeeAlso [] ***********************************************************************/ -int Ssw_SmlFindOutputCounterExample( Aig_Man_t * pAig, Ssw_Cex_t * p ) +int Ssw_SmlFindOutputCounterExample( Aig_Man_t * pAig, Abc_Cex_t * p ) { Ssw_Sml_t * pSml; Aig_Obj_t * pObj; @@ -1359,9 +1367,9 @@ int Ssw_SmlFindOutputCounterExample( Aig_Man_t * pAig, Ssw_Cex_t * p ) SeeAlso [] ***********************************************************************/ -Ssw_Cex_t * Ssw_SmlGetCounterExample( Ssw_Sml_t * p ) +Abc_Cex_t * Ssw_SmlGetCounterExample( Ssw_Sml_t * p ) { - Ssw_Cex_t * pCex; + Abc_Cex_t * pCex; Aig_Obj_t * pObj; unsigned * pSims; int iPo, iFrame, iBit, i, k; @@ -1433,9 +1441,9 @@ Ssw_Cex_t * Ssw_SmlGetCounterExample( Ssw_Sml_t * p ) SeeAlso [] ***********************************************************************/ -Ssw_Cex_t * Ssw_SmlCopyCounterExample( Aig_Man_t * pAig, Aig_Man_t * pFrames, int * pModel ) +Abc_Cex_t * Ssw_SmlCopyCounterExample( Aig_Man_t * pAig, Aig_Man_t * pFrames, int * pModel ) { - Ssw_Cex_t * pCex; + Abc_Cex_t * pCex; Aig_Obj_t * pObj; int i, nFrames, nTruePis, nTruePos, iPo, iFrame; // get the number of frames @@ -1493,9 +1501,9 @@ Ssw_Cex_t * Ssw_SmlCopyCounterExample( Aig_Man_t * pAig, Aig_Man_t * pFrames, in SeeAlso [] ***********************************************************************/ -Ssw_Cex_t * Ssw_SmlTrivCounterExample( Aig_Man_t * pAig, int iFrameOut ) +Abc_Cex_t * Ssw_SmlTrivCounterExample( Aig_Man_t * pAig, int iFrameOut ) { - Ssw_Cex_t * pCex; + Abc_Cex_t * pCex; int nTruePis, nTruePos, iPo, iFrame; assert( Aig_ManRegNum(pAig) > 0 ); nTruePis = Aig_ManPiNum(pAig)-Aig_ManRegNum(pAig); @@ -1520,9 +1528,9 @@ Ssw_Cex_t * Ssw_SmlTrivCounterExample( Aig_Man_t * pAig, int iFrameOut ) SeeAlso [] ***********************************************************************/ -Ssw_Cex_t * Ssw_SmlDupCounterExample( Ssw_Cex_t * p, int nRegsNew ) +Abc_Cex_t * Ssw_SmlDupCounterExample( Abc_Cex_t * p, int nRegsNew ) { - Ssw_Cex_t * pCex; + Abc_Cex_t * pCex; int i; pCex = Ssw_SmlAllocCounterExample( nRegsNew, p->nPis, p->iFrame+1 ); pCex->iPo = p->iPo; @@ -1544,7 +1552,7 @@ Ssw_Cex_t * Ssw_SmlDupCounterExample( Ssw_Cex_t * p, int nRegsNew ) SeeAlso [] ***********************************************************************/ -int Ssw_SmlWriteCounterExample( FILE * pFile, Aig_Man_t * pAig, Ssw_Cex_t * p ) +int Ssw_SmlWriteCounterExample( FILE * pFile, Aig_Man_t * pAig, Abc_Cex_t * p ) { Ssw_Sml_t * pSml; Aig_Obj_t * pObj; @@ -1614,3 +1622,5 @@ int Ssw_SmlWriteCounterExample( FILE * pFile, Aig_Man_t * pAig, Ssw_Cex_t * p ) //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ssw/sswSimSat.c b/src/aig/ssw/sswSimSat.c index c85b8bcf..6b18a3a6 100644 --- a/src/aig/ssw/sswSimSat.c +++ b/src/aig/ssw/sswSimSat.c @@ -20,6 +20,9 @@ #include "sswInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -51,21 +54,25 @@ void Ssw_ManResimulateBit( Ssw_Man_t * p, Aig_Obj_t * pCand, Aig_Obj_t * pRepr ) Aig_ManForEachNode( p->pAig, pObj, i ) pObj->fMarkB = ( Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj) ) & ( Aig_ObjFanin1(pObj)->fMarkB ^ Aig_ObjFaninC1(pObj) ); - // check equivalence classes - RetValue1 = Ssw_ClassesRefineConst1( p->ppClasses, 0 ); - RetValue2 = Ssw_ClassesRefine( p->ppClasses, 0 ); - // make sure refinement happened - if ( Aig_ObjIsConst1(pRepr) ) - { - assert( RetValue1 ); - if ( RetValue1 == 0 ) - printf( "\nSsw_ManResimulateBit() Error: RetValue1 does not hold.\n" ); - } - else + // if repr is given, perform refinement + if ( pRepr ) { - assert( RetValue2 ); - if ( RetValue2 == 0 ) - printf( "\nSsw_ManResimulateBit() Error: RetValue2 does not hold.\n" ); + // check equivalence classes + RetValue1 = Ssw_ClassesRefineConst1( p->ppClasses, 0 ); + RetValue2 = Ssw_ClassesRefine( p->ppClasses, 0 ); + // make sure refinement happened + if ( Aig_ObjIsConst1(pRepr) ) + { + assert( RetValue1 ); + if ( RetValue1 == 0 ) + printf( "\nSsw_ManResimulateBit() Error: RetValue1 does not hold.\n" ); + } + else + { + assert( RetValue2 ); + if ( RetValue2 == 0 ) + printf( "\nSsw_ManResimulateBit() Error: RetValue2 does not hold.\n" ); + } } p->timeSimSat += clock() - clk; } @@ -112,3 +119,5 @@ p->timeSimSat += clock() - clk; //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ssw/sswSweep.c b/src/aig/ssw/sswSweep.c index a2f3c175..39fcd48e 100644 --- a/src/aig/ssw/sswSweep.c +++ b/src/aig/ssw/sswSweep.c @@ -21,6 +21,9 @@ #include "sswInt.h" #include "bar.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -157,14 +160,14 @@ void Ssw_SmlAddPatternDyn( Ssw_Man_t * p ) unsigned * pInfo; int i, nVarNum; // iterate through the PIs of the frames - Vec_PtrForEachEntry( p->pMSat->vUsedPis, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->pMSat->vUsedPis, pObj, i ) { assert( Aig_ObjIsPi(pObj) ); nVarNum = Ssw_ObjSatNum( p->pMSat, pObj ); assert( nVarNum > 0 ); if ( sat_solver_var_value( p->pMSat->pSat, nVarNum ) ) { - pInfo = Vec_PtrEntry( p->vSimInfo, Aig_ObjPioNum(pObj) ); + pInfo = (unsigned *)Vec_PtrEntry( p->vSimInfo, Aig_ObjPioNum(pObj) ); Aig_InfoSetBit( pInfo, p->nPatterns ); } } @@ -232,34 +235,7 @@ p->timeMarkCones += clock() - clk; } else Ssw_SmlSavePatternAig( p, f ); - // consider uniqueness - if ( !fBmc && !p->pPars->fDynamic && p->pPars->fUniqueness && p->pPars->nFramesK > 1 && - Ssw_ManUniqueOne( p, pObjRepr, pObj, p->pPars->fVerbose ) && p->iOutputLit == -1 ) - { - if ( Ssw_ManUniqueAddConstraint( p, p->vCommon, 0, 1 ) ) - { - int RetValue2 = Ssw_NodesAreEquiv( p, Aig_Regular(pObjReprFraig), Aig_Regular(pObjFraig) ); - p->iOutputLit = -1; - p->nUniques++; - p->nUniquesAdded++; - if ( RetValue2 == 0 ) - { - int x; -// printf( "Second time:\n" ); - x = Ssw_ManUniqueOne( p, pObjRepr, pObj, p->pPars->fVerbose ); - Ssw_SmlSavePatternAig( p, f ); - Ssw_ManResimulateWord( p, pObj, pObjRepr, f ); - if ( Aig_ObjRepr( p->pAig, pObj ) == pObjRepr ) - printf( "Ssw_ManSweepNode(): Refinement did not happen!!!.\n" ); - return 1; - } - else - p->nUniquesUseful++; -// printf( "Counter-example prevented!!!\n" ); - return 0; - } - } - if ( p->pPars->nConstrs == 0 ) + if ( !p->pPars->fConstrs ) Ssw_ManResimulateWord( p, pObj, pObjRepr, f ); else Ssw_ManResimulateBit( p, pObj, pObjRepr ); @@ -298,7 +274,6 @@ clk = clock(); p->fRefined = 0; if ( p->pPars->fVerbose ) pProgress = Bar_ProgressStart( stdout, Aig_ManObjNumMax(p->pAig) * p->pPars->nFramesK ); -// Ssw_ManStartSolver( p ); for ( f = 0; f < p->pPars->nFramesK; f++ ) { // map constants and PIs @@ -318,10 +293,12 @@ clk = clock(); if ( f == p->pPars->nFramesK - 1 ) break; // transfer latch input to the latch outputs + Aig_ManForEachPo( p->pAig, pObj, i ) + Ssw_ObjSetFrame( p, pObj, f, Ssw_ObjChild0Fra(p, pObj, f) ); // build logic cones for register outputs Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i ) { - pObjNew = Ssw_ObjChild0Fra(p, pObjLi,f); + pObjNew = Ssw_ObjFrame( p, pObjLi, f ); Ssw_ObjSetFrame( p, pObjLo, f+1, pObjNew ); Ssw_CnfNodeAddToSolver( p->pMSat, Aig_Regular(pObjNew) );// } @@ -350,7 +327,7 @@ int Ssw_ManSweep( Ssw_Man_t * p ) { Bar_Progress_t * pProgress = NULL; Aig_Obj_t * pObj, * pObj2, * pObjNew; - int nConstrPairs, clk, i, f, v; + int nConstrPairs, clk, i, f; // perform speculative reduction clk = clock(); @@ -380,12 +357,6 @@ clk = clock(); Ssw_ObjSetFrame( p, pObj, f, Aig_ObjCreatePi(p->pFrames) ); p->timeReduce += clock() - clk; - // bring up the previous frames - if ( p->pPars->fUniqueness ) - for ( v = 0; v < f; v++ ) - Saig_ManForEachLo( p->pAig, pObj, i ) - Ssw_CnfNodeAddToSolver( p->pMSat, Aig_Regular(Ssw_ObjFrame(p, pObj, v)) ); - // sweep internal nodes p->fRefined = 0; Ssw_ClassesClearRefined( p->ppClasses ); @@ -417,3 +388,5 @@ p->timeReduce += clock() - clk; //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/ssw/sswUnique.c b/src/aig/ssw/sswUnique.c index d6590716..b5f6a853 100644 --- a/src/aig/ssw/sswUnique.c +++ b/src/aig/ssw/sswUnique.c @@ -20,6 +20,9 @@ #include "sswInt.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -100,7 +103,7 @@ int Ssw_ManUniqueOne( Ssw_Man_t * p, Aig_Obj_t * pRepr, Aig_Obj_t * pObj, int fV RetValue = Vec_PtrSize( p->vCommon ); fFeasible = 0; k = 0; - Vec_PtrForEachEntry( p->vCommon, pTemp, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vCommon, pTemp, i ) { assert( Aig_ObjIsPi(pTemp) ); if ( !Saig_ObjIsLo(p->pAig, pTemp) ) @@ -119,7 +122,7 @@ int Ssw_ManUniqueOne( Ssw_Man_t * p, Aig_Obj_t * pRepr, Aig_Obj_t * pObj, int fV // check the current values RetValue = 1; - Vec_PtrForEachEntry( p->vCommon, pTemp, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, p->vCommon, pTemp, i ) { Value0 = Ssw_ManGetSatVarValue( p, pTemp, 0 ); Value1 = Ssw_ManGetSatVarValue( p, pTemp, 1 ); @@ -153,7 +156,7 @@ int Ssw_ManUniqueAddConstraint( Ssw_Man_t * p, Vec_Ptr_t * vCommon, int f1, int assert( Vec_PtrSize(vCommon) > 0 ); // generate the constraint pTotal = Aig_ManConst0(p->pFrames); - Vec_PtrForEachEntry( vCommon, pObj, i ) + Vec_PtrForEachEntry( Aig_Obj_t *, vCommon, pObj, i ) { assert( Saig_ObjIsLo(p->pAig, pObj) ); pObj1New = Ssw_ObjFrame( p, pObj, f1 ); @@ -190,3 +193,5 @@ int Ssw_ManUniqueAddConstraint( Ssw_Man_t * p, Vec_Ptr_t * vCommon, int f1, int //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/tim/tim.c b/src/aig/tim/tim.c index e565b01f..6b7e310c 100644 --- a/src/aig/tim/tim.c +++ b/src/aig/tim/tim.c @@ -28,6 +28,9 @@ #include "mem.h" #include "tim.h" +ABC_NAMESPACE_IMPL_START + + //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -71,12 +74,12 @@ struct Tim_Obj_t_ float timeReq; // required time of the object }; -static inline Tim_Obj_t * Tim_ManCi( Tim_Man_t * p, int i ) { assert( i < p->nCis ); return p->pCis + i; } -static inline Tim_Obj_t * Tim_ManCo( Tim_Man_t * p, int i ) { assert( i < p->nCos ); return p->pCos + i; } -static inline Tim_Box_t * Tim_ManBox( Tim_Man_t * p, int i ) { return Vec_PtrEntry(p->vBoxes, i); } +static inline Tim_Obj_t * Tim_ManCi( Tim_Man_t * p, int i ) { assert( i < p->nCis ); return p->pCis + i; } +static inline Tim_Obj_t * Tim_ManCo( Tim_Man_t * p, int i ) { assert( i < p->nCos ); return p->pCos + i; } +static inline Tim_Box_t * Tim_ManBox( Tim_Man_t * p, int i ) { return (Tim_Box_t *)Vec_PtrEntry(p->vBoxes, i); } -static inline Tim_Box_t * Tim_ManCiBox( Tim_Man_t * p, int i ) { return Tim_ManCi(p,i)->iObj2Box < 0 ? NULL : Vec_PtrEntry( p->vBoxes, Tim_ManCi(p,i)->iObj2Box ); } -static inline Tim_Box_t * Tim_ManCoBox( Tim_Man_t * p, int i ) { return Tim_ManCo(p,i)->iObj2Box < 0 ? NULL : Vec_PtrEntry( p->vBoxes, Tim_ManCo(p,i)->iObj2Box ); } +static inline Tim_Box_t * Tim_ManCiBox( Tim_Man_t * p, int i ) { return Tim_ManCi(p,i)->iObj2Box < 0 ? NULL : (Tim_Box_t *)Vec_PtrEntry( p->vBoxes, Tim_ManCi(p,i)->iObj2Box ); } +static inline Tim_Box_t * Tim_ManCoBox( Tim_Man_t * p, int i ) { return Tim_ManCo(p,i)->iObj2Box < 0 ? NULL : (Tim_Box_t *)Vec_PtrEntry( p->vBoxes, Tim_ManCo(p,i)->iObj2Box ); } static inline Tim_Obj_t * Tim_ManBoxInput( Tim_Man_t * p, Tim_Box_t * pBox, int i ) { assert( i < pBox->nInputs ); return p->pCos + pBox->Inouts[i]; } static inline Tim_Obj_t * Tim_ManBoxOutput( Tim_Man_t * p, Tim_Box_t * pBox, int i ) { assert( i < pBox->nOutputs ); return p->pCis + pBox->Inouts[pBox->nInputs+i]; } @@ -93,7 +96,7 @@ static inline Tim_Obj_t * Tim_ManBoxOutput( Tim_Man_t * p, Tim_Box_t * pBox, int for ( i = 0; (i < (p)->nCos) && ((pObj) = (p)->pCos + i); i++ ) \ if ( pObj->iObj2Box >= 0 ) {} else #define Tim_ManForEachBox( p, pBox, i ) \ - Vec_PtrForEachEntry( p->vBoxes, pBox, i ) + Vec_PtrForEachEntry( Tim_Box_t *, p->vBoxes, pBox, i ) //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -178,12 +181,25 @@ Tim_Man_t * Tim_ManDup( Tim_Man_t * p, int fDiscrete ) pNew->vDelayTables = Vec_PtrAlloc( 100 ); Tim_ManForEachBox( p, pBox, i ) { +//printf( "%d %d\n", pBox->nInputs, pBox->nOutputs ); pDelayTableNew = ABC_ALLOC( float, pBox->nInputs * pBox->nOutputs ); Vec_PtrPush( pNew->vDelayTables, pDelayTableNew ); if ( fDiscrete ) { for ( k = 0; k < pBox->nInputs * pBox->nOutputs; k++ ) pDelayTableNew[k] = 1.0; // modify here + +///// begin part of improved CIN/COUT propagation + for ( k = 0; k < pBox->nInputs; k++ ) // fill in the first row + pDelayTableNew[k] = 0.5; + for ( k = 0; k < pBox->nOutputs; k++ ) // fill in the first column + pDelayTableNew[k*pBox->nInputs] = 0.5; + pDelayTableNew[0] = 0.0; // fill in the first entry +///// end part of improved CIN/COUT propagation + + /// change +// pDelayTableNew[0] = 0.0; + /// change } else memcpy( pDelayTableNew, pBox->pDelayTable, sizeof(float) * pBox->nInputs * pBox->nOutputs ); @@ -278,7 +294,7 @@ void Tim_ManStop( Tim_Man_t * p ) int i; if ( p->vDelayTables ) { - Vec_PtrForEachEntry( p->vDelayTables, pTable, i ) + Vec_PtrForEachEntry( float *, p->vDelayTables, pTable, i ) ABC_FREE( pTable ); Vec_PtrFree( p->vDelayTables ); } @@ -300,6 +316,25 @@ void Tim_ManStop( Tim_Man_t * p ) SeeAlso [] ***********************************************************************/ +void Tim_ManStopP( Tim_Man_t ** p ) +{ + if ( *p == NULL ) + return; + Tim_ManStop( *p ); + *p = NULL; +} + +/**Function************************************************************* + + Synopsis [Stops the timing manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ void Tim_ManPrint( Tim_Man_t * p ) { Tim_Box_t * pBox; @@ -547,11 +582,10 @@ void Tim_ManCreateBoxFirst( Tim_Man_t * p, int firstIn, int nIns, int firstOut, { Tim_Box_t * pBox; int i; + pBox = (Tim_Box_t *)Mem_FlexEntryFetch( p->pMemObj, sizeof(Tim_Box_t) + sizeof(int) * (nIns+nOuts) ); memset( pBox, 0, sizeof(Tim_Box_t) ); pBox->iBox = Vec_PtrSize( p->vBoxes ); -//printf( "Creating box %d: First in = %d. (%d) First out = %d. (%d)\n", pBox->iBox, -// firstIn, nIns, firstOut, nOuts ); Vec_PtrPush( p->vBoxes, pBox ); pBox->pDelayTable = pDelayTable; pBox->nInputs = nIns; @@ -570,6 +604,8 @@ void Tim_ManCreateBoxFirst( Tim_Man_t * p, int firstIn, int nIns, int firstOut, p->pCis[firstOut+i].iObj2Box = pBox->iBox; p->pCis[firstOut+i].iObj2Num = i; } +// if ( pBox->iBox < 50 ) +// printf( "%4d %4d %4d %4d \n", firstIn, nIns, firstOut, nOuts ); } @@ -726,7 +762,10 @@ void Tim_ManSetCoRequiredAll( Tim_Man_t * p, float Delay ) Tim_Obj_t * pObj; int i; Tim_ManForEachCo( p, pObj, i ) + { Tim_ManSetCoRequired( p, i, Delay ); +//printf( "%d ", i ); + } } @@ -873,7 +912,7 @@ int Tim_ManBoxForCo( Tim_Man_t * p, int iCo ) ***********************************************************************/ int Tim_ManBoxInputFirst( Tim_Man_t * p, int iBox ) { - Tim_Box_t * pBox = Vec_PtrEntry( p->vBoxes, iBox ); + Tim_Box_t * pBox = (Tim_Box_t *)Vec_PtrEntry( p->vBoxes, iBox ); return pBox->Inouts[0]; } @@ -890,7 +929,7 @@ int Tim_ManBoxInputFirst( Tim_Man_t * p, int iBox ) ***********************************************************************/ int Tim_ManBoxOutputFirst( Tim_Man_t * p, int iBox ) { - Tim_Box_t * pBox = Vec_PtrEntry( p->vBoxes, iBox ); + Tim_Box_t * pBox = (Tim_Box_t *)Vec_PtrEntry( p->vBoxes, iBox ); return pBox->Inouts[pBox->nInputs]; } @@ -907,7 +946,7 @@ int Tim_ManBoxOutputFirst( Tim_Man_t * p, int iBox ) ***********************************************************************/ int Tim_ManBoxInputNum( Tim_Man_t * p, int iBox ) { - Tim_Box_t * pBox = Vec_PtrEntry( p->vBoxes, iBox ); + Tim_Box_t * pBox = (Tim_Box_t *)Vec_PtrEntry( p->vBoxes, iBox ); return pBox->nInputs; } @@ -924,13 +963,34 @@ int Tim_ManBoxInputNum( Tim_Man_t * p, int iBox ) ***********************************************************************/ int Tim_ManBoxOutputNum( Tim_Man_t * p, int iBox ) { - Tim_Box_t * pBox = Vec_PtrEntry( p->vBoxes, iBox ); + Tim_Box_t * pBox = (Tim_Box_t *)Vec_PtrEntry( p->vBoxes, iBox ); return pBox->nOutputs; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Tim_ManChangeForAdders( Tim_Man_t * p ) +{ + Tim_Box_t * pBox; + int i; + Tim_ManForEachBox( p, pBox, i ) + pBox->pDelayTable[0] = 0.0; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/tim/tim.h b/src/aig/tim/tim.h index bdb8e61e..2d52b7b1 100644 --- a/src/aig/tim/tim.h +++ b/src/aig/tim/tim.h @@ -21,6 +21,7 @@ #ifndef __TIM_H__ #define __TIM_H__ + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -29,9 +30,10 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif + + +ABC_NAMESPACE_HEADER_START + //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -63,6 +65,7 @@ extern Tim_Man_t * Tim_ManDup( Tim_Man_t * p, int fDiscrete ); extern Tim_Man_t * Tim_ManDupUnit( Tim_Man_t * p ); extern Tim_Man_t * Tim_ManDupApprox( Tim_Man_t * p ); extern void Tim_ManStop( Tim_Man_t * p ); +extern void Tim_ManStopP( Tim_Man_t ** p ); extern void Tim_ManPrint( Tim_Man_t * p ); extern void Tim_ManTravIdDisable( Tim_Man_t * p ); extern void Tim_ManTravIdEnable( Tim_Man_t * p ); @@ -91,10 +94,13 @@ extern int Tim_ManBoxInputFirst( Tim_Man_t * p, int iBox ); extern int Tim_ManBoxOutputFirst( Tim_Man_t * p, int iBox ); extern int Tim_ManBoxInputNum( Tim_Man_t * p, int iBox ); extern int Tim_ManBoxOutputNum( Tim_Man_t * p, int iBox ); +extern void Tim_ManChangeForAdders( Tim_Man_t * p ); + + + +ABC_NAMESPACE_HEADER_END + -#ifdef __cplusplus -} -#endif #endif |