Commit 480ca14c by Alan Mishchenko

Extending Liberty parser to handle multi-output cells.

parent 3af0f719
...@@ -661,6 +661,8 @@ extern ABC_DLL int Abc_LibFindTopLevelModels( Abc_Lib_t * pLib ); ...@@ -661,6 +661,8 @@ extern ABC_DLL int Abc_LibFindTopLevelModels( Abc_Lib_t * pLib );
extern ABC_DLL Abc_Ntk_t * Abc_LibDeriveRoot( Abc_Lib_t * pLib ); extern ABC_DLL Abc_Ntk_t * Abc_LibDeriveRoot( Abc_Lib_t * pLib );
/*=== abcLog.c ==========================================================*/ /*=== abcLog.c ==========================================================*/
extern ABC_DLL void Abc_NtkWriteLogFile( char * pFileName, Abc_Cex_t * pSeqCex, int Status, int nFrames, char * pCommand ); extern ABC_DLL void Abc_NtkWriteLogFile( char * pFileName, Abc_Cex_t * pSeqCex, int Status, int nFrames, char * pCommand );
/*=== abcMap.c ==========================================================*/
extern ABC_DLL Abc_Obj_t * Abc_NtkFetchTwinNode( Abc_Obj_t * pNode );
/*=== abcMiter.c ==========================================================*/ /*=== abcMiter.c ==========================================================*/
extern ABC_DLL int Abc_NtkMinimumBase( Abc_Ntk_t * pNtk ); extern ABC_DLL int Abc_NtkMinimumBase( Abc_Ntk_t * pNtk );
extern ABC_DLL int Abc_NodeMinimumBase( Abc_Obj_t * pNode ); extern ABC_DLL int Abc_NodeMinimumBase( Abc_Obj_t * pNode );
......
...@@ -357,22 +357,22 @@ int Abc_NtkGetClauseNum( Abc_Ntk_t * pNtk ) ...@@ -357,22 +357,22 @@ int Abc_NtkGetClauseNum( Abc_Ntk_t * pNtk )
***********************************************************************/ ***********************************************************************/
double Abc_NtkGetMappedArea( Abc_Ntk_t * pNtk ) double Abc_NtkGetMappedArea( Abc_Ntk_t * pNtk )
{ {
Abc_Obj_t * pNode; Abc_Obj_t * pObj;
double TotalArea; double TotalArea;
int i; int i;
assert( Abc_NtkHasMapping(pNtk) ); assert( Abc_NtkHasMapping(pNtk) );
TotalArea = 0.0; TotalArea = 0.0;
Abc_NtkForEachNode( pNtk, pNode, i ) Abc_NtkForEachNode( pNtk, pObj, i )
{ {
// assert( pNode->pData ); // assert( pObj->pData );
if ( pNode->pData == NULL ) if ( pObj->pData == NULL )
{ {
printf( "Node without mapping is encountered.\n" ); printf( "Node without mapping is encountered.\n" );
continue; continue;
} }
TotalArea += Mio_GateReadArea( (Mio_Gate_t *)pNode->pData ); TotalArea += Mio_GateReadArea( (Mio_Gate_t *)pObj->pData );
// assuming that twin gates follow each other // assuming that twin gates follow each other
if ( Mio_GateReadTwin(((Mio_Gate_t *)pNode->pData)) != NULL ) if ( Abc_NtkFetchTwinNode(pObj) )
i++; i++;
} }
return TotalArea; return TotalArea;
......
...@@ -682,6 +682,35 @@ Abc_Obj_t * Abc_NodeFromMapSuperChoice_rec( Abc_Ntk_t * pNtkNew, Map_Super_t * p ...@@ -682,6 +682,35 @@ Abc_Obj_t * Abc_NodeFromMapSuperChoice_rec( Abc_Ntk_t * pNtkNew, Map_Super_t * p
return pNodeNew; return pNodeNew;
} }
/**Function*************************************************************
Synopsis [Returns the twin node if it exists.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t * Abc_NtkFetchTwinNode( Abc_Obj_t * pNode )
{
Abc_Obj_t * pNode2;
Mio_Gate_t * pGate = (Mio_Gate_t *)pNode->pData;
assert( Abc_NtkHasMapping(pNode->pNtk) );
if ( pGate == NULL || Mio_GateReadTwin(pGate) == NULL )
return NULL;
// assuming the twin node is following next
if ( (int)Abc_ObjId(pNode) == Abc_NtkObjNumMax(pNode->pNtk) - 1 )
return NULL;
pNode2 = Abc_NtkObj( pNode->pNtk, Abc_ObjId(pNode) + 1 );
if ( pNode2 == NULL || !Abc_ObjIsNode(pNode2) || Abc_ObjFaninNum(pNode) != Abc_ObjFaninNum(pNode2) )
return NULL;
if ( Mio_GateReadTwin(pGate) != (Mio_Gate_t *)pNode2->pData )
return NULL;
return pNode2;
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// END OF FILE /// /// END OF FILE ///
......
...@@ -1025,7 +1025,7 @@ void Abc_NtkPrintGates( Abc_Ntk_t * pNtk, int fUseLibrary ) ...@@ -1025,7 +1025,7 @@ void Abc_NtkPrintGates( Abc_Ntk_t * pNtk, int fUseLibrary )
Mio_GateSetValue( (Mio_Gate_t *)pObj->pData, 1 + Mio_GateReadValue((Mio_Gate_t *)pObj->pData) ); Mio_GateSetValue( (Mio_Gate_t *)pObj->pData, 1 + Mio_GateReadValue((Mio_Gate_t *)pObj->pData) );
CounterTotal++; CounterTotal++;
// assuming that twin gates follow each other // assuming that twin gates follow each other
if ( Mio_GateReadTwin(((Mio_Gate_t *)pObj->pData)) != NULL ) if ( Abc_NtkFetchTwinNode(pObj) )
i++; i++;
} }
......
...@@ -514,6 +514,7 @@ void Io_NtkWriteNodeFanins( FILE * pFile, Abc_Obj_t * pNode ) ...@@ -514,6 +514,7 @@ void Io_NtkWriteNodeFanins( FILE * pFile, Abc_Obj_t * pNode )
fprintf( pFile, " %s", pName ); fprintf( pFile, " %s", pName );
} }
/**Function************************************************************* /**Function*************************************************************
Synopsis [Writes the primary input list.] Synopsis [Writes the primary input list.]
...@@ -527,12 +528,11 @@ void Io_NtkWriteNodeFanins( FILE * pFile, Abc_Obj_t * pNode ) ...@@ -527,12 +528,11 @@ void Io_NtkWriteNodeFanins( FILE * pFile, Abc_Obj_t * pNode )
***********************************************************************/ ***********************************************************************/
int Io_NtkWriteNodeGate( FILE * pFile, Abc_Obj_t * pNode, int Length ) int Io_NtkWriteNodeGate( FILE * pFile, Abc_Obj_t * pNode, int Length )
{ {
static int fReport = 0;
Mio_Gate_t * pGate = (Mio_Gate_t *)pNode->pData; Mio_Gate_t * pGate = (Mio_Gate_t *)pNode->pData;
Mio_Gate_t * pGate2;
Mio_Pin_t * pGatePin; Mio_Pin_t * pGatePin;
Abc_Obj_t * pNode2; Abc_Obj_t * pNode2;
int i; int i;
// write the node
fprintf( pFile, " %-*s ", Length, Mio_GateReadName(pGate) ); fprintf( pFile, " %-*s ", Length, Mio_GateReadName(pGate) );
for ( pGatePin = Mio_GateReadPins(pGate), i = 0; pGatePin; pGatePin = Mio_PinReadNext(pGatePin), i++ ) for ( pGatePin = Mio_GateReadPins(pGate), i = 0; pGatePin; pGatePin = Mio_PinReadNext(pGatePin), i++ )
fprintf( pFile, "%s=%s ", Mio_PinReadName(pGatePin), Abc_ObjName( Abc_ObjFanin(pNode,i) ) ); fprintf( pFile, "%s=%s ", Mio_PinReadName(pGatePin), Abc_ObjName( Abc_ObjFanin(pNode,i) ) );
...@@ -540,25 +540,14 @@ int Io_NtkWriteNodeGate( FILE * pFile, Abc_Obj_t * pNode, int Length ) ...@@ -540,25 +540,14 @@ int Io_NtkWriteNodeGate( FILE * pFile, Abc_Obj_t * pNode, int Length )
fprintf( pFile, "%s=%s", Mio_GateReadOutName(pGate), Abc_ObjName( Abc_ObjFanout0(pNode) ) ); fprintf( pFile, "%s=%s", Mio_GateReadOutName(pGate), Abc_ObjName( Abc_ObjFanout0(pNode) ) );
if ( Mio_GateReadTwin(pGate) == NULL ) if ( Mio_GateReadTwin(pGate) == NULL )
return 0; return 0;
// assuming the twin node is following next pNode2 = Abc_NtkFetchTwinNode( pNode );
if ( (int)Abc_ObjId(pNode) == Abc_NtkObjNumMax(pNode->pNtk) - 1 ) if ( pNode2 == NULL )
{
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) ); if ( !fReport )
fReport = 1, printf( "Warning: Missing second output of gate(s) \"%s\".\n", Mio_GateReadName(pGate) );
return 0; return 0;
} }
fprintf( pFile, " %s=%s", Mio_GateReadOutName(pGate2), Abc_ObjName( Abc_ObjFanout0(pNode2) ) ); fprintf( pFile, " %s=%s", Mio_GateReadOutName((Mio_Gate_t *)pNode2->pData), Abc_ObjName( Abc_ObjFanout0(pNode2) ) );
return 1; return 1;
} }
......
...@@ -149,6 +149,7 @@ struct Amap_Pin_t_ ...@@ -149,6 +149,7 @@ struct Amap_Pin_t_
struct Amap_Gat_t_ struct Amap_Gat_t_
{ {
Amap_Lib_t * pLib; // library Amap_Lib_t * pLib; // library
Amap_Gat_t * pTwin; // twin gate
char * pName; // the name of the gate char * pName; // the name of the gate
char * pOutName; // name of the output char * pOutName; // name of the output
double dArea; // the area of the gate double dArea; // the area of the gate
......
...@@ -269,11 +269,11 @@ Vec_Ptr_t * Amap_LibSelectGates( Amap_Lib_t * p, int fVerbose ) ...@@ -269,11 +269,11 @@ Vec_Ptr_t * Amap_LibSelectGates( Amap_Lib_t * p, int fVerbose )
vSelect = Vec_PtrAlloc( 100 ); vSelect = Vec_PtrAlloc( 100 );
Vec_PtrForEachEntry( Amap_Gat_t *, p->vSorted, pGate, i ) Vec_PtrForEachEntry( Amap_Gat_t *, p->vSorted, pGate, i )
{ {
if ( pGate->pFunc == NULL ) if ( pGate->pFunc == NULL || pGate->pTwin != NULL )
continue; continue;
Vec_PtrForEachEntryStop( Amap_Gat_t *, p->vSorted, pGate2, k, i ) Vec_PtrForEachEntryStop( Amap_Gat_t *, p->vSorted, pGate2, k, i )
{ {
if ( pGate2->pFunc == NULL ) if ( pGate2->pFunc == NULL || pGate2->pTwin != NULL )
continue; continue;
if ( pGate2->nPins != pGate->nPins ) if ( pGate2->nPins != pGate->nPins )
continue; continue;
......
...@@ -229,7 +229,7 @@ Amap_Item_t * Amap_LibertyPinFunction( Amap_Tree_t * p, Amap_Item_t * pPin ) ...@@ -229,7 +229,7 @@ Amap_Item_t * Amap_LibertyPinFunction( Amap_Tree_t * p, Amap_Item_t * pPin )
/**Function************************************************************* /**Function*************************************************************
Synopsis [Returns cell's function.] Synopsis [Returns output pin(s).]
Description [] Description []
...@@ -250,6 +250,20 @@ Amap_Item_t * Amap_LibertyCellOutput( Amap_Tree_t * p, Amap_Item_t * pCell ) ...@@ -250,6 +250,20 @@ Amap_Item_t * Amap_LibertyCellOutput( Amap_Tree_t * p, Amap_Item_t * pCell )
} }
return NULL; return NULL;
} }
Vec_Ptr_t * Amap_LibertyCellOutputs( Amap_Tree_t * p, Amap_Item_t * pCell )
{
Amap_Item_t * pPin;
Vec_Ptr_t * vOutPins;
vOutPins = Vec_PtrAlloc( 2 );
Amap_ItemForEachChild( p, pCell, pPin )
{
if ( Amap_LibertyCompare(p, pPin->Key, "pin") )
continue;
if ( Amap_LibertyPinFunction(p, pPin) )
Vec_PtrPush( vOutPins, pPin );
}
return vOutPins;
}
/**Function************************************************************* /**Function*************************************************************
...@@ -353,9 +367,10 @@ char * Amap_LibertyGetStringFormula( Amap_Tree_t * p, Amap_Pair_t Pair ) ...@@ -353,9 +367,10 @@ char * Amap_LibertyGetStringFormula( Amap_Tree_t * p, Amap_Pair_t Pair )
int Amap_LibertyPrintGenlib( Amap_Tree_t * p, char * pFileName, int fVerbose ) int Amap_LibertyPrintGenlib( Amap_Tree_t * p, char * pFileName, int fVerbose )
{ {
FILE * pFile; FILE * pFile;
Vec_Ptr_t * vOutputs;
Amap_Item_t * pCell, * pArea, * pFunc, * pPin, * pOutput; Amap_Item_t * pCell, * pArea, * pFunc, * pPin, * pOutput;
char * pForm; char * pForm;
int Counter; int i, Counter;
if ( pFileName == NULL ) if ( pFileName == NULL )
pFile = stdout; pFile = stdout;
else else
...@@ -406,12 +421,14 @@ int Amap_LibertyPrintGenlib( Amap_Tree_t * p, char * pFileName, int fVerbose ) ...@@ -406,12 +421,14 @@ int Amap_LibertyPrintGenlib( Amap_Tree_t * p, char * pFileName, int fVerbose )
printf( "Amap_LibertyPrintGenlib() skipped cell \"%s\" without logic function.\n", Amap_LibertyGetString(p, pCell->Head) ); printf( "Amap_LibertyPrintGenlib() skipped cell \"%s\" without logic function.\n", Amap_LibertyGetString(p, pCell->Head) );
continue; continue;
} }
/*
if ( Counter > 1 ) if ( Counter > 1 )
{ {
if ( fVerbose ) if ( fVerbose )
printf( "Amap_LibertyPrintGenlib() skipped multi-output cell \"%s\".\n", Amap_LibertyGetString(p, pCell->Head) ); printf( "Amap_LibertyPrintGenlib() skipped multi-output cell \"%s\".\n", Amap_LibertyGetString(p, pCell->Head) );
continue; continue;
} }
*/
pArea = Amap_LibertyCellArea( p, pCell ); pArea = Amap_LibertyCellArea( p, pCell );
if ( pArea == NULL ) if ( pArea == NULL )
{ {
...@@ -419,25 +436,28 @@ int Amap_LibertyPrintGenlib( Amap_Tree_t * p, char * pFileName, int fVerbose ) ...@@ -419,25 +436,28 @@ int Amap_LibertyPrintGenlib( Amap_Tree_t * p, char * pFileName, int fVerbose )
printf( "Amap_LibertyPrintGenlib() skipped cell \"%s\" with unspecified area.\n", Amap_LibertyGetString(p, pCell->Head) ); printf( "Amap_LibertyPrintGenlib() skipped cell \"%s\" with unspecified area.\n", Amap_LibertyGetString(p, pCell->Head) );
continue; continue;
} }
pOutput = Amap_LibertyCellOutput( p, pCell ); // pOutput = Amap_LibertyCellOutput( p, pCell );
pFunc = Amap_LibertyPinFunction( p, pOutput ); vOutputs = Amap_LibertyCellOutputs( p, pCell );
pForm = Amap_LibertyGetStringFormula( p, pFunc->Head ); Vec_PtrForEachEntry( Amap_Item_t *, vOutputs, pOutput, i )
if ( !strcmp(pForm, "0") || !strcmp(pForm, "1") )
{ {
if ( fVerbose ) pFunc = Amap_LibertyPinFunction( p, pOutput );
printf( "Amap_LibertyPrintGenlib() skipped cell \"%s\" with constant formula \"%s\".\n", Amap_LibertyGetString(p, pCell->Head), pForm ); pForm = Amap_LibertyGetStringFormula( p, pFunc->Head );
continue; if ( !strcmp(pForm, "0") || !strcmp(pForm, "1") )
{
if ( fVerbose )
printf( "Amap_LibertyPrintGenlib() skipped cell \"%s\" with constant formula \"%s\".\n", Amap_LibertyGetString(p, pCell->Head), pForm );
continue;
}
fprintf( pFile, "GATE " );
fprintf( pFile, "%16s ", Amap_LibertyGetString(p, pCell->Head) );
fprintf( pFile, "%f ", atof(Amap_LibertyGetString(p, pArea->Head)) );
fprintf( pFile, "%s=", Amap_LibertyGetString(p, pOutput->Head) );
fprintf( pFile, "%s;\n", Amap_LibertyGetStringFormula(p, pFunc->Head) );
Amap_ItemForEachChild( p, pCell, pPin )
if ( pPin != pOutput && !Amap_LibertyCompare(p, pPin->Key, "pin") )
fprintf( pFile, " PIN %13s UNKNOWN 1 999 1.00 0.00 1.00 0.00\n", Amap_LibertyGetString(p, pPin->Head) );
} }
Vec_PtrFree( vOutputs );
fprintf( pFile, "GATE " );
fprintf( pFile, "%16s ", Amap_LibertyGetString(p, pCell->Head) );
fprintf( pFile, "%f ", atof(Amap_LibertyGetString(p, pArea->Head)) );
fprintf( pFile, "%s=", Amap_LibertyGetString(p, pOutput->Head) );
fprintf( pFile, "%s;\n", Amap_LibertyGetStringFormula(p, pFunc->Head) );
Amap_ItemForEachChild( p, pCell, pPin )
if ( pPin != pOutput && !Amap_LibertyCompare(p, pPin->Key, "pin") )
fprintf( pFile, " PIN %13s UNKNOWN 1 999 1.00 0.00 1.00 0.00\n", Amap_LibertyGetString(p, pPin->Head) );
} }
if ( pFile != stdout ) if ( pFile != stdout )
fclose( pFile ); fclose( pFile );
......
...@@ -326,10 +326,10 @@ int Amap_CollectFormulaTokens( Vec_Ptr_t * vTokens, char * pToken, int iPos ) ...@@ -326,10 +326,10 @@ int Amap_CollectFormulaTokens( Vec_Ptr_t * vTokens, char * pToken, int iPos )
Amap_Lib_t * Amap_ParseTokens( Vec_Ptr_t * vTokens, int fVerbose ) Amap_Lib_t * Amap_ParseTokens( Vec_Ptr_t * vTokens, int fVerbose )
{ {
Amap_Lib_t * p; Amap_Lib_t * p;
Amap_Gat_t * pGate; Amap_Gat_t * pGate, * pPrev;
Amap_Pin_t * pPin; Amap_Pin_t * pPin;
char * pToken; char * pToken;
int nPins, iPos = 0; int i, nPins, iPos = 0;
p = Amap_LibAlloc(); p = Amap_LibAlloc();
pToken = (char *)Vec_PtrEntry(vTokens, iPos++); pToken = (char *)Vec_PtrEntry(vTokens, iPos++);
do do
...@@ -409,8 +409,21 @@ Amap_Lib_t * Amap_ParseTokens( Vec_Ptr_t * vTokens, int fVerbose ) ...@@ -409,8 +409,21 @@ Amap_Lib_t * Amap_ParseTokens( Vec_Ptr_t * vTokens, int fVerbose )
Vec_PtrPush( p->vGates, pGate ); Vec_PtrPush( p->vGates, pGate );
} }
pToken = (char *)Vec_PtrEntry(vTokens, iPos++); pToken = (char *)Vec_PtrEntry(vTokens, iPos++);
//printf( "Finished reading gate %s (%s)\n", pGate->pName, pGate->pOutName );
} }
while ( strcmp( pToken, ".end" ) ); while ( strcmp( pToken, ".end" ) );
// check if there are gates with identical names
pPrev = NULL;
Amap_LibForEachGate( p, pGate, i )
{
if ( pPrev && !strcmp(pPrev->pName, pGate->pName) )
{
pPrev->pTwin = pGate, pGate->pTwin = pPrev;
printf( "Warning: Detected multi-output gate \"%s\".\n", pGate->pName );
}
pPrev = pGate;
}
return p; return p;
} }
......
...@@ -319,6 +319,8 @@ Mio_Gate_t ** Mio_CollectRoots( Mio_Library_t * pLib, int nInputs, float tDelay, ...@@ -319,6 +319,8 @@ Mio_Gate_t ** Mio_CollectRoots( Mio_Library_t * pLib, int nInputs, float tDelay,
continue; continue;
if ( pGate->uTruth == ~0xAAAAAAAAAAAAAAAA && fSkipInv ) if ( pGate->uTruth == ~0xAAAAAAAAAAAAAAAA && fSkipInv )
continue; continue;
if ( pGate->pTwin ) // skip multi-output gates for now
continue;
// check if the gate with this functionality already exists // check if the gate with this functionality already exists
for ( i = 0; i < iGate; i++ ) for ( i = 0; i < iGate; i++ )
if ( ppGates[i]->uTruth == pGate->uTruth ) if ( ppGates[i]->uTruth == pGate->uTruth )
......
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