summaryrefslogtreecommitdiffstats
path: root/src/map/mapper/mapperMatch.c
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2014-03-23 16:52:40 -0700
committerAlan Mishchenko <alanmi@berkeley.edu>2014-03-23 16:52:40 -0700
commit6f17c44e9167f810d6f7f03582f2f132464115d5 (patch)
treedd3205f236474b69407e1e7b0118f4ef4567c9ac /src/map/mapper/mapperMatch.c
parentf6eb5262a3176a97f4063f1c49a7d56545fcd53e (diff)
downloadabc-6f17c44e9167f810d6f7f03582f2f132464115d5.tar.gz
abc-6f17c44e9167f810d6f7f03582f2f132464115d5.tar.bz2
abc-6f17c44e9167f810d6f7f03582f2f132464115d5.zip
Integrating barrier buffers into the mapper.
Diffstat (limited to 'src/map/mapper/mapperMatch.c')
-rw-r--r--src/map/mapper/mapperMatch.c508
1 files changed, 264 insertions, 244 deletions
diff --git a/src/map/mapper/mapperMatch.c b/src/map/mapper/mapperMatch.c
index ad559d6a..aa0d97a3 100644
--- a/src/map/mapper/mapperMatch.c
+++ b/src/map/mapper/mapperMatch.c
@@ -36,217 +36,93 @@ ABC_NAMESPACE_IMPL_START
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
-static int Map_MatchNodePhase( Map_Man_t * p, Map_Node_t * pNode, int fPhase );
-static int Map_MatchNodeCut( Map_Man_t * p, Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase, float fWorstLimit );
-
-static void Map_MappingSetPiArrivalTimes( Map_Man_t * p );
-static void Map_NodeTryDroppingOnePhase( Map_Man_t * p, Map_Node_t * pNode );
-static void Map_NodeTransferArrivalTimes( Map_Man_t * p, Map_Node_t * pNode );
-
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
- Synopsis [Computes the best matches of the nodes.]
+ Synopsis [Cleans the match.]
- Description [Uses parameter p->fMappingMode to decide how to assign
- the matches for both polarities of the node. While the matches are
- being assigned, one of them may turn out to be better than the other
- (in terms of delay, for example). In this case, the worse match can
- be permanently dropped, and the corresponding pointer set to NULL.]
+ Description []
SideEffects []
SeeAlso []
***********************************************************************/
-int Map_MappingMatches( Map_Man_t * p )
+void Map_MatchClean( Map_Match_t * pMatch )
{
- ProgressBar * pProgress;
- Map_Node_t * pNode;
- int i;
-
- assert( p->fMappingMode >= 0 && p->fMappingMode <= 4 );
-
- // use the externally given PI arrival times
- if ( p->fMappingMode == 0 )
- Map_MappingSetPiArrivalTimes( p );
-
- // estimate the fanouts
- if ( p->fMappingMode == 0 )
- Map_MappingEstimateRefsInit( p );
- else if ( p->fMappingMode == 1 )
- Map_MappingEstimateRefs( p );
-
- // the PI cuts are matched in the cut computation package
- // in the loop below we match the internal nodes
- pProgress = Extra_ProgressBarStart( stdout, p->vAnds->nSize );
- for ( i = 0; i < p->vAnds->nSize; i++ )
- {
- // skip primary inputs and secondary nodes if mapping with choices
- pNode = p->vAnds->pArray[i];
- if ( !Map_NodeIsAnd( pNode ) || pNode->pRepr )
- continue;
-
- // make sure that at least one non-trival cut is present
- if ( pNode->pCuts->pNext == NULL )
- {
- Extra_ProgressBarStop( pProgress );
- printf( "\nError: A node in the mapping graph does not have feasible cuts.\n" );
- return 0;
- }
-
- // match negative phase
- if ( !Map_MatchNodePhase( p, pNode, 0 ) )
- {
- Extra_ProgressBarStop( pProgress );
- return 0;
- }
- // match positive phase
- if ( !Map_MatchNodePhase( p, pNode, 1 ) )
- {
- Extra_ProgressBarStop( pProgress );
- return 0;
- }
-
- // make sure that at least one phase is mapped
- if ( pNode->pCutBest[0] == NULL && pNode->pCutBest[1] == NULL )
- {
- printf( "\nError: Could not match both phases of AIG node %d.\n", pNode->Num );
- printf( "Please make sure that the supergate library has equivalents of AND2 or NAND2.\n" );
- printf( "If such supergates exist in the library, report a bug.\n" );
- Extra_ProgressBarStop( pProgress );
- return 0;
- }
-
- // if both phases are assigned, check if one of them can be dropped
- Map_NodeTryDroppingOnePhase( p, pNode );
- // set the arrival times of the node using the best cuts
- Map_NodeTransferArrivalTimes( p, pNode );
-
- // update the progress bar
- Extra_ProgressBarUpdate( pProgress, i, "Matches ..." );
- }
- Extra_ProgressBarStop( pProgress );
- return 1;
+ memset( pMatch, 0, sizeof(Map_Match_t) );
+ pMatch->AreaFlow = MAP_FLOAT_LARGE; // unassigned
+ pMatch->tArrive.Rise = MAP_FLOAT_LARGE; // unassigned
+ pMatch->tArrive.Fall = MAP_FLOAT_LARGE; // unassigned
+ pMatch->tArrive.Worst = MAP_FLOAT_LARGE; // unassigned
}
/**Function*************************************************************
- Synopsis [Find the matching of one polarity of the node.]
+ Synopsis [Compares two matches.]
- Description []
+ Description [Returns 1 if the second match is better. Otherwise returns 0.]
SideEffects []
SeeAlso []
***********************************************************************/
-int Map_MatchNodePhase( Map_Man_t * p, Map_Node_t * pNode, int fPhase )
+int Map_MatchCompare( Map_Man_t * pMan, Map_Match_t * pM1, Map_Match_t * pM2, int fDoingArea )
{
- Map_Match_t MatchBest, * pMatch;
- Map_Cut_t * pCut, * pCutBest;
- float Area1 = 0.0; // Suppress "might be used uninitialized
- float Area2, fWorstLimit;
-
- // skip the cuts that have been unassigned during area recovery
- pCutBest = pNode->pCutBest[fPhase];
- if ( p->fMappingMode != 0 && pCutBest == NULL )
- return 1;
-
- // recompute the arrival times of the current best match
- // because the arrival times of the fanins may have changed
- // as a result of remapping fanins in the topological order
- if ( p->fMappingMode != 0 )
- {
- Map_TimeCutComputeArrival( pNode, pCutBest, fPhase, MAP_FLOAT_LARGE );
- // make sure that the required times are met
- assert( pCutBest->M[fPhase].tArrive.Rise < pNode->tRequired[fPhase].Rise + p->fEpsilon );
- assert( pCutBest->M[fPhase].tArrive.Fall < pNode->tRequired[fPhase].Fall + p->fEpsilon );
- }
-
- // recompute the exact area of the current best match
- // because the exact area of the fanins may have changed
- // as a result of remapping fanins in the topological order
- if ( p->fMappingMode == 2 || p->fMappingMode == 3 )
- {
- pMatch = pCutBest->M + fPhase;
- if ( pNode->nRefAct[fPhase] > 0 ||
- (pNode->pCutBest[!fPhase] == NULL && pNode->nRefAct[!fPhase] > 0) )
- pMatch->AreaFlow = Area1 = Map_CutDeref( pCutBest, fPhase );
- else
- pMatch->AreaFlow = Area1 = Map_CutGetAreaDerefed( pCutBest, fPhase );
- }
- else if ( p->fMappingMode == 4 )
+ if ( !fDoingArea )
{
- pMatch = pCutBest->M + fPhase;
- if ( pNode->nRefAct[fPhase] > 0 ||
- (pNode->pCutBest[!fPhase] == NULL && pNode->nRefAct[!fPhase] > 0) )
- pMatch->AreaFlow = Area1 = Map_SwitchCutDeref( pNode, pCutBest, fPhase );
- else
- pMatch->AreaFlow = Area1 = Map_SwitchCutGetDerefed( pNode, pCutBest, fPhase );
+ // compare the arrival times
+ if ( pM1->tArrive.Worst < pM2->tArrive.Worst - pMan->fEpsilon )
+ return 0;
+ if ( pM1->tArrive.Worst > pM2->tArrive.Worst + pMan->fEpsilon )
+ return 1;
+ // compare the areas or area flows
+ if ( pM1->AreaFlow < pM2->AreaFlow - pMan->fEpsilon )
+ return 0;
+ if ( pM1->AreaFlow > pM2->AreaFlow + pMan->fEpsilon )
+ return 1;
+ // compare the fanout limits
+ if ( pM1->pSuperBest->nFanLimit > pM2->pSuperBest->nFanLimit )
+ return 0;
+ if ( pM1->pSuperBest->nFanLimit < pM2->pSuperBest->nFanLimit )
+ return 1;
+ // compare the number of leaves
+ if ( pM1->pSuperBest->nFanins < pM2->pSuperBest->nFanins )
+ return 0;
+ if ( pM1->pSuperBest->nFanins > pM2->pSuperBest->nFanins )
+ return 1;
+ // otherwise prefer the old cut
+ return 0;
}
-
- // save the old mapping
- if ( pCutBest )
- MatchBest = pCutBest->M[fPhase];
else
- Map_MatchClean( &MatchBest );
-
- // select the new best cut
- fWorstLimit = pNode->tRequired[fPhase].Worst;
- for ( pCut = pNode->pCuts->pNext; pCut; pCut = pCut->pNext )
- {
- // limit gate sizes based on fanout count
- if ( (pNode->nRefs > 3 && pCut->nLeaves > 2) || (pNode->nRefs > 1 && pCut->nLeaves > 3) )
- continue;
- pMatch = pCut->M + fPhase;
- if ( pMatch->pSupers == NULL )
- continue;
-
- // find the matches for the cut
- Map_MatchNodeCut( p, pNode, pCut, fPhase, fWorstLimit );
- if ( pMatch->pSuperBest == NULL || pMatch->tArrive.Worst > fWorstLimit + p->fEpsilon )
- continue;
-
- // if the cut can be matched compare the matchings
- if ( Map_MatchCompare( p, &MatchBest, pMatch, p->fMappingMode ) )
- {
- pCutBest = pCut;
- MatchBest = *pMatch;
- // if we are mapping for delay, the worst-case limit should be tightened
- if ( p->fMappingMode == 0 )
- fWorstLimit = MatchBest.tArrive.Worst;
- }
- }
-
- if ( pCutBest == NULL )
- return 1;
-
- // set the new mapping
- pNode->pCutBest[fPhase] = pCutBest;
- pCutBest->M[fPhase] = MatchBest;
-
- // reference the new cut if it used
- if ( p->fMappingMode >= 2 &&
- (pNode->nRefAct[fPhase] > 0 ||
- (pNode->pCutBest[!fPhase] == NULL && pNode->nRefAct[!fPhase] > 0)) )
{
- if ( p->fMappingMode == 2 || p->fMappingMode == 3 )
- Area2 = Map_CutRef( pNode->pCutBest[fPhase], fPhase );
- else if ( p->fMappingMode == 4 )
- Area2 = Map_SwitchCutRef( pNode, pNode->pCutBest[fPhase], fPhase );
- else
- assert( 0 );
-// assert( Area2 < Area1 + p->fEpsilon );
+ // compare the areas or area flows
+ if ( pM1->AreaFlow < pM2->AreaFlow - pMan->fEpsilon )
+ return 0;
+ if ( pM1->AreaFlow > pM2->AreaFlow + pMan->fEpsilon )
+ return 1;
+ // compare the arrival times
+ if ( pM1->tArrive.Worst < pM2->tArrive.Worst - pMan->fEpsilon )
+ return 0;
+ if ( pM1->tArrive.Worst > pM2->tArrive.Worst + pMan->fEpsilon )
+ return 1;
+ // compare the fanout limits
+ if ( pM1->pSuperBest->nFanLimit > pM2->pSuperBest->nFanLimit )
+ return 0;
+ if ( pM1->pSuperBest->nFanLimit < pM2->pSuperBest->nFanLimit )
+ return 1;
+ // compare the number of leaves
+ if ( pM1->pSuperBest->nFanins < pM2->pSuperBest->nFanins )
+ return 0;
+ if ( pM1->pSuperBest->nFanins > pM2->pSuperBest->nFanins )
+ return 1;
+ // otherwise prefer the old cut
+ return 0;
}
-
- // make sure that the requited times are met
- assert( MatchBest.tArrive.Rise < pNode->tRequired[fPhase].Rise + p->fEpsilon );
- assert( MatchBest.tArrive.Fall < pNode->tRequired[fPhase].Fall + p->fEpsilon );
- return 1;
}
/**Function*************************************************************
@@ -347,7 +223,7 @@ int Map_MatchNodeCut( Map_Man_t * p, Map_Node_t * pNode, Map_Cut_t * pCut, int f
/**Function*************************************************************
- Synopsis [Cleans the match.]
+ Synopsis [Find the matching of one polarity of the node.]
Description []
@@ -356,78 +232,109 @@ int Map_MatchNodeCut( Map_Man_t * p, Map_Node_t * pNode, Map_Cut_t * pCut, int f
SeeAlso []
***********************************************************************/
-void Map_MatchClean( Map_Match_t * pMatch )
+int Map_MatchNodePhase( Map_Man_t * p, Map_Node_t * pNode, int fPhase )
{
- memset( pMatch, 0, sizeof(Map_Match_t) );
- pMatch->AreaFlow = MAP_FLOAT_LARGE; // unassigned
- pMatch->tArrive.Rise = MAP_FLOAT_LARGE; // unassigned
- pMatch->tArrive.Fall = MAP_FLOAT_LARGE; // unassigned
- pMatch->tArrive.Worst = MAP_FLOAT_LARGE; // unassigned
-}
-
-/**Function*************************************************************
-
- Synopsis [Compares two matches.]
+ Map_Match_t MatchBest, * pMatch;
+ Map_Cut_t * pCut, * pCutBest;
+ float Area1 = 0.0; // Suppress "might be used uninitialized
+ float Area2, fWorstLimit;
- Description [Returns 1 if the second match is better. Otherwise returns 0.]
-
- SideEffects []
+ // skip the cuts that have been unassigned during area recovery
+ pCutBest = pNode->pCutBest[fPhase];
+ if ( p->fMappingMode != 0 && pCutBest == NULL )
+ return 1;
- SeeAlso []
+ // recompute the arrival times of the current best match
+ // because the arrival times of the fanins may have changed
+ // as a result of remapping fanins in the topological order
+ if ( p->fMappingMode != 0 )
+ {
+ Map_TimeCutComputeArrival( pNode, pCutBest, fPhase, MAP_FLOAT_LARGE );
+ // make sure that the required times are met
+ assert( pCutBest->M[fPhase].tArrive.Rise < pNode->tRequired[fPhase].Rise + p->fEpsilon );
+ assert( pCutBest->M[fPhase].tArrive.Fall < pNode->tRequired[fPhase].Fall + p->fEpsilon );
+ }
-***********************************************************************/
-int Map_MatchCompare( Map_Man_t * pMan, Map_Match_t * pM1, Map_Match_t * pM2, int fDoingArea )
-{
- if ( !fDoingArea )
+ // recompute the exact area of the current best match
+ // because the exact area of the fanins may have changed
+ // as a result of remapping fanins in the topological order
+ if ( p->fMappingMode == 2 || p->fMappingMode == 3 )
{
- // compare the arrival times
- if ( pM1->tArrive.Worst < pM2->tArrive.Worst - pMan->fEpsilon )
- return 0;
- if ( pM1->tArrive.Worst > pM2->tArrive.Worst + pMan->fEpsilon )
- return 1;
- // compare the areas or area flows
- if ( pM1->AreaFlow < pM2->AreaFlow - pMan->fEpsilon )
- return 0;
- if ( pM1->AreaFlow > pM2->AreaFlow + pMan->fEpsilon )
- return 1;
- // compare the fanout limits
- if ( pM1->pSuperBest->nFanLimit > pM2->pSuperBest->nFanLimit )
- return 0;
- if ( pM1->pSuperBest->nFanLimit < pM2->pSuperBest->nFanLimit )
- return 1;
- // compare the number of leaves
- if ( pM1->pSuperBest->nFanins < pM2->pSuperBest->nFanins )
- return 0;
- if ( pM1->pSuperBest->nFanins > pM2->pSuperBest->nFanins )
- return 1;
- // otherwise prefer the old cut
- return 0;
+ pMatch = pCutBest->M + fPhase;
+ if ( pNode->nRefAct[fPhase] > 0 ||
+ (pNode->pCutBest[!fPhase] == NULL && pNode->nRefAct[!fPhase] > 0) )
+ pMatch->AreaFlow = Area1 = Map_CutDeref( pCutBest, fPhase );
+ else
+ pMatch->AreaFlow = Area1 = Map_CutGetAreaDerefed( pCutBest, fPhase );
}
+ else if ( p->fMappingMode == 4 )
+ {
+ pMatch = pCutBest->M + fPhase;
+ if ( pNode->nRefAct[fPhase] > 0 ||
+ (pNode->pCutBest[!fPhase] == NULL && pNode->nRefAct[!fPhase] > 0) )
+ pMatch->AreaFlow = Area1 = Map_SwitchCutDeref( pNode, pCutBest, fPhase );
+ else
+ pMatch->AreaFlow = Area1 = Map_SwitchCutGetDerefed( pNode, pCutBest, fPhase );
+ }
+
+ // save the old mapping
+ if ( pCutBest )
+ MatchBest = pCutBest->M[fPhase];
else
+ Map_MatchClean( &MatchBest );
+
+ // select the new best cut
+ fWorstLimit = pNode->tRequired[fPhase].Worst;
+ for ( pCut = pNode->pCuts->pNext; pCut; pCut = pCut->pNext )
{
- // compare the areas or area flows
- if ( pM1->AreaFlow < pM2->AreaFlow - pMan->fEpsilon )
- return 0;
- if ( pM1->AreaFlow > pM2->AreaFlow + pMan->fEpsilon )
- return 1;
- // compare the arrival times
- if ( pM1->tArrive.Worst < pM2->tArrive.Worst - pMan->fEpsilon )
- return 0;
- if ( pM1->tArrive.Worst > pM2->tArrive.Worst + pMan->fEpsilon )
- return 1;
- // compare the fanout limits
- if ( pM1->pSuperBest->nFanLimit > pM2->pSuperBest->nFanLimit )
- return 0;
- if ( pM1->pSuperBest->nFanLimit < pM2->pSuperBest->nFanLimit )
- return 1;
- // compare the number of leaves
- if ( pM1->pSuperBest->nFanins < pM2->pSuperBest->nFanins )
- return 0;
- if ( pM1->pSuperBest->nFanins > pM2->pSuperBest->nFanins )
- return 1;
- // otherwise prefer the old cut
- return 0;
+ // limit gate sizes based on fanout count
+ if ( (pNode->nRefs > 3 && pCut->nLeaves > 2) || (pNode->nRefs > 1 && pCut->nLeaves > 3) )
+ continue;
+ pMatch = pCut->M + fPhase;
+ if ( pMatch->pSupers == NULL )
+ continue;
+
+ // find the matches for the cut
+ Map_MatchNodeCut( p, pNode, pCut, fPhase, fWorstLimit );
+ if ( pMatch->pSuperBest == NULL || pMatch->tArrive.Worst > fWorstLimit + p->fEpsilon )
+ continue;
+
+ // if the cut can be matched compare the matchings
+ if ( Map_MatchCompare( p, &MatchBest, pMatch, p->fMappingMode ) )
+ {
+ pCutBest = pCut;
+ MatchBest = *pMatch;
+ // if we are mapping for delay, the worst-case limit should be tightened
+ if ( p->fMappingMode == 0 )
+ fWorstLimit = MatchBest.tArrive.Worst;
+ }
}
+
+ if ( pCutBest == NULL )
+ return 1;
+
+ // set the new mapping
+ pNode->pCutBest[fPhase] = pCutBest;
+ pCutBest->M[fPhase] = MatchBest;
+
+ // reference the new cut if it used
+ if ( p->fMappingMode >= 2 &&
+ (pNode->nRefAct[fPhase] > 0 ||
+ (pNode->pCutBest[!fPhase] == NULL && pNode->nRefAct[!fPhase] > 0)) )
+ {
+ if ( p->fMappingMode == 2 || p->fMappingMode == 3 )
+ Area2 = Map_CutRef( pNode->pCutBest[fPhase], fPhase );
+ else if ( p->fMappingMode == 4 )
+ Area2 = Map_SwitchCutRef( pNode, pNode->pCutBest[fPhase], fPhase );
+ else
+ assert( 0 );
+// assert( Area2 < Area1 + p->fEpsilon );
+ }
+
+ // make sure that the requited times are met
+ assert( MatchBest.tArrive.Rise < pNode->tRequired[fPhase].Rise + p->fEpsilon );
+ assert( MatchBest.tArrive.Fall < pNode->tRequired[fPhase].Fall + p->fEpsilon );
+ return 1;
}
/**Function*************************************************************
@@ -460,6 +367,25 @@ void Map_MappingSetPiArrivalTimes( Map_Man_t * p )
}
}
+/**function*************************************************************
+
+ synopsis [Computes the exact area associated with the cut.]
+
+ description []
+
+ sideeffects []
+
+ seealso []
+
+***********************************************************************/
+float Map_TimeMatchWithInverter( Map_Man_t * p, Map_Match_t * pMatch )
+{
+ Map_Time_t tArrInv;
+ tArrInv.Fall = pMatch->tArrive.Rise + p->pSuperLib->tDelayInv.Fall;
+ tArrInv.Rise = pMatch->tArrive.Fall + p->pSuperLib->tDelayInv.Rise;
+ tArrInv.Worst = MAP_MAX( tArrInv.Rise, tArrInv.Fall );
+ return tArrInv.Worst;
+}
/**Function*************************************************************
@@ -609,6 +535,100 @@ void Map_NodeTransferArrivalTimes( Map_Man_t * p, Map_Node_t * pNode )
assert( pNode->tArrival[1].Fall < pNode->tRequired[1].Fall + p->fEpsilon );
}
+/**Function*************************************************************
+
+ Synopsis [Computes the best matches of the nodes.]
+
+ Description [Uses parameter p->fMappingMode to decide how to assign
+ the matches for both polarities of the node. While the matches are
+ being assigned, one of them may turn out to be better than the other
+ (in terms of delay, for example). In this case, the worse match can
+ be permanently dropped, and the corresponding pointer set to NULL.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Map_MappingMatches( Map_Man_t * p )
+{
+ ProgressBar * pProgress;
+ Map_Node_t * pNode;
+ int i;
+
+ assert( p->fMappingMode >= 0 && p->fMappingMode <= 4 );
+
+ // use the externally given PI arrival times
+ if ( p->fMappingMode == 0 )
+ Map_MappingSetPiArrivalTimes( p );
+
+ // estimate the fanouts
+ if ( p->fMappingMode == 0 )
+ Map_MappingEstimateRefsInit( p );
+ else if ( p->fMappingMode == 1 )
+ Map_MappingEstimateRefs( p );
+
+ // the PI cuts are matched in the cut computation package
+ // in the loop below we match the internal nodes
+ pProgress = Extra_ProgressBarStart( stdout, p->vMapObjs->nSize );
+ for ( i = 0; i < p->vMapObjs->nSize; i++ )
+ {
+ pNode = p->vMapObjs->pArray[i];
+ if ( Map_NodeIsBuf(pNode) )
+ {
+ assert( pNode->p2 == NULL );
+ pNode->tArrival[0] = Map_Regular(pNode->p1)->tArrival[ Map_IsComplement(pNode->p1)];
+ pNode->tArrival[1] = Map_Regular(pNode->p1)->tArrival[!Map_IsComplement(pNode->p1)];
+ continue;
+ }
+
+ // skip primary inputs and secondary nodes if mapping with choices
+ if ( !Map_NodeIsAnd( pNode ) || pNode->pRepr )
+ continue;
+
+ // make sure that at least one non-trival cut is present
+ if ( pNode->pCuts->pNext == NULL )
+ {
+ Extra_ProgressBarStop( pProgress );
+ printf( "\nError: A node in the mapping graph does not have feasible cuts.\n" );
+ return 0;
+ }
+
+ // match negative phase
+ if ( !Map_MatchNodePhase( p, pNode, 0 ) )
+ {
+ Extra_ProgressBarStop( pProgress );
+ return 0;
+ }
+ // match positive phase
+ if ( !Map_MatchNodePhase( p, pNode, 1 ) )
+ {
+ Extra_ProgressBarStop( pProgress );
+ return 0;
+ }
+
+ // make sure that at least one phase is mapped
+ if ( pNode->pCutBest[0] == NULL && pNode->pCutBest[1] == NULL )
+ {
+ printf( "\nError: Could not match both phases of AIG node %d.\n", pNode->Num );
+ printf( "Please make sure that the supergate library has equivalents of AND2 or NAND2.\n" );
+ printf( "If such supergates exist in the library, report a bug.\n" );
+ Extra_ProgressBarStop( pProgress );
+ return 0;
+ }
+
+ // if both phases are assigned, check if one of them can be dropped
+ Map_NodeTryDroppingOnePhase( p, pNode );
+ // set the arrival times of the node using the best cuts
+ Map_NodeTransferArrivalTimes( p, pNode );
+
+ // update the progress bar
+ Extra_ProgressBarUpdate( pProgress, i, "Matches ..." );
+ }
+ Extra_ProgressBarStop( pProgress );
+ return 1;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////