/**Function************************************************************* Synopsis [Performs clock-gating for the AIG.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Cgt_ClockGatingRangeCheck( Cgt_Man_t * p, int iStart, int nOutputs ) { Vec_Ptr_t * vNodes = p->vFanout; Aig_Obj_t * pMiter, * pCand, * pMiterFrame, * pCandFrame, * pMiterPart, * pCandPart; int i, k, RetValue, nCalls; assert( Vec_VecSize(p->vGatesAll) == Aig_ManPoNum(p->pFrame) ); // go through all the registers inputs of this range for ( i = iStart; i < iStart + nOutputs; i++ ) { nCalls = p->nCalls; 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( Aig_Obj_t *, vNodes, pCand, k ) { // get the corresponding nodes from the frames pCandFrame = (Aig_Obj_t *)pCand->pData; pMiterFrame = (Aig_Obj_t *)pMiter->pData; // get the corresponding nodes from the part pCandPart = (Aig_Obj_t *)pCandFrame->pData; pMiterPart = (Aig_Obj_t *)pMiterFrame->pData; // try direct polarity if ( Cgt_SimulationFilter( p, pCandPart, pMiterPart ) ) { RetValue = Cgt_CheckImplication( p, pCandPart, pMiterPart ); if ( RetValue == 1 ) { Vec_VecPush( p->vGatesAll, i, pCand ); continue; } if ( RetValue == 0 ) Cgt_SimulationRecord( p ); } else p->nCallsFiltered++; // try reverse polarity if ( Cgt_SimulationFilter( p, Aig_Not(pCandPart), pMiterPart ) ) { RetValue = Cgt_CheckImplication( p, Aig_Not(pCandPart), pMiterPart ); if ( RetValue == 1 ) { Vec_VecPush( p->vGatesAll, i, Aig_Not(pCand) ); continue; } if ( RetValue == 0 ) Cgt_SimulationRecord( p ); } else p->nCallsFiltered++; } if ( p->pPars->fVerbose ) { // printf( "Flop %3d : Cand = %4d. Gate = %4d. SAT calls = %3d.\n", // i, Vec_PtrSize(vNodes), Vec_PtrSize(Vec_VecEntry(p->vGatesAll, i)), p->nCalls-nCalls ); } }
Vec_Ptr_t * Dar_BalanceCone( Aig_Obj_t * pObj, Vec_Vec_t * vStore, int Level ) { Vec_Ptr_t * vNodes; assert( !Aig_IsComplement(pObj) ); assert( Aig_ObjIsNode(pObj) ); // extend the storage if ( Vec_VecSize( vStore ) <= Level ) Vec_VecPush( vStore, Level, 0 ); // get the temporary array of nodes vNodes = Vec_VecEntry( vStore, Level ); Vec_PtrClear( vNodes ); // collect the nodes in the implication supergate Dar_BalanceCone_rec( pObj, pObj, vNodes ); // remove duplicates Dar_BalanceUniqify( pObj, vNodes, Aig_ObjIsExor(pObj) ); return vNodes; }
/**Function************************************************************* Synopsis [Verifies sequential equivalence by fraiging followed by SAT.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Abc_NtkCecFraigPartAuto( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fVerbose ) { extern int Abc_NtkCombinePos( Abc_Ntk_t * pNtk, int fAnd ); extern Vec_Vec_t * Abc_NtkPartitionSmart( Abc_Ntk_t * pNtk, int nPartSizeLimit, int fVerbose ); extern int Cmd_CommandExecute( void * pAbc, char * sCommand ); extern void * Abc_FrameGetGlobalFrame(); Vec_Vec_t * vParts; Vec_Ptr_t * vOne; Prove_Params_t Params, * pParams = &Params; Abc_Ntk_t * pMiter, * pMiterPart; int i, RetValue, Status, nOutputs; // solve the CNF using the SAT solver Prove_ParamsSetDefault( pParams ); pParams->nItersMax = 5; // pParams->fVerbose = 1; // get the miter of the two networks pMiter = Abc_NtkMiter( pNtk1, pNtk2, 1, 1 ); if ( pMiter == NULL ) { printf( "Miter computation has failed.\n" ); return; } RetValue = Abc_NtkMiterIsConstant( pMiter ); if ( RetValue == 0 ) { printf( "Networks are NOT EQUIVALENT after structural hashing.\n" ); // report the error pMiter->pModel = Abc_NtkVerifyGetCleanModel( pMiter, 1 ); Abc_NtkVerifyReportError( pNtk1, pNtk2, pMiter->pModel ); FREE( pMiter->pModel ); Abc_NtkDelete( pMiter ); return; } if ( RetValue == 1 ) { printf( "Networks are equivalent after structural hashing.\n" ); Abc_NtkDelete( pMiter ); return; } Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "unset progressbar" ); // partition the outputs vParts = Abc_NtkPartitionSmart( pMiter, 50, 1 ); // fraig each partition Status = 1; nOutputs = 0; Vec_VecForEachLevel( vParts, vOne, i ) { // get this part of the miter pMiterPart = Abc_NtkCreateConeArray( pMiter, vOne, 0 ); Abc_NtkCombinePos( pMiterPart, 0 ); // check the miter for being constant RetValue = Abc_NtkMiterIsConstant( pMiterPart ); if ( RetValue == 0 ) { printf( "Networks are NOT EQUIVALENT after partitioning.\n" ); Abc_NtkDelete( pMiterPart ); break; } if ( RetValue == 1 ) { Abc_NtkDelete( pMiterPart ); continue; } // solve the problem RetValue = Abc_NtkIvyProve( &pMiterPart, pParams ); if ( RetValue == -1 ) { printf( "Networks are undecided (resource limits is reached).\r" ); Status = -1; } else if ( RetValue == 0 ) { int * pSimInfo = Abc_NtkVerifySimulatePattern( pMiterPart, pMiterPart->pModel ); if ( pSimInfo[0] != 1 ) printf( "ERROR in Abc_NtkMiterProve(): Generated counter-example is invalid.\n" ); else printf( "Networks are NOT EQUIVALENT. \n" ); free( pSimInfo ); Status = 0; Abc_NtkDelete( pMiterPart ); break; } else { printf( "Finished part %d (out of %d)\r", i+1, Vec_VecSize(vParts) ); nOutputs += Vec_PtrSize(vOne); } Abc_NtkDelete( pMiterPart ); }