diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2012-09-19 17:35:04 -0700 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2012-09-19 17:35:04 -0700 |
commit | 480ca14c75e9f8c54ca9b55c39162324aaa1e288 (patch) | |
tree | 446dc0fd3a98d5d60c01f01f5b95e380b002ce34 /src | |
parent | 3af0f719afa368cafbe7c8178d0995819b47be90 (diff) | |
download | abc-480ca14c75e9f8c54ca9b55c39162324aaa1e288.tar.gz abc-480ca14c75e9f8c54ca9b55c39162324aaa1e288.tar.bz2 abc-480ca14c75e9f8c54ca9b55c39162324aaa1e288.zip |
Extending Liberty parser to handle multi-output cells.
Diffstat (limited to 'src')
-rw-r--r-- | src/base/abc/abc.h | 2 | ||||
-rw-r--r-- | src/base/abc/abcUtil.c | 12 | ||||
-rw-r--r-- | src/base/abci/abcMap.c | 29 | ||||
-rw-r--r-- | src/base/abci/abcPrint.c | 2 | ||||
-rw-r--r-- | src/base/io/ioWriteBlif.c | 25 | ||||
-rw-r--r-- | src/map/amap/amapInt.h | 1 | ||||
-rw-r--r-- | src/map/amap/amapLib.c | 4 | ||||
-rw-r--r-- | src/map/amap/amapLiberty.c | 58 | ||||
-rw-r--r-- | src/map/amap/amapRead.c | 17 | ||||
-rw-r--r-- | src/map/mio/mioUtils.c | 2 |
10 files changed, 104 insertions, 48 deletions
diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h index 83aa3f7b..683bb76b 100644 --- a/src/base/abc/abc.h +++ b/src/base/abc/abc.h @@ -661,6 +661,8 @@ extern ABC_DLL int Abc_LibFindTopLevelModels( Abc_Lib_t * pLib ); extern ABC_DLL Abc_Ntk_t * Abc_LibDeriveRoot( Abc_Lib_t * pLib ); /*=== abcLog.c ==========================================================*/ extern ABC_DLL void Abc_NtkWriteLogFile( char * pFileName, Abc_Cex_t * pSeqCex, int Status, int nFrames, char * pCommand ); +/*=== abcMap.c ==========================================================*/ +extern ABC_DLL Abc_Obj_t * Abc_NtkFetchTwinNode( Abc_Obj_t * pNode ); /*=== abcMiter.c ==========================================================*/ extern ABC_DLL int Abc_NtkMinimumBase( Abc_Ntk_t * pNtk ); extern ABC_DLL int Abc_NodeMinimumBase( Abc_Obj_t * pNode ); diff --git a/src/base/abc/abcUtil.c b/src/base/abc/abcUtil.c index 2ad32dba..e2ffb016 100644 --- a/src/base/abc/abcUtil.c +++ b/src/base/abc/abcUtil.c @@ -357,22 +357,22 @@ int Abc_NtkGetClauseNum( Abc_Ntk_t * pNtk ) ***********************************************************************/ double Abc_NtkGetMappedArea( Abc_Ntk_t * pNtk ) { - Abc_Obj_t * pNode; + Abc_Obj_t * pObj; double TotalArea; int i; assert( Abc_NtkHasMapping(pNtk) ); TotalArea = 0.0; - Abc_NtkForEachNode( pNtk, pNode, i ) + Abc_NtkForEachNode( pNtk, pObj, i ) { -// assert( pNode->pData ); - if ( pNode->pData == NULL ) +// assert( pObj->pData ); + if ( pObj->pData == NULL ) { printf( "Node without mapping is encountered.\n" ); continue; } - TotalArea += Mio_GateReadArea( (Mio_Gate_t *)pNode->pData ); + TotalArea += Mio_GateReadArea( (Mio_Gate_t *)pObj->pData ); // assuming that twin gates follow each other - if ( Mio_GateReadTwin(((Mio_Gate_t *)pNode->pData)) != NULL ) + if ( Abc_NtkFetchTwinNode(pObj) ) i++; } return TotalArea; diff --git a/src/base/abci/abcMap.c b/src/base/abci/abcMap.c index c9d743eb..fb8c87ed 100644 --- a/src/base/abci/abcMap.c +++ b/src/base/abci/abcMap.c @@ -682,6 +682,35 @@ Abc_Obj_t * Abc_NodeFromMapSuperChoice_rec( Abc_Ntk_t * pNtkNew, Map_Super_t * p return pNodeNew; } +/**Function************************************************************* + + Synopsis [Returns the twin node if it exists.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NtkFetchTwinNode( Abc_Obj_t * pNode ) +{ + Abc_Obj_t * pNode2; + Mio_Gate_t * pGate = (Mio_Gate_t *)pNode->pData; + assert( Abc_NtkHasMapping(pNode->pNtk) ); + if ( pGate == NULL || Mio_GateReadTwin(pGate) == NULL ) + return NULL; + // assuming the twin node is following next + if ( (int)Abc_ObjId(pNode) == Abc_NtkObjNumMax(pNode->pNtk) - 1 ) + return NULL; + pNode2 = Abc_NtkObj( pNode->pNtk, Abc_ObjId(pNode) + 1 ); + if ( pNode2 == NULL || !Abc_ObjIsNode(pNode2) || Abc_ObjFaninNum(pNode) != Abc_ObjFaninNum(pNode2) ) + return NULL; + if ( Mio_GateReadTwin(pGate) != (Mio_Gate_t *)pNode2->pData ) + return NULL; + return pNode2; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// diff --git a/src/base/abci/abcPrint.c b/src/base/abci/abcPrint.c index 5f151b49..71900771 100644 --- a/src/base/abci/abcPrint.c +++ b/src/base/abci/abcPrint.c @@ -1025,7 +1025,7 @@ void Abc_NtkPrintGates( Abc_Ntk_t * pNtk, int fUseLibrary ) Mio_GateSetValue( (Mio_Gate_t *)pObj->pData, 1 + Mio_GateReadValue((Mio_Gate_t *)pObj->pData) ); CounterTotal++; // assuming that twin gates follow each other - if ( Mio_GateReadTwin(((Mio_Gate_t *)pObj->pData)) != NULL ) + if ( Abc_NtkFetchTwinNode(pObj) ) i++; } diff --git a/src/base/io/ioWriteBlif.c b/src/base/io/ioWriteBlif.c index a8305d07..0a33c9a2 100644 --- a/src/base/io/ioWriteBlif.c +++ b/src/base/io/ioWriteBlif.c @@ -514,6 +514,7 @@ void Io_NtkWriteNodeFanins( FILE * pFile, Abc_Obj_t * pNode ) fprintf( pFile, " %s", pName ); } + /**Function************************************************************* Synopsis [Writes the primary input list.] @@ -527,12 +528,11 @@ void Io_NtkWriteNodeFanins( FILE * pFile, Abc_Obj_t * pNode ) ***********************************************************************/ int Io_NtkWriteNodeGate( FILE * pFile, Abc_Obj_t * pNode, int Length ) { + static int fReport = 0; Mio_Gate_t * pGate = (Mio_Gate_t *)pNode->pData; - Mio_Gate_t * pGate2; Mio_Pin_t * pGatePin; Abc_Obj_t * pNode2; int i; - // write the node fprintf( pFile, " %-*s ", Length, Mio_GateReadName(pGate) ); for ( pGatePin = Mio_GateReadPins(pGate), i = 0; pGatePin; pGatePin = Mio_PinReadNext(pGatePin), i++ ) fprintf( pFile, "%s=%s ", Mio_PinReadName(pGatePin), Abc_ObjName( Abc_ObjFanin(pNode,i) ) ); @@ -540,25 +540,14 @@ int Io_NtkWriteNodeGate( FILE * pFile, Abc_Obj_t * pNode, int Length ) fprintf( pFile, "%s=%s", Mio_GateReadOutName(pGate), Abc_ObjName( Abc_ObjFanout0(pNode) ) ); if ( Mio_GateReadTwin(pGate) == NULL ) return 0; - // assuming the twin node is following next - if ( (int)Abc_ObjId(pNode) == Abc_NtkObjNumMax(pNode->pNtk) - 1 ) - { - printf( "Warning: Missing second output of gate \"%s\".\n", Mio_GateReadName(pGate) ); - return 0; - } - pNode2 = Abc_NtkObj( pNode->pNtk, Abc_ObjId(pNode) + 1 ); - if ( !Abc_ObjIsNode(pNode2) || Abc_ObjFaninNum(pNode) != Abc_ObjFaninNum(pNode2) ) - { - printf( "Warning: Missing second output of gate \"%s\".\n", Mio_GateReadName(pGate) ); - return 0; - } - pGate2 = (Mio_Gate_t *)pNode2->pData; - if ( strcmp( Mio_GateReadName(pGate), Mio_GateReadName(pGate2)) ) + pNode2 = Abc_NtkFetchTwinNode( pNode ); + if ( pNode2 == NULL ) { - printf( "Warning: Missing second output of gate \"%s\".\n", Mio_GateReadName(pGate) ); + if ( !fReport ) + fReport = 1, printf( "Warning: Missing second output of gate(s) \"%s\".\n", Mio_GateReadName(pGate) ); return 0; } - fprintf( pFile, " %s=%s", Mio_GateReadOutName(pGate2), Abc_ObjName( Abc_ObjFanout0(pNode2) ) ); + fprintf( pFile, " %s=%s", Mio_GateReadOutName((Mio_Gate_t *)pNode2->pData), Abc_ObjName( Abc_ObjFanout0(pNode2) ) ); return 1; } diff --git a/src/map/amap/amapInt.h b/src/map/amap/amapInt.h index a9a593c0..e2284ce6 100644 --- a/src/map/amap/amapInt.h +++ b/src/map/amap/amapInt.h @@ -149,6 +149,7 @@ struct Amap_Pin_t_ struct Amap_Gat_t_ { Amap_Lib_t * pLib; // library + Amap_Gat_t * pTwin; // twin gate char * pName; // the name of the gate char * pOutName; // name of the output double dArea; // the area of the gate diff --git a/src/map/amap/amapLib.c b/src/map/amap/amapLib.c index cf087218..002386ad 100644 --- a/src/map/amap/amapLib.c +++ b/src/map/amap/amapLib.c @@ -269,11 +269,11 @@ Vec_Ptr_t * Amap_LibSelectGates( Amap_Lib_t * p, int fVerbose ) vSelect = Vec_PtrAlloc( 100 ); Vec_PtrForEachEntry( Amap_Gat_t *, p->vSorted, pGate, i ) { - if ( pGate->pFunc == NULL ) + if ( pGate->pFunc == NULL || pGate->pTwin != NULL ) continue; Vec_PtrForEachEntryStop( Amap_Gat_t *, p->vSorted, pGate2, k, i ) { - if ( pGate2->pFunc == NULL ) + if ( pGate2->pFunc == NULL || pGate2->pTwin != NULL ) continue; if ( pGate2->nPins != pGate->nPins ) continue; diff --git a/src/map/amap/amapLiberty.c b/src/map/amap/amapLiberty.c index 7e8a9af5..e961b68c 100644 --- a/src/map/amap/amapLiberty.c +++ b/src/map/amap/amapLiberty.c @@ -229,7 +229,7 @@ Amap_Item_t * Amap_LibertyPinFunction( Amap_Tree_t * p, Amap_Item_t * pPin ) /**Function************************************************************* - Synopsis [Returns cell's function.] + Synopsis [Returns output pin(s).] Description [] @@ -250,6 +250,20 @@ Amap_Item_t * Amap_LibertyCellOutput( Amap_Tree_t * p, Amap_Item_t * pCell ) } return NULL; } +Vec_Ptr_t * Amap_LibertyCellOutputs( Amap_Tree_t * p, Amap_Item_t * pCell ) +{ + Amap_Item_t * pPin; + Vec_Ptr_t * vOutPins; + vOutPins = Vec_PtrAlloc( 2 ); + Amap_ItemForEachChild( p, pCell, pPin ) + { + if ( Amap_LibertyCompare(p, pPin->Key, "pin") ) + continue; + if ( Amap_LibertyPinFunction(p, pPin) ) + Vec_PtrPush( vOutPins, pPin ); + } + return vOutPins; +} /**Function************************************************************* @@ -353,9 +367,10 @@ char * Amap_LibertyGetStringFormula( Amap_Tree_t * p, Amap_Pair_t Pair ) int Amap_LibertyPrintGenlib( Amap_Tree_t * p, char * pFileName, int fVerbose ) { FILE * pFile; + Vec_Ptr_t * vOutputs; Amap_Item_t * pCell, * pArea, * pFunc, * pPin, * pOutput; char * pForm; - int Counter; + int i, Counter; if ( pFileName == NULL ) pFile = stdout; else @@ -406,12 +421,14 @@ int Amap_LibertyPrintGenlib( Amap_Tree_t * p, char * pFileName, int fVerbose ) printf( "Amap_LibertyPrintGenlib() skipped cell \"%s\" without logic function.\n", Amap_LibertyGetString(p, pCell->Head) ); continue; } +/* if ( Counter > 1 ) { if ( fVerbose ) printf( "Amap_LibertyPrintGenlib() skipped multi-output cell \"%s\".\n", Amap_LibertyGetString(p, pCell->Head) ); continue; } +*/ pArea = Amap_LibertyCellArea( p, pCell ); if ( pArea == NULL ) { @@ -419,25 +436,28 @@ int Amap_LibertyPrintGenlib( Amap_Tree_t * p, char * pFileName, int fVerbose ) printf( "Amap_LibertyPrintGenlib() skipped cell \"%s\" with unspecified area.\n", Amap_LibertyGetString(p, pCell->Head) ); continue; } - pOutput = Amap_LibertyCellOutput( p, pCell ); - pFunc = Amap_LibertyPinFunction( p, pOutput ); - pForm = Amap_LibertyGetStringFormula( p, pFunc->Head ); - if ( !strcmp(pForm, "0") || !strcmp(pForm, "1") ) +// pOutput = Amap_LibertyCellOutput( p, pCell ); + vOutputs = Amap_LibertyCellOutputs( p, pCell ); + Vec_PtrForEachEntry( Amap_Item_t *, vOutputs, pOutput, i ) { - if ( fVerbose ) - printf( "Amap_LibertyPrintGenlib() skipped cell \"%s\" with constant formula \"%s\".\n", Amap_LibertyGetString(p, pCell->Head), pForm ); - continue; + pFunc = Amap_LibertyPinFunction( p, pOutput ); + pForm = Amap_LibertyGetStringFormula( p, pFunc->Head ); + if ( !strcmp(pForm, "0") || !strcmp(pForm, "1") ) + { + if ( fVerbose ) + printf( "Amap_LibertyPrintGenlib() skipped cell \"%s\" with constant formula \"%s\".\n", Amap_LibertyGetString(p, pCell->Head), pForm ); + continue; + } + fprintf( pFile, "GATE " ); + fprintf( pFile, "%16s ", Amap_LibertyGetString(p, pCell->Head) ); + fprintf( pFile, "%f ", atof(Amap_LibertyGetString(p, pArea->Head)) ); + fprintf( pFile, "%s=", Amap_LibertyGetString(p, pOutput->Head) ); + fprintf( pFile, "%s;\n", Amap_LibertyGetStringFormula(p, pFunc->Head) ); + Amap_ItemForEachChild( p, pCell, pPin ) + if ( pPin != pOutput && !Amap_LibertyCompare(p, pPin->Key, "pin") ) + fprintf( pFile, " PIN %13s UNKNOWN 1 999 1.00 0.00 1.00 0.00\n", Amap_LibertyGetString(p, pPin->Head) ); } - - fprintf( pFile, "GATE " ); - fprintf( pFile, "%16s ", Amap_LibertyGetString(p, pCell->Head) ); - fprintf( pFile, "%f ", atof(Amap_LibertyGetString(p, pArea->Head)) ); - fprintf( pFile, "%s=", Amap_LibertyGetString(p, pOutput->Head) ); - fprintf( pFile, "%s;\n", Amap_LibertyGetStringFormula(p, pFunc->Head) ); - - Amap_ItemForEachChild( p, pCell, pPin ) - if ( pPin != pOutput && !Amap_LibertyCompare(p, pPin->Key, "pin") ) - fprintf( pFile, " PIN %13s UNKNOWN 1 999 1.00 0.00 1.00 0.00\n", Amap_LibertyGetString(p, pPin->Head) ); + Vec_PtrFree( vOutputs ); } if ( pFile != stdout ) fclose( pFile ); diff --git a/src/map/amap/amapRead.c b/src/map/amap/amapRead.c index bf308c08..e8206e31 100644 --- a/src/map/amap/amapRead.c +++ b/src/map/amap/amapRead.c @@ -326,10 +326,10 @@ int Amap_CollectFormulaTokens( Vec_Ptr_t * vTokens, char * pToken, int iPos ) Amap_Lib_t * Amap_ParseTokens( Vec_Ptr_t * vTokens, int fVerbose ) { Amap_Lib_t * p; - Amap_Gat_t * pGate; + Amap_Gat_t * pGate, * pPrev; Amap_Pin_t * pPin; char * pToken; - int nPins, iPos = 0; + int i, nPins, iPos = 0; p = Amap_LibAlloc(); pToken = (char *)Vec_PtrEntry(vTokens, iPos++); do @@ -409,8 +409,21 @@ Amap_Lib_t * Amap_ParseTokens( Vec_Ptr_t * vTokens, int fVerbose ) Vec_PtrPush( p->vGates, pGate ); } pToken = (char *)Vec_PtrEntry(vTokens, iPos++); +//printf( "Finished reading gate %s (%s)\n", pGate->pName, pGate->pOutName ); } while ( strcmp( pToken, ".end" ) ); + + // check if there are gates with identical names + pPrev = NULL; + Amap_LibForEachGate( p, pGate, i ) + { + if ( pPrev && !strcmp(pPrev->pName, pGate->pName) ) + { + pPrev->pTwin = pGate, pGate->pTwin = pPrev; + printf( "Warning: Detected multi-output gate \"%s\".\n", pGate->pName ); + } + pPrev = pGate; + } return p; } diff --git a/src/map/mio/mioUtils.c b/src/map/mio/mioUtils.c index 41b03d7d..347d81f5 100644 --- a/src/map/mio/mioUtils.c +++ b/src/map/mio/mioUtils.c @@ -319,6 +319,8 @@ Mio_Gate_t ** Mio_CollectRoots( Mio_Library_t * pLib, int nInputs, float tDelay, continue; if ( pGate->uTruth == ~0xAAAAAAAAAAAAAAAA && fSkipInv ) continue; + if ( pGate->pTwin ) // skip multi-output gates for now + continue; // check if the gate with this functionality already exists for ( i = 0; i < iGate; i++ ) if ( ppGates[i]->uTruth == pGate->uTruth ) |