| /**CFile**************************************************************** |
| |
| FileName [abcScorr.c] |
| |
| SystemName [ABC: Logic synthesis and verification system.] |
| |
| PackageName [Network and node package.] |
| |
| Synopsis [Signal correspondence testing procedures.] |
| |
| Author [Alan Mishchenko] |
| |
| Affiliation [UC Berkeley] |
| |
| Date [Ver. 1.0. Started - June 20, 2005.] |
| |
| Revision [$Id: abcScorr.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] |
| |
| ***********************************************************************/ |
| |
| #include "base/abc/abc.h" |
| #include "base/io/ioAbc.h" |
| #include "aig/saig/saig.h" |
| #include "proof/ssw/ssw.h" |
| #include "aig/gia/gia.h" |
| #include "proof/cec/cec.h" |
| #include "aig/gia/giaAig.h" |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// DECLARATIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| typedef struct Tst_Dat_t_ Tst_Dat_t; |
| struct Tst_Dat_t_ |
| { |
| Abc_Ntk_t * pNetlist; |
| Aig_Man_t * pAig; |
| Gia_Man_t * pGia; |
| Vec_Int_t * vId2Name; |
| char * pFileNameOut; |
| int fFlopOnly; |
| int fFfNdOnly; |
| int fDumpBmc; |
| }; |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// FUNCTION DEFINITIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Vec_Int_t * Abc_NtkMapGiaIntoNameId( Abc_Ntk_t * pNetlist, Aig_Man_t * pAig, Gia_Man_t * pGia ) |
| { |
| Vec_Int_t * vId2Name; |
| Abc_Obj_t * pNet, * pNode, * pAnd; |
| Aig_Obj_t * pObjAig; |
| int i; |
| vId2Name = Vec_IntAlloc( 0 ); |
| Vec_IntFill( vId2Name, pGia ? Gia_ManObjNum(pGia) : Aig_ManObjNumMax(pAig), ~0 ); |
| // copy all names |
| Abc_NtkForEachNet( pNetlist, pNet, i ) |
| { |
| pNode = Abc_ObjFanin0(pNet)->pCopy; |
| if ( pNode && (pAnd = Abc_ObjRegular(pNode->pCopy)) && |
| (pObjAig = (Aig_Obj_t *)Abc_ObjRegular(pAnd->pCopy)) && |
| Aig_ObjType(pObjAig) != AIG_OBJ_NONE ) |
| { |
| if ( pGia == NULL ) |
| Vec_IntWriteEntry( vId2Name, Aig_ObjId(pObjAig), Abc_ObjId(pNet) ); |
| else |
| Vec_IntWriteEntry( vId2Name, Abc_Lit2Var(pObjAig->iData), Abc_ObjId(pNet) ); |
| } |
| } |
| // overwrite CO names |
| Abc_NtkForEachCo( pNetlist, pNode, i ) |
| { |
| pNet = Abc_ObjFanin0(pNode); |
| pNode = pNode->pCopy; |
| if ( pNode && (pAnd = Abc_ObjRegular(pNode->pCopy)) && |
| (pObjAig = (Aig_Obj_t *)Abc_ObjRegular(pAnd->pCopy)) && |
| Aig_ObjType(pObjAig) != AIG_OBJ_NONE ) |
| { |
| if ( pGia == NULL ) |
| Vec_IntWriteEntry( vId2Name, Aig_ObjId(pObjAig), Abc_ObjId(pNet) ); |
| else |
| Vec_IntWriteEntry( vId2Name, Abc_Lit2Var(pObjAig->iData), Abc_ObjId(pNet) ); |
| } |
| } |
| // overwrite CI names |
| Abc_NtkForEachCi( pNetlist, pNode, i ) |
| { |
| pNet = Abc_ObjFanout0(pNode); |
| pNode = pNode->pCopy; |
| if ( pNode && (pAnd = Abc_ObjRegular(pNode->pCopy)) && |
| (pObjAig = (Aig_Obj_t *)Abc_ObjRegular(pAnd->pCopy)) && |
| Aig_ObjType(pObjAig) != AIG_OBJ_NONE ) |
| { |
| if ( pGia == NULL ) |
| Vec_IntWriteEntry( vId2Name, Aig_ObjId(pObjAig), Abc_ObjId(pNet) ); |
| else |
| Vec_IntWriteEntry( vId2Name, Abc_Lit2Var(pObjAig->iData), Abc_ObjId(pNet) ); |
| } |
| } |
| return vId2Name; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| char * Abc_NtkTestScorrGetName( Abc_Ntk_t * pNetlist, Vec_Int_t * vId2Name, int Id ) |
| { |
| // Abc_Obj_t * pObj; |
| //printf( "trying to get name for %d\n", Id ); |
| if ( Vec_IntEntry(vId2Name, Id) == ~0 ) |
| return NULL; |
| // pObj = Abc_NtkObj( pNetlist, Vec_IntEntry(vId2Name, Id) ); |
| // pObj = Abc_ObjFanin0(pObj); |
| // assert( Abc_ObjIsCi(pObj) ); |
| return Nm_ManFindNameById( pNetlist->pManName, Vec_IntEntry(vId2Name, Id) ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Abc_NtkTestScorrWriteEquivPair( Abc_Ntk_t * pNetlist, Vec_Int_t * vId2Name, int Id1, int Id2, FILE * pFile, int fPol ) |
| { |
| char * pName1 = Abc_NtkTestScorrGetName( pNetlist, vId2Name, Id1 ); |
| char * pName2 = Abc_NtkTestScorrGetName( pNetlist, vId2Name, Id2 ); |
| if ( pName1 == NULL || pName2 == NULL ) |
| return 0; |
| fprintf( pFile, "%s=%s%s\n", pName1, fPol? "~": "", pName2 ); |
| return 1; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Abc_NtkTestScorrWriteEquivConst( Abc_Ntk_t * pNetlist, Vec_Int_t * vId2Name, int Id1, FILE * pFile, int fPol ) |
| { |
| char * pName1 = Abc_NtkTestScorrGetName( pNetlist, vId2Name, Id1 ); |
| if ( pName1 == NULL ) |
| return 0; |
| fprintf( pFile, "%s=%s%s\n", pName1, fPol? "~": "", "const0" ); |
| return 1; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| char * Abc_NtkBmcFileName( char * pName ) |
| { |
| static char Buffer[1000]; |
| char * pNameGeneric = Extra_FileNameGeneric( pName ); |
| sprintf( Buffer, "%s_bmc%s", pNameGeneric, pName + strlen(pNameGeneric) ); |
| ABC_FREE( pNameGeneric ); |
| return Buffer; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Abc_NtkTestScorrWriteEquivGia( Tst_Dat_t * pData ) |
| { |
| Abc_Ntk_t * pNetlist = pData->pNetlist; |
| Vec_Int_t * vId2Name = pData->vId2Name; |
| Gia_Man_t * pGia = pData->pGia; |
| char * pFileNameOut = pData->pFileNameOut; |
| FILE * pFile; |
| Gia_Obj_t * pObj, * pRepr; |
| int i, Counter = 0; |
| if ( pData->fDumpBmc ) |
| { |
| pData->fDumpBmc = 0; |
| pFileNameOut = Abc_NtkBmcFileName( pFileNameOut ); |
| } |
| pFile = fopen( pFileNameOut, "wb" ); |
| Gia_ManSetPhase( pGia ); |
| Gia_ManForEachObj( pGia, pObj, i ) |
| { |
| if ( !Gia_ObjHasRepr(pGia, i) ) |
| continue; |
| pRepr = Gia_ManObj( pGia,Gia_ObjRepr(pGia, i) ); |
| if ( pData->fFlopOnly ) |
| { |
| if ( !Gia_ObjIsRo(pGia, pObj) || !(Gia_ObjIsRo(pGia, pRepr)||Gia_ObjIsConst0(pRepr)) ) |
| continue; |
| } |
| else if ( pData->fFfNdOnly ) |
| { |
| if ( !Gia_ObjIsRo(pGia, pObj) && !(Gia_ObjIsRo(pGia, pRepr)||Gia_ObjIsConst0(pRepr)) ) |
| continue; |
| } |
| if ( Gia_ObjRepr(pGia, i) == 0 ) |
| Counter += Abc_NtkTestScorrWriteEquivConst( pNetlist, vId2Name, i, pFile, Gia_ObjPhase(pObj) ); |
| else |
| Counter += Abc_NtkTestScorrWriteEquivPair( pNetlist, vId2Name, Gia_ObjRepr(pGia, i), i, pFile, |
| Gia_ObjPhase(pRepr) ^ Gia_ObjPhase(pObj) ); |
| } |
| fclose( pFile ); |
| printf( "%d pairs of sequentially equivalent nodes are written into file \"%s\".\n", Counter, pFileNameOut ); |
| return Counter; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Abc_NtkTestScorrWriteEquivAig( Tst_Dat_t * pData ) |
| { |
| Abc_Ntk_t * pNetlist = pData->pNetlist; |
| Vec_Int_t * vId2Name = pData->vId2Name; |
| Aig_Man_t * pAig = pData->pAig; |
| char * pFileNameOut = pData->pFileNameOut; |
| FILE * pFile; |
| Aig_Obj_t * pObj, * pRepr; |
| int i, Counter = 0; |
| if ( pData->fDumpBmc ) |
| { |
| pData->fDumpBmc = 0; |
| pFileNameOut = Abc_NtkBmcFileName( pFileNameOut ); |
| } |
| pFile = fopen( pFileNameOut, "wb" ); |
| Aig_ManForEachObj( pAig, pObj, i ) |
| { |
| if ( (pRepr = Aig_ObjRepr(pAig, pObj)) == NULL ) |
| continue; |
| if ( pData->fFlopOnly ) |
| { |
| if ( !Saig_ObjIsLo(pAig, pObj) || !(Saig_ObjIsLo(pAig, pRepr)||pRepr==Aig_ManConst1(pAig)) ) |
| continue; |
| } |
| else if ( pData->fFfNdOnly ) |
| { |
| if ( !Saig_ObjIsLo(pAig, pObj) && !(Saig_ObjIsLo(pAig, pRepr)||pRepr==Aig_ManConst1(pAig)) ) |
| continue; |
| } |
| if ( pRepr == Aig_ManConst1(pAig) ) |
| Counter += Abc_NtkTestScorrWriteEquivConst( pNetlist, vId2Name, Aig_ObjId(pObj), pFile, Aig_ObjPhase(pObj) ); |
| else |
| Counter += Abc_NtkTestScorrWriteEquivPair( pNetlist, vId2Name, Aig_ObjId(pRepr), Aig_ObjId(pObj), pFile, |
| Aig_ObjPhase(pRepr) ^ Aig_ObjPhase(pObj) ); |
| } |
| fclose( pFile ); |
| printf( "%d pairs of sequentially equivalent nodes are written into file \"%s\".\n", Counter, pFileNameOut ); |
| return Counter; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Abc_Ntk_t * Abc_NtkTestScorr( char * pFileNameIn, char * pFileNameOut, int nStepsMax, int nBTLimit, int fNewAlgo, int fFlopOnly, int fFfNdOnly, int fVerbose ) |
| { |
| extern Aig_Man_t * Abc_NtkToDar( Abc_Ntk_t * pNtk, int fExors, int fRegisters ); |
| extern Abc_Ntk_t * Abc_NtkFromDarSeqSweep( Abc_Ntk_t * pNtkOld, Aig_Man_t * pMan ); |
| |
| FILE * pFile; |
| Tst_Dat_t Data, * pData = &Data; |
| Vec_Int_t * vId2Name; |
| Abc_Ntk_t * pNetlist, * pLogic, * pStrash, * pResult; |
| Aig_Man_t * pAig, * pTempAig; |
| Gia_Man_t * pGia, * pTempGia; |
| // int Counter = 0; |
| // check the files |
| pFile = fopen( pFileNameIn, "rb" ); |
| if ( pFile == NULL ) |
| { |
| printf( "Input file \"%s\" cannot be opened.\n", pFileNameIn ); |
| return NULL; |
| } |
| fclose( pFile ); |
| // check the files |
| pFile = fopen( pFileNameOut, "wb" ); |
| if ( pFile == NULL ) |
| { |
| printf( "Output file \"%s\" cannot be opened.\n", pFileNameOut ); |
| return NULL; |
| } |
| fclose( pFile ); |
| // derive AIG for signal correspondence |
| pNetlist = Io_ReadNetlist( pFileNameIn, Io_ReadFileType(pFileNameIn), 1 ); |
| if ( pNetlist == NULL ) |
| { |
| printf( "Reading input file \"%s\" has failed.\n", pFileNameIn ); |
| return NULL; |
| } |
| pLogic = Abc_NtkToLogic( pNetlist ); |
| if ( pLogic == NULL ) |
| { |
| Abc_NtkDelete( pNetlist ); |
| printf( "Deriving logic network from input file %s has failed.\n", pFileNameIn ); |
| return NULL; |
| } |
| if ( Extra_FileIsType( pFileNameIn, ".bench", ".BENCH", NULL ) ) |
| { |
| // get the init file name |
| char * pFileNameInit = Extra_FileNameGenericAppend( pLogic->pSpec, ".init" ); |
| pFile = fopen( pFileNameInit, "rb" ); |
| if ( pFile == NULL ) |
| { |
| printf( "Init file \"%s\" cannot be opened.\n", pFileNameInit ); |
| return NULL; |
| } |
| Io_ReadBenchInit( pLogic, pFileNameInit ); |
| Abc_NtkConvertDcLatches( pLogic ); |
| if ( fVerbose ) |
| printf( "Initial state was derived from file \"%s\".\n", pFileNameInit ); |
| } |
| pStrash = Abc_NtkStrash( pLogic, 0, 1, 0 ); |
| if ( pStrash == NULL ) |
| { |
| Abc_NtkDelete( pLogic ); |
| Abc_NtkDelete( pNetlist ); |
| printf( "Deriving strashed network from input file %s has failed.\n", pFileNameIn ); |
| return NULL; |
| } |
| pAig = Abc_NtkToDar( pStrash, 0, 1 ); // performs "zero" internally |
| // the newer computation (&scorr) |
| if ( fNewAlgo ) |
| { |
| Cec_ParCor_t CorPars, * pCorPars = &CorPars; |
| Cec_ManCorSetDefaultParams( pCorPars ); |
| pCorPars->nBTLimit = nBTLimit; |
| pCorPars->nStepsMax = nStepsMax; |
| pCorPars->fVerbose = fVerbose; |
| pCorPars->fUseCSat = 1; |
| pGia = Gia_ManFromAig( pAig ); |
| // prepare the data-structure |
| memset( pData, 0, sizeof(Tst_Dat_t) ); |
| pData->pNetlist = pNetlist; |
| pData->pAig = NULL; |
| pData->pGia = pGia; |
| pData->vId2Name = vId2Name = Abc_NtkMapGiaIntoNameId( pNetlist, pAig, pGia ); |
| pData->pFileNameOut = pFileNameOut; |
| pData->fFlopOnly = fFlopOnly; |
| pData->fFfNdOnly = fFfNdOnly; |
| pData->fDumpBmc = 1; |
| pCorPars->pData = pData; |
| pCorPars->pFunc = (void *)Abc_NtkTestScorrWriteEquivGia; |
| // call signal correspondence |
| pTempGia = Cec_ManLSCorrespondence( pGia, pCorPars ); |
| pTempAig = Gia_ManToAigSimple( pTempGia ); |
| Gia_ManStop( pTempGia ); |
| Gia_ManStop( pGia ); |
| } |
| // the older computation (scorr) |
| else |
| { |
| Ssw_Pars_t SswPars, * pSswPars = &SswPars; |
| Ssw_ManSetDefaultParams( pSswPars ); |
| pSswPars->nBTLimit = nBTLimit; |
| pSswPars->nStepsMax = nStepsMax; |
| pSswPars->fVerbose = fVerbose; |
| // preSswPare the data-structure |
| memset( pData, 0, sizeof(Tst_Dat_t) ); |
| pData->pNetlist = pNetlist; |
| pData->pAig = pAig; |
| pData->pGia = NULL; |
| pData->vId2Name = vId2Name = Abc_NtkMapGiaIntoNameId( pNetlist, pAig, NULL ); |
| pData->pFileNameOut = pFileNameOut; |
| pData->fFlopOnly = fFlopOnly; |
| pData->fFfNdOnly = fFfNdOnly; |
| pData->fDumpBmc = 1; |
| pSswPars->pData = pData; |
| pSswPars->pFunc = (void *)Abc_NtkTestScorrWriteEquivAig; |
| // call signal correspondence |
| pTempAig = Ssw_SignalCorrespondence( pAig, pSswPars ); |
| } |
| // create the resulting AIG |
| pResult = Abc_NtkFromDarSeqSweep( pStrash, pTempAig ); |
| // cleanup |
| Vec_IntFree( vId2Name ); |
| Aig_ManStop( pAig ); |
| Aig_ManStop( pTempAig ); |
| Abc_NtkDelete( pStrash ); |
| Abc_NtkDelete( pLogic ); |
| Abc_NtkDelete( pNetlist ); |
| return pResult; |
| } |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// END OF FILE /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| ABC_NAMESPACE_IMPL_END |
| |