diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2008-01-30 20:01:00 -0800 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2008-01-30 20:01:00 -0800 |
commit | 0c6505a26a537dc911b6566f82d759521e527c08 (patch) | |
tree | f2687995efd4943fe3b1307fce7ef5942d0a57b3 /src/base/io/ioReadBlif.c | |
parent | 4d30a1e4f1edecff86d5066ce4653a370e59e5e1 (diff) | |
download | abc-0c6505a26a537dc911b6566f82d759521e527c08.tar.gz abc-0c6505a26a537dc911b6566f82d759521e527c08.tar.bz2 abc-0c6505a26a537dc911b6566f82d759521e527c08.zip |
Version abc80130_2
Diffstat (limited to 'src/base/io/ioReadBlif.c')
-rw-r--r-- | src/base/io/ioReadBlif.c | 772 |
1 files changed, 575 insertions, 197 deletions
diff --git a/src/base/io/ioReadBlif.c b/src/base/io/ioReadBlif.c index 946de42b..d0750178 100644 --- a/src/base/io/ioReadBlif.c +++ b/src/base/io/ioReadBlif.c @@ -33,42 +33,47 @@ struct Io_ReadBlif_t_ char * pFileName; // the name of the file Extra_FileReader_t * pReader; // the input file reader // current processing info - Abc_Ntk_t * pNtk; // the primary network - Abc_Ntk_t * pNtkExdc; // the exdc network - int fParsingExdc; // this flag is on, when we are parsing EXDC network + Abc_Ntk_t * pNtkMaster; // the primary network + Abc_Ntk_t * pNtkCur; // the primary network int LineCur; // the line currently parsed // temporary storage for tokens + Vec_Ptr_t * vTokens; // the current tokens Vec_Ptr_t * vNewTokens; // the temporary storage for the tokens Vec_Str_t * vCubes; // the temporary storage for the tokens // the error message FILE * Output; // the output stream char sError[1000]; // the error string generated during parsing + int fError; // set to 1 when error occurs }; static Io_ReadBlif_t * Io_ReadBlifFile( char * pFileName ); static void Io_ReadBlifFree( Io_ReadBlif_t * p ); static void Io_ReadBlifPrintErrorMessage( Io_ReadBlif_t * p ); static Vec_Ptr_t * Io_ReadBlifGetTokens( Io_ReadBlif_t * p ); -static Abc_Ntk_t * Io_ReadBlifNetwork( Io_ReadBlif_t * p ); static char * Io_ReadBlifCleanName( char * pName ); +static Abc_Ntk_t * Io_ReadBlifNetwork( Io_ReadBlif_t * p ); +static Abc_Ntk_t * Io_ReadBlifNetworkOne( Io_ReadBlif_t * p ); static int Io_ReadBlifNetworkInputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ); static int Io_ReadBlifNetworkOutputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ); +static int Io_ReadBlifNetworkAsserts( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ); static int Io_ReadBlifNetworkLatch( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ); static int Io_ReadBlifNetworkNames( Io_ReadBlif_t * p, Vec_Ptr_t ** pvTokens ); static int Io_ReadBlifNetworkGate( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ); +static int Io_ReadBlifNetworkSubcircuit( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ); static int Io_ReadBlifNetworkInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ); static int Io_ReadBlifNetworkDefaultInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ); +static int Io_ReadBlifNetworkConnectBoxes( Io_ReadBlif_t * p, Abc_Ntk_t * pNtkMaster ); //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// +/// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* - Synopsis [Reads the network from a BLIF file.] + Synopsis [Reads the (hierarchical) network from the BLIF file.] - Description [Works only for flat (non-hierarchical) BLIF.] + Description [] SideEffects [] @@ -78,34 +83,22 @@ static int Io_ReadBlifNetworkDefaultInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * Abc_Ntk_t * Io_ReadBlif( char * pFileName, int fCheck ) { Io_ReadBlif_t * p; - Abc_Ntk_t * pNtk, * pNtkExdc; + Abc_Ntk_t * pNtk; // start the file p = Io_ReadBlifFile( pFileName ); if ( p == NULL ) return NULL; - // read the network + // read the hierarchical network pNtk = Io_ReadBlifNetwork( p ); if ( pNtk == NULL ) { Io_ReadBlifFree( p ); return NULL; } + pNtk->pSpec = Extra_UtilStrsav( pFileName ); Abc_NtkTimeInitialize( pNtk ); - - // read the EXDC network - if ( p->fParsingExdc ) - { - pNtkExdc = Io_ReadBlifNetwork( p ); - if ( pNtkExdc == NULL ) - { - Abc_NtkDelete( pNtk ); - Io_ReadBlifFree( p ); - return NULL; - } - pNtk->pExdc = pNtkExdc; - } Io_ReadBlifFree( p ); // make sure that everything is okay with the network structure @@ -120,7 +113,7 @@ Abc_Ntk_t * Io_ReadBlif( char * pFileName, int fCheck ) /**Function************************************************************* - Synopsis [Starts the reading data structure.] + Synopsis [Iteratively reads several networks in the hierarchical design.] Description [] @@ -129,140 +122,80 @@ Abc_Ntk_t * Io_ReadBlif( char * pFileName, int fCheck ) SeeAlso [] ***********************************************************************/ -Io_ReadBlif_t * Io_ReadBlifFile( char * pFileName ) -{ - Extra_FileReader_t * pReader; - Io_ReadBlif_t * p; - - // start the reader - pReader = Extra_FileReaderAlloc( pFileName, "#", "\n", " \t\r" ); - if ( pReader == NULL ) - return NULL; - - // start the reading data structure - p = ALLOC( Io_ReadBlif_t, 1 ); - memset( p, 0, sizeof(Io_ReadBlif_t) ); - p->pFileName = pFileName; - p->pReader = pReader; - p->Output = stdout; - p->vNewTokens = Vec_PtrAlloc( 100 ); - p->vCubes = Vec_StrAlloc( 100 ); - return p; -} - -/**Function************************************************************* - - Synopsis [Frees the data structure.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Io_ReadBlifFree( Io_ReadBlif_t * p ) -{ - Extra_FileReaderFree( p->pReader ); - Vec_PtrFree( p->vNewTokens ); - Vec_StrFree( p->vCubes ); - free( p ); -} - -/**Function************************************************************* - - Synopsis [Prints the error message including the file name and line number.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Io_ReadBlifPrintErrorMessage( Io_ReadBlif_t * p ) -{ - if ( p->LineCur == 0 ) // the line number is not given - fprintf( p->Output, "%s: %s\n", p->pFileName, p->sError ); - else // print the error message with the line number - fprintf( p->Output, "%s (line %d): %s\n", p->pFileName, p->LineCur, p->sError ); -} - -/**Function************************************************************* - - Synopsis [Gets the tokens taking into account the line breaks.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Io_ReadBlifGetTokens( Io_ReadBlif_t * p ) +Abc_Ntk_t * Io_ReadBlifNetwork( Io_ReadBlif_t * p ) { - Vec_Ptr_t * vTokens; - char * pLastToken; - int i; + Abc_Ntk_t * pNtk, * pNtkMaster; - // get rid of the old tokens - if ( p->vNewTokens->nSize > 0 ) + // read the name of the master network + p->vTokens = Io_ReadBlifGetTokens(p); + if ( p->vTokens == NULL || strcmp( p->vTokens->pArray[0], ".model" ) ) { - for ( i = 0; i < p->vNewTokens->nSize; i++ ) - free( p->vNewTokens->pArray[i] ); - p->vNewTokens->nSize = 0; + p->LineCur = 0; + sprintf( p->sError, "Wrong input file format." ); + Io_ReadBlifPrintErrorMessage( p ); + return NULL; } - // get the new tokens - vTokens = Extra_FileReaderGetTokens(p->pReader); - if ( vTokens == NULL ) - return vTokens; - - // check if there is a transfer to another line - pLastToken = vTokens->pArray[vTokens->nSize - 1]; - if ( pLastToken[ strlen(pLastToken)-1 ] != '\\' ) - return vTokens; - - // remove the slash - pLastToken[ strlen(pLastToken)-1 ] = 0; - if ( pLastToken[0] == 0 ) - vTokens->nSize--; - // load them into the new array - for ( i = 0; i < vTokens->nSize; i++ ) - Vec_PtrPush( p->vNewTokens, util_strsav(vTokens->pArray[i]) ); - - // load as long as there is the line break - while ( 1 ) + // read networks (with EXDC) + pNtkMaster = NULL; + while ( p->vTokens ) { - // get the new tokens - vTokens = Extra_FileReaderGetTokens(p->pReader); - if ( vTokens->nSize == 0 ) - return p->vNewTokens; - // check if there is a transfer to another line - pLastToken = vTokens->pArray[vTokens->nSize - 1]; - if ( pLastToken[ strlen(pLastToken)-1 ] == '\\' ) + // read the network and its EXDC if present + pNtk = Io_ReadBlifNetworkOne( p ); + if ( pNtk == NULL ) + break; + if ( p->vTokens && strcmp(p->vTokens->pArray[0], ".exdc") == 0 ) { - // remove the slash - pLastToken[ strlen(pLastToken)-1 ] = 0; - if ( pLastToken[0] == 0 ) - vTokens->nSize--; - // load them into the new array - for ( i = 0; i < vTokens->nSize; i++ ) - Vec_PtrPush( p->vNewTokens, util_strsav(vTokens->pArray[i]) ); + pNtk->pExdc = Io_ReadBlifNetworkOne( p ); + Abc_NtkFinalizeRead( pNtk->pExdc ); + if ( pNtk->pExdc == NULL ) + break; + } + // add this network as part of the hierarchy + if ( pNtkMaster == NULL ) // no master network so far + { + p->pNtkMaster = pNtkMaster = pNtk; continue; } - // otherwise, load them and break - for ( i = 0; i < vTokens->nSize; i++ ) - Vec_PtrPush( p->vNewTokens, util_strsav(vTokens->pArray[i]) ); - break; +/* + // make sure hierarchy does not have the network with this name + if ( pNtkMaster->tName2Model && stmm_is_member( pNtkMaster->tName2Model, pNtk->pName ) ) + { + p->LineCur = 0; + sprintf( p->sError, "Model %s is multiply defined in the file.", pNtk->pName ); + Io_ReadBlifPrintErrorMessage( p ); + Abc_NtkDelete( pNtk ); + Abc_NtkDelete( pNtkMaster ); + pNtkMaster = NULL; + return NULL; + } + // add the network to the hierarchy + if ( pNtkMaster->tName2Model == NULL ) + pNtkMaster->tName2Model = stmm_init_table(strcmp, stmm_strhash); + stmm_insert( pNtkMaster->tName2Model, pNtk->pName, (char *)pNtk ); +*/ } - return p->vNewTokens; +/* + // if there is a hierarchy, connect the boxes + if ( pNtkMaster && pNtkMaster->tName2Model ) + { + if ( Io_ReadBlifNetworkConnectBoxes( p, pNtkMaster ) ) + { + Abc_NtkDelete( pNtkMaster ); + return NULL; + } + } + else +*/ + if ( !p->fError ) + Abc_NtkFinalizeRead( pNtkMaster ); + // return the master network + return pNtkMaster; } - /**Function************************************************************* - Synopsis [Reads the BLIF file.] + Synopsis [Reads one (main or exdc) network from the BLIF file.] Description [] @@ -271,74 +204,89 @@ Vec_Ptr_t * Io_ReadBlifGetTokens( Io_ReadBlif_t * p ) SeeAlso [] ***********************************************************************/ -Abc_Ntk_t * Io_ReadBlifNetwork( Io_ReadBlif_t * p ) +Abc_Ntk_t * Io_ReadBlifNetworkOne( Io_ReadBlif_t * p ) { ProgressBar * pProgress; - Vec_Ptr_t * vTokens; - char * pModelName, * pDirective; + Abc_Ntk_t * pNtk; + char * pDirective; int iLine, fTokensReady, fStatus; + // make sure the tokens are present + assert( p->vTokens != NULL ); + + // create the new network + p->pNtkCur = pNtk = Abc_NtkAlloc( ABC_NTK_NETLIST, ABC_FUNC_SOP, 1 ); // read the model name - if ( !p->fParsingExdc ) + if ( strcmp( p->vTokens->pArray[0], ".model" ) == 0 ) + pNtk->pName = Extra_UtilStrsav( p->vTokens->pArray[1] ); + else if ( strcmp( p->vTokens->pArray[0], ".exdc" ) != 0 ) { - // read the model name - vTokens = Io_ReadBlifGetTokens(p); - if ( vTokens == NULL || strcmp( vTokens->pArray[0], ".model" ) ) - { - p->LineCur = 0; - sprintf( p->sError, "Wrong input file format." ); - Io_ReadBlifPrintErrorMessage( p ); - return NULL; - } - pModelName = vTokens->pArray[1]; - // allocate the empty network - p->pNtk = Abc_NtkAlloc( ABC_TYPE_NETLIST, ABC_FUNC_SOP ); - p->pNtk->pName = util_strsav( pModelName ); - p->pNtk->pSpec = util_strsav( p->pFileName ); + printf( "%s: File parsing skipped after line %d (\"%s\").\n", p->pFileName, + Extra_FileReaderGetLineNumber(p->pReader, 0), p->vTokens->pArray[0] ); + Abc_NtkDelete(pNtk); + p->pNtkCur = NULL; + return NULL; } - else - p->pNtk = Abc_NtkAlloc( ABC_TYPE_NETLIST, ABC_FUNC_SOP ); // read the inputs/outputs + if ( p->pNtkMaster == NULL ) pProgress = Extra_ProgressBarStart( stdout, Extra_FileReaderGetFileSize(p->pReader) ); fTokensReady = fStatus = 0; - for ( iLine = 0; fTokensReady || (vTokens = Io_ReadBlifGetTokens(p)); iLine++ ) + for ( iLine = 0; fTokensReady || (p->vTokens = Io_ReadBlifGetTokens(p)); iLine++ ) { - if ( iLine % 1000 == 0 ) + if ( p->pNtkMaster == NULL && iLine % 1000 == 0 ) Extra_ProgressBarUpdate( pProgress, Extra_FileReaderGetCurPosition(p->pReader), NULL ); // consider different line types fTokensReady = 0; - pDirective = vTokens->pArray[0]; + pDirective = p->vTokens->pArray[0]; if ( !strcmp( pDirective, ".names" ) ) - { fStatus = Io_ReadBlifNetworkNames( p, &vTokens ); fTokensReady = 1; } + { fStatus = Io_ReadBlifNetworkNames( p, &p->vTokens ); fTokensReady = 1; } else if ( !strcmp( pDirective, ".gate" ) ) - fStatus = Io_ReadBlifNetworkGate( p, vTokens ); + fStatus = Io_ReadBlifNetworkGate( p, p->vTokens ); else if ( !strcmp( pDirective, ".latch" ) ) - fStatus = Io_ReadBlifNetworkLatch( p, vTokens ); + fStatus = Io_ReadBlifNetworkLatch( p, p->vTokens ); else if ( !strcmp( pDirective, ".inputs" ) ) - fStatus = Io_ReadBlifNetworkInputs( p, vTokens ); + fStatus = Io_ReadBlifNetworkInputs( p, p->vTokens ); else if ( !strcmp( pDirective, ".outputs" ) ) - fStatus = Io_ReadBlifNetworkOutputs( p, vTokens ); + fStatus = Io_ReadBlifNetworkOutputs( p, p->vTokens ); + else if ( !strcmp( pDirective, ".asserts" ) ) + fStatus = Io_ReadBlifNetworkAsserts( p, p->vTokens ); else if ( !strcmp( pDirective, ".input_arrival" ) ) - fStatus = Io_ReadBlifNetworkInputArrival( p, vTokens ); + fStatus = Io_ReadBlifNetworkInputArrival( p, p->vTokens ); else if ( !strcmp( pDirective, ".default_input_arrival" ) ) - fStatus = Io_ReadBlifNetworkDefaultInputArrival( p, vTokens ); + fStatus = Io_ReadBlifNetworkDefaultInputArrival( p, p->vTokens ); +// else if ( !strcmp( pDirective, ".subckt" ) ) +// fStatus = Io_ReadBlifNetworkSubcircuit( p, p->vTokens ); else if ( !strcmp( pDirective, ".exdc" ) ) - { p->fParsingExdc = 1; break; } + break; else if ( !strcmp( pDirective, ".end" ) ) + { + p->vTokens = Io_ReadBlifGetTokens(p); break; + } + else if ( !strcmp( pDirective, ".blackbox" ) ) + { + pNtk->ntkType = ABC_NTK_NETLIST; + pNtk->ntkFunc = ABC_FUNC_BLACKBOX; + Extra_MmFlexStop( pNtk->pManFunc ); + pNtk->pManFunc = NULL; + } else printf( "%s (line %d): Skipping directive \"%s\".\n", p->pFileName, Extra_FileReaderGetLineNumber(p->pReader, 0), pDirective ); - if ( vTokens == NULL ) // some files do not have ".end" in the end + if ( p->vTokens == NULL ) // some files do not have ".end" in the end break; if ( fStatus == 1 ) + { + Extra_ProgressBarStop( pProgress ); + Abc_NtkDelete( pNtk ); return NULL; + } } + if ( p->pNtkMaster == NULL ) Extra_ProgressBarStop( pProgress ); - Abc_NtkFinalizeRead( p->pNtk ); - return p->pNtk; + return pNtk; } /**Function************************************************************* @@ -356,7 +304,7 @@ int Io_ReadBlifNetworkInputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) { int i; for ( i = 1; i < vTokens->nSize; i++ ) - Io_ReadCreatePi( p->pNtk, vTokens->pArray[i] ); + Io_ReadCreatePi( p->pNtkCur, vTokens->pArray[i] ); return 0; } @@ -375,7 +323,7 @@ int Io_ReadBlifNetworkOutputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) { int i; for ( i = 1; i < vTokens->nSize; i++ ) - Io_ReadCreatePo( p->pNtk, vTokens->pArray[i] ); + Io_ReadCreatePo( p->pNtkCur, vTokens->pArray[i] ); return 0; } @@ -390,12 +338,30 @@ int Io_ReadBlifNetworkOutputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) SeeAlso [] ***********************************************************************/ -int Io_ReadBlifNetworkLatch( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) +int Io_ReadBlifNetworkAsserts( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) { - Abc_Ntk_t * pNtk = p->pNtk; + int i; + for ( i = 1; i < vTokens->nSize; i++ ) + Io_ReadCreateAssert( p->pNtkCur, vTokens->pArray[i] ); + return 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Io_ReadBlifNetworkLatch( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) +{ + Abc_Ntk_t * pNtk = p->pNtkCur; Abc_Obj_t * pLatch; int ResetValue; - if ( vTokens->nSize < 3 ) { p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); @@ -407,10 +373,10 @@ int Io_ReadBlifNetworkLatch( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) pLatch = Io_ReadCreateLatch( pNtk, vTokens->pArray[1], vTokens->pArray[2] ); // get the latch reset value if ( vTokens->nSize == 3 ) - ResetValue = 2; + Abc_LatchSetInitDc( pLatch ); else { - ResetValue = atoi(vTokens->pArray[3]); + ResetValue = atoi(vTokens->pArray[vTokens->nSize-1]); if ( ResetValue != 0 && ResetValue != 1 && ResetValue != 2 ) { p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); @@ -418,8 +384,13 @@ int Io_ReadBlifNetworkLatch( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) Io_ReadBlifPrintErrorMessage( p ); return 1; } + if ( ResetValue == 0 ) + Abc_LatchSetInit0( pLatch ); + else if ( ResetValue == 1 ) + Abc_LatchSetInit1( pLatch ); + else if ( ResetValue == 2 ) + Abc_LatchSetInitDc( pLatch ); } - Abc_ObjSetData( pLatch, (void *)ResetValue ); return 0; } @@ -437,7 +408,7 @@ int Io_ReadBlifNetworkLatch( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) int Io_ReadBlifNetworkNames( Io_ReadBlif_t * p, Vec_Ptr_t ** pvTokens ) { Vec_Ptr_t * vTokens = *pvTokens; - Abc_Ntk_t * pNtk = p->pNtk; + Abc_Ntk_t * pNtk = p->pNtkCur; Abc_Obj_t * pNode; char * pToken, Char, ** ppNames; int nFanins, nNames; @@ -500,7 +471,7 @@ int Io_ReadBlifNetworkNames( Io_ReadBlif_t * p, Vec_Ptr_t ** pvTokens ) Vec_StrAppend( p->vCubes, vTokens->pArray[0] ); // check the char Char = ((char *)vTokens->pArray[1])[0]; - if ( Char != '0' && Char != '1' ) + if ( Char != '0' && Char != '1' && Char != 'x' && Char != 'n' ) { p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); sprintf( p->sError, "The output character in the constant cube is wrong." ); @@ -525,6 +496,16 @@ int Io_ReadBlifNetworkNames( Io_ReadBlif_t * p, Vec_Ptr_t ** pvTokens ) // set the pointer to the functionality of the node Abc_ObjSetData( pNode, Abc_SopRegister(pNtk->pManFunc, p->vCubes->pArray) ); + // check the size + if ( Abc_ObjFaninNum(pNode) != Abc_SopGetVarNum(Abc_ObjData(pNode)) ) + { + p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); + sprintf( p->sError, "The number of fanins (%d) of node %s is different from SOP size (%d).", + Abc_ObjFaninNum(pNode), Abc_ObjName(Abc_ObjFanout(pNode,0)), Abc_SopGetVarNum(Abc_ObjData(pNode)) ); + Io_ReadBlifPrintErrorMessage( p ); + return 1; + } + // return the last array of tokens *pvTokens = vTokens; return 0; @@ -550,7 +531,7 @@ int Io_ReadBlifNetworkGate( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) int i, nNames; // check that the library is available - pGenlib = Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()); + pGenlib = Abc_FrameReadLibGen(); if ( pGenlib == NULL ) { p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); @@ -579,12 +560,12 @@ int Io_ReadBlifNetworkGate( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) } // if this is the first line with gate, update the network type - if ( Abc_NtkNodeNum(p->pNtk) == 0 ) + if ( Abc_NtkNodeNum(p->pNtkCur) == 0 ) { - assert( p->pNtk->ntkFunc == ABC_FUNC_SOP ); - p->pNtk->ntkFunc = ABC_FUNC_MAP; - Extra_MmFlexStop( p->pNtk->pManFunc, 0 ); - p->pNtk->pManFunc = pGenlib; + assert( p->pNtkCur->ntkFunc == ABC_FUNC_SOP ); + p->pNtkCur->ntkFunc = ABC_FUNC_MAP; + Extra_MmFlexStop( p->pNtkCur->pManFunc ); + p->pNtkCur->pManFunc = pGenlib; } // remove the formal parameter names @@ -603,13 +584,54 @@ int Io_ReadBlifNetworkGate( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) // create the node ppNames = (char **)vTokens->pArray + 2; nNames = vTokens->nSize - 3; - pNode = Io_ReadCreateNode( p->pNtk, ppNames[nNames], ppNames, nNames ); + pNode = Io_ReadCreateNode( p->pNtkCur, ppNames[nNames], ppNames, nNames ); // set the pointer to the functionality of the node Abc_ObjSetData( pNode, pGate ); return 0; } +/**Function************************************************************* + + Synopsis [Creates a multi-input multi-output box in the hierarchical design.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Io_ReadBlifNetworkSubcircuit( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) +{ + Abc_Obj_t * pBox; + Vec_Ptr_t * vNames; + char * pName; + int i; + + // create a new node and add it to the network + if ( vTokens->nSize < 3 ) + { + p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); + sprintf( p->sError, "The .subcircuit line has less than three tokens." ); + Io_ReadBlifPrintErrorMessage( p ); + return 1; + } + + // store the names of formal/actual inputs/outputs of the box + vNames = Vec_PtrAlloc( 10 ); + Vec_PtrForEachEntryStart( vTokens, pName, i, 1 ) +// Vec_PtrPush( vNames, Abc_NtkRegisterName(p->pNtkCur, pName) ); + Vec_PtrPush( vNames, Extra_UtilStrsav(pName) ); // memory leak!!! + + // create a new box and add it to the network + pBox = Abc_NtkCreateBlackbox( p->pNtkCur ); + // set the pointer to the node names + Abc_ObjSetData( pBox, vNames ); + // remember the line of the file + pBox->pCopy = (void *)Extra_FileReaderGetLineNumber(p->pReader, 0); + return 0; +} /**Function************************************************************* @@ -658,7 +680,7 @@ int Io_ReadBlifNetworkInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) Io_ReadBlifPrintErrorMessage( p ); return 1; } - pNet = Abc_NtkFindNet( p->pNtk, vTokens->pArray[1] ); + pNet = Abc_NtkFindNet( p->pNtkCur, vTokens->pArray[1] ); if ( pNet == NULL ) { p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); @@ -676,7 +698,7 @@ int Io_ReadBlifNetworkInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) return 1; } // set the arrival time - Abc_NtkTimeSetArrival( p->pNtk, pNet->Id, (float)TimeRise, (float)TimeFall ); + Abc_NtkTimeSetArrival( p->pNtkCur, Abc_ObjFanin0(pNet)->Id, (float)TimeRise, (float)TimeFall ); return 0; } @@ -715,10 +737,366 @@ int Io_ReadBlifNetworkDefaultInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vToken return 1; } // set the arrival time - Abc_NtkTimeSetDefaultArrival( p->pNtk, (float)TimeRise, (float)TimeFall ); + Abc_NtkTimeSetDefaultArrival( p->pNtkCur, (float)TimeRise, (float)TimeFall ); + return 0; +} + +/**Function************************************************************* + + Synopsis [Prints the error message including the file name and line number.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Io_ReadBlifPrintErrorMessage( Io_ReadBlif_t * p ) +{ + p->fError = 1; + if ( p->LineCur == 0 ) // the line number is not given + fprintf( p->Output, "%s: %s\n", p->pFileName, p->sError ); + else // print the error message with the line number + fprintf( p->Output, "%s (line %d): %s\n", p->pFileName, p->LineCur, p->sError ); +} + +/**Function************************************************************* + + Synopsis [Gets the tokens taking into account the line breaks.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Io_ReadBlifGetTokens( Io_ReadBlif_t * p ) +{ + Vec_Ptr_t * vTokens; + char * pLastToken; + int i; + + // get rid of the old tokens + if ( p->vNewTokens->nSize > 0 ) + { + for ( i = 0; i < p->vNewTokens->nSize; i++ ) + free( p->vNewTokens->pArray[i] ); + p->vNewTokens->nSize = 0; + } + + // get the new tokens + vTokens = Extra_FileReaderGetTokens(p->pReader); + if ( vTokens == NULL ) + return vTokens; + + // check if there is a transfer to another line + pLastToken = vTokens->pArray[vTokens->nSize - 1]; + if ( pLastToken[ strlen(pLastToken)-1 ] != '\\' ) + return vTokens; + + // remove the slash + pLastToken[ strlen(pLastToken)-1 ] = 0; + if ( pLastToken[0] == 0 ) + vTokens->nSize--; + // load them into the new array + for ( i = 0; i < vTokens->nSize; i++ ) + Vec_PtrPush( p->vNewTokens, Extra_UtilStrsav(vTokens->pArray[i]) ); + + // load as long as there is the line break + while ( 1 ) + { + // get the new tokens + vTokens = Extra_FileReaderGetTokens(p->pReader); + if ( vTokens->nSize == 0 ) + return p->vNewTokens; + // check if there is a transfer to another line + pLastToken = vTokens->pArray[vTokens->nSize - 1]; + if ( pLastToken[ strlen(pLastToken)-1 ] == '\\' ) + { + // remove the slash + pLastToken[ strlen(pLastToken)-1 ] = 0; + if ( pLastToken[0] == 0 ) + vTokens->nSize--; + // load them into the new array + for ( i = 0; i < vTokens->nSize; i++ ) + Vec_PtrPush( p->vNewTokens, Extra_UtilStrsav(vTokens->pArray[i]) ); + continue; + } + // otherwise, load them and break + for ( i = 0; i < vTokens->nSize; i++ ) + Vec_PtrPush( p->vNewTokens, Extra_UtilStrsav(vTokens->pArray[i]) ); + break; + } + return p->vNewTokens; +} + +/**Function************************************************************* + + Synopsis [Starts the reading data structure.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Io_ReadBlif_t * Io_ReadBlifFile( char * pFileName ) +{ + Extra_FileReader_t * pReader; + Io_ReadBlif_t * p; + + // start the reader + pReader = Extra_FileReaderAlloc( pFileName, "#", "\n\r", " \t" ); + + if ( pReader == NULL ) + return NULL; + + // start the reading data structure + p = ALLOC( Io_ReadBlif_t, 1 ); + memset( p, 0, sizeof(Io_ReadBlif_t) ); + p->pFileName = pFileName; + p->pReader = pReader; + p->Output = stdout; + p->vNewTokens = Vec_PtrAlloc( 100 ); + p->vCubes = Vec_StrAlloc( 100 ); + return p; +} + +/**Function************************************************************* + + Synopsis [Frees the data structure.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Io_ReadBlifFree( Io_ReadBlif_t * p ) +{ + Extra_FileReaderFree( p->pReader ); + Vec_PtrFree( p->vNewTokens ); + Vec_StrFree( p->vCubes ); + free( p ); +} + + +/**Function************************************************************* + + Synopsis [Connect one box.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Io_ReadBlifNetworkConnectBoxesOneBox( Io_ReadBlif_t * p, Abc_Obj_t * pBox, stmm_table * tName2Model ) +{ + Vec_Ptr_t * pNames; + Abc_Ntk_t * pNtkModel; + Abc_Obj_t * pObj, * pNet; + char * pName, * pActual; + int i, Length, Start; + + // get the model for this box + pNames = pBox->pData; + if ( !stmm_lookup( tName2Model, Vec_PtrEntry(pNames, 0), (char **)&pNtkModel ) ) + { + p->LineCur = (int)pBox->pCopy; + sprintf( p->sError, "Cannot find the model for subcircuit %s.", Vec_PtrEntry(pNames, 0) ); + Io_ReadBlifPrintErrorMessage( p ); + return 1; + } + + // create the fanins of the box + Abc_NtkForEachPi( pNtkModel, pObj, i ) + pObj->pCopy = NULL; + if ( Abc_NtkPiNum(pNtkModel) == 0 ) + Start = 1; + else + { + Vec_PtrForEachEntryStart( pNames, pName, i, 1 ) + { + pActual = Io_ReadBlifCleanName(pName); + if ( pActual == NULL ) + { + p->LineCur = (int)pBox->pCopy; + sprintf( p->sError, "Cannot parse formal/actual name pair \"%s\".", pName ); + Io_ReadBlifPrintErrorMessage( p ); + return 1; + } + Length = pActual - pName - 1; + pName[Length] = 0; + // find the PI net with this name + pObj = Abc_NtkFindNet( pNtkModel, pName ); + if ( pObj == NULL ) + { + p->LineCur = (int)pBox->pCopy; + sprintf( p->sError, "Cannot find formal input \"%s\" as an PI of model \"%s\".", pName, Vec_PtrEntry(pNames, 0) ); + Io_ReadBlifPrintErrorMessage( p ); + return 1; + } + // get the PI + pObj = Abc_ObjFanin0(pObj); + // quit if this is not a PI net + if ( !Abc_ObjIsPi(pObj) ) + { + pName[Length] = '='; + Start = i; + break; + } + // remember the actual name in the net + if ( pObj->pCopy != NULL ) + { + p->LineCur = (int)pBox->pCopy; + sprintf( p->sError, "Formal input \"%s\" is used more than once.", pName ); + Io_ReadBlifPrintErrorMessage( p ); + return 1; + } + pObj->pCopy = (void *)pActual; + // quit if we processed all PIs + if ( i == Abc_NtkPiNum(pNtkModel) ) + { + Start = i+1; + break; + } + } + } + // create the fanins of the box + Abc_NtkForEachPi( pNtkModel, pObj, i ) + { + pActual = (void *)pObj->pCopy; + if ( pActual == NULL ) + { + p->LineCur = (int)pBox->pCopy; + sprintf( p->sError, "Formal input \"%s\" of model %s is not driven.", pName, Vec_PtrEntry(pNames, 0) ); + Io_ReadBlifPrintErrorMessage( p ); + return 1; + } + pNet = Abc_NtkFindOrCreateNet( pBox->pNtk, pActual ); + Abc_ObjAddFanin( pBox, pNet ); + } + Abc_NtkForEachPi( pNtkModel, pObj, i ) + pObj->pCopy = NULL; + + // create the fanouts of the box + Abc_NtkForEachPo( pNtkModel, pObj, i ) + pObj->pCopy = NULL; + Vec_PtrForEachEntryStart( pNames, pName, i, Start ) + { + pActual = Io_ReadBlifCleanName(pName); + if ( pActual == NULL ) + { + p->LineCur = (int)pBox->pCopy; + sprintf( p->sError, "Cannot parse formal/actual name pair \"%s\".", pName ); + Io_ReadBlifPrintErrorMessage( p ); + return 1; + } + Length = pActual - pName - 1; + pName[Length] = 0; + // find the PO net with this name + pObj = Abc_NtkFindNet( pNtkModel, pName ); + if ( pObj == NULL ) + { + p->LineCur = (int)pBox->pCopy; + sprintf( p->sError, "Cannot find formal output \"%s\" as an PO of model \"%s\".", pName, Vec_PtrEntry(pNames, 0) ); + Io_ReadBlifPrintErrorMessage( p ); + return 1; + } + // get the PO + pObj = Abc_ObjFanout0(pObj); + if ( pObj->pCopy != NULL ) + { + p->LineCur = (int)pBox->pCopy; + sprintf( p->sError, "Formal output \"%s\" is used more than once.", pName ); + Io_ReadBlifPrintErrorMessage( p ); + return 1; + } + pObj->pCopy = (void *)pActual; + } + // create the fanouts of the box + Abc_NtkForEachPo( pNtkModel, pObj, i ) + { + pActual = (void *)pObj->pCopy; + if ( pActual == NULL ) + { + p->LineCur = (int)pBox->pCopy; + sprintf( p->sError, "Formal output \"%s\" of model %s is not driven.", pName, Vec_PtrEntry(pNames, 0) ); + Io_ReadBlifPrintErrorMessage( p ); + return 1; + } + pNet = Abc_NtkFindOrCreateNet( pBox->pNtk, pActual ); + Abc_ObjAddFanin( pNet, pBox ); + } + Abc_NtkForEachPo( pNtkModel, pObj, i ) + pObj->pCopy = NULL; + + // remove the array of names, assign the pointer to the model + Vec_PtrForEachEntry( pBox->pData, pName, i ) + free( pName ); + Vec_PtrFree( pBox->pData ); + pBox->pData = pNtkModel; + return 0; +} + +/**Function************************************************************* + + Synopsis [Connect the boxes in the hierarchy of networks.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Io_ReadBlifNetworkConnectBoxesOne( Io_ReadBlif_t * p, Abc_Ntk_t * pNtk, stmm_table * tName2Model ) +{ + Abc_Obj_t * pBox; + int i; + // go through the boxes + Abc_NtkForEachBlackbox( pNtk, pBox, i ) + if ( Io_ReadBlifNetworkConnectBoxesOneBox( p, pBox, tName2Model ) ) + return 1; + Abc_NtkFinalizeRead( pNtk ); + return 0; +} + +#if 0 + +/**Function************************************************************* + + Synopsis [Connect the boxes in the hierarchy of networks.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Io_ReadBlifNetworkConnectBoxes( Io_ReadBlif_t * p, Abc_Ntk_t * pNtkMaster ) +{ + stmm_generator * gen; + Abc_Ntk_t * pNtk; + char * pName; + // connect the master network + if ( Io_ReadBlifNetworkConnectBoxesOne( p, pNtkMaster, pNtkMaster->tName2Model ) ) + return 1; + // connect other networks + stmm_foreach_item( pNtkMaster->tName2Model, gen, &pName, (char **)&pNtk ) + if ( Io_ReadBlifNetworkConnectBoxesOne( p, pNtk, pNtkMaster->tName2Model ) ) + return 1; return 0; } +#endif //////////////////////////////////////////////////////////////////////// /// END OF FILE /// |