summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2012-09-19 16:28:06 -0700
committerAlan Mishchenko <alanmi@berkeley.edu>2012-09-19 16:28:06 -0700
commit3af0f719afa368cafbe7c8178d0995819b47be90 (patch)
treed7d4bb682fc4d3b9607569580810c9c229b48266
parent60c661488507d3ff5866e795979bdef64b10f58f (diff)
downloadabc-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.c3
-rw-r--r--src/base/abci/abcDar.c4
-rw-r--r--src/base/abci/abcPrint.c5
-rw-r--r--src/base/io/ioReadBlif.c127
-rw-r--r--src/base/io/ioReadBlifMv.c36
-rw-r--r--src/base/io/ioWriteBlif.c140
-rw-r--r--src/base/ver/verCore.c20
-rw-r--r--src/map/mapper/mapperSuper.c2
-rw-r--r--src/map/mapper/mapperTree.c2
-rw-r--r--src/map/mapper/mapperTree_old.c2
-rw-r--r--src/map/mio/mio.h9
-rw-r--r--src/map/mio/mioApi.c25
-rw-r--r--src/map/mio/mioRead.c13
-rw-r--r--src/map/mio/mioUtils.c35
-rw-r--r--src/map/scl/sclUtil.c2
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 );
}
}