| /**CFile**************************************************************** |
| |
| FileName [mapperSuper.c] |
| |
| PackageName [MVSIS 1.3: Multi-valued logic synthesis system.] |
| |
| Synopsis [Generic technology mapping engine.] |
| |
| Author [MVSIS Group] |
| |
| Affiliation [UC Berkeley] |
| |
| Date [Ver. 2.0. Started - June 1, 2004.] |
| |
| Revision [$Id: mapperSuper.c,v 1.6 2005/01/23 06:59:44 alanmi Exp $] |
| |
| ***********************************************************************/ |
| |
| #include "mapperInt.h" |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// DECLARATIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| static int Map_LibraryReadFile( Map_SuperLib_t * pLib, FILE * pFile ); |
| static Map_Super_t * Map_LibraryReadGate( Map_SuperLib_t * pLib, char * pBuffer, int nVars ); |
| static int Map_LibraryTruthVerify( Map_SuperLib_t * pLib, Map_Super_t * pGate ); |
| static void Map_LibraryComputeTruth( Map_SuperLib_t * pLib, char * pFormula, unsigned uTruthRes[] ); |
| static void Map_LibraryComputeTruth_rec( Map_SuperLib_t * pLib, char * pFormula, unsigned uTruthsIn[][2], unsigned uTruthRes[] ); |
| static void Map_LibraryPrintClasses( Map_SuperLib_t * p ); |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// FUNCTION DEFINITIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| /**Function************************************************************* |
| |
| Synopsis [Reads the supergate library from file.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Map_LibraryRead( Map_SuperLib_t * pLib, char * pFileName ) |
| { |
| FILE * pFile; |
| int Status; |
| // read the beginning of the file |
| assert( pLib->pGenlib == NULL ); |
| pFile = fopen( pFileName, "r" ); |
| if ( pFile == NULL ) |
| { |
| printf( "Cannot open input file \"%s\".\n", pFileName ); |
| return 0; |
| } |
| Status = Map_LibraryReadFile( pLib, pFile ); |
| fclose( pFile ); |
| // Map_LibraryPrintClasses( pLib ); |
| return Status; |
| } |
| |
| |
| /**Function************************************************************* |
| |
| Synopsis [Reads the library file.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Map_LibraryReadFile( Map_SuperLib_t * pLib, FILE * pFile ) |
| { |
| ProgressBar * pProgress; |
| char pBuffer[5000]; |
| FILE * pFileGen; |
| Map_Super_t * pGate; |
| char * pTemp = NULL; // Suppress "might be used uninitialized" |
| char * pLibName; |
| int nCounter, nGatesTotal; |
| unsigned uCanon[2]; |
| int RetValue; |
| |
| // skip empty and comment lines |
| while ( fgets( pBuffer, 2000, pFile ) != NULL ) |
| { |
| // skip leading spaces |
| for ( pTemp = pBuffer; *pTemp == ' ' || *pTemp == '\r' || *pTemp == '\n'; pTemp++ ); |
| // skip comment lines and empty lines |
| if ( *pTemp != 0 && *pTemp != '#' ) |
| break; |
| } |
| |
| // get the genlib file name |
| pLibName = strtok( pTemp, " \t\r\n" ); |
| if ( strcmp( pLibName, "GATE" ) == 0 ) |
| { |
| printf( "The input file \"%s\" looks like a genlib file and not a supergate library file.\n", pLib->pName ); |
| return 0; |
| } |
| pFileGen = fopen( pLibName, "r" ); |
| if ( pFileGen == NULL ) |
| { |
| printf( "Cannot open the genlib file \"%s\".\n", pLibName ); |
| return 0; |
| } |
| fclose( pFileGen ); |
| |
| // read the genlib library |
| pLib->pGenlib = Mio_LibraryRead( pLibName, NULL, 0, 0 ); |
| if ( pLib->pGenlib == NULL ) |
| { |
| printf( "Cannot read genlib file \"%s\".\n", pLibName ); |
| return 0; |
| } |
| |
| // read the number of variables |
| RetValue = fscanf( pFile, "%d\n", &pLib->nVarsMax ); |
| if ( pLib->nVarsMax < 2 || pLib->nVarsMax > 10 ) |
| { |
| printf( "Suspicious number of variables (%d).\n", pLib->nVarsMax ); |
| return 0; |
| } |
| |
| // read the number of gates |
| RetValue = fscanf( pFile, "%d\n", &nGatesTotal ); |
| if ( nGatesTotal < 1 || nGatesTotal > 10000000 ) |
| { |
| printf( "Suspicious number of gates (%d).\n", nGatesTotal ); |
| return 0; |
| } |
| |
| // read the lines |
| nCounter = 0; |
| pProgress = Extra_ProgressBarStart( stdout, nGatesTotal ); |
| while ( fgets( pBuffer, 5000, pFile ) != NULL ) |
| { |
| for ( pTemp = pBuffer; *pTemp == ' ' || *pTemp == '\r' || *pTemp == '\n'; pTemp++ ); |
| if ( pTemp[0] == '\0' ) |
| continue; |
| // get the gate |
| pGate = Map_LibraryReadGate( pLib, pTemp, pLib->nVarsMax ); |
| assert( pGate->Num == nCounter + 1 ); |
| // count the number of parentheses in the formula - this is the number of gates |
| for ( pTemp = pGate->pFormula; *pTemp; pTemp++ ) |
| pGate->nGates += (*pTemp == '('); |
| // verify the truth table |
| assert( Map_LibraryTruthVerify(pLib, pGate) ); |
| |
| // find the N-canonical form of this supergate |
| pGate->nPhases = Map_CanonComputeSlow( pLib->uTruths, pLib->nVarsMax, pLib->nVarsMax, pGate->uTruth, pGate->uPhases, uCanon ); |
| // add the supergate into the table by its N-canonical table |
| Map_SuperTableInsertC( pLib->tTableC, uCanon, pGate ); |
| // update the progress bar |
| Extra_ProgressBarUpdate( pProgress, ++nCounter, NULL ); |
| } |
| Extra_ProgressBarStop( pProgress ); |
| pLib->nSupersAll = nCounter; |
| if ( nCounter != nGatesTotal ) |
| printf( "The number of gates read (%d) is different what the file says (%d).\n", nGatesTotal, nCounter ); |
| return 1; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Map_Super_t * Map_LibraryReadGate( Map_SuperLib_t * pLib, char * pBuffer, int nVars ) |
| { |
| Map_Super_t * pGate; |
| char * pTemp; |
| int i; |
| |
| // start and clean the gate |
| pGate = (Map_Super_t *)Extra_MmFixedEntryFetch( pLib->mmSupers ); |
| memset( pGate, 0, sizeof(Map_Super_t) ); |
| |
| // read the number |
| pTemp = strtok( pBuffer, " " ); |
| pGate->Num = atoi(pTemp); |
| |
| // read the signature |
| pTemp = strtok( NULL, " " ); |
| if ( pLib->nVarsMax < 6 ) |
| { |
| pGate->uTruth[0] = Extra_ReadBinary(pTemp); |
| pGate->uTruth[1] = 0; |
| } |
| else |
| { |
| pGate->uTruth[0] = Extra_ReadBinary(pTemp+32); |
| pTemp[32] = 0; |
| pGate->uTruth[1] = Extra_ReadBinary(pTemp); |
| } |
| |
| // read the max delay |
| pTemp = strtok( NULL, " " ); |
| pGate->tDelayMax.Rise = (float)atof(pTemp); |
| pGate->tDelayMax.Fall = pGate->tDelayMax.Rise; |
| |
| // read the pin-to-pin delay |
| for ( i = 0; i < nVars; i++ ) |
| { |
| pTemp = strtok( NULL, " " ); |
| pGate->tDelaysR[i].Rise = (float)atof(pTemp); |
| pGate->tDelaysF[i].Fall = pGate->tDelaysR[i].Rise; |
| } |
| |
| // read the area |
| pTemp = strtok( NULL, " " ); |
| pGate->Area = (float)atof(pTemp); |
| |
| // the rest is the gate name |
| pTemp = strtok( NULL, " \r\n" ); |
| if ( strlen(pTemp) == 0 ) |
| printf( "A gate name is empty.\n" ); |
| |
| // save the gate name |
| pGate->pFormula = Extra_MmFlexEntryFetch( pLib->mmForms, strlen(pTemp) + 1 ); |
| strcpy( pGate->pFormula, pTemp ); |
| |
| // the rest is the gate name |
| pTemp = strtok( NULL, " \n\0" ); |
| if ( pTemp != NULL ) |
| printf( "The following trailing symbols found \"%s\".\n", pTemp ); |
| return pGate; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Performs one step of parsing the formula into parts.] |
| |
| Description [This function will eventually be replaced when the |
| tree-supergate library representation will become standard.] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| char * Map_LibraryReadFormulaStep( char * pFormula, char * pStrings[], int * pnStrings ) |
| { |
| char * pName, * pPar1, * pPar2, * pCur; |
| int nStrings, CountPars; |
| |
| // skip leading spaces |
| for ( pName = pFormula; *pName && *pName == ' '; pName++ ); |
| assert( *pName ); |
| // find the first opening parenthesis |
| for ( pPar1 = pName; *pPar1 && *pPar1 != '('; pPar1++ ); |
| if ( *pPar1 == 0 ) |
| { |
| *pnStrings = 0; |
| return pName; |
| } |
| // overwrite it with space |
| assert( *pPar1 == '(' ); |
| *pPar1 = 0; |
| // find the corresponding closing parenthesis |
| for ( CountPars = 1, pPar2 = pPar1 + 1; *pPar2 && CountPars; pPar2++ ) |
| if ( *pPar2 == '(' ) |
| CountPars++; |
| else if ( *pPar2 == ')' ) |
| CountPars--; |
| pPar2--; |
| assert( CountPars == 0 ); |
| // overwrite it with space |
| assert( *pPar2 == ')' ); |
| *pPar2 = 0; |
| // save the intervals between the commas |
| nStrings = 0; |
| pCur = pPar1 + 1; |
| while ( 1 ) |
| { |
| // save the current string |
| pStrings[ nStrings++ ] = pCur; |
| // find the beginning of the next string |
| for ( CountPars = 0; *pCur && (CountPars || *pCur != ','); pCur++ ) |
| if ( *pCur == '(' ) |
| CountPars++; |
| else if ( *pCur == ')' ) |
| CountPars--; |
| if ( *pCur == 0 ) |
| break; |
| assert( *pCur == ',' ); |
| *pCur = 0; |
| pCur++; |
| } |
| // save the results and return |
| *pnStrings = nStrings; |
| return pName; |
| } |
| |
| |
| /**Function************************************************************* |
| |
| Synopsis [Verifies the truth table of the supergate.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Map_LibraryTruthVerify( Map_SuperLib_t * pLib, Map_Super_t * pGate ) |
| { |
| unsigned uTruthRes[2]; |
| Map_LibraryComputeTruth( pLib, pGate->pFormula, uTruthRes ); |
| if ( uTruthRes[0] != pGate->uTruth[0] || uTruthRes[1] != pGate->uTruth[1] ) |
| return 0; |
| return 1; |
| } |
| |
| |
| /**Function************************************************************* |
| |
| Synopsis [Derives the functionality of the supergate.] |
| |
| Description [This procedure is useful for verification the supergate |
| library. The truth table derived by this procedure should be the same |
| as the one contained in the original supergate file.] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Map_LibraryComputeTruth( Map_SuperLib_t * pLib, char * pFormula, unsigned uTruthRes[] ) |
| { |
| char Buffer[1000]; |
| strcpy( Buffer, pFormula ); |
| Map_LibraryComputeTruth_rec( pLib, Buffer, pLib->uTruths, uTruthRes ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Derives the functionality of the supergate.] |
| |
| Description [This procedure is useful for verification the supergate |
| library. The truth table derived by this procedure should be the same |
| as the one contained in the original supergate file.] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Map_LibraryComputeTruth_rec( Map_SuperLib_t * pLib, char * pFormula, unsigned uTruthsIn[][2], unsigned uTruthRes[] ) |
| { |
| Mio_Gate_t * pMioGate; |
| char * pGateName, * pStrings[6]; |
| unsigned uTruthsFanins[6][2]; |
| int nStrings, i; |
| |
| // perform one step parsing of the formula |
| // detect the root gate name, the next-step strings, and their number |
| pGateName = Map_LibraryReadFormulaStep( pFormula, pStrings, &nStrings ); |
| if ( nStrings == 0 ) // elementary variable |
| { |
| assert( pGateName[0] - 'a' < pLib->nVarsMax ); |
| uTruthRes[0] = uTruthsIn[pGateName[0] - 'a'][0]; |
| uTruthRes[1] = uTruthsIn[pGateName[0] - 'a'][1]; |
| return; |
| } |
| // derive the functionality of the fanins |
| for ( i = 0; i < nStrings; i++ ) |
| Map_LibraryComputeTruth_rec( pLib, pStrings[i], uTruthsIn, uTruthsFanins[i] ); |
| // get the root supergate |
| pMioGate = Mio_LibraryReadGateByName( pLib->pGenlib, pGateName, NULL ); |
| if ( pMioGate == NULL ) |
| printf( "A supergate contains gate \"%s\" that is not in \"%s\".\n", pGateName, Mio_LibraryReadName(pLib->pGenlib) ); |
| // derive the functionality of the output of the supergate |
| Mio_DeriveTruthTable( pMioGate, uTruthsFanins, nStrings, pLib->nVarsMax, uTruthRes ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Map_LibraryPrintSupergate( Map_Super_t * pGate ) |
| { |
| printf( "%5d : ", pGate->nUsed ); |
| printf( "%5d ", pGate->Num ); |
| printf( "A = %5.2f ", pGate->Area ); |
| printf( "D = %5.2f/%5.2f/%5.2f ", pGate->tDelayMax.Rise, pGate->tDelayMax.Fall, pGate->tDelayMax.Worst ); |
| printf( "%s", pGate->pFormula ); |
| printf( "\n" ); |
| } |
| |
| |
| /**Function************************************************************* |
| |
| Synopsis [Prints N-classes of supergates.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Map_LibraryPrintClasses( Map_SuperLib_t * p ) |
| { |
| /* |
| st__generator * gen; |
| Map_Super_t * pSuper, * pSuper2; |
| unsigned Key, uTruth; |
| int Counter = 0; |
| // copy all the supergates into one array |
| st__foreach_item( p->tSuplib, gen, (char **)&Key, (char **)&pSuper ) |
| { |
| for ( pSuper2 = pSuper; pSuper2; pSuper2 = pSuper2->pNext ) |
| { |
| uTruth = pSuper2->Phase; |
| Extra_PrintBinary( stdout, &uTruth, 5 ); |
| printf( " %5d ", pSuper2->Num ); |
| printf( "%s", pSuper2->pFormula ); |
| printf( "\n" ); |
| } |
| printf( "\n" ); |
| if ( ++ Counter == 100 ) |
| break; |
| } |
| */ |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// END OF FILE /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| ABC_NAMESPACE_IMPL_END |
| |