mirror of https://github.com/YosysHQ/abc.git
469 lines
12 KiB
C
469 lines
12 KiB
C
/**CFile****************************************************************
|
|
|
|
FileName [seqUtil.c]
|
|
|
|
SystemName [ABC: Logic synthesis and verification system.]
|
|
|
|
PackageName [Construction and manipulation of sequential AIGs.]
|
|
|
|
Synopsis [Various utilities working with sequential AIGs.]
|
|
|
|
Author [Alan Mishchenko]
|
|
|
|
Affiliation [UC Berkeley]
|
|
|
|
Date [Ver. 1.0. Started - June 20, 2005.]
|
|
|
|
Revision [$Id: seqUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
|
|
|
***********************************************************************/
|
|
|
|
#include "seqInt.h"
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// DECLARATIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// FUNCTION DEFINITIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Returns the maximum latch number on any of the fanouts.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Seq_NtkLevelMax( Abc_Ntk_t * pNtk )
|
|
{
|
|
Abc_Obj_t * pNode;
|
|
int i, Result;
|
|
assert( Abc_NtkIsSeq(pNtk) );
|
|
Result = 0;
|
|
Abc_NtkForEachPo( pNtk, pNode, i )
|
|
{
|
|
pNode = Abc_ObjFanin0(pNode);
|
|
if ( Result < (int)pNode->Level )
|
|
Result = pNode->Level;
|
|
}
|
|
Abc_SeqForEachCutsetNode( pNtk, pNode, i )
|
|
{
|
|
if ( Result < (int)pNode->Level )
|
|
Result = pNode->Level;
|
|
}
|
|
return Result;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Returns the maximum latch number on any of the fanouts.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Seq_ObjFanoutLMax( Abc_Obj_t * pObj )
|
|
{
|
|
Abc_Obj_t * pFanout;
|
|
int i, nLatchCur, nLatchRes;
|
|
if ( Abc_ObjFanoutNum(pObj) == 0 )
|
|
return 0;
|
|
nLatchRes = 0;
|
|
Abc_ObjForEachFanout( pObj, pFanout, i )
|
|
{
|
|
nLatchCur = Seq_ObjFanoutL(pObj, pFanout);
|
|
if ( nLatchRes < nLatchCur )
|
|
nLatchRes = nLatchCur;
|
|
}
|
|
assert( nLatchRes >= 0 );
|
|
return nLatchRes;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Returns the minimum latch number on any of the fanouts.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Seq_ObjFanoutLMin( Abc_Obj_t * pObj )
|
|
{
|
|
Abc_Obj_t * pFanout;
|
|
int i, nLatchCur, nLatchRes;
|
|
if ( Abc_ObjFanoutNum(pObj) == 0 )
|
|
return 0;
|
|
nLatchRes = ABC_INFINITY;
|
|
Abc_ObjForEachFanout( pObj, pFanout, i )
|
|
{
|
|
nLatchCur = Seq_ObjFanoutL(pObj, pFanout);
|
|
if ( nLatchRes > nLatchCur )
|
|
nLatchRes = nLatchCur;
|
|
}
|
|
assert( nLatchRes < ABC_INFINITY );
|
|
return nLatchRes;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Returns the sum of latches on the fanout edges.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Seq_ObjFanoutLSum( Abc_Obj_t * pObj )
|
|
{
|
|
Abc_Obj_t * pFanout;
|
|
int i, nSum = 0;
|
|
Abc_ObjForEachFanout( pObj, pFanout, i )
|
|
nSum += Seq_ObjFanoutL(pObj, pFanout);
|
|
return nSum;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Returns the sum of latches on the fanin edges.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Seq_ObjFaninLSum( Abc_Obj_t * pObj )
|
|
{
|
|
Abc_Obj_t * pFanin;
|
|
int i, nSum = 0;
|
|
Abc_ObjForEachFanin( pObj, pFanin, i )
|
|
nSum += Seq_ObjFaninL(pObj, i);
|
|
return nSum;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Generates the printable edge label with the initial state.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
char * Seq_ObjFaninGetInitPrintable( Abc_Obj_t * pObj, int Edge )
|
|
{
|
|
static char Buffer[1000];
|
|
Abc_InitType_t Init;
|
|
int nLatches, i;
|
|
nLatches = Seq_ObjFaninL( pObj, Edge );
|
|
for ( i = 0; i < nLatches; i++ )
|
|
{
|
|
Init = Seq_LatInit( Seq_NodeGetLat(pObj, Edge, i) );
|
|
if ( Init == ABC_INIT_NONE )
|
|
Buffer[i] = '_';
|
|
else if ( Init == ABC_INIT_ZERO )
|
|
Buffer[i] = '0';
|
|
else if ( Init == ABC_INIT_ONE )
|
|
Buffer[i] = '1';
|
|
else if ( Init == ABC_INIT_DC )
|
|
Buffer[i] = 'x';
|
|
else assert( 0 );
|
|
}
|
|
Buffer[nLatches] = 0;
|
|
return Buffer;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Sets the given value to all the latches of the edge.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Seq_NodeLatchSetValues( Abc_Obj_t * pObj, int Edge, Abc_InitType_t Init )
|
|
{
|
|
Seq_Lat_t * pLat, * pRing;
|
|
int c;
|
|
pRing = Seq_NodeGetRing(pObj, Edge);
|
|
if ( pRing == NULL )
|
|
return;
|
|
for ( c = 0, pLat = pRing; !c || pLat != pRing; c++, pLat = pLat->pNext )
|
|
Seq_LatSetInit( pLat, Init );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Sets the given value to all the latches of the edge.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Seq_NtkLatchSetValues( Abc_Ntk_t * pNtk, Abc_InitType_t Init )
|
|
{
|
|
Abc_Obj_t * pObj;
|
|
int i;
|
|
assert( Abc_NtkIsSeq( pNtk ) );
|
|
Abc_NtkForEachPo( pNtk, pObj, i )
|
|
Seq_NodeLatchSetValues( pObj, 0, Init );
|
|
Abc_NtkForEachNode( pNtk, pObj, i )
|
|
{
|
|
Seq_NodeLatchSetValues( pObj, 0, Init );
|
|
Seq_NodeLatchSetValues( pObj, 1, Init );
|
|
}
|
|
}
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Counts the number of latches in the sequential AIG.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Seq_NtkLatchNum( Abc_Ntk_t * pNtk )
|
|
{
|
|
Abc_Obj_t * pObj;
|
|
int i, Counter;
|
|
assert( Abc_NtkIsSeq( pNtk ) );
|
|
Counter = 0;
|
|
Abc_NtkForEachNode( pNtk, pObj, i )
|
|
Counter += Seq_ObjFaninLSum( pObj );
|
|
Abc_NtkForEachPo( pNtk, pObj, i )
|
|
Counter += Seq_ObjFaninLSum( pObj );
|
|
return Counter;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Counts the number of latches in the sequential AIG.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Seq_NtkLatchNumMax( Abc_Ntk_t * pNtk )
|
|
{
|
|
Abc_Obj_t * pObj;
|
|
int i, Max, Cur;
|
|
assert( Abc_NtkIsSeq( pNtk ) );
|
|
Max = 0;
|
|
Abc_AigForEachAnd( pNtk, pObj, i )
|
|
{
|
|
Cur = Seq_ObjFaninLMax( pObj );
|
|
if ( Max < Cur )
|
|
Max = Cur;
|
|
}
|
|
Abc_NtkForEachPo( pNtk, pObj, i )
|
|
{
|
|
Cur = Seq_ObjFaninL0( pObj );
|
|
if ( Max < Cur )
|
|
Max = Cur;
|
|
}
|
|
return Max;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Counts the number of latches in the sequential AIG.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Seq_NtkLatchNumShared( Abc_Ntk_t * pNtk )
|
|
{
|
|
Abc_Obj_t * pObj;
|
|
int i, Counter;
|
|
assert( Abc_NtkIsSeq( pNtk ) );
|
|
Counter = 0;
|
|
Abc_NtkForEachPi( pNtk, pObj, i )
|
|
Counter += Seq_ObjFanoutLMax( pObj );
|
|
Abc_NtkForEachNode( pNtk, pObj, i )
|
|
Counter += Seq_ObjFanoutLMax( pObj );
|
|
return Counter;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Counts the number of latches in the sequential AIG.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Seq_ObjLatchGetInitNums( Abc_Obj_t * pObj, int Edge, int * pInits )
|
|
{
|
|
Abc_InitType_t Init;
|
|
int nLatches, i;
|
|
nLatches = Seq_ObjFaninL( pObj, Edge );
|
|
for ( i = 0; i < nLatches; i++ )
|
|
{
|
|
Init = Seq_NodeGetInitOne( pObj, Edge, i );
|
|
pInits[Init]++;
|
|
}
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Counts the number of latches in the sequential AIG.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Seq_NtkLatchGetInitNums( Abc_Ntk_t * pNtk, int * pInits )
|
|
{
|
|
Abc_Obj_t * pObj;
|
|
int i;
|
|
assert( Abc_NtkIsSeq( pNtk ) );
|
|
for ( i = 0; i < 4; i++ )
|
|
pInits[i] = 0;
|
|
Abc_NtkForEachPo( pNtk, pObj, i )
|
|
Seq_ObjLatchGetInitNums( pObj, 0, pInits );
|
|
Abc_NtkForEachNode( pNtk, pObj, i )
|
|
{
|
|
if ( Abc_ObjFaninNum(pObj) > 0 )
|
|
Seq_ObjLatchGetInitNums( pObj, 0, pInits );
|
|
if ( Abc_ObjFaninNum(pObj) > 1 )
|
|
Seq_ObjLatchGetInitNums( pObj, 1, pInits );
|
|
}
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Report nodes with equal fanins.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Seq_NtkLatchGetEqualFaninNum( Abc_Ntk_t * pNtk )
|
|
{
|
|
Abc_Obj_t * pObj;
|
|
int i, Counter;
|
|
assert( Abc_NtkIsSeq( pNtk ) );
|
|
Counter = 0;
|
|
Abc_AigForEachAnd( pNtk, pObj, i )
|
|
if ( Abc_ObjFaninId0(pObj) == Abc_ObjFaninId1(pObj) )
|
|
Counter++;
|
|
if ( Counter )
|
|
printf( "The number of nodes with equal fanins = %d.\n", Counter );
|
|
return Counter;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Returns the maximum latch number on any of the fanouts.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Seq_NtkCountNodesAboveLimit( Abc_Ntk_t * pNtk, int Limit )
|
|
{
|
|
Abc_Obj_t * pNode;
|
|
int i, Counter;
|
|
assert( !Abc_NtkIsSeq(pNtk) );
|
|
Counter = 0;
|
|
Abc_NtkForEachNode( pNtk, pNode, i )
|
|
if ( Abc_ObjFaninNum(pNode) > Limit )
|
|
Counter++;
|
|
return Counter;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Computes area flows.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Seq_MapComputeAreaFlows( Abc_Ntk_t * pNtk, int fVerbose )
|
|
{
|
|
Abc_Seq_t * p = pNtk->pManFunc;
|
|
Abc_Obj_t * pObj;
|
|
float AFlow;
|
|
int i, c;
|
|
|
|
assert( Abc_NtkIsSeq(pNtk) );
|
|
|
|
Vec_IntFill( p->vAFlows, p->nSize, Abc_Float2Int( (float)0.0 ) );
|
|
|
|
// update all values iteratively
|
|
for ( c = 0; c < 7; c++ )
|
|
{
|
|
Abc_AigForEachAnd( pNtk, pObj, i )
|
|
{
|
|
AFlow = (float)1.0 + Seq_NodeGetFlow( Abc_ObjFanin0(pObj) ) + Seq_NodeGetFlow( Abc_ObjFanin1(pObj) );
|
|
AFlow /= Abc_ObjFanoutNum(pObj);
|
|
pObj->pNext = (void *)Abc_Float2Int( AFlow );
|
|
}
|
|
Abc_AigForEachAnd( pNtk, pObj, i )
|
|
{
|
|
AFlow = Abc_Int2Float( (int)pObj->pNext );
|
|
pObj->pNext = NULL;
|
|
Seq_NodeSetFlow( pObj, AFlow );
|
|
|
|
// printf( "%5d : %6.1f\n", pObj->Id, Seq_NodeGetFlow(pObj) );
|
|
}
|
|
// printf( "\n" );
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// END OF FILE ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|