00001 
00019 #include "fpgaInt.h"
00020 
00024 
00025 static int          Fpga_MatchNode( Fpga_Man_t * p, Fpga_Node_t * pNode, int fDelayOriented );
00026 static int          Fpga_MatchNodeArea( Fpga_Man_t * p, Fpga_Node_t * pNode );
00027 static int          Fpga_MatchNodeSwitch( Fpga_Man_t * p, Fpga_Node_t * pNode );
00028 
00029 static Fpga_Cut_t * Fpga_MappingAreaWithoutNode( Fpga_Man_t * p, Fpga_Node_t * pFanout, Fpga_Node_t * pNodeNo );
00030 static int          Fpga_MappingMatchesAreaArray( Fpga_Man_t * p, Fpga_NodeVec_t * vNodes );
00031 
00035 
00064 int Fpga_MappingMatches( Fpga_Man_t * p, int fDelayOriented )
00065 {
00066     ProgressBar * pProgress;
00067     Fpga_Node_t * pNode;
00068     int i, nNodes;
00069     
00070     
00071     for ( i = 0; i < p->nInputs; i++ )
00072         p->pInputs[i]->pCutBest->tArrival = p->pInputArrivals[i];
00073 
00074     
00075     nNodes = p->vAnds->nSize;
00076     pProgress = Extra_ProgressBarStart( stdout, nNodes );
00077     for ( i = 0; i < nNodes; i++ )
00078     {
00079         pNode = p->vAnds->pArray[i];
00080         if ( !Fpga_NodeIsAnd( pNode ) )
00081             continue;
00082         
00083         if ( pNode->pRepr )
00084             continue;
00085         
00086         Fpga_MatchNode( p, pNode, fDelayOriented );
00087         Extra_ProgressBarUpdate( pProgress, i, "Matches ..." );
00088     }
00089     Extra_ProgressBarStop( pProgress );
00090 
00091 
00092 
00093 
00094 
00095 
00096 
00097 
00098 
00099 
00100 
00101 
00102     return 1;
00103 }
00104 
00116 int Fpga_MatchNode( Fpga_Man_t * p, Fpga_Node_t * pNode, int fDelayOriented )
00117 {
00118     Fpga_Cut_t * pCut, * pCutBestOld;
00119     int clk;
00120     
00121     if ( pNode->pCuts->pNext == NULL )
00122     {
00123         printf( "\nError: A node in the mapping graph does not have feasible cuts.\n" );
00124         return 0;
00125     }
00126 
00127     
00128     if ( pNode->aEstFanouts < 0 )
00129         pNode->aEstFanouts = (float)pNode->nRefs;
00130     else
00131         pNode->aEstFanouts = (float)((2.0 * pNode->aEstFanouts + pNode->nRefs) / 3.0);
00132 
00133 
00134     pCutBestOld = pNode->pCutBest;
00135     pNode->pCutBest = NULL;
00136     for ( pCut = pNode->pCuts->pNext; pCut; pCut = pCut->pNext )
00137     {
00138         
00139 clk = clock();
00140         Fpga_CutGetParameters( p, pCut );
00141 
00142         
00143         if ( Fpga_FloatMoreThan(p, pCut->tArrival, pNode->tRequired) )
00144             continue;
00145         
00146         if ( pNode->pCutBest == NULL )
00147         {
00148             pNode->pCutBest = pCut;
00149             continue;
00150         }
00151         
00152         
00153         
00154         if ( (fDelayOriented && 
00155                (Fpga_FloatMoreThan(p, pNode->pCutBest->tArrival, pCut->tArrival) || 
00156                 Fpga_FloatEqual(p, pNode->pCutBest->tArrival, pCut->tArrival) && Fpga_FloatMoreThan(p, pNode->pCutBest->aFlow, pCut->aFlow) )) ||
00157              (!fDelayOriented && 
00158                (Fpga_FloatMoreThan(p, pNode->pCutBest->aFlow, pCut->aFlow) || 
00159                 Fpga_FloatEqual(p, pNode->pCutBest->aFlow, pCut->aFlow) && Fpga_FloatMoreThan(p, pNode->pCutBest->tArrival, pCut->tArrival)))  )
00160         {
00161             pNode->pCutBest = pCut;
00162         }
00163     }
00164 
00165     
00166     if ( pNode->pCutBest == NULL )
00167     {
00168         if ( pCutBestOld == NULL )
00169         {
00170 
00171             return 0;
00172         }
00173         pNode->pCutBest = pCutBestOld;
00174     }
00175     return 1;
00176 }
00177 
00178 
00179 
00180 
00181 
00193 int Fpga_MappingMatchesArea( Fpga_Man_t * p )
00194 {
00195     ProgressBar * pProgress;
00196     Fpga_Node_t * pNode;
00197     int i, nNodes;
00198     
00199     
00200     for ( i = 0; i < p->nInputs; i++ )
00201         p->pInputs[i]->pCutBest->tArrival = p->pInputArrivals[i];
00202 
00203     
00204     nNodes = p->vAnds->nSize;
00205     pProgress = Extra_ProgressBarStart( stdout, nNodes );
00206     for ( i = 0; i < nNodes; i++ )
00207     {
00208         pNode = p->vAnds->pArray[i];
00209         if ( !Fpga_NodeIsAnd( pNode ) )
00210             continue;
00211         
00212         if ( pNode->pRepr )
00213             continue;
00214         
00215         Fpga_MatchNodeArea( p, pNode );
00216         Extra_ProgressBarUpdate( pProgress, i, "Matches ..." );
00217     }
00218     Extra_ProgressBarStop( pProgress );
00219     return 1;
00220 }
00221 
00233 int Fpga_MappingMatchesAreaArray( Fpga_Man_t * p, Fpga_NodeVec_t * vNodes )
00234 {
00235     Fpga_Node_t * pNode;
00236     int i;
00237 
00238     
00239     for ( i = 0; i < vNodes->nSize; i++ )
00240     {
00241         pNode = vNodes->pArray[i];
00242         if ( !Fpga_NodeIsAnd( pNode ) )
00243             continue;
00244         
00245         if ( pNode->pRepr )
00246             continue;
00247         
00248         if ( !Fpga_MatchNodeArea( p, pNode ) )
00249             return 0;
00250     }
00251     return 1;
00252 }
00253 
00265 int Fpga_MatchNodeArea( Fpga_Man_t * p, Fpga_Node_t * pNode )
00266 {
00267     Fpga_Cut_t * pCut, * pCutBestOld;
00268     float aAreaCutBest;
00269     int clk;
00270     
00271     if ( pNode->pCuts->pNext == NULL )
00272     {
00273         printf( "\nError: A node in the mapping graph does not have feasible cuts.\n" );
00274         return 0;
00275     }
00276 
00277     
00278     pCutBestOld = pNode->pCutBest;
00279     
00280     if ( pNode->nRefs ) 
00281         aAreaCutBest = Fpga_CutDeref( p, pNode, pNode->pCutBest, 0 );
00282 
00283     
00284     pNode->pCutBest = NULL;
00285     for ( pCut = pNode->pCuts->pNext; pCut; pCut = pCut->pNext )
00286     {
00287         
00288 clk = clock();
00289         pCut->tArrival = Fpga_TimeCutComputeArrival( p, pCut );
00290 
00291         
00292         if ( Fpga_FloatMoreThan( p, pCut->tArrival, pNode->tRequired ) )
00293             continue;
00294         
00295         pCut->aFlow = Fpga_CutGetAreaDerefed( p, pCut );
00296         
00297         if ( pNode->pCutBest == NULL )
00298         {
00299             pNode->pCutBest = pCut;
00300             continue;
00301         }
00302         
00303         if ( Fpga_FloatMoreThan(p, pNode->pCutBest->aFlow, pCut->aFlow) || 
00304              Fpga_FloatEqual(p, pNode->pCutBest->aFlow, pCut->aFlow) && Fpga_FloatMoreThan(p, pNode->pCutBest->tArrival, pCut->tArrival) )
00305         {
00306             pNode->pCutBest = pCut;
00307         }
00308     }
00309 
00310     
00311     if ( pNode->pCutBest == NULL )
00312     {
00313         pNode->pCutBest = pCutBestOld; 
00314         
00315         if ( pNode->nRefs ) 
00316             pNode->pCutBest->aFlow = Fpga_CutRef( p, pNode, pNode->pCutBest, 0 );
00317 
00318         return 0;
00319     }
00320 
00321     
00322     
00323     if ( pNode->nRefs ) 
00324     {
00325         pNode->pCutBest->aFlow = Fpga_CutRef( p, pNode, pNode->pCutBest, 0 );
00326 
00327 
00328     }
00329     return 1;
00330 }
00331 
00332 
00333 
00334 
00346 int Fpga_MappingMatchesSwitch( Fpga_Man_t * p )
00347 {
00348     ProgressBar * pProgress;
00349     Fpga_Node_t * pNode;
00350     int i, nNodes;
00351     
00352     
00353     for ( i = 0; i < p->nInputs; i++ )
00354         p->pInputs[i]->pCutBest->tArrival = p->pInputArrivals[i];
00355 
00356     
00357     nNodes = p->vAnds->nSize;
00358     pProgress = Extra_ProgressBarStart( stdout, nNodes );
00359     for ( i = 0; i < nNodes; i++ )
00360     {
00361         pNode = p->vAnds->pArray[i];
00362         if ( !Fpga_NodeIsAnd( pNode ) )
00363             continue;
00364         
00365         if ( pNode->pRepr )
00366             continue;
00367         
00368         Fpga_MatchNodeSwitch( p, pNode );
00369         Extra_ProgressBarUpdate( pProgress, i, "Matches ..." );
00370     }
00371     Extra_ProgressBarStop( pProgress );
00372     return 1;
00373 }
00374 
00386 int Fpga_MatchNodeSwitch( Fpga_Man_t * p, Fpga_Node_t * pNode )
00387 {
00388     Fpga_Cut_t * pCut, * pCutBestOld;
00389     float aAreaCutBest;
00390     int clk;
00391     
00392     if ( pNode->pCuts->pNext == NULL )
00393     {
00394         printf( "\nError: A node in the mapping graph does not have feasible cuts.\n" );
00395         return 0;
00396     }
00397 
00398     
00399     pCutBestOld = pNode->pCutBest;
00400     
00401     if ( pNode->nRefs ) 
00402         aAreaCutBest = Fpga_CutDerefSwitch( p, pNode, pNode->pCutBest, 0 );
00403 
00404     
00405     pNode->pCutBest = NULL;
00406     for ( pCut = pNode->pCuts->pNext; pCut; pCut = pCut->pNext )
00407     {
00408         
00409 clk = clock();
00410         pCut->tArrival = Fpga_TimeCutComputeArrival( p, pCut );
00411 
00412         
00413         if ( Fpga_FloatMoreThan( p, pCut->tArrival, pNode->tRequired ) )
00414             continue;
00415         
00416         pCut->aFlow = Fpga_CutGetSwitchDerefed( p, pNode, pCut );
00417         
00418         if ( pNode->pCutBest == NULL )
00419         {
00420             pNode->pCutBest = pCut;
00421             continue;
00422         }
00423         
00424         if ( Fpga_FloatMoreThan(p, pNode->pCutBest->aFlow, pCut->aFlow) || 
00425              Fpga_FloatEqual(p, pNode->pCutBest->aFlow, pCut->aFlow) && Fpga_FloatMoreThan(p, pNode->pCutBest->tArrival, pCut->tArrival) )
00426         {
00427             pNode->pCutBest = pCut;
00428         }
00429     }
00430 
00431     
00432     if ( pNode->pCutBest == NULL )
00433     {
00434         pNode->pCutBest = pCutBestOld; 
00435         
00436         if ( pNode->nRefs ) 
00437             pNode->pCutBest->aFlow = Fpga_CutRefSwitch( p, pNode, pNode->pCutBest, 0 );
00438 
00439         return 0;
00440     }
00441 
00442     
00443     
00444     if ( pNode->nRefs ) 
00445     {
00446         pNode->pCutBest->aFlow = Fpga_CutRefSwitch( p, pNode, pNode->pCutBest, 0 );
00447         assert( pNode->pCutBest->aFlow <= aAreaCutBest + 0.001 );
00448 
00449     }
00450     return 1;
00451 }
00452 
00453 
00454 #if 0
00455 
00466 void Fpga_Experiment( Fpga_Man_t * p )
00467 {
00468     int Counter[10] = {0};
00469     Fpga_Node_t * pNode;
00470     int i;
00471 
00472     for ( i = 0; i < p->nOutputs; i++ )
00473     {
00474         pNode = Fpga_Regular(p->pOutputs[i]);
00475         pNode->vFanouts = NULL;
00476     }
00477 
00478     for ( i = 0; i < p->vAnds->nSize; i++ )
00479     {
00480         pNode = p->vAnds->pArray[i];
00481         if ( !Fpga_NodeIsAnd( pNode ) )
00482             continue;
00483         if ( pNode->vFanouts == NULL )
00484             continue;
00485         if ( pNode->vFanouts->nSize >= 10 )
00486             continue;
00487         Counter[pNode->vFanouts->nSize]++;
00488     }
00489 
00490     printf( "Fanout stats: " );
00491     for ( i = 0; i < 10; i++ )
00492         printf( " %d=%d", i, Counter[i] );
00493     printf( "\n" );
00494     printf( "Area before = %4.2f.\n", Fpga_MappingArea(p) );
00495 
00496     for ( i = 0; i < p->vAnds->nSize; i++ )
00497     {
00498         Fpga_NodeVec_t * vNodesTfo;
00499         float AreaBefore;
00500 
00501         pNode = p->vAnds->pArray[i];
00502         if ( !Fpga_NodeIsAnd( pNode ) )
00503             continue;
00504         if ( pNode->vFanouts == NULL )
00505             continue;
00506         if ( pNode->vFanouts->nSize != 1 && pNode->vFanouts->nSize != 2 && pNode->vFanouts->nSize != 3 )
00507             continue;
00508 
00509 
00510         if ( pNode->nRefs == 0 )
00511             continue;
00512 
00513         AreaBefore = pNode->pCutBest->aFlow;
00514         pNode->pCutBest->aFlow = FPGA_FLOAT_LARGE;
00515 
00516         Fpga_TimeComputeRequiredGlobal( p, 0 );
00517 
00518         vNodesTfo = Fpga_CollectNodeTfo( p, pNode );
00519         if ( Fpga_MappingMatchesAreaArray( p, vNodesTfo ) == 0 )
00520             printf( "attempt failed\n" );
00521         else
00522             printf( "attempt succeeded\n" );
00523         Fpga_NodeVecFree( vNodesTfo );
00524 
00525         pNode->pCutBest->aFlow = AreaBefore;
00526 
00527     }
00528     printf( "Area after = %4.2f.\n", Fpga_MappingArea(p) );
00529 
00530 }
00531 
00532 
00533 
00545 void Fpga_Experiment2( Fpga_Man_t * p )
00546 {
00547     int Counter[10] = {0};
00548     Fpga_Cut_t * ppCutsNew[10];
00549     Fpga_Cut_t * ppCutsOld[10];
00550     Fpga_Node_t * pFanout, * pNode;
00551     float Gain, Loss, GainTotal,  Area1, Area2;
00552     int i, k;
00553 
00554     for ( i = 0; i < p->nOutputs; i++ )
00555     {
00556         pNode = Fpga_Regular(p->pOutputs[i]);
00557         pNode->vFanouts = NULL;
00558     }
00559 
00560     for ( i = 0; i < p->vAnds->nSize; i++ )
00561     {
00562         pNode = p->vAnds->pArray[i];
00563         if ( !Fpga_NodeIsAnd( pNode ) )
00564             continue;
00565         if ( pNode->vFanouts == NULL )
00566             continue;
00567         if ( pNode->vFanouts->nSize >= 10 )
00568             continue;
00569         Counter[pNode->vFanouts->nSize]++;
00570     }
00571 
00572     printf( "Fanout stats: " );
00573     for ( i = 0; i < 10; i++ )
00574         printf( " %d=%d", i, Counter[i] );
00575     printf( "\n" );
00576     printf( "Area before = %4.2f.\n", Fpga_MappingArea(p) );
00577 
00578     GainTotal = 0;
00579     for ( i = 0; i < p->vAnds->nSize; i++ )
00580     {
00581         pNode = p->vAnds->pArray[i];
00582         if ( !Fpga_NodeIsAnd( pNode ) )
00583             continue;
00584         if ( pNode->vFanouts == NULL )
00585             continue;
00586         if ( pNode->vFanouts->nSize != 2 )
00587             continue;
00588 
00589         assert( pNode->nRefs > 0 );
00590 
00591         
00592         for ( k = 0; k < pNode->vFanouts->nSize; k++ )
00593         {
00594             pFanout = pNode->vFanouts->pArray[k];
00595             ppCutsOld[k] = pFanout->pCutBest;
00596             ppCutsNew[k] = Fpga_MappingAreaWithoutNode( p, pFanout, pNode );
00597             if ( ppCutsNew[k] == NULL )
00598                 break;
00599         }
00600         if ( k != pNode->vFanouts->nSize )
00601         {
00602             printf( "Node %4d: Skipped.\n", pNode->Num );
00603             continue;
00604         }
00605 
00606 
00607         
00608         Gain = 0;
00609         for ( k = 0; k < pNode->vFanouts->nSize; k++ )
00610         {
00611             pFanout = pNode->vFanouts->pArray[k];
00612             
00613             Area1 = Fpga_MatchAreaDeref( p, ppCutsOld[k] );
00614             
00615             pFanout->pCutBest = ppCutsNew[k];
00616             
00617             Area2 = Fpga_MatchAreaRef( p, ppCutsNew[k] );
00618             
00619             Gain += Area1 - Area2;
00620         }
00621 
00622         printf( "%d ", pNode->nRefs );
00623 
00624         
00625         Loss = 0;
00626         for ( k = 0; k < pNode->vFanouts->nSize; k++ )
00627         {
00628             pFanout = pNode->vFanouts->pArray[k];
00629             
00630             Area1 = Fpga_MatchAreaDeref( p, ppCutsNew[k] );
00631             
00632             pFanout->pCutBest = ppCutsOld[k];
00633             
00634             Area2 = Fpga_MatchAreaRef( p, ppCutsOld[k] );
00635             
00636             Loss += Area2 - Area1;
00637         }
00638         assert( Gain == Loss );
00639 
00640 
00641         printf( "Node %4d: Fanouts = %d. Cut area = %4.2f. Gain = %4.2f.\n", 
00642             pNode->Num, pNode->nRefs, pNode->pCutBest->aFlow, Gain );
00643 
00644         if ( Gain > 0 )
00645             GainTotal += Gain;
00646     }
00647     printf( "Area after = %4.2f.\n", Fpga_MappingArea(p) );
00648     printf( "AREA GAIN = %4.2f (%.2f %%)\n", GainTotal, 100.0 * GainTotal / Fpga_MappingArea(p) );
00649 }
00650 
00651 
00663 Fpga_Cut_t * Fpga_MappingAreaWithoutNode( Fpga_Man_t * p, Fpga_Node_t * pNode, Fpga_Node_t * pNodeNo )
00664 {
00665     Fpga_Cut_t * pCut, * pCutBestOld, * pCutRes;
00666     float aAreaCutBest;
00667     int i, clk;
00668     
00669     if ( pNode->pCuts->pNext == NULL )
00670     {
00671         printf( "\nError: A node in the mapping graph does not have feasible cuts.\n" );
00672         return 0;
00673     }
00674 
00675     assert( pNode->nRefs > 0 );
00676 
00677     
00678     pCutBestOld = pNode->pCutBest;
00679     
00680     aAreaCutBest = Fpga_MatchAreaDeref( p, pNode->pCutBest );
00681 
00682     
00683     pNode->pCutBest = NULL;
00684     for ( pCut = pNode->pCuts->pNext; pCut; pCut = pCut->pNext )
00685     {
00686         
00687 clk = clock();
00688         Fpga_MatchCutGetArrTime( p, pCut );
00689 
00690         
00691         if ( pCut->tArrival > pNode->tRequired )
00692             continue;
00693 
00694         
00695         for ( i = 0; i < pCut->nLeaves; i++ )
00696             if ( pCut->ppLeaves[i] == pNodeNo )
00697                 break;
00698         if ( i != pCut->nLeaves )
00699             continue;
00700 
00701         
00702         pCut->aFlow = Fpga_MatchAreaCount( p, pCut );
00703         
00704         if ( pNode->pCutBest == NULL )
00705         {
00706             pNode->pCutBest = pCut;
00707             continue;
00708         }
00709         
00710         if ( pNode->pCutBest->aFlow >  pCut->aFlow || 
00711              pNode->pCutBest->aFlow == pCut->aFlow && pNode->pCutBest->tArrival > pCut->tArrival  )
00712         {
00713             pNode->pCutBest = pCut;
00714         }
00715     }
00716 
00717     
00718     if ( pNode->pCutBest == NULL )
00719     {
00720         pNode->pCutBest = pCutBestOld;
00721         
00722         pNode->pCutBest->aFlow = Fpga_MatchAreaRef( p, pNode->pCutBest );
00723         return NULL;
00724     }
00725 
00726     pCutRes = pNode->pCutBest;
00727     pNode->pCutBest = pCutBestOld;
00728 
00729     
00730     pNode->pCutBest->aFlow = Fpga_MatchAreaRef( p, pNode->pCutBest );
00731 
00732     
00733     assert( pNode->pCutBest->aFlow == aAreaCutBest );
00734     assert( pNode->tRequired < FPGA_FLOAT_LARGE );
00735     return pCutRes;
00736 }
00737 
00738 #endif
00739 
00740 
00752 float Fpga_FindBestNode( Fpga_Man_t * p, Fpga_NodeVec_t * vNodes, Fpga_Node_t ** ppNode, Fpga_Cut_t ** ppCutBest )
00753 {
00754     Fpga_Node_t * pNode;
00755     Fpga_Cut_t * pCut;
00756     float Gain, CutArea1, CutArea2, CutArea3;
00757     int i;
00758 
00759     Gain = 0;
00760     for ( i = 0; i < vNodes->nSize; i++ )
00761     {
00762         pNode = vNodes->pArray[i];
00763         
00764         CutArea1 = Fpga_CutDeref( p, pNode, pNode->pCutBest, 0 );
00765 
00766         
00767         for ( pCut = pNode->pCuts->pNext; pCut; pCut = pCut->pNext )
00768         {
00769             if ( pCut == pNode->pCutBest )
00770                 continue;
00771             if ( pCut->tArrival > pNode->tRequired )
00772                 continue;
00773 
00774             CutArea2 = Fpga_CutGetAreaDerefed( p, pCut );
00775             if ( Gain < CutArea1 - CutArea2 )
00776             {
00777                 *ppNode = pNode;
00778                 *ppCutBest = pCut;
00779                 Gain = CutArea1 - CutArea2;
00780             }
00781         }
00782         
00783         CutArea3 = Fpga_CutRef( p, pNode, pNode->pCutBest, 0 );
00784         assert( CutArea1 == CutArea3 );
00785     }
00786     if ( Gain == 0 )
00787         printf( "Returning no gain.\n" );
00788 
00789     return Gain;
00790 }
00791