From 881b2ec46f0519cbab41ba51245b3de949fdbee9 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 8 Aug 2013 18:23:00 -0700 Subject: Integrated buffering and sizing. --- abclib.dsp | 4 + src/base/abc/abc.h | 3 + src/base/abc/abcNtk.c | 2 + src/map/scl/module.make | 1 + src/map/scl/scl.c | 104 +++++++++++++ src/map/scl/sclBufSize.c | 376 +++++++++++++++++++++++++++++++++++++++++++++++ src/map/scl/sclBuffer.c | 15 +- src/map/scl/sclDnsize.c | 23 +-- src/map/scl/sclLib.c | 50 ++++++- src/map/scl/sclLib.h | 37 ++++- src/map/scl/sclLoad.c | 6 +- src/map/scl/sclSize.c | 32 ++-- src/map/scl/sclSize.h | 26 ++-- src/map/scl/sclUpsize.c | 44 ++++-- src/map/scl/sclUtil.c | 68 ++++++--- src/misc/vec/vecFlt.h | 5 + 16 files changed, 697 insertions(+), 99 deletions(-) create mode 100644 src/map/scl/sclBufSize.c 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 ); @@ -690,6 +692,108 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + 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 : target gain percentage [default = %d]\n", GainRatio ); + fprintf( pAbc->Err, "\t-M : 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 [] 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************************************************************* -- cgit v1.2.3