abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
cutPre22.c
Go to the documentation of this file.
1 /**CFile****************************************************************
2 
3  FileName [cutPre22.c]
4 
5  SystemName [ABC: Logic synthesis and verification system.]
6 
7  PackageName [Network and node package.]
8 
9  Synopsis [Precomputes truth tables for the 2x2 macro cell.]
10 
11  Author [Alan Mishchenko]
12 
13  Affiliation [UC Berkeley]
14 
15  Date [Ver. 1.0. Started - June 20, 2005.]
16 
17  Revision [$Id: cutPre22.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include "cutInt.h"
22 
24 
25 
26 ////////////////////////////////////////////////////////////////////////
27 /// DECLARATIONS ///
28 ////////////////////////////////////////////////////////////////////////
29 
30 #define CUT_CELL_MVAR 9
31 
32 typedef struct Cut_Cell_t_ Cut_Cell_t;
33 typedef struct Cut_CMan_t_ Cut_CMan_t;
34 
36 {
37  Cut_Cell_t * pNext; // pointer to the next cell in the table
38  Cut_Cell_t * pNextVar; // pointer to the next cell of this support size
39  Cut_Cell_t * pParent; // pointer to the cell used to derive this one
40  int nUsed; // the number of times the cell is used
41  char Box[4]; // functions in the boxes
42  unsigned nVars : 4; // the number of variables
43  unsigned CrossBar0 : 4; // the variable set equal
44  unsigned CrossBar1 : 4; // the variable set equal
45  unsigned CrossBarPhase : 2; // the phase of the cross bar (0, 1, or 2)
46  unsigned CanonPhase : 18; // the canonical phase
47  char CanonPerm[CUT_CELL_MVAR+3]; // semicanonical permutation
48  short Store[2*CUT_CELL_MVAR]; // minterm counts in the cofactors
49  unsigned uTruth[1<<(CUT_CELL_MVAR-5)]; // the current truth table
50 };
51 
53 {
54  // storage for canonical cells
58  // elementary truth tables
59  unsigned uInputs[CUT_CELL_MVAR][1<<(CUT_CELL_MVAR-5)];
60  // temporary truth tables
61  unsigned uTemp1[22][1<<(CUT_CELL_MVAR-5)];
62  unsigned uTemp2[22][1<<(CUT_CELL_MVAR-5)];
63  unsigned uTemp3[22][1<<(CUT_CELL_MVAR-5)];
64  unsigned uFinal[1<<(CUT_CELL_MVAR-5)];
65  unsigned puAux[1<<(CUT_CELL_MVAR-5)];
66  // statistical variables
67  int nTotal;
68  int nGood;
77 };
78 
79 // NP-classes of functions of 3 variables (22)
80 //static char * s_NP3[22] = {
81 // " 0\n", // 00 const 0 // 0 vars
82 // " 1\n", // 01 const 1 // 0 vars
83 // "1 1\n", // 02 a // 1 vars
84 // "11 1\n", // 03 ab // 2 vars
85 // "11 0\n", // 04 (ab)' // 2 vars
86 // "10 1\n01 1\n", // 05 a<+>b // 2 vars
87 // "111 1\n", // 06 0s abc // 3 vars
88 // "111 0\n", // 07 (abc)' //
89 // "11- 1\n1-1 1\n", // 08 1p a(b+c) //
90 // "11- 0\n1-1 0\n", // 09 (a(b+c))' //
91 // "111 1\n100 1\n010 1\n001 1\n", // 10 2s a<+>b<+>c //
92 // "10- 0\n1-0 0\n011 0\n", // 11 3p a<+>bc //
93 // "101 1\n110 1\n", // 12 4p a(b<+>c) //
94 // "101 0\n110 0\n", // 13 (a(b<+>c))' //
95 // "11- 1\n1-1 1\n-11 1\n", // 14 5s ab+bc+ac //
96 // "111 1\n000 1\n", // 15 6s abc+a'b'c' //
97 // "111 0\n000 0\n", // 16 (abc+a'b'c')' //
98 // "11- 1\n-11 1\n0-1 1\n", // 17 7 ab+bc+a'c //
99 // "011 1\n101 1\n110 1\n", // 18 8s a'bc+ab'c+abc' //
100 // "011 0\n101 0\n110 0\n", // 19 (a'bc+ab'c+abc')' //
101 // "100 1\n-11 1\n", // 20 9p ab'c'+bc //
102 // "100 0\n-11 0\n" // 21 (ab'c'+bc)' //
103 //};
104 
105 // NP-classes of functions of 3 variables (22)
106 static char * s_NP3Names[22] = {
107  " const 0 ",
108  " const 1 ",
109  " a ",
110  " ab ",
111  " (ab)' ",
112  " a<+>b ",
113  "0s abc ",
114  " (abc)' ",
115  "1p a(b+c) ",
116  " (a(b+c))' ",
117  "2s a<+>b<+>c ",
118  "3p a<+>bc ",
119  "4p a(b<+>c) ",
120  " (a(b<+>c))' ",
121  "5s ab+bc+ac ",
122  "6s abc+a'b'c' ",
123  " (abc+a'b'c')' ",
124  "7 ab+bc+a'c ",
125  "8s a'bc+ab'c+abc' ",
126  " (a'bc+ab'c+abc')' ",
127  "9p ab'c'+bc ",
128  " (ab'c'+bc)' "
129 };
130 
131 // the number of variables in each function
132 //static int s_NP3VarNums[22] = { 0, 0, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 };
133 
134 // NPN classes of functions of exactly 3 inputs (10)
135 static int s_NPNe3[10] = { 6, 8, 10, 11, 12, 14, 15, 17, 18, 20 };
136 
137 // NPN classes of functions of exactly 3 inputs that are symmetric (5)
138 //static int s_NPNe3s[10] = { 6, 10, 14, 15, 18 };
139 
140 // NPN classes of functions of exactly 3 inputs (4)
141 //static int s_NPNe3p[10] = { 8, 11, 12, 20 };
142 
143 static Cut_CMan_t * Cut_CManStart();
144 static void Cut_CManStop( Cut_CMan_t * p );
145 static void Cut_CellTruthElem( unsigned * InA, unsigned * InB, unsigned * InC, unsigned * pOut, int nVars, int Type );
146 static void Cut_CellCanonicize( Cut_CMan_t * p, Cut_Cell_t * pCell );
147 static int Cut_CellTableLookup( Cut_CMan_t * p, Cut_Cell_t * pCell );
148 static void Cut_CellSuppMin( Cut_Cell_t * pCell );
149 static void Cut_CellCrossBar( Cut_Cell_t * pCell );
150 
151 
152 static Cut_CMan_t * s_pCMan = NULL;
153 
154 ////////////////////////////////////////////////////////////////////////
155 /// FUNCTION DEFINITIONS ///
156 ////////////////////////////////////////////////////////////////////////
157 
158 /**Function*************************************************************
159 
160  Synopsis [Start the precomputation manager.]
161 
162  Description []
163 
164  SideEffects []
165 
166  SeeAlso []
167 
168 ***********************************************************************/
170 {
171  FILE * pFile;
172  char * pFileName = "cells22_daomap_iwls.txt";
173  char pString[1000];
174  Cut_CMan_t * p;
175  Cut_Cell_t * pCell;
176  int Length; //, i;
177  pFile = fopen( pFileName, "r" );
178  if ( pFile == NULL )
179  {
180  printf( "Cannot open file \"%s\".\n", pFileName );
181  return;
182  }
183  // start the manager
184  p = Cut_CManStart();
185  // load truth tables
186  while ( fgets(pString, 1000, pFile) )
187  {
188  Length = strlen(pString);
189  pString[Length--] = 0;
190  if ( Length == 0 )
191  continue;
192  // derive the cell
193  pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem );
194  memset( pCell, 0, sizeof(Cut_Cell_t) );
195  pCell->nVars = Abc_Base2Log(Length*4);
196  pCell->nUsed = 1;
197 // Extra_TruthCopy( pCell->uTruth, pTruth, nVars );
198  Extra_ReadHexadecimal( pCell->uTruth, pString, pCell->nVars );
199  Cut_CellSuppMin( pCell );
200 /*
201  // set the elementary permutation
202  for ( i = 0; i < (int)pCell->nVars; i++ )
203  pCell->CanonPerm[i] = i;
204  // canonicize
205  pCell->CanonPhase = Extra_TruthSemiCanonicize( pCell->uTruth, p->puAux, pCell->nVars, pCell->CanonPerm, pCell->Store );
206 */
207  // add to the table
208  p->nTotal++;
209 
210 // Extra_PrintHexadecimal( stdout, pCell->uTruth, pCell->nVars ); printf( "\n" );
211 // if ( p->nTotal == 500 )
212 // break;
213 
214  if ( !Cut_CellTableLookup( p, pCell ) ) // new cell
215  p->nGood++;
216  }
217  printf( "Read %d cells from file \"%s\". Added %d cells to the table.\n", p->nTotal, pFileName, p->nGood );
218  fclose( pFile );
219 // return p;
220 }
221 
222 /**Function*************************************************************
223 
224  Synopsis [Precomputes truth tables for the 2x2 macro cell.]
225 
226  Description []
227 
228  SideEffects []
229 
230  SeeAlso []
231 
232 ***********************************************************************/
234 {
235  Cut_CMan_t * p;
236  Cut_Cell_t * pCell, * pTemp;
237  int i1, i2, i3, i, j, k, c;
238  abctime clk = Abc_Clock(); //, clk2 = Abc_Clock();
239 
240  p = Cut_CManStart();
241 
242  // precompute truth tables
243  for ( i = 0; i < 22; i++ )
244  Cut_CellTruthElem( p->uInputs[0], p->uInputs[1], p->uInputs[2], p->uTemp1[i], 9, i );
245  for ( i = 0; i < 22; i++ )
246  Cut_CellTruthElem( p->uInputs[3], p->uInputs[4], p->uInputs[5], p->uTemp2[i], 9, i );
247  for ( i = 0; i < 22; i++ )
248  Cut_CellTruthElem( p->uInputs[6], p->uInputs[7], p->uInputs[8], p->uTemp3[i], 9, i );
249 /*
250  if ( k == 8 && ((i1 == 6 && i2 == 14 && i3 == 20) || (i1 == 20 && i2 == 6 && i3 == 14)) )
251  {
252  Extra_PrintBinary( stdout, &pCell->CanonPhase, pCell->nVars+1 ); printf( " : " );
253  for ( i = 0; i < pCell->nVars; i++ )
254  printf( "%d=%d/%d ", pCell->CanonPerm[i], pCell->Store[2*i], pCell->Store[2*i+1] );
255  Extra_PrintHexadecimal( stdout, pCell->uTruth, pCell->nVars );
256  printf( "\n" );
257  }
258 */
259 /*
260  // go through symmetric roots
261  for ( k = 0; k < 5; k++ )
262  for ( i1 = 0; i1 < 22; i1++ )
263  for ( i2 = i1; i2 < 22; i2++ )
264  for ( i3 = i2; i3 < 22; i3++ )
265  {
266  // derive the cell
267  pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem );
268  memset( pCell, 0, sizeof(Cut_Cell_t) );
269  pCell->nVars = 9;
270  pCell->Box[0] = s_NPNe3s[k];
271  pCell->Box[1] = i1;
272  pCell->Box[2] = i2;
273  pCell->Box[3] = i3;
274  // fill in the truth table
275  Cut_CellTruthElem( p->uTemp1[i1], p->uTemp2[i2], p->uTemp3[i3], pCell->uTruth, 9, s_NPNe3s[k] );
276  // canonicize
277  Cut_CellCanonicize( pCell );
278 
279  // add to the table
280  p->nTotal++;
281  if ( Cut_CellTableLookup( p, pCell ) ) // already exists
282  Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell );
283  else
284  p->nGood++;
285  }
286 
287  // go through partially symmetric roots
288  for ( k = 0; k < 4; k++ )
289  for ( i1 = 0; i1 < 22; i1++ )
290  for ( i2 = 0; i2 < 22; i2++ )
291  for ( i3 = i2; i3 < 22; i3++ )
292  {
293  // derive the cell
294  pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem );
295  memset( pCell, 0, sizeof(Cut_Cell_t) );
296  pCell->nVars = 9;
297  pCell->Box[0] = s_NPNe3p[k];
298  pCell->Box[1] = i1;
299  pCell->Box[2] = i2;
300  pCell->Box[3] = i3;
301  // fill in the truth table
302  Cut_CellTruthElem( p->uTemp1[i1], p->uTemp2[i2], p->uTemp3[i3], pCell->uTruth, 9, s_NPNe3p[k] );
303  // canonicize
304  Cut_CellCanonicize( pCell );
305 
306  // add to the table
307  p->nTotal++;
308  if ( Cut_CellTableLookup( p, pCell ) ) // already exists
309  Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell );
310  else
311  p->nGood++;
312  }
313 
314  // go through non-symmetric functions
315  for ( i1 = 0; i1 < 22; i1++ )
316  for ( i2 = 0; i2 < 22; i2++ )
317  for ( i3 = 0; i3 < 22; i3++ )
318  {
319  // derive the cell
320  pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem );
321  memset( pCell, 0, sizeof(Cut_Cell_t) );
322  pCell->nVars = 9;
323  pCell->Box[0] = 17;
324  pCell->Box[1] = i1;
325  pCell->Box[2] = i2;
326  pCell->Box[3] = i3;
327  // fill in the truth table
328  Cut_CellTruthElem( p->uTemp1[i1], p->uTemp2[i2], p->uTemp3[i3], pCell->uTruth, 9, 17 );
329  // canonicize
330  Cut_CellCanonicize( pCell );
331 
332  // add to the table
333  p->nTotal++;
334  if ( Cut_CellTableLookup( p, pCell ) ) // already exists
335  Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell );
336  else
337  p->nGood++;
338  }
339 */
340 
341  // go through non-symmetric functions
342  for ( k = 0; k < 10; k++ )
343  for ( i1 = 0; i1 < 22; i1++ )
344  for ( i2 = 0; i2 < 22; i2++ )
345  for ( i3 = 0; i3 < 22; i3++ )
346  {
347  // derive the cell
348  pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem );
349  memset( pCell, 0, sizeof(Cut_Cell_t) );
350  pCell->nVars = 9;
351  pCell->Box[0] = s_NPNe3[k];
352  pCell->Box[1] = i1;
353  pCell->Box[2] = i2;
354  pCell->Box[3] = i3;
355  // set the elementary permutation
356  for ( i = 0; i < (int)pCell->nVars; i++ )
357  pCell->CanonPerm[i] = i;
358  // fill in the truth table
359  Cut_CellTruthElem( p->uTemp1[i1], p->uTemp2[i2], p->uTemp3[i3], pCell->uTruth, 9, s_NPNe3[k] );
360  // minimize the support
361  Cut_CellSuppMin( pCell );
362 
363  // canonicize
364  pCell->CanonPhase = Extra_TruthSemiCanonicize( pCell->uTruth, p->puAux, pCell->nVars, pCell->CanonPerm, pCell->Store );
365 
366  // add to the table
367  p->nTotal++;
368  if ( Cut_CellTableLookup( p, pCell ) ) // already exists
369  Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell );
370  else
371  {
372  p->nGood++;
373  p->nVarCounts[pCell->nVars]++;
374 
375  if ( pCell->nVars )
376  for ( i = 0; i < (int)pCell->nVars-1; i++ )
377  {
378  if ( pCell->Store[2*i] != pCell->Store[2*(i+1)] ) // i and i+1 cannot be symmetric
379  continue;
380  // i and i+1 can be symmetric
381  // find the end of this group
382  for ( j = i+1; j < (int)pCell->nVars; j++ )
383  if ( pCell->Store[2*i] != pCell->Store[2*j] )
384  break;
385 
386  if ( pCell->Store[2*i] == pCell->Store[2*i+1] )
387  p->nSymGroupsE[j-i]++;
388  else
389  p->nSymGroups[j-i]++;
390  i = j - 1;
391  }
392 /*
393  if ( pCell->nVars == 3 )
394  {
395  Extra_PrintBinary( stdout, pCell->uTruth, 32 ); printf( "\n" );
396  for ( i = 0; i < (int)pCell->nVars; i++ )
397  printf( "%d=%d/%d ", pCell->CanonPerm[i], pCell->Store[2*i], pCell->Store[2*i+1] );
398  printf( "\n" );
399  }
400 */
401  }
402  }
403 
404  printf( "BASIC: Total = %d. Good = %d. Entry = %d. ", (int)p->nTotal, (int)p->nGood, (int)sizeof(Cut_Cell_t) );
405  ABC_PRT( "Time", Abc_Clock() - clk );
406  printf( "Cells: " );
407  for ( i = 0; i <= 9; i++ )
408  printf( "%d=%d ", i, p->nVarCounts[i] );
409  printf( "\nDiffs: " );
410  for ( i = 0; i <= 9; i++ )
411  printf( "%d=%d ", i, p->nSymGroups[i] );
412  printf( "\nEquals: " );
413  for ( i = 0; i <= 9; i++ )
414  printf( "%d=%d ", i, p->nSymGroupsE[i] );
415  printf( "\n" );
416 
417  // continue adding new cells using support
418  for ( k = CUT_CELL_MVAR; k > 3; k-- )
419  {
420  for ( pTemp = p->pSameVar[k]; pTemp; pTemp = pTemp->pNextVar )
421  for ( i1 = 0; i1 < k; i1++ )
422  for ( i2 = i1+1; i2 < k; i2++ )
423  for ( c = 0; c < 3; c++ )
424  {
425  // derive the cell
426  pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem );
427  memset( pCell, 0, sizeof(Cut_Cell_t) );
428  pCell->nVars = pTemp->nVars;
429  pCell->pParent = pTemp;
430  // set the elementary permutation
431  for ( i = 0; i < (int)pCell->nVars; i++ )
432  pCell->CanonPerm[i] = i;
433  // fill in the truth table
434  Extra_TruthCopy( pCell->uTruth, pTemp->uTruth, pTemp->nVars );
435  // create the cross-bar
436  pCell->CrossBar0 = i1;
437  pCell->CrossBar1 = i2;
438  pCell->CrossBarPhase = c;
439  Cut_CellCrossBar( pCell );
440  // minimize the support
441 //clk2 = Abc_Clock();
442  Cut_CellSuppMin( pCell );
443 //p->timeSupp += Abc_Clock() - clk2;
444  // canonicize
445 //clk2 = Abc_Clock();
446  pCell->CanonPhase = Extra_TruthSemiCanonicize( pCell->uTruth, p->puAux, pCell->nVars, pCell->CanonPerm, pCell->Store );
447 //p->timeCanon += Abc_Clock() - clk2;
448 
449  // add to the table
450 //clk2 = Abc_Clock();
451  p->nTotal++;
452  if ( Cut_CellTableLookup( p, pCell ) ) // already exists
453  Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell );
454  else
455  {
456  p->nGood++;
457  p->nVarCounts[pCell->nVars]++;
458 
459  for ( i = 0; i < (int)pCell->nVars-1; i++ )
460  {
461  if ( pCell->Store[2*i] != pCell->Store[2*(i+1)] ) // i and i+1 cannot be symmetric
462  continue;
463  // i and i+1 can be symmetric
464  // find the end of this group
465  for ( j = i+1; j < (int)pCell->nVars; j++ )
466  if ( pCell->Store[2*i] != pCell->Store[2*j] )
467  break;
468 
469  if ( pCell->Store[2*i] == pCell->Store[2*i+1] )
470  p->nSymGroupsE[j-i]++;
471  else
472  p->nSymGroups[j-i]++;
473  i = j - 1;
474  }
475 /*
476  if ( pCell->nVars == 3 )
477  {
478  Extra_PrintBinary( stdout, pCell->uTruth, 32 ); printf( "\n" );
479  for ( i = 0; i < (int)pCell->nVars; i++ )
480  printf( "%d=%d/%d ", pCell->CanonPerm[i], pCell->Store[2*i], pCell->Store[2*i+1] );
481  printf( "\n" );
482  }
483 */
484  }
485 //p->timeTable += Abc_Clock() - clk2;
486  }
487 
488  printf( "VAR %d: Total = %d. Good = %d. Entry = %d. ", k, p->nTotal, p->nGood, (int)sizeof(Cut_Cell_t) );
489  ABC_PRT( "Time", Abc_Clock() - clk );
490  printf( "Cells: " );
491  for ( i = 0; i <= 9; i++ )
492  printf( "%d=%d ", i, p->nVarCounts[i] );
493  printf( "\nDiffs: " );
494  for ( i = 0; i <= 9; i++ )
495  printf( "%d=%d ", i, p->nSymGroups[i] );
496  printf( "\nEquals: " );
497  for ( i = 0; i <= 9; i++ )
498  printf( "%d=%d ", i, p->nSymGroupsE[i] );
499  printf( "\n" );
500  }
501 // printf( "\n" );
502  ABC_PRT( "Supp ", p->timeSupp );
503  ABC_PRT( "Canon", p->timeCanon );
504  ABC_PRT( "Table", p->timeTable );
505 // Cut_CManStop( p );
506 }
507 
508 /**Function*************************************************************
509 
510  Synopsis [Check the table.]
511 
512  Description [Returns 1 if such a truth table already exists.]
513 
514  SideEffects []
515 
516  SeeAlso []
517 
518 ***********************************************************************/
520 {
521  Cut_Cell_t ** pSlot, * pTemp;
522  unsigned Hash;
523  Hash = Extra_TruthHash( pCell->uTruth, Extra_TruthWordNum( pCell->nVars ) );
524  if ( ! st__find_or_add( p->tTable, (char *)(ABC_PTRUINT_T)Hash, (char ***)&pSlot ) )
525  *pSlot = NULL;
526  for ( pTemp = *pSlot; pTemp; pTemp = pTemp->pNext )
527  {
528  if ( pTemp->nVars != pCell->nVars )
529  continue;
530  if ( Extra_TruthIsEqual(pTemp->uTruth, pCell->uTruth, pCell->nVars) )
531  return 1;
532  }
533  // the entry is new
534  pCell->pNext = *pSlot;
535  *pSlot = pCell;
536  // add it to the variable support list
537  pCell->pNextVar = p->pSameVar[pCell->nVars];
538  p->pSameVar[pCell->nVars] = pCell;
539  return 0;
540 }
541 
542 /**Function*************************************************************
543 
544  Synopsis []
545 
546  Description []
547 
548  SideEffects []
549 
550  SeeAlso []
551 
552 ***********************************************************************/
554 {
555  static unsigned uTemp[1<<(CUT_CELL_MVAR-5)];
556  unsigned * pIn, * pOut, * pTemp;
557  int i, k, Counter, Temp;
558 
559  // go backward through the support variables and remove redundant
560  for ( k = pCell->nVars - 1; k >= 0; k-- )
561  if ( !Extra_TruthVarInSupport(pCell->uTruth, pCell->nVars, k) )
562  {
563  // shift all the variables above this one
564  Counter = 0;
565  pIn = pCell->uTruth; pOut = uTemp;
566  for ( i = k; i < (int)pCell->nVars - 1; i++ )
567  {
568  Extra_TruthSwapAdjacentVars( pOut, pIn, pCell->nVars, i );
569  pTemp = pIn; pIn = pOut; pOut = pTemp;
570  // swap the support vars
571  Temp = pCell->CanonPerm[i];
572  pCell->CanonPerm[i] = pCell->CanonPerm[i+1];
573  pCell->CanonPerm[i+1] = Temp;
574  Counter++;
575  }
576  // return the function back into its place
577  if ( Counter & 1 )
578  Extra_TruthCopy( pOut, pIn, pCell->nVars );
579  // remove one variable
580  pCell->nVars--;
581 // Extra_PrintBinary( stdout, pCell->uTruth, (1<<pCell->nVars) ); printf( "\n" );
582  }
583 }
584 
585 /**Function*************************************************************
586 
587  Synopsis []
588 
589  Description []
590 
591  SideEffects []
592 
593  SeeAlso []
594 
595 ***********************************************************************/
597 {
598  static unsigned uTemp0[1<<(CUT_CELL_MVAR-5)];
599  static unsigned uTemp1[1<<(CUT_CELL_MVAR-5)];
600  Extra_TruthCopy( uTemp0, pCell->uTruth, pCell->nVars );
601  Extra_TruthCopy( uTemp1, pCell->uTruth, pCell->nVars );
602  if ( pCell->CanonPhase == 0 )
603  {
604  Extra_TruthCofactor0( uTemp0, pCell->nVars, pCell->CrossBar0 );
605  Extra_TruthCofactor0( uTemp0, pCell->nVars, pCell->CrossBar1 );
606  Extra_TruthCofactor1( uTemp1, pCell->nVars, pCell->CrossBar0 );
607  Extra_TruthCofactor1( uTemp1, pCell->nVars, pCell->CrossBar1 );
608  }
609  else if ( pCell->CanonPhase == 1 )
610  {
611  Extra_TruthCofactor1( uTemp0, pCell->nVars, pCell->CrossBar0 );
612  Extra_TruthCofactor0( uTemp0, pCell->nVars, pCell->CrossBar1 );
613  Extra_TruthCofactor0( uTemp1, pCell->nVars, pCell->CrossBar0 );
614  Extra_TruthCofactor1( uTemp1, pCell->nVars, pCell->CrossBar1 );
615  }
616  else if ( pCell->CanonPhase == 2 )
617  {
618  Extra_TruthCofactor0( uTemp0, pCell->nVars, pCell->CrossBar0 );
619  Extra_TruthCofactor1( uTemp0, pCell->nVars, pCell->CrossBar1 );
620  Extra_TruthCofactor1( uTemp1, pCell->nVars, pCell->CrossBar0 );
621  Extra_TruthCofactor0( uTemp1, pCell->nVars, pCell->CrossBar1 );
622  }
623  else assert( 0 );
624  Extra_TruthMux( pCell->uTruth, uTemp0, uTemp1, pCell->nVars, pCell->CrossBar0 );
625 }
626 
627 /**Function*************************************************************
628 
629  Synopsis []
630 
631  Description []
632 
633  SideEffects []
634 
635  SeeAlso []
636 
637 ***********************************************************************/
638 void Cut_CellTruthElem( unsigned * InA, unsigned * InB, unsigned * InC, unsigned * pOut, int nVars, int Type )
639 {
640  int nWords = Extra_TruthWordNum( nVars );
641  int i;
642 
643  assert( Type < 22 );
644  switch ( Type )
645  {
646  // " 0\n", // 00 const 0
647  case 0:
648  for ( i = 0; i < nWords; i++ )
649  pOut[i] = 0;
650  return;
651  // " 1\n", // 01 const 1
652  case 1:
653  for ( i = 0; i < nWords; i++ )
654  pOut[i] = 0xFFFFFFFF;
655  return;
656  // "1 1\n", // 02 a
657  case 2:
658  for ( i = 0; i < nWords; i++ )
659  pOut[i] = InA[i];
660  return;
661  // "11 1\n", // 03 ab
662  case 3:
663  for ( i = 0; i < nWords; i++ )
664  pOut[i] = InA[i] & InB[i];
665  return;
666  // "11 0\n", // 04 (ab)'
667  case 4:
668  for ( i = 0; i < nWords; i++ )
669  pOut[i] = ~(InA[i] & InB[i]);
670  return;
671  // "10 1\n01 1\n", // 05 a<+>b
672  case 5:
673  for ( i = 0; i < nWords; i++ )
674  pOut[i] = InA[i] ^ InB[i];
675  return;
676  // "111 1\n", // 06 + abc
677  case 6:
678  for ( i = 0; i < nWords; i++ )
679  pOut[i] = InA[i] & InB[i] & InC[i];
680  return;
681  // "111 0\n", // 07 (abc)'
682  case 7:
683  for ( i = 0; i < nWords; i++ )
684  pOut[i] = ~(InA[i] & InB[i] & InC[i]);
685  return;
686  // "11- 1\n1-1 1\n", // 08 + a(b+c)
687  case 8:
688  for ( i = 0; i < nWords; i++ )
689  pOut[i] = InA[i] & (InB[i] | InC[i]);
690  return;
691  // "11- 0\n1-1 0\n", // 09 (a(b+c))'
692  case 9:
693  for ( i = 0; i < nWords; i++ )
694  pOut[i] = ~(InA[i] & (InB[i] | InC[i]));
695  return;
696  // "111 1\n100 1\n010 1\n001 1\n", // 10 + a<+>b<+>c
697  case 10:
698  for ( i = 0; i < nWords; i++ )
699  pOut[i] = InA[i] ^ InB[i] ^ InC[i];
700  return;
701  // "10- 0\n1-0 0\n011 0\n", // 11 + a<+>bc
702  case 11:
703  for ( i = 0; i < nWords; i++ )
704  pOut[i] = InA[i] ^ (InB[i] & InC[i]);
705  return;
706  // "101 1\n110 1\n", // 12 + a(b<+>c)
707  case 12:
708  for ( i = 0; i < nWords; i++ )
709  pOut[i] = InA[i] & (InB[i] ^ InC[i]);
710  return;
711  // "101 0\n110 0\n", // 13 (a(b<+>c))'
712  case 13:
713  for ( i = 0; i < nWords; i++ )
714  pOut[i] = ~(InA[i] & (InB[i] ^ InC[i]));
715  return;
716  // "11- 1\n1-1 1\n-11 1\n", // 14 + ab+bc+ac
717  case 14:
718  for ( i = 0; i < nWords; i++ )
719  pOut[i] = (InA[i] & InB[i]) | (InB[i] & InC[i]) | (InA[i] & InC[i]);
720  return;
721  // "111 1\n000 1\n", // 15 + abc+a'b'c'
722  case 15:
723  for ( i = 0; i < nWords; i++ )
724  pOut[i] = (InA[i] & InB[i] & InC[i]) | (~InA[i] & ~InB[i] & ~InC[i]);
725  return;
726  // "111 0\n000 0\n", // 16 (abc+a'b'c')'
727  case 16:
728  for ( i = 0; i < nWords; i++ )
729  pOut[i] = ~((InA[i] & InB[i] & InC[i]) | (~InA[i] & ~InB[i] & ~InC[i]));
730  return;
731  // "11- 1\n-11 1\n0-1 1\n", // 17 + ab+bc+a'c
732  case 17:
733  for ( i = 0; i < nWords; i++ )
734  pOut[i] = (InA[i] & InB[i]) | (InB[i] & InC[i]) | (~InA[i] & InC[i]);
735  return;
736  // "011 1\n101 1\n110 1\n", // 18 + a'bc+ab'c+abc'
737  case 18:
738  for ( i = 0; i < nWords; i++ )
739  pOut[i] = (~InA[i] & InB[i] & InC[i]) | (InA[i] & ~InB[i] & InC[i]) | (InA[i] & InB[i] & ~InC[i]);
740  return;
741  // "011 0\n101 0\n110 0\n", // 19 (a'bc+ab'c+abc')'
742  case 19:
743  for ( i = 0; i < nWords; i++ )
744  pOut[i] = ~((~InA[i] & InB[i] & InC[i]) | (InA[i] & ~InB[i] & InC[i]) | (InA[i] & InB[i] & ~InC[i]));
745  return;
746  // "100 1\n-11 1\n", // 20 + ab'c'+bc
747  case 20:
748  for ( i = 0; i < nWords; i++ )
749  pOut[i] = (InA[i] & ~InB[i] & ~InC[i]) | (InB[i] & InC[i]);
750  return;
751  // "100 0\n-11 0\n" // 21 (ab'c'+bc)'
752  case 21:
753  for ( i = 0; i < nWords; i++ )
754  pOut[i] = ~((InA[i] & ~InB[i] & ~InC[i]) | (InB[i] & InC[i]));
755  return;
756  }
757 }
758 
759 
760 /**Function*************************************************************
761 
762  Synopsis [Start the precomputation manager.]
763 
764  Description []
765 
766  SideEffects []
767 
768  SeeAlso []
769 
770 ***********************************************************************/
772 {
773  Cut_CMan_t * p;
774  int i, k;
775  // start the manager
776  assert( sizeof(unsigned) == 4 );
777  p = ABC_ALLOC( Cut_CMan_t, 1 );
778  memset( p, 0, sizeof(Cut_CMan_t) );
779  // start the table and the memory manager
781  p->pMem = Extra_MmFixedStart( sizeof(Cut_Cell_t) );
782  // set elementary truth tables
783  for ( k = 0; k < CUT_CELL_MVAR; k++ )
784  for ( i = 0; i < (1<<CUT_CELL_MVAR); i++ )
785  if ( i & (1 << k) )
786  p->uInputs[k][i>>5] |= (1 << (i&31));
787  s_pCMan = p;
788  return p;
789 }
790 
791 /**Function*************************************************************
792 
793  Synopsis []
794 
795  Description []
796 
797  SideEffects []
798 
799  SeeAlso []
800 
801 ***********************************************************************/
803 {
804  st__free_table( p->tTable );
805  Extra_MmFixedStop( p->pMem );
806  ABC_FREE( p );
807 }
808 /**Function*************************************************************
809 
810  Synopsis []
811 
812  Description []
813 
814  SideEffects []
815 
816  SeeAlso []
817 
818 ***********************************************************************/
820 {
821  return s_pCMan != NULL;
822 }
823 
824 /**Function*************************************************************
825 
826  Synopsis []
827 
828  Description []
829 
830  SideEffects []
831 
832  SeeAlso []
833 
834 ***********************************************************************/
836 {
837  FILE * pFile;
838  Cut_CMan_t * p = s_pCMan;
839  Cut_Cell_t * pTemp;
840  char * pFileName = "celllib22.txt";
841  int NumUsed[10][5] = {{0}};
842  int BoxUsed[22][5] = {{0}};
843  int i, k, Counter;
844  abctime clk = Abc_Clock();
845 
846  if ( p == NULL )
847  {
848  printf( "Cut_CellDumpToFile: Cell manager is not defined.\n" );
849  return;
850  }
851 
852  // count the number of cells used
853  for ( k = CUT_CELL_MVAR; k >= 0; k-- )
854  {
855  for ( pTemp = p->pSameVar[k]; pTemp; pTemp = pTemp->pNextVar )
856  {
857  if ( pTemp->nUsed == 0 )
858  NumUsed[k][0]++;
859  else if ( pTemp->nUsed < 10 )
860  NumUsed[k][1]++;
861  else if ( pTemp->nUsed < 100 )
862  NumUsed[k][2]++;
863  else if ( pTemp->nUsed < 1000 )
864  NumUsed[k][3]++;
865  else
866  NumUsed[k][4]++;
867 
868  for ( i = 0; i < 4; i++ )
869  if ( pTemp->nUsed == 0 )
870  BoxUsed[ (int)pTemp->Box[i] ][0]++;
871  else if ( pTemp->nUsed < 10 )
872  BoxUsed[ (int)pTemp->Box[i] ][1]++;
873  else if ( pTemp->nUsed < 100 )
874  BoxUsed[ (int)pTemp->Box[i] ][2]++;
875  else if ( pTemp->nUsed < 1000 )
876  BoxUsed[ (int)pTemp->Box[i] ][3]++;
877  else
878  BoxUsed[ (int)pTemp->Box[i] ][4]++;
879  }
880  }
881 
882  printf( "Functions found = %10d. Functions not found = %10d.\n", p->nCellFound, p->nCellNotFound );
883  for ( k = 0; k <= CUT_CELL_MVAR; k++ )
884  {
885  printf( "%3d : ", k );
886  for ( i = 0; i < 5; i++ )
887  printf( "%8d ", NumUsed[k][i] );
888  printf( "\n" );
889  }
890  printf( "Box usage:\n" );
891  for ( k = 0; k < 22; k++ )
892  {
893  printf( "%3d : ", k );
894  for ( i = 0; i < 5; i++ )
895  printf( "%8d ", BoxUsed[k][i] );
896  printf( " %s", s_NP3Names[k] );
897  printf( "\n" );
898  }
899 
900  pFile = fopen( pFileName, "w" );
901  if ( pFile == NULL )
902  {
903  printf( "Cut_CellDumpToFile: Cannout open output file.\n" );
904  return;
905  }
906 
907  Counter = 0;
908  for ( k = 0; k <= CUT_CELL_MVAR; k++ )
909  {
910  for ( pTemp = p->pSameVar[k]; pTemp; pTemp = pTemp->pNextVar )
911  if ( pTemp->nUsed > 0 )
912  {
913  Extra_PrintHexadecimal( pFile, pTemp->uTruth, (k <= 5? 5 : k) );
914  fprintf( pFile, "\n" );
915  Counter++;
916  }
917  fprintf( pFile, "\n" );
918  }
919  fclose( pFile );
920 
921  printf( "Library composed of %d functions is written into file \"%s\". ", Counter, pFileName );
922 
923  ABC_PRT( "Time", Abc_Clock() - clk );
924 }
925 
926 
927 /**Function*************************************************************
928 
929  Synopsis [Looks up if the given function exists in the hash table.]
930 
931  Description [If the function exists, returns 1, meaning that it can be
932  implemented using two levels of 3-input LUTs. If the function does not
933  exist, return 0.]
934 
935  SideEffects []
936 
937  SeeAlso []
938 
939 ***********************************************************************/
940 int Cut_CellTruthLookup( unsigned * pTruth, int nVars )
941 {
942  Cut_CMan_t * p = s_pCMan;
943  Cut_Cell_t * pTemp;
944  Cut_Cell_t Cell, * pCell = &Cell;
945  unsigned Hash;
946  int i;
947 
948  // cell manager is not defined
949  if ( p == NULL )
950  {
951  printf( "Cut_CellTruthLookup: Cell manager is not defined.\n" );
952  return 0;
953  }
954 
955  // canonicize
956  memset( pCell, 0, sizeof(Cut_Cell_t) );
957  pCell->nVars = nVars;
958  Extra_TruthCopy( pCell->uTruth, pTruth, nVars );
959  Cut_CellSuppMin( pCell );
960  // set the elementary permutation
961  for ( i = 0; i < (int)pCell->nVars; i++ )
962  pCell->CanonPerm[i] = i;
963  // canonicize
964  pCell->CanonPhase = Extra_TruthSemiCanonicize( pCell->uTruth, p->puAux, pCell->nVars, pCell->CanonPerm, pCell->Store );
965 
966 
967  // check if the cell exists
968  Hash = Extra_TruthHash( pCell->uTruth, Extra_TruthWordNum(pCell->nVars) );
969  if ( st__lookup( p->tTable, (char *)(ABC_PTRUINT_T)Hash, (char **)&pTemp ) )
970  {
971  for ( ; pTemp; pTemp = pTemp->pNext )
972  {
973  if ( pTemp->nVars != pCell->nVars )
974  continue;
975  if ( Extra_TruthIsEqual(pTemp->uTruth, pCell->uTruth, pCell->nVars) )
976  {
977  pTemp->nUsed++;
978  p->nCellFound++;
979  return 1;
980  }
981  }
982  }
983  p->nCellNotFound++;
984  return 0;
985 }
986 
987 
988 ////////////////////////////////////////////////////////////////////////
989 /// END OF FILE ///
990 ////////////////////////////////////////////////////////////////////////
991 
992 
994 
char * memset()
unsigned CanonPhase
Definition: cutPre22.c:46
static void Cut_CellTruthElem(unsigned *InA, unsigned *InB, unsigned *InC, unsigned *pOut, int nVars, int Type)
Definition: cutPre22.c:638
int Cut_CellTruthLookup(unsigned *pTruth, int nVars)
Definition: cutPre22.c:940
void st__free_table(st__table *table)
Definition: st.c:81
void Cut_CellLoad()
FUNCTION DEFINITIONS ///.
Definition: cutPre22.c:169
Cut_Cell_t * pNext
Definition: cutPre22.c:37
void Extra_TruthMux(unsigned *pOut, unsigned *pCof0, unsigned *pCof1, int nVars, int iVar)
abctime timeTable
Definition: cutPre22.c:74
static void Cut_CellSuppMin(Cut_Cell_t *pCell)
Definition: cutPre22.c:553
unsigned CrossBarPhase
Definition: cutPre22.c:45
static Llb_Mgr_t * p
Definition: llb3Image.c:950
int nSymGroupsE[CUT_CELL_MVAR+1]
Definition: cutPre22.c:71
abctime timeCanon
Definition: cutPre22.c:72
void Extra_MmFixedStop(Extra_MmFixed_t *p)
int nUsed
Definition: cutPre22.c:40
Cut_Cell_t * pNextVar
Definition: cutPre22.c:38
int st__ptrcmp(const char *, const char *)
Definition: st.c:480
Extra_MmFixed_t * pMem
Definition: cutPre22.c:55
void Cut_CellPrecompute()
Definition: cutPre22.c:233
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
unsigned puAux[1<<(CUT_CELL_MVAR-5)]
Definition: cutPre22.c:65
int nCellFound
Definition: cutPre22.c:75
static abctime Abc_Clock()
Definition: abc_global.h:279
unsigned nVars
Definition: cutPre22.c:42
static char * s_NP3Names[22]
Definition: cutPre22.c:106
int nWords
Definition: abcNpn.c:127
char * Extra_MmFixedEntryFetch(Extra_MmFixed_t *p)
void Extra_TruthCofactor1(unsigned *pTruth, int nVars, int iVar)
abctime timeSupp
Definition: cutPre22.c:73
static Cut_CMan_t * s_pCMan
Definition: cutPre22.c:152
void Cut_CellDumpToFile()
Definition: cutPre22.c:835
st__table * st__init_table(st__compare_func_type compare, st__hash_func_type hash)
Definition: st.c:72
unsigned uTemp3[22][1<<(CUT_CELL_MVAR-5)]
Definition: cutPre22.c:63
#define CUT_CELL_MVAR
DECLARATIONS ///.
Definition: cutPre22.c:30
static int Cut_CellTableLookup(Cut_CMan_t *p, Cut_Cell_t *pCell)
Definition: cutPre22.c:519
unsigned Extra_TruthHash(unsigned *pIn, int nWords)
static int s_NPNe3[10]
Definition: cutPre22.c:135
int st__find_or_add(st__table *table, char *key, char ***slot)
Definition: st.c:230
unsigned uTemp1[22][1<<(CUT_CELL_MVAR-5)]
Definition: cutPre22.c:61
Definition: st.h:52
int nVarCounts[CUT_CELL_MVAR+1]
Definition: cutPre22.c:69
static void Cut_CellCanonicize(Cut_CMan_t *p, Cut_Cell_t *pCell)
unsigned CrossBar0
Definition: cutPre22.c:43
int nGood
Definition: cutPre22.c:68
st__table * tTable
Definition: cutPre22.c:56
Extra_MmFixed_t * Extra_MmFixedStart(int nEntrySize)
char Box[4]
Definition: cutPre22.c:41
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
if(last==0)
Definition: sparse_int.h:34
int nCellNotFound
Definition: cutPre22.c:76
static int Counter
unsigned uFinal[1<<(CUT_CELL_MVAR-5)]
Definition: cutPre22.c:64
int Extra_ReadHexadecimal(unsigned Sign[], char *pString, int nVars)
int nTotal
Definition: cutPre22.c:67
static void Cut_CManStop(Cut_CMan_t *p)
Definition: cutPre22.c:802
static int Extra_TruthWordNum(int nVars)
Definition: extra.h:249
static int Extra_TruthIsEqual(unsigned *pIn0, unsigned *pIn1, int nVars)
Definition: extra.h:270
static Cut_CMan_t * Cut_CManStart()
Definition: cutPre22.c:771
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
int st__lookup(st__table *table, const char *key, char **value)
Definition: st.c:114
int Extra_TruthVarInSupport(unsigned *pTruth, int nVars, int iVar)
unsigned uTemp2[22][1<<(CUT_CELL_MVAR-5)]
Definition: cutPre22.c:62
int Cut_CellIsRunning()
Definition: cutPre22.c:819
unsigned CrossBar1
Definition: cutPre22.c:44
#define ABC_FREE(obj)
Definition: abc_global.h:232
#define ABC_PRT(a, t)
Definition: abc_global.h:220
static int Abc_Base2Log(unsigned n)
Definition: abc_global.h:251
unsigned uInputs[CUT_CELL_MVAR][1<<(CUT_CELL_MVAR-5)]
Definition: cutPre22.c:59
void Extra_TruthSwapAdjacentVars(unsigned *pOut, unsigned *pIn, int nVars, int Start)
unsigned Extra_TruthSemiCanonicize(unsigned *pInOut, unsigned *pAux, int nVars, char *pCanonPerm, short *pStore)
short Store[2 *CUT_CELL_MVAR]
Definition: cutPre22.c:48
Cut_Cell_t * pParent
Definition: cutPre22.c:39
Cut_Cell_t * pSameVar[CUT_CELL_MVAR+1]
Definition: cutPre22.c:57
void Extra_TruthCofactor0(unsigned *pTruth, int nVars, int iVar)
#define assert(ex)
Definition: util_old.h:213
int strlen()
static void Cut_CellCrossBar(Cut_Cell_t *pCell)
Definition: cutPre22.c:596
void Extra_MmFixedEntryRecycle(Extra_MmFixed_t *p, char *pEntry)
unsigned uTruth[1<<(CUT_CELL_MVAR-5)]
Definition: cutPre22.c:49
void Extra_PrintHexadecimal(FILE *pFile, unsigned Sign[], int nVars)
ABC_INT64_T abctime
Definition: abc_global.h:278
int st__ptrhash(const char *, int)
Definition: st.c:468
char CanonPerm[CUT_CELL_MVAR+3]
Definition: cutPre22.c:47
static void Extra_TruthCopy(unsigned *pOut, unsigned *pIn, int nVars)
Definition: extra.h:302
int nSymGroups[CUT_CELL_MVAR+1]
Definition: cutPre22.c:70