Commit fdd043ca by Alan Mishchenko

Upgrading hierarchy timing manager.

parent c1f8baaf
...@@ -2905,6 +2905,30 @@ SOURCE=.\src\misc\tim\tim.c ...@@ -2905,6 +2905,30 @@ SOURCE=.\src\misc\tim\tim.c
SOURCE=.\src\misc\tim\tim.h SOURCE=.\src\misc\tim\tim.h
# End Source File # End Source File
# Begin Source File
SOURCE=.\src\misc\tim\timBox.c
# End Source File
# Begin Source File
SOURCE=.\src\misc\tim\timDump.c
# End Source File
# Begin Source File
SOURCE=.\src\misc\tim\timInt.h
# End Source File
# Begin Source File
SOURCE=.\src\misc\tim\timMan.c
# End Source File
# Begin Source File
SOURCE=.\src\misc\tim\timTime.c
# End Source File
# Begin Source File
SOURCE=.\src\misc\tim\timTrav.c
# End Source File
# End Group # End Group
# End Group # End Group
# Begin Group "ai" # Begin Group "ai"
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
***********************************************************************/ ***********************************************************************/
#include "gia.h" #include "gia.h"
#include "misc/tim/tim.h"
ABC_NAMESPACE_IMPL_START ABC_NAMESPACE_IMPL_START
...@@ -872,6 +873,17 @@ Gia_Man_t * Gia_ReadAigerFromMemory( char * pContents, int nFileSize, int fSkipS ...@@ -872,6 +873,17 @@ Gia_Man_t * Gia_ReadAigerFromMemory( char * pContents, int nFileSize, int fSkipS
// read switching activity // read switching activity
pNew->pSwitching = Gia_ReadSwitching( &pCur, Gia_ManObjNum(pNew) ); pNew->pSwitching = Gia_ReadSwitching( &pCur, Gia_ManObjNum(pNew) );
} }
if ( *pCur == 't' )
{
Vec_Str_t * vStr;
pCur++;
// read timing manager
vStr = Vec_StrStart( Gia_ReadInt(pCur) ); pCur += 4;
memcpy( Vec_StrArray(vStr), pCur, Vec_StrSize(vStr) );
pCur += Vec_StrSize(vStr);
pNew->pManTime = Tim_ManLoad( vStr );
Vec_StrFree( vStr );
}
if ( *pCur == 'c' ) if ( *pCur == 'c' )
{ {
pCur++; pCur++;
...@@ -1046,10 +1058,12 @@ Gia_Man_t * Gia_ReadAigerFromMemory( char * pContents, int nFileSize, int fSkipS ...@@ -1046,10 +1058,12 @@ Gia_Man_t * Gia_ReadAigerFromMemory( char * pContents, int nFileSize, int fSkipS
if ( Gia_ManHasDangling(pNew) ) if ( Gia_ManHasDangling(pNew) )
{ {
Tim_Man_t * pManTime;
Vec_Int_t * vFlopMap, * vGateMap, * vObjMap; Vec_Int_t * vFlopMap, * vGateMap, * vObjMap;
vFlopMap = pNew->vFlopClasses; pNew->vFlopClasses = NULL; vFlopMap = pNew->vFlopClasses; pNew->vFlopClasses = NULL;
vGateMap = pNew->vGateClasses; pNew->vGateClasses = NULL; vGateMap = pNew->vGateClasses; pNew->vGateClasses = NULL;
vObjMap = pNew->vObjClasses; pNew->vObjClasses = NULL; vObjMap = pNew->vObjClasses; pNew->vObjClasses = NULL;
pManTime = pNew->pManTime; pNew->pManTime = NULL;
pNew = Gia_ManCleanup( pTemp = pNew ); pNew = Gia_ManCleanup( pTemp = pNew );
if ( (vGateMap || vObjMap) && (Gia_ManObjNum(pNew) < Gia_ManObjNum(pTemp)) ) if ( (vGateMap || vObjMap) && (Gia_ManObjNum(pNew) < Gia_ManObjNum(pTemp)) )
printf( "Cleanup removed objects after reading. Old gate/object abstraction maps are invalid!\n" ); printf( "Cleanup removed objects after reading. Old gate/object abstraction maps are invalid!\n" );
...@@ -1057,6 +1071,7 @@ Gia_Man_t * Gia_ReadAigerFromMemory( char * pContents, int nFileSize, int fSkipS ...@@ -1057,6 +1071,7 @@ Gia_Man_t * Gia_ReadAigerFromMemory( char * pContents, int nFileSize, int fSkipS
pNew->vFlopClasses = vFlopMap; pNew->vFlopClasses = vFlopMap;
pNew->vGateClasses = vGateMap; pNew->vGateClasses = vGateMap;
pNew->vObjClasses = vObjMap; pNew->vObjClasses = vObjMap;
pNew->pManTime = pManTime;
} }
return pNew; return pNew;
} }
...@@ -1377,8 +1392,11 @@ void Gia_WriteAiger( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int ...@@ -1377,8 +1392,11 @@ void Gia_WriteAiger( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int
// create normalized AIG // create normalized AIG
if ( !Gia_ManIsNormalized(pInit) ) if ( !Gia_ManIsNormalized(pInit) )
{ {
Tim_Man_t * pManTime;
pManTime = pInit->pManTime; pInit->pManTime = NULL;
// printf( "Gia_WriteAiger(): Normalizing AIG for writing.\n" ); // printf( "Gia_WriteAiger(): Normalizing AIG for writing.\n" );
p = Gia_ManDupNormalized( pInit ); p = Gia_ManDupNormalized( pInit );
p->pManTime = pManTime;
} }
else else
p = pInit; p = pInit;
...@@ -1519,7 +1537,7 @@ void Gia_WriteAiger( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int ...@@ -1519,7 +1537,7 @@ void Gia_WriteAiger( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int
fwrite( Buffer, 1, 4, pFile ); fwrite( Buffer, 1, 4, pFile );
fwrite( p->pPlacement, 1, nSize, pFile ); fwrite( p->pPlacement, 1, nSize, pFile );
} }
// write flop classes // write switching activity
if ( p->pSwitching ) if ( p->pSwitching )
{ {
unsigned char Buffer[10]; unsigned char Buffer[10];
...@@ -1529,6 +1547,18 @@ void Gia_WriteAiger( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int ...@@ -1529,6 +1547,18 @@ void Gia_WriteAiger( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int
fwrite( Buffer, 1, 4, pFile ); fwrite( Buffer, 1, 4, pFile );
fwrite( p->pSwitching, 1, nSize, pFile ); fwrite( p->pSwitching, 1, nSize, pFile );
} }
// write timing information
if ( p->pManTime )
{
Vec_Str_t * vStr = Tim_ManSave( p->pManTime );
unsigned char Buffer[10];
int nSize = Vec_StrSize(vStr);
Gia_WriteInt( Buffer, nSize );
fprintf( pFile, "t" );
fwrite( Buffer, 1, 4, pFile );
fwrite( Vec_StrArray(vStr), 1, nSize, pFile );
Vec_StrFree( vStr );
}
/* /*
// write constraints // write constraints
if ( p->nConstrs ) if ( p->nConstrs )
......
...@@ -279,7 +279,7 @@ float Gia_ManDelayTraceLut( Gia_Man_t * p ) ...@@ -279,7 +279,7 @@ float Gia_ManDelayTraceLut( Gia_Man_t * p )
if ( p->pManTime ) if ( p->pManTime )
{ {
Tim_ManIncrementTravId( (Tim_Man_t *)p->pManTime ); Tim_ManIncrementTravId( (Tim_Man_t *)p->pManTime );
Tim_ManSetCoRequiredAll( (Tim_Man_t *)p->pManTime, tArrival ); Tim_ManInitPoRequiredAll( (Tim_Man_t *)p->pManTime, tArrival );
} }
else else
{ {
......
...@@ -128,7 +128,6 @@ struct If_Par_t_ ...@@ -128,7 +128,6 @@ struct If_Par_t_
int fUseSops; // use local SOPs as a cost function int fUseSops; // use local SOPs as a cost function
int fUseCnfs; // use local CNFs as a cost function int fUseCnfs; // use local CNFs as a cost function
int fUseMv; // use local MV-SOPs as a cost function int fUseMv; // use local MV-SOPs as a cost function
int fUseAdders; // timing model for adders
int nLatchesCi; // the number of latches among the CIs int nLatchesCi; // the number of latches among the CIs
int nLatchesCo; // the number of latches among the COs int nLatchesCo; // the number of latches among the COs
int nLatchesCiBox; // the number of white box outputs among the CIs int nLatchesCiBox; // the number of white box outputs among the CIs
...@@ -531,8 +530,8 @@ extern int If_ManCountSpecialPos( If_Man_t * p ); ...@@ -531,8 +530,8 @@ extern int If_ManCountSpecialPos( If_Man_t * p );
extern int If_CutDelayRecCost(If_Man_t* p, If_Cut_t* pCut, If_Obj_t * pObj); extern int If_CutDelayRecCost(If_Man_t* p, If_Cut_t* pCut, If_Obj_t * pObj);
extern int If_CutDelayRecCost2(If_Man_t* p, If_Cut_t* pCut, If_Obj_t * pObj); extern int If_CutDelayRecCost2(If_Man_t* p, If_Cut_t* pCut, If_Obj_t * pObj);
/*=== abcRec2.c ============================================================*/ /*=== abcRec2.c ============================================================*/
extern int Abc_NtkRecIsRunning(); extern ABC_DLL int Abc_NtkRecIsRunning();
extern int Abc_NtkRecIsRunning2(); extern ABC_DLL int Abc_NtkRecIsRunning2();
// othe packages // othe packages
extern int Bat_ManCellFuncLookup( unsigned * pTruth, int nVars, int nLeaves ); extern int Bat_ManCellFuncLookup( unsigned * pTruth, int nVars, int nLeaves );
......
...@@ -286,7 +286,7 @@ void If_ManComputeRequired( If_Man_t * p ) ...@@ -286,7 +286,7 @@ void If_ManComputeRequired( If_Man_t * p )
} }
else else
{ {
Tim_ManSetCoRequiredAll( p->pManTim, p->RequiredGlo ); Tim_ManInitPoRequiredAll( p->pManTim, p->RequiredGlo );
// If_ManForEachCo( p, pObj, i ) // If_ManForEachCo( p, pObj, i )
// Tim_ManSetCoRequired( p->pManTim, pObj->IdPio, p->RequiredGlo ); // Tim_ManSetCoRequired( p->pManTim, pObj->IdPio, p->RequiredGlo );
} }
......
SRC += src/misc/tim/tim.c SRC += src/misc/tim/tim.c \
src/misc/tim/timBox.c \
src/misc/tim/timDump.c \
src/misc/tim/timMan.c \
src/misc/tim/timTime.c \
src/misc/tim/timTrav.c
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
SystemName [ABC: Logic synthesis and verification system.] SystemName [ABC: Logic synthesis and verification system.]
PackageName [A timing manager.] PackageName [Hierarchy/timing manager.]
Synopsis [Representation of timing information.] Synopsis [Representation of timing information.]
...@@ -18,975 +18,18 @@ ...@@ -18,975 +18,18 @@
***********************************************************************/ ***********************************************************************/
#include <stdio.h> #include "timInt.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "misc/vec/vec.h"
#include "misc/mem/mem.h"
#include "tim.h"
ABC_NAMESPACE_IMPL_START ABC_NAMESPACE_IMPL_START
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// DECLARATIONS /// /// DECLARATIONS ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
typedef struct Tim_Box_t_ Tim_Box_t;
typedef struct Tim_Obj_t_ Tim_Obj_t;
// timing manager
struct Tim_Man_t_
{
Vec_Ptr_t * vBoxes; // the timing boxes
Vec_Ptr_t * vDelayTables; // pointers to the delay tables
Mem_Flex_t * pMemObj; // memory manager for boxes
int nTravIds; // traversal ID of the manager
int fUseTravId; // enables the use of traversal ID
int nCis; // the number of PIs
int nCos; // the number of POs
Tim_Obj_t * pCis; // timing info for the PIs
Tim_Obj_t * pCos; // timing info for the POs
};
// timing box
struct Tim_Box_t_
{
int iBox; // the unique ID of this box
int TravId; // traversal ID of this box
int nInputs; // the number of box inputs (POs)
int nOutputs; // the number of box outputs (PIs)
float * pDelayTable; // delay for each input->output path
int Inouts[0]; // the int numbers of PIs and POs
};
// timing object
struct Tim_Obj_t_
{
int Id; // the ID of this object
int TravId; // traversal ID of this object
int iObj2Box; // mapping of the object into its box
int iObj2Num; // mapping of the object into its number in the box
float timeArr; // arrival time of the object
float timeReq; // required time of the object
};
static inline Tim_Obj_t * Tim_ManCi( Tim_Man_t * p, int i ) { assert( i < p->nCis ); return p->pCis + i; }
static inline Tim_Obj_t * Tim_ManCo( Tim_Man_t * p, int i ) { assert( i < p->nCos ); return p->pCos + i; }
static inline Tim_Box_t * Tim_ManBox( Tim_Man_t * p, int i ) { return (Tim_Box_t *)Vec_PtrEntry(p->vBoxes, i); }
static inline Tim_Box_t * Tim_ManCiBox( Tim_Man_t * p, int i ) { return Tim_ManCi(p,i)->iObj2Box < 0 ? NULL : (Tim_Box_t *)Vec_PtrEntry( p->vBoxes, Tim_ManCi(p,i)->iObj2Box ); }
static inline Tim_Box_t * Tim_ManCoBox( Tim_Man_t * p, int i ) { return Tim_ManCo(p,i)->iObj2Box < 0 ? NULL : (Tim_Box_t *)Vec_PtrEntry( p->vBoxes, Tim_ManCo(p,i)->iObj2Box ); }
static inline Tim_Obj_t * Tim_ManBoxInput( Tim_Man_t * p, Tim_Box_t * pBox, int i ) { assert( i < pBox->nInputs ); return p->pCos + pBox->Inouts[i]; }
static inline Tim_Obj_t * Tim_ManBoxOutput( Tim_Man_t * p, Tim_Box_t * pBox, int i ) { assert( i < pBox->nOutputs ); return p->pCis + pBox->Inouts[pBox->nInputs+i]; }
#define Tim_ManBoxForEachInput( p, pBox, pObj, i ) \
for ( i = 0; (i < (pBox)->nInputs) && ((pObj) = Tim_ManBoxInput(p, pBox, i)); i++ )
#define Tim_ManBoxForEachOutput( p, pBox, pObj, i ) \
for ( i = 0; (i < (pBox)->nOutputs) && ((pObj) = Tim_ManBoxOutput(p, pBox, i)); i++ )
#define Tim_ManForEachCi( p, pObj, i ) \
for ( i = 0; (i < (p)->nCis) && ((pObj) = (p)->pCis + i); i++ ) \
if ( pObj->iObj2Box >= 0 ) {} else
#define Tim_ManForEachCo( p, pObj, i ) \
for ( i = 0; (i < (p)->nCos) && ((pObj) = (p)->pCos + i); i++ ) \
if ( pObj->iObj2Box >= 0 ) {} else
#define Tim_ManForEachBox( p, pBox, i ) \
Vec_PtrForEachEntry( Tim_Box_t *, p->vBoxes, pBox, i )
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS /// /// FUNCTION DEFINITIONS ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Starts the timing manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Tim_Man_t * Tim_ManStart( int nCis, int nCos )
{
Tim_Man_t * p;
int i;
p = ABC_ALLOC( Tim_Man_t, 1 );
memset( p, 0, sizeof(Tim_Man_t) );
p->pMemObj = Mem_FlexStart();
p->vBoxes = Vec_PtrAlloc( 100 );
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 );
for ( i = 0; i < nCis; i++ )
{
p->pCis[i].Id = i;
p->pCis[i].iObj2Box = p->pCis[i].iObj2Num = -1;
p->pCis[i].timeReq = TIM_ETERNITY;
p->pCis[i].timeArr = 0.0;
p->pCis[i].TravId = 0;
}
for ( i = 0; i < nCos; i++ )
{
p->pCos[i].Id = i;
p->pCos[i].iObj2Box = p->pCos[i].iObj2Num = -1;
p->pCos[i].timeReq = TIM_ETERNITY;
p->pCos[i].timeArr = 0.0;
p->pCos[i].TravId = 0;
}
p->fUseTravId = 1;
return p;
}
/**Function*************************************************************
Synopsis [Duplicates the timing manager.]
Description [Derives discrete-delay-model timing manager.
Useful for AIG optimization with approximate timing information.]
SideEffects []
SeeAlso []
***********************************************************************/
Tim_Man_t * Tim_ManDup( Tim_Man_t * p, int fDiscrete )
{
Tim_Man_t * pNew;
Tim_Box_t * pBox;
float * pDelayTableNew;
int i, k;
pNew = Tim_ManStart( p->nCis, p->nCos );
memcpy( pNew->pCis, p->pCis, sizeof(Tim_Obj_t) * p->nCis );
memcpy( pNew->pCos, p->pCos, sizeof(Tim_Obj_t) * p->nCos );
for ( k = 0; k < p->nCis; k++ )
pNew->pCis[k].TravId = 0;
for ( k = 0; k < p->nCos; k++ )
pNew->pCos[k].TravId = 0;
if ( fDiscrete )
{
for ( k = 0; k < p->nCis; k++ )
pNew->pCis[k].timeArr = 0.0; // modify here
// modify the required times
}
pNew->vDelayTables = Vec_PtrAlloc( 100 );
Tim_ManForEachBox( p, pBox, i )
{
//printf( "%d %d\n", pBox->nInputs, pBox->nOutputs );
pDelayTableNew = ABC_ALLOC( float, pBox->nInputs * pBox->nOutputs );
Vec_PtrPush( pNew->vDelayTables, pDelayTableNew );
if ( fDiscrete )
{
for ( k = 0; k < pBox->nInputs * pBox->nOutputs; k++ )
pDelayTableNew[k] = 1.0; // modify here
///// begin part of improved CIN/COUT propagation
for ( k = 0; k < pBox->nInputs; k++ ) // fill in the first row
pDelayTableNew[k] = 0.5;
for ( k = 0; k < pBox->nOutputs; k++ ) // fill in the first column
pDelayTableNew[k*pBox->nInputs] = 0.5;
pDelayTableNew[0] = 0.0; // fill in the first entry
///// end part of improved CIN/COUT propagation
/// change
// pDelayTableNew[0] = 0.0;
/// change
}
else
memcpy( pDelayTableNew, pBox->pDelayTable, sizeof(float) * pBox->nInputs * pBox->nOutputs );
Tim_ManCreateBoxFirst( pNew, pBox->Inouts[0], pBox->nInputs,
pBox->Inouts[pBox->nInputs], pBox->nOutputs, pDelayTableNew );
}
return pNew;
}
/**Function*************************************************************
Synopsis [Duplicates the timing manager.]
Description [Derives unit-delay-model timing manager.
Useful for levelizing the network.]
SideEffects []
SeeAlso []
***********************************************************************/
Tim_Man_t * Tim_ManDupUnit( Tim_Man_t * p )
{
Tim_Man_t * pNew;
Tim_Box_t * pBox;
float * pDelayTableNew;
int i, k;
pNew = Tim_ManStart( p->nCis, p->nCos );
memcpy( pNew->pCis, p->pCis, sizeof(Tim_Obj_t) * p->nCis );
memcpy( pNew->pCos, p->pCos, sizeof(Tim_Obj_t) * p->nCos );
for ( k = 0; k < p->nCis; k++ )
{
pNew->pCis[k].TravId = 0;
pNew->pCis[k].timeArr = 0.0;
}
for ( k = 0; k < p->nCos; k++ )
pNew->pCos[k].TravId = 0;
pNew->vDelayTables = Vec_PtrAlloc( 100 );
Tim_ManForEachBox( p, pBox, i )
{
pDelayTableNew = ABC_ALLOC( float, pBox->nInputs * pBox->nOutputs );
Vec_PtrPush( pNew->vDelayTables, pDelayTableNew );
for ( k = 0; k < pBox->nInputs * pBox->nOutputs; k++ )
pDelayTableNew[k] = 1.0;
Tim_ManCreateBoxFirst( pNew, pBox->Inouts[0], pBox->nInputs,
pBox->Inouts[pBox->nInputs], pBox->nOutputs, pDelayTableNew );
}
return pNew;
}
/**Function*************************************************************
Synopsis [Duplicates the timing manager.]
Description [Derives the approximate timing manager with realistic delays
but without white-boxes.]
SideEffects []
SeeAlso []
***********************************************************************/
Tim_Man_t * Tim_ManDupApprox( Tim_Man_t * p )
{
Tim_Man_t * pNew;
int k;
pNew = Tim_ManStart( p->nCis, p->nCos );
for ( k = 0; k < p->nCis; k++ )
if ( p->pCis[k].iObj2Box == -1 )
pNew->pCis[k].timeArr = p->pCis[k].timeArr;
else
pNew->pCis[k].timeArr = p->pCis[k].timeReq;
for ( k = 0; k < p->nCos; k++ )
pNew->pCos[k].timeReq = p->pCos[k].timeReq;
return pNew;
}
/**Function*************************************************************
Synopsis [Stops the timing manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManStop( Tim_Man_t * p )
{
float * pTable;
int i;
if ( p->vDelayTables )
{
Vec_PtrForEachEntry( float *, p->vDelayTables, pTable, i )
ABC_FREE( pTable );
Vec_PtrFree( p->vDelayTables );
}
Vec_PtrFree( p->vBoxes );
Mem_FlexStop( p->pMemObj, 0 );
ABC_FREE( p->pCis );
ABC_FREE( p->pCos );
ABC_FREE( p );
}
/**Function*************************************************************
Synopsis [Stops the timing manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManStopP( Tim_Man_t ** p )
{
if ( *p == NULL )
return;
Tim_ManStop( *p );
*p = NULL;
}
/**Function*************************************************************
Synopsis [Stops the timing manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManPrint( Tim_Man_t * p )
{
Tim_Box_t * pBox;
Tim_Obj_t * pObj;
int i;
printf( "TIMING INFORMATION:\n" );
Tim_ManForEachCi( p, pObj, i )
printf( "pi%5d : arr = %5.3f req = %5.3f\n", i, pObj->timeArr, pObj->timeReq );
Tim_ManForEachCo( p, pObj, i )
printf( "po%5d : arr = %5.3f req = %5.3f\n", i, pObj->timeArr, pObj->timeReq );
Tim_ManForEachBox( p, pBox, i )
{
printf( "*** Box %3d : Ins = %d. Outs = %d.\n", i, pBox->nInputs, pBox->nOutputs );
printf( "Delay table:" );
for ( i = 0; i < pBox->nInputs * pBox->nOutputs; i++ )
printf( " %5.3f", pBox->pDelayTable[i] );
printf( "\n" );
Tim_ManBoxForEachInput( p, pBox, pObj, i )
printf( "box-inp%3d : arr = %5.3f req = %5.3f\n", i, pObj->timeArr, pObj->timeReq );
Tim_ManBoxForEachOutput( p, pBox, pObj, i )
printf( "box-out%3d : arr = %5.3f req = %5.3f\n", i, pObj->timeArr, pObj->timeReq );
}
printf( "\n" );
}
/**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;
}
/**Function*************************************************************
Synopsis [Label box inputs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManSetCurrentTravIdBoxInputs( Tim_Man_t * p, int iBox )
{
Tim_Box_t * pBox;
Tim_Obj_t * pObj;
int i;
pBox = Tim_ManBox( p, iBox );
Tim_ManBoxForEachInput( p, pBox, pObj, i )
pObj->TravId = p->nTravIds;
}
/**Function*************************************************************
Synopsis [Label box outputs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManSetCurrentTravIdBoxOutputs( Tim_Man_t * p, int iBox )
{
Tim_Box_t * pBox;
Tim_Obj_t * pObj;
int i;
pBox = Tim_ManBox( p, iBox );
Tim_ManBoxForEachOutput( p, pBox, pObj, i )
pObj->TravId = p->nTravIds;
}
/**Function*************************************************************
Synopsis [Label box inputs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManSetPreviousTravIdBoxInputs( Tim_Man_t * p, int iBox )
{
Tim_Box_t * pBox;
Tim_Obj_t * pObj;
int i;
pBox = Tim_ManBox( p, iBox );
Tim_ManBoxForEachInput( p, pBox, pObj, i )
pObj->TravId = p->nTravIds - 1;
}
/**Function*************************************************************
Synopsis [Label box outputs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManSetPreviousTravIdBoxOutputs( Tim_Man_t * p, int iBox )
{
Tim_Box_t * pBox;
Tim_Obj_t * pObj;
int i;
pBox = Tim_ManBox( p, iBox );
Tim_ManBoxForEachOutput( p, pBox, pObj, i )
pObj->TravId = p->nTravIds - 1;
}
/**Function*************************************************************
Synopsis [Updates required time of the PO.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Tim_ManIsCiTravIdCurrent( Tim_Man_t * p, int iCi )
{
assert( iCi < p->nCis );
assert( p->fUseTravId );
return p->pCis[iCi].TravId == p->nTravIds;
}
/**Function*************************************************************
Synopsis [Updates required time of the PO.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Tim_ManIsCoTravIdCurrent( Tim_Man_t * p, int iCo )
{
assert( iCo < p->nCos );
assert( p->fUseTravId );
return p->pCos[iCo].TravId == p->nTravIds;
}
/**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 [Creates the new timing box.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManCreateBox( Tim_Man_t * p, int * pIns, int nIns, int * pOuts, int nOuts, float * pDelayTable )
{
Tim_Box_t * pBox;
int i;
pBox = (Tim_Box_t *)Mem_FlexEntryFetch( p->pMemObj, sizeof(Tim_Box_t) + sizeof(int) * (nIns+nOuts) );
memset( pBox, 0, sizeof(Tim_Box_t) );
pBox->iBox = Vec_PtrSize( p->vBoxes );
Vec_PtrPush( p->vBoxes, pBox );
pBox->pDelayTable = pDelayTable;
pBox->nInputs = nIns;
pBox->nOutputs = nOuts;
for ( i = 0; i < nIns; i++ )
{
assert( pIns[i] < p->nCos );
pBox->Inouts[i] = pIns[i];
p->pCos[pIns[i]].iObj2Box = pBox->iBox;
p->pCos[pIns[i]].iObj2Num = i;
}
for ( i = 0; i < nOuts; i++ )
{
assert( pOuts[i] < p->nCis );
pBox->Inouts[nIns+i] = pOuts[i];
p->pCis[pOuts[i]].iObj2Box = pBox->iBox;
p->pCis[pOuts[i]].iObj2Num = i;
}
}
/**Function*************************************************************
Synopsis [Creates the new timing box.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManCreateBoxFirst( Tim_Man_t * p, int firstIn, int nIns, int firstOut, int nOuts, float * pDelayTable )
{
Tim_Box_t * pBox;
int i;
// printf( "Creating %d x %d box with first inputs (%d and %d).\n", nIns, nOuts, firstIn, firstOut );
pBox = (Tim_Box_t *)Mem_FlexEntryFetch( p->pMemObj, sizeof(Tim_Box_t) + sizeof(int) * (nIns+nOuts) );
memset( pBox, 0, sizeof(Tim_Box_t) );
pBox->iBox = Vec_PtrSize( p->vBoxes );
Vec_PtrPush( p->vBoxes, pBox );
pBox->pDelayTable = pDelayTable;
pBox->nInputs = nIns;
pBox->nOutputs = nOuts;
for ( i = 0; i < nIns; i++ )
{
assert( firstIn+i < p->nCos );
pBox->Inouts[i] = firstIn+i;
p->pCos[firstIn+i].iObj2Box = pBox->iBox;
p->pCos[firstIn+i].iObj2Num = i;
}
for ( i = 0; i < nOuts; i++ )
{
assert( firstOut+i < p->nCis );
pBox->Inouts[nIns+i] = firstOut+i;
p->pCis[firstOut+i].iObj2Box = pBox->iBox;
p->pCis[firstOut+i].iObj2Num = i;
}
// if ( pBox->iBox < 50 )
// printf( "%4d %4d %4d %4d \n", firstIn, nIns, firstOut, nOuts );
}
/**Function*************************************************************
Synopsis [Increments the trav ID of the manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManIncrementTravId( Tim_Man_t * p )
{
int i;
if ( p->nTravIds >= (1<<30)-1 )
{
p->nTravIds = 0;
for ( i = 0; i < p->nCis; i++ )
p->pCis[i].TravId = 0;
for ( i = 0; i < p->nCos; i++ )
p->pCos[i].TravId = 0;
}
assert( p->nTravIds < (1<<30)-1 );
p->nTravIds++;
}
/**Function*************************************************************
Synopsis [Initializes arrival time of the PI.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManInitCiArrival( Tim_Man_t * p, int iCi, float Delay )
{
assert( iCi < p->nCis );
p->pCis[iCi].timeArr = Delay;
}
/**Function*************************************************************
Synopsis [Initializes required time of the PO.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManInitCoRequired( Tim_Man_t * p, int iCo, float Delay )
{
assert( iCo < p->nCos );
p->pCos[iCo].timeReq = Delay;
}
/**Function*************************************************************
Synopsis [Updates required time of the PO.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManSetCoArrival( Tim_Man_t * p, int iCo, float Delay )
{
assert( iCo < p->nCos );
assert( !p->fUseTravId || p->pCos[iCo].TravId != p->nTravIds );
p->pCos[iCo].timeArr = Delay;
p->pCos[iCo].TravId = p->nTravIds;
}
/**Function*************************************************************
Synopsis [Updates arrival time of the PI.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManSetCiRequired( Tim_Man_t * p, int iCi, float Delay )
{
assert( iCi < p->nCis );
assert( !p->fUseTravId || p->pCis[iCi].TravId != p->nTravIds );
p->pCis[iCi].timeReq = Delay;
p->pCis[iCi].TravId = p->nTravIds;
}
/**Function*************************************************************
Synopsis [Updates required time of the PO.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManSetCoRequired( Tim_Man_t * p, int iCo, float Delay )
{
assert( iCo < p->nCos );
assert( !p->fUseTravId || p->pCos[iCo].TravId != p->nTravIds );
p->pCos[iCo].timeReq = Delay;
p->pCos[iCo].TravId = p->nTravIds;
}
/**Function*************************************************************
Synopsis [Sets the correct required times for all POs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManSetCiArrivalAll( Tim_Man_t * p, float Delay )
{
Tim_Obj_t * pObj;
int i;
Tim_ManForEachCi( p, pObj, i )
Tim_ManInitCiArrival( p, i, Delay );
}
/**Function*************************************************************
Synopsis [Sets the correct required times for all POs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManSetCoRequiredAll( Tim_Man_t * p, float Delay )
{
Tim_Obj_t * pObj;
int i;
Tim_ManForEachCo( p, pObj, i )
{
Tim_ManSetCoRequired( p, i, Delay );
//printf( "%d ", i );
}
}
/**Function*************************************************************
Synopsis [Returns PI arrival time.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
float Tim_ManGetCiArrival( Tim_Man_t * p, int iCi )
{
Tim_Box_t * pBox;
Tim_Obj_t * pObjThis, * pObj, * pObjRes;
float * pDelays, DelayBest;
int i, k;
// consider the already processed PI
pObjThis = Tim_ManCi( p, iCi );
if ( p->fUseTravId && pObjThis->TravId == p->nTravIds )
return pObjThis->timeArr;
pObjThis->TravId = p->nTravIds;
// consider the main PI
pBox = Tim_ManCiBox( p, iCi );
if ( pBox == NULL )
return pObjThis->timeArr;
// update box timing
pBox->TravId = p->nTravIds;
// get the arrival times of the inputs of the box (POs)
if ( p->fUseTravId )
Tim_ManBoxForEachInput( p, pBox, pObj, i )
if ( pObj->TravId != p->nTravIds )
printf( "Tim_ManGetCiArrival(): Input arrival times of the box are not up to date!\n" );
// compute the arrival times for each output of the box (PIs)
Tim_ManBoxForEachOutput( p, pBox, pObjRes, i )
{
pDelays = pBox->pDelayTable + i * pBox->nInputs;
DelayBest = -TIM_ETERNITY;
Tim_ManBoxForEachInput( p, pBox, pObj, k )
DelayBest = Abc_MaxInt( DelayBest, pObj->timeArr + pDelays[k] );
pObjRes->timeArr = DelayBest;
pObjRes->TravId = p->nTravIds;
}
return pObjThis->timeArr;
}
/**Function*************************************************************
Synopsis [Returns PO required time.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
float Tim_ManGetCoRequired( Tim_Man_t * p, int iCo )
{
Tim_Box_t * pBox;
Tim_Obj_t * pObjThis, * pObj, * pObjRes;
float * pDelays, DelayBest;
int i, k;
// consider the already processed PO
pObjThis = Tim_ManCo( p, iCo );
if ( p->fUseTravId && pObjThis->TravId == p->nTravIds )
return pObjThis->timeReq;
pObjThis->TravId = p->nTravIds;
// consider the main PO
pBox = Tim_ManCoBox( p, iCo );
if ( pBox == NULL )
return pObjThis->timeReq;
// update box timing
pBox->TravId = p->nTravIds;
// get the required times of the outputs of the box (PIs)
if ( p->fUseTravId )
Tim_ManBoxForEachOutput( p, pBox, pObj, i )
if ( pObj->TravId != p->nTravIds )
printf( "Tim_ManGetCoRequired(): Output required times of output %d the box %d are not up to date!\n", i, pBox->iBox );
// compute the required times for each input of the box (POs)
Tim_ManBoxForEachInput( p, pBox, pObjRes, i )
{
DelayBest = TIM_ETERNITY;
Tim_ManBoxForEachOutput( p, pBox, pObj, k )
{
pDelays = pBox->pDelayTable + k * pBox->nInputs;
DelayBest = Abc_MinFloat( DelayBest, pObj->timeReq - pDelays[i] );
}
pObjRes->timeReq = DelayBest;
pObjRes->TravId = p->nTravIds;
}
return pObjThis->timeReq;
}
/**Function*************************************************************
Synopsis [Returns the box number for the given input.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Tim_ManBoxForCi( Tim_Man_t * p, int iCi )
{
if ( iCi >= p->nCis )
return -1;
return p->pCis[iCi].iObj2Box;
}
/**Function*************************************************************
Synopsis [Returns the box number for the given output.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Tim_ManBoxForCo( Tim_Man_t * p, int iCo )
{
if ( iCo >= p->nCos )
return -1;
return p->pCos[iCo].iObj2Box;
}
/**Function*************************************************************
Synopsis [Returns the first input of the box.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Tim_ManBoxInputFirst( Tim_Man_t * p, int iBox )
{
Tim_Box_t * pBox = (Tim_Box_t *)Vec_PtrEntry( p->vBoxes, iBox );
return pBox->Inouts[0];
}
/**Function*************************************************************
Synopsis [Returns the first input of the box.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Tim_ManBoxOutputFirst( Tim_Man_t * p, int iBox )
{
Tim_Box_t * pBox = (Tim_Box_t *)Vec_PtrEntry( p->vBoxes, iBox );
return pBox->Inouts[pBox->nInputs];
}
/**Function*************************************************************
Synopsis [Returns the first input of the box.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Tim_ManBoxInputNum( Tim_Man_t * p, int iBox )
{
Tim_Box_t * pBox = (Tim_Box_t *)Vec_PtrEntry( p->vBoxes, iBox );
return pBox->nInputs;
}
/**Function*************************************************************
Synopsis [Returns the first input of the box.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Tim_ManBoxOutputNum( Tim_Man_t * p, int iBox )
{
Tim_Box_t * pBox = (Tim_Box_t *)Vec_PtrEntry( p->vBoxes, iBox );
return pBox->nOutputs;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManChangeForAdders( Tim_Man_t * p )
{
Tim_Box_t * pBox;
int i;
Tim_ManForEachBox( p, pBox, i )
pBox->pDelayTable[0] = 0.0;
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// END OF FILE /// /// END OF FILE ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
SystemName [ABC: Logic synthesis and verification system.] SystemName [ABC: Logic synthesis and verification system.]
PackageName [A timing manager.] PackageName [Hierarchy/timing manager.]
Synopsis [External declarations.] Synopsis [External declarations.]
...@@ -30,11 +30,8 @@ ...@@ -30,11 +30,8 @@
/// PARAMETERS /// /// PARAMETERS ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_HEADER_START ABC_NAMESPACE_HEADER_START
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// BASIC TYPES /// /// BASIC TYPES ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
...@@ -59,43 +56,51 @@ typedef struct Tim_Man_t_ Tim_Man_t; ...@@ -59,43 +56,51 @@ typedef struct Tim_Man_t_ Tim_Man_t;
/// FUNCTION DECLARATIONS /// /// FUNCTION DECLARATIONS ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/*=== time.c ===========================================================*/ /*=== timBox.c ===========================================================*/
extern void Tim_ManCreateBox( Tim_Man_t * p, int firstIn, int nIns, int firstOut, int nOuts, int iDelayTable );
extern int Tim_ManBoxForCi( Tim_Man_t * p, int iCo );
extern int Tim_ManBoxForCo( Tim_Man_t * p, int iCi );
extern int Tim_ManBoxInputFirst( Tim_Man_t * p, int iBox );
extern int Tim_ManBoxOutputFirst( Tim_Man_t * p, int iBox );
extern int Tim_ManBoxInputNum( Tim_Man_t * p, int iBox );
extern int Tim_ManBoxOutputNum( Tim_Man_t * p, int iBox );
extern float * Tim_ManBoxDelayTable( Tim_Man_t * p, int iBox );
/*=== timDump.c ===========================================================*/
extern Vec_Str_t * Tim_ManSave( Tim_Man_t * p );
extern Tim_Man_t * Tim_ManLoad( Vec_Str_t * p );
/*=== timMan.c ===========================================================*/
extern Tim_Man_t * Tim_ManStart( int nCis, int nCos ); extern Tim_Man_t * Tim_ManStart( int nCis, int nCos );
extern Tim_Man_t * Tim_ManDup( Tim_Man_t * p, int fDiscrete ); extern Tim_Man_t * Tim_ManDup( Tim_Man_t * p, int fUnitDelay );
extern Tim_Man_t * Tim_ManDupUnit( Tim_Man_t * p );
extern Tim_Man_t * Tim_ManDupApprox( Tim_Man_t * p );
extern void Tim_ManStop( Tim_Man_t * p ); extern void Tim_ManStop( Tim_Man_t * p );
extern void Tim_ManStopP( Tim_Man_t ** p ); extern void Tim_ManStopP( Tim_Man_t ** p );
extern void Tim_ManPrint( Tim_Man_t * p ); extern void Tim_ManPrint( Tim_Man_t * p );
extern int Tim_ManCiNum( Tim_Man_t * p );
extern int Tim_ManCoNum( Tim_Man_t * p );
extern int Tim_ManPiNum( Tim_Man_t * p );
extern int Tim_ManPoNum( Tim_Man_t * p );
extern int Tim_ManBoxNum( Tim_Man_t * p );
extern int Tim_ManDelayTableNum( Tim_Man_t * p );
extern void Tim_ManSetDelayTables( Tim_Man_t * p, Vec_Ptr_t * vDelayTables );
extern void Tim_ManTravIdDisable( Tim_Man_t * p ); extern void Tim_ManTravIdDisable( Tim_Man_t * p );
extern void Tim_ManTravIdEnable( Tim_Man_t * p ); extern void Tim_ManTravIdEnable( Tim_Man_t * p );
/*=== timTime.c ===========================================================*/
extern void Tim_ManInitPiArrival( Tim_Man_t * p, int iPi, float Delay );
extern void Tim_ManInitPoRequired( Tim_Man_t * p, int iPo, float Delay );
extern void Tim_ManInitPiArrivalAll( Tim_Man_t * p, float Delay );
extern void Tim_ManInitPoRequiredAll( Tim_Man_t * p, float Delay );
extern void Tim_ManSetCoArrival( Tim_Man_t * p, int iCo, float Delay );
extern void Tim_ManSetCiRequired( Tim_Man_t * p, int iCi, float Delay );
extern void Tim_ManSetCoRequired( Tim_Man_t * p, int iCo, float Delay );
extern float Tim_ManGetCiArrival( Tim_Man_t * p, int iCi );
extern float Tim_ManGetCoRequired( Tim_Man_t * p, int iCo );
/*=== timTrav.c ===========================================================*/
extern void Tim_ManIncrementTravId( Tim_Man_t * p );
extern void Tim_ManSetCurrentTravIdBoxInputs( Tim_Man_t * p, int iBox ); extern void Tim_ManSetCurrentTravIdBoxInputs( Tim_Man_t * p, int iBox );
extern void Tim_ManSetCurrentTravIdBoxOutputs( Tim_Man_t * p, int iBox ); extern void Tim_ManSetCurrentTravIdBoxOutputs( Tim_Man_t * p, int iBox );
extern void Tim_ManSetPreviousTravIdBoxInputs( Tim_Man_t * p, int iBox ); extern void Tim_ManSetPreviousTravIdBoxInputs( Tim_Man_t * p, int iBox );
extern void Tim_ManSetPreviousTravIdBoxOutputs( Tim_Man_t * p, int iBox ); extern void Tim_ManSetPreviousTravIdBoxOutputs( Tim_Man_t * p, int iBox );
extern int Tim_ManIsCiTravIdCurrent( Tim_Man_t * p, int iCi ); extern int Tim_ManIsCiTravIdCurrent( Tim_Man_t * p, int iCi );
extern int Tim_ManIsCoTravIdCurrent( Tim_Man_t * p, int iCo ); extern int Tim_ManIsCoTravIdCurrent( Tim_Man_t * p, int iCo );
extern void Tim_ManSetDelayTables( Tim_Man_t * p, Vec_Ptr_t * vDelayTables );
extern void Tim_ManCreateBox( Tim_Man_t * p, int * pIns, int nIns, int * pOuts, int nOuts, float * pDelayTable );
extern void Tim_ManCreateBoxFirst( Tim_Man_t * p, int firstIn, int nIns, int firstOut, int nOuts, float * pDelayTable );
extern void Tim_ManIncrementTravId( Tim_Man_t * p );
extern void Tim_ManInitCiArrival( Tim_Man_t * p, int iCi, float Delay );
extern void Tim_ManInitCoRequired( Tim_Man_t * p, int iCo, float Delay );
extern void Tim_ManSetCoArrival( Tim_Man_t * p, int iCo, float Delay );
extern void Tim_ManSetCiRequired( Tim_Man_t * p, int iCi, float Delay );
extern void Tim_ManSetCoRequired( Tim_Man_t * p, int iCo, float Delay );
extern void Tim_ManSetCiArrivalAll( Tim_Man_t * p, float Delay );
extern void Tim_ManSetCoRequiredAll( Tim_Man_t * p, float Delay );
extern float Tim_ManGetCiArrival( Tim_Man_t * p, int iCi );
extern float Tim_ManGetCoRequired( Tim_Man_t * p, int iCo );
extern int Tim_ManBoxForCi( Tim_Man_t * p, int iCo );
extern int Tim_ManBoxForCo( Tim_Man_t * p, int iCi );
extern int Tim_ManBoxInputFirst( Tim_Man_t * p, int iBox );
extern int Tim_ManBoxOutputFirst( Tim_Man_t * p, int iBox );
extern int Tim_ManBoxInputNum( Tim_Man_t * p, int iBox );
extern int Tim_ManBoxOutputNum( Tim_Man_t * p, int iBox );
extern void Tim_ManChangeForAdders( Tim_Man_t * p );
ABC_NAMESPACE_HEADER_END ABC_NAMESPACE_HEADER_END
......
/**CFile****************************************************************
FileName [timBox.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Hierarchy/timing manager.]
Synopsis [Manipulation of timing boxes.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - April 28, 2007.]
Revision [$Id: timBox.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
***********************************************************************/
#include "timInt.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Creates the new timing box.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManCreateBox( Tim_Man_t * p, int firstIn, int nIns, int firstOut, int nOuts, int iDelayTable )
{
Tim_Box_t * pBox;
int i;
if ( p->vBoxes == NULL )
p->vBoxes = Vec_PtrAlloc( 100 );
pBox = (Tim_Box_t *)Mem_FlexEntryFetch( p->pMemObj, sizeof(Tim_Box_t) + sizeof(int) * (nIns+nOuts) );
memset( pBox, 0, sizeof(Tim_Box_t) );
pBox->iBox = Vec_PtrSize( p->vBoxes );
Vec_PtrPush( p->vBoxes, pBox );
pBox->iDelayTable = iDelayTable;
pBox->nInputs = nIns;
pBox->nOutputs = nOuts;
for ( i = 0; i < nIns; i++ )
{
assert( firstIn+i < p->nCos );
pBox->Inouts[i] = firstIn+i;
p->pCos[firstIn+i].iObj2Box = pBox->iBox;
p->pCos[firstIn+i].iObj2Num = i;
}
for ( i = 0; i < nOuts; i++ )
{
assert( firstOut+i < p->nCis );
pBox->Inouts[nIns+i] = firstOut+i;
p->pCis[firstOut+i].iObj2Box = pBox->iBox;
p->pCis[firstOut+i].iObj2Num = i;
}
// if ( pBox->iBox < 20 )
// printf( "%4d %4d %4d %4d \n", firstIn, nIns, firstOut, nOuts );
}
/**Function*************************************************************
Synopsis [Returns the box number for the given input.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Tim_ManBoxForCi( Tim_Man_t * p, int iCi )
{
if ( iCi >= p->nCis )
return -1;
return p->pCis[iCi].iObj2Box;
}
/**Function*************************************************************
Synopsis [Returns the box number for the given output.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Tim_ManBoxForCo( Tim_Man_t * p, int iCo )
{
if ( iCo >= p->nCos )
return -1;
return p->pCos[iCo].iObj2Box;
}
/**Function*************************************************************
Synopsis [Returns the first input of the box.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Tim_ManBoxInputFirst( Tim_Man_t * p, int iBox )
{
Tim_Box_t * pBox = (Tim_Box_t *)Vec_PtrEntry( p->vBoxes, iBox );
return pBox->Inouts[0];
}
/**Function*************************************************************
Synopsis [Returns the first input of the box.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Tim_ManBoxOutputFirst( Tim_Man_t * p, int iBox )
{
Tim_Box_t * pBox = (Tim_Box_t *)Vec_PtrEntry( p->vBoxes, iBox );
return pBox->Inouts[pBox->nInputs];
}
/**Function*************************************************************
Synopsis [Returns the first input of the box.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Tim_ManBoxInputNum( Tim_Man_t * p, int iBox )
{
Tim_Box_t * pBox = (Tim_Box_t *)Vec_PtrEntry( p->vBoxes, iBox );
return pBox->nInputs;
}
/**Function*************************************************************
Synopsis [Returns the first input of the box.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Tim_ManBoxOutputNum( Tim_Man_t * p, int iBox )
{
Tim_Box_t * pBox = (Tim_Box_t *)Vec_PtrEntry( p->vBoxes, iBox );
return pBox->nOutputs;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
float * Tim_ManBoxDelayTable( Tim_Man_t * p, int iBox )
{
Tim_Box_t * pBox = (Tim_Box_t *)Vec_PtrEntry( p->vBoxes, iBox );
if ( pBox->iDelayTable < 0 )
return NULL;
return (float *)Vec_PtrEntry( p->vDelayTables, pBox->iDelayTable );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END
/**CFile****************************************************************
FileName [timDump.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Hierarchy/timing manager.]
Synopsis [Saving and loading the hierarchy timing manager.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - April 28, 2007.]
Revision [$Id: timDump.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
***********************************************************************/
#include "timInt.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
#define TIM_DUMP_VER_NUM 1
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Transform the timing manager into the char stream.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Str_t * Tim_ManSave( Tim_Man_t * p )
{
Tim_Box_t * pBox;
Tim_Obj_t * pObj;
Vec_Str_t * vStr;
float * pDelayTable;
int i, k, TableSize;
// create output stream
vStr = Vec_StrAlloc( 10000 );
// dump version number
Vec_StrPutI_ne( vStr, TIM_DUMP_VER_NUM );
// save CI/CO counts
Vec_StrPutI_ne( vStr, Tim_ManCiNum(p) );
Vec_StrPutI_ne( vStr, Tim_ManCoNum(p) );
// save PI/PO counts
Vec_StrPutI_ne( vStr, Tim_ManPiNum(p) );
Vec_StrPutI_ne( vStr, Tim_ManPoNum(p) );
// save number of boxes
Vec_StrPutI_ne( vStr, Tim_ManBoxNum(p) );
// for each box, save num_inputs, num_outputs, and delay table ID
Tim_ManForEachBox( p, pBox, i )
{
Vec_StrPutI_ne( vStr, Tim_ManBoxInputNum(p, pBox->iBox) );
Vec_StrPutI_ne( vStr, Tim_ManBoxOutputNum(p, pBox->iBox) );
Vec_StrPutI_ne( vStr, pBox->iDelayTable ); // can be -1 if delay table is not given
}
// save the number of delay tables
Vec_StrPutI_ne( vStr, Tim_ManDelayTableNum(p) );
// save the delay tables
Vec_PtrForEachEntry( float *, p->vDelayTables, pDelayTable, i )
{
assert( (int)pDelayTable[0] == i );
// save table ID and dimensions (inputs x outputs)
Vec_StrPutI_ne( vStr, (int)pDelayTable[0] );
Vec_StrPutI_ne( vStr, (int)pDelayTable[1] );
Vec_StrPutI_ne( vStr, (int)pDelayTable[2] );
// save table contents
TableSize = (int)pDelayTable[1] * (int)pDelayTable[2];
for ( k = 0; k < TableSize; k++ )
Vec_StrPutF( vStr, pDelayTable[k+3] );
}
// save PI arrival times
Tim_ManForEachPi( p, pObj, i )
Vec_StrPutF( vStr, Tim_ManGetCiArrival(p, pObj->Id) );
// save PO required times
Tim_ManForEachPo( p, pObj, i )
Vec_StrPutF( vStr, Tim_ManGetCoRequired(p, pObj->Id) );
return vStr;
}
/**Function*************************************************************
Synopsis [Restores the timing manager from the char stream.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Tim_Man_t * Tim_ManLoad( Vec_Str_t * p )
{
Tim_Man_t * pMan;
int VerNum, nCis, nCos, nPis, nPos;
int nBoxes, nBoxIns, nBoxOuts;
int TableId, nTables, TableSize, TableX, TableY;
int i, k, curPi, curPo, iStr = 0;
float * pDelayTable;
// get version number
VerNum = Vec_StrGetI_ne( p, &iStr );
assert( VerNum == TIM_DUMP_VER_NUM );
// get the number of CIs/COs
nCis = Vec_StrGetI_ne( p, &iStr );
nCos = Vec_StrGetI_ne( p, &iStr );
// get the number of PIs/POs
nPis = Vec_StrGetI_ne( p, &iStr );
nPos = Vec_StrGetI_ne( p, &iStr );
// start the timing manager
pMan = Tim_ManStart( nCis, nCos );
// start boxes
nBoxes = Vec_StrGetI_ne( p, &iStr );
assert( pMan->vBoxes == NULL );
pMan->vBoxes = Vec_PtrAlloc( nBoxes );
// create boxes
curPi = nPis;
curPo = 0;
for ( i = 0; i < nBoxes; i++ )
{
nBoxIns = Vec_StrGetI_ne( p, &iStr );
nBoxOuts = Vec_StrGetI_ne( p, &iStr );
TableId = Vec_StrGetI_ne( p, &iStr );
Tim_ManCreateBox( pMan, curPo, nBoxIns, curPi, nBoxOuts, TableId );
curPi += nBoxOuts;
curPo += nBoxIns;
}
curPo += nPos;
assert( curPi == nCis );
assert( curPo == nCos );
// create delay tables
nTables = Vec_StrGetI_ne( p, &iStr );
assert( pMan->vDelayTables == NULL );
pMan->vDelayTables = Vec_PtrAlloc( nTables );
// read delay tables
assert( Vec_PtrSize(pMan->vDelayTables) == 0 );
for ( i = 0; i < nTables; i++ )
{
// read table ID and dimensions
TableId = Vec_StrGetI_ne( p, &iStr );
TableX = Vec_StrGetI_ne( p, &iStr );
TableY = Vec_StrGetI_ne( p, &iStr );
assert( TableId == i );
// create new table
TableSize = TableX * TableY;
pDelayTable = ABC_ALLOC( float, TableSize + 3 );
pDelayTable[0] = TableId;
pDelayTable[1] = TableX;
pDelayTable[2] = TableY;
// read table contents
for ( k = 0; k < TableSize; k++ )
pDelayTable[k+3] = Vec_StrGetF( p, &iStr );
assert( Vec_PtrSize(pMan->vDelayTables) == TableId );
Vec_PtrPush( pMan->vDelayTables, pDelayTable );
}
assert( Vec_PtrSize(pMan->vDelayTables) == nTables );
// Tim_ManPrint( pMan );
return pMan;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END
/**CFile****************************************************************
FileName [timInt.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Hierarchy/timing manager.]
Synopsis [Internal declarations.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - April 28, 2007.]
Revision [$Id: timInt.h,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
***********************************************************************/
#ifndef ABC__aig__tim__timInt_h
#define ABC__aig__tim__timInt_h
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "misc/vec/vec.h"
#include "misc/mem/mem.h"
#include "tim.h"
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_HEADER_START
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
typedef struct Tim_Box_t_ Tim_Box_t;
typedef struct Tim_Obj_t_ Tim_Obj_t;
// timing manager
struct Tim_Man_t_
{
Vec_Ptr_t * vBoxes; // the timing boxes
Vec_Ptr_t * vDelayTables; // pointers to the delay tables
Mem_Flex_t * pMemObj; // memory manager for boxes
int nTravIds; // traversal ID of the manager
int fUseTravId; // enables the use of traversal ID
int nCis; // the number of PIs
int nCos; // the number of POs
Tim_Obj_t * pCis; // timing info for the PIs
Tim_Obj_t * pCos; // timing info for the POs
};
// timing box
struct Tim_Box_t_
{
int iBox; // the unique ID of this box
int TravId; // traversal ID of this box
int nInputs; // the number of box inputs (POs)
int nOutputs; // the number of box outputs (PIs)
int iDelayTable; // index of the delay table
int Inouts[0]; // the int numbers of PIs and POs
};
// timing object
struct Tim_Obj_t_
{
int Id; // the ID of this object
int TravId; // traversal ID of this object
int iObj2Box; // mapping of the object into its box
int iObj2Num; // mapping of the object into its number in the box
float timeArr; // arrival time of the object
float timeReq; // required time of the object
};
/*
A delay table is a one-dimensional array of floats whose size is: 3 + nInputs * nOutputs.
The first entry is the delay table ID used by the boxes to refer to the table.
The second and third entris are nInputs and nOutputs.
The following entries list the delay numbers for per output,
that is, the first nInputs entries give delay of the first output, etc.
*/
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
static inline Tim_Obj_t * Tim_ManCi( Tim_Man_t * p, int i ) { assert( i < p->nCis ); return p->pCis + i; }
static inline Tim_Obj_t * Tim_ManCo( Tim_Man_t * p, int i ) { assert( i < p->nCos ); return p->pCos + i; }
static inline Tim_Box_t * Tim_ManBox( Tim_Man_t * p, int i ) { return (Tim_Box_t *)Vec_PtrEntry(p->vBoxes, i); }
static inline Tim_Box_t * Tim_ManCiBox( Tim_Man_t * p, int i ) { return Tim_ManCi(p,i)->iObj2Box < 0 ? NULL : (Tim_Box_t *)Vec_PtrEntry( p->vBoxes, Tim_ManCi(p,i)->iObj2Box ); }
static inline Tim_Box_t * Tim_ManCoBox( Tim_Man_t * p, int i ) { return Tim_ManCo(p,i)->iObj2Box < 0 ? NULL : (Tim_Box_t *)Vec_PtrEntry( p->vBoxes, Tim_ManCo(p,i)->iObj2Box ); }
static inline Tim_Obj_t * Tim_ManBoxInput( Tim_Man_t * p, Tim_Box_t * pBox, int i ) { assert( i < pBox->nInputs ); return p->pCos + pBox->Inouts[i]; }
static inline Tim_Obj_t * Tim_ManBoxOutput( Tim_Man_t * p, Tim_Box_t * pBox, int i ) { assert( i < pBox->nOutputs ); return p->pCis + pBox->Inouts[pBox->nInputs+i]; }
////////////////////////////////////////////////////////////////////////
/// ITERATORS ///
////////////////////////////////////////////////////////////////////////
#define Tim_ManForEachCi( p, pObj, i ) \
for ( i = 0; (i < (p)->nCis) && ((pObj) = (p)->pCis + i); i++ )
#define Tim_ManForEachCo( p, pObj, i ) \
for ( i = 0; (i < (p)->nCos) && ((pObj) = (p)->pCos + i); i++ )
#define Tim_ManForEachPi( p, pObj, i ) \
Tim_ManForEachCi( p, pObj, i ) if ( pObj->iObj2Box >= 0 ) {} else
#define Tim_ManForEachPo( p, pObj, i ) \
Tim_ManForEachCo( p, pObj, i ) if ( pObj->iObj2Box >= 0 ) {} else
#define Tim_ManForEachBox( p, pBox, i ) \
Vec_PtrForEachEntry( Tim_Box_t *, p->vBoxes, pBox, i )
#define Tim_ManBoxForEachInput( p, pBox, pObj, i ) \
for ( i = 0; (i < (pBox)->nInputs) && ((pObj) = Tim_ManBoxInput(p, pBox, i)); i++ )
#define Tim_ManBoxForEachOutput( p, pBox, pObj, i ) \
for ( i = 0; (i < (pBox)->nOutputs) && ((pObj) = Tim_ManBoxOutput(p, pBox, i)); i++ )
////////////////////////////////////////////////////////////////////////
/// SEQUENTIAL ITERATORS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
/*=== time.c ===========================================================*/
ABC_NAMESPACE_HEADER_END
#endif
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**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"
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;
// 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 );
// clear traversal IDs
Tim_ManForEachCi( p, pObj, i )
pObj->TravId = 0;
Tim_ManForEachCo( p, pObj, i )
pObj->TravId = 0;
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
pNew->vDelayTables = Vec_PtrAlloc( Vec_PtrSize(p->vDelayTables) );
Vec_PtrForEachEntry( float *, p->vDelayTables, pDelayTable, i )
{
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] = fUnitDelay ? 1.0 : pDelayTable[3+k];
assert( (int)pDelayTableNew[0] == Vec_PtrSize(pNew->vDelayTables) );
Vec_PtrPush( pNew->vDelayTables, pDelayTableNew );
}
// duplicate boxes
Tim_ManForEachBox( p, pBox, i )
Tim_ManCreateBox( pNew, pBox->Inouts[0], pBox->nInputs,
pBox->Inouts[pBox->nInputs], pBox->nOutputs, pBox->iDelayTable );
return pNew;
}
/**Function*************************************************************
Synopsis [Stops the timing manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManStop( Tim_Man_t * p )
{
float * pTable;
int i;
if ( p->vDelayTables )
{
Vec_PtrForEachEntry( float *, p->vDelayTables, pTable, i )
ABC_FREE( pTable );
Vec_PtrFree( p->vDelayTables );
}
Vec_PtrFree( 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 [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, k;
printf( "TIMING INFORMATION:\n" );
// 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 : arr = %5.3f req = %5.3f\n", pPrev->timeArr, pPrev->timeReq );
else
Tim_ManForEachPi( p, pObj, i )
printf( "PI%5d : arr = %5.3f req = %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 : arr = %5.3f req = %5.3f\n", pPrev->timeArr, pPrev->timeReq );
else
Tim_ManForEachPo( p, pObj, i )
printf( "PO%5d : arr = %5.3f req = %5.3f\n", i, pObj->timeArr, pObj->timeReq );
// print box info
Tim_ManForEachBox( p, pBox, i )
{
printf( "*** Box %3d : Ins = %d. Outs = %d.\n", i, pBox->nInputs, pBox->nOutputs );
printf( "Delay table:\n" );
pTable = Tim_ManBoxDelayTable( p, pBox->iBox );
for ( i = 0; i < pBox->nOutputs; i++, printf( "\n" ) )
for ( k = 0; k < pBox->nInputs; k++ )
if ( pTable[3+i*pBox->nInputs+k] == -ABC_INFINITY )
printf( "%5s", "-" );
else
printf( "%5.0f", pTable[3+i*pBox->nInputs+k] );
printf( "\n" );
// print box inputs
pPrev = Tim_ManBoxInput( p, pBox, 0 );
Tim_ManBoxForEachInput( p, pBox, pObj, i )
if ( pPrev->timeArr != pObj->timeArr || pPrev->timeReq != pObj->timeReq )
break;
if ( i == Tim_ManBoxInputNum(p, pBox->iBox) )
printf( "Box inputs : arr = %5.3f req = %5.3f\n", pPrev->timeArr, pPrev->timeReq );
else
Tim_ManBoxForEachInput( p, pBox, pObj, i )
printf( "box-inp%3d : arr = %5.3f req = %5.3f\n", i, pObj->timeArr, pObj->timeReq );
// print box outputs
pPrev = Tim_ManBoxOutput( p, pBox, 0 );
Tim_ManBoxForEachOutput( p, pBox, pObj, i )
if ( pPrev->timeArr != pObj->timeArr || pPrev->timeReq != pObj->timeReq )
break;
if ( i == Tim_ManBoxOutputNum(p, pBox->iBox) )
printf( "Box outputs : arr = %5.3f req = %5.3f\n", pPrev->timeArr, pPrev->timeReq );
else
Tim_ManBoxForEachOutput( p, pBox, pObj, i )
printf( "box-out%3d : arr = %5.3f req = %5.3f\n", i, pObj->timeArr, pObj->timeReq );
}
printf( "\n" );
}
/**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 )
{
return Tim_ManBoxOutputFirst(p, 0);
}
int Tim_ManPoNum( Tim_Man_t * p )
{
int 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 Vec_PtrSize(p->vBoxes);
}
int Tim_ManDelayTableNum( Tim_Man_t * p )
{
return Vec_PtrSize(p->vDelayTables);
}
/**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
/**CFile****************************************************************
FileName [timTime.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Hierarchy/timing manager.]
Synopsis [Setting and resetting timing information of the boxes.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - April 28, 2007.]
Revision [$Id: timTime.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
***********************************************************************/
#include "timInt.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Initializes arrival time of the PI.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManInitPiArrival( Tim_Man_t * p, int iPi, float Delay )
{
assert( iPi < p->nCis );
p->pCis[iPi].timeArr = Delay;
}
/**Function*************************************************************
Synopsis [Initializes required time of the PO.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManInitPoRequired( Tim_Man_t * p, int iPo, float Delay )
{
assert( iPo < p->nCos );
p->pCos[iPo].timeReq = Delay;
}
/**Function*************************************************************
Synopsis [Sets arrival times of all PIs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManInitPiArrivalAll( Tim_Man_t * p, float Delay )
{
Tim_Obj_t * pObj;
int i;
Tim_ManForEachPi( p, pObj, i )
Tim_ManInitPiArrival( p, i, Delay );
}
/**Function*************************************************************
Synopsis [Sets required times of all POs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManInitPoRequiredAll( Tim_Man_t * p, float Delay )
{
Tim_Obj_t * pObj;
int i;
Tim_ManForEachPo( p, pObj, i )
Tim_ManSetCoRequired( p, i, Delay );
}
/**Function*************************************************************
Synopsis [Updates arrival time of the CO.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManSetCoArrival( Tim_Man_t * p, int iCo, float Delay )
{
assert( iCo < p->nCos );
assert( !p->fUseTravId || p->pCos[iCo].TravId != p->nTravIds );
p->pCos[iCo].timeArr = Delay;
p->pCos[iCo].TravId = p->nTravIds;
}
/**Function*************************************************************
Synopsis [Updates required time of the CI.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManSetCiRequired( Tim_Man_t * p, int iCi, float Delay )
{
assert( iCi < p->nCis );
assert( !p->fUseTravId || p->pCis[iCi].TravId != p->nTravIds );
p->pCis[iCi].timeReq = Delay;
p->pCis[iCi].TravId = p->nTravIds;
}
/**Function*************************************************************
Synopsis [Updates required time of the CO.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManSetCoRequired( Tim_Man_t * p, int iCo, float Delay )
{
assert( iCo < p->nCos );
assert( !p->fUseTravId || p->pCos[iCo].TravId != p->nTravIds );
p->pCos[iCo].timeReq = Delay;
p->pCos[iCo].TravId = p->nTravIds;
}
/**Function*************************************************************
Synopsis [Returns CO arrival time.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
float Tim_ManGetCiArrival( Tim_Man_t * p, int iCi )
{
Tim_Box_t * pBox;
Tim_Obj_t * pObjThis, * pObj, * pObjRes;
float * pTable, * pDelays, DelayBest;
int i, k;
// consider the already processed PI
pObjThis = Tim_ManCi( p, iCi );
if ( p->fUseTravId && pObjThis->TravId == p->nTravIds )
return pObjThis->timeArr;
pObjThis->TravId = p->nTravIds;
// consider the main PI
pBox = Tim_ManCiBox( p, iCi );
if ( pBox == NULL )
return pObjThis->timeArr;
// update box timing
pBox->TravId = p->nTravIds;
// get the arrival times of the inputs of the box (POs)
if ( p->fUseTravId )
Tim_ManBoxForEachInput( p, pBox, pObj, i )
if ( pObj->TravId != p->nTravIds )
printf( "Tim_ManGetCiArrival(): Input arrival times of the box are not up to date!\n" );
// compute the arrival times for each output of the box (PIs)
pTable = Tim_ManBoxDelayTable( p, pBox->iBox );
Tim_ManBoxForEachOutput( p, pBox, pObjRes, i )
{
pDelays = pTable + 3 + i * pBox->nInputs;
DelayBest = -TIM_ETERNITY;
Tim_ManBoxForEachInput( p, pBox, pObj, k )
DelayBest = Abc_MaxInt( DelayBest, pObj->timeArr + pDelays[k] );
pObjRes->timeArr = DelayBest;
pObjRes->TravId = p->nTravIds;
}
return pObjThis->timeArr;
}
/**Function*************************************************************
Synopsis [Returns CO required time.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
float Tim_ManGetCoRequired( Tim_Man_t * p, int iCo )
{
Tim_Box_t * pBox;
Tim_Obj_t * pObjThis, * pObj, * pObjRes;
float * pTable, * pDelays, DelayBest;
int i, k;
// consider the already processed PO
pObjThis = Tim_ManCo( p, iCo );
if ( p->fUseTravId && pObjThis->TravId == p->nTravIds )
return pObjThis->timeReq;
pObjThis->TravId = p->nTravIds;
// consider the main PO
pBox = Tim_ManCoBox( p, iCo );
if ( pBox == NULL )
return pObjThis->timeReq;
// update box timing
pBox->TravId = p->nTravIds;
// get the required times of the outputs of the box (PIs)
if ( p->fUseTravId )
Tim_ManBoxForEachOutput( p, pBox, pObj, i )
if ( pObj->TravId != p->nTravIds )
printf( "Tim_ManGetCoRequired(): Output required times of output %d the box %d are not up to date!\n", i, pBox->iBox );
// compute the required times for each input of the box (POs)
pTable = Tim_ManBoxDelayTable( p, pBox->iBox );
Tim_ManBoxForEachInput( p, pBox, pObjRes, i )
{
DelayBest = TIM_ETERNITY;
Tim_ManBoxForEachOutput( p, pBox, pObj, k )
{
pDelays = pTable + 3 + k * pBox->nInputs;
DelayBest = Abc_MinFloat( DelayBest, pObj->timeReq - pDelays[i] );
}
pObjRes->timeReq = DelayBest;
pObjRes->TravId = p->nTravIds;
}
return pObjThis->timeReq;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END
/**CFile****************************************************************
FileName [timTrav.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Hierarchy/timing manager.]
Synopsis [Manipulation of traversal IDs.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - April 28, 2007.]
Revision [$Id: timTrav.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
***********************************************************************/
#include "timInt.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Increments the trav ID of the manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManIncrementTravId( Tim_Man_t * p )
{
int i;
if ( p->nTravIds >= (1<<30)-1 )
{
p->nTravIds = 0;
for ( i = 0; i < p->nCis; i++ )
p->pCis[i].TravId = 0;
for ( i = 0; i < p->nCos; i++ )
p->pCos[i].TravId = 0;
}
assert( p->nTravIds < (1<<30)-1 );
p->nTravIds++;
}
/**Function*************************************************************
Synopsis [Label box inputs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManSetCurrentTravIdBoxInputs( Tim_Man_t * p, int iBox )
{
Tim_Box_t * pBox;
Tim_Obj_t * pObj;
int i;
pBox = Tim_ManBox( p, iBox );
Tim_ManBoxForEachInput( p, pBox, pObj, i )
pObj->TravId = p->nTravIds;
}
/**Function*************************************************************
Synopsis [Label box outputs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManSetCurrentTravIdBoxOutputs( Tim_Man_t * p, int iBox )
{
Tim_Box_t * pBox;
Tim_Obj_t * pObj;
int i;
pBox = Tim_ManBox( p, iBox );
Tim_ManBoxForEachOutput( p, pBox, pObj, i )
pObj->TravId = p->nTravIds;
}
/**Function*************************************************************
Synopsis [Label box inputs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManSetPreviousTravIdBoxInputs( Tim_Man_t * p, int iBox )
{
Tim_Box_t * pBox;
Tim_Obj_t * pObj;
int i;
pBox = Tim_ManBox( p, iBox );
Tim_ManBoxForEachInput( p, pBox, pObj, i )
pObj->TravId = p->nTravIds - 1;
}
/**Function*************************************************************
Synopsis [Label box outputs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tim_ManSetPreviousTravIdBoxOutputs( Tim_Man_t * p, int iBox )
{
Tim_Box_t * pBox;
Tim_Obj_t * pObj;
int i;
pBox = Tim_ManBox( p, iBox );
Tim_ManBoxForEachOutput( p, pBox, pObj, i )
pObj->TravId = p->nTravIds - 1;
}
/**Function*************************************************************
Synopsis [Updates required time of the CI.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Tim_ManIsCiTravIdCurrent( Tim_Man_t * p, int iCi )
{
assert( iCi < p->nCis );
assert( p->fUseTravId );
return p->pCis[iCi].TravId == p->nTravIds;
}
/**Function*************************************************************
Synopsis [Updates required time of the CO.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Tim_ManIsCoTravIdCurrent( Tim_Man_t * p, int iCo )
{
assert( iCo < p->nCos );
assert( p->fUseTravId );
return p->pCos[iCo].TravId == p->nTravIds;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END
...@@ -638,6 +638,28 @@ static inline void Vec_StrReverseOrder( Vec_Str_t * p ) ...@@ -638,6 +638,28 @@ static inline void Vec_StrReverseOrder( Vec_Str_t * p )
/**Function************************************************************* /**Function*************************************************************
Synopsis [Compares two strings.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Vec_StrEqual( Vec_Str_t * p1, Vec_Str_t * p2 )
{
int i;
if ( p1->nSize != p2->nSize )
return 0;
for ( i = 0; i < p1->nSize; i++ )
if ( p1->pArray[i] != p2->pArray[i] )
return 0;
return 1;
}
/**Function*************************************************************
Synopsis [Comparison procedure for two clauses.] Synopsis [Comparison procedure for two clauses.]
Description [] Description []
......
...@@ -110,7 +110,7 @@ int Nwk_ManLevelBackup( Nwk_Man_t * pNtk ) ...@@ -110,7 +110,7 @@ int Nwk_ManLevelBackup( Nwk_Man_t * pNtk )
Nwk_ObjSetLevel( pObj, 0 ); Nwk_ObjSetLevel( pObj, 0 );
// perform level computation // perform level computation
LevelMax = 0; LevelMax = 0;
pManTimeUnit = pNtk->pManTime ? Tim_ManDupUnit( pNtk->pManTime ) : NULL; pManTimeUnit = pNtk->pManTime ? Tim_ManDup( pNtk->pManTime, 1 ) : NULL;
if ( pManTimeUnit ) if ( pManTimeUnit )
Tim_ManIncrementTravId( pManTimeUnit ); Tim_ManIncrementTravId( pManTimeUnit );
Nwk_ManForEachObj( pNtk, pObj, i ) Nwk_ManForEachObj( pNtk, pObj, i )
......
...@@ -373,7 +373,7 @@ float Nwk_ManDelayTraceLut( Nwk_Man_t * pNtk ) ...@@ -373,7 +373,7 @@ float Nwk_ManDelayTraceLut( Nwk_Man_t * pNtk )
if ( pNtk->pManTime ) if ( pNtk->pManTime )
{ {
Tim_ManIncrementTravId( pNtk->pManTime ); Tim_ManIncrementTravId( pNtk->pManTime );
Tim_ManSetCoRequiredAll( pNtk->pManTime, tArrival ); Tim_ManInitPoRequiredAll( pNtk->pManTime, tArrival );
} }
else else
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment