ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
ifTruth.c
Go to the documentation of this file.
1
20
21#include "if.h"
22#include "bool/kit/kit.h"
23#include "misc/extra/extra.h"
24
26
27
31
32//#define IF_TRY_NEW
33
37
49void If_CutTruthPermute( word * pTruth, int nLeaves, int nVars, int nWords, float * pDelays, int * pVars )
50{
51 while ( 1 )
52 {
53 int i, fChange = 0;
54 for ( i = 0; i < nLeaves - 1; i++ )
55 {
56 if ( pDelays[i] >= pDelays[i+1] )
57 continue;
58 ABC_SWAP( float, pDelays[i], pDelays[i+1] );
59 ABC_SWAP( int, pVars[i], pVars[i+1] );
60 if ( pTruth )
61 Abc_TtSwapAdjacent( pTruth, nWords, i );
62 fChange = 1;
63 }
64 if ( !fChange )
65 return;
66 }
67}
69{
70 If_Obj_t * pLeaf;
71 float PinDelays[IF_MAX_LUTSIZE];
72 int i, truthId;
73 assert( !p->pPars->fUseTtPerm );
74 If_CutForEachLeaf( p, pCut, pLeaf, i )
75 PinDelays[i] = If_ObjCutBest(pLeaf)->Delay;
76 if ( p->vTtMem[pCut->nLeaves] == NULL )
77 {
78 If_CutTruthPermute( NULL, If_CutLeaveNum(pCut), pCut->nLeaves, p->nTruth6Words[pCut->nLeaves], PinDelays, If_CutLeaves(pCut) );
79 return;
80 }
81 Abc_TtCopy( p->puTempW, If_CutTruthWR(p, pCut), p->nTruth6Words[pCut->nLeaves], 0 );
82 If_CutTruthPermute( p->puTempW, If_CutLeaveNum(pCut), pCut->nLeaves, p->nTruth6Words[pCut->nLeaves], PinDelays, If_CutLeaves(pCut) );
83 truthId = Vec_MemHashInsert( p->vTtMem[pCut->nLeaves], p->puTempW );
84 pCut->iCutFunc = Abc_Var2Lit( truthId, If_CutTruthIsCompl(pCut) );
85 assert( (p->puTempW[0] & 1) == 0 );
86}
87
99int If_CutComputeTruth( If_Man_t * p, If_Cut_t * pCut, If_Cut_t * pCut0, If_Cut_t * pCut1, int fCompl0, int fCompl1 )
100{
101 int fCompl, truthId, nLeavesNew, PrevSize, RetValue = 0;
102 word * pTruth0s = Vec_MemReadEntry( p->vTtMem[pCut0->nLeaves], Abc_Lit2Var(pCut0->iCutFunc) );
103 word * pTruth1s = Vec_MemReadEntry( p->vTtMem[pCut1->nLeaves], Abc_Lit2Var(pCut1->iCutFunc) );
104 word * pTruth0 = (word *)p->puTemp[0];
105 word * pTruth1 = (word *)p->puTemp[1];
106 word * pTruth = (word *)p->puTemp[2];
107 Abc_TtCopy( pTruth0, pTruth0s, p->nTruth6Words[pCut0->nLeaves], fCompl0 ^ pCut0->fCompl ^ Abc_LitIsCompl(pCut0->iCutFunc) );
108 Abc_TtCopy( pTruth1, pTruth1s, p->nTruth6Words[pCut1->nLeaves], fCompl1 ^ pCut1->fCompl ^ Abc_LitIsCompl(pCut1->iCutFunc) );
109 Abc_TtStretch6( pTruth0, pCut0->nLeaves, pCut->nLeaves );
110 Abc_TtStretch6( pTruth1, pCut1->nLeaves, pCut->nLeaves );
111 Abc_TtExpand( pTruth0, pCut->nLeaves, pCut0->pLeaves, pCut0->nLeaves, pCut->pLeaves, pCut->nLeaves );
112 Abc_TtExpand( pTruth1, pCut->nLeaves, pCut1->pLeaves, pCut1->nLeaves, pCut->pLeaves, pCut->nLeaves );
113 fCompl = (pTruth0[0] & pTruth1[0] & 1);
114 Abc_TtAnd( pTruth, pTruth0, pTruth1, p->nTruth6Words[pCut->nLeaves], fCompl );
115 if ( p->pPars->fCutMin && (pCut0->nLeaves + pCut1->nLeaves > pCut->nLeaves || pCut0->nLeaves == 0 || pCut1->nLeaves == 0) )
116 {
117 nLeavesNew = Abc_TtMinBase( pTruth, pCut->pLeaves, pCut->nLeaves, pCut->nLeaves );
118 if ( nLeavesNew < If_CutLeaveNum(pCut) )
119 {
120 pCut->nLeaves = nLeavesNew;
121 pCut->uSign = If_ObjCutSignCompute( pCut );
122 RetValue = 1;
123 }
124 }
125 PrevSize = Vec_MemEntryNum( p->vTtMem[pCut->nLeaves] );
126 truthId = Vec_MemHashInsert( p->vTtMem[pCut->nLeaves], pTruth );
127 pCut->iCutFunc = Abc_Var2Lit( truthId, fCompl );
128 assert( (pTruth[0] & 1) == 0 );
129#ifdef IF_TRY_NEW
130 {
131 word pCopy[1024];
132 char pCanonPerm[16];
133 memcpy( pCopy, If_CutTruthW(pCut), sizeof(word) * p->nTruth6Words[pCut->nLeaves] );
134 Abc_TtCanonicize( pCopy, pCut->nLeaves, pCanonPerm );
135 }
136#endif
137 if ( p->vTtIsops[pCut->nLeaves] && PrevSize != Vec_MemEntryNum(p->vTtMem[pCut->nLeaves]) )
138 {
139 Vec_Int_t * vLevel = Vec_WecPushLevel( p->vTtIsops[pCut->nLeaves] );
140 fCompl = Kit_TruthIsop( (unsigned *)pTruth, pCut->nLeaves, p->vCover, 1 );
141 if ( fCompl >= 0 )
142 {
143 Vec_IntGrow( vLevel, Vec_IntSize(p->vCover) );
144 Vec_IntAppend( vLevel, p->vCover );
145 if ( fCompl )
146 vLevel->nCap ^= (1<<16); // hack to remember complemented attribute
147 }
148 assert( Vec_WecSize(p->vTtIsops[pCut->nLeaves]) == Vec_MemEntryNum(p->vTtMem[pCut->nLeaves]) );
149 }
150 return RetValue;
151}
152
164int If_CutComputeTruthPerm_int( If_Man_t * p, If_Cut_t * pCut, If_Cut_t * pCut0, If_Cut_t * pCut1, int iCutFunc0, int iCutFunc1 )
165{
166 int fVerbose = 0;
167 abctime clk = 0;
168 int pPerm[IF_MAX_LUTSIZE];
169 int v, Place, fCompl, truthId, nLeavesNew, RetValue = 0;
170 word * pTruth0s = Vec_MemReadEntry( p->vTtMem[pCut0->nLeaves], Abc_Lit2Var(iCutFunc0) );
171 word * pTruth1s = Vec_MemReadEntry( p->vTtMem[pCut1->nLeaves], Abc_Lit2Var(iCutFunc1) );
172 word * pTruth0 = (word *)p->puTemp[0];
173 word * pTruth1 = (word *)p->puTemp[1];
174 word * pTruth = (word *)p->puTemp[2];
175 assert( pCut0->uMaskFunc >= 0 );
176 assert( pCut1->uMaskFunc >= 0 );
177 Abc_TtCopy( pTruth0, pTruth0s, p->nTruth6Words[pCut0->nLeaves], Abc_LitIsCompl(iCutFunc0) );
178 Abc_TtCopy( pTruth1, pTruth1s, p->nTruth6Words[pCut1->nLeaves], Abc_LitIsCompl(iCutFunc1) );
179 Abc_TtStretch6( pTruth0, pCut0->nLeaves, pCut->nLeaves );
180 Abc_TtStretch6( pTruth1, pCut1->nLeaves, pCut->nLeaves );
181
182if ( fVerbose )
183{
184//Kit_DsdPrintFromTruth( pTruth0, pCut0->nLeaves ); printf( "\n" );
185//Kit_DsdPrintFromTruth( pTruth1, pCut1->nLeaves ); printf( "\n" );
186}
187 // create literals
188 for ( v = 0; v < (int)pCut0->nLeaves; v++ )
189 pCut->pLeaves[v] = Abc_Var2Lit( pCut0->pLeaves[v], If_CutLeafBit(pCut0, v) );
190 for ( v = 0; v < (int)pCut1->nLeaves; v++ )
191 if ( p->pPerm[1][v] >= (int)pCut0->nLeaves )
192 pCut->pLeaves[p->pPerm[1][v]] = Abc_Var2Lit( pCut1->pLeaves[v], If_CutLeafBit(pCut1, v) );
193 else if ( If_CutLeafBit(pCut0, p->pPerm[1][v]) != If_CutLeafBit(pCut1, v) )
194 Abc_TtFlip( pTruth1, p->nTruth6Words[pCut1->nLeaves], v );
195 // permute variables
196 for ( v = (int)pCut1->nLeaves; v < (int)pCut->nLeaves; v++ )
197 p->pPerm[1][v] = -1;
198 for ( v = 0; v < (int)pCut1->nLeaves; v++ )
199 {
200 Place = p->pPerm[1][v];
201 if ( Place == v || Place == -1 )
202 continue;
203 Abc_TtSwapVars( pTruth1, pCut->nLeaves, v, Place );
204 p->pPerm[1][v] = p->pPerm[1][Place];
205 p->pPerm[1][Place] = Place;
206 v--;
207 }
208
209if ( fVerbose )
210{
211//Kit_DsdPrintFromTruth( pTruth0, pCut0->nLeaves ); printf( "\n" );
212//Kit_DsdPrintFromTruth( pTruth1, pCut->nLeaves ); printf( "\n" );
213}
214
215 // perform operation
216 Abc_TtAnd( pTruth, pTruth0, pTruth1, p->nTruth6Words[pCut->nLeaves], 0 );
217 // minimize support
218 if ( p->pPars->fCutMin && (pCut0->nLeaves + pCut1->nLeaves > pCut->nLeaves || pCut0->nLeaves == 0 || pCut1->nLeaves == 0) )
219 {
220 nLeavesNew = Abc_TtMinBase( pTruth, pCut->pLeaves, pCut->nLeaves, pCut->nLeaves );
221 if ( nLeavesNew < If_CutLeaveNum(pCut) )
222 {
223 pCut->nLeaves = nLeavesNew;
224 RetValue = 1;
225 }
226 }
227 // compute canonical form
228if ( p->pPars->fVerbose )
229clk = Abc_Clock();
230 p->uCanonPhase = Abc_TtCanonicize( pTruth, pCut->nLeaves, p->pCanonPerm );
231if ( p->pPars->fVerbose )
232p->timeCache[3] += Abc_Clock() - clk;
233 for ( v = 0; v < (int)pCut->nLeaves; v++ )
234 pPerm[v] = Abc_LitNotCond( pCut->pLeaves[(int)p->pCanonPerm[v]], ((p->uCanonPhase>>v)&1) );
235 pCut->uMaskFunc = 0;
236 for ( v = 0; v < (int)pCut->nLeaves; v++ )
237 {
238 pCut->pLeaves[v] = Abc_Lit2Var(pPerm[v]);
239 if ( Abc_LitIsCompl(pPerm[v]) )
240 pCut->uMaskFunc |= (1 << v);
241 }
242 // create signature after lowering literals
243 if ( RetValue )
244 pCut->uSign = If_ObjCutSignCompute( pCut );
245 else
246 assert( pCut->uSign == If_ObjCutSignCompute( pCut ) );
247
248 assert( Vec_IntSize(p->vTtOccurs[pCut->nLeaves]) == Vec_MemEntryNum(p->vTtMem[pCut->nLeaves]) );
249 // hash function
250 fCompl = ((p->uCanonPhase >> pCut->nLeaves) & 1);
251 truthId = Vec_MemHashInsert( p->vTtMem[pCut->nLeaves], pTruth );
252 pCut->iCutFunc = Abc_Var2Lit( truthId, fCompl );
253 // count how many time this truth table is used
254 if ( Vec_IntSize(p->vTtOccurs[pCut->nLeaves]) < Vec_MemEntryNum(p->vTtMem[pCut->nLeaves]) )
255 Vec_IntPush( p->vTtOccurs[pCut->nLeaves], 0 );
256 Vec_IntAddToEntry( p->vTtOccurs[pCut->nLeaves], truthId, 1 );
257
258if ( fVerbose )
259{
260//Kit_DsdPrintFromTruth( pTruth, pCut->nLeaves ); printf( "\n" );
261//If_CutPrint( pCut0 );
262//If_CutPrint( pCut1 );
263//If_CutPrint( pCut );
264//printf( "%d\n\n", pCut->iCutFunc );
265}
266
267 return RetValue;
268}
269int If_CutComputeTruthPerm( If_Man_t * p, If_Cut_t * pCut, If_Cut_t * pCut0, If_Cut_t * pCut1, int iCutFunc0, int iCutFunc1 )
270{
271 abctime clk = 0;
272 int i, Num, nEntriesOld, RetValue;
273 if ( pCut0->nLeaves + pCut1->nLeaves > pCut->nLeaves || iCutFunc0 < 2 || iCutFunc1 < 2 )
274 {
275if ( p->pPars->fVerbose )
276clk = Abc_Clock();
277 RetValue = If_CutComputeTruthPerm_int( p, pCut, pCut0, pCut1, iCutFunc0, iCutFunc1 );
278if ( p->pPars->fVerbose )
279p->timeCache[0] += Abc_Clock() - clk;
280 return RetValue;
281 }
282 assert( pCut0->nLeaves + pCut1->nLeaves == pCut->nLeaves );
283 nEntriesOld = Hash_IntManEntryNum(p->vPairHash);
284 Num = Hash_Int2ManInsert( p->vPairHash, (iCutFunc0 << 5)|pCut0->nLeaves, (iCutFunc1 << 5)|pCut1->nLeaves, -1 );
285 assert( Num > 0 );
286 if ( nEntriesOld == Hash_IntManEntryNum(p->vPairHash) )
287 {
288 char * pCanonPerm;
289 int v, pPerm[IF_MAX_LUTSIZE];
290 pCut->iCutFunc = Vec_IntEntry( p->vPairRes, Num );
291 // move complements from the fanin cuts
292 for ( v = 0; v < (int)pCut->nLeaves; v++ )
293 if ( v < (int)pCut0->nLeaves )
294 pCut->pLeaves[v] = Abc_Var2Lit( pCut->pLeaves[v], If_CutLeafBit(pCut0, v) );
295 else
296 pCut->pLeaves[v] = Abc_Var2Lit( pCut->pLeaves[v], If_CutLeafBit(pCut1, v-(int)pCut0->nLeaves) );
297 // reorder the cut
298 pCanonPerm = Vec_StrEntryP( p->vPairPerms, Num * pCut->nLimit );
299 for ( v = 0; v < (int)pCut->nLeaves; v++ )
300 pPerm[v] = Abc_LitNotCond( pCut->pLeaves[Abc_Lit2Var((int)pCanonPerm[v])], Abc_LitIsCompl((int)pCanonPerm[v]) );
301 // generate the result
302 pCut->uMaskFunc = 0;
303 for ( v = 0; v < (int)pCut->nLeaves; v++ )
304 {
305 pCut->pLeaves[v] = Abc_Lit2Var(pPerm[v]);
306 if ( Abc_LitIsCompl(pPerm[v]) )
307 pCut->uMaskFunc |= (1 << v);
308 }
309// printf( "Found: %d(%d) %d(%d) -> %d(%d)\n", iCutFunc0, pCut0->nLeaves, iCutFunc1, pCut0->nLeaves, pCut->iCutFunc, pCut->nLeaves );
310 p->nCacheHits++;
311//p->timeCache[1] += Abc_Clock() - clk;
312 return 0;
313 }
314if ( p->pPars->fVerbose )
315clk = Abc_Clock();
316 p->nCacheMisses++;
317 RetValue = If_CutComputeTruthPerm_int( p, pCut, pCut0, pCut1, iCutFunc0, iCutFunc1 );
318 assert( RetValue == 0 );
319// printf( "Added: %d(%d) %d(%d) -> %d(%d)\n", iCutFunc0, pCut0->nLeaves, iCutFunc1, pCut0->nLeaves, pCut->iCutFunc, pCut->nLeaves );
320 // save the result
321 assert( Num == Vec_IntSize(p->vPairRes) );
322 Vec_IntPush( p->vPairRes, pCut->iCutFunc );
323 // save the permutation
324 assert( Num * (int)pCut->nLimit == Vec_StrSize(p->vPairPerms) );
325 for ( i = 0; i < (int)pCut->nLeaves; i++ )
326 Vec_StrPush( p->vPairPerms, (char)Abc_Var2Lit((int)p->pCanonPerm[i], ((p->uCanonPhase>>i)&1)) );
327 for ( i = (int)pCut0->nLeaves + (int)pCut1->nLeaves; i < (int)pCut->nLimit; i++ )
328 Vec_StrPush( p->vPairPerms, (char)-1 );
329if ( p->pPars->fVerbose )
330p->timeCache[2] += Abc_Clock() - clk;
331 return 0;
332}
333
345Vec_Mem_t * If_DeriveHashTable6( int nVars, word uTruth )
346{
347 int fVerbose = 0;
348 int nMints = (1 << nVars);
349 int nPerms = Extra_Factorial( nVars );
350 int * pComp = Extra_GreyCodeSchedule( nVars );
351 int * pPerm = Extra_PermSchedule( nVars );
352 word Canon = ABC_CONST(0xFFFFFFFFFFFFFFFF);
353 word tCur, tTemp1, tTemp2;
354 Vec_Mem_t * vTtMem6 = Vec_MemAllocForTTSimple( nVars );
355 int i, p, c;
356 for ( i = 0; i < 2; i++ )
357 {
358 tCur = i ? ~uTruth : uTruth;
359 tTemp1 = tCur;
360 for ( p = 0; p < nPerms; p++ )
361 {
362 tTemp2 = tCur;
363 for ( c = 0; c < nMints; c++ )
364 {
365 if ( Canon > tCur )
366 Canon = tCur;
367 Vec_MemHashInsert( vTtMem6, &tCur );
368 tCur = Abc_Tt6Flip( tCur, pComp[c] );
369 }
370 assert( tTemp2 == tCur );
371 tCur = Abc_Tt6SwapAdjacent( tCur, pPerm[p] );
372 }
373 assert( tTemp1 == tCur );
374 }
375 ABC_FREE( pComp );
376 ABC_FREE( pPerm );
377 if ( fVerbose )
378 {
379/*
380 word * pEntry;
381 Vec_MemForEachEntry( vTtMem6, pEntry, i )
382 {
383 Extra_PrintHex( stdout, (unsigned*)pEntry, nVars );
384 printf( ", " );
385 if ( i % 4 == 3 )
386 printf( "\n" );
387 }
388*/
389 Extra_PrintHex( stdout, (unsigned*)&uTruth, nVars ); printf( "\n" );
390 Extra_PrintHex( stdout, (unsigned*)&Canon, nVars ); printf( "\n" );
391 printf( "Members = %d.\n", Vec_MemEntryNum(vTtMem6) );
392 }
393 return vTtMem6;
394}
395
397{
398 if ( pCut->nLeaves != 6 )
399 return 0;
400 if ( p->vTtMem6 == NULL )
401 p->vTtMem6 = If_DeriveHashTable6( 6, ABC_CONST(0xfedcba9876543210) );
402 if ( *Vec_MemHashLookup( p->vTtMem6, If_CutTruthWR(p, pCut) ) == -1 )
403 return 0;
404 return 1;
405}
406
410
411
413
int nWords
Definition abcNpn.c:127
#define ABC_SWAP(Type, a, b)
Definition abc_global.h:253
ABC_INT64_T abctime
Definition abc_global.h:332
#define ABC_FREE(obj)
Definition abc_global.h:267
#define ABC_CONST(number)
PARAMETERS ///.
Definition abc_global.h:240
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
Definition bblif.c:37
unsigned Abc_TtCanonicize(word *pTruth, int nVars, char *pCanonPerm)
FUNCTION DECLARATIONS ///.
Definition dauCanon.c:1036
Cube * p
Definition exorList.c:222
int * Extra_PermSchedule(int n)
int Extra_Factorial(int n)
int * Extra_GreyCodeSchedule(int n)
void Extra_PrintHex(FILE *pFile, unsigned *pTruth, int nVars)
Vec_Mem_t * If_DeriveHashTable6(int nVars, word uTruth)
Definition ifTruth.c:345
void If_CutRotatePins(If_Man_t *p, If_Cut_t *pCut)
Definition ifTruth.c:68
int If_CutCheckTruth6(If_Man_t *p, If_Cut_t *pCut)
Definition ifTruth.c:396
int If_CutComputeTruthPerm_int(If_Man_t *p, If_Cut_t *pCut, If_Cut_t *pCut0, If_Cut_t *pCut1, int iCutFunc0, int iCutFunc1)
Definition ifTruth.c:164
int If_CutComputeTruthPerm(If_Man_t *p, If_Cut_t *pCut, If_Cut_t *pCut0, If_Cut_t *pCut1, int iCutFunc0, int iCutFunc1)
Definition ifTruth.c:269
ABC_NAMESPACE_IMPL_START void If_CutTruthPermute(word *pTruth, int nLeaves, int nVars, int nWords, float *pDelays, int *pVars)
DECLARATIONS ///.
Definition ifTruth.c:49
int If_CutComputeTruth(If_Man_t *p, If_Cut_t *pCut, If_Cut_t *pCut0, If_Cut_t *pCut1, int fCompl0, int fCompl1)
Definition ifTruth.c:99
struct If_Cut_t_ If_Cut_t
Definition if.h:80
#define IF_MAX_LUTSIZE
INCLUDES ///.
Definition if.h:53
#define If_CutForEachLeaf(p, pCut, pLeaf, i)
Definition if.h:503
struct If_Man_t_ If_Man_t
BASIC TYPES ///.
Definition if.h:77
struct If_Obj_t_ If_Obj_t
Definition if.h:79
unsigned __int64 word
DECLARATIONS ///.
Definition kitPerm.c:36
int Kit_TruthIsop(unsigned *puTruth, int nVars, Vec_Int_t *vMemory, int fTryBoth)
Definition kitIsop.c:134
int pLeaves[0]
Definition if.h:318
unsigned nLeaves
Definition if.h:316
unsigned nLimit
Definition if.h:315
unsigned fCompl
Definition if.h:311
unsigned uSign
Definition if.h:309
int uMaskFunc
Definition if.h:308
int iCutFunc
Definition if.h:307
typedefABC_NAMESPACE_IMPL_START struct Vec_Mem_t_ Vec_Mem_t
DECLARATIONS ///.
Definition utilMem.c:35
#define assert(ex)
Definition util_old.h:213
char * memcpy()