blob: 8cec978875f7be5508bcca641fc7609c728e6f4e [file] [log] [blame]
/**CFile****************************************************************
FileName [timMan.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Hierarchy/timing manager.]
Synopsis [Manipulation of manager data-structure.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - April 28, 2007.]
Revision [$Id: timMan.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
***********************************************************************/
#include "timInt.h"
#include "map/if/if.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Starts the timing manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Tim_Man_t * Tim_ManStart( int nCis, int nCos )
{
Tim_Man_t * p;
Tim_Obj_t * pObj;
int i;
p = ABC_ALLOC( Tim_Man_t, 1 );
memset( p, 0, sizeof(Tim_Man_t) );
p->pMemObj = Mem_FlexStart();
p->nCis = nCis;
p->nCos = nCos;
p->pCis = ABC_ALLOC( Tim_Obj_t, nCis );
memset( p->pCis, 0, sizeof(Tim_Obj_t) * nCis );
p->pCos = ABC_ALLOC( Tim_Obj_t, nCos );
memset( p->pCos, 0, sizeof(Tim_Obj_t) * nCos );
Tim_ManForEachCi( p, pObj, i )
{
pObj->Id = i;
pObj->iObj2Box = pObj->iObj2Num = -1;
pObj->timeReq = TIM_ETERNITY;
}
Tim_ManForEachCo( p, pObj, i )
{
pObj->Id = i;
pObj->iObj2Box = pObj->iObj2Num = -1;
pObj->timeReq = TIM_ETERNITY;
}
p->fUseTravId = 1;
return p;
}
/**Function*************************************************************
Synopsis [Duplicates the timing manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Tim_Man_t * Tim_ManDup( Tim_Man_t * p, int fUnitDelay )
{
Tim_Man_t * pNew;
Tim_Box_t * pBox;
Tim_Obj_t * pObj;
float * pDelayTable, * pDelayTableNew;
int i, k, nInputs, nOutputs;
// clear traversal IDs
Tim_ManForEachCi( p, pObj, i )
pObj->TravId = 0;
Tim_ManForEachCo( p, pObj, i )
pObj->TravId = 0;
// create new manager
pNew = Tim_ManStart( p->nCis, p->nCos );
// copy box connectivity information
memcpy( pNew->pCis, p->pCis, sizeof(Tim_Obj_t) * p->nCis );
memcpy( pNew->pCos, p->pCos, sizeof(Tim_Obj_t) * p->nCos );
if ( fUnitDelay )
{
// discretize PI arrival times
// Tim_ManForEachPi( pNew, pObj, k )
// pObj->timeArr = (int)pObj->timeArr;
// discretize PO required times
// Tim_ManForEachPo( pNew, pObj, k )
// pObj->timeReq = 1 + (int)pObj->timeReq;
// clear PI arrival and PO required
Tim_ManInitPiArrivalAll( p, 0.0 );
Tim_ManInitPoRequiredAll( p, (float)TIM_ETERNITY );
}
// duplicate delay tables
if ( Tim_ManDelayTableNum(p) > 0 )
{
pNew->vDelayTables = Vec_PtrStart( Vec_PtrSize(p->vDelayTables) );
Tim_ManForEachTable( p, pDelayTable, i )
{
if ( pDelayTable == NULL )
continue;
assert( i == (int)pDelayTable[0] );
nInputs = (int)pDelayTable[1];
nOutputs = (int)pDelayTable[2];
pDelayTableNew = ABC_ALLOC( float, 3 + nInputs * nOutputs );
pDelayTableNew[0] = (int)pDelayTable[0];
pDelayTableNew[1] = (int)pDelayTable[1];
pDelayTableNew[2] = (int)pDelayTable[2];
for ( k = 0; k < nInputs * nOutputs; k++ )
if ( pDelayTable[3+k] == -ABC_INFINITY )
pDelayTableNew[3+k] = -ABC_INFINITY;
else
pDelayTableNew[3+k] = fUnitDelay ? (float)fUnitDelay : pDelayTable[3+k];
// assert( (int)pDelayTableNew[0] == Vec_PtrSize(pNew->vDelayTables) );
assert( Vec_PtrEntry(pNew->vDelayTables, i) == NULL );
Vec_PtrWriteEntry( pNew->vDelayTables, i, pDelayTableNew );
//printf( "Finished duplicating delay table %d.\n", i );
}
}
// duplicate boxes
if ( Tim_ManBoxNum(p) > 0 )
{
pNew->vBoxes = Vec_PtrAlloc( Tim_ManBoxNum(p) );
Tim_ManForEachBox( p, pBox, i )
{
Tim_ManCreateBox( pNew, pBox->Inouts[0], pBox->nInputs,
pBox->Inouts[pBox->nInputs], pBox->nOutputs, pBox->iDelayTable, pBox->fBlack );
Tim_ManBoxSetCopy( pNew, i, pBox->iCopy );
}
}
return pNew;
}
/**Function*************************************************************
Synopsis [Trims the timing manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Tim_Man_t * Tim_ManTrim( Tim_Man_t * p, Vec_Int_t * vBoxPres )
{
Tim_Man_t * pNew;
Tim_Box_t * pBox;
Tim_Obj_t * pObj;
float * pDelayTable, * pDelayTableNew;
int i, k, nNewCis, nNewCos, nInputs, nOutputs;
assert( Vec_IntSize(vBoxPres) == Tim_ManBoxNum(p) );
// count the number of CIs and COs in the trimmed manager
nNewCis = Tim_ManPiNum(p);
nNewCos = Tim_ManPoNum(p);
if ( Tim_ManBoxNum(p) )
Tim_ManForEachBox( p, pBox, i )
if ( Vec_IntEntry(vBoxPres, i) )
{
nNewCis += pBox->nOutputs;
nNewCos += pBox->nInputs;
}
if ( nNewCis == Tim_ManCiNum(p) && nNewCos == Tim_ManCoNum(p) )
return Tim_ManDup( p, 0 );
assert( nNewCis < Tim_ManCiNum(p) );
assert( nNewCos < Tim_ManCoNum(p) );
// clear traversal IDs
Tim_ManForEachCi( p, pObj, i )
pObj->TravId = 0;
Tim_ManForEachCo( p, pObj, i )
pObj->TravId = 0;
// create new manager
pNew = Tim_ManStart( nNewCis, nNewCos );
// copy box connectivity information
memcpy( pNew->pCis, p->pCis, sizeof(Tim_Obj_t) * Tim_ManPiNum(p) );
memcpy( pNew->pCos + nNewCos - Tim_ManPoNum(p),
p->pCos + Tim_ManCoNum(p) - Tim_ManPoNum(p),
sizeof(Tim_Obj_t) * Tim_ManPoNum(p) );
// duplicate delay tables
if ( Tim_ManDelayTableNum(p) > 0 )
{
pNew->vDelayTables = Vec_PtrStart( Vec_PtrSize(p->vDelayTables) );
Tim_ManForEachTable( p, pDelayTable, i )
{
if ( pDelayTable == NULL )
continue;
assert( i == (int)pDelayTable[0] );
nInputs = (int)pDelayTable[1];
nOutputs = (int)pDelayTable[2];
pDelayTableNew = ABC_ALLOC( float, 3 + nInputs * nOutputs );
pDelayTableNew[0] = (int)pDelayTable[0];
pDelayTableNew[1] = (int)pDelayTable[1];
pDelayTableNew[2] = (int)pDelayTable[2];
for ( k = 0; k < nInputs * nOutputs; k++ )
pDelayTableNew[3+k] = pDelayTable[3+k];
// assert( (int)pDelayTableNew[0] == Vec_PtrSize(pNew->vDelayTables) );
assert( Vec_PtrEntry(pNew->vDelayTables, i) == NULL );
Vec_PtrWriteEntry( pNew->vDelayTables, i, pDelayTableNew );
}
}
// duplicate boxes
if ( Tim_ManBoxNum(p) > 0 )
{
int curPi = Tim_ManPiNum(p);
int curPo = 0;
pNew->vBoxes = Vec_PtrAlloc( Tim_ManBoxNum(p) );
Tim_ManForEachBox( p, pBox, i )
if ( Vec_IntEntry(vBoxPres, i) )
{
Tim_ManCreateBox( pNew, curPo, pBox->nInputs, curPi, pBox->nOutputs, pBox->iDelayTable, pBox->fBlack );
Tim_ManBoxSetCopy( pNew, Tim_ManBoxNum(pNew) - 1, Tim_ManBoxCopy(p, i) == -1 ? i : Tim_ManBoxCopy(p, i) );
curPi += pBox->nOutputs;
curPo += pBox->nInputs;
}
curPo += Tim_ManPoNum(p);
assert( curPi == Tim_ManCiNum(pNew) );
assert( curPo == Tim_ManCoNum(pNew) );
}
return pNew;
}
/**Function*************************************************************
Synopsis [Reduces the timing manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Tim_Man_t * Tim_ManReduce( Tim_Man_t * p, Vec_Int_t * vBoxesLeft, int nTermsDiff )
{
Tim_Man_t * pNew;
Tim_Box_t * pBox;
Tim_Obj_t * pObj;
float * pDelayTable, * pDelayTableNew;
int i, k, iBox, nNewCis, nNewCos, nInputs, nOutputs;
int nNewPiNum = Tim_ManPiNum(p) - nTermsDiff;
int nNewPoNum = Tim_ManPoNum(p) - nTermsDiff;
assert( Vec_IntSize(vBoxesLeft) <= Tim_ManBoxNum(p) );
// count the number of CIs and COs in the trimmed manager
nNewCis = nNewPiNum;
nNewCos = nNewPoNum;
Vec_IntForEachEntry( vBoxesLeft, iBox, i )
{
pBox = Tim_ManBox( p, iBox );
nNewCis += pBox->nOutputs;
nNewCos += pBox->nInputs;
}
assert( nNewCis <= Tim_ManCiNum(p) - nTermsDiff );
assert( nNewCos <= Tim_ManCoNum(p) - nTermsDiff );
// clear traversal IDs
Tim_ManForEachCi( p, pObj, i )
pObj->TravId = 0;
Tim_ManForEachCo( p, pObj, i )
pObj->TravId = 0;
// create new manager
pNew = Tim_ManStart( nNewCis, nNewCos );
// copy box connectivity information
memcpy( pNew->pCis, p->pCis, sizeof(Tim_Obj_t) * nNewPiNum );
memcpy( pNew->pCos + nNewCos - nNewPoNum,
p->pCos + Tim_ManCoNum(p) - Tim_ManPoNum(p),
sizeof(Tim_Obj_t) * nNewPoNum );
// duplicate delay tables
if ( Tim_ManDelayTableNum(p) > 0 )
{
int fWarning = 0;
pNew->vDelayTables = Vec_PtrStart( Vec_PtrSize(p->vDelayTables) );
Tim_ManForEachTable( p, pDelayTable, i )
{
if ( pDelayTable == NULL )
continue;
if ( i != (int)pDelayTable[0] && fWarning == 0 )
{
printf( "Warning: Mismatch in delay-table number between the manager and the box.\n" );
fWarning = 1;
}
//assert( i == (int)pDelayTable[0] );
nInputs = (int)pDelayTable[1];
nOutputs = (int)pDelayTable[2];
pDelayTableNew = ABC_ALLOC( float, 3 + nInputs * nOutputs );
pDelayTableNew[0] = i;//(int)pDelayTable[0];
pDelayTableNew[1] = (int)pDelayTable[1];
pDelayTableNew[2] = (int)pDelayTable[2];
for ( k = 0; k < nInputs * nOutputs; k++ )
pDelayTableNew[3+k] = pDelayTable[3+k];
// assert( (int)pDelayTableNew[0] == Vec_PtrSize(pNew->vDelayTables) );
assert( Vec_PtrEntry(pNew->vDelayTables, i) == NULL );
Vec_PtrWriteEntry( pNew->vDelayTables, i, pDelayTableNew );
}
}
// duplicate boxes
if ( Tim_ManBoxNum(p) > 0 )
{
int curPi = nNewPiNum;
int curPo = 0;
pNew->vBoxes = Vec_PtrAlloc( Tim_ManBoxNum(p) );
Vec_IntForEachEntry( vBoxesLeft, iBox, i )
{
pBox = Tim_ManBox( p, iBox );
Tim_ManCreateBox( pNew, curPo, pBox->nInputs, curPi, pBox->nOutputs, pBox->iDelayTable, pBox->fBlack );
Tim_ManBoxSetCopy( pNew, Tim_ManBoxNum(pNew) - 1, Tim_ManBoxCopy(p, iBox) == -1 ? iBox : Tim_ManBoxCopy(p, iBox) );
curPi += pBox->nOutputs;
curPo += pBox->nInputs;
}
curPo += nNewPoNum;
assert( curPi == Tim_ManCiNum(pNew) );
assert( curPo == Tim_ManCoNum(pNew) );
}
return pNew;
}
/**Function*************************************************************
Synopsis [Aligns two sets of boxes using the copy field.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t * Tim_ManAlignTwo( Tim_Man_t * pSpec, Tim_Man_t * pImpl )
{
Vec_Int_t * vBoxPres;
Tim_Box_t * pBox;
int i;
assert( Tim_ManBoxNum(pSpec) > Tim_ManBoxNum(pImpl) );
// check if boxes of pImpl can be aligned
Tim_ManForEachBox( pImpl, pBox, i )
if ( pBox->iCopy < 0 || pBox->iCopy >= Tim_ManBoxNum(pSpec) )
return NULL;
// map dropped boxes into 1, others into 0
vBoxPres = Vec_IntStart( Tim_ManBoxNum(pSpec) );
Tim_ManForEachBox( pImpl, pBox, i )
{
assert( !Vec_IntEntry(vBoxPres, pBox->iCopy) );
Vec_IntWriteEntry( vBoxPres, pBox->iCopy, 1 );
}
return vBoxPres;
}
/**Function*************************************************************
Synopsis [Stops the timing manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManStop( Tim_Man_t * p )
{
Vec_PtrFreeFree( p->vDelayTables );
Vec_PtrFreeP( &p->vBoxes );
Mem_FlexStop( p->pMemObj, 0 );
ABC_FREE( p->pCis );
ABC_FREE( p->pCos );
ABC_FREE( p );
}
void Tim_ManStopP( Tim_Man_t ** p )
{
if ( *p == NULL )
return;
Tim_ManStop( *p );
*p = NULL;
}
/**Function*************************************************************
Synopsis [Creates manager using hierarchy / box library / delay info.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManCreate( Tim_Man_t * p, void * pLib, Vec_Flt_t * vInArrs, Vec_Flt_t * vOutReqs )
{
If_LibBox_t * pLibBox = (If_LibBox_t *)pLib;
If_Box_t * pIfBox;
Tim_Box_t * pBox;
Tim_Obj_t * pObj;
float * pTable;
int i, k;
assert( p->vDelayTables == NULL );
p->vDelayTables = pLibBox ? Vec_PtrStart( Vec_PtrSize(pLibBox->vBoxes) ) : Vec_PtrAlloc( 100 );
if ( p->vBoxes )
Tim_ManForEachBox( p, pBox, i )
{
if ( pBox->iDelayTable == -1 || pLibBox == NULL )
{
// create table with constants
pTable = ABC_ALLOC( float, 3 + pBox->nInputs * pBox->nOutputs );
pTable[0] = pBox->iDelayTable;
pTable[1] = pBox->nInputs;
pTable[2] = pBox->nOutputs;
for ( k = 0; k < pBox->nInputs * pBox->nOutputs; k++ )
pTable[3 + k] = 1.0;
// save table
pBox->iDelayTable = Vec_PtrSize(p->vDelayTables);
Vec_PtrPush( p->vDelayTables, pTable );
continue;
}
assert( pBox->iDelayTable >= 0 && pBox->iDelayTable < Vec_PtrSize(pLibBox->vBoxes) );
pIfBox = (If_Box_t *)Vec_PtrEntry( pLibBox->vBoxes, pBox->iDelayTable );
assert( pIfBox != NULL );
assert( pIfBox->nPis == pBox->nInputs );
assert( pIfBox->nPos == pBox->nOutputs );
pBox->fBlack = pIfBox->fBlack;
if ( Vec_PtrEntry( p->vDelayTables, pBox->iDelayTable ) != NULL )
continue;
// create table of boxes
pTable = ABC_ALLOC( float, 3 + pBox->nInputs * pBox->nOutputs );
pTable[0] = pBox->iDelayTable;
pTable[1] = pBox->nInputs;
pTable[2] = pBox->nOutputs;
for ( k = 0; k < pBox->nInputs * pBox->nOutputs; k++ )
pTable[3 + k] = pIfBox->pDelays[k];
// save table
Vec_PtrWriteEntry( p->vDelayTables, pBox->iDelayTable, pTable );
}
// create arrival times
if ( vInArrs )
{
assert( Vec_FltSize(vInArrs) == Tim_ManPiNum(p) );
Tim_ManForEachPi( p, pObj, i )
pObj->timeArr = Vec_FltEntry(vInArrs, i);
}
// create required times
if ( vOutReqs )
{
k = 0;
assert( Vec_FltSize(vOutReqs) == Tim_ManPoNum(p) );
Tim_ManForEachPo( p, pObj, i )
pObj->timeReq = Vec_FltEntry(vOutReqs, k++);
assert( k == Tim_ManPoNum(p) );
}
}
/**Function*************************************************************
Synopsis [Get arrival and required times if they are non-trivial.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
float * Tim_ManGetArrTimes( Tim_Man_t * p )
{
float * pTimes;
Tim_Obj_t * pObj;
int i;
Tim_ManForEachPi( p, pObj, i )
if ( pObj->timeArr != 0.0 )
break;
if ( i == Tim_ManPiNum(p) )
return NULL;
pTimes = ABC_FALLOC( float, Tim_ManCiNum(p) );
Tim_ManForEachPi( p, pObj, i )
pTimes[i] = pObj->timeArr;
return pTimes;
}
float * Tim_ManGetReqTimes( Tim_Man_t * p )
{
float * pTimes;
Tim_Obj_t * pObj;
int i, k = 0;
Tim_ManForEachPo( p, pObj, i )
if ( pObj->timeReq != TIM_ETERNITY )
break;
if ( i == Tim_ManPoNum(p) )
return NULL;
pTimes = ABC_FALLOC( float, Tim_ManCoNum(p) );
Tim_ManForEachPo( p, pObj, i )
pTimes[k++] = pObj->timeArr;
assert( k == Tim_ManPoNum(p) );
return pTimes;
}
/**Function*************************************************************
Synopsis [Prints the timing manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManPrint( Tim_Man_t * p )
{
Tim_Box_t * pBox;
Tim_Obj_t * pObj, * pPrev;
float * pTable;
int i, j, k, TableX, TableY;
if ( p == NULL )
return;
printf( "TIMING MANAGER:\n" );
printf( "PI = %d. CI = %d. PO = %d. CO = %d. Box = %d.\n",
Tim_ManPiNum(p), Tim_ManCiNum(p), Tim_ManPoNum(p), Tim_ManCoNum(p), Tim_ManBoxNum(p) );
// print CI info
pPrev = p->pCis;
Tim_ManForEachPi( p, pObj, i )
if ( pPrev->timeArr != pObj->timeArr || pPrev->timeReq != pObj->timeReq )
break;
if ( i == Tim_ManCiNum(p) )
printf( "All PIs : arrival = %5.3f required = %5.3f\n", pPrev->timeArr, pPrev->timeReq );
else
Tim_ManForEachPi( p, pObj, i )
printf( "PI%5d : arrival = %5.3f required = %5.3f\n", i, pObj->timeArr, pObj->timeReq );
// print CO info
pPrev = p->pCos;
Tim_ManForEachPo( p, pObj, i )
if ( pPrev->timeArr != pObj->timeArr || pPrev->timeReq != pObj->timeReq )
break;
if ( i == Tim_ManCoNum(p) )
printf( "All POs : arrival = %5.3f required = %5.3f\n", pPrev->timeArr, pPrev->timeReq );
else
{
int k = 0;
Tim_ManForEachPo( p, pObj, i )
printf( "PO%5d : arrival = %5.3f required = %5.3f\n", k++, pObj->timeArr, pObj->timeReq );
}
// print box info
if ( Tim_ManBoxNum(p) > 0 )
Tim_ManForEachBox( p, pBox, i )
{
printf( "*** Box %5d : I =%4d. O =%4d. I1 =%6d. O1 =%6d. Table =%4d\n",
i, pBox->nInputs, pBox->nOutputs,
Tim_ManBoxInputFirst(p, i), Tim_ManBoxOutputFirst(p, i),
pBox->iDelayTable );
// print box inputs
pPrev = Tim_ManBoxInput( p, pBox, 0 );
Tim_ManBoxForEachInput( p, pBox, pObj, k )
if ( pPrev->timeArr != pObj->timeArr || pPrev->timeReq != pObj->timeReq )
break;
if ( k == Tim_ManBoxInputNum(p, pBox->iBox) )
printf( "Box inputs : arrival = %5.3f required = %5.3f\n", pPrev->timeArr, pPrev->timeReq );
else
Tim_ManBoxForEachInput( p, pBox, pObj, k )
printf( "box-in%4d : arrival = %5.3f required = %5.3f\n", k, pObj->timeArr, pObj->timeReq );
// print box outputs
pPrev = Tim_ManBoxOutput( p, pBox, 0 );
Tim_ManBoxForEachOutput( p, pBox, pObj, k )
if ( pPrev->timeArr != pObj->timeArr || pPrev->timeReq != pObj->timeReq )
break;
if ( k == Tim_ManBoxOutputNum(p, pBox->iBox) )
printf( "Box outputs : arrival = %5.3f required = %5.3f\n", pPrev->timeArr, pPrev->timeReq );
else
Tim_ManBoxForEachOutput( p, pBox, pObj, k )
printf( "box-out%3d : arrival = %5.3f required = %5.3f\n", k, pObj->timeArr, pObj->timeReq );
if ( i > 2 )
break;
}
// print delay tables
if ( Tim_ManDelayTableNum(p) > 0 )
Tim_ManForEachTable( p, pTable, i )
{
if ( pTable == NULL )
continue;
printf( "Delay table %d:\n", i );
assert( i == (int)pTable[0] );
TableX = (int)pTable[1];
TableY = (int)pTable[2];
for ( j = 0; j < TableY; j++, printf( "\n" ) )
for ( k = 0; k < TableX; k++ )
if ( pTable[3+j*TableX+k] == -ABC_INFINITY )
printf( "%5s", "-" );
else
printf( "%5.0f", pTable[3+j*TableX+k] );
}
printf( "\n" );
}
void Tim_ManPrintBoxCopy( Tim_Man_t * p )
{
Tim_Box_t * pBox;
int i;
if ( p == NULL )
return;
printf( "TIMING MANAGER:\n" );
printf( "PI = %d. CI = %d. PO = %d. CO = %d. Box = %d.\n",
Tim_ManPiNum(p), Tim_ManCiNum(p), Tim_ManPoNum(p), Tim_ManCoNum(p), Tim_ManBoxNum(p) );
if ( Tim_ManBoxNum(p) > 0 )
Tim_ManForEachBox( p, pBox, i )
printf( "%d ", pBox->iCopy );
printf( "\n" );
}
/**Function*************************************************************
Synopsis [Prints statistics of the timing manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManPrintStats( Tim_Man_t * p, int nAnd2Delay )
{
Tim_Box_t * pBox;
Vec_Int_t * vCounts;
Vec_Ptr_t * vBoxes;
int i, Count, IdMax;
if ( p == NULL )
return;
Abc_Print( 1, "Hierarchy : " );
printf( "PI/CI = %d/%d PO/CO = %d/%d Box = %d ",
Tim_ManPiNum(p), Tim_ManCiNum(p),
Tim_ManPoNum(p), Tim_ManCoNum(p),
Tim_ManBoxNum(p) );
if ( nAnd2Delay )
printf( "delay(AND2) = %d", nAnd2Delay );
printf( "\n" );
if ( Tim_ManBoxNum(p) == 0 )
return;
IdMax = 0;
Tim_ManForEachBox( p, pBox, i )
IdMax = Abc_MaxInt( IdMax, pBox->iDelayTable );
vCounts = Vec_IntStart( IdMax+1 );
vBoxes = Vec_PtrStart( IdMax+1 );
Tim_ManForEachBox( p, pBox, i )
{
Vec_IntAddToEntry( vCounts, pBox->iDelayTable, 1 );
Vec_PtrWriteEntry( vBoxes, pBox->iDelayTable, pBox );
}
// print statistics about boxes
Vec_IntForEachEntry( vCounts, Count, i )
{
if ( Count == 0 ) continue;
pBox = (Tim_Box_t *)Vec_PtrEntry( vBoxes, i );
printf( " Box %4d ", i );
printf( "Num = %4d ", Count );
printf( "Ins = %4d ", pBox->nInputs );
printf( "Outs = %4d", pBox->nOutputs );
printf( "\n" );
}
Vec_IntFree( vCounts );
Vec_PtrFree( vBoxes );
}
/**Function*************************************************************
Synopsis [Read parameters.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Tim_ManCiNum( Tim_Man_t * p )
{
return p->nCis;
}
int Tim_ManCoNum( Tim_Man_t * p )
{
return p->nCos;
}
int Tim_ManPiNum( Tim_Man_t * p )
{
if ( Tim_ManBoxNum(p) == 0 )
return Tim_ManCiNum(p);
return Tim_ManBoxOutputFirst(p, 0);
}
int Tim_ManPoNum( Tim_Man_t * p )
{
int iLastBoxId;
if ( Tim_ManBoxNum(p) == 0 )
return Tim_ManCoNum(p);
iLastBoxId = Tim_ManBoxNum(p) - 1;
return Tim_ManCoNum(p) - (Tim_ManBoxInputFirst(p, iLastBoxId) + Tim_ManBoxInputNum(p, iLastBoxId));
}
int Tim_ManBoxNum( Tim_Man_t * p )
{
return p->vBoxes ? Vec_PtrSize(p->vBoxes) : 0;
}
int Tim_ManBlackBoxNum( Tim_Man_t * p )
{
Tim_Box_t * pBox;
int i, Counter = 0;
if ( Tim_ManBoxNum(p) )
Tim_ManForEachBox( p, pBox, i )
Counter += pBox->fBlack;
return Counter;
}
void Tim_ManBlackBoxIoNum( Tim_Man_t * p, int * pnBbIns, int * pnBbOuts )
{
Tim_Box_t * pBox;
int i;
*pnBbIns = *pnBbOuts = 0;
if ( Tim_ManBoxNum(p) )
Tim_ManForEachBox( p, pBox, i )
{
if ( !pBox->fBlack )
continue;
*pnBbIns += Tim_ManBoxInputNum( p, i );
*pnBbOuts += Tim_ManBoxOutputNum( p, i );
}
}
int Tim_ManDelayTableNum( Tim_Man_t * p )
{
return p->vDelayTables ? Vec_PtrSize(p->vDelayTables) : 0;
}
/**Function*************************************************************
Synopsis [Sets the vector of timing tables associated with the manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManSetDelayTables( Tim_Man_t * p, Vec_Ptr_t * vDelayTables )
{
assert( p->vDelayTables == NULL );
p->vDelayTables = vDelayTables;
}
/**Function*************************************************************
Synopsis [Disables the use of the traversal ID.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManTravIdDisable( Tim_Man_t * p )
{
p->fUseTravId = 0;
}
/**Function*************************************************************
Synopsis [Enables the use of the traversal ID.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManTravIdEnable( Tim_Man_t * p )
{
p->fUseTravId = 1;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END