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);
|
void json_debug_value(json_t *json, json_value_t val, int indent);
|
||||||
|
|
||||||
extern Abc_Ntk_t * Abc_NtkFromMiniMapping( int * pArray );
|
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 ///
|
/// FUNCTION DEFINITIONS ///
|
||||||
|
|
@ -671,6 +673,68 @@ static const char * Jsonc_GetNodeOutName( Abc_Obj_t * pObj )
|
||||||
snprintf( Buffer, sizeof(Buffer), "n%d", Abc_ObjId(pObj) );
|
snprintf( Buffer, sizeof(Buffer), "n%d", Abc_ObjId(pObj) );
|
||||||
return Buffer;
|
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*************************************************************
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
|
@ -692,8 +756,18 @@ void Jsonc_WriteTest( Abc_Ntk_t * p, char * pFileName )
|
||||||
int i, Counter, Total;
|
int i, Counter, Total;
|
||||||
assert( Abc_NtkHasMapping(p) );
|
assert( Abc_NtkHasMapping(p) );
|
||||||
vNodes = Abc_NtkDfs2( p );
|
vNodes = Abc_NtkDfs2( p );
|
||||||
|
{
|
||||||
|
Vec_Ptr_t * vTemp = Jsonc_OrderTwinNodes( p, vNodes );
|
||||||
|
Vec_PtrFree( vNodes );
|
||||||
|
vNodes = vTemp;
|
||||||
|
}
|
||||||
vObj2Num = Vec_IntStartFull( Abc_NtkObjNumMax(p) );
|
vObj2Num = Vec_IntStartFull( Abc_NtkObjNumMax(p) );
|
||||||
Total = Abc_NtkPiNum(p) + Vec_PtrSize(vNodes) + Abc_NtkPoNum(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" );
|
pFile = fopen( pFileName, "wb" );
|
||||||
if ( pFile == NULL )
|
if ( pFile == NULL )
|
||||||
{
|
{
|
||||||
|
|
@ -727,6 +801,8 @@ void Jsonc_WriteTest( Abc_Ntk_t * p, char * pFileName )
|
||||||
fprintf( pFile, " {\n" );
|
fprintf( pFile, " {\n" );
|
||||||
fprintf( pFile, " \"type\": \"%s\",\n", "instance" );
|
fprintf( pFile, " \"type\": \"%s\",\n", "instance" );
|
||||||
fprintf( pFile, " \"name\": \"%s\",\n", Mio_GateReadName(pGate) );
|
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, " \"fanins\":\n" );
|
||||||
fprintf( pFile, " {\n" );
|
fprintf( pFile, " {\n" );
|
||||||
for ( pPin = Mio_GateReadPins(pGate), k = 0; pPin; pPin = Mio_PinReadNext(pPin), k++ )
|
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( vCounts );
|
||||||
Vec_IntFree( vBaseIds );
|
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 * vPiBases = NULL, * vPoBases = NULL;
|
||||||
|
Vec_Ptr_t * vNodeOutNames = NULL;
|
||||||
Vec_Int_t * vPiBits = NULL, * vPoBits = NULL;
|
Vec_Int_t * vPiBits = NULL, * vPoBits = NULL;
|
||||||
Vec_Int_t * vNodeMap = NULL, * vGateIdx = NULL, * vPoIdx = NULL;
|
Vec_Int_t * vNodeMap = NULL, * vGateIdx = NULL, * vPoIdx = NULL;
|
||||||
Vec_Int_t * vMapping = NULL, * vPoDrivers = 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;
|
int fSuccess = 0;
|
||||||
if ( ppDesignName )
|
if ( ppDesignName )
|
||||||
*ppDesignName = NULL;
|
*ppDesignName = NULL;
|
||||||
|
if ( pvNodeOutNames )
|
||||||
|
*pvNodeOutNames = NULL;
|
||||||
if ( pLib == NULL )
|
if ( pLib == NULL )
|
||||||
{
|
{
|
||||||
printf( "Genlib library is not available.\n" );
|
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 );
|
vPiBits = Vec_IntAlloc( pNodes->count );
|
||||||
vPoBases = Vec_PtrAlloc( pNodes->count );
|
vPoBases = Vec_PtrAlloc( pNodes->count );
|
||||||
vPoBits = Vec_IntAlloc( pNodes->count );
|
vPoBits = Vec_IntAlloc( pNodes->count );
|
||||||
|
vNodeOutNames = Vec_PtrAlloc( pNodes->count );
|
||||||
// first pass: collect object types and names
|
// first pass: collect object types and names
|
||||||
for ( i = 0; i < (int)pNodes->count; i++ )
|
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;
|
json_container_t * pFanObj;
|
||||||
Mio_Gate_t * pGate;
|
Mio_Gate_t * pGate;
|
||||||
Mio_Pin_t * pPin;
|
Mio_Pin_t * pPin;
|
||||||
char * pGateStr;
|
char * pGateStr, * pOutStr;
|
||||||
if ( pGateName == NULL || pGateName->type != JSON_STRING )
|
if ( pGateName == NULL || pGateName->type != JSON_STRING )
|
||||||
{
|
{
|
||||||
printf( "Gate node %d is missing a name.\n", i );
|
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 );
|
printf( "Gate node %d has an invalid name.\n", i );
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
pGate = Mio_LibraryReadGateByName( pLib, pGateStr, NULL );
|
pOutStr = Jsonc_GetInstanceOutName( pJson, Node );
|
||||||
|
pGate = Mio_LibraryReadGateByName( pLib, pGateStr, pOutStr );
|
||||||
if ( pGate == NULL )
|
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 );
|
ABC_FREE( pGateStr );
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
if ( pFanins == NULL || pFanins->type != JSON_OBJECT )
|
if ( pFanins == NULL || pFanins->type != JSON_OBJECT )
|
||||||
{
|
{
|
||||||
printf( "Gate \"%s\" is missing \"fanins\" description.\n", pGateStr );
|
printf( "Gate \"%s\" is missing \"fanins\" description.\n", pGateStr );
|
||||||
|
ABC_FREE( pOutStr );
|
||||||
ABC_FREE( pGateStr );
|
ABC_FREE( pGateStr );
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
@ -1049,6 +1132,7 @@ static Vec_Int_t * Jsonc_ConvertToMiniMapping( json_t * pJson, Mio_Library_t * p
|
||||||
if ( pFanObj == NULL )
|
if ( pFanObj == NULL )
|
||||||
{
|
{
|
||||||
printf( "Gate \"%s\" has incomplete fanin information.\n", pGateStr );
|
printf( "Gate \"%s\" has incomplete fanin information.\n", pGateStr );
|
||||||
|
ABC_FREE( pOutStr );
|
||||||
ABC_FREE( pGateStr );
|
ABC_FREE( pGateStr );
|
||||||
goto cleanup;
|
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 )
|
if ( pPinInfo == NULL || pPinInfo->type != JSON_OBJECT )
|
||||||
{
|
{
|
||||||
printf( "Gate \"%s\" is missing connection for pin \"%s\".\n", pGateStr, Mio_PinReadName(pPin) );
|
printf( "Gate \"%s\" is missing connection for pin \"%s\".\n", pGateStr, Mio_PinReadName(pPin) );
|
||||||
|
ABC_FREE( pOutStr );
|
||||||
ABC_FREE( pGateStr );
|
ABC_FREE( pGateStr );
|
||||||
goto cleanup;
|
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 ) )
|
if ( pNodeLit == NULL || !Jsonc_ParseInt( pJson, *pNodeLit, &NodeId ) )
|
||||||
{
|
{
|
||||||
printf( "Gate \"%s\" has invalid node reference on pin \"%s\".\n", pGateStr, Mio_PinReadName(pPin) );
|
printf( "Gate \"%s\" has invalid node reference on pin \"%s\".\n", pGateStr, Mio_PinReadName(pPin) );
|
||||||
|
ABC_FREE( pOutStr );
|
||||||
ABC_FREE( pGateStr );
|
ABC_FREE( pGateStr );
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
if ( NodeId < 0 || NodeId >= Vec_IntSize(vNodeMap) )
|
if ( NodeId < 0 || NodeId >= Vec_IntSize(vNodeMap) )
|
||||||
{
|
{
|
||||||
printf( "Gate \"%s\" references out-of-range node %d.\n", pGateStr, NodeId );
|
printf( "Gate \"%s\" references out-of-range node %d.\n", pGateStr, NodeId );
|
||||||
|
ABC_FREE( pOutStr );
|
||||||
ABC_FREE( pGateStr );
|
ABC_FREE( pGateStr );
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
@ -1081,6 +1168,7 @@ static Vec_Int_t * Jsonc_ConvertToMiniMapping( json_t * pJson, Mio_Library_t * p
|
||||||
if ( MapId < 0 )
|
if ( MapId < 0 )
|
||||||
{
|
{
|
||||||
printf( "Gate \"%s\" refers to unsupported node %d.\n", pGateStr, NodeId );
|
printf( "Gate \"%s\" refers to unsupported node %d.\n", pGateStr, NodeId );
|
||||||
|
ABC_FREE( pOutStr );
|
||||||
ABC_FREE( pGateStr );
|
ABC_FREE( pGateStr );
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
@ -1088,6 +1176,7 @@ static Vec_Int_t * Jsonc_ConvertToMiniMapping( json_t * pJson, Mio_Library_t * p
|
||||||
}
|
}
|
||||||
Vec_StrPrintStr( vNames, pGateStr );
|
Vec_StrPrintStr( vNames, pGateStr );
|
||||||
Vec_StrPush( vNames, '\0' );
|
Vec_StrPush( vNames, '\0' );
|
||||||
|
Vec_PtrPush( vNodeOutNames, pOutStr );
|
||||||
ABC_FREE( pGateStr );
|
ABC_FREE( pGateStr );
|
||||||
}
|
}
|
||||||
else if ( Jsonc_StringEqual( pJson, *pType, "PO" ) || Jsonc_StringEqual( pJson, *pType, "po" ) )
|
else if ( Jsonc_StringEqual( pJson, *pType, "PO" ) || Jsonc_StringEqual( pJson, *pType, "po" ) )
|
||||||
|
|
@ -1148,6 +1237,18 @@ cleanup:
|
||||||
Vec_IntFreeP( &vPoBits );
|
Vec_IntFreeP( &vPoBits );
|
||||||
if ( vNames )
|
if ( vNames )
|
||||||
Vec_StrFree( 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 )
|
if ( vPiBases )
|
||||||
{
|
{
|
||||||
Vec_PtrForEachEntry( char *, vPiBases, pBase, i )
|
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();
|
Mio_Library_t * pLib = (Mio_Library_t *)Abc_FrameReadLibGen();
|
||||||
Vec_Int_t * vMapping;
|
Vec_Int_t * vMapping;
|
||||||
|
Vec_Ptr_t * vNodeOutNames = NULL;
|
||||||
Abc_Ntk_t * pNtk;
|
Abc_Ntk_t * pNtk;
|
||||||
|
Abc_Obj_t * pObj;
|
||||||
char * pDesignName = NULL;
|
char * pDesignName = NULL;
|
||||||
|
char * pOutName;
|
||||||
|
int i;
|
||||||
json_t * pJson = json_create();
|
json_t * pJson = json_create();
|
||||||
if ( pJson == NULL )
|
if ( pJson == NULL )
|
||||||
{
|
{
|
||||||
|
|
@ -1185,7 +1290,7 @@ Abc_Ntk_t * Jsonc_ReadNetwork( char * pFileName )
|
||||||
json_destroy( pJson );
|
json_destroy( pJson );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
vMapping = Jsonc_ConvertToMiniMapping( pJson, pLib, &pDesignName );
|
vMapping = Jsonc_ConvertToMiniMapping( pJson, pLib, &pDesignName, &vNodeOutNames );
|
||||||
json_destroy( pJson );
|
json_destroy( pJson );
|
||||||
if ( vMapping == NULL )
|
if ( vMapping == NULL )
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -1193,9 +1298,35 @@ Abc_Ntk_t * Jsonc_ReadNetwork( char * pFileName )
|
||||||
Vec_IntFree( vMapping );
|
Vec_IntFree( vMapping );
|
||||||
if ( pNtk == NULL )
|
if ( pNtk == NULL )
|
||||||
{
|
{
|
||||||
|
if ( vNodeOutNames )
|
||||||
|
{
|
||||||
|
Vec_PtrForEachEntry( char *, vNodeOutNames, pOutName, i )
|
||||||
|
ABC_FREE( pOutName );
|
||||||
|
Vec_PtrFree( vNodeOutNames );
|
||||||
|
}
|
||||||
ABC_FREE( pDesignName );
|
ABC_FREE( pDesignName );
|
||||||
return NULL;
|
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 );
|
ABC_FREE( pNtk->pName );
|
||||||
pNtk->pName = pDesignName ? pDesignName : Extra_FileNameGeneric( pFileName );
|
pNtk->pName = pDesignName ? pDesignName : Extra_FileNameGeneric( pFileName );
|
||||||
ABC_FREE( pNtk->pSpec );
|
ABC_FREE( pNtk->pSpec );
|
||||||
|
|
|
||||||
|
|
@ -622,46 +622,65 @@ int Io_ReadBlifReorderFormalNames( Vec_Ptr_t * vTokens, Mio_Gate_t * pGate, Mio_
|
||||||
}
|
}
|
||||||
else
|
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;
|
return 0;
|
||||||
// check the last two entries
|
// reorder the input pins to be in the same order as in the gate
|
||||||
if ( nSize - 3 == Mio_GateReadPinNum(pGate) ) // only one output is available
|
for ( pGatePin = Mio_GateReadPins(pGate), i = 0; pGatePin; pGatePin = Mio_PinReadNext(pGatePin), i++ )
|
||||||
{
|
{
|
||||||
pNamePin = Mio_GateReadOutName(pGate);
|
pNamePin = Mio_PinReadName(pGatePin);
|
||||||
Length = strlen(pNamePin);
|
Length = strlen(pNamePin);
|
||||||
pName = (char *)Vec_PtrEntry(vTokens, nSize - 1);
|
for ( k = 2; k < nSize; k++ )
|
||||||
if ( !strncmp( pNamePin, pName, Length ) && pName[Length] == '=' ) // the last entry is pGate
|
|
||||||
{
|
{
|
||||||
Vec_PtrPush( vTokens, NULL );
|
pName = (char *)Vec_PtrEntry(vTokens, k);
|
||||||
return 1;
|
if ( !strncmp( pNamePin, pName, Length ) && pName[Length] == '=' )
|
||||||
}
|
|
||||||
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 = (char *)Vec_PtrPop( vTokens );
|
|
||||||
Vec_PtrPush( vTokens, NULL );
|
|
||||||
Vec_PtrPush( vTokens, pName );
|
Vec_PtrPush( vTokens, pName );
|
||||||
return 1;
|
nMatched++;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if ( k == nSize )
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if ( nSize - 4 == Mio_GateReadPinNum(pGate) ) // two outputs are available
|
// add the outputs in the base/twin order, with NULL for a missing output
|
||||||
{
|
|
||||||
pNamePin = Mio_GateReadOutName(pGate);
|
pNamePin = Mio_GateReadOutName(pGate);
|
||||||
Length = strlen(pNamePin);
|
Length = strlen(pNamePin);
|
||||||
pName = (char *)Vec_PtrEntry(vTokens, nSize - 2);
|
for ( k = 2; k < nSize; k++ )
|
||||||
if ( !(!strncmp( pNamePin, pName, Length ) && pName[Length] == '=') )
|
{
|
||||||
return 0;
|
pName = (char *)Vec_PtrEntry(vTokens, k);
|
||||||
|
if ( !strncmp( pNamePin, pName, Length ) && pName[Length] == '=' )
|
||||||
|
{
|
||||||
|
Vec_PtrPush( vTokens, pName );
|
||||||
|
nMatched++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( k == nSize )
|
||||||
|
Vec_PtrPush( vTokens, NULL );
|
||||||
pNamePin = Mio_GateReadOutName(pTwin);
|
pNamePin = Mio_GateReadOutName(pTwin);
|
||||||
Length = strlen(pNamePin);
|
Length = strlen(pNamePin);
|
||||||
pName = (char *)Vec_PtrEntry(vTokens, nSize - 1);
|
for ( k = 2; k < nSize; k++ )
|
||||||
if ( !(!strncmp( pNamePin, pName, Length ) && pName[Length] == '=') )
|
{
|
||||||
return 0;
|
pName = (char *)Vec_PtrEntry(vTokens, k);
|
||||||
return 1;
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -1713,4 +1732,3 @@ int Io_ReadBlifNetworkConnectBoxes( Io_ReadBlif_t * p, Abc_Ntk_t * pNtkMaster )
|
||||||
|
|
||||||
|
|
||||||
ABC_NAMESPACE_IMPL_END
|
ABC_NAMESPACE_IMPL_END
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -573,6 +573,17 @@ void Io_NtkWriteSubcktFanins( FILE * pFile, Abc_Obj_t * pNode )
|
||||||
SeeAlso []
|
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 )
|
int Io_NtkWriteNodeGate( FILE * pFile, Abc_Obj_t * pNode, int Length )
|
||||||
{
|
{
|
||||||
static int fReport = 0;
|
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) );
|
fReport = 1, printf( "Warning: Missing second output of gate(s) \"%s\".\n", Mio_GateReadName(pGate) );
|
||||||
return 0;
|
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) ) );
|
fprintf( pFile, " %s=%s", Mio_GateReadOutName((Mio_Gate_t *)pNode2->pData), Abc_ObjName( Abc_ObjFanout0(pNode2) ) );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -1407,4 +1420,3 @@ void Io_WriteBlifSpecial( Abc_Ntk_t * pNtk, char * FileName, char * pLutStruct,
|
||||||
|
|
||||||
|
|
||||||
ABC_NAMESPACE_IMPL_END
|
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 void Io_WriteVerilogObjects( FILE * pFile, Abc_Ntk_t * pNtk, int fOnlyAnds );
|
||||||
static int Io_WriteVerilogWiresCount( Abc_Ntk_t * pNtk );
|
static int Io_WriteVerilogWiresCount( Abc_Ntk_t * pNtk );
|
||||||
static char * Io_WriteVerilogGetName( char * pName );
|
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 ///
|
/// FUNCTION DEFINITIONS ///
|
||||||
|
|
@ -512,6 +514,54 @@ void Io_WriteVerilogLatches( FILE * pFile, Abc_Ntk_t * pNtk )
|
||||||
fprintf( pFile, " end\n" );
|
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*************************************************************
|
/**Function*************************************************************
|
||||||
|
|
||||||
Synopsis [Writes the nodes and boxes.]
|
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 )
|
Abc_NtkForEachNode( pNtk, pObj, k )
|
||||||
{
|
{
|
||||||
Mio_Gate_t * pGate = (Mio_Gate_t *)pObj->pData;
|
Mio_Gate_t * pGate = (Mio_Gate_t *)pObj->pData;
|
||||||
|
Abc_Obj_t * pNode2 = NULL;
|
||||||
Mio_Pin_t * pGatePin;
|
Mio_Pin_t * pGatePin;
|
||||||
|
if ( Io_WriteVerilogIsPrevTwinNode( pObj ) )
|
||||||
|
continue;
|
||||||
if ( Abc_ObjFaninNum(pObj) == 0 && (!strcmp(Mio_GateReadName(pGate), "_const0_") || !strcmp(Mio_GateReadName(pGate), "_const1_")) )
|
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_") );
|
fprintf( pFile, " %-*s %s = 1\'b%d;\n", Length, "assign", Io_WriteVerilogGetName(Abc_ObjName( Abc_ObjFanout0(pObj) )), !strcmp(Mio_GateReadName(pGate), "_const1_") );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
pNode2 = Abc_NtkFetchTwinNode( pObj );
|
||||||
|
if ( pNode2 && !Io_WriteVerilogNodesHaveSameFanins( pObj, pNode2 ) )
|
||||||
|
pNode2 = NULL;
|
||||||
// write the node
|
// write the node
|
||||||
if ( fUseSimpleGateNames )
|
if ( fUseSimpleGateNames )
|
||||||
{
|
{
|
||||||
|
|
@ -591,6 +647,12 @@ void Io_WriteVerilogObjects( FILE * pFile, Abc_Ntk_t * pNtk, int fOnlyAnds )
|
||||||
assert ( i == Abc_ObjFaninNum(pObj) );
|
assert ( i == Abc_ObjFaninNum(pObj) );
|
||||||
fprintf( pFile, ".%s", Io_WriteVerilogGetName(Mio_GateReadOutName(pGate)) );
|
fprintf( pFile, ".%s", Io_WriteVerilogGetName(Mio_GateReadOutName(pGate)) );
|
||||||
fprintf( pFile, "(%s)", Io_WriteVerilogGetName(Abc_ObjName( Abc_ObjFanout0(pObj) )) );
|
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" );
|
fprintf( pFile, ");\n" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -972,4 +1034,3 @@ void Io_WriteVerilogLut( Abc_Ntk_t * pNtk, char * pFileName, int nLutSize, int f
|
||||||
|
|
||||||
|
|
||||||
ABC_NAMESPACE_IMPL_END
|
ABC_NAMESPACE_IMPL_END
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -656,12 +656,13 @@ static inline void Scl_LibPinRequiredI( SC_Timing * pTime, SC_PairI * pReqIn, SC
|
||||||
SeeAlso []
|
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_Pin * pPin;
|
||||||
SC_Timings * pRTime;
|
SC_Timings * pRTime;
|
||||||
|
assert( iOut >= 0 && iOut < pCell->n_outputs );
|
||||||
assert( iPin >= 0 && iPin < pCell->n_inputs );
|
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 );
|
assert( Vec_PtrSize(&pPin->vRTimings) == pCell->n_inputs );
|
||||||
pRTime = (SC_Timings *)Vec_PtrEntry( &pPin->vRTimings, iPin );
|
pRTime = (SC_Timings *)Vec_PtrEntry( &pPin->vRTimings, iPin );
|
||||||
if ( Vec_PtrSize(&pRTime->vTimings) == 0 )
|
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 );
|
assert( Vec_PtrSize(&pRTime->vTimings) == 1 );
|
||||||
return (SC_Timing *)Vec_PtrEntry( &pRTime->vTimings, 0 );
|
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 )
|
static inline float Scl_LibPinArrivalEstimate( SC_Cell * pCell, int iPin, float Slew, float Load )
|
||||||
{
|
{
|
||||||
SC_Pair LoadIn = { Load, 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;
|
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*************************************************************
|
/**Function*************************************************************
|
||||||
|
|
||||||
Synopsis [Printing timing information for the node/network.]
|
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) );
|
SC_PairClean( Abc_SclObjDept(p, pObj) );
|
||||||
Abc_ObjForEachFanout( pObj, pFanout, i )
|
Abc_ObjForEachFanout( pObj, pFanout, i )
|
||||||
{
|
{
|
||||||
|
SC_Cell * pFanoutCell;
|
||||||
|
int iFanin, iOut;
|
||||||
if ( Abc_ObjIsCo(pFanout) || Abc_ObjIsLatch(pFanout) )
|
if ( Abc_ObjIsCo(pFanout) || Abc_ObjIsLatch(pFanout) )
|
||||||
continue;
|
continue;
|
||||||
pTime = Scl_CellPinTime( Abc_SclObjCell(pFanout), Abc_NodeFindFanin(pFanout, pObj) );
|
pFanoutCell = Abc_SclObjCell( pFanout );
|
||||||
Abc_SclDeptFanin( p, pTime, pFanout, pObj, Abc_NodeFindFanin(pFanout, pObj) );
|
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 )
|
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
|
// compute for each fanin
|
||||||
Abc_ObjForEachFanin( pObj, pFanin, k )
|
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 )
|
if ( fDept )
|
||||||
Abc_SclDeptFanin( p, pTime, pObj, pFanin, k );
|
Abc_SclDeptFanin( p, pTime, pObj, pFanin, k );
|
||||||
else
|
else
|
||||||
|
|
@ -928,4 +973,3 @@ void Abc_SclPrintBuffers( SC_Lib * pLib, Abc_Ntk_t * pNtk, int fVerbose )
|
||||||
|
|
||||||
ABC_NAMESPACE_IMPL_END
|
ABC_NAMESPACE_IMPL_END
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue