| /**CFile**************************************************************** |
| |
| FileName [kliveness.c] |
| |
| SystemName [ABC: Logic synthesis and verification system.] |
| |
| PackageName [Liveness property checking.] |
| |
| Synopsis [Main implementation module of the algorithm k-Liveness ] |
| [invented by Koen Claessen, Niklas Sorensson. Implements] |
| [the code for 'kcs'. 'kcs' pre-processes based on switch] |
| [and then runs the (absorber circuit >> pdr) loop ] |
| |
| Author [Sayak Ray] |
| |
| Affiliation [UC Berkeley] |
| |
| Date [Ver. 1.0. Started - October 31, 2012.] |
| |
| ***********************************************************************/ |
| |
| #include <stdio.h> |
| #include "base/main/main.h" |
| #include "aig/aig/aig.h" |
| #include "aig/saig/saig.h" |
| #include <string.h> |
| #include "base/main/mainInt.h" |
| #include "proof/pdr/pdr.h" |
| #include <time.h> |
| |
| //#define WITHOUT_CONSTRAINTS |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| /***************** Declaration of standard ABC related functions ********************/ |
| extern Aig_Man_t * Abc_NtkToDar( Abc_Ntk_t * pNtk, int fExors, int fRegisters ); |
| extern Abc_Ntk_t * Abc_NtkFromAigPhase( Aig_Man_t * pMan ); |
| extern Abc_Ntk_t * Abc_NtkMakeOnePo( Abc_Ntk_t * pNtk, int Output, int nRange ); |
| extern void Aig_ManDumpBlif( Aig_Man_t * p, char * pFileName, Vec_Ptr_t * vPiNames, Vec_Ptr_t * vPoNames ); |
| /***********************************************************************************/ |
| |
| /***************** Declaration of kLiveness related functions **********************/ |
| //function defined in kLiveConstraints.c |
| extern Aig_Man_t *generateWorkingAig( Aig_Man_t *pAig, Abc_Ntk_t *pNtk, int *pIndex0Live ); |
| |
| //function defined in arenaViolation.c |
| extern Aig_Man_t *generateWorkingAigWithDSC( Aig_Man_t *pAig, Abc_Ntk_t *pNtk, int *pIndex0Live, Vec_Ptr_t *vMasterBarriers ); |
| |
| //function defined in disjunctiveMonotone.c |
| extern Vec_Ptr_t *findDisjunctiveMonotoneSignals( Abc_Ntk_t *pNtk ); |
| extern Vec_Int_t *createSingletonIntVector( int i ); |
| /***********************************************************************************/ |
| extern Aig_Man_t *generateDisjunctiveTester( Abc_Ntk_t *pNtk, Aig_Man_t *pAig, int combN, int combK ); |
| extern Aig_Man_t *generateGeneralDisjunctiveTester( Abc_Ntk_t *pNtk, Aig_Man_t *pAig, int combK ); |
| |
| //Definition of some macros pertaining to modes/switches |
| #define SIMPLE_kCS 0 |
| #define kCS_WITH_SAFETY_INVARIANTS 1 |
| #define kCS_WITH_DISCOVER_MONOTONE_SIGNALS 2 |
| #define kCS_WITH_SAFETY_AND_DCS_INVARIANTS 3 |
| #define kCS_WITH_SAFETY_AND_USER_GIVEN_DCS_INVARIANTS 4 |
| |
| //unused function |
| #if 0 |
| Aig_Obj_t *readTargetPinSignal(Aig_Man_t *pAig, Abc_Ntk_t *pNtk) |
| { |
| Aig_Obj_t *pObj; |
| int i; |
| |
| Saig_ManForEachPo( pAig, pObj, i ) |
| { |
| if( strstr( Abc_ObjName(Abc_NtkPo( pNtk, i )), "0Liveness_" ) != NULL ) |
| { |
| //return Aig_ObjFanin0(pObj); |
| return Aig_NotCond((Aig_Obj_t *)Aig_ObjFanin0(pObj), Aig_ObjFaninC0(pObj)); |
| } |
| } |
| |
| return NULL; |
| } |
| #endif |
| |
| Aig_Obj_t *readLiveSignal_0( Aig_Man_t *pAig, int liveIndex_0 ) |
| { |
| Aig_Obj_t *pObj; |
| |
| pObj = Aig_ManCo( pAig, liveIndex_0 ); |
| return Aig_NotCond((Aig_Obj_t *)Aig_ObjFanin0(pObj), Aig_ObjFaninC0(pObj)); |
| } |
| |
| Aig_Obj_t *readLiveSignal_k( Aig_Man_t *pAig, int liveIndex_k ) |
| { |
| Aig_Obj_t *pObj; |
| |
| pObj = Aig_ManCo( pAig, liveIndex_k ); |
| return Aig_NotCond((Aig_Obj_t *)Aig_ObjFanin0(pObj), Aig_ObjFaninC0(pObj)); |
| } |
| |
| //unused funtion |
| #if 0 |
| Aig_Obj_t *readTargetPoutSignal(Aig_Man_t *pAig, Abc_Ntk_t *pNtk, int nonFirstIteration) |
| { |
| Aig_Obj_t *pObj; |
| int i; |
| |
| if( nonFirstIteration == 0 ) |
| return NULL; |
| else |
| Saig_ManForEachPo( pAig, pObj, i ) |
| { |
| if( strstr( Abc_ObjName(Abc_NtkPo( pNtk, i )), "kLiveness_" ) != NULL ) |
| { |
| //return Aig_ObjFanin0(pObj); |
| return Aig_NotCond((Aig_Obj_t *)Aig_ObjFanin0(pObj), Aig_ObjFaninC0(pObj)); |
| } |
| } |
| |
| return NULL; |
| } |
| #endif |
| |
| //unused function |
| #if 0 |
| void updateNewNetworkNameManager_kCS( Abc_Ntk_t *pNtk, Aig_Man_t *pAig, Vec_Ptr_t *vPiNames, |
| Vec_Ptr_t *vLoNames, Vec_Ptr_t *vPoNames, Vec_Ptr_t *vLiNames ) |
| { |
| 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; |
| 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; |
| Nm_ManStoreIdName( pNtk->pManName, ntkObjId, Aig_ObjType(pObj), (char *)Vec_PtrEntry(vLoNames, i), NULL ); |
| } |
| } |
| |
| if( vPoNames ) |
| { |
| Saig_ManForEachPo( pAig, pObj, i ) |
| { |
| ntkObjId = Abc_NtkCo( pNtk, i )->Id; |
| Nm_ManStoreIdName( pNtk->pManName, ntkObjId, Aig_ObjType(pObj), (char *)Vec_PtrEntry(vPoNames, i), NULL ); |
| } |
| } |
| |
| if( vLiNames ) |
| { |
| Saig_ManForEachLi( pAig, pObj, i ) |
| { |
| ntkObjId = Abc_NtkCo( pNtk, Saig_ManPoNum( pAig ) + i )->Id; |
| Nm_ManStoreIdName( pNtk->pManName, ntkObjId, Aig_ObjType(pObj), (char *)Vec_PtrEntry(vLiNames, i), NULL ); |
| } |
| } |
| |
| // 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 ); |
| } |
| #endif |
| |
| Aig_Man_t *introduceAbsorberLogic( Aig_Man_t *pAig, int *pLiveIndex_0, int *pLiveIndex_k, int nonFirstIteration ) |
| { |
| Aig_Man_t *pNewAig; |
| Aig_Obj_t *pObj, *pObjAbsorberLo, *pPInNewArg, *pPOutNewArg; |
| Aig_Obj_t *pPIn = NULL, *pPOut = NULL, *pPOutCo = NULL; |
| Aig_Obj_t *pFirstAbsorberOr, *pSecondAbsorberOr; |
| int i; |
| int piCopied = 0, loCreated = 0, loCopied = 0, liCreated = 0, liCopied = 0; |
| int nRegCount; |
| |
| assert(*pLiveIndex_0 != -1); |
| if(nonFirstIteration == 0) |
| assert( *pLiveIndex_k == -1 ); |
| else |
| assert( *pLiveIndex_k != -1 ); |
| |
| //**************************************************************** |
| // 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 |
| //**************************************************************** |
| pNewAig = Aig_ManStart( Aig_ManObjNumMax(pAig) ); |
| pNewAig->pName = (char *)malloc( strlen( pAig->pName ) + strlen("_kCS") + 1 ); |
| sprintf(pNewAig->pName, "%s_%s", pAig->pName, "kCS"); |
| pNewAig->pSpec = NULL; |
| |
| //**************************************************************** |
| // reading the signal pIn, and pOut |
| //**************************************************************** |
| |
| pPIn = readLiveSignal_0( pAig, *pLiveIndex_0 ); |
| if( *pLiveIndex_k == -1 ) |
| pPOut = NULL; |
| else |
| pPOut = readLiveSignal_k( pAig, *pLiveIndex_k ); |
| |
| //**************************************************************** |
| // Step 2: map constant nodes |
| //**************************************************************** |
| pObj = Aig_ManConst1( pAig ); |
| pObj->pData = Aig_ManConst1( pNewAig ); |
| |
| //**************************************************************** |
| // Step 3: create true PIs |
| //**************************************************************** |
| Saig_ManForEachPi( pAig, pObj, i ) |
| { |
| piCopied++; |
| pObj->pData = Aig_ObjCreateCi(pNewAig); |
| } |
| |
| //**************************************************************** |
| // Step 5: create register outputs |
| //**************************************************************** |
| Saig_ManForEachLo( pAig, pObj, i ) |
| { |
| loCopied++; |
| pObj->pData = Aig_ObjCreateCi(pNewAig); |
| } |
| |
| //**************************************************************** |
| // Step 6: create "D" register output for the ABSORBER logic |
| //**************************************************************** |
| loCreated++; |
| pObjAbsorberLo = Aig_ObjCreateCi( pNewAig ); |
| |
| nRegCount = loCreated + loCopied; |
| |
| //******************************************************************** |
| // Step 7: create internal nodes |
| //******************************************************************** |
| Aig_ManForEachNode( pAig, pObj, i ) |
| { |
| pObj->pData = Aig_And( pNewAig, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); |
| } |
| |
| //**************************************************************** |
| // Step 8: create the two OR gates of the OBSERVER logic |
| //**************************************************************** |
| if( nonFirstIteration == 0 ) |
| { |
| assert(pPIn); |
| |
| pPInNewArg = !Aig_IsComplement(pPIn)? |
| (Aig_Obj_t *)((Aig_Regular(pPIn))->pData) : |
| Aig_Not((Aig_Obj_t *)((Aig_Regular(pPIn))->pData)); |
| |
| pFirstAbsorberOr = Aig_Or( pNewAig, Aig_Not(pPInNewArg), pObjAbsorberLo ); |
| pSecondAbsorberOr = Aig_Or( pNewAig, pPInNewArg, Aig_Not(pObjAbsorberLo) ); |
| } |
| else |
| { |
| assert( pPOut ); |
| |
| pPInNewArg = !Aig_IsComplement(pPIn)? |
| (Aig_Obj_t *)((Aig_Regular(pPIn))->pData) : |
| Aig_Not((Aig_Obj_t *)((Aig_Regular(pPIn))->pData)); |
| pPOutNewArg = !Aig_IsComplement(pPOut)? |
| (Aig_Obj_t *)((Aig_Regular(pPOut))->pData) : |
| Aig_Not((Aig_Obj_t *)((Aig_Regular(pPOut))->pData)); |
| |
| pFirstAbsorberOr = Aig_Or( pNewAig, Aig_Not(pPOutNewArg), pObjAbsorberLo ); |
| pSecondAbsorberOr = Aig_Or( pNewAig, pPInNewArg, Aig_Not(pObjAbsorberLo) ); |
| } |
| |
| //******************************************************************** |
| // Step 9: create primary outputs |
| //******************************************************************** |
| Saig_ManForEachPo( pAig, pObj, i ) |
| { |
| pObj->pData = Aig_ObjCreateCo( pNewAig, Aig_ObjChild0Copy(pObj) ); |
| if( i == *pLiveIndex_k ) |
| pPOutCo = (Aig_Obj_t *)(pObj->pData); |
| } |
| |
| //create new po |
| if( nonFirstIteration == 0 ) |
| { |
| assert(pPOutCo == NULL); |
| pPOutCo = Aig_ObjCreateCo( pNewAig, pSecondAbsorberOr ); |
| |
| *pLiveIndex_k = i; |
| } |
| else |
| { |
| assert( pPOutCo != NULL ); |
| //pPOutCo = Aig_ObjCreateCo( pNewAig, pSecondAbsorberOr ); |
| //*pLiveIndex_k = Saig_ManPoNum(pAig); |
| |
| Aig_ObjPatchFanin0( pNewAig, pPOutCo, pSecondAbsorberOr ); |
| } |
| |
| Saig_ManForEachLi( pAig, pObj, i ) |
| { |
| liCopied++; |
| Aig_ObjCreateCo( pNewAig, Aig_ObjChild0Copy(pObj) ); |
| } |
| |
| //create new li |
| liCreated++; |
| Aig_ObjCreateCo( pNewAig, pFirstAbsorberOr ); |
| |
| Aig_ManSetRegNum( pNewAig, nRegCount ); |
| Aig_ManCleanup( pNewAig ); |
| |
| assert( Aig_ManCheck( pNewAig ) ); |
| |
| assert( *pLiveIndex_k != - 1); |
| return pNewAig; |
| } |
| |
| void modifyAigToApplySafetyInvar(Aig_Man_t *pAig, int csTarget, int safetyInvarPO) |
| { |
| Aig_Obj_t *pObjPOSafetyInvar, *pObjSafetyInvar; |
| Aig_Obj_t *pObjPOCSTarget, *pObjCSTarget; |
| Aig_Obj_t *pObjCSTargetNew; |
| |
| pObjPOSafetyInvar = Aig_ManCo( pAig, safetyInvarPO ); |
| pObjSafetyInvar = Aig_NotCond((Aig_Obj_t *)Aig_ObjFanin0(pObjPOSafetyInvar), Aig_ObjFaninC0(pObjPOSafetyInvar)); |
| pObjPOCSTarget = Aig_ManCo( pAig, csTarget ); |
| pObjCSTarget = Aig_NotCond((Aig_Obj_t *)Aig_ObjFanin0(pObjPOCSTarget), Aig_ObjFaninC0(pObjPOCSTarget)); |
| |
| pObjCSTargetNew = Aig_And( pAig, pObjSafetyInvar, pObjCSTarget ); |
| Aig_ObjPatchFanin0( pAig, pObjPOCSTarget, pObjCSTargetNew ); |
| } |
| |
| int flipConePdr( Aig_Man_t *pAig, int directive, int targetCSPropertyIndex, int safetyInvariantPOIndex, int absorberCount ) |
| { |
| int RetValue, i; |
| Aig_Obj_t *pObjTargetPo; |
| Aig_Man_t *pAigDupl; |
| Pdr_Par_t Pars, * pPars = &Pars; |
| Abc_Cex_t * pCex = NULL; |
| |
| char *fileName; |
| |
| fileName = (char *)malloc(sizeof(char) * 50); |
| sprintf(fileName, "%s_%d.%s", "kLive", absorberCount, "blif" ); |
| |
| if( directive == kCS_WITH_SAFETY_INVARIANTS || directive == kCS_WITH_SAFETY_AND_DCS_INVARIANTS || directive == kCS_WITH_SAFETY_AND_USER_GIVEN_DCS_INVARIANTS ) |
| { |
| assert( safetyInvariantPOIndex != -1 ); |
| modifyAigToApplySafetyInvar(pAig, targetCSPropertyIndex, safetyInvariantPOIndex); |
| } |
| |
| pAigDupl = pAig; |
| pAig = Aig_ManDupSimple( pAigDupl ); |
| |
| for( i=0; i<Saig_ManPoNum(pAig); i++ ) |
| { |
| pObjTargetPo = Aig_ManCo( pAig, i ); |
| Aig_ObjChild0Flip( pObjTargetPo ); |
| } |
| |
| Pdr_ManSetDefaultParams( pPars ); |
| pPars->fVerbose = 1; |
| pPars->fNotVerbose = 1; |
| pPars->fSolveAll = 1; |
| pAig->vSeqModelVec = NULL; |
| |
| Aig_ManCleanup( pAig ); |
| assert( Aig_ManCheck( pAig ) ); |
| |
| Pdr_ManSolve( pAig, pPars ); |
| |
| if( pAig->vSeqModelVec ) |
| { |
| pCex = (Abc_Cex_t *)Vec_PtrEntry( pAig->vSeqModelVec, targetCSPropertyIndex ); |
| if( pCex == NULL ) |
| { |
| RetValue = 1; |
| } |
| else |
| RetValue = 0; |
| } |
| else |
| { |
| RetValue = -1; |
| exit(0); |
| } |
| |
| free(fileName); |
| |
| for( i=0; i<Saig_ManPoNum(pAig); i++ ) |
| { |
| pObjTargetPo = Aig_ManCo( pAig, i ); |
| Aig_ObjChild0Flip( pObjTargetPo ); |
| } |
| |
| Aig_ManStop( pAig ); |
| return RetValue; |
| } |
| |
| //unused function |
| #if 0 |
| int read0LiveIndex( Abc_Ntk_t *pNtk ) |
| { |
| Abc_Obj_t *pObj; |
| int i; |
| |
| Abc_NtkForEachPo( pNtk, pObj, i ) |
| { |
| if( strstr( Abc_ObjName( pObj ), "0Liveness_" ) != NULL ) |
| return i; |
| } |
| |
| return -1; |
| } |
| #endif |
| |
| int collectSafetyInvariantPOIndex(Abc_Ntk_t *pNtk) |
| { |
| Abc_Obj_t *pObj; |
| int i; |
| |
| Abc_NtkForEachPo( pNtk, pObj, i ) |
| { |
| if( strstr( Abc_ObjName( pObj ), "csSafetyInvar_" ) != NULL ) |
| return i; |
| } |
| |
| return -1; |
| } |
| |
| Vec_Ptr_t *collectUserGivenDisjunctiveMonotoneSignals( Abc_Ntk_t *pNtk ) |
| { |
| Abc_Obj_t *pObj; |
| int i; |
| Vec_Ptr_t *monotoneVector; |
| Vec_Int_t *newIntVector; |
| |
| monotoneVector = Vec_PtrAlloc(0); |
| Abc_NtkForEachPo( pNtk, pObj, i ) |
| { |
| if( strstr( Abc_ObjName( pObj ), "csLevel1Stabil_" ) != NULL ) |
| { |
| newIntVector = createSingletonIntVector(i); |
| Vec_PtrPush(monotoneVector, newIntVector); |
| } |
| } |
| |
| if( Vec_PtrSize(monotoneVector) > 0 ) |
| return monotoneVector; |
| else |
| return NULL; |
| |
| } |
| |
| void deallocateMasterBarrierDisjunctInt(Vec_Ptr_t *vMasterBarrierDisjunctsArg) |
| { |
| Vec_Int_t *vInt; |
| int i; |
| |
| if(vMasterBarrierDisjunctsArg) |
| { |
| Vec_PtrForEachEntry(Vec_Int_t *, vMasterBarrierDisjunctsArg, vInt, i) |
| { |
| Vec_IntFree(vInt); |
| } |
| Vec_PtrFree(vMasterBarrierDisjunctsArg); |
| } |
| } |
| |
| void deallocateMasterBarrierDisjunctVecPtrVecInt(Vec_Ptr_t *vMasterBarrierDisjunctsArg) |
| { |
| Vec_Int_t *vInt; |
| Vec_Ptr_t *vPtr; |
| int i, j, k, iElem; |
| |
| if(vMasterBarrierDisjunctsArg) |
| { |
| Vec_PtrForEachEntry(Vec_Ptr_t *, vMasterBarrierDisjunctsArg, vPtr, i) |
| { |
| assert(vPtr); |
| Vec_PtrForEachEntry( Vec_Int_t *, vPtr, vInt, j ) |
| { |
| //Vec_IntFree(vInt); |
| Vec_IntForEachEntry( vInt, iElem, k ) |
| printf("%d - ", iElem); |
| //printf("Chung Chang j = %d\n", j); |
| } |
| Vec_PtrFree(vPtr); |
| } |
| Vec_PtrFree(vMasterBarrierDisjunctsArg); |
| } |
| } |
| |
| Vec_Ptr_t *getVecOfVecFairness(FILE *fp) |
| { |
| Vec_Ptr_t *masterVector = Vec_PtrAlloc(0); |
| //Vec_Ptr_t *currSignalVector; |
| char stringBuffer[100]; |
| //int i; |
| |
| while(fgets(stringBuffer, 50, fp)) |
| { |
| if(strstr(stringBuffer, ":")) |
| { |
| |
| } |
| else |
| { |
| |
| } |
| } |
| |
| return masterVector; |
| } |
| |
| |
| int Abc_CommandCS_kLiveness( Abc_Frame_t * pAbc, int argc, char ** argv ) |
| { |
| Abc_Ntk_t * pNtk, * pNtkTemp; |
| Aig_Man_t * pAig, *pAigCS, *pAigCSNew; |
| int absorberCount; |
| int absorberLimit = 500; |
| int RetValue; |
| int liveIndex_0 = -1, liveIndex_k = -1; |
| int fVerbose = 1; |
| int directive = -1; |
| int c; |
| int safetyInvariantPO = -1; |
| abctime beginTime, endTime; |
| double time_spent; |
| Vec_Ptr_t *vMasterBarrierDisjuncts = NULL; |
| Aig_Man_t *pWorkingAig; |
| //FILE *fp; |
| |
| pNtk = Abc_FrameReadNtk(pAbc); |
| |
| //fp = fopen("propFile.txt", "r"); |
| //if( fp ) |
| // getVecOfVecFairness(fp); |
| //exit(0); |
| |
| /************************************************* |
| Extraction of Command Line Argument |
| *************************************************/ |
| if( argc == 1 ) |
| { |
| assert( directive == -1 ); |
| directive = SIMPLE_kCS; |
| } |
| else |
| { |
| Extra_UtilGetoptReset(); |
| while ( ( c = Extra_UtilGetopt( argc, argv, "cmCgh" ) ) != EOF ) |
| { |
| switch( c ) |
| { |
| case 'c': |
| directive = kCS_WITH_SAFETY_INVARIANTS; |
| break; |
| case 'm': |
| directive = kCS_WITH_DISCOVER_MONOTONE_SIGNALS; |
| break; |
| case 'C': |
| directive = kCS_WITH_SAFETY_AND_DCS_INVARIANTS; |
| break; |
| case 'g': |
| directive = kCS_WITH_SAFETY_AND_USER_GIVEN_DCS_INVARIANTS; |
| break; |
| case 'h': |
| goto usage; |
| break; |
| default: |
| goto usage; |
| } |
| } |
| } |
| /************************************************* |
| Extraction of Command Line Argument Ends |
| *************************************************/ |
| |
| if( !Abc_NtkIsStrash( pNtk ) ) |
| { |
| printf("The input network was not strashed, strashing....\n"); |
| pNtkTemp = Abc_NtkStrash( pNtk, 0, 0, 0 ); |
| pAig = Abc_NtkToDar( pNtkTemp, 0, 1 ); |
| } |
| else |
| { |
| pAig = Abc_NtkToDar( pNtk, 0, 1 ); |
| pNtkTemp = pNtk; |
| } |
| |
| if( directive == kCS_WITH_SAFETY_INVARIANTS ) |
| { |
| safetyInvariantPO = collectSafetyInvariantPOIndex(pNtkTemp); |
| assert( safetyInvariantPO != -1 ); |
| } |
| |
| if(directive == kCS_WITH_DISCOVER_MONOTONE_SIGNALS) |
| { |
| beginTime = Abc_Clock(); |
| vMasterBarrierDisjuncts = findDisjunctiveMonotoneSignals( pNtk ); |
| endTime = Abc_Clock(); |
| time_spent = (double)(endTime - beginTime)/CLOCKS_PER_SEC; |
| printf("pre-processing time = %f\n",time_spent); |
| return 0; |
| } |
| |
| if(directive == kCS_WITH_SAFETY_AND_DCS_INVARIANTS) |
| { |
| safetyInvariantPO = collectSafetyInvariantPOIndex(pNtkTemp); |
| assert( safetyInvariantPO != -1 ); |
| |
| beginTime = Abc_Clock(); |
| vMasterBarrierDisjuncts = findDisjunctiveMonotoneSignals( pNtk ); |
| endTime = Abc_Clock(); |
| time_spent = (double)(endTime - beginTime)/CLOCKS_PER_SEC; |
| printf("pre-processing time = %f\n",time_spent); |
| |
| assert( vMasterBarrierDisjuncts != NULL ); |
| assert( Vec_PtrSize(vMasterBarrierDisjuncts) > 0 ); |
| } |
| |
| if(directive == kCS_WITH_SAFETY_AND_USER_GIVEN_DCS_INVARIANTS) |
| { |
| safetyInvariantPO = collectSafetyInvariantPOIndex(pNtkTemp); |
| assert( safetyInvariantPO != -1 ); |
| |
| beginTime = Abc_Clock(); |
| vMasterBarrierDisjuncts = collectUserGivenDisjunctiveMonotoneSignals( pNtk ); |
| endTime = Abc_Clock(); |
| time_spent = (double)(endTime - beginTime)/CLOCKS_PER_SEC; |
| printf("pre-processing time = %f\n",time_spent); |
| |
| assert( vMasterBarrierDisjuncts != NULL ); |
| assert( Vec_PtrSize(vMasterBarrierDisjuncts) > 0 ); |
| } |
| |
| if(directive == kCS_WITH_SAFETY_AND_DCS_INVARIANTS || directive == kCS_WITH_SAFETY_AND_USER_GIVEN_DCS_INVARIANTS) |
| { |
| assert( vMasterBarrierDisjuncts != NULL ); |
| pWorkingAig = generateWorkingAigWithDSC( pAig, pNtk, &liveIndex_0, vMasterBarrierDisjuncts ); |
| pAigCS = introduceAbsorberLogic(pWorkingAig, &liveIndex_0, &liveIndex_k, 0); |
| } |
| else |
| { |
| pWorkingAig = generateWorkingAig( pAig, pNtk, &liveIndex_0 ); |
| pAigCS = introduceAbsorberLogic(pWorkingAig, &liveIndex_0, &liveIndex_k, 0); |
| } |
| |
| Aig_ManStop(pWorkingAig); |
| |
| for( absorberCount=1; absorberCount<absorberLimit; absorberCount++ ) |
| { |
| //printf( "\nindex of the liveness output = %d\n", liveIndex_k ); |
| RetValue = flipConePdr( pAigCS, directive, liveIndex_k, safetyInvariantPO, absorberCount ); |
| |
| if ( RetValue == 1 ) |
| { |
| Abc_Print( 1, "k = %d, Property proved\n", absorberCount ); |
| break; |
| } |
| else if ( RetValue == 0 ) |
| { |
| if( fVerbose ) |
| { |
| Abc_Print( 1, "k = %d, Property DISPROVED\n", absorberCount ); |
| } |
| } |
| else if ( RetValue == -1 ) |
| { |
| Abc_Print( 1, "Property UNDECIDED with k = %d.\n", absorberCount ); |
| } |
| else |
| assert( 0 ); |
| |
| pAigCSNew = introduceAbsorberLogic(pAigCS, &liveIndex_0, &liveIndex_k, absorberCount); |
| Aig_ManStop(pAigCS); |
| pAigCS = pAigCSNew; |
| } |
| |
| Aig_ManStop(pAigCS); |
| Aig_ManStop(pAig); |
| |
| if(directive == kCS_WITH_SAFETY_AND_USER_GIVEN_DCS_INVARIANTS) |
| { |
| deallocateMasterBarrierDisjunctInt(vMasterBarrierDisjuncts); |
| } |
| else |
| { |
| //if(vMasterBarrierDisjuncts) |
| // Vec_PtrFree(vMasterBarrierDisjuncts); |
| //deallocateMasterBarrierDisjunctVecPtrVecInt(vMasterBarrierDisjuncts); |
| deallocateMasterBarrierDisjunctInt(vMasterBarrierDisjuncts); |
| } |
| return 0; |
| |
| usage: |
| fprintf( stdout, "usage: kcs [-cmgCh]\n" ); |
| fprintf( stdout, "\timplements Claessen-Sorensson's k-Liveness algorithm\n" ); |
| fprintf( stdout, "\t-c : verification with constraints, looks for POs prefixed with csSafetyInvar_\n"); |
| fprintf( stdout, "\t-m : discovers monotone signals\n"); |
| fprintf( stdout, "\t-g : verification with user-supplied barriers, looks for POs prefixed with csLevel1Stabil_\n"); |
| fprintf( stdout, "\t-C : verification with discovered monotone signals\n"); |
| fprintf( stdout, "\t-h : print usage\n"); |
| return 1; |
| |
| } |
| |
| int Abc_CommandNChooseK( Abc_Frame_t * pAbc, int argc, char ** argv ) |
| { |
| Abc_Ntk_t * pNtk, * pNtkTemp, *pNtkCombStabil; |
| Aig_Man_t * pAig, *pAigCombStabil; |
| int directive = -1; |
| int c; |
| int parameterizedCombK; |
| |
| pNtk = Abc_FrameReadNtk(pAbc); |
| |
| |
| /************************************************* |
| Extraction of Command Line Argument |
| *************************************************/ |
| if( argc == 1 ) |
| { |
| assert( directive == -1 ); |
| directive = SIMPLE_kCS; |
| } |
| else |
| { |
| Extra_UtilGetoptReset(); |
| while ( ( c = Extra_UtilGetopt( argc, argv, "cmCgh" ) ) != EOF ) |
| { |
| switch( c ) |
| { |
| case 'c': |
| directive = kCS_WITH_SAFETY_INVARIANTS; |
| break; |
| case 'm': |
| directive = kCS_WITH_DISCOVER_MONOTONE_SIGNALS; |
| break; |
| case 'C': |
| directive = kCS_WITH_SAFETY_AND_DCS_INVARIANTS; |
| break; |
| case 'g': |
| directive = kCS_WITH_SAFETY_AND_USER_GIVEN_DCS_INVARIANTS; |
| break; |
| case 'h': |
| goto usage; |
| break; |
| default: |
| goto usage; |
| } |
| } |
| } |
| /************************************************* |
| Extraction of Command Line Argument Ends |
| *************************************************/ |
| |
| if( !Abc_NtkIsStrash( pNtk ) ) |
| { |
| printf("The input network was not strashed, strashing....\n"); |
| pNtkTemp = Abc_NtkStrash( pNtk, 0, 0, 0 ); |
| pAig = Abc_NtkToDar( pNtkTemp, 0, 1 ); |
| } |
| else |
| { |
| pAig = Abc_NtkToDar( pNtk, 0, 1 ); |
| pNtkTemp = pNtk; |
| } |
| |
| /**********************Code for generation of nCk outputs**/ |
| //combCount = countCombination(1000, 3); |
| //pAigCombStabil = generateDisjunctiveTester( pNtk, pAig, 7, 2 ); |
| printf("Enter parameterizedCombK = " ); |
| if( scanf("%d", ¶meterizedCombK) != 1 ) |
| { |
| printf("\nFailed to read integer!\n"); |
| return 0; |
| } |
| printf("\n"); |
| |
| pAigCombStabil = generateGeneralDisjunctiveTester( pNtk, pAig, parameterizedCombK ); |
| Aig_ManPrintStats(pAigCombStabil); |
| pNtkCombStabil = Abc_NtkFromAigPhase( pAigCombStabil ); |
| pNtkCombStabil->pName = Abc_UtilStrsav( pAigCombStabil->pName ); |
| if ( !Abc_NtkCheck( pNtkCombStabil ) ) |
| fprintf( stdout, "Abc_NtkCreateCone(): Network check has failed.\n" ); |
| Abc_FrameSetCurrentNetwork( pAbc, pNtkCombStabil ); |
| |
| Aig_ManStop( pAigCombStabil ); |
| Aig_ManStop( pAig ); |
| |
| return 1; |
| //printf("\ncombCount = %d\n", combCount); |
| //exit(0); |
| /**********************************************************/ |
| |
| usage: |
| fprintf( stdout, "usage: nck [-cmgCh]\n" ); |
| fprintf( stdout, "\tgenerates combinatorial signals for stabilization\n" ); |
| fprintf( stdout, "\t-h : print usage\n"); |
| return 1; |
| |
| } |
| |
| |
| ABC_NAMESPACE_IMPL_END |