/**CFile**************************************************************** FileName [utilBridge.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [] Synopsis [] Author [Alan Mishchenko] Affiliation [UC Berkeley] Date [Ver. 1.0. Started - June 20, 2005.] Revision [$Id: utilBridge.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] ***********************************************************************/ #include #include #include #include #if defined(LIN) || defined(LIN64) #include #endif #include "aig/gia/gia.h" ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// #define BRIDGE_TEXT_MESSAGE 999996 #define BRIDGE_ABORT 5 #define BRIDGE_PROGRESS 3 #define BRIDGE_RESULTS 101 #define BRIDGE_BAD_ABS 105 //#define BRIDGE_NETLIST 106 //#define BRIDGE_ABS_NETLIST 107 #define BRIDGE_VALUE_X 0 #define BRIDGE_VALUE_0 2 #define BRIDGE_VALUE_1 3 //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Vec_Str_t * Gia_ManToBridgeVec( Gia_Man_t * p ) { Vec_Str_t * vStr; Gia_Obj_t * pObj; int i, uLit0, uLit1, nNodes; assert( Gia_ManPoNum(p) > 0 ); // start with const1 node (number 1) nNodes = 1; // assign literals(!!!) to the value field Gia_ManConst0(p)->Value = Abc_Var2Lit( nNodes++, 1 ); Gia_ManForEachCi( p, pObj, i ) pObj->Value = Abc_Var2Lit( nNodes++, 0 ); Gia_ManForEachAnd( p, pObj, i ) pObj->Value = Abc_Var2Lit( nNodes++, 0 ); // write header vStr = Vec_StrAlloc( 1000 ); Gia_AigerWriteUnsigned( vStr, Gia_ManPiNum(p) ); Gia_AigerWriteUnsigned( vStr, Gia_ManRegNum(p) ); Gia_AigerWriteUnsigned( vStr, Gia_ManAndNum(p) ); // write the nodes Gia_ManForEachAnd( p, pObj, i ) { uLit0 = Gia_ObjFanin0Copy( pObj ); uLit1 = Gia_ObjFanin1Copy( pObj ); assert( uLit0 != uLit1 ); Gia_AigerWriteUnsigned( vStr, uLit0 << 1 ); Gia_AigerWriteUnsigned( vStr, uLit1 ); } // write latch drivers Gia_ManForEachRi( p, pObj, i ) { uLit0 = Gia_ObjFanin0Copy( pObj ); Gia_AigerWriteUnsigned( vStr, (uLit0 << 2) | BRIDGE_VALUE_0 ); } // write PO drivers Gia_AigerWriteUnsigned( vStr, Gia_ManPoNum(p) ); Gia_ManForEachPo( p, pObj, i ) { uLit0 = Gia_ObjFanin0Copy( pObj ); // complement property output!!! Gia_AigerWriteUnsigned( vStr, Abc_LitNot(uLit0) ); } return vStr; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Gia_CreateHeader( FILE * pFile, int Type, int Size, unsigned char * pBuffer ) { fprintf( pFile, "%.6d", Type ); fprintf( pFile, " " ); fprintf( pFile, "%.16d", Size ); fprintf( pFile, " " ); #if !defined(LIN) && !defined(LIN64) { int RetValue; RetValue = fwrite( pBuffer, Size, 1, pFile ); assert( RetValue == 1 || Size == 0); fflush( pFile ); } #else fflush(pFile); int fd = fileno(pFile); ssize_t bytes_written = 0; while (bytes_written < Size){ ssize_t n = write(fd, &pBuffer[bytes_written], Size - bytes_written); if (n < 0){ fprintf(stderr, "BridgeMode: failed to send package; aborting\n"); fflush(stderr); _exit(255); } bytes_written += n; } #endif } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Gia_ManToBridgeText( FILE * pFile, int Size, unsigned char * pBuffer ) { Gia_CreateHeader( pFile, BRIDGE_TEXT_MESSAGE, Size, pBuffer ); return 1; } int Gia_ManToBridgeAbort( FILE * pFile, int Size, unsigned char * pBuffer ) { Gia_CreateHeader( pFile, BRIDGE_ABORT, Size, pBuffer ); return 1; } int Gia_ManToBridgeProgress( FILE * pFile, int Size, unsigned char * pBuffer ) { Gia_CreateHeader( pFile, BRIDGE_PROGRESS, Size, pBuffer ); return 1; } int Gia_ManToBridgeAbsNetlist( FILE * pFile, void * p, int pkg_type ) { Vec_Str_t * vBuffer; vBuffer = Gia_ManToBridgeVec( (Gia_Man_t *)p ); Gia_CreateHeader( pFile, pkg_type, Vec_StrSize(vBuffer), (unsigned char *)Vec_StrArray(vBuffer) ); Vec_StrFree( vBuffer ); return 1; } int Gia_ManToBridgeBadAbs( FILE * pFile ) { Gia_CreateHeader( pFile, BRIDGE_BAD_ABS, 0, NULL ); return 1; } static int aigerNumSize( unsigned x ) { int sz = 1; while (x & ~0x7f) { sz++; x >>= 7; } return sz; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Gia_ManFromBridgeHolds( FILE * pFile, int iPoProved ) { fprintf( pFile, "%.6d", 101 /*message type = Result*/); fprintf( pFile, " " ); fprintf( pFile, "%.16d", 3 + aigerNumSize(iPoProved) /*size in bytes*/); fprintf( pFile, " " ); fputc( (char)BRIDGE_VALUE_1, pFile ); // true fputc( (char)1, pFile ); // size of vector (Armin's encoding) Gia_AigerWriteUnsignedFile( pFile, iPoProved ); // number of the property (Armin's encoding) fputc( (char)0, pFile ); // no invariant fflush(pFile); } void Gia_ManFromBridgeUnknown( FILE * pFile, int iPoUnknown ) { fprintf( pFile, "%.6d", 101 /*message type = Result*/); fprintf( pFile, " " ); fprintf( pFile, "%.16d", 2 + aigerNumSize(iPoUnknown) /*size in bytes*/); fprintf( pFile, " " ); fputc( (char)BRIDGE_VALUE_X, pFile ); // undef fputc( (char)1, pFile ); // size of vector (Armin's encoding) Gia_AigerWriteUnsignedFile( pFile, iPoUnknown ); // number of the property (Armin's encoding) fflush(pFile); } void Gia_ManFromBridgeCex( FILE * pFile, Abc_Cex_t * pCex ) { int i, f, iBit;//, RetValue; Vec_Str_t * vStr = Vec_StrAlloc( 1000 ); Vec_StrPush( vStr, (char)BRIDGE_VALUE_0 ); // false Vec_StrPush( vStr, (char)1 ); // size of vector (Armin's encoding) Gia_AigerWriteUnsigned( vStr, pCex->iPo ); // number of the property (Armin's encoding) Vec_StrPush( vStr, (char)1 ); // size of vector (Armin's encoding) Gia_AigerWriteUnsigned( vStr, pCex->iFrame ); // depth Gia_AigerWriteUnsigned( vStr, 1 ); // concrete Gia_AigerWriteUnsigned( vStr, pCex->iFrame + 1 ); // number of frames (1 more than depth) iBit = pCex->nRegs; for ( f = 0; f <= pCex->iFrame; f++ ) { Gia_AigerWriteUnsigned( vStr, pCex->nPis ); // num of inputs for ( i = 0; i < pCex->nPis; i++, iBit++ ) Vec_StrPush( vStr, (char)(Abc_InfoHasBit(pCex->pData, iBit) ? BRIDGE_VALUE_1:BRIDGE_VALUE_0) ); // value } assert( iBit == pCex->nBits ); Vec_StrPush( vStr, (char)1 ); // the number of frames (for a concrete counter-example) Gia_AigerWriteUnsigned( vStr, pCex->nRegs ); // num of flops for ( i = 0; i < pCex->nRegs; i++ ) Vec_StrPush( vStr, (char)BRIDGE_VALUE_0 ); // always zero!!! // RetValue = fwrite( Vec_StrArray(vStr), Vec_StrSize(vStr), 1, pFile ); Gia_CreateHeader(pFile, 101/*type=Result*/, Vec_StrSize(vStr), (unsigned char*)Vec_StrArray(vStr)); Vec_StrFree( vStr ); fflush(pFile); } int Gia_ManToBridgeResult( FILE * pFile, int Result, Abc_Cex_t * pCex, int iPoProved ) { if ( Result == 0 ) // sat Gia_ManFromBridgeCex( pFile, pCex ); else if ( Result == 1 ) // unsat Gia_ManFromBridgeHolds( pFile, iPoProved ); else if ( Result == -1 ) // undef Gia_ManFromBridgeUnknown( pFile, iPoProved ); else assert( 0 ); return 1; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Gia_Man_t * Gia_ManFromBridgeReadBody( int Size, unsigned char * pBuffer, Vec_Int_t ** pvInits ) { int fHash = 0; Vec_Int_t * vLits, * vInits; Gia_Man_t * p = NULL; unsigned char * pBufferPivot, * pBufferEnd = pBuffer + Size; int i, nInputs, nFlops, nGates, nProps; unsigned iFan0, iFan1; nInputs = Gia_AigerReadUnsigned( &pBuffer ); nFlops = Gia_AigerReadUnsigned( &pBuffer ); nGates = Gia_AigerReadUnsigned( &pBuffer ); vLits = Vec_IntAlloc( 1000 ); Vec_IntPush( vLits, -999 ); Vec_IntPush( vLits, 1 ); // start the AIG package p = Gia_ManStart( nInputs + nFlops * 2 + nGates + 1 + 1 ); // PI+FO+FI+AND+PO+1 p->pName = Abc_UtilStrsav( "temp" ); // create PIs for ( i = 0; i < nInputs; i++ ) Vec_IntPush( vLits, Gia_ManAppendCi( p ) ); // create flop outputs for ( i = 0; i < nFlops; i++ ) Vec_IntPush( vLits, Gia_ManAppendCi( p ) ); // create nodes if ( fHash ) Gia_ManHashAlloc( p ); for ( i = 0; i < nGates; i++ ) { iFan0 = Gia_AigerReadUnsigned( &pBuffer ); iFan1 = Gia_AigerReadUnsigned( &pBuffer ); assert( !(iFan0 & 1) ); iFan0 >>= 1; iFan0 = Abc_LitNotCond( Vec_IntEntry(vLits, iFan0 >> 1), iFan0 & 1 ); iFan1 = Abc_LitNotCond( Vec_IntEntry(vLits, iFan1 >> 1), iFan1 & 1 ); if ( fHash ) Vec_IntPush( vLits, Gia_ManHashAnd(p, iFan0, iFan1) ); else Vec_IntPush( vLits, Gia_ManAppendAnd(p, iFan0, iFan1) ); } if ( fHash ) Gia_ManHashStop( p ); // remember where flops begin pBufferPivot = pBuffer; // scroll through flops for ( i = 0; i < nFlops; i++ ) Gia_AigerReadUnsigned( &pBuffer ); // create POs nProps = Gia_AigerReadUnsigned( &pBuffer ); // assert( nProps == 1 ); for ( i = 0; i < nProps; i++ ) { iFan0 = Gia_AigerReadUnsigned( &pBuffer ); iFan0 = Abc_LitNotCond( Vec_IntEntry(vLits, iFan0 >> 1), iFan0 & 1 ); // complement property output!!! Gia_ManAppendCo( p, Abc_LitNot(iFan0) ); } // make sure the end of buffer is reached assert( pBufferEnd == pBuffer ); // resetting to flops pBuffer = pBufferPivot; vInits = Vec_IntAlloc( nFlops ); for ( i = 0; i < nFlops; i++ ) { iFan0 = Gia_AigerReadUnsigned( &pBuffer ); assert( (iFan0 & 3) == BRIDGE_VALUE_0 ); Vec_IntPush( vInits, iFan0 & 3 ); // 0 = X value; 1 = not used; 2 = false; 3 = true iFan0 >>= 2; iFan0 = Abc_LitNotCond( Vec_IntEntry(vLits, iFan0 >> 1), iFan0 & 1 ); Gia_ManAppendCo( p, iFan0 ); } Gia_ManSetRegNum( p, nFlops ); Vec_IntFree( vLits ); // remove wholes in the node list if ( fHash ) { Gia_Man_t * pTemp; p = Gia_ManCleanup( pTemp = p ); Gia_ManStop( pTemp ); } // return if ( pvInits ) *pvInits = vInits; else Vec_IntFree( vInits ); return p; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Gia_ManFromBridgeReadPackage( FILE * pFile, int * pType, int * pSize, unsigned char ** ppBuffer ) { char Temp[24]; int RetValue; RetValue = fread( Temp, 24, 1, pFile ); if ( RetValue != 1 ) { printf( "Gia_ManFromBridgeReadPackage(); Error 1: Something is wrong!\n" ); return 0; } Temp[6] = 0; Temp[23]= 0; *pType = atoi( Temp ); *pSize = atoi( Temp + 7 ); *ppBuffer = ABC_ALLOC( unsigned char, *pSize ); RetValue = fread( *ppBuffer, *pSize, 1, pFile ); if ( RetValue != 1 && *pSize != 0 ) { ABC_FREE( *ppBuffer ); printf( "Gia_ManFromBridgeReadPackage(); Error 2: Something is wrong!\n" ); return 0; } return 1; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Gia_Man_t * Gia_ManFromBridge( FILE * pFile, Vec_Int_t ** pvInit ) { unsigned char * pBuffer; int Type, Size, RetValue; Gia_Man_t * p = NULL; RetValue = Gia_ManFromBridgeReadPackage( pFile, &Type, &Size, &pBuffer ); ABC_FREE( pBuffer ); if ( !RetValue ) return NULL; RetValue = Gia_ManFromBridgeReadPackage( pFile, &Type, &Size, &pBuffer ); if ( !RetValue ) return NULL; p = Gia_ManFromBridgeReadBody( Size, pBuffer, pvInit ); ABC_FREE( pBuffer ); if ( p == NULL ) return NULL; RetValue = Gia_ManFromBridgeReadPackage( pFile, &Type, &Size, &pBuffer ); ABC_FREE( pBuffer ); if ( !RetValue ) return NULL; return p; } /* { extern void Gia_ManFromBridgeTest( char * pFileName ); Gia_ManFromBridgeTest( "C:\\_projects\\abc\\_TEST\\bug\\65\\par.dump" ); } */ /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Gia_ManToBridgeAbsNetlistTest( char * pFileName, Gia_Man_t * p, int msg_type ) { FILE * pFile = fopen( pFileName, "wb" ); if ( pFile == NULL ) { printf( "Cannot open output file \"%s\".\n", pFileName ); return; } Gia_ManToBridgeAbsNetlist( pFile, p, msg_type ); fclose ( pFile ); } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Gia_ManFromBridgeTest( char * pFileName ) { Gia_Man_t * p; FILE * pFile = fopen( pFileName, "rb" ); if ( pFile == NULL ) { printf( "Cannot open input file \"%s\".\n", pFileName ); return; } p = Gia_ManFromBridge( pFile, NULL ); fclose ( pFile ); Gia_ManPrintStats( p, NULL ); Gia_AigerWrite( p, "temp.aig", 0, 0 ); Gia_ManToBridgeAbsNetlistTest( "par_.dump", p, BRIDGE_ABS_NETLIST ); Gia_ManStop( p ); } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END