| /**CFile**************************************************************** |
| |
| FileName [giaSat.c] |
| |
| SystemName [ABC: Logic synthesis and verification system.] |
| |
| PackageName [Scalable AIG package.] |
| |
| Synopsis [New constraint-propagation procedures.] |
| |
| Author [Alan Mishchenko] |
| |
| Affiliation [UC Berkeley] |
| |
| Date [Ver. 1.0. Started - June 20, 2005.] |
| |
| Revision [$Id: giaSat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] |
| |
| ***********************************************************************/ |
| |
| #include "gia.h" |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// DECLARATIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| #define GIA_LIMIT 10 |
| |
| |
| typedef struct Gia_ManSat_t_ Gia_ManSat_t; |
| struct Gia_ManSat_t_ |
| { |
| Aig_MmFlex_t * pMem; |
| }; |
| |
| typedef struct Gia_ObjSat1_t_ Gia_ObjSat1_t; |
| struct Gia_ObjSat1_t_ |
| { |
| char nFans; |
| char nOffset; |
| char PathsH; |
| char PathsV; |
| }; |
| |
| typedef struct Gia_ObjSat2_t_ Gia_ObjSat2_t; |
| struct Gia_ObjSat2_t_ |
| { |
| unsigned fTerm : 1; |
| unsigned iLit : 31; |
| }; |
| |
| typedef struct Gia_ObjSat_t_ Gia_ObjSat_t; |
| struct Gia_ObjSat_t_ |
| { |
| union { |
| Gia_ObjSat1_t Obj1; |
| Gia_ObjSat2_t Obj2; |
| }; |
| }; |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// FUNCTION DEFINITIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Gia_ManSat_t * Gia_ManSatStart() |
| { |
| Gia_ManSat_t * p; |
| p = ABC_CALLOC( Gia_ManSat_t, 1 ); |
| p->pMem = Aig_MmFlexStart(); |
| return p; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Gia_ManSatStop( Gia_ManSat_t * p ) |
| { |
| Aig_MmFlexStop( p->pMem, 0 ); |
| ABC_FREE( p ); |
| } |
| |
| |
| /**Function************************************************************* |
| |
| Synopsis [Collects the supergate rooted at this ] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Gia_ManSatPartCollectSuper( Gia_Man_t * p, Gia_Obj_t * pObj, int * pLits, int * pnLits ) |
| { |
| Gia_Obj_t * pFanin; |
| assert( Gia_ObjIsAnd(pObj) ); |
| assert( pObj->fMark0 == 0 ); |
| pFanin = Gia_ObjFanin0(pObj); |
| if ( pFanin->fMark0 || Gia_ObjFaninC0(pObj) ) |
| pLits[(*pnLits)++] = Gia_Var2Lit(Gia_ObjId(p, pFanin), Gia_ObjFaninC0(pObj)); |
| else |
| Gia_ManSatPartCollectSuper(p, pFanin, pLits, pnLits); |
| pFanin = Gia_ObjFanin1(pObj); |
| if ( pFanin->fMark0 || Gia_ObjFaninC1(pObj) ) |
| pLits[(*pnLits)++] = Gia_Var2Lit(Gia_ObjId(p, pFanin), Gia_ObjFaninC1(pObj)); |
| else |
| Gia_ManSatPartCollectSuper(p, pFanin, pLits, pnLits); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Returns the number of words used.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Gia_ManSatPartCreate_rec( Gia_Man_t * p, Gia_Obj_t * pObj, int * pObjPlace, int * pStore ) |
| { |
| Gia_Obj_t * pFanin; |
| int i, nWordsUsed, nSuperSize = 0, Super[2*GIA_LIMIT]; |
| // make sure this is a valid node |
| assert( Gia_ObjIsAnd(pObj) ); |
| assert( pObj->fMark0 == 0 ); |
| // collect inputs to the supergate |
| Gia_ManSatPartCollectSuper( p, pObj, Super, &nSuperSize ); |
| assert( nSuperSize <= 2*GIA_LIMIT ); |
| // create the root entry |
| *pObjPlace = 0; |
| ((Gia_ObjSat1_t *)pObjPlace)->nFans = Gia_Var2Lit( nSuperSize, 0 ); |
| ((Gia_ObjSat1_t *)pObjPlace)->nOffset = pStore - pObjPlace; |
| nWordsUsed = nSuperSize; |
| for ( i = 0; i < nSuperSize; i++ ) |
| { |
| pFanin = Gia_ManObj( p, Gia_Lit2Var(Super[i]) ); |
| if ( pFanin->fMark0 ) |
| { |
| ((Gia_ObjSat2_t *)(pStore + i))->fTerm = 1; |
| ((Gia_ObjSat2_t *)(pStore + i))->iLit = Super[i]; |
| } |
| else |
| { |
| assert( Gia_LitIsCompl(Super[i]) ); |
| nWordsUsed += Gia_ManSatPartCreate_rec( p, pFanin, pStore + i, pStore + nWordsUsed ); |
| } |
| } |
| return nWordsUsed; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Creates part and returns the number of words used.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Gia_ManSatPartCreate( Gia_Man_t * p, Gia_Obj_t * pObj, int * pStore ) |
| { |
| return 1 + Gia_ManSatPartCreate_rec( p, pObj, pStore, pStore + 1 ); |
| } |
| |
| |
| /**Function************************************************************* |
| |
| Synopsis [Count the number of internal nodes in the leaf-DAG.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Gia_ManSatPartCountClauses( Gia_Man_t * p, Gia_Obj_t * pObj, int * pnOnset, int * pnOffset ) |
| { |
| Gia_Obj_t * pFanin; |
| int nOnset0, nOnset1, nOffset0, nOffset1; |
| assert( Gia_ObjIsAnd(pObj) ); |
| pFanin = Gia_ObjFanin0(pObj); |
| if ( pFanin->fMark0 ) |
| nOnset0 = 1, nOffset0 = 1; |
| else |
| { |
| Gia_ManSatPartCountClauses(p, pFanin, &nOnset0, &nOffset0); |
| if ( Gia_ObjFaninC0(pObj) ) |
| { |
| int Temp = nOnset0; |
| nOnset0 = nOffset0; |
| nOffset0 = Temp; |
| } |
| } |
| pFanin = Gia_ObjFanin1(pObj); |
| if ( pFanin->fMark0 ) |
| nOnset1 = 1, nOffset1 = 1; |
| else |
| { |
| Gia_ManSatPartCountClauses(p, pFanin, &nOnset1, &nOffset1); |
| if ( Gia_ObjFaninC1(pObj) ) |
| { |
| int Temp = nOnset1; |
| nOnset1 = nOffset1; |
| nOffset1 = Temp; |
| } |
| } |
| *pnOnset = nOnset0 * nOnset1; |
| *pnOffset = nOffset0 + nOffset1; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Count the number of internal nodes in the leaf-DAG.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Gia_ManSatPartCount( Gia_Man_t * p, Gia_Obj_t * pObj, int * pnLeaves, int * pnNodes ) |
| { |
| Gia_Obj_t * pFanin; |
| int Level0 = 0, Level1 = 0; |
| assert( Gia_ObjIsAnd(pObj) ); |
| assert( pObj->fMark0 == 0 ); |
| (*pnNodes)++; |
| pFanin = Gia_ObjFanin0(pObj); |
| if ( pFanin->fMark0 ) |
| (*pnLeaves)++; |
| else |
| Level0 = Gia_ManSatPartCount(p, pFanin, pnLeaves, pnNodes) + Gia_ObjFaninC0(pObj); |
| pFanin = Gia_ObjFanin1(pObj); |
| if ( pFanin->fMark0 ) |
| (*pnLeaves)++; |
| else |
| Level1 = Gia_ManSatPartCount(p, pFanin, pnLeaves, pnNodes) + Gia_ObjFaninC1(pObj); |
| return Abc_MaxInt( Level0, Level1 ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Count the number of internal nodes in the leaf-DAG.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Gia_ManSatPartCountNodes( Gia_Man_t * p, Gia_Obj_t * pObj ) |
| { |
| Gia_Obj_t * pFanin; |
| int nNodes0 = 0, nNodes1 = 0; |
| assert( Gia_ObjIsAnd(pObj) ); |
| assert( pObj->fMark0 == 0 ); |
| pFanin = Gia_ObjFanin0(pObj); |
| if ( !(pFanin->fMark0) ) |
| nNodes0 = Gia_ManSatPartCountNodes(p, pFanin); |
| pFanin = Gia_ObjFanin1(pObj); |
| if ( !(pFanin->fMark0) ) |
| nNodes1 = Gia_ManSatPartCountNodes(p, pFanin); |
| return nNodes0 + nNodes1 + 1; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Count the number of internal nodes in the leaf-DAG.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Gia_ManSatPartPrint( Gia_Man_t * p, Gia_Obj_t * pObj, int Step ) |
| { |
| Gia_Obj_t * pFanin; |
| assert( Gia_ObjIsAnd(pObj) ); |
| assert( pObj->fMark0 == 0 ); |
| pFanin = Gia_ObjFanin0(pObj); |
| if ( pFanin->fMark0 ) |
| printf( "%s%d", Gia_ObjFaninC0(pObj)?"!":"", Gia_ObjId(p,pFanin) ); |
| else |
| { |
| if ( Gia_ObjFaninC0(pObj) ) |
| printf( "(" ); |
| Gia_ManSatPartPrint(p, pFanin, Step + Gia_ObjFaninC0(pObj)); |
| if ( Gia_ObjFaninC0(pObj) ) |
| printf( ")" ); |
| } |
| printf( "%s", (Step & 1)? " + " : "*" ); |
| pFanin = Gia_ObjFanin1(pObj); |
| if ( pFanin->fMark0 ) |
| printf( "%s%d", Gia_ObjFaninC1(pObj)?"!":"", Gia_ObjId(p,pFanin) ); |
| else |
| { |
| if ( Gia_ObjFaninC1(pObj) ) |
| printf( "(" ); |
| Gia_ManSatPartPrint(p, pFanin, Step + Gia_ObjFaninC1(pObj)); |
| if ( Gia_ObjFaninC1(pObj) ) |
| printf( ")" ); |
| } |
| } |
| |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Gia_ManSatExperiment( Gia_Man_t * p ) |
| { |
| int nStored, Storage[1000], * pStart; |
| Gia_ManSat_t * pMan; |
| Gia_Obj_t * pObj; |
| int i, nLevels, nLeaves, nNodes, nCount[2*GIA_LIMIT+2] = {0}, nCountAll = 0; |
| int Num0 = 0, Num1 = 0; |
| clock_t clk = clock(); |
| int nWords = 0, nWords2 = 0; |
| pMan = Gia_ManSatStart(); |
| // mark the nodes to become roots of leaf-DAGs |
| Gia_ManCreateValueRefs( p ); |
| Gia_ManForEachObj( p, pObj, i ) |
| { |
| pObj->fMark0 = 0; |
| if ( Gia_ObjIsCo(pObj) ) |
| Gia_ObjFanin0(pObj)->fMark0 = 1; |
| else if ( Gia_ObjIsCi(pObj) ) |
| pObj->fMark0 = 1; |
| else if ( Gia_ObjIsAnd(pObj) ) |
| { |
| if ( pObj->Value > 1 || Gia_ManSatPartCountNodes(p,pObj) >= GIA_LIMIT ) |
| pObj->fMark0 = 1; |
| } |
| pObj->Value = 0; |
| } |
| // compute the sizes of leaf-DAGs |
| Gia_ManForEachAnd( p, pObj, i ) |
| { |
| if ( pObj->fMark0 == 0 ) |
| continue; |
| pObj->fMark0 = 0; |
| |
| nCountAll++; |
| nStored = Gia_ManSatPartCreate( p, pObj, Storage ); |
| nWords2 += nStored; |
| assert( nStored < 500 ); |
| pStart = (int *)Aig_MmFlexEntryFetch( pMan->pMem, sizeof(int) * nStored ); |
| memcpy( pStart, Storage, sizeof(int) * nStored ); |
| |
| nLeaves = nNodes = 0; |
| nLevels = 1+Gia_ManSatPartCount( p, pObj, &nLeaves, &nNodes ); |
| nWords += nLeaves + nNodes; |
| if ( nNodes <= 2*GIA_LIMIT ) |
| nCount[nNodes]++; |
| else |
| nCount[2*GIA_LIMIT+1]++; |
| // if ( nNodes > 10 && i % 100 == 0 ) |
| // if ( nNodes > 5 ) |
| if ( 0 ) |
| { |
| Gia_ManSatPartCountClauses( p, pObj, &Num0, &Num1 ); |
| printf( "%8d : And = %3d. Lev = %2d. Clauses = %3d. (%3d + %3d).\n", i, nNodes, nLevels, Num0+Num1, Num0, Num1 ); |
| Gia_ManSatPartPrint( p, pObj, 0 ); |
| printf( "\n" ); |
| } |
| |
| pObj->fMark0 = 1; |
| } |
| printf( "\n" ); |
| Gia_ManForEachObj( p, pObj, i ) |
| pObj->fMark0 = 0; |
| Gia_ManSatStop( pMan ); |
| for ( i = 0; i < 2*GIA_LIMIT+2; i++ ) |
| printf( "%2d=%6d %7.2f %% %7.2f %%\n", i, nCount[i], 100.0*nCount[i]/nCountAll, 100.0*i*nCount[i]/Gia_ManAndNum(p) ); |
| ABC_PRMn( "MemoryEst", 4*nWords ); |
| ABC_PRMn( "MemoryReal", 4*nWords2 ); |
| printf( "%5.2f bpn ", 4.0*nWords2/Gia_ManObjNum(p) ); |
| ABC_PRT( "Time", clock() - clk ); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// END OF FILE /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| ABC_NAMESPACE_IMPL_END |
| |