abc/src/aig/ntl/ntlTime.c

241 lines
7.3 KiB
C

/**CFile****************************************************************
FileName [ntlTime.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Netlist representation.]
Synopsis [Creates timing manager.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: ntlTime.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "ntl.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
float * Ntl_ManCreateDelayTable( Vec_Int_t * vDelays, int nIns, int nOuts )
{
float * pDelayTable, Delay;
int iIn, iOut, i, k;
assert( Vec_IntSize(vDelays) % 3 == 0 );
pDelayTable = ALLOC( float, nIns * nOuts );
memset( pDelayTable, 0, sizeof(float) * nIns * nOuts );
Vec_IntForEachEntry( vDelays, iIn, i )
{
iOut = Vec_IntEntry(vDelays, ++i);
Delay = Aig_Int2Float( Vec_IntEntry(vDelays, ++i) );
if ( iIn == -1 && iOut == -1 )
for ( k = 0; k < nIns * nOuts; k++ )
pDelayTable[k] = Delay;
else if ( iIn == -1 )
for ( k = 0; k < nIns; k++ )
pDelayTable[iOut * nIns + k] = Delay;
else if ( iOut == -1 )
for ( k = 0; k < nOuts; k++ )
pDelayTable[k * nIns + iIn] = Delay;
else
pDelayTable[iOut * nIns + iIn] = Delay;
}
return pDelayTable;
}
/**Function*************************************************************
Synopsis [Records the arrival times for the map leaves.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ntl_ManUnpackLeafTiming( Ntl_Man_t * p, Tim_Man_t * pMan )
{
Vec_Int_t * vTimes;
Ntl_Mod_t * pRoot;
Ntl_Obj_t * pObj;
Ntl_Net_t * pNet;
float dTime;
int i, k, v, Entry, Counter;
// clean the place
pRoot = Ntl_ManRootModel( p );
Ntl_ModelForEachMapLeaf( pRoot, pObj, i )
Ntl_ObjForEachFanout( pObj, pNet, k )
pNet->dTemp = 0;
// store the PI timing
vTimes = pRoot->vTimeInputs;
if ( vTimes ) {
Vec_IntForEachEntry( vTimes, Entry, i )
{
dTime = Aig_Int2Float( Vec_IntEntry(vTimes,++i) );
if ( Entry == -1 )
{
Ntl_ModelForEachPi( pRoot, pObj, v )
Ntl_ObjFanout0(pObj)->dTemp = dTime;
}
else
{
pObj = Ntl_ModelPi( pRoot, Entry );
Ntl_ObjFanout0(pObj)->dTemp = dTime;
}
}
}
// store box timing
Ntl_ModelForEachMapLeaf( pRoot, pObj, k )
{
if ( !(Ntl_ObjIsBox(pObj) && Ntl_BoxIsSeq(pObj)) )
continue;
vTimes = pObj->pImplem->vTimeOutputs;
if ( vTimes == NULL )
continue;
Vec_IntForEachEntry( vTimes, Entry, i )
{
dTime = Aig_Int2Float( Vec_IntEntry(vTimes,++i) );
if ( Entry == -1 )
{
Ntl_ObjForEachFanout( pObj, pNet, v )
pNet->dTemp = dTime;
}
else
{
pNet = Ntl_ObjFanout( pObj, Entry );
pNet->dTemp = dTime;
}
}
}
// load them into the timing manager
Counter = 0;
Ntl_ModelForEachMapLeaf( pRoot, pObj, i )
Ntl_ObjForEachFanout( pObj, pNet, k )
{
if ( pNet->dTemp == TIM_ETERNITY )
pNet->dTemp = -TIM_ETERNITY;
Tim_ManInitCiArrival( pMan, Counter++, pNet->dTemp );
}
assert( Counter == p->iLastCi );
}
/**Function*************************************************************
Synopsis [Records the required times for the map leaves.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ntl_ManUnpackRootTiming( Ntl_Man_t * p, Tim_Man_t * pMan )
{
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Tim_Man_t * Ntl_ManCreateTiming( Ntl_Man_t * p )
{
Tim_Man_t * pMan;
Vec_Ptr_t * vDelayTables;
Ntl_Mod_t * pRoot, * pModel;
Ntl_Obj_t * pObj;
int i, curPi, iBox;//, Entry;
assert( p->pAig != NULL );
pRoot = Ntl_ManRootModel( p );
// start the timing manager
pMan = Tim_ManStart( Aig_ManPiNum(p->pAig), Aig_ManPoNum(p->pAig) );
// unpack the timing data
Ntl_ManUnpackLeafTiming( p, pMan );
// Ntl_ManUnpackRootTiming( p, pMan );
/*
if ( pRoot->vTimeInputs )
{
Vec_IntForEachEntry( pRoot->vTimeInputs, Entry, i )
{
if ( Entry == -1 )
Tim_ManSetCiArrivalAll( pMan, Aig_Int2Float(Vec_IntEntry(pRoot->vTimeInputs,++i)) );
else
Tim_ManInitCiArrival( pMan, Entry, Aig_Int2Float(Vec_IntEntry(pRoot->vTimeInputs,++i)) );
}
}
// unpack the data in the required times
if ( pRoot->vTimeOutputs )
{
Vec_IntForEachEntry( pRoot->vTimeOutputs, Entry, i )
{
if ( Entry == -1 )
Tim_ManSetCoRequiredAll( pMan, Aig_Int2Float(Vec_IntEntry(pRoot->vTimeOutputs,++i)) );
else
Tim_ManInitCoRequired( pMan, Entry, Aig_Int2Float(Vec_IntEntry(pRoot->vTimeOutputs,++i)) );
}
}
*/
// derive timing tables for the whilte comb boxes
vDelayTables = Vec_PtrAlloc( Vec_PtrSize(p->vModels) );
Ntl_ManForEachModel( p, pModel, i )
{
if ( pModel->vDelays )
pModel->pDelayTable = Ntl_ManCreateDelayTable( pModel->vDelays, Ntl_ModelPiNum(pModel), Ntl_ModelPoNum(pModel) );
Vec_PtrPush( vDelayTables, pModel->pDelayTable );
}
Tim_ManSetDelayTables( pMan, vDelayTables );
// set up the boxes
iBox = 0;
curPi = p->iLastCi;
Vec_PtrForEachEntry( p->vVisNodes, pObj, i )
{
if ( !Ntl_ObjIsBox(pObj) )
continue;
Tim_ManCreateBoxFirst( pMan, Vec_IntEntry(p->vBox1Cios, iBox), Ntl_ObjFaninNum(pObj), curPi, Ntl_ObjFanoutNum(pObj), pObj->pImplem->pDelayTable );
curPi += Ntl_ObjFanoutNum(pObj);
iBox++;
}
// forget refs to the delay tables in the network
Ntl_ManForEachModel( p, pModel, i )
pModel->pDelayTable = NULL;
// Tim_ManPrint( pMan );
return pMan;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////