diff options
Diffstat (limited to 'src/base')
-rw-r--r-- | src/base/abc/abc.h | 13 | ||||
-rw-r--r-- | src/base/abc/abcAig.c | 98 | ||||
-rw-r--r-- | src/base/abc/abcHie.c | 294 | ||||
-rw-r--r-- | src/base/abc/abcLib.c | 27 | ||||
-rw-r--r-- | src/base/abc/abcNtk.c | 19 | ||||
-rw-r--r-- | src/base/abci/abc.c | 18 | ||||
-rw-r--r-- | src/base/abci/abcIvy.c | 4 | ||||
-rw-r--r-- | src/base/abci/abcPlace.c | 253 | ||||
-rw-r--r-- | src/base/abci/abcProve.c | 8 | ||||
-rw-r--r-- | src/base/abci/abcRewrite.c | 86 | ||||
-rw-r--r-- | src/base/abci/module.make | 1 | ||||
-rw-r--r-- | src/base/io/io.c | 62 | ||||
-rw-r--r-- | src/base/io/io.h | 1 | ||||
-rw-r--r-- | src/base/io/ioReadBlifMv.c | 5 | ||||
-rw-r--r-- | src/base/io/ioReadVerilog.c | 11 | ||||
-rw-r--r-- | src/base/io/ioUtil.c | 73 | ||||
-rw-r--r-- | src/base/io/ioWriteAiger.c | 2 | ||||
-rw-r--r-- | src/base/io/ioWriteBlif.c | 46 | ||||
-rw-r--r-- | src/base/io/ioWriteBlifMv.c | 2 | ||||
-rw-r--r-- | src/base/ver/verCore.c | 56 | ||||
-rw-r--r-- | src/base/ver/verStream.c | 23 |
21 files changed, 938 insertions, 164 deletions
diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h index e15ca557..d19fbcef 100644 --- a/src/base/abc/abc.h +++ b/src/base/abc/abc.h @@ -116,12 +116,17 @@ typedef enum { #endif #endif +#ifndef SINT64 +#define SINT64 + #ifdef _WIN32 typedef signed __int64 sint64; // compatible with MS VS 6.0 #else typedef long long sint64; #endif +#endif + typedef struct Abc_Lib_t_ Abc_Lib_t; typedef struct Abc_Ntk_t_ Abc_Ntk_t; typedef struct Abc_Obj_t_ Abc_Obj_t; @@ -204,6 +209,7 @@ struct Abc_Ntk_t_ int * pModel; // counter-example (for miters) Abc_Ntk_t * pExdc; // the EXDC network (if given) void * pData; // misc + Abc_Ntk_t * pCopy; // node attributes Vec_Ptr_t * vAttrs; // managers of various node attributes (node functionality, global BDDs, etc) }; @@ -521,6 +527,11 @@ extern void Abc_AigPrintNode( Abc_Obj_t * pNode ); extern bool Abc_AigNodeIsAcyclic( Abc_Obj_t * pNode, Abc_Obj_t * pRoot ); extern void Abc_AigCheckFaninOrder( Abc_Aig_t * pMan ); extern void Abc_AigSetNodePhases( Abc_Ntk_t * pNtk ); +extern Vec_Ptr_t * Abc_AigUpdateStart( Abc_Aig_t * pMan ); +extern void Abc_AigUpdateStop( Abc_Aig_t * pMan ); +extern void Abc_AigUpdateReset( Abc_Aig_t * pMan ); +extern void Abc_AigUpdateAdd( Abc_Aig_t * pMan, Abc_Obj_t * pObj ); +extern Vec_Ptr_t * Abc_AigUpdateRead( Abc_Aig_t * pMan ); /*=== abcAttach.c ==========================================================*/ extern int Abc_NtkAttach( Abc_Ntk_t * pNtk ); /*=== abcBalance.c ==========================================================*/ @@ -733,7 +744,7 @@ extern int Abc_NodeRef_rec( Abc_Obj_t * pNode ); /*=== abcRefactor.c ==========================================================*/ extern int Abc_NtkRefactor( Abc_Ntk_t * pNtk, int nNodeSizeMax, int nConeSizeMax, bool fUpdateLevel, bool fUseZeros, bool fUseDcs, bool fVerbose ); /*=== abcRewrite.c ==========================================================*/ -extern int Abc_NtkRewrite( Abc_Ntk_t * pNtk, int fUpdateLevel, int fUseZeros, int fVerbose, int fVeryVerbose ); +extern int Abc_NtkRewrite( Abc_Ntk_t * pNtk, int fUpdateLevel, int fUseZeros, int fVerbose, int fVeryVerbose, int fPlaceEnable ); /*=== abcSat.c ==========================================================*/ extern int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, sint64 nConfLimit, sint64 nInsLimit, int fVerbose, sint64 * pNumConfs, sint64 * pNumInspects ); extern void * Abc_NtkMiterSatCreate( Abc_Ntk_t * pNtk, int fAllPrimes ); diff --git a/src/base/abc/abcAig.c b/src/base/abc/abcAig.c index 1761e10e..c92f3b57 100644 --- a/src/base/abc/abcAig.c +++ b/src/base/abc/abcAig.c @@ -59,6 +59,7 @@ struct Abc_Aig_t_ Vec_Ptr_t * vStackReplaceNew; // the nodes to be used for replacement Vec_Vec_t * vLevels; // the nodes to be updated Vec_Vec_t * vLevelsR; // the nodes to be updated + Vec_Ptr_t * vUpdates; // the added and removed nodes int nStrash0; int nStrash1; @@ -162,6 +163,8 @@ void Abc_AigFree( Abc_Aig_t * pMan ) assert( Vec_PtrSize( pMan->vStackReplaceOld ) == 0 ); assert( Vec_PtrSize( pMan->vStackReplaceNew ) == 0 ); // free the table + if ( pMan->vUpdates ) + Vec_PtrFree( pMan->vUpdates ); Vec_VecFree( pMan->vLevels ); Vec_VecFree( pMan->vLevelsR ); Vec_PtrFree( pMan->vStackReplaceOld ); @@ -322,6 +325,9 @@ Abc_Obj_t * Abc_AigAndCreate( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 ) // if ( pAnd->pNtk->pManCut ) // Abc_NodeGetCuts( pAnd->pNtk->pManCut, pAnd ); pAnd->pCopy = NULL; + // add the node to the list of updated nodes + if ( pMan->vUpdates ) + Vec_PtrPush( pMan->vUpdates, pAnd ); return pAnd; } @@ -359,6 +365,9 @@ Abc_Obj_t * Abc_AigAndCreateFrom( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * // if ( pAnd->pNtk->pManCut ) // Abc_NodeGetCuts( pAnd->pNtk->pManCut, pAnd ); pAnd->pCopy = NULL; + // add the node to the list of updated nodes + if ( pMan->vUpdates ) + Vec_PtrPush( pMan->vUpdates, pAnd ); return pAnd; } @@ -539,6 +548,9 @@ void Abc_AigAndDelete( Abc_Aig_t * pMan, Abc_Obj_t * pThis ) // delete the cuts if defined if ( pThis->pNtk->pManCut ) Abc_NodeFreeCuts( pThis->pNtk->pManCut, pThis ); + // add the node to the list of updated nodes + if ( pMan->vUpdates ) + Vec_PtrPush( pMan->vUpdates, pThis ); } /**Function************************************************************* @@ -1343,6 +1355,92 @@ void Abc_AigSetNodePhases( Abc_Ntk_t * pNtk ) pObj->fPhase = (Abc_ObjFanin0(pObj)->fPhase ^ Abc_ObjFaninC0(pObj)); } + + +/**Function************************************************************* + + Synopsis [Start the update list.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Abc_AigUpdateStart( Abc_Aig_t * pMan ) +{ + assert( pMan->vUpdates == NULL ); + return pMan->vUpdates = Vec_PtrAlloc( 1000 ); +} + +/**Function************************************************************* + + Synopsis [Start the update list.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_AigUpdateStop( Abc_Aig_t * pMan ) +{ + assert( pMan->vUpdates != NULL ); + Vec_PtrFree( pMan->vUpdates ); +} + +/**Function************************************************************* + + Synopsis [Start the update list.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_AigUpdateReset( Abc_Aig_t * pMan ) +{ + assert( pMan->vUpdates != NULL ); + Vec_PtrClear( pMan->vUpdates ); +} + +/**Function************************************************************* + + Synopsis [Add a new update.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_AigUpdateAdd( Abc_Aig_t * pMan, Abc_Obj_t * pObj ) +{ + if ( pMan->vUpdates ) + Vec_PtrPush( pMan->vUpdates, pObj ); +} + +/**Function************************************************************* + + Synopsis [Read the updates array.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Abc_AigUpdateRead( Abc_Aig_t * pMan ) +{ + return pMan->vUpdates; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/abc/abcHie.c b/src/base/abc/abcHie.c index 1047650f..342d6c83 100644 --- a/src/base/abc/abcHie.c +++ b/src/base/abc/abcHie.c @@ -54,16 +54,17 @@ void Abc_NtkFlattenLogicHierarchy_rec( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk, in assert( Abc_NtkBoxNum(pNtk) == 1 ); pObj = Abc_NtkBox( pNtk, 0 ); Abc_NtkDupBox( pNtkNew, pObj, 1 ); + pObj->pCopy->pData = pNtk; // connect blackbox fanins to the PI nets assert( Abc_ObjFaninNum(pObj->pCopy) == Abc_NtkPiNum(pNtk) ); Abc_NtkForEachPi( pNtk, pTerm, i ) - Abc_ObjAddFanin( Abc_ObjFanin(pObj->pCopy,i), Abc_ObjFanout0(pTerm) ); + Abc_ObjAddFanin( Abc_ObjFanin(pObj->pCopy,i), Abc_ObjFanout0(pTerm)->pCopy ); // connect blackbox fanouts to the PO nets assert( Abc_ObjFanoutNum(pObj->pCopy) == Abc_NtkPoNum(pNtk) ); Abc_NtkForEachPo( pNtk, pTerm, i ) - Abc_ObjAddFanin( Abc_ObjFanin0(pTerm), Abc_ObjFanout(pObj->pCopy,i) ); + Abc_ObjAddFanin( Abc_ObjFanin0(pTerm)->pCopy, Abc_ObjFanout(pObj->pCopy,i) ); return; } @@ -163,8 +164,9 @@ Abc_Ntk_t * Abc_NtkFlattenLogicHierarchy( Abc_Ntk_t * pNtk ) Abc_Ntk_t * pNtkNew; Abc_Obj_t * pTerm, * pNet; int i, Counter; - assert( Abc_NtkIsNetlist(pNtk) ); + extern Abc_Lib_t * Abc_LibDupBlackboxes( Abc_Lib_t * pLib, Abc_Ntk_t * pNtkSave ); + assert( Abc_NtkIsNetlist(pNtk) ); // start the network pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc, 1 ); // duplicate the name and the spec @@ -193,9 +195,16 @@ Abc_Ntk_t * Abc_NtkFlattenLogicHierarchy( Abc_Ntk_t * pNtk ) // recursively flatten hierarchy, create internal logic, add new PI/PO names if there are black boxes Counter = -1; Abc_NtkFlattenLogicHierarchy_rec( pNtkNew, pNtk, &Counter ); - printf( "Abc_NtkFlattenLogicHierarchy(): Flattened %d logic instances. Preserved %d black boxes.\n", + printf( "Hierarchy reader flattened %d logic instances. Preserved %d black boxes.\n", Counter, Abc_NtkBlackboxNum(pNtkNew) ); + // pass the design + assert( Vec_PtrEntry(pNtk->pDesign->vModules, 0) == pNtk ); + pNtkNew->pDesign = Abc_LibDupBlackboxes( pNtk->pDesign, pNtkNew ); + // update the pointers + Abc_NtkForEachBlackbox( pNtkNew, pTerm, i ) + pTerm->pData = ((Abc_Ntk_t *)pTerm->pData)->pCopy; + // copy the timing information // Abc_ManTimeDup( pNtk, pNtkNew ); // duplicate EXDC @@ -328,6 +337,13 @@ Abc_Ntk_t * Abc_NtkInsertNewLogic( Abc_Ntk_t * pNtkH, Abc_Ntk_t * pNtkL ) assert( Abc_NtkWhiteboxNum(pNtkL) == 0 ); assert( Abc_NtkBlackboxNum(pNtkL) == 0 ); + if ( Abc_NtkIsSopNetlist(pNtkH) && Abc_NtkIsAigNetlist(pNtkL) ) + Abc_NtkSopToAig( pNtkH ); + if ( Abc_NtkIsAigNetlist(pNtkH) && Abc_NtkIsSopNetlist(pNtkL) ) + Abc_NtkSopToAig( pNtkL ); + + assert( pNtkH->ntkFunc == pNtkL->ntkFunc ); + // prepare the logic network for copying Abc_NtkCleanCopy( pNtkL ); @@ -462,6 +478,276 @@ Abc_Ntk_t * Abc_NtkInsertNewLogic( Abc_Ntk_t * pNtkH, Abc_Ntk_t * pNtkL ) return pNtkNew; } +/**Function************************************************************* + + Synopsis [Assigns name with index.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkConvertAssignName( Abc_Obj_t * pObj, Abc_Obj_t * pNet, int Index ) +{ + char Suffix[16]; + assert( Abc_ObjIsTerm(pObj) ); + assert( Abc_ObjIsNet(pNet) ); + sprintf( Suffix, "[%d]", Index ); + Abc_ObjAssignName( pObj, Abc_ObjName(pNet), Suffix ); +} + +/**Function************************************************************* + + Synopsis [Strashes the BLIF-MV netlist.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkConvertBlifMv( Abc_Ntk_t * pNtk ) +{ + char * pSop; + Vec_Ptr_t * vNodes; + Abc_Obj_t * pBits[16]; + Abc_Obj_t ** pValues, ** pValuesF; + Abc_Ntk_t * pNtkNew; + Abc_Obj_t * pObj, * pTemp, * pBit, * pFanin, * pNet; + int fUsePositional = 0; + int i, k, v, nValues, Val, Index, Len, nBits, Def; + + assert( Abc_NtkIsNetlist(pNtk) ); + assert( Abc_NtkHasBlifMv(pNtk) ); + + // clean the node copy fields + Abc_NtkCleanCopy( pNtk ); + + // start the network + pNtkNew = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG, 1 ); + // duplicate the name and the spec + pNtkNew->pName = Extra_UtilStrsav( pNtk->pName ); +// pNtkNew->pSpec = Extra_UtilStrsav( pNtk->pName ); + + // check temporary assumptions + Abc_NtkForEachNet( pNtk, pObj, i ) + assert( Abc_ObjMvVarNum(pObj) < 10 ); + + // encode the CI nets + if ( fUsePositional ) + { + Abc_NtkForEachCi( pNtk, pObj, i ) + { + pNet = Abc_ObjFanout0(pObj); + nValues = Abc_ObjMvVarNum(pNet); + pValues = ALLOC( Abc_Obj_t *, nValues ); + // create PIs for the values + for ( v = 0; v < nValues; v++ ) + { + pValues[v] = Abc_NtkCreatePi( pNtkNew ); + Abc_NtkConvertAssignName( pValues[v], pNet, v ); + } + // save the values in the fanout net + pNet->pCopy = (Abc_Obj_t *)pValues; + } + } + else + { + Abc_NtkForEachCi( pNtk, pObj, i ) + { + pNet = Abc_ObjFanout0(pObj); + nValues = Abc_ObjMvVarNum(pNet); + pValues = ALLOC( Abc_Obj_t *, nValues ); + // create PIs for the encoding bits + nBits = Extra_Base2Log( nValues ); + for ( k = 0; k < nBits; k++ ) + { + pBits[k] = Abc_NtkCreatePi( pNtkNew ); + Abc_NtkConvertAssignName( pBits[k], pNet, k ); + } + // encode the values + for ( v = 0; v < nValues; v++ ) + { + pValues[v] = Abc_AigConst1(pNtkNew); + for ( k = 0; k < nBits; k++ ) + { + pBit = Abc_ObjNotCond( pBits[k], (v&(1<<k)) == 0 ); + pValues[v] = Abc_AigAnd( pNtkNew->pManFunc, pValues[v], pBit ); + } + } + // save the values in the fanout net + pNet->pCopy = (Abc_Obj_t *)pValues; + } + } + + // process nodes in the topological order + vNodes = Abc_NtkDfs( pNtk, 0 ); + Vec_PtrForEachEntry( vNodes, pObj, i ) + { + assert( Abc_ObjIsNode(pObj) ); + pNet = Abc_ObjFanout0(pObj); + nValues = Abc_ObjMvVarNum(pNet); + pValues = ALLOC( Abc_Obj_t *, nValues ); + for ( v = 0; v < nValues; v++ ) + pValues[v] = Abc_ObjNot( Abc_AigConst1(pNtkNew) ); + // get the BLIF-MV formula + pSop = pObj->pData; + // skip the value line + while ( *pSop++ != '\n' ); + + // handle the constant + if ( Abc_ObjFaninNum(pObj) == 0 ) + { + Index = *pSop-'0'; + pValues[Index] = Abc_AigConst1(pNtkNew); + // save the values in the fanout net + pNet->pCopy = (Abc_Obj_t *)pValues; + continue; + } +/* + // handle the mux + if ( *pSop != 'd' ) + { + assert( Abc_ObjFaninNum(pObj) == 3 ); + pValuesF = (Abc_Obj_t **)Abc_ObjFanin(pObj,1)->pCopy; + for ( v = 0; v < nValues; v++ ) + pValues[v] = pValuesF[v]; + // save the values in the fanout net + pNet->pCopy = (Abc_Obj_t *)pValues; + continue; + } +*/ + // detect muxes + Len = strlen(pSop); + for ( k = 0; k < Len; k++ ) + if ( *(pSop+k) == '=' ) + break; + if ( k < Len ) + { + assert( Abc_ObjFaninNum(pObj) == 3 ); + pValuesF = (Abc_Obj_t **)Abc_ObjFanin(pObj,1)->pCopy; + for ( v = 0; v < nValues; v++ ) + pValues[v] = pValuesF[v]; + // save the values in the fanout net + pNet->pCopy = (Abc_Obj_t *)pValues; + continue; + } + + // skip the default line +// assert( *pSop == 'd' ); + if ( *pSop == 'd' ) + { + Def = *(pSop+1) - '0'; + while ( *pSop++ != '\n' ); + } + else + Def = -1; + // convert the values + while ( *pSop ) + { + // encode the values + pTemp = Abc_AigConst1(pNtkNew); + Abc_ObjForEachFanin( pObj, pFanin, k ) + { + if ( *pSop == '-' ) + { + pSop += 2; + continue; + } + Val = Abc_ObjMvVarNum(pFanin); + pValuesF = (Abc_Obj_t **)pFanin->pCopy; + Index = *pSop-'0'; + assert( Index >= 0 && Index <= 9 && Index < Val ); + pTemp = Abc_AigAnd( pNtkNew->pManFunc, pTemp, pValuesF[Index] ); + pSop += 2; + } + // get the output value + Index = *pSop-'0'; + assert( Index >= 0 && Index <= 9 ); + pValues[Index] = Abc_AigOr( pNtkNew->pManFunc, pValues[Index], pTemp ); + pSop++; + assert( *pSop == '\n' ); + pSop++; + } + // compute the default value +// Def = 0; + if ( Def >= 0 ) + { + assert( pValues[Def] == Abc_ObjNot( Abc_AigConst1(pNtkNew) ) ); + pValues[Def] = Abc_AigConst1(pNtkNew); + for ( v = 0; v < nValues; v++ ) + { + if ( v == Def ) + continue; + pValues[Def] = Abc_AigAnd( pNtkNew->pManFunc, pValues[Def], Abc_ObjNot(pValues[v]) ); + } + // experiment + // if ( nValues > 2 ) + // pValues[Def] = Abc_ObjNot( Abc_AigConst1(pNtkNew) ); + } + + // save the values in the fanout net + pNet->pCopy = (Abc_Obj_t *)pValues; + } + Vec_PtrFree( vNodes ); + + // encode the CO nets + if ( fUsePositional ) + { + Abc_NtkForEachCo( pNtk, pObj, i ) + { + pNet = Abc_ObjFanin0(pObj); + nValues = Abc_ObjMvVarNum(pNet); + pValues = (Abc_Obj_t **)pNet->pCopy; + for ( v = 0; v < nValues; v++ ) + { + pTemp = Abc_NtkCreatePo( pNtkNew ); + Abc_ObjAddFanin( pTemp, pValues[v] ); + Abc_NtkConvertAssignName( pTemp, pNet, v ); + } + } + } + else + { + Abc_NtkForEachCo( pNtk, pObj, i ) + { + pNet = Abc_ObjFanin0(pObj); + nValues = Abc_ObjMvVarNum(pNet); + pValues = (Abc_Obj_t **)pNet->pCopy; + nBits = Extra_Base2Log( nValues ); + for ( k = 0; k < nBits; k++ ) + { + pBit = Abc_ObjNot( Abc_AigConst1(pNtkNew) ); + for ( v = 0; v < nValues; v++ ) + if ( v & (1<<k) ) + pBit = Abc_AigOr( pNtkNew->pManFunc, pBit, pValues[v] ); + pTemp = Abc_NtkCreatePo( pNtkNew ); + Abc_ObjAddFanin( pTemp, pBit ); + Abc_NtkConvertAssignName( pTemp, pNet, k ); + } + } + } + + // cleanup + Abc_NtkForEachObj( pNtk, pObj, i ) + if ( pObj->pCopy ) + free( pObj->pCopy ); + + Abc_AigCleanup(pNtkNew->pManFunc); + + // check integrity + if ( !Abc_NtkCheck( pNtkNew ) ) + { + fprintf( stdout, "Abc_NtkConvertBlifMv(): Network check has failed.\n" ); + Abc_NtkDelete( pNtkNew ); + return NULL; + } + return pNtkNew; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/abc/abcLib.c b/src/base/abc/abcLib.c index b31fed6b..247f3915 100644 --- a/src/base/abc/abcLib.c +++ b/src/base/abc/abcLib.c @@ -81,6 +81,7 @@ void Abc_LibFree( Abc_Lib_t * pLib, Abc_Ntk_t * pNtkSave ) // pNtk->pManFunc = NULL; if ( pNtk == pNtkSave ) continue; + pNtk->pManFunc = NULL; Abc_NtkDelete( pNtk ); } Vec_PtrFree( pLib->vModules ); @@ -92,6 +93,32 @@ void Abc_LibFree( Abc_Lib_t * pLib, Abc_Ntk_t * pNtkSave ) /**Function************************************************************* + Synopsis [Frees the library.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Lib_t * Abc_LibDupBlackboxes( Abc_Lib_t * pLib, Abc_Ntk_t * pNtkSave ) +{ + Abc_Lib_t * pLibNew; + Abc_Ntk_t * pNtkTemp; + int i; + pLibNew = Abc_LibCreate( pLib->pName ); +// pLibNew->pManFunc = pNtkSave->pManFunc; + Vec_PtrPush( pLibNew->vModules, pNtkSave ); + Vec_PtrForEachEntry( pLib->vModules, pNtkTemp, i ) + if ( Abc_NtkHasBlackbox( pNtkTemp ) ) + Vec_PtrPush( pLibNew->vModules, Abc_NtkDup(pNtkTemp) ); + return pLibNew; +} + + +/**Function************************************************************* + Synopsis [Prints the library.] Description [] diff --git a/src/base/abc/abcNtk.c b/src/base/abc/abcNtk.c index 66426268..18b4a7c4 100644 --- a/src/base/abc/abcNtk.c +++ b/src/base/abc/abcNtk.c @@ -242,15 +242,23 @@ Abc_Ntk_t * Abc_NtkStartRead( char * pName ) ***********************************************************************/ void Abc_NtkFinalizeRead( Abc_Ntk_t * pNtk ) { - Abc_Obj_t * pBox, * pObj; + Abc_Obj_t * pBox, * pObj, * pTerm; int i; if ( Abc_NtkHasBlackbox(pNtk) ) { pBox = Abc_NtkCreateBlackbox(pNtk); Abc_NtkForEachPi( pNtk, pObj, i ) - Abc_ObjAddFanin( pBox, Abc_ObjFanout0(pObj) ); + { + pTerm = Abc_NtkCreateBi(pNtk); + Abc_ObjAddFanin( pTerm, Abc_ObjFanout0(pObj) ); + Abc_ObjAddFanin( pBox, pTerm ); + } Abc_NtkForEachPo( pNtk, pObj, i ) - Abc_ObjAddFanin( Abc_ObjFanin0(pObj), pBox ); + { + pTerm = Abc_NtkCreateBo(pNtk); + Abc_ObjAddFanin( pTerm, pBox ); + Abc_ObjAddFanin( Abc_ObjFanin0(pObj), pTerm ); + } return; } assert( Abc_NtkIsNetlist(pNtk) ); @@ -315,6 +323,7 @@ Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk ) pNtkNew->pExdc = Abc_NtkDup( pNtk->pExdc ); if ( !Abc_NtkCheck( pNtkNew ) ) fprintf( stdout, "Abc_NtkDup(): Network check has failed.\n" ); + pNtk->pCopy = pNtkNew; return pNtkNew; } @@ -799,8 +808,6 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk ) free( pObj ); } - FREE( pNtk->pName ); - FREE( pNtk->pSpec ); // free the arrays Vec_PtrFree( pNtk->vPios ); Vec_PtrFree( pNtk->vPis ); @@ -852,6 +859,8 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk ) if ( pAttrMan ) Vec_AttFree( pAttrMan, 1 ); Vec_PtrFree( pNtk->vAttrs ); + FREE( pNtk->pName ); + FREE( pNtk->pSpec ); free( pNtk ); } diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 30602af5..e7f8c8ea 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -2680,6 +2680,7 @@ int Abc_CommandRewrite( Abc_Frame_t * pAbc, int argc, char ** argv ) bool fUseZeros; bool fVerbose; bool fVeryVerbose; + bool fPlaceEnable; // external functions extern void Rwr_Precompute(); @@ -2693,8 +2694,9 @@ int Abc_CommandRewrite( Abc_Frame_t * pAbc, int argc, char ** argv ) fUseZeros = 0; fVerbose = 0; fVeryVerbose = 0; + fPlaceEnable = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "lxzvwh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "lxzvwph" ) ) != EOF ) { switch ( c ) { @@ -2713,6 +2715,9 @@ int Abc_CommandRewrite( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'w': fVeryVerbose ^= 1; break; + case 'p': + fPlaceEnable ^= 1; + break; case 'h': goto usage; default: @@ -2743,7 +2748,7 @@ int Abc_CommandRewrite( Abc_Frame_t * pAbc, int argc, char ** argv ) } // modify the current network - if ( !Abc_NtkRewrite( pNtk, fUpdateLevel, fUseZeros, fVerbose, fVeryVerbose ) ) + if ( !Abc_NtkRewrite( pNtk, fUpdateLevel, fUseZeros, fVerbose, fVeryVerbose, fPlaceEnable ) ) { fprintf( pErr, "Rewriting has failed.\n" ); return 1; @@ -2751,12 +2756,13 @@ int Abc_CommandRewrite( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - fprintf( pErr, "usage: rewrite [-lzvwh]\n" ); + fprintf( pErr, "usage: rewrite [-lzvwph]\n" ); fprintf( pErr, "\t performs technology-independent rewriting of the AIG\n" ); fprintf( pErr, "\t-l : toggle preserving the number of levels [default = %s]\n", fUpdateLevel? "yes": "no" ); fprintf( pErr, "\t-z : toggle using zero-cost replacements [default = %s]\n", fUseZeros? "yes": "no" ); fprintf( pErr, "\t-v : toggle verbose printout [default = %s]\n", fVerbose? "yes": "no" ); fprintf( pErr, "\t-w : toggle printout subgraph statistics [default = %s]\n", fVeryVerbose? "yes": "no" ); + fprintf( pErr, "\t-p : toggle placement-aware rewriting [default = %s]\n", fPlaceEnable? "yes": "no" ); fprintf( pErr, "\t-h : print the command usage\n"); return 1; } @@ -5424,8 +5430,8 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) int nLevels; // extern Abc_Ntk_t * Abc_NtkNewAig( Abc_Ntk_t * pNtk ); // extern Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk ); - extern void Abc_NtkMaxFlowTest( Abc_Ntk_t * pNtk ); - extern int Pr_ManProofTest( char * pFileName ); +// extern void Abc_NtkMaxFlowTest( Abc_Ntk_t * pNtk ); +// extern int Pr_ManProofTest( char * pFileName ); pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); @@ -5520,7 +5526,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); */ // Abc_NtkMaxFlowTest( pNtk ); - Pr_ManProofTest( "trace.cnf" ); +// Pr_ManProofTest( "trace.cnf" ); return 0; usage: diff --git a/src/base/abci/abcIvy.c b/src/base/abci/abcIvy.c index 00f8c183..0f0d9c8b 100644 --- a/src/base/abci/abcIvy.c +++ b/src/base/abci/abcIvy.c @@ -525,10 +525,10 @@ int Abc_NtkIvyProve( Abc_Ntk_t ** ppNtk, void * pPars ) if ( pParams->fUseRewriting && Abc_NtkNodeNum(pNtk) > 500 ) { pParams->fUseRewriting = 0; - Abc_NtkRewrite( pNtk, 0, 0, 0, 0 ); + Abc_NtkRewrite( pNtk, 0, 0, 0, 0, 0 ); pNtk = Abc_NtkBalance( pNtkTemp = pNtk, 0, 0, 0 ); Abc_NtkDelete( pNtkTemp ); - Abc_NtkRewrite( pNtk, 0, 0, 0, 0 ); + Abc_NtkRewrite( pNtk, 0, 0, 0, 0, 0 ); Abc_NtkRefactor( pNtk, 10, 16, 0, 0, 0, 0 ); } diff --git a/src/base/abci/abcPlace.c b/src/base/abci/abcPlace.c new file mode 100644 index 00000000..5ceffd6f --- /dev/null +++ b/src/base/abci/abcPlace.c @@ -0,0 +1,253 @@ +/**CFile**************************************************************** + + FileName [abcPlace.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Interface with a placer.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abcPlace.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" + +// placement includes +#include "place_base.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +AbstractCell *abstractCells = NULL; +ConcreteCell *cells = NULL; +ConcreteNet *nets = NULL; +int nAllocSize = 0; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Creates a new cell.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Abc_PlaceCreateCell( Abc_Obj_t * pObj, int fAnd ) +{ + assert( cells[pObj->Id].m_id == 0 ); + + cells[pObj->Id].m_id = pObj->Id; + cells[pObj->Id].m_label = ""; + cells[pObj->Id].m_parent = &(abstractCells[fAnd]); + cells[pObj->Id].m_fixed = 0; + addConcreteCell(&(cells[pObj->Id])); +} + +/**Function************************************************************* + + Synopsis [Updates the net.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Abc_PlaceUpdateNet( Abc_Obj_t * pObj ) +{ + Abc_Obj_t * pFanout; + int k; + // free the old array of net terminals + if ( nets[pObj->Id].m_terms ) + free( nets[pObj->Id].m_terms ); + // fill in the net with the new information + nets[pObj->Id].m_id = pObj->Id; + nets[pObj->Id].m_weight = 1.0; + nets[pObj->Id].m_numTerms = Abc_ObjFanoutNum(pObj); //fanout + nets[pObj->Id].m_terms = ALLOC(ConcreteCell*, Abc_ObjFanoutNum(pObj)); + Abc_ObjForEachFanout( pObj, pFanout, k ) + nets[pObj->Id].m_terms[k] = &(cells[pFanout->Id]); + addConcreteNet(&(nets[pObj->Id])); +} + +/**Function************************************************************* + + Synopsis [Returns the placement cost of the cut.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +float Abc_PlaceEvaluateCut( Abc_Obj_t * pRoot, Vec_Ptr_t * vFanins ) +{ + Abc_Obj_t * pObj; +// double x, y; + int i; + Vec_PtrForEachEntry( vFanins, pObj, i ) + { +// pObj->Id + } + return 0.0; +} + +/**Function************************************************************* + + Synopsis [Updates placement after one step of rewriting.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_PlaceUpdate( Vec_Ptr_t * vUpdates, int nNodesOld ) +{ + Abc_Obj_t * pObj, * pFanin; + int i, k; + Vec_Ptr_t * vCells, * vNets; + + // start the arrays of new cells and nets + vCells = Vec_PtrAlloc( 16 ); + vNets = Vec_PtrAlloc( 32 ); + + // go through the modified nodes + Vec_PtrForEachEntry( vUpdates, pObj, i ) + { + if ( pObj->Id > nNodesOld ) // pObj is a new node + { + Abc_PlaceCreateCell( pObj, 1 ); + Abc_PlaceUpdateNet( pObj ); + + // add the new cell and its fanin nets to temporary storage + Vec_PtrPush( vCells, &(cells[pObj->Id]) ); + Abc_ObjForEachFanin( pObj, pFanin, k ) + Vec_PtrPushUnique( vNets, &(nets[pFanin->Id]) ); + } + else // pObj is an old node + { + Abc_PlaceUpdateNet( Abc_ObjFanin0(pObj) ); + Abc_PlaceUpdateNet( Abc_ObjFanin1(pObj) ); + } + } + + // update the placement +// fastPlace( Vec_PtrSize(vCells), (ConcreteCell **)Vec_PtrArray(vCells), +// Vec_PtrSize(vNets), (ConcreteNet **)Vec_PtrArray(vNets) ); + + // clean up + Vec_PtrFree( vCells ); + Vec_PtrFree( vNets ); +} + +/**Function************************************************************* + + Synopsis [This procedure is called before the writing start.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_PlaceBegin( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pObj; + int i; + + // allocate and clean internal storage + nAllocSize = 5 * Abc_NtkObjNumMax(pNtk); + cells = REALLOC(ConcreteCell, cells, nAllocSize); + nets = REALLOC(ConcreteNet, nets, nAllocSize); + memset( cells, 0, sizeof(ConcreteCell) * nAllocSize ); + memset( nets, 0, sizeof(ConcreteNet) * nAllocSize ); + + // create AbstractCells + // 1: pad + // 2: and + if (!abstractCells) + abstractCells = ALLOC(AbstractCell,2); + + abstractCells[0].m_height = 1.0; + abstractCells[0].m_width = 1.0; + abstractCells[0].m_label = "pio"; + abstractCells[0].m_pad = 1; + + abstractCells[1].m_height = 1.0; + abstractCells[1].m_width = 1.0; + abstractCells[1].m_label = "and"; + abstractCells[1].m_pad = 0; + + // input pads + Abc_NtkForEachCi( pNtk, pObj, i ) + Abc_PlaceCreateCell( pObj, 0 ); + + // ouput pads + Abc_NtkForEachCo( pNtk, pObj, i ) + Abc_PlaceCreateCell( pObj, 0 ); + + // AND nodes + Abc_AigForEachAnd( pNtk, pObj, i ) + Abc_PlaceCreateCell( pObj, 1 ); + + // all nets + Abc_NtkForEachObj( pNtk, pObj, i ) + { + if ( !Abc_ObjIsCi(pObj) && !Abc_ObjIsNode(pObj) ) + continue; + Abc_PlaceUpdateNet( pObj ); + } + + globalPreplace((float)0.8); + globalPlace(); +} + +/**Function************************************************************* + + Synopsis [This procedure is called after the writing completes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_PlaceEnd( Abc_Ntk_t * pNtk ) +{ + int i; + + + // clean up + for ( i = 0; i < nAllocSize; i++ ) + FREE( nets[i].m_terms ); + FREE( abstractCells ); + FREE( cells ); + FREE( nets ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abci/abcProve.c b/src/base/abci/abcProve.c index 6d1ed161..a4220216 100644 --- a/src/base/abci/abcProve.c +++ b/src/base/abci/abcProve.c @@ -133,13 +133,13 @@ int Abc_NtkMiterProve( Abc_Ntk_t ** ppNtk, void * pPars ) break; */ /* - Abc_NtkRewrite( pNtk, 0, 0, 0, 0 ); + Abc_NtkRewrite( pNtk, 0, 0, 0, 0, 0 ); if ( (RetValue = Abc_NtkMiterIsConstant(pNtk)) >= 0 ) break; if ( --Counter == 0 ) break; */ - Abc_NtkRewrite( pNtk, 0, 0, 0, 0 ); + Abc_NtkRewrite( pNtk, 0, 0, 0, 0, 0 ); if ( (RetValue = Abc_NtkMiterIsConstant(pNtk)) >= 0 ) break; if ( --Counter == 0 ) @@ -328,9 +328,9 @@ void Abc_NtkMiterPrint( Abc_Ntk_t * pNtk, char * pString, int clk, int fVerbose Abc_Ntk_t * Abc_NtkMiterRwsat( Abc_Ntk_t * pNtk ) { Abc_Ntk_t * pNtkTemp; - Abc_NtkRewrite( pNtk, 0, 0, 0, 0 ); + Abc_NtkRewrite( pNtk, 0, 0, 0, 0, 0 ); pNtk = Abc_NtkBalance( pNtkTemp = pNtk, 0, 0, 0 ); Abc_NtkDelete( pNtkTemp ); - Abc_NtkRewrite( pNtk, 0, 0, 0, 0 ); + Abc_NtkRewrite( pNtk, 0, 0, 0, 0, 0 ); Abc_NtkRefactor( pNtk, 10, 16, 0, 0, 0, 0 ); return pNtk; } diff --git a/src/base/abci/abcRewrite.c b/src/base/abci/abcRewrite.c index e7dbf3a1..a3209275 100644 --- a/src/base/abci/abcRewrite.c +++ b/src/base/abci/abcRewrite.c @@ -36,6 +36,10 @@ static Cut_Man_t * Abc_NtkStartCutManForRewrite( Abc_Ntk_t * pNtk ); static void Abc_NodePrintCuts( Abc_Obj_t * pNode ); static void Abc_ManShowCutCone( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves ); +extern void Abc_PlaceBegin( Abc_Ntk_t * pNtk ); +extern void Abc_PlaceEnd( Abc_Ntk_t * pNtk ); +extern void Abc_PlaceUpdate( Vec_Ptr_t * vUpdates, int nNodesOld ); + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -51,18 +55,28 @@ static void Abc_ManShowCutCone( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves ); SeeAlso [] ***********************************************************************/ -int Abc_NtkRewrite( Abc_Ntk_t * pNtk, int fUpdateLevel, int fUseZeros, int fVerbose, int fVeryVerbose ) +int Abc_NtkRewrite( Abc_Ntk_t * pNtk, int fUpdateLevel, int fUseZeros, int fVerbose, int fVeryVerbose, int fPlaceEnable ) { ProgressBar * pProgress; Cut_Man_t * pManCut; Rwr_Man_t * pManRwr; Abc_Obj_t * pNode; - int i, nNodes, nGain; + Vec_Ptr_t * vUpdates = NULL; + Dec_Graph_t * pGraph; + int i, nNodes, nGain, fCompl; int clk, clkStart = clock(); assert( Abc_NtkIsStrash(pNtk) ); // cleanup the AIG Abc_AigCleanup(pNtk->pManFunc); + + // start placement package + if ( fPlaceEnable ) + { + Abc_PlaceBegin( pNtk ); + vUpdates = Abc_AigUpdateStart( pNtk->pManFunc ); + } + // start the rewriting manager pManRwr = Rwr_ManStart( 0 ); if ( pManRwr == NULL ) @@ -88,61 +102,37 @@ Rwr_ManAddTimeCuts( pManRwr, clock() - clk ); // stop if all nodes have been tried once if ( i >= nNodes ) break; - // skip the constant node -// if ( Abc_NodeIsConst(pNode) ) -// continue; // skip persistant nodes if ( Abc_NodeIsPersistant(pNode) ) continue; // skip the nodes with many fanouts if ( Abc_ObjFanoutNum(pNode) > 1000 ) continue; -//printf( "*******Node %d: \n", pNode->Id ); // for each cut, try to resynthesize it - nGain = Rwr_NodeRewrite( pManRwr, pManCut, pNode, fUpdateLevel, fUseZeros ); - if ( nGain > 0 || nGain == 0 && fUseZeros ) - { -// extern void Abc_RwrExpWithCut( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves ); - - Dec_Graph_t * pGraph = Rwr_ManReadDecs(pManRwr); - int fCompl = Rwr_ManReadCompl(pManRwr); + nGain = Rwr_NodeRewrite( pManRwr, pManCut, pNode, fUpdateLevel, fUseZeros, fPlaceEnable ); + if ( !(nGain > 0 || nGain == 0 && fUseZeros) ) + continue; + // if we end up here, a rewriting step is accepted -// Abc_RwrExpWithCut( pNode, Rwr_ManReadLeaves(pManRwr) ); + // get hold of the new subgraph to be added to the AIG + pGraph = Rwr_ManReadDecs(pManRwr); + fCompl = Rwr_ManReadCompl(pManRwr); -/* - { - Abc_Obj_t * pObj; - int i; - printf( "USING: (" ); - Vec_PtrForEachEntry( Rwr_ManReadLeaves(pManRwr), pObj, i ) - printf( "%d ", Abc_ObjFanoutNum(Abc_ObjRegular(pObj)) ); - printf( ") Gain = %d.\n", nGain ); - } -*/ - -// if ( nGain > 0 ) -// Abc_ManShowCutCone( pNode, Rwr_ManReadLeaves(pManRwr) ); + // reset the array of the changed nodes + if ( fPlaceEnable ) + Abc_AigUpdateReset( pNtk->pManFunc ); -/* - if ( nGain > 0 ) - { // print stats on the MFFC - extern void Abc_NodeMffsConeSuppPrint( Abc_Obj_t * pNode ); - printf( "Node %6d : Gain = %4d ", pNode->Id, nGain ); - Abc_NodeMffsConeSuppPrint( pNode ); - } -*/ - // complement the FF if needed - if ( fCompl ) Dec_GraphComplement( pGraph ); + // complement the FF if needed + if ( fCompl ) Dec_GraphComplement( pGraph ); clk = clock(); - Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain ); + Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain ); Rwr_ManAddTimeUpdate( pManRwr, clock() - clk ); - if ( fCompl ) Dec_GraphComplement( pGraph ); -// { -// extern int s_TotalChanges; -// s_TotalChanges++; -// } - } + if ( fCompl ) Dec_GraphComplement( pGraph ); + + // use the array of changed nodes to update placement + if ( fPlaceEnable ) + Abc_PlaceUpdate( vUpdates, nNodes ); } Extra_ProgressBarStop( pProgress ); Rwr_ManAddTimeTotal( pManRwr, clock() - clkStart ); @@ -156,6 +146,14 @@ Rwr_ManAddTimeTotal( pManRwr, clock() - clkStart ); Rwr_ManStop( pManRwr ); Cut_ManStop( pManCut ); pNtk->pManCut = NULL; + + // start placement package + if ( fPlaceEnable ) + { + Abc_PlaceEnd( pNtk ); + Abc_AigUpdateStop( pNtk->pManFunc ); + } + // put the nodes into the DFS order and reassign their IDs Abc_NtkReassignIds( pNtk ); // Abc_AigCheckFaninOrder( pNtk->pManFunc ); diff --git a/src/base/abci/module.make b/src/base/abci/module.make index 97f42f0e..4aa05d07 100644 --- a/src/base/abci/module.make +++ b/src/base/abci/module.make @@ -26,6 +26,7 @@ SRC += src/base/abci/abc.c \ src/base/abci/abcNtbdd.c \ src/base/abci/abcOdc.c \ src/base/abci/abcOrder.c \ + src/base/abci/abcPlace.c \ src/base/abci/abcPrint.c \ src/base/abci/abcProve.c \ src/base/abci/abcReconv.c \ diff --git a/src/base/io/io.c b/src/base/io/io.c index e79e1857..2267d4e7 100644 --- a/src/base/io/io.c +++ b/src/base/io/io.c @@ -26,7 +26,6 @@ //////////////////////////////////////////////////////////////////////// static int IoCommandRead ( Abc_Frame_t * pAbc, int argc, char **argv ); -static int IoCommandReadHie ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandReadAiger ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandReadBaf ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandReadBlif ( Abc_Frame_t * pAbc, int argc, char **argv ); @@ -76,7 +75,6 @@ extern Abc_Lib_t * Ver_ParseFile( char * pFileName, Abc_Lib_t * pGateLib, int fC void Io_Init( Abc_Frame_t * pAbc ) { Cmd_CommandAdd( pAbc, "I/O", "read", IoCommandRead, 1 ); - Cmd_CommandAdd( pAbc, "I/O", "read_hie", IoCommandReadHie, 1 ); Cmd_CommandAdd( pAbc, "I/O", "read_aiger", IoCommandReadAiger, 1 ); Cmd_CommandAdd( pAbc, "I/O", "read_baf", IoCommandReadBaf, 1 ); Cmd_CommandAdd( pAbc, "I/O", "read_blif", IoCommandReadBlif, 1 ); @@ -189,61 +187,6 @@ usage: SeeAlso [] ***********************************************************************/ -int IoCommandReadHie( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - Abc_Ntk_t * pNtk; - char * pFileName; - int fCheck; - int c; - - fCheck = 1; - Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "ch" ) ) != EOF ) - { - switch ( c ) - { - case 'c': - fCheck ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; - } - } - if ( argc != globalUtilOptind + 1 ) - goto usage; - // get the input file name - pFileName = argv[globalUtilOptind]; - // read the file using the corresponding file reader - pNtk = Io_ReadHie( pFileName, Io_ReadFileType(pFileName), fCheck ); - if ( pNtk == NULL ) - return 0; - // replace the current network - Abc_FrameReplaceCurrentNetwork( pAbc, pNtk ); - return 0; - -usage: - fprintf( pAbc->Err, "usage: read_hie [-ch] <file>\n" ); - fprintf( pAbc->Err, "\t reads hierarchical design represented in BLIF or BLIF-MV\n" ); - fprintf( pAbc->Err, "\t by calling the parser that matches the extension of <file>\n" ); - fprintf( pAbc->Err, "\t-c : toggle network check after reading [default = %s]\n", fCheck? "yes":"no" ); - fprintf( pAbc->Err, "\t-h : prints the command summary\n" ); - fprintf( pAbc->Err, "\tfile : the name of a file to read\n" ); - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ int IoCommandReadAiger( Abc_Frame_t * pAbc, int argc, char ** argv ) { Abc_Ntk_t * pNtk; @@ -388,7 +331,8 @@ int IoCommandReadBlif( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( fReadAsAig ) pNtk = Io_ReadBlifAsAig( pFileName, fCheck ); else - pNtk = Io_Read( pFileName, IO_FILE_BLIF, fCheck ); +// pNtk = Io_Read( pFileName, IO_FILE_BLIF, fCheck ); + pNtk = Io_ReadBlif( pFileName, fCheck ); if ( pNtk == NULL ) return 1; // replace the current network @@ -1704,7 +1648,7 @@ int IoCommandWriteVerLib( Abc_Frame_t * pAbc, int argc, char **argv ) fprintf( pAbc->Out, "Verilog library is not specified.\n" ); return 0; } - Io_WriteVerilogLibrary( pLibrary, pFileName ); +// Io_WriteVerilogLibrary( pLibrary, pFileName ); return 0; usage: diff --git a/src/base/io/io.h b/src/base/io/io.h index 8ce7c690..472e7b2d 100644 --- a/src/base/io/io.h +++ b/src/base/io/io.h @@ -119,7 +119,6 @@ extern void Io_WriteVerilog( Abc_Ntk_t * pNtk, char * FileName ); extern Io_FileType_t Io_ReadFileType( char * pFileName ); extern Abc_Ntk_t * Io_ReadNetlist( char * pFileName, Io_FileType_t FileType, int fCheck ); extern Abc_Ntk_t * Io_Read( char * pFileName, Io_FileType_t FileType, int fCheck ); -extern Abc_Ntk_t * Io_ReadHie( char * pFileName, Io_FileType_t FileType, int fCheck ); extern void Io_Write( Abc_Ntk_t * pNtk, char * pFileName, Io_FileType_t FileType ); extern void Io_WriteHie( Abc_Ntk_t * pNtk, char * pBaseName, char * pFileName ); extern Abc_Obj_t * Io_ReadCreatePi( Abc_Ntk_t * pNtk, char * pName ); diff --git a/src/base/io/ioReadBlifMv.c b/src/base/io/ioReadBlifMv.c index 99656422..46a202e1 100644 --- a/src/base/io/ioReadBlifMv.c +++ b/src/base/io/ioReadBlifMv.c @@ -186,9 +186,10 @@ Abc_Ntk_t * Io_ReadBlifMv( char * pFileName, int fBlifMv, int fCheck ) assert( Vec_PtrSize(pDesign->vModules) > 0 ); if ( Vec_PtrSize(pDesign->vModules) == 1 ) { - printf( "Warning: The design is not hierarchical.\n" ); +// printf( "Warning: The design is not hierarchical.\n" ); Abc_LibFree( pDesign, pNtk ); pNtk->pDesign = NULL; + pNtk->pSpec = Extra_UtilStrsav( pFileName ); } else Abc_NtkIsAcyclicHierarchy( pNtk ); @@ -1303,7 +1304,7 @@ static int Io_MvParseLineNamesMv( Io_MvMod_t * p, char * pLine, int fReset ) // split names line into tokens Io_MvSplitIntoTokens( vTokens, pLine, '\0' ); if ( fReset ) - assert( !strcmp(Vec_PtrEntry(vTokens,0), "r") ); + assert( !strcmp(Vec_PtrEntry(vTokens,0), "r") || !strcmp(Vec_PtrEntry(vTokens,0), "reset") ); else assert( !strcmp(Vec_PtrEntry(vTokens,0), "names") || !strcmp(Vec_PtrEntry(vTokens,0), "table") ); // find the number of inputs and outputs diff --git a/src/base/io/ioReadVerilog.c b/src/base/io/ioReadVerilog.c index eda2d0b0..5956a9bc 100644 --- a/src/base/io/ioReadVerilog.c +++ b/src/base/io/ioReadVerilog.c @@ -45,6 +45,7 @@ Abc_Ntk_t * Io_ReadVerilog( char * pFileName, int fCheck ) { Abc_Ntk_t * pNtk; Abc_Lib_t * pDesign; + int i; // parse the verilog file pDesign = Ver_ParseFile( pFileName, NULL, 1, fCheck ); @@ -60,12 +61,20 @@ Abc_Ntk_t * Io_ReadVerilog( char * pFileName, int fCheck ) assert( Vec_PtrSize(pDesign->vModules) > 0 ); if ( Vec_PtrSize(pDesign->vModules) == 1 ) { - printf( "Warning: The design is not hierarchical.\n" ); +// printf( "Warning: The design is not hierarchical.\n" ); Abc_LibFree( pDesign, pNtk ); pNtk->pDesign = NULL; + pNtk->pSpec = Extra_UtilStrsav( pFileName ); } else + { + // bring the root model to the beginning + for ( i = Vec_PtrSize(pDesign->vModules) - 2; i >= 0; i-- ) + Vec_PtrWriteEntry(pDesign->vModules, i+1, Vec_PtrEntry(pDesign->vModules, i) ); + Vec_PtrWriteEntry(pDesign->vModules, 0, pNtk ); + // check that there is no cyclic dependency Abc_NtkIsAcyclicHierarchy( pNtk ); + } return pNtk; } diff --git a/src/base/io/ioUtil.c b/src/base/io/ioUtil.c index 7b4c7c76..2de93ddf 100644 --- a/src/base/io/ioUtil.c +++ b/src/base/io/ioUtil.c @@ -123,7 +123,10 @@ Abc_Ntk_t * Io_ReadNetlist( char * pFileName, Io_FileType_t FileType, int fCheck } // read the new netlist if ( FileType == IO_FILE_BLIF ) - pNtk = Io_ReadBlif( pFileName, fCheck ); +// pNtk = Io_ReadBlif( pFileName, fCheck ); + pNtk = Io_ReadBlifMv( pFileName, 0, fCheck ); + else if ( Io_ReadFileType(pFileName) == IO_FILE_BLIFMV ) + pNtk = Io_ReadBlifMv( pFileName, 1, fCheck ); else if ( FileType == IO_FILE_BENCH ) pNtk = Io_ReadBench( pFileName, fCheck ); else if ( FileType == IO_FILE_EDIF ) @@ -144,16 +147,12 @@ Abc_Ntk_t * Io_ReadNetlist( char * pFileName, Io_FileType_t FileType, int fCheck fprintf( stdout, "Reading network from file has failed.\n" ); return NULL; } - if ( Abc_NtkBlackboxNum(pNtk) || Abc_NtkBlackboxNum(pNtk) ) - { - fprintf( stdout, "The network contains hierarchy. Use \"read_hie\".\n" ); - Abc_NtkDelete( pNtk ); - return NULL; - } + if ( Abc_NtkBlackboxNum(pNtk) || Abc_NtkWhiteboxNum(pNtk) ) + fprintf( stdout, "Warning: The network contains hierarchy.\n" ); return pNtk; } - + /**Function************************************************************* Synopsis [Read the network from a file.] @@ -174,6 +173,51 @@ Abc_Ntk_t * Io_Read( char * pFileName, Io_FileType_t FileType, int fCheck ) return NULL; if ( !Abc_NtkIsNetlist(pNtk) ) return pNtk; + // consider the case of BLIF-MV + if ( Io_ReadFileType(pFileName) == IO_FILE_BLIFMV ) + { + extern Abc_Ntk_t * Abc_NtkConvertBlifMv( Abc_Ntk_t * pNtk ); +Abc_NtkPrintStats( stdout, pNtk, 0 ); +/* +{ + FILE * pFile = fopen( "_temp_.mv", "w" ); + Io_NtkWriteBlifMv( pFile, pNtk ); + fclose( pFile ); +} +*/ + pNtk = Abc_NtkConvertBlifMv( pTemp = pNtk ); + Abc_NtkDelete( pTemp ); + if ( pNtk == NULL ) + { + fprintf( stdout, "Converting BLIF-MV has failed.\n" ); + return NULL; + } + return pNtk; + } + // flatten logic hierarchy + assert( Abc_NtkIsNetlist(pNtk) ); + if ( Abc_NtkWhiteboxNum(pNtk) > 0 ) + { + pNtk = Abc_NtkFlattenLogicHierarchy( pTemp = pNtk ); + Abc_NtkDelete( pTemp ); + if ( pNtk == NULL ) + { + fprintf( stdout, "Flattening logic hierarchy has failed.\n" ); + return NULL; + } + } + // convert blackboxes + if ( Abc_NtkBlackboxNum(pNtk) > 0 ) + { + printf( "Hierarchy reader converted %d blackboxes.\n", Abc_NtkBlackboxNum(pNtk) ); + pNtk = Abc_NtkConvertBlackboxes( pTemp = pNtk ); + Abc_NtkDelete( pTemp ); + if ( pNtk == NULL ) + { + fprintf( stdout, "Converting blackboxes has failed.\n" ); + return NULL; + } + } // convert the netlist into the logic network pNtk = Abc_NtkNetlistToLogic( pTemp = pNtk ); Abc_NtkDelete( pTemp ); @@ -230,7 +274,7 @@ Abc_Ntk_t * Io_ReadHie( char * pFileName, Io_FileType_t FileType, int fCheck ) // convert blackboxes if ( Abc_NtkBlackboxNum(pNtk) > 0 ) { - printf( "Hierarchical parser converted %d blackboxes.\n", Abc_NtkBlackboxNum(pNtk) ); + printf( "Hierarchy reader converted %d blackboxes.\n", Abc_NtkBlackboxNum(pNtk) ); pNtk = Abc_NtkConvertBlackboxes( pTemp = pNtk ); Abc_NtkDelete( pTemp ); if ( pNtk == NULL ) @@ -389,6 +433,8 @@ void Io_WriteHie( Abc_Ntk_t * pNtk, char * pBaseName, char * pFileName ) assert( Abc_NtkIsStrash(pNtk) || Abc_NtkIsLogic(pNtk) ); if ( Io_ReadFileType(pBaseName) == IO_FILE_BLIF ) pNtkBase = Io_ReadBlifMv( pBaseName, 0, 1 ); + else if ( Io_ReadFileType(pBaseName) == IO_FILE_VERILOG ) + pNtkBase = Io_ReadVerilog( pBaseName, 1 ); else fprintf( stderr, "Unknown input file format.\n" ); if ( pNtkBase == NULL ) @@ -405,6 +451,15 @@ void Io_WriteHie( Abc_Ntk_t * pNtk, char * pBaseName, char * pFileName ) // reintroduce the boxes into the netlist if ( Abc_NtkBlackboxNum(pNtkBase) > 0 ) { + // bring the current network to the same representation + if ( Abc_NtkIsLogic(pNtk) ) + { + if ( Abc_NtkIsSopNetlist(pNtkBase) ) + Abc_NtkLogicToSop( pNtk, 0 ); + else if ( Abc_NtkIsAigNetlist(pNtkBase) ) + Abc_NtkLogicToAig( pNtk ); + } + // derive the netlist pNtkResult = Abc_NtkLogicToNetlist( pNtk, 0 ); pNtkResult = Abc_NtkInsertNewLogic( pNtkBase, pNtkTemp = pNtkResult ); Abc_NtkDelete( pNtkTemp ); diff --git a/src/base/io/ioWriteAiger.c b/src/base/io/ioWriteAiger.c index 2bc2ded3..3b7d78ca 100644 --- a/src/base/io/ioWriteAiger.c +++ b/src/base/io/ioWriteAiger.c @@ -160,7 +160,7 @@ void Io_WriteAiger( Abc_Ntk_t * pNtk, char * pFileName ) pFile = fopen( pFileName, "wb" ); if ( pFile == NULL ) { - fprintf( stdout, "Io_WriteBaf(): Cannot open the output file \"%s\".\n", pFileName ); + fprintf( stdout, "Io_WriteAiger(): Cannot open the output file \"%s\".\n", pFileName ); return; } diff --git a/src/base/io/ioWriteBlif.c b/src/base/io/ioWriteBlif.c index 94580e33..e48d0be8 100644 --- a/src/base/io/ioWriteBlif.c +++ b/src/base/io/ioWriteBlif.c @@ -30,6 +30,7 @@ static void Io_NtkWrite( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches ); static void Io_NtkWriteOne( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches ); static void Io_NtkWritePis( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches ); static void Io_NtkWritePos( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches ); +static void Io_NtkWriteSubckt( FILE * pFile, Abc_Obj_t * pNode ); static void Io_NtkWriteAsserts( FILE * pFile, Abc_Ntk_t * pNtk ); static void Io_NtkWriteNodeGate( FILE * pFile, Abc_Obj_t * pNode ); static void Io_NtkWriteNodeFanins( FILE * pFile, Abc_Obj_t * pNode ); @@ -194,6 +195,16 @@ void Io_NtkWriteOne( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches ) fprintf( pFile, "\n" ); } + // write the subcircuits + assert( Abc_NtkWhiteboxNum(pNtk) == 0 ); + if ( Abc_NtkBlackboxNum(pNtk) > 0 ) + { + fprintf( pFile, "\n" ); + Abc_NtkForEachBlackbox( pNtk, pNode, i ) + Io_NtkWriteSubckt( pFile, pNode ); + fprintf( pFile, "\n" ); + } + // write each internal node pProgress = Extra_ProgressBarStart( stdout, Abc_NtkObjNumMax(pNtk) ); Abc_NtkForEachNode( pNtk, pNode, i ) @@ -382,6 +393,41 @@ void Io_NtkWriteAsserts( FILE * pFile, Abc_Ntk_t * pNtk ) SeeAlso [] ***********************************************************************/ +void Io_NtkWriteSubckt( FILE * pFile, Abc_Obj_t * pNode ) +{ + Abc_Ntk_t * pModel = pNode->pData; + Abc_Obj_t * pTerm; + int i; + // write the subcircuit +// fprintf( pFile, ".subckt %s %s", Abc_NtkName(pModel), Abc_ObjName(pNode) ); + fprintf( pFile, ".subckt %s", Abc_NtkName(pModel) ); + // write pairs of the formal=actual names + Abc_NtkForEachPi( pModel, pTerm, i ) + { + fprintf( pFile, " %s", Abc_ObjName(Abc_ObjFanout0(pTerm)) ); + pTerm = Abc_ObjFanin( pNode, i ); + fprintf( pFile, "=%s", Abc_ObjName(Abc_ObjFanin0(pTerm)) ); + } + Abc_NtkForEachPo( pModel, pTerm, i ) + { + fprintf( pFile, " %s", Abc_ObjName(Abc_ObjFanin0(pTerm)) ); + pTerm = Abc_ObjFanout( pNode, i ); + fprintf( pFile, "=%s", Abc_ObjName(Abc_ObjFanout0(pTerm)) ); + } + fprintf( pFile, "\n" ); +} + +/**Function************************************************************* + + Synopsis [Write the latch into a file.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ void Io_NtkWriteLatch( FILE * pFile, Abc_Obj_t * pLatch ) { Abc_Obj_t * pNetLi, * pNetLo; diff --git a/src/base/io/ioWriteBlifMv.c b/src/base/io/ioWriteBlifMv.c index 1c7e7bed..597ca945 100644 --- a/src/base/io/ioWriteBlifMv.c +++ b/src/base/io/ioWriteBlifMv.c @@ -26,7 +26,7 @@ /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -static void Io_NtkWriteBlifMv( FILE * pFile, Abc_Ntk_t * pNtk ); +void Io_NtkWriteBlifMv( FILE * pFile, Abc_Ntk_t * pNtk ); static void Io_NtkWriteBlifMvOne( FILE * pFile, Abc_Ntk_t * pNtk ); static void Io_NtkWriteBlifMvPis( FILE * pFile, Abc_Ntk_t * pNtk ); static void Io_NtkWriteBlifMvPos( FILE * pFile, Abc_Ntk_t * pNtk ); diff --git a/src/base/ver/verCore.c b/src/base/ver/verCore.c index 3a1a9584..a8ac99e5 100644 --- a/src/base/ver/verCore.c +++ b/src/base/ver/verCore.c @@ -66,7 +66,7 @@ static Abc_Obj_t * Ver_ParseCreateInv( Abc_Ntk_t * pNtk, Abc_Obj_t * pNet ); //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// - + /**Function************************************************************* Synopsis [File parser.] @@ -396,15 +396,15 @@ int Ver_ParseModule( Ver_Man_t * pMan ) else Abc_ObjAddFanin( pNet, Abc_NtkCreateNodeConst1(pNtk) ); - // fix the dangling nets - Abc_NtkFinalizeRead( pNtk ); - // check the functionality to blackbox if insides are not defined if ( Abc_NtkNodeNum(pNtk) == 0 && Abc_NtkBoxNum(pNtk) == 0 ) { pNtk->ntkFunc = ABC_FUNC_BLACKBOX; pNtk->pManFunc = NULL; } + + // fix the dangling nets + Abc_NtkFinalizeRead( pNtk ); return 1; } @@ -435,18 +435,43 @@ int Ver_ParseSignal( Ver_Man_t * pMan, Ver_SignalType_t SigType ) if ( pWord[0] == '[' && !pMan->fNameLast ) { Lower = atoi( pWord + 1 ); - while ( *pWord && *pWord != ':' ) + // find the splitter + while ( *pWord && *pWord != ':' && *pWord != ']' ) pWord++; if ( *pWord == 0 ) + { + sprintf( pMan->sError, "Cannot find closing bracket in this line." ); + Ver_ParsePrintErrorMessage( pMan ); + return 0; + } + if ( *pWord == ']' ) Upper = Lower; else + { Upper = atoi( pWord + 1 ); - if ( Lower > Upper ) - i = Lower, Lower = Upper, Upper = i; - // get the signal name - pWord = Ver_ParseGetName( pMan ); - if ( pWord == NULL ) - return 0; + if ( Lower > Upper ) + i = Lower, Lower = Upper, Upper = i; + // find the closing paranthesis + while ( *pWord && *pWord != ']' ) + pWord++; + if ( *pWord == 0 ) + { + sprintf( pMan->sError, "Cannot find closing bracket in this line." ); + Ver_ParsePrintErrorMessage( pMan ); + return 0; + } + assert( *pWord == ']' ); + } + // check the case of no space between bracket and the next word + if ( *(pWord+1) != 0 ) + pWord++; + else + { + // get the signal name + pWord = Ver_ParseGetName( pMan ); + if ( pWord == NULL ) + return 0; + } for ( i = Lower; i <= Upper; i++ ) { sprintf( Buffer, "%s[%d]", pWord, i ); @@ -559,7 +584,11 @@ int Ver_ParseAssign( Ver_Man_t * pMan ) else pEquation = Ver_StreamGetWord( p, ",;" ); if ( pEquation == NULL ) + { + sprintf( pMan->sError, "Cannot read the equation for %s.", Abc_ObjName(pNet) ); + Ver_ParsePrintErrorMessage( pMan ); return 0; + } // parse the formula if ( fReduction ) @@ -969,7 +998,10 @@ int Ver_ParseGate( Ver_Man_t * pMan, Abc_Ntk_t * pNtkGate ) memset( pPolarity, 0, nBytes ); } // create box to represent this gate - pNode = Abc_NtkCreateBlackbox( pMan->pNtkCur ); + if ( Abc_NtkHasBlackbox(pNtkGate) ) + pNode = Abc_NtkCreateBlackbox( pMan->pNtkCur ); + else + pNode = Abc_NtkCreateWhitebox( pMan->pNtkCur ); pNode->pNext = (Abc_Obj_t *)pPolarity; pNode->pData = pNtkGate; // connect to fanin nets diff --git a/src/base/ver/verStream.c b/src/base/ver/verStream.c index 0edbcdcb..eed322b9 100644 --- a/src/base/ver/verStream.c +++ b/src/base/ver/verStream.c @@ -307,9 +307,6 @@ void Ver_StreamSkipChars( Ver_Stream_t * p, char * pCharsToSkip ) // skip the symbols for ( pChar = p->pBufferCur; pChar < p->pBufferEnd; pChar++ ) { - // count the lines - if ( *pChar == '\n' ) - p->nLineCounter++; // skip symbols as long as they are in the list for ( pTemp = pCharsToSkip; *pTemp; pTemp++ ) if ( *pChar == *pTemp ) @@ -319,6 +316,9 @@ void Ver_StreamSkipChars( Ver_Stream_t * p, char * pCharsToSkip ) p->pBufferCur = pChar; return; } + // count the lines + if ( *pChar == '\n' ) + p->nLineCounter++; } // the file is finished or the last part continued // through VER_OFFSET_SIZE chars till the end of the buffer @@ -352,19 +352,18 @@ void Ver_StreamSkipToChars( Ver_Stream_t * p, char * pCharsToStop ) // skip the symbols for ( pChar = p->pBufferCur; pChar < p->pBufferEnd; pChar++ ) { - // count the lines - if ( *pChar == '\n' ) - p->nLineCounter++; // skip symbols as long as they are NOT in the list for ( pTemp = pCharsToStop; *pTemp; pTemp++ ) if ( *pChar == *pTemp ) break; if ( *pTemp == 0 ) // pChar is not found in the list + { + // count the lines + if ( *pChar == '\n' ) + p->nLineCounter++; continue; + } // the symbol is found - move position and return - if ( *pChar == '\n' ) - p->nLineCounter--; - // update buffer p->pBufferCur = pChar; return; } @@ -403,9 +402,6 @@ char * Ver_StreamGetWord( Ver_Stream_t * p, char * pCharsToStop ) p->nChars = 0; for ( pChar = p->pBufferCur; pChar < p->pBufferEnd; pChar++ ) { - // count the lines - if ( *pChar == '\n' ) - p->nLineCounter++; // skip symbols as long as they are NOT in the list for ( pTemp = pCharsToStop; *pTemp; pTemp++ ) if ( *pChar == *pTemp ) @@ -415,6 +411,9 @@ char * Ver_StreamGetWord( Ver_Stream_t * p, char * pCharsToStop ) p->pChars[p->nChars++] = *pChar; if ( p->nChars == VER_WORD_SIZE ) return NULL; + // count the lines + if ( *pChar == '\n' ) + p->nLineCounter++; continue; } // the symbol is found - move the position, set the word end, return the word |