| /**CFile**************************************************************** |
| |
| FileName [abcSense.c] |
| |
| SystemName [ABC: Logic synthesis and verification system.] |
| |
| PackageName [Network and node package.] |
| |
| Synopsis [] |
| |
| Author [Alan Mishchenko] |
| |
| Affiliation [UC Berkeley] |
| |
| Date [Ver. 1.0. Started - June 20, 2005.] |
| |
| Revision [$Id: abc_.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] |
| |
| ***********************************************************************/ |
| |
| #include "base/abc/abc.h" |
| #include "proof/fraig/fraig.h" |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// DECLARATIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// FUNCTION DEFINITIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| /**Function************************************************************* |
| |
| Synopsis [Copies the topmost levels of the network.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Abc_Obj_t * Abc_NtkSensitivityMiter_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode ) |
| { |
| assert( !Abc_ObjIsComplement(pNode) ); |
| if ( pNode->pCopy ) |
| return pNode->pCopy; |
| Abc_NtkSensitivityMiter_rec( pNtkNew, Abc_ObjFanin0(pNode) ); |
| Abc_NtkSensitivityMiter_rec( pNtkNew, Abc_ObjFanin1(pNode) ); |
| return pNode->pCopy = Abc_AigAnd( (Abc_Aig_t *)pNtkNew->pManFunc, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Creates miter for the sensitivity analysis.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Abc_Ntk_t * Abc_NtkSensitivityMiter( Abc_Ntk_t * pNtk, int iVar ) |
| { |
| Abc_Ntk_t * pMiter; |
| Vec_Ptr_t * vNodes; |
| Abc_Obj_t * pObj, * pNext, * pFanin, * pOutput, * pObjNew; |
| int i; |
| assert( Abc_NtkIsStrash(pNtk) ); |
| assert( iVar < Abc_NtkCiNum(pNtk) ); |
| |
| // duplicate the network |
| pMiter = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG, 1 ); |
| pMiter->pName = Extra_UtilStrsav(pNtk->pName); |
| pMiter->pSpec = Extra_UtilStrsav(pNtk->pSpec); |
| |
| // assign the PIs |
| Abc_NtkCleanCopy( pNtk ); |
| Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pMiter); |
| Abc_AigConst1(pNtk)->pData = Abc_AigConst1(pMiter); |
| Abc_NtkForEachCi( pNtk, pObj, i ) |
| { |
| pObj->pCopy = Abc_NtkCreatePi( pMiter ); |
| pObj->pData = pObj->pCopy; |
| } |
| Abc_NtkAddDummyPiNames( pMiter ); |
| |
| // assign the cofactors of the CI node to be constants |
| pObj = Abc_NtkCi( pNtk, iVar ); |
| pObj->pCopy = Abc_ObjNot( Abc_AigConst1(pMiter) ); |
| pObj->pData = Abc_AigConst1(pMiter); |
| |
| // collect the internal nodes |
| vNodes = Abc_NtkDfsReverseNodes( pNtk, &pObj, 1 ); |
| Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i ) |
| { |
| for ( pNext = pObj? pObj->pCopy : pObj; pObj; pObj = pNext, pNext = pObj? pObj->pCopy : pObj ) |
| { |
| pFanin = Abc_ObjFanin0(pObj); |
| if ( !Abc_NodeIsTravIdCurrent(pFanin) ) |
| pFanin->pData = Abc_NtkSensitivityMiter_rec( pMiter, pFanin ); |
| pFanin = Abc_ObjFanin1(pObj); |
| if ( !Abc_NodeIsTravIdCurrent(pFanin) ) |
| pFanin->pData = Abc_NtkSensitivityMiter_rec( pMiter, pFanin ); |
| pObj->pCopy = Abc_AigAnd( (Abc_Aig_t *)pMiter->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) ); |
| pObj->pData = Abc_AigAnd( (Abc_Aig_t *)pMiter->pManFunc, Abc_ObjChild0Data(pObj), Abc_ObjChild1Data(pObj) ); |
| } |
| } |
| Vec_PtrFree( vNodes ); |
| |
| // update the affected COs |
| pOutput = Abc_ObjNot( Abc_AigConst1(pMiter) ); |
| Abc_NtkForEachCo( pNtk, pObj, i ) |
| { |
| if ( !Abc_NodeIsTravIdCurrent(pObj) ) |
| continue; |
| // get the result of quantification |
| if ( i == Abc_NtkCoNum(pNtk) - 1 ) |
| { |
| pOutput = Abc_AigAnd( (Abc_Aig_t *)pMiter->pManFunc, pOutput, Abc_ObjChild0Data(pObj) ); |
| pOutput = Abc_AigAnd( (Abc_Aig_t *)pMiter->pManFunc, pOutput, Abc_ObjChild0Copy(pObj) ); |
| } |
| else |
| { |
| pNext = Abc_AigXor( (Abc_Aig_t *)pMiter->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild0Data(pObj) ); |
| pOutput = Abc_AigOr( (Abc_Aig_t *)pMiter->pManFunc, pOutput, pNext ); |
| } |
| } |
| // add the PO node and name |
| pObjNew = Abc_NtkCreatePo(pMiter); |
| Abc_ObjAddFanin( pObjNew, pOutput ); |
| Abc_ObjAssignName( pObjNew, "miter", NULL ); |
| // make sure everything is okay |
| if ( !Abc_NtkCheck( pMiter ) ) |
| { |
| printf( "Abc_NtkSensitivityMiter: The network check has failed.\n" ); |
| Abc_NtkDelete( pMiter ); |
| return NULL; |
| } |
| return pMiter; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Computing sensitivity of POs to POs under constraints.] |
| |
| Description [The input network is a combinatonal AIG. The last output |
| is a constraint. The procedure returns the list of number of PIs, |
| such that at least one PO depends on this PI, under the constraint.] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Vec_Int_t * Abc_NtkSensitivity( Abc_Ntk_t * pNtk, int nConfLim, int fVerbose ) |
| { |
| ProgressBar * pProgress; |
| Prove_Params_t Params, * pParams = &Params; |
| Vec_Int_t * vResult = NULL; |
| Abc_Ntk_t * pMiter; |
| Abc_Obj_t * pObj; |
| int RetValue, i; |
| assert( Abc_NtkIsStrash(pNtk) ); |
| assert( Abc_NtkLatchNum(pNtk) == 0 ); |
| // set up solving parameters |
| Prove_ParamsSetDefault( pParams ); |
| pParams->nItersMax = 3; |
| pParams->nMiteringLimitLast = nConfLim; |
| // iterate through the PIs |
| vResult = Vec_IntAlloc( 100 ); |
| pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCiNum(pNtk) ); |
| Abc_NtkForEachCi( pNtk, pObj, i ) |
| { |
| Extra_ProgressBarUpdate( pProgress, i, NULL ); |
| // generate the sensitivity miter |
| pMiter = Abc_NtkSensitivityMiter( pNtk, i ); |
| // solve the miter using CEC engine |
| RetValue = Abc_NtkIvyProve( &pMiter, pParams ); |
| if ( RetValue == -1 ) // undecided |
| Vec_IntPush( vResult, i ); |
| else if ( RetValue == 0 ) |
| { |
| int * pSimInfo = Abc_NtkVerifySimulatePattern( pMiter, pMiter->pModel ); |
| if ( pSimInfo[0] != 1 ) |
| printf( "ERROR in Abc_NtkMiterProve(): Generated counter-example is invalid.\n" ); |
| // else |
| // printf( "Networks are NOT EQUIVALENT.\n" ); |
| ABC_FREE( pSimInfo ); |
| Vec_IntPush( vResult, i ); |
| } |
| Abc_NtkDelete( pMiter ); |
| } |
| Extra_ProgressBarStop( pProgress ); |
| if ( fVerbose ) |
| { |
| printf( "The outputs are sensitive to %d (out of %d) inputs:\n", |
| Vec_IntSize(vResult), Abc_NtkCiNum(pNtk) ); |
| Vec_IntForEachEntry( vResult, RetValue, i ) |
| printf( "%d ", RetValue ); |
| printf( "\n" ); |
| } |
| return vResult; |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// END OF FILE /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| ABC_NAMESPACE_IMPL_END |
| |