00001
00019 #include "superInt.h"
00020
00024
00025
00026 #define SUPER_MASK(n) ((~((unsigned)0)) >> (32-n))
00027 #define SUPER_FULL (~((unsigned)0))
00028
00029
00030 typedef struct Super2_ManStruct_t_ Super2_Man_t;
00031 typedef struct Super2_LibStruct_t_ Super2_Lib_t;
00032 typedef struct Super2_GateStruct_t_ Super2_Gate_t;
00033
00034 struct Super2_ManStruct_t_
00035 {
00036 Extra_MmFixed_t * pMem;
00037 stmm_table * tTable;
00038 int nTried;
00039 };
00040
00041 struct Super2_LibStruct_t_
00042 {
00043 int i;
00044 int k;
00045 int nInputs;
00046 int nMints;
00047 int nLevels;
00048 int nGates;
00049 int nGatesAlloc;
00050 Super2_Gate_t ** pGates;
00051 unsigned uMaskBit;
00052 };
00053
00054 struct Super2_GateStruct_t_
00055 {
00056 unsigned uTruth;
00057 Super2_Gate_t * pOne;
00058 Super2_Gate_t * pTwo;
00059 Super2_Gate_t * pNext;
00060 };
00061
00062
00063
00064 #define Super2_IsComplement(p) (((int)((unsigned long) (p) & 01)))
00065 #define Super2_Regular(p) ((Super2_Gate_t *)((unsigned long)(p) & ~01))
00066 #define Super2_Not(p) ((Super2_Gate_t *)((unsigned long)(p) ^ 01))
00067 #define Super2_NotCond(p,c) ((Super2_Gate_t *)((unsigned long)(p) ^ (c)))
00068
00069
00070 #define Super2_LibForEachGate( Lib, Gate ) \
00071 for ( Lib->i = 0; \
00072 Lib->i < Lib->nGates && (Gate = Lib->pGates[Lib->i]); \
00073 Lib->i++ )
00074 #define Super2_LibForEachGate2( Lib, Gate2 ) \
00075 for ( Lib->k = 0; \
00076 Lib->k < Lib->i && (Gate2 = Lib->pGates[Lib->k]); \
00077 Lib->k++ )
00078
00079
00080 static Super2_Man_t * Super2_ManStart();
00081 static void Super2_ManStop( Super2_Man_t * pMan );
00082 static Super2_Lib_t * Super2_LibStart();
00083 static Super2_Lib_t * Super2_LibDup( Super2_Lib_t * pLib );
00084 static void Super2_LibStop( Super2_Lib_t * pLib );
00085 static void Super2_LibAddGate( Super2_Lib_t * pLib, Super2_Gate_t * pGate );
00086 static Super2_Lib_t * Super2_LibFirst( Super2_Man_t * pMan, int nInputs );
00087 static Super2_Lib_t * Super2_LibCompute( Super2_Man_t * pMan, Super2_Lib_t * pLib );
00088
00089 static void Super2_LibWrite( Super2_Lib_t * pLib );
00090 static void Super2_LibWriteGate( FILE * pFile, Super2_Lib_t * pLib, Super2_Gate_t * pGate );
00091 static char * Super2_LibWriteGate_rec( Super2_Gate_t * pGate, int fInv, int Level );
00092 static int Super2_LibWriteCompare( char * pStr1, char * pStr2 );
00093 static int Super2_LibCompareGates( Super2_Gate_t ** ppG1, Super2_Gate_t ** ppG2 );
00094
00098
00110 void Super2_Precompute( int nInputs, int nLevels, int fVerbose )
00111 {
00112 Super2_Man_t * pMan;
00113 Super2_Lib_t * pLibCur, * pLibNext;
00114 int Level;
00115 int clk;
00116
00117 assert( nInputs < 6 );
00118
00119
00120 pMan = Super2_ManStart();
00121
00122
00123 pLibCur = Super2_LibFirst( pMan, nInputs );
00124
00125
00126 printf( "Computing supergates for %d inputs and %d levels:\n", nInputs, nLevels );
00127 for ( Level = 1; Level <= nLevels; Level++ )
00128 {
00129 clk = clock();
00130 pLibNext = Super2_LibCompute( pMan, pLibCur );
00131 pLibNext->nLevels = Level;
00132 Super2_LibStop( pLibCur );
00133 pLibCur = pLibNext;
00134 printf( "Level %d: Tried = %7d. Computed = %7d. ", Level, pMan->nTried, pLibCur->nGates );
00135 PRT( "Runtime", clock() - clk );
00136 fflush( stdout );
00137 }
00138
00139 printf( "Writing the output file...\n" );
00140 fflush( stdout );
00141
00142 Super2_LibWrite( pLibCur );
00143 Super2_LibStop( pLibCur );
00144
00145
00146 Super2_ManStop( pMan );
00147 }
00148
00149
00150
00151
00163 Super2_Man_t * Super2_ManStart()
00164 {
00165 Super2_Man_t * pMan;
00166 pMan = ALLOC( Super2_Man_t, 1 );
00167 memset( pMan, 0, sizeof(Super2_Man_t) );
00168 pMan->pMem = Extra_MmFixedStart( sizeof(Super2_Gate_t) );
00169 pMan->tTable = stmm_init_table( st_ptrcmp, st_ptrhash );
00170 return pMan;
00171 }
00172
00184 void Super2_ManStop( Super2_Man_t * pMan )
00185 {
00186 Extra_MmFixedStop( pMan->pMem );
00187 stmm_free_table( pMan->tTable );
00188 free( pMan );
00189 }
00190
00202 Super2_Lib_t * Super2_LibStart()
00203 {
00204 Super2_Lib_t * pLib;
00205 pLib = ALLOC( Super2_Lib_t, 1 );
00206 memset( pLib, 0, sizeof(Super2_Lib_t) );
00207 return pLib;
00208 }
00209
00221 Super2_Lib_t * Super2_LibDup( Super2_Lib_t * pLib )
00222 {
00223 Super2_Lib_t * pLibNew;
00224 pLibNew = Super2_LibStart();
00225 pLibNew->nInputs = pLib->nInputs;
00226 pLibNew->nMints = pLib->nMints;
00227 pLibNew->nLevels = pLib->nLevels;
00228 pLibNew->nGates = pLib->nGates;
00229 pLibNew->uMaskBit = pLib->uMaskBit;
00230 pLibNew->nGatesAlloc = 1000 + pLib->nGatesAlloc;
00231 pLibNew->pGates = ALLOC( Super2_Gate_t *, pLibNew->nGatesAlloc );
00232 memcpy( pLibNew->pGates, pLib->pGates, pLibNew->nGates * sizeof(Super2_Gate_t *) );
00233 return pLibNew;
00234 }
00235
00247 void Super2_LibAddGate( Super2_Lib_t * pLib, Super2_Gate_t * pGate )
00248 {
00249 if ( pLib->nGates == pLib->nGatesAlloc )
00250 {
00251 pLib->pGates = REALLOC( Super2_Gate_t *, pLib->pGates, 3 * pLib->nGatesAlloc );
00252 pLib->nGatesAlloc *= 3;
00253 }
00254 pLib->pGates[ pLib->nGates++ ] = pGate;
00255 }
00256
00268 void Super2_LibStop( Super2_Lib_t * pLib )
00269 {
00270 free( pLib->pGates );
00271 free( pLib );
00272 }
00273
00285 Super2_Lib_t * Super2_LibFirst( Super2_Man_t * pMan, int nInputs )
00286 {
00287 Super2_Lib_t * pLib;
00288 int v, m;
00289
00290
00291 pLib = Super2_LibStart();
00292
00293
00294 pLib->nInputs = nInputs;
00295 pLib->nMints = (1 << nInputs);
00296 pLib->nLevels = 0;
00297 pLib->nGates = nInputs + 1;
00298 pLib->nGatesAlloc = nInputs + 1;
00299 pLib->uMaskBit = (1 << (pLib->nMints-1));
00300 pLib->pGates = ALLOC( Super2_Gate_t *, nInputs + 1 );
00301
00302 pLib->pGates[0] = (Super2_Gate_t *)Extra_MmFixedEntryFetch( pMan->pMem );
00303 memset( pLib->pGates[0], 0, sizeof(Super2_Gate_t) );
00304
00305 for ( v = 0; v < nInputs; v++ )
00306 {
00307 pLib->pGates[v+1] = (Super2_Gate_t *)Extra_MmFixedEntryFetch( pMan->pMem );
00308 memset( pLib->pGates[v+1], 0, sizeof(Super2_Gate_t) );
00309 pLib->pGates[v+1]->pTwo = (Super2_Gate_t *)v;
00310 }
00311
00312
00313 for ( m = 0; m < pLib->nMints; m++ )
00314 for ( v = 0; v < nInputs; v++ )
00315 if ( m & (1 << v) )
00316 pLib->pGates[v+1]->uTruth |= (1 << m);
00317 return pLib;
00318 }
00319
00331 Super2_Lib_t * Super2_LibCompute( Super2_Man_t * pMan, Super2_Lib_t * pLib )
00332 {
00333 Super2_Lib_t * pLibNew;
00334 Super2_Gate_t * pGate1, * pGate2, * pGateNew;
00335 Super2_Gate_t ** ppGate;
00336 unsigned Mask = SUPER_MASK(pLib->nMints);
00337 unsigned uTruth, uTruthR, uTruth1, uTruth2, uTruth1c, uTruth2c;
00338
00339
00340 pLibNew = Super2_LibDup( pLib );
00341
00342
00343 stmm_free_table( pMan->tTable );
00344 pMan->tTable = stmm_init_table( st_ptrcmp, st_ptrhash );
00345
00346 Super2_LibForEachGate( pLibNew, pGate1 )
00347 {
00348 uTruthR = ((pGate1->uTruth & pLibNew->uMaskBit)? Mask & ~pGate1->uTruth : pGate1->uTruth);
00349
00350 if ( stmm_lookup( pMan->tTable, (char *)uTruthR, (char **)&pGate2 ) )
00351 {
00352 printf( "New gate:\n" );
00353 Super2_LibWriteGate( stdout, pLibNew, pGate1 );
00354 printf( "Gate in the table:\n" );
00355 Super2_LibWriteGate( stdout, pLibNew, pGate2 );
00356 assert( 0 );
00357 }
00358 stmm_insert( pMan->tTable, (char *)uTruthR, (char *)pGate1 );
00359 }
00360
00361
00362
00363 pMan->nTried = pLibNew->nGates;
00364
00365
00366 Super2_LibForEachGate( pLib, pGate1 )
00367 {
00368 if ( pLib->i && pLib->i % 300 == 0 )
00369 {
00370 printf( "Tried %5d first gates...\n", pLib->i );
00371 fflush( stdout );
00372 }
00373
00374 Super2_LibForEachGate2( pLib, pGate2 )
00375 {
00376 uTruth1 = pGate1->uTruth;
00377 uTruth2 = pGate2->uTruth;
00378 uTruth1c = Mask & ~uTruth1;
00379 uTruth2c = Mask & ~uTruth2;
00380
00381
00382 uTruth = uTruth1 & uTruth2;
00383 uTruthR = ((uTruth & pLibNew->uMaskBit)? Mask & ~uTruth : uTruth);
00384
00385 if ( !stmm_find_or_add( pMan->tTable, (char *)uTruthR, (char ***)&ppGate ) )
00386 {
00387 pGateNew = (Super2_Gate_t *)Extra_MmFixedEntryFetch( pMan->pMem );
00388 pGateNew->pOne = pGate1;
00389 pGateNew->pTwo = pGate2;
00390 pGateNew->uTruth = uTruth;
00391 *ppGate = pGateNew;
00392 Super2_LibAddGate( pLibNew, pGateNew );
00393 }
00394
00395
00396 uTruth = uTruth1c & uTruth2;
00397 uTruthR = ((uTruth & pLibNew->uMaskBit)? Mask & ~uTruth : uTruth);
00398
00399 if ( !stmm_find_or_add( pMan->tTable, (char *)uTruthR, (char ***)&ppGate ) )
00400 {
00401 pGateNew = (Super2_Gate_t *)Extra_MmFixedEntryFetch( pMan->pMem );
00402 pGateNew->pOne = Super2_Not(pGate1);
00403 pGateNew->pTwo = pGate2;
00404 pGateNew->uTruth = uTruth;
00405 *ppGate = pGateNew;
00406 Super2_LibAddGate( pLibNew, pGateNew );
00407 }
00408
00409
00410 uTruth = uTruth1 & uTruth2c;
00411 uTruthR = ((uTruth & pLibNew->uMaskBit)? Mask & ~uTruth : uTruth);
00412
00413 if ( !stmm_find_or_add( pMan->tTable, (char *)uTruthR, (char ***)&ppGate ) )
00414 {
00415 pGateNew = (Super2_Gate_t *)Extra_MmFixedEntryFetch( pMan->pMem );
00416 pGateNew->pOne = pGate1;
00417 pGateNew->pTwo = Super2_Not(pGate2);
00418 pGateNew->uTruth = uTruth;
00419 *ppGate = pGateNew;
00420 Super2_LibAddGate( pLibNew, pGateNew );
00421 }
00422
00423
00424 uTruth = uTruth1c & uTruth2c;
00425 uTruthR = ((uTruth & pLibNew->uMaskBit)? Mask & ~uTruth : uTruth);
00426
00427 if ( !stmm_find_or_add( pMan->tTable, (char *)uTruthR, (char ***)&ppGate ) )
00428 {
00429 pGateNew = (Super2_Gate_t *)Extra_MmFixedEntryFetch( pMan->pMem );
00430 pGateNew->pOne = Super2_Not(pGate1);
00431 pGateNew->pTwo = Super2_Not(pGate2);
00432 pGateNew->uTruth = uTruth;
00433 *ppGate = pGateNew;
00434 Super2_LibAddGate( pLibNew, pGateNew );
00435 }
00436
00437 pMan->nTried += 4;
00438 }
00439 }
00440 return pLibNew;
00441 }
00442
00443
00444 static unsigned s_uMaskBit;
00445 static unsigned s_uMaskAll;
00446
00458 void Super2_LibWrite( Super2_Lib_t * pLib )
00459 {
00460 Super2_Gate_t * pGate;
00461 FILE * pFile;
00462 char FileName[100];
00463 int clk;
00464
00465 if ( pLib->nLevels > 5 )
00466 {
00467 printf( "Cannot write file for %d levels.\n", pLib->nLevels );
00468 return;
00469 }
00470
00471 clk = clock();
00472
00473 s_uMaskBit = pLib->uMaskBit;
00474 s_uMaskAll = SUPER_MASK(pLib->nMints);
00475 qsort( (void *)pLib->pGates, pLib->nGates, sizeof(Super2_Gate_t *),
00476 (int (*)(const void *, const void *)) Super2_LibCompareGates );
00477 assert( Super2_LibCompareGates( pLib->pGates, pLib->pGates + pLib->nGates - 1 ) < 0 );
00478 PRT( "Sorting", clock() - clk );
00479
00480
00481
00482 sprintf( FileName, "superI%dL%d", pLib->nInputs, pLib->nLevels );
00483 pFile = fopen( FileName, "w" );
00484 fprintf( pFile, "# AND2/INV supergates derived on %s.\n", Extra_TimeStamp() );
00485 fprintf( pFile, "# Command line: \"super2 -i %d -l %d\".\n", pLib->nInputs, pLib->nLevels );
00486 fprintf( pFile, "# The number of inputs = %6d.\n", pLib->nInputs );
00487 fprintf( pFile, "# The number of levels = %6d.\n", pLib->nLevels );
00488 fprintf( pFile, "# The number of supergates = %6d.\n", pLib->nGates );
00489 fprintf( pFile, "# The total functions = %6d.\n", (1<<(pLib->nMints-1)) );
00490 fprintf( pFile, "\n" );
00491 fprintf( pFile, "%6d\n", pLib->nGates );
00492
00493
00494 Super2_LibForEachGate( pLib, pGate )
00495 Super2_LibWriteGate( pFile, pLib, pGate );
00496 fclose( pFile );
00497
00498 printf( "The supergates are written into file \"%s\" ", FileName );
00499 printf( "(%0.2f Mb).\n", ((double)Extra_FileSize(FileName))/(1<<20) );
00500 }
00501
00513 int Super2_LibCompareGates( Super2_Gate_t ** ppG1, Super2_Gate_t ** ppG2 )
00514 {
00515 Super2_Gate_t * pG1 = *ppG1;
00516 Super2_Gate_t * pG2 = *ppG2;
00517 unsigned uTruth1, uTruth2;
00518
00519 uTruth1 = (pG1->uTruth & s_uMaskBit)? s_uMaskAll & ~pG1->uTruth : pG1->uTruth;
00520 uTruth2 = (pG2->uTruth & s_uMaskBit)? s_uMaskAll & ~pG2->uTruth : pG2->uTruth;
00521
00522 if ( uTruth1 < uTruth2 )
00523 return -1;
00524 return 1;
00525 }
00526
00538 void Super2_LibWriteGate( FILE * pFile, Super2_Lib_t * pLib, Super2_Gate_t * pGate )
00539 {
00540
00541 unsigned uTruth;
00542 int fInv;
00543
00544
00545 fInv = (int)(pGate->uTruth & pLib->uMaskBit);
00546 uTruth = (fInv? ~pGate->uTruth : pGate->uTruth);
00547
00548
00549
00550
00551
00552
00553
00554
00555 Extra_PrintBinary( pFile, &uTruth, pLib->nMints );
00556 fprintf( pFile, " " );
00557
00558 fprintf( pFile, "%s", Super2_LibWriteGate_rec( pGate, fInv, pLib->nLevels ) );
00559 fprintf( pFile, "\n" );
00560 }
00561
00562
00574 char * Super2_LibWriteGate_rec( Super2_Gate_t * pGate, int fInv, int Level )
00575 {
00576 static char Buff01[ 3], Buff02[ 3];
00577 static char Buff11[ 6], Buff12[ 6];
00578 static char Buff21[ 12], Buff22[ 12];
00579 static char Buff31[ 25], Buff32[ 25];
00580 static char Buff41[ 50], Buff42[ 50];
00581 static char Buff51[100], Buff52[100];
00582 static char * pBuffs1[6] = { Buff01, Buff11, Buff21, Buff31, Buff41, Buff51 };
00583 static char * pBuffs2[6] = { Buff02, Buff12, Buff22, Buff32, Buff42, Buff52 };
00584 char * pBranch;
00585 char * pBuffer1 = pBuffs1[Level];
00586 char * pBuffer2 = pBuffs2[Level];
00587 Super2_Gate_t * pGateNext1, * pGateNext2;
00588 int fInvNext1, fInvNext2;
00589 int RetValue;
00590
00591
00592 assert( Level >= 0 );
00593 if ( pGate->pOne == NULL )
00594 {
00595 if ( pGate->uTruth == 0 )
00596 {
00597 pBuffer1[0] = (fInv? '1': '0');
00598 pBuffer1[1] = '$';
00599 pBuffer1[2] = 0;
00600 }
00601 else
00602 {
00603 pBuffer1[0] = (fInv? 'A' + ((int)pGate->pTwo): 'a' + ((int)pGate->pTwo));
00604 pBuffer1[1] = 0;
00605 }
00606 return pBuffer1;
00607 }
00608 assert( Level > 0 );
00609
00610
00611
00612 pGateNext1 = Super2_Regular(pGate->pOne);
00613 fInvNext1 = Super2_IsComplement(pGate->pOne);
00614 pBranch = Super2_LibWriteGate_rec(pGateNext1, fInvNext1, Level - 1);
00615
00616 strcpy( pBuffer1, pBranch );
00617
00618
00619 pGateNext2 = Super2_Regular(pGate->pTwo);
00620 fInvNext2 = Super2_IsComplement(pGate->pTwo);
00621 pBranch = Super2_LibWriteGate_rec(pGateNext2, fInvNext2, Level - 1);
00622
00623
00624 if ( fInvNext1 ^ fInvNext2 )
00625 {
00626 if ( fInvNext1 > fInvNext2 )
00627 sprintf( pBuffer2, "%c%s%s%c", (fInv? '<': '('), pBuffer1, pBranch, (fInv? '>': ')') );
00628 else
00629 sprintf( pBuffer2, "%c%s%s%c", (fInv? '<': '('), pBranch, pBuffer1, (fInv? '>': ')') );
00630 }
00631 else
00632 {
00633
00634 RetValue = Super2_LibWriteCompare( pBuffer1, pBranch );
00635 if ( RetValue == 1 )
00636 sprintf( pBuffer2, "%c%s%s%c", (fInv? '<': '('), pBuffer1, pBranch, (fInv? '>': ')') );
00637 else
00638 {
00639 sprintf( pBuffer2, "%c%s%s%c", (fInv? '<': '('), pBranch, pBuffer1, (fInv? '>': ')') );
00640 if ( RetValue == 0 )
00641 printf( "Strange!\n" );
00642 }
00643 }
00644 return pBuffer2;
00645 }
00646
00658 int Super2_LibWriteCompare( char * pStr1, char * pStr2 )
00659 {
00660 while ( 1 )
00661 {
00662
00663 while ( *pStr1 && *pStr1 < 'A' )
00664 pStr1++;
00665 while ( *pStr2 && *pStr2 < 'A' )
00666 pStr2++;
00667
00668
00669 if ( *pStr1 == 0 || *pStr2 == 0 )
00670 {
00671 if ( *pStr2 )
00672 return 1;
00673 return -1;
00674 }
00675
00676
00677 if ( *pStr1 == *pStr2 )
00678 {
00679 pStr1++;
00680 pStr2++;
00681 }
00682 else
00683 {
00684 if ( *pStr1 < *pStr2 )
00685 return 1;
00686 return -1;
00687 }
00688 }
00689 return 0;
00690 }
00691
00695
00696