From bebd7ee6cb49f4876a7411e2986c12d4e72ff06a Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 29 Aug 2012 00:48:36 -0700 Subject: New package to read/write a subset of Liberty for STA. --- src/map/mio/mioRead.c | 40 +++--- src/map/scl/scl.c | 39 ++++-- src/map/scl/scl.h | 6 +- src/map/scl/sclFile.c | 8 +- src/map/scl/sclInt.h | 10 +- src/map/scl/sclMan.h | 181 +++++++++++++++++++++++++ src/map/scl/sclSize.c | 172 +++++++++++++++++++++++- src/map/scl/sclTime.c | 366 ++++++++++++++++++++++++++------------------------ src/map/scl/sclUtil.c | 31 ++++- 9 files changed, 626 insertions(+), 227 deletions(-) create mode 100644 src/map/scl/sclMan.h diff --git a/src/map/mio/mioRead.c b/src/map/mio/mioRead.c index ea755b47..e79baeee 100644 --- a/src/map/mio/mioRead.c +++ b/src/map/mio/mioRead.c @@ -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" ); diff --git a/src/map/scl/scl.c b/src/map/scl/scl.c index 7b18bb12..91aaac5e 100644 --- a/src/map/scl/scl.c +++ b/src/map/scl/scl.c @@ -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 : 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 : 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 : 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; } diff --git a/src/map/scl/scl.h b/src/map/scl/scl.h index 660bfe1f..c87fd42b 100644 --- a/src/map/scl/scl.h +++ b/src/map/scl/scl.h @@ -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 diff --git a/src/map/scl/sclFile.c b/src/map/scl/sclFile.c index 96092e2e..71e06e28 100644 --- a/src/map/scl/sclFile.c +++ b/src/map/scl/sclFile.c @@ -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 ); } diff --git a/src/map/scl/sclInt.h b/src/map/scl/sclInt.h index b9a78f75..034308b5 100644 --- a/src/map/scl/sclInt.h +++ b/src/map/scl/sclInt.h @@ -28,6 +28,7 @@ #include #include #include +#include #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 ) diff --git a/src/map/scl/sclMan.h b/src/map/scl/sclMan.h new file mode 100644 index 00000000..6dd24ac1 --- /dev/null +++ b/src/map/scl/sclMan.h @@ -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 /// +//////////////////////////////////////////////////////////////////////// diff --git a/src/map/scl/sclSize.c b/src/map/scl/sclSize.c index 850a2501..4b7ef595 100644 --- a/src/map/scl/sclSize.c +++ b/src/map/scl/sclSize.c @@ -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 ); } diff --git a/src/map/scl/sclTime.c b/src/map/scl/sclTime.c index b78d1b23..55ff7efb 100644 --- a/src/map/scl/sclTime.c +++ b/src/map/scl/sclTime.c @@ -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 ) { - Vec_IntFree( p->vGates ); - ABC_FREE( p->pLoads ); - ABC_FREE( p->pArrs ); - ABC_FREE( p->pSlews ); - ABC_FREE( p ); + 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************************************************************* @@ -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_SclUpdateLoad( SC_Man * p, Abc_Obj_t * pObj, SC_Cell * pOld, SC_Cell * pNew ) { -} -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 ) + 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,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 ); } diff --git a/src/map/scl/sclUtil.c b/src/map/scl/sclUtil.c index 19f6ed58..d1eb2869 100644 --- a/src/map/scl/sclUtil.c +++ b/src/map/scl/sclUtil.c @@ -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 /// -- cgit v1.2.3