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