/**CFile**************************************************************** FileName [fpgaLib.c] PackageName [MVSIS 1.3: Multi-valued logic synthesis system.] Synopsis [Technology mapping for variable-size-LUT FPGAs.] Author [MVSIS Group] Affiliation [UC Berkeley] Date [Ver. 2.0. Started - August 18, 2004.] Revision [$Id: fpgaLib.c,v 1.4 2005/01/23 06:59:41 alanmi Exp $] ***********************************************************************/ #include "fpgaInt.h" ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [APIs to access LUT library.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Fpga_LutLibReadVarMax( Fpga_LutLib_t * p ) { return p->LutMax; } float * Fpga_LutLibReadLutAreas( Fpga_LutLib_t * p ) { return p->pLutAreas; } float Fpga_LutLibReadLutArea( Fpga_LutLib_t * p, int Size ) { assert( Size <= p->LutMax ); return p->pLutAreas[Size]; } /**Function************************************************************* Synopsis [Reads the description of LUTs from the LUT library file.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Fpga_LutLib_t * Fpga_LutLibRead( char * FileName, int fVerbose ) { char pBuffer[1000], * pToken; Fpga_LutLib_t * p; FILE * pFile; int i, k; pFile = fopen( FileName, "r" ); if ( pFile == NULL ) { printf( "Cannot open LUT library file \"%s\".\n", FileName ); return NULL; } p = ABC_ALLOC( Fpga_LutLib_t, 1 ); memset( p, 0, sizeof(Fpga_LutLib_t) ); p->pName = Extra_UtilStrsav( FileName ); i = 1; while ( fgets( pBuffer, 1000, pFile ) != NULL ) { pToken = strtok( pBuffer, " \t\n" ); if ( pToken == NULL ) continue; if ( pToken[0] == '#' ) continue; if ( i != atoi(pToken) ) { printf( "Error in the LUT library file \"%s\".\n", FileName ); ABC_FREE( p ); return NULL; } // read area pToken = strtok( NULL, " \t\n" ); p->pLutAreas[i] = (float)atof(pToken); // read delays k = 0; while ( (pToken = strtok( NULL, " \t\n" )) ) p->pLutDelays[i][k++] = (float)atof(pToken); // check for out-of-bound if ( k > i ) { printf( "LUT %d has too many pins (%d). Max allowed is %d.\n", i, k, i ); return NULL; } // check if var delays are specifies if ( k > 1 ) p->fVarPinDelays = 1; if ( i == FPGA_MAX_LUTSIZE ) { printf( "Skipping LUTs of size more than %d.\n", i ); return NULL; } i++; } p->LutMax = i-1; /* if ( p->LutMax > FPGA_MAX_LEAVES ) { p->LutMax = FPGA_MAX_LEAVES; printf( "Warning: LUTs with more than %d inputs will not be used.\n", FPGA_MAX_LEAVES ); } */ // check the library if ( p->fVarPinDelays ) { for ( i = 1; i <= p->LutMax; i++ ) for ( k = 0; k < i; k++ ) { if ( p->pLutDelays[i][k] <= 0.0 ) printf( "Warning: Pin %d of LUT %d has delay %f. Pin delays should be non-negative numbers. Technology mapping may not work correctly.\n", k, i, p->pLutDelays[i][k] ); if ( k && p->pLutDelays[i][k-1] > p->pLutDelays[i][k] ) printf( "Warning: Pin %d of LUT %d has delay %f. Pin %d of LUT %d has delay %f. Pin delays should be in non-decreasing order. Technology mapping may not work correctly.\n", k-1, i, p->pLutDelays[i][k-1], k, i, p->pLutDelays[i][k] ); } } else { for ( i = 1; i <= p->LutMax; i++ ) { if ( p->pLutDelays[i][0] <= 0.0 ) printf( "Warning: LUT %d has delay %f. Pin delays should be non-negative numbers. Technology mapping may not work correctly.\n", i, p->pLutDelays[i][0] ); } } return p; } /**Function************************************************************* Synopsis [Duplicates the LUT library.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Fpga_LutLib_t * Fpga_LutLibDup( Fpga_LutLib_t * p ) { Fpga_LutLib_t * pNew; pNew = ABC_ALLOC( Fpga_LutLib_t, 1 ); *pNew = *p; pNew->pName = Extra_UtilStrsav( pNew->pName ); return pNew; } /**Function************************************************************* Synopsis [Frees the LUT library.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Fpga_LutLibFree( Fpga_LutLib_t * pLutLib ) { if ( pLutLib == NULL ) return; ABC_FREE( pLutLib->pName ); ABC_FREE( pLutLib ); } /**Function************************************************************* Synopsis [Prints the LUT library.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Fpga_LutLibPrint( Fpga_LutLib_t * pLutLib ) { int i, k; printf( "# The area/delay of k-variable LUTs:\n" ); printf( "# k area delay\n" ); if ( pLutLib->fVarPinDelays ) { for ( i = 1; i <= pLutLib->LutMax; i++ ) { printf( "%d %7.2f ", i, pLutLib->pLutAreas[i] ); for ( k = 0; k < i; k++ ) printf( " %7.2f", pLutLib->pLutDelays[i][k] ); printf( "\n" ); } } else for ( i = 1; i <= pLutLib->LutMax; i++ ) printf( "%d %7.2f %7.2f\n", i, pLutLib->pLutAreas[i], pLutLib->pLutDelays[i][0] ); } /**Function************************************************************* Synopsis [Returns 1 if the delays are discrete.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Fpga_LutLibDelaysAreDiscrete( Fpga_LutLib_t * pLutLib ) { float Delay; int i; for ( i = 1; i <= pLutLib->LutMax; i++ ) { Delay = pLutLib->pLutDelays[i][0]; if ( ((float)((int)Delay)) != Delay ) return 0; } return 1; } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END