Commit 35143e83 by Alan Mishchenko

Experiments with precomputation and matching.

parent bd586dd3
...@@ -154,6 +154,7 @@ extern int Mio_GateReadValue ( Mio_Gate_t * pGate ); ...@@ -154,6 +154,7 @@ extern int Mio_GateReadValue ( Mio_Gate_t * pGate );
extern char * Mio_GateReadPinName ( Mio_Gate_t * pGate, int iPin ); extern char * Mio_GateReadPinName ( Mio_Gate_t * pGate, int iPin );
extern float Mio_GateReadPinDelay ( Mio_Gate_t * pGate, int iPin ); extern float Mio_GateReadPinDelay ( Mio_Gate_t * pGate, int iPin );
extern void Mio_GateSetValue ( Mio_Gate_t * pGate, int Value ); extern void Mio_GateSetValue ( Mio_Gate_t * pGate, int Value );
extern int Mio_GateIsInv ( Mio_Gate_t * pGate );
extern char * Mio_PinReadName ( Mio_Pin_t * pPin ); extern char * Mio_PinReadName ( Mio_Pin_t * pPin );
extern Mio_PinPhase_t Mio_PinReadPhase ( Mio_Pin_t * pPin ); extern Mio_PinPhase_t Mio_PinReadPhase ( Mio_Pin_t * pPin );
extern double Mio_PinReadInputLoad ( Mio_Pin_t * pPin ); extern double Mio_PinReadInputLoad ( Mio_Pin_t * pPin );
......
...@@ -179,6 +179,7 @@ word Mio_GateReadTruth ( Mio_Gate_t * pGate ) { return ...@@ -179,6 +179,7 @@ word Mio_GateReadTruth ( Mio_Gate_t * pGate ) { return
word * Mio_GateReadTruthP ( Mio_Gate_t * pGate ) { return pGate->nInputs <= 6 ? NULL: pGate->pTruth; } word * Mio_GateReadTruthP ( Mio_Gate_t * pGate ) { return pGate->nInputs <= 6 ? NULL: pGate->pTruth; }
int Mio_GateReadValue ( Mio_Gate_t * pGate ) { return pGate->Value; } int Mio_GateReadValue ( Mio_Gate_t * pGate ) { return pGate->Value; }
void Mio_GateSetValue ( Mio_Gate_t * pGate, int Value ) { pGate->Value = Value; } void Mio_GateSetValue ( Mio_Gate_t * pGate, int Value ) { pGate->Value = Value; }
int Mio_GateIsInv ( Mio_Gate_t * pGate ) { return pGate->uTruth == ABC_CONST(0x5555555555555555); }
/**Function************************************************************* /**Function*************************************************************
......
...@@ -59,6 +59,9 @@ struct Sfm_Dec_t_ ...@@ -59,6 +59,9 @@ struct Sfm_Dec_t_
int DelayMin; // temporary min delay int DelayMin; // temporary min delay
int iTarget; // target node int iTarget; // target node
int DeltaCrit; // critical delta int DeltaCrit; // critical delta
int AreaInv; // inverter area
int DelayInv; // inverter delay
Mio_Gate_t * pGateInv; // inverter
word uCareSet; // computed careset word uCareSet; // computed careset
Vec_Int_t vObjRoots; // roots of the window Vec_Int_t vObjRoots; // roots of the window
Vec_Int_t vObjGates; // functionality Vec_Int_t vObjGates; // functionality
...@@ -188,8 +191,10 @@ Sfm_Dec_t * Sfm_DecStart( Sfm_Par_t * pPars, Mio_Library_t * pLib, Abc_Ntk_t * p ...@@ -188,8 +191,10 @@ Sfm_Dec_t * Sfm_DecStart( Sfm_Par_t * pPars, Mio_Library_t * pLib, Abc_Ntk_t * p
p->pPars = pPars; p->pPars = pPars;
p->pNtk = pNtk; p->pNtk = pNtk;
p->pSat = sat_solver_new(); p->pSat = sat_solver_new();
if ( pPars->DeltaCrit == 0 ) p->pGateInv = Mio_LibraryReadInv( pLib );
p->DeltaCrit = 5 * (int)(MIO_NUM*Mio_LibraryReadDelayInvMax(pLib)) / 2; p->AreaInv = MIO_NUM*Mio_GateReadArea( p->pGateInv );
p->DelayInv = MIO_NUM*Mio_GateReadDelayMax( p->pGateInv );
p->DeltaCrit = pPars->DeltaCrit ? MIO_NUM*pPars->DeltaCrit : 5 * (int)(MIO_NUM*Mio_LibraryReadDelayInvMax(pLib)) / 2;
p->timeLib = Abc_Clock(); p->timeLib = Abc_Clock();
p->pLib = Sfm_LibPrepare( pPars->nVarMax, 1, !pPars->fArea, pPars->fVerbose, pPars->fLibVerbose ); p->pLib = Sfm_LibPrepare( pPars->nVarMax, 1, !pPars->fArea, pPars->fVerbose, pPars->fLibVerbose );
p->timeLib = Abc_Clock() - p->timeLib; p->timeLib = Abc_Clock() - p->timeLib;
...@@ -827,6 +832,39 @@ void Sfm_DecPrepareVec( Vec_Int_t * vMap, int * pNodes, int nNodes, Vec_Int_t * ...@@ -827,6 +832,39 @@ void Sfm_DecPrepareVec( Vec_Int_t * vMap, int * pNodes, int nNodes, Vec_Int_t *
for ( i = 0; i < nNodes; i++ ) for ( i = 0; i < nNodes; i++ )
Vec_IntPush( vCut, Vec_IntEntry(vMap, pNodes[i]) ); Vec_IntPush( vCut, Vec_IntEntry(vMap, pNodes[i]) );
} }
int Sfm_DecComputeFlipInvGain( Sfm_Dec_t * p, Abc_Obj_t * pPivot, int * pfNeedInv )
{
Abc_Obj_t * pFanout;
Mio_Gate_t * pGate, * pGateNew;
int i, Handle, fNeedInv = 0, Gain = 0;
Abc_ObjForEachFanout( pPivot, pFanout, i )
{
if ( !Abc_ObjIsNode(pFanout) )
{
fNeedInv = 1;
continue;
}
pGate = (Mio_Gate_t*)pFanout->pData;
if ( Abc_ObjFaninNum(pFanout) == 1 && Mio_GateIsInv(pGate) )
{
Gain += p->AreaInv;
continue;
}
Handle = Sfm_LibFindComplInputGate( &p->vGateFuncs, Mio_GateReadValue(pGate), Abc_ObjFaninNum(pFanout), Abc_NodeFindFanin(pFanout, pPivot), NULL );
if ( Handle == -1 )
{
fNeedInv = 1;
continue;
}
pGateNew = (Mio_Gate_t *)Vec_PtrEntry( &p->vGateHands, Handle );
Gain += MIO_NUM*Mio_GateReadArea(pGate) - MIO_NUM*Mio_GateReadArea(pGateNew);
}
if ( fNeedInv )
Gain -= p->AreaInv;
if ( pfNeedInv )
*pfNeedInv = fNeedInv;
return Gain;
}
/**Function************************************************************* /**Function*************************************************************
...@@ -1081,6 +1119,25 @@ int Sfm_DecPeformDec_rec( Sfm_Dec_t * p, word * pTruth, int * pSupp, int * pAssu ...@@ -1081,6 +1119,25 @@ int Sfm_DecPeformDec_rec( Sfm_Dec_t * p, word * pTruth, int * pSupp, int * pAssu
} }
} }
} }
/*
{
int Lit0 = Vec_IntSize(&p->vImpls[0]) ? Vec_IntEntry(&p->vImpls[0], 0) : -1;
int Lit1 = Vec_IntSize(&p->vImpls[1]) ? Vec_IntEntry(&p->vImpls[1], 0) : -1;
if ( Lit0 == -1 && Lit1 >= 0 )
Var = Abc_Lit2Var(Lit1);
else if ( Lit1 == -1 && Lit0 >= 0 )
Var = Abc_Lit2Var(Lit0);
else if ( Lit0 >= 0 && Lit1 >= 0 )
{
if ( Lit0 < Lit1 )
Var = Abc_Lit2Var(Lit0);
else
Var = Abc_Lit2Var(Lit1);
}
}
*/
if ( Var == -1 && fCofactor ) if ( Var == -1 && fCofactor )
{ {
//for ( Var = p->nDivs - 1; Var >= 0; Var-- ) //for ( Var = p->nDivs - 1; Var >= 0; Var-- )
...@@ -1130,9 +1187,11 @@ int Sfm_DecPeformDec2( Sfm_Dec_t * p, Abc_Obj_t * pObj ) ...@@ -1130,9 +1187,11 @@ int Sfm_DecPeformDec2( Sfm_Dec_t * p, Abc_Obj_t * pObj )
int nSupp[SFM_DEC_MAX], pAssump[SFM_WIN_MAX]; int nSupp[SFM_DEC_MAX], pAssump[SFM_WIN_MAX];
int fVeryVerbose = p->pPars->fPrintDecs || p->pPars->fVeryVerbose; int fVeryVerbose = p->pPars->fPrintDecs || p->pPars->fVeryVerbose;
int nDecs = Abc_MaxInt(p->pPars->nDecMax, 1); int nDecs = Abc_MaxInt(p->pPars->nDecMax, 1);
int i, RetValue, Prev = 0, iBest = -1, AreaThis, AreaNew; int fNeedInv, AreaGainInv = Sfm_DecComputeFlipInvGain(p, pObj, &fNeedInv);
int i, RetValue, Prev = 0, iBest = -1, AreaThis, AreaNew;//, AreaNewInv;
int GainThis, GainBest = -1, iLibObj, iLibObjBest = -1; int GainThis, GainBest = -1, iLibObj, iLibObjBest = -1;
assert( p->pPars->fArea == 1 ); assert( p->pPars->fArea == 1 );
//printf( "AreaGainInv = %8.2f ", MIO_NUMINV*AreaGainInv );
if ( p->pPars->fUseSim ) if ( p->pPars->fUseSim )
Sfm_ObjSetupSimInfo( pObj ); Sfm_ObjSetupSimInfo( pObj );
else else
...@@ -1173,11 +1232,26 @@ int Sfm_DecPeformDec2( Sfm_Dec_t * p, Abc_Obj_t * pObj ) ...@@ -1173,11 +1232,26 @@ int Sfm_DecPeformDec2( Sfm_Dec_t * p, Abc_Obj_t * pObj )
p->nLuckySizes[nSupp[i]]++; p->nLuckySizes[nSupp[i]]++;
assert( RetValue <= 2 ); assert( RetValue <= 2 );
p->nLuckyGates[RetValue]++; p->nLuckyGates[RetValue]++;
//printf( "\n" );
return RetValue; return RetValue;
} }
AreaNew = Sfm_LibFindAreaMatch( p->pLib, uTruth[i], nSupp[i], &iLibObj ); AreaNew = Sfm_LibFindAreaMatch( p->pLib, uTruth[i], nSupp[i], &iLibObj );
/*
uTruth[i][0] = ~uTruth[i][0];
AreaNewInv = Sfm_LibFindAreaMatch( p->pLib, uTruth[i], nSupp[i], NULL );
uTruth[i][0] = ~uTruth[i][0];
if ( AreaNew > 0 && AreaNewInv > 0 && AreaNew - AreaNewInv + AreaGainInv > 0 )
printf( "AreaNew = %8.2f AreaNewInv = %8.2f Gain = %8.2f Total = %8.2f\n",
MIO_NUMINV*AreaNew, MIO_NUMINV*AreaNewInv, MIO_NUMINV*(AreaNew - AreaNewInv), MIO_NUMINV*(AreaNew - AreaNewInv + AreaGainInv) );
else
printf( "\n" );
*/
if ( AreaNew == -1 ) if ( AreaNew == -1 )
continue; continue;
// compute area savings // compute area savings
Sfm_DecPrepareVec( &p->vObjMap, pSupp[i], nSupp[i], &p->vTemp ); Sfm_DecPrepareVec( &p->vObjMap, pSupp[i], nSupp[i], &p->vTemp );
AreaThis = Sfm_DecMffcAreaReal(pObj, &p->vTemp); AreaThis = Sfm_DecMffcAreaReal(pObj, &p->vTemp);
...@@ -1187,7 +1261,7 @@ int Sfm_DecPeformDec2( Sfm_Dec_t * p, Abc_Obj_t * pObj ) ...@@ -1187,7 +1261,7 @@ int Sfm_DecPeformDec2( Sfm_Dec_t * p, Abc_Obj_t * pObj )
// find the best gain // find the best gain
GainThis = AreaThis - AreaNew; GainThis = AreaThis - AreaNew;
assert( GainThis >= 0 ); assert( GainThis >= 0 );
if ( p->pPars->fZeroCost ? (GainBest <= GainThis) : (GainBest < GainThis) ) if ( GainBest < GainThis )
{ {
GainBest = GainThis; GainBest = GainThis;
iLibObjBest = iLibObj; iLibObjBest = iLibObj;
...@@ -1201,6 +1275,7 @@ int Sfm_DecPeformDec2( Sfm_Dec_t * p, Abc_Obj_t * pObj ) ...@@ -1201,6 +1275,7 @@ int Sfm_DecPeformDec2( Sfm_Dec_t * p, Abc_Obj_t * pObj )
if ( fVeryVerbose ) if ( fVeryVerbose )
printf( "Best : NO DEC.\n" ); printf( "Best : NO DEC.\n" );
p->nNoDecs++; p->nNoDecs++;
//printf( "\n" );
return -2; return -2;
} }
if ( fVeryVerbose ) if ( fVeryVerbose )
...@@ -1245,6 +1320,7 @@ int Sfm_DecPeformDec3( Sfm_Dec_t * p, Abc_Obj_t * pObj ) ...@@ -1245,6 +1320,7 @@ int Sfm_DecPeformDec3( Sfm_Dec_t * p, Abc_Obj_t * pObj )
Vec_IntClear( &p->vObjDec ); Vec_IntClear( &p->vObjDec );
for ( i = 0; i < nDecs; i++ ) for ( i = 0; i < nDecs; i++ )
{ {
DelayMin = DelayOrig = Sfm_TimReadObjDelay( p->pTim, Abc_ObjId(pObj) );
// reduce the variable array // reduce the variable array
if ( Vec_IntSize(&p->vObjDec) > Prev ) if ( Vec_IntSize(&p->vObjDec) > Prev )
Vec_IntShrink( &p->vObjDec, Prev ); Vec_IntShrink( &p->vObjDec, Prev );
...@@ -1262,6 +1338,12 @@ int Sfm_DecPeformDec3( Sfm_Dec_t * p, Abc_Obj_t * pObj ) ...@@ -1262,6 +1338,12 @@ int Sfm_DecPeformDec3( Sfm_Dec_t * p, Abc_Obj_t * pObj )
printf( "Dec %d: Pat0 = %2d Pat1 = %2d Supp = %d ", i, p->nPats[0], p->nPats[1], nSupp[i] ); printf( "Dec %d: Pat0 = %2d Pat1 = %2d Supp = %d ", i, p->nPats[0], p->nPats[1], nSupp[i] );
if ( fVeryVerbose ) if ( fVeryVerbose )
Dau_DsdPrintFromTruth( uTruth[i], nSupp[i] ); Dau_DsdPrintFromTruth( uTruth[i], nSupp[i] );
if ( nSupp[i] == 1 && uTruth[i][0] == ABC_CONST(0x5555555555555555) && DelayMin <= p->DelayInv + Sfm_TimReadObjDelay(p->pTim, Vec_IntEntry(&p->vObjMap, pSupp[i][0])) )
{
if ( fVeryVerbose )
printf( "Dec %d: Pat0 = %2d Pat1 = %2d NO DEC.\n", i, p->nPats[0], p->nPats[1] );
continue;
}
if ( nSupp[i] < 2 ) if ( nSupp[i] < 2 )
{ {
RetValue = Sfm_LibImplementSimple( p->pLib, uTruth[i], pSupp[i], nSupp[i], &p->vObjGates, &p->vObjFanins ); RetValue = Sfm_LibImplementSimple( p->pLib, uTruth[i], pSupp[i], nSupp[i], &p->vObjGates, &p->vObjFanins );
...@@ -1278,7 +1360,6 @@ int Sfm_DecPeformDec3( Sfm_Dec_t * p, Abc_Obj_t * pObj ) ...@@ -1278,7 +1360,6 @@ int Sfm_DecPeformDec3( Sfm_Dec_t * p, Abc_Obj_t * pObj )
// try the delay // try the delay
nMatches = Sfm_LibFindDelayMatches( p->pLib, uTruth[i], pSupp[i], nSupp[i], &p->vMatchGates, &p->vMatchFans ); nMatches = Sfm_LibFindDelayMatches( p->pLib, uTruth[i], pSupp[i], nSupp[i], &p->vMatchGates, &p->vMatchFans );
DelayMin = DelayOrig = Sfm_TimReadObjDelay( p->pTim, Abc_ObjId(pObj) );
for ( k = 0; k < nMatches; k++ ) for ( k = 0; k < nMatches; k++ )
{ {
Mio_Gate_t * pGate1 = (Mio_Gate_t *)Vec_PtrEntry( &p->vMatchGates, 2*k+0 ); Mio_Gate_t * pGate1 = (Mio_Gate_t *)Vec_PtrEntry( &p->vMatchGates, 2*k+0 );
......
...@@ -605,7 +605,8 @@ int Sfm_LibFindAreaMatch( Sfm_Lib_t * p, word * pTruth, int nFanins, int * piObj ...@@ -605,7 +605,8 @@ int Sfm_LibFindAreaMatch( Sfm_Lib_t * p, word * pTruth, int nFanins, int * piObj
return -1; return -1;
Sfm_LibForEachSuper( p, pObj, iFunc ) Sfm_LibForEachSuper( p, pObj, iFunc )
break; break;
*piObj = pObj - p->pObjs; if ( piObj )
*piObj = pObj - p->pObjs;
return pObj->Area; return pObj->Area;
} }
int Sfm_LibFindDelayMatches( Sfm_Lib_t * p, word * pTruth, int * pFanins, int nFanins, Vec_Ptr_t * vGates, Vec_Ptr_t * vFans ) int Sfm_LibFindDelayMatches( Sfm_Lib_t * p, word * pTruth, int * pFanins, int nFanins, Vec_Ptr_t * vGates, Vec_Ptr_t * vFans )
......
...@@ -242,10 +242,10 @@ Sfm_Tim_t * Sfm_TimStart( Mio_Library_t * pLib, Scl_Con_t * pExt, Abc_Ntk_t * pN ...@@ -242,10 +242,10 @@ Sfm_Tim_t * Sfm_TimStart( Mio_Library_t * pLib, Scl_Con_t * pExt, Abc_Ntk_t * pN
p->pLib = pLib; p->pLib = pLib;
p->pExt = pExt; p->pExt = pExt;
p->pNtk = pNtk; p->pNtk = pNtk;
Vec_IntFill( &p->vTimArrs, 4*Abc_NtkObjNumMax(pNtk), 0 ); Vec_IntFill( &p->vTimArrs, 3*Abc_NtkObjNumMax(pNtk), 0 );
Vec_IntFill( &p->vTimReqs, 4*Abc_NtkObjNumMax(pNtk), 0 ); Vec_IntFill( &p->vTimReqs, 3*Abc_NtkObjNumMax(pNtk), 0 );
// Vec_IntFill( &p->vTimSlews, 4*Abc_NtkObjNumMax(pNtk), 0 ); // Vec_IntFill( &p->vTimSlews, 3*Abc_NtkObjNumMax(pNtk), 0 );
// Vec_IntFill( &p->vTimLoads, 4*Abc_NtkObjNumMax(pNtk), 0 ); // Vec_IntFill( &p->vTimLoads, 3*Abc_NtkObjNumMax(pNtk), 0 );
// Vec_IntFill( &p->vObjOffs, 2*Abc_NtkObjNumMax(pNtk), 0 ); // Vec_IntFill( &p->vObjOffs, 2*Abc_NtkObjNumMax(pNtk), 0 );
// Abc_NtkForEachNode( pNtk, pObj, i ) // Abc_NtkForEachNode( pNtk, pObj, i )
// { // {
...@@ -339,6 +339,8 @@ static inline void Sfm_TimUpdateClean( Sfm_Tim_t * p ) ...@@ -339,6 +339,8 @@ static inline void Sfm_TimUpdateClean( Sfm_Tim_t * p )
void Sfm_TimUpdateTiming( Sfm_Tim_t * p, Vec_Int_t * vTimeNodes ) void Sfm_TimUpdateTiming( Sfm_Tim_t * p, Vec_Int_t * vTimeNodes )
{ {
assert( Vec_IntSize(vTimeNodes) > 0 && Vec_IntSize(vTimeNodes) <= 2 ); assert( Vec_IntSize(vTimeNodes) > 0 && Vec_IntSize(vTimeNodes) <= 2 );
Vec_IntFillExtra( &p->vTimArrs, 2*Abc_NtkObjNumMax(p->pNtk), 0 );
Vec_IntFillExtra( &p->vTimReqs, 2*Abc_NtkObjNumMax(p->pNtk), 0 );
p->Delay = Sfm_TimTrace( p ); p->Delay = Sfm_TimTrace( p );
} }
......
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