| /**CFile**************************************************************** |
| |
| FileName [ioReadBlif.c] |
| |
| SystemName [ABC: Logic synthesis and verification system.] |
| |
| PackageName [Command processing package.] |
| |
| Synopsis [Procedures to read BLIF files.] |
| |
| Author [Alan Mishchenko] |
| |
| Affiliation [UC Berkeley] |
| |
| Date [Ver. 1.0. Started - June 20, 2005.] |
| |
| Revision [$Id: ioReadBlif.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] |
| |
| ***********************************************************************/ |
| |
| #include "ioAbc.h" |
| #include "base/main/main.h" |
| #include "map/mio/mio.h" |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// DECLARATIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| typedef struct Io_ReadBlif_t_ Io_ReadBlif_t; // all reading info |
| struct Io_ReadBlif_t_ |
| { |
| // general info about file |
| char * pFileName; // the name of the file |
| Extra_FileReader_t * pReader; // the input file reader |
| // current processing info |
| 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 |
| // timing information |
| Vec_Int_t * vInArrs; // input arrival |
| Vec_Int_t * vOutReqs; // output required |
| Vec_Int_t * vInDrives; // input drive |
| Vec_Int_t * vOutLoads; // output load |
| float DefInArrRise; // input arrival default |
| float DefInArrFall; // input arrival default |
| float DefOutReqRise;// output required default |
| float DefOutReqFall;// output required default |
| float DefInDriRise; // input drive default |
| float DefInDriFall; // input drive default |
| float DefOutLoadRise;// output load default |
| float DefOutLoadFall;// output load default |
| int fHaveDefInArr; // provided in the file |
| int fHaveDefOutReq; // provided in the file |
| int fHaveDefInDri; // provided in the file |
| int fHaveDefOutLoad;// provided in the file |
| // 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 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_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_ReadBlifNetworkOutputRequired( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ); |
| static int Io_ReadBlifNetworkDefaultInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ); |
| static int Io_ReadBlifNetworkDefaultOutputRequired( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ); |
| static int Io_ReadBlifNetworkInputDrive( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ); |
| static int Io_ReadBlifNetworkOutputLoad( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ); |
| static int Io_ReadBlifNetworkDefaultInputDrive( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ); |
| static int Io_ReadBlifNetworkDefaultOutputLoad( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ); |
| static int Io_ReadBlifNetworkAndGateDelay( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ); |
| static int Io_ReadBlifNetworkConnectBoxes( Io_ReadBlif_t * p, Abc_Ntk_t * pNtkMaster ); |
| static int Io_ReadBlifCreateTiming( Io_ReadBlif_t * p, Abc_Ntk_t * pNtkMaster ); |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// FUNCTION DEFINITIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| /**Function************************************************************* |
| |
| Synopsis [Reads the (hierarchical) network from the BLIF file.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Abc_Ntk_t * Io_ReadBlif( char * pFileName, int fCheck ) |
| { |
| Io_ReadBlif_t * p; |
| Abc_Ntk_t * pNtk; |
| |
| // start the file |
| p = Io_ReadBlifFile( pFileName ); |
| if ( p == NULL ) |
| return NULL; |
| |
| // read the hierarchical network |
| pNtk = Io_ReadBlifNetwork( p ); |
| if ( pNtk == NULL ) |
| { |
| Io_ReadBlifFree( p ); |
| return NULL; |
| } |
| pNtk->pSpec = Extra_UtilStrsav( pFileName ); |
| Io_ReadBlifCreateTiming( p, pNtk ); |
| Io_ReadBlifFree( p ); |
| |
| // make sure that everything is okay with the network structure |
| if ( fCheck && !Abc_NtkCheckRead( pNtk ) ) |
| { |
| printf( "Io_ReadBlif: The network check has failed.\n" ); |
| Abc_NtkDelete( pNtk ); |
| return NULL; |
| } |
| return pNtk; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Iteratively reads several networks in the hierarchical design.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Abc_Ntk_t * Io_ReadBlifNetwork( Io_ReadBlif_t * p ) |
| { |
| Abc_Ntk_t * pNtk, * pNtkMaster; |
| |
| // read the name of the master network |
| p->vTokens = Io_ReadBlifGetTokens(p); |
| if ( p->vTokens == NULL || strcmp( (char *)p->vTokens->pArray[0], ".model" ) ) |
| { |
| p->LineCur = 0; |
| sprintf( p->sError, "Wrong input file format." ); |
| Io_ReadBlifPrintErrorMessage( p ); |
| return NULL; |
| } |
| |
| // read networks (with EXDC) |
| pNtkMaster = NULL; |
| while ( p->vTokens ) |
| { |
| // read the network and its EXDC if present |
| pNtk = Io_ReadBlifNetworkOne( p ); |
| if ( pNtk == NULL ) |
| break; |
| if ( p->vTokens && strcmp((char *)p->vTokens->pArray[0], ".exdc") == 0 ) |
| { |
| pNtk->pExdc = Io_ReadBlifNetworkOne( p ); |
| if ( pNtk->pExdc == NULL ) |
| break; |
| Abc_NtkFinalizeRead( pNtk->pExdc ); |
| } |
| // add this network as part of the hierarchy |
| if ( pNtkMaster == NULL ) // no master network so far |
| { |
| p->pNtkMaster = pNtkMaster = pNtk; |
| continue; |
| } |
| /* |
| // 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((int (*)(void))strcmp, (int (*)(void))stmm_strhash); |
| stmm_insert( pNtkMaster->tName2Model, pNtk->pName, (char *)pNtk ); |
| */ |
| } |
| /* |
| // 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 one (main or exdc) network from the BLIF file.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Abc_Ntk_t * Io_ReadBlifNetworkOne( Io_ReadBlif_t * p ) |
| { |
| ProgressBar * pProgress = NULL; |
| 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 ( strcmp( (char *)p->vTokens->pArray[0], ".model" ) == 0 ) |
| { |
| char * pToken, * pPivot; |
| if ( Vec_PtrSize(p->vTokens) != 2 ) |
| { |
| p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); |
| sprintf( p->sError, "The .model line does not have exactly two entries." ); |
| Io_ReadBlifPrintErrorMessage( p ); |
| return NULL; |
| } |
| for ( pPivot = pToken = (char *)Vec_PtrEntry(p->vTokens, 1); *pToken; pToken++ ) |
| if ( *pToken == '/' || *pToken == '\\' ) |
| pPivot = pToken+1; |
| pNtk->pName = Extra_UtilStrsav( pPivot ); |
| } |
| else if ( strcmp( (char *)p->vTokens->pArray[0], ".exdc" ) != 0 ) |
| { |
| printf( "%s: File parsing skipped after line %d (\"%s\").\n", p->pFileName, |
| Extra_FileReaderGetLineNumber(p->pReader, 0), (char*)p->vTokens->pArray[0] ); |
| Abc_NtkDelete(pNtk); |
| p->pNtkCur = NULL; |
| return NULL; |
| } |
| |
| // read the inputs/outputs |
| if ( p->pNtkMaster == NULL ) |
| pProgress = Extra_ProgressBarStart( stdout, Extra_FileReaderGetFileSize(p->pReader) ); |
| fTokensReady = fStatus = 0; |
| for ( iLine = 0; fTokensReady || (p->vTokens = Io_ReadBlifGetTokens(p)); iLine++ ) |
| { |
| if ( p->pNtkMaster == NULL && iLine % 1000 == 0 ) |
| Extra_ProgressBarUpdate( pProgress, Extra_FileReaderGetCurPosition(p->pReader), NULL ); |
| |
| // consider different line types |
| fTokensReady = 0; |
| pDirective = (char *)p->vTokens->pArray[0]; |
| if ( !strcmp( pDirective, ".names" ) ) |
| { fStatus = Io_ReadBlifNetworkNames( p, &p->vTokens ); fTokensReady = 1; } |
| else if ( !strcmp( pDirective, ".gate" ) ) |
| fStatus = Io_ReadBlifNetworkGate( p, p->vTokens ); |
| else if ( !strcmp( pDirective, ".latch" ) ) |
| fStatus = Io_ReadBlifNetworkLatch( p, p->vTokens ); |
| else if ( !strcmp( pDirective, ".inputs" ) ) |
| fStatus = Io_ReadBlifNetworkInputs( p, p->vTokens ); |
| else if ( !strcmp( pDirective, ".outputs" ) ) |
| fStatus = Io_ReadBlifNetworkOutputs( p, p->vTokens ); |
| else if ( !strcmp( pDirective, ".input_arrival" ) ) |
| fStatus = Io_ReadBlifNetworkInputArrival( p, p->vTokens ); |
| else if ( !strcmp( pDirective, ".output_required" ) ) |
| fStatus = Io_ReadBlifNetworkOutputRequired( p, p->vTokens ); |
| else if ( !strcmp( pDirective, ".default_input_arrival" ) ) |
| fStatus = Io_ReadBlifNetworkDefaultInputArrival( p, p->vTokens ); |
| else if ( !strcmp( pDirective, ".default_output_required" ) ) |
| fStatus = Io_ReadBlifNetworkDefaultOutputRequired( p, p->vTokens ); |
| else if ( !strcmp( pDirective, ".input_drive" ) ) |
| fStatus = Io_ReadBlifNetworkInputDrive( p, p->vTokens ); |
| else if ( !strcmp( pDirective, ".output_load" ) ) |
| fStatus = Io_ReadBlifNetworkOutputLoad( p, p->vTokens ); |
| else if ( !strcmp( pDirective, ".default_input_drive" ) ) |
| fStatus = Io_ReadBlifNetworkDefaultInputDrive( p, p->vTokens ); |
| else if ( !strcmp( pDirective, ".default_output_load" ) ) |
| fStatus = Io_ReadBlifNetworkDefaultOutputLoad( p, p->vTokens ); |
| else if ( !strcmp( pDirective, ".and_gate_delay" ) ) |
| fStatus = Io_ReadBlifNetworkAndGateDelay( p, p->vTokens ); |
| // else if ( !strcmp( pDirective, ".subckt" ) ) |
| // fStatus = Io_ReadBlifNetworkSubcircuit( p, p->vTokens ); |
| else if ( !strcmp( pDirective, ".exdc" ) ) |
| 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; |
| Mem_FlexStop( (Mem_Flex_t *)pNtk->pManFunc, 0 ); |
| pNtk->pManFunc = NULL; |
| } |
| else |
| printf( "%s (line %d): Skipping directive \"%s\".\n", p->pFileName, |
| Extra_FileReaderGetLineNumber(p->pReader, 0), pDirective ); |
| 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 ); |
| return pNtk; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Io_ReadBlifNetworkInputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) |
| { |
| int i; |
| for ( i = 1; i < vTokens->nSize; i++ ) |
| Io_ReadCreatePi( p->pNtkCur, (char *)vTokens->pArray[i] ); |
| return 0; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Io_ReadBlifNetworkOutputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) |
| { |
| int i; |
| for ( i = 1; i < vTokens->nSize; i++ ) |
| Io_ReadCreatePo( p->pNtkCur, (char *)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); |
| sprintf( p->sError, "The .latch line does not have enough tokens." ); |
| Io_ReadBlifPrintErrorMessage( p ); |
| return 1; |
| } |
| // create the latch |
| pLatch = Io_ReadCreateLatch( pNtk, (char *)vTokens->pArray[1], (char *)vTokens->pArray[2] ); |
| // get the latch reset value |
| if ( vTokens->nSize == 3 ) |
| Abc_LatchSetInitDc( pLatch ); |
| else |
| { |
| ResetValue = atoi((char *)vTokens->pArray[vTokens->nSize-1]); |
| if ( ResetValue != 0 && ResetValue != 1 && ResetValue != 2 ) |
| { |
| p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); |
| sprintf( p->sError, "The .latch line has an unknown reset value (%s).", (char*)vTokens->pArray[3] ); |
| 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 ); |
| } |
| return 0; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Io_ReadBlifNetworkNames( Io_ReadBlif_t * p, Vec_Ptr_t ** pvTokens ) |
| { |
| Vec_Ptr_t * vTokens = *pvTokens; |
| Abc_Ntk_t * pNtk = p->pNtkCur; |
| Abc_Obj_t * pNode; |
| char * pToken, Char, ** ppNames; |
| int nFanins, nNames; |
| |
| // create a new node and add it to the network |
| if ( vTokens->nSize < 2 ) |
| { |
| p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); |
| sprintf( p->sError, "The .names line has less than two tokens." ); |
| Io_ReadBlifPrintErrorMessage( p ); |
| return 1; |
| } |
| |
| // create the node |
| ppNames = (char **)vTokens->pArray + 1; |
| nNames = vTokens->nSize - 2; |
| pNode = Io_ReadCreateNode( pNtk, ppNames[nNames], ppNames, nNames ); |
| |
| // derive the functionality of the node |
| p->vCubes->nSize = 0; |
| nFanins = vTokens->nSize - 2; |
| if ( nFanins == 0 ) |
| { |
| while ( (vTokens = Io_ReadBlifGetTokens(p)) ) |
| { |
| pToken = (char *)vTokens->pArray[0]; |
| if ( pToken[0] == '.' ) |
| break; |
| // read the cube |
| if ( vTokens->nSize != 1 ) |
| { |
| p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); |
| sprintf( p->sError, "The number of tokens in the constant cube is wrong." ); |
| Io_ReadBlifPrintErrorMessage( p ); |
| return 1; |
| } |
| // create the cube |
| Char = ((char *)vTokens->pArray[0])[0]; |
| Vec_StrPush( p->vCubes, ' ' ); |
| Vec_StrPush( p->vCubes, Char ); |
| Vec_StrPush( p->vCubes, '\n' ); |
| } |
| } |
| else |
| { |
| while ( (vTokens = Io_ReadBlifGetTokens(p)) ) |
| { |
| pToken = (char *)vTokens->pArray[0]; |
| if ( pToken[0] == '.' ) |
| break; |
| // read the cube |
| if ( vTokens->nSize != 2 ) |
| { |
| p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); |
| sprintf( p->sError, "The number of tokens in the cube is wrong." ); |
| Io_ReadBlifPrintErrorMessage( p ); |
| return 1; |
| } |
| // create the cube |
| Vec_StrPrintStr( p->vCubes, (char *)vTokens->pArray[0] ); |
| // check the char |
| Char = ((char *)vTokens->pArray[1])[0]; |
| 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." ); |
| Io_ReadBlifPrintErrorMessage( p ); |
| return 1; |
| } |
| Vec_StrPush( p->vCubes, ' ' ); |
| Vec_StrPush( p->vCubes, Char ); |
| Vec_StrPush( p->vCubes, '\n' ); |
| } |
| } |
| // if there is nothing there |
| if ( p->vCubes->nSize == 0 ) |
| { |
| // create an empty cube |
| Vec_StrPush( p->vCubes, ' ' ); |
| Vec_StrPush( p->vCubes, '0' ); |
| Vec_StrPush( p->vCubes, '\n' ); |
| } |
| Vec_StrPush( p->vCubes, 0 ); |
| |
| // set the pointer to the functionality of the node |
| Abc_ObjSetData( pNode, Abc_SopRegister((Mem_Flex_t *)pNtk->pManFunc, p->vCubes->pArray) ); |
| |
| // check the size |
| if ( Abc_ObjFaninNum(pNode) != Abc_SopGetVarNum((char *)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((char *)Abc_ObjData(pNode)) ); |
| Io_ReadBlifPrintErrorMessage( p ); |
| return 1; |
| } |
| |
| // return the last array of tokens |
| *pvTokens = vTokens; |
| return 0; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Io_ReadBlifReorderFormalNames( Vec_Ptr_t * vTokens, Mio_Gate_t * pGate, Mio_Gate_t * pTwin ) |
| { |
| Mio_Pin_t * pGatePin; |
| char * pName, * pNamePin; |
| int i, k, nSize, Length; |
| nSize = Vec_PtrSize(vTokens); |
| if ( pTwin == NULL ) |
| { |
| if ( nSize - 3 != Mio_GateReadPinNum(pGate) ) |
| return 0; |
| } |
| else |
| { |
| if ( nSize - 3 != Mio_GateReadPinNum(pGate) && nSize - 4 != Mio_GateReadPinNum(pGate) ) |
| return 0; |
| } |
| // check if the names are in order |
| for ( pGatePin = Mio_GateReadPins(pGate), i = 0; pGatePin; pGatePin = Mio_PinReadNext(pGatePin), i++ ) |
| { |
| pNamePin = Mio_PinReadName(pGatePin); |
| Length = strlen(pNamePin); |
| pName = (char *)Vec_PtrEntry(vTokens, i+2); |
| if ( !strncmp( pNamePin, pName, Length ) && pName[Length] == '=' ) |
| continue; |
| break; |
| } |
| if ( pTwin == NULL ) |
| { |
| if ( i == Mio_GateReadPinNum(pGate) ) |
| return 1; |
| // reorder the pins |
| for ( pGatePin = Mio_GateReadPins(pGate), i = 0; pGatePin; pGatePin = Mio_PinReadNext(pGatePin), i++ ) |
| { |
| pNamePin = Mio_PinReadName(pGatePin); |
| Length = strlen(pNamePin); |
| for ( k = 2; k < nSize; k++ ) |
| { |
| pName = (char *)Vec_PtrEntry(vTokens, k); |
| if ( !strncmp( pNamePin, pName, Length ) && pName[Length] == '=' ) |
| { |
| Vec_PtrPush( vTokens, pName ); |
| break; |
| } |
| } |
| } |
| pNamePin = Mio_GateReadOutName(pGate); |
| Length = strlen(pNamePin); |
| for ( k = 2; k < nSize; k++ ) |
| { |
| pName = (char *)Vec_PtrEntry(vTokens, k); |
| if ( !strncmp( pNamePin, pName, Length ) && pName[Length] == '=' ) |
| { |
| Vec_PtrPush( vTokens, pName ); |
| break; |
| } |
| } |
| if ( Vec_PtrSize(vTokens) - nSize != nSize - 2 ) |
| return 0; |
| Vec_PtrForEachEntryStart( char *, vTokens, pName, k, nSize ) |
| Vec_PtrWriteEntry( vTokens, k - nSize + 2, pName ); |
| Vec_PtrShrink( vTokens, nSize ); |
| } |
| else |
| { |
| if ( i != Mio_GateReadPinNum(pGate) ) // expect the correct order of input pins in the network with twin gates |
| return 0; |
| // check the last two entries |
| if ( nSize - 3 == Mio_GateReadPinNum(pGate) ) // only one output is available |
| { |
| pNamePin = Mio_GateReadOutName(pGate); |
| Length = strlen(pNamePin); |
| pName = (char *)Vec_PtrEntry(vTokens, nSize - 1); |
| if ( !strncmp( pNamePin, pName, Length ) && pName[Length] == '=' ) // the last entry is pGate |
| { |
| Vec_PtrPush( vTokens, NULL ); |
| return 1; |
| } |
| pNamePin = Mio_GateReadOutName(pTwin); |
| Length = strlen(pNamePin); |
| pName = (char *)Vec_PtrEntry(vTokens, nSize - 1); |
| if ( !strncmp( pNamePin, pName, Length ) && pName[Length] == '=' ) // the last entry is pTwin |
| { |
| pName = (char *)Vec_PtrPop( vTokens ); |
| Vec_PtrPush( vTokens, NULL ); |
| Vec_PtrPush( vTokens, pName ); |
| return 1; |
| } |
| return 0; |
| } |
| if ( nSize - 4 == Mio_GateReadPinNum(pGate) ) // two outputs are available |
| { |
| pNamePin = Mio_GateReadOutName(pGate); |
| Length = strlen(pNamePin); |
| pName = (char *)Vec_PtrEntry(vTokens, nSize - 2); |
| if ( !(!strncmp( pNamePin, pName, Length ) && pName[Length] == '=') ) |
| return 0; |
| pNamePin = Mio_GateReadOutName(pTwin); |
| Length = strlen(pNamePin); |
| pName = (char *)Vec_PtrEntry(vTokens, nSize - 1); |
| if ( !(!strncmp( pNamePin, pName, Length ) && pName[Length] == '=') ) |
| return 0; |
| return 1; |
| } |
| assert( 0 ); |
| } |
| return 1; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Io_ReadBlifNetworkGate( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) |
| { |
| Mio_Library_t * pGenlib; |
| Mio_Gate_t * pGate; |
| Abc_Obj_t * pNode; |
| char ** ppNames; |
| int i, nNames; |
| |
| // check that the library is available |
| pGenlib = (Mio_Library_t *)Abc_FrameReadLibGen(); |
| if ( pGenlib == NULL ) |
| { |
| p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); |
| sprintf( p->sError, "The current library is not available." ); |
| Io_ReadBlifPrintErrorMessage( p ); |
| return 1; |
| } |
| |
| // create a new node and add it to the network |
| if ( vTokens->nSize < 2 ) |
| { |
| p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); |
| sprintf( p->sError, "The .gate line has less than two tokens." ); |
| Io_ReadBlifPrintErrorMessage( p ); |
| return 1; |
| } |
| |
| // get the gate |
| pGate = Mio_LibraryReadGateByName( pGenlib, (char *)vTokens->pArray[1], NULL ); |
| if ( pGate == NULL ) |
| { |
| p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); |
| sprintf( p->sError, "Cannot find gate \"%s\" in the library.", (char*)vTokens->pArray[1] ); |
| Io_ReadBlifPrintErrorMessage( p ); |
| return 1; |
| } |
| |
| // if this is the first line with gate, update the network type |
| if ( Abc_NtkNodeNum(p->pNtkCur) == 0 ) |
| { |
| assert( p->pNtkCur->ntkFunc == ABC_FUNC_SOP ); |
| p->pNtkCur->ntkFunc = ABC_FUNC_MAP; |
| Mem_FlexStop( (Mem_Flex_t *)p->pNtkCur->pManFunc, 0 ); |
| p->pNtkCur->pManFunc = pGenlib; |
| } |
| |
| // reorder the formal inputs to be in the same order as in the gate |
| if ( !Io_ReadBlifReorderFormalNames( vTokens, pGate, Mio_GateReadTwin(pGate) ) ) |
| { |
| p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); |
| sprintf( p->sError, "Mismatch in the fanins of gate \"%s\".", (char*)vTokens->pArray[1] ); |
| Io_ReadBlifPrintErrorMessage( p ); |
| return 1; |
| } |
| |
| |
| // remove the formal parameter names |
| for ( i = 2; i < vTokens->nSize; i++ ) |
| { |
| vTokens->pArray[i] = Io_ReadBlifCleanName( (char *)vTokens->pArray[i] ); |
| if ( vTokens->pArray[i] == NULL ) |
| { |
| p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); |
| sprintf( p->sError, "Invalid gate input assignment." ); |
| Io_ReadBlifPrintErrorMessage( p ); |
| return 1; |
| } |
| } |
| |
| // create the node |
| if ( Mio_GateReadTwin(pGate) == NULL ) |
| { |
| nNames = vTokens->nSize - 3; |
| ppNames = (char **)vTokens->pArray + 2; |
| pNode = Io_ReadCreateNode( p->pNtkCur, ppNames[nNames], ppNames, nNames ); |
| Abc_ObjSetData( pNode, pGate ); |
| } |
| else |
| { |
| nNames = vTokens->nSize - 4; |
| ppNames = (char **)vTokens->pArray + 2; |
| assert( ppNames[nNames] != NULL || ppNames[nNames+1] != NULL ); |
| if ( ppNames[nNames] ) |
| { |
| pNode = Io_ReadCreateNode( p->pNtkCur, ppNames[nNames], ppNames, nNames ); |
| Abc_ObjSetData( pNode, pGate ); |
| } |
| if ( ppNames[nNames+1] ) |
| { |
| pNode = Io_ReadCreateNode( p->pNtkCur, ppNames[nNames+1], ppNames, nNames ); |
| Abc_ObjSetData( pNode, Mio_GateReadTwin(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( char *, 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 = (Abc_Obj_t *)(ABC_PTRINT_T)Extra_FileReaderGetLineNumber(p->pReader, 0); |
| return 0; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| char * Io_ReadBlifCleanName( char * pName ) |
| { |
| int i, Length; |
| Length = strlen(pName); |
| for ( i = 0; i < Length; i++ ) |
| if ( pName[i] == '=' ) |
| return pName + i + 1; |
| return NULL; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Io_ReadBlifNetworkInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) |
| { |
| Abc_Obj_t * pNet; |
| char * pFoo1, * pFoo2; |
| double TimeRise, TimeFall; |
| |
| // make sure this is indeed the .inputs line |
| assert( strncmp( (char *)vTokens->pArray[0], ".input_arrival", 14 ) == 0 ); |
| if ( vTokens->nSize != 4 ) |
| { |
| p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); |
| sprintf( p->sError, "Wrong number of arguments on .input_arrival line." ); |
| Io_ReadBlifPrintErrorMessage( p ); |
| return 1; |
| } |
| pNet = Abc_NtkFindNet( p->pNtkCur, (char *)vTokens->pArray[1] ); |
| if ( pNet == NULL ) |
| { |
| p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); |
| sprintf( p->sError, "Cannot find object corresponding to %s on .input_arrival line.", (char*)vTokens->pArray[1] ); |
| Io_ReadBlifPrintErrorMessage( p ); |
| return 1; |
| } |
| TimeRise = strtod( (char *)vTokens->pArray[2], &pFoo1 ); |
| TimeFall = strtod( (char *)vTokens->pArray[3], &pFoo2 ); |
| if ( *pFoo1 != '\0' || *pFoo2 != '\0' ) |
| { |
| p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); |
| sprintf( p->sError, "Bad value (%s %s) for rise or fall time on .input_arrival line.", (char*)vTokens->pArray[2], (char*)vTokens->pArray[3] ); |
| Io_ReadBlifPrintErrorMessage( p ); |
| return 1; |
| } |
| // set timing info |
| //Abc_NtkTimeSetArrival( p->pNtkCur, Abc_ObjFanin0(pNet)->Id, (float)TimeRise, (float)TimeFall ); |
| Vec_IntPush( p->vInArrs, Abc_ObjFanin0(pNet)->Id ); |
| Vec_IntPush( p->vInArrs, Abc_Float2Int((float)TimeRise) ); |
| Vec_IntPush( p->vInArrs, Abc_Float2Int((float)TimeFall) ); |
| return 0; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Io_ReadBlifNetworkOutputRequired( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) |
| { |
| Abc_Obj_t * pNet; |
| char * pFoo1, * pFoo2; |
| double TimeRise, TimeFall; |
| |
| // make sure this is indeed the .inputs line |
| assert( strncmp( (char *)vTokens->pArray[0], ".output_required", 16 ) == 0 ); |
| if ( vTokens->nSize != 4 ) |
| { |
| p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); |
| sprintf( p->sError, "Wrong number of arguments on .output_required line." ); |
| Io_ReadBlifPrintErrorMessage( p ); |
| return 1; |
| } |
| pNet = Abc_NtkFindNet( p->pNtkCur, (char *)vTokens->pArray[1] ); |
| if ( pNet == NULL ) |
| { |
| p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); |
| sprintf( p->sError, "Cannot find object corresponding to %s on .output_required line.", (char*)vTokens->pArray[1] ); |
| Io_ReadBlifPrintErrorMessage( p ); |
| return 1; |
| } |
| TimeRise = strtod( (char *)vTokens->pArray[2], &pFoo1 ); |
| TimeFall = strtod( (char *)vTokens->pArray[3], &pFoo2 ); |
| if ( *pFoo1 != '\0' || *pFoo2 != '\0' ) |
| { |
| p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); |
| sprintf( p->sError, "Bad value (%s %s) for rise or fall time on .output_required line.", (char*)vTokens->pArray[2], (char*)vTokens->pArray[3] ); |
| Io_ReadBlifPrintErrorMessage( p ); |
| return 1; |
| } |
| // set timing info |
| // Abc_NtkTimeSetRequired( p->pNtkCur, Abc_ObjFanout0(pNet)->Id, (float)TimeRise, (float)TimeFall ); |
| Vec_IntPush( p->vOutReqs, Abc_ObjFanout0(pNet)->Id ); |
| Vec_IntPush( p->vOutReqs, Abc_Float2Int((float)TimeRise) ); |
| Vec_IntPush( p->vOutReqs, Abc_Float2Int((float)TimeFall) ); |
| return 0; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Io_ReadBlifNetworkDefaultInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) |
| { |
| char * pFoo1, * pFoo2; |
| double TimeRise, TimeFall; |
| |
| // make sure this is indeed the .inputs line |
| assert( strncmp( (char *)vTokens->pArray[0], ".default_input_arrival", 23 ) == 0 ); |
| if ( vTokens->nSize != 3 ) |
| { |
| p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); |
| sprintf( p->sError, "Wrong number of arguments on .default_input_arrival line." ); |
| Io_ReadBlifPrintErrorMessage( p ); |
| return 1; |
| } |
| TimeRise = strtod( (char *)vTokens->pArray[1], &pFoo1 ); |
| TimeFall = strtod( (char *)vTokens->pArray[2], &pFoo2 ); |
| if ( *pFoo1 != '\0' || *pFoo2 != '\0' ) |
| { |
| p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); |
| sprintf( p->sError, "Bad value (%s %s) for rise or fall time on .default_input_arrival line.", (char*)vTokens->pArray[1], (char*)vTokens->pArray[2] ); |
| Io_ReadBlifPrintErrorMessage( p ); |
| return 1; |
| } |
| // set timing info |
| //Abc_NtkTimeSetDefaultArrival( p->pNtkCur, (float)TimeRise, (float)TimeFall ); |
| p->DefInArrRise = (float)TimeRise; |
| p->DefInArrFall = (float)TimeFall; |
| p->fHaveDefInArr = 1; |
| return 0; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Io_ReadBlifNetworkDefaultOutputRequired( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) |
| { |
| char * pFoo1, * pFoo2; |
| double TimeRise, TimeFall; |
| |
| // make sure this is indeed the .inputs line |
| assert( strncmp( (char *)vTokens->pArray[0], ".default_output_required", 25 ) == 0 ); |
| if ( vTokens->nSize != 3 ) |
| { |
| p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); |
| sprintf( p->sError, "Wrong number of arguments on .default_output_required line." ); |
| Io_ReadBlifPrintErrorMessage( p ); |
| return 1; |
| } |
| TimeRise = strtod( (char *)vTokens->pArray[1], &pFoo1 ); |
| TimeFall = strtod( (char *)vTokens->pArray[2], &pFoo2 ); |
| if ( *pFoo1 != '\0' || *pFoo2 != '\0' ) |
| { |
| p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); |
| sprintf( p->sError, "Bad value (%s %s) for rise or fall time on .default_output_required line.", (char*)vTokens->pArray[1], (char*)vTokens->pArray[2] ); |
| Io_ReadBlifPrintErrorMessage( p ); |
| return 1; |
| } |
| // set timing info |
| // Abc_NtkTimeSetDefaultRequired( p->pNtkCur, (float)TimeRise, (float)TimeFall ); |
| p->DefOutReqRise = (float)TimeRise; |
| p->DefOutReqFall = (float)TimeFall; |
| p->fHaveDefOutReq = 1; |
| return 0; |
| } |
| |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Io_ReadFindCiId( Abc_Ntk_t * pNtk, Abc_Obj_t * pObj ) |
| { |
| Abc_Obj_t * pTemp; |
| int i; |
| Abc_NtkForEachCi( pNtk, pTemp, i ) |
| if ( pTemp == pObj ) |
| return i; |
| return -1; |
| } |
| int Io_ReadBlifNetworkInputDrive( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) |
| { |
| Abc_Obj_t * pNet; |
| char * pFoo1, * pFoo2; |
| double TimeRise, TimeFall; |
| |
| // make sure this is indeed the .inputs line |
| assert( strncmp( (char *)vTokens->pArray[0], ".input_drive", 12 ) == 0 ); |
| if ( vTokens->nSize != 4 ) |
| { |
| p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); |
| sprintf( p->sError, "Wrong number of arguments on .input_drive line." ); |
| Io_ReadBlifPrintErrorMessage( p ); |
| return 1; |
| } |
| pNet = Abc_NtkFindNet( p->pNtkCur, (char *)vTokens->pArray[1] ); |
| if ( pNet == NULL ) |
| { |
| p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); |
| sprintf( p->sError, "Cannot find object corresponding to %s on .input_drive line.", (char*)vTokens->pArray[1] ); |
| Io_ReadBlifPrintErrorMessage( p ); |
| return 1; |
| } |
| TimeRise = strtod( (char *)vTokens->pArray[2], &pFoo1 ); |
| TimeFall = strtod( (char *)vTokens->pArray[3], &pFoo2 ); |
| if ( *pFoo1 != '\0' || *pFoo2 != '\0' ) |
| { |
| p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); |
| sprintf( p->sError, "Bad value (%s %s) for rise or fall time on .input_drive line.", (char*)vTokens->pArray[2], (char*)vTokens->pArray[3] ); |
| Io_ReadBlifPrintErrorMessage( p ); |
| return 1; |
| } |
| // set timing info |
| //Abc_NtkTimeSetInputDrive( p->pNtkCur, Io_ReadFindCiId(p->pNtkCur, Abc_NtkObj(p->pNtkCur, Abc_ObjFanin0(pNet)->Id)), (float)TimeRise, (float)TimeFall ); |
| Vec_IntPush( p->vInDrives, Io_ReadFindCiId(p->pNtkCur, Abc_NtkObj(p->pNtkCur, Abc_ObjFanin0(pNet)->Id)) ); |
| Vec_IntPush( p->vInDrives, Abc_Float2Int((float)TimeRise) ); |
| Vec_IntPush( p->vInDrives, Abc_Float2Int((float)TimeFall) ); |
| return 0; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Io_ReadFindCoId( Abc_Ntk_t * pNtk, Abc_Obj_t * pObj ) |
| { |
| Abc_Obj_t * pTemp; |
| int i; |
| Abc_NtkForEachPo( pNtk, pTemp, i ) |
| if ( pTemp == pObj ) |
| return i; |
| return -1; |
| } |
| int Io_ReadBlifNetworkOutputLoad( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) |
| { |
| Abc_Obj_t * pNet; |
| char * pFoo1, * pFoo2; |
| double TimeRise, TimeFall; |
| |
| // make sure this is indeed the .inputs line |
| assert( strncmp( (char *)vTokens->pArray[0], ".output_load", 12 ) == 0 ); |
| if ( vTokens->nSize != 4 ) |
| { |
| p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); |
| sprintf( p->sError, "Wrong number of arguments on .output_load line." ); |
| Io_ReadBlifPrintErrorMessage( p ); |
| return 1; |
| } |
| pNet = Abc_NtkFindNet( p->pNtkCur, (char *)vTokens->pArray[1] ); |
| if ( pNet == NULL ) |
| { |
| p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); |
| sprintf( p->sError, "Cannot find object corresponding to %s on .output_load line.", (char*)vTokens->pArray[1] ); |
| Io_ReadBlifPrintErrorMessage( p ); |
| return 1; |
| } |
| TimeRise = strtod( (char *)vTokens->pArray[2], &pFoo1 ); |
| TimeFall = strtod( (char *)vTokens->pArray[3], &pFoo2 ); |
| if ( *pFoo1 != '\0' || *pFoo2 != '\0' ) |
| { |
| p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); |
| sprintf( p->sError, "Bad value (%s %s) for rise or fall time on .output_load line.", (char*)vTokens->pArray[2], (char*)vTokens->pArray[3] ); |
| Io_ReadBlifPrintErrorMessage( p ); |
| return 1; |
| } |
| // set timing info |
| // Abc_NtkTimeSetOutputLoad( p->pNtkCur, Io_ReadFindCoId(p->pNtkCur, Abc_NtkObj(p->pNtkCur, Abc_ObjFanout0(pNet)->Id)), (float)TimeRise, (float)TimeFall ); |
| Vec_IntPush( p->vOutLoads, Io_ReadFindCoId(p->pNtkCur, Abc_NtkObj(p->pNtkCur, Abc_ObjFanout0(pNet)->Id)) ); |
| Vec_IntPush( p->vOutLoads, Abc_Float2Int((float)TimeRise) ); |
| Vec_IntPush( p->vOutLoads, Abc_Float2Int((float)TimeFall) ); |
| return 0; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Io_ReadBlifNetworkDefaultInputDrive( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) |
| { |
| char * pFoo1, * pFoo2; |
| double TimeRise, TimeFall; |
| |
| // make sure this is indeed the .inputs line |
| assert( strncmp( (char *)vTokens->pArray[0], ".default_input_drive", 21 ) == 0 ); |
| if ( vTokens->nSize != 3 ) |
| { |
| p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); |
| sprintf( p->sError, "Wrong number of arguments on .default_input_drive line." ); |
| Io_ReadBlifPrintErrorMessage( p ); |
| return 1; |
| } |
| TimeRise = strtod( (char *)vTokens->pArray[1], &pFoo1 ); |
| TimeFall = strtod( (char *)vTokens->pArray[2], &pFoo2 ); |
| if ( *pFoo1 != '\0' || *pFoo2 != '\0' ) |
| { |
| p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); |
| sprintf( p->sError, "Bad value (%s %s) for rise or fall time on .default_input_drive line.", (char*)vTokens->pArray[1], (char*)vTokens->pArray[2] ); |
| Io_ReadBlifPrintErrorMessage( p ); |
| return 1; |
| } |
| // set timing info |
| // Abc_NtkTimeSetDefaultInputDrive( p->pNtkCur, (float)TimeRise, (float)TimeFall ); |
| p->DefInDriRise = (float)TimeRise; |
| p->DefInDriFall = (float)TimeFall; |
| p->fHaveDefInDri = 1; |
| return 0; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Io_ReadBlifNetworkDefaultOutputLoad( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) |
| { |
| char * pFoo1, * pFoo2; |
| double TimeRise, TimeFall; |
| |
| // make sure this is indeed the .inputs line |
| assert( strncmp( (char *)vTokens->pArray[0], ".default_output_load", 21 ) == 0 ); |
| if ( vTokens->nSize != 3 ) |
| { |
| p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); |
| sprintf( p->sError, "Wrong number of arguments on .default_output_load line." ); |
| Io_ReadBlifPrintErrorMessage( p ); |
| return 1; |
| } |
| TimeRise = strtod( (char *)vTokens->pArray[1], &pFoo1 ); |
| TimeFall = strtod( (char *)vTokens->pArray[2], &pFoo2 ); |
| if ( *pFoo1 != '\0' || *pFoo2 != '\0' ) |
| { |
| p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); |
| sprintf( p->sError, "Bad value (%s %s) for rise or fall time on .default_output_load line.", (char*)vTokens->pArray[1], (char*)vTokens->pArray[2] ); |
| Io_ReadBlifPrintErrorMessage( p ); |
| return 1; |
| } |
| // set timing info |
| // Abc_NtkTimeSetDefaultOutputLoad( p->pNtkCur, (float)TimeRise, (float)TimeFall ); |
| p->DefOutLoadRise = (float)TimeRise; |
| p->DefOutLoadFall = (float)TimeFall; |
| p->fHaveDefOutLoad = 1; |
| return 0; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Io_ReadBlifNetworkAndGateDelay( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) |
| { |
| char * pFoo1; |
| double AndGateDelay; |
| |
| // make sure this is indeed the .inputs line |
| assert( strncmp( (char *)vTokens->pArray[0], ".and_gate_delay", 25 ) == 0 ); |
| if ( vTokens->nSize != 2 ) |
| { |
| p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); |
| sprintf( p->sError, "Wrong number of arguments (%d) on .and_gate_delay line (should be 1).", vTokens->nSize-1 ); |
| Io_ReadBlifPrintErrorMessage( p ); |
| return 1; |
| } |
| AndGateDelay = strtod( (char *)vTokens->pArray[1], &pFoo1 ); |
| if ( *pFoo1 != '\0' ) |
| { |
| p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); |
| sprintf( p->sError, "Bad value (%s) for AND gate delay in on .and_gate_delay line line.", (char*)vTokens->pArray[1] ); |
| Io_ReadBlifPrintErrorMessage( p ); |
| return 1; |
| } |
| // set timing info |
| p->pNtkCur->AndGateDelay = (float)AndGateDelay; |
| 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++ ) |
| ABC_FREE( p->vNewTokens->pArray[i] ); |
| p->vNewTokens->nSize = 0; |
| } |
| |
| // get the new tokens |
| vTokens = (Vec_Ptr_t *)Extra_FileReaderGetTokens(p->pReader); |
| if ( vTokens == NULL ) |
| return vTokens; |
| |
| // check if there is a transfer to another line |
| pLastToken = (char *)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((char *)vTokens->pArray[i]) ); |
| |
| // load as long as there is the line break |
| while ( 1 ) |
| { |
| // get the new tokens |
| vTokens = (Vec_Ptr_t *)Extra_FileReaderGetTokens(p->pReader); |
| if ( vTokens->nSize == 0 ) |
| return p->vNewTokens; |
| // check if there is a transfer to another line |
| pLastToken = (char *)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((char *)vTokens->pArray[i]) ); |
| continue; |
| } |
| // otherwise, load them and break |
| for ( i = 0; i < vTokens->nSize; i++ ) |
| Vec_PtrPush( p->vNewTokens, Extra_UtilStrsav((char *)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 = ABC_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 ); |
| p->vInArrs = Vec_IntAlloc( 100 ); |
| p->vOutReqs = Vec_IntAlloc( 100 ); |
| p->vInDrives = Vec_IntAlloc( 100 ); |
| p->vOutLoads = Vec_IntAlloc( 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 ); |
| Vec_IntFree( p->vInArrs ); |
| Vec_IntFree( p->vOutReqs ); |
| Vec_IntFree( p->vInDrives ); |
| Vec_IntFree( p->vOutLoads ); |
| ABC_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 = NULL, * pActual; |
| int i, Length, Start = -1; |
| |
| // get the model for this box |
| pNames = (Vec_Ptr_t *)pBox->pData; |
| if ( !stmm_lookup( tName2Model, (char *)Vec_PtrEntry(pNames, 0), (char **)&pNtkModel ) ) |
| { |
| p->LineCur = (int)(ABC_PTRINT_T)pBox->pCopy; |
| sprintf( p->sError, "Cannot find the model for subcircuit %s.", (char*)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( char *, pNames, pName, i, 1 ) |
| { |
| pActual = Io_ReadBlifCleanName(pName); |
| if ( pActual == NULL ) |
| { |
| p->LineCur = (int)(ABC_PTRINT_T)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)(ABC_PTRINT_T)pBox->pCopy; |
| sprintf( p->sError, "Cannot find formal input \"%s\" as an PI of model \"%s\".", pName, (char*)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)(ABC_PTRINT_T)pBox->pCopy; |
| sprintf( p->sError, "Formal input \"%s\" is used more than once.", pName ); |
| Io_ReadBlifPrintErrorMessage( p ); |
| return 1; |
| } |
| pObj->pCopy = (Abc_Obj_t *)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 = (char *)pObj->pCopy; |
| if ( pActual == NULL ) |
| { |
| p->LineCur = (int)(ABC_PTRINT_T)pBox->pCopy; |
| sprintf( p->sError, "Formal input \"%s\" of model %s is not driven.", pName, (char*)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( char *, pNames, pName, i, Start ) |
| { |
| pActual = Io_ReadBlifCleanName(pName); |
| if ( pActual == NULL ) |
| { |
| p->LineCur = (int)(ABC_PTRINT_T)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)(ABC_PTRINT_T)pBox->pCopy; |
| sprintf( p->sError, "Cannot find formal output \"%s\" as an PO of model \"%s\".", pName, (char*)Vec_PtrEntry(pNames, 0) ); |
| Io_ReadBlifPrintErrorMessage( p ); |
| return 1; |
| } |
| // get the PO |
| pObj = Abc_ObjFanout0(pObj); |
| if ( pObj->pCopy != NULL ) |
| { |
| p->LineCur = (int)(ABC_PTRINT_T)pBox->pCopy; |
| sprintf( p->sError, "Formal output \"%s\" is used more than once.", pName ); |
| Io_ReadBlifPrintErrorMessage( p ); |
| return 1; |
| } |
| pObj->pCopy = (Abc_Obj_t *)pActual; |
| } |
| // create the fanouts of the box |
| Abc_NtkForEachPo( pNtkModel, pObj, i ) |
| { |
| pActual = (char *)pObj->pCopy; |
| if ( pActual == NULL ) |
| { |
| p->LineCur = (int)(ABC_PTRINT_T)pBox->pCopy; |
| sprintf( p->sError, "Formal output \"%s\" of model %s is not driven.", pName, (char*)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( char *, (Vec_Ptr_t *)pBox->pData, pName, i ) |
| ABC_FREE( pName ); |
| Vec_PtrFree( (Vec_Ptr_t *)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; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Creates timing manager.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Io_ReadBlifCreateTiming( Io_ReadBlif_t * p, Abc_Ntk_t * pNtk ) |
| { |
| int Id, Rise, Fall, i; |
| |
| // set timing info |
| //Abc_NtkTimeSetDefaultArrival( p->pNtkCur, (float)TimeRise, (float)TimeFall ); |
| // p->DefInArrRise = (float)TimeRise; |
| // p->DefInArrFall = (float)TimeFall; |
| if ( p->fHaveDefInArr ) |
| Abc_NtkTimeSetDefaultArrival( pNtk, p->DefInArrRise, p->DefInArrFall ); |
| // set timing info |
| //Abc_NtkTimeSetDefaultRequired( p->pNtkCur, (float)TimeRise, (float)TimeFall ); |
| // p->DefOutReqRise = (float)TimeRise; |
| // p->DefOutReqFall = (float)TimeFall; |
| if ( p->fHaveDefOutReq ) |
| Abc_NtkTimeSetDefaultRequired( pNtk, p->DefOutReqRise, p->DefOutReqFall ); |
| // set timing info |
| //Abc_NtkTimeSetDefaultInputDrive( p->pNtkCur, (float)TimeRise, (float)TimeFall ); |
| // p->DefInDriRise = (float)TimeRise; |
| // p->DefInDriFall = (float)TimeFall; |
| if ( p->fHaveDefInDri ) |
| Abc_NtkTimeSetDefaultInputDrive( pNtk, p->DefInDriRise, p->DefInDriFall ); |
| // set timing info |
| //Abc_NtkTimeSetDefaultOutputLoad( p->pNtkCur, (float)TimeRise, (float)TimeFall ); |
| // p->DefOutLoadRise = (float)TimeRise; |
| // p->DefOutLoadFall = (float)TimeFall; |
| if ( p->fHaveDefOutLoad ) |
| Abc_NtkTimeSetDefaultOutputLoad( pNtk, p->DefOutLoadRise, p->DefOutLoadFall ); |
| |
| // set timing info |
| //Abc_NtkTimeSetArrival( p->pNtkCur, Abc_ObjFanin0(pNet)->Id, (float)TimeRise, (float)TimeFall ); |
| // Vec_IntPush( p->vInArrs, Abc_ObjFanin0(pNet)->Id ); |
| // Vec_IntPush( p->vInArrs, Abc_Float2Int((float)TimeRise) ); |
| // Vec_IntPush( p->vInArrs, Abc_Float2Int((float)TimeFall) ); |
| Vec_IntForEachEntryTriple( p->vInArrs, Id, Rise, Fall, i ) |
| Abc_NtkTimeSetArrival( pNtk, Id, Abc_Int2Float(Rise), Abc_Int2Float(Fall) ); |
| // set timing info |
| //Abc_NtkTimeSetRequired( p->pNtkCur, Abc_ObjFanout0(pNet)->Id, (float)TimeRise, (float)TimeFall ); |
| // Vec_IntPush( p->vOutReqs, Abc_ObjFanout0(pNet)->Id ); |
| // Vec_IntPush( p->vOutReqs, Abc_Float2Int((float)TimeRise) ); |
| // Vec_IntPush( p->vOutReqs, Abc_Float2Int((float)TimeFall) ); |
| Vec_IntForEachEntryTriple( p->vOutReqs, Id, Rise, Fall, i ) |
| Abc_NtkTimeSetRequired( pNtk, Id, Abc_Int2Float(Rise), Abc_Int2Float(Fall) ); |
| // set timing info |
| //Abc_NtkTimeSetInputDrive( p->pNtkCur, Io_ReadFindCiId(p->pNtkCur, Abc_NtkObj(p->pNtkCur, Abc_ObjFanin0(pNet)->Id)), (float)TimeRise, (float)TimeFall ); |
| // Vec_IntPush( p->vInDrives, Io_ReadFindCiId(p->pNtkCur, Abc_NtkObj(p->pNtkCur, Abc_ObjFanin0(pNet)->Id)) ); |
| // Vec_IntPush( p->vInDrives, Abc_Float2Int((float)TimeRise) ); |
| // Vec_IntPush( p->vInDrives, Abc_Float2Int((float)TimeFall) ); |
| Vec_IntForEachEntryTriple( p->vInDrives, Id, Rise, Fall, i ) |
| Abc_NtkTimeSetInputDrive( pNtk, Id, Abc_Int2Float(Rise), Abc_Int2Float(Fall) ); |
| // set timing info |
| //Abc_NtkTimeSetOutputLoad( p->pNtkCur, Io_ReadFindCoId(p->pNtkCur, Abc_NtkObj(p->pNtkCur, Abc_ObjFanout0(pNet)->Id)), (float)TimeRise, (float)TimeFall ); |
| // Vec_IntPush( p->vOutLoads, Io_ReadFindCoId(p->pNtkCur, Abc_NtkObj(p->pNtkCur, Abc_ObjFanout0(pNet)->Id)) ); |
| // Vec_IntPush( p->vOutLoads, Abc_Float2Int((float)TimeRise) ); |
| // Vec_IntPush( p->vOutLoads, Abc_Float2Int((float)TimeFall) ); |
| Vec_IntForEachEntryTriple( p->vOutLoads, Id, Rise, Fall, i ) |
| Abc_NtkTimeSetOutputLoad( pNtk, Id, Abc_Int2Float(Rise), Abc_Int2Float(Fall) ); |
| return 1; |
| } |
| |
| #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 /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| ABC_NAMESPACE_IMPL_END |
| |