Commit bebd7ee6 by Alan Mishchenko

New package to read/write a subset of Liberty for STA.

parent 5ff49be9
......@@ -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,12 +338,13 @@ 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, "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"
......@@ -179,6 +180,9 @@ static inline SC_Cell * SC_LibCell( SC_Lib * p, int i ) { return (SC_Cell *)V
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 )
#define SC_CellForEachPinIn( p, pPin, i ) Vec_PtrForEachEntryStop( SC_Pin *, pCell->vPins, pPin, i, pCell->n_inputs )
......
/**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,154 @@ 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*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
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*************************************************************
......@@ -41,8 +192,27 @@ ABC_NAMESPACE_IMPL_START
SeeAlso []
***********************************************************************/
void Abc_SclSizingPerform( SC_Lib * pLib, void * pNtk )
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,40 +28,13 @@ 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.]
Synopsis []
Description []
......@@ -69,45 +43,110 @@ static inline SC_Cell * Abc_SclObjCell( SC_Man * p, Abc_Obj_t * pObj ) { return
SeeAlso []
***********************************************************************/
void Abc_SclManFindGates( SC_Man * p )
float Abc_SclTotalArea( SC_Man * p )
{
double Area = 0;
Abc_Obj_t * pObj;
char * pName;
int i, gateId;
assert( p->vGates == NULL );
p->vGates = Vec_IntStartFull( p->nObjs );
int i;
Abc_NtkForEachNode( p->pNtk, pObj, i )
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 )
{
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 );
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" );
}
}
SC_Man * Abc_SclManAlloc( SC_Lib * pLib, Abc_Ntk_t * pNtk )
Abc_Obj_t * Abc_SclFindMostCritical( SC_Man * p, int * pfRise )
{
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;
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;
}
void Abc_SclManFree( SC_Man * p )
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 )
{
Vec_IntFree( p->vGates );
ABC_FREE( p->pLoads );
ABC_FREE( p->pArrs );
ABC_FREE( p->pSlews );
ABC_FREE( 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*************************************************************
......@@ -121,22 +160,13 @@ void Abc_SclManFree( SC_Man * p )
SeeAlso []
***********************************************************************/
float Abc_SclTotalArea( SC_Man * p )
{
double Area = 0;
Abc_Obj_t * pObj;
int i;
Abc_NtkForEachNode( p->pNtk, pObj, i )
Area += Abc_SclObjCell( p, pObj )->area;
return Area;
}
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 )
{
Abc_Obj_t * pObj, * pPivot = NULL;
float fMaxArr = 0;
int i;
Abc_NtkForEachNode( p->pNtk, 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;
}
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 )
void Abc_SclUpdateLoad( SC_Man * p, Abc_Obj_t * pObj, SC_Cell * pOld, SC_Cell * pNew )
{
/*
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 )
Abc_Obj_t * pFanin;
int k;
Abc_ObjForEachFanin( pObj, pFanin, k )
{
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,20 +333,21 @@ 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_SclTimeNtk( SC_Man * p )
void Abc_SclTimeObj( SC_Man * p, Abc_Obj_t * pObj )
{
Vec_Flt_t * vWireCaps;
Abc_Obj_t * pObj;
int i, k;
vWireCaps = Abc_SclFindWireCaps( p );
Abc_SclComputeLoad( p, vWireCaps );
Abc_NtkForEachNode( p->pNtk, pObj, i )
{
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
SC_Cell * pCell = Abc_SclObjCell( p, pObj );
pCell = Abc_SclObjCell( p, pObj );
// get the output pin
assert( pCell->n_outputs == 1 );
pPin = SC_CellPin( pCell, pCell->n_inputs );
......@@ -394,11 +359,54 @@ void Abc_SclTimeNtk( SC_Man * p )
pTime = (SC_Timing *)Vec_PtrEntry( pRTime->vTimings, 0 );
Abc_SclTimeGate( p, pTime, pObj, Abc_ObjFanin(pObj, k) );
}
}
void Abc_SclTimeNtk( SC_Man * p )
{
Abc_Obj_t * pObj;
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 )
{
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 ///
......
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