ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
ivySeq.c
Go to the documentation of this file.
1
20
21#include "ivy.h"
22#include "bool/deco/deco.h"
23#include "opt/rwt/rwt.h"
24
26
27
31
32static int Ivy_NodeRewriteSeq( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pNode, int fUseZeroCost );
33static void Ivy_GraphPrepare( Dec_Graph_t * pGraph, Ivy_Cut_t * pCut, Vec_Ptr_t * vFanins, char * pPerm );
34static unsigned Ivy_CutGetTruth( Ivy_Man_t * p, Ivy_Obj_t * pObj, int * pNums, int nNums );
35static Dec_Graph_t * Rwt_CutEvaluateSeq( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pRoot, Ivy_Cut_t * pCut, char * pPerm, Vec_Ptr_t * vFaninsCur, int nNodesSaved, int * pGainBest, unsigned uTruth );
36static int Ivy_GraphToNetworkSeqCountSeq( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMax );
37static Ivy_Obj_t * Ivy_GraphToNetworkSeq( Ivy_Man_t * p, Dec_Graph_t * pGraph );
38static void Ivy_GraphUpdateNetworkSeq( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int nGain );
39static Ivy_Store_t * Ivy_CutComputeForNode( Ivy_Man_t * p, Ivy_Obj_t * pObj, int nLeaves );
40
41static inline int Ivy_CutHashValue( int NodeId ) { return 1 << (NodeId % 31); }
42
46
47//int nMoves;
48//int nMovesS;
49//int nClauses;
50//int timeInv;
51
63int Ivy_ManRewriteSeq( Ivy_Man_t * p, int fUseZeroCost, int fVerbose )
64{
65 Rwt_Man_t * pManRwt;
66 Ivy_Obj_t * pNode;
67 int i, nNodes, nGain;
68 abctime clk, clkStart = Abc_Clock();
69
70 // set the DC latch values
71 Ivy_ManForEachLatch( p, pNode, i )
72 pNode->Init = IVY_INIT_DC;
73 // start the rewriting manager
74 pManRwt = Rwt_ManStart( 0 );
75 p->pData = pManRwt;
76 if ( pManRwt == NULL )
77 return 0;
78 // create fanouts
79 if ( p->fFanout == 0 )
81 // resynthesize each node once
82 nNodes = Ivy_ManObjIdMax(p);
83 Ivy_ManForEachNode( p, pNode, i )
84 {
85 assert( !Ivy_ObjIsBuf(pNode) );
86 assert( !Ivy_ObjIsBuf(Ivy_ObjFanin0(pNode)) );
87 assert( !Ivy_ObjIsBuf(Ivy_ObjFanin1(pNode)) );
88 // fix the fanin buffer problem
89// Ivy_NodeFixBufferFanins( p, pNode );
90// if ( Ivy_ObjIsBuf(pNode) )
91// continue;
92 // stop if all nodes have been tried once
93 if ( i > nNodes )
94 break;
95 // for each cut, try to resynthesize it
96 nGain = Ivy_NodeRewriteSeq( p, pManRwt, pNode, fUseZeroCost );
97 if ( nGain > 0 || (nGain == 0 && fUseZeroCost) )
98 {
99 Dec_Graph_t * pGraph = (Dec_Graph_t *)Rwt_ManReadDecs(pManRwt);
100 int fCompl = Rwt_ManReadCompl(pManRwt);
101 // complement the FF if needed
102clk = Abc_Clock();
103 if ( fCompl ) Dec_GraphComplement( pGraph );
104 Ivy_GraphUpdateNetworkSeq( p, pNode, pGraph, nGain );
105 if ( fCompl ) Dec_GraphComplement( pGraph );
106Rwt_ManAddTimeUpdate( pManRwt, Abc_Clock() - clk );
107 }
108 }
109Rwt_ManAddTimeTotal( pManRwt, Abc_Clock() - clkStart );
110 // print stats
111 if ( fVerbose )
112 Rwt_ManPrintStats( pManRwt );
113 // delete the managers
114 Rwt_ManStop( pManRwt );
115 p->pData = NULL;
116 // fix the levels
118// if ( Ivy_ManCheckFanoutNums(p) )
119// printf( "Ivy_ManRewritePre(): The check has failed.\n" );
120 // check
121 if ( !Ivy_ManCheck(p) )
122 printf( "Ivy_ManRewritePre(): The check has failed.\n" );
123 return 1;
124}
125
126
145int Ivy_NodeRewriteSeq( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pNode, int fUseZeroCost )
146{
147 int fVeryVerbose = 0;
148 Dec_Graph_t * pGraph;
149 Ivy_Store_t * pStore;
150 Ivy_Cut_t * pCut;
151 Ivy_Obj_t * pFanin;//, * pFanout;
152 Vec_Ptr_t * vFanout;
153 unsigned uPhase;
154 unsigned uTruthBest = 0; // Suppress "might be used uninitialized"
155 unsigned uTruth;//, nNewClauses;
156 char * pPerm;
157 int nNodesSaved;
158 int nNodesSaveCur = -1; // Suppress "might be used uninitialized"
159 int i, c, GainCur = -1, GainBest = -1;
160 abctime clk, clk2;//, clk3;
161
162 p->nNodesConsidered++;
163 // get the node's cuts
164clk = Abc_Clock();
165 pStore = Ivy_CutComputeForNode( pMan, pNode, 5 );
166p->timeCut += Abc_Clock() - clk;
167
168 // go through the cuts
169clk = Abc_Clock();
170 vFanout = Vec_PtrAlloc( 100 );
171 for ( c = 1; c < pStore->nCuts; c++ )
172 {
173 pCut = pStore->pCuts + c;
174 // consider only 4-input cuts
175 if ( pCut->nSize != 4 )
176 continue;
177 // skip the cuts with buffers
178 for ( i = 0; i < (int)pCut->nSize; i++ )
179 if ( Ivy_ObjIsBuf( Ivy_ManObj(pMan, Ivy_LeafId(pCut->pArray[i])) ) )
180 break;
181 if ( i != pCut->nSize )
182 {
183 p->nCutsBad++;
184 continue;
185 }
186 p->nCutsGood++;
187 // get the fanin permutation
188clk2 = Abc_Clock();
189 uTruth = 0xFFFF & Ivy_CutGetTruth( pMan, pNode, pCut->pArray, pCut->nSize ); // truth table
190p->timeTruth += Abc_Clock() - clk2;
191 pPerm = p->pPerms4[ (int)p->pPerms[uTruth] ];
192 uPhase = p->pPhases[uTruth];
193 // collect fanins with the corresponding permutation/phase
194 Vec_PtrClear( p->vFaninsCur );
195 Vec_PtrFill( p->vFaninsCur, (int)pCut->nSize, 0 );
196 for ( i = 0; i < (int)pCut->nSize; i++ )
197 {
198 pFanin = Ivy_ManObj( pMan, Ivy_LeafId( pCut->pArray[(int)pPerm[i]] ) );
199 assert( Ivy_ObjIsNode(pFanin) || Ivy_ObjIsCi(pFanin) || Ivy_ObjIsConst1(pFanin) );
200 pFanin = Ivy_NotCond(pFanin, ((uPhase & (1<<i)) > 0) );
201 Vec_PtrWriteEntry( p->vFaninsCur, i, pFanin );
202 }
203clk2 = Abc_Clock();
204 // mark the fanin boundary
205 Vec_PtrForEachEntry( Ivy_Obj_t *, p->vFaninsCur, pFanin, i )
206 Ivy_ObjRefsInc( Ivy_Regular(pFanin) );
207 // label MFFC with current ID
209 nNodesSaved = Ivy_ObjMffcLabel( pMan, pNode );
210 // label fanouts with the current ID
211// Ivy_ObjForEachFanout( pMan, pNode, vFanout, pFanout, i )
212// Ivy_ObjSetTravIdCurrent( pMan, pFanout );
213 // unmark the fanin boundary
214 Vec_PtrForEachEntry( Ivy_Obj_t *, p->vFaninsCur, pFanin, i )
215 Ivy_ObjRefsDec( Ivy_Regular(pFanin) );
216p->timeMffc += Abc_Clock() - clk2;
217
218 // evaluate the cut
219clk2 = Abc_Clock();
220 pGraph = Rwt_CutEvaluateSeq( pMan, p, pNode, pCut, pPerm, p->vFaninsCur, nNodesSaved, &GainCur, uTruth );
221p->timeEval += Abc_Clock() - clk2;
222
223
224 // check if the cut is better than the current best one
225 if ( pGraph != NULL && GainBest < GainCur )
226 {
227 // save this form
228 nNodesSaveCur = nNodesSaved;
229 GainBest = GainCur;
230 p->pGraph = pGraph;
231 p->pCut = pCut;
232 p->pPerm = pPerm;
233 p->fCompl = ((uPhase & (1<<4)) > 0);
234 uTruthBest = uTruth;
235 // collect fanins in the
236 Vec_PtrClear( p->vFanins );
237 Vec_PtrForEachEntry( Ivy_Obj_t *, p->vFaninsCur, pFanin, i )
238 Vec_PtrPush( p->vFanins, pFanin );
239 }
240 }
241 Vec_PtrFree( vFanout );
242p->timeRes += Abc_Clock() - clk;
243
244 if ( GainBest == -1 )
245 return -1;
246/*
247 {
248 Ivy_Cut_t * pCut = p->pCut;
249 printf( "Node %5d. Using cut : {", Ivy_ObjId(pNode) );
250 for ( i = 0; i < pCut->nSize; i++ )
251 printf( " %d(%d)", Ivy_LeafId(pCut->pArray[i]), Ivy_LeafLat(pCut->pArray[i]) );
252 printf( " }\n" );
253 }
254*/
255
256//clk3 = Abc_Clock();
257//nNewClauses = Ivy_CutTruthPrint( pMan, p->pCut, uTruth );
258//timeInv += Abc_Clock() - clk;
259
260// nClauses += nNewClauses;
261// nMoves++;
262// if ( nNewClauses > 0 )
263// nMovesS++;
264
265 // copy the leaves
266 Ivy_GraphPrepare( (Dec_Graph_t *)p->pGraph, (Ivy_Cut_t *)p->pCut, p->vFanins, p->pPerm );
267
268 p->nScores[p->pMap[uTruthBest]]++;
269 p->nNodesGained += GainBest;
270 if ( fUseZeroCost || GainBest > 0 )
271 p->nNodesRewritten++;
272
273/*
274 if ( GainBest > 0 )
275 {
276 Ivy_Cut_t * pCut = p->pCut;
277 printf( "Node %5d. Using cut : {", Ivy_ObjId(pNode) );
278 for ( i = 0; i < pCut->nSize; i++ )
279 printf( " %5d(%2d)", Ivy_LeafId(pCut->pArray[i]), Ivy_LeafLat(pCut->pArray[i]) );
280 printf( " }\n" );
281 }
282*/
283
284 // report the progress
285 if ( fVeryVerbose && GainBest > 0 )
286 {
287 printf( "Node %6d : ", Ivy_ObjId(pNode) );
288 printf( "Fanins = %d. ", p->vFanins->nSize );
289 printf( "Save = %d. ", nNodesSaveCur );
290 printf( "Add = %d. ", nNodesSaveCur-GainBest );
291 printf( "GAIN = %d. ", GainBest );
292 printf( "Cone = %d. ", p->pGraph? Dec_GraphNodeNum((Dec_Graph_t *)p->pGraph) : 0 );
293 printf( "Class = %d. ", p->pMap[uTruthBest] );
294 printf( "\n" );
295 }
296 return GainBest;
297}
298
299
311Dec_Graph_t * Rwt_CutEvaluateSeq( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pRoot, Ivy_Cut_t * pCut, char * pPerm, Vec_Ptr_t * vFaninsCur, int nNodesSaved, int * pGainBest, unsigned uTruth )
312{
313 Vec_Ptr_t * vSubgraphs;
314 Dec_Graph_t * pGraphBest = NULL; // Suppress "might be used uninitialized"
315 Dec_Graph_t * pGraphCur;
316 Rwt_Node_t * pNode;
317 int nNodesAdded, GainBest, i;
318 // find the matching class of subgraphs
319 vSubgraphs = Vec_VecEntry( p->vClasses, p->pMap[uTruth] );
320 p->nSubgraphs += vSubgraphs->nSize;
321 // determine the best subgraph
322 GainBest = -1;
323 Vec_PtrForEachEntry( Rwt_Node_t *, vSubgraphs, pNode, i )
324 {
325 // get the current graph
326 pGraphCur = (Dec_Graph_t *)pNode->pNext;
327
328// if ( pRoot->Id == 8648 )
329// Dec_GraphPrint( stdout, pGraphCur, NULL, NULL );
330 // copy the leaves
331// Vec_PtrForEachEntry( Ivy_Obj_t *, vFaninsCur, pFanin, k )
332// Dec_GraphNode(pGraphCur, k)->pFunc = pFanin;
333 Ivy_GraphPrepare( pGraphCur, pCut, vFaninsCur, pPerm );
334
335 // detect how many unlabeled nodes will be reused
336 nNodesAdded = Ivy_GraphToNetworkSeqCountSeq( pMan, pRoot, pGraphCur, nNodesSaved );
337 if ( nNodesAdded == -1 )
338 continue;
339 assert( nNodesSaved >= nNodesAdded );
340 // count the gain at this node
341 if ( GainBest < nNodesSaved - nNodesAdded )
342 {
343 GainBest = nNodesSaved - nNodesAdded;
344 pGraphBest = pGraphCur;
345 }
346 }
347 if ( GainBest == -1 )
348 return NULL;
349 *pGainBest = GainBest;
350 return pGraphBest;
351}
352
364void Ivy_GraphPrepare( Dec_Graph_t * pGraph, Ivy_Cut_t * pCut, Vec_Ptr_t * vFanins, char * pPerm )
365{
366 Dec_Node_t * pNode, * pNode0, * pNode1;
367 int i;
368 assert( Dec_GraphLeaveNum(pGraph) == pCut->nSize );
369 assert( Vec_PtrSize(vFanins) == pCut->nSize );
370 // label the leaves with latch numbers
371 Dec_GraphForEachLeaf( pGraph, pNode, i )
372 {
373 pNode->pFunc = Vec_PtrEntry( vFanins, i );
374 pNode->nLat2 = Ivy_LeafLat( pCut->pArray[(int)pPerm[i]] );
375 }
376 // propagate latches through the nodes
377 Dec_GraphForEachNode( pGraph, pNode, i )
378 {
379 // get the children of this node
380 pNode0 = Dec_GraphNode( pGraph, pNode->eEdge0.Node );
381 pNode1 = Dec_GraphNode( pGraph, pNode->eEdge1.Node );
382 // distribute the latches
383 pNode->nLat2 = IVY_MIN( pNode0->nLat2, pNode1->nLat2 );
384 pNode->nLat0 = pNode0->nLat2 - pNode->nLat2;
385 pNode->nLat1 = pNode1->nLat2 - pNode->nLat2;
386 }
387}
388
403int Ivy_GraphToNetworkSeqCountSeq( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMax )
404{
405 Dec_Node_t * pNode, * pNode0, * pNode1;
406 Ivy_Obj_t * pAnd, * pAnd0, * pAnd1;
407 int i, k, Counter, fCompl;
408 // check for constant function or a literal
409 if ( Dec_GraphIsConst(pGraph) || Dec_GraphIsVar(pGraph) )
410 return 0;
411 // compute the AIG size after adding the internal nodes
412 Counter = 0;
413 Dec_GraphForEachNode( pGraph, pNode, i )
414 {
415 // get the children of this node
416 pNode0 = Dec_GraphNode( pGraph, pNode->eEdge0.Node );
417 pNode1 = Dec_GraphNode( pGraph, pNode->eEdge1.Node );
418 // get the AIG nodes corresponding to the children
419 pAnd0 = (Ivy_Obj_t *)pNode0->pFunc;
420 pAnd1 = (Ivy_Obj_t *)pNode1->pFunc;
421 // skip the latches
422 for ( k = 0; pAnd0 && k < (int)pNode->nLat0; k++ )
423 {
424 fCompl = Ivy_IsComplement(pAnd0);
425 pAnd0 = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, Ivy_Regular(pAnd0), NULL, IVY_LATCH, IVY_INIT_DC) );
426 if ( pAnd0 )
427 pAnd0 = Ivy_NotCond( pAnd0, fCompl );
428 }
429 for ( k = 0; pAnd1 && k < (int)pNode->nLat1; k++ )
430 {
431 fCompl = Ivy_IsComplement(pAnd1);
432 pAnd1 = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, Ivy_Regular(pAnd1), NULL, IVY_LATCH, IVY_INIT_DC) );
433 if ( pAnd1 )
434 pAnd1 = Ivy_NotCond( pAnd1, fCompl );
435 }
436 // get the new node
437 if ( pAnd0 && pAnd1 )
438 {
439 // if they are both present, find the resulting node
440 pAnd0 = Ivy_NotCond( pAnd0, pNode->eEdge0.fCompl );
441 pAnd1 = Ivy_NotCond( pAnd1, pNode->eEdge1.fCompl );
442 assert( !Ivy_ObjIsLatch(Ivy_Regular(pAnd0)) || !Ivy_ObjIsLatch(Ivy_Regular(pAnd1)) );
443 if ( Ivy_Regular(pAnd0) == Ivy_Regular(pAnd1) || Ivy_ObjIsConst1(Ivy_Regular(pAnd0)) || Ivy_ObjIsConst1(Ivy_Regular(pAnd1)) )
444 pAnd = Ivy_And( p, pAnd0, pAnd1 );
445 else
446 pAnd = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, pAnd0, pAnd1, IVY_AND, IVY_INIT_NONE) );
447 // return -1 if the node is the same as the original root
448 if ( Ivy_Regular(pAnd) == pRoot )
449 return -1;
450 }
451 else
452 pAnd = NULL;
453 // count the number of added nodes
454 if ( pAnd == NULL || Ivy_ObjIsTravIdCurrent(p, Ivy_Regular(pAnd)) )
455 {
456 if ( ++Counter > NodeMax )
457 return -1;
458 }
459 pNode->pFunc = pAnd;
460 }
461 return Counter;
462}
463
464
477Ivy_Obj_t * Ivy_GraphToNetworkSeq( Ivy_Man_t * p, Dec_Graph_t * pGraph )
478{
479 Ivy_Obj_t * pAnd0, * pAnd1;
480 Dec_Node_t * pNode = NULL; // Suppress "might be used uninitialized"
481 int i, k;
482 // check for constant function
483 if ( Dec_GraphIsConst(pGraph) )
484 return Ivy_NotCond( Ivy_ManConst1(p), Dec_GraphIsComplement(pGraph) );
485 // check for a literal
486 if ( Dec_GraphIsVar(pGraph) )
487 {
488 // get the variable node
489 pNode = Dec_GraphVar(pGraph);
490 // add the remaining latches
491 for ( k = 0; k < (int)pNode->nLat2; k++ )
492 pNode->pFunc = Ivy_Latch( p, (Ivy_Obj_t *)pNode->pFunc, IVY_INIT_DC );
493 return Ivy_NotCond( (Ivy_Obj_t *)pNode->pFunc, Dec_GraphIsComplement(pGraph) );
494 }
495 // build the AIG nodes corresponding to the AND gates of the graph
496 Dec_GraphForEachNode( pGraph, pNode, i )
497 {
498 pAnd0 = Ivy_NotCond( (Ivy_Obj_t *)Dec_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl );
499 pAnd1 = Ivy_NotCond( (Ivy_Obj_t *)Dec_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl );
500 // add the latches
501 for ( k = 0; k < (int)pNode->nLat0; k++ )
502 pAnd0 = Ivy_Latch( p, pAnd0, IVY_INIT_DC );
503 for ( k = 0; k < (int)pNode->nLat1; k++ )
504 pAnd1 = Ivy_Latch( p, pAnd1, IVY_INIT_DC );
505 // create the node
506 pNode->pFunc = Ivy_And( p, pAnd0, pAnd1 );
507 }
508 // add the remaining latches
509 for ( k = 0; k < (int)pNode->nLat2; k++ )
510 pNode->pFunc = Ivy_Latch( p, (Ivy_Obj_t *)pNode->pFunc, IVY_INIT_DC );
511 // complement the result if necessary
512 return Ivy_NotCond( (Ivy_Obj_t *)pNode->pFunc, Dec_GraphIsComplement(pGraph) );
513}
514
526void Ivy_GraphUpdateNetworkSeq( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int nGain )
527{
528 Ivy_Obj_t * pRootNew;
529 int nNodesNew, nNodesOld;
530 nNodesOld = Ivy_ManNodeNum(p);
531 // create the new structure of nodes
532 pRootNew = Ivy_GraphToNetworkSeq( p, pGraph );
533 Ivy_ObjReplace( p, pRoot, pRootNew, 1, 0, 0 );
534 // compare the gains
535 nNodesNew = Ivy_ManNodeNum(p);
536 assert( nGain <= nNodesOld - nNodesNew );
537 // propagate the buffer
539}
540
541
542
543
544
545
546
547
548
560unsigned Ivy_CutGetTruth_rec( Ivy_Man_t * p, int Leaf, int * pNums, int nNums )
561{
562 static unsigned uMasks[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 };
563 unsigned uTruth0, uTruth1;
564 Ivy_Obj_t * pObj;
565 int i;
566 for ( i = 0; i < nNums; i++ )
567 if ( Leaf == pNums[i] )
568 return uMasks[i];
569 pObj = Ivy_ManObj( p, Ivy_LeafId(Leaf) );
570 if ( Ivy_ObjIsLatch(pObj) )
571 {
572 assert( !Ivy_ObjFaninC0(pObj) );
573 Leaf = Ivy_LeafCreate( Ivy_ObjFaninId0(pObj), Ivy_LeafLat(Leaf) + 1 );
574 return Ivy_CutGetTruth_rec( p, Leaf, pNums, nNums );
575 }
576 assert( Ivy_ObjIsNode(pObj) || Ivy_ObjIsBuf(pObj) );
577 Leaf = Ivy_LeafCreate( Ivy_ObjFaninId0(pObj), Ivy_LeafLat(Leaf) );
578 uTruth0 = Ivy_CutGetTruth_rec( p, Leaf, pNums, nNums );
579 if ( Ivy_ObjFaninC0(pObj) )
580 uTruth0 = ~uTruth0;
581 if ( Ivy_ObjIsBuf(pObj) )
582 return uTruth0;
583 Leaf = Ivy_LeafCreate( Ivy_ObjFaninId1(pObj), Ivy_LeafLat(Leaf) );
584 uTruth1 = Ivy_CutGetTruth_rec( p, Leaf, pNums, nNums );
585 if ( Ivy_ObjFaninC1(pObj) )
586 uTruth1 = ~uTruth1;
587 return uTruth0 & uTruth1;
588}
589
590
602unsigned Ivy_CutGetTruth( Ivy_Man_t * p, Ivy_Obj_t * pObj, int * pNums, int nNums )
603{
604 assert( Ivy_ObjIsNode(pObj) );
605 assert( nNums < 6 );
606 return Ivy_CutGetTruth_rec( p, Ivy_LeafCreate(pObj->Id, 0), pNums, nNums );
607}
608
609
610
611
612
624static inline int Ivy_CutPrescreen( Ivy_Cut_t * pCut, int Id0, int Id1 )
625{
626 int i;
627 if ( pCut->nSize < pCut->nSizeMax )
628 return 1;
629 for ( i = 0; i < pCut->nSize; i++ )
630 if ( pCut->pArray[i] == Id0 || pCut->pArray[i] == Id1 )
631 return 1;
632 return 0;
633}
634
646static inline int Ivy_CutDeriveNew2( Ivy_Cut_t * pCut, Ivy_Cut_t * pCutNew, int IdOld, int IdNew0, int IdNew1 )
647{
648 unsigned uHash = 0;
649 int i, k;
650 assert( pCut->nSize > 0 );
651 assert( IdNew0 < IdNew1 );
652 for ( i = k = 0; i < pCut->nSize; i++ )
653 {
654 if ( pCut->pArray[i] == IdOld )
655 continue;
656 if ( IdNew0 >= 0 )
657 {
658 if ( IdNew0 <= pCut->pArray[i] )
659 {
660 if ( IdNew0 < pCut->pArray[i] )
661 {
662 if ( k == pCut->nSizeMax )
663 return 0;
664 pCutNew->pArray[ k++ ] = IdNew0;
665 uHash |= Ivy_CutHashValue( IdNew0 );
666 }
667 IdNew0 = -1;
668 }
669 }
670 if ( IdNew1 >= 0 )
671 {
672 if ( IdNew1 <= pCut->pArray[i] )
673 {
674 if ( IdNew1 < pCut->pArray[i] )
675 {
676 if ( k == pCut->nSizeMax )
677 return 0;
678 pCutNew->pArray[ k++ ] = IdNew1;
679 uHash |= Ivy_CutHashValue( IdNew1 );
680 }
681 IdNew1 = -1;
682 }
683 }
684 if ( k == pCut->nSizeMax )
685 return 0;
686 pCutNew->pArray[ k++ ] = pCut->pArray[i];
687 uHash |= Ivy_CutHashValue( pCut->pArray[i] );
688 }
689 if ( IdNew0 >= 0 )
690 {
691 if ( k == pCut->nSizeMax )
692 return 0;
693 pCutNew->pArray[ k++ ] = IdNew0;
694 uHash |= Ivy_CutHashValue( IdNew0 );
695 }
696 if ( IdNew1 >= 0 )
697 {
698 if ( k == pCut->nSizeMax )
699 return 0;
700 pCutNew->pArray[ k++ ] = IdNew1;
701 uHash |= Ivy_CutHashValue( IdNew1 );
702 }
703 pCutNew->nSize = k;
704 pCutNew->uHash = uHash;
705 assert( pCutNew->nSize <= pCut->nSizeMax );
706 for ( i = 1; i < pCutNew->nSize; i++ )
707 assert( pCutNew->pArray[i-1] < pCutNew->pArray[i] );
708 return 1;
709}
710
722static inline int Ivy_CutDeriveNew( Ivy_Cut_t * pCut, Ivy_Cut_t * pCutNew, int IdOld, int IdNew0, int IdNew1 )
723{
724 unsigned uHash = 0;
725 int i, k;
726 assert( pCut->nSize > 0 );
727 assert( IdNew0 < IdNew1 );
728 for ( i = k = 0; i < pCut->nSize; i++ )
729 {
730 if ( pCut->pArray[i] == IdOld )
731 continue;
732 if ( IdNew0 <= pCut->pArray[i] )
733 {
734 if ( IdNew0 < pCut->pArray[i] )
735 {
736 pCutNew->pArray[ k++ ] = IdNew0;
737 uHash |= Ivy_CutHashValue( IdNew0 );
738 }
739 IdNew0 = 0x7FFFFFFF;
740 }
741 if ( IdNew1 <= pCut->pArray[i] )
742 {
743 if ( IdNew1 < pCut->pArray[i] )
744 {
745 pCutNew->pArray[ k++ ] = IdNew1;
746 uHash |= Ivy_CutHashValue( IdNew1 );
747 }
748 IdNew1 = 0x7FFFFFFF;
749 }
750 pCutNew->pArray[ k++ ] = pCut->pArray[i];
751 uHash |= Ivy_CutHashValue( pCut->pArray[i] );
752 }
753 if ( IdNew0 < 0x7FFFFFFF )
754 {
755 pCutNew->pArray[ k++ ] = IdNew0;
756 uHash |= Ivy_CutHashValue( IdNew0 );
757 }
758 if ( IdNew1 < 0x7FFFFFFF )
759 {
760 pCutNew->pArray[ k++ ] = IdNew1;
761 uHash |= Ivy_CutHashValue( IdNew1 );
762 }
763 pCutNew->nSize = k;
764 pCutNew->uHash = uHash;
765 assert( pCutNew->nSize <= pCut->nSizeMax );
766// for ( i = 1; i < pCutNew->nSize; i++ )
767// assert( pCutNew->pArray[i-1] < pCutNew->pArray[i] );
768 return 1;
769}
770
782static inline unsigned Ivy_NodeCutHash( Ivy_Cut_t * pCut )
783{
784 int i;
785 pCut->uHash = 0;
786 for ( i = 0; i < pCut->nSize; i++ )
787 pCut->uHash |= (1 << (pCut->pArray[i] % 31));
788 return pCut->uHash;
789}
790
802static inline int Ivy_CutDeriveNew3( Ivy_Cut_t * pCut, Ivy_Cut_t * pCutNew, int IdOld, int IdNew0, int IdNew1 )
803{
804 int i, k;
805 assert( pCut->nSize > 0 );
806 assert( IdNew0 < IdNew1 );
807 for ( i = k = 0; i < pCut->nSize; i++ )
808 {
809 if ( pCut->pArray[i] == IdOld )
810 continue;
811 if ( IdNew0 <= pCut->pArray[i] )
812 {
813 if ( IdNew0 < pCut->pArray[i] )
814 pCutNew->pArray[ k++ ] = IdNew0;
815 IdNew0 = 0x7FFFFFFF;
816 }
817 if ( IdNew1 <= pCut->pArray[i] )
818 {
819 if ( IdNew1 < pCut->pArray[i] )
820 pCutNew->pArray[ k++ ] = IdNew1;
821 IdNew1 = 0x7FFFFFFF;
822 }
823 pCutNew->pArray[ k++ ] = pCut->pArray[i];
824 }
825 if ( IdNew0 < 0x7FFFFFFF )
826 pCutNew->pArray[ k++ ] = IdNew0;
827 if ( IdNew1 < 0x7FFFFFFF )
828 pCutNew->pArray[ k++ ] = IdNew1;
829 pCutNew->nSize = k;
830 assert( pCutNew->nSize <= pCut->nSizeMax );
831 Ivy_NodeCutHash( pCutNew );
832 return 1;
833}
834
846static inline int Ivy_CutCheckDominance( Ivy_Cut_t * pDom, Ivy_Cut_t * pCut )
847{
848 int i, k;
849 for ( i = 0; i < pDom->nSize; i++ )
850 {
851 assert( i==0 || pDom->pArray[i-1] < pDom->pArray[i] );
852 for ( k = 0; k < pCut->nSize; k++ )
853 if ( pDom->pArray[i] == pCut->pArray[k] )
854 break;
855 if ( k == pCut->nSize ) // node i in pDom is not contained in pCut
856 return 0;
857 }
858 // every node in pDom is contained in pCut
859 return 1;
860}
861
873int Ivy_CutFindOrAddFilter( Ivy_Store_t * pCutStore, Ivy_Cut_t * pCutNew )
874{
875 Ivy_Cut_t * pCut;
876 int i, k;
877 assert( pCutNew->uHash );
878 // try to find the cut
879 for ( i = 0; i < pCutStore->nCuts; i++ )
880 {
881 pCut = pCutStore->pCuts + i;
882 if ( pCut->nSize == 0 )
883 continue;
884 if ( pCut->nSize == pCutNew->nSize )
885 {
886 if ( pCut->uHash == pCutNew->uHash )
887 {
888 for ( k = 0; k < pCutNew->nSize; k++ )
889 if ( pCut->pArray[k] != pCutNew->pArray[k] )
890 break;
891 if ( k == pCutNew->nSize )
892 return 1;
893 }
894 continue;
895 }
896 if ( pCut->nSize < pCutNew->nSize )
897 {
898 // skip the non-contained cuts
899 if ( (pCut->uHash & pCutNew->uHash) != pCut->uHash )
900 continue;
901 // check containment seriously
902 if ( Ivy_CutCheckDominance( pCut, pCutNew ) )
903 return 1;
904 continue;
905 }
906 // check potential containment of other cut
907
908 // skip the non-contained cuts
909 if ( (pCut->uHash & pCutNew->uHash) != pCutNew->uHash )
910 continue;
911 // check containment seriously
912 if ( Ivy_CutCheckDominance( pCutNew, pCut ) )
913 {
914 // remove the current cut
915 pCut->nSize = 0;
916 }
917 }
918 assert( pCutStore->nCuts < pCutStore->nCutsMax );
919 // add the cut
920 pCut = pCutStore->pCuts + pCutStore->nCuts++;
921 *pCut = *pCutNew;
922 return 0;
923}
924
937{
938 Ivy_Cut_t * pCut;
939 int i, k;
940 pCutStore->nCutsM = 0;
941 for ( i = k = 0; i < pCutStore->nCuts; i++ )
942 {
943 pCut = pCutStore->pCuts + i;
944 if ( pCut->nSize == 0 )
945 continue;
946 if ( pCut->nSize < pCut->nSizeMax )
947 pCutStore->nCutsM++;
948 pCutStore->pCuts[k++] = *pCut;
949 }
950 pCutStore->nCuts = k;
951}
952
965{
966 int i;
967 assert( pCut->nSize > 0 );
968 printf( "%d : {", pCut->nSize );
969 for ( i = 0; i < pCut->nSize; i++ )
970 printf( " %d", pCut->pArray[i] );
971 printf( " }\n" );
972}
973
986{
987 int i;
988 printf( "Node %d\n", pCutStore->pCuts[0].pArray[0] );
989 for ( i = 0; i < pCutStore->nCuts; i++ )
990 Ivy_CutPrintForNode( pCutStore->pCuts + i );
991}
992
1004static inline int Ivy_CutReadLeaf( Ivy_Obj_t * pFanin )
1005{
1006 int nLats, iLeaf;
1007 assert( !Ivy_IsComplement(pFanin) );
1008 if ( !Ivy_ObjIsLatch(pFanin) )
1009 return Ivy_LeafCreate( pFanin->Id, 0 );
1010 iLeaf = Ivy_CutReadLeaf(Ivy_ObjFanin0(pFanin));
1011 nLats = Ivy_LeafLat(iLeaf);
1012 assert( nLats < IVY_LEAF_MASK );
1013 return 1 + iLeaf;
1014}
1015
1027Ivy_Store_t * Ivy_CutComputeForNode( Ivy_Man_t * p, Ivy_Obj_t * pObj, int nLeaves )
1028{
1029 static Ivy_Store_t CutStore, * pCutStore = &CutStore;
1030 Ivy_Cut_t CutNew, * pCutNew = &CutNew, * pCut;
1031 Ivy_Obj_t * pLeaf;
1032 int i, k, Temp, nLats, iLeaf0, iLeaf1;
1033
1034 assert( nLeaves <= IVY_CUT_INPUT );
1035
1036 // start the structure
1037 pCutStore->nCuts = 0;
1038 pCutStore->nCutsMax = IVY_CUT_LIMIT;
1039 // start the trivial cut
1040 pCutNew->uHash = 0;
1041 pCutNew->nSize = 1;
1042 pCutNew->nSizeMax = nLeaves;
1043 pCutNew->pArray[0] = Ivy_LeafCreate( pObj->Id, 0 );
1044 pCutNew->uHash = Ivy_CutHashValue( pCutNew->pArray[0] );
1045 // add the trivial cut
1046 pCutStore->pCuts[pCutStore->nCuts++] = *pCutNew;
1047 assert( pCutStore->nCuts == 1 );
1048
1049 // explore the cuts
1050 for ( i = 0; i < pCutStore->nCuts; i++ )
1051 {
1052 // expand this cut
1053 pCut = pCutStore->pCuts + i;
1054 if ( pCut->nSize == 0 )
1055 continue;
1056 for ( k = 0; k < pCut->nSize; k++ )
1057 {
1058 pLeaf = Ivy_ManObj( p, Ivy_LeafId(pCut->pArray[k]) );
1059 if ( Ivy_ObjIsCi(pLeaf) || Ivy_ObjIsConst1(pLeaf) )
1060 continue;
1061 assert( Ivy_ObjIsNode(pLeaf) );
1062 nLats = Ivy_LeafLat(pCut->pArray[k]);
1063
1064 // get the fanins fanins
1065 iLeaf0 = Ivy_CutReadLeaf( Ivy_ObjFanin0(pLeaf) );
1066 iLeaf1 = Ivy_CutReadLeaf( Ivy_ObjFanin1(pLeaf) );
1067 assert( nLats + Ivy_LeafLat(iLeaf0) < IVY_LEAF_MASK && nLats + Ivy_LeafLat(iLeaf1) < IVY_LEAF_MASK );
1068 iLeaf0 = nLats + iLeaf0;
1069 iLeaf1 = nLats + iLeaf1;
1070 if ( !Ivy_CutPrescreen( pCut, iLeaf0, iLeaf1 ) )
1071 continue;
1072 // the given cut exist
1073 if ( iLeaf0 > iLeaf1 )
1074 Temp = iLeaf0, iLeaf0 = iLeaf1, iLeaf1 = Temp;
1075 // create the new cut
1076 if ( !Ivy_CutDeriveNew( pCut, pCutNew, pCut->pArray[k], iLeaf0, iLeaf1 ) )
1077 continue;
1078 // add the cut
1079 Ivy_CutFindOrAddFilter( pCutStore, pCutNew );
1080 if ( pCutStore->nCuts == IVY_CUT_LIMIT )
1081 break;
1082 }
1083 if ( pCutStore->nCuts == IVY_CUT_LIMIT )
1084 break;
1085 }
1086 if ( pCutStore->nCuts == IVY_CUT_LIMIT )
1087 pCutStore->fSatur = 1;
1088 else
1089 pCutStore->fSatur = 0;
1090// printf( "%d ", pCutStore->nCuts );
1091 Ivy_CutCompactAll( pCutStore );
1092// printf( "%d \n", pCutStore->nCuts );
1093// Ivy_CutPrintForNodes( pCutStore );
1094 return pCutStore;
1095}
1096
1108void Ivy_CutComputeAll( Ivy_Man_t * p, int nInputs )
1109{
1110 Ivy_Store_t * pStore;
1111 Ivy_Obj_t * pObj;
1112 int i, nCutsTotal, nCutsTotalM, nNodeTotal, nNodeOver;
1113 abctime clk = Abc_Clock();
1114 if ( nInputs > IVY_CUT_INPUT )
1115 {
1116 printf( "Cannot compute cuts for more than %d inputs.\n", IVY_CUT_INPUT );
1117 return;
1118 }
1119 nNodeTotal = nNodeOver = 0;
1120 nCutsTotal = nCutsTotalM = -Ivy_ManNodeNum(p);
1121 Ivy_ManForEachObj( p, pObj, i )
1122 {
1123 if ( !Ivy_ObjIsNode(pObj) )
1124 continue;
1125 pStore = Ivy_CutComputeForNode( p, pObj, nInputs );
1126 nCutsTotal += pStore->nCuts;
1127 nCutsTotalM += pStore->nCutsM;
1128 nNodeOver += pStore->fSatur;
1129 nNodeTotal++;
1130 }
1131 printf( "All = %6d. Minus = %6d. Triv = %6d. Node = %6d. Satur = %6d. ",
1132 nCutsTotal, nCutsTotalM, Ivy_ManPiNum(p) + Ivy_ManNodeNum(p), nNodeTotal, nNodeOver );
1133 ABC_PRT( "Time", Abc_Clock() - clk );
1134}
1135
1139
1140
1142
ABC_INT64_T abctime
Definition abc_global.h:332
#define ABC_PRT(a, t)
Definition abc_global.h:255
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
struct Dec_Node_t_ Dec_Node_t
Definition dec.h:49
#define Dec_GraphForEachLeaf(pGraph, pLeaf, i)
ITERATORS ///.
Definition dec.h:98
#define Dec_GraphForEachNode(pGraph, pAnd, i)
Definition dec.h:101
struct Dec_Graph_t_ Dec_Graph_t
Definition dec.h:68
Cube * p
Definition exorList.c:222
void Ivy_CutComputeAll(Ivy_Man_t *p, int nInputs)
Definition ivySeq.c:1108
void Ivy_CutCompactAll(Ivy_Store_t *pCutStore)
Definition ivySeq.c:936
int Ivy_ManRewriteSeq(Ivy_Man_t *p, int fUseZeroCost, int fVerbose)
FUNCTION DEFINITIONS ///.
Definition ivySeq.c:63
void Ivy_CutPrintForNode(Ivy_Cut_t *pCut)
Definition ivySeq.c:964
unsigned Ivy_CutGetTruth_rec(Ivy_Man_t *p, int Leaf, int *pNums, int nNums)
Definition ivySeq.c:560
int Ivy_CutFindOrAddFilter(Ivy_Store_t *pCutStore, Ivy_Cut_t *pCutNew)
Definition ivySeq.c:873
void Ivy_CutPrintForNodes(Ivy_Store_t *pCutStore)
Definition ivySeq.c:985
int Ivy_ManCheck(Ivy_Man_t *p)
DECLARATIONS ///.
Definition ivyCheck.c:45
struct Ivy_Cut_t_ Ivy_Cut_t
Definition ivy.h:155
#define IVY_CUT_INPUT
Definition ivy.h:153
int Ivy_ObjMffcLabel(Ivy_Man_t *p, Ivy_Obj_t *pObj)
Definition ivyUtil.c:359
typedefABC_NAMESPACE_HEADER_START struct Ivy_Man_t_ Ivy_Man_t
INCLUDES ///.
Definition ivy.h:46
@ IVY_INIT_DC
Definition ivy.h:69
@ IVY_INIT_NONE
Definition ivy.h:66
void Ivy_ManIncrementTravId(Ivy_Man_t *p)
DECLARATIONS ///.
Definition ivyUtil.c:45
Ivy_Obj_t * Ivy_Latch(Ivy_Man_t *p, Ivy_Obj_t *pObj, Ivy_Init_t Init)
Definition ivyOper.c:287
#define Ivy_ManForEachLatch(p, pObj, i)
Definition ivy.h:405
Ivy_Obj_t * Ivy_TableLookup(Ivy_Man_t *p, Ivy_Obj_t *pObj)
FUNCTION DEFINITIONS ///.
Definition ivyTable.c:71
void Ivy_ManResetLevels(Ivy_Man_t *p)
Definition ivyUtil.c:292
#define Ivy_ManForEachObj(p, pObj, i)
Definition ivy.h:393
#define Ivy_ManForEachNode(p, pObj, i)
Definition ivy.h:402
#define IVY_MIN(a, b)
MACRO DEFINITIONS ///.
Definition ivy.h:182
struct Ivy_Store_t_ Ivy_Store_t
Definition ivy.h:165
struct Ivy_Obj_t_ Ivy_Obj_t
Definition ivy.h:47
void Ivy_ObjReplace(Ivy_Man_t *p, Ivy_Obj_t *pObjOld, Ivy_Obj_t *pObjNew, int fDeleteOld, int fFreeTop, int fUpdateLevel)
Definition ivyObj.c:328
int Ivy_ManPropagateBuffers(Ivy_Man_t *p, int fUpdateLevel)
Definition ivyMan.c:414
@ IVY_AND
Definition ivy.h:58
@ IVY_LATCH
Definition ivy.h:57
#define IVY_LEAF_MASK
Definition ivy.h:175
void Ivy_ManStartFanout(Ivy_Man_t *p)
FUNCTION DEFINITIONS ///.
Definition ivyFanout.c:136
Ivy_Obj_t * Ivy_And(Ivy_Man_t *p, Ivy_Obj_t *p0, Ivy_Obj_t *p1)
Definition ivyOper.c:84
#define IVY_CUT_LIMIT
Definition ivy.h:152
struct Rwt_Man_t_ Rwt_Man_t
Definition rwt.h:55
void Rwt_ManPrintStats(Rwt_Man_t *p)
Definition rwtMan.c:183
struct Rwt_Node_t_ Rwt_Node_t
Definition rwt.h:56
int Rwt_ManReadCompl(Rwt_Man_t *p)
Definition rwtMan.c:285
void Rwt_ManAddTimeUpdate(Rwt_Man_t *p, abctime Time)
Definition rwtMan.c:317
void * Rwt_ManReadDecs(Rwt_Man_t *p)
Definition rwtMan.c:253
void Rwt_ManAddTimeTotal(Rwt_Man_t *p, abctime Time)
Definition rwtMan.c:333
void Rwt_ManStop(Rwt_Man_t *p)
Definition rwtMan.c:149
Rwt_Man_t * Rwt_ManStart(int fPrecompute)
Definition rwtMan.c:87
Dec_Edge_t eEdge1
Definition dec.h:53
void * pFunc
Definition dec.h:56
unsigned nLat0
Definition dec.h:63
unsigned nLat1
Definition dec.h:64
Dec_Edge_t eEdge0
Definition dec.h:52
unsigned nLat2
Definition dec.h:65
unsigned uHash
Definition ivy.h:162
short nSize
Definition ivy.h:159
short nSizeMax
Definition ivy.h:160
int pArray[IVY_CUT_INPUT]
Definition ivy.h:161
int Id
Definition ivy.h:75
unsigned Init
Definition ivy.h:83
Ivy_Cut_t pCuts[IVY_CUT_LIMIT]
Definition ivy.h:172
int nCutsMax
Definition ivy.h:170
int fSatur
Definition ivy.h:171
int nCuts
Definition ivy.h:168
int nCutsM
Definition ivy.h:169
Rwt_Node_t * pNext
Definition rwt.h:118
#define assert(ex)
Definition util_old.h:213
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