/**CFile**************************************************************** FileName [fraHot.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [New FRAIG package.] Synopsis [Computing and using one-hotness conditions.] Author [Alan Mishchenko] Affiliation [UC Berkeley] Date [Ver. 1.0. Started - June 30, 2007.] Revision [$Id: fraHot.c,v 1.00 2007/06/30 00:00:00 alanmi Exp $] ***********************************************************************/ #include "fra.h" ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// static inline int Fra_RegToLit( int n, int c ) { return c? -n-1 : n+1; } static inline int Fra_LitReg( int n ) { return (n>0)? n-1 : -n-1; } static inline int Fra_LitSign( int n ) { return (n<0); } //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Returns 1 if simulation info is composed of all zeros.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Fra_OneHotNodeIsConst( Fra_Sml_t * pSeq, Aig_Obj_t * pObj ) { unsigned * pSims; int i; pSims = Fra_ObjSim(pSeq, pObj->Id); for ( i = pSeq->nWordsPref; i < pSeq->nWordsTotal; i++ ) if ( pSims[i] ) return 0; return 1; } /**Function************************************************************* Synopsis [Returns 1 if simulation infos are equal.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Fra_OneHotNodesAreEqual( Fra_Sml_t * pSeq, Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 ) { unsigned * pSims0, * pSims1; int i; pSims0 = Fra_ObjSim(pSeq, pObj0->Id); pSims1 = Fra_ObjSim(pSeq, pObj1->Id); for ( i = pSeq->nWordsPref; i < pSeq->nWordsTotal; i++ ) if ( pSims0[i] != pSims1[i] ) return 0; return 1; } /**Function************************************************************* Synopsis [Returns 1 if implications holds.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Fra_OneHotNodesAreClause( Fra_Sml_t * pSeq, Aig_Obj_t * pObj1, Aig_Obj_t * pObj2, int fCompl1, int fCompl2 ) { unsigned * pSim1, * pSim2; int k; pSim1 = Fra_ObjSim(pSeq, pObj1->Id); pSim2 = Fra_ObjSim(pSeq, pObj2->Id); if ( fCompl1 && fCompl2 ) { for ( k = pSeq->nWordsPref; k < pSeq->nWordsTotal; k++ ) if ( pSim1[k] & pSim2[k] ) return 0; } else if ( fCompl1 ) { for ( k = pSeq->nWordsPref; k < pSeq->nWordsTotal; k++ ) if ( pSim1[k] & ~pSim2[k] ) return 0; } else if ( fCompl2 ) { for ( k = pSeq->nWordsPref; k < pSeq->nWordsTotal; k++ ) if ( ~pSim1[k] & pSim2[k] ) return 0; } else assert( 0 ); return 1; } /**Function************************************************************* Synopsis [Computes one-hot implications.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Vec_Int_t * Fra_OneHotCompute( Fra_Man_t * p, Fra_Sml_t * pSim ) { int fSkipConstEqu = 1; Vec_Int_t * vOneHots; Aig_Obj_t * pObj1, * pObj2; int i, k; int nTruePis = Aig_ManCiNum(pSim->pAig) - Aig_ManRegNum(pSim->pAig); assert( pSim->pAig == p->pManAig ); vOneHots = Vec_IntAlloc( 100 ); Aig_ManForEachLoSeq( pSim->pAig, pObj1, i ) { if ( fSkipConstEqu && Fra_OneHotNodeIsConst(pSim, pObj1) ) continue; assert( i-nTruePis >= 0 ); // Aig_ManForEachLoSeq( pSim->pAig, pObj2, k ) // Vec_PtrForEachEntryStart( Aig_Obj_t *, pSim->pAig->vPis, pObj2, k, Aig_ManCiNum(p)-Aig_ManRegNum(p) ) Vec_PtrForEachEntryStart( Aig_Obj_t *, pSim->pAig->vCis, pObj2, k, i+1 ) { if ( fSkipConstEqu && Fra_OneHotNodeIsConst(pSim, pObj2) ) continue; if ( fSkipConstEqu && Fra_OneHotNodesAreEqual( pSim, pObj1, pObj2 ) ) continue; assert( k-nTruePis >= 0 ); if ( Fra_OneHotNodesAreClause( pSim, pObj1, pObj2, 1, 1 ) ) { Vec_IntPush( vOneHots, Fra_RegToLit(i-nTruePis, 1) ); Vec_IntPush( vOneHots, Fra_RegToLit(k-nTruePis, 1) ); continue; } if ( Fra_OneHotNodesAreClause( pSim, pObj1, pObj2, 0, 1 ) ) { Vec_IntPush( vOneHots, Fra_RegToLit(i-nTruePis, 0) ); Vec_IntPush( vOneHots, Fra_RegToLit(k-nTruePis, 1) ); continue; } if ( Fra_OneHotNodesAreClause( pSim, pObj1, pObj2, 1, 0 ) ) { Vec_IntPush( vOneHots, Fra_RegToLit(i-nTruePis, 1) ); Vec_IntPush( vOneHots, Fra_RegToLit(k-nTruePis, 0) ); continue; } } } return vOneHots; } /**Function************************************************************* Synopsis [Assumes one-hot implications in the SAT solver.] Description [] SideEffects [] SeeAlso [] **********************************************************************/ void Fra_OneHotAssume( Fra_Man_t * p, Vec_Int_t * vOneHots ) { Aig_Obj_t * pObj1, * pObj2; int i, Out1, Out2, pLits[2]; int nPiNum = Aig_ManCiNum(p->pManFraig) - Aig_ManRegNum(p->pManFraig); assert( p->pPars->nFramesK == 1 ); // add to only one frame for ( i = 0; i < Vec_IntSize(vOneHots); i += 2 ) { Out1 = Vec_IntEntry( vOneHots, i ); Out2 = Vec_IntEntry( vOneHots, i+1 ); if ( Out1 == 0 && Out2 == 0 ) continue; pObj1 = Aig_ManCi( p->pManFraig, nPiNum + Fra_LitReg(Out1) ); pObj2 = Aig_ManCi( 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 constraint to solver if ( !sat_solver_addclause( p->pSat, pLits, pLits + 2 ) ) { printf( "Fra_OneHotAssume(): Adding clause makes SAT solver unsat.\n" ); sat_solver_delete( p->pSat ); p->pSat = NULL; return; } } } /**Function************************************************************* Synopsis [Checks one-hot implications.] Description [] SideEffects [] SeeAlso [] **********************************************************************/ void Fra_OneHotCheck( Fra_Man_t * p, Vec_Int_t * vOneHots ) { Aig_Obj_t * pObj1, * pObj2; int RetValue, i, Out1, Out2; int nTruePos = Aig_ManCoNum(p->pManFraig) - Aig_ManRegNum(p->pManFraig); for ( i = 0; i < Vec_IntSize(vOneHots); i += 2 ) { Out1 = Vec_IntEntry( vOneHots, i ); Out2 = Vec_IntEntry( vOneHots, i+1 ); if ( Out1 == 0 && Out2 == 0 ) continue; pObj1 = Aig_ManCo( p->pManFraig, nTruePos + Fra_LitReg(Out1) ); pObj2 = Aig_ManCo( p->pManFraig, nTruePos + Fra_LitReg(Out2) ); RetValue = Fra_NodesAreClause( p, pObj1, pObj2, Fra_LitSign(Out1), Fra_LitSign(Out2) ); if ( RetValue != 1 ) { p->pCla->fRefinement = 1; if ( RetValue == 0 ) Fra_SmlResimulate( p ); if ( Vec_IntEntry(vOneHots, i) != 0 ) printf( "Fra_OneHotCheck(): Clause is not refined!\n" ); assert( Vec_IntEntry(vOneHots, i) == 0 ); } } } /**Function************************************************************* Synopsis [Removes those implications that no longer hold.] Description [Returns 1 if refinement has happened.] SideEffects [] SeeAlso [] ***********************************************************************/ int Fra_OneHotRefineUsingCex( Fra_Man_t * p, Vec_Int_t * vOneHots ) { Aig_Obj_t * pObj1, * pObj2; int i, Out1, Out2, RetValue = 0; int nPiNum = Aig_ManCiNum(p->pManAig) - Aig_ManRegNum(p->pManAig); assert( p->pSml->pAig == p->pManAig ); for ( i = 0; i < Vec_IntSize(vOneHots); i += 2 ) { Out1 = Vec_IntEntry( vOneHots, i ); Out2 = Vec_IntEntry( vOneHots, i+1 ); if ( Out1 == 0 && Out2 == 0 ) continue; // get the corresponding nodes pObj1 = Aig_ManCi( p->pManAig, nPiNum + Fra_LitReg(Out1) ); pObj2 = Aig_ManCi( p->pManAig, nPiNum + Fra_LitReg(Out2) ); // check if implication holds using this simulation info if ( !Fra_OneHotNodesAreClause( p->pSml, pObj1, pObj2, Fra_LitSign(Out1), Fra_LitSign(Out2) ) ) { Vec_IntWriteEntry( vOneHots, i, 0 ); Vec_IntWriteEntry( vOneHots, i+1, 0 ); RetValue = 1; } } return RetValue; } /**Function************************************************************* Synopsis [Removes those implications that no longer hold.] Description [Returns 1 if refinement has happened.] SideEffects [] SeeAlso [] ***********************************************************************/ int Fra_OneHotCount( Fra_Man_t * p, Vec_Int_t * vOneHots ) { int i, Out1, Out2, Counter = 0; for ( i = 0; i < Vec_IntSize(vOneHots); i += 2 ) { Out1 = Vec_IntEntry( vOneHots, i ); Out2 = Vec_IntEntry( vOneHots, i+1 ); if ( Out1 == 0 && Out2 == 0 ) continue; Counter++; } return Counter; } /**Function************************************************************* Synopsis [Estimates the coverage of state space by clauses.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Fra_OneHotEstimateCoverage( Fra_Man_t * p, Vec_Int_t * vOneHots ) { int nSimWords = (1<<14); int nRegs = Aig_ManRegNum(p->pManAig); Vec_Ptr_t * vSimInfo; unsigned * pSim1, * pSim2, * pSimTot; int i, w, Out1, Out2, nCovered, Counter = 0; abctime clk = Abc_Clock(); // generate random sim-info at register outputs vSimInfo = Vec_PtrAllocSimInfo( nRegs + 1, nSimWords ); // srand( 0xAABBAABB ); Aig_ManRandom(1); for ( i = 0; i < nRegs; i++ ) { pSim1 = (unsigned *)Vec_PtrEntry( vSimInfo, i ); for ( w = 0; w < nSimWords; w++ ) pSim1[w] = Fra_ObjRandomSim(); } pSimTot = (unsigned *)Vec_PtrEntry( vSimInfo, nRegs ); // collect simulation info memset( pSimTot, 0, sizeof(unsigned) * nSimWords ); for ( i = 0; i < Vec_IntSize(vOneHots); i += 2 ) { Out1 = Vec_IntEntry( vOneHots, i ); Out2 = Vec_IntEntry( vOneHots, i+1 ); if ( Out1 == 0 && Out2 == 0 ) continue; //printf( "(%c%d,%c%d) ", //Fra_LitSign(Out1)? '-': '+', Fra_LitReg(Out1), //Fra_LitSign(Out2)? '-': '+', Fra_LitReg(Out2) ); Counter++; 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]; else if ( Fra_LitSign(Out1) ) for ( w = 0; w < nSimWords; w++ ) pSimTot[w] |= pSim1[w] & ~pSim2[w]; else if ( Fra_LitSign(Out2) ) for ( w = 0; w < nSimWords; w++ ) pSimTot[w] |= ~pSim1[w] & pSim2[w]; else assert( 0 ); } //printf( "\n" ); // count the total number of patterns contained in the don't-care nCovered = 0; for ( w = 0; w < nSimWords; w++ ) nCovered += Aig_WordCountOnes( pSimTot[w] ); Vec_PtrFree( vSimInfo ); // print the result printf( "Care states ratio = %f. ", 1.0 * (nSimWords * 32 - nCovered) / (nSimWords * 32) ); printf( "(%d out of %d patterns) ", nSimWords * 32 - nCovered, nSimWords * 32 ); ABC_PRT( "Time", Abc_Clock() - clk ); } /**Function************************************************************* Synopsis [Creates one-hotness EXDC.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Aig_Man_t * Fra_OneHotCreateExdc( Fra_Man_t * p, Vec_Int_t * vOneHots ) { Aig_Man_t * pNew; Aig_Obj_t * pObj1, * pObj2, * pObj; int i, Out1, Out2, nTruePis; pNew = Aig_ManStart( Vec_IntSize(vOneHots)/2 ); // for ( i = 0; i < Aig_ManRegNum(p->pManAig); i++ ) // Aig_ObjCreateCi(pNew); Aig_ManForEachCi( p->pManAig, pObj, i ) Aig_ObjCreateCi(pNew); nTruePis = Aig_ManCiNum(p->pManAig) - Aig_ManRegNum(p->pManAig); for ( i = 0; i < Vec_IntSize(vOneHots); i += 2 ) { Out1 = Vec_IntEntry( vOneHots, i ); Out2 = Vec_IntEntry( vOneHots, i+1 ); if ( Out1 == 0 && Out2 == 0 ) continue; pObj1 = Aig_ManCi( pNew, nTruePis + Fra_LitReg(Out1) ); pObj2 = Aig_ManCi( pNew, nTruePis + Fra_LitReg(Out2) ); pObj1 = Aig_NotCond( pObj1, Fra_LitSign(Out1) ); pObj2 = Aig_NotCond( pObj2, Fra_LitSign(Out2) ); pObj = Aig_Or( pNew, pObj1, pObj2 ); Aig_ObjCreateCo( pNew, pObj ); } Aig_ManCleanup(pNew); // printf( "Created AIG with %d nodes and %d outputs.\n", Aig_ManNodeNum(pNew), Aig_ManCoNum(pNew) ); return pNew; } /**Function************************************************************* Synopsis [Assumes one-hot implications in the SAT solver.] Description [] SideEffects [] SeeAlso [] **********************************************************************/ void Fra_OneHotAddKnownConstraint( Fra_Man_t * p, Vec_Ptr_t * vOnehots ) { Vec_Int_t * vGroup; Aig_Obj_t * pObj1, * pObj2; int k, i, j, Out1, Out2, pLits[2]; // // these constrants should be added to different timeframes! // (also note that PIs follow first - then registers) // Vec_PtrForEachEntry( Vec_Int_t *, vOnehots, vGroup, k ) { Vec_IntForEachEntry( vGroup, Out1, i ) Vec_IntForEachEntryStart( vGroup, Out2, j, i+1 ) { pObj1 = Aig_ManCi( p->pManFraig, Out1 ); pObj2 = Aig_ManCi( p->pManFraig, Out2 ); pLits[0] = toLitCond( Fra_ObjSatNum(pObj1), 1 ); pLits[1] = toLitCond( Fra_ObjSatNum(pObj2), 1 ); // add constraint to solver if ( !sat_solver_addclause( p->pSat, pLits, pLits + 2 ) ) { printf( "Fra_OneHotAddKnownConstraint(): Adding clause makes SAT solver unsat.\n" ); sat_solver_delete( p->pSat ); p->pSat = NULL; return; } } } } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END