mirror of https://github.com/YosysHQ/abc.git
New package to read/write a subset of Liberty for STA.
This commit is contained in:
parent
5ff49be993
commit
bebd7ee6cb
|
|
@ -526,6 +526,16 @@ void Mio_LibrarySortGates( Mio_Library_t * pLib )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Mio_Gate_t * Mio_GateCompare( Mio_Gate_t * pThis, Mio_Gate_t * pNew, word uTruth )
|
||||
{
|
||||
if ( pNew->uTruth != uTruth )
|
||||
return pThis;
|
||||
if ( pThis == NULL )
|
||||
return pNew;
|
||||
if ( pThis->dArea > pNew->dArea || (pThis->dArea == pNew->dArea && strcmp(pThis->pName, pNew->pName) > 0) )
|
||||
return pNew;
|
||||
return pThis;
|
||||
}
|
||||
void Mio_LibraryDetectSpecialGates( Mio_Library_t * pLib )
|
||||
{
|
||||
Mio_Gate_t * pGate;
|
||||
|
|
@ -538,45 +548,29 @@ void Mio_LibraryDetectSpecialGates( Mio_Library_t * pLib )
|
|||
uFuncInv = ~uFuncBuf;
|
||||
uFuncNand2 = ~uFuncAnd2;
|
||||
|
||||
// get buffer
|
||||
// get smallest-area buffer
|
||||
Mio_LibraryForEachGate( pLib, pGate )
|
||||
if ( pLib->pGateBuf == NULL && pGate->uTruth == uFuncBuf )
|
||||
{
|
||||
pLib->pGateBuf = pGate;
|
||||
break;
|
||||
}
|
||||
pLib->pGateBuf = Mio_GateCompare( pLib->pGateBuf, pGate, uFuncBuf );
|
||||
if ( pLib->pGateBuf == NULL )
|
||||
{
|
||||
printf( "Warnings: GENLIB library reader cannot detect the buffer gate.\n" );
|
||||
printf( "Some parts of the supergate-based technology mapper may not work correctly.\n" );
|
||||
}
|
||||
|
||||
// get inverter
|
||||
// get smallest-area inverter
|
||||
Mio_LibraryForEachGate( pLib, pGate )
|
||||
if ( pLib->pGateInv == NULL && pGate->uTruth == uFuncInv )
|
||||
{
|
||||
pLib->pGateInv = pGate;
|
||||
break;
|
||||
}
|
||||
pLib->pGateInv = Mio_GateCompare( pLib->pGateInv, pGate, uFuncInv );
|
||||
if ( pLib->pGateInv == NULL )
|
||||
{
|
||||
printf( "Warnings: GENLIB library reader cannot detect the invertor gate.\n" );
|
||||
printf( "Some parts of the supergate-based technology mapper may not work correctly.\n" );
|
||||
}
|
||||
|
||||
// get the NAND2 and AND2 gates
|
||||
// get smallest-area NAND2/AND2 gates
|
||||
Mio_LibraryForEachGate( pLib, pGate )
|
||||
if ( pLib->pGateNand2 == NULL && pGate->uTruth == uFuncNand2 )
|
||||
{
|
||||
pLib->pGateNand2 = pGate;
|
||||
break;
|
||||
}
|
||||
pLib->pGateNand2 = Mio_GateCompare( pLib->pGateNand2, pGate, uFuncNand2 );
|
||||
Mio_LibraryForEachGate( pLib, pGate )
|
||||
if ( pLib->pGateAnd2 == NULL && pGate->uTruth == uFuncAnd2 )
|
||||
{
|
||||
pLib->pGateAnd2 = pGate;
|
||||
break;
|
||||
}
|
||||
pLib->pGateAnd2 = Mio_GateCompare( pLib->pGateAnd2, pGate, uFuncAnd2 );
|
||||
if ( pLib->pGateAnd2 == NULL && pLib->pGateNand2 == NULL )
|
||||
{
|
||||
printf( "Warnings: GENLIB library reader cannot detect the AND2 or NAND2 gate.\n" );
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ void Scl_Init( Abc_Frame_t * pAbc )
|
|||
}
|
||||
void Scl_End( Abc_Frame_t * pAbc )
|
||||
{
|
||||
Abc_SclLoad( NULL, &pAbc->pLibScl );
|
||||
Abc_SclLoad( NULL, (SC_Lib **)&pAbc->pLibScl );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -109,7 +109,7 @@ int Scl_CommandRead( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
fclose( pFile );
|
||||
|
||||
// read new library
|
||||
Abc_SclLoad( pFileName, &pAbc->pLibScl );
|
||||
Abc_SclLoad( pFileName, (SC_Lib **)&pAbc->pLibScl );
|
||||
Abc_SclWriteText( "sizing\\scl_out.txt", pAbc->pLibScl );
|
||||
return 0;
|
||||
|
||||
|
|
@ -166,7 +166,7 @@ int Scl_CommandWrite( Abc_Frame_t * pAbc, int argc, char **argv )
|
|||
fclose( pFile );
|
||||
|
||||
// save current library
|
||||
Abc_SclSave( pFileName, pAbc->pLibScl );
|
||||
Abc_SclSave( pFileName, (SC_Lib *)pAbc->pLibScl );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
|
|
@ -292,12 +292,24 @@ usage:
|
|||
int Scl_CommandGsize( Abc_Frame_t * pAbc, int argc, char **argv )
|
||||
{
|
||||
int c;
|
||||
int nSteps = 100;
|
||||
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "Nh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'N':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-N\" should be followed by a positive integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
nSteps = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( nSteps <= 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
|
|
@ -326,13 +338,14 @@ int Scl_CommandGsize( Abc_Frame_t * pAbc, int argc, char **argv )
|
|||
return 1;
|
||||
}
|
||||
|
||||
// Abc_SclSizingPerform( pAbc->pLibScl, Abc_FrameReadNtk(pAbc) );
|
||||
// Abc_SclSizingPerform( pAbc->pLibScl, Abc_FrameReadNtk(pAbc), nSteps );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pAbc->Err, "usage: gsize [-h]\n" );
|
||||
fprintf( pAbc->Err, "\t performs gate sizing using Liberty library\n" );
|
||||
fprintf( pAbc->Err, "\t-h : print the help massage\n" );
|
||||
fprintf( pAbc->Err, "usage: gsize [-N num] [-h]\n" );
|
||||
fprintf( pAbc->Err, "\t performs gate sizing using Liberty library\n" );
|
||||
fprintf( pAbc->Err, "\t-N <num> : the number of refinement iterations [default = %d]\n", nSteps );
|
||||
fprintf( pAbc->Err, "\t-h : print the help massage\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -404,11 +417,11 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
return 0;
|
||||
|
||||
usage:
|
||||
Abc_Print( -2, "usage: buffer [-N num] [-vh]\n" );
|
||||
Abc_Print( -2, "\t performs buffering of the mapped network\n" );
|
||||
Abc_Print( -2, "\t-N <num> : the number of refinement iterations [default = %d]\n", Degree );
|
||||
Abc_Print( -2, "\t-v : toggle printing optimization summary [default = %s]\n", fVerbose? "yes": "no" );
|
||||
Abc_Print( -2, "\t-h : print the command usage\n");
|
||||
fprintf( pAbc->Err, "usage: buffer [-N num] [-vh]\n" );
|
||||
fprintf( pAbc->Err, "\t performs buffering of the mapped network\n" );
|
||||
fprintf( pAbc->Err, "\t-N <num> : the number of refinement iterations [default = %d]\n", Degree );
|
||||
fprintf( pAbc->Err, "\t-v : toggle printing optimization summary [default = %s]\n", fVerbose? "yes": "no" );
|
||||
fprintf( pAbc->Err, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,12 +47,12 @@ ABC_NAMESPACE_HEADER_START
|
|||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*=== sclFile.c =============================================================*/
|
||||
extern void Abc_SclLoad( char * pFileName, void ** ppScl );
|
||||
extern void Abc_SclSave( char * pFileName, void * pScl );
|
||||
extern void Abc_SclLoad( char * pFileName, SC_Lib ** ppScl );
|
||||
extern void Abc_SclSave( char * pFileName, SC_Lib * pScl );
|
||||
/*=== sclTime.c =============================================================*/
|
||||
extern void Abc_SclTimePerform( SC_Lib * pLib, void * pNtk );
|
||||
/*=== sclSize.c =============================================================*/
|
||||
extern void Abc_SclSizingPerform( SC_Lib * pLib, void * pNtk );
|
||||
extern void Abc_SclSizingPerform( SC_Lib * pLib, void * pNtk, int nSteps );
|
||||
|
||||
ABC_NAMESPACE_HEADER_END
|
||||
|
||||
|
|
|
|||
|
|
@ -332,11 +332,11 @@ SC_Lib * Abc_SclRead( char * pFileName )
|
|||
Abc_SclLinkCells( p );
|
||||
return p;
|
||||
}
|
||||
void Abc_SclLoad( char * pFileName, void ** ppScl )
|
||||
void Abc_SclLoad( char * pFileName, SC_Lib ** ppScl )
|
||||
{
|
||||
if ( *ppScl )
|
||||
{
|
||||
Abc_SclLibFree( *(SC_Lib **)ppScl );
|
||||
Abc_SclLibFree( *ppScl );
|
||||
*ppScl = NULL;
|
||||
}
|
||||
assert( *ppScl == NULL );
|
||||
|
|
@ -522,10 +522,10 @@ void Abc_SclWrite( char * pFileName, SC_Lib * p )
|
|||
}
|
||||
Vec_StrFree( vOut );
|
||||
}
|
||||
void Abc_SclSave( char * pFileName, void * pScl )
|
||||
void Abc_SclSave( char * pFileName, SC_Lib * pScl )
|
||||
{
|
||||
if ( pScl == NULL ) return;
|
||||
Abc_SclWrite( pFileName, (SC_Lib *)pScl );
|
||||
Abc_SclWrite( pFileName, pScl );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "misc/vec/vec.h"
|
||||
|
||||
|
|
@ -175,9 +176,12 @@ struct SC_Lib_
|
|||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static inline SC_Cell * SC_LibCell( SC_Lib * p, int i ) { return (SC_Cell *)Vec_PtrEntry(p->vCells, i); }
|
||||
static inline SC_Pin * SC_CellPin( SC_Cell * p, int i ) { return (SC_Pin *)Vec_PtrEntry(p->vPins, i); }
|
||||
static inline Vec_Wrd_t * SC_CellFunc( SC_Cell * p ) { return SC_CellPin(p, p->n_inputs)->vFunc; }
|
||||
static inline SC_Cell * SC_LibCell( SC_Lib * p, int i ) { return (SC_Cell *)Vec_PtrEntry(p->vCells, i); }
|
||||
static inline SC_Pin * SC_CellPin( SC_Cell * p, int i ) { return (SC_Pin *)Vec_PtrEntry(p->vPins, i); }
|
||||
static inline Vec_Wrd_t * SC_CellFunc( SC_Cell * p ) { return SC_CellPin(p, p->n_inputs)->vFunc; }
|
||||
|
||||
static inline double SC_LibCapFf( SC_Lib * p, double cap ) { return cap * p->unit_cap_fst * pow(10, 15 - p->unit_cap_snd); }
|
||||
static inline double SC_LibTimePs( SC_Lib * p, double time ) { return time * pow(10, 12 - p->unit_time); }
|
||||
|
||||
#define SC_LitForEachCell( p, pCell, i ) Vec_PtrForEachEntry( SC_Cell *, p->vCells, pCell, i )
|
||||
#define SC_CellForEachPin( p, pPin, i ) Vec_PtrForEachEntry( SC_Pin *, pCell->vPins, pPin, i )
|
||||
|
|
|
|||
|
|
@ -0,0 +1,181 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [sclMan.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
Synopsis [Standard-cell library representation.]
|
||||
|
||||
Author [Alan Mishchenko, Niklas Een]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - August 24, 2012.]
|
||||
|
||||
Revision [$Id: sclMan.h,v 1.0 2012/08/24 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef ABC__map__scl__sclMan_h
|
||||
#define ABC__map__scl__sclMan_h
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ABC_NAMESPACE_HEADER_START
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// STRUCTURE DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct SC_Pair_ SC_Pair;
|
||||
typedef struct SC_Man_ SC_Man;
|
||||
|
||||
struct SC_Pair_
|
||||
{
|
||||
float rise;
|
||||
float fall;
|
||||
};
|
||||
|
||||
struct SC_Man_
|
||||
{
|
||||
SC_Lib * pLib; // library
|
||||
Abc_Ntk_t * pNtk; // network
|
||||
float SumArea; // total area
|
||||
int nObjs; // allocated size
|
||||
Vec_Int_t * vGates; // mapping of objId into gateId
|
||||
SC_Pair * pLoads; // loads for each gate
|
||||
SC_Pair * pTimes; // arrivals for each gate
|
||||
SC_Pair * pSlews; // slews for each gate
|
||||
SC_Pair * pTimes2; // arrivals for each gate
|
||||
SC_Pair * pSlews2; // slews for each gate
|
||||
char * pWLoadUsed; // name of the used WireLoad model
|
||||
clock_t clkStart; // starting time
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// GLOBAL VARIABLES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static inline SC_Pair * Abc_SclObjLoad( SC_Man * p, Abc_Obj_t * pObj ) { return p->pLoads + Abc_ObjId(pObj); }
|
||||
static inline SC_Pair * Abc_SclObjTime( SC_Man * p, Abc_Obj_t * pObj ) { return p->pTimes + Abc_ObjId(pObj); }
|
||||
static inline SC_Pair * Abc_SclObjSlew( SC_Man * p, Abc_Obj_t * pObj ) { return p->pSlews + Abc_ObjId(pObj); }
|
||||
|
||||
static inline SC_Pair * Abc_SclObjTime2( SC_Man * p, Abc_Obj_t * pObj ) { return p->pTimes2 + Abc_ObjId(pObj); }
|
||||
static inline SC_Pair * Abc_SclObjSlew2( SC_Man * p, Abc_Obj_t * pObj ) { return p->pSlews2 + Abc_ObjId(pObj); }
|
||||
|
||||
static inline float Abc_SclObjGain( SC_Man * p, Abc_Obj_t * pObj ) { return (Abc_SclObjTime2(p, pObj)->rise - Abc_SclObjTime(p, pObj)->rise) + (Abc_SclObjTime2(p, pObj)->fall - Abc_SclObjTime(p, pObj)->fall); }
|
||||
|
||||
static inline void Abc_SclObjDupFanin( SC_Man * p, Abc_Obj_t * pObj )
|
||||
{
|
||||
assert( Abc_ObjIsCo(pObj) );
|
||||
*Abc_SclObjTime(p, pObj) = *Abc_SclObjTime(p, Abc_ObjFanin0(pObj));
|
||||
}
|
||||
|
||||
static inline double Abc_SclObjLoadFf( SC_Man * p, Abc_Obj_t * pObj, int fRise ) { return SC_LibCapFf( p->pLib, fRise ? Abc_SclObjLoad(p, pObj)->rise : Abc_SclObjLoad(p, pObj)->fall); }
|
||||
static inline double Abc_SclObjTimePs( SC_Man * p, Abc_Obj_t * pObj, int fRise ) { return SC_LibTimePs(p->pLib, fRise ? Abc_SclObjTime(p, pObj)->rise : Abc_SclObjTime(p, pObj)->fall); }
|
||||
static inline double Abc_SclObjSlewPs( SC_Man * p, Abc_Obj_t * pObj, int fRise ) { return SC_LibTimePs(p->pLib, fRise ? Abc_SclObjSlew(p, pObj)->rise : Abc_SclObjSlew(p, pObj)->fall); }
|
||||
|
||||
static inline SC_Cell * Abc_SclObjCell( SC_Man * p, Abc_Obj_t * pObj ) { return SC_LibCell( p->pLib, Vec_IntEntry(p->vGates, Abc_ObjId(pObj)) ); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Abc_SclConeStore( SC_Man * p, Vec_Int_t * vCone )
|
||||
{
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
Abc_NtkForEachObjVec( vCone, p->pNtk, pObj, i )
|
||||
{
|
||||
*Abc_SclObjTime2(p, pObj) = *Abc_SclObjTime(p, pObj);
|
||||
*Abc_SclObjSlew2(p, pObj) = *Abc_SclObjSlew(p, pObj);
|
||||
}
|
||||
}
|
||||
static inline void Abc_SclConeRestore( SC_Man * p, Vec_Int_t * vCone )
|
||||
{
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
Abc_NtkForEachObjVec( vCone, p->pNtk, pObj, i )
|
||||
{
|
||||
*Abc_SclObjTime(p, pObj) = *Abc_SclObjTime2(p, pObj);
|
||||
*Abc_SclObjSlew(p, pObj) = *Abc_SclObjSlew2(p, pObj);
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Prepares STA manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline SC_Man * Abc_SclManAlloc( SC_Lib * pLib, Abc_Ntk_t * pNtk )
|
||||
{
|
||||
SC_Man * p;
|
||||
assert( Abc_NtkHasMapping(pNtk) );
|
||||
p = ABC_CALLOC( SC_Man, 1 );
|
||||
p->pLib = pLib;
|
||||
p->pNtk = pNtk;
|
||||
p->nObjs = Abc_NtkObjNumMax(pNtk);
|
||||
p->pLoads = ABC_CALLOC( SC_Pair, p->nObjs );
|
||||
p->pTimes = ABC_CALLOC( SC_Pair, p->nObjs );
|
||||
p->pSlews = ABC_CALLOC( SC_Pair, p->nObjs );
|
||||
p->pTimes2 = ABC_CALLOC( SC_Pair, p->nObjs );
|
||||
p->pSlews2 = ABC_CALLOC( SC_Pair, p->nObjs );
|
||||
p->clkStart = clock();
|
||||
return p;
|
||||
}
|
||||
static inline void Abc_SclManFree( SC_Man * p )
|
||||
{
|
||||
Vec_IntFreeP( &p->vGates );
|
||||
ABC_FREE( p->pLoads );
|
||||
ABC_FREE( p->pTimes );
|
||||
ABC_FREE( p->pSlews );
|
||||
ABC_FREE( p->pTimes2 );
|
||||
ABC_FREE( p->pSlews2 );
|
||||
ABC_FREE( p );
|
||||
}
|
||||
|
||||
|
||||
/*=== sclTime.c =============================================================*/
|
||||
extern SC_Man * Abc_SclManStart( SC_Lib * pLib, Abc_Ntk_t * pNtk );
|
||||
extern Abc_Obj_t * Abc_SclFindMostCritical( SC_Man * p, int * pfRise );
|
||||
extern Vec_Int_t * Abc_SclCriticalPathFind( SC_Man * p );
|
||||
extern void Abc_SclTimeCone( SC_Man * p, Vec_Int_t * vCone );
|
||||
extern void Abc_SclUpdateLoad( SC_Man * p, Abc_Obj_t * pObj, SC_Cell * pOld, SC_Cell * pNew );
|
||||
extern void Abc_SclCriticalPathPrint( SC_Man * p );
|
||||
|
||||
ABC_NAMESPACE_HEADER_END
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -16,7 +16,10 @@
|
|||
|
||||
***********************************************************************/
|
||||
|
||||
#include "base/abc/abc.h"
|
||||
#include "map/mio/mio.h"
|
||||
#include "sclInt.h"
|
||||
#include "sclMan.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
|
@ -29,6 +32,43 @@ ABC_NAMESPACE_IMPL_START
|
|||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collect TFO of the fanins of the object.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_SclCollectTfo_rec( Abc_Obj_t * pObj, Vec_Int_t * vVisited )
|
||||
{
|
||||
Abc_Obj_t * pNext;
|
||||
int i;
|
||||
if ( Abc_NodeIsTravIdCurrent( pObj ) )
|
||||
return;
|
||||
Abc_NodeSetTravIdCurrent( pObj );
|
||||
Abc_ObjForEachFanout( pObj, pNext, i )
|
||||
Abc_SclCollectTfo_rec( pNext, vVisited );
|
||||
Vec_IntPush( vVisited, Abc_ObjId(pObj) );
|
||||
}
|
||||
Vec_Int_t * Abc_SclCollectTfo( Abc_Ntk_t * p, Abc_Obj_t * pObj )
|
||||
{
|
||||
Vec_Int_t * vVisited;
|
||||
Abc_Obj_t * pFanin;
|
||||
int i;
|
||||
assert( Abc_ObjIsNode(pObj) );
|
||||
vVisited = Vec_IntAlloc( 100 );
|
||||
Abc_NtkIncrementTravId( p );
|
||||
Abc_SclCollectTfo_rec( pObj, vVisited );
|
||||
Abc_ObjForEachFanin( pObj, pFanin, i )
|
||||
if ( Abc_ObjIsNode(pFanin) )
|
||||
Abc_SclCollectTfo_rec( pFanin, vVisited );
|
||||
Vec_IntReverseOrder( vVisited );
|
||||
return vVisited;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
@ -41,8 +81,138 @@ ABC_NAMESPACE_IMPL_START
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_SclSizingPerform( SC_Lib * pLib, void * pNtk )
|
||||
SC_Cell * Abc_SclObjResiable( SC_Man * p, Abc_Obj_t * pObj )
|
||||
{
|
||||
SC_Cell * pOld = Abc_SclObjCell( p, pObj );
|
||||
return pOld->pNext != pOld ? pOld->pNext : NULL;
|
||||
}
|
||||
float Abc_SclSizingGain( SC_Man * p, Abc_Obj_t * pPivot )
|
||||
{
|
||||
double dGain = 0;
|
||||
Vec_Int_t * vCone;
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
assert( Abc_ObjIsNode(pPivot) );
|
||||
vCone = Abc_SclCollectTfo( p->pNtk, pPivot );
|
||||
Abc_SclConeStore( p, vCone );
|
||||
Abc_SclTimeCone( p, vCone );
|
||||
Abc_NtkForEachObjVec( vCone, p->pNtk, pObj, i )
|
||||
if ( Abc_ObjIsCo(pObj) )
|
||||
dGain += Abc_SclObjGain( p, pObj );
|
||||
Abc_SclConeRestore( p, vCone );
|
||||
Vec_IntFree( vCone );
|
||||
return dGain;
|
||||
}
|
||||
Abc_Obj_t * Abc_SclChooseBiggestGain( SC_Man * p, Vec_Int_t * vPath )
|
||||
{
|
||||
SC_Cell * pOld, * pNew;
|
||||
Abc_Obj_t * pPivot = NULL, * pObj;
|
||||
double dGainBest = 0, dGain;
|
||||
int i, gateId;
|
||||
Abc_NtkForEachObjVec( vPath, p->pNtk, pObj, i )
|
||||
{
|
||||
if ( Abc_ObjIsCo(pObj) )
|
||||
continue;
|
||||
pOld = Abc_SclObjCell( p, pObj );
|
||||
pNew = Abc_SclObjResiable( p, pObj );
|
||||
if ( pNew == NULL )
|
||||
continue;
|
||||
printf( "changing %s for %s\n", pOld->name, pNew->name );
|
||||
|
||||
gateId = Vec_IntEntry(p->vGates, Abc_ObjId(pObj));
|
||||
Vec_IntWriteEntry( p->vGates, Abc_ObjId(pObj), Abc_SclCellFind(p->pLib, pNew->name) );
|
||||
|
||||
Abc_SclUpdateLoad( p, pObj, pOld, pNew );
|
||||
dGain = Abc_SclSizingGain( p, pObj );
|
||||
Abc_SclUpdateLoad( p, pObj, pNew, pOld );
|
||||
|
||||
Vec_IntWriteEntry( p->vGates, Abc_ObjId(pObj), Abc_SclCellFind(p->pLib, pOld->name) );
|
||||
assert( gateId == Vec_IntEntry(p->vGates, Abc_ObjId(pObj)) );
|
||||
|
||||
if ( dGainBest < dGain )
|
||||
{
|
||||
dGainBest = dGain;
|
||||
pPivot = pObj;
|
||||
}
|
||||
}
|
||||
return pPivot;
|
||||
}
|
||||
void Abc_SclUpdateNetwork( SC_Man * p, Abc_Obj_t * pObj )
|
||||
{
|
||||
Vec_Int_t * vCone;
|
||||
SC_Cell * pOld, * pNew;
|
||||
// find new gate
|
||||
pOld = Abc_SclObjCell( p, pObj );
|
||||
pNew = Abc_SclObjResiable( p, pObj );
|
||||
assert( pNew != NULL );
|
||||
// update gate
|
||||
Vec_IntWriteEntry( p->vGates, Abc_ObjId(pObj), Abc_SclCellFind(p->pLib, pNew->name) );
|
||||
pObj->pData = Mio_LibraryReadGateByName( (Mio_Library_t *)p->pNtk->pManFunc, pNew->name );
|
||||
Abc_SclUpdateLoad( p, pObj, pOld, pNew );
|
||||
p->SumArea += pNew->area - pOld->area;
|
||||
// update info
|
||||
vCone = Abc_SclCollectTfo( p->pNtk, pObj );
|
||||
Abc_SclTimeCone( p, vCone );
|
||||
Vec_IntFree( vCone );
|
||||
}
|
||||
|
||||
float Abc_SclFindMaxDelay( SC_Man * p )
|
||||
{
|
||||
float fMaxArr = 0;
|
||||
Abc_Obj_t * pObj;
|
||||
SC_Pair * pArr;
|
||||
int i;
|
||||
Abc_NtkForEachCo( p->pNtk, pObj, i )
|
||||
{
|
||||
pArr = Abc_SclObjTime( p, pObj );
|
||||
if ( fMaxArr < pArr->rise ) fMaxArr = pArr->rise;
|
||||
if ( fMaxArr < pArr->fall ) fMaxArr = pArr->fall;
|
||||
}
|
||||
return fMaxArr;
|
||||
}
|
||||
|
||||
void Abc_SclPrintResult( SC_Man * p, int i )
|
||||
{
|
||||
int fRise = 0;
|
||||
Abc_Obj_t * pPivot = Abc_SclFindMostCritical( p, &fRise );
|
||||
printf( "%5d : ", i );
|
||||
printf( "area =%10.2f ", p->SumArea );
|
||||
printf( "delay =%8.2f ps ", Abc_SclObjTimePs(p, pPivot, fRise) );
|
||||
Abc_PrintTime( 1, "time", clock() - p->clkStart );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_SclSizingPerform( SC_Lib * pLib, void * pNt, int nSteps )
|
||||
{
|
||||
SC_Man * p;
|
||||
Abc_Ntk_t * pNtk = (Abc_Ntk_t *)pNt;
|
||||
Vec_Int_t * vPath;
|
||||
Abc_Obj_t * pBest;
|
||||
int i;
|
||||
p = Abc_SclManStart( pLib, pNtk );
|
||||
Abc_SclCriticalPathPrint( p );
|
||||
for ( i = 0; i < nSteps; i++ )
|
||||
{
|
||||
vPath = Abc_SclCriticalPathFind( p );
|
||||
pBest = Abc_SclChooseBiggestGain( p, vPath );
|
||||
Vec_IntFree( vPath );
|
||||
if ( pBest == NULL )
|
||||
break;
|
||||
Abc_SclUpdateNetwork( p, pBest );
|
||||
Abc_SclPrintResult( p, i );
|
||||
}
|
||||
Abc_SclCriticalPathPrint( p );
|
||||
Abc_SclManFree( p );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
#include "base/abc/abc.h"
|
||||
#include "map/mio/mio.h"
|
||||
#include "sclInt.h"
|
||||
#include "sclMan.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
|
@ -27,89 +28,10 @@ ABC_NAMESPACE_IMPL_START
|
|||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct SC_Pair_ SC_Pair;
|
||||
typedef struct SC_Man_ SC_Man;
|
||||
|
||||
struct SC_Pair_
|
||||
{
|
||||
float rise;
|
||||
float fall;
|
||||
};
|
||||
|
||||
struct SC_Man_
|
||||
{
|
||||
SC_Lib * pLib; // library
|
||||
Abc_Ntk_t * pNtk; // network
|
||||
int nObjs; // allocated size
|
||||
Vec_Int_t * vGates; // mapping of objId into gateId
|
||||
SC_Pair * pLoads; // loads for each gate
|
||||
SC_Pair * pArrs; // arrivals for each gate
|
||||
SC_Pair * pSlews; // slews for each gate
|
||||
char * pWireLoadUsed; // name of the used WireLoad model
|
||||
};
|
||||
|
||||
static inline SC_Pair * Abc_SclObjLoad( SC_Man * p, Abc_Obj_t * pObj ) { return p->pLoads + Abc_ObjId(pObj); }
|
||||
static inline SC_Pair * Abc_SclObjArr ( SC_Man * p, Abc_Obj_t * pObj ) { return p->pArrs + Abc_ObjId(pObj); }
|
||||
static inline SC_Pair * Abc_SclObjSlew( SC_Man * p, Abc_Obj_t * pObj ) { return p->pSlews + Abc_ObjId(pObj); }
|
||||
|
||||
static inline SC_Cell * Abc_SclObjCell( SC_Man * p, Abc_Obj_t * pObj ) { return SC_LibCell( p->pLib, Vec_IntEntry(p->vGates, Abc_ObjId(pObj)) ); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Prepares STA manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_SclManFindGates( SC_Man * p )
|
||||
{
|
||||
Abc_Obj_t * pObj;
|
||||
char * pName;
|
||||
int i, gateId;
|
||||
assert( p->vGates == NULL );
|
||||
p->vGates = Vec_IntStartFull( p->nObjs );
|
||||
Abc_NtkForEachNode( p->pNtk, pObj, i )
|
||||
{
|
||||
pName = Mio_GateReadName((Mio_Gate_t *)pObj->pData);
|
||||
gateId = Abc_SclCellFind( p->pLib, pName );
|
||||
assert( gateId >= 0 );
|
||||
Vec_IntWriteEntry( p->vGates, i, gateId );
|
||||
//printf( "Found gate %s\n", pName );
|
||||
}
|
||||
}
|
||||
SC_Man * Abc_SclManAlloc( SC_Lib * pLib, Abc_Ntk_t * pNtk )
|
||||
{
|
||||
SC_Man * p;
|
||||
assert( Abc_NtkHasMapping(pNtk) );
|
||||
p = ABC_CALLOC( SC_Man, 1 );
|
||||
p->pLib = pLib;
|
||||
p->pNtk = pNtk;
|
||||
p->nObjs = Abc_NtkObjNumMax(pNtk);
|
||||
p->pLoads = ABC_CALLOC( SC_Pair, p->nObjs );
|
||||
p->pArrs = ABC_CALLOC( SC_Pair, p->nObjs );
|
||||
p->pSlews = ABC_CALLOC( SC_Pair, p->nObjs );
|
||||
Abc_SclManFindGates( p );
|
||||
return p;
|
||||
}
|
||||
void Abc_SclManFree( SC_Man * p )
|
||||
{
|
||||
Vec_IntFree( p->vGates );
|
||||
ABC_FREE( p->pLoads );
|
||||
ABC_FREE( p->pArrs );
|
||||
ABC_FREE( p->pSlews );
|
||||
ABC_FREE( p );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
@ -130,13 +52,121 @@ float Abc_SclTotalArea( SC_Man * p )
|
|||
Area += Abc_SclObjCell( p, pObj )->area;
|
||||
return Area;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_SclTimeNtkPrint( SC_Man * p )
|
||||
{
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
printf( "Total area = %f.\n", Abc_SclTotalArea( p ) );
|
||||
printf( "WireLoad model = \"%s\".\n", p->pWLoadUsed );
|
||||
Abc_NtkForEachNode( p->pNtk, pObj, i )
|
||||
{
|
||||
printf( "Node %6d : ", Abc_ObjId(pObj) );
|
||||
printf( "TimeR = %f. ", Abc_SclObjTime(p, pObj)->rise );
|
||||
printf( "RimeF = %f. ", Abc_SclObjTime(p, pObj)->fall );
|
||||
printf( "SlewR = %f. ", Abc_SclObjSlew(p, pObj)->rise );
|
||||
printf( "SlewF = %f. ", Abc_SclObjSlew(p, pObj)->fall );
|
||||
printf( "LoadR = %f. ", Abc_SclObjLoad(p, pObj)->rise );
|
||||
printf( "LoadF = %f. ", Abc_SclObjLoad(p, pObj)->fall );
|
||||
printf( "\n" );
|
||||
}
|
||||
}
|
||||
Abc_Obj_t * Abc_SclFindMostCritical( SC_Man * p, int * pfRise )
|
||||
{
|
||||
Abc_Obj_t * pObj, * pPivot = NULL;
|
||||
float fMaxArr = 0;
|
||||
int i;
|
||||
Abc_NtkForEachCo( p->pNtk, pObj, i )
|
||||
{
|
||||
SC_Pair * pArr = Abc_SclObjTime( p, pObj );
|
||||
if ( fMaxArr < pArr->rise ) fMaxArr = pArr->rise, *pfRise = 1, pPivot = pObj;
|
||||
if ( fMaxArr < pArr->fall ) fMaxArr = pArr->fall, *pfRise = 0, pPivot = pObj;
|
||||
}
|
||||
assert( pPivot != NULL );
|
||||
return pPivot;
|
||||
}
|
||||
Abc_Obj_t * Abc_SclFindMostCriticalFanin( SC_Man * p, int * pfRise, Abc_Obj_t * pNode )
|
||||
{
|
||||
Abc_Obj_t * pObj, * pPivot = NULL;
|
||||
float fMaxArr = 0;
|
||||
int i;
|
||||
Abc_ObjForEachFanin( pNode, pObj, i )
|
||||
{
|
||||
SC_Pair * pArr = Abc_SclObjTime( p, pObj );
|
||||
if ( fMaxArr < pArr->rise ) fMaxArr = pArr->rise, *pfRise = 1, pPivot = pObj;
|
||||
if ( fMaxArr < pArr->fall ) fMaxArr = pArr->fall, *pfRise = 0, pPivot = pObj;
|
||||
}
|
||||
return pPivot;
|
||||
}
|
||||
Vec_Int_t * Abc_SclCriticalPathFind( SC_Man * p )
|
||||
{
|
||||
int fRise = 0;
|
||||
Abc_Obj_t * pPivot = Abc_SclFindMostCritical( p, &fRise );
|
||||
Vec_Int_t * vPath = Vec_IntAlloc( 100 );
|
||||
Vec_IntPush( vPath, Abc_ObjId(pPivot) );
|
||||
pPivot = Abc_ObjFanin0(pPivot);
|
||||
while ( pPivot && Abc_ObjIsNode(pPivot) )
|
||||
{
|
||||
Vec_IntPush( vPath, Abc_ObjId(pPivot) );
|
||||
pPivot = Abc_SclFindMostCriticalFanin( p, &fRise, pPivot );
|
||||
}
|
||||
return vPath;
|
||||
}
|
||||
void Abc_SclCriticalPathPrint( SC_Man * p )
|
||||
{
|
||||
int fRise = 0;
|
||||
Abc_Obj_t * pPivot = Abc_SclFindMostCritical( p, &fRise );
|
||||
|
||||
printf( "Total area = %10.2f.\n", Abc_SclTotalArea( p ) );
|
||||
printf( "WireLoad model = \"%s\".\n", p->pWLoadUsed );
|
||||
printf( "Critical delay = %.1f ps\n", Abc_SclObjTimePs(p, pPivot, fRise) );
|
||||
|
||||
printf( "Critical path: \n" );
|
||||
pPivot = Abc_ObjFanin0(pPivot);
|
||||
while ( pPivot && Abc_ObjIsNode(pPivot) )
|
||||
{
|
||||
printf( "%5d : ", Abc_ObjId(pPivot) );
|
||||
printf( "%-10s ", Abc_SclObjCell(p, pPivot)->name );
|
||||
printf( "(%s) ", fRise ? "rise" : "fall" );
|
||||
printf( "delay =%6.1f ps ", Abc_SclObjTimePs(p, pPivot, fRise) );
|
||||
printf( "load =%6.2f ff ", Abc_SclObjLoadFf(p, pPivot, fRise) );
|
||||
printf( "slew =%6.1f ps ", Abc_SclObjSlewPs(p, pPivot, fRise) );
|
||||
printf( "\n" );
|
||||
|
||||
pPivot = Abc_SclFindMostCriticalFanin( p, &fRise, pPivot );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Flt_t * Abc_SclFindWireCaps( SC_Man * p )
|
||||
{
|
||||
Vec_Flt_t * vCaps = NULL;
|
||||
SC_WireLoad * pWL = NULL;
|
||||
int i, Entry, EntryMax;
|
||||
float EntryPrev, EntryCur;
|
||||
p->pWireLoadUsed = NULL;
|
||||
p->pWLoadUsed = NULL;
|
||||
if ( p->pLib->default_wire_load_sel && strlen(p->pLib->default_wire_load_sel) )
|
||||
{
|
||||
float Area;
|
||||
|
|
@ -153,27 +183,27 @@ Vec_Flt_t * Abc_SclFindWireCaps( SC_Man * p )
|
|||
for ( i = 0; i < Vec_FltSize(pWLS->vAreaFrom); i++)
|
||||
if ( Area >= Vec_FltEntry(pWLS->vAreaFrom, i) && Area < Vec_FltEntry(pWLS->vAreaTo, i) )
|
||||
{
|
||||
p->pWireLoadUsed = (char *)Vec_PtrEntry(pWLS->vWireLoadModel, i);
|
||||
p->pWLoadUsed = (char *)Vec_PtrEntry(pWLS->vWireLoadModel, i);
|
||||
break;
|
||||
}
|
||||
if ( i == Vec_FltSize(pWLS->vAreaFrom) )
|
||||
p->pWireLoadUsed = (char *)Vec_PtrEntryLast(pWLS->vWireLoadModel);
|
||||
p->pWLoadUsed = (char *)Vec_PtrEntryLast(pWLS->vWireLoadModel);
|
||||
}
|
||||
else if ( p->pLib->default_wire_load && strlen(p->pLib->default_wire_load) )
|
||||
p->pWireLoadUsed = p->pLib->default_wire_load;
|
||||
p->pWLoadUsed = p->pLib->default_wire_load;
|
||||
else
|
||||
{
|
||||
Abc_Print( 0, "No wire model given.\n" );
|
||||
return NULL;
|
||||
}
|
||||
// Get the actual table and reformat it for 'wire_cap' output:
|
||||
assert( p->pWireLoadUsed != NULL );
|
||||
assert( p->pWLoadUsed != NULL );
|
||||
Vec_PtrForEachEntry( SC_WireLoad *, p->pLib->vWireLoads, pWL, i )
|
||||
if ( !strcmp(pWL->name, p->pWireLoadUsed) )
|
||||
if ( !strcmp(pWL->name, p->pWLoadUsed) )
|
||||
break;
|
||||
if ( i == Vec_PtrSize(p->pLib->vWireLoadSels) )
|
||||
{
|
||||
Abc_Print( -1, "Cannot find wire load model \"%s\".\n", p->pWireLoadUsed );
|
||||
Abc_Print( -1, "Cannot find wire load model \"%s\".\n", p->pWLoadUsed );
|
||||
exit(1);
|
||||
}
|
||||
// find the biggest fanout
|
||||
|
|
@ -195,20 +225,9 @@ Vec_Flt_t * Abc_SclFindWireCaps( SC_Man * p )
|
|||
}
|
||||
return vCaps;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_SclComputeLoad( SC_Man * p, Vec_Flt_t * vWireCaps )
|
||||
void Abc_SclComputeLoad( SC_Man * p )
|
||||
{
|
||||
Vec_Flt_t * vWireCaps;
|
||||
Abc_Obj_t * pObj, * pFanin;
|
||||
int i, k;
|
||||
Abc_NtkForEachNode( p->pNtk, pObj, i )
|
||||
|
|
@ -216,12 +235,13 @@ void Abc_SclComputeLoad( SC_Man * p, Vec_Flt_t * vWireCaps )
|
|||
SC_Cell * pCell = Abc_SclObjCell( p, pObj );
|
||||
Abc_ObjForEachFanin( pObj, pFanin, k )
|
||||
{
|
||||
SC_Pin * pPin = SC_CellPin( pCell, k );
|
||||
SC_Pair * pLoad = Abc_SclObjLoad( p, pFanin );
|
||||
SC_Pin * pPin = SC_CellPin( pCell, k );
|
||||
pLoad->rise += pPin->rise_cap;
|
||||
pLoad->fall += pPin->fall_cap;
|
||||
}
|
||||
}
|
||||
vWireCaps = Abc_SclFindWireCaps( p );
|
||||
if ( vWireCaps )
|
||||
{
|
||||
Abc_NtkForEachNode( p->pNtk, pObj, i )
|
||||
|
|
@ -232,75 +252,19 @@ void Abc_SclComputeLoad( SC_Man * p, Vec_Flt_t * vWireCaps )
|
|||
pLoad->fall += Vec_FltEntry(vWireCaps, k);
|
||||
}
|
||||
}
|
||||
Vec_FltFree( vWireCaps );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Obj_t * Abc_SclFindMostCritical( SC_Man * p, int * pfRise )
|
||||
void Abc_SclUpdateLoad( SC_Man * p, Abc_Obj_t * pObj, SC_Cell * pOld, SC_Cell * pNew )
|
||||
{
|
||||
Abc_Obj_t * pObj, * pPivot = NULL;
|
||||
float fMaxArr = 0;
|
||||
int i;
|
||||
Abc_NtkForEachNode( p->pNtk, pObj, i )
|
||||
Abc_Obj_t * pFanin;
|
||||
int k;
|
||||
Abc_ObjForEachFanin( pObj, pFanin, k )
|
||||
{
|
||||
SC_Pair * pArr = Abc_SclObjArr( p, pObj );
|
||||
if ( fMaxArr < pArr->rise ) fMaxArr = pArr->rise, *pfRise = 1, pPivot = pObj;
|
||||
if ( fMaxArr < pArr->fall ) fMaxArr = pArr->fall, *pfRise = 0, pPivot = pObj;
|
||||
}
|
||||
assert( pPivot != NULL );
|
||||
return pPivot;
|
||||
}
|
||||
Abc_Obj_t * Abc_SclFindMostCriticalFanin( SC_Man * p, int * pfRise, Abc_Obj_t * pNode )
|
||||
{
|
||||
Abc_Obj_t * pObj, * pPivot = NULL;
|
||||
float fMaxArr = 0;
|
||||
int i;
|
||||
Abc_ObjForEachFanin( pNode, pObj, i )
|
||||
{
|
||||
SC_Pair * pArr = Abc_SclObjArr( p, pObj );
|
||||
if ( fMaxArr < pArr->rise ) fMaxArr = pArr->rise, *pfRise = 1, pPivot = pObj;
|
||||
if ( fMaxArr < pArr->fall ) fMaxArr = pArr->fall, *pfRise = 0, pPivot = pObj;
|
||||
}
|
||||
assert( pPivot != NULL );
|
||||
return pPivot;
|
||||
}
|
||||
void Abc_SclCriticalPathPrint( SC_Man * p, Vec_Ptr_t * vNodes )
|
||||
{
|
||||
}
|
||||
void Abc_SclTimeNtkPrint( SC_Man * p )
|
||||
{
|
||||
/*
|
||||
int fRise = 0;
|
||||
Abc_Obj_t * pPivot = Abc_SclFindMostCritical( p, &fRise, vNodes );
|
||||
printf( "Critical delay: ObjId = %d. ", Abc_ObjId(pPivot) );
|
||||
printf( "Rise = %f. ", Abc_SclObjArr(p, pPivot)->rise );
|
||||
printf( "Fall = %f. ", Abc_SclObjArr(p, pPivot)->fall );
|
||||
printf( "\n" );
|
||||
*/
|
||||
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
printf( "WireLoad model = \"%s\".\n", p->pWireLoadUsed );
|
||||
printf( "Area = %f.\n", Abc_SclTotalArea( p ) );
|
||||
Abc_NtkForEachNode( p->pNtk, pObj, i )
|
||||
{
|
||||
printf( "Node %6d : ", Abc_ObjId(pObj) );
|
||||
printf( "TimeR = %f. ", Abc_SclObjArr(p, pObj)->rise );
|
||||
printf( "RimeF = %f. ", Abc_SclObjArr(p, pObj)->fall );
|
||||
printf( "SlewR = %f. ", Abc_SclObjSlew(p, pObj)->rise );
|
||||
printf( "SlewF = %f. ", Abc_SclObjSlew(p, pObj)->fall );
|
||||
printf( "LoadR = %f. ", Abc_SclObjLoad(p, pObj)->rise );
|
||||
printf( "LoadF = %f. ", Abc_SclObjLoad(p, pObj)->fall );
|
||||
printf( "\n" );
|
||||
SC_Pair * pLoad = Abc_SclObjLoad( p, pFanin );
|
||||
SC_Pin * pPinOld = SC_CellPin( pOld, k );
|
||||
SC_Pin * pPinNew = SC_CellPin( pNew, k );
|
||||
pLoad->rise += pPinNew->rise_cap - pPinOld->rise_cap;
|
||||
pLoad->fall += pPinNew->fall_cap - pPinOld->fall_cap;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -346,12 +310,12 @@ static inline float Abc_SclLookup( SC_Surface * p, float slew, float load )
|
|||
|
||||
return p0 + sfrac * (p1 - p0); // <<== multiply result with K factor here
|
||||
}
|
||||
void Abc_SclTimeGate( SC_Man * p, SC_Timing * pTime, Abc_Obj_t * pObj, Abc_Obj_t * pFanin )
|
||||
static inline void Abc_SclTimeGate( SC_Man * p, SC_Timing * pTime, Abc_Obj_t * pObj, Abc_Obj_t * pFanin )
|
||||
{
|
||||
SC_Pair * pArrIn = Abc_SclObjArr ( p, pFanin );
|
||||
SC_Pair * pArrIn = Abc_SclObjTime ( p, pFanin );
|
||||
SC_Pair * pSlewIn = Abc_SclObjSlew( p, pFanin );
|
||||
SC_Pair * pLoad = Abc_SclObjLoad( p, pObj );
|
||||
SC_Pair * pArrOut = Abc_SclObjArr ( p, pObj ); // modified
|
||||
SC_Pair * pArrOut = Abc_SclObjTime ( p, pObj ); // modified
|
||||
SC_Pair * pSlewOut = Abc_SclObjSlew( p, pObj ); // modified
|
||||
|
||||
if (pTime->tsense == sc_ts_Pos || pTime->tsense == sc_ts_Non)
|
||||
|
|
@ -369,36 +333,80 @@ void Abc_SclTimeGate( SC_Man * p, SC_Timing * pTime, Abc_Obj_t * pObj, Abc_Obj_t
|
|||
pSlewOut->fall = Abc_MaxFloat( pSlewOut->fall, Abc_SclLookup(pTime->pFallTrans, pSlewIn->rise, pLoad->fall) );
|
||||
}
|
||||
}
|
||||
void Abc_SclTimeObj( SC_Man * p, Abc_Obj_t * pObj )
|
||||
{
|
||||
SC_Timings * pRTime;
|
||||
SC_Timing * pTime;
|
||||
SC_Pin * pPin;
|
||||
SC_Cell * pCell;
|
||||
int k;
|
||||
if ( Abc_ObjIsCo(pObj) )
|
||||
{
|
||||
Abc_SclObjDupFanin( p, pObj );
|
||||
return;
|
||||
}
|
||||
assert( Abc_ObjIsNode(pObj) );
|
||||
// get the library cell
|
||||
pCell = Abc_SclObjCell( p, pObj );
|
||||
// get the output pin
|
||||
assert( pCell->n_outputs == 1 );
|
||||
pPin = SC_CellPin( pCell, pCell->n_inputs );
|
||||
// compute timing using each fanin
|
||||
assert( Vec_PtrSize(pPin->vRTimings) == pCell->n_inputs );
|
||||
Vec_PtrForEachEntry( SC_Timings *, pPin->vRTimings, pRTime, k )
|
||||
{
|
||||
assert( Vec_PtrSize(pRTime->vTimings) == 1 );
|
||||
pTime = (SC_Timing *)Vec_PtrEntry( pRTime->vTimings, 0 );
|
||||
Abc_SclTimeGate( p, pTime, pObj, Abc_ObjFanin(pObj, k) );
|
||||
}
|
||||
}
|
||||
void Abc_SclTimeNtk( SC_Man * p )
|
||||
{
|
||||
Vec_Flt_t * vWireCaps;
|
||||
Abc_Obj_t * pObj;
|
||||
int i, k;
|
||||
vWireCaps = Abc_SclFindWireCaps( p );
|
||||
Abc_SclComputeLoad( p, vWireCaps );
|
||||
int i;
|
||||
Abc_NtkForEachNode( p->pNtk, pObj, i )
|
||||
Abc_SclTimeObj( p, pObj );
|
||||
Abc_NtkForEachCo( p->pNtk, pObj, i )
|
||||
Abc_SclObjDupFanin( p, pObj );
|
||||
}
|
||||
void Abc_SclTimeCone( SC_Man * p, Vec_Int_t * vCone )
|
||||
{
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
Abc_NtkForEachObjVec( vCone, p->pNtk, pObj, i )
|
||||
{
|
||||
SC_Timings * pRTime;
|
||||
SC_Timing * pTime;
|
||||
SC_Pin * pPin;
|
||||
// get the library cell
|
||||
SC_Cell * pCell = Abc_SclObjCell( p, pObj );
|
||||
// get the output pin
|
||||
assert( pCell->n_outputs == 1 );
|
||||
pPin = SC_CellPin( pCell, pCell->n_inputs );
|
||||
// compute timing using each fanin
|
||||
assert( Vec_PtrSize(pPin->vRTimings) == pCell->n_inputs );
|
||||
Vec_PtrForEachEntry( SC_Timings *, pPin->vRTimings, pRTime, k )
|
||||
{
|
||||
assert( Vec_PtrSize(pRTime->vTimings) == 1 );
|
||||
pTime = (SC_Timing *)Vec_PtrEntry( pRTime->vTimings, 0 );
|
||||
Abc_SclTimeGate( p, pTime, pObj, Abc_ObjFanin(pObj, k) );
|
||||
}
|
||||
if ( Abc_ObjIsNode(pObj) )
|
||||
printf( " Updating node with gate %s\n", Abc_SclObjCell(p, pObj)->name );
|
||||
|
||||
printf( " before %6.1f ps ", Abc_SclObjTimePs(p, pObj, 0) );
|
||||
Abc_SclTimeObj( p, pObj );
|
||||
printf( "after %6.1f ps\n", Abc_SclObjTimePs(p, pObj, 0) );
|
||||
}
|
||||
Abc_SclTimeNtkPrint( p );
|
||||
Vec_FltFree( vWireCaps );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
SC_Man * Abc_SclManStart( SC_Lib * pLib, Abc_Ntk_t * pNtk )
|
||||
{
|
||||
extern Vec_Int_t * Abc_SclManFindGates( SC_Lib * pLib, Abc_Ntk_t * p );
|
||||
// prepare timing manager
|
||||
SC_Man * p = Abc_SclManAlloc( pLib, pNtk );
|
||||
assert( p->vGates == NULL );
|
||||
p->vGates = Abc_SclManFindGates( pLib, pNtk );
|
||||
p->SumArea = Abc_SclTotalArea( p );
|
||||
Abc_SclComputeLoad( p );
|
||||
Abc_SclTimeNtk( p );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
@ -414,8 +422,8 @@ void Abc_SclTimeNtk( SC_Man * p )
|
|||
void Abc_SclTimePerform( SC_Lib * pLib, void * pNtk )
|
||||
{
|
||||
SC_Man * p;
|
||||
p = Abc_SclManAlloc( pLib, (Abc_Ntk_t *)pNtk );
|
||||
Abc_SclTimeNtk( p );
|
||||
p = Abc_SclManStart( pLib, (Abc_Ntk_t *)pNtk );
|
||||
Abc_SclCriticalPathPrint( p );
|
||||
Abc_SclManFree( p );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
***********************************************************************/
|
||||
|
||||
#include "base/abc/abc.h"
|
||||
#include "map/mio/mio.h"
|
||||
#include "sclInt.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
|
@ -29,7 +31,6 @@ ABC_NAMESPACE_IMPL_START
|
|||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Reading library from file.]
|
||||
|
|
@ -177,6 +178,34 @@ void Abc_SclPrintCells( SC_Lib * p )
|
|||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Abc_SclManFindGates( SC_Lib * pLib, Abc_Ntk_t * p )
|
||||
{
|
||||
Vec_Int_t * vVec;
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
vVec = Vec_IntStartFull( Abc_NtkObjNumMax(p) );
|
||||
Abc_NtkForEachNode( p, pObj, i )
|
||||
{
|
||||
char * pName = Mio_GateReadName((Mio_Gate_t *)pObj->pData);
|
||||
int gateId = Abc_SclCellFind( pLib, pName );
|
||||
assert( gateId >= 0 );
|
||||
Vec_IntWriteEntry( vVec, i, gateId );
|
||||
//printf( "Found gate %s\n", pName );
|
||||
}
|
||||
return vVec;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
|
|
|
|||
Loading…
Reference in New Issue