ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
superGate.c
Go to the documentation of this file.
1
18
19#include <math.h>
20#include "superInt.h"
21
23
24
28
29// the bit masks
30#define SUPER_MASK(n) ((~((unsigned)0)) >> (32-(n)))
31#define SUPER_FULL (~((unsigned)0))
32#define SUPER_NO_VAR (-9999.0)
33#define SUPER_EPSILON (0.001)
34
35// data structure for supergate precomputation
36typedef struct Super_ManStruct_t_ Super_Man_t; // manager
37typedef struct Super_GateStruct_t_ Super_Gate_t; // supergate
38
40{
41 // parameters
42 char * pName; // the original genlib file name
43 int nVarsMax; // the number of inputs
44 int nMints; // the number of minterms
45 int nLevels; // the number of logic levels
46 int nGatesMax; // the number of gates computed
47 float tDelayMax; // the max delay of the supergates in the library
48 float tAreaMax; // the max area of the supergates in the library
49 int fSkipInv; // the flag says about skipping inverters
50 int fWriteOldFormat; // in addition, writes the file in the old format
52
53 // supergates
54 Super_Gate_t * pInputs[10]; // the input supergates
55 int nGates; // the number of gates in the library
56 Super_Gate_t ** pGates; // the gates themselves
57 stmm_table * tTable; // mapping of truth tables into gates
58
59 // memory managers
60 Extra_MmFixed_t * pMem; // memory manager for the supergates
61 Extra_MmFlex_t * pMemFlex; // memory manager for the fanin arrays
62
63 // statistics
64 int nTried; // the total number of tried
65 int nAdded; // the number of entries added
66 int nRemoved; // the number of entries removed
67 int nClasses; // the number of gate classes
68 int nUnique; // the number of unique gates
69 int nLookups; // the number of hash table lookups
70 int nAliases; // the number of hash table lookups thrown away due to aliasing
71
72 // runtime
73 abctime Time; // the runtime of the generation procedure
74 int TimeLimit; // the runtime limit (in seconds)
75 int TimeSec; // the time passed (in seconds)
76 abctime TimeStop; // the time to stop computation (in miliseconds)
77 abctime TimePrint; // the time to print message
78};
79
81{
82 Mio_Gate_t * pRoot; // the root gate for this supergate
83 unsigned fVar : 1; // the flag signaling the elementary variable
84 unsigned fSuper : 1; // the flag signaling the elementary variable
85 unsigned nFanins : 6; // the number of fanin gates
86 unsigned Number : 24; // the number assigned in the process
87 unsigned uTruth[2]; // the truth table of this supergate
88 Super_Gate_t * pFanins[6]; // the fanins of the gate
89 float Area; // the area of this gate
90 float ptDelays[6]; // the pin-to-pin delays for all inputs
91 float tDelayMax; // the maximum delay
92 Super_Gate_t * pNext; // the next gate in the table
93};
94
95
96// iterating through the gates in the library
97#define Super_ManForEachGate( GateArray, Limit, Index, Gate ) \
98 for ( Index = 0; \
99 Index < Limit && (Gate = GateArray[Index]); \
100 Index++ )
101
102// static functions
103static Super_Man_t * Super_ManStart();
104static void Super_ManStop( Super_Man_t * pMan );
105
106static void Super_AddGateToTable( Super_Man_t * pMan, Super_Gate_t * pGate );
107static void Super_First( Super_Man_t * pMan, int nVarsMax );
108static Super_Man_t * Super_Compute( Super_Man_t * pMan, Mio_Gate_t ** ppGates, int nGates, int nGatesMax, int fSkipInv );
109static 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 );
110static int Super_CompareGates( Super_Man_t * pMan, unsigned uTruth[], float Area, float tPinDelaysRes[], int nPins );
111static int Super_DelayCompare( Super_Gate_t ** ppG1, Super_Gate_t ** ppG2 );
112static int Super_AreaCompare( Super_Gate_t ** ppG1, Super_Gate_t ** ppG2 );
113static void Super_TranferGatesToArray( Super_Man_t * pMan );
114static int Super_CheckTimeout( ProgressBar * pPro, Super_Man_t * pMan );
115
116static Vec_Str_t * Super_Write( Super_Man_t * pMan );
117static int Super_WriteCompare( Super_Gate_t ** ppG1, Super_Gate_t ** ppG2 );
118static void Super_WriteFileHeader( Super_Man_t * pMan, FILE * pFile );
119
120static void Super_WriteLibrary( Super_Man_t * pMan );
121
122static void Super_WriteLibraryTreeFile( Super_Man_t * pMan );
123static Vec_Str_t * Super_WriteLibraryTreeStr( Super_Man_t * pMan );
124
128
140void Super_Precompute( Mio_Library_t * pLibGen, int nVarsMax, int nLevels, int nGatesMax, float tDelayMax, float tAreaMax, int TimeLimit, int fSkipInv, int fVerbose, char * pFileName )
141{
142 Vec_Str_t * vStr;
143 FILE * pFile = fopen( pFileName, "wb" );
144 if ( pFile == NULL )
145 {
146 printf( "Cannot open output file \"%s\".\n", pFileName );
147 return;
148 }
149 vStr = Super_PrecomputeStr( pLibGen, nVarsMax, nLevels, nGatesMax, tDelayMax, tAreaMax, TimeLimit, fSkipInv, fVerbose );
150 if ( vStr )
151 {
152 fwrite( Vec_StrArray(vStr), 1, Vec_StrSize(vStr), pFile );
153 Vec_StrFree( vStr );
154 }
155 fclose( pFile );
156 // report the result of writing
157 if ( fVerbose )
158 {
159 printf( "The supergates are written using new format \"%s\" ", pFileName );
160 printf( "(%0.3f MB).\n", ((double)Extra_FileSize(pFileName))/(1<<20) );
161 }
162}
163
175Vec_Str_t * Super_PrecomputeStr( Mio_Library_t * pLibGen, int nVarsMax, int nLevels, int nGatesMax, float tDelayMax, float tAreaMax, int TimeLimit, int fSkipInv, int fVerbose )
176{
177 Vec_Str_t * vStr;
178 Super_Man_t * pMan;
179 Mio_Gate_t ** ppGates;
180 int nGates, Level;
181 abctime clk, clockStart;
182
183 assert( nVarsMax < 7 );
184 if ( nGatesMax && nGatesMax < nVarsMax )
185 {
186 fprintf( stderr, "Erro! The number of supergates requested (%d) in less than the number of variables (%d).\n", nGatesMax, nVarsMax );
187 fprintf( stderr, "The library cannot be computed.\n" );
188 return NULL;
189 }
190
191 // get the root gates
192 ppGates = Mio_CollectRoots( pLibGen, nVarsMax, tDelayMax, 0, &nGates, fVerbose );
193 if ( nGatesMax && nGates >= nGatesMax )
194 {
195 fprintf( stdout, "Warning! Genlib library contains more gates than can be computed.\n");
196 fprintf( stdout, "Only one-gate supergates are included in the supergate library.\n" );
197 }
198
199 // start the manager
200 pMan = Super_ManStart();
201 pMan->pName = Mio_LibraryReadName(pLibGen);
202 pMan->nGatesMax = nGatesMax;
203 pMan->fSkipInv = fSkipInv;
204 pMan->tDelayMax = tDelayMax;
205 pMan->tAreaMax = tAreaMax;
206 pMan->TimeLimit = TimeLimit; // in seconds
207 pMan->TimeStop = TimeLimit ? TimeLimit * CLOCKS_PER_SEC + Abc_Clock() : 0; // in CPU ticks
208 pMan->fVerbose = fVerbose;
209
210 if ( nGates == 0 )
211 {
212 fprintf( stderr, "Error: No genlib gates satisfy the limits criteria. Stop.\n");
213 fprintf( stderr, "Limits: max delay = %.2f, max area = %.2f, time limit = %d sec.\n",
214 pMan->tDelayMax, pMan->tAreaMax, pMan->TimeLimit );
215
216 // stop the manager
217 Super_ManStop( pMan );
218 ABC_FREE( ppGates );
219
220 return NULL;
221 }
222
223 // get the starting supergates
224 Super_First( pMan, nVarsMax );
225
226 // perform the computation of supergates
227 clockStart = Abc_Clock();
228if ( fVerbose )
229{
230 printf( "Computing supergates with %d inputs, %d levels, and %d max gates.\n",
231 pMan->nVarsMax, nLevels, nGatesMax );
232 printf( "Limits: max delay = %.2f, max area = %.2f, time limit = %d sec.\n",
233 pMan->tDelayMax, pMan->tAreaMax, pMan->TimeLimit );
234}
235
236 for ( Level = 1; Level <= nLevels; Level++ )
237 {
238 if ( pMan->TimeStop && Abc_Clock() > pMan->TimeStop )
239 break;
240clk = Abc_Clock();
241 Super_Compute( pMan, ppGates, nGates, nGatesMax, fSkipInv );
242 pMan->nLevels = Level;
243if ( fVerbose )
244{
245 printf( "Lev %d: Try =%12d. Add =%6d. Rem =%5d. Save =%6d. Lookups =%12d. Aliases =%12d. ",
246 Level, pMan->nTried, pMan->nAdded, pMan->nRemoved, pMan->nAdded - pMan->nRemoved, pMan->nLookups, pMan->nAliases );
247ABC_PRT( "Time", Abc_Clock() - clk );
248fflush( stdout );
249}
250 }
251 pMan->Time = Abc_Clock() - clockStart;
252
253if ( fVerbose )
254{
255printf( "Writing the output file...\n" );
256fflush( stdout );
257}
258 // write them into a file
259 vStr = Super_Write( pMan );
260
261 // stop the manager
262 Super_ManStop( pMan );
263 ABC_FREE( ppGates );
264 return vStr;
265}
266
267
279void Super_First( Super_Man_t * pMan, int nVarsMax )
280{
281 Super_Gate_t * pSuper;
282 int nMintLimit, nVarLimit;
283 int v, m;
284 // set the parameters
285 pMan->nVarsMax = nVarsMax;
286 pMan->nMints = (1 << nVarsMax);
287 pMan->nLevels = 0;
288 // allocate room for the gates
289 pMan->nGates = nVarsMax;
290 pMan->pGates = ABC_ALLOC( Super_Gate_t *, nVarsMax + 2 );
291 // create the gates corresponding to the elementary variables
292 for ( v = 0; v < nVarsMax; v++ )
293 {
294 // get a new gate
295 pSuper = (Super_Gate_t *)Extra_MmFixedEntryFetch( pMan->pMem );
296 memset( pSuper, 0, sizeof(Super_Gate_t) );
297 // assign the elementary variable, the truth table, and the delays
298 pSuper->fVar = 1;
299 pSuper->Number = v;
300 for ( m = 0; m < nVarsMax; m++ )
301 pSuper->ptDelays[m] = SUPER_NO_VAR;
302 pSuper->ptDelays[v] = 0.0;
303 // set the gate
304 pMan->pGates[v] = pSuper;
305 Super_AddGateToTable( pMan, pSuper );
306 pMan->pInputs[v] = pSuper;
307 }
308 // set up their truth tables
309 nVarLimit = (nVarsMax >= 5)? 5 : nVarsMax;
310 nMintLimit = (1 << nVarLimit);
311 for ( m = 0; m < nMintLimit; m++ )
312 for ( v = 0; v < nVarLimit; v++ )
313 if ( m & (1 << v) )
314 pMan->pGates[v]->uTruth[0] |= (1 << m);
315 // make adjustments for the case of 6 variables
316 if ( nVarsMax == 6 )
317 {
318 for ( v = 0; v < 5; v++ )
319 pMan->pGates[v]->uTruth[1] = pMan->pGates[v]->uTruth[0];
320 pMan->pGates[5]->uTruth[0] = 0;
321 pMan->pGates[5]->uTruth[1] = ~((unsigned)0);
322 }
323 else
324 {
325 for ( v = 0; v < nVarsMax; v++ )
326 pMan->pGates[v]->uTruth[1] = 0;
327 }
328}
329
346Super_Man_t * Super_Compute( Super_Man_t * pMan, Mio_Gate_t ** ppGates, int nGates, int nGatesMax, int fSkipInv )
347{
348 Super_Gate_t * pSupers[6], * pGate0, * pGate1, * pGate2, * pGate3, * pGate4, * pGate5, * pGateNew;
349 float tPinDelaysRes[6], * ptPinDelays[6], tPinDelayMax, tDelayMio;
350 float Area = 0.0; // Suppress "might be used uninitialized"
351 float Area0, Area1, Area2, Area3, Area4, AreaMio;
352 unsigned uTruth[2], uTruths[6][2];
353 int i0, i1, i2, i3, i4, i5;
354 Super_Gate_t ** ppGatesLimit;
355 int nFanins, nGatesLimit, k, s, t;
356 ProgressBar * pProgress;
357 int fTimeOut;
358 int fPrune = 1; // Shall we prune?
359 int iPruneLimit = 3; // Each of the gates plugged into the root gate will have
360 // less than these many fanins
361 int iPruneLimitRoot = 4; // The root gate may have only less than these many fanins
362
363 // put the gates from the unique table into the array
364 // the gates from the array will be used to compose other gates
365 // the gates in tbe table are used to check uniqueness of collected gates
366 Super_TranferGatesToArray( pMan );
367
368 // sort the gates in the increasing order of maximum delay
369 if ( pMan->nGates > 10000 )
370 {
371 printf( "Sorting array of %d supergates...\r", pMan->nGates );
372 fflush( stdout );
373 }
374 qsort( (void *)pMan->pGates, (size_t)pMan->nGates, sizeof(Super_Gate_t *),
375 (int (*)(const void *, const void *)) Super_DelayCompare );
376 assert( Super_DelayCompare( pMan->pGates, pMan->pGates + pMan->nGates - 1 ) <= 0 );
377 if ( pMan->nGates > 10000 )
378 {
379 printf( " \r" );
380 }
381
382 pProgress = Extra_ProgressBarStart( stdout, pMan->TimeLimit );
383 pMan->TimePrint = Abc_Clock() + CLOCKS_PER_SEC;
384 ppGatesLimit = ABC_ALLOC( Super_Gate_t *, pMan->nGates );
385 // go through the root gates
386 // the root gates are sorted in the increasing gelay
387 fTimeOut = 0;
388 for ( k = 0; k < nGates; k++ )
389 {
390 if ( fTimeOut ) break;
391
392 if ( fPrune )
393 {
394 if ( pMan->nLevels >= 1 ) // First level gates have been computed
395 {
396 if ( Mio_GateReadPinNum(ppGates[k]) >= iPruneLimitRoot )
397 continue;
398 }
399 }
400/*
401 if ( strcmp(Mio_GateReadName(ppGates[k]), "MUX2IX0") == 0 )
402 {
403 int s = 0;
404 }
405*/
406 // select the subset of gates to be considered with this root gate
407 // all the gates past this point will lead to delay larger than the limit
408 tDelayMio = (float)Mio_GateReadDelayMax(ppGates[k]);
409 for ( s = 0, t = 0; s < pMan->nGates; s++ )
410 {
411 if ( fPrune && ( pMan->nLevels >= 1 ) && ( ((int)pMan->pGates[s]->nFanins) >= iPruneLimit ))
412 continue;
413
414 ppGatesLimit[t] = pMan->pGates[s];
415 if ( ppGatesLimit[t++]->tDelayMax + tDelayMio > pMan->tDelayMax && pMan->tDelayMax > 0.0 )
416 break;
417 }
418 nGatesLimit = t;
419
420 if ( pMan->fVerbose )
421 {
422 printf ("Trying %d choices for %d inputs\r", t, Mio_GateReadPinNum(ppGates[k]) );
423 }
424
425 // resort part of this range by area
426 // now we can prune the search by going up in the list until we reach the limit on area
427 // all the gates beyond this point can be skipped because their area can be only larger
428 if ( nGatesLimit > 10000 )
429 printf( "Sorting array of %d supergates...\r", nGatesLimit );
430 qsort( (void *)ppGatesLimit, (size_t)nGatesLimit, sizeof(Super_Gate_t *),
431 (int (*)(const void *, const void *)) Super_AreaCompare );
432 assert( Super_AreaCompare( ppGatesLimit, ppGatesLimit + nGatesLimit - 1 ) <= 0 );
433 if ( nGatesLimit > 10000 )
434 printf( " \r" );
435
436 // consider the combinations of gates with the root gate on top
437 AreaMio = (float)Mio_GateReadArea(ppGates[k]);
438 nFanins = Mio_GateReadPinNum(ppGates[k]);
439 switch ( nFanins )
440 {
441 case 0: // should not happen
442 assert( 0 );
443 break;
444 case 1: // interter root
445 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i0, pGate0 )
446 {
447 if ( fTimeOut ) break;
448 fTimeOut = Super_CheckTimeout( pProgress, pMan );
449 // skip the inverter as the root gate before the elementary variable
450 // as a result, the supergates will not have inverters on the input side
451 // but inverters still may occur at the output of or inside complex supergates
452 if ( fSkipInv && pGate0->tDelayMax == 0 )
453 continue;
454 // compute area
455 Area = AreaMio + pGate0->Area;
456 if ( pMan->tAreaMax > 0.0 && Area > pMan->tAreaMax )
457 break;
458
459 pSupers[0] = pGate0; uTruths[0][0] = pGate0->uTruth[0]; uTruths[0][1] = pGate0->uTruth[1]; ptPinDelays[0] = pGate0->ptDelays;
460 Mio_DeriveGateDelays( ppGates[k], ptPinDelays, nFanins, pMan->nVarsMax, SUPER_NO_VAR, tPinDelaysRes, &tPinDelayMax );
461 Mio_DeriveTruthTable( ppGates[k], uTruths, nFanins, pMan->nVarsMax, uTruth );
462 if ( !Super_CompareGates( pMan, uTruth, Area, tPinDelaysRes, pMan->nVarsMax ) )
463 continue;
464 // create a new gate
465 pGateNew = Super_CreateGateNew( pMan, ppGates[k], pSupers, nFanins, uTruth, Area, tPinDelaysRes, tPinDelayMax, pMan->nVarsMax );
466 Super_AddGateToTable( pMan, pGateNew );
467 if ( nGatesMax && pMan->nClasses > nGatesMax )
468 goto done;
469 }
470 break;
471 case 2: // two-input root gate
472 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i0, pGate0 )
473 {
474 Area0 = AreaMio + pGate0->Area;
475 if ( pMan->tAreaMax > 0.0 && Area0 > pMan->tAreaMax )
476 break;
477 pSupers[0] = pGate0; uTruths[0][0] = pGate0->uTruth[0]; uTruths[0][1] = pGate0->uTruth[1]; ptPinDelays[0] = pGate0->ptDelays;
478 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i1, pGate1 )
479 if ( i1 != i0 )
480 {
481 if ( fTimeOut ) goto done;
482 fTimeOut = Super_CheckTimeout( pProgress, pMan );
483 // compute area
484 Area = Area0 + pGate1->Area;
485 if ( pMan->tAreaMax > 0.0 && Area > pMan->tAreaMax )
486 break;
487
488 pSupers[1] = pGate1; uTruths[1][0] = pGate1->uTruth[0]; uTruths[1][1] = pGate1->uTruth[1]; ptPinDelays[1] = pGate1->ptDelays;
489 Mio_DeriveGateDelays( ppGates[k], ptPinDelays, nFanins, pMan->nVarsMax, SUPER_NO_VAR, tPinDelaysRes, &tPinDelayMax );
490 Mio_DeriveTruthTable( ppGates[k], uTruths, nFanins, pMan->nVarsMax, uTruth );
491 if ( !Super_CompareGates( pMan, uTruth, Area, tPinDelaysRes, pMan->nVarsMax ) )
492 continue;
493 // create a new gate
494 pGateNew = Super_CreateGateNew( pMan, ppGates[k], pSupers, nFanins, uTruth, Area, tPinDelaysRes, tPinDelayMax, pMan->nVarsMax );
495 Super_AddGateToTable( pMan, pGateNew );
496 if ( nGatesMax && pMan->nClasses > nGatesMax )
497 goto done;
498 }
499 }
500 break;
501 case 3: // three-input root gate
502 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i0, pGate0 )
503 {
504 Area0 = AreaMio + pGate0->Area;
505 if ( pMan->tAreaMax > 0.0 && Area0 > pMan->tAreaMax )
506 break;
507 pSupers[0] = pGate0; uTruths[0][0] = pGate0->uTruth[0]; uTruths[0][1] = pGate0->uTruth[1]; ptPinDelays[0] = pGate0->ptDelays;
508
509 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i1, pGate1 )
510 if ( i1 != i0 )
511 {
512 Area1 = Area0 + pGate1->Area;
513 if ( pMan->tAreaMax > 0.0 && Area1 > pMan->tAreaMax )
514 break;
515 pSupers[1] = pGate1; uTruths[1][0] = pGate1->uTruth[0]; uTruths[1][1] = pGate1->uTruth[1]; ptPinDelays[1] = pGate1->ptDelays;
516
517 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i2, pGate2 )
518 if ( i2 != i0 && i2 != i1 )
519 {
520 if ( fTimeOut ) goto done;
521 fTimeOut = Super_CheckTimeout( pProgress, pMan );
522 // compute area
523 Area = Area1 + pGate2->Area;
524 if ( pMan->tAreaMax > 0.0 && Area > pMan->tAreaMax )
525 break;
526 pSupers[2] = pGate2; uTruths[2][0] = pGate2->uTruth[0]; uTruths[2][1] = pGate2->uTruth[1]; ptPinDelays[2] = pGate2->ptDelays;
527
528 Mio_DeriveGateDelays( ppGates[k], ptPinDelays, nFanins, pMan->nVarsMax, SUPER_NO_VAR, tPinDelaysRes, &tPinDelayMax );
529 Mio_DeriveTruthTable( ppGates[k], uTruths, nFanins, pMan->nVarsMax, uTruth );
530 if ( !Super_CompareGates( pMan, uTruth, Area, tPinDelaysRes, pMan->nVarsMax ) )
531 continue;
532 // create a new gate
533 pGateNew = Super_CreateGateNew( pMan, ppGates[k], pSupers, nFanins, uTruth, Area, tPinDelaysRes, tPinDelayMax, pMan->nVarsMax );
534 Super_AddGateToTable( pMan, pGateNew );
535 if ( nGatesMax && pMan->nClasses > nGatesMax )
536 goto done;
537 }
538 }
539 }
540 break;
541 case 4: // four-input root gate
542 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i0, pGate0 )
543 {
544 Area0 = AreaMio + pGate0->Area;
545 if ( pMan->tAreaMax > 0.0 && Area0 > pMan->tAreaMax )
546 break;
547 pSupers[0] = pGate0; uTruths[0][0] = pGate0->uTruth[0]; uTruths[0][1] = pGate0->uTruth[1]; ptPinDelays[0] = pGate0->ptDelays;
548
549 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i1, pGate1 )
550 if ( i1 != i0 )
551 {
552 Area1 = Area0 + pGate1->Area;
553 if ( pMan->tAreaMax > 0.0 && Area1 > pMan->tAreaMax )
554 break;
555 pSupers[1] = pGate1; uTruths[1][0] = pGate1->uTruth[0]; uTruths[1][1] = pGate1->uTruth[1]; ptPinDelays[1] = pGate1->ptDelays;
556
557 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i2, pGate2 )
558 if ( i2 != i0 && i2 != i1 )
559 {
560 Area2 = Area1 + pGate2->Area;
561 if ( pMan->tAreaMax > 0.0 && Area2 > pMan->tAreaMax )
562 break;
563 pSupers[2] = pGate2; uTruths[2][0] = pGate2->uTruth[0]; uTruths[2][1] = pGate2->uTruth[1]; ptPinDelays[2] = pGate2->ptDelays;
564
565 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i3, pGate3 )
566 if ( i3 != i0 && i3 != i1 && i3 != i2 )
567 {
568 if ( fTimeOut ) goto done;
569 fTimeOut = Super_CheckTimeout( pProgress, pMan );
570 // compute area
571 Area = Area2 + pGate3->Area;
572 if ( pMan->tAreaMax > 0.0 && Area > pMan->tAreaMax )
573 break;
574 pSupers[3] = pGate3; uTruths[3][0] = pGate3->uTruth[0]; uTruths[3][1] = pGate3->uTruth[1]; ptPinDelays[3] = pGate3->ptDelays;
575
576 Mio_DeriveGateDelays( ppGates[k], ptPinDelays, nFanins, pMan->nVarsMax, SUPER_NO_VAR, tPinDelaysRes, &tPinDelayMax );
577 Mio_DeriveTruthTable( ppGates[k], uTruths, nFanins, pMan->nVarsMax, uTruth );
578 if ( !Super_CompareGates( pMan, uTruth, Area, tPinDelaysRes, pMan->nVarsMax ) )
579 continue;
580 // create a new gate
581 pGateNew = Super_CreateGateNew( pMan, ppGates[k], pSupers, nFanins, uTruth, Area, tPinDelaysRes, tPinDelayMax, pMan->nVarsMax );
582 Super_AddGateToTable( pMan, pGateNew );
583 if ( nGatesMax && pMan->nClasses > nGatesMax )
584 goto done;
585 }
586 }
587 }
588 }
589 break;
590 case 5: // five-input root gate
591 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i0, pGate0 )
592 {
593 Area0 = AreaMio + pGate0->Area;
594 if ( pMan->tAreaMax > 0.0 && Area0 > pMan->tAreaMax )
595 break;
596 pSupers[0] = pGate0; uTruths[0][0] = pGate0->uTruth[0]; uTruths[0][1] = pGate0->uTruth[1]; ptPinDelays[0] = pGate0->ptDelays;
597
598 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i1, pGate1 )
599 if ( i1 != i0 )
600 {
601 Area1 = Area0 + pGate1->Area;
602 if ( pMan->tAreaMax > 0.0 && Area1 > pMan->tAreaMax )
603 break;
604 pSupers[1] = pGate1; uTruths[1][0] = pGate1->uTruth[0]; uTruths[1][1] = pGate1->uTruth[1]; ptPinDelays[1] = pGate1->ptDelays;
605
606 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i2, pGate2 )
607 if ( i2 != i0 && i2 != i1 )
608 {
609 Area2 = Area1 + pGate2->Area;
610 if ( pMan->tAreaMax > 0.0 && Area2 > pMan->tAreaMax )
611 break;
612 pSupers[2] = pGate2; uTruths[2][0] = pGate2->uTruth[0]; uTruths[2][1] = pGate2->uTruth[1]; ptPinDelays[2] = pGate2->ptDelays;
613
614 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i3, pGate3 )
615 if ( i3 != i0 && i3 != i1 && i3 != i2 )
616 {
617 Area3 = Area2 + pGate3->Area;
618 if ( pMan->tAreaMax > 0.0 && Area3 > pMan->tAreaMax )
619 break;
620 pSupers[3] = pGate3; uTruths[3][0] = pGate3->uTruth[0]; uTruths[3][1] = pGate3->uTruth[1]; ptPinDelays[3] = pGate3->ptDelays;
621
622 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i4, pGate4 )
623 if ( i4 != i0 && i4 != i1 && i4 != i2 && i4 != i3 )
624 {
625 if ( fTimeOut ) goto done;
626 fTimeOut = Super_CheckTimeout( pProgress, pMan );
627 // compute area
628 Area = Area3 + pGate4->Area;
629 if ( pMan->tAreaMax > 0.0 && Area > pMan->tAreaMax )
630 break;
631 pSupers[4] = pGate4; uTruths[4][0] = pGate4->uTruth[0]; uTruths[4][1] = pGate4->uTruth[1]; ptPinDelays[4] = pGate4->ptDelays;
632
633 Mio_DeriveGateDelays( ppGates[k], ptPinDelays, nFanins, pMan->nVarsMax, SUPER_NO_VAR, tPinDelaysRes, &tPinDelayMax );
634 Mio_DeriveTruthTable( ppGates[k], uTruths, nFanins, pMan->nVarsMax, uTruth );
635 if ( !Super_CompareGates( pMan, uTruth, Area, tPinDelaysRes, pMan->nVarsMax ) )
636 continue;
637 // create a new gate
638 pGateNew = Super_CreateGateNew( pMan, ppGates[k], pSupers, nFanins, uTruth, Area, tPinDelaysRes, tPinDelayMax, pMan->nVarsMax );
639 Super_AddGateToTable( pMan, pGateNew );
640 if ( nGatesMax && pMan->nClasses > nGatesMax )
641 goto done;
642 }
643 }
644 }
645 }
646 }
647 break;
648 case 6: // six-input root gate
649 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i0, pGate0 )
650 {
651 Area0 = AreaMio + pGate0->Area;
652 if ( pMan->tAreaMax > 0.0 && Area0 > pMan->tAreaMax )
653 break;
654 pSupers[0] = pGate0; uTruths[0][0] = pGate0->uTruth[0]; uTruths[0][1] = pGate0->uTruth[1]; ptPinDelays[0] = pGate0->ptDelays;
655
656 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i1, pGate1 )
657 if ( i1 != i0 )
658 {
659 Area1 = Area0 + pGate1->Area;
660 if ( pMan->tAreaMax > 0.0 && Area1 > pMan->tAreaMax )
661 break;
662 pSupers[1] = pGate1; uTruths[1][0] = pGate1->uTruth[0]; uTruths[1][1] = pGate1->uTruth[1]; ptPinDelays[1] = pGate1->ptDelays;
663
664 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i2, pGate2 )
665 if ( i2 != i0 && i2 != i1 )
666 {
667 Area2 = Area1 + pGate2->Area;
668 if ( pMan->tAreaMax > 0.0 && Area2 > pMan->tAreaMax )
669 break;
670 pSupers[2] = pGate2; uTruths[2][0] = pGate2->uTruth[0]; uTruths[2][1] = pGate2->uTruth[1]; ptPinDelays[2] = pGate2->ptDelays;
671
672 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i3, pGate3 )
673 if ( i3 != i0 && i3 != i1 && i3 != i2 )
674 {
675 Area3 = Area2 + pGate3->Area;
676 if ( pMan->tAreaMax > 0.0 && Area3 > pMan->tAreaMax )
677 break;
678 pSupers[3] = pGate3; uTruths[3][0] = pGate3->uTruth[0]; uTruths[3][1] = pGate3->uTruth[1]; ptPinDelays[3] = pGate3->ptDelays;
679
680 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i4, pGate4 )
681 if ( i4 != i0 && i4 != i1 && i4 != i2 && i4 != i3 )
682 {
683 if ( fTimeOut ) break;
684 fTimeOut = Super_CheckTimeout( pProgress, pMan );
685 // compute area
686 Area4 = Area3 + pGate4->Area;
687 if ( pMan->tAreaMax > 0.0 && Area > pMan->tAreaMax )
688 break;
689 pSupers[4] = pGate4; uTruths[4][0] = pGate4->uTruth[0]; uTruths[4][1] = pGate4->uTruth[1]; ptPinDelays[4] = pGate4->ptDelays;
690
691 Super_ManForEachGate( ppGatesLimit, nGatesLimit, i5, pGate5 )
692 if ( i5 != i0 && i5 != i1 && i5 != i2 && i5 != i3 && i5 != i4 )
693 {
694 if ( fTimeOut ) goto done;
695 fTimeOut = Super_CheckTimeout( pProgress, pMan );
696 // compute area
697 Area = Area4 + pGate5->Area;
698 if ( pMan->tAreaMax > 0.0 && Area > pMan->tAreaMax )
699 break;
700 pSupers[5] = pGate5; uTruths[5][0] = pGate5->uTruth[0]; uTruths[5][1] = pGate5->uTruth[1]; ptPinDelays[5] = pGate5->ptDelays;
701
702 Mio_DeriveGateDelays( ppGates[k], ptPinDelays, nFanins, pMan->nVarsMax, SUPER_NO_VAR, tPinDelaysRes, &tPinDelayMax );
703 Mio_DeriveTruthTable( ppGates[k], uTruths, nFanins, pMan->nVarsMax, uTruth );
704 if ( !Super_CompareGates( pMan, uTruth, Area, tPinDelaysRes, pMan->nVarsMax ) )
705 continue;
706 // create a new gate
707 pGateNew = Super_CreateGateNew( pMan, ppGates[k], pSupers, nFanins, uTruth, Area, tPinDelaysRes, tPinDelayMax, pMan->nVarsMax );
708 Super_AddGateToTable( pMan, pGateNew );
709 if ( nGatesMax && pMan->nClasses > nGatesMax )
710 goto done;
711 }
712 }
713 }
714 }
715 }
716 }
717 break;
718 default :
719 assert( 0 );
720 break;
721 }
722 }
723done:
724 Extra_ProgressBarStop( pProgress );
725 ABC_FREE( ppGatesLimit );
726 return pMan;
727}
728
740int Super_CheckTimeout( ProgressBar * pPro, Super_Man_t * pMan )
741{
742 abctime TimeNow = Abc_Clock();
743 if ( TimeNow > pMan->TimePrint )
744 {
745 Extra_ProgressBarUpdate( pPro, ++pMan->TimeSec, NULL );
746 pMan->TimePrint = Abc_Clock() + CLOCKS_PER_SEC;
747 }
748 if ( pMan->TimeStop && TimeNow > pMan->TimeStop )
749 {
750 printf ("Timeout!\n");
751 return 1;
752 }
753 pMan->nTried++;
754 return 0;
755}
756
757
769void Super_TranferGatesToArray( Super_Man_t * pMan )
770{
771 stmm_generator * gen;
772 Super_Gate_t * pGate, * pList;
773 ABC_PTRUINT_T Key;
774
775 // put the gates fron the table into the array
776 ABC_FREE( pMan->pGates );
777 pMan->pGates = ABC_ALLOC( Super_Gate_t *, pMan->nAdded );
778 pMan->nGates = 0;
779 stmm_foreach_item( pMan->tTable, gen, (char **)&Key, (char **)&pList )
780 {
781 for ( pGate = pList; pGate; pGate = pGate->pNext )
782 pMan->pGates[ pMan->nGates++ ] = pGate;
783 }
784// assert( pMan->nGates == pMan->nAdded - pMan->nRemoved );
785}
786
798void Super_AddGateToTable( Super_Man_t * pMan, Super_Gate_t * pGate )
799{
800 Super_Gate_t ** ppList;
801 ABC_PTRUINT_T Key;
802// Key = pGate->uTruth[0] + 2003 * pGate->uTruth[1];
803 Key = pGate->uTruth[0] ^ pGate->uTruth[1];
804 if ( !stmm_find_or_add( pMan->tTable, (char *)Key, (char ***)&ppList ) )
805 {
806 *ppList = NULL;
807 pMan->nClasses++;
808 }
809 pGate->pNext = *ppList;
810 *ppList = pGate;
811 pMan->nAdded++;
812}
813
827int Super_CompareGates( Super_Man_t * pMan, unsigned uTruth[], float Area, float tPinDelaysRes[], int nPins )
828{
829 Super_Gate_t ** ppList, * pPrev, * pGate, * pGate2;
830 int i, fNewIsBetter, fGateIsBetter;
831 ABC_PTRUINT_T Key;
832
833 // skip constant functions
834 if ( pMan->nVarsMax < 6 )
835 {
836 if ( uTruth[0] == 0 || ~uTruth[0] == 0 )
837 return 0;
838 }
839 else
840 {
841 if ( ( uTruth[0] == 0 && uTruth[1] == 0 ) || ( ~uTruth[0] == 0 && ~uTruth[1] == 0 ) )
842 return 0;
843 }
844
845 // get hold of the place where the entry is stored
846// Key = uTruth[0] + 2003 * uTruth[1];
847 Key = uTruth[0] ^ uTruth[1];
848 if ( !stmm_find( pMan->tTable, (char *)Key, (char ***)&ppList ) )
849 return 1;
850 // the entry with this truth table is found
851 pPrev = NULL;
852 for ( pGate = *ppList, pGate2 = pGate? pGate->pNext: NULL; pGate;
853 pGate = pGate2, pGate2 = pGate? pGate->pNext: NULL )
854 {
855 pMan->nLookups++;
856 if ( pGate->uTruth[0] != uTruth[0] || pGate->uTruth[1] != uTruth[1] )
857 {
858 pMan->nAliases++;
859 continue;
860 }
861 fGateIsBetter = 0;
862 fNewIsBetter = 0;
863 if ( pGate->Area + SUPER_EPSILON < Area )
864 fGateIsBetter = 1;
865 else if ( pGate->Area > Area + SUPER_EPSILON )
866 fNewIsBetter = 1;
867 for ( i = 0; i < nPins; i++ )
868 {
869 if ( pGate->ptDelays[i] == SUPER_NO_VAR || tPinDelaysRes[i] == SUPER_NO_VAR )
870 continue;
871 if ( pGate->ptDelays[i] + SUPER_EPSILON < tPinDelaysRes[i] )
872 fGateIsBetter = 1;
873 else if ( pGate->ptDelays[i] > tPinDelaysRes[i] + SUPER_EPSILON )
874 fNewIsBetter = 1;
875 if ( fGateIsBetter && fNewIsBetter )
876 break;
877 }
878 // consider 4 cases
879 if ( fGateIsBetter && fNewIsBetter ) // Pareto points; save both
880 pPrev = pGate;
881 else if ( fNewIsBetter ) // gate is worse; remove the gate
882 {
883 if ( pPrev == NULL )
884 *ppList = pGate->pNext;
885 else
886 pPrev->pNext = pGate->pNext;
887 Extra_MmFixedEntryRecycle( pMan->pMem, (char *)pGate );
888 pMan->nRemoved++;
889 }
890 else if ( fGateIsBetter ) // new is worse, already dominated no need to see others
891 return 0;
892 else // if ( !fGateIsBetter && !fNewIsBetter ) // they are identical, no need to see others
893 return 0;
894 }
895 return 1;
896}
897
898
910Super_Gate_t * Super_CreateGateNew( Super_Man_t * pMan, Mio_Gate_t * pRoot, Super_Gate_t ** pSupers, int nSupers,
911 unsigned uTruth[], float Area, float tPinDelaysRes[], float tDelayMax, int nPins )
912{
913 Super_Gate_t * pSuper;
914 pSuper = (Super_Gate_t *)Extra_MmFixedEntryFetch( pMan->pMem );
915 memset( pSuper, 0, sizeof(Super_Gate_t) );
916 pSuper->pRoot = pRoot;
917 pSuper->uTruth[0] = uTruth[0];
918 pSuper->uTruth[1] = uTruth[1];
919 memcpy( pSuper->ptDelays, tPinDelaysRes, sizeof(float) * nPins );
920 pSuper->Area = Area;
921 pSuper->nFanins = nSupers;
922 memcpy( pSuper->pFanins, pSupers, sizeof(Super_Gate_t *) * nSupers );
923 pSuper->pNext = NULL;
924 pSuper->tDelayMax = tDelayMax;
925 return pSuper;
926}
927
939Super_Man_t * Super_ManStart()
940{
941 Super_Man_t * pMan;
942 pMan = ABC_CALLOC( Super_Man_t, 1 );
943 pMan->pMem = Extra_MmFixedStart( sizeof(Super_Gate_t) );
945 return pMan;
946}
947
959void Super_ManStop( Super_Man_t * pMan )
960{
961 Extra_MmFixedStop( pMan->pMem );
962 if ( pMan->tTable ) stmm_free_table( pMan->tTable );
963 ABC_FREE( pMan->pGates );
964 ABC_FREE( pMan );
965}
966
967
968
969
970
982Vec_Str_t * Super_Write( Super_Man_t * pMan )
983{
984 Vec_Str_t * vStr;
985 Super_Gate_t * pGateRoot, * pGate;
986 stmm_generator * gen;
987 int fZeroFound, v;
988 abctime clk;
989 ABC_PTRUINT_T Key;
990
991 if ( pMan->nGates < 1 )
992 {
993 printf( "The generated library is empty. No output file written.\n" );
994 return NULL;
995 }
996
997 // Filters the supergates by removing those that have fewer inputs than
998 // the given limit, provided that the inputs are not consequtive.
999 // For example, NAND2(a,c) is removed, but NAND2(a,b) is left,
1000 // because a and b are consequtive.
1001 ABC_FREE( pMan->pGates );
1002 pMan->pGates = ABC_ALLOC( Super_Gate_t *, pMan->nAdded );
1003 pMan->nGates = 0;
1004 stmm_foreach_item( pMan->tTable, gen, (char **)&Key, (char **)&pGateRoot )
1005 {
1006 for ( pGate = pGateRoot; pGate; pGate = pGate->pNext )
1007 {
1008 // skip the elementary variables
1009 if ( pGate->pRoot == NULL )
1010 continue;
1011 // skip the non-consequtive gates
1012 fZeroFound = 0;
1013 for ( v = 0; v < pMan->nVarsMax; v++ )
1014 if ( pGate->ptDelays[v] < SUPER_NO_VAR + SUPER_EPSILON )
1015 fZeroFound = 1;
1016 else if ( fZeroFound )
1017 break;
1018 if ( v < pMan->nVarsMax )
1019 continue;
1020 // save the unique gate
1021 pMan->pGates[ pMan->nGates++ ] = pGate;
1022 }
1023 }
1024
1025clk = Abc_Clock();
1026 // sort the supergates by truth table
1027 qsort( (void *)pMan->pGates, (size_t)pMan->nGates, sizeof(Super_Gate_t *),
1028 (int (*)(const void *, const void *)) Super_WriteCompare );
1029 assert( Super_WriteCompare( pMan->pGates, pMan->pGates + pMan->nGates - 1 ) <= 0 );
1030if ( pMan->fVerbose )
1031{
1032ABC_PRT( "Sorting", Abc_Clock() - clk );
1033}
1034
1035
1036 // write library in the old format
1037clk = Abc_Clock();
1038 if ( pMan->fWriteOldFormat )
1039 Super_WriteLibrary( pMan );
1040if ( pMan->fVerbose )
1041{
1042ABC_PRT( "Writing old format", Abc_Clock() - clk );
1043}
1044
1045 // write the tree-like structure of supergates
1046clk = Abc_Clock();
1047 vStr = Super_WriteLibraryTreeStr( pMan );
1048if ( pMan->fVerbose )
1049{
1050ABC_PRT( "Writing new format", Abc_Clock() - clk );
1051}
1052 return vStr;
1053}
1054
1055
1067void Super_WriteFileHeader( Super_Man_t * pMan, FILE * pFile )
1068{
1069 fprintf( pFile, "#\n" );
1070 fprintf( pFile, "# Supergate library derived for \"%s\" on %s.\n", pMan->pName, Extra_TimeStamp() );
1071 fprintf( pFile, "#\n" );
1072 fprintf( pFile, "# Command line: \"super -I %d -L %d -N %d -T %d -D %.2f -A %.2f %s %s\".\n",
1073 pMan->nVarsMax, pMan->nLevels, pMan->nGatesMax, pMan->TimeLimit, pMan->tDelayMax, pMan->tAreaMax, (pMan->fSkipInv? "" : "-s"), pMan->pName );
1074 fprintf( pFile, "#\n" );
1075 fprintf( pFile, "# The number of inputs = %10d.\n", pMan->nVarsMax );
1076 fprintf( pFile, "# The number of levels = %10d.\n", pMan->nLevels );
1077 fprintf( pFile, "# The maximum delay = %10.2f.\n", pMan->tDelayMax );
1078 fprintf( pFile, "# The maximum area = %10.2f.\n", pMan->tAreaMax );
1079 fprintf( pFile, "# The maximum runtime (sec) = %10d.\n", pMan->TimeLimit );
1080 fprintf( pFile, "#\n" );
1081 fprintf( pFile, "# The number of attempts = %10d.\n", pMan->nTried );
1082 fprintf( pFile, "# The number of supergates = %10d.\n", pMan->nGates );
1083 fprintf( pFile, "# The number of functions = %10d.\n", pMan->nUnique );
1084 fprintf( pFile, "# The total functions = %.0f (2^%d).\n", pow((double)2,pMan->nMints), pMan->nMints );
1085 fprintf( pFile, "#\n" );
1086 fprintf( pFile, "# Generation time = %10.2f sec.\n", (float)(pMan->Time)/(float)(CLOCKS_PER_SEC) );
1087 fprintf( pFile, "#\n" );
1088 fprintf( pFile, "%s\n", pMan->pName );
1089 fprintf( pFile, "%d\n", pMan->nVarsMax );
1090 fprintf( pFile, "%d\n", pMan->nGates );
1091}
1093{
1094 char pBuffer[1000];
1095 sprintf( pBuffer, "#\n" );
1096 Vec_StrPrintStr( vStr, pBuffer );
1097 sprintf( pBuffer, "# Supergate library derived for \"%s\" on %s.\n", pMan->pName, Extra_TimeStamp() );
1098 Vec_StrPrintStr( vStr, pBuffer );
1099 sprintf( pBuffer, "#\n" );
1100 Vec_StrPrintStr( vStr, pBuffer );
1101 sprintf( pBuffer, "# Command line: \"super -I %d -L %d -N %d -T %d -D %.2f -A %.2f %s %s\".\n",
1102 pMan->nVarsMax, pMan->nLevels, pMan->nGatesMax, pMan->TimeLimit, pMan->tDelayMax, pMan->tAreaMax, (pMan->fSkipInv? "" : "-s"), pMan->pName );
1103 Vec_StrPrintStr( vStr, pBuffer );
1104 sprintf( pBuffer, "#\n" );
1105 Vec_StrPrintStr( vStr, pBuffer );
1106 sprintf( pBuffer, "# The number of inputs = %10d.\n", pMan->nVarsMax );
1107 Vec_StrPrintStr( vStr, pBuffer );
1108 sprintf( pBuffer, "# The number of levels = %10d.\n", pMan->nLevels );
1109 Vec_StrPrintStr( vStr, pBuffer );
1110 sprintf( pBuffer, "# The maximum delay = %10.2f.\n", pMan->tDelayMax );
1111 Vec_StrPrintStr( vStr, pBuffer );
1112 sprintf( pBuffer, "# The maximum area = %10.2f.\n", pMan->tAreaMax );
1113 Vec_StrPrintStr( vStr, pBuffer );
1114 sprintf( pBuffer, "# The maximum runtime (sec) = %10d.\n", pMan->TimeLimit );
1115 Vec_StrPrintStr( vStr, pBuffer );
1116 sprintf( pBuffer, "#\n" );
1117 Vec_StrPrintStr( vStr, pBuffer );
1118 sprintf( pBuffer, "# The number of attempts = %10d.\n", pMan->nTried );
1119 Vec_StrPrintStr( vStr, pBuffer );
1120 sprintf( pBuffer, "# The number of supergates = %10d.\n", pMan->nGates );
1121 Vec_StrPrintStr( vStr, pBuffer );
1122 sprintf( pBuffer, "# The number of functions = %10d.\n", pMan->nUnique );
1123 Vec_StrPrintStr( vStr, pBuffer );
1124 sprintf( pBuffer, "# The total functions = %.0f (2^%d).\n", pow((double)2,pMan->nMints), pMan->nMints );
1125 Vec_StrPrintStr( vStr, pBuffer );
1126 sprintf( pBuffer, "#\n" );
1127 Vec_StrPrintStr( vStr, pBuffer );
1128 sprintf( pBuffer, "# Generation time = %10.2f sec.\n", (float)(pMan->Time)/(float)(CLOCKS_PER_SEC) );
1129 Vec_StrPrintStr( vStr, pBuffer );
1130 sprintf( pBuffer, "#\n" );
1131 Vec_StrPrintStr( vStr, pBuffer );
1132 sprintf( pBuffer, "%s\n", pMan->pName );
1133 Vec_StrPrintStr( vStr, pBuffer );
1134 sprintf( pBuffer, "%d\n", pMan->nVarsMax );
1135 Vec_StrPrintStr( vStr, pBuffer );
1136 sprintf( pBuffer, "%d\n", pMan->nGates );
1137 Vec_StrPrintStr( vStr, pBuffer );
1138}
1139
1151int Super_WriteCompare( Super_Gate_t ** ppG1, Super_Gate_t ** ppG2 )
1152{
1153 unsigned * pTruth1 = (*ppG1)->uTruth;
1154 unsigned * pTruth2 = (*ppG2)->uTruth;
1155 if ( pTruth1[1] < pTruth2[1] )
1156 return -1;
1157 if ( pTruth1[1] > pTruth2[1] )
1158 return 1;
1159 if ( pTruth1[0] < pTruth2[0] )
1160 return -1;
1161 if ( pTruth1[0] > pTruth2[0] )
1162 return 1;
1163 return 0;
1164}
1165int Super_DelayCompare( Super_Gate_t ** ppG1, Super_Gate_t ** ppG2 )
1166{
1167 if ( (*ppG1)->tDelayMax < (*ppG2)->tDelayMax )
1168 return -1;
1169 if ( (*ppG1)->tDelayMax > (*ppG2)->tDelayMax )
1170 return 1;
1171 return 0;
1172}
1173int Super_AreaCompare( Super_Gate_t ** ppG1, Super_Gate_t ** ppG2 )
1174{
1175 if ( (*ppG1)->Area < (*ppG2)->Area )
1176 return -1;
1177 if ( (*ppG1)->Area > (*ppG2)->Area )
1178 return 1;
1179 return 0;
1180}
1181
1182
1183
1184
1185
1186
1198void Super_WriteLibraryGateName_rec( Super_Gate_t * pGate, char * pBuffer )
1199{
1200 char Buffer[10];
1201 int i;
1202
1203 if ( pGate->pRoot == NULL )
1204 {
1205 sprintf( Buffer, "%c", 'a' + pGate->Number );
1206 strcat( pBuffer, Buffer );
1207 return;
1208 }
1209 strcat( pBuffer, Mio_GateReadName(pGate->pRoot) );
1210 strcat( pBuffer, "(" );
1211 for ( i = 0; i < (int)pGate->nFanins; i++ )
1212 {
1213 if ( i )
1214 strcat( pBuffer, "," );
1215 Super_WriteLibraryGateName_rec( pGate->pFanins[i], pBuffer );
1216 }
1217 strcat( pBuffer, ")" );
1218}
1220{
1221 static char Buffer[2000];
1222 Buffer[0] = 0;
1223 Super_WriteLibraryGateName_rec( pGate, Buffer );
1224 return Buffer;
1225}
1226void Super_WriteLibraryGate( FILE * pFile, Super_Man_t * pMan, Super_Gate_t * pGate, int Num )
1227{
1228 int i;
1229 fprintf( pFile, "%04d ", Num ); // the number
1230 Extra_PrintBinary( pFile, pGate->uTruth, pMan->nMints ); // the truth table
1231 fprintf( pFile, " %5.2f", pGate->tDelayMax ); // the max delay
1232 fprintf( pFile, " " );
1233 for ( i = 0; i < pMan->nVarsMax; i++ ) // the pin-to-pin delays
1234 fprintf( pFile, " %5.2f", pGate->ptDelays[i]==SUPER_NO_VAR? 0.0 : pGate->ptDelays[i] );
1235 fprintf( pFile, " %5.2f", pGate->Area ); // the area
1236 fprintf( pFile, " " );
1237 fprintf( pFile, "%s", Super_WriteLibraryGateName(pGate) ); // the symbolic expression
1238 fprintf( pFile, "\n" );
1239}
1240void Super_WriteLibrary( Super_Man_t * pMan )
1241{
1242 Super_Gate_t * pGate, * pGateNext;
1243 FILE * pFile;
1244 char * FileName;
1245 char * pNameGeneric;
1246 int i, Counter;
1247
1248 FileName = ABC_ALLOC( char, 10000 );
1249
1250 // get the file name
1251 pNameGeneric = Extra_FileNameGeneric( pMan->pName );
1252 sprintf( FileName, "%s.super_old", pNameGeneric );
1253 ABC_FREE( pNameGeneric );
1254
1255 // count the number of unique functions
1256 pMan->nUnique = 1;
1257 Super_ManForEachGate( pMan->pGates, pMan->nGates, i, pGate )
1258 {
1259 if ( i == pMan->nGates - 1 )
1260 break;
1261 // print the newline if this gate is different from the following one
1262 pGateNext = pMan->pGates[i+1];
1263 if ( pGateNext->uTruth[0] != pGate->uTruth[0] || pGateNext->uTruth[1] != pGate->uTruth[1] )
1264 pMan->nUnique++;
1265 }
1266
1267 // start the file
1268 pFile = fopen( FileName, "w" );
1269 Super_WriteFileHeader( pMan, pFile );
1270
1271 // print the gates
1272 Counter = 0;
1273 Super_ManForEachGate( pMan->pGates, pMan->nGates, i, pGate )
1274 {
1275 Super_WriteLibraryGate( pFile, pMan, pGate, ++Counter );
1276 if ( i == pMan->nGates - 1 )
1277 break;
1278 // print the newline if this gate is different from the following one
1279 pGateNext = pMan->pGates[i+1];
1280 if ( pGateNext->uTruth[0] != pGate->uTruth[0] || pGateNext->uTruth[1] != pGate->uTruth[1] )
1281 fprintf( pFile, "\n" );
1282 }
1283 assert( Counter == pMan->nGates );
1284 fclose( pFile );
1285
1286 if ( pMan->fVerbose )
1287 {
1288 printf( "The supergates are written using old format \"%s\" ", FileName );
1289 printf( "(%0.3f MB).\n", ((double)Extra_FileSize(FileName))/(1<<20) );
1290 }
1291
1292 ABC_FREE( FileName );
1293}
1294
1295
1296
1297
1309void Super_WriteLibraryTreeFile_rec( FILE * pFile, Super_Man_t * pMan, Super_Gate_t * pSuper, int * pCounter )
1310{
1311 int nFanins, i;
1312 // skip an elementary variable and a gate that was already written
1313 if ( pSuper->fVar || pSuper->Number > 0 )
1314 return;
1315 // write the fanins
1316 nFanins = Mio_GateReadPinNum(pSuper->pRoot);
1317 for ( i = 0; i < nFanins; i++ )
1318 Super_WriteLibraryTreeFile_rec( pFile, pMan, pSuper->pFanins[i], pCounter );
1319 // finally write the gate
1320 pSuper->Number = (*pCounter)++;
1321 fprintf( pFile, "%s", pSuper->fSuper? "* " : "" );
1322 fprintf( pFile, "%s", Mio_GateReadName(pSuper->pRoot) );
1323 for ( i = 0; i < nFanins; i++ )
1324 fprintf( pFile, " %d", pSuper->pFanins[i]->Number );
1325 // write the formula
1326 // this step is optional, the resulting library will work in any case
1327 // however, it may be helpful to for debugging to compare the same library
1328 // written in the old format and written in the new format with formulas
1329// fprintf( pFile, " # %s", Super_WriteLibraryGateName( pSuper ) );
1330 fprintf( pFile, "\n" );
1331}
1332void Super_WriteLibraryTreeFile( Super_Man_t * pMan )
1333{
1334 Super_Gate_t * pSuper;
1335 FILE * pFile;
1336 char * FileName;
1337 char * pNameGeneric;
1338 int i, Counter;
1339 int posStart;
1340
1341 FileName = ABC_ALLOC( char, 10000 );
1342
1343 // get the file name
1344 pNameGeneric = Extra_FileNameGeneric( pMan->pName );
1345 sprintf( FileName, "%s.super", pNameGeneric );
1346 ABC_FREE( pNameGeneric );
1347
1348 // write the elementary variables
1349 pFile = fopen( FileName, "wb" );
1350 Super_WriteFileHeader( pMan, pFile );
1351 // write the place holder for the number of lines
1352 posStart = ftell( pFile );
1353 fprintf( pFile, " \n" );
1354 // mark the real supergates
1355 Super_ManForEachGate( pMan->pGates, pMan->nGates, i, pSuper )
1356 pSuper->fSuper = 1;
1357 // write the supergates
1358 Counter = pMan->nVarsMax;
1359 Super_ManForEachGate( pMan->pGates, pMan->nGates, i, pSuper )
1360 Super_WriteLibraryTreeFile_rec( pFile, pMan, pSuper, &Counter );
1361 fclose( pFile );
1362 // write the number of lines
1363 pFile = fopen( FileName, "rb+" );
1364 fseek( pFile, posStart, SEEK_SET );
1365 fprintf( pFile, "%d", Counter );
1366 fclose( pFile );
1367
1368if ( pMan->fVerbose )
1369{
1370 printf( "The supergates are written using new format \"%s\" ", FileName );
1371 printf( "(%0.3f MB).\n", ((double)Extra_FileSize(FileName))/(1<<20) );
1372}
1373
1374 ABC_FREE( FileName );
1375}
1376
1377
1389void Super_WriteLibraryTreeStr_rec( Vec_Str_t * vStr, Super_Man_t * pMan, Super_Gate_t * pSuper, int * pCounter )
1390{
1391 int nFanins, i;
1392 // skip an elementary variable and a gate that was already written
1393 if ( pSuper->fVar || pSuper->Number > 0 )
1394 return;
1395 // write the fanins
1396 nFanins = Mio_GateReadPinNum(pSuper->pRoot);
1397 for ( i = 0; i < nFanins; i++ )
1398 Super_WriteLibraryTreeStr_rec( vStr, pMan, pSuper->pFanins[i], pCounter );
1399 // finally write the gate
1400 pSuper->Number = (*pCounter)++;
1401// fprintf( pFile, "%s", pSuper->fSuper? "* " : "" );
1402// fprintf( pFile, "%s", Mio_GateReadName(pSuper->pRoot) );
1403// for ( i = 0; i < nFanins; i++ )
1404// fprintf( pFile, " %d", pSuper->pFanins[i]->Number );
1405 Vec_StrPrintStr( vStr, pSuper->fSuper? "* " : "" );
1406 Vec_StrPrintStr( vStr, Mio_GateReadName(pSuper->pRoot) );
1407 for ( i = 0; i < nFanins; i++ )
1408 {
1409 Vec_StrPrintStr( vStr, " " );
1410 Vec_StrPrintNum( vStr, pSuper->pFanins[i]->Number );
1411 }
1412 // write the formula
1413 // this step is optional, the resulting library will work in any case
1414 // however, it may be helpful to for debugging to compare the same library
1415 // written in the old format and written in the new format with formulas
1416// fprintf( pFile, " # %s", Super_WriteLibraryGateName( pSuper ) );
1417// fprintf( pFile, "\n" );
1418 Vec_StrPrintStr( vStr, "\n" );
1419}
1420Vec_Str_t * Super_WriteLibraryTreeStr( Super_Man_t * pMan )
1421{
1422 char pInsert[16];
1423 Vec_Str_t * vStr;
1424 Super_Gate_t * pSuper;
1425 int i, Counter;
1426 int posStart;
1427 // write the elementary variables
1428 vStr = Vec_StrAlloc( 1000 );
1429 Super_WriteFileHeaderStr( pMan, vStr );
1430 // write the place holder for the number of lines
1431 posStart = Vec_StrSize( vStr );
1432 for ( i = 0; i < 9; i++ )
1433 Vec_StrPush( vStr, ' ' );
1434 Vec_StrPush( vStr, '\n' );
1435 // mark the real supergates
1436 Super_ManForEachGate( pMan->pGates, pMan->nGates, i, pSuper )
1437 pSuper->fSuper = 1;
1438 // write the supergates
1439 Counter = pMan->nVarsMax;
1440 Super_ManForEachGate( pMan->pGates, pMan->nGates, i, pSuper )
1441 Super_WriteLibraryTreeStr_rec( vStr, pMan, pSuper, &Counter );
1442 Vec_StrPush( vStr, 0 );
1443 // write the number of lines
1444 sprintf( pInsert, "%d", Counter );
1445 for ( i = 0; i < (int)strlen(pInsert); i++ )
1446 Vec_StrWriteEntry( vStr, posStart + i, pInsert[i] );
1447 return vStr;
1448}
1450{
1451 Vec_Str_t * vStr;
1452 char * pFileName = Extra_FileNameGenericAppend( pMan->pName, ".super" );
1453 FILE * pFile = fopen( pFileName, "wb" );
1454 if ( pFile == NULL )
1455 {
1456 printf( "Cannot open output file \"%s\".\n", pFileName );
1457 return;
1458 }
1459 vStr = Super_WriteLibraryTreeStr( pMan );
1460 fwrite( Vec_StrArray(vStr), 1, Vec_StrSize(vStr), pFile );
1461 fclose( pFile );
1462 Vec_StrFree( vStr );
1463 // report the result of writing
1464 if ( pMan->fVerbose )
1465 {
1466 printf( "The supergates are written using new format \"%s\" ", pFileName );
1467 printf( "(%0.3f MB).\n", ((double)Extra_FileSize(pFileName))/(1<<20) );
1468 }
1469}
1470
1474
1476
ABC_INT64_T abctime
Definition abc_global.h:332
#define ABC_PRT(a, t)
Definition abc_global.h:255
#define ABC_ALLOC(type, num)
Definition abc_global.h:264
#define ABC_CALLOC(type, num)
Definition abc_global.h:265
#define ABC_FREE(obj)
Definition abc_global.h:267
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
struct Vec_Str_t_ Vec_Str_t
Definition bblif.c:46
ABC_NAMESPACE_IMPL_START typedef char ProgressBar
Definition bbrNtbdd.c:27
int Extra_FileSize(char *pFileName)
char * Extra_MmFixedEntryFetch(Extra_MmFixed_t *p)
void Extra_ProgressBarStop(ProgressBar *p)
void Extra_MmFixedStop(Extra_MmFixed_t *p)
Extra_MmFixed_t * Extra_MmFixedStart(int nEntrySize)
struct Extra_MmFixed_t_ Extra_MmFixed_t
Definition extra.h:147
char * Extra_TimeStamp()
void Extra_MmFixedEntryRecycle(Extra_MmFixed_t *p, char *pEntry)
char * Extra_FileNameGenericAppend(char *pBase, char *pSuffix)
char * Extra_FileNameGeneric(char *FileName)
ProgressBar * Extra_ProgressBarStart(FILE *pFile, int nItemsTotal)
FUNCTION DEFINITIONS ///.
struct Extra_MmFlex_t_ Extra_MmFlex_t
Definition extra.h:148
void Extra_PrintBinary(FILE *pFile, unsigned Sign[], int nBits)
int Mio_GateReadPinNum(Mio_Gate_t *pGate)
Definition mioApi.c:177
Mio_Gate_t ** Mio_CollectRoots(Mio_Library_t *pLib, int nInputs, float tDelay, int fSkipInv, int *pnGates, int fVerbose)
Definition mioUtils.c:515
char * Mio_LibraryReadName(Mio_Library_t *pLib)
DECLARATIONS ///.
Definition mioApi.c:43
void Mio_DeriveTruthTable(Mio_Gate_t *pGate, unsigned uTruthsIn[][2], int nSigns, int nInputs, unsigned uTruthRes[])
Definition mioUtils.c:1036
double Mio_GateReadArea(Mio_Gate_t *pGate)
Definition mioApi.c:171
struct Mio_LibraryStruct_t_ Mio_Library_t
Definition mio.h:42
void Mio_DeriveGateDelays(Mio_Gate_t *pGate, float **ptPinDelays, int nPins, int nInputs, float tDelayZero, float *ptDelaysRes, float *ptPinDelayMax)
Definition mioUtils.c:1153
char * Mio_GateReadName(Mio_Gate_t *pGate)
Definition mioApi.c:169
struct Mio_GateStruct_t_ Mio_Gate_t
Definition mio.h:43
double Mio_GateReadDelayMax(Mio_Gate_t *pGate)
Definition mioApi.c:178
int st__ptrhash(const char *, int)
Definition st.c:467
int st__ptrcmp(const char *, const char *)
Definition st.c:479
int stmm_find_or_add(stmm_table *table, char *key, char ***slot)
Definition stmm.c:266
void stmm_free_table(stmm_table *table)
Definition stmm.c:79
int stmm_find(stmm_table *table, char *key, char ***slot)
Definition stmm.c:306
stmm_table * stmm_init_table(stmm_compare_func_type compare, stmm_hash_func_type hash)
Definition stmm.c:69
#define stmm_foreach_item(table, gen, key, value)
Definition stmm.h:121
unsigned uTruth[2]
Definition superGate.c:87
Super_Gate_t * pNext
Definition superGate.c:92
Super_Gate_t * pFanins[6]
Definition superGate.c:88
Mio_Gate_t * pRoot
Definition superGate.c:82
Super_Gate_t * pInputs[10]
Definition superGate.c:54
Extra_MmFlex_t * pMemFlex
Definition superGate.c:61
Super_Gate_t ** pGates
Definition superGate.c:56
stmm_table * tTable
Definition superGate.c:57
Extra_MmFixed_t * pMem
Definition superGate.c:60
void Super_WriteLibraryGate(FILE *pFile, Super_Man_t *pMan, Super_Gate_t *pGate, int Num)
Definition superGate.c:1226
char * Super_WriteLibraryGateName(Super_Gate_t *pGate)
Definition superGate.c:1219
void Super_WriteLibraryTreeFile_rec(FILE *pFile, Super_Man_t *pMan, Super_Gate_t *pSuper, int *pCounter)
Definition superGate.c:1309
struct Super_GateStruct_t_ Super_Gate_t
Definition superGate.c:37
#define Super_ManForEachGate(GateArray, Limit, Index, Gate)
Definition superGate.c:97
void Super_WriteLibraryGateName_rec(Super_Gate_t *pGate, char *pBuffer)
Definition superGate.c:1198
void Super_WriteLibraryTreeStr_rec(Vec_Str_t *vStr, Super_Man_t *pMan, Super_Gate_t *pSuper, int *pCounter)
Definition superGate.c:1389
#define SUPER_EPSILON
Definition superGate.c:33
void Super_WriteLibraryTree(Super_Man_t *pMan)
Definition superGate.c:1449
struct Super_ManStruct_t_ Super_Man_t
Definition superGate.c:36
#define SUPER_NO_VAR
Definition superGate.c:32
void Super_Precompute(Mio_Library_t *pLibGen, int nVarsMax, int nLevels, int nGatesMax, float tDelayMax, float tAreaMax, int TimeLimit, int fSkipInv, int fVerbose, char *pFileName)
FUNCTION DEFINITIONS ///.
Definition superGate.c:140
void Super_WriteFileHeaderStr(Super_Man_t *pMan, Vec_Str_t *vStr)
Definition superGate.c:1092
Vec_Str_t * Super_PrecomputeStr(Mio_Library_t *pLibGen, int nVarsMax, int nLevels, int nGatesMax, float tDelayMax, float tAreaMax, int TimeLimit, int fSkipInv, int fVerbose)
Definition superGate.c:175
#define assert(ex)
Definition util_old.h:213
char * memcpy()
char * memset()
int strlen()
char * sprintf()
char * strcat()
#define SEEK_SET
Definition zconf.h:390