📄 ioreadlines.c
字号:
/**CFile**************************************************************** FileName [ioReadLines.c] PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] Synopsis [Extracts preliminary information about the network in the file.] Author [MVSIS Group] Affiliation [UC Berkeley] Date [Ver. 1.0. Started - February 1, 2003.] Revision [$Id: ioReadLines.c,v 1.15 2003/05/27 23:14:14 alanmi Exp $]***********************************************************************/#include "ioInt.h"/////////////////////////////////////////////////////////////////////////// DECLARATIONS ///////////////////////////////////////////////////////////////////////////static int Io_ReadLinesDotMv( Io_Read_t * p, int Line );static Io_Var_t * Io_ReadLinesDotMvCopyVar( Io_Var_t * pVar );static char * Io_ReadLinesDotMvPivot( char * pStr );static int Io_ReadLinesDotLatch( Io_Read_t * p, Io_Latch_t * pIoLatch );static int Io_ReadLinesDotNode( Io_Read_t * p, Io_Node_t * pIoNode );static int Io_ReadLinesDotRes( Io_Read_t * p, int Line );static char * Io_ReadLinesLastEntry( char * pStr );static void Io_ReadLinesRemoveExtenders( Io_Read_t * p, int Line );static int Io_ReadLinesDetectFileType( Io_Read_t * p, Io_Node_t * pIoNode );/////////////////////////////////////////////////////////////////////////// FUNCTION DEFITIONS ////////////////////////////////////////////////////////////////////////////**Function************************************************************* Synopsis [Preliminary parsing actions before compiling the network.] Description [Assumes that the file has been split into lines. Sorts through the lines and assigns the Io_Node_t structure for each would-be node.] SideEffects [] SeeAlso []***********************************************************************/int Io_ReadLines( Io_Read_t * p ){ char * pDot; int nDotNodesInit, nDotMvsInit; int nDotResesInit, nDotLatchesInit; int nDotInputsInit, nDotOutputsInit; int i, n; // set a flag to show that this is the EXDC network p->fParsingExdcNet = 0; if ( p->LineExdc ) p->fParsingExdcNet = 1; // save the initial parameters nDotInputsInit = p->nDotInputs; nDotOutputsInit = p->nDotOutputs; nDotNodesInit = p->nDotNodes; nDotMvsInit = p->nDotMvs; nDotLatchesInit = p->nDotLatches; nDotResesInit = p->nDotReses; p->nDotInputs = 0; p->nDotOutputs = 0; p->nDotNodes = 0; p->nDotMvs = 0; p->nDotLatches = 0; p->nDotReses = 0; p->LineModel = -1; p->LineSpec = -1; // clean the tables for EXDC network if ( p->fParsingExdcNet ) Io_ReadStructCleanTables( p ); // sort the dot statements for ( i = p->fParsingExdcNet? p->LineExdc + 1: 0; i < p->nDots; i++ ) { // get the pointer to the line with the current dot-statement pDot = p->pLines[ p->pDots[i] ]; assert( pDot[0] == '.' ); // sort through dot-statements // strncmp() is not used to make string comparison faster if ( pDot[1] == 'n' && pDot[2] == 'a' && pDot[3] == 'm' && pDot[4] == 'e' && pDot[5] == 's' ) p->pIoNodes[ p->nDotNodes++ ].LineNames = p->pDots[i]; else if ( pDot[1] == 't' && pDot[2] == 'a' && pDot[3] == 'b' && pDot[4] == 'l' && pDot[5] == 'e' ) { p->Type = IO_FILE_BLIF_MV; p->pIoNodes[ p->nDotNodes++ ].LineNames = p->pDots[i]; } else if ( pDot[1] == 'd' && pDot[2] == 'e' && pDot[3] == 'f' && pDot[4] == ' ' ) // default line continue; else if ( pDot[1] == 'd' && pDot[2] == 'e' && pDot[3] == 'f' && pDot[4] == 'a' && pDot[5] == 'u' && pDot[6] == 'l' && pDot[7] == 't' && pDot[8] == ' ' ) // default line continue; else if ( pDot[1] == 'm' && pDot[2] == 'v' ) p->pDotMvs[ p->nDotMvs++ ] = p->pDots[i]; else if ( pDot[1] == 'l' && pDot[2] == 'a' && pDot[3] == 't' && pDot[4] == 'c' && pDot[5] == 'h' ) p->pIoLatches[ p->nDotLatches++ ].LineLatch = p->pDots[i]; else if ( pDot[1] == 'm' && pDot[2] == 'o' && pDot[3] == 'd' && pDot[4] == 'e' && pDot[5] == 'l' ) p->LineModel = p->pDots[i]; else if ( pDot[1] == 's' && pDot[2] == 'p' && pDot[3] == 'e' && pDot[4] == 'c' ) p->LineSpec = p->pDots[i]; else if ( pDot[1] == 'i' && pDot[2] == 'n' && pDot[3] == 'p' && pDot[4] == 'u' && pDot[5] == 't' && pDot[6] == 's' ) p->pDotInputs[ p->nDotInputs++ ] = p->pDots[i]; else if ( pDot[1] == 'o' && pDot[2] == 'u' && pDot[3] == 't' && pDot[4] == 'p' && pDot[5] == 'u' && pDot[6] == 't' && pDot[7] == 's' ) p->pDotOutputs[ p->nDotOutputs++ ] = p->pDots[i]; else if ( pDot[1] == 'e' && pDot[2] == 'n' && pDot[3] == 'd' ) { p->LineEnd = p->pDots[i]; break; } else if ( pDot[1] == 'e' && pDot[2] == 'x' && pDot[3] == 'd' && pDot[4] == 'c' ) { p->LineExdc = i; break; } else if ( pDot[1] == 'r' && pDot[2] == ' ' || pDot[1] == 'r' && pDot[2] == 'e' && pDot[3] == 's' ) // reset line { if ( Io_ReadLinesDotRes( p, p->pDots[i] ) ) return 1; } else { p->LineCur = p->pDots[i]; sprintf( p->sError, "Ignoring \"%s\" (warning only).", strtok( pDot, " \t" ) ); Io_ReadPrintErrorMessage( p ); // overwrite this line with spaces for ( n = 0; pDot[n]; n++ ) pDot[n] = 0; } } // make sure the lines are read correctly if ( !p->fParsingExdcNet && !p->LineExdc ) { // this is not an EXDC network and there is no EXDC network assert( nDotInputsInit == p->nDotInputs ); assert( nDotOutputsInit == p->nDotOutputs ); assert( nDotNodesInit == p->nDotNodes ); assert( nDotMvsInit == p->nDotMvs ); assert( nDotLatchesInit == p->nDotLatches ); assert( nDotResesInit == p->nDotReses ); } // error diagnostics if ( !p->fParsingExdcNet && p->LineModel < 0 ) { // this is a primary network p->LineCur = 0; sprintf( p->sError, ".model line is missing in the file." ); Io_ReadPrintErrorMessage( p ); return 1; } if ( p->nDotInputs == 0 ) { p->LineCur = 0; sprintf( p->sError, ".inputs line for the %s network is missing.", p->fParsingExdcNet? "EXDC" : "primary" ); Io_ReadPrintErrorMessage( p ); return 1; } if ( p->nDotOutputs == 0 ) { p->LineCur = 0; sprintf( p->sError, ".outputs line for the %s network is missing.", p->fParsingExdcNet? "EXDC" : "primary" ); Io_ReadPrintErrorMessage( p ); return 1; } if ( (!p->LineExdc || p->fParsingExdcNet ) && p->LineEnd < 0 ) { // there is no EXDC network or this is an EXDC network p->LineCur = 0; sprintf( p->sError, ".end line is missing in the file." ); Io_ReadPrintErrorMessage( p ); return 1; } if ( p->nDotReses != 0 && p->nDotLatches != p->nDotReses ) { p->LineCur = 0; sprintf( p->sError, "The number of latches differs from the number of reset lines." ); Io_ReadPrintErrorMessage( p ); return 1; } // remove backward slash line extenders for ( n = 0; n < p->nDotInputs; n++ ) Io_ReadLinesRemoveExtenders( p, p->pDotInputs[n] ); for ( n = 0; n < p->nDotOutputs; n++ ) Io_ReadLinesRemoveExtenders( p, p->pDotOutputs[n] ); for ( n = 0; n < p->nDotNodes; n++ ) Io_ReadLinesRemoveExtenders( p, p->pIoNodes[n].LineNames ); // preparse the .mv statements for ( n = 0; n < p->nDotMvs; n++ ) if ( Io_ReadLinesDotMv( p, p->pDotMvs[n] ) ) return 1; // preparse the latch statements for ( n = 0; n < p->nDotLatches; n++ ) if ( Io_ReadLinesDotLatch( p, p->pIoLatches + n ) ) return 1; // preparse the nodes for ( n = 0; n < p->nDotNodes; n++ ) if ( Io_ReadLinesDotNode( p, p->pIoNodes + n ) ) return 1; // preparse the latch reset tables for ( n = 0; n < p->nDotLatches; n++ ) if ( p->pIoLatches[n].IoNode.LineNames != -1 ) if ( Io_ReadLinesDotNode( p, &(p->pIoLatches[n].IoNode) ) ) return 1; return 0;}/**Function************************************************************* Synopsis [Parses one .mv line.] Description [Parses one .mv line. Derives the MV variable (represented by the number of values and the list of value names). For each node name associated with this variable, stores the copy of the MV variable in the hash table (p->tMvLines).] SideEffects [] SeeAlso []***********************************************************************/int Io_ReadLinesDotMv( Io_Read_t * p, int Line ){ Io_Var_t * pVar; char * pLine, * pTemp, * pPivot; int nValues; int i; // get the line pLine = p->pLines[ Line ]; assert( strncmp( pLine, ".mv", 3 ) == 0 ); // find the place in the line where the number of values is written pPivot = Io_ReadLinesDotMvPivot( pLine ); // separate the line in two *(pPivot - 1) = '\0'; // read the number of values; pTemp = strtok( pPivot, " \t" ); if ( pTemp == NULL ) { p->LineCur = Line; sprintf( p->sError, "The number of values is not specified." ); Io_ReadPrintErrorMessage( p ); return 1; } // get the variable nValues = atoi( pTemp ); if ( nValues < 2 || nValues > 32000 ) { p->LineCur = Line; sprintf( p->sError, "The number of values (%s) is wrong.", pTemp ); Io_ReadPrintErrorMessage( p ); return 1; } // read the first value name pTemp = strtok( NULL, " \t" ); if ( pTemp != NULL ) { // allocate the variable pVar = ALLOC( Io_Var_t, 1 ); // assing the number of values pVar->nValues = nValues; // allocate the value names pVar->pValueNames = ALLOC( char *, pVar->nValues ); // assing the value names one by one i = 0; do pVar->pValueNames[i++] = util_strsav( pTemp ); while ( pTemp = strtok( NULL, " \t" ) ); // check if the number of value names is okay if ( i != pVar->nValues ) { p->LineCur = Line; sprintf( p->sError, "The number of value names (%d) should be %d.", i, pVar->nValues ); Io_ReadPrintErrorMessage( p ); return 1; } // allocate the table to store value names if it does not exist if ( p->tName2Var == NULL ) p->tName2Var = st_init_table(strcmp, st_strhash); // allocate the table to store number of values if it does not exist if ( p->tName2Values == NULL ) p->tName2Values = st_init_table(strcmp, st_strhash); // skip the .mv line pTemp = strtok( pLine, " \t" ); // get the node names, to which this variable belongs for ( i = 0; pTemp = strtok( NULL, ", \t" ); i++ ) { if ( i ) pVar = Io_ReadLinesDotMvCopyVar( pVar ); st_insert( p->tName2Var, pTemp, (char *)pVar ); // store the number of values if it is larger than 2 if ( nValues > 2 ) if ( Io_ReadLinesAddNumValues( p, pTemp, nValues ) ) return 1; } } else if ( nValues > 2 ) { // allocate the table to store number of values if it does not exist if ( p->tName2Values == NULL ) p->tName2Values = st_init_table(strcmp, st_strhash); // get the node names, to which this num values applies // skip the .mv line pTemp = strtok( pLine, " \t" ); // read the node names for ( i = 0; pTemp = strtok( NULL, ", \t" ); i++ ) if ( Io_ReadLinesAddNumValues( p, pTemp, nValues ) ) return 1; } return 0;}/**Function************************************************************* Synopsis [Produces a copy of the MV variable.] Description [] SideEffects [] SeeAlso []***********************************************************************/Io_Var_t * Io_ReadLinesDotMvCopyVar( Io_Var_t * pVar ){ Io_Var_t * pCopy; int i; pCopy = ALLOC( Io_Var_t, 1 ); pCopy->nValues = pVar->nValues; pCopy->pValueNames = ALLOC( char *, pVar->nValues ); for ( i = 0; i < pVar->nValues; i++ ) pCopy->pValueNames[i] = util_strsav( pVar->pValueNames[i] ); return pCopy;}/**Function************************************************************* Synopsis [Finds the place in MV line where the number of values is written.] Description [] SideEffects [] SeeAlso []***********************************************************************/char * Io_ReadLinesDotMvPivot( char * pStr ){ char * pComma, * pTemp; // find the last comma pComma = NULL; for ( pTemp = pStr; *pTemp; pTemp++ ) if ( *pTemp == ',' ) pComma = pTemp; if ( pComma ) { // find the next non-space char pTemp = pComma + 1; while ( *pTemp && (*pTemp == ' ' || *pTemp == '\t') ) pTemp++; // find the next space char while ( *pTemp && *pTemp != ' ' && *pTemp != '\t' ) pTemp++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -