Commit 3af0f719 by Alan Mishchenko

Extending BLIF parser/write to hangle multi-output cells.

parent 60c66148
......@@ -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;
}
......
......@@ -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++ )
{
......
......@@ -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
......
......@@ -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 ( 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,7 +551,9 @@ int Io_ReadBlifReorderFormalNames( Vec_Ptr_t * vTokens, Mio_Gate_t * pGate )
continue;
break;
}
if ( i == nSize - 3 )
if ( pTwin == NULL )
{
if ( i == Mio_GateReadInputs(pGate) )
return 1;
// reorder the pins
for ( pGatePin = Mio_GateReadPins(pGate), i = 0; pGatePin; pGatePin = Mio_PinReadNext(pGatePin), i++ )
......@@ -576,6 +586,50 @@ int Io_ReadBlifReorderFormalNames( Vec_Ptr_t * vTokens, Mio_Gate_t * pGate )
Vec_PtrForEachEntryStart( char *, vTokens, pName, k, nSize )
Vec_PtrWriteEntry( vTokens, k - nSize + 2, pName );
Vec_PtrShrink( vTokens, nSize );
}
else
{
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
{
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 );
}
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;
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 );
// set the pointer to the functionality of the node
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;
}
......
......@@ -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;
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 );
// set the pointer to the functionality of the node
Abc_ObjSetData( pNode, pGate );
}
if ( ppNames[nNames+1] )
{
pNode = Io_ReadCreateNode( p->pNtk, ppNames[nNames+1], ppNames, nNames );
Abc_ObjSetData( pNode, Mio_GateReadTwin(pGate) );
}
}
return 1;
}
......
......@@ -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;
}
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 );
LineLength += AddedLength;
NameCounter++;
}
// 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*************************************************************
......
......@@ -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 );
......
......@@ -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
......
......@@ -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 );
......
......@@ -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 );
......
......@@ -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 );
......
......@@ -43,8 +43,7 @@ ABC_NAMESPACE_IMPL_START
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_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; }
......@@ -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; }
......
......@@ -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 );
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 more than once. Creating multi-output gate.\n", pGate->pName );
printf( "Gate \"%s\" appears two times. Creating a 2-output gate.\n", pGate->pName );
}
}
}
......
......@@ -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*************************************************************
......@@ -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*************************************************************
......
......@@ -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 );
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment