ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
abcOdc.c
Go to the documentation of this file.
1
20
21#include "base/abc/abc.h"
22
24
25
29
30#define ABC_DC_MAX_NODES (1<<15)
31
32typedef unsigned short Odc_Lit_t;
33
34typedef struct Odc_Obj_t_ Odc_Obj_t; // 16 bytes
36{
37 Odc_Lit_t iFan0; // first fanin
38 Odc_Lit_t iFan1; // second fanin
39 Odc_Lit_t iNext; // next node in the hash table
40 unsigned short TravId; // the traversal ID
41 unsigned uData; // the computed data
42 unsigned uMask; // the variable mask
43};
44
46{
47 // don't-care parameters
48 int nVarsMax; // the max number of cut variables
49 int nLevels; // the number of ODC levels
50 int fVerbose; // the verbosiness flag
51 int fVeryVerbose;// the verbosiness flag to print per-node stats
52 int nPercCutoff; // cutoff percentage
54
55 // windowing
56 Abc_Obj_t * pNode; // the node for windowing
57 Vec_Ptr_t * vLeaves; // the number of the cut
58 Vec_Ptr_t * vRoots; // the roots of the cut
59 Vec_Ptr_t * vBranches; // additional inputs
60
61 // internal AIG package
62 // objects
63 int nPis; // number of PIs (nVarsMax + 32)
64 int nObjs; // number of objects (Const1, PIs, ANDs)
65 int nObjsAlloc; // number of objects allocated
66 Odc_Obj_t * pObjs; // objects
67 Odc_Lit_t iRoot; // the root object
68 unsigned short nTravIds; // the number of travIDs
69 // structural hashing
70 Odc_Lit_t * pTable; // hash table
71 int nTableSize; // hash table size
72 Vec_Int_t * vUsedSpots; // the used spots
73
74 // truth tables
75 int nBits; // the number of bits
76 int nWords; // the number of words
77 Vec_Ptr_t * vTruths; // truth tables for each node
78 Vec_Ptr_t * vTruthsElem; // elementary truth tables for the PIs
79 unsigned * puTruth; // the place where the resulting truth table does
80
81 // statistics
82 int nWins; // the number of windows processed
83 int nWinsEmpty; // the number of empty windows
84 int nSimsEmpty; // the number of empty simulation infos
85 int nQuantsOver; // the number of quantification overflows
86 int nWinsFinish; // the number of windows that finished
87 int nTotalDcs; // total percentage of DCs
88
89 // runtime
90 abctime timeClean; // windowing
91 abctime timeWin; // windowing
92 abctime timeMiter; // computing the miter
93 abctime timeSim; // simulation
94 abctime timeQuant; // quantification
95 abctime timeTruth; // truth table
96 abctime timeTotal; // useful runtime
97 abctime timeAbort; // aborted runtime
98};
99
100
101// quantity of different objects
102static inline int Odc_PiNum( Odc_Man_t * p ) { return p->nPis; }
103static inline int Odc_NodeNum( Odc_Man_t * p ) { return p->nObjs - p->nPis - 1; }
104static inline int Odc_ObjNum( Odc_Man_t * p ) { return p->nObjs; }
105
106// complemented attributes of objects
107static inline int Odc_IsComplement( Odc_Lit_t Lit ) { return Lit & (Odc_Lit_t)1; }
108static inline Odc_Lit_t Odc_Regular( Odc_Lit_t Lit ) { return Lit & ~(Odc_Lit_t)1; }
109static inline Odc_Lit_t Odc_Not( Odc_Lit_t Lit ) { return Lit ^ (Odc_Lit_t)1; }
110static inline Odc_Lit_t Odc_NotCond( Odc_Lit_t Lit, int c ) { return Lit ^ (Odc_Lit_t)(c!=0); }
111
112// specialized Literals
113static inline Odc_Lit_t Odc_Const0() { return 1; }
114static inline Odc_Lit_t Odc_Const1() { return 0; }
115static inline Odc_Lit_t Odc_Var( Odc_Man_t * p, int i ) { assert( i >= 0 && i < p->nPis ); return (i+1) << 1; }
116static inline int Odc_IsConst( Odc_Lit_t Lit ) { return Lit < (Odc_Lit_t)2; }
117static inline int Odc_IsTerm( Odc_Man_t * p, Odc_Lit_t Lit ) { return (int)(Lit>>1) <= p->nPis; }
118
119// accessing internal storage
120static inline Odc_Obj_t * Odc_ObjNew( Odc_Man_t * p ) { assert( p->nObjs < p->nObjsAlloc ); return p->pObjs + p->nObjs++; }
121static inline Odc_Lit_t Odc_Obj2Lit( Odc_Man_t * p, Odc_Obj_t * pObj ) { assert( pObj ); return (pObj - p->pObjs) << 1; }
122static inline Odc_Obj_t * Odc_Lit2Obj( Odc_Man_t * p, Odc_Lit_t Lit ) { assert( !(Lit & 1) && (int)(Lit>>1) < p->nObjs ); return p->pObjs + (Lit>>1); }
123
124// fanins and their complements
125static inline Odc_Lit_t Odc_ObjChild0( Odc_Obj_t * pObj ) { return pObj->iFan0; }
126static inline Odc_Lit_t Odc_ObjChild1( Odc_Obj_t * pObj ) { return pObj->iFan1; }
127static inline Odc_Lit_t Odc_ObjFanin0( Odc_Obj_t * pObj ) { return Odc_Regular(pObj->iFan0); }
128static inline Odc_Lit_t Odc_ObjFanin1( Odc_Obj_t * pObj ) { return Odc_Regular(pObj->iFan1); }
129static inline int Odc_ObjFaninC0( Odc_Obj_t * pObj ) { return Odc_IsComplement(pObj->iFan0); }
130static inline int Odc_ObjFaninC1( Odc_Obj_t * pObj ) { return Odc_IsComplement(pObj->iFan1); }
131
132// traversal IDs
133static inline void Odc_ManIncrementTravId( Odc_Man_t * p ) { p->nTravIds++; }
134static inline void Odc_ObjSetTravIdCurrent( Odc_Man_t * p, Odc_Obj_t * pObj ) { pObj->TravId = p->nTravIds; }
135static inline int Odc_ObjIsTravIdCurrent( Odc_Man_t * p, Odc_Obj_t * pObj ) { return (int )((int)pObj->TravId == p->nTravIds); }
136
137// truth tables
138static inline unsigned * Odc_ObjTruth( Odc_Man_t * p, Odc_Lit_t Lit ) { assert( !(Lit & 1) ); return (unsigned *) Vec_PtrEntry(p->vTruths, Lit >> 1); }
139
140// iterators
141#define Odc_ForEachPi( p, Lit, i ) \
142 for ( i = 0; (i < Odc_PiNum(p)) && (((Lit) = Odc_Var(p, i)), 1); i++ )
143#define Odc_ForEachAnd( p, pObj, i ) \
144 for ( i = 1 + Odc_CiNum(p); (i < Odc_ObjNum(p)) && ((pObj) = (p)->pObjs + i); i++ )
145
146
150
163Odc_Man_t * Abc_NtkDontCareAlloc( int nVarsMax, int nLevels, int fVerbose, int fVeryVerbose )
164{
165 Odc_Man_t * p;
166 unsigned * pData;
167 int i, k;
168 p = ABC_ALLOC( Odc_Man_t, 1 );
169 memset( p, 0, sizeof(Odc_Man_t) );
170 assert( nVarsMax > 4 && nVarsMax < 16 );
171 assert( nLevels > 0 && nLevels < 10 );
172
173 srand( 0xABC );
174
175 // dont'-care parameters
176 p->nVarsMax = nVarsMax;
177 p->nLevels = nLevels;
178 p->fVerbose = fVerbose;
179 p->fVeryVerbose = fVeryVerbose;
180 p->nPercCutoff = 10;
181 p->skipQuant = 0;
182
183 // windowing
184 p->vRoots = Vec_PtrAlloc( 128 );
185 p->vBranches = Vec_PtrAlloc( 128 );
186
187 // internal AIG package
188 // allocate room for objects
189 p->nObjsAlloc = ABC_DC_MAX_NODES;
190 p->pObjs = ABC_ALLOC( Odc_Obj_t, p->nObjsAlloc * sizeof(Odc_Obj_t) );
191 p->nPis = nVarsMax + 32;
192 p->nObjs = 1 + p->nPis;
193 memset( p->pObjs, 0, p->nObjs * sizeof(Odc_Obj_t) );
194 // set the PI masks
195 for ( i = 0; i < 32; i++ )
196 p->pObjs[1 + p->nVarsMax + i].uMask = (1 << i);
197 // allocate hash table
198 p->nTableSize = p->nObjsAlloc/3 + 1;
199 p->pTable = ABC_ALLOC( Odc_Lit_t, p->nTableSize * sizeof(Odc_Lit_t) );
200 memset( p->pTable, 0, p->nTableSize * sizeof(Odc_Lit_t) );
201 p->vUsedSpots = Vec_IntAlloc( 1000 );
202
203 // truth tables
204 p->nWords = Abc_TruthWordNum( p->nVarsMax );
205 p->nBits = p->nWords * 8 * sizeof(unsigned);
206 p->vTruths = Vec_PtrAllocSimInfo( p->nObjsAlloc, p->nWords );
207 p->vTruthsElem = Vec_PtrAllocSimInfo( p->nVarsMax, p->nWords );
208
209 // set elementary truth tables
210 Abc_InfoFill( (unsigned *)Vec_PtrEntry(p->vTruths, 0), p->nWords );
211 for ( k = 0; k < p->nVarsMax; k++ )
212 {
213// pData = Odc_ObjTruth( p, Odc_Var(p, k) );
214 pData = (unsigned *)Vec_PtrEntry( p->vTruthsElem, k );
215 Abc_InfoClear( pData, p->nWords );
216 for ( i = 0; i < p->nBits; i++ )
217 if ( i & (1 << k) )
218 pData[i>>5] |= (1 << (i&31));
219 }
220
221 // set random truth table for the additional inputs
222 for ( k = p->nVarsMax; k < p->nPis; k++ )
223 {
224 pData = Odc_ObjTruth( p, Odc_Var(p, k) );
225 Abc_InfoRandom( pData, p->nWords );
226 }
227
228 // set the miter to the unused value
229 p->iRoot = 0xffff;
230 return p;
231}
232
245{
246 abctime clk = Abc_Clock();
247 // clean the structural hashing table
248 if ( Vec_IntSize(p->vUsedSpots) > p->nTableSize/3 ) // more than one third
249 memset( p->pTable, 0, sizeof(Odc_Lit_t) * p->nTableSize );
250 else
251 {
252 int iSpot, i;
253 Vec_IntForEachEntry( p->vUsedSpots, iSpot, i )
254 p->pTable[iSpot] = 0;
255 }
256 Vec_IntClear( p->vUsedSpots );
257 // reset the number of nodes
258 p->nObjs = 1 + p->nPis;
259 // reset the root node
260 p->iRoot = 0xffff;
261
262p->timeClean += Abc_Clock() - clk;
263}
264
277{
278 if ( p->fVerbose )
279 {
280 printf( "Wins = %5d. Empty = %5d. SimsEmpty = %5d. QuantOver = %5d. WinsFinish = %5d.\n",
281 p->nWins, p->nWinsEmpty, p->nSimsEmpty, p->nQuantsOver, p->nWinsFinish );
282 printf( "Ave DCs per window = %6.2f %%. Ave DCs per finished window = %6.2f %%.\n",
283 1.0*p->nTotalDcs/p->nWins, 1.0*p->nTotalDcs/p->nWinsFinish );
284 printf( "Runtime stats of the ODC manager:\n" );
285 ABC_PRT( "Cleaning ", p->timeClean );
286 ABC_PRT( "Windowing ", p->timeWin );
287 ABC_PRT( "Miter ", p->timeMiter );
288 ABC_PRT( "Simulation ", p->timeSim );
289 ABC_PRT( "Quantifying ", p->timeQuant );
290 ABC_PRT( "Truth table ", p->timeTruth );
291 ABC_PRT( "TOTAL ", p->timeTotal );
292 ABC_PRT( "Aborted ", p->timeAbort );
293 }
294 Vec_PtrFree( p->vRoots );
295 Vec_PtrFree( p->vBranches );
296 Vec_PtrFree( p->vTruths );
297 Vec_PtrFree( p->vTruthsElem );
298 Vec_IntFree( p->vUsedSpots );
299 ABC_FREE( p->pObjs );
300 ABC_FREE( p->pTable );
301 ABC_FREE( p );
302}
303
304
305
317void Abc_NtkDontCareWinSweepLeafTfo_rec( Abc_Obj_t * pObj, int nLevelLimit, Abc_Obj_t * pNode )
318{
319 Abc_Obj_t * pFanout;
320 int i;
321 if ( Abc_ObjIsCo(pObj) || (int)pObj->Level > nLevelLimit || pObj == pNode )
322 return;
323 if ( Abc_NodeIsTravIdCurrent(pObj) )
324 return;
325 Abc_NodeSetTravIdCurrent( pObj );
327 // try to reduce the runtime
328 if ( Abc_ObjFanoutNum(pObj) > 100 )
329 return;
331 Abc_ObjForEachFanout( pObj, pFanout, i )
332 Abc_NtkDontCareWinSweepLeafTfo_rec( pFanout, nLevelLimit, pNode );
333}
334
347{
348 Abc_Obj_t * pObj;
349 int i;
350 Abc_NtkIncrementTravId( p->pNode->pNtk );
351 Vec_PtrForEachEntry( Abc_Obj_t *, p->vLeaves, pObj, i )
352 Abc_NtkDontCareWinSweepLeafTfo_rec( pObj, p->pNode->Level + p->nLevels, p->pNode );
353}
354
367{
368 Abc_Obj_t * pFanout;
369 int i;
370 assert( Abc_ObjIsNode(pObj) );
371 assert( Abc_NodeIsTravIdCurrent(pObj) );
372 // check if the node has all fanouts marked
373 Abc_ObjForEachFanout( pObj, pFanout, i )
374 if ( !Abc_NodeIsTravIdCurrent(pFanout) )
375 break;
376 // if some of the fanouts are unmarked, add the node to the root
377 if ( i < Abc_ObjFanoutNum(pObj) )
378 {
379 Vec_PtrPushUnique( vRoots, pObj );
380 return;
381 }
382 // otherwise, call recursively
383 Abc_ObjForEachFanout( pObj, pFanout, i )
384 Abc_NtkDontCareWinCollectRoots_rec( pFanout, vRoots );
385}
386
400{
401 assert( !Abc_NodeIsTravIdCurrent(p->pNode) );
402 // mark the node with the old traversal ID
403 Abc_NodeSetTravIdCurrent( p->pNode );
404 // collect the roots
405 Vec_PtrClear( p->vRoots );
406 Abc_NtkDontCareWinCollectRoots_rec( p->pNode, p->vRoots );
407}
408
421{
422 Abc_Obj_t * pFanin;
423 int i;
424 // skip the already collected leaves and branches
425 if ( Abc_NodeIsTravIdCurrent(pObj) )
426 return 1;
427 // if this is not an internal node - make it a new branch
428 if ( !Abc_NodeIsTravIdPrevious(pObj) || Abc_ObjIsCi(pObj) ) //|| (int)pObj->Level <= p->nLevLeaves )
429 {
430 Abc_NodeSetTravIdCurrent( pObj );
431 Vec_PtrPush( p->vBranches, pObj );
432 return Vec_PtrSize(p->vBranches) <= 32;
433 }
434 // visit the fanins of the node
435 Abc_ObjForEachFanin( pObj, pFanin, i )
436 if ( !Abc_NtkDontCareWinAddMissing_rec( p, pFanin ) )
437 return 0;
438 return 1;
439}
440
453{
454 Abc_Obj_t * pObj;
455 int i;
456 // set the leaves
457 Abc_NtkIncrementTravId( p->pNode->pNtk );
458 Vec_PtrForEachEntry( Abc_Obj_t *, p->vLeaves, pObj, i )
459 Abc_NodeSetTravIdCurrent( pObj );
460 // explore from the roots
461 Vec_PtrClear( p->vBranches );
462 Vec_PtrForEachEntry( Abc_Obj_t *, p->vRoots, pObj, i )
463 if ( !Abc_NtkDontCareWinAddMissing_rec( p, pObj ) )
464 return 0;
465 return 1;
466}
467
480{
481 // mark the TFO of the collected nodes up to the given level (p->pNode->Level + p->nWinTfoMax)
483 // find the roots of the window
485 if ( Vec_PtrSize(p->vRoots) == 1 && Vec_PtrEntry(p->vRoots, 0) == p->pNode )
486 {
487// printf( "Empty window\n" );
488 return 0;
489 }
490 // add the nodes in the TFI of the roots that are not yet in the window
492 {
493// printf( "Too many branches (%d)\n", Vec_PtrSize(p->vBranches) );
494 return 0;
495 }
496 return 1;
497}
498
499
500
501
502
514static inline unsigned Odc_HashKey( Odc_Lit_t iFan0, Odc_Lit_t iFan1, int TableSize )
515{
516 unsigned Key = 0;
517 Key ^= Odc_Regular(iFan0) * 7937;
518 Key ^= Odc_Regular(iFan1) * 2971;
519 Key ^= Odc_IsComplement(iFan0) * 911;
520 Key ^= Odc_IsComplement(iFan1) * 353;
521 return Key % TableSize;
522}
523
535static inline Odc_Lit_t * Odc_HashLookup( Odc_Man_t * p, Odc_Lit_t iFan0, Odc_Lit_t iFan1 )
536{
537 Odc_Obj_t * pObj;
538 Odc_Lit_t * pEntry;
539 unsigned uHashKey;
540 assert( iFan0 < iFan1 );
541 // get the hash key for this node
542 uHashKey = Odc_HashKey( iFan0, iFan1, p->nTableSize );
543 // remember the spot in the hash table that will be used
544 if ( p->pTable[uHashKey] == 0 )
545 Vec_IntPush( p->vUsedSpots, uHashKey );
546 // find the entry
547 for ( pEntry = p->pTable + uHashKey; *pEntry; pEntry = &pObj->iNext )
548 {
549 pObj = Odc_Lit2Obj( p, *pEntry );
550 if ( pObj->iFan0 == iFan0 && pObj->iFan1 == iFan1 )
551 return pEntry;
552 }
553 return pEntry;
554}
555
567static inline Odc_Lit_t Odc_And( Odc_Man_t * p, Odc_Lit_t iFan0, Odc_Lit_t iFan1 )
568{
569 Odc_Obj_t * pObj;
570 Odc_Lit_t * pEntry;
571 unsigned uMask0, uMask1;
572 int Temp;
573 // consider trivial cases
574 if ( iFan0 == iFan1 )
575 return iFan0;
576 if ( iFan0 == Odc_Not(iFan1) )
577 return Odc_Const0();
578 if ( Odc_Regular(iFan0) == Odc_Const1() )
579 return iFan0 == Odc_Const1() ? iFan1 : Odc_Const0();
580 if ( Odc_Regular(iFan1) == Odc_Const1() )
581 return iFan1 == Odc_Const1() ? iFan0 : Odc_Const0();
582 // canonicize the fanin order
583 if ( iFan0 > iFan1 )
584 Temp = iFan0, iFan0 = iFan1, iFan1 = Temp;
585 // check if a node with these fanins exists
586 pEntry = Odc_HashLookup( p, iFan0, iFan1 );
587 if ( *pEntry )
588 return *pEntry;
589 // create a new node
590 pObj = Odc_ObjNew( p );
591 pObj->iFan0 = iFan0;
592 pObj->iFan1 = iFan1;
593 pObj->iNext = 0;
594 pObj->TravId = 0;
595 // set the mask
596 uMask0 = Odc_Lit2Obj(p, Odc_Regular(iFan0))->uMask;
597 uMask1 = Odc_Lit2Obj(p, Odc_Regular(iFan1))->uMask;
598 pObj->uMask = uMask0 | uMask1;
599 // add to the table
600 *pEntry = Odc_Obj2Lit( p, pObj );
601 return *pEntry;
602}
603
615static inline Odc_Lit_t Odc_Or( Odc_Man_t * p, Odc_Lit_t iFan0, Odc_Lit_t iFan1 )
616{
617 return Odc_Not( Odc_And(p, Odc_Not(iFan0), Odc_Not(iFan1)) );
618}
619
631static inline Odc_Lit_t Odc_Xor( Odc_Man_t * p, Odc_Lit_t iFan0, Odc_Lit_t iFan1 )
632{
633 return Odc_Or( p, Odc_And(p, iFan0, Odc_Not(iFan1)), Odc_And(p, Odc_Not(iFan0), iFan1) );
634}
635
636
637
638
639
652{
653 unsigned uData0, uData1;
654 Odc_Lit_t uLit0, uLit1, uRes0, uRes1;
655 assert( !Abc_ObjIsComplement(pNode) );
656 // skip visited objects
657 if ( Abc_NodeIsTravIdCurrent(pNode) )
658 return pNode->pCopy;
659 Abc_NodeSetTravIdCurrent(pNode);
660 assert( Abc_ObjIsNode(pNode) );
661 // consider the case when the node is the pivot
662 if ( pNode == pPivot )
663 return pNode->pCopy = (Abc_Obj_t *)(ABC_PTRUINT_T)((Odc_Const1() << 16) | Odc_Const0());
664 // compute the cofactors
665 uData0 = (unsigned)(ABC_PTRUINT_T)Abc_NtkDontCareTransfer_rec( p, Abc_ObjFanin0(pNode), pPivot );
666 uData1 = (unsigned)(ABC_PTRUINT_T)Abc_NtkDontCareTransfer_rec( p, Abc_ObjFanin1(pNode), pPivot );
667 // find the 0-cofactor
668 uLit0 = Odc_NotCond( (Odc_Lit_t)(uData0 & 0xffff), Abc_ObjFaninC0(pNode) );
669 uLit1 = Odc_NotCond( (Odc_Lit_t)(uData1 & 0xffff), Abc_ObjFaninC1(pNode) );
670 uRes0 = Odc_And( p, uLit0, uLit1 );
671 // find the 1-cofactor
672 uLit0 = Odc_NotCond( (Odc_Lit_t)(uData0 >> 16), Abc_ObjFaninC0(pNode) );
673 uLit1 = Odc_NotCond( (Odc_Lit_t)(uData1 >> 16), Abc_ObjFaninC1(pNode) );
674 uRes1 = Odc_And( p, uLit0, uLit1 );
675 // find the result
676 return pNode->pCopy = (Abc_Obj_t *)(ABC_PTRUINT_T)((uRes1 << 16) | uRes0);
677}
678
691{
692 Abc_Obj_t * pObj;
693 Odc_Lit_t uRes0, uRes1;
694 Odc_Lit_t uLit;
695 unsigned uData;
696 int i;
697 Abc_NtkIncrementTravId( p->pNode->pNtk );
698 // set elementary variables at the leaves
699 Vec_PtrForEachEntry( Abc_Obj_t *, p->vLeaves, pObj, i )
700 {
701 uLit = Odc_Var( p, i );
702 pObj->pCopy = (Abc_Obj_t *)(ABC_PTRUINT_T)((uLit << 16) | uLit);
703 Abc_NodeSetTravIdCurrent(pObj);
704 }
705 // set elementary variables at the branched
706 Vec_PtrForEachEntry( Abc_Obj_t *, p->vBranches, pObj, i )
707 {
708 uLit = Odc_Var( p, i+p->nVarsMax );
709 pObj->pCopy = (Abc_Obj_t *)(ABC_PTRUINT_T)((uLit << 16) | uLit);
710 Abc_NodeSetTravIdCurrent(pObj);
711 }
712 // compute the AIG for the window
713 p->iRoot = Odc_Const0();
714 Vec_PtrForEachEntry( Abc_Obj_t *, p->vRoots, pObj, i )
715 {
716 uData = (unsigned)(ABC_PTRUINT_T)Abc_NtkDontCareTransfer_rec( p, pObj, p->pNode );
717 // get the cofactors
718 uRes0 = uData & 0xffff;
719 uRes1 = uData >> 16;
720 // compute the miter
721// assert( uRes0 != uRes1 ); // may be false if the node is redundant w.r.t. this root
722 uLit = Odc_Xor( p, uRes0, uRes1 );
723 p->iRoot = Odc_Or( p, p->iRoot, uLit );
724 }
725 return 1;
726}
727
728
740unsigned Abc_NtkDontCareCofactors_rec( Odc_Man_t * p, Odc_Lit_t Lit, unsigned uMask )
741{
742 Odc_Obj_t * pObj;
743 unsigned uData0, uData1;
744 Odc_Lit_t uLit0, uLit1, uRes0, uRes1;
745 assert( !Odc_IsComplement(Lit) );
746 // skip visited objects
747 pObj = Odc_Lit2Obj( p, Lit );
748 if ( Odc_ObjIsTravIdCurrent(p, pObj) )
749 {
750 p->skipQuant = 1;
751 return pObj->uData;
752 }
753 Odc_ObjSetTravIdCurrent(p, pObj);
754 // skip objects out of the cone
755 if ( (pObj->uMask & uMask) == 0 )
756 return pObj->uData = ((Lit << 16) | Lit);
757 // consider the case when the node is the var
758 if ( pObj->uMask == uMask && Odc_IsTerm(p, Lit) )
759 return pObj->uData = ((Odc_Const1() << 16) | Odc_Const0());
760 // compute the cofactors
761 uData0 = Abc_NtkDontCareCofactors_rec( p, Odc_ObjFanin0(pObj), uMask );
762 uData1 = Abc_NtkDontCareCofactors_rec( p, Odc_ObjFanin1(pObj), uMask );
763 // find the 0-cofactor
764 uLit0 = Odc_NotCond( (Odc_Lit_t)(uData0 & 0xffff), Odc_ObjFaninC0(pObj) );
765 uLit1 = Odc_NotCond( (Odc_Lit_t)(uData1 & 0xffff), Odc_ObjFaninC1(pObj) );
766 uRes0 = Odc_And( p, uLit0, uLit1 );
767 // find the 1-cofactor
768 uLit0 = Odc_NotCond( (Odc_Lit_t)(uData0 >> 16), Odc_ObjFaninC0(pObj) );
769 uLit1 = Odc_NotCond( (Odc_Lit_t)(uData1 >> 16), Odc_ObjFaninC1(pObj) );
770 uRes1 = Odc_And( p, uLit0, uLit1 );
771 // find the result
772 p->skipQuant = 0;
773 return pObj->uData = ((uRes1 << 16) | uRes0);
774}
775
788{
789 Odc_Lit_t uRes0, uRes1;
790 unsigned uData;
791 int i;
792 p->skipQuant = 0;
793 assert( p->iRoot < 0xffff );
794 assert( Vec_PtrSize(p->vBranches) <= 32 ); // the mask size
795 for ( i = 0; i < Vec_PtrSize(p->vBranches); i++ )
796 {
797 // compute the cofactors w.r.t. this variable
798 Odc_ManIncrementTravId( p );
799 uData = Abc_NtkDontCareCofactors_rec( p, Odc_Regular(p->iRoot), (1 << i) );
800 if ( p->skipQuant )
801 continue;
802 uRes0 = Odc_NotCond( (Odc_Lit_t)(uData & 0xffff), Odc_IsComplement(p->iRoot) );
803 uRes1 = Odc_NotCond( (Odc_Lit_t)(uData >> 16), Odc_IsComplement(p->iRoot) );
804 // quantify this variable existentially
805 p->iRoot = Odc_Or( p, uRes0, uRes1 );
806 // check the limit
807 if ( Odc_ObjNum(p) > ABC_DC_MAX_NODES/2 )
808 return 0;
809 }
810 assert( p->nObjs <= p->nObjsAlloc );
811 return 1;
812}
813
814
815
828{
829 unsigned * pData;
830 int i, k;
831 for ( k = 0; k < p->nVarsMax; k++ )
832 {
833 pData = Odc_ObjTruth( p, Odc_Var(p, k) );
834 Abc_InfoClear( pData, p->nWords );
835 for ( i = 0; i < p->nBits; i++ )
836 if ( i & (1 << k) )
837 pData[i>>5] |= (1 << (i&31));
838 }
839}
840
853{
854 unsigned * pData, * pData2;
855 int k;
856 for ( k = 0; k < p->nVarsMax; k++ )
857 {
858 pData = Odc_ObjTruth( p, Odc_Var(p, k) );
859 pData2 = (unsigned *)Vec_PtrEntry( p->vTruthsElem, k );
860 Abc_InfoCopy( pData, pData2, p->nWords );
861 }
862}
863
876{
877 unsigned * pData;
878 int w, k, Number;
879 for ( w = 0; w < p->nWords; w++ )
880 {
881 Number = rand();
882 for ( k = 0; k < p->nVarsMax; k++ )
883 {
884 pData = Odc_ObjTruth( p, Odc_Var(p, k) );
885 pData[w] = (Number & (1<<k)) ? ~0 : 0;
886 }
887 }
888}
889
901int Abc_NtkDontCareCountMintsWord( Odc_Man_t * p, unsigned * puTruth )
902{
903 int w, Counter = 0;
904 for ( w = 0; w < p->nWords; w++ )
905 if ( puTruth[w] )
906 Counter++;
907 return Counter;
908}
909
922{
923 Odc_Obj_t * pObj;
924 unsigned * pInfo, * pInfo1, * pInfo2;
925 int k, fComp1, fComp2;
926 assert( !Odc_IsComplement( Lit ) );
927 assert( !Odc_IsTerm( p, Lit ) );
928 // get the truth tables
929 pObj = Odc_Lit2Obj( p, Lit );
930 pInfo = Odc_ObjTruth( p, Lit );
931 pInfo1 = Odc_ObjTruth( p, Odc_ObjFanin0(pObj) );
932 pInfo2 = Odc_ObjTruth( p, Odc_ObjFanin1(pObj) );
933 fComp1 = Odc_ObjFaninC0( pObj );
934 fComp2 = Odc_ObjFaninC1( pObj );
935 // simulate
936 if ( fComp1 && fComp2 )
937 for ( k = 0; k < p->nWords; k++ )
938 pInfo[k] = ~pInfo1[k] & ~pInfo2[k];
939 else if ( fComp1 && !fComp2 )
940 for ( k = 0; k < p->nWords; k++ )
941 pInfo[k] = ~pInfo1[k] & pInfo2[k];
942 else if ( !fComp1 && fComp2 )
943 for ( k = 0; k < p->nWords; k++ )
944 pInfo[k] = pInfo1[k] & ~pInfo2[k];
945 else // if ( fComp1 && fComp2 )
946 for ( k = 0; k < p->nWords; k++ )
947 pInfo[k] = pInfo1[k] & pInfo2[k];
948}
949
962{
963 Odc_Obj_t * pObj;
964 assert( !Odc_IsComplement(Lit) );
965 // skip terminals
966 if ( Odc_IsTerm(p, Lit) )
967 return;
968 // skip visited objects
969 pObj = Odc_Lit2Obj( p, Lit );
970 if ( Odc_ObjIsTravIdCurrent(p, pObj) )
971 return;
972 Odc_ObjSetTravIdCurrent(p, pObj);
973 // call recursively
974 Abc_NtkDontCareSimulate_rec( p, Odc_ObjFanin0(pObj) );
975 Abc_NtkDontCareSimulate_rec( p, Odc_ObjFanin1(pObj) );
976 // construct the truth table
978}
979
991int Abc_NtkDontCareSimulate( Odc_Man_t * p, unsigned * puTruth )
992{
993 Odc_ManIncrementTravId( p );
994 Abc_NtkDontCareSimulate_rec( p, Odc_Regular(p->iRoot) );
995 Abc_InfoCopy( puTruth, Odc_ObjTruth(p, Odc_Regular(p->iRoot)), p->nWords );
996 if ( Odc_IsComplement(p->iRoot) )
997 Abc_InfoNot( puTruth, p->nWords );
998 return Extra_TruthCountOnes( puTruth, p->nVarsMax );
999}
1000
1012int Abc_NtkDontCareSimulateBefore( Odc_Man_t * p, unsigned * puTruth )
1013{
1014 int nIters = 2;
1015 int nRounds, Counter, r;
1016 // decide how many rounds to simulate
1017 nRounds = p->nBits / p->nWords;
1018 Counter = 0;
1019 for ( r = 0; r < nIters; r++ )
1020 {
1022 Abc_NtkDontCareSimulate( p, puTruth );
1023 Counter += Abc_NtkDontCareCountMintsWord( p, puTruth );
1024 }
1025 // normalize
1026 Counter = Counter * nRounds / nIters;
1027 return Counter;
1028}
1029
1042int Abc_NtkDontCareCompute( Odc_Man_t * p, Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves, unsigned * puTruth )
1043{
1044 int nMints, RetValue;
1045 abctime clk, clkTotal = Abc_Clock();
1046
1047 p->nWins++;
1048
1049 // set the parameters
1050 assert( !Abc_ObjIsComplement(pNode) );
1051 assert( Abc_ObjIsNode(pNode) );
1052 assert( Vec_PtrSize(vLeaves) <= p->nVarsMax );
1053 p->vLeaves = vLeaves;
1054 p->pNode = pNode;
1055
1056 // compute the window
1057clk = Abc_Clock();
1058 RetValue = Abc_NtkDontCareWindow( p );
1059p->timeWin += Abc_Clock() - clk;
1060 if ( !RetValue )
1061 {
1062p->timeAbort += Abc_Clock() - clkTotal;
1063 Abc_InfoFill( puTruth, p->nWords );
1064 p->nWinsEmpty++;
1065 return 0;
1066 }
1067
1068 if ( p->fVeryVerbose )
1069 {
1070 printf( " %5d : ", pNode->Id );
1071 printf( "Leaf = %2d ", Vec_PtrSize(p->vLeaves) );
1072 printf( "Root = %2d ", Vec_PtrSize(p->vRoots) );
1073 printf( "Bran = %2d ", Vec_PtrSize(p->vBranches) );
1074 printf( " | " );
1075 }
1076
1077 // transfer the window into the AIG package
1078clk = Abc_Clock();
1080p->timeMiter += Abc_Clock() - clk;
1081
1082 // simulate to estimate the amount of don't-cares
1083clk = Abc_Clock();
1084 nMints = Abc_NtkDontCareSimulateBefore( p, puTruth );
1085p->timeSim += Abc_Clock() - clk;
1086 if ( p->fVeryVerbose )
1087 {
1088 printf( "AIG = %5d ", Odc_NodeNum(p) );
1089 printf( "%6.2f %% ", 100.0 * (p->nBits - nMints) / p->nBits );
1090 }
1091
1092 // if there is less then the given percentage of don't-cares, skip
1093 if ( 100.0 * (p->nBits - nMints) / p->nBits < 1.0 * p->nPercCutoff )
1094 {
1095p->timeAbort += Abc_Clock() - clkTotal;
1096 if ( p->fVeryVerbose )
1097 printf( "Simulation cutoff.\n" );
1098 Abc_InfoFill( puTruth, p->nWords );
1099 p->nSimsEmpty++;
1100 return 0;
1101 }
1102
1103 // quantify external variables
1104clk = Abc_Clock();
1105 RetValue = Abc_NtkDontCareQuantify( p );
1106p->timeQuant += Abc_Clock() - clk;
1107 if ( !RetValue )
1108 {
1109p->timeAbort += Abc_Clock() - clkTotal;
1110 if ( p->fVeryVerbose )
1111 printf( "=== Overflow! ===\n" );
1112 Abc_InfoFill( puTruth, p->nWords );
1113 p->nQuantsOver++;
1114 return 0;
1115 }
1116
1117 // get the truth table
1118clk = Abc_Clock();
1120 nMints = Abc_NtkDontCareSimulate( p, puTruth );
1121p->timeTruth += Abc_Clock() - clk;
1122 if ( p->fVeryVerbose )
1123 {
1124 printf( "AIG = %5d ", Odc_NodeNum(p) );
1125 printf( "%6.2f %% ", 100.0 * (p->nBits - nMints) / p->nBits );
1126 printf( "\n" );
1127 }
1128p->timeTotal += Abc_Clock() - clkTotal;
1129 p->nWinsFinish++;
1130 p->nTotalDcs += (int)(100.0 * (p->nBits - nMints) / p->nBits);
1131 return nMints;
1132}
1133
1134
1138
1139
1141
void Abc_NtkDontCareSimulateSetElem2(Odc_Man_t *p)
Definition abcOdc.c:827
int Abc_NtkDontCareCountMintsWord(Odc_Man_t *p, unsigned *puTruth)
Definition abcOdc.c:901
unsigned short Odc_Lit_t
Definition abcOdc.c:32
int Abc_NtkDontCareTransfer(Odc_Man_t *p)
Definition abcOdc.c:690
int Abc_NtkDontCareQuantify(Odc_Man_t *p)
Definition abcOdc.c:787
int Abc_NtkDontCareWindow(Odc_Man_t *p)
Definition abcOdc.c:479
void Abc_NtkDontCareWinSweepLeafTfo(Odc_Man_t *p)
Definition abcOdc.c:346
void Abc_NtkDontCareFree(Odc_Man_t *p)
Definition abcOdc.c:276
#define ABC_DC_MAX_NODES
DECLARATIONS ///.
Definition abcOdc.c:30
int Abc_NtkDontCareSimulateBefore(Odc_Man_t *p, unsigned *puTruth)
Definition abcOdc.c:1012
int Abc_NtkDontCareSimulate(Odc_Man_t *p, unsigned *puTruth)
Definition abcOdc.c:991
int Abc_NtkDontCareCompute(Odc_Man_t *p, Abc_Obj_t *pNode, Vec_Ptr_t *vLeaves, unsigned *puTruth)
Definition abcOdc.c:1042
void Abc_NtkDontCareWinSweepLeafTfo_rec(Abc_Obj_t *pObj, int nLevelLimit, Abc_Obj_t *pNode)
Definition abcOdc.c:317
unsigned Abc_NtkDontCareCofactors_rec(Odc_Man_t *p, Odc_Lit_t Lit, unsigned uMask)
Definition abcOdc.c:740
void Abc_NtkDontCareSimulateSetRand(Odc_Man_t *p)
Definition abcOdc.c:875
void Abc_NtkDontCareTruthOne(Odc_Man_t *p, Odc_Lit_t Lit)
Definition abcOdc.c:921
void Abc_NtkDontCareWinCollectRoots(Odc_Man_t *p)
Definition abcOdc.c:399
void Abc_NtkDontCareSimulateSetElem(Odc_Man_t *p)
Definition abcOdc.c:852
int Abc_NtkDontCareWinAddMissing(Odc_Man_t *p)
Definition abcOdc.c:452
struct Odc_Obj_t_ Odc_Obj_t
Definition abcOdc.c:34
void Abc_NtkDontCareSimulate_rec(Odc_Man_t *p, Odc_Lit_t Lit)
Definition abcOdc.c:961
void * Abc_NtkDontCareTransfer_rec(Odc_Man_t *p, Abc_Obj_t *pNode, Abc_Obj_t *pPivot)
Definition abcOdc.c:651
void Abc_NtkDontCareWinCollectRoots_rec(Abc_Obj_t *pObj, Vec_Ptr_t *vRoots)
Definition abcOdc.c:366
void Abc_NtkDontCareClear(Odc_Man_t *p)
Definition abcOdc.c:244
int Abc_NtkDontCareWinAddMissing_rec(Odc_Man_t *p, Abc_Obj_t *pObj)
Definition abcOdc.c:420
Odc_Man_t * Abc_NtkDontCareAlloc(int nVarsMax, int nLevels, int fVerbose, int fVeryVerbose)
FUNCTION DEFINITIONS ///.
Definition abcOdc.c:163
struct Abc_Obj_t_ Abc_Obj_t
Definition abc.h:116
#define Abc_ObjForEachFanin(pObj, pFanin, i)
Definition abc.h:527
#define Abc_ObjForEachFanout(pObj, pFanout, i)
Definition abc.h:529
struct Odc_Man_t_ Odc_Man_t
Definition abc.h:832
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_FREE(obj)
Definition abc_global.h:267
#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
Cube * p
Definition exorList.c:222
int Id
Definition abc.h:132
Abc_Obj_t * pCopy
Definition abc.h:148
unsigned Level
Definition abc.h:142
int nTotalDcs
Definition abcOdc.c:87
int nTableSize
Definition abcOdc.c:71
Odc_Obj_t * pObjs
Definition abcOdc.c:66
Abc_Obj_t * pNode
Definition abcOdc.c:56
Odc_Lit_t iRoot
Definition abcOdc.c:67
unsigned * puTruth
Definition abcOdc.c:79
unsigned short nTravIds
Definition abcOdc.c:68
abctime timeClean
Definition abcOdc.c:90
int nWins
Definition abcOdc.c:82
Vec_Ptr_t * vTruthsElem
Definition abcOdc.c:78
abctime timeQuant
Definition abcOdc.c:94
abctime timeTotal
Definition abcOdc.c:96
Vec_Int_t * vUsedSpots
Definition abcOdc.c:72
abctime timeTruth
Definition abcOdc.c:95
int nObjsAlloc
Definition abcOdc.c:65
int nWords
Definition abcOdc.c:76
int nVarsMax
Definition abcOdc.c:48
int nPercCutoff
Definition abcOdc.c:52
abctime timeMiter
Definition abcOdc.c:92
int nLevels
Definition abcOdc.c:49
int nPis
Definition abcOdc.c:63
abctime timeWin
Definition abcOdc.c:91
Vec_Ptr_t * vLeaves
Definition abcOdc.c:57
int nBits
Definition abcOdc.c:75
abctime timeAbort
Definition abcOdc.c:97
Vec_Ptr_t * vRoots
Definition abcOdc.c:58
int fVerbose
Definition abcOdc.c:50
int nWinsEmpty
Definition abcOdc.c:83
int nQuantsOver
Definition abcOdc.c:85
Vec_Ptr_t * vTruths
Definition abcOdc.c:77
Vec_Ptr_t * vBranches
Definition abcOdc.c:59
int nSimsEmpty
Definition abcOdc.c:84
int nWinsFinish
Definition abcOdc.c:86
abctime timeSim
Definition abcOdc.c:93
int fVeryVerbose
Definition abcOdc.c:51
Odc_Lit_t * pTable
Definition abcOdc.c:70
int nObjs
Definition abcOdc.c:64
int skipQuant
Definition abcOdc.c:53
unsigned uData
Definition abcOdc.c:41
unsigned uMask
Definition abcOdc.c:42
Odc_Lit_t iFan1
Definition abcOdc.c:38
unsigned short TravId
Definition abcOdc.c:40
Odc_Lit_t iNext
Definition abcOdc.c:39
Odc_Lit_t iFan0
Definition abcOdc.c:37
#define assert(ex)
Definition util_old.h:213
char * memset()
#define Vec_IntForEachEntry(vVec, Entry, i)
MACRO DEFINITIONS ///.
Definition vecInt.h:54
typedefABC_NAMESPACE_HEADER_START struct Vec_Ptr_t_ Vec_Ptr_t
INCLUDES ///.
Definition vecPtr.h:42
#define Vec_PtrForEachEntry(Type, vVec, pEntry, i)
MACRO DEFINITIONS ///.
Definition vecPtr.h:55