mirror of https://github.com/YosysHQ/abc.git
Streamlining support for multi-output gates
This commit is contained in:
parent
fc4cfc0c35
commit
eaa8496b42
|
|
@ -108,6 +108,8 @@ void json_print_string(json_t *json, json_value_t val, FILE *fp);
|
|||
void json_debug_value(json_t *json, json_value_t val, int indent);
|
||||
|
||||
extern Abc_Ntk_t * Abc_NtkFromMiniMapping( int * pArray );
|
||||
static json_value_t * Jsonc_ObjectLookup( json_t * pJson, json_value_t object, const char * pKey );
|
||||
static char * Jsonc_StringDup( json_t * pJson, json_value_t value );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
|
|
@ -671,6 +673,68 @@ static const char * Jsonc_GetNodeOutName( Abc_Obj_t * pObj )
|
|||
snprintf( Buffer, sizeof(Buffer), "n%d", Abc_ObjId(pObj) );
|
||||
return Buffer;
|
||||
}
|
||||
static char * Jsonc_GetInstanceOutName( json_t * pJson, json_value_t Node )
|
||||
{
|
||||
json_value_t * pOutName = Jsonc_ObjectLookup( pJson, Node, "pin" );
|
||||
if ( pOutName == NULL )
|
||||
pOutName = Jsonc_ObjectLookup( pJson, Node, "output" );
|
||||
return pOutName && pOutName->type == JSON_STRING ? Jsonc_StringDup( pJson, *pOutName ) : NULL;
|
||||
}
|
||||
static int Jsonc_IsPrevTwinNode( Abc_Obj_t * pObj, Abc_Obj_t ** ppPrev )
|
||||
{
|
||||
Abc_Obj_t * pPrev;
|
||||
Mio_Gate_t * pGate = (Mio_Gate_t *)pObj->pData;
|
||||
if ( ppPrev )
|
||||
*ppPrev = NULL;
|
||||
if ( pGate == NULL || Mio_GateReadTwin(pGate) == NULL || Abc_ObjId(pObj) == 0 )
|
||||
return 0;
|
||||
pPrev = Abc_NtkObj( pObj->pNtk, Abc_ObjId(pObj) - 1 );
|
||||
if ( pPrev == NULL || !Abc_ObjIsNode(pPrev) || Abc_ObjFaninNum(pPrev) != Abc_ObjFaninNum(pObj) )
|
||||
return 0;
|
||||
if ( Mio_GateReadTwin(pGate) != (Mio_Gate_t *)pPrev->pData )
|
||||
return 0;
|
||||
if ( ppPrev )
|
||||
*ppPrev = pPrev;
|
||||
return 1;
|
||||
}
|
||||
static Vec_Ptr_t * Jsonc_OrderTwinNodes( Abc_Ntk_t * p, Vec_Ptr_t * vNodes )
|
||||
{
|
||||
Vec_Int_t * vInDfs = Vec_IntStart( Abc_NtkObjNumMax(p) );
|
||||
Vec_Int_t * vSeen = Vec_IntStart( Abc_NtkObjNumMax(p) );
|
||||
Vec_Ptr_t * vRes = Vec_PtrAlloc( Vec_PtrSize(vNodes) );
|
||||
Abc_Obj_t * pObj, * pTwin;
|
||||
int i;
|
||||
Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
|
||||
Vec_IntWriteEntry( vInDfs, Abc_ObjId(pObj), 1 );
|
||||
Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
|
||||
{
|
||||
if ( Vec_IntEntry(vSeen, Abc_ObjId(pObj)) )
|
||||
continue;
|
||||
if ( Jsonc_IsPrevTwinNode( pObj, &pTwin ) && Vec_IntEntry(vInDfs, Abc_ObjId(pTwin)) )
|
||||
{
|
||||
if ( !Vec_IntEntry(vSeen, Abc_ObjId(pTwin)) )
|
||||
{
|
||||
Vec_PtrPush( vRes, pTwin );
|
||||
Vec_IntWriteEntry( vSeen, Abc_ObjId(pTwin), 1 );
|
||||
}
|
||||
Vec_PtrPush( vRes, pObj );
|
||||
Vec_IntWriteEntry( vSeen, Abc_ObjId(pObj), 1 );
|
||||
continue;
|
||||
}
|
||||
Vec_PtrPush( vRes, pObj );
|
||||
Vec_IntWriteEntry( vSeen, Abc_ObjId(pObj), 1 );
|
||||
pTwin = Abc_NtkFetchTwinNode( pObj );
|
||||
if ( pTwin && Vec_IntEntry(vInDfs, Abc_ObjId(pTwin)) && !Vec_IntEntry(vSeen, Abc_ObjId(pTwin)) )
|
||||
{
|
||||
Vec_PtrPush( vRes, pTwin );
|
||||
Vec_IntWriteEntry( vSeen, Abc_ObjId(pTwin), 1 );
|
||||
}
|
||||
}
|
||||
assert( Vec_PtrSize(vRes) == Vec_PtrSize(vNodes) );
|
||||
Vec_IntFree( vInDfs );
|
||||
Vec_IntFree( vSeen );
|
||||
return vRes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
@ -692,8 +756,18 @@ void Jsonc_WriteTest( Abc_Ntk_t * p, char * pFileName )
|
|||
int i, Counter, Total;
|
||||
assert( Abc_NtkHasMapping(p) );
|
||||
vNodes = Abc_NtkDfs2( p );
|
||||
{
|
||||
Vec_Ptr_t * vTemp = Jsonc_OrderTwinNodes( p, vNodes );
|
||||
Vec_PtrFree( vNodes );
|
||||
vNodes = vTemp;
|
||||
}
|
||||
vObj2Num = Vec_IntStartFull( Abc_NtkObjNumMax(p) );
|
||||
Total = Abc_NtkPiNum(p) + Vec_PtrSize(vNodes) + Abc_NtkPoNum(p);
|
||||
Counter = 0;
|
||||
Abc_NtkForEachPi( p, pObj, i )
|
||||
Vec_IntWriteEntry( vObj2Num, Abc_ObjId(pObj), Counter++ );
|
||||
Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
|
||||
Vec_IntWriteEntry( vObj2Num, Abc_ObjId(pObj), Counter++ );
|
||||
pFile = fopen( pFileName, "wb" );
|
||||
if ( pFile == NULL )
|
||||
{
|
||||
|
|
@ -727,6 +801,8 @@ void Jsonc_WriteTest( Abc_Ntk_t * p, char * pFileName )
|
|||
fprintf( pFile, " {\n" );
|
||||
fprintf( pFile, " \"type\": \"%s\",\n", "instance" );
|
||||
fprintf( pFile, " \"name\": \"%s\",\n", Mio_GateReadName(pGate) );
|
||||
if ( Mio_GateReadTwin(pGate) != NULL )
|
||||
fprintf( pFile, " \"pin\": \"%s\",\n", Mio_GateReadOutName(pGate) );
|
||||
fprintf( pFile, " \"fanins\":\n" );
|
||||
fprintf( pFile, " {\n" );
|
||||
for ( pPin = Mio_GateReadPins(pGate), k = 0; pPin; pPin = Mio_PinReadNext(pPin), k++ )
|
||||
|
|
@ -897,9 +973,10 @@ static void Jsonc_AppendPortNames( Vec_Str_t * vNames, Vec_Ptr_t * vBases, Vec_I
|
|||
Vec_IntFree( vCounts );
|
||||
Vec_IntFree( vBaseIds );
|
||||
}
|
||||
static Vec_Int_t * Jsonc_ConvertToMiniMapping( json_t * pJson, Mio_Library_t * pLib, char ** ppDesignName )
|
||||
static Vec_Int_t * Jsonc_ConvertToMiniMapping( json_t * pJson, Mio_Library_t * pLib, char ** ppDesignName, Vec_Ptr_t ** pvNodeOutNames )
|
||||
{
|
||||
Vec_Ptr_t * vPiBases = NULL, * vPoBases = NULL;
|
||||
Vec_Ptr_t * vNodeOutNames = NULL;
|
||||
Vec_Int_t * vPiBits = NULL, * vPoBits = NULL;
|
||||
Vec_Int_t * vNodeMap = NULL, * vGateIdx = NULL, * vPoIdx = NULL;
|
||||
Vec_Int_t * vMapping = NULL, * vPoDrivers = NULL;
|
||||
|
|
@ -911,6 +988,8 @@ static Vec_Int_t * Jsonc_ConvertToMiniMapping( json_t * pJson, Mio_Library_t * p
|
|||
int fSuccess = 0;
|
||||
if ( ppDesignName )
|
||||
*ppDesignName = NULL;
|
||||
if ( pvNodeOutNames )
|
||||
*pvNodeOutNames = NULL;
|
||||
if ( pLib == NULL )
|
||||
{
|
||||
printf( "Genlib library is not available.\n" );
|
||||
|
|
@ -943,6 +1022,7 @@ static Vec_Int_t * Jsonc_ConvertToMiniMapping( json_t * pJson, Mio_Library_t * p
|
|||
vPiBits = Vec_IntAlloc( pNodes->count );
|
||||
vPoBases = Vec_PtrAlloc( pNodes->count );
|
||||
vPoBits = Vec_IntAlloc( pNodes->count );
|
||||
vNodeOutNames = Vec_PtrAlloc( pNodes->count );
|
||||
// first pass: collect object types and names
|
||||
for ( i = 0; i < (int)pNodes->count; i++ )
|
||||
{
|
||||
|
|
@ -1020,7 +1100,7 @@ static Vec_Int_t * Jsonc_ConvertToMiniMapping( json_t * pJson, Mio_Library_t * p
|
|||
json_container_t * pFanObj;
|
||||
Mio_Gate_t * pGate;
|
||||
Mio_Pin_t * pPin;
|
||||
char * pGateStr;
|
||||
char * pGateStr, * pOutStr;
|
||||
if ( pGateName == NULL || pGateName->type != JSON_STRING )
|
||||
{
|
||||
printf( "Gate node %d is missing a name.\n", i );
|
||||
|
|
@ -1032,16 +1112,19 @@ static Vec_Int_t * Jsonc_ConvertToMiniMapping( json_t * pJson, Mio_Library_t * p
|
|||
printf( "Gate node %d has an invalid name.\n", i );
|
||||
goto cleanup;
|
||||
}
|
||||
pGate = Mio_LibraryReadGateByName( pLib, pGateStr, NULL );
|
||||
pOutStr = Jsonc_GetInstanceOutName( pJson, Node );
|
||||
pGate = Mio_LibraryReadGateByName( pLib, pGateStr, pOutStr );
|
||||
if ( pGate == NULL )
|
||||
{
|
||||
printf( "Gate \"%s\" is not found in the current library.\n", pGateStr );
|
||||
printf( "Gate \"%s\"%s%s%s is not found in the current library.\n", pGateStr, pOutStr ? " with output pin \"" : "", pOutStr ? pOutStr : "", pOutStr ? "\"" : "" );
|
||||
ABC_FREE( pOutStr );
|
||||
ABC_FREE( pGateStr );
|
||||
goto cleanup;
|
||||
}
|
||||
if ( pFanins == NULL || pFanins->type != JSON_OBJECT )
|
||||
{
|
||||
printf( "Gate \"%s\" is missing \"fanins\" description.\n", pGateStr );
|
||||
ABC_FREE( pOutStr );
|
||||
ABC_FREE( pGateStr );
|
||||
goto cleanup;
|
||||
}
|
||||
|
|
@ -1049,6 +1132,7 @@ static Vec_Int_t * Jsonc_ConvertToMiniMapping( json_t * pJson, Mio_Library_t * p
|
|||
if ( pFanObj == NULL )
|
||||
{
|
||||
printf( "Gate \"%s\" has incomplete fanin information.\n", pGateStr );
|
||||
ABC_FREE( pOutStr );
|
||||
ABC_FREE( pGateStr );
|
||||
goto cleanup;
|
||||
}
|
||||
|
|
@ -1061,6 +1145,7 @@ static Vec_Int_t * Jsonc_ConvertToMiniMapping( json_t * pJson, Mio_Library_t * p
|
|||
if ( pPinInfo == NULL || pPinInfo->type != JSON_OBJECT )
|
||||
{
|
||||
printf( "Gate \"%s\" is missing connection for pin \"%s\".\n", pGateStr, Mio_PinReadName(pPin) );
|
||||
ABC_FREE( pOutStr );
|
||||
ABC_FREE( pGateStr );
|
||||
goto cleanup;
|
||||
}
|
||||
|
|
@ -1068,12 +1153,14 @@ static Vec_Int_t * Jsonc_ConvertToMiniMapping( json_t * pJson, Mio_Library_t * p
|
|||
if ( pNodeLit == NULL || !Jsonc_ParseInt( pJson, *pNodeLit, &NodeId ) )
|
||||
{
|
||||
printf( "Gate \"%s\" has invalid node reference on pin \"%s\".\n", pGateStr, Mio_PinReadName(pPin) );
|
||||
ABC_FREE( pOutStr );
|
||||
ABC_FREE( pGateStr );
|
||||
goto cleanup;
|
||||
}
|
||||
if ( NodeId < 0 || NodeId >= Vec_IntSize(vNodeMap) )
|
||||
{
|
||||
printf( "Gate \"%s\" references out-of-range node %d.\n", pGateStr, NodeId );
|
||||
ABC_FREE( pOutStr );
|
||||
ABC_FREE( pGateStr );
|
||||
goto cleanup;
|
||||
}
|
||||
|
|
@ -1081,6 +1168,7 @@ static Vec_Int_t * Jsonc_ConvertToMiniMapping( json_t * pJson, Mio_Library_t * p
|
|||
if ( MapId < 0 )
|
||||
{
|
||||
printf( "Gate \"%s\" refers to unsupported node %d.\n", pGateStr, NodeId );
|
||||
ABC_FREE( pOutStr );
|
||||
ABC_FREE( pGateStr );
|
||||
goto cleanup;
|
||||
}
|
||||
|
|
@ -1088,6 +1176,7 @@ static Vec_Int_t * Jsonc_ConvertToMiniMapping( json_t * pJson, Mio_Library_t * p
|
|||
}
|
||||
Vec_StrPrintStr( vNames, pGateStr );
|
||||
Vec_StrPush( vNames, '\0' );
|
||||
Vec_PtrPush( vNodeOutNames, pOutStr );
|
||||
ABC_FREE( pGateStr );
|
||||
}
|
||||
else if ( Jsonc_StringEqual( pJson, *pType, "PO" ) || Jsonc_StringEqual( pJson, *pType, "po" ) )
|
||||
|
|
@ -1148,6 +1237,18 @@ cleanup:
|
|||
Vec_IntFreeP( &vPoBits );
|
||||
if ( vNames )
|
||||
Vec_StrFree( vNames );
|
||||
if ( vNodeOutNames )
|
||||
{
|
||||
if ( fSuccess && pvNodeOutNames )
|
||||
*pvNodeOutNames = vNodeOutNames;
|
||||
else
|
||||
{
|
||||
char * pOutName;
|
||||
Vec_PtrForEachEntry( char *, vNodeOutNames, pOutName, i )
|
||||
ABC_FREE( pOutName );
|
||||
Vec_PtrFree( vNodeOutNames );
|
||||
}
|
||||
}
|
||||
if ( vPiBases )
|
||||
{
|
||||
Vec_PtrForEachEntry( char *, vPiBases, pBase, i )
|
||||
|
|
@ -1171,8 +1272,12 @@ Abc_Ntk_t * Jsonc_ReadNetwork( char * pFileName )
|
|||
{
|
||||
Mio_Library_t * pLib = (Mio_Library_t *)Abc_FrameReadLibGen();
|
||||
Vec_Int_t * vMapping;
|
||||
Vec_Ptr_t * vNodeOutNames = NULL;
|
||||
Abc_Ntk_t * pNtk;
|
||||
Abc_Obj_t * pObj;
|
||||
char * pDesignName = NULL;
|
||||
char * pOutName;
|
||||
int i;
|
||||
json_t * pJson = json_create();
|
||||
if ( pJson == NULL )
|
||||
{
|
||||
|
|
@ -1185,7 +1290,7 @@ Abc_Ntk_t * Jsonc_ReadNetwork( char * pFileName )
|
|||
json_destroy( pJson );
|
||||
return NULL;
|
||||
}
|
||||
vMapping = Jsonc_ConvertToMiniMapping( pJson, pLib, &pDesignName );
|
||||
vMapping = Jsonc_ConvertToMiniMapping( pJson, pLib, &pDesignName, &vNodeOutNames );
|
||||
json_destroy( pJson );
|
||||
if ( vMapping == NULL )
|
||||
return NULL;
|
||||
|
|
@ -1193,9 +1298,35 @@ Abc_Ntk_t * Jsonc_ReadNetwork( char * pFileName )
|
|||
Vec_IntFree( vMapping );
|
||||
if ( pNtk == NULL )
|
||||
{
|
||||
if ( vNodeOutNames )
|
||||
{
|
||||
Vec_PtrForEachEntry( char *, vNodeOutNames, pOutName, i )
|
||||
ABC_FREE( pOutName );
|
||||
Vec_PtrFree( vNodeOutNames );
|
||||
}
|
||||
ABC_FREE( pDesignName );
|
||||
return NULL;
|
||||
}
|
||||
if ( vNodeOutNames )
|
||||
{
|
||||
Vec_PtrForEachEntry( char *, vNodeOutNames, pOutName, i )
|
||||
{
|
||||
Mio_Gate_t * pGate;
|
||||
pObj = Abc_NtkObj( pNtk, Abc_NtkCiNum(pNtk) + i + 1 );
|
||||
if ( pObj == NULL )
|
||||
continue;
|
||||
pGate = (Mio_Gate_t *)pObj->pData;
|
||||
if ( pOutName && pGate )
|
||||
{
|
||||
Mio_Gate_t * pGateOut = Mio_LibraryReadGateByName( pLib, Mio_GateReadName(pGate), pOutName );
|
||||
if ( pGateOut )
|
||||
pObj->pData = pGateOut;
|
||||
}
|
||||
}
|
||||
Vec_PtrForEachEntry( char *, vNodeOutNames, pOutName, i )
|
||||
ABC_FREE( pOutName );
|
||||
Vec_PtrFree( vNodeOutNames );
|
||||
}
|
||||
ABC_FREE( pNtk->pName );
|
||||
pNtk->pName = pDesignName ? pDesignName : Extra_FileNameGeneric( pFileName );
|
||||
ABC_FREE( pNtk->pSpec );
|
||||
|
|
|
|||
|
|
@ -622,46 +622,65 @@ int Io_ReadBlifReorderFormalNames( Vec_Ptr_t * vTokens, Mio_Gate_t * pGate, Mio_
|
|||
}
|
||||
else
|
||||
{
|
||||
if ( i != Mio_GateReadPinNum(pGate) ) // expect the correct order of input pins in the network with twin gates
|
||||
int nInputs = Mio_GateReadPinNum(pGate);
|
||||
int nOutputs = nSize - 2 - nInputs;
|
||||
int nMatched = 0;
|
||||
if ( nOutputs != 1 && nOutputs != 2 )
|
||||
return 0;
|
||||
// check the last two entries
|
||||
if ( nSize - 3 == Mio_GateReadPinNum(pGate) ) // only one output is available
|
||||
// reorder the input pins to be in the same order as in the gate
|
||||
for ( pGatePin = Mio_GateReadPins(pGate), i = 0; pGatePin; pGatePin = Mio_PinReadNext(pGatePin), i++ )
|
||||
{
|
||||
pNamePin = Mio_GateReadOutName(pGate);
|
||||
pNamePin = Mio_PinReadName(pGatePin);
|
||||
Length = strlen(pNamePin);
|
||||
pName = (char *)Vec_PtrEntry(vTokens, nSize - 1);
|
||||
if ( !strncmp( pNamePin, pName, Length ) && pName[Length] == '=' ) // the last entry is pGate
|
||||
for ( k = 2; k < nSize; k++ )
|
||||
{
|
||||
Vec_PtrPush( vTokens, NULL );
|
||||
return 1;
|
||||
pName = (char *)Vec_PtrEntry(vTokens, k);
|
||||
if ( !strncmp( pNamePin, pName, Length ) && pName[Length] == '=' )
|
||||
{
|
||||
Vec_PtrPush( vTokens, pName );
|
||||
nMatched++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
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
|
||||
if ( k == nSize )
|
||||
return 0;
|
||||
}
|
||||
// add the outputs in the base/twin order, with NULL for a missing output
|
||||
pNamePin = Mio_GateReadOutName(pGate);
|
||||
Length = strlen(pNamePin);
|
||||
for ( k = 2; k < nSize; k++ )
|
||||
{
|
||||
pName = (char *)Vec_PtrEntry(vTokens, k);
|
||||
if ( !strncmp( pNamePin, pName, Length ) && pName[Length] == '=' )
|
||||
{
|
||||
pName = (char *)Vec_PtrPop( vTokens );
|
||||
Vec_PtrPush( vTokens, NULL );
|
||||
Vec_PtrPush( vTokens, pName );
|
||||
return 1;
|
||||
nMatched++;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if ( nSize - 4 == Mio_GateReadPinNum(pGate) ) // two outputs are available
|
||||
if ( k == nSize )
|
||||
Vec_PtrPush( vTokens, NULL );
|
||||
pNamePin = Mio_GateReadOutName(pTwin);
|
||||
Length = strlen(pNamePin);
|
||||
for ( k = 2; k < nSize; k++ )
|
||||
{
|
||||
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;
|
||||
pName = (char *)Vec_PtrEntry(vTokens, k);
|
||||
if ( !strncmp( pNamePin, pName, Length ) && pName[Length] == '=' )
|
||||
{
|
||||
Vec_PtrPush( vTokens, pName );
|
||||
nMatched++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert( 0 );
|
||||
if ( k == nSize )
|
||||
Vec_PtrPush( vTokens, NULL );
|
||||
if ( Vec_PtrEntry(vTokens, nSize + nInputs) == NULL && Vec_PtrEntry(vTokens, nSize + nInputs + 1) == NULL )
|
||||
return 0;
|
||||
if ( nMatched != nSize - 2 )
|
||||
return 0;
|
||||
Vec_PtrForEachEntryStart( char *, vTokens, pName, k, nSize )
|
||||
Vec_PtrWriteEntry( vTokens, k - nSize + 2, pName );
|
||||
Vec_PtrShrink( vTokens, 2 + nInputs + 2 );
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -1713,4 +1732,3 @@ int Io_ReadBlifNetworkConnectBoxes( Io_ReadBlif_t * p, Abc_Ntk_t * pNtkMaster )
|
|||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
|
|
@ -573,6 +573,17 @@ void Io_NtkWriteSubcktFanins( FILE * pFile, Abc_Obj_t * pNode )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static int Io_NtkNodesHaveSameFanins( Abc_Obj_t * pNode, Abc_Obj_t * pNode2 )
|
||||
{
|
||||
Abc_Obj_t * pFanin;
|
||||
int i;
|
||||
if ( Abc_ObjFaninNum(pNode) != Abc_ObjFaninNum(pNode2) )
|
||||
return 0;
|
||||
Abc_ObjForEachFanin( pNode, pFanin, i )
|
||||
if ( pFanin != Abc_ObjFanin(pNode2, i) )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
int Io_NtkWriteNodeGate( FILE * pFile, Abc_Obj_t * pNode, int Length )
|
||||
{
|
||||
static int fReport = 0;
|
||||
|
|
@ -594,6 +605,8 @@ int Io_NtkWriteNodeGate( FILE * pFile, Abc_Obj_t * pNode, int Length )
|
|||
fReport = 1, printf( "Warning: Missing second output of gate(s) \"%s\".\n", Mio_GateReadName(pGate) );
|
||||
return 0;
|
||||
}
|
||||
if ( !Io_NtkNodesHaveSameFanins( pNode, pNode2 ) )
|
||||
return 0;
|
||||
fprintf( pFile, " %s=%s", Mio_GateReadOutName((Mio_Gate_t *)pNode2->pData), Abc_ObjName( Abc_ObjFanout0(pNode2) ) );
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -1407,4 +1420,3 @@ void Io_WriteBlifSpecial( Abc_Ntk_t * pNtk, char * FileName, char * pLutStruct,
|
|||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@ static void Io_WriteVerilogLatches( FILE * pFile, Abc_Ntk_t * pNtk );
|
|||
static void Io_WriteVerilogObjects( FILE * pFile, Abc_Ntk_t * pNtk, int fOnlyAnds );
|
||||
static int Io_WriteVerilogWiresCount( Abc_Ntk_t * pNtk );
|
||||
static char * Io_WriteVerilogGetName( char * pName );
|
||||
static int Io_WriteVerilogNodesHaveSameFanins( Abc_Obj_t * pNode, Abc_Obj_t * pNode2 );
|
||||
static int Io_WriteVerilogIsPrevTwinNode( Abc_Obj_t * pNode );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
|
|
@ -512,6 +514,54 @@ void Io_WriteVerilogLatches( FILE * pFile, Abc_Ntk_t * pNtk )
|
|||
fprintf( pFile, " end\n" );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks whether two mapped nodes have the same fanins.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static int Io_WriteVerilogNodesHaveSameFanins( Abc_Obj_t * pNode, Abc_Obj_t * pNode2 )
|
||||
{
|
||||
Abc_Obj_t * pFanin;
|
||||
int i;
|
||||
if ( Abc_ObjFaninNum(pNode) != Abc_ObjFaninNum(pNode2) )
|
||||
return 0;
|
||||
Abc_ObjForEachFanin( pNode, pFanin, i )
|
||||
if ( pFanin != Abc_ObjFanin(pNode2, i) )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks whether this mapped node is the second output of a twin.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static int Io_WriteVerilogIsPrevTwinNode( Abc_Obj_t * pNode )
|
||||
{
|
||||
Abc_Obj_t * pPrev;
|
||||
Mio_Gate_t * pGate = (Mio_Gate_t *)pNode->pData;
|
||||
if ( pGate == NULL || Mio_GateReadTwin(pGate) == NULL || Abc_ObjId(pNode) == 0 )
|
||||
return 0;
|
||||
pPrev = Abc_NtkObj( pNode->pNtk, Abc_ObjId(pNode) - 1 );
|
||||
if ( pPrev == NULL || !Abc_ObjIsNode(pPrev) )
|
||||
return 0;
|
||||
if ( Mio_GateReadTwin(pGate) != (Mio_Gate_t *)pPrev->pData )
|
||||
return 0;
|
||||
return Io_WriteVerilogNodesHaveSameFanins( pPrev, pNode );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Writes the nodes and boxes.]
|
||||
|
|
@ -563,12 +613,18 @@ void Io_WriteVerilogObjects( FILE * pFile, Abc_Ntk_t * pNtk, int fOnlyAnds )
|
|||
Abc_NtkForEachNode( pNtk, pObj, k )
|
||||
{
|
||||
Mio_Gate_t * pGate = (Mio_Gate_t *)pObj->pData;
|
||||
Abc_Obj_t * pNode2 = NULL;
|
||||
Mio_Pin_t * pGatePin;
|
||||
if ( Io_WriteVerilogIsPrevTwinNode( pObj ) )
|
||||
continue;
|
||||
if ( Abc_ObjFaninNum(pObj) == 0 && (!strcmp(Mio_GateReadName(pGate), "_const0_") || !strcmp(Mio_GateReadName(pGate), "_const1_")) )
|
||||
{
|
||||
fprintf( pFile, " %-*s %s = 1\'b%d;\n", Length, "assign", Io_WriteVerilogGetName(Abc_ObjName( Abc_ObjFanout0(pObj) )), !strcmp(Mio_GateReadName(pGate), "_const1_") );
|
||||
continue;
|
||||
}
|
||||
pNode2 = Abc_NtkFetchTwinNode( pObj );
|
||||
if ( pNode2 && !Io_WriteVerilogNodesHaveSameFanins( pObj, pNode2 ) )
|
||||
pNode2 = NULL;
|
||||
// write the node
|
||||
if ( fUseSimpleGateNames )
|
||||
{
|
||||
|
|
@ -591,6 +647,12 @@ void Io_WriteVerilogObjects( FILE * pFile, Abc_Ntk_t * pNtk, int fOnlyAnds )
|
|||
assert ( i == Abc_ObjFaninNum(pObj) );
|
||||
fprintf( pFile, ".%s", Io_WriteVerilogGetName(Mio_GateReadOutName(pGate)) );
|
||||
fprintf( pFile, "(%s)", Io_WriteVerilogGetName(Abc_ObjName( Abc_ObjFanout0(pObj) )) );
|
||||
if ( pNode2 )
|
||||
{
|
||||
fprintf( pFile, ", " );
|
||||
fprintf( pFile, ".%s", Io_WriteVerilogGetName(Mio_GateReadOutName((Mio_Gate_t *)pNode2->pData)) );
|
||||
fprintf( pFile, "(%s)", Io_WriteVerilogGetName(Abc_ObjName( Abc_ObjFanout0(pNode2) )) );
|
||||
}
|
||||
fprintf( pFile, ");\n" );
|
||||
}
|
||||
}
|
||||
|
|
@ -972,4 +1034,3 @@ void Io_WriteVerilogLut( Abc_Ntk_t * pNtk, char * pFileName, int nLutSize, int f
|
|||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
|
|
@ -656,12 +656,13 @@ static inline void Scl_LibPinRequiredI( SC_Timing * pTime, SC_PairI * pReqIn, SC
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline SC_Timing * Scl_CellPinTime( SC_Cell * pCell, int iPin )
|
||||
static inline SC_Timing * Scl_CellPinOutTime( SC_Cell * pCell, int iOut, int iPin )
|
||||
{
|
||||
SC_Pin * pPin;
|
||||
SC_Timings * pRTime;
|
||||
assert( iOut >= 0 && iOut < pCell->n_outputs );
|
||||
assert( iPin >= 0 && iPin < pCell->n_inputs );
|
||||
pPin = SC_CellPin( pCell, pCell->n_inputs );
|
||||
pPin = SC_CellPin( pCell, pCell->n_inputs + iOut );
|
||||
assert( Vec_PtrSize(&pPin->vRTimings) == pCell->n_inputs );
|
||||
pRTime = (SC_Timings *)Vec_PtrEntry( &pPin->vRTimings, iPin );
|
||||
if ( Vec_PtrSize(&pRTime->vTimings) == 0 )
|
||||
|
|
@ -669,6 +670,10 @@ static inline SC_Timing * Scl_CellPinTime( SC_Cell * pCell, int iPin )
|
|||
assert( Vec_PtrSize(&pRTime->vTimings) == 1 );
|
||||
return (SC_Timing *)Vec_PtrEntry( &pRTime->vTimings, 0 );
|
||||
}
|
||||
static inline SC_Timing * Scl_CellPinTime( SC_Cell * pCell, int iPin )
|
||||
{
|
||||
return Scl_CellPinOutTime( pCell, 0, iPin );
|
||||
}
|
||||
static inline float Scl_LibPinArrivalEstimate( SC_Cell * pCell, int iPin, float Slew, float Load )
|
||||
{
|
||||
SC_Pair LoadIn = { Load, Load };
|
||||
|
|
|
|||
|
|
@ -103,6 +103,35 @@ Abc_Obj_t * Abc_SclFindMostCriticalFanin( SC_Man * p, int * pfRise, Abc_Obj_t *
|
|||
return pPivot;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Find the output pin represented by this mapped node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Abc_SclObjOutputIndex( Abc_Obj_t * pObj, SC_Cell * pCell )
|
||||
{
|
||||
Mio_Gate_t * pGate;
|
||||
char * pOutName;
|
||||
int i;
|
||||
if ( pCell->n_outputs == 1 )
|
||||
return 0;
|
||||
pGate = (Mio_Gate_t *)pObj->pData;
|
||||
assert( pGate != NULL );
|
||||
pOutName = Mio_GateReadOutName( pGate );
|
||||
assert( pOutName != NULL );
|
||||
for ( i = 0; i < pCell->n_outputs; i++ )
|
||||
if ( !strcmp( pOutName, SC_CellPinName(pCell, pCell->n_inputs + i) ) )
|
||||
return i;
|
||||
assert( 0 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Printing timing information for the node/network.]
|
||||
|
|
@ -299,10 +328,20 @@ static inline void Abc_SclDeptObj( SC_Man * p, Abc_Obj_t * pObj )
|
|||
SC_PairClean( Abc_SclObjDept(p, pObj) );
|
||||
Abc_ObjForEachFanout( pObj, pFanout, i )
|
||||
{
|
||||
SC_Cell * pFanoutCell;
|
||||
int iFanin, iOut;
|
||||
if ( Abc_ObjIsCo(pFanout) || Abc_ObjIsLatch(pFanout) )
|
||||
continue;
|
||||
pTime = Scl_CellPinTime( Abc_SclObjCell(pFanout), Abc_NodeFindFanin(pFanout, pObj) );
|
||||
Abc_SclDeptFanin( p, pTime, pFanout, pObj, Abc_NodeFindFanin(pFanout, pObj) );
|
||||
pFanoutCell = Abc_SclObjCell( pFanout );
|
||||
iFanin = Abc_NodeFindFanin( pFanout, pObj );
|
||||
iOut = Abc_SclObjOutputIndex( pFanout, pFanoutCell );
|
||||
pTime = Scl_CellPinOutTime( pFanoutCell, iOut, iFanin );
|
||||
if ( pTime == NULL )
|
||||
{
|
||||
assert( pFanoutCell->n_outputs > 1 );
|
||||
continue;
|
||||
}
|
||||
Abc_SclDeptFanin( p, pTime, pFanout, pObj, iFanin );
|
||||
}
|
||||
}
|
||||
static inline float Abc_SclObjLoadValue( SC_Man * p, Abc_Obj_t * pObj )
|
||||
|
|
@ -370,7 +409,13 @@ void Abc_SclTimeNode( SC_Man * p, Abc_Obj_t * pObj, int fDept )
|
|||
// compute for each fanin
|
||||
Abc_ObjForEachFanin( pObj, pFanin, k )
|
||||
{
|
||||
pTime = Scl_CellPinTime( pCell, k );
|
||||
int iOut = Abc_SclObjOutputIndex( pObj, pCell );
|
||||
pTime = Scl_CellPinOutTime( pCell, iOut, k );
|
||||
if ( pTime == NULL )
|
||||
{
|
||||
assert( pCell->n_outputs > 1 );
|
||||
continue;
|
||||
}
|
||||
if ( fDept )
|
||||
Abc_SclDeptFanin( p, pTime, pObj, pFanin, k );
|
||||
else
|
||||
|
|
@ -928,4 +973,3 @@ void Abc_SclPrintBuffers( SC_Lib * pLib, Abc_Ntk_t * pNtk, int fVerbose )
|
|||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue