mirror of https://github.com/YosysHQ/abc.git
Improvements to buffering and sizing.
This commit is contained in:
parent
4be8eba9d9
commit
95684b044a
|
|
@ -34,6 +34,7 @@ struct Bus_Man_t_
|
|||
// parameters
|
||||
float Gain; // target gain
|
||||
int nDegree; // max branching factor
|
||||
int fAddBufs; // add buffers
|
||||
int fBufPis; // use CI buffering
|
||||
int fVerbose; // verbose
|
||||
// user data
|
||||
|
|
@ -50,11 +51,11 @@ struct Bus_Man_t_
|
|||
|
||||
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 void Bus_SclObjSetCin( Abc_Obj_t * p, float cap ) { Vec_FltWriteEntry( Bus_SclObjMan(p)->vCins, Abc_ObjId(p), cap ); }
|
||||
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 void Bus_SclObjSetLoad( Abc_Obj_t * p, float cap ) { Vec_FltWriteEntry( Bus_SclObjMan(p)->vLoads, Abc_ObjId(p), cap ); }
|
||||
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; }
|
||||
static inline void Bus_SclObjUpdateDept( Abc_Obj_t * p, float time ) { float *q = Vec_FltEntryP( Bus_SclObjMan(p)->vDepts, Abc_ObjId(p) ); if (*q < time) *q = time; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
|
|
@ -71,17 +72,18 @@ static inline void Bus_SclObjUpdateDept( Abc_Obj_t * p, float dept ) { f
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Bus_Man_t * Bus_ManStart( Abc_Ntk_t * pNtk, SC_Lib * pLib, int GainRatio, int nDegree, int fBufPis, int fVerbose )
|
||||
Bus_Man_t * Bus_ManStart( Abc_Ntk_t * pNtk, SC_Lib * pLib, int GainRatio, int nDegree, int fAddBufs, int fBufPis, int fVerbose )
|
||||
{
|
||||
Bus_Man_t * p;
|
||||
p = ABC_CALLOC( Bus_Man_t, 1 );
|
||||
p->Gain = 0.01 * GainRatio;
|
||||
p->nDegree = nDegree;
|
||||
p->fAddBufs = fAddBufs;
|
||||
p->fBufPis = fBufPis;
|
||||
p->fVerbose = fVerbose;
|
||||
p->pNtk = pNtk;
|
||||
p->pLib = pLib;
|
||||
p->pInv = Abc_SclFindInvertor(pLib)->pAve;
|
||||
p->pInv = Abc_SclFindInvertor(pLib, fAddBufs)->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) );
|
||||
|
|
@ -118,7 +120,7 @@ void Bus_ManReadInOutLoads( Bus_Man_t * p )
|
|||
{
|
||||
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) );
|
||||
Bus_SclObjSetCin( pObj, SC_LibCapFromFf(p->pLib, 0.5 * pTime->Rise + 0.5 * pTime->Fall) );
|
||||
}
|
||||
if ( Abc_NodeReadInputDrive(p->pNtk, 0) != NULL )
|
||||
{
|
||||
|
|
@ -126,7 +128,7 @@ void Bus_ManReadInOutLoads( Bus_Man_t * p )
|
|||
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) );
|
||||
Bus_SclObjSetCin( pObj, SC_LibCapFromFf(p->pLib, 0.5 * pTime->Rise + 0.5 * pTime->Fall) );
|
||||
}
|
||||
}
|
||||
// read output load
|
||||
|
|
@ -135,7 +137,7 @@ void Bus_ManReadInOutLoads( Bus_Man_t * p )
|
|||
{
|
||||
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) );
|
||||
Bus_SclObjSetCin( pObj, SC_LibCapFromFf(p->pLib, 0.5 * pTime->Rise + 0.5 * pTime->Fall) );
|
||||
}
|
||||
if ( Abc_NodeReadOutputLoad(p->pNtk, 0) != NULL )
|
||||
{
|
||||
|
|
@ -143,7 +145,7 @@ void Bus_ManReadInOutLoads( Bus_Man_t * p )
|
|||
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) );
|
||||
Bus_SclObjSetCin( pObj, SC_LibCapFromFf(p->pLib, 0.5 * pTime->Rise + 0.5 * pTime->Fall) );
|
||||
}
|
||||
}
|
||||
// read arrival/required times
|
||||
|
|
@ -191,7 +193,7 @@ float Abc_NtkComputeNodeDept( Abc_Obj_t * pObj )
|
|||
continue;
|
||||
Load = Bus_SclObjLoad( pFanout );
|
||||
Dept = Bus_SclObjDept( pFanout );
|
||||
Edge = Scl_LibPinTime( Abc_SclObjCell(pFanout), Abc_NodeFindFanin(pFanout, pObj), Load );
|
||||
Edge = Scl_LibPinArrivalEstimate( Abc_SclObjCell(pFanout), Abc_NodeFindFanin(pFanout, pObj), Load );
|
||||
Bus_SclObjUpdateDept( pObj, Dept + Edge );
|
||||
assert( Edge > 0 );
|
||||
assert( Load > 0 );
|
||||
|
|
@ -208,7 +210,7 @@ void Abc_NtkUpdateFaninDeparture( Bus_Man_t * p, Abc_Obj_t * pObj, float Load )
|
|||
Dept = Bus_SclObjDept( pObj );
|
||||
Abc_ObjForEachFanin( pObj, pFanin, i )
|
||||
{
|
||||
Edge = Scl_LibPinTime( pCell, i, Load );
|
||||
Edge = Scl_LibPinArrivalEstimate( pCell, i, Load );
|
||||
Bus_SclObjUpdateDept( pFanin, Dept + Edge );
|
||||
}
|
||||
}
|
||||
|
|
@ -276,7 +278,7 @@ Abc_Obj_t * Abc_SclAddOneInv( Bus_Man_t * p, Abc_Obj_t * pObj, Vec_Ptr_t * vFano
|
|||
{
|
||||
SC_Cell * pCellNew;
|
||||
Abc_Obj_t * pFanout, * pInv;
|
||||
float Target = SC_CellPinCap( p->pInv, 0 ) * Gain;
|
||||
float Target = SC_CellPinCap(p->pInv, 0) * Gain;
|
||||
float Load = 0;
|
||||
int i, iStop;
|
||||
Vec_PtrForEachEntryStop( Abc_Obj_t *, vFanouts, pFanout, iStop, Degree )
|
||||
|
|
@ -286,7 +288,10 @@ Abc_Obj_t * Abc_SclAddOneInv( Bus_Man_t * p, Abc_Obj_t * pObj, Vec_Ptr_t * vFano
|
|||
break;
|
||||
}
|
||||
// create inverter
|
||||
pInv = Abc_NtkCreateNodeInv( p->pNtk, NULL );
|
||||
if ( p->fAddBufs )
|
||||
pInv = Abc_NtkCreateNodeBuf( p->pNtk, NULL );
|
||||
else
|
||||
pInv = Abc_NtkCreateNodeInv( p->pNtk, NULL );
|
||||
assert( (int)Abc_ObjId(pInv) < Vec_FltSize(p->vDepts) );
|
||||
Vec_PtrForEachEntryStop( Abc_Obj_t *, vFanouts, pFanout, i, iStop )
|
||||
{
|
||||
|
|
@ -358,7 +363,7 @@ Abc_Ntk_t * Abc_SclBufSizePerform( Abc_Ntk_t * pNtk, SC_Lib * pLib, int GainRati
|
|||
if ( !Abc_SclCheckNtk( pNtk, 0 ) )
|
||||
return NULL;
|
||||
Abc_SclReportDupFanins( pNtk );
|
||||
p = Bus_ManStart( pNtk, pLib, GainRatio, nDegree, fBufPis, fVerbose );
|
||||
p = Bus_ManStart( pNtk, pLib, GainRatio, nDegree, fAddBufs, fBufPis, fVerbose );
|
||||
Bus_ManReadInOutLoads( p );
|
||||
Abc_SclBufSize( p );
|
||||
Bus_ManStop( p );
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ clk = Abc_Clock();
|
|||
// save old gate, timing, fanin load
|
||||
pCellOld = Abc_SclObjCell( pObj );
|
||||
Abc_SclConeStore( p, vNodes );
|
||||
Abc_SclEvalStore( p, vEvals );
|
||||
Abc_SclLoadStore( p, pObj );
|
||||
// try different gate sizes for this node
|
||||
gateBest = -1;
|
||||
|
|
@ -131,6 +132,7 @@ clk = Abc_Clock();
|
|||
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) )
|
||||
|
|
@ -143,6 +145,10 @@ clk = Abc_Clock();
|
|||
if ( k < Vec_IntSize(vEvals) )
|
||||
continue;
|
||||
dGain /= Vec_IntSize(vEvals);
|
||||
*/
|
||||
dGain = Abc_SclEvalPerformLegal( p, vEvals, p->MaxDelay0 );
|
||||
if ( dGain == -1 )
|
||||
continue;
|
||||
// save best gain
|
||||
if ( dGainBest < dGain )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -815,12 +815,13 @@ void Abc_SclLinkCells( SC_Lib * p )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
SC_Cell * Abc_SclFindInvertor( SC_Lib * p )
|
||||
SC_Cell * Abc_SclFindInvertor( SC_Lib * p, int fFindBuff )
|
||||
{
|
||||
SC_Cell * pCell = NULL;
|
||||
word Truth = fFindBuff ? ABC_CONST(0x5555555555555555) : ABC_CONST(0xAAAAAAAAAAAAAAAA);
|
||||
int k;
|
||||
SC_LibForEachCellClass( p, pCell, k )
|
||||
if ( pCell->n_inputs == 1 && Vec_WrdEntry(SC_CellPin(pCell, 1)->vFunc, 0) == ABC_CONST(0x5555555555555555) )
|
||||
if ( pCell->n_inputs == 1 && Vec_WrdEntry(SC_CellPin(pCell, 1)->vFunc, 0) == Truth )
|
||||
break;
|
||||
// take representative
|
||||
return pCell ? pCell->pRepr : NULL;
|
||||
|
|
@ -911,26 +912,16 @@ SC_WireLoad * Abc_SclFindWireLoadModel( SC_Lib * p, float Area )
|
|||
***********************************************************************/
|
||||
void Abc_SclComputeParametersPin( SC_Lib * p, SC_Cell * pCell, int iPin, float Slew, float * pED, float * pPD )
|
||||
{
|
||||
SC_Timings * pRTime;
|
||||
SC_Timing * pTime = NULL;
|
||||
SC_Pin * pPin;
|
||||
SC_Pair Load0, Load1, Load2;
|
||||
SC_Pair ArrIn = { 0.0, 0.0 };
|
||||
SC_Pair SlewIn = { Slew, Slew };
|
||||
SC_Pair Load0, Load1, Load2;
|
||||
SC_Pair ArrOut0 = { 0.0, 0.0 };
|
||||
SC_Pair ArrOut1 = { 0.0, 0.0 };
|
||||
SC_Pair ArrOut2 = { 0.0, 0.0 };
|
||||
SC_Pair SlewOut = { 0.0, 0.0 };
|
||||
Vec_Flt_t * vIndex;
|
||||
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 );
|
||||
SC_Timing * pTime = Scl_CellPinTime( pCell, iPin );
|
||||
Vec_Flt_t * vIndex = pTime->pCellRise->vIndex1; // capacitance
|
||||
// get load points
|
||||
vIndex = pTime->pCellRise->vIndex1; // capacitance
|
||||
Load0.rise = Load0.fall = 0.0;
|
||||
Load1.rise = Load1.fall = Vec_FltEntry( vIndex, 0 );
|
||||
Load2.rise = Load2.fall = Vec_FltEntry( vIndex, Vec_FltSize(vIndex) - 2 );
|
||||
|
|
@ -938,9 +929,9 @@ void Abc_SclComputeParametersPin( SC_Lib * p, SC_Cell * pCell, int iPin, float S
|
|||
Scl_LibPinArrival( pTime, &ArrIn, &SlewIn, &Load0, &ArrOut0, &SlewOut );
|
||||
Scl_LibPinArrival( pTime, &ArrIn, &SlewIn, &Load1, &ArrOut1, &SlewOut );
|
||||
Scl_LibPinArrival( pTime, &ArrIn, &SlewIn, &Load2, &ArrOut2, &SlewOut );
|
||||
ArrOut0.rise = 0.5 * (ArrOut0.rise + ArrOut0.fall);
|
||||
ArrOut1.rise = 0.5 * (ArrOut1.rise + ArrOut1.fall);
|
||||
ArrOut2.rise = 0.5 * (ArrOut2.rise + ArrOut2.fall);
|
||||
ArrOut0.rise = 0.5 * ArrOut0.rise + 0.5 * ArrOut0.fall;
|
||||
ArrOut1.rise = 0.5 * ArrOut1.rise + 0.5 * ArrOut1.fall;
|
||||
ArrOut2.rise = 0.5 * ArrOut2.rise + 0.5 * ArrOut2.fall;
|
||||
// get tangent
|
||||
*pED = (ArrOut2.rise - ArrOut1.rise) / ((Load2.rise - Load1.rise) / SC_CellPinCap(pCell, iPin));
|
||||
// get constant
|
||||
|
|
@ -983,7 +974,7 @@ void Abc_SclComputeParametersClassPin( SC_Lib * p, SC_Cell * pRepr, int iPin, fl
|
|||
ED = PD = ed = pd = 0;
|
||||
SC_RingForEachCell( pRepr, pCell, i )
|
||||
{
|
||||
Abc_SclComputeParametersPin( p, pCell, Slew, iPin, &ed, &pd );
|
||||
Abc_SclComputeParametersPin( p, pCell, iPin, Slew, &ed, &pd );
|
||||
ED += ed; PD += pd;
|
||||
Count++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -213,7 +213,7 @@ struct SC_Lib_
|
|||
static inline SC_Cell * SC_LibCell( SC_Lib * p, int i ) { return (SC_Cell *)Vec_PtrEntry(p->vCells, i); }
|
||||
static inline SC_Pin * SC_CellPin( SC_Cell * p, int i ) { return (SC_Pin *)Vec_PtrEntry(p->vPins, i); }
|
||||
static inline Vec_Wrd_t * SC_CellFunc( SC_Cell * p ) { return SC_CellPin(p, p->n_inputs)->vFunc; }
|
||||
static inline 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 + 0.5 * 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; }
|
||||
|
|
@ -532,30 +532,29 @@ static inline void Scl_LibPinDeparture( SC_Timing * pTime, SC_Pair * pDepIn, SC_
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline float Scl_LibPinTime( SC_Cell * pCell, int iPin, float load )
|
||||
static inline SC_Timing * Scl_CellPinTime( SC_Cell * pCell, int iPin )
|
||||
{
|
||||
SC_Pin * pPin;
|
||||
SC_Timings * pRTime;
|
||||
SC_Timing * pTime;
|
||||
assert( iPin >= 0 && iPin < pCell->n_inputs );
|
||||
pPin = SC_CellPin( pCell, pCell->n_inputs );
|
||||
assert( Vec_PtrSize(pPin->vRTimings) == pCell->n_inputs );
|
||||
pRTime = (SC_Timings *)Vec_PtrEntry( pPin->vRTimings, iPin );
|
||||
assert( Vec_PtrSize(pRTime->vTimings) == 1 );
|
||||
return (SC_Timing *)Vec_PtrEntry( pRTime->vTimings, 0 );
|
||||
}
|
||||
static inline float Scl_LibPinArrivalEstimate( SC_Cell * pCell, int iPin, float load )
|
||||
{
|
||||
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 );
|
||||
SC_Timing * pTime = Scl_CellPinTime( pCell, iPin );
|
||||
Vec_Flt_t * vIndex0 = pTime->pCellRise->vIndex0; // slew
|
||||
SlewIn.fall = SlewIn.rise = Vec_FltEntry( vIndex0, Vec_FltSize(vIndex0)/2 );
|
||||
Scl_LibPinArrival( pTime, &ArrIn, &SlewIn, &Load, &ArrOut, &SlewOut );
|
||||
return 0.5 * (ArrOut.fall + ArrOut.rise);
|
||||
return 0.5 * ArrOut.fall + 0.5 * ArrOut.rise;
|
||||
}
|
||||
|
||||
/*=== sclLib.c ===============================================================*/
|
||||
|
|
@ -569,7 +568,7 @@ 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_SclFindInvertor( SC_Lib * p, int fFindBuff );
|
||||
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 );
|
||||
|
|
|
|||
|
|
@ -205,16 +205,27 @@ static inline void Abc_SclDeptFanin( SC_Man * p, SC_Timing * pTime, Abc_Obj_t *
|
|||
SC_Pair * pDepOut = Abc_SclObjDept( p, pObj );
|
||||
Scl_LibPinDeparture( pTime, pDepIn, pSlewIn, pLoad, pDepOut );
|
||||
}
|
||||
static inline void Abc_SclDeptObj( SC_Man * p, Abc_Obj_t * pObj )
|
||||
{
|
||||
SC_Cell * pCell;
|
||||
SC_Timing * pTime;
|
||||
Abc_Obj_t * pFanout;
|
||||
int i;
|
||||
pCell = Abc_SclObjCell( pObj );
|
||||
Abc_ObjForEachFanout( pObj, pFanout, i )
|
||||
{
|
||||
pTime = Scl_CellPinTime( pCell, Abc_NodeFindFanin(pFanout, pObj) );
|
||||
Abc_SclDeptFanin( p, pTime, pFanout, pObj );
|
||||
}
|
||||
}
|
||||
static inline float Abc_SclObjLoadValue( SC_Man * p, Abc_Obj_t * pObj )
|
||||
{
|
||||
// float Value = Abc_MaxFloat(pLoad->fall, pLoad->rise) / (p->EstLoadAve * p->EstLoadMax);
|
||||
return 0.5 * (Abc_SclObjLoad(p, pObj)->fall + Abc_SclObjLoad(p, pObj)->rise) / (p->EstLoadAve * p->EstLoadMax);
|
||||
return (0.5 * Abc_SclObjLoad(p, pObj)->fall + 0.5 * Abc_SclObjLoad(p, pObj)->rise) / (p->EstLoadAve * p->EstLoadMax);
|
||||
}
|
||||
void Abc_SclTimeNode( SC_Man * p, Abc_Obj_t * pObj, int fDept )
|
||||
{
|
||||
SC_Timings * pRTime;
|
||||
SC_Timing * pTime;
|
||||
SC_Pin * pPin;
|
||||
SC_Cell * pCell;
|
||||
int k;
|
||||
SC_Pair * pLoad = Abc_SclObjLoad( p, pObj );
|
||||
|
|
@ -223,6 +234,7 @@ void Abc_SclTimeNode( SC_Man * p, Abc_Obj_t * pObj, int fDept )
|
|||
float DeptRise = 0;
|
||||
float DeptFall = 0;
|
||||
float Value = p->EstLoadMax ? Abc_SclObjLoadValue( p, pObj ) : 0;
|
||||
Abc_Obj_t * pFanin;
|
||||
if ( Abc_ObjIsCo(pObj) )
|
||||
{
|
||||
if ( !fDept )
|
||||
|
|
@ -248,19 +260,14 @@ void Abc_SclTimeNode( SC_Man * p, Abc_Obj_t * pObj, int fDept )
|
|||
}
|
||||
// get the library cell
|
||||
pCell = Abc_SclObjCell( pObj );
|
||||
// get the output pin
|
||||
// assert( pCell->n_outputs == 1 );
|
||||
pPin = SC_CellPin( pCell, pCell->n_inputs );
|
||||
// compute timing using each fanin
|
||||
assert( Vec_PtrSize(pPin->vRTimings) == pCell->n_inputs );
|
||||
SC_PinForEachRTiming( pPin, pRTime, k )
|
||||
// compute for each fanin
|
||||
Abc_ObjForEachFanin( pObj, pFanin, k )
|
||||
{
|
||||
assert( Vec_PtrSize(pRTime->vTimings) == 1 );
|
||||
pTime = (SC_Timing *)Vec_PtrEntry( pRTime->vTimings, 0 );
|
||||
pTime = Scl_CellPinTime( pCell, k );
|
||||
if ( fDept )
|
||||
Abc_SclDeptFanin( p, pTime, pObj, Abc_ObjFanin(pObj, k) );
|
||||
Abc_SclDeptFanin( p, pTime, pObj, pFanin );
|
||||
else
|
||||
Abc_SclTimeFanin( p, pTime, pObj, Abc_ObjFanin(pObj, k) );
|
||||
Abc_SclTimeFanin( p, pTime, pObj, pFanin );
|
||||
}
|
||||
if ( p->EstLoadMax && Value > 1 )
|
||||
{
|
||||
|
|
@ -385,7 +392,7 @@ void Abc_SclManReadSlewAndLoad( SC_Man * p, Abc_Ntk_t * pNtk )
|
|||
if ( p->pInDrive == NULL )
|
||||
p->pInDrive = ABC_CALLOC( float, Abc_NtkObjNumMax(pNtk) );
|
||||
Abc_NtkForEachPi( pNtk, pObj, i )
|
||||
p->pInDrive[Abc_ObjId(pObj)] = 0.5 * SC_LibCapFromFf( p->pLib, pTime->Rise ) + 0.5 * SC_LibCapFromFf( p->pLib, pTime->Fall );
|
||||
p->pInDrive[Abc_ObjId(pObj)] = SC_LibCapFromFf( p->pLib, 0.5 * pTime->Rise + 0.5 * pTime->Fall );
|
||||
}
|
||||
if ( Abc_NodeReadInputDrive(pNtk, 0) != NULL )
|
||||
{
|
||||
|
|
@ -395,7 +402,7 @@ void Abc_SclManReadSlewAndLoad( SC_Man * p, Abc_Ntk_t * pNtk )
|
|||
Abc_NtkForEachPi( pNtk, pObj, i )
|
||||
{
|
||||
pTime = Abc_NodeReadInputDrive(pNtk, i);
|
||||
p->pInDrive[Abc_ObjId(pObj)] = 0.5 * SC_LibCapFromFf( p->pLib, pTime->Rise ) + 0.5 * SC_LibCapFromFf( p->pLib, pTime->Fall );
|
||||
p->pInDrive[Abc_ObjId(pObj)] = SC_LibCapFromFf( p->pLib, 0.5 * pTime->Rise + 0.5 * pTime->Fall );
|
||||
}
|
||||
}
|
||||
// read output load
|
||||
|
|
|
|||
|
|
@ -58,6 +58,8 @@ struct SC_Man_
|
|||
SC_Pair * pSlews; // slews for each gate
|
||||
SC_Pair * pTimes2; // arrivals for each gate
|
||||
SC_Pair * pSlews2; // slews for each gate
|
||||
Vec_Flt_t * vTimes2; // backup storage for times
|
||||
Vec_Flt_t * vTimes3; // backup storage for slews
|
||||
Vec_Flt_t * vLoads2; // backup storage for loads
|
||||
Vec_Flt_t * vLoads3; // backup storage for loads
|
||||
float * pSlack; // slacks for each gatt
|
||||
|
|
@ -116,11 +118,11 @@ static inline float Abc_SclObjGetSlack( SC_Man * p, Abc_Obj_t * pObj, float
|
|||
static inline float Abc_SclObjGetSlackR( SC_Man * p, Abc_Obj_t * pObj, float D ){ return D - (Abc_SclObjTime(p, pObj)->rise + Abc_SclObjDept(p, pObj)->rise); }
|
||||
static inline float Abc_SclObjGetSlackF( SC_Man * p, Abc_Obj_t * pObj, float D ){ return D - (Abc_SclObjTime(p, pObj)->fall + Abc_SclObjDept(p, pObj)->fall); }
|
||||
static inline float Abc_SclObjSlack( SC_Man * p, Abc_Obj_t * pObj ) { return p->pSlack[Abc_ObjId(pObj)]; }
|
||||
static inline float Abc_SclObjLoadAve( SC_Man * p, Abc_Obj_t * pObj ) { return 0.5 * (Abc_SclObjLoad(p, pObj)->rise + Abc_SclObjLoad(p, pObj)->fall); }
|
||||
static inline float Abc_SclObjLoadAve( SC_Man * p, Abc_Obj_t * pObj ) { return 0.5 * Abc_SclObjLoad(p, pObj)->rise + 0.5 * Abc_SclObjLoad(p, pObj)->fall; }
|
||||
|
||||
static inline void Abc_SclObjDupFanin( SC_Man * p, Abc_Obj_t * pObj ) { assert( Abc_ObjIsCo(pObj) ); *Abc_SclObjTime(p, pObj) = *Abc_SclObjTime(p, Abc_ObjFanin0(pObj)); }
|
||||
static inline float Abc_SclObjGain( SC_Man * p, Abc_Obj_t * pObj ) { return 0.5*((Abc_SclObjTime2(p, pObj)->rise - Abc_SclObjTime(p, pObj)->rise) + (Abc_SclObjTime2(p, pObj)->fall - Abc_SclObjTime(p, pObj)->fall)); }
|
||||
static inline int Abc_SclObjLegal( SC_Man * p, Abc_Obj_t * pObj, float D ) { return Abc_SclObjTime(p, pObj)->rise <= Abc_SclObjTime2(p, pObj)->rise + Abc_SclObjGetSlackR(p, pObj, D) && Abc_SclObjTime(p, pObj)->fall <= Abc_SclObjTime2(p, pObj)->fall + Abc_SclObjGetSlackF(p, pObj, D); }
|
||||
//static inline int Abc_SclObjLegal( SC_Man * p, Abc_Obj_t * pObj, float D ) { return Abc_SclObjTime(p, pObj)->rise <= Abc_SclObjTime2(p, pObj)->rise + Abc_SclObjGetSlackR(p, pObj, D) && Abc_SclObjTime(p, pObj)->fall <= Abc_SclObjTime2(p, pObj)->fall + Abc_SclObjGetSlackF(p, pObj, D); }
|
||||
|
||||
static inline double Abc_SclObjLoadFf( SC_Man * p, Abc_Obj_t * pObj, int fRise ) { return SC_LibCapFf( p->pLib, fRise ? Abc_SclObjLoad(p, pObj)->rise : Abc_SclObjLoad(p, pObj)->fall); }
|
||||
static inline double Abc_SclObjTimePs( SC_Man * p, Abc_Obj_t * pObj, int fRise ) { return SC_LibTimePs(p->pLib, fRise ? Abc_SclObjTime(p, pObj)->rise : Abc_SclObjTime(p, pObj)->fall); }
|
||||
|
|
@ -168,6 +170,8 @@ static inline SC_Man * Abc_SclManAlloc( SC_Lib * pLib, Abc_Ntk_t * pNtk )
|
|||
p->vUpdates2 = Vec_IntAlloc( 1000 );
|
||||
p->vLoads2 = Vec_FltAlloc( 1000 );
|
||||
p->vLoads3 = Vec_FltAlloc( 1000 );
|
||||
p->vTimes2 = Vec_FltAlloc( 1000 );
|
||||
p->vTimes3 = Vec_FltAlloc( 1000 );
|
||||
// intermediate data
|
||||
p->vNode2Gain = Vec_FltStart( p->nObjs );
|
||||
p->vNode2Gate = Vec_IntStart( p->nObjs );
|
||||
|
|
@ -185,6 +189,8 @@ static inline void Abc_SclManFree( SC_Man * p )
|
|||
Vec_FltFreeP( &p->vNode2Gain );
|
||||
Vec_IntFreeP( &p->vNode2Gate );
|
||||
// intermediate data
|
||||
Vec_FltFreeP( &p->vTimes2 );
|
||||
Vec_FltFreeP( &p->vTimes3 );
|
||||
Vec_FltFreeP( &p->vLoads2 );
|
||||
Vec_FltFreeP( &p->vLoads3 );
|
||||
Vec_IntFreeP( &p->vUpdates );
|
||||
|
|
@ -233,50 +239,7 @@ static inline void Abc_SclManCleanTime( SC_Man * p )
|
|||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Stores/retrivies timing information for the logic cone.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Abc_SclConeStore( SC_Man * p, Vec_Int_t * vCone )
|
||||
{
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
Abc_NtkForEachObjVec( vCone, p->pNtk, pObj, i )
|
||||
{
|
||||
*Abc_SclObjTime2(p, pObj) = *Abc_SclObjTime(p, pObj);
|
||||
*Abc_SclObjSlew2(p, pObj) = *Abc_SclObjSlew(p, pObj);
|
||||
}
|
||||
}
|
||||
static inline void Abc_SclConeRestore( SC_Man * p, Vec_Int_t * vCone )
|
||||
{
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
Abc_NtkForEachObjVec( vCone, p->pNtk, pObj, i )
|
||||
{
|
||||
*Abc_SclObjTime(p, pObj) = *Abc_SclObjTime2(p, pObj);
|
||||
*Abc_SclObjSlew(p, pObj) = *Abc_SclObjSlew2(p, pObj);
|
||||
}
|
||||
}
|
||||
static inline void Abc_SclConeClear( SC_Man * p, Vec_Int_t * vCone )
|
||||
{
|
||||
SC_Pair Zero = { 0.0, 0.0 };
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
Abc_NtkForEachObjVec( vCone, p->pNtk, pObj, i )
|
||||
{
|
||||
*Abc_SclObjTime(p, pObj) = Zero;
|
||||
*Abc_SclObjSlew(p, pObj) = Zero;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Stores/retrivies load information.]
|
||||
Synopsis [Stores/retrivies information for the logic cone.]
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -299,13 +262,13 @@ static inline void Abc_SclLoadStore( SC_Man * p, Abc_Obj_t * pObj )
|
|||
static inline void Abc_SclLoadRestore( SC_Man * p, Abc_Obj_t * pObj )
|
||||
{
|
||||
Abc_Obj_t * pFanin;
|
||||
int i;
|
||||
assert( Vec_FltSize(p->vLoads2) == 2 * Abc_ObjFaninNum(pObj) );
|
||||
int i, k = 0;
|
||||
Abc_ObjForEachFanin( pObj, pFanin, i )
|
||||
{
|
||||
Abc_SclObjLoad(p, pFanin)->rise = Vec_FltEntry(p->vLoads2, 2*i);
|
||||
Abc_SclObjLoad(p, pFanin)->fall = Vec_FltEntry(p->vLoads2, 2*i+1);
|
||||
Abc_SclObjLoad(p, pFanin)->rise = Vec_FltEntry(p->vLoads2, k++);
|
||||
Abc_SclObjLoad(p, pFanin)->fall = Vec_FltEntry(p->vLoads2, k++);
|
||||
}
|
||||
assert( Vec_FltSize(p->vLoads2) == k );
|
||||
}
|
||||
|
||||
static inline void Abc_SclLoadStore3( SC_Man * p, Abc_Obj_t * pObj )
|
||||
|
|
@ -313,26 +276,108 @@ static inline void Abc_SclLoadStore3( SC_Man * p, Abc_Obj_t * pObj )
|
|||
Abc_Obj_t * pFanin;
|
||||
int i;
|
||||
Vec_FltClear( p->vLoads3 );
|
||||
Vec_FltPush( p->vLoads3, Abc_SclObjLoad(p, pObj)->rise );
|
||||
Vec_FltPush( p->vLoads3, Abc_SclObjLoad(p, pObj)->fall );
|
||||
Abc_ObjForEachFanin( pObj, pFanin, i )
|
||||
{
|
||||
Vec_FltPush( p->vLoads3, Abc_SclObjLoad(p, pFanin)->rise );
|
||||
Vec_FltPush( p->vLoads3, Abc_SclObjLoad(p, pFanin)->fall );
|
||||
}
|
||||
Vec_FltPush( p->vLoads3, Abc_SclObjLoad(p, pObj)->rise );
|
||||
Vec_FltPush( p->vLoads3, Abc_SclObjLoad(p, pObj)->fall );
|
||||
}
|
||||
static inline void Abc_SclLoadRestore3( SC_Man * p, Abc_Obj_t * pObj )
|
||||
{
|
||||
Abc_Obj_t * pFanin;
|
||||
int i;
|
||||
assert( Vec_FltSize(p->vLoads3) == 2 * Abc_ObjFaninNum(pObj) + 2 );
|
||||
int i, k = 0;
|
||||
Abc_SclObjLoad(p, pObj)->rise = Vec_FltEntry(p->vLoads3, k++);
|
||||
Abc_SclObjLoad(p, pObj)->fall = Vec_FltEntry(p->vLoads3, k++);
|
||||
Abc_ObjForEachFanin( pObj, pFanin, i )
|
||||
{
|
||||
Abc_SclObjLoad(p, pFanin)->rise = Vec_FltEntry(p->vLoads3, 2*i);
|
||||
Abc_SclObjLoad(p, pFanin)->fall = Vec_FltEntry(p->vLoads3, 2*i+1);
|
||||
Abc_SclObjLoad(p, pFanin)->rise = Vec_FltEntry(p->vLoads3, k++);
|
||||
Abc_SclObjLoad(p, pFanin)->fall = Vec_FltEntry(p->vLoads3, k++);
|
||||
}
|
||||
Abc_SclObjLoad(p, pObj)->rise = Vec_FltEntry(p->vLoads3, 2*i);
|
||||
Abc_SclObjLoad(p, pObj)->fall = Vec_FltEntry(p->vLoads3, 2*i+1);
|
||||
assert( Vec_FltSize(p->vLoads3) == k );
|
||||
}
|
||||
static inline void Abc_SclConeClear( SC_Man * p, Vec_Int_t * vCone )
|
||||
{
|
||||
SC_Pair Zero = { 0.0, 0.0 };
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
Abc_NtkForEachObjVec( vCone, p->pNtk, pObj, i )
|
||||
{
|
||||
*Abc_SclObjTime(p, pObj) = Zero;
|
||||
*Abc_SclObjSlew(p, pObj) = Zero;
|
||||
}
|
||||
}
|
||||
static inline void Abc_SclConeStore( SC_Man * p, Vec_Int_t * vCone )
|
||||
{
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
Vec_FltClear( p->vTimes2 );
|
||||
Abc_NtkForEachObjVec( vCone, p->pNtk, pObj, i )
|
||||
{
|
||||
Vec_FltPush( p->vTimes2, Abc_SclObjTime(p, pObj)->rise );
|
||||
Vec_FltPush( p->vTimes2, Abc_SclObjTime(p, pObj)->fall );
|
||||
Vec_FltPush( p->vTimes2, Abc_SclObjSlew(p, pObj)->rise );
|
||||
Vec_FltPush( p->vTimes2, Abc_SclObjSlew(p, pObj)->fall );
|
||||
*Abc_SclObjTime2(p, pObj) = *Abc_SclObjTime(p, pObj);
|
||||
*Abc_SclObjSlew2(p, pObj) = *Abc_SclObjSlew(p, pObj);
|
||||
}
|
||||
}
|
||||
static inline void Abc_SclConeRestore( SC_Man * p, Vec_Int_t * vCone )
|
||||
{
|
||||
Abc_Obj_t * pObj;
|
||||
int i, k = 0;
|
||||
Abc_NtkForEachObjVec( vCone, p->pNtk, pObj, i )
|
||||
{
|
||||
Abc_SclObjTime(p, pObj)->rise = Vec_FltEntry(p->vTimes2, k++);
|
||||
Abc_SclObjTime(p, pObj)->fall = Vec_FltEntry(p->vTimes2, k++);
|
||||
Abc_SclObjSlew(p, pObj)->rise = Vec_FltEntry(p->vTimes2, k++);
|
||||
Abc_SclObjSlew(p, pObj)->fall = Vec_FltEntry(p->vTimes2, k++);
|
||||
*Abc_SclObjTime(p, pObj) = *Abc_SclObjTime2(p, pObj);
|
||||
*Abc_SclObjSlew(p, pObj) = *Abc_SclObjSlew2(p, pObj);
|
||||
}
|
||||
assert( Vec_FltSize(p->vTimes2) == k );
|
||||
}
|
||||
static inline void Abc_SclEvalStore( SC_Man * p, Vec_Int_t * vCone )
|
||||
{
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
Vec_FltClear( p->vTimes3 );
|
||||
Abc_NtkForEachObjVec( vCone, p->pNtk, pObj, i )
|
||||
{
|
||||
Vec_FltPush( p->vTimes3, Abc_SclObjTime(p, pObj)->rise );
|
||||
Vec_FltPush( p->vTimes3, Abc_SclObjTime(p, pObj)->fall );
|
||||
}
|
||||
}
|
||||
static inline float Abc_SclEvalPerform( SC_Man * p, Vec_Int_t * vCone )
|
||||
{
|
||||
Abc_Obj_t * pObj;
|
||||
float Diff, Multi = 2.0, Eval = 0;
|
||||
int i, k = 0;
|
||||
Abc_NtkForEachObjVec( vCone, p->pNtk, pObj, i )
|
||||
{
|
||||
Diff = (Vec_FltEntry(p->vTimes3, k++) - Abc_SclObjTime(p, pObj)->rise);
|
||||
Diff += (Vec_FltEntry(p->vTimes3, k++) - Abc_SclObjTime(p, pObj)->fall);
|
||||
Eval += 0.5 * (Diff > 0 ? Diff : Multi * Diff);
|
||||
}
|
||||
assert( Vec_FltSize(p->vTimes3) == k );
|
||||
return Eval / Vec_IntSize(vCone);
|
||||
}
|
||||
static inline float Abc_SclEvalPerformLegal( SC_Man * p, Vec_Int_t * vCone, float D )
|
||||
{
|
||||
Abc_Obj_t * pObj;
|
||||
float Rise, Fall, Eval = 0;
|
||||
int i, k = 0;
|
||||
Abc_NtkForEachObjVec( vCone, p->pNtk, pObj, i )
|
||||
{
|
||||
Rise = Vec_FltEntry(p->vTimes3, k++) - Abc_SclObjTime(p, pObj)->rise;
|
||||
Fall = Vec_FltEntry(p->vTimes3, k++) - Abc_SclObjTime(p, pObj)->fall;
|
||||
if ( Rise + Abc_SclObjGetSlackR(p, pObj, D) < 0 || Fall + Abc_SclObjGetSlackF(p, pObj, D) < 0 )
|
||||
return -1;
|
||||
Eval = 0.5 * Rise + 0.5 * Fall;
|
||||
}
|
||||
assert( Vec_FltSize(p->vTimes3) == k );
|
||||
return Eval / Vec_IntSize(vCone);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
|
|||
|
|
@ -277,6 +277,7 @@ int Abc_SclFindBestCell( SC_Man * p, Abc_Obj_t * pObj, Vec_Int_t * vRecalcs, Vec
|
|||
// save old gate, timing, fanin load
|
||||
pCellOld = Abc_SclObjCell( pObj );
|
||||
Abc_SclConeStore( p, vRecalcs );
|
||||
Abc_SclEvalStore( p, vEvals );
|
||||
Abc_SclLoadStore( p, pObj );
|
||||
// try different gate sizes for this node
|
||||
gateBest = -1;
|
||||
|
|
@ -298,6 +299,7 @@ int Abc_SclFindBestCell( SC_Man * p, Abc_Obj_t * pObj, Vec_Int_t * vRecalcs, Vec
|
|||
Abc_SclObjSetCell( pObj, pCellOld );
|
||||
Abc_SclLoadRestore( p, pObj );
|
||||
// evaluate gain
|
||||
|
||||
dGain = 0.0;
|
||||
Abc_NtkForEachObjVec( vEvals, p->pNtk, pTemp, n )
|
||||
{
|
||||
|
|
@ -305,6 +307,8 @@ int Abc_SclFindBestCell( SC_Man * p, Abc_Obj_t * pObj, Vec_Int_t * vRecalcs, Vec
|
|||
dGain += (gGainCur > 0) ? gGainCur : 2.0 * gGainCur;
|
||||
}
|
||||
dGain /= Vec_IntSize(vEvals);
|
||||
|
||||
// dGain = Abc_SclEvalPerform( p, vEvals );
|
||||
// save best gain
|
||||
if ( dGainBest < dGain )
|
||||
{
|
||||
|
|
@ -461,9 +465,9 @@ int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notc
|
|||
Vec_IntPush( p->vUpdates, Abc_ObjId(pFanin) );
|
||||
Vec_IntPush( p->vUpdates, pCellNew->Id );
|
||||
// remember when this node was upsized
|
||||
Vec_IntWriteEntry( p->vNodeIter, Abc_ObjId(pFanout), 0 );
|
||||
Vec_IntWriteEntry( p->vNodeIter, Abc_ObjId(pBuf), 0 );
|
||||
Vec_IntWriteEntry( p->vNodeIter, Abc_ObjId(pFanin), 0 );
|
||||
Vec_IntWriteEntry( p->vNodeIter, Abc_ObjId(pFanout), -1 );
|
||||
Vec_IntWriteEntry( p->vNodeIter, Abc_ObjId(pBuf), -1 );
|
||||
Vec_IntWriteEntry( p->vNodeIter, Abc_ObjId(pFanin), -1 );
|
||||
// update polarity
|
||||
if ( p->pNtk->vPhases && Abc_SclIsInv(pBuf) )
|
||||
Abc_NodeInvUpdateObjFanoutPolarity( pFanin, pFanout );
|
||||
|
|
|
|||
Loading…
Reference in New Issue