Commit 881b2ec4 by Alan Mishchenko

Integrated buffering and sizing.

parent 655dc4e7
...@@ -2459,6 +2459,10 @@ SOURCE=.\src\map\scl\sclBuffer.c ...@@ -2459,6 +2459,10 @@ SOURCE=.\src\map\scl\sclBuffer.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\src\map\scl\sclBufSize.c
# End Source File
# Begin Source File
SOURCE=.\src\map\scl\sclDnsize.c SOURCE=.\src\map\scl\sclDnsize.c
# End Source File # End Source File
# Begin Source File # Begin Source File
......
...@@ -204,6 +204,9 @@ struct Abc_Ntk_t_ ...@@ -204,6 +204,9 @@ struct Abc_Ntk_t_
void * pExcare; // the EXDC network (if given) void * pExcare; // the EXDC network (if given)
void * pData; // misc void * pData; // misc
Abc_Ntk_t * pCopy; // copy of this network 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 Vec_Int_t * vPhases; // fanins phases in the mapped netlist
char * pWLoadUsed; // wire load model used char * pWLoadUsed; // wire load model used
float * pLutTimes; // arrivals/requireds/slacks using LUT-delay model float * pLutTimes; // arrivals/requireds/slacks using LUT-delay model
......
...@@ -1351,6 +1351,8 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk ) ...@@ -1351,6 +1351,8 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk )
//printf( "deleting attr\n" ); //printf( "deleting attr\n" );
Vec_AttFree( (Vec_Att_t *)pAttrMan, 1 ); Vec_AttFree( (Vec_Att_t *)pAttrMan, 1 );
} }
assert( pNtk->pSCLib == NULL );
Vec_IntFreeP( &pNtk->vGates );
Vec_PtrFree( pNtk->vAttrs ); Vec_PtrFree( pNtk->vAttrs );
ABC_FREE( pNtk->pWLoadUsed ); ABC_FREE( pNtk->pWLoadUsed );
ABC_FREE( pNtk->pName ); ABC_FREE( pNtk->pName );
......
SRC += src/map/scl/scl.c \ SRC += src/map/scl/scl.c \
src/map/scl/sclBuffer.c \ src/map/scl/sclBuffer.c \
src/map/scl/sclBufSize.c \
src/map/scl/sclDnsize.c \ src/map/scl/sclDnsize.c \
src/map/scl/sclLib.c \ src/map/scl/sclLib.c \
src/map/scl/sclLoad.c \ src/map/scl/sclLoad.c \
......
...@@ -36,6 +36,7 @@ static int Scl_CommandPrintGS ( Abc_Frame_t * pAbc, int argc, char **argv ); ...@@ -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_CommandStime ( Abc_Frame_t * pAbc, int argc, char **argv );
static int Scl_CommandTopo ( 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_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_CommandUnBuffer( Abc_Frame_t * pAbc, int argc, char **argv );
static int Scl_CommandMinsize ( 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 ); static int Scl_CommandMaxsize ( Abc_Frame_t * pAbc, int argc, char **argv );
...@@ -69,6 +70,7 @@ void Scl_Init( Abc_Frame_t * pAbc ) ...@@ -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", "stime", Scl_CommandStime, 0 );
Cmd_CommandAdd( pAbc, "SCL mapping", "topo", Scl_CommandTopo, 1 ); Cmd_CommandAdd( pAbc, "SCL mapping", "topo", Scl_CommandTopo, 1 );
Cmd_CommandAdd( pAbc, "SCL mapping", "buffer", Scl_CommandBuffer, 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", "unbuffer", Scl_CommandUnBuffer, 1 );
Cmd_CommandAdd( pAbc, "SCL mapping", "minsize", Scl_CommandMinsize, 1 ); Cmd_CommandAdd( pAbc, "SCL mapping", "minsize", Scl_CommandMinsize, 1 );
Cmd_CommandAdd( pAbc, "SCL mapping", "maxsize", Scl_CommandMaxsize, 1 ); Cmd_CommandAdd( pAbc, "SCL mapping", "maxsize", Scl_CommandMaxsize, 1 );
...@@ -701,6 +703,108 @@ usage: ...@@ -701,6 +703,108 @@ usage:
SeeAlso [] 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 ) int Scl_CommandUnBuffer( Abc_Frame_t * pAbc, int argc, char **argv )
{ {
Abc_Ntk_t * pNtkRes, * pNtk = Abc_FrameReadNtk(pAbc); Abc_Ntk_t * pNtkRes, * pNtk = Abc_FrameReadNtk(pAbc);
......
/**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
...@@ -315,7 +315,7 @@ int Abc_SclCheckNtk( Abc_Ntk_t * p, int fVerbose ) ...@@ -315,7 +315,7 @@ int Abc_SclCheckNtk( Abc_Ntk_t * p, int fVerbose )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
void Abc_NodeInvUpdateFanPolarity( Abc_Obj_t * pObj, int fVerbose ) void Abc_NodeInvUpdateFanPolarity( Abc_Obj_t * pObj )
{ {
Abc_Obj_t * pFanout; Abc_Obj_t * pFanout;
int i; int i;
...@@ -323,22 +323,17 @@ void Abc_NodeInvUpdateFanPolarity( Abc_Obj_t * pObj, int fVerbose ) ...@@ -323,22 +323,17 @@ void Abc_NodeInvUpdateFanPolarity( Abc_Obj_t * pObj, int fVerbose )
Abc_ObjForEachFanout( pObj, pFanout, i ) Abc_ObjForEachFanout( pObj, pFanout, i )
{ {
if ( Abc_SclObjIsBufInv(pFanout) ) if ( Abc_SclObjIsBufInv(pFanout) )
Abc_NodeInvUpdateFanPolarity( pFanout, fVerbose ); Abc_NodeInvUpdateFanPolarity( pFanout );
else else
{
Abc_ObjFaninFlipPhase( pFanout, Abc_NodeFindFanin(pFanout, pObj) ); 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 ) void Abc_NodeInvUpdateObjFanoutPolarity( Abc_Obj_t * pObj, Abc_Obj_t * pFanout )
{ {
if ( Abc_SclObjIsBufInv(pFanout) ) if ( Abc_SclObjIsBufInv(pFanout) )
Abc_NodeInvUpdateFanPolarity( pFanout, 1 ); Abc_NodeInvUpdateFanPolarity( pFanout );
else else
Abc_ObjFaninFlipPhase( pFanout, Abc_NodeFindFanin(pFanout, pObj) ); Abc_ObjFaninFlipPhase( pFanout, Abc_NodeFindFanin(pFanout, pObj) );
// printf( "\n" );
} }
int Abc_NodeCompareLevels( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 ) 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 ...@@ -413,7 +408,7 @@ Abc_Obj_t * Abc_SclPerformBufferingOne( Abc_Obj_t * pObj, int Degree, int fUseIn
Abc_ObjAddFanin( pBuffer, pObj ); Abc_ObjAddFanin( pBuffer, pObj );
pBuffer->Level = Abc_SclComputeReverseLevel( pBuffer ); pBuffer->Level = Abc_SclComputeReverseLevel( pBuffer );
if ( fUseInvs ) if ( fUseInvs )
Abc_NodeInvUpdateFanPolarity( pBuffer, 0 ); Abc_NodeInvUpdateFanPolarity( pBuffer );
return pBuffer; return pBuffer;
} }
void Abc_SclPerformBuffering_rec( Abc_Obj_t * pObj, int DegreeR, int Degree, int fUseInvs, int fVerbose ) 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 ...@@ -451,7 +446,7 @@ void Abc_SclPerformBuffering_rec( Abc_Obj_t * pObj, int DegreeR, int Degree, int
Abc_ObjAddFanin( pBuffer, pObj ); Abc_ObjAddFanin( pBuffer, pObj );
pBuffer->Level = Abc_SclComputeReverseLevel( pBuffer ); pBuffer->Level = Abc_SclComputeReverseLevel( pBuffer );
if ( fUseInvs ) if ( fUseInvs )
Abc_NodeInvUpdateFanPolarity( pBuffer, 0 ); Abc_NodeInvUpdateFanPolarity( pBuffer );
} }
// compute the new level of the node // compute the new level of the node
pObj->Level = Abc_SclComputeReverseLevel( pObj ); pObj->Level = Abc_SclComputeReverseLevel( pObj );
......
...@@ -102,13 +102,13 @@ int Abc_SclCheckImprovement( SC_Man * p, Abc_Obj_t * pObj, Vec_Int_t * vNodes, V ...@@ -102,13 +102,13 @@ int Abc_SclCheckImprovement( SC_Man * p, Abc_Obj_t * pObj, Vec_Int_t * vNodes, V
{ {
Abc_Obj_t * pTemp; Abc_Obj_t * pTemp;
SC_Cell * pCellOld, * pCellNew; SC_Cell * pCellOld, * pCellNew;
float dGain, dGainBest; float dGain, dGainBest, gGainCur;
int i, k, gateBest; int i, k, gateBest;
abctime clk; abctime clk;
clk = Abc_Clock(); clk = Abc_Clock();
// printf( "%d -> %d\n", Vec_IntSize(vNodes), Vec_IntSize(vEvals) ); // printf( "%d -> %d\n", Vec_IntSize(vNodes), Vec_IntSize(vEvals) );
// save old gate, timing, fanin load // save old gate, timing, fanin load
pCellOld = Abc_SclObjCell( p, pObj ); pCellOld = Abc_SclObjCell( pObj );
Abc_SclConeStore( p, vNodes ); Abc_SclConeStore( p, vNodes );
Abc_SclLoadStore( p, pObj ); Abc_SclLoadStore( p, pObj );
// try different gate sizes for this node // try different gate sizes for this node
...@@ -123,18 +123,21 @@ clk = Abc_Clock(); ...@@ -123,18 +123,21 @@ clk = Abc_Clock();
if ( p->pInDrive && !Abc_SclInputDriveOk( p, pObj, pCellNew ) ) if ( p->pInDrive && !Abc_SclInputDriveOk( p, pObj, pCellNew ) )
continue; continue;
// set new cell // set new cell
Abc_SclObjSetCell( p, pObj, pCellNew ); Abc_SclObjSetCell( pObj, pCellNew );
Abc_SclUpdateLoad( p, pObj, pCellOld, pCellNew ); Abc_SclUpdateLoad( p, pObj, pCellOld, pCellNew );
// recompute timing // recompute timing
Abc_SclTimeCone( p, vNodes ); Abc_SclTimeCone( p, vNodes );
// set old cell // set old cell
Abc_SclObjSetCell( p, pObj, pCellOld ); Abc_SclObjSetCell( pObj, pCellOld );
Abc_SclLoadRestore( p, pObj ); Abc_SclLoadRestore( p, pObj );
// evaluate gain // evaluate gain
dGain = 0.0; dGain = 0.0;
Abc_NtkForEachObjVec( vEvals, p->pNtk, pTemp, k ) Abc_NtkForEachObjVec( vEvals, p->pNtk, pTemp, k )
if ( Abc_SclObjLegal(p, pTemp, p->MaxDelay0) ) 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 else
break; break;
if ( k < Vec_IntSize(vEvals) ) if ( k < Vec_IntSize(vEvals) )
...@@ -148,13 +151,13 @@ clk = Abc_Clock(); ...@@ -148,13 +151,13 @@ clk = Abc_Clock();
} }
} }
// put back old cell and timing // put back old cell and timing
Abc_SclObjSetCell( p, pObj, pCellOld ); Abc_SclObjSetCell( pObj, pCellOld );
Abc_SclConeRestore( p, vNodes ); Abc_SclConeRestore( p, vNodes );
p->timeSize += Abc_Clock() - clk; p->timeSize += Abc_Clock() - clk;
if ( gateBest >= 0 ) if ( gateBest >= 0 )
{ {
pCellNew = SC_LibCell( p->pLib, gateBest ); pCellNew = SC_LibCell( p->pLib, gateBest );
Abc_SclObjSetCell( p, pObj, pCellNew ); Abc_SclObjSetCell( pObj, pCellNew );
p->SumArea += pCellNew->area - pCellOld->area; p->SumArea += pCellNew->area - pCellOld->area;
// printf( "%f %f -> %f\n", pCellNew->area - pCellOld->area, p->SumArea - (pCellNew->area - pCellOld->area), p->SumArea ); // 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 ); // 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 ) ...@@ -187,7 +190,7 @@ void Abc_NtkCollectNodesByArea( SC_Man * p, Abc_Ntk_t * pNtk )
Abc_NtkForEachNode( pNtk, pObj, i ) Abc_NtkForEachNode( pNtk, pObj, i )
if ( Abc_ObjFaninNum(pObj) > 0 ) 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) ); Vec_QuePush( p->vNodeByGain, Abc_ObjId(pObj) );
} }
} }
...@@ -267,7 +270,7 @@ void Abc_SclDnsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars ...@@ -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 = Abc_SclManStart( pLib, pNtk, pPars->fUseWireLoads, pPars->fUseDept, SC_LibTimeFromPs(pLib, pPars->DelayUser), pPars->BuffTreeEst );
p->timeTotal = Abc_Clock(); p->timeTotal = Abc_Clock();
assert( p->vGatesBest == NULL ); assert( p->vGatesBest == NULL );
p->vGatesBest = Vec_IntDup( p->vGates ); p->vGatesBest = Vec_IntDup( p->pNtk->vGates );
// perform upsizing // perform upsizing
vNodes = Vec_IntAlloc( 1000 ); vNodes = Vec_IntAlloc( 1000 );
...@@ -342,7 +345,7 @@ void Abc_SclDnsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars ...@@ -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 ); printf( "Gate sizing timed out at %d seconds.\n", pPars->TimeOut );
// save the result and quit // 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_SclManFree( p );
// Abc_NtkCleanMarkAB( pNtk ); // Abc_NtkCleanMarkAB( pNtk );
} }
......
...@@ -749,6 +749,7 @@ static int Abc_SclCompareCells( SC_Cell ** pp1, SC_Cell ** pp2 ) ...@@ -749,6 +749,7 @@ static int Abc_SclCompareCells( SC_Cell ** pp1, SC_Cell ** pp2 )
} }
void Abc_SclLinkCells( SC_Lib * p ) void Abc_SclLinkCells( SC_Lib * p )
{ {
Vec_Ptr_t * vList;
SC_Cell * pCell, * pRepr = NULL; SC_Cell * pCell, * pRepr = NULL;
int i, k; int i, k;
assert( Vec_PtrSize(p->vCellClasses) == 0 ); assert( Vec_PtrSize(p->vCellClasses) == 0 );
...@@ -770,30 +771,69 @@ void Abc_SclLinkCells( SC_Lib * p ) ...@@ -770,30 +771,69 @@ void Abc_SclLinkCells( SC_Lib * p )
pRepr->pPrev->pNext = pCell; pCell->pNext = pRepr; pRepr->pPrev->pNext = pCell; pCell->pNext = pRepr;
pCell->pPrev = pRepr->pPrev; pRepr->pPrev = pCell; 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 ); qsort( (void *)Vec_PtrArray(p->vCellClasses), Vec_PtrSize(p->vCellClasses), sizeof(void *), (int(*)(const void *,const void *))Abc_SclCompareCells );
// sort cell lists // sort cell lists
vList = Vec_PtrAlloc( 100 );
SC_LibForEachCellClass( p, pRepr, k ) SC_LibForEachCellClass( p, pRepr, k )
{ {
Vec_Ptr_t * vList = Vec_PtrAlloc( 100 ); Vec_PtrClear( vList );
SC_RingForEachCell( pRepr, pCell, i ) SC_RingForEachCell( pRepr, pCell, i )
Vec_PtrPush( vList, pCell ); Vec_PtrPush( vList, pCell );
qsort( (void *)Vec_PtrArray(vList), Vec_PtrSize(vList), sizeof(void *), (int(*)(const void *,const void *))Abc_SclCompareCells ); qsort( (void *)Vec_PtrArray(vList), Vec_PtrSize(vList), sizeof(void *), (int(*)(const void *,const void *))Abc_SclCompareCells );
// create new representative // create new representative
pRepr = (SC_Cell *)Vec_PtrEntry( vList, 0 ); pRepr = (SC_Cell *)Vec_PtrEntry( vList, 0 );
pRepr->pNext = pRepr->pPrev = pRepr; pRepr->pNext = pRepr->pPrev = pRepr;
pRepr->pRepr = pRepr;
pRepr->pAve = (SC_Cell *)Vec_PtrEntry( vList, Vec_PtrSize(vList)/2 );
pRepr->Order = 0; pRepr->Order = 0;
pRepr->nGates = Vec_PtrSize(vList);
// relink cells // relink cells
Vec_PtrForEachEntryStart( SC_Cell *, vList, pCell, i, 1 ) Vec_PtrForEachEntryStart( SC_Cell *, vList, pCell, i, 1 )
{ {
pRepr->pPrev->pNext = pCell; pCell->pNext = pRepr; pRepr->pPrev->pNext = pCell; pCell->pNext = pRepr;
pCell->pPrev = pRepr->pPrev; pRepr->pPrev = pCell; 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->Order = i;
pCell->nGates = Vec_PtrSize(vList);
} }
// update list // update list
Vec_PtrWriteEntry( p->vCellClasses, k, pRepr ); 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************************************************************* /**Function*************************************************************
...@@ -1066,8 +1106,8 @@ void Abc_SclPrintCells( SC_Lib * p, float Slew, float Gain ) ...@@ -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( "D =%6.0f ps ", 0.01 * ED * Gain + PD );
printf( "ED =%6.0f ps ", ED ); printf( "ED =%6.0f ps ", ED );
printf( "PD =%6.0f ps ", PD ); printf( "PD =%6.0f ps ", PD );
printf( "C =%5.1f ff ", Abc_SclGatePinCapAve(p, pCell) ); printf( "C =%5.1f ff ", SC_CellPinCapAve(pCell) );
printf( "Lm =%5.1f ff ", 0.01 * Gain * Abc_SclGatePinCapAve(p, 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( "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( "Lm2 =%5.0f ff ", SC_CellPin(pCell, pCell->n_inputs)->max_out_cap );
printf( "\n" ); printf( "\n" );
......
...@@ -178,7 +178,10 @@ struct SC_Cell_ ...@@ -178,7 +178,10 @@ struct SC_Cell_
int n_outputs; // -- 'pins[n_inputs .. n_inputs+n_outputs-1]' are output pins 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 * pNext; // same-functionality cells linked into a ring by area
SC_Cell * pPrev; // 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 Order; // order of the gate in the list
int nGates; // the number of gates in the list
}; };
struct SC_Lib_ struct SC_Lib_
...@@ -211,6 +214,7 @@ static inline SC_Cell * SC_LibCell( SC_Lib * p, int i ) { return (SC ...@@ -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 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 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_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_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; } 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_ ...@@ -519,7 +523,7 @@ static inline void Scl_LibPinDeparture( SC_Timing * pTime, SC_Pair * pDepIn, SC_
/**Function************************************************************* /**Function*************************************************************
Synopsis [Computes input capacitance.] Synopsis [Compute one timing edge.]
Description [] Description []
...@@ -528,17 +532,32 @@ static inline void Scl_LibPinDeparture( SC_Timing * pTime, SC_Pair * pDepIn, SC_ ...@@ -528,17 +532,32 @@ static inline void Scl_LibPinDeparture( SC_Timing * pTime, SC_Pair * pDepIn, SC_
SeeAlso [] 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; SC_Pin * pPin;
int k; SC_Timings * pRTime;
float Cap = 0.0; SC_Timing * pTime;
SC_CellForEachPinIn( pCell, pPin, k ) SC_Pair Load = { load, load };
Cap += 0.5 * (pPin->rise_cap + pPin->fall_cap); SC_Pair ArrIn = { 0.0, 0.0 };
return Cap / pCell->n_inputs; 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 ===============================================================*/ /*=== sclLib.c ===============================================================*/
extern SC_Lib * Abc_SclRead( char * pFileName ); extern SC_Lib * Abc_SclRead( char * pFileName );
extern void Abc_SclWrite( char * pFileName, SC_Lib * p ); extern void Abc_SclWrite( char * pFileName, SC_Lib * p );
...@@ -550,6 +569,8 @@ extern int Abc_SclCellFind( SC_Lib * p, char * pName ); ...@@ -550,6 +569,8 @@ extern int Abc_SclCellFind( SC_Lib * p, char * pName );
extern int Abc_SclClassCellNum( SC_Cell * pClass ); extern int Abc_SclClassCellNum( SC_Cell * pClass );
extern void Abc_SclLinkCells( SC_Lib * p ); extern void Abc_SclLinkCells( SC_Lib * p );
extern void Abc_SclPrintCells( SC_Lib * p, float Slew, float Gain ); 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_SclFindWireLoadModel( SC_Lib * p, float Area );
extern SC_WireLoad * Abc_SclFetchWireLoadModel( SC_Lib * p, char * pName ); 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 ); extern void Abc_SclDumpGenlib( char * pFileName, SC_Lib * p, float Slew, float Gain, int nGatesMin );
......
...@@ -94,7 +94,7 @@ void Abc_SclComputeLoad( SC_Man * p ) ...@@ -94,7 +94,7 @@ void Abc_SclComputeLoad( SC_Man * p )
// add cell load // add cell load
Abc_NtkForEachNode1( p->pNtk, pObj, i ) Abc_NtkForEachNode1( p->pNtk, pObj, i )
{ {
SC_Cell * pCell = Abc_SclObjCell( p, pObj ); SC_Cell * pCell = Abc_SclObjCell( pObj );
Abc_ObjForEachFanin( pObj, pFanin, k ) Abc_ObjForEachFanin( pObj, pFanin, k )
{ {
SC_Pair * pLoad = Abc_SclObjLoad( p, pFanin ); SC_Pair * pLoad = Abc_SclObjLoad( p, pFanin );
...@@ -142,7 +142,7 @@ void Abc_SclComputeLoad( SC_Man * p ) ...@@ -142,7 +142,7 @@ void Abc_SclComputeLoad( SC_Man * p )
} }
} }
// calculate average load // calculate average load
if ( p->EstLoadMax ) // if ( p->EstLoadMax )
{ {
double TotalLoad = 0; double TotalLoad = 0;
int nObjs = 0; int nObjs = 0;
...@@ -194,7 +194,7 @@ void Abc_SclUpdateLoadSplit( SC_Man * p, Abc_Obj_t * pBuffer, Abc_Obj_t * pFanou ...@@ -194,7 +194,7 @@ void Abc_SclUpdateLoadSplit( SC_Man * p, Abc_Obj_t * pBuffer, Abc_Obj_t * pFanou
int iFanin = Abc_NodeFindFanin( pFanout, pBuffer ); int iFanin = Abc_NodeFindFanin( pFanout, pBuffer );
assert( iFanin >= 0 ); assert( iFanin >= 0 );
assert( Abc_ObjFaninNum(pBuffer) == 1 ); 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 // update load of the buffer
pLoad = Abc_SclObjLoad( p, pBuffer ); pLoad = Abc_SclObjLoad( p, pBuffer );
pLoad->rise -= pPin->rise_cap; pLoad->rise -= pPin->rise_cap;
......
...@@ -108,7 +108,7 @@ Abc_Obj_t * Abc_SclFindMostCriticalFanin( SC_Man * p, int * pfRise, Abc_Obj_t * ...@@ -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 ) 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( "%6d : ", Abc_ObjId(pObj) );
printf( "%d ", Abc_ObjFaninNum(pObj) ); printf( "%d ", Abc_ObjFaninNum(pObj) );
printf( "%4d ", Abc_ObjFanoutNum(pObj) ); printf( "%4d ", Abc_ObjFanoutNum(pObj) );
...@@ -118,7 +118,7 @@ static inline void Abc_SclTimeNodePrint( SC_Man * p, Abc_Obj_t * pObj, int fRise ...@@ -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( "%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( "%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( "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( "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( "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 ); 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 ) ...@@ -132,10 +132,13 @@ void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll, int fPrintPath )
float maxDelay = Abc_SclObjTimePs(p, pPivot, fRise); float maxDelay = Abc_SclObjTimePs(p, pPivot, fRise);
p->ReportDelay = maxDelay; p->ReportDelay = maxDelay;
printf( "WireLoad model = \"%s\". ", p->pWLoadUsed ? p->pWLoadUsed->pName : "none" ); printf( "WireLoad model = \"%s\" ", p->pWLoadUsed ? p->pWLoadUsed->pName : "none" );
printf( "Gates = %6d. ", Abc_NtkNodeNum(p->pNtk) ); printf( "Gates = %6d ", Abc_NtkNodeNum(p->pNtk) );
printf( "Area = %12.2f. ", Abc_SclGetTotalArea( p ) ); printf( "Cave = %5.1f ", p->EstLoadAve );
printf( "Critical delay = %8.2f ps\n", maxDelay ); 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 ) if ( !fPrintPath )
return; return;
...@@ -145,7 +148,7 @@ void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll, int fPrintPath ) ...@@ -145,7 +148,7 @@ void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll, int fPrintPath )
// find the longest cell name // find the longest cell name
Abc_NtkForEachNodeReverse( p->pNtk, pObj, i ) Abc_NtkForEachNodeReverse( p->pNtk, pObj, i )
if ( Abc_ObjFaninNum(pObj) > 0 ) 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 // print timing
Abc_NtkForEachNodeReverse( p->pNtk, pObj, i ) Abc_NtkForEachNodeReverse( p->pNtk, pObj, i )
if ( Abc_ObjFaninNum(pObj) > 0 ) if ( Abc_ObjFaninNum(pObj) > 0 )
...@@ -160,7 +163,7 @@ void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll, int fPrintPath ) ...@@ -160,7 +163,7 @@ void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll, int fPrintPath )
while ( pObj && Abc_ObjIsNode(pObj) ) while ( pObj && Abc_ObjIsNode(pObj) )
{ {
i++; 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 ); pObj = Abc_SclFindMostCriticalFanin( p, &fRise, pObj );
} }
// print timing // print timing
...@@ -244,7 +247,7 @@ void Abc_SclTimeNode( SC_Man * p, Abc_Obj_t * pObj, int fDept ) ...@@ -244,7 +247,7 @@ void Abc_SclTimeNode( SC_Man * p, Abc_Obj_t * pObj, int fDept )
p->nEstNodes++; p->nEstNodes++;
} }
// get the library cell // get the library cell
pCell = Abc_SclObjCell( p, pObj ); pCell = Abc_SclObjCell( pObj );
// get the output pin // get the output pin
// assert( pCell->n_outputs == 1 ); // assert( pCell->n_outputs == 1 );
pPin = SC_CellPin( pCell, pCell->n_inputs ); pPin = SC_CellPin( pCell, pCell->n_inputs );
...@@ -287,7 +290,7 @@ void Abc_SclTimeCone( SC_Man * p, Vec_Int_t * vCone ) ...@@ -287,7 +290,7 @@ void Abc_SclTimeCone( SC_Man * p, Vec_Int_t * vCone )
Abc_NtkForEachObjVec( vCone, p->pNtk, pObj, i ) Abc_NtkForEachObjVec( vCone, p->pNtk, pObj, i )
{ {
if ( fVerbose && Abc_ObjIsNode(pObj) ) 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) ) if ( fVerbose && Abc_ObjIsNode(pObj) )
printf( " before (%6.1f ps %6.1f ps) ", Abc_SclObjTimePs(p, pObj, 1), Abc_SclObjTimePs(p, pObj, 0) ); printf( " before (%6.1f ps %6.1f ps) ", Abc_SclObjTimePs(p, pObj, 1), Abc_SclObjTimePs(p, pObj, 0) );
Abc_SclTimeNode( 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 ...@@ -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->EstLoadMax = 0.01 * nTreeCRatio; // max ratio of Cout/Cave when the estimation is used
p->EstLinear = 100; // linear coefficient p->EstLinear = 100; // linear coefficient
} }
assert( p->vGates == NULL ); Abc_SclMioGates2SclGates( pLib, pNtk );
p->vGates = Abc_SclManFindGates( pLib, pNtk );
Abc_SclManReadSlewAndLoad( p, pNtk ); Abc_SclManReadSlewAndLoad( p, pNtk );
if ( fUseWireLoads ) if ( fUseWireLoads )
{ {
...@@ -605,7 +607,7 @@ float Abc_SclCountNonBufferLoadInt( SC_Man * p, Abc_Obj_t * pObj ) ...@@ -605,7 +607,7 @@ float Abc_SclCountNonBufferLoadInt( SC_Man * p, Abc_Obj_t * pObj )
Abc_ObjForEachFanout( pObj, pFanout, i ) Abc_ObjForEachFanout( pObj, pFanout, i )
Load += Abc_SclCountNonBufferLoadInt( p, pFanout ); Load += Abc_SclCountNonBufferLoadInt( p, pFanout );
Load += 0.5 * Abc_SclObjLoad(p, pObj)->rise + 0.5 * Abc_SclObjLoad(p, pObj)->fall; 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; return Load;
} }
float Abc_SclCountNonBufferLoad( SC_Man * p, Abc_Obj_t * pObj ) 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 ) ...@@ -631,7 +633,7 @@ void Abc_SclPrintBuffersOne( SC_Man * p, Abc_Obj_t * pObj, int nOffset )
Abc_SclCountNonBufferFanouts(pObj) ); Abc_SclCountNonBufferFanouts(pObj) );
for ( ; i < 4; i++ ) for ( ; i < 4; i++ )
printf( " " ); 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( "d = (" );
printf( "%6.0f ps; ", Abc_SclObjTimePs(p, pObj, 1) ); printf( "%6.0f ps; ", Abc_SclObjTimePs(p, pObj, 1) );
printf( "%6.0f ps) ", Abc_SclObjTimePs(p, pObj, 0) ); 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 ) ...@@ -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) ); printf( "%d : %.0f ", i, 0.5 * (Abc_SclObjLoad(p, pObj)->fall + Abc_SclObjLoad(p, pObj)->rise) );
Abc_ObjForEachFanout( pObj, pFanout, k ) Abc_ObjForEachFanout( pObj, pFanout, k )
printf( "%.1f ", Abc_SclGatePinCapAve(p->pLib, Abc_SclObjCell(p, pFanout)) ); printf( "%.1f ", SC_CellPinCapAve(Abc_SclObjCell(pFanout)) );
printf( "\n" ); printf( "\n" );
*/ */
// skip non-critical nodes // skip non-critical nodes
......
...@@ -47,7 +47,7 @@ struct SC_Man_ ...@@ -47,7 +47,7 @@ struct SC_Man_
Abc_Ntk_t * pNtk; // network Abc_Ntk_t * pNtk; // network
int nObjs; // allocated size int nObjs; // allocated size
// get assignment // 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 * vGatesBest; // best gate sizes found so far
Vec_Int_t * vUpdates; // sizing updates in this round Vec_Int_t * vUpdates; // sizing updates in this round
Vec_Int_t * vUpdates2; // sizing updates in this round Vec_Int_t * vUpdates2; // sizing updates in this round
...@@ -99,8 +99,9 @@ struct SC_Man_ ...@@ -99,8 +99,9 @@ struct SC_Man_
/// MACRO DEFINITIONS /// /// 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 SC_Lib * Abc_SclObjLib( Abc_Obj_t * p ) { return (SC_Lib *)p->pNtk->pSCLib; }
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_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_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); } 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 ) ...@@ -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 ) static inline void Abc_SclManFree( SC_Man * p )
{ {
p->pNtk->pSCLib = NULL;
Vec_IntFreeP( &p->pNtk->vGates );
Vec_IntFreeP( &p->vNodeIter ); Vec_IntFreeP( &p->vNodeIter );
Vec_QueFreeP( &p->vNodeByGain ); Vec_QueFreeP( &p->vNodeByGain );
Vec_FltFreeP( &p->vNode2Gain ); Vec_FltFreeP( &p->vNode2Gain );
...@@ -191,7 +194,7 @@ static inline void Abc_SclManFree( SC_Man * p ) ...@@ -191,7 +194,7 @@ static inline void Abc_SclManFree( SC_Man * p )
Vec_QueCheck( p->vQue ); Vec_QueCheck( p->vQue );
Vec_QueFreeP( &p->vQue ); Vec_QueFreeP( &p->vQue );
Vec_FltFreeP( &p->vTimesOut ); Vec_FltFreeP( &p->vTimesOut );
Vec_IntFreeP( &p->vGates ); // Vec_IntFreeP( &p->vGates );
Vec_IntFreeP( &p->vBestFans ); Vec_IntFreeP( &p->vBestFans );
ABC_FREE( p->pLoads ); ABC_FREE( p->pLoads );
ABC_FREE( p->pDepts ); ABC_FREE( p->pDepts );
...@@ -349,7 +352,7 @@ static inline float Abc_SclGetTotalArea( SC_Man * p ) ...@@ -349,7 +352,7 @@ static inline float Abc_SclGetTotalArea( SC_Man * p )
Abc_Obj_t * pObj; Abc_Obj_t * pObj;
int i; int i;
Abc_NtkForEachNode1( p->pNtk, pObj, i ) Abc_NtkForEachNode1( p->pNtk, pObj, i )
Area += Abc_SclObjCell( p, pObj )->area; Area += Abc_SclObjCell(pObj)->area;
return Area; return Area;
} }
static inline float Abc_SclGetMaxDelay( SC_Man * p ) static inline float Abc_SclGetMaxDelay( SC_Man * p )
...@@ -389,7 +392,7 @@ static inline float Abc_SclReadMaxDelay( 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 ) 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 ) if ( fUpsize )
return pOld->pNext->Order > pOld->Order ? pOld->pNext : NULL; return pOld->pNext->Order > pOld->Order ? pOld->pNext : NULL;
else else
...@@ -435,10 +438,13 @@ static inline void Abc_SclDumpStats( SC_Man * p, char * pFileName, abctime Time ...@@ -435,10 +438,13 @@ static inline void Abc_SclDumpStats( SC_Man * p, char * pFileName, abctime Time
fclose( pTable ); 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 ===============================================================*/ /*=== sclBuffer.c ===============================================================*/
extern int Abc_SclIsInv( Abc_Obj_t * pObj ); 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_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_SclUnBufferPerform( Abc_Ntk_t * pNtk, int fVerbose );
extern Abc_Ntk_t * Abc_SclUnBufferPhase( 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 ); 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 ...@@ -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 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 ); extern int Abc_SclInputDriveOk( SC_Man * p, Abc_Obj_t * pObj, SC_Cell * pCell );
/*=== sclUpsize.c ===============================================================*/ /*=== sclUpsize.c ===============================================================*/
extern int Abc_SclCountNearCriticalNodes( SC_Man * p );
extern void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars ); extern void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars );
/*=== sclUtil.c ===============================================================*/ /*=== sclUtil.c ===============================================================*/
extern Vec_Int_t * Abc_SclManFindGates( SC_Lib * pLib, Abc_Ntk_t * p ); extern void Abc_SclMioGates2SclGates( 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_SclSclGates2MioGates( SC_Lib * pLib, Abc_Ntk_t * p );
extern void Abc_SclPrintGateSizes( 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 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 ABC_NAMESPACE_HEADER_END
......
...@@ -181,6 +181,20 @@ void Abc_SclUnmarkCriticalNodeWindow( SC_Man * p, Vec_Int_t * vPath ) ...@@ -181,6 +181,20 @@ void Abc_SclUnmarkCriticalNodeWindow( SC_Man * p, Vec_Int_t * vPath )
Abc_NtkForEachObjVec( vPath, p->pNtk, pObj, i ) Abc_NtkForEachObjVec( vPath, p->pNtk, pObj, i )
pObj->fMarkA = 0; 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************************************************************* /**Function*************************************************************
...@@ -261,7 +275,7 @@ int Abc_SclFindBestCell( SC_Man * p, Abc_Obj_t * pObj, Vec_Int_t * vRecalcs, Vec ...@@ -261,7 +275,7 @@ int Abc_SclFindBestCell( SC_Man * p, Abc_Obj_t * pObj, Vec_Int_t * vRecalcs, Vec
float dGain, dGainBest, gGainCur; float dGain, dGainBest, gGainCur;
int k, n, gateBest; int k, n, gateBest;
// save old gate, timing, fanin load // save old gate, timing, fanin load
pCellOld = Abc_SclObjCell( p, pObj ); pCellOld = Abc_SclObjCell( pObj );
Abc_SclConeStore( p, vRecalcs ); Abc_SclConeStore( p, vRecalcs );
Abc_SclLoadStore( p, pObj ); Abc_SclLoadStore( p, pObj );
// try different gate sizes for this node // 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 ...@@ -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 ) ) if ( p->pInDrive && !Abc_SclInputDriveOk( p, pObj, pCellNew ) )
continue; continue;
// set new cell // set new cell
Abc_SclObjSetCell( p, pObj, pCellNew ); Abc_SclObjSetCell( pObj, pCellNew );
Abc_SclUpdateLoad( p, pObj, pCellOld, pCellNew ); Abc_SclUpdateLoad( p, pObj, pCellOld, pCellNew );
// recompute timing // recompute timing
Abc_SclTimeCone( p, vRecalcs ); Abc_SclTimeCone( p, vRecalcs );
// set old cell // set old cell
Abc_SclObjSetCell( p, pObj, pCellOld ); Abc_SclObjSetCell( pObj, pCellOld );
Abc_SclLoadRestore( p, pObj ); Abc_SclLoadRestore( p, pObj );
// evaluate gain // evaluate gain
dGain = 0.0; dGain = 0.0;
...@@ -299,7 +313,7 @@ int Abc_SclFindBestCell( SC_Man * p, Abc_Obj_t * pObj, Vec_Int_t * vRecalcs, Vec ...@@ -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 // put back old cell and timing
Abc_SclObjSetCell( p, pObj, pCellOld ); Abc_SclObjSetCell( pObj, pCellOld );
Abc_SclConeRestore( p, vRecalcs ); Abc_SclConeRestore( p, vRecalcs );
*pGainBest = dGainBest; *pGainBest = dGainBest;
return gateBest; return gateBest;
...@@ -438,11 +452,11 @@ int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notc ...@@ -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(pFanin) );
Vec_IntPush( p->vUpdates2, Abc_ObjId(pBuf) ); Vec_IntPush( p->vUpdates2, Abc_ObjId(pBuf) );
// find old and new gates // find old and new gates
pCellOld = Abc_SclObjCell( p, pFanin ); pCellOld = Abc_SclObjCell( pFanin );
pCellNew = SC_LibCell( p->pLib, Vec_IntEntry(p->vNode2Gate, iNode) ); pCellNew = SC_LibCell( p->pLib, Vec_IntEntry(p->vNode2Gate, iNode) );
// update cell // update cell
p->SumArea += pCellNew->area - pCellOld->area; p->SumArea += pCellNew->area - pCellOld->area;
Abc_SclObjSetCell( p, pFanin, pCellNew ); Abc_SclObjSetCell( pFanin, pCellNew );
// record the update // record the update
Vec_IntPush( p->vUpdates, Abc_ObjId(pFanin) ); Vec_IntPush( p->vUpdates, Abc_ObjId(pFanin) );
Vec_IntPush( p->vUpdates, pCellNew->Id ); Vec_IntPush( p->vUpdates, pCellNew->Id );
...@@ -462,7 +476,7 @@ int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notc ...@@ -462,7 +476,7 @@ int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notc
// check if the node became useless // check if the node became useless
if ( Abc_ObjFanoutNum(pBuf) == 0 ) if ( Abc_ObjFanoutNum(pBuf) == 0 )
{ {
pCellOld = Abc_SclObjCell( p, pBuf ); pCellOld = Abc_SclObjCell( pBuf );
p->SumArea -= pCellOld->area; p->SumArea -= pCellOld->area;
Abc_NtkDeleteObj_rec( pBuf, 1 ); Abc_NtkDeleteObj_rec( pBuf, 1 );
printf( "Removed node %d.\n", iNode ); printf( "Removed node %d.\n", iNode );
...@@ -583,7 +597,7 @@ int Abc_SclFindUpsizes( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notch ...@@ -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) ); pObj = Abc_NtkObj( p->pNtk, Vec_QuePop(p->vNodeByGain) );
assert( pObj->fMarkA ); assert( pObj->fMarkA );
// find old and new gates // 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)) ); pCellNew = SC_LibCell( p->pLib, Vec_IntEntry(p->vNode2Gate, Abc_ObjId(pObj)) );
assert( pCellNew != NULL ); assert( pCellNew != NULL );
//printf( "%6d %20s -> %20s ", Abc_ObjId(pObj), pCellOld->pName, pCellNew->pName ); //printf( "%6d %20s -> %20s ", Abc_ObjId(pObj), pCellOld->pName, pCellNew->pName );
...@@ -622,7 +636,7 @@ return Limit; ...@@ -622,7 +636,7 @@ return Limit;
// printf( "%.1f ", Vec_FltEntry(p->vNode2Gain, iNode) ); // printf( "%.1f ", Vec_FltEntry(p->vNode2Gain, iNode) );
// find old and new gates // 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)) ); pCellNew = SC_LibCell( p->pLib, Vec_IntEntry(p->vNode2Gate, Abc_ObjId(pObj)) );
assert( pCellNew != NULL ); assert( pCellNew != NULL );
//printf( "%6d %20s -> %20s ", Abc_ObjId(pObj), pCellOld->pName, pCellNew->pName ); //printf( "%6d %20s -> %20s ", Abc_ObjId(pObj), pCellOld->pName, pCellNew->pName );
...@@ -630,7 +644,7 @@ return Limit; ...@@ -630,7 +644,7 @@ return Limit;
// update gate // update gate
Abc_SclUpdateLoad( p, pObj, pCellOld, pCellNew ); Abc_SclUpdateLoad( p, pObj, pCellOld, pCellNew );
p->SumArea += pCellNew->area - pCellOld->area; p->SumArea += pCellNew->area - pCellOld->area;
Abc_SclObjSetCell( p, pObj, pCellNew ); Abc_SclObjSetCell( pObj, pCellNew );
// record the update // record the update
Vec_IntPush( p->vUpdates, Abc_ObjId(pObj) ); Vec_IntPush( p->vUpdates, Abc_ObjId(pObj) );
Vec_IntPush( p->vUpdates, pCellNew->Id ); Vec_IntPush( p->vUpdates, pCellNew->Id );
...@@ -788,7 +802,7 @@ void Abc_SclUpsizeRemoveDangling( SC_Man * p, Abc_Ntk_t * pNtk ) ...@@ -788,7 +802,7 @@ void Abc_SclUpsizeRemoveDangling( SC_Man * p, Abc_Ntk_t * pNtk )
Abc_NtkForEachNode( pNtk, pObj, i ) Abc_NtkForEachNode( pNtk, pObj, i )
if ( Abc_ObjFanoutNum(pObj) == 0 ) if ( Abc_ObjFanoutNum(pObj) == 0 )
{ {
pCell = Abc_SclObjCell( p, pObj ); pCell = Abc_SclObjCell( pObj );
p->SumArea -= pCell->area; p->SumArea -= pCell->area;
Abc_NtkDeleteObj_rec( pObj, 1 ); Abc_NtkDeleteObj_rec( pObj, 1 );
// printf( "Removed node %d.\n", i ); // printf( "Removed node %d.\n", i );
...@@ -834,7 +848,7 @@ void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars ...@@ -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 = Abc_SclManStart( pLib, pNtk, pPars->fUseWireLoads, pPars->fUseDept, 0, pPars->BuffTreeEst );
p->timeTotal = Abc_Clock(); p->timeTotal = Abc_Clock();
assert( p->vGatesBest == NULL ); assert( p->vGatesBest == NULL );
p->vGatesBest = Vec_IntDup( p->vGates ); p->vGatesBest = Vec_IntDup( p->pNtk->vGates );
p->BestDelay = p->MaxDelay0; p->BestDelay = p->MaxDelay0;
// perform upsizing // perform upsizing
...@@ -893,7 +907,7 @@ void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars ...@@ -893,7 +907,7 @@ void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars
if ( p->BestDelay > p->MaxDelay ) if ( p->BestDelay > p->MaxDelay )
{ {
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 ); Vec_IntClear( p->vUpdates2 );
nFramesNoChange = 0; nFramesNoChange = 0;
} }
...@@ -920,7 +934,7 @@ void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars ...@@ -920,7 +934,7 @@ void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars
break; break;
} }
// update for best gates and recompute timing // 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 ) if ( pPars->BypassFreq != 0 )
Abc_SclUndoRecentChanges( p->pNtk, p->vUpdates2 ); Abc_SclUndoRecentChanges( p->pNtk, p->vUpdates2 );
if ( pPars->BypassFreq != 0 ) if ( pPars->BypassFreq != 0 )
...@@ -947,7 +961,7 @@ void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars ...@@ -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 ); printf( "Gate sizing timed out at %d seconds.\n", pPars->TimeOut );
// save the result and quit // 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_SclManFree( p );
// Abc_NtkCleanMarkAB( pNtk ); // Abc_NtkCleanMarkAB( pNtk );
} }
......
...@@ -44,29 +44,30 @@ ABC_NAMESPACE_IMPL_START ...@@ -44,29 +44,30 @@ ABC_NAMESPACE_IMPL_START
SeeAlso [] 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; Abc_Obj_t * pObj;
int i; int i;
vVec = Vec_IntStartFull( Abc_NtkObjNumMax(p) ); assert( p->vGates == NULL );
p->vGates = Vec_IntStartFull( Abc_NtkObjNumMax(p) );
Abc_NtkForEachNode1( p, pObj, i ) Abc_NtkForEachNode1( p, pObj, i )
{ {
char * pName = Mio_GateReadName((Mio_Gate_t *)pObj->pData); char * pName = Mio_GateReadName((Mio_Gate_t *)pObj->pData);
int gateId = Abc_SclCellFind( pLib, pName ); int gateId = Abc_SclCellFind( pLib, pName );
assert( gateId >= 0 ); assert( gateId >= 0 );
Vec_IntWriteEntry( vVec, i, gateId ); Vec_IntWriteEntry( p->vGates, i, gateId );
//printf( "Found gate %s\n", pName ); //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; Abc_Obj_t * pObj;
int i, Counter = 0, CounterAll = 0; int i, Counter = 0, CounterAll = 0;
assert( p->vGates != NULL );
Abc_NtkForEachNode1( p, pObj, i ) 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) ); assert( pCell->n_inputs == Abc_ObjFaninNum(pObj) );
pObj->pData = Mio_LibraryReadGateByName( (Mio_Library_t *)p->pManFunc, pCell->pName, NULL ); pObj->pData = Mio_LibraryReadGateByName( (Mio_Library_t *)p->pManFunc, pCell->pName, NULL );
Counter += (pObj->pData == NULL); Counter += (pObj->pData == NULL);
...@@ -76,6 +77,8 @@ void Abc_SclManSetGates( SC_Lib * pLib, Abc_Ntk_t * p, Vec_Int_t * vGates ) ...@@ -76,6 +77,8 @@ void Abc_SclManSetGates( SC_Lib * pLib, Abc_Ntk_t * p, Vec_Int_t * vGates )
} }
if ( Counter ) if ( Counter )
printf( "Could not find %d (out of %d) gates in the current library.\n", Counter, CounterAll ); printf( "Could not find %d (out of %d) gates in the current library.\n", Counter, CounterAll );
Vec_IntFreeP( &p->vGates );
p->pSCLib = NULL;
} }
/**Function************************************************************* /**Function*************************************************************
...@@ -119,10 +122,10 @@ void Abc_SclManPrintGateSizes( SC_Lib * pLib, Abc_Ntk_t * p, Vec_Int_t * vGates ...@@ -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 ) void Abc_SclPrintGateSizes( SC_Lib * pLib, Abc_Ntk_t * p )
{ {
Vec_Int_t * vGates; Abc_SclMioGates2SclGates( pLib, p );
vGates = Abc_SclManFindGates( pLib, p ); Abc_SclManPrintGateSizes( pLib, p, p->vGates );
Abc_SclManPrintGateSizes( pLib, p, vGates ); Vec_IntFreeP( &p->vGates );
Vec_IntFree( vGates ); p->pSCLib = NULL;
} }
/**Function************************************************************* /**Function*************************************************************
...@@ -149,13 +152,12 @@ SC_Cell * Abc_SclFindMaxAreaCell( SC_Cell * pRepr ) ...@@ -149,13 +152,12 @@ SC_Cell * Abc_SclFindMaxAreaCell( SC_Cell * pRepr )
} }
return pBest; 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; SC_Cell * pCell, * pRepr = NULL, * pBest = NULL;
Abc_Obj_t * pObj; int i, k;
int i, k, gateId; // map each gate in the library into its min/max-size prototype
// map each gate in the library into its min-size prototype
vMinCells = Vec_IntStartFull( Vec_PtrSize(pLib->vCells) ); vMinCells = Vec_IntStartFull( Vec_PtrSize(pLib->vCells) );
SC_LibForEachCellClass( pLib, pRepr, i ) SC_LibForEachCellClass( pLib, pRepr, i )
{ {
...@@ -163,21 +165,39 @@ void Abc_SclMinsizePerform( SC_Lib * pLib, Abc_Ntk_t * p, int fUseMax, int fVerb ...@@ -163,21 +165,39 @@ void Abc_SclMinsizePerform( SC_Lib * pLib, Abc_Ntk_t * p, int fUseMax, int fVerb
SC_RingForEachCell( pRepr, pCell, k ) SC_RingForEachCell( pRepr, pCell, k )
Vec_IntWriteEntry( vMinCells, pCell->Id, pBest->Id ); Vec_IntWriteEntry( vMinCells, pCell->Id, pBest->Id );
} }
// update each cell return vMinCells;
vGates = Abc_SclManFindGates( pLib, p ); }
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 ) Abc_NtkForEachNode1( p, pObj, i )
{ {
gateId = Vec_IntEntry( vGates, i ); gateId = Vec_IntEntry( p->vGates, i );
// if ( SC_LibCell(pLib, gateId)->n_outputs > 1 )
// continue;
assert( gateId >= 0 && gateId < Vec_PtrSize(pLib->vCells) ); assert( gateId >= 0 && gateId < Vec_PtrSize(pLib->vCells) );
gateId = Vec_IntEntry( vMinCells, gateId ); gateId = Vec_IntEntry( vMinCells, gateId );
assert( gateId >= 0 && gateId < Vec_PtrSize(pLib->vCells) ); 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( vMinCells );
Vec_IntFree( vGates ); return Counter;
} }
/**Function************************************************************* /**Function*************************************************************
......
...@@ -336,6 +336,11 @@ static inline float Vec_FltEntry( Vec_Flt_t * p, int i ) ...@@ -336,6 +336,11 @@ static inline float Vec_FltEntry( Vec_Flt_t * p, int i )
assert( i >= 0 && i < p->nSize ); assert( i >= 0 && i < p->nSize );
return p->pArray[i]; 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************************************************************* /**Function*************************************************************
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment