diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2006-02-11 08:01:00 -0800 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2006-02-11 08:01:00 -0800 |
commit | 77d7377442c28fd5c65144d7ea23938600967b2b (patch) | |
tree | dad44cc2d4bad07bf91c47c889c8c8c46ef13006 /src/sat/aig | |
parent | c0ef1f469a3204adbd26edec0b9d3af56532d794 (diff) | |
download | abc-77d7377442c28fd5c65144d7ea23938600967b2b.tar.gz abc-77d7377442c28fd5c65144d7ea23938600967b2b.tar.bz2 abc-77d7377442c28fd5c65144d7ea23938600967b2b.zip |
Version abc60211
Diffstat (limited to 'src/sat/aig')
-rw-r--r-- | src/sat/aig/aig.h | 12 | ||||
-rw-r--r-- | src/sat/aig/aigMan.c | 12 | ||||
-rw-r--r-- | src/sat/aig/fraigClass.c | 182 | ||||
-rw-r--r-- | src/sat/aig/fraigCore.c | 2 | ||||
-rw-r--r-- | src/sat/aig/fraigEngine.c | 125 | ||||
-rw-r--r-- | src/sat/aig/fraigSim.c | 55 | ||||
-rw-r--r-- | src/sat/aig/rwrTruth.c | 454 |
7 files changed, 781 insertions, 61 deletions
diff --git a/src/sat/aig/aig.h b/src/sat/aig/aig.h index 55a75cf5..ee029789 100644 --- a/src/sat/aig/aig.h +++ b/src/sat/aig/aig.h @@ -160,6 +160,7 @@ struct Aig_Man_t_ Aig_SimInfo_t * pInfo; // random and systematic sim info for PIs Aig_SimInfo_t * pInfoPi; // temporary sim info for the PI nodes Aig_SimInfo_t * pInfoTemp; // temporary sim info for all nodes + Aig_Pattern_t * pPatMask; // the mask which shows what patterns are used // simulation patterns int nPiWords; // the number of words in the PI info int nPatsMax; // the max number of patterns @@ -169,6 +170,7 @@ struct Aig_Man_t_ // temporary data Vec_Ptr_t * vFanouts; // temporary storage for fanouts of a node Vec_Ptr_t * vToReplace; // the nodes to replace + Vec_Int_t * vClassTemp; // temporary class representatives }; // the simulation patter @@ -254,6 +256,7 @@ static inline int Aig_NodeWhatFanin( Aig_Node_t * pNode, Aig_Node_t * p static inline int Aig_NodeGetLevelNew( Aig_Node_t * pNode ) { return 1 + AIG_MAX(Aig_NodeFanin0(pNode)->Level, Aig_NodeFanin1(pNode)->Level); } static inline int Aig_NodeRequiredLevel( Aig_Node_t * pNode ) { return pNode->pMan->nLevelMax + 1 - pNode->LevelR; } +static inline unsigned * Aig_SimInfoForNodeId( Aig_SimInfo_t * p, int NodeId ) { assert( p->Type ); return p->pData + p->nWords * NodeId; } static inline unsigned * Aig_SimInfoForNode( Aig_SimInfo_t * p, Aig_Node_t * pNode ) { assert( p->Type ); return p->pData + p->nWords * pNode->Id; } static inline unsigned * Aig_SimInfoForPi( Aig_SimInfo_t * p, int Num ) { assert( !p->Type ); return p->pData + p->nWords * Num; } @@ -332,15 +335,16 @@ extern Aig_Node_t * Aig_NodeRecognizeMux( Aig_Node_t * pNode, Aig_Node_t extern Aig_ProofType_t Aig_FraigProve( Aig_Man_t * pMan ); /*=== fraigClasses.c ==========================================================*/ extern Vec_Vec_t * Aig_ManDeriveClassesFirst( Aig_Man_t * p, Aig_SimInfo_t * pInfoAll ); -extern void Aig_ManUpdateClasses( Aig_Man_t * p, Aig_SimInfo_t * pInfo, Vec_Vec_t * vClasses ); +extern int Aig_ManUpdateClasses( Aig_Man_t * p, Aig_SimInfo_t * pInfo, Vec_Vec_t * vClasses, Aig_Pattern_t * pPatMask ); +extern void Aig_ManCollectPatterns( Aig_Man_t * p, Aig_SimInfo_t * pInfo, Aig_Pattern_t * pMask, Vec_Ptr_t * vPats ); /*=== fraigCnf.c ==========================================================*/ extern Aig_ProofType_t Aig_ClauseSolverStart( Aig_Man_t * pMan ); /*=== fraigEngine.c ==========================================================*/ +extern void Aig_EngineSimulateRandomFirst( Aig_Man_t * p ); extern void Aig_EngineSimulateFirst( Aig_Man_t * p ); extern int Aig_EngineSimulate( Aig_Man_t * p ); -extern void Aig_EngineSimulateRandomFirst( Aig_Man_t * p ); /*=== fraigSim.c ==========================================================*/ -extern Aig_SimInfo_t * Aig_SimInfoAlloc( int nNodes, int nWords, int Type ); +extern Aig_SimInfo_t * Aig_SimInfoAlloc( int nNodes, int nBits, int Type ); extern void Aig_SimInfoClean( Aig_SimInfo_t * p ); extern void Aig_SimInfoRandom( Aig_SimInfo_t * p ); extern void Aig_SimInfoFromPattern( Aig_SimInfo_t * p, Aig_Pattern_t * pPat ); @@ -349,6 +353,8 @@ extern void Aig_SimInfoFree( Aig_SimInfo_t * p ); extern void Aig_ManSimulateInfo( Aig_Man_t * p, Aig_SimInfo_t * pInfoPi, Aig_SimInfo_t * pInfoAll ); extern Aig_Pattern_t * Aig_PatternAlloc( int nBits ); extern void Aig_PatternClean( Aig_Pattern_t * pPat ); +extern void Aig_PatternFill( Aig_Pattern_t * pPat ); +extern int Aig_PatternCount( Aig_Pattern_t * pPat ); extern void Aig_PatternRandom( Aig_Pattern_t * pPat ); extern void Aig_PatternFree( Aig_Pattern_t * pPat ); diff --git a/src/sat/aig/aigMan.c b/src/sat/aig/aigMan.c index 3807d28a..4c64c897 100644 --- a/src/sat/aig/aigMan.c +++ b/src/sat/aig/aigMan.c @@ -42,7 +42,7 @@ void Aig_ManSetDefaultParams( Aig_Param_t * pParam ) { memset( pParam, 0, sizeof(Aig_Param_t) ); - pParam->nPatsRand = 1024; // the number of random patterns + pParam->nPatsRand = 4096; // the number of random patterns pParam->nBTLimit = 99; // backtrack limit at the intermediate nodes pParam->nSeconds = 1; // the timeout for the final miter in seconds } @@ -67,8 +67,8 @@ Aig_Man_t * Aig_ManStart( Aig_Param_t * pParam ) p = ALLOC( Aig_Man_t, 1 ); memset( p, 0, sizeof(Aig_Man_t) ); p->pParam = &p->Param; - p->nTravIds = 1; - p->nPatsMax = 20; + p->nTravIds = 1; + p->nPatsMax = 25; // set the defaults *p->pParam = *pParam; // start memory managers @@ -84,6 +84,8 @@ Aig_Man_t * Aig_ManStart( Aig_Param_t * pParam ) // initialize other variables p->vFanouts = Vec_PtrAlloc( 10 ); p->vToReplace = Vec_PtrAlloc( 10 ); + p->vClassTemp = Vec_IntAlloc( 10 ); + p->vPats = Vec_PtrAlloc( p->nPatsMax ); return p; } @@ -132,6 +134,9 @@ void Aig_ManStop( Aig_Man_t * p ) if ( p->vFanFans0 ) Vec_PtrFree( p->vFanFans0 ); if ( p->vFanFans1 ) Vec_PtrFree( p->vFanFans1 ); if ( p->vClasses ) Vec_VecFree( p->vClasses ); + // patterns + if ( p->vPats ) Vec_PtrFree( p->vPats ); + if ( p->pPatMask ) Aig_PatternFree( p->pPatMask ); // nodes Aig_MemFixedStop( p->mmNodes, 0 ); Vec_PtrFree( p->vNodes ); @@ -140,6 +145,7 @@ void Aig_ManStop( Aig_Man_t * p ) // temporary Vec_PtrFree( p->vFanouts ); Vec_PtrFree( p->vToReplace ); + Vec_IntFree( p->vClassTemp ); Aig_TableFree( p->pTable ); free( p ); } diff --git a/src/sat/aig/fraigClass.c b/src/sat/aig/fraigClass.c index 2f2d3e0c..a8df9a72 100644 --- a/src/sat/aig/fraigClass.c +++ b/src/sat/aig/fraigClass.c @@ -80,7 +80,7 @@ Vec_Vec_t * Aig_ManDeriveClassesFirst( Aig_Man_t * p, Aig_SimInfo_t * pInfo ) } } stmm_free_table( tSim2Node ); - +/* // print the classes { Vec_Ptr_t * vVec; @@ -93,6 +93,8 @@ Vec_Vec_t * Aig_ManDeriveClassesFirst( Aig_Man_t * p, Aig_SimInfo_t * pInfo ) printf( "%d ", Vec_PtrSize(vVec) ); printf( "\n" ); } +*/ + printf( "Classes = %6d. Pairs = %6d.\n", Vec_VecSize(vClasses), Vec_VecSizeSize(vClasses) - Vec_VecSize(vClasses) ); return vClasses; } @@ -115,14 +117,86 @@ unsigned Aig_ManHashKey( unsigned * pData, int nWords, bool fPhase ) uKey = 0; if ( fPhase ) for ( i = 0; i < nWords; i++ ) - uKey ^= Primes[i%10] * pData[i]; + uKey ^= i * Primes[i%10] * pData[i]; else for ( i = 0; i < nWords; i++ ) - uKey ^= Primes[i%10] * ~pData[i]; + uKey ^= i * Primes[i%10] * ~pData[i]; return uKey; } + +/**Function************************************************************* + + Synopsis [Splits the equivalence class.] + + Description [Given an equivalence class (vClass) and the simulation info, + split the class into two based on the info.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_ManSplitClass( Aig_Man_t * p, Aig_SimInfo_t * pInfo, Vec_Int_t * vClass, Vec_Int_t * vClass2, Aig_Pattern_t * pPat ) +{ + int NodeId, i, k, w; + Aig_Node_t * pRoot, * pTemp; + unsigned * pRootData, * pTempData; + assert( Vec_IntSize(vClass) > 1 ); + assert( pInfo->nPatsCur == pPat->nBits ); +// printf( "Class = %5d. --> ", Vec_IntSize(vClass) ); + // clear storage for the new classes + Vec_IntClear( vClass2 ); + // get the root member of the class + pRoot = Aig_ManNode( p, Vec_IntEntry(vClass, 0) ); + pRootData = Aig_SimInfoForNode( pInfo, pRoot ); + // sort the class members: + // (1) with the same siminfo as pRoot remain in vClass + // (2) nodes with other siminfo go to vClass2 + k = 1; + Vec_IntForEachEntryStart( vClass, NodeId, i, 1 ) + { + NodeId = Vec_IntEntry(vClass, i); + pTemp = Aig_ManNode( p, NodeId ); + pTempData = Aig_SimInfoForNode( pInfo, pTemp ); + if ( pRoot->fPhase == pTemp->fPhase ) + { + for ( w = 0; w < pInfo->nWords; w++ ) + if ( pRootData[w] != pTempData[w] ) + break; + if ( w == pInfo->nWords ) // the same info + Vec_IntWriteEntry( vClass, k++, NodeId ); + else + { + Vec_IntPush( vClass2, NodeId ); + // record the diffs if they are not distinguished by the first pattern + if ( ((pRootData[0] ^ pTempData[0]) & 1) == 0 ) + for ( w = 0; w < pInfo->nWords; w++ ) + pPat->pData[w] |= (pRootData[w] ^ pTempData[w]); + } + } + else + { + for ( w = 0; w < pInfo->nWords; w++ ) + if ( pRootData[w] != ~pTempData[w] ) + break; + if ( w == pInfo->nWords ) // the same info + Vec_IntWriteEntry( vClass, k++, NodeId ); + else + { + Vec_IntPush( vClass2, NodeId ); + // record the diffs if they are not distinguished by the first pattern + if ( ((pRootData[0] ^ ~pTempData[0]) & 1) == 0 ) + for ( w = 0; w < pInfo->nWords; w++ ) + pPat->pData[w] |= (pRootData[w] ^ ~pTempData[w]); + } + } + } + Vec_IntShrink( vClass, k ); +// printf( "Class1 = %5d. Class2 = %5d.\n", Vec_IntSize(vClass), Vec_IntSize(vClass2) ); +} + /**Function************************************************************* Synopsis [Updates the equivalence classes using the simulation info.] @@ -135,8 +209,108 @@ unsigned Aig_ManHashKey( unsigned * pData, int nWords, bool fPhase ) SeeAlso [] ***********************************************************************/ -void Aig_ManUpdateClasses( Aig_Man_t * p, Aig_SimInfo_t * pInfo, Vec_Vec_t * vClasses ) +int Aig_ManUpdateClasses( Aig_Man_t * p, Aig_SimInfo_t * pInfo, Vec_Vec_t * vClasses, Aig_Pattern_t * pPatMask ) +{ + Vec_Ptr_t * vClass; + int i, k, fSplit = 0; + assert( Vec_VecSize(vClasses) > 0 ); + // collect patterns that lead to changes + Aig_PatternClean( pPatMask ); + // split the classes using the new symmetry info + Vec_VecForEachLevel( vClasses, vClass, i ) + { + if ( i == 0 ) + continue; + // split vClass into two parts (vClass and vClassTemp) + Aig_ManSplitClass( p, pInfo, (Vec_Int_t *)vClass, p->vClassTemp, pPatMask ); + // check if there is any splitting + if ( Vec_IntSize(p->vClassTemp) > 0 ) + fSplit = 1; + // skip the new class if it is empty or trivial + if ( Vec_IntSize(p->vClassTemp) < 2 ) + continue; + // consider replacing the current class with the new one + if ( Vec_PtrSize(vClass) == 1 ) + { + assert( vClasses->pArray[i] == vClass ); + vClasses->pArray[i] = p->vClassTemp; + p->vClassTemp = (Vec_Int_t *)vClass; + i--; + continue; + } + // add the new non-trival class in the end + Vec_PtrPush( (Vec_Ptr_t *)vClasses, p->vClassTemp ); + p->vClassTemp = Vec_IntAlloc( 10 ); + } + // free trivial classes + k = 0; + Vec_VecForEachLevel( vClasses, vClass, i ) + { + assert( Vec_PtrSize(vClass) > 0 ); + if ( Vec_PtrSize(vClass) == 1 ) + Vec_PtrFree(vClass); + else + vClasses->pArray[k++] = vClass; + } + Vec_PtrShrink( (Vec_Ptr_t *)vClasses, k ); + // catch the patterns which led to splitting + printf( "Classes = %6d. Pairs = %6d. Patterns = %3d.\n", + Vec_VecSize(vClasses), + Vec_VecSizeSize(vClasses) - Vec_VecSize(vClasses), + Vec_PtrSize(p->vPats) ); + return fSplit; +} + +/**Function************************************************************* + + Synopsis [Collects useful patterns.] + + Description [If the flag fAddToVector is 1, creates and adds new patterns + to the internal storage of patterns.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_ManCollectPatterns( Aig_Man_t * p, Aig_SimInfo_t * pInfo, Aig_Pattern_t * pMask, Vec_Ptr_t * vPats ) { + Aig_SimInfo_t * pInfoRes = p->pInfo; + Aig_Pattern_t * pPatNew; + Aig_Node_t * pNode; + int i, k; + + assert( Aig_InfoHasBit(pMask->pData, 0) == 0 ); + for ( i = 0; i < pMask->nBits; i++ ) + { + if ( vPats && Vec_PtrSize(vPats) >= p->nPatsMax ) + break; + if ( i == 0 || Aig_InfoHasBit(pMask->pData, i) ) + { + // expand storage if needed + if ( pInfoRes->nPatsCur == pInfoRes->nPatsMax ) + Aig_SimInfoResize( pInfoRes ); + // create a new pattern + if ( vPats ) + { + pPatNew = Aig_PatternAlloc( Aig_ManPiNum(p) ); + Aig_PatternClean( pPatNew ); + } + // go through the PIs + Aig_ManForEachPi( p, pNode, k ) + { + if ( Aig_InfoHasBit( Aig_SimInfoForNode(pInfo, pNode), i ) ) + { + Aig_InfoSetBit( Aig_SimInfoForPi(pInfoRes, k), pInfoRes->nPatsCur ); + if ( vPats ) Aig_InfoSetBit( pPatNew->pData, k ); + } + } + // store the new pattern + if ( vPats ) Vec_PtrPush( vPats, pPatNew ); + // increment the number of patterns stored + pInfoRes->nPatsCur++; + } + } } //////////////////////////////////////////////////////////////////////// diff --git a/src/sat/aig/fraigCore.c b/src/sat/aig/fraigCore.c index e7df1335..decf05ee 100644 --- a/src/sat/aig/fraigCore.c +++ b/src/sat/aig/fraigCore.c @@ -68,6 +68,8 @@ Aig_ProofType_t Aig_FraigProve( Aig_Man_t * pMan ) // create equivalence classes Aig_EngineSimulateRandomFirst( pMan ); + // reduce equivalence classes using simulation + Aig_EngineSimulateFirst( pMan ); return RetValue; } diff --git a/src/sat/aig/fraigEngine.c b/src/sat/aig/fraigEngine.c index 6214bf3b..17468e8f 100644 --- a/src/sat/aig/fraigEngine.c +++ b/src/sat/aig/fraigEngine.c @@ -30,6 +30,39 @@ /**Function************************************************************* + Synopsis [Simulates all nodes using random simulation for the first time.] + + Description [Assigns the original simulation info and the storage for the + future simulation info.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_EngineSimulateRandomFirst( Aig_Man_t * p ) +{ + Aig_SimInfo_t * pInfoPi, * pInfoAll; + assert( !p->pInfo && !p->pInfoTemp ); + // create random PI info + pInfoPi = Aig_SimInfoAlloc( Aig_ManPiNum(p), p->pParam->nPatsRand, 0 ); + Aig_SimInfoRandom( pInfoPi ); + // allocate sim info for all nodes + pInfoAll = Aig_SimInfoAlloc( Aig_ManNodeNum(p), p->pParam->nPatsRand, 1 ); + // simulate though the circuit + Aig_ManSimulateInfo( p, pInfoPi, pInfoAll ); + // detect classes + p->vClasses = Aig_ManDeriveClassesFirst( p, pInfoAll ); + Aig_SimInfoFree( pInfoAll ); + // save simulation info + p->pInfo = pInfoPi; + p->pInfoPi = Aig_SimInfoAlloc( Aig_ManPiNum(p), Aig_ManPiNum(p)+1, 0 ); + p->pInfoTemp = Aig_SimInfoAlloc( Aig_ManNodeNum(p), Aig_ManPiNum(p)+1, 1 ); + p->pPatMask = Aig_PatternAlloc( Aig_ManPiNum(p)+1 ); +} + +/**Function************************************************************* + Synopsis [Starts the simulation engine for the first time.] Description [Tries several random patterns and their distance-1 @@ -43,15 +76,55 @@ void Aig_EngineSimulateFirst( Aig_Man_t * p ) { Aig_Pattern_t * pPat; - int i; - assert( Vec_PtrSize(p->vPats) == 0 ); - for ( i = 0; i < p->nPatsMax; i++ ) + int i, Counter; + + // simulate the pattern of all zeros + pPat = Aig_PatternAlloc( Aig_ManPiNum(p) ); + Aig_PatternClean( pPat ); + Vec_PtrPush( p->vPats, pPat ); + if ( !Aig_EngineSimulate( p ) ) + return; + + // simulate the pattern of all ones + pPat = Aig_PatternAlloc( Aig_ManPiNum(p) ); + Aig_PatternFill( pPat ); + Vec_PtrPush( p->vPats, pPat ); + if ( !Aig_EngineSimulate( p ) ) + return; + + // simulate random until the number of new patterns is reasonable + do { + // generate random PI siminfo + Aig_SimInfoRandom( p->pInfoPi ); + // simulate this info + Aig_ManSimulateInfo( p, p->pInfoPi, p->pInfoTemp ); + // split the classes and collect the new patterns + if ( Aig_ManUpdateClasses( p, p->pInfoTemp, p->vClasses, p->pPatMask ) ) + Aig_ManCollectPatterns( p, p->pInfoTemp, p->pPatMask, NULL ); + if ( Vec_VecSize(p->vClasses) == 0 ) + return; + // count the number of useful patterns + Counter = Aig_PatternCount(p->pPatMask); + } + while ( Counter > p->nPatsMax/2 ); + + // perform targetted simulation + for ( i = 0; i < 3; i++ ) { - pPat = Aig_PatternAlloc( Aig_ManPiNum(p) ); - Aig_PatternRandom( pPat ); - Vec_PtrPush( p->vPats, pPat ); - if ( !Aig_EngineSimulate( p ) ) + assert( Vec_PtrSize(p->vPats) == 0 ); + // generate random PI siminfo + Aig_SimInfoRandom( p->pInfoPi ); + // simulate this info + Aig_ManSimulateInfo( p, p->pInfoPi, p->pInfoTemp ); + // split the classes and collect the new patterns + if ( Aig_ManUpdateClasses( p, p->pInfoTemp, p->vClasses, p->pPatMask ) ) + Aig_ManCollectPatterns( p, p->pInfoTemp, p->pPatMask, p->vPats ); + if ( Vec_VecSize(p->vClasses) == 0 ) return; + // simulate the remaining patters + if ( Vec_PtrSize(p->vPats) > 0 ) + if ( !Aig_EngineSimulate( p ) ) + return; } } @@ -79,51 +152,21 @@ int Aig_EngineSimulate( Aig_Man_t * p ) { // get the pattern and create new siminfo pPat = Vec_PtrPop(p->vPats); + assert( pPat->nBits == Aig_ManPiNum(p) ); // create the new siminfo Aig_SimInfoFromPattern( p->pInfoPi, pPat ); - // free the patter + // free the pattern Aig_PatternFree( pPat ); // simulate this info Aig_ManSimulateInfo( p, p->pInfoPi, p->pInfoTemp ); // split the classes and collect the new patterns - Aig_ManUpdateClasses( p, p->pInfoTemp, p->vClasses ); + if ( Aig_ManUpdateClasses( p, p->pInfoTemp, p->vClasses, p->pPatMask ) ) + Aig_ManCollectPatterns( p, p->pInfoTemp, p->pPatMask, p->vPats ); } return Vec_VecSize(p->vClasses) > 0; } -/**Function************************************************************* - - Synopsis [Simulates all nodes using random simulation for the first time.] - - Description [Assigns the original simulation info and the storage for the - future simulation info.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_EngineSimulateRandomFirst( Aig_Man_t * p ) -{ - Aig_SimInfo_t * pInfoPi, * pInfoAll; - assert( !p->pInfo && !p->pInfoTemp ); - // create random PI info - pInfoPi = Aig_SimInfoAlloc( p->vPis->nSize, Aig_BitWordNum(p->pParam->nPatsRand), 0 ); - Aig_SimInfoRandom( pInfoPi ); - // allocate sim info for all nodes - pInfoAll = Aig_SimInfoAlloc( p->vNodes->nSize, pInfoPi->nWords, 1 ); - // simulate though the circuit - Aig_ManSimulateInfo( p, pInfoPi, pInfoAll ); - // detect classes - p->vClasses = Aig_ManDeriveClassesFirst( p, pInfoAll ); - Aig_SimInfoFree( pInfoAll ); - // save simulation info - p->pInfo = pInfoPi; - p->pInfoPi = Aig_SimInfoAlloc( p->vPis->nSize, Aig_BitWordNum(p->vPis->nSize), 0 ); - p->pInfoTemp = Aig_SimInfoAlloc( p->vNodes->nSize, Aig_BitWordNum(p->vPis->nSize), 1 ); -} - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/sat/aig/fraigSim.c b/src/sat/aig/fraigSim.c index 415b6918..6d4f214c 100644 --- a/src/sat/aig/fraigSim.c +++ b/src/sat/aig/fraigSim.c @@ -80,7 +80,7 @@ void Aig_ManSimulateInfo( Aig_Man_t * p, Aig_SimInfo_t * pInfoPi, Aig_SimInfo_t pDataAnd[k] = pData0[k] & pData1[k]; } // derive the PO siminfo - Aig_ManForEachPi( p, pNode, i ) + Aig_ManForEachPo( p, pNode, i ) { pDataPo = Aig_SimInfoForNode( pInfoAll, pNode ); pDataAnd = Aig_SimInfoForNode( pInfoAll, Aig_NodeFanin0(pNode) ); @@ -106,16 +106,17 @@ void Aig_ManSimulateInfo( Aig_Man_t * p, Aig_SimInfo_t * pInfoPi, Aig_SimInfo_t SeeAlso [] ***********************************************************************/ -Aig_SimInfo_t * Aig_SimInfoAlloc( int nNodes, int nWords, int Type ) +Aig_SimInfo_t * Aig_SimInfoAlloc( int nNodes, int nBits, int Type ) { Aig_SimInfo_t * p; p = ALLOC( Aig_SimInfo_t, 1 ); memset( p, 0, sizeof(Aig_SimInfo_t) ); p->Type = Type; p->nNodes = nNodes; - p->nWords = nWords; - p->nPatsMax = nWords * sizeof(unsigned) * 8; - p->pData = ALLOC( unsigned, nNodes * nWords ); + p->nWords = Aig_BitWordNum(nBits); + p->nPatsCur = nBits; + p->nPatsMax = p->nWords * sizeof(unsigned) * 8; + p->pData = ALLOC( unsigned, nNodes * p->nWords ); return p; } @@ -161,7 +162,6 @@ void Aig_SimInfoRandom( Aig_SimInfo_t * p ) pData = p->pData + p->nWords * i; *pData <<= 1; } - p->nPatsCur = p->nPatsMax; } /**Function************************************************************* @@ -180,8 +180,8 @@ void Aig_SimInfoFromPattern( Aig_SimInfo_t * p, Aig_Pattern_t * pPat ) unsigned * pData; int i, k; assert( p->Type == 0 ); - assert( p->nNodes == pPat->nBits ); - for ( i = 0; i < p->nNodes; i++ ) + assert( p->nPatsCur == pPat->nBits+1 ); + for ( i = 0; i < p->nPatsCur; i++ ) { // get the pointer to the bitdata for node i pData = p->pData + p->nWords * i; @@ -192,8 +192,8 @@ void Aig_SimInfoFromPattern( Aig_SimInfo_t * p, Aig_Pattern_t * pPat ) else for ( k = 0; k < p->nWords; k++ ) pData[k] = 0; - // flip one bit - Aig_InfoXorBit( pData, i ); + // flip one bit, starting from the first pattern + if ( i ) Aig_InfoXorBit( pData, i-1 ); } } @@ -285,6 +285,22 @@ void Aig_PatternClean( Aig_Pattern_t * pPat ) /**Function************************************************************* + Synopsis [Cleans the pattern.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_PatternFill( Aig_Pattern_t * pPat ) +{ + memset( pPat->pData, 0xff, sizeof(unsigned) * pPat->nWords ); +} + +/**Function************************************************************* + Synopsis [Sets the random pattern.] Description [] @@ -303,6 +319,25 @@ void Aig_PatternRandom( Aig_Pattern_t * pPat ) /**Function************************************************************* + Synopsis [Counts the number of 1s in the pattern.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Aig_PatternCount( Aig_Pattern_t * pPat ) +{ + int i, Counter = 0; + for ( i = 0; i < pPat->nBits; i++ ) + Counter += Aig_InfoHasBit( pPat->pData, i ); + return Counter; +} + +/**Function************************************************************* + Synopsis [Deallocates the pattern.] Description [] diff --git a/src/sat/aig/rwrTruth.c b/src/sat/aig/rwrTruth.c new file mode 100644 index 00000000..2c402184 --- /dev/null +++ b/src/sat/aig/rwrTruth.c @@ -0,0 +1,454 @@ +/**CFile**************************************************************** + + FileName [rwrTruth.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [And-Inverter Graph package.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: rwrTruth.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "aig.h" + +/* The code in this file was written with portability to 64-bits in mind. + The type "unsigned" is assumed to be 32-bit on any platform. +*/ + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +#define ABCTMAX 8 // the max number of vars + +typedef struct Aig_Truth_t_ Aig_Truth_t; +struct Aig_Truth_t_ +{ + short nVars; // the number of variables + short nWords; // the number of 32-bit words + unsigned Truth[1<<(ABCTMAX-5)]; // the truth table + unsigned Cofs[2][1<<(ABCTMAX-6)]; // the truth table of cofactors + unsigned Data[4][1<<(ABCTMAX-7)]; // the truth table of cofactors + short Counts[ABCTMAX][2]; // the minterm counters + Aig_Node_t * pLeaves[ABCTMAX]; // the pointers to leaves + Aig_Man_t * pMan; // the AIG manager +}; + +static void Aig_TruthCount( Aig_Truth_t * p ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Creates the function given the truth table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Truth_t * Aig_TruthCreate( int nVars, unsigned * pTruth, Aig_Node_t ** pLeaves ) +{ + Aig_Truth_t * p; + int i; + p = ALLOC( Aig_Truth_t, 1 ); + memset( p, 0, sizeof(Aig_Truth_t) ); + p->nVars = nVars; + p->nWords = (nVars < 5)? 1 : (1 << (nVars-5)); + for ( i = 0; i < p->nWords; i++ ) + p->Truth[i] = pTruth[i]; + if ( nVars < 5 ) + p->Truth[0] &= (~0u >> (32-(1<<nVars))); + for ( i = 0; i < p->nVars; i++ ) + p->pLeaves[i] = pLeaves[i]; + Aig_TruthCount( p ); + return p; +} + +/**Function************************************************************* + + Synopsis [Counts the number of miterms in the cofactors.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Aig_WordCountOnes( unsigned val ) +{ + val = (val & 0x55555555) + ((val>>1) & 0x55555555); + val = (val & 0x33333333) + ((val>>2) & 0x33333333); + val = (val & 0x0F0F0F0F) + ((val>>4) & 0x0F0F0F0F); + val = (val & 0x00FF00FF) + ((val>>8) & 0x00FF00FF); + return (val & 0x0000FFFF) + (val>>8); +} + +/**Function************************************************************* + + Synopsis [Counts the number of miterms in the cofactors.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_TruthCount( Aig_Truth_t * p ) +{ + static unsigned Masks[5][2] = { + { 0x33333333, 0xAAAAAAAA }, + { 0x55555555, 0xCCCCCCCC }, + { 0x0F0F0F0F, 0xF0F0F0F0 }, + { 0x00FF00FF, 0xFF00FF00 }, + { 0x0000FFFF, 0xFFFF0000 } + }; + + int i, k; + assert( p->Counts[0][0] == 0 && p->Counts[0][1] == 0 ); + for ( i = 0; i < p->nVars; i++ ) + { + p->Counts[i][0] = p->Counts[i][1] = 0; + if ( i < 5 ) + { + for ( k = 0; k < p->nWords; k++ ) + { + p->Counts[i][0] += Aig_WordCountOnes( p->Truth[k] & Masks[i][0] ); + p->Counts[i][1] += Aig_WordCountOnes( p->Truth[k] & Masks[i][1] ); + } + } + else + { + for ( k = 0; k < p->nWords; k++ ) + if ( i & (1 << (k-5)) ) + p->Counts[i][1] += Aig_WordCountOnes( p->Truth[k] ); + else + p->Counts[i][0] += Aig_WordCountOnes( p->Truth[k] ); + } + } +/* + // normalize the variables + for ( i = 0; i < p->nVars; i++ ) + if ( p->Counts[i][0] > p->Counts[i][1] ) + { + k = p->Counts[i][0]; + p->Counts[i][0] = p->Counts[i][1]; + p->Counts[i][1] = k; + p->pLeaves[i] = Aig_Not( p->pLeaves[i] ); + } +*/ +} + +/**Function************************************************************* + + Synopsis [Extracts one part of the bitstring.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline unsigned Aig_WordGetPart( unsigned * p, int Start, int Size ) +{ + return (p[Start/5] >> (Start%32)) & (~0u >> (32-Size)); +} + +/**Function************************************************************* + + Synopsis [Inserts one part of the bitstring.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Aig_WordSetPart( unsigned * p, int Start, unsigned Part ) +{ + p[Start/5] |= (Part << (Start%32)); +} + +/**Function************************************************************* + + Synopsis [Computes the cofactor with respect to one variable.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_TruthCofactor( int Var, int Pol, int nVars, unsigned * pTruth, unsigned * pResult ) +{ + if ( Var < 5 ) + { + int nPartSize = ( 1 << Var ); + int nParts = ( 1 << (nVars-Var-1) ); + unsigned uPart; + int i; + for ( i = 0; i < nParts; i++ ) + { + uPart = Aig_WordGetPart( pTruth, (2*i+Pol)*nPartSize, nPartSize ); + Aig_WordSetPart( pResult, i*nPartSize, uPart ); + } + if ( nVars <= 5 ) + pResult[0] &= (~0u >> (32-(1<<(nVars-1)))); + } + else + { + int nWords = (1 << (nVars-5)); + int i, k = 0; + for ( i = 0; i < nWords; i++ ) + if ( (i & (1 << (Var-5))) == Pol ) + pResult[k++] = pTruth[i]; + assert( k == nWords/2 ); + } +} + + + + +/**Function************************************************************* + + Synopsis [Computes the BDD of the truth table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * Aig_TruthToBdd_rec( DdManager * dd, unsigned * pTruth, int Shift, int nVars, int iVar ) +{ + DdNode * bCof0, * bCof1, * bRes; + if ( nVars == 1 ) + return Cudd_NotCond( Cudd_ReadOne(dd), !Aig_WordGetPart(pTruth, Shift, 1) ); + if ( nVars == 3 ) + { + unsigned char * pChar = ((char *)pTruth) + Shift/8; + assert( Shift % 8 == 0 ); + if ( *pChar == 0 ) + return Cudd_ReadLogicZero(dd); + if ( *pChar == 0xFF ) + return Cudd_ReadOne(dd); + } + if ( nVars == 5 ) + { + unsigned * pWord = pTruth + Shift/32; + assert( Shift % 32 == 0 ); + if ( *pWord == 0 ) + return Cudd_ReadLogicZero(dd); + if ( *pWord == 0xFFFFFFFF ) + return Cudd_ReadOne(dd); + } + bCof0 = Aig_TruthToBdd_rec( dd, pTruth, Shift, nVars-1, iVar+1 ); Cudd_Ref( bCof0 ); + bCof1 = Aig_TruthToBdd_rec( dd, pTruth, Shift + (1 << (nVars-1)), nVars-1, iVar+1 ); Cudd_Ref( bCof1 ); + bRes = Cudd_bddIte( dd, Cudd_bddIthVar(dd, iVar), bCof1, bCof0 ); Cudd_Ref( bRes ); + Cudd_RecursiveDeref( dd, bCof0 ); + Cudd_RecursiveDeref( dd, bCof1 ); + Cudd_Deref( bRes ); + return bRes; +} + +/**Function************************************************************* + + Synopsis [Computes the BDD of the truth table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * Aig_TruthToBdd( DdManager * dd, Aig_Truth_t * p ) +{ + return Aig_TruthToBdd_rec( dd, p->Truth, 0, p->nVars, 0 ); +} + + + + +/**Function************************************************************* + + Synopsis [Compare bistrings.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Aig_WordCompare( unsigned * p0, unsigned * p1, int nWords ) +{ + int i; + for ( i = 0; i < nWords; i++ ) + if ( p0[i] != p1[i] ) + return 0; + return 1; +} + +/**Function************************************************************* + + Synopsis [Compare bistrings.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Aig_WordCompareCompl( unsigned * p0, unsigned * p1, int nWords ) +{ + int i; + for ( i = 0; i < nWords; i++ ) + if ( p0[i] != ~p1[i] ) + return 0; + return 1; +} + +/**Function************************************************************* + + Synopsis [Computes the cofactor with respect to one variable.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_TruthReplaceByCofactor( Aig_Truth_t * p, int iVar, unsigned * pTruth ) +{ +} + + +/**Function************************************************************* + + Synopsis [Computes the cofactor with respect to one variable.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Node_t * Aig_TruthDecompose( Aig_Truth_t * p ) +{ + Aig_Node_t * pVar; + int nOnesCof = ( 1 << (p->nVars-1) ); + int nWordsCof = (p->nWords == 1 ? 1 : p->nWords/2); + int i; + + // check for constant function + if ( p->nVars == 0 ) + return Aig_NotCond( Aig_ManConst1(p->pMan), (p->Truth[0]&1)==0 ); + + // count the number of minterms in the cofactors + Aig_TruthCount( p ); + + // remove redundant variables and EXORs + for ( i = p->nVars - 1; i >= 0; i-- ) + { + if ( p->Counts[i][0] == p->Counts[i][1] ) + { + // compute cofactors + Aig_TruthCofactor( i, 0, p->nVars, p->Truth, p->Cofs[0] ); + Aig_TruthCofactor( i, 1, p->nVars, p->Truth, p->Cofs[1] ); + if ( Aig_WordCompare( p->Cofs[0], p->Cofs[1], nWordsCof ) ) + { // equal + // remove redundant variable + Aig_TruthReplaceByCofactor( p, i, p->Cofs[0] ); + return Aig_TruthDecompose( p ); + } + } + // check the case of EXOR + if ( p->Counts[i][0] == nOnesCof - p->Counts[i][1] ) + { + // compute cofactors + Aig_TruthCofactor( i, 0, p->nVars, p->Truth, p->Cofs[0] ); + Aig_TruthCofactor( i, 1, p->nVars, p->Truth, p->Cofs[1] ); + if ( Aig_WordCompareCompl( p->Cofs[0], p->Cofs[1], nWordsCof ) ) + { // equal + pVar = p->pLeaves[i]; + // remove redundant variable + Aig_TruthReplaceByCofactor( p, i, p->Cofs[0] ); + // F = x' * F0 + x * F1 = x <+> F0 assuming that F0 == ~F1 + return Aig_Xor( p->pMan, pVar, Aig_TruthDecompose( p ) ); + } + } + } + + // process variables with constant cofactors + for ( i = p->nVars - 1; i >= 0; i-- ) + { + if ( p->Counts[i][0] != 0 && p->Counts[i][1] != 0 && + p->Counts[i][0] != nOnesCof && p->Counts[i][1] != nOnesCof ) + continue; + pVar = p->pLeaves[i]; + if ( p->Counts[i][0] == 0 ) + { + Aig_TruthCofactor( i, 1, p->nVars, p->Truth, p->Cofs[1] ); + // remove redundant variable + Aig_TruthReplaceByCofactor( p, i, p->Cofs[1] ); + // F = x' * 0 + x * F1 = x * F1 + return Aig_And( p->pMan, pVar, Aig_TruthDecompose( p ) ); + } + if ( p->Counts[i][1] == 0 ) + { + Aig_TruthCofactor( i, 0, p->nVars, p->Truth, p->Cofs[0] ); + // remove redundant variable + Aig_TruthReplaceByCofactor( p, i, p->Cofs[0] ); + // F = x' * F0 + x * 0 = x' * F0 + return Aig_And( p->pMan, Aig_Not(pVar), Aig_TruthDecompose( p ) ); + } + if ( p->Counts[i][0] == nOnesCof ) + { + Aig_TruthCofactor( i, 1, p->nVars, p->Truth, p->Cofs[1] ); + // remove redundant variable + Aig_TruthReplaceByCofactor( p, i, p->Cofs[1] ); + // F = x' * 1 + x * F1 = x' + F1 + return Aig_Or( p->pMan, Aig_Not(pVar), Aig_TruthDecompose( p ) ); + } + if ( p->Counts[i][1] == nOnesCof ) + { + Aig_TruthCofactor( i, 0, p->nVars, p->Truth, p->Cofs[0] ); + // remove redundant variable + Aig_TruthReplaceByCofactor( p, i, p->Cofs[0] ); + // F = x' * F0 + x * 1 = x + F0 + return Aig_Or( p->pMan, pVar, Aig_TruthDecompose( p ) ); + } + assert( 0 ); + } + +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + |