summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2012-08-29 00:48:36 -0700
committerAlan Mishchenko <alanmi@berkeley.edu>2012-08-29 00:48:36 -0700
commitbebd7ee6cb49f4876a7411e2986c12d4e72ff06a (patch)
treeaab595e9063be03365b396668c20cf0c505b9ecd
parent5ff49be9931a7be3037812230f5d9eb085f59593 (diff)
downloadabc-bebd7ee6cb49f4876a7411e2986c12d4e72ff06a.tar.gz
abc-bebd7ee6cb49f4876a7411e2986c12d4e72ff06a.tar.bz2
abc-bebd7ee6cb49f4876a7411e2986c12d4e72ff06a.zip
New package to read/write a subset of Liberty for STA.
-rw-r--r--src/map/mio/mioRead.c40
-rw-r--r--src/map/scl/scl.c39
-rw-r--r--src/map/scl/scl.h6
-rw-r--r--src/map/scl/sclFile.c8
-rw-r--r--src/map/scl/sclInt.h10
-rw-r--r--src/map/scl/sclMan.h181
-rw-r--r--src/map/scl/sclSize.c172
-rw-r--r--src/map/scl/sclTime.c366
-rw-r--r--src/map/scl/sclUtil.c31
9 files changed, 626 insertions, 227 deletions
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 <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;
}
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 <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 )
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 ///