summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2013-08-08 18:23:00 -0700
committerAlan Mishchenko <alanmi@berkeley.edu>2013-08-08 18:23:00 -0700
commit881b2ec46f0519cbab41ba51245b3de949fdbee9 (patch)
treefaa822cf70c81f4d55c1d36fb5335cc396e4922a
parent655dc4e727e2c4e74cc511f343007cee5b8e35b6 (diff)
downloadabc-881b2ec46f0519cbab41ba51245b3de949fdbee9.tar.gz
abc-881b2ec46f0519cbab41ba51245b3de949fdbee9.tar.bz2
abc-881b2ec46f0519cbab41ba51245b3de949fdbee9.zip
Integrated buffering and sizing.
-rw-r--r--abclib.dsp4
-rw-r--r--src/base/abc/abc.h3
-rw-r--r--src/base/abc/abcNtk.c2
-rw-r--r--src/map/scl/module.make1
-rw-r--r--src/map/scl/scl.c104
-rw-r--r--src/map/scl/sclBufSize.c376
-rw-r--r--src/map/scl/sclBuffer.c15
-rw-r--r--src/map/scl/sclDnsize.c23
-rw-r--r--src/map/scl/sclLib.c50
-rw-r--r--src/map/scl/sclLib.h37
-rw-r--r--src/map/scl/sclLoad.c6
-rw-r--r--src/map/scl/sclSize.c32
-rw-r--r--src/map/scl/sclSize.h26
-rw-r--r--src/map/scl/sclUpsize.c44
-rw-r--r--src/map/scl/sclUtil.c68
-rw-r--r--src/misc/vec/vecFlt.h5
16 files changed, 697 insertions, 99 deletions
diff --git a/abclib.dsp b/abclib.dsp
index 78b90961..b0c8616b 100644
--- a/abclib.dsp
+++ b/abclib.dsp
@@ -2459,6 +2459,10 @@ SOURCE=.\src\map\scl\sclBuffer.c
# End Source File
# Begin Source File
+SOURCE=.\src\map\scl\sclBufSize.c
+# End Source File
+# Begin Source File
+
SOURCE=.\src\map\scl\sclDnsize.c
# End Source File
# Begin Source File
diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h
index d5f55b64..b0bae148 100644
--- a/src/base/abc/abc.h
+++ b/src/base/abc/abc.h
@@ -204,6 +204,9 @@ struct Abc_Ntk_t_
void * pExcare; // the EXDC network (if given)
void * pData; // misc
Abc_Ntk_t * pCopy; // copy of this network
+ void * pBSMan; // application manager
+ void * pSCLib; // SC library
+ Vec_Int_t * vGates; // SC library gates
Vec_Int_t * vPhases; // fanins phases in the mapped netlist
char * pWLoadUsed; // wire load model used
float * pLutTimes; // arrivals/requireds/slacks using LUT-delay model
diff --git a/src/base/abc/abcNtk.c b/src/base/abc/abcNtk.c
index 39a3c9af..5631902b 100644
--- a/src/base/abc/abcNtk.c
+++ b/src/base/abc/abcNtk.c
@@ -1351,6 +1351,8 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk )
//printf( "deleting attr\n" );
Vec_AttFree( (Vec_Att_t *)pAttrMan, 1 );
}
+ assert( pNtk->pSCLib == NULL );
+ Vec_IntFreeP( &pNtk->vGates );
Vec_PtrFree( pNtk->vAttrs );
ABC_FREE( pNtk->pWLoadUsed );
ABC_FREE( pNtk->pName );
diff --git a/src/map/scl/module.make b/src/map/scl/module.make
index 6063a3de..ff15f1b6 100644
--- a/src/map/scl/module.make
+++ b/src/map/scl/module.make
@@ -1,5 +1,6 @@
SRC += src/map/scl/scl.c \
src/map/scl/sclBuffer.c \
+ src/map/scl/sclBufSize.c \
src/map/scl/sclDnsize.c \
src/map/scl/sclLib.c \
src/map/scl/sclLoad.c \
diff --git a/src/map/scl/scl.c b/src/map/scl/scl.c
index 1e47dba3..aa93136a 100644
--- a/src/map/scl/scl.c
+++ b/src/map/scl/scl.c
@@ -36,6 +36,7 @@ static int Scl_CommandPrintGS ( Abc_Frame_t * pAbc, int argc, char **argv );
static int Scl_CommandStime ( Abc_Frame_t * pAbc, int argc, char **argv );
static int Scl_CommandTopo ( Abc_Frame_t * pAbc, int argc, char **argv );
static int Scl_CommandBuffer ( Abc_Frame_t * pAbc, int argc, char **argv );
+static int Scl_CommandBufSize ( Abc_Frame_t * pAbc, int argc, char **argv );
static int Scl_CommandUnBuffer( Abc_Frame_t * pAbc, int argc, char **argv );
static int Scl_CommandMinsize ( Abc_Frame_t * pAbc, int argc, char **argv );
static int Scl_CommandMaxsize ( Abc_Frame_t * pAbc, int argc, char **argv );
@@ -69,6 +70,7 @@ void Scl_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "SCL mapping", "stime", Scl_CommandStime, 0 );
Cmd_CommandAdd( pAbc, "SCL mapping", "topo", Scl_CommandTopo, 1 );
Cmd_CommandAdd( pAbc, "SCL mapping", "buffer", Scl_CommandBuffer, 1 );
+ Cmd_CommandAdd( pAbc, "SCL mapping", "bufsize", Scl_CommandBufSize, 1 );
Cmd_CommandAdd( pAbc, "SCL mapping", "unbuffer", Scl_CommandUnBuffer, 1 );
Cmd_CommandAdd( pAbc, "SCL mapping", "minsize", Scl_CommandMinsize, 1 );
Cmd_CommandAdd( pAbc, "SCL mapping", "maxsize", Scl_CommandMaxsize, 1 );
@@ -701,6 +703,108 @@ usage:
SeeAlso []
***********************************************************************/
+int Scl_CommandBufSize( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
+ Abc_Ntk_t * pNtkRes;
+ int c, GainRatio, nDegree, fBufPis, fAddBufs, fVerbose;
+ GainRatio = 200;
+ nDegree = 4;
+ fAddBufs = 0;
+ fBufPis = 0;
+ fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "GNbpvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'G':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-G\" should be followed by a positive integer.\n" );
+ goto usage;
+ }
+ GainRatio = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( GainRatio < 0 )
+ goto usage;
+ break;
+ case 'N':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-N\" should be followed by a positive integer.\n" );
+ goto usage;
+ }
+ nDegree = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nDegree < 0 )
+ goto usage;
+ break;
+ case 'b':
+ fAddBufs ^= 1;
+ break;
+ case 'p':
+ fBufPis ^= 1;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ Abc_Print( -1, "Empty network.\n" );
+ return 1;
+ }
+ if ( !Abc_NtkIsLogic(pNtk) )
+ {
+ Abc_Print( -1, "This command can only be applied to a logic network.\n" );
+ return 1;
+ }
+ if ( !fAddBufs && pNtk->vPhases == NULL )
+ {
+ Abc_Print( -1, "Fanin phase information is not avaiable.\n" );
+ return 1;
+ }
+ // modify the current network
+ pNtkRes = Abc_SclBufSizePerform( pNtk, (SC_Lib *)pAbc->pLibScl, GainRatio, nDegree, fAddBufs, fBufPis, fVerbose );
+ if ( pNtkRes == NULL )
+ {
+ Abc_Print( -1, "The command has failed.\n" );
+ return 1;
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+
+usage:
+ fprintf( pAbc->Err, "usage: bufsize [-GM num] [-bpvh]\n" );
+ fprintf( pAbc->Err, "\t performs buffering and sizing and mapped network\n" );
+ fprintf( pAbc->Err, "\t-G <num> : target gain percentage [default = %d]\n", GainRatio );
+ fprintf( pAbc->Err, "\t-M <num> : the maximum fanout degree [default = %d]\n", nDegree );
+ fprintf( pAbc->Err, "\t-b : toggle using buffers instead of inverters [default = %s]\n", fAddBufs? "yes": "no" );
+ fprintf( pAbc->Err, "\t-p : toggle buffering primary inputs [default = %s]\n", fBufPis? "yes": "no" );
+ fprintf( pAbc->Err, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
+ fprintf( pAbc->Err, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
int Scl_CommandUnBuffer( Abc_Frame_t * pAbc, int argc, char **argv )
{
Abc_Ntk_t * pNtkRes, * pNtk = Abc_FrameReadNtk(pAbc);
diff --git a/src/map/scl/sclBufSize.c b/src/map/scl/sclBufSize.c
new file mode 100644
index 00000000..229b387a
--- /dev/null
+++ b/src/map/scl/sclBufSize.c
@@ -0,0 +1,376 @@
+/**CFile****************************************************************
+
+ FileName [sclBufSize.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Standard-cell library representation.]
+
+ Synopsis [Buffering and sizing combined.]
+
+ Author [Alan Mishchenko, Niklas Een]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - August 24, 2012.]
+
+ Revision [$Id: sclBufSize.c,v 1.0 2012/08/24 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sclSize.h"
+#include "map/mio/mio.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Bus_Man_t_ Bus_Man_t;
+struct Bus_Man_t_
+{
+ // parameters
+ float Gain; // target gain
+ int nDegree; // max branching factor
+ int fBufPis; // use CI buffering
+ int fVerbose; // verbose
+ // user data
+ Abc_Ntk_t * pNtk; // user's network
+ // library
+ SC_Lib * pLib; // cell library
+ SC_Cell * pInv; // base interter (largest/average/???)
+ // internal
+ Vec_Flt_t * vCins; // input cap for fanouts
+ Vec_Flt_t * vLoads; // loads for all nodes
+ Vec_Flt_t * vDepts; // departure times
+};
+
+
+static inline Bus_Man_t * Bus_SclObjMan( Abc_Obj_t * p ) { return (Bus_Man_t *)p->pNtk->pBSMan; }
+static inline float Bus_SclObjCin( Abc_Obj_t * p ) { return Vec_FltEntry( Bus_SclObjMan(p)->vCins, Abc_ObjId(p) ); }
+static inline void Bus_SclObjSetCin( Abc_Obj_t * p, float load ) { Vec_FltWriteEntry( Bus_SclObjMan(p)->vCins, Abc_ObjId(p), load ); }
+static inline float Bus_SclObjLoad( Abc_Obj_t * p ) { return Vec_FltEntry( Bus_SclObjMan(p)->vLoads, Abc_ObjId(p) ); }
+static inline void Bus_SclObjSetLoad( Abc_Obj_t * p, float load ) { Vec_FltWriteEntry( Bus_SclObjMan(p)->vLoads, Abc_ObjId(p), load ); }
+static inline float Bus_SclObjDept( Abc_Obj_t * p ) { return Vec_FltEntry( Bus_SclObjMan(p)->vDepts, Abc_ObjId(p) ); }
+static inline void Bus_SclObjUpdateDept( Abc_Obj_t * p, float dept ) { float *q = Vec_FltEntryP( Bus_SclObjMan(p)->vDepts, Abc_ObjId(p) ); if (*q < dept) *q = dept; }
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Bus_Man_t * Bus_ManStart( Abc_Ntk_t * pNtk, SC_Lib * pLib, int GainRatio, int nDegree, int fBufPis, int fVerbose )
+{
+ Bus_Man_t * p;
+ p = ABC_CALLOC( Bus_Man_t, 1 );
+ p->Gain = 0.01 * GainRatio;
+ p->nDegree = nDegree;
+ p->fBufPis = fBufPis;
+ p->fVerbose = fVerbose;
+ p->pNtk = pNtk;
+ p->pLib = pLib;
+ p->pInv = Abc_SclFindInvertor(pLib)->pAve;
+ p->vCins = Vec_FltStart( 2*Abc_NtkObjNumMax(pNtk) );
+ p->vLoads = Vec_FltStart( 2*Abc_NtkObjNumMax(pNtk) );
+ p->vDepts = Vec_FltStart( 2*Abc_NtkObjNumMax(pNtk) );
+ pNtk->pBSMan = p;
+ return p;
+}
+void Bus_ManStop( Bus_Man_t * p )
+{
+ Vec_FltFree( p->vCins );
+ Vec_FltFree( p->vLoads );
+ Vec_FltFree( p->vDepts );
+ ABC_FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Bus_ManReadInOutLoads( Bus_Man_t * p )
+{
+ Abc_Time_t * pTime;
+ Abc_Obj_t * pObj;
+ int i;
+ // read input load
+ pTime = Abc_NtkReadDefaultInputDrive( p->pNtk );
+ if ( Abc_MaxFloat(pTime->Rise, pTime->Fall) != 0 )
+ {
+ printf( "Default input drive strength is specified (%.2f ff; %.2f ff).\n", pTime->Rise, pTime->Fall );
+ Abc_NtkForEachPi( p->pNtk, pObj, i )
+ Vec_FltWriteEntry( p->vLoads, Abc_ObjId(pObj), 0.5 * SC_LibCapFromFf(p->pLib, pTime->Rise) + 0.5 * SC_LibCapFromFf(p->pLib, pTime->Fall) );
+ }
+ if ( Abc_NodeReadInputDrive(p->pNtk, 0) != NULL )
+ {
+ printf( "Input drive strengths for some primary inputs are specified.\n" );
+ Abc_NtkForEachPi( p->pNtk, pObj, i )
+ {
+ pTime = Abc_NodeReadInputDrive(p->pNtk, i);
+ Vec_FltWriteEntry( p->vLoads, Abc_ObjId(pObj), 0.5 * SC_LibCapFromFf(p->pLib, pTime->Rise) + 0.5 * SC_LibCapFromFf(p->pLib, pTime->Fall) );
+ }
+ }
+ // read output load
+ pTime = Abc_NtkReadDefaultOutputLoad( p->pNtk );
+ if ( Abc_MaxFloat(pTime->Rise, pTime->Fall) != 0 )
+ {
+ printf( "Default output load is specified (%.2f ff; %.2f ff).\n", pTime->Rise, pTime->Fall );
+ Abc_NtkForEachPo( p->pNtk, pObj, i )
+ Vec_FltWriteEntry( p->vLoads, Abc_ObjId(pObj), 0.5 * SC_LibCapFromFf(p->pLib, pTime->Rise) + 0.5 * SC_LibCapFromFf(p->pLib, pTime->Fall) );
+ }
+ if ( Abc_NodeReadOutputLoad(p->pNtk, 0) != NULL )
+ {
+ printf( "Output loads for some primary outputs are specified.\n" );
+ Abc_NtkForEachPo( p->pNtk, pObj, i )
+ {
+ pTime = Abc_NodeReadOutputLoad(p->pNtk, i);
+ Vec_FltWriteEntry( p->vLoads, Abc_ObjId(pObj), 0.5 * SC_LibCapFromFf(p->pLib, pTime->Rise) + 0.5 * SC_LibCapFromFf(p->pLib, pTime->Fall) );
+ }
+ }
+ // read arrival/required times
+}
+
+/**Function*************************************************************
+
+ Synopsis [Compute load and departure times of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkComputeFanoutCins( Abc_Obj_t * pObj )
+{
+ Abc_Obj_t * pFanout;
+ int i;
+ Abc_ObjForEachFanout( pObj, pFanout, i )
+ if ( Abc_ObjIsNode(pFanout) )
+ Bus_SclObjSetCin( pFanout, SC_CellPinCap( Abc_SclObjCell(pFanout), Abc_NodeFindFanin(pFanout, pObj) ) );
+}
+float Abc_NtkComputeNodeLoad( Abc_Obj_t * pObj )
+{
+ Abc_Obj_t * pFanout;
+ float Load = 0;
+ int i;
+ assert( Bus_SclObjLoad(pObj) == 0 );
+ Abc_ObjForEachFanout( pObj, pFanout, i )
+ Load += Bus_SclObjCin( pFanout );
+ Bus_SclObjSetLoad( pObj, Load );
+ return Load;
+}
+float Abc_NtkComputeNodeDept( Abc_Obj_t * pObj )
+{
+ Abc_Obj_t * pFanout;
+ float Load, Dept, Edge;
+ int i;
+ assert( Bus_SclObjDept(pObj) == 0 );
+ Abc_ObjForEachFanout( pObj, pFanout, i )
+ {
+ if ( Abc_ObjIsCo(pFanout) ) // add required times here
+ continue;
+ Load = Bus_SclObjLoad( pFanout );
+ Dept = Bus_SclObjDept( pFanout );
+ Edge = Scl_LibPinTime( Abc_SclObjCell(pFanout), Abc_NodeFindFanin(pFanout, pObj), Load );
+ Bus_SclObjUpdateDept( pObj, Dept + Edge );
+ assert( Edge > 0 );
+ assert( Load > 0 );
+ }
+ return Bus_SclObjDept( pObj );
+}
+/*
+void Abc_NtkUpdateFaninDeparture( Bus_Man_t * p, Abc_Obj_t * pObj, float Load )
+{
+ SC_Cell * pCell = Abc_SclObjCell( pObj );
+ Abc_Obj_t * pFanin;
+ float Dept, Edge;
+ int i;
+ Dept = Bus_SclObjDept( pObj );
+ Abc_ObjForEachFanin( pObj, pFanin, i )
+ {
+ Edge = Scl_LibPinTime( pCell, i, Load );
+ Bus_SclObjUpdateDept( pFanin, Dept + Edge );
+ }
+}
+*/
+
+/**Function*************************************************************
+
+ Synopsis [Compare two fanouts by their departure times.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Bus_SclCompareFanouts( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 )
+{
+ float Espilon = 10; // 10 ps
+ if ( Bus_SclObjDept(*pp1) < Bus_SclObjDept(*pp2) - Espilon )
+ return -1;
+ if ( Bus_SclObjDept(*pp1) > Bus_SclObjDept(*pp2) + Espilon )
+ return 1;
+ if ( Bus_SclObjCin(*pp1) > Bus_SclObjCin(*pp2) - Espilon )
+ return -1;
+ if ( Bus_SclObjCin(*pp1) < Bus_SclObjCin(*pp2) + Espilon )
+ return 1;
+ return -1;
+}
+void Bus_SclInsertFanout( Vec_Ptr_t * vFanouts, Abc_Obj_t * pObj )
+{
+ Abc_Obj_t * pCur;
+ int i, k;
+ assert( Bus_SclObjDept(pObj) > 0 );
+ assert( Bus_SclObjLoad(pObj) > 0 );
+ // compact array
+ for ( i = k = 0; i < Vec_PtrSize(vFanouts); i++ )
+ if ( Vec_PtrEntry(vFanouts, i) != NULL )
+ Vec_PtrWriteEntry( vFanouts, k++, Vec_PtrEntry(vFanouts, i) );
+ Vec_PtrShrink( vFanouts, k );
+ // insert new entry
+ Vec_PtrPush( vFanouts, pObj );
+ for ( i = Vec_PtrSize(vFanouts) - 1; i > 0; i-- )
+ {
+ pCur = (Abc_Obj_t *)Vec_PtrEntry(vFanouts, i-1);
+ pObj = (Abc_Obj_t *)Vec_PtrEntry(vFanouts, i);
+ if ( Bus_SclCompareFanouts( &pCur, &pObj ) == -1 )
+ break;
+ ABC_SWAP( void *, Vec_PtrArray(vFanouts)[i-1], Vec_PtrArray(vFanouts)[i] );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_SclAddOneInv( Bus_Man_t * p, Abc_Obj_t * pObj, Vec_Ptr_t * vFanouts, float Gain, int Degree )
+{
+ SC_Cell * pCellNew;
+ Abc_Obj_t * pFanout, * pInv;
+ float Target = SC_CellPinCap( p->pInv, 0 ) * Gain;
+ float Load = 0;
+ int i, iStop;
+ Vec_PtrForEachEntryStop( Abc_Obj_t *, vFanouts, pFanout, iStop, Degree )
+ {
+ Load += Bus_SclObjCin( pFanout );
+ if ( Load > Target )
+ break;
+ }
+ // create inverter
+ pInv = Abc_NtkCreateNodeInv( p->pNtk, NULL );
+ assert( (int)Abc_ObjId(pInv) < Vec_FltSize(p->vDepts) );
+ Vec_PtrForEachEntryStop( Abc_Obj_t *, vFanouts, pFanout, i, iStop )
+ {
+ Vec_PtrWriteEntry( vFanouts, i, NULL );
+ if ( Abc_ObjFanin0(pFanout) == NULL )
+ Abc_ObjAddFanin( pFanout, pInv );
+ else
+ Abc_ObjPatchFanin( pFanout, pObj, pInv );
+ }
+ // set the gate
+ pCellNew = Abc_SclFindSmallestGate( p->pInv, Load / Gain );
+ Vec_IntSetEntry( p->pNtk->vGates, Abc_ObjId(pInv), pCellNew->Id );
+ Bus_SclObjSetCin( pInv, SC_CellPinCap(pCellNew, 0) );
+ // update timing
+ Abc_NtkComputeNodeLoad( pInv );
+ Abc_NtkComputeNodeDept( pInv );
+ // update phases
+ if ( p->pNtk->vPhases && Abc_SclIsInv(pInv) )
+ Abc_NodeInvUpdateFanPolarity( pInv );
+ return pInv;
+}
+void Abc_SclBufSize( Bus_Man_t * p )
+{
+ SC_Cell * pCell, * pCellNew;
+ Vec_Ptr_t * vFanouts;
+ Abc_Obj_t * pObj, * pInv;
+ float Load, Cin;
+ int i;
+ vFanouts = Vec_PtrAlloc( 100 );
+ Abc_SclMioGates2SclGates( p->pLib, p->pNtk );
+ Abc_NtkForEachNodeReverse( p->pNtk, pObj, i )
+ {
+ // compute load
+ Abc_NtkComputeFanoutCins( pObj );
+ Load = Abc_NtkComputeNodeLoad( pObj );
+ // consider the gate
+ pCell = Abc_SclObjCell( pObj );
+ Cin = SC_CellPinCapAve( pCell->pAve );
+ // consider upsizing the gate
+ if ( Load > p->Gain * Cin )
+ {
+ // add one or more inverters
+ Abc_NodeCollectFanouts( pObj, vFanouts );
+ Vec_PtrSort( vFanouts, (int(*)(const void *,const void *))Bus_SclCompareFanouts );
+ do
+ {
+ pInv = Abc_SclAddOneInv( p, pObj, vFanouts, p->Gain, p->nDegree );
+ Bus_SclInsertFanout( vFanouts, pInv );
+ Load = Bus_SclObjCin( pInv );
+ }
+ while ( Vec_PtrSize(vFanouts) > 1 || Load > p->Gain * Cin );
+ // connect last inverter
+ assert( Abc_ObjFanin0(pInv) == NULL );
+ Abc_ObjAddFanin( pInv, pObj );
+ Bus_SclObjSetLoad( pObj, Load );
+ }
+ // create cell
+ pCellNew = Abc_SclFindSmallestGate( pCell, Load / p->Gain );
+ Abc_SclObjSetCell( pObj, pCellNew );
+ Abc_NtkComputeNodeDept( pObj );
+ }
+ Abc_SclSclGates2MioGates( p->pLib, p->pNtk );
+ Vec_PtrFree( vFanouts );
+}
+Abc_Ntk_t * Abc_SclBufSizePerform( Abc_Ntk_t * pNtk, SC_Lib * pLib, int GainRatio, int nDegree, int fAddBufs, int fBufPis, int fVerbose )
+{
+ Abc_Ntk_t * pNtkNew;
+ Bus_Man_t * p;
+ if ( !Abc_SclCheckNtk( pNtk, 0 ) )
+ return NULL;
+ Abc_SclReportDupFanins( pNtk );
+ p = Bus_ManStart( pNtk, pLib, GainRatio, nDegree, fBufPis, fVerbose );
+ Bus_ManReadInOutLoads( p );
+ Abc_SclBufSize( p );
+ Bus_ManStop( p );
+ Vec_IntFillExtra( pNtk->vPhases, Abc_NtkObjNumMax(pNtk), 0 );
+ pNtkNew = Abc_NtkDupDfs( pNtk );
+ return pNtkNew;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/map/scl/sclBuffer.c b/src/map/scl/sclBuffer.c
index e9060f7b..f205a0fe 100644
--- a/src/map/scl/sclBuffer.c
+++ b/src/map/scl/sclBuffer.c
@@ -315,7 +315,7 @@ int Abc_SclCheckNtk( Abc_Ntk_t * p, int fVerbose )
SeeAlso []
***********************************************************************/
-void Abc_NodeInvUpdateFanPolarity( Abc_Obj_t * pObj, int fVerbose )
+void Abc_NodeInvUpdateFanPolarity( Abc_Obj_t * pObj )
{
Abc_Obj_t * pFanout;
int i;
@@ -323,22 +323,17 @@ void Abc_NodeInvUpdateFanPolarity( Abc_Obj_t * pObj, int fVerbose )
Abc_ObjForEachFanout( pObj, pFanout, i )
{
if ( Abc_SclObjIsBufInv(pFanout) )
- Abc_NodeInvUpdateFanPolarity( pFanout, fVerbose );
+ Abc_NodeInvUpdateFanPolarity( pFanout );
else
- {
Abc_ObjFaninFlipPhase( pFanout, Abc_NodeFindFanin(pFanout, pObj) );
-// if ( fVerbose )
-// printf( "Flipping fanin %d of node %d.\n", Abc_NodeFindFanin(pFanout, pObj), Abc_ObjId(pFanout) );
- }
}
}
void Abc_NodeInvUpdateObjFanoutPolarity( Abc_Obj_t * pObj, Abc_Obj_t * pFanout )
{
if ( Abc_SclObjIsBufInv(pFanout) )
- Abc_NodeInvUpdateFanPolarity( pFanout, 1 );
+ Abc_NodeInvUpdateFanPolarity( pFanout );
else
Abc_ObjFaninFlipPhase( pFanout, Abc_NodeFindFanin(pFanout, pObj) );
-// printf( "\n" );
}
int Abc_NodeCompareLevels( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 )
{
@@ -413,7 +408,7 @@ Abc_Obj_t * Abc_SclPerformBufferingOne( Abc_Obj_t * pObj, int Degree, int fUseIn
Abc_ObjAddFanin( pBuffer, pObj );
pBuffer->Level = Abc_SclComputeReverseLevel( pBuffer );
if ( fUseInvs )
- Abc_NodeInvUpdateFanPolarity( pBuffer, 0 );
+ Abc_NodeInvUpdateFanPolarity( pBuffer );
return pBuffer;
}
void Abc_SclPerformBuffering_rec( Abc_Obj_t * pObj, int DegreeR, int Degree, int fUseInvs, int fVerbose )
@@ -451,7 +446,7 @@ void Abc_SclPerformBuffering_rec( Abc_Obj_t * pObj, int DegreeR, int Degree, int
Abc_ObjAddFanin( pBuffer, pObj );
pBuffer->Level = Abc_SclComputeReverseLevel( pBuffer );
if ( fUseInvs )
- Abc_NodeInvUpdateFanPolarity( pBuffer, 0 );
+ Abc_NodeInvUpdateFanPolarity( pBuffer );
}
// compute the new level of the node
pObj->Level = Abc_SclComputeReverseLevel( pObj );
diff --git a/src/map/scl/sclDnsize.c b/src/map/scl/sclDnsize.c
index 1b21d808..50c994e9 100644
--- a/src/map/scl/sclDnsize.c
+++ b/src/map/scl/sclDnsize.c
@@ -102,13 +102,13 @@ int Abc_SclCheckImprovement( SC_Man * p, Abc_Obj_t * pObj, Vec_Int_t * vNodes, V
{
Abc_Obj_t * pTemp;
SC_Cell * pCellOld, * pCellNew;
- float dGain, dGainBest;
+ float dGain, dGainBest, gGainCur;
int i, k, gateBest;
abctime clk;
clk = Abc_Clock();
// printf( "%d -> %d\n", Vec_IntSize(vNodes), Vec_IntSize(vEvals) );
// save old gate, timing, fanin load
- pCellOld = Abc_SclObjCell( p, pObj );
+ pCellOld = Abc_SclObjCell( pObj );
Abc_SclConeStore( p, vNodes );
Abc_SclLoadStore( p, pObj );
// try different gate sizes for this node
@@ -123,18 +123,21 @@ clk = Abc_Clock();
if ( p->pInDrive && !Abc_SclInputDriveOk( p, pObj, pCellNew ) )
continue;
// set new cell
- Abc_SclObjSetCell( p, pObj, pCellNew );
+ Abc_SclObjSetCell( pObj, pCellNew );
Abc_SclUpdateLoad( p, pObj, pCellOld, pCellNew );
// recompute timing
Abc_SclTimeCone( p, vNodes );
// set old cell
- Abc_SclObjSetCell( p, pObj, pCellOld );
+ Abc_SclObjSetCell( pObj, pCellOld );
Abc_SclLoadRestore( p, pObj );
// evaluate gain
dGain = 0.0;
Abc_NtkForEachObjVec( vEvals, p->pNtk, pTemp, k )
if ( Abc_SclObjLegal(p, pTemp, p->MaxDelay0) )
- dGain += Abc_SclObjGain( p, pTemp );
+ {
+ gGainCur = Abc_SclObjGain( p, pTemp );
+ dGain += (gGainCur > 0) ? gGainCur : 1.0 * gGainCur;
+ }
else
break;
if ( k < Vec_IntSize(vEvals) )
@@ -148,13 +151,13 @@ clk = Abc_Clock();
}
}
// put back old cell and timing
- Abc_SclObjSetCell( p, pObj, pCellOld );
+ Abc_SclObjSetCell( pObj, pCellOld );
Abc_SclConeRestore( p, vNodes );
p->timeSize += Abc_Clock() - clk;
if ( gateBest >= 0 )
{
pCellNew = SC_LibCell( p->pLib, gateBest );
- Abc_SclObjSetCell( p, pObj, pCellNew );
+ Abc_SclObjSetCell( pObj, pCellNew );
p->SumArea += pCellNew->area - pCellOld->area;
// printf( "%f %f -> %f\n", pCellNew->area - pCellOld->area, p->SumArea - (pCellNew->area - pCellOld->area), p->SumArea );
// printf( "%6d %20s -> %20s %f -> %f\n", Abc_ObjId(pObj), pCellOld->pName, pCellNew->pName, pCellOld->area, pCellNew->area );
@@ -187,7 +190,7 @@ void Abc_NtkCollectNodesByArea( SC_Man * p, Abc_Ntk_t * pNtk )
Abc_NtkForEachNode( pNtk, pObj, i )
if ( Abc_ObjFaninNum(pObj) > 0 )
{
- Vec_FltWriteEntry( p->vNode2Gain, Abc_ObjId(pObj), Abc_SclObjCell(p, pObj)->area );
+ Vec_FltWriteEntry( p->vNode2Gain, Abc_ObjId(pObj), Abc_SclObjCell(pObj)->area );
Vec_QuePush( p->vNodeByGain, Abc_ObjId(pObj) );
}
}
@@ -267,7 +270,7 @@ void Abc_SclDnsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars
p = Abc_SclManStart( pLib, pNtk, pPars->fUseWireLoads, pPars->fUseDept, SC_LibTimeFromPs(pLib, pPars->DelayUser), pPars->BuffTreeEst );
p->timeTotal = Abc_Clock();
assert( p->vGatesBest == NULL );
- p->vGatesBest = Vec_IntDup( p->vGates );
+ p->vGatesBest = Vec_IntDup( p->pNtk->vGates );
// perform upsizing
vNodes = Vec_IntAlloc( 1000 );
@@ -342,7 +345,7 @@ void Abc_SclDnsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars
printf( "Gate sizing timed out at %d seconds.\n", pPars->TimeOut );
// save the result and quit
- Abc_SclManSetGates( pLib, pNtk, p->vGates ); // updates gate pointers
+ Abc_SclSclGates2MioGates( pLib, pNtk ); // updates gate pointers
Abc_SclManFree( p );
// Abc_NtkCleanMarkAB( pNtk );
}
diff --git a/src/map/scl/sclLib.c b/src/map/scl/sclLib.c
index d3ac29df..d2b3d72b 100644
--- a/src/map/scl/sclLib.c
+++ b/src/map/scl/sclLib.c
@@ -749,6 +749,7 @@ static int Abc_SclCompareCells( SC_Cell ** pp1, SC_Cell ** pp2 )
}
void Abc_SclLinkCells( SC_Lib * p )
{
+ Vec_Ptr_t * vList;
SC_Cell * pCell, * pRepr = NULL;
int i, k;
assert( Vec_PtrSize(p->vCellClasses) == 0 );
@@ -770,30 +771,69 @@ void Abc_SclLinkCells( SC_Lib * p )
pRepr->pPrev->pNext = pCell; pCell->pNext = pRepr;
pCell->pPrev = pRepr->pPrev; pRepr->pPrev = pCell;
}
- // sort cells by size the then by name
+ // sort cells by size then by name
qsort( (void *)Vec_PtrArray(p->vCellClasses), Vec_PtrSize(p->vCellClasses), sizeof(void *), (int(*)(const void *,const void *))Abc_SclCompareCells );
// sort cell lists
+ vList = Vec_PtrAlloc( 100 );
SC_LibForEachCellClass( p, pRepr, k )
{
- Vec_Ptr_t * vList = Vec_PtrAlloc( 100 );
+ Vec_PtrClear( vList );
SC_RingForEachCell( pRepr, pCell, i )
Vec_PtrPush( vList, pCell );
qsort( (void *)Vec_PtrArray(vList), Vec_PtrSize(vList), sizeof(void *), (int(*)(const void *,const void *))Abc_SclCompareCells );
// create new representative
pRepr = (SC_Cell *)Vec_PtrEntry( vList, 0 );
pRepr->pNext = pRepr->pPrev = pRepr;
+ pRepr->pRepr = pRepr;
+ pRepr->pAve = (SC_Cell *)Vec_PtrEntry( vList, Vec_PtrSize(vList)/2 );
pRepr->Order = 0;
+ pRepr->nGates = Vec_PtrSize(vList);
// relink cells
Vec_PtrForEachEntryStart( SC_Cell *, vList, pCell, i, 1 )
{
pRepr->pPrev->pNext = pCell; pCell->pNext = pRepr;
pCell->pPrev = pRepr->pPrev; pRepr->pPrev = pCell;
+ pCell->pRepr = pRepr;
+ pCell->pAve = (SC_Cell *)Vec_PtrEntry( vList, Vec_PtrSize(vList)/2 );
pCell->Order = i;
+ pCell->nGates = Vec_PtrSize(vList);
}
// update list
Vec_PtrWriteEntry( p->vCellClasses, k, pRepr );
- Vec_PtrFree( vList );
}
+ Vec_PtrFree( vList );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the largest inverter.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+SC_Cell * Abc_SclFindInvertor( SC_Lib * p )
+{
+ SC_Cell * pCell = NULL;
+ int k;
+ SC_LibForEachCellClass( p, pCell, k )
+ if ( pCell->n_inputs == 1 && Vec_WrdEntry(SC_CellPin(pCell, 1)->vFunc, 0) == ABC_CONST(0x5555555555555555) )
+ break;
+ // take representative
+ return pCell ? pCell->pRepr : NULL;
+}
+SC_Cell * Abc_SclFindSmallestGate( SC_Cell * p, float CinMin )
+{
+ SC_Cell * pRes = NULL;
+ int i;
+ SC_RingForEachCell( p->pRepr, pRes, i )
+ if ( SC_CellPinCapAve(pRes) > CinMin )
+ return pRes;
+ // take the largest gate
+ return p->pRepr->pPrev;
}
/**Function*************************************************************
@@ -1066,8 +1106,8 @@ void Abc_SclPrintCells( SC_Lib * p, float Slew, float Gain )
printf( "D =%6.0f ps ", 0.01 * ED * Gain + PD );
printf( "ED =%6.0f ps ", ED );
printf( "PD =%6.0f ps ", PD );
- printf( "C =%5.1f ff ", Abc_SclGatePinCapAve(p, pCell) );
- printf( "Lm =%5.1f ff ", 0.01 * Gain * Abc_SclGatePinCapAve(p, pCell) );
+ printf( "C =%5.1f ff ", SC_CellPinCapAve(pCell) );
+ printf( "Lm =%5.1f ff ", 0.01 * Gain * SC_CellPinCapAve(pCell) );
// printf( "MaxS =%5.1f ps ", SC_CellPin(pCell, pCell->n_inputs)->max_out_slew );
printf( "Lm2 =%5.0f ff ", SC_CellPin(pCell, pCell->n_inputs)->max_out_cap );
printf( "\n" );
diff --git a/src/map/scl/sclLib.h b/src/map/scl/sclLib.h
index 5084997e..7d5964a4 100644
--- a/src/map/scl/sclLib.h
+++ b/src/map/scl/sclLib.h
@@ -178,7 +178,10 @@ struct SC_Cell_
int n_outputs; // -- 'pins[n_inputs .. n_inputs+n_outputs-1]' are output pins
SC_Cell * pNext; // same-functionality cells linked into a ring by area
SC_Cell * pPrev; // same-functionality cells linked into a ring by area
+ SC_Cell * pRepr; // representative of the class
+ SC_Cell * pAve; // average size cell of this class
int Order; // order of the gate in the list
+ int nGates; // the number of gates in the list
};
struct SC_Lib_
@@ -211,6 +214,7 @@ static inline SC_Cell * SC_LibCell( SC_Lib * p, int i ) { return (SC
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 float SC_CellPinCap( SC_Cell * p, int i ) { return 0.5 * (SC_CellPin(p, i)->rise_cap + SC_CellPin(p, i)->fall_cap); }
+static inline float SC_CellPinCapAve( SC_Cell * p ) { int i; float c = 0; for (i = 0; i < p->n_inputs; i++) c += SC_CellPinCap(p, i); return c / p->n_inputs; }
static inline char * SC_CellPinOutFunc( SC_Cell * p, int i ) { return SC_CellPin(p, p->n_inputs + i)->func_text; }
static inline char * SC_CellPinName( SC_Cell * p, int i ) { return SC_CellPin(p, i)->pName; }
@@ -519,7 +523,7 @@ static inline void Scl_LibPinDeparture( SC_Timing * pTime, SC_Pair * pDepIn, SC_
/**Function*************************************************************
- Synopsis [Computes input capacitance.]
+ Synopsis [Compute one timing edge.]
Description []
@@ -528,17 +532,32 @@ static inline void Scl_LibPinDeparture( SC_Timing * pTime, SC_Pair * pDepIn, SC_
SeeAlso []
***********************************************************************/
-static inline float Abc_SclGatePinCapAve( SC_Lib * p, SC_Cell * pCell )
+static inline float Scl_LibPinTime( SC_Cell * pCell, int iPin, float load )
{
SC_Pin * pPin;
- int k;
- float Cap = 0.0;
- SC_CellForEachPinIn( pCell, pPin, k )
- Cap += 0.5 * (pPin->rise_cap + pPin->fall_cap);
- return Cap / pCell->n_inputs;
+ SC_Timings * pRTime;
+ SC_Timing * pTime;
+ SC_Pair Load = { load, load };
+ SC_Pair ArrIn = { 0.0, 0.0 };
+ SC_Pair ArrOut = { 0.0, 0.0 };
+ SC_Pair SlewIn = { 0.0, 0.0 };
+ SC_Pair SlewOut = { 0.0, 0.0 };
+ Vec_Flt_t * vIndex0;
+ assert( iPin >= 0 && iPin < pCell->n_inputs );
+ pPin = SC_CellPin( pCell, pCell->n_inputs );
+ // find timing info for this pin
+ assert( Vec_PtrSize(pPin->vRTimings) == pCell->n_inputs );
+ pRTime = (SC_Timings *)Vec_PtrEntry( pPin->vRTimings, iPin );
+ assert( Vec_PtrSize(pRTime->vTimings) == 1 );
+ pTime = (SC_Timing *)Vec_PtrEntry( pRTime->vTimings, 0 );
+ // get delay points
+ vIndex0 = pTime->pCellRise->vIndex0; // slew
+ SlewIn.fall = Vec_FltEntry( vIndex0, Vec_FltSize(vIndex0)/2 );
+ SlewIn.rise = Vec_FltEntry( vIndex0, Vec_FltSize(vIndex0)/2 );
+ Scl_LibPinArrival( pTime, &ArrIn, &SlewIn, &Load, &ArrOut, &SlewOut );
+ return 0.5 * (ArrOut.fall + ArrOut.rise);
}
-
/*=== sclLib.c ===============================================================*/
extern SC_Lib * Abc_SclRead( char * pFileName );
extern void Abc_SclWrite( char * pFileName, SC_Lib * p );
@@ -550,6 +569,8 @@ extern int Abc_SclCellFind( SC_Lib * p, char * pName );
extern int Abc_SclClassCellNum( SC_Cell * pClass );
extern void Abc_SclLinkCells( SC_Lib * p );
extern void Abc_SclPrintCells( SC_Lib * p, float Slew, float Gain );
+extern SC_Cell * Abc_SclFindInvertor( SC_Lib * p );
+extern SC_Cell * Abc_SclFindSmallestGate( SC_Cell * p, float CinMin );
extern SC_WireLoad * Abc_SclFindWireLoadModel( SC_Lib * p, float Area );
extern SC_WireLoad * Abc_SclFetchWireLoadModel( SC_Lib * p, char * pName );
extern void Abc_SclDumpGenlib( char * pFileName, SC_Lib * p, float Slew, float Gain, int nGatesMin );
diff --git a/src/map/scl/sclLoad.c b/src/map/scl/sclLoad.c
index 7ea13db2..282fd7ee 100644
--- a/src/map/scl/sclLoad.c
+++ b/src/map/scl/sclLoad.c
@@ -94,7 +94,7 @@ void Abc_SclComputeLoad( SC_Man * p )
// add cell load
Abc_NtkForEachNode1( p->pNtk, pObj, i )
{
- SC_Cell * pCell = Abc_SclObjCell( p, pObj );
+ SC_Cell * pCell = Abc_SclObjCell( pObj );
Abc_ObjForEachFanin( pObj, pFanin, k )
{
SC_Pair * pLoad = Abc_SclObjLoad( p, pFanin );
@@ -142,7 +142,7 @@ void Abc_SclComputeLoad( SC_Man * p )
}
}
// calculate average load
- if ( p->EstLoadMax )
+// if ( p->EstLoadMax )
{
double TotalLoad = 0;
int nObjs = 0;
@@ -194,7 +194,7 @@ void Abc_SclUpdateLoadSplit( SC_Man * p, Abc_Obj_t * pBuffer, Abc_Obj_t * pFanou
int iFanin = Abc_NodeFindFanin( pFanout, pBuffer );
assert( iFanin >= 0 );
assert( Abc_ObjFaninNum(pBuffer) == 1 );
- pPin = SC_CellPin( Abc_SclObjCell(p, pFanout), iFanin );
+ pPin = SC_CellPin( Abc_SclObjCell(pFanout), iFanin );
// update load of the buffer
pLoad = Abc_SclObjLoad( p, pBuffer );
pLoad->rise -= pPin->rise_cap;
diff --git a/src/map/scl/sclSize.c b/src/map/scl/sclSize.c
index 18c520c3..7fb80a27 100644
--- a/src/map/scl/sclSize.c
+++ b/src/map/scl/sclSize.c
@@ -108,7 +108,7 @@ Abc_Obj_t * Abc_SclFindMostCriticalFanin( SC_Man * p, int * pfRise, Abc_Obj_t *
***********************************************************************/
static inline void Abc_SclTimeNodePrint( SC_Man * p, Abc_Obj_t * pObj, int fRise, int Length, float maxDelay )
{
- SC_Cell * pCell = Abc_ObjIsNode(pObj) ? Abc_SclObjCell(p, pObj) : NULL;
+ SC_Cell * pCell = Abc_ObjIsNode(pObj) ? Abc_SclObjCell(pObj) : NULL;
printf( "%6d : ", Abc_ObjId(pObj) );
printf( "%d ", Abc_ObjFaninNum(pObj) );
printf( "%4d ", Abc_ObjFanoutNum(pObj) );
@@ -118,7 +118,7 @@ static inline void Abc_SclTimeNodePrint( SC_Man * p, Abc_Obj_t * pObj, int fRise
printf( "%5.0f", Abc_MaxFloat(Abc_SclObjTimePs(p, pObj, 0), Abc_SclObjTimePs(p, pObj, 1)) );
printf( "%6.0f ps ", -Abc_AbsFloat(Abc_SclObjTimePs(p, pObj, 0) - Abc_SclObjTimePs(p, pObj, 1)) );
printf( "S =%5.0f ps ", Abc_SclObjSlewPs(p, pObj, fRise >= 0 ? fRise : 0 ) );
- printf( "Cin =%4.0f ff ", pCell ? Abc_SclGatePinCapAve(p->pLib, pCell) : 0.0 );
+ printf( "Cin =%4.0f ff ", pCell ? SC_CellPinCapAve(pCell) : 0.0 );
printf( "Cout =%5.0f ff ", Abc_SclObjLoadFf(p, pObj, fRise >= 0 ? fRise : 0 ) );
printf( "Cmax =%5.0f ff ", pCell ? SC_CellPin(pCell, pCell->n_inputs)->max_out_cap : 0.0 );
printf( "G =%5.1f ", pCell ? Abc_SclObjLoadAve(p, pObj) / SC_CellPinCap(pCell, 0) : 0.0 );
@@ -132,10 +132,13 @@ void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll, int fPrintPath )
float maxDelay = Abc_SclObjTimePs(p, pPivot, fRise);
p->ReportDelay = maxDelay;
- printf( "WireLoad model = \"%s\". ", p->pWLoadUsed ? p->pWLoadUsed->pName : "none" );
- printf( "Gates = %6d. ", Abc_NtkNodeNum(p->pNtk) );
- printf( "Area = %12.2f. ", Abc_SclGetTotalArea( p ) );
- printf( "Critical delay = %8.2f ps\n", maxDelay );
+ printf( "WireLoad model = \"%s\" ", p->pWLoadUsed ? p->pWLoadUsed->pName : "none" );
+ printf( "Gates = %6d ", Abc_NtkNodeNum(p->pNtk) );
+ printf( "Cave = %5.1f ", p->EstLoadAve );
+ printf( "Min = %5.1f %% ", 100.0 * Abc_SclCountMinSize(p->pLib, p->pNtk, 0) / Abc_NtkNodeNum(p->pNtk) );
+ printf( "Area = %12.2f ", Abc_SclGetTotalArea( p ) );
+ printf( "Delay = %8.2f ps ", maxDelay );
+ printf( "Min = %5.1f %%\n", 100.0 * Abc_SclCountNearCriticalNodes(p) / Abc_NtkNodeNum(p->pNtk) );
if ( !fPrintPath )
return;
@@ -145,7 +148,7 @@ void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll, int fPrintPath )
// find the longest cell name
Abc_NtkForEachNodeReverse( p->pNtk, pObj, i )
if ( Abc_ObjFaninNum(pObj) > 0 )
- nLength = Abc_MaxInt( nLength, strlen(Abc_SclObjCell(p, pObj)->pName) );
+ nLength = Abc_MaxInt( nLength, strlen(Abc_SclObjCell(pObj)->pName) );
// print timing
Abc_NtkForEachNodeReverse( p->pNtk, pObj, i )
if ( Abc_ObjFaninNum(pObj) > 0 )
@@ -160,7 +163,7 @@ void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll, int fPrintPath )
while ( pObj && Abc_ObjIsNode(pObj) )
{
i++;
- nLength = Abc_MaxInt( nLength, strlen(Abc_SclObjCell(p, pObj)->pName) );
+ nLength = Abc_MaxInt( nLength, strlen(Abc_SclObjCell(pObj)->pName) );
pObj = Abc_SclFindMostCriticalFanin( p, &fRise, pObj );
}
// print timing
@@ -244,7 +247,7 @@ void Abc_SclTimeNode( SC_Man * p, Abc_Obj_t * pObj, int fDept )
p->nEstNodes++;
}
// get the library cell
- pCell = Abc_SclObjCell( p, pObj );
+ pCell = Abc_SclObjCell( pObj );
// get the output pin
// assert( pCell->n_outputs == 1 );
pPin = SC_CellPin( pCell, pCell->n_inputs );
@@ -287,7 +290,7 @@ void Abc_SclTimeCone( SC_Man * p, Vec_Int_t * vCone )
Abc_NtkForEachObjVec( vCone, p->pNtk, pObj, i )
{
if ( fVerbose && Abc_ObjIsNode(pObj) )
- printf( " Updating node %d with gate %s\n", Abc_ObjId(pObj), Abc_SclObjCell(p, pObj)->pName );
+ printf( " Updating node %d with gate %s\n", Abc_ObjId(pObj), Abc_SclObjCell(pObj)->pName );
if ( fVerbose && Abc_ObjIsNode(pObj) )
printf( " before (%6.1f ps %6.1f ps) ", Abc_SclObjTimePs(p, pObj, 1), Abc_SclObjTimePs(p, pObj, 0) );
Abc_SclTimeNode( p, pObj, 0 );
@@ -439,8 +442,7 @@ SC_Man * Abc_SclManStart( SC_Lib * pLib, Abc_Ntk_t * pNtk, int fUseWireLoads, in
p->EstLoadMax = 0.01 * nTreeCRatio; // max ratio of Cout/Cave when the estimation is used
p->EstLinear = 100; // linear coefficient
}
- assert( p->vGates == NULL );
- p->vGates = Abc_SclManFindGates( pLib, pNtk );
+ Abc_SclMioGates2SclGates( pLib, pNtk );
Abc_SclManReadSlewAndLoad( p, pNtk );
if ( fUseWireLoads )
{
@@ -605,7 +607,7 @@ float Abc_SclCountNonBufferLoadInt( SC_Man * p, Abc_Obj_t * pObj )
Abc_ObjForEachFanout( pObj, pFanout, i )
Load += Abc_SclCountNonBufferLoadInt( p, pFanout );
Load += 0.5 * Abc_SclObjLoad(p, pObj)->rise + 0.5 * Abc_SclObjLoad(p, pObj)->fall;
- Load -= 0.5 * SC_CellPin(Abc_SclObjCell(p, pObj), 0)->rise_cap + 0.5 * SC_CellPin(Abc_SclObjCell(p, pObj), 0)->fall_cap;
+ Load -= 0.5 * SC_CellPin(Abc_SclObjCell(pObj), 0)->rise_cap + 0.5 * SC_CellPin(Abc_SclObjCell(pObj), 0)->fall_cap;
return Load;
}
float Abc_SclCountNonBufferLoad( SC_Man * p, Abc_Obj_t * pObj )
@@ -631,7 +633,7 @@ void Abc_SclPrintBuffersOne( SC_Man * p, Abc_Obj_t * pObj, int nOffset )
Abc_SclCountNonBufferFanouts(pObj) );
for ( ; i < 4; i++ )
printf( " " );
- printf( "a =%5.2f ", Abc_ObjIsPi(pObj) ? 0 : Abc_SclObjCell(p, pObj)->area );
+ printf( "a =%5.2f ", Abc_ObjIsPi(pObj) ? 0 : Abc_SclObjCell(pObj)->area );
printf( "d = (" );
printf( "%6.0f ps; ", Abc_SclObjTimePs(p, pObj, 1) );
printf( "%6.0f ps) ", Abc_SclObjTimePs(p, pObj, 0) );
@@ -740,7 +742,7 @@ Vec_Wec_t * Abc_SclSelectSplitNodes( SC_Man * p, Abc_Ntk_t * pNtk )
/*
printf( "%d : %.0f ", i, 0.5 * (Abc_SclObjLoad(p, pObj)->fall + Abc_SclObjLoad(p, pObj)->rise) );
Abc_ObjForEachFanout( pObj, pFanout, k )
- printf( "%.1f ", Abc_SclGatePinCapAve(p->pLib, Abc_SclObjCell(p, pFanout)) );
+ printf( "%.1f ", SC_CellPinCapAve(Abc_SclObjCell(pFanout)) );
printf( "\n" );
*/
// skip non-critical nodes
diff --git a/src/map/scl/sclSize.h b/src/map/scl/sclSize.h
index 9660cbe9..fad63243 100644
--- a/src/map/scl/sclSize.h
+++ b/src/map/scl/sclSize.h
@@ -47,7 +47,7 @@ struct SC_Man_
Abc_Ntk_t * pNtk; // network
int nObjs; // allocated size
// get assignment
- Vec_Int_t * vGates; // mapping of objId into gateId
+// Vec_Int_t * vGates; // mapping of objId into gateId
Vec_Int_t * vGatesBest; // best gate sizes found so far
Vec_Int_t * vUpdates; // sizing updates in this round
Vec_Int_t * vUpdates2; // sizing updates in this round
@@ -99,8 +99,9 @@ struct SC_Man_
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
-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)) ); }
-static inline void Abc_SclObjSetCell( SC_Man * p, Abc_Obj_t * pObj, SC_Cell * pCell ) { Vec_IntWriteEntry( p->vGates, Abc_ObjId(pObj), pCell->Id ); }
+static inline SC_Lib * Abc_SclObjLib( Abc_Obj_t * p ) { return (SC_Lib *)p->pNtk->pSCLib; }
+static inline SC_Cell * Abc_SclObjCell( Abc_Obj_t * p ) { return SC_LibCell( Abc_SclObjLib(p), Vec_IntEntry(p->pNtk->vGates, Abc_ObjId(p)) ); }
+static inline void Abc_SclObjSetCell( Abc_Obj_t * p, SC_Cell * pCell ) { Vec_IntWriteEntry( p->pNtk->vGates, Abc_ObjId(p), pCell->Id ); }
static inline SC_Pair * Abc_SclObjLoad( SC_Man * p, Abc_Obj_t * pObj ) { return p->pLoads + Abc_ObjId(pObj); }
static inline SC_Pair * Abc_SclObjDept( SC_Man * p, Abc_Obj_t * pObj ) { return p->pDepts + Abc_ObjId(pObj); }
@@ -177,6 +178,8 @@ static inline SC_Man * Abc_SclManAlloc( SC_Lib * pLib, Abc_Ntk_t * pNtk )
}
static inline void Abc_SclManFree( SC_Man * p )
{
+ p->pNtk->pSCLib = NULL;
+ Vec_IntFreeP( &p->pNtk->vGates );
Vec_IntFreeP( &p->vNodeIter );
Vec_QueFreeP( &p->vNodeByGain );
Vec_FltFreeP( &p->vNode2Gain );
@@ -191,7 +194,7 @@ static inline void Abc_SclManFree( SC_Man * p )
Vec_QueCheck( p->vQue );
Vec_QueFreeP( &p->vQue );
Vec_FltFreeP( &p->vTimesOut );
- Vec_IntFreeP( &p->vGates );
+// Vec_IntFreeP( &p->vGates );
Vec_IntFreeP( &p->vBestFans );
ABC_FREE( p->pLoads );
ABC_FREE( p->pDepts );
@@ -349,7 +352,7 @@ static inline float Abc_SclGetTotalArea( SC_Man * p )
Abc_Obj_t * pObj;
int i;
Abc_NtkForEachNode1( p->pNtk, pObj, i )
- Area += Abc_SclObjCell( p, pObj )->area;
+ Area += Abc_SclObjCell(pObj)->area;
return Area;
}
static inline float Abc_SclGetMaxDelay( SC_Man * p )
@@ -389,7 +392,7 @@ static inline float Abc_SclReadMaxDelay( SC_Man * p )
***********************************************************************/
static inline SC_Cell * Abc_SclObjResiable( SC_Man * p, Abc_Obj_t * pObj, int fUpsize )
{
- SC_Cell * pOld = Abc_SclObjCell( p, pObj );
+ SC_Cell * pOld = Abc_SclObjCell(pObj);
if ( fUpsize )
return pOld->pNext->Order > pOld->Order ? pOld->pNext : NULL;
else
@@ -435,10 +438,13 @@ static inline void Abc_SclDumpStats( SC_Man * p, char * pFileName, abctime Time
fclose( pTable );
}
-
+/*=== sclBufSize.c ===============================================================*/
+extern Abc_Ntk_t * Abc_SclBufSizePerform( Abc_Ntk_t * pNtk, SC_Lib * pLib, int GainRatio, int nDegree, int fAddBufs, int fBufPis, int fVerbose );
/*=== sclBuffer.c ===============================================================*/
extern int Abc_SclIsInv( Abc_Obj_t * pObj );
+extern void Abc_NodeInvUpdateFanPolarity( Abc_Obj_t * pObj );
extern void Abc_NodeInvUpdateObjFanoutPolarity( Abc_Obj_t * pObj, Abc_Obj_t * pFanout );
+extern void Abc_SclReportDupFanins( Abc_Ntk_t * pNtk );
extern Abc_Ntk_t * Abc_SclUnBufferPerform( Abc_Ntk_t * pNtk, int fVerbose );
extern Abc_Ntk_t * Abc_SclUnBufferPhase( Abc_Ntk_t * pNtk, int fVerbose );
extern Abc_Ntk_t * Abc_SclBufferPhase( Abc_Ntk_t * pNtk, int fVerbose );
@@ -462,12 +468,14 @@ extern void Abc_SclTimePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, int nT
extern void Abc_SclPrintBuffers( SC_Lib * pLib, Abc_Ntk_t * pNtk, int fVerbose );
extern int Abc_SclInputDriveOk( SC_Man * p, Abc_Obj_t * pObj, SC_Cell * pCell );
/*=== sclUpsize.c ===============================================================*/
+extern int Abc_SclCountNearCriticalNodes( SC_Man * p );
extern void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars );
/*=== sclUtil.c ===============================================================*/
-extern Vec_Int_t * Abc_SclManFindGates( SC_Lib * pLib, Abc_Ntk_t * p );
-extern void Abc_SclManSetGates( SC_Lib * pLib, Abc_Ntk_t * p, Vec_Int_t * vGates );
+extern void Abc_SclMioGates2SclGates( SC_Lib * pLib, Abc_Ntk_t * p );
+extern void Abc_SclSclGates2MioGates( SC_Lib * pLib, Abc_Ntk_t * p );
extern void Abc_SclPrintGateSizes( SC_Lib * pLib, Abc_Ntk_t * p );
extern void Abc_SclMinsizePerform( SC_Lib * pLib, Abc_Ntk_t * p, int fUseMax, int fVerbose );
+extern int Abc_SclCountMinSize( SC_Lib * pLib, Abc_Ntk_t * p, int fUseMax );
ABC_NAMESPACE_HEADER_END
diff --git a/src/map/scl/sclUpsize.c b/src/map/scl/sclUpsize.c
index 9cc8d370..8bdc3a5d 100644
--- a/src/map/scl/sclUpsize.c
+++ b/src/map/scl/sclUpsize.c
@@ -181,6 +181,20 @@ void Abc_SclUnmarkCriticalNodeWindow( SC_Man * p, Vec_Int_t * vPath )
Abc_NtkForEachObjVec( vPath, p->pNtk, pObj, i )
pObj->fMarkA = 0;
}
+int Abc_SclCountNearCriticalNodes( SC_Man * p )
+{
+ int RetValue;
+ Vec_Int_t * vPathPos, * vPathNodes;
+ vPathPos = Abc_SclFindCriticalCoWindow( p, 5 );
+ vPathNodes = Abc_SclFindCriticalNodeWindow( p, vPathPos, 5, 0 );
+ RetValue = Vec_IntSize(vPathNodes);
+ Abc_SclUnmarkCriticalNodeWindow( p, vPathNodes );
+ Abc_SclUnmarkCriticalNodeWindow( p, vPathPos );
+ Vec_IntFree( vPathPos );
+ Vec_IntFree( vPathNodes );
+ return RetValue;
+}
+
/**Function*************************************************************
@@ -261,7 +275,7 @@ int Abc_SclFindBestCell( SC_Man * p, Abc_Obj_t * pObj, Vec_Int_t * vRecalcs, Vec
float dGain, dGainBest, gGainCur;
int k, n, gateBest;
// save old gate, timing, fanin load
- pCellOld = Abc_SclObjCell( p, pObj );
+ pCellOld = Abc_SclObjCell( pObj );
Abc_SclConeStore( p, vRecalcs );
Abc_SclLoadStore( p, pObj );
// try different gate sizes for this node
@@ -276,12 +290,12 @@ int Abc_SclFindBestCell( SC_Man * p, Abc_Obj_t * pObj, Vec_Int_t * vRecalcs, Vec
if ( p->pInDrive && !Abc_SclInputDriveOk( p, pObj, pCellNew ) )
continue;
// set new cell
- Abc_SclObjSetCell( p, pObj, pCellNew );
+ Abc_SclObjSetCell( pObj, pCellNew );
Abc_SclUpdateLoad( p, pObj, pCellOld, pCellNew );
// recompute timing
Abc_SclTimeCone( p, vRecalcs );
// set old cell
- Abc_SclObjSetCell( p, pObj, pCellOld );
+ Abc_SclObjSetCell( pObj, pCellOld );
Abc_SclLoadRestore( p, pObj );
// evaluate gain
dGain = 0.0;
@@ -299,7 +313,7 @@ int Abc_SclFindBestCell( SC_Man * p, Abc_Obj_t * pObj, Vec_Int_t * vRecalcs, Vec
}
}
// put back old cell and timing
- Abc_SclObjSetCell( p, pObj, pCellOld );
+ Abc_SclObjSetCell( pObj, pCellOld );
Abc_SclConeRestore( p, vRecalcs );
*pGainBest = dGainBest;
return gateBest;
@@ -438,11 +452,11 @@ int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notc
Vec_IntPush( p->vUpdates2, Abc_ObjId(pFanin) );
Vec_IntPush( p->vUpdates2, Abc_ObjId(pBuf) );
// find old and new gates
- pCellOld = Abc_SclObjCell( p, pFanin );
+ pCellOld = Abc_SclObjCell( pFanin );
pCellNew = SC_LibCell( p->pLib, Vec_IntEntry(p->vNode2Gate, iNode) );
// update cell
p->SumArea += pCellNew->area - pCellOld->area;
- Abc_SclObjSetCell( p, pFanin, pCellNew );
+ Abc_SclObjSetCell( pFanin, pCellNew );
// record the update
Vec_IntPush( p->vUpdates, Abc_ObjId(pFanin) );
Vec_IntPush( p->vUpdates, pCellNew->Id );
@@ -462,7 +476,7 @@ int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notc
// check if the node became useless
if ( Abc_ObjFanoutNum(pBuf) == 0 )
{
- pCellOld = Abc_SclObjCell( p, pBuf );
+ pCellOld = Abc_SclObjCell( pBuf );
p->SumArea -= pCellOld->area;
Abc_NtkDeleteObj_rec( pBuf, 1 );
printf( "Removed node %d.\n", iNode );
@@ -583,7 +597,7 @@ int Abc_SclFindUpsizes( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notch
pObj = Abc_NtkObj( p->pNtk, Vec_QuePop(p->vNodeByGain) );
assert( pObj->fMarkA );
// find old and new gates
- pCellOld = Abc_SclObjCell( p, pObj );
+ pCellOld = Abc_SclObjCell( pObj );
pCellNew = SC_LibCell( p->pLib, Vec_IntEntry(p->vNode2Gate, Abc_ObjId(pObj)) );
assert( pCellNew != NULL );
//printf( "%6d %20s -> %20s ", Abc_ObjId(pObj), pCellOld->pName, pCellNew->pName );
@@ -622,7 +636,7 @@ return Limit;
// printf( "%.1f ", Vec_FltEntry(p->vNode2Gain, iNode) );
// find old and new gates
- pCellOld = Abc_SclObjCell( p, pObj );
+ pCellOld = Abc_SclObjCell( pObj );
pCellNew = SC_LibCell( p->pLib, Vec_IntEntry(p->vNode2Gate, Abc_ObjId(pObj)) );
assert( pCellNew != NULL );
//printf( "%6d %20s -> %20s ", Abc_ObjId(pObj), pCellOld->pName, pCellNew->pName );
@@ -630,7 +644,7 @@ return Limit;
// update gate
Abc_SclUpdateLoad( p, pObj, pCellOld, pCellNew );
p->SumArea += pCellNew->area - pCellOld->area;
- Abc_SclObjSetCell( p, pObj, pCellNew );
+ Abc_SclObjSetCell( pObj, pCellNew );
// record the update
Vec_IntPush( p->vUpdates, Abc_ObjId(pObj) );
Vec_IntPush( p->vUpdates, pCellNew->Id );
@@ -788,7 +802,7 @@ void Abc_SclUpsizeRemoveDangling( SC_Man * p, Abc_Ntk_t * pNtk )
Abc_NtkForEachNode( pNtk, pObj, i )
if ( Abc_ObjFanoutNum(pObj) == 0 )
{
- pCell = Abc_SclObjCell( p, pObj );
+ pCell = Abc_SclObjCell( pObj );
p->SumArea -= pCell->area;
Abc_NtkDeleteObj_rec( pObj, 1 );
// printf( "Removed node %d.\n", i );
@@ -834,7 +848,7 @@ void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars
p = Abc_SclManStart( pLib, pNtk, pPars->fUseWireLoads, pPars->fUseDept, 0, pPars->BuffTreeEst );
p->timeTotal = Abc_Clock();
assert( p->vGatesBest == NULL );
- p->vGatesBest = Vec_IntDup( p->vGates );
+ p->vGatesBest = Vec_IntDup( p->pNtk->vGates );
p->BestDelay = p->MaxDelay0;
// perform upsizing
@@ -893,7 +907,7 @@ void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars
if ( p->BestDelay > p->MaxDelay )
{
p->BestDelay = p->MaxDelay;
- Abc_SclApplyUpdateToBest( p->vGatesBest, p->vGates, p->vUpdates );
+ Abc_SclApplyUpdateToBest( p->vGatesBest, p->pNtk->vGates, p->vUpdates );
Vec_IntClear( p->vUpdates2 );
nFramesNoChange = 0;
}
@@ -920,7 +934,7 @@ void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars
break;
}
// update for best gates and recompute timing
- ABC_SWAP( Vec_Int_t *, p->vGatesBest, p->vGates );
+ ABC_SWAP( Vec_Int_t *, p->vGatesBest, p->pNtk->vGates );
if ( pPars->BypassFreq != 0 )
Abc_SclUndoRecentChanges( p->pNtk, p->vUpdates2 );
if ( pPars->BypassFreq != 0 )
@@ -947,7 +961,7 @@ void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars
printf( "Gate sizing timed out at %d seconds.\n", pPars->TimeOut );
// save the result and quit
- Abc_SclManSetGates( pLib, pNtk, p->vGates ); // updates gate pointers
+ Abc_SclSclGates2MioGates( pLib, pNtk ); // updates gate pointers
Abc_SclManFree( p );
// Abc_NtkCleanMarkAB( pNtk );
}
diff --git a/src/map/scl/sclUtil.c b/src/map/scl/sclUtil.c
index a28ef0cd..45980b6f 100644
--- a/src/map/scl/sclUtil.c
+++ b/src/map/scl/sclUtil.c
@@ -44,29 +44,30 @@ ABC_NAMESPACE_IMPL_START
SeeAlso []
***********************************************************************/
-Vec_Int_t * Abc_SclManFindGates( SC_Lib * pLib, Abc_Ntk_t * p )
+void Abc_SclMioGates2SclGates( SC_Lib * pLib, Abc_Ntk_t * p )
{
- Vec_Int_t * vVec;
Abc_Obj_t * pObj;
int i;
- vVec = Vec_IntStartFull( Abc_NtkObjNumMax(p) );
+ assert( p->vGates == NULL );
+ p->vGates = Vec_IntStartFull( Abc_NtkObjNumMax(p) );
Abc_NtkForEachNode1( 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 );
+ Vec_IntWriteEntry( p->vGates, i, gateId );
//printf( "Found gate %s\n", pName );
}
- return vVec;
+ p->pSCLib = pLib;
}
-void Abc_SclManSetGates( SC_Lib * pLib, Abc_Ntk_t * p, Vec_Int_t * vGates )
+void Abc_SclSclGates2MioGates( SC_Lib * pLib, Abc_Ntk_t * p )
{
Abc_Obj_t * pObj;
int i, Counter = 0, CounterAll = 0;
+ assert( p->vGates != NULL );
Abc_NtkForEachNode1( p, pObj, i )
{
- SC_Cell * pCell = SC_LibCell( pLib, Vec_IntEntry(vGates, Abc_ObjId(pObj)) );
+ SC_Cell * pCell = Abc_SclObjCell(pObj);
assert( pCell->n_inputs == Abc_ObjFaninNum(pObj) );
pObj->pData = Mio_LibraryReadGateByName( (Mio_Library_t *)p->pManFunc, pCell->pName, NULL );
Counter += (pObj->pData == NULL);
@@ -76,6 +77,8 @@ void Abc_SclManSetGates( SC_Lib * pLib, Abc_Ntk_t * p, Vec_Int_t * vGates )
}
if ( Counter )
printf( "Could not find %d (out of %d) gates in the current library.\n", Counter, CounterAll );
+ Vec_IntFreeP( &p->vGates );
+ p->pSCLib = NULL;
}
/**Function*************************************************************
@@ -119,10 +122,10 @@ void Abc_SclManPrintGateSizes( SC_Lib * pLib, Abc_Ntk_t * p, Vec_Int_t * vGates
}
void Abc_SclPrintGateSizes( SC_Lib * pLib, Abc_Ntk_t * p )
{
- Vec_Int_t * vGates;
- vGates = Abc_SclManFindGates( pLib, p );
- Abc_SclManPrintGateSizes( pLib, p, vGates );
- Vec_IntFree( vGates );
+ Abc_SclMioGates2SclGates( pLib, p );
+ Abc_SclManPrintGateSizes( pLib, p, p->vGates );
+ Vec_IntFreeP( &p->vGates );
+ p->pSCLib = NULL;
}
/**Function*************************************************************
@@ -149,13 +152,12 @@ SC_Cell * Abc_SclFindMaxAreaCell( SC_Cell * pRepr )
}
return pBest;
}
-void Abc_SclMinsizePerform( SC_Lib * pLib, Abc_Ntk_t * p, int fUseMax, int fVerbose )
+Vec_Int_t * Abc_SclFindMinAreas( SC_Lib * pLib, int fUseMax )
{
- Vec_Int_t * vMinCells, * vGates;
+ Vec_Int_t * vMinCells;
SC_Cell * pCell, * pRepr = NULL, * pBest = NULL;
- Abc_Obj_t * pObj;
- int i, k, gateId;
- // map each gate in the library into its min-size prototype
+ int i, k;
+ // map each gate in the library into its min/max-size prototype
vMinCells = Vec_IntStartFull( Vec_PtrSize(pLib->vCells) );
SC_LibForEachCellClass( pLib, pRepr, i )
{
@@ -163,21 +165,39 @@ void Abc_SclMinsizePerform( SC_Lib * pLib, Abc_Ntk_t * p, int fUseMax, int fVerb
SC_RingForEachCell( pRepr, pCell, k )
Vec_IntWriteEntry( vMinCells, pCell->Id, pBest->Id );
}
- // update each cell
- vGates = Abc_SclManFindGates( pLib, p );
+ return vMinCells;
+}
+void Abc_SclMinsizePerform( SC_Lib * pLib, Abc_Ntk_t * p, int fUseMax, int fVerbose )
+{
+ Vec_Int_t * vMinCells;
+ Abc_Obj_t * pObj;
+ int i, gateId;
+ vMinCells = Abc_SclFindMinAreas( pLib, fUseMax );
+ Abc_SclMioGates2SclGates( pLib, p );
Abc_NtkForEachNode1( p, pObj, i )
{
- gateId = Vec_IntEntry( vGates, i );
-// if ( SC_LibCell(pLib, gateId)->n_outputs > 1 )
-// continue;
+ gateId = Vec_IntEntry( p->vGates, i );
assert( gateId >= 0 && gateId < Vec_PtrSize(pLib->vCells) );
gateId = Vec_IntEntry( vMinCells, gateId );
assert( gateId >= 0 && gateId < Vec_PtrSize(pLib->vCells) );
- Vec_IntWriteEntry( vGates, i, gateId );
+ Vec_IntWriteEntry( p->vGates, i, gateId );
+ }
+ Abc_SclSclGates2MioGates( pLib, p );
+ Vec_IntFree( vMinCells );
+}
+int Abc_SclCountMinSize( SC_Lib * pLib, Abc_Ntk_t * p, int fUseMax )
+{
+ Vec_Int_t * vMinCells;
+ Abc_Obj_t * pObj;
+ int i, gateId, Counter = 0;
+ vMinCells = Abc_SclFindMinAreas( pLib, fUseMax );
+ Abc_NtkForEachNode1( p, pObj, i )
+ {
+ gateId = Vec_IntEntry( p->vGates, i );
+ Counter += ( gateId == Vec_IntEntry(vMinCells, gateId) );
}
- Abc_SclManSetGates( pLib, p, vGates );
Vec_IntFree( vMinCells );
- Vec_IntFree( vGates );
+ return Counter;
}
/**Function*************************************************************
diff --git a/src/misc/vec/vecFlt.h b/src/misc/vec/vecFlt.h
index 43e34217..9eb13962 100644
--- a/src/misc/vec/vecFlt.h
+++ b/src/misc/vec/vecFlt.h
@@ -336,6 +336,11 @@ static inline float Vec_FltEntry( Vec_Flt_t * p, int i )
assert( i >= 0 && i < p->nSize );
return p->pArray[i];
}
+static inline float * Vec_FltEntryP( Vec_Flt_t * p, int i )
+{
+ assert( i >= 0 && i < p->nSize );
+ return p->pArray + i;
+}
/**Function*************************************************************