00001
00019 #include "superInt.h"
00020
00024
00025
00026 #define SUPER_MASK(n) ((~((unsigned)0)) >> (32-(n)))
00027 #define SUPER_FULL (~((unsigned)0))
00028 #define SUPER_NO_VAR (-9999.0)
00029 #define SUPER_EPSILON (0.001)
00030
00031
00032 typedef struct Super_ManStruct_t_ Super_Man_t;
00033 typedef struct Super_GateStruct_t_ Super_Gate_t;
00034
00035 struct Super_ManStruct_t_
00036 {
00037
00038 char * pName;
00039 int nVarsMax;
00040 int nMints;
00041 int nLevels;
00042 float tDelayMax;
00043 float tAreaMax;
00044 int fSkipInv;
00045 int fWriteOldFormat;
00046 int fVerbose;
00047
00048
00049 Super_Gate_t * pInputs[10];
00050 int nGates;
00051 Super_Gate_t ** pGates;
00052 stmm_table * tTable;
00053
00054
00055 Extra_MmFixed_t * pMem;
00056 Extra_MmFlex_t * pMemFlex;
00057
00058
00059 int nTried;
00060 int nAdded;
00061 int nRemoved;
00062 int nUnique;
00063 int nLookups;
00064 int nAliases;
00065
00066
00067 int Time;
00068 int TimeLimit;
00069 int TimeSec;
00070 int TimeStop;
00071 int TimePrint;
00072 };
00073
00074 struct Super_GateStruct_t_
00075 {
00076 Mio_Gate_t * pRoot;
00077 unsigned fVar : 1;
00078 unsigned fSuper : 1;
00079 unsigned nFanins : 6;
00080 unsigned Number : 24;
00081 unsigned uTruth[2];
00082 Super_Gate_t * pFanins[6];
00083 float Area;
00084 float ptDelays[6];
00085 float tDelayMax;
00086 Super_Gate_t * pNext;
00087 };
00088
00089
00090
00091 #define Super_ManForEachGate( GateArray, Limit, Index, Gate ) \
00092 for ( Index = 0; \
00093 Index < Limit && (Gate = GateArray[Index]); \
00094 Index++ )
00095
00096
00097 static Super_Man_t * Super_ManStart();
00098 static void Super_ManStop( Super_Man_t * pMan );
00099
00100 static void Super_AddGateToTable( Super_Man_t * pMan, Super_Gate_t * pGate );
00101 static void Super_First( Super_Man_t * pMan, int nVarsMax );
00102 static Super_Man_t * Super_Compute( Super_Man_t * pMan, Mio_Gate_t ** ppGates, int nGates, bool fSkipInv );
00103 static Super_Gate_t * Super_CreateGateNew( Super_Man_t * pMan, Mio_Gate_t * pRoot, Super_Gate_t ** pSupers, int nSupers, unsigned uTruth[], float Area, float tPinDelaysRes[], float tDelayMax, int nPins );
00104 static bool Super_CompareGates( Super_Man_t * pMan, unsigned uTruth[], float Area, float tPinDelaysRes[], int nPins );
00105 static int Super_DelayCompare( Super_Gate_t ** ppG1, Super_Gate_t ** ppG2 );
00106 static int Super_AreaCompare( Super_Gate_t ** ppG1, Super_Gate_t ** ppG2 );
00107 static void Super_TranferGatesToArray( Super_Man_t * pMan );
00108 static int Super_CheckTimeout( ProgressBar * pPro, Super_Man_t * pMan );
00109
00110 static void Super_Write( Super_Man_t * pMan );
00111 static int Super_WriteCompare( Super_Gate_t ** ppG1, Super_Gate_t ** ppG2 );
00112 static void Super_WriteFileHeader( Super_Man_t * pMan, FILE * pFile );
00113
00114 static void Super_WriteLibrary( Super_Man_t * pMan );
00115 static void Super_WriteLibraryGate( FILE * pFile, Super_Man_t * pMan, Super_Gate_t * pGate, int Num );
00116 static char * Super_WriteLibraryGateName( Super_Gate_t * pGate );
00117 static void Super_WriteLibraryGateName_rec( Super_Gate_t * pGate, char * pBuffer );
00118
00119 static void Super_WriteLibraryTree( Super_Man_t * pMan );
00120 static void Super_WriteLibraryTree_rec( FILE * pFile, Super_Man_t * pMan, Super_Gate_t * pSuper, int * pCounter );
00121
00125
00137 void Super_Precompute( Mio_Library_t * pLibGen, int nVarsMax, int nLevels, float tDelayMax, float tAreaMax, int TimeLimit, bool fSkipInv, bool fWriteOldFormat, int fVerbose )
00138 {
00139 Super_Man_t * pMan;
00140 Mio_Gate_t ** ppGates;
00141 int nGates, Level, clk, clockStart;
00142
00143 assert( nVarsMax < 7 );
00144
00145
00146 ppGates = Mio_CollectRoots( pLibGen, nVarsMax, tDelayMax, 0, &nGates );
00147
00148
00149 pMan = Super_ManStart();
00150 pMan->pName = Mio_LibraryReadName(pLibGen);
00151 pMan->fSkipInv = fSkipInv;
00152 pMan->tDelayMax = tDelayMax;
00153 pMan->tAreaMax = tAreaMax;
00154 pMan->TimeLimit = TimeLimit;
00155 pMan->TimeStop = TimeLimit * CLOCKS_PER_SEC + clock();
00156 pMan->fWriteOldFormat = fWriteOldFormat;
00157 pMan->fVerbose = fVerbose;
00158
00159 if ( nGates == 0 )
00160 {
00161 fprintf( stderr, "Error: No genlib gates satisfy the limits criteria. Stop.\n");
00162 fprintf( stderr, "Limits: max delay = %.2f, max area = %.2f, time limit = %d sec.\n",
00163 pMan->tDelayMax, pMan->tAreaMax, pMan->TimeLimit );
00164
00165
00166 Super_ManStop( pMan );
00167 free( ppGates );
00168
00169 return;
00170 }
00171
00172
00173 Super_First( pMan, nVarsMax );
00174
00175
00176 clockStart = clock();
00177 if ( fVerbose )
00178 {
00179 printf( "Computing supergates with %d inputs and %d levels.\n",
00180 pMan->nVarsMax, nLevels );
00181 printf( "Limits: max delay = %.2f, max area = %.2f, time limit = %d sec.\n",
00182 pMan->tDelayMax, pMan->tAreaMax, pMan->TimeLimit );
00183 }
00184
00185 for ( Level = 1; Level <= nLevels; Level++ )
00186 {
00187 if ( clock() > pMan->TimeStop )
00188 break;
00189 clk = clock();
00190 Super_Compute( pMan, ppGates, nGates, fSkipInv );
00191 pMan->nLevels = Level;
00192 if ( fVerbose )
00193 {
00194 printf( "Lev %d: Try =%12d. Add =%6d. Rem =%5d. Save =%6d. Lookups =%12d. Aliases =%12d. ",
00195 Level, pMan->nTried, pMan->nAdded, pMan->nRemoved, pMan->nAdded - pMan->nRemoved, pMan->nLookups, pMan->nAliases );
00196 PRT( "Time", clock() - clk );
00197 fflush( stdout );
00198 }
00199 }
00200 pMan->Time = clock() - clockStart;
00201
00202 if ( fVerbose )
00203 {
00204 printf( "Writing the output file...\n" );
00205 fflush( stdout );
00206 }
00207
00208 Super_Write( pMan );
00209
00210
00211 Super_ManStop( pMan );
00212 free( ppGates );
00213 }
00214
00215
00227 void Super_First( Super_Man_t * pMan, int nVarsMax )
00228 {
00229 Super_Gate_t * pSuper;
00230 int nMintLimit, nVarLimit;
00231 int v, m;
00232
00233 pMan->nVarsMax = nVarsMax;
00234 pMan->nMints = (1 << nVarsMax);
00235 pMan->nLevels = 0;
00236
00237 pMan->nGates = nVarsMax;
00238 pMan->pGates = ALLOC( Super_Gate_t *, nVarsMax + 2 );
00239
00240 for ( v = 0; v < nVarsMax; v++ )
00241 {
00242
00243 pSuper = (Super_Gate_t *)Extra_MmFixedEntryFetch( pMan->pMem );
00244 memset( pSuper, 0, sizeof(Super_Gate_t) );
00245
00246 pSuper->fVar = 1;
00247 pSuper->Number = v;
00248 for ( m = 0; m < nVarsMax; m++ )
00249 pSuper->ptDelays[m] = SUPER_NO_VAR;
00250 pSuper->ptDelays[v] = 0.0;
00251
00252 pMan->pGates[v] = pSuper;
00253 Super_AddGateToTable( pMan, pSuper );
00254 pMan->pInputs[v] = pSuper;
00255 }
00256
00257 nVarLimit = (nVarsMax >= 5)? 5 : nVarsMax;
00258 nMintLimit = (1 << nVarLimit);
00259 for ( m = 0; m < nMintLimit; m++ )
00260 for ( v = 0; v < nVarLimit; v++ )
00261 if ( m & (1 << v) )
00262 pMan->pGates[v]->uTruth[0] |= (1 << m);
00263
00264 if ( nVarsMax == 6 )
00265 {
00266 for ( v = 0; v < 5; v++ )
00267 pMan->pGates[v]->uTruth[1] = pMan->pGates[v]->uTruth[0];
00268 pMan->pGates[5]->uTruth[0] = 0;
00269 pMan->pGates[5]->uTruth[1] = ~((unsigned)0);
00270 }
00271 else
00272 {
00273 for ( v = 0; v < nVarsMax; v++ )
00274 pMan->pGates[v]->uTruth[1] = 0;
00275 }
00276 }
00277
00294 Super_Man_t * Super_Compute( Super_Man_t * pMan, Mio_Gate_t ** ppGates, int nGates, bool fSkipInv )
00295 {
00296 Super_Gate_t * pSupers[6], * pGate0, * pGate1, * pGate2, * pGate3, * pGate4, * pGate5, * pGateNew;
00297 float tPinDelaysRes[6], * ptPinDelays[6], tPinDelayMax, tDelayMio;
00298 float Area, Area0, Area1, Area2, Area3, Area4, AreaMio;
00299 unsigned uTruth[2], uTruths[6][2];
00300 int i0, i1, i2, i3, i4, i5;
00301 Super_Gate_t ** ppGatesLimit;
00302 int nFanins, nGatesLimit, k, s, t;
00303 ProgressBar * pProgress;
00304 int fTimeOut;
00305 int fPrune = 1;
00306 int iPruneLimit = 3;
00307
00308 int iPruneLimitRoot = 4;
00309
00310
00311
00312
00313 Super_TranferGatesToArray( pMan );
00314
00315
00316 if ( pMan->nGates > 10000 )
00317 {
00318 printf( "Sorting array of %d supergates...\r", pMan->nGates );
00319 fflush( stdout );
00320 }
00321 qsort( (void *)pMan->pGates, pMan->nGates, sizeof(Super_Gate_t *),
00322 (int (*)(const void *, const void *)) Super_DelayCompare );
00323 assert( Super_DelayCompare( pMan->pGates, pMan->pGates + pMan->nGates - 1 ) <= 0 );
00324 if ( pMan->nGates > 10000 )
00325 {
00326 printf( " \r" );
00327 }
00328
00329 pProgress = Extra_ProgressBarStart( stdout, pMan->TimeLimit );
00330 pMan->TimePrint = clock() + CLOCKS_PER_SEC;
00331 ppGatesLimit = ALLOC( Super_Gate_t *, pMan->nGates );
00332
00333
00334 fTimeOut = 0;
00335 for ( k = 0; k < nGates; k++ )
00336 {
00337 if ( fTimeOut ) break;
00338
00339 if ( fPrune )
00340 {
00341 if ( pMan->nLevels >= 1 )
00342 {
00343 if ( Mio_GateReadInputs(ppGates[k]) >= iPruneLimitRoot )
00344 continue;
00345 }
00346 }
00347
00348
00349
00350 tDelayMio = (float)Mio_GateReadDelayMax(ppGates[k]);
00351 for ( s = 0, t = 0; s < pMan->nGates; s++ )
00352 {
00353 if ( fPrune && ( pMan->nLevels >= 1 ) && ( ((int)pMan->pGates[s]->nFanins) >= iPruneLimit ))
00354 continue;
00355
00356 ppGatesLimit[t] = pMan->pGates[s];
00357 if ( ppGatesLimit[t++]->tDelayMax + tDelayMio > pMan->tDelayMax )
00358 break;
00359 }
00360 nGatesLimit = t;
00361
00362 if ( pMan->fVerbose )
00363 {
00364 printf ("Trying %d choices for %d inputs\n", t, Mio_GateReadInputs(ppGates[k]) );
00365 }
00366
00367
00368
00369
00370 if ( nGatesLimit > 10000 )
00371 printf( "Sorting array of %d supergates...\r", nGatesLimit );
00372 qsort( (void *)ppGatesLimit, nGatesLimit, sizeof(Super_Gate_t *),
00373 (int (*)(const void *, const void *)) Super_AreaCompare );
00374 assert( Super_AreaCompare( ppGatesLimit, ppGatesLimit + nGatesLimit - 1 ) <= 0 );
00375 if ( nGatesLimit > 10000 )
00376 printf( " \r" );
00377
00378
00379 AreaMio = (float)Mio_GateReadArea(ppGates[k]);
00380 nFanins = Mio_GateReadInputs(ppGates[k]);
00381 switch ( nFanins )
00382 {
00383 case 0:
00384 assert( 0 );
00385 break;
00386 case 1:
00387 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i0, pGate0 )
00388 {
00389 if ( fTimeOut ) break;
00390 fTimeOut = Super_CheckTimeout( pProgress, pMan );
00391
00392
00393
00394 if ( fSkipInv && pGate0->tDelayMax == 0 )
00395 continue;
00396
00397 Area = AreaMio + pGate0->Area;
00398 if ( Area > pMan->tAreaMax )
00399 break;
00400
00401 pSupers[0] = pGate0; uTruths[0][0] = pGate0->uTruth[0]; uTruths[0][1] = pGate0->uTruth[1]; ptPinDelays[0] = pGate0->ptDelays;
00402 Mio_DeriveGateDelays( ppGates[k], ptPinDelays, nFanins, pMan->nVarsMax, SUPER_NO_VAR, tPinDelaysRes, &tPinDelayMax );
00403 Mio_DeriveTruthTable( ppGates[k], uTruths, nFanins, pMan->nVarsMax, uTruth );
00404 if ( !Super_CompareGates( pMan, uTruth, Area, tPinDelaysRes, pMan->nVarsMax ) )
00405 continue;
00406
00407 pGateNew = Super_CreateGateNew( pMan, ppGates[k], pSupers, nFanins, uTruth, Area, tPinDelaysRes, tPinDelayMax, pMan->nVarsMax );
00408 Super_AddGateToTable( pMan, pGateNew );
00409 }
00410 break;
00411 case 2:
00412 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i0, pGate0 )
00413 {
00414 Area0 = AreaMio + pGate0->Area;
00415 if ( Area0 > pMan->tAreaMax )
00416 break;
00417 pSupers[0] = pGate0; uTruths[0][0] = pGate0->uTruth[0]; uTruths[0][1] = pGate0->uTruth[1]; ptPinDelays[0] = pGate0->ptDelays;
00418 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i1, pGate1 )
00419 if ( i1 != i0 )
00420 {
00421 if ( fTimeOut ) goto done;
00422 fTimeOut = Super_CheckTimeout( pProgress, pMan );
00423
00424 Area = Area0 + pGate1->Area;
00425 if ( Area > pMan->tAreaMax )
00426 break;
00427
00428 pSupers[1] = pGate1; uTruths[1][0] = pGate1->uTruth[0]; uTruths[1][1] = pGate1->uTruth[1]; ptPinDelays[1] = pGate1->ptDelays;
00429 Mio_DeriveGateDelays( ppGates[k], ptPinDelays, nFanins, pMan->nVarsMax, SUPER_NO_VAR, tPinDelaysRes, &tPinDelayMax );
00430 Mio_DeriveTruthTable( ppGates[k], uTruths, nFanins, pMan->nVarsMax, uTruth );
00431 if ( !Super_CompareGates( pMan, uTruth, Area, tPinDelaysRes, pMan->nVarsMax ) )
00432 continue;
00433
00434 pGateNew = Super_CreateGateNew( pMan, ppGates[k], pSupers, nFanins, uTruth, Area, tPinDelaysRes, tPinDelayMax, pMan->nVarsMax );
00435 Super_AddGateToTable( pMan, pGateNew );
00436 }
00437 }
00438 break;
00439 case 3:
00440 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i0, pGate0 )
00441 {
00442 Area0 = AreaMio + pGate0->Area;
00443 if ( Area0 > pMan->tAreaMax )
00444 break;
00445 pSupers[0] = pGate0; uTruths[0][0] = pGate0->uTruth[0]; uTruths[0][1] = pGate0->uTruth[1]; ptPinDelays[0] = pGate0->ptDelays;
00446
00447 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i1, pGate1 )
00448 if ( i1 != i0 )
00449 {
00450 Area1 = Area0 + pGate1->Area;
00451 if ( Area1 > pMan->tAreaMax )
00452 break;
00453 pSupers[1] = pGate1; uTruths[1][0] = pGate1->uTruth[0]; uTruths[1][1] = pGate1->uTruth[1]; ptPinDelays[1] = pGate1->ptDelays;
00454
00455 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i2, pGate2 )
00456 if ( i2 != i0 && i2 != i1 )
00457 {
00458 if ( fTimeOut ) goto done;
00459 fTimeOut = Super_CheckTimeout( pProgress, pMan );
00460
00461 Area = Area1 + pGate2->Area;
00462 if ( Area > pMan->tAreaMax )
00463 break;
00464 pSupers[2] = pGate2; uTruths[2][0] = pGate2->uTruth[0]; uTruths[2][1] = pGate2->uTruth[1]; ptPinDelays[2] = pGate2->ptDelays;
00465
00466 Mio_DeriveGateDelays( ppGates[k], ptPinDelays, nFanins, pMan->nVarsMax, SUPER_NO_VAR, tPinDelaysRes, &tPinDelayMax );
00467 Mio_DeriveTruthTable( ppGates[k], uTruths, nFanins, pMan->nVarsMax, uTruth );
00468 if ( !Super_CompareGates( pMan, uTruth, Area, tPinDelaysRes, pMan->nVarsMax ) )
00469 continue;
00470
00471 pGateNew = Super_CreateGateNew( pMan, ppGates[k], pSupers, nFanins, uTruth, Area, tPinDelaysRes, tPinDelayMax, pMan->nVarsMax );
00472 Super_AddGateToTable( pMan, pGateNew );
00473 }
00474 }
00475 }
00476 break;
00477 case 4:
00478 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i0, pGate0 )
00479 {
00480 Area0 = AreaMio + pGate0->Area;
00481 if ( Area0 > pMan->tAreaMax )
00482 break;
00483 pSupers[0] = pGate0; uTruths[0][0] = pGate0->uTruth[0]; uTruths[0][1] = pGate0->uTruth[1]; ptPinDelays[0] = pGate0->ptDelays;
00484
00485 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i1, pGate1 )
00486 if ( i1 != i0 )
00487 {
00488 Area1 = Area0 + pGate1->Area;
00489 if ( Area1 > pMan->tAreaMax )
00490 break;
00491 pSupers[1] = pGate1; uTruths[1][0] = pGate1->uTruth[0]; uTruths[1][1] = pGate1->uTruth[1]; ptPinDelays[1] = pGate1->ptDelays;
00492
00493 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i2, pGate2 )
00494 if ( i2 != i0 && i2 != i1 )
00495 {
00496 Area2 = Area1 + pGate2->Area;
00497 if ( Area2 > pMan->tAreaMax )
00498 break;
00499 pSupers[2] = pGate2; uTruths[2][0] = pGate2->uTruth[0]; uTruths[2][1] = pGate2->uTruth[1]; ptPinDelays[2] = pGate2->ptDelays;
00500
00501 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i3, pGate3 )
00502 if ( i3 != i0 && i3 != i1 && i3 != i2 )
00503 {
00504 if ( fTimeOut ) goto done;
00505 fTimeOut = Super_CheckTimeout( pProgress, pMan );
00506
00507 Area = Area2 + pGate3->Area;
00508 if ( Area > pMan->tAreaMax )
00509 break;
00510 pSupers[3] = pGate3; uTruths[3][0] = pGate3->uTruth[0]; uTruths[3][1] = pGate3->uTruth[1]; ptPinDelays[3] = pGate3->ptDelays;
00511
00512 Mio_DeriveGateDelays( ppGates[k], ptPinDelays, nFanins, pMan->nVarsMax, SUPER_NO_VAR, tPinDelaysRes, &tPinDelayMax );
00513 Mio_DeriveTruthTable( ppGates[k], uTruths, nFanins, pMan->nVarsMax, uTruth );
00514 if ( !Super_CompareGates( pMan, uTruth, Area, tPinDelaysRes, pMan->nVarsMax ) )
00515 continue;
00516
00517 pGateNew = Super_CreateGateNew( pMan, ppGates[k], pSupers, nFanins, uTruth, Area, tPinDelaysRes, tPinDelayMax, pMan->nVarsMax );
00518 Super_AddGateToTable( pMan, pGateNew );
00519 }
00520 }
00521 }
00522 }
00523 break;
00524 case 5:
00525 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i0, pGate0 )
00526 {
00527 Area0 = AreaMio + pGate0->Area;
00528 if ( Area0 > pMan->tAreaMax )
00529 break;
00530 pSupers[0] = pGate0; uTruths[0][0] = pGate0->uTruth[0]; uTruths[0][1] = pGate0->uTruth[1]; ptPinDelays[0] = pGate0->ptDelays;
00531
00532 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i1, pGate1 )
00533 if ( i1 != i0 )
00534 {
00535 Area1 = Area0 + pGate1->Area;
00536 if ( Area1 > pMan->tAreaMax )
00537 break;
00538 pSupers[1] = pGate1; uTruths[1][0] = pGate1->uTruth[0]; uTruths[1][1] = pGate1->uTruth[1]; ptPinDelays[1] = pGate1->ptDelays;
00539
00540 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i2, pGate2 )
00541 if ( i2 != i0 && i2 != i1 )
00542 {
00543 Area2 = Area1 + pGate2->Area;
00544 if ( Area2 > pMan->tAreaMax )
00545 break;
00546 pSupers[2] = pGate2; uTruths[2][0] = pGate2->uTruth[0]; uTruths[2][1] = pGate2->uTruth[1]; ptPinDelays[2] = pGate2->ptDelays;
00547
00548 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i3, pGate3 )
00549 if ( i3 != i0 && i3 != i1 && i3 != i2 )
00550 {
00551 Area3 = Area2 + pGate3->Area;
00552 if ( Area3 > pMan->tAreaMax )
00553 break;
00554 pSupers[3] = pGate3; uTruths[3][0] = pGate3->uTruth[0]; uTruths[3][1] = pGate3->uTruth[1]; ptPinDelays[3] = pGate3->ptDelays;
00555
00556 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i4, pGate4 )
00557 if ( i4 != i0 && i4 != i1 && i4 != i2 && i4 != i3 )
00558 {
00559 if ( fTimeOut ) goto done;
00560 fTimeOut = Super_CheckTimeout( pProgress, pMan );
00561
00562 Area = Area3 + pGate4->Area;
00563 if ( Area > pMan->tAreaMax )
00564 break;
00565 pSupers[4] = pGate4; uTruths[4][0] = pGate4->uTruth[0]; uTruths[4][1] = pGate4->uTruth[1]; ptPinDelays[4] = pGate4->ptDelays;
00566
00567 Mio_DeriveGateDelays( ppGates[k], ptPinDelays, nFanins, pMan->nVarsMax, SUPER_NO_VAR, tPinDelaysRes, &tPinDelayMax );
00568 Mio_DeriveTruthTable( ppGates[k], uTruths, nFanins, pMan->nVarsMax, uTruth );
00569 if ( !Super_CompareGates( pMan, uTruth, Area, tPinDelaysRes, pMan->nVarsMax ) )
00570 continue;
00571
00572 pGateNew = Super_CreateGateNew( pMan, ppGates[k], pSupers, nFanins, uTruth, Area, tPinDelaysRes, tPinDelayMax, pMan->nVarsMax );
00573 Super_AddGateToTable( pMan, pGateNew );
00574 }
00575 }
00576 }
00577 }
00578 }
00579 break;
00580 case 6:
00581 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i0, pGate0 )
00582 {
00583 Area0 = AreaMio + pGate0->Area;
00584 if ( Area0 > pMan->tAreaMax )
00585 break;
00586 pSupers[0] = pGate0; uTruths[0][0] = pGate0->uTruth[0]; uTruths[0][1] = pGate0->uTruth[1]; ptPinDelays[0] = pGate0->ptDelays;
00587
00588 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i1, pGate1 )
00589 if ( i1 != i0 )
00590 {
00591 Area1 = Area0 + pGate1->Area;
00592 if ( Area1 > pMan->tAreaMax )
00593 break;
00594 pSupers[1] = pGate1; uTruths[1][0] = pGate1->uTruth[0]; uTruths[1][1] = pGate1->uTruth[1]; ptPinDelays[1] = pGate1->ptDelays;
00595
00596 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i2, pGate2 )
00597 if ( i2 != i0 && i2 != i1 )
00598 {
00599 Area2 = Area1 + pGate2->Area;
00600 if ( Area2 > pMan->tAreaMax )
00601 break;
00602 pSupers[2] = pGate2; uTruths[2][0] = pGate2->uTruth[0]; uTruths[2][1] = pGate2->uTruth[1]; ptPinDelays[2] = pGate2->ptDelays;
00603
00604 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i3, pGate3 )
00605 if ( i3 != i0 && i3 != i1 && i3 != i2 )
00606 {
00607 Area3 = Area2 + pGate3->Area;
00608 if ( Area3 > pMan->tAreaMax )
00609 break;
00610 pSupers[3] = pGate3; uTruths[3][0] = pGate3->uTruth[0]; uTruths[3][1] = pGate3->uTruth[1]; ptPinDelays[3] = pGate3->ptDelays;
00611
00612 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i4, pGate4 )
00613 if ( i4 != i0 && i4 != i1 && i4 != i2 && i4 != i3 )
00614 {
00615 if ( fTimeOut ) break;
00616 fTimeOut = Super_CheckTimeout( pProgress, pMan );
00617
00618 Area4 = Area3 + pGate4->Area;
00619 if ( Area > pMan->tAreaMax )
00620 break;
00621 pSupers[4] = pGate4; uTruths[4][0] = pGate4->uTruth[0]; uTruths[4][1] = pGate4->uTruth[1]; ptPinDelays[4] = pGate4->ptDelays;
00622
00623 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i5, pGate5 )
00624 if ( i5 != i0 && i5 != i1 && i5 != i2 && i5 != i3 && i5 != i4 )
00625 {
00626 if ( fTimeOut ) goto done;
00627 fTimeOut = Super_CheckTimeout( pProgress, pMan );
00628
00629 Area = Area4 + pGate5->Area;
00630 if ( Area > pMan->tAreaMax )
00631 break;
00632 pSupers[5] = pGate5; uTruths[5][0] = pGate5->uTruth[0]; uTruths[5][1] = pGate5->uTruth[1]; ptPinDelays[5] = pGate5->ptDelays;
00633
00634 Mio_DeriveGateDelays( ppGates[k], ptPinDelays, nFanins, pMan->nVarsMax, SUPER_NO_VAR, tPinDelaysRes, &tPinDelayMax );
00635 Mio_DeriveTruthTable( ppGates[k], uTruths, nFanins, pMan->nVarsMax, uTruth );
00636 if ( !Super_CompareGates( pMan, uTruth, Area, tPinDelaysRes, pMan->nVarsMax ) )
00637 continue;
00638
00639 pGateNew = Super_CreateGateNew( pMan, ppGates[k], pSupers, nFanins, uTruth, Area, tPinDelaysRes, tPinDelayMax, pMan->nVarsMax );
00640 Super_AddGateToTable( pMan, pGateNew );
00641 }
00642 }
00643 }
00644 }
00645 }
00646 }
00647 break;
00648 default :
00649 assert( 0 );
00650 break;
00651 }
00652 }
00653 done:
00654 Extra_ProgressBarStop( pProgress );
00655 free( ppGatesLimit );
00656 return pMan;
00657 }
00658
00670 int Super_CheckTimeout( ProgressBar * pPro, Super_Man_t * pMan )
00671 {
00672 int TimeNow = clock();
00673 if ( TimeNow > pMan->TimePrint )
00674 {
00675 Extra_ProgressBarUpdate( pPro, ++pMan->TimeSec, NULL );
00676 pMan->TimePrint = clock() + CLOCKS_PER_SEC;
00677 }
00678 if ( TimeNow > pMan->TimeStop )
00679 {
00680 printf ("Timeout!\n");
00681 return 1;
00682 }
00683 pMan->nTried++;
00684 return 0;
00685 }
00686
00687
00699 void Super_TranferGatesToArray( Super_Man_t * pMan )
00700 {
00701 stmm_generator * gen;
00702 Super_Gate_t * pGate, * pList;
00703 unsigned Key;
00704
00705
00706 free( pMan->pGates );
00707 pMan->pGates = ALLOC( Super_Gate_t *, pMan->nAdded );
00708 pMan->nGates = 0;
00709 stmm_foreach_item( pMan->tTable, gen, (char **)&Key, (char **)&pList )
00710 {
00711 for ( pGate = pList; pGate; pGate = pGate->pNext )
00712 pMan->pGates[ pMan->nGates++ ] = pGate;
00713 }
00714
00715 }
00716
00728 void Super_AddGateToTable( Super_Man_t * pMan, Super_Gate_t * pGate )
00729 {
00730 Super_Gate_t ** ppList;
00731 unsigned Key;
00732
00733 Key = pGate->uTruth[0] ^ pGate->uTruth[1];
00734 if ( !stmm_find_or_add( pMan->tTable, (char *)Key, (char ***)&ppList ) )
00735 *ppList = NULL;
00736 pGate->pNext = *ppList;
00737 *ppList = pGate;
00738 pMan->nAdded++;
00739 }
00740
00754 bool Super_CompareGates( Super_Man_t * pMan, unsigned uTruth[], float Area, float tPinDelaysRes[], int nPins )
00755 {
00756 Super_Gate_t ** ppList, * pPrev, * pGate, * pGate2;
00757 int i, fNewIsBetter, fGateIsBetter;
00758 unsigned Key;
00759
00760
00761 if ( pMan->nVarsMax < 6 )
00762 {
00763 if ( uTruth[0] == 0 || ~uTruth[0] == 0 )
00764 return 0;
00765 }
00766 else
00767 {
00768 if ( ( uTruth[0] == 0 && uTruth[1] == 0 ) || ( ~uTruth[0] == 0 && ~uTruth[1] == 0 ) )
00769 return 0;
00770 }
00771
00772
00773
00774 Key = uTruth[0] ^ uTruth[1];
00775 if ( !stmm_find( pMan->tTable, (char *)Key, (char ***)&ppList ) )
00776 return 1;
00777
00778 pPrev = NULL;
00779 for ( pGate = *ppList, pGate2 = pGate? pGate->pNext: NULL; pGate;
00780 pGate = pGate2, pGate2 = pGate? pGate->pNext: NULL )
00781 {
00782 pMan->nLookups++;
00783 if ( pGate->uTruth[0] != uTruth[0] || pGate->uTruth[1] != uTruth[1] )
00784 {
00785 pMan->nAliases++;
00786 continue;
00787 }
00788 fGateIsBetter = 0;
00789 fNewIsBetter = 0;
00790 if ( pGate->Area + SUPER_EPSILON < Area )
00791 fGateIsBetter = 1;
00792 else if ( pGate->Area > Area + SUPER_EPSILON )
00793 fNewIsBetter = 1;
00794 for ( i = 0; i < nPins; i++ )
00795 {
00796 if ( pGate->ptDelays[i] == SUPER_NO_VAR || tPinDelaysRes[i] == SUPER_NO_VAR )
00797 continue;
00798 if ( pGate->ptDelays[i] + SUPER_EPSILON < tPinDelaysRes[i] )
00799 fGateIsBetter = 1;
00800 else if ( pGate->ptDelays[i] > tPinDelaysRes[i] + SUPER_EPSILON )
00801 fNewIsBetter = 1;
00802 if ( fGateIsBetter && fNewIsBetter )
00803 break;
00804 }
00805
00806 if ( fGateIsBetter && fNewIsBetter )
00807 pPrev = pGate;
00808 else if ( fNewIsBetter )
00809 {
00810 if ( pPrev == NULL )
00811 *ppList = pGate->pNext;
00812 else
00813 pPrev->pNext = pGate->pNext;
00814 Extra_MmFixedEntryRecycle( pMan->pMem, (char *)pGate );
00815 pMan->nRemoved++;
00816 }
00817 else if ( fGateIsBetter )
00818 return 0;
00819 else
00820 return 0;
00821 }
00822 return 1;
00823 }
00824
00825
00837 Super_Gate_t * Super_CreateGateNew( Super_Man_t * pMan, Mio_Gate_t * pRoot, Super_Gate_t ** pSupers, int nSupers,
00838 unsigned uTruth[], float Area, float tPinDelaysRes[], float tDelayMax, int nPins )
00839 {
00840 Super_Gate_t * pSuper;
00841 pSuper = (Super_Gate_t *)Extra_MmFixedEntryFetch( pMan->pMem );
00842 memset( pSuper, 0, sizeof(Super_Gate_t) );
00843 pSuper->pRoot = pRoot;
00844 pSuper->uTruth[0] = uTruth[0];
00845 pSuper->uTruth[1] = uTruth[1];
00846 memcpy( pSuper->ptDelays, tPinDelaysRes, sizeof(float) * nPins );
00847 pSuper->Area = Area;
00848 pSuper->nFanins = nSupers;
00849 memcpy( pSuper->pFanins, pSupers, sizeof(Super_Gate_t *) * nSupers );
00850 pSuper->pNext = NULL;
00851 pSuper->tDelayMax = tDelayMax;
00852 return pSuper;
00853 }
00854
00866 Super_Man_t * Super_ManStart()
00867 {
00868 Super_Man_t * pMan;
00869 pMan = ALLOC( Super_Man_t, 1 );
00870 memset( pMan, 0, sizeof(Super_Man_t) );
00871 pMan->pMem = Extra_MmFixedStart( sizeof(Super_Gate_t) );
00872 pMan->tTable = stmm_init_table( st_ptrcmp, st_ptrhash );
00873 return pMan;
00874 }
00875
00887 void Super_ManStop( Super_Man_t * pMan )
00888 {
00889 Extra_MmFixedStop( pMan->pMem );
00890 if ( pMan->tTable ) stmm_free_table( pMan->tTable );
00891 FREE( pMan->pGates );
00892 free( pMan );
00893 }
00894
00895
00896
00897
00898
00910 void Super_Write( Super_Man_t * pMan )
00911 {
00912 Super_Gate_t * pGateRoot, * pGate;
00913 stmm_generator * gen;
00914 int fZeroFound, clk, v;
00915 unsigned Key;
00916
00917 if ( pMan->nGates < 1 )
00918 {
00919 printf( "The generated library is empty. No output file written.\n" );
00920 return;
00921 }
00922
00923
00924
00925
00926
00927 FREE( pMan->pGates );
00928 pMan->pGates = ALLOC( Super_Gate_t *, pMan->nAdded );
00929 pMan->nGates = 0;
00930 stmm_foreach_item( pMan->tTable, gen, (char **)&Key, (char **)&pGateRoot )
00931 {
00932 for ( pGate = pGateRoot; pGate; pGate = pGate->pNext )
00933 {
00934
00935 if ( pGate->pRoot == NULL )
00936 continue;
00937
00938 fZeroFound = 0;
00939 for ( v = 0; v < pMan->nVarsMax; v++ )
00940 if ( pGate->ptDelays[v] < SUPER_NO_VAR + SUPER_EPSILON )
00941 fZeroFound = 1;
00942 else if ( fZeroFound )
00943 break;
00944 if ( v < pMan->nVarsMax )
00945 continue;
00946
00947 pMan->pGates[ pMan->nGates++ ] = pGate;
00948 }
00949 }
00950
00951 clk = clock();
00952
00953 qsort( (void *)pMan->pGates, pMan->nGates, sizeof(Super_Gate_t *),
00954 (int (*)(const void *, const void *)) Super_WriteCompare );
00955 assert( Super_WriteCompare( pMan->pGates, pMan->pGates + pMan->nGates - 1 ) <= 0 );
00956 if ( pMan->fVerbose )
00957 {
00958 PRT( "Sorting", clock() - clk );
00959 }
00960
00961
00962
00963 clk = clock();
00964 if ( pMan->fWriteOldFormat )
00965 Super_WriteLibrary( pMan );
00966 if ( pMan->fVerbose )
00967 {
00968 PRT( "Writing old format", clock() - clk );
00969 }
00970
00971
00972 clk = clock();
00973 Super_WriteLibraryTree( pMan );
00974 if ( pMan->fVerbose )
00975 {
00976 PRT( "Writing new format", clock() - clk );
00977 }
00978 }
00979
00980
00992 void Super_WriteFileHeader( Super_Man_t * pMan, FILE * pFile )
00993 {
00994 fprintf( pFile, "#\n" );
00995 fprintf( pFile, "# Supergate library derived for \"%s\" on %s.\n", pMan->pName, Extra_TimeStamp() );
00996 fprintf( pFile, "#\n" );
00997 fprintf( pFile, "# Command line: \"super -i %d -l %d -d %.2f -a %.2f -t %d %s %s\".\n",
00998 pMan->nVarsMax, pMan->nLevels, pMan->tDelayMax, pMan->tAreaMax, pMan->TimeLimit, (pMan->fSkipInv? "" : "-s"), pMan->pName );
00999 fprintf( pFile, "#\n" );
01000 fprintf( pFile, "# The number of inputs = %10d.\n", pMan->nVarsMax );
01001 fprintf( pFile, "# The number of levels = %10d.\n", pMan->nLevels );
01002 fprintf( pFile, "# The maximum delay = %10.2f.\n", pMan->tDelayMax );
01003 fprintf( pFile, "# The maximum area = %10.2f.\n", pMan->tAreaMax );
01004 fprintf( pFile, "# The maximum runtime (sec) = %10d.\n", pMan->TimeLimit );
01005 fprintf( pFile, "#\n" );
01006 fprintf( pFile, "# The number of attempts = %10d.\n", pMan->nTried );
01007 fprintf( pFile, "# The number of supergates = %10d.\n", pMan->nGates );
01008 fprintf( pFile, "# The number of functions = %10d.\n", pMan->nUnique );
01009 fprintf( pFile, "# The total functions = %.0f (2^%d).\n", pow(2,pMan->nMints), pMan->nMints );
01010 fprintf( pFile, "#\n" );
01011 fprintf( pFile, "# Generation time (sec) = %10.2f.\n", (float)(pMan->Time)/(float)(CLOCKS_PER_SEC) );
01012 fprintf( pFile, "#\n" );
01013 fprintf( pFile, "%s\n", pMan->pName );
01014 fprintf( pFile, "%d\n", pMan->nVarsMax );
01015 fprintf( pFile, "%d\n", pMan->nGates );
01016 }
01017
01029 int Super_WriteCompare( Super_Gate_t ** ppG1, Super_Gate_t ** ppG2 )
01030 {
01031 unsigned * pTruth1 = (*ppG1)->uTruth;
01032 unsigned * pTruth2 = (*ppG2)->uTruth;
01033 if ( pTruth1[1] < pTruth2[1] )
01034 return -1;
01035 if ( pTruth1[1] > pTruth2[1] )
01036 return 1;
01037 if ( pTruth1[0] < pTruth2[0] )
01038 return -1;
01039 if ( pTruth1[0] > pTruth2[0] )
01040 return 1;
01041 return 0;
01042 }
01043
01055 int Super_DelayCompare( Super_Gate_t ** ppG1, Super_Gate_t ** ppG2 )
01056 {
01057 if ( (*ppG1)->tDelayMax < (*ppG2)->tDelayMax )
01058 return -1;
01059 if ( (*ppG1)->tDelayMax > (*ppG2)->tDelayMax )
01060 return 1;
01061 return 0;
01062 }
01063
01075 int Super_AreaCompare( Super_Gate_t ** ppG1, Super_Gate_t ** ppG2 )
01076 {
01077 if ( (*ppG1)->Area < (*ppG2)->Area )
01078 return -1;
01079 if ( (*ppG1)->Area > (*ppG2)->Area )
01080 return 1;
01081 return 0;
01082 }
01083
01084
01085
01086
01087
01088
01100 void Super_WriteLibrary( Super_Man_t * pMan )
01101 {
01102 Super_Gate_t * pGate, * pGateNext;
01103 FILE * pFile;
01104 char FileName[100];
01105 char * pNameGeneric;
01106 int i, Counter;
01107
01108
01109 pNameGeneric = Extra_FileNameGeneric( pMan->pName );
01110 sprintf( FileName, "%s.super_old", pNameGeneric );
01111 free( pNameGeneric );
01112
01113
01114 pMan->nUnique = 1;
01115 Super_ManForEachGate( pMan->pGates, pMan->nGates, i, pGate )
01116 {
01117 if ( i == pMan->nGates - 1 )
01118 break;
01119
01120 pGateNext = pMan->pGates[i+1];
01121 if ( pGateNext->uTruth[0] != pGate->uTruth[0] || pGateNext->uTruth[1] != pGate->uTruth[1] )
01122 pMan->nUnique++;
01123 }
01124
01125
01126 pFile = fopen( FileName, "w" );
01127 Super_WriteFileHeader( pMan, pFile );
01128
01129
01130 Counter = 0;
01131 Super_ManForEachGate( pMan->pGates, pMan->nGates, i, pGate )
01132 {
01133 Super_WriteLibraryGate( pFile, pMan, pGate, ++Counter );
01134 if ( i == pMan->nGates - 1 )
01135 break;
01136
01137 pGateNext = pMan->pGates[i+1];
01138 if ( pGateNext->uTruth[0] != pGate->uTruth[0] || pGateNext->uTruth[1] != pGate->uTruth[1] )
01139 fprintf( pFile, "\n" );
01140 }
01141 assert( Counter == pMan->nGates );
01142 fclose( pFile );
01143
01144 if ( pMan->fVerbose )
01145 {
01146 printf( "The supergates are written using old format \"%s\" ", FileName );
01147 printf( "(%0.3f Mb).\n", ((double)Extra_FileSize(FileName))/(1<<20) );
01148 }
01149 }
01150
01162 void Super_WriteLibraryGate( FILE * pFile, Super_Man_t * pMan, Super_Gate_t * pGate, int Num )
01163 {
01164 int i;
01165 fprintf( pFile, "%04d ", Num );
01166 Extra_PrintBinary( pFile, pGate->uTruth, pMan->nMints );
01167 fprintf( pFile, " %5.2f", pGate->tDelayMax );
01168 fprintf( pFile, " " );
01169 for ( i = 0; i < pMan->nVarsMax; i++ )
01170 fprintf( pFile, " %5.2f", pGate->ptDelays[i]==SUPER_NO_VAR? 0.0 : pGate->ptDelays[i] );
01171 fprintf( pFile, " %5.2f", pGate->Area );
01172 fprintf( pFile, " " );
01173 fprintf( pFile, "%s", Super_WriteLibraryGateName(pGate) );
01174 fprintf( pFile, "\n" );
01175 }
01176
01188 char * Super_WriteLibraryGateName( Super_Gate_t * pGate )
01189 {
01190 static char Buffer[2000];
01191 Buffer[0] = 0;
01192 Super_WriteLibraryGateName_rec( pGate, Buffer );
01193 return Buffer;
01194 }
01195
01207 void Super_WriteLibraryGateName_rec( Super_Gate_t * pGate, char * pBuffer )
01208 {
01209 char Buffer[10];
01210 int i;
01211
01212 if ( pGate->pRoot == NULL )
01213 {
01214 sprintf( Buffer, "%c", 'a' + pGate->Number );
01215 strcat( pBuffer, Buffer );
01216 return;
01217 }
01218 strcat( pBuffer, Mio_GateReadName(pGate->pRoot) );
01219 strcat( pBuffer, "(" );
01220 for ( i = 0; i < (int)pGate->nFanins; i++ )
01221 {
01222 if ( i )
01223 strcat( pBuffer, "," );
01224 Super_WriteLibraryGateName_rec( pGate->pFanins[i], pBuffer );
01225 }
01226 strcat( pBuffer, ")" );
01227 }
01228
01229
01230
01231
01232
01244 void Super_WriteLibraryTree( Super_Man_t * pMan )
01245 {
01246 Super_Gate_t * pSuper;
01247 FILE * pFile;
01248 char FileName[100];
01249 char * pNameGeneric;
01250 int i, Counter;
01251 int posStart;
01252
01253
01254 pNameGeneric = Extra_FileNameGeneric( pMan->pName );
01255 sprintf( FileName, "%s.super", pNameGeneric );
01256 free( pNameGeneric );
01257
01258
01259 pFile = fopen( FileName, "w" );
01260 Super_WriteFileHeader( pMan, pFile );
01261
01262 posStart = ftell( pFile );
01263 fprintf( pFile, " \n" );
01264
01265 Super_ManForEachGate( pMan->pGates, pMan->nGates, i, pSuper )
01266 pSuper->fSuper = 1;
01267
01268 Counter = pMan->nVarsMax;
01269 Super_ManForEachGate( pMan->pGates, pMan->nGates, i, pSuper )
01270 Super_WriteLibraryTree_rec( pFile, pMan, pSuper, &Counter );
01271 fclose( pFile );
01272
01273 pFile = fopen( FileName, "rb+" );
01274 fseek( pFile, posStart, SEEK_SET );
01275 fprintf( pFile, "%d", Counter );
01276 fclose( pFile );
01277
01278 if ( pMan->fVerbose )
01279 {
01280 printf( "The supergates are written using new format \"%s\" ", FileName );
01281 printf( "(%0.3f Mb).\n", ((double)Extra_FileSize(FileName))/(1<<20) );
01282 }
01283 }
01284
01296 void Super_WriteLibraryTree_rec( FILE * pFile, Super_Man_t * pMan, Super_Gate_t * pSuper, int * pCounter )
01297 {
01298 int nFanins, i;
01299
01300 if ( pSuper->fVar || pSuper->Number > 0 )
01301 return;
01302
01303 nFanins = Mio_GateReadInputs(pSuper->pRoot);
01304 for ( i = 0; i < nFanins; i++ )
01305 Super_WriteLibraryTree_rec( pFile, pMan, pSuper->pFanins[i], pCounter );
01306
01307 pSuper->Number = (*pCounter)++;
01308 fprintf( pFile, "%s", pSuper->fSuper? "* " : "" );
01309 fprintf( pFile, "%s", Mio_GateReadName(pSuper->pRoot) );
01310 for ( i = 0; i < nFanins; i++ )
01311 fprintf( pFile, " %d", pSuper->pFanins[i]->Number );
01312
01313
01314
01315
01316
01317 fprintf( pFile, "\n" );
01318 }
01319
01320
01324