Commit 606fed3b by Alan Mishchenko

Added optimization for average rather than maximum delay.

parent e868d057
......@@ -1659,10 +1659,6 @@ Gia_Man_t * Gia_ManPerformMapping( Gia_Man_t * p, void * pp, int fNormalized )
pNew->pAigExtra = p->pAigExtra; p->pAigExtra = NULL;
pNew->nAnd2Delay = p->nAnd2Delay; p->nAnd2Delay = 0;
Gia_ManStop( p );
// printf( "PERFORMING VERIFICATION:\n" );
// Gia_ManVerifyWithBoxes( pNew, NULL );
// if ( pPars->fRepack )
// Gia_ManIffTest( pNew, pPars->pLutLib, pPars->fVerbose );
return pNew;
}
......
......@@ -14770,7 +14770,7 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
char LutSize[100];
Abc_Ntk_t * pNtk, * pNtkRes;
If_Par_t Pars, * pPars = &Pars;
int c, fLutMux;
int c;
extern Abc_Ntk_t * Abc_NtkIf( Abc_Ntk_t * pNtk, If_Par_t * pPars );
pNtk = Abc_FrameReadNtk(pAbc);
......@@ -14804,9 +14804,8 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
pPars->pTimesArr = NULL;
pPars->pFuncCost = NULL;
fLutMux = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "KCFAGNDEWSTqaflepmrsdbugxyojikncvh" ) ) != EOF )
while ( ( c = Extra_UtilGetopt( argc, argv, "KCFAGNDEWSTqaflepmrsdbgxyojiktncvh" ) ) != EOF )
{
switch ( c )
{
......@@ -14969,9 +14968,6 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'b':
pPars->fUseBat ^= 1;
break;
case 'u':
fLutMux ^= 1;
break;
case 'g':
pPars->fDelayOpt ^= 1;
break;
......@@ -14993,6 +14989,9 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'k':
pPars->fEnableCheck10 ^= 1;
break;
case 't':
pPars->fDoAverage ^= 1;
break;
case 'n':
pPars->fUseDsd ^= 1;
break;
......@@ -15034,14 +15033,6 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
return 1;
}
if ( fLutMux )
{
extern int Abc_NtkCutCostMux( If_Man_t * p, If_Cut_t * pCut );
pPars->fCutMin = 1;
pPars->fTruth = 1;
pPars->pFuncCost = Abc_NtkCutCostMux;
}
// enable truth table computation if choices are selected
if ( (c = Abc_NtkGetChoiceNum( pNtk )) )
{
......@@ -15252,7 +15243,7 @@ usage:
sprintf(LutSize, "library" );
else
sprintf(LutSize, "%d", pPars->nLutSize );
Abc_Print( -2, "usage: if [-KCFANGT num] [-DEW float] [-S str] [-qarlepmsdbugxyojikncvh]\n" );
Abc_Print( -2, "usage: if [-KCFANGT num] [-DEW float] [-S str] [-qarlepmsdbgxyojiktncvh]\n" );
Abc_Print( -2, "\t performs FPGA technology mapping of the network\n" );
Abc_Print( -2, "\t-K num : the number of LUT inputs (2 < num < %d) [default = %s]\n", IF_MAX_LUTSIZE+1, LutSize );
Abc_Print( -2, "\t-C num : the max number of priority cuts (0 < num < 2^12) [default = %d]\n", pPars->nCutsMax );
......@@ -15267,7 +15258,6 @@ usage:
Abc_Print( -2, "\t-T num : the type of LUT structures [default = any]\n", pPars->nStructType );
Abc_Print( -2, "\t-q : toggles preprocessing using several starting points [default = %s]\n", pPars->fPreprocess? "yes": "no" );
Abc_Print( -2, "\t-a : toggles area-oriented mapping [default = %s]\n", pPars->fArea? "yes": "no" );
// Abc_Print( -2, "\t-f : toggles one fancy feature [default = %s]\n", pPars->fFancy? "yes": "no" );
Abc_Print( -2, "\t-r : enables expansion/reduction of the best cuts [default = %s]\n", pPars->fExpRed? "yes": "no" );
Abc_Print( -2, "\t-l : optimizes latch paths for delay, other paths for area [default = %s]\n", pPars->fLatchPaths? "yes": "no" );
Abc_Print( -2, "\t-e : uses edge-based cut selection heuristics [default = %s]\n", pPars->fEdge? "yes": "no" );
......@@ -15276,7 +15266,6 @@ usage:
Abc_Print( -2, "\t-s : toggles delay-oriented mapping used with -S <NN> [default = %s]\n", pPars->fDelayOptLut? "yes": "no" );
Abc_Print( -2, "\t-d : toggles deriving local AIGs using bi-decomposition [default = %s]\n", pPars->fBidec? "yes": "no" );
Abc_Print( -2, "\t-b : toggles the use of one special feature [default = %s]\n", pPars->fUseBat? "yes": "no" );
Abc_Print( -2, "\t-u : toggles the use of MUXes along with LUTs [default = %s]\n", fLutMux? "yes": "no" );
Abc_Print( -2, "\t-g : toggles delay optimization by SOP balancing [default = %s]\n", pPars->fDelayOpt? "yes": "no" );
Abc_Print( -2, "\t-x : toggles delay optimization by DSD balancing [default = %s]\n", pPars->fDsdBalance? "yes": "no" );
Abc_Print( -2, "\t-y : toggles delay optimization with recorded library [default = %s]\n", pPars->fUserRecLib? "yes": "no" );
......@@ -15284,6 +15273,7 @@ usage:
Abc_Print( -2, "\t-j : toggles enabling additional check [default = %s]\n", pPars->fEnableCheck07? "yes": "no" );
Abc_Print( -2, "\t-i : toggles enabling additional check [default = %s]\n", pPars->fEnableCheck08? "yes": "no" );
Abc_Print( -2, "\t-k : toggles enabling additional check [default = %s]\n", pPars->fEnableCheck10? "yes": "no" );
Abc_Print( -2, "\t-t : toggles optimizing average rather than maximum level [default = %s]\n", pPars->fDoAverage? "yes": "no" );
Abc_Print( -2, "\t-n : toggles computing DSDs of the cut functions [default = %s]\n", pPars->fUseDsd? "yes": "no" );
Abc_Print( -2, "\t-c : toggles computing truth tables in a new way [default = %s]\n", pPars->fUseTtPerm? "yes": "no" );
Abc_Print( -2, "\t-v : toggles verbose output [default = %s]\n", pPars->fVerbose? "yes": "no" );
......@@ -29743,7 +29733,7 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv )
pPars->fDeriveLuts ^= 1;
break;
case 't':
pPars->fRepack ^= 1;
pPars->fDoAverage ^= 1;
break;
case 'n':
pPars->fUseDsd ^= 1;
......@@ -29766,12 +29756,6 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv )
return 1;
}
if ( pPars->pLutLib == NULL && pPars->fRepack )
{
Abc_Print( 0, "Cannot perform repacking because LUT library is not given.\n" );
pPars->fRepack = 0;
}
if ( pPars->nLutSize == -1 )
{
if ( pPars->pLutLib == NULL )
......@@ -30027,7 +30011,7 @@ usage:
Abc_Print( -2, "\t-f : toggles enabling additional check [default = %s]\n", pPars->fEnableCheck75? "yes": "no" );
Abc_Print( -2, "\t-u : toggles enabling additional check [default = %s]\n", pPars->fEnableCheck75u? "yes": "no" );
Abc_Print( -2, "\t-z : toggles deriving LUTs when mapping into LUT structures [default = %s]\n", pPars->fDeriveLuts? "yes": "no" );
Abc_Print( -2, "\t-t : toggles repacking LUTs into new structures [default = %s]\n", pPars->fRepack? "yes": "no" );
Abc_Print( -2, "\t-t : toggles optimizing average rather than maximum level [default = %s]\n", pPars->fDoAverage? "yes": "no" );
Abc_Print( -2, "\t-n : toggles computing DSDs of the cut functions [default = %s]\n", pPars->fUseDsd? "yes": "no" );
Abc_Print( -2, "\t-c : toggles computing truth tables in a new way [default = %s]\n", pPars->fUseTtPerm? "yes": "no" );
Abc_Print( -2, "\t-v : toggles verbose output [default = %s]\n", pPars->fVerbose? "yes": "no" );
......@@ -132,7 +132,7 @@ struct If_Par_t_
int fUseDsd; // compute DSD of the cut functions
int fUseTtPerm; // compute truth tables of the cut functions
int fDeriveLuts; // enables deriving LUT structures
int fRepack; // repack after mapping
int fDoAverage; // optimize average rather than maximum level
int fVerbose; // the verbosity flag
char * pLutStruct; // LUT structure
float WireDelay; // wire delay
......@@ -605,6 +605,8 @@ extern int If_ManPerformMappingSeq( If_Man_t * p );
/*=== ifTime.c ============================================================*/
extern float If_CutDelay( If_Man_t * p, If_Obj_t * pObj, If_Cut_t * pCut );
extern void If_CutPropagateRequired( If_Man_t * p, If_Obj_t * pObj, If_Cut_t * pCut, float Required );
extern float If_ManDelayMax( If_Man_t * p, int fSeq );
extern void If_ManComputeRequired( If_Man_t * p );
/*=== ifTruth.c ===========================================================*/
extern void If_CutRotatePins( If_Man_t * p, If_Cut_t * pCut );
extern int If_CutComputeTruth( If_Man_t * p, If_Cut_t * pCut, If_Cut_t * pCut0, If_Cut_t * pCut1, int fCompl0, int fCompl1 );
......@@ -613,8 +615,6 @@ extern int If_CutComputeTruthPerm( If_Man_t * p, If_Cut_t * pCut, If
extern void If_ManCleanNodeCopy( If_Man_t * p );
extern void If_ManCleanCutData( If_Man_t * p );
extern void If_ManCleanMarkV( If_Man_t * p );
extern float If_ManDelayMax( If_Man_t * p, int fSeq );
extern void If_ManComputeRequired( If_Man_t * p );
extern float If_ManScanMapping( If_Man_t * p );
extern float If_ManScanMappingDirect( If_Man_t * p );
extern float If_ManScanMappingSeq( If_Man_t * p );
......
......@@ -88,248 +88,6 @@ void If_ManCleanMarkV( If_Man_t * p )
pObj->fVisit = 0;
}
/**Function*************************************************************
Synopsis [Returns the max delay of the POs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
float If_ManDelayMax( If_Man_t * p, int fSeq )
{
If_Obj_t * pObj;
float DelayBest;
int i;
if ( p->pPars->fLatchPaths && (p->pPars->nLatchesCi == 0 || p->pPars->nLatchesCo == 0) )
{
Abc_Print( 0, "Delay optimization of latch path is not performed because there is no latches.\n" );
p->pPars->fLatchPaths = 0;
}
DelayBest = -IF_FLOAT_LARGE;
if ( fSeq )
{
assert( p->pPars->nLatchesCi > 0 );
If_ManForEachPo( p, pObj, i )
if ( DelayBest < If_ObjArrTime(If_ObjFanin0(pObj)) )
DelayBest = If_ObjArrTime(If_ObjFanin0(pObj));
}
else if ( p->pPars->fLatchPaths )
{
If_ManForEachLatchInput( p, pObj, i )
if ( DelayBest < If_ObjArrTime(If_ObjFanin0(pObj)) )
DelayBest = If_ObjArrTime(If_ObjFanin0(pObj));
}
else
{
If_ManForEachCo( p, pObj, i )
if ( DelayBest < If_ObjArrTime(If_ObjFanin0(pObj)) )
DelayBest = If_ObjArrTime(If_ObjFanin0(pObj));
}
return DelayBest;
}
/**Function*************************************************************
Synopsis [Computes the required times of all nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void If_ManComputeRequired( If_Man_t * p )
{
If_Obj_t * pObj;
int i, Counter;
float reqTime;
// compute area, clean required times, collect nodes used in the mapping
// p->AreaGlo = If_ManScanMapping( p );
If_ManMarkMapping( p );
if ( p->pManTim == NULL )
{
// consider the case when the required times are given
if ( p->pPars->pTimesReq && !p->pPars->fAreaOnly )
{
// make sure that the required time hold
Counter = 0;
If_ManForEachCo( p, pObj, i )
{
if ( If_ObjArrTime(If_ObjFanin0(pObj)) > p->pPars->pTimesReq[i] + p->fEpsilon )
{
If_ObjFanin0(pObj)->Required = If_ObjArrTime(If_ObjFanin0(pObj));
Counter++;
// Abc_Print( 0, "Required times are violated for output %d (arr = %d; req = %d).\n",
// i, (int)If_ObjArrTime(If_ObjFanin0(pObj)), (int)p->pPars->pTimesReq[i] );
}
else
If_ObjFanin0(pObj)->Required = p->pPars->pTimesReq[i];
}
if ( Counter && !p->fReqTimeWarn )
{
Abc_Print( 0, "Required times are exceeded at %d output%s. The earliest arrival times are used.\n", Counter, Counter > 1 ? "s":"" );
p->fReqTimeWarn = 1;
}
}
else
{
// get the global required times
p->RequiredGlo = If_ManDelayMax( p, 0 );
// find new delay target
if ( p->pPars->nRelaxRatio && p->pPars->DelayTargetNew == 0 )
p->pPars->DelayTargetNew = p->RequiredGlo * (100.0 + p->pPars->nRelaxRatio) / 100.0;
// update the required times according to the target
if ( p->pPars->DelayTarget != -1 )
{
if ( p->RequiredGlo > p->pPars->DelayTarget + p->fEpsilon )
{
if ( p->fNextRound == 0 )
{
p->fNextRound = 1;
Abc_Print( 0, "Cannot meet the target required times (%4.2f). Mapping continues anyway.\n", p->pPars->DelayTarget );
}
}
else if ( p->RequiredGlo < p->pPars->DelayTarget - p->fEpsilon )
{
if ( p->fNextRound == 0 )
{
p->fNextRound = 1;
// Abc_Print( 0, "Relaxing the required times from (%4.2f) to the target (%4.2f).\n", p->RequiredGlo, p->pPars->DelayTarget );
}
p->RequiredGlo = p->pPars->DelayTarget;
}
}
else if ( p->pPars->DelayTargetNew > 0 ) // relax the required times
p->RequiredGlo = p->pPars->DelayTargetNew;
// do not propagate required times if area minimization is requested
if ( p->pPars->fAreaOnly )
return;
// set the required times for the POs
if ( p->pPars->fLatchPaths )
{
If_ManForEachLatchInput( p, pObj, i )
If_ObjFanin0(pObj)->Required = p->RequiredGlo;
}
else
{
If_ManForEachCo( p, pObj, i )
If_ObjFanin0(pObj)->Required = p->RequiredGlo;
}
}
// go through the nodes in the reverse topological order
// Vec_PtrForEachEntry( If_Obj_t *, p->vMapped, pObj, i )
// If_CutPropagateRequired( p, pObj, If_ObjCutBest(pObj), pObj->Required );
If_ManForEachObjReverse( p, pObj, i )
{
if ( pObj->nRefs == 0 )
continue;
If_CutPropagateRequired( p, pObj, If_ObjCutBest(pObj), pObj->Required );
}
}
else
{
// get the global required times
p->RequiredGlo = If_ManDelayMax( p, 0 );
// find new delay target
if ( p->pPars->nRelaxRatio && p->pPars->DelayTargetNew == 0 )
p->pPars->DelayTargetNew = p->RequiredGlo * (100.0 + p->pPars->nRelaxRatio) / 100.0;
// update the required times according to the target
if ( p->pPars->DelayTarget != -1 )
{
if ( p->RequiredGlo > p->pPars->DelayTarget + p->fEpsilon )
{
if ( p->fNextRound == 0 )
{
p->fNextRound = 1;
Abc_Print( 0, "Cannot meet the target required times (%4.2f). Mapping continues anyway.\n", p->pPars->DelayTarget );
}
}
else if ( p->RequiredGlo < p->pPars->DelayTarget - p->fEpsilon )
{
if ( p->fNextRound == 0 )
{
p->fNextRound = 1;
// Abc_Print( 0, "Relaxing the required times from (%4.2f) to the target (%4.2f).\n", p->RequiredGlo, p->pPars->DelayTarget );
}
p->RequiredGlo = p->pPars->DelayTarget;
}
}
else if ( p->pPars->DelayTargetNew > 0 ) // relax the required times
p->RequiredGlo = p->pPars->DelayTargetNew;
// do not propagate required times if area minimization is requested
if ( p->pPars->fAreaOnly )
return;
// set the required times for the POs
Tim_ManIncrementTravId( p->pManTim );
if ( p->vCoAttrs )
{
assert( If_ManCoNum(p) == Vec_IntSize(p->vCoAttrs) );
If_ManForEachCo( p, pObj, i )
{
if ( Vec_IntEntry(p->vCoAttrs, i) == -1 ) // -1=internal
continue;
if ( Vec_IntEntry(p->vCoAttrs, i) == 0 ) // 0=optimize
Tim_ManSetCoRequired( p->pManTim, i, p->RequiredGlo );
else if ( Vec_IntEntry(p->vCoAttrs, i) == 1 ) // 1=keep
Tim_ManSetCoRequired( p->pManTim, i, If_ObjArrTime(If_ObjFanin0(pObj)) );
else if ( Vec_IntEntry(p->vCoAttrs, i) == 2 ) // 2=relax
Tim_ManSetCoRequired( p->pManTim, i, IF_FLOAT_LARGE );
else assert( 0 );
}
}
else if ( p->pPars->fLatchPaths )
{
If_ManForEachPo( p, pObj, i )
Tim_ManSetCoRequired( p->pManTim, i, IF_FLOAT_LARGE );
If_ManForEachLatchInput( p, pObj, i )
Tim_ManSetCoRequired( p->pManTim, i, p->RequiredGlo );
}
else
{
Tim_ManInitPoRequiredAll( p->pManTim, p->RequiredGlo );
// If_ManForEachCo( p, pObj, i )
// Tim_ManSetCoRequired( p->pManTim, pObj->IdPio, p->RequiredGlo );
}
// go through the nodes in the reverse topological order
If_ManForEachObjReverse( p, pObj, i )
{
if ( If_ObjIsAnd(pObj) )
{
if ( pObj->nRefs == 0 )
continue;
If_CutPropagateRequired( p, pObj, If_ObjCutBest(pObj), pObj->Required );
}
else if ( If_ObjIsCi(pObj) )
{
reqTime = pObj->Required;
Tim_ManSetCiRequired( p->pManTim, pObj->IdPio, reqTime );
}
else if ( If_ObjIsCo(pObj) )
{
reqTime = Tim_ManGetCoRequired( p->pManTim, pObj->IdPio );
If_ObjFanin0(pObj)->Required = IF_MIN( reqTime, If_ObjFanin0(pObj)->Required );
}
else if ( If_ObjIsConst1(pObj) )
{
}
else // add the node to the mapper
assert( 0 );
}
}
}
#if 0
/**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