/**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