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