/**CFile**************************************************************** FileName [luckyRead.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [Semi-canonical form computation package.] Synopsis [Reading truth tables from file.] Author [Jake] Date [Started - August 2012] ***********************************************************************/ #include "luckyInt.h" ABC_NAMESPACE_IMPL_START // read/write/flip i-th bit of a bit string table: static inline int Abc_TruthGetBit( word * p, int i ) { return (int)(p[i>>6] >> (i & 63)) & 1; } static inline void Abc_TruthSetBit( word * p, int i ) { p[i>>6] |= (((word)1)<<(i & 63)); } static inline void Abc_TruthXorBit( word * p, int i ) { p[i>>6] ^= (((word)1)<<(i & 63)); } // read/write k-th digit d of a hexadecimal number: static inline int Abc_TruthGetHex( word * p, int k ) { return (int)(p[k>>4] >> ((k<<2) & 63)) & 15; } static inline void Abc_TruthSetHex( word * p, int k, int d ) { p[k>>4] |= (((word)d)<<((k<<2) & 63)); } static inline void Abc_TruthXorHex( word * p, int k, int d ) { p[k>>4] ^= (((word)d)<<((k<<2) & 63)); } // read one hex character static inline int Abc_TruthReadHexDigit( char HexChar ) { if ( HexChar >= '0' && HexChar <= '9' ) return HexChar - '0'; if ( HexChar >= 'A' && HexChar <= 'F' ) return HexChar - 'A' + 10; if ( HexChar >= 'a' && HexChar <= 'f' ) return HexChar - 'a' + 10; assert( 0 ); // not a hexadecimal symbol return -1; // return value which makes no sense } // write one hex character static inline void Abc_TruthWriteHexDigit( FILE * pFile, int HexDigit ) { assert( HexDigit >= 0 && HexDigit < 16 ); if ( HexDigit < 10 ) fprintf( pFile, "%d", HexDigit ); else fprintf( pFile, "%c", 'A' + HexDigit-10 ); } // read one truth table in hexadecimal static inline void Abc_TruthReadHex( word * pTruth, char * pString, int nVars ) { int nWords = (nVars < 7)? 1 : (1 << (nVars-6)); int k, Digit, nDigits = (nWords << 4); char EndSymbol; // skip the first 2 symbols if they are "0x" if ( pString[0] == '0' && pString[1] == 'x' ) pString += 2; // get the last symbol EndSymbol = pString[nDigits]; // the end symbol of the TT (the one immediately following hex digits) // should be one of the following: space, a new-line, or a zero-terminator // (note that on Windows symbols '\r' can be inserted before each '\n') assert( EndSymbol == ' ' || EndSymbol == '\n' || EndSymbol == '\r' || EndSymbol == '\0' ); // read hexadecimal digits in the reverse order // (the last symbol in the string is the least significant digit) for ( k = 0; k < nDigits; k++ ) { Digit = Abc_TruthReadHexDigit( pString[nDigits - 1 - k] ); assert( Digit >= 0 && Digit < 16 ); Abc_TruthSetHex( pTruth, k, Digit ); } } // write one truth table in hexadecimal (do not add end-of-line!) static inline void Abc_TruthWriteHex( FILE * pFile, word * pTruth, int nVars ) { int nDigits, Digit, k; // write hexadecimal digits in the reverse order // (the last symbol in the string is the least significant digit) nDigits = (1 << (nVars-2)); for ( k = 0; k < nDigits; k++ ) { Digit = Abc_TruthGetHex( pTruth, nDigits - 1 - k ); assert( Digit >= 0 && Digit < 16 ); Abc_TruthWriteHexDigit( pFile, Digit ); } } // allocate and clear memory to store 'nTruths' truth tables of 'nVars' variables static inline Abc_TtStore_t * Abc_TruthStoreAlloc( int nVars, int nFuncs ) { Abc_TtStore_t * p; int i; p = (Abc_TtStore_t *)malloc( sizeof(Abc_TtStore_t) ); p->nVars = nVars; p->nWords = (nVars < 7) ? 1 : (1 << (nVars-6)); p->nFuncs = nFuncs; // alloc array of 'nFuncs' pointers to truth tables p->pFuncs = (word **)malloc( sizeof(word *) * p->nFuncs ); // alloc storage for 'nFuncs' truth tables as one chunk of memory p->pFuncs[0] = (word *)calloc( sizeof(word), p->nFuncs * p->nWords ); // split it up into individual truth tables for ( i = 1; i < p->nFuncs; i++ ) p->pFuncs[i] = p->pFuncs[i-1] + p->nWords; return p; } // free memory previously allocated for storing truth tables void Abc_TruthStoreFree( Abc_TtStore_t * p ) { free( p->pFuncs[0] ); free( p->pFuncs ); free( p ); } // read file contents static char * Abc_FileRead( char * pFileName ) { FILE * pFile; char * pBuffer; int nFileSize; int RetValue; pFile = fopen( pFileName, "r" ); if ( pFile == NULL ) { printf( "Cannot open file \"%s\" for reading.\n", pFileName ); return NULL; } // get the file size, in bytes fseek( pFile, 0, SEEK_END ); nFileSize = ftell( pFile ); // move the file current reading position to the beginning rewind( pFile ); // load the contents of the file into memory pBuffer = (char *)malloc( nFileSize + 3 ); RetValue = fread( pBuffer, nFileSize, 1, pFile ); // add several empty lines at the end // (these will be used to signal the end of parsing) pBuffer[ nFileSize + 0] = '\n'; pBuffer[ nFileSize + 1] = '\n'; // terminate the string with '\0' pBuffer[ nFileSize + 2] = '\0'; fclose( pFile ); return pBuffer; } // determine the number of variables by reading the first line // determine the number of functions by counting the lines static void Abc_TruthGetParams( char * pFileName, int * pnVars, int * pnTruths ) { char * pContents; int i, nVars, nLines; // prepare the output if ( pnVars ) *pnVars = 0; if ( pnTruths ) *pnTruths = 0; // read data from file pContents = Abc_FileRead( pFileName ); if ( pContents == NULL ) return; // count the number of symbols before the first space or new-line // (note that on Windows symbols '\r' can be inserted before each '\n') for ( i = 0; pContents[i]; i++ ) if ( pContents[i] == ' ' || pContents[i] == '\n' || pContents[i] == '\r' ) break; if ( pContents[i] == 0 ) printf( "Strange, the input file does not have spaces and new-lines...\n" ); // account for the fact that truth tables may have "0x" at the beginning of each line if ( pContents[0] == '0' && pContents[1] == 'x' ) i = i - 2; // determine the number of variables for ( nVars = 0; nVars < 32; nVars++ ) if ( 4 * i == (1 << nVars) ) // the number of bits equal to the size of truth table break; if ( nVars < 2 || nVars > 16 ) { printf( "Does not look like the input file contains truth tables...\n" ); return; } if ( pnVars ) *pnVars = nVars; // determine the number of functions by counting the lines nLines = 0; for ( i = 0; pContents[i]; i++ ) nLines += (pContents[i] == '\n'); if ( pnTruths ) *pnTruths = nLines; } static Abc_TtStore_t * Abc_Create_TtSpore (char * pFileInput) { int nVars, nTruths; Abc_TtStore_t * p; Abc_TruthGetParams( pFileInput, &nVars, &nTruths ); p = Abc_TruthStoreAlloc( nVars, nTruths ); return p; } // read truth tables from file static void Abc_TruthStoreRead( char * pFileName, Abc_TtStore_t* p ) { char * pContents; int i, nLines; pContents = Abc_FileRead( pFileName ); if ( pContents == NULL ) return; // here it is assumed (without checking!) that each line of the file // begins with a string of hexadecimal chars followed by space // the file will be read till the first empty line (pContents[i] == '\n') // (note that Abc_FileRead() added several empty lines at the end of the file contents) for ( nLines = i = 0; pContents[i] != '\n'; ) { // read one line Abc_TruthReadHex( p->pFuncs[nLines++], &pContents[i], p->nVars ); // skip till after the end-of-line symbol // (note that end-of-line symbol is also skipped) while ( pContents[i++] != '\n' ); } // adjust the number of functions read // (we may have allocated more storage because some lines in the file were empty) assert( p->nFuncs >= nLines ); p->nFuncs = nLines; } // write truth tables into file // (here we write one symbol at a time - it can be optimized by writing // each truth table into a string and then writing the string into a file) static void Abc_TruthStoreWrite( char * pFileName, Abc_TtStore_t * p ) { FILE * pFile; int i; pFile = fopen( pFileName, "wb" ); if ( pFile == NULL ) { printf( "Cannot open file \"%s\" for writing.\n", pFileName ); return; } for ( i = 0; i < p->nFuncs; i++ ) { Abc_TruthWriteHex( pFile, p->pFuncs[i], p->nVars ); fprintf( pFile, "\n" ); } fclose( pFile ); } static void WriteToFile(char * pFileName, Abc_TtStore_t * p, word* a) { FILE * pFile; int i; pFile = fopen( pFileName, "w" ); if ( pFile == NULL ) { printf( "Cannot open file \"%s\" for writing.\n", pFileName ); return; } for ( i = 0; i < p->nFuncs; i++ ) { Abc_TruthWriteHex( pFile, &a[i], p->nVars ); fprintf( pFile, "\n" ); } fclose( pFile ); } static void WriteToFile1(char * pFileName, Abc_TtStore_t * p, word** a) { FILE * pFile; int i,j; pFile = fopen( pFileName, "w" ); if ( pFile == NULL ) { printf( "Cannot open file \"%s\" for writing.\n", pFileName ); return; } for ( i = 0; i < p->nFuncs; i++ ) { fprintf( pFile, "0" ); fprintf( pFile, "x" ); for ( j=p->nWords-1; j >= 0; j-- ) Abc_TruthWriteHex( pFile, &a[i][j], p->nVars ); fprintf( pFile, "\n" ); } fprintf( pFile, "\n" ); fclose( pFile ); } static void WriteToFile2(char * pFileName, Abc_TtStore_t * p, word* a) { FILE * pFile; int i,j; pFile = fopen( pFileName, "w" ); if ( pFile == NULL ) { printf( "Cannot open file \"%s\" for writing.\n", pFileName ); return; } for ( i = 0; i < p->nFuncs; i++ ) { fprintf( pFile, "0" ); fprintf( pFile, "x" ); for ( j=p->nWords-1; j >= 0; j-- ) Abc_TruthWriteHex( pFile, a+i, p->nVars ); fprintf( pFile, "\n" ); } fprintf( pFile, "\n" ); fclose( pFile ); } Abc_TtStore_t * setTtStore(char * pFileInput) { int nVars, nTruths; Abc_TtStore_t * p; // figure out how many truth table and how many variables Abc_TruthGetParams( pFileInput, &nVars, &nTruths ); // allocate data-structure p = Abc_TruthStoreAlloc( nVars, nTruths ); Abc_TruthStoreRead( pFileInput, p ); return p; } ABC_NAMESPACE_IMPL_END