abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
abcNpn.c
Go to the documentation of this file.
1 /**CFile****************************************************************
2 
3  FileName [abcNpn.c]
4 
5  SystemName [ABC: Logic synthesis and verification system.]
6 
7  PackageName [Network and node package.]
8 
9  Synopsis [Procedures for testing and comparing semi-canonical forms.]
10 
11  Author [Alan Mishchenko]
12 
13  Affiliation [UC Berkeley]
14 
15  Date [Ver. 1.0. Started - June 20, 2005.]
16 
17  Revision [$Id: abcNpn.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include "misc/extra/extra.h"
22 #include "misc/vec/vec.h"
23 
24 #include "bool/kit/kit.h"
25 #include "bool/lucky/lucky.h"
26 #include "opt/dau/dau.h"
27 
29 
30 
31 ////////////////////////////////////////////////////////////////////////
32 /// DECLARATIONS ///
33 ////////////////////////////////////////////////////////////////////////
34 
35 // semi-canonical form types
36 // 0 - none
37 // 1 - based on counting 1s in cofactors
38 // 2 - based on minimum truth table value
39 // 3 - exact NPN
40 
41 // data-structure to store a bunch of truth tables
43 struct Abc_TtStore_t_
44 {
45  int nVars;
46  int nWords;
47  int nFuncs;
48  word ** pFuncs;
49 };
50 
51 extern Abc_TtStore_t * Abc_TtStoreLoad( char * pFileName, int nVarNum );
52 extern void Abc_TtStoreFree( Abc_TtStore_t * p, int nVarNum );
53 extern void Abc_TtStoreWrite( char * pFileName, Abc_TtStore_t * p, int fBinary );
54 
55 ////////////////////////////////////////////////////////////////////////
56 /// FUNCTION DEFINITIONS ///
57 ////////////////////////////////////////////////////////////////////////
58 
59 /**Function*************************************************************
60 
61  Synopsis [Counts the number of unique truth tables.]
62 
63  Description []
64 
65  SideEffects []
66 
67  SeeAlso []
68 
69 ***********************************************************************/
70 // returns hash key of the truth table
71 static inline int Abc_TruthHashKey( word * pFunc, int nWords, int nTableSize )
72 {
73  static unsigned s_BigPrimes[7] = {12582917, 25165843, 50331653, 100663319, 201326611, 402653189, 805306457};
74  int w;
75  word Key = 0;
76  for ( w = 0; w < nWords; w++ )
77  Key += pFunc[w] * s_BigPrimes[w % 7];
78  return (int)(Key % nTableSize);
79 }
80 // returns 1 if the entry with this truth table exits
81 static inline int Abc_TruthHashLookup( word ** pFuncs, int iThis, int nWords, int * pTable, int * pNexts, int Key )
82 {
83  int iThat;
84  for ( iThat = pTable[Key]; iThat != -1; iThat = pNexts[iThat] )
85  if ( !memcmp( pFuncs[iThat], pFuncs[iThis], sizeof(word) * nWords ) )
86  return 1;
87  return 0;
88 }
89 // hashes truth tables and collects unique ones
91 {
92  // allocate hash table
93  int nTableSize = Abc_PrimeCudd(p->nFuncs);
94  int * pTable = ABC_FALLOC( int, nTableSize );
95  int * pNexts = ABC_FALLOC( int, nTableSize );
96  // hash functions
97  int i, k, Key;
98  for ( i = 0; i < p->nFuncs; i++ )
99  {
100  Key = Abc_TruthHashKey( p->pFuncs[i], p->nWords, nTableSize );
101  if ( Abc_TruthHashLookup( p->pFuncs, i, p->nWords, pTable, pNexts, Key ) ) // found equal
102  p->pFuncs[i] = NULL;
103  else // there is no equal (the first time this one occurs so far)
104  pNexts[i] = pTable[Key], pTable[Key] = i;
105  }
106  ABC_FREE( pTable );
107  ABC_FREE( pNexts );
108  // count the number of unqiue functions
109  assert( p->pFuncs[0] != NULL );
110  for ( i = k = 1; i < p->nFuncs; i++ )
111  if ( p->pFuncs[i] != NULL )
112  p->pFuncs[k++] = p->pFuncs[i];
113  return (p->nFuncs = k);
114 }
115 
116 /**Function*************************************************************
117 
118  Synopsis [Counts the number of unique truth tables.]
119 
120  Description []
121 
122  SideEffects []
123 
124  SeeAlso []
125 
126 ***********************************************************************/
127 int nWords = 0; // unfortunate global variable
128 int Abc_TruthCompare( word ** p1, word ** p2 ) { return memcmp(*p1, *p2, sizeof(word) * nWords); }
130 {
131  int i, k;
132  // sort them by value
133  nWords = p->nWords;
134  assert( nWords > 0 );
135  qsort( (void *)p->pFuncs, p->nFuncs, sizeof(word *), (int(*)(const void *,const void *))Abc_TruthCompare );
136  // count the number of unqiue functions
137  for ( i = k = 1; i < p->nFuncs; i++ )
138  if ( memcmp( p->pFuncs[i-1], p->pFuncs[i], sizeof(word) * nWords ) )
139  p->pFuncs[k++] = p->pFuncs[i];
140  return (p->nFuncs = k);
141 }
142 
143 /**Function*************************************************************
144 
145  Synopsis [Prints out one NPN transform.]
146 
147  Description []
148 
149  SideEffects []
150 
151  SeeAlso []
152 
153 ***********************************************************************/
154 void Abc_TruthNpnPrint( char * pCanonPermInit, unsigned uCanonPhase, int nVars )
155 {
156  char pCanonPerm[16]; int i;
157  assert( nVars <= 16 );
158  for ( i = 0; i < nVars; i++ )
159  pCanonPerm[i] = pCanonPermInit ? pCanonPermInit[i] : 'a' + i;
160  printf( " %c = ( ", Abc_InfoHasBit(&uCanonPhase, nVars) ? 'Z':'z' );
161  for ( i = 0; i < nVars; i++ )
162  printf( "%c%s", pCanonPerm[i] + ('A'-'a') * Abc_InfoHasBit(&uCanonPhase, pCanonPerm[i]-'a'), i == nVars-1 ? "":"," );
163  printf( " ) " );
164 }
165 
166 /**Function*************************************************************
167 
168  Synopsis [Apply decomposition to the truth table.]
169 
170  Description [Returns the number of AIG nodes.]
171 
172  SideEffects []
173 
174  SeeAlso []
175 
176 ***********************************************************************/
177 void Abc_TruthNpnPerform( Abc_TtStore_t * p, int NpnType, int fVerbose )
178 {
179  unsigned pAux[2048];
180  word pAuxWord[1024], pAuxWord1[1024];
181  char pCanonPerm[16];
182  unsigned uCanonPhase=0;
183  abctime clk = Abc_Clock();
184  int i;
185 
186  char * pAlgoName = NULL;
187  if ( NpnType == 0 )
188  pAlgoName = "uniqifying ";
189  else if ( NpnType == 1 )
190  pAlgoName = "exact NPN ";
191  else if ( NpnType == 2 )
192  pAlgoName = "counting 1s ";
193  else if ( NpnType == 3 )
194  pAlgoName = "Jake's hybrid fast ";
195  else if ( NpnType == 4 )
196  pAlgoName = "Jake's hybrid good ";
197  else if ( NpnType == 5 )
198  pAlgoName = "new hybrid fast ";
199  else if ( NpnType == 6 )
200  pAlgoName = "new phase flipping ";
201 
202  assert( p->nVars <= 16 );
203  if ( pAlgoName )
204  printf( "Applying %-20s to %8d func%s of %2d vars... ",
205  pAlgoName, p->nFuncs, (p->nFuncs == 1 ? "":"s"), p->nVars );
206  if ( fVerbose )
207  printf( "\n" );
208 
209  if ( NpnType == 0 )
210  {
211  for ( i = 0; i < p->nFuncs; i++ )
212  {
213  if ( fVerbose )
214  printf( "%7d : ", i );
215  if ( fVerbose )
216  Extra_PrintHex( stdout, (unsigned *)p->pFuncs[i], p->nVars ), printf( "\n" );
217  }
218  }
219  else if ( NpnType == 1 )
220  {
221  permInfo* pi;
223  pi = setPermInfoPtr(p->nVars);
224  for ( i = 0; i < p->nFuncs; i++ )
225  {
226  if ( fVerbose )
227  printf( "%7d : ", i );
228  simpleMinimal(p->pFuncs[i], pAuxWord, pAuxWord1, pi, p->nVars);
229  if ( fVerbose )
230  Extra_PrintHex( stdout, (unsigned *)p->pFuncs[i], p->nVars ), Abc_TruthNpnPrint(pCanonPerm, uCanonPhase, p->nVars), printf( "\n" );
231  }
232  freePermInfoPtr(pi);
233  }
234  else if ( NpnType == 2 )
235  {
236  for ( i = 0; i < p->nFuncs; i++ )
237  {
238  if ( fVerbose )
239  printf( "%7d : ", i );
240  resetPCanonPermArray(pCanonPerm, p->nVars);
241  uCanonPhase = Kit_TruthSemiCanonicize( (unsigned *)p->pFuncs[i], pAux, p->nVars, pCanonPerm );
242  if ( fVerbose )
243  Extra_PrintHex( stdout, (unsigned *)p->pFuncs[i], p->nVars ), Abc_TruthNpnPrint(pCanonPerm, uCanonPhase, p->nVars), printf( "\n" );
244  }
245  }
246  else if ( NpnType == 3 )
247  {
248  for ( i = 0; i < p->nFuncs; i++ )
249  {
250  if ( fVerbose )
251  printf( "%7d : ", i );
252  resetPCanonPermArray(pCanonPerm, p->nVars);
253  uCanonPhase = luckyCanonicizer_final_fast( p->pFuncs[i], p->nVars, pCanonPerm );
254  if ( fVerbose )
255  Extra_PrintHex( stdout, (unsigned *)p->pFuncs[i], p->nVars ), Abc_TruthNpnPrint(pCanonPerm, uCanonPhase, p->nVars), printf( "\n" );
256  }
257  }
258  else if ( NpnType == 4 )
259  {
260  for ( i = 0; i < p->nFuncs; i++ )
261  {
262  if ( fVerbose )
263  printf( "%7d : ", i );
264  resetPCanonPermArray(pCanonPerm, p->nVars);
265  uCanonPhase = luckyCanonicizer_final_fast1( p->pFuncs[i], p->nVars, pCanonPerm );
266  if ( fVerbose )
267  Extra_PrintHex( stdout, (unsigned *)p->pFuncs[i], p->nVars ), Abc_TruthNpnPrint(pCanonPerm, uCanonPhase, p->nVars), printf( "\n" );
268  }
269  }
270  else if ( NpnType == 5 )
271  {
272  for ( i = 0; i < p->nFuncs; i++ )
273  {
274  if ( fVerbose )
275  printf( "%7d : ", i );
276  uCanonPhase = Abc_TtCanonicize( p->pFuncs[i], p->nVars, pCanonPerm );
277  if ( fVerbose )
278  Extra_PrintHex( stdout, (unsigned *)p->pFuncs[i], p->nVars ), Abc_TruthNpnPrint(pCanonPerm, uCanonPhase, p->nVars), printf( "\n" );
279  }
280  }
281  else if ( NpnType == 6 )
282  {
283  for ( i = 0; i < p->nFuncs; i++ )
284  {
285  if ( fVerbose )
286  printf( "%7d : ", i );
287  uCanonPhase = Abc_TtCanonicizePhase( p->pFuncs[i], p->nVars );
288  if ( fVerbose )
289  Extra_PrintHex( stdout, (unsigned *)p->pFuncs[i], p->nVars ), Abc_TruthNpnPrint(NULL, uCanonPhase, p->nVars), printf( "\n" );
290  }
291  }
292  else assert( 0 );
293  clk = Abc_Clock() - clk;
294  printf( "Classes =%9d ", Abc_TruthNpnCountUnique(p) );
295  Abc_PrintTime( 1, "Time", clk );
296 }
297 
298 /**Function*************************************************************
299 
300  Synopsis [Apply decomposition to truth tables.]
301 
302  Description []
303 
304  SideEffects []
305 
306  SeeAlso []
307 
308 ***********************************************************************/
309 void Abc_TruthNpnTest( char * pFileName, int NpnType, int nVarNum, int fDumpRes, int fBinary, int fVerbose )
310 {
311  Abc_TtStore_t * p;
312  char * pFileNameOut;
313 
314  // read info from file
315  p = Abc_TtStoreLoad( pFileName, nVarNum );
316  if ( p == NULL )
317  return;
318 
319  // consider functions from the file
320  Abc_TruthNpnPerform( p, NpnType, fVerbose );
321 
322  // write the result
323  if ( fDumpRes )
324  {
325  if ( fBinary )
326  pFileNameOut = Extra_FileNameGenericAppend( pFileName, "_out.tt" );
327  else
328  pFileNameOut = Extra_FileNameGenericAppend( pFileName, "_out.txt" );
329  Abc_TtStoreWrite( pFileNameOut, p, fBinary );
330  if ( fVerbose )
331  printf( "The resulting functions are written into file \"%s\".\n", pFileNameOut );
332  }
333 
334  // delete data-structure
335  Abc_TtStoreFree( p, nVarNum );
336 // printf( "Finished computing canonical forms for functions from file \"%s\".\n", pFileName );
337 }
338 
339 
340 /**Function*************************************************************
341 
342  Synopsis [Testbench for decomposition algorithms.]
343 
344  Description []
345 
346  SideEffects []
347 
348  SeeAlso []
349 
350 ***********************************************************************/
351 int Abc_NpnTest( char * pFileName, int NpnType, int nVarNum, int fDumpRes, int fBinary, int fVerbose )
352 {
353  if ( fVerbose )
354  printf( "Using truth tables from file \"%s\"...\n", pFileName );
355  if ( NpnType >= 0 && NpnType <= 6 )
356  Abc_TruthNpnTest( pFileName, NpnType, nVarNum, fDumpRes, fBinary, fVerbose );
357  else
358  printf( "Unknown canonical form value (%d).\n", NpnType );
359  fflush( stdout );
360  return 0;
361 }
362 
363 ////////////////////////////////////////////////////////////////////////
364 /// END OF FILE ///
365 ////////////////////////////////////////////////////////////////////////
366 
367 
369 
void Abc_TtStoreFree(Abc_TtStore_t *p, int nVarNum)
Definition: abcDec.c:175
int Abc_TruthCompare(word **p1, word **p2)
Definition: abcNpn.c:128
static int Abc_PrimeCudd(unsigned int p)
Definition: abc_global.h:383
static Llb_Mgr_t * p
Definition: llb3Image.c:950
int Abc_TruthNpnCountUniqueSort(Abc_TtStore_t *p)
Definition: abcNpn.c:129
static int Abc_InfoHasBit(unsigned *p, int i)
Definition: abc_global.h:258
int Abc_NpnTest(char *pFileName, int NpnType, int nVarNum, int fDumpRes, int fBinary, int fVerbose)
Definition: abcNpn.c:351
word ** pFuncs
Definition: luckyInt.h:70
void Abc_TruthNpnTest(char *pFileName, int NpnType, int nVarNum, int fDumpRes, int fBinary, int fVerbose)
Definition: abcNpn.c:309
int nFuncs
Definition: abcDec.c:49
static abctime Abc_Clock()
Definition: abc_global.h:279
int nWords
Definition: abcNpn.c:127
void resetPCanonPermArray(char *x, int nVars)
Definition: luckyFast6.c:30
void Abc_TruthNpnPrint(char *pCanonPermInit, unsigned uCanonPhase, int nVars)
Definition: abcNpn.c:154
static void Abc_PrintTime(int level, const char *pStr, abctime time)
Definition: abc_global.h:367
unsigned Abc_TtCanonicizePhase(word *pTruth, int nVars)
Definition: dauCanon.c:999
void Extra_PrintHex(FILE *pFile, unsigned *pTruth, int nVars)
int Abc_TruthNpnCountUnique(Abc_TtStore_t *p)
Definition: abcNpn.c:90
Abc_TtStore_t * Abc_TtStoreLoad(char *pFileName, int nVarNum)
Definition: abcDec.c:395
void Abc_TtStoreWrite(char *pFileName, Abc_TtStore_t *p, int fBinary)
Definition: abcDec.c:358
unsigned __int64 word
DECLARATIONS ///.
Definition: kitPerm.c:36
int nWords
Definition: abcDec.c:48
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
int memcmp()
permInfo * setPermInfoPtr(int var)
Definition: luckySimple.c:110
unsigned Kit_TruthSemiCanonicize(unsigned *pInOut, unsigned *pAux, int nVars, char *pCanonPerm)
Definition: kitTruth.c:1657
unsigned luckyCanonicizer_final_fast(word *pInOut, int nVars, char *pCanonPerm)
Definition: luckyFast16.c:818
void freePermInfoPtr(permInfo *x)
Definition: luckySimple.c:126
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
void Abc_TruthNpnPerform(Abc_TtStore_t *p, int NpnType, int fVerbose)
Definition: abcNpn.c:177
#define ABC_FREE(obj)
Definition: abc_global.h:232
unsigned Abc_TtCanonicize(word *pTruth, int nVars, char *pCanonPerm)
FUNCTION DECLARATIONS ///.
Definition: dauCanon.c:895
#define assert(ex)
Definition: util_old.h:213
char * Extra_FileNameGenericAppend(char *pBase, char *pSuffix)
void simpleMinimal(word *x, word *pAux, word *minimal, permInfo *pi, int nVars)
Definition: luckySimple.c:151
word ** pFuncs
Definition: abcDec.c:50
ABC_INT64_T abctime
Definition: abc_global.h:278
unsigned luckyCanonicizer_final_fast1(word *pInOut, int nVars, char *pCanonPerm)
Definition: luckyFast16.c:843
static int Abc_TruthHashKey(word *pFunc, int nWords, int nTableSize)
FUNCTION DEFINITIONS ///.
Definition: abcNpn.c:71
Definition: lucky.h:23
#define ABC_FALLOC(type, num)
Definition: abc_global.h:231
static int Abc_TruthHashLookup(word **pFuncs, int iThis, int nWords, int *pTable, int *pNexts, int Key)
Definition: abcNpn.c:81