summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2014-04-19 19:57:32 -0700
committerAlan Mishchenko <alanmi@berkeley.edu>2014-04-19 19:57:32 -0700
commit606fed3b847bc2029a9eb4622f0e23eae3c3bb1c (patch)
tree7c18a2f82f814aa01e5b3ff2ae655aae238cf50f
parente868d057bbc6d0d0a0a32bd39f0b90698c50428d (diff)
downloadabc-606fed3b847bc2029a9eb4622f0e23eae3c3bb1c.tar.gz
abc-606fed3b847bc2029a9eb4622f0e23eae3c3bb1c.tar.bz2
abc-606fed3b847bc2029a9eb4622f0e23eae3c3bb1c.zip
Added optimization for average rather than maximum delay.
-rw-r--r--src/aig/gia/giaIf.c4
-rw-r--r--src/base/abci/abc.c34
-rw-r--r--src/map/if/if.h6
-rw-r--r--src/map/if/ifTime.c251
-rw-r--r--src/map/if/ifUtil.c242
5 files changed, 263 insertions, 274 deletions
diff --git a/src/aig/gia/giaIf.c b/src/aig/gia/giaIf.c
index 57cc988f..11a349e3 100644
--- a/src/aig/gia/giaIf.c
+++ b/src/aig/gia/giaIf.c
@@ -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;
}
diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c
index 3a846433..6801ccaa 100644
--- a/src/base/abci/abc.c
+++ b/src/base/abci/abc.c
@@ -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" );
diff --git a/src/map/if/if.h b/src/map/if/if.h
index eeb1abd7..69f8100c 100644
--- a/src/map/if/if.h
+++ b/src/map/if/if.h
@@ -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 );
diff --git a/src/map/if/ifTime.c b/src/map/if/ifTime.c
index 3193c8b0..7402bd31 100644
--- a/src/map/if/ifTime.c
+++ b/src/map/if/ifTime.c
@@ -236,6 +236,257 @@ void If_CutPropagateRequired( If_Man_t * p, If_Obj_t * pObj, If_Cut_t * pCut, fl
}
}
+/**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->fDoAverage )
+ {
+ If_ManForEachCo( p, pObj, i )
+ If_ObjFanin0(pObj)->Required = If_ObjArrTime(If_ObjFanin0(pObj));
+ }
+ else 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->fDoAverage )
+ {
+ If_ManForEachCo( p, pObj, i )
+ Tim_ManSetCoRequired( p->pManTim, i, If_ObjArrTime(If_ObjFanin0(pObj)) );
+ }
+ 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 );
+ }
+ }
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/map/if/ifUtil.c b/src/map/if/ifUtil.c
index eca5fbc6..ec172b1b 100644
--- a/src/map/if/ifUtil.c
+++ b/src/map/if/ifUtil.c
@@ -87,248 +87,6 @@ void If_ManCleanMarkV( If_Man_t * p )
If_ManForEachObj( p, pObj, i )
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