diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2012-09-19 16:28:06 -0700 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2012-09-19 16:28:06 -0700 |
commit | 3af0f719afa368cafbe7c8178d0995819b47be90 (patch) | |
tree | d7d4bb682fc4d3b9607569580810c9c229b48266 | |
parent | 60c661488507d3ff5866e795979bdef64b10f58f (diff) | |
download | abc-3af0f719afa368cafbe7c8178d0995819b47be90.tar.gz abc-3af0f719afa368cafbe7c8178d0995819b47be90.tar.bz2 abc-3af0f719afa368cafbe7c8178d0995819b47be90.zip |
Extending BLIF parser/write to hangle multi-output cells.
-rw-r--r-- | src/base/abc/abcUtil.c | 3 | ||||
-rw-r--r-- | src/base/abci/abcDar.c | 4 | ||||
-rw-r--r-- | src/base/abci/abcPrint.c | 5 | ||||
-rw-r--r-- | src/base/io/ioReadBlif.c | 127 | ||||
-rw-r--r-- | src/base/io/ioReadBlifMv.c | 36 | ||||
-rw-r--r-- | src/base/io/ioWriteBlif.c | 140 | ||||
-rw-r--r-- | src/base/ver/verCore.c | 20 | ||||
-rw-r--r-- | src/map/mapper/mapperSuper.c | 2 | ||||
-rw-r--r-- | src/map/mapper/mapperTree.c | 2 | ||||
-rw-r--r-- | src/map/mapper/mapperTree_old.c | 2 | ||||
-rw-r--r-- | src/map/mio/mio.h | 9 | ||||
-rw-r--r-- | src/map/mio/mioApi.c | 25 | ||||
-rw-r--r-- | src/map/mio/mioRead.c | 13 | ||||
-rw-r--r-- | src/map/mio/mioUtils.c | 35 | ||||
-rw-r--r-- | src/map/scl/sclUtil.c | 2 |
15 files changed, 289 insertions, 136 deletions
diff --git a/src/base/abc/abcUtil.c b/src/base/abc/abcUtil.c index 5a41b109..2ad32dba 100644 --- a/src/base/abc/abcUtil.c +++ b/src/base/abc/abcUtil.c @@ -371,6 +371,9 @@ double Abc_NtkGetMappedArea( Abc_Ntk_t * pNtk ) continue; } TotalArea += Mio_GateReadArea( (Mio_Gate_t *)pNode->pData ); + // assuming that twin gates follow each other + if ( Mio_GateReadTwin(((Mio_Gate_t *)pNode->pData)) != NULL ) + i++; } return TotalArea; } diff --git a/src/base/abci/abcDar.c b/src/base/abci/abcDar.c index 60911e59..6072a9db 100644 --- a/src/base/abci/abcDar.c +++ b/src/base/abci/abcDar.c @@ -3926,7 +3926,7 @@ Abc_Ntk_t * Amap_ManProduceNetwork( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMapping ) int i, k, iPis, iPos, nDupGates; // make sure gates exist in the current library Vec_PtrForEachEntry( Amap_Out_t *, vMapping, pRes, i ) - if ( pRes->pName && Mio_LibraryReadGateByName( pLib, pRes->pName ) == NULL ) + if ( pRes->pName && Mio_LibraryReadGateByName( pLib, pRes->pName, NULL ) == NULL ) { Abc_Print( 1, "Current library does not contain gate \"%s\".\n", pRes->pName ); return NULL; @@ -3945,7 +3945,7 @@ Abc_Ntk_t * Amap_ManProduceNetwork( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMapping ) else { pNodeNew = Abc_NtkCreateNode( pNtkNew ); - pNodeNew->pData = Mio_LibraryReadGateByName( pLib, pRes->pName ); + pNodeNew->pData = Mio_LibraryReadGateByName( pLib, pRes->pName, NULL ); } for ( k = 0; k < pRes->nFans; k++ ) { diff --git a/src/base/abci/abcPrint.c b/src/base/abci/abcPrint.c index 3244a196..5f151b49 100644 --- a/src/base/abci/abcPrint.c +++ b/src/base/abci/abcPrint.c @@ -1013,7 +1013,7 @@ void Abc_NtkPrintGates( Abc_Ntk_t * pNtk, int fUseLibrary ) // clean value of all gates nGates = Mio_LibraryReadGateNum( (Mio_Library_t *)pNtk->pManFunc ); - ppGates = Mio_LibraryReadGatesByName( (Mio_Library_t *)pNtk->pManFunc ); + ppGates = Mio_LibraryReadGateArray( (Mio_Library_t *)pNtk->pManFunc ); for ( i = 0; i < nGates; i++ ) Mio_GateSetValue( ppGates[i], 0 ); @@ -1024,6 +1024,9 @@ void Abc_NtkPrintGates( Abc_Ntk_t * pNtk, int fUseLibrary ) if ( i == 0 ) continue; 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 ) + i++; } // determine the longest gate name diff --git a/src/base/io/ioReadBlif.c b/src/base/io/ioReadBlif.c index 592bee4a..74b2927d 100644 --- a/src/base/io/ioReadBlif.c +++ b/src/base/io/ioReadBlif.c @@ -525,14 +525,22 @@ int Io_ReadBlifNetworkNames( Io_ReadBlif_t * p, Vec_Ptr_t ** pvTokens ) SeeAlso [] ***********************************************************************/ -int Io_ReadBlifReorderFormalNames( Vec_Ptr_t * vTokens, Mio_Gate_t * pGate ) +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 ( nSize - 3 != Mio_GateReadInputs(pGate) ) - return 0; + if ( pTwin == NULL ) + { + if ( nSize - 3 != Mio_GateReadInputs(pGate) ) + return 0; + } + else + { + if ( nSize - 3 != Mio_GateReadInputs(pGate) && nSize - 4 != Mio_GateReadInputs(pGate) ) + return 0; + } // check if the names are in order for ( pGatePin = Mio_GateReadPins(pGate), i = 0; pGatePin; pGatePin = Mio_PinReadNext(pGatePin), i++ ) { @@ -543,12 +551,26 @@ int Io_ReadBlifReorderFormalNames( Vec_Ptr_t * vTokens, Mio_Gate_t * pGate ) continue; break; } - if ( i == nSize - 3 ) - return 1; - // reorder the pins - for ( pGatePin = Mio_GateReadPins(pGate), i = 0; pGatePin; pGatePin = Mio_PinReadNext(pGatePin), i++ ) + if ( pTwin == NULL ) { - pNamePin = Mio_PinReadName(pGatePin); + if ( i == Mio_GateReadInputs(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++ ) { @@ -559,23 +581,55 @@ int Io_ReadBlifReorderFormalNames( Vec_Ptr_t * vTokens, Mio_Gate_t * pGate ) 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 ); } - pNamePin = Mio_GateReadOutName(pGate); - Length = strlen(pNamePin); - for ( k = 2; k < nSize; k++ ) + else { - pName = (char *)Vec_PtrEntry(vTokens, k); - if ( !strncmp( pNamePin, pName, Length ) && pName[Length] == '=' ) + if ( i != Mio_GateReadInputs(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_GateReadInputs(pGate) ) // only one output is available { - Vec_PtrPush( vTokens, pName ); - break; + 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 = Vec_PtrPop( vTokens ); + Vec_PtrPush( vTokens, NULL ); + Vec_PtrPush( vTokens, pName ); + return 1; + } + return 0; } + if ( nSize - 4 == Mio_GateReadInputs(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 ); } - 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 ); return 1; } @@ -618,7 +672,7 @@ int Io_ReadBlifNetworkGate( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) } // get the gate - pGate = Mio_LibraryReadGateByName( pGenlib, (char *)vTokens->pArray[1] ); + pGate = Mio_LibraryReadGateByName( pGenlib, (char *)vTokens->pArray[1], NULL ); if ( pGate == NULL ) { p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); @@ -637,7 +691,7 @@ int Io_ReadBlifNetworkGate( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) } // reorder the formal inputs to be in the same order as in the gate - if ( !Io_ReadBlifReorderFormalNames( vTokens, pGate ) ) + 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] ); @@ -660,12 +714,29 @@ int Io_ReadBlifNetworkGate( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) } // create the node - ppNames = (char **)vTokens->pArray + 2; - nNames = vTokens->nSize - 3; - pNode = Io_ReadCreateNode( p->pNtkCur, ppNames[nNames], ppNames, nNames ); - - // set the pointer to the functionality of the node - Abc_ObjSetData( pNode, pGate ); + 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; } diff --git a/src/base/io/ioReadBlifMv.c b/src/base/io/ioReadBlifMv.c index 57cbb915..bbaad423 100644 --- a/src/base/io/ioReadBlifMv.c +++ b/src/base/io/ioReadBlifMv.c @@ -2090,7 +2090,7 @@ static char * Io_ReadBlifCleanName( char * pName ) ***********************************************************************/ static int Io_MvParseLineGateBlif( Io_MvMod_t * p, Vec_Ptr_t * vTokens ) { - extern int Io_ReadBlifReorderFormalNames( Vec_Ptr_t * vTokens, Mio_Gate_t * pGate ); + extern int Io_ReadBlifReorderFormalNames( Vec_Ptr_t * vTokens, Mio_Gate_t * pGate, Mio_Gate_t * pTwin ); Mio_Library_t * pGenlib; Mio_Gate_t * pGate; Abc_Obj_t * pNode; @@ -2115,7 +2115,7 @@ static int Io_MvParseLineGateBlif( Io_MvMod_t * p, Vec_Ptr_t * vTokens ) } // get the gate - pGate = Mio_LibraryReadGateByName( pGenlib, (char *)vTokens->pArray[1] ); + pGate = Mio_LibraryReadGateByName( pGenlib, (char *)vTokens->pArray[1], NULL ); if ( pGate == NULL ) { sprintf( p->pMan->sError, "Line %d: Cannot find gate \"%s\" in the library.", Io_MvGetLine(p->pMan, pName), (char*)vTokens->pArray[1] ); @@ -2132,7 +2132,7 @@ static int Io_MvParseLineGateBlif( Io_MvMod_t * p, Vec_Ptr_t * vTokens ) } // reorder the formal inputs to be in the same order as in the gate - if ( !Io_ReadBlifReorderFormalNames( vTokens, pGate ) ) + if ( !Io_ReadBlifReorderFormalNames( vTokens, pGate, Mio_GateReadTwin(pGate) ) ) { sprintf( p->pMan->sError, "Line %d: Mismatch in the fanins of gate \"%s\".", Io_MvGetLine(p->pMan, pName), (char*)vTokens->pArray[1] ); return 0; @@ -2141,6 +2141,8 @@ static int Io_MvParseLineGateBlif( Io_MvMod_t * p, Vec_Ptr_t * vTokens ) // remove the formal parameter names for ( i = 2; i < vTokens->nSize; i++ ) { + if ( vTokens->pArray[i] == NULL ) + continue; vTokens->pArray[i] = Io_ReadBlifCleanName( (char *)vTokens->pArray[i] ); if ( vTokens->pArray[i] == NULL ) { @@ -2150,12 +2152,30 @@ static int Io_MvParseLineGateBlif( Io_MvMod_t * p, Vec_Ptr_t * vTokens ) } // create the node - ppNames = (char **)vTokens->pArray + 2; - nNames = vTokens->nSize - 3; - pNode = Io_ReadCreateNode( p->pNtk, ppNames[nNames], ppNames, nNames ); + if ( Mio_GateReadTwin(pGate) == NULL ) + { + nNames = vTokens->nSize - 3; + ppNames = (char **)vTokens->pArray + 2; + pNode = Io_ReadCreateNode( p->pNtk, 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->pNtk, ppNames[nNames], ppNames, nNames ); + Abc_ObjSetData( pNode, pGate ); + } + if ( ppNames[nNames+1] ) + { + pNode = Io_ReadCreateNode( p->pNtk, ppNames[nNames+1], ppNames, nNames ); + Abc_ObjSetData( pNode, Mio_GateReadTwin(pGate) ); + } + } - // set the pointer to the functionality of the node - Abc_ObjSetData( pNode, pGate ); return 1; } diff --git a/src/base/io/ioWriteBlif.c b/src/base/io/ioWriteBlif.c index 54be8434..a8305d07 100644 --- a/src/base/io/ioWriteBlif.c +++ b/src/base/io/ioWriteBlif.c @@ -37,9 +37,8 @@ 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, int Length ); static void Io_NtkWriteNodeFanins( FILE * pFile, Abc_Obj_t * pNode ); -static void Io_NtkWriteNode( FILE * pFile, Abc_Obj_t * pNode, int Length ); +static int Io_NtkWriteNode( FILE * pFile, Abc_Obj_t * pNode, int Length ); static void Io_NtkWriteLatch( FILE * pFile, Abc_Obj_t * pLatch ); //////////////////////////////////////////////////////////////////////// @@ -251,7 +250,8 @@ void Io_NtkWriteOne( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches, int fBb2 Abc_NtkForEachNode( pNtk, pNode, i ) { Extra_ProgressBarUpdate( pProgress, i, NULL ); - Io_NtkWriteNode( pFile, pNode, Length ); + if ( Io_NtkWriteNode( pFile, pNode, Length ) ) // skip the next node + i++; } Extra_ProgressBarStop( pProgress ); } @@ -462,7 +462,7 @@ void Io_NtkWriteLatch( FILE * pFile, Abc_Obj_t * pLatch ) /**Function************************************************************* - Synopsis [Write the node into a file.] + Synopsis [Writes the primary input list.] Description [] @@ -471,24 +471,47 @@ void Io_NtkWriteLatch( FILE * pFile, Abc_Obj_t * pLatch ) SeeAlso [] ***********************************************************************/ -void Io_NtkWriteNode( FILE * pFile, Abc_Obj_t * pNode, int Length ) +void Io_NtkWriteNodeFanins( FILE * pFile, Abc_Obj_t * pNode ) { - if ( Abc_NtkHasMapping(pNode->pNtk) ) + Abc_Obj_t * pNet; + int LineLength; + int AddedLength; + int NameCounter; + char * pName; + int i; + + LineLength = 6; + NameCounter = 0; + Abc_ObjForEachFanin( pNode, pNet, i ) { - // write the .gate line - fprintf( pFile, ".gate" ); - Io_NtkWriteNodeGate( pFile, pNode, Length ); - fprintf( pFile, "\n" ); + // get the fanin name + pName = Abc_ObjName(pNet); + // get the line length after the fanin name is written + AddedLength = strlen(pName) + 1; + if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH ) + { // write the line extender + fprintf( pFile, " \\\n" ); + // reset the line length + LineLength = 0; + NameCounter = 0; + } + fprintf( pFile, " %s", pName ); + LineLength += AddedLength; + NameCounter++; } - else - { - // write the .names line - fprintf( pFile, ".names" ); - Io_NtkWriteNodeFanins( pFile, pNode ); - fprintf( pFile, "\n" ); - // write the cubes - fprintf( pFile, "%s", (char*)Abc_ObjData(pNode) ); + + // get the output name + pName = Abc_ObjName(Abc_ObjFanout0(pNode)); + // get the line length after the output name is written + AddedLength = strlen(pName) + 1; + if ( NameCounter && LineLength + AddedLength > 75 ) + { // write the line extender + fprintf( pFile, " \\\n" ); + // reset the line length + LineLength = 0; + NameCounter = 0; } + fprintf( pFile, " %s", pName ); } /**Function************************************************************* @@ -502,10 +525,12 @@ void Io_NtkWriteNode( FILE * pFile, Abc_Obj_t * pNode, int Length ) SeeAlso [] ***********************************************************************/ -void Io_NtkWriteNodeGate( FILE * pFile, Abc_Obj_t * pNode, int Length ) +int Io_NtkWriteNodeGate( FILE * pFile, Abc_Obj_t * pNode, int Length ) { 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) ); @@ -513,11 +538,33 @@ void Io_NtkWriteNodeGate( FILE * pFile, Abc_Obj_t * pNode, int Length ) fprintf( pFile, "%s=%s ", Mio_PinReadName(pGatePin), Abc_ObjName( Abc_ObjFanin(pNode,i) ) ); assert ( i == Abc_ObjFaninNum(pNode) ); 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)) ) + { + printf( "Warning: Missing second output of gate \"%s\".\n", Mio_GateReadName(pGate) ); + return 0; + } + fprintf( pFile, " %s=%s", Mio_GateReadOutName(pGate2), Abc_ObjName( Abc_ObjFanout0(pNode2) ) ); + return 1; } /**Function************************************************************* - Synopsis [Writes the primary input list.] + Synopsis [Write the node into a file.] Description [] @@ -526,47 +573,26 @@ void Io_NtkWriteNodeGate( FILE * pFile, Abc_Obj_t * pNode, int Length ) SeeAlso [] ***********************************************************************/ -void Io_NtkWriteNodeFanins( FILE * pFile, Abc_Obj_t * pNode ) +int Io_NtkWriteNode( FILE * pFile, Abc_Obj_t * pNode, int Length ) { - Abc_Obj_t * pNet; - int LineLength; - int AddedLength; - int NameCounter; - char * pName; - int i; - - LineLength = 6; - NameCounter = 0; - Abc_ObjForEachFanin( pNode, pNet, i ) + int RetValue = 0; + if ( Abc_NtkHasMapping(pNode->pNtk) ) { - // get the fanin name - pName = Abc_ObjName(pNet); - // get the line length after the fanin name is written - AddedLength = strlen(pName) + 1; - if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH ) - { // write the line extender - fprintf( pFile, " \\\n" ); - // reset the line length - LineLength = 0; - NameCounter = 0; - } - fprintf( pFile, " %s", pName ); - LineLength += AddedLength; - NameCounter++; + // write the .gate line + fprintf( pFile, ".gate" ); + RetValue = Io_NtkWriteNodeGate( pFile, pNode, Length ); + fprintf( pFile, "\n" ); } - - // get the output name - pName = Abc_ObjName(Abc_ObjFanout0(pNode)); - // get the line length after the output name is written - AddedLength = strlen(pName) + 1; - if ( NameCounter && LineLength + AddedLength > 75 ) - { // write the line extender - fprintf( pFile, " \\\n" ); - // reset the line length - LineLength = 0; - NameCounter = 0; + else + { + // write the .names line + fprintf( pFile, ".names" ); + Io_NtkWriteNodeFanins( pFile, pNode ); + fprintf( pFile, "\n" ); + // write the cubes + fprintf( pFile, "%s", (char*)Abc_ObjData(pNode) ); } - fprintf( pFile, " %s", pName ); + return RetValue; } /**Function************************************************************* diff --git a/src/base/ver/verCore.c b/src/base/ver/verCore.c index 4e131c85..aeea1984 100644 --- a/src/base/ver/verCore.c +++ b/src/base/ver/verCore.c @@ -490,7 +490,7 @@ int Ver_ParseModule( Ver_Man_t * pMan ) RetValue = Ver_ParseInitial( pMan, pNtk ); else if ( !strcmp( pWord, "endmodule" ) ) break; - else if ( pMan->pDesign->pGenlib && (pGate = Mio_LibraryReadGateByName((Mio_Library_t *)pMan->pDesign->pGenlib, pWord)) ) // current design + else if ( pMan->pDesign->pGenlib && (pGate = Mio_LibraryReadGateByName((Mio_Library_t *)pMan->pDesign->pGenlib, pWord, NULL)) ) // current design RetValue = Ver_ParseGate( pMan, pNtk, pGate ); // else if ( pMan->pDesign->pLibrary && st_lookup(pMan->pDesign->pLibrary->tModules, pWord, (char**)&pNtkTemp) ) // gate library // RetValue = Ver_ParseGate( pMan, pNtkTemp ); @@ -1506,6 +1506,8 @@ int Ver_FindGateInput( Mio_Gate_t * pGate, char * pName ) return i; if ( strcmp(pName, Mio_GateReadOutName(pGate)) == 0 ) return i; + if ( Mio_GateReadTwin(pGate) && strcmp(pName, Mio_GateReadOutName(Mio_GateReadTwin(pGate))) == 0 ) + return i+1; return -1; } @@ -1523,7 +1525,7 @@ int Ver_FindGateInput( Mio_Gate_t * pGate, char * pName ) int Ver_ParseGate( Ver_Man_t * pMan, Abc_Ntk_t * pNtk, Mio_Gate_t * pGate ) { Ver_Stream_t * p = pMan->pReader; - Abc_Obj_t * pNetActual, * pNode; + Abc_Obj_t * pNetActual, * pNode, * pNode2 = NULL; char * pWord, Symbol; int Input, i, nFanins = Mio_GateReadInputs(pGate); @@ -1555,7 +1557,11 @@ int Ver_ParseGate( Ver_Man_t * pMan, Abc_Ntk_t * pNtk, Mio_Gate_t * pGate ) // start the node pNode = Abc_NtkCreateNode( pNtk ); pNode->pData = pGate; - + if ( Mio_GateReadTwin(pGate) ) + { + pNode2 = Abc_NtkCreateNode( pNtk ); + pNode2->pData = Mio_GateReadTwin(pGate); + } // parse pairs of formal/actural inputs Vec_IntClear( pMan->vPerm ); while ( 1 ) @@ -1628,9 +1634,15 @@ int Ver_ParseGate( Ver_Man_t * pMan, Abc_Ntk_t * pNtk, Mio_Gate_t * pGate ) { Vec_IntPush( pMan->vPerm, Input ); Abc_ObjAddFanin( pNode, pNetActual ); // fanin + if ( pNode2 ) + Abc_ObjAddFanin( pNode2, pNetActual ); // fanin } - else + else if ( Input == nFanins ) Abc_ObjAddFanin( pNetActual, pNode ); // fanout + else if ( Input == nFanins + 1 ) + Abc_ObjAddFanin( pNetActual, pNode2 ); // fanout + else + assert( 0 ); // check if it is the end of gate Ver_ParseSkipComments( pMan ); diff --git a/src/map/mapper/mapperSuper.c b/src/map/mapper/mapperSuper.c index efcb90ea..bf351a54 100644 --- a/src/map/mapper/mapperSuper.c +++ b/src/map/mapper/mapperSuper.c @@ -382,7 +382,7 @@ void Map_LibraryComputeTruth_rec( Map_SuperLib_t * pLib, char * pFormula, unsign for ( i = 0; i < nStrings; i++ ) Map_LibraryComputeTruth_rec( pLib, pStrings[i], uTruthsIn, uTruthsFanins[i] ); // get the root supergate - pMioGate = Mio_LibraryReadGateByName( pLib->pGenlib, pGateName ); + pMioGate = Mio_LibraryReadGateByName( pLib->pGenlib, pGateName, NULL ); if ( pMioGate == NULL ) printf( "A supergate contains gate \"%s\" that is not in \"%s\".\n", pGateName, Mio_LibraryReadName(pLib->pGenlib) ); // derive the functionality of the output of the supergate diff --git a/src/map/mapper/mapperTree.c b/src/map/mapper/mapperTree.c index 2244fa26..36ad4920 100644 --- a/src/map/mapper/mapperTree.c +++ b/src/map/mapper/mapperTree.c @@ -302,7 +302,7 @@ Map_Super_t * Map_LibraryReadGateTree( Map_SuperLib_t * pLib, char * pBuffer, in } // read the root gate - pGate->pRoot = Mio_LibraryReadGateByName( pLib->pGenlib, pTemp ); + pGate->pRoot = Mio_LibraryReadGateByName( pLib->pGenlib, pTemp, NULL ); if ( pGate->pRoot == NULL ) { printf( "Cannot read the root gate names %s.\n", pTemp ); diff --git a/src/map/mapper/mapperTree_old.c b/src/map/mapper/mapperTree_old.c index 1a76b267..eafba376 100644 --- a/src/map/mapper/mapperTree_old.c +++ b/src/map/mapper/mapperTree_old.c @@ -299,7 +299,7 @@ Map_Super_t * Map_LibraryReadGateTree( Map_SuperLib_t * pLib, char * pBuffer, in } // read the root gate - pGate->pRoot = Mio_LibraryReadGateByName( pLib->pGenlib, pTemp ); + pGate->pRoot = Mio_LibraryReadGateByName( pLib->pGenlib, pTemp, NULL ); if ( pGate->pRoot == NULL ) { printf( "Cannot read the root gate names %s.\n", pTemp ); diff --git a/src/map/mio/mio.h b/src/map/mio/mio.h index 7bccc3a1..3aff8790 100644 --- a/src/map/mio/mio.h +++ b/src/map/mio/mio.h @@ -68,8 +68,8 @@ static inline char * Mio_UtilStrsav( char * s ) { return s ? strcpy(ABC_A for ( Pin = Mio_GateReadPins(Gate); \ Pin; \ Pin = Mio_PinReadNext(Pin) ) -#define Mio_GateForEachPinSafe( Gate, Pin, Pin2 ) \ - for ( Pin = Mio_GateReadPins(Gate), \ +#define Mio_GateForEachPinSafe( Gate, Pin, Pin2 ) \ + for ( Pin = Mio_GateReadPins(Gate), \ Pin2 = (Pin? Mio_PinReadNext(Pin): NULL); \ Pin; \ Pin = Pin2, \ @@ -83,8 +83,8 @@ static inline char * Mio_UtilStrsav( char * s ) { return s ? strcpy(ABC_A extern char * Mio_LibraryReadName ( Mio_Library_t * pLib ); extern int Mio_LibraryReadGateNum ( Mio_Library_t * pLib ); extern Mio_Gate_t * Mio_LibraryReadGates ( Mio_Library_t * pLib ); -extern Mio_Gate_t ** Mio_LibraryReadGatesByName( Mio_Library_t * pLib ); -extern Mio_Gate_t * Mio_LibraryReadGateByName ( Mio_Library_t * pLib, char * pName ); +extern Mio_Gate_t ** Mio_LibraryReadGateArray ( Mio_Library_t * pLib ); +extern Mio_Gate_t * Mio_LibraryReadGateByName ( Mio_Library_t * pLib, char * pName, char * pOutName ); extern char * Mio_LibraryReadSopByName ( Mio_Library_t * pLib, char * pName ); extern Mio_Gate_t * Mio_LibraryReadConst0 ( Mio_Library_t * pLib ); extern Mio_Gate_t * Mio_LibraryReadConst1 ( Mio_Library_t * pLib ); @@ -110,6 +110,7 @@ extern char * Mio_GateReadForm ( Mio_Gate_t * pGate ); extern Mio_Pin_t * Mio_GateReadPins ( Mio_Gate_t * pGate ); extern Mio_Library_t * Mio_GateReadLib ( Mio_Gate_t * pGate ); extern Mio_Gate_t * Mio_GateReadNext ( Mio_Gate_t * pGate ); +extern Mio_Gate_t * Mio_GateReadTwin ( Mio_Gate_t * pGate ); extern int Mio_GateReadInputs ( Mio_Gate_t * pGate ); extern double Mio_GateReadDelayMax ( Mio_Gate_t * pGate ); extern char * Mio_GateReadSop ( Mio_Gate_t * pGate ); diff --git a/src/map/mio/mioApi.c b/src/map/mio/mioApi.c index d2357e7d..2fe23c2c 100644 --- a/src/map/mio/mioApi.c +++ b/src/map/mio/mioApi.c @@ -40,13 +40,12 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ -char * Mio_LibraryReadName ( Mio_Library_t * pLib ) { return pLib->pName; } -int Mio_LibraryReadGateNum ( Mio_Library_t * pLib ) { return pLib->nGates; } -Mio_Gate_t * Mio_LibraryReadGates ( Mio_Library_t * pLib ) { return pLib->pGates; } -Mio_Gate_t ** Mio_LibraryReadGatesByName ( Mio_Library_t * pLib ) { return pLib->ppGatesName;} -//DdManager * Mio_LibraryReadDd ( Mio_Library_t * pLib ) { return pLib->dd; } -Mio_Gate_t * Mio_LibraryReadBuf ( Mio_Library_t * pLib ) { return pLib->pGateBuf; } -Mio_Gate_t * Mio_LibraryReadInv ( Mio_Library_t * pLib ) { return pLib->pGateInv; } +char * Mio_LibraryReadName ( Mio_Library_t * pLib ) { return pLib->pName; } +int Mio_LibraryReadGateNum ( Mio_Library_t * pLib ) { return pLib->nGates; } +Mio_Gate_t * Mio_LibraryReadGates ( Mio_Library_t * pLib ) { return pLib->pGates; } +Mio_Gate_t ** Mio_LibraryReadGateArray ( Mio_Library_t * pLib ) { return pLib->ppGatesName;} +Mio_Gate_t * Mio_LibraryReadBuf ( Mio_Library_t * pLib ) { return pLib->pGateBuf; } +Mio_Gate_t * Mio_LibraryReadInv ( Mio_Library_t * pLib ) { return pLib->pGateInv; } Mio_Gate_t * Mio_LibraryReadConst0 ( Mio_Library_t * pLib ) { return pLib->pGate0; } Mio_Gate_t * Mio_LibraryReadConst1 ( Mio_Library_t * pLib ) { return pLib->pGate1; } Mio_Gate_t * Mio_LibraryReadNand2 ( Mio_Library_t * pLib ) { return pLib->pGateNand2; } @@ -97,11 +96,17 @@ int Mio_LibraryReadGateNameMax( Mio_Library_t * pLib ) SeeAlso [] ***********************************************************************/ -Mio_Gate_t * Mio_LibraryReadGateByName( Mio_Library_t * pLib, char * pName ) +Mio_Gate_t * Mio_LibraryReadGateByName( Mio_Library_t * pLib, char * pName, char * pOutName ) { Mio_Gate_t * pGate; - if ( st_lookup( pLib->tName2Gate, pName, (char **)&pGate ) ) + if ( !st_lookup( pLib->tName2Gate, pName, (char **)&pGate ) ) + return NULL; + if ( pOutName == NULL ) + return pGate; + if ( !strcmp(pGate->pOutName, pOutName) ) return pGate; + if ( pGate->pTwin && !strcmp(pGate->pTwin->pOutName, pOutName) ) + return pGate->pTwin; return NULL; } @@ -142,10 +147,10 @@ char * Mio_GateReadForm ( Mio_Gate_t * pGate ) { return Mio_Pin_t * Mio_GateReadPins ( Mio_Gate_t * pGate ) { return pGate->pPins; } Mio_Library_t * Mio_GateReadLib ( Mio_Gate_t * pGate ) { return pGate->pLib; } Mio_Gate_t * Mio_GateReadNext ( Mio_Gate_t * pGate ) { return pGate->pNext; } +Mio_Gate_t * Mio_GateReadTwin ( Mio_Gate_t * pGate ) { return pGate->pTwin; } int Mio_GateReadInputs ( Mio_Gate_t * pGate ) { return pGate->nInputs; } double Mio_GateReadDelayMax( Mio_Gate_t * pGate ) { return pGate->dDelayMax; } char * Mio_GateReadSop ( Mio_Gate_t * pGate ) { return pGate->pSop; } -//DdNode * Mio_GateReadFunc ( Mio_Gate_t * pGate ) { return pGate->bFunc; } word Mio_GateReadTruth ( Mio_Gate_t * pGate ) { return pGate->nInputs <= 6 ? pGate->uTruth : 0; } word * Mio_GateReadTruthP ( Mio_Gate_t * pGate ) { return pGate->nInputs <= 6 ? NULL: pGate->pTruth; } int Mio_GateReadValue ( Mio_Gate_t * pGate ) { return pGate->Value; } diff --git a/src/map/mio/mioRead.c b/src/map/mio/mioRead.c index 87fb68e2..53ea7d2d 100644 --- a/src/map/mio/mioRead.c +++ b/src/map/mio/mioRead.c @@ -233,10 +233,15 @@ int Mio_LibraryReadInternal( Mio_Library_t * pLib, char * pBuffer, int fExtended st_insert( pLib->tName2Gate, pGate->pName, (char *)pGate ); else { - Mio_Gate_t * pBase = Mio_LibraryReadGateByName( pLib, pGate->pName ); - pBase->pTwin = pGate; - pGate->pTwin = pBase; - printf( "Gate \"%s\" appears more than once. Creating multi-output gate.\n", pGate->pName ); + Mio_Gate_t * pBase = Mio_LibraryReadGateByName( pLib, pGate->pName, NULL ); + if ( pBase->pTwin != NULL ) + { + printf( "Gates with more than 2 outputs are not supported.\n" ); + continue; + } + pBase->pTwin = pGate; + pGate->pTwin = pBase; + printf( "Gate \"%s\" appears two times. Creating a 2-output gate.\n", pGate->pName ); } } } diff --git a/src/map/mio/mioUtils.c b/src/map/mio/mioUtils.c index fcc59dcc..41b03d7d 100644 --- a/src/map/mio/mioUtils.c +++ b/src/map/mio/mioUtils.c @@ -164,6 +164,18 @@ int Mio_CheckPins( Mio_Pin_t * pPin1, Mio_Pin_t * pPin2 ) return 0; return 1; } +int Mio_CheckGates( Mio_Library_t * pLib ) +{ + Mio_Gate_t * pGate; + Mio_Pin_t * pPin0 = NULL, * pPin = NULL; + Mio_LibraryForEachGate( pLib, pGate ) + Mio_GateForEachPin( pGate, pPin ) + if ( Mio_CheckPins( pPin0, pPin ) ) + pPin0 = pPin; + else + return 0; + return 1; +} /**Function************************************************************* @@ -182,7 +194,7 @@ void Mio_WritePin( FILE * pFile, Mio_Pin_t * pPin, int NameLen, int fAllPins ) if ( fAllPins ) fprintf( pFile, "PIN * " ); else - fprintf( pFile, "\n PIN %*s ", NameLen, pPin->pName ); + fprintf( pFile, "\n PIN %*s ", NameLen, pPin->pName ); fprintf( pFile, "%7s ", pPhaseNames[pPin->Phase] ); fprintf( pFile, "%3d ", (int)pPin->dLoadInput ); fprintf( pFile, "%3d ", (int)pPin->dLoadMax ); @@ -203,29 +215,23 @@ void Mio_WritePin( FILE * pFile, Mio_Pin_t * pPin, int NameLen, int fAllPins ) SeeAlso [] ***********************************************************************/ -void Mio_WriteGate( FILE * pFile, Mio_Gate_t * pGate, int GateLen, int NameLen, int FormLen, int fPrintSops ) +void Mio_WriteGate( FILE * pFile, Mio_Gate_t * pGate, int GateLen, int NameLen, int FormLen, int fPrintSops, int fAllPins ) { char Buffer[5000]; - Mio_Pin_t * pPin = NULL, * pPin0 = NULL; + Mio_Pin_t * pPin; assert( NameLen+FormLen+2 < 5000 ); sprintf( Buffer, "%s=%s;", pGate->pOutName, pGate->pForm ); fprintf( pFile, "GATE %-*s ", GateLen, pGate->pName ); fprintf( pFile, "%8.2f ", pGate->dArea ); - fprintf( pFile, "%-*s ", NameLen+FormLen+2, Buffer ); - // compare pins and decide if their properties are the same - Mio_GateForEachPin( pGate, pPin ) - if ( Mio_CheckPins( pPin0, pPin ) ) - pPin0 = pPin; - else - break; + fprintf( pFile, "%-*s ", Abc_MinInt(NameLen+FormLen+2, 30), Buffer ); // print the pins if ( fPrintSops ) fprintf( pFile, "%s", pGate->pSop? pGate->pSop : "unspecified\n" ); - if ( pPin != NULL ) // different pins + if ( fAllPins && pGate->pPins ) // equal pins + Mio_WritePin( pFile, pGate->pPins, NameLen, 1 ); + else // different pins Mio_GateForEachPin( pGate, pPin ) Mio_WritePin( pFile, pPin, NameLen, 0 ); - else if ( pPin0 != NULL ) // equal pins - Mio_WritePin( pFile, pPin0, NameLen, 1 ); fprintf( pFile, "\n" ); } @@ -245,6 +251,7 @@ void Mio_WriteLibrary( FILE * pFile, Mio_Library_t * pLib, int fPrintSops ) Mio_Gate_t * pGate; Mio_Pin_t * pPin; int i, GateLen = 0, NameLen = 0, FormLen = 0; + int fAllPins = Mio_CheckGates( pLib ); Mio_LibraryForEachGate( pLib, pGate ) { GateLen = Abc_MaxInt( GateLen, strlen(pGate->pName) ); @@ -255,7 +262,7 @@ void Mio_WriteLibrary( FILE * pFile, Mio_Library_t * pLib, int fPrintSops ) } fprintf( pFile, "# The genlib library \"%s\".\n", pLib->pName ); for ( i = 0; i < pLib->nGates; i++ ) - Mio_WriteGate( pFile, pLib->ppGates0[i], GateLen, NameLen, FormLen, fPrintSops ); + Mio_WriteGate( pFile, pLib->ppGates0[i], GateLen, NameLen, FormLen, fPrintSops, fAllPins ); } /**Function************************************************************* diff --git a/src/map/scl/sclUtil.c b/src/map/scl/sclUtil.c index a9b94902..dc513d56 100644 --- a/src/map/scl/sclUtil.c +++ b/src/map/scl/sclUtil.c @@ -232,7 +232,7 @@ void Abc_SclManSetGates( SC_Lib * pLib, Abc_Ntk_t * p, Vec_Int_t * vGates ) { SC_Cell * pCell = SC_LibCell( pLib, Vec_IntEntry(vGates, Abc_ObjId(pObj)) ); assert( pCell->n_inputs == Abc_ObjFaninNum(pObj) ); - pObj->pData = Mio_LibraryReadGateByName( (Mio_Library_t *)p->pManFunc, pCell->pName ); + pObj->pData = Mio_LibraryReadGateByName( (Mio_Library_t *)p->pManFunc, pCell->pName, NULL ); //printf( "Found gate %s\n", pCell->name ); } } |