#include "ivy.h"
Go to the source code of this file.
Function*************************************************************
Synopsis [Returns 1 if pDom is contained in pCut.]
Description []
SideEffects []
SeeAlso []
Definition at line 712 of file ivyCut.c.
00713 { 00714 int i, k; 00715 for ( i = 0; i < pDom->nSize; i++ ) 00716 { 00717 for ( k = 0; k < pCut->nSize; k++ ) 00718 if ( pDom->pArray[i] == pCut->pArray[k] ) 00719 break; 00720 if ( k == pCut->nSize ) // node i in pDom is not contained in pCut 00721 return 0; 00722 } 00723 // every node in pDom is contained in pCut 00724 return 1; 00725 }
int Ivy_ManFindBoolCut | ( | Ivy_Man_t * | p, | |
Ivy_Obj_t * | pRoot, | |||
Vec_Ptr_t * | vFront, | |||
Vec_Ptr_t * | vVolume, | |||
Vec_Ptr_t * | vLeaves | |||
) |
Function*************************************************************
Synopsis [Computing Boolean cut.]
Description []
SideEffects []
SeeAlso []
Definition at line 301 of file ivyCut.c.
00302 { 00303 Ivy_Obj_t * pObj, * pFaninC, * pFanin0, * pFanin1, * pPivot; 00304 int RetValue, LevelLimit, Lev, k; 00305 assert( !Ivy_IsComplement(pRoot) ); 00306 // clear the frontier and collect the nodes 00307 Vec_PtrClear( vFront ); 00308 Vec_PtrClear( vVolume ); 00309 if ( Ivy_ObjIsMuxType(pRoot) ) 00310 pFaninC = Ivy_ObjRecognizeMux( pRoot, &pFanin0, &pFanin1 ); 00311 else 00312 { 00313 pFaninC = NULL; 00314 pFanin0 = Ivy_ObjFanin0(pRoot); 00315 pFanin1 = Ivy_ObjFanin1(pRoot); 00316 } 00317 // start cone A 00318 pFanin0->fMarkA = 1; 00319 Vec_PtrPush( vFront, pFanin0 ); 00320 Vec_PtrPush( vVolume, pFanin0 ); 00321 // start cone B 00322 pFanin1->fMarkB = 1; 00323 Vec_PtrPush( vFront, pFanin1 ); 00324 Vec_PtrPush( vVolume, pFanin1 ); 00325 // iteratively expand until the common node (pPivot) is found or limit is reached 00326 assert( Ivy_ObjLevel(pRoot) == Ivy_ObjLevelNew(pRoot) ); 00327 pPivot = NULL; 00328 LevelLimit = IVY_MAX( Ivy_ObjLevel(pRoot) - 10, 1 ); 00329 for ( Lev = Ivy_ObjLevel(pRoot) - 1; Lev >= LevelLimit; Lev-- ) 00330 { 00331 while ( 1 ) 00332 { 00333 // find the next node to expand on this level 00334 Vec_PtrForEachEntry( vFront, pObj, k ) 00335 if ( (int)pObj->Level == Lev ) 00336 break; 00337 if ( k == Vec_PtrSize(vFront) ) 00338 break; 00339 assert( (int)pObj->Level <= Lev ); 00340 assert( pObj->fMarkA ^ pObj->fMarkB ); 00341 // remove the old node 00342 Vec_PtrRemove( vFront, pObj ); 00343 00344 // expand this node 00345 pFanin0 = Ivy_ObjFanin0(pObj); 00346 if ( !pFanin0->fMarkA && !pFanin0->fMarkB ) 00347 { 00348 Vec_PtrPush( vFront, pFanin0 ); 00349 Vec_PtrPush( vVolume, pFanin0 ); 00350 } 00351 // mark the new nodes 00352 if ( pObj->fMarkA ) 00353 pFanin0->fMarkA = 1; 00354 if ( pObj->fMarkB ) 00355 pFanin0->fMarkB = 1; 00356 00357 if ( Ivy_ObjIsBuf(pObj) ) 00358 { 00359 if ( pFanin0->fMarkA && pFanin0->fMarkB ) 00360 { 00361 pPivot = pFanin0; 00362 break; 00363 } 00364 continue; 00365 } 00366 00367 // expand this node 00368 pFanin1 = Ivy_ObjFanin1(pObj); 00369 if ( !pFanin1->fMarkA && !pFanin1->fMarkB ) 00370 { 00371 Vec_PtrPush( vFront, pFanin1 ); 00372 Vec_PtrPush( vVolume, pFanin1 ); 00373 } 00374 // mark the new nodes 00375 if ( pObj->fMarkA ) 00376 pFanin1->fMarkA = 1; 00377 if ( pObj->fMarkB ) 00378 pFanin1->fMarkB = 1; 00379 00380 // consider if it is time to quit 00381 if ( pFanin0->fMarkA && pFanin0->fMarkB ) 00382 { 00383 pPivot = pFanin0; 00384 break; 00385 } 00386 if ( pFanin1->fMarkA && pFanin1->fMarkB ) 00387 { 00388 pPivot = pFanin1; 00389 break; 00390 } 00391 } 00392 if ( pPivot != NULL ) 00393 break; 00394 } 00395 if ( pPivot == NULL ) 00396 return 0; 00397 // if the MUX control is defined, it should not be 00398 if ( pFaninC && !pFaninC->fMarkA && !pFaninC->fMarkB ) 00399 Vec_PtrPush( vFront, pFaninC ); 00400 // clean the markings 00401 Vec_PtrForEachEntry( vVolume, pObj, k ) 00402 pObj->fMarkA = pObj->fMarkB = 0; 00403 00404 // mark the nodes on the frontier (including the pivot) 00405 Vec_PtrForEachEntry( vFront, pObj, k ) 00406 pObj->fMarkA = 1; 00407 // cut exists, collect all the nodes on the shortest path to the pivot 00408 Vec_PtrClear( vLeaves ); 00409 Vec_PtrClear( vVolume ); 00410 RetValue = Ivy_ManFindBoolCut_rec( p, pRoot, vLeaves, vVolume, pPivot ); 00411 assert( RetValue == 1 ); 00412 // unmark the nodes on the frontier (including the pivot) 00413 Vec_PtrForEachEntry( vFront, pObj, k ) 00414 pObj->fMarkA = 0; 00415 00416 // mark the nodes in the volume 00417 Vec_PtrForEachEntry( vVolume, pObj, k ) 00418 pObj->fMarkA = 1; 00419 // expand the cut without increasing its size 00420 while ( 1 ) 00421 { 00422 Vec_PtrForEachEntry( vLeaves, pObj, k ) 00423 if ( Ivy_ManFindBoolCutCost(pObj) < 2 ) 00424 break; 00425 if ( k == Vec_PtrSize(vLeaves) ) 00426 break; 00427 // the node can be expanded 00428 // remove the old node 00429 Vec_PtrRemove( vLeaves, pObj ); 00430 // expand this node 00431 pFanin0 = Ivy_ObjFanin0(pObj); 00432 if ( !pFanin0->fMarkA ) 00433 { 00434 pFanin0->fMarkA = 1; 00435 Vec_PtrPush( vVolume, pFanin0 ); 00436 Vec_PtrPush( vLeaves, pFanin0 ); 00437 } 00438 if ( Ivy_ObjIsBuf(pObj) ) 00439 continue; 00440 // expand this node 00441 pFanin1 = Ivy_ObjFanin1(pObj); 00442 if ( !pFanin1->fMarkA ) 00443 { 00444 pFanin1->fMarkA = 1; 00445 Vec_PtrPush( vVolume, pFanin1 ); 00446 Vec_PtrPush( vLeaves, pFanin1 ); 00447 } 00448 } 00449 // unmark the nodes in the volume 00450 Vec_PtrForEachEntry( vVolume, pObj, k ) 00451 pObj->fMarkA = 0; 00452 return 1; 00453 }
int Ivy_ManFindBoolCut_rec | ( | Ivy_Man_t * | p, | |
Ivy_Obj_t * | pObj, | |||
Vec_Ptr_t * | vLeaves, | |||
Vec_Ptr_t * | vVolume, | |||
Ivy_Obj_t * | pPivot | |||
) |
Function*************************************************************
Synopsis [Computing Boolean cut.]
Description []
SideEffects []
SeeAlso []
Definition at line 218 of file ivyCut.c.
00219 { 00220 int RetValue0, RetValue1; 00221 if ( pObj == pPivot ) 00222 { 00223 Vec_PtrPushUnique( vLeaves, pObj ); 00224 Vec_PtrPushUnique( vVolume, pObj ); 00225 return 1; 00226 } 00227 if ( pObj->fMarkA ) 00228 return 0; 00229 00230 // assert( !Ivy_ObjIsCi(pObj) ); 00231 if ( Ivy_ObjIsCi(pObj) ) 00232 return 0; 00233 00234 if ( Ivy_ObjIsBuf(pObj) ) 00235 { 00236 RetValue0 = Ivy_ManFindBoolCut_rec( p, Ivy_ObjFanin0(pObj), vLeaves, vVolume, pPivot ); 00237 if ( !RetValue0 ) 00238 return 0; 00239 Vec_PtrPushUnique( vVolume, pObj ); 00240 return 1; 00241 } 00242 assert( Ivy_ObjIsNode(pObj) ); 00243 RetValue0 = Ivy_ManFindBoolCut_rec( p, Ivy_ObjFanin0(pObj), vLeaves, vVolume, pPivot ); 00244 RetValue1 = Ivy_ManFindBoolCut_rec( p, Ivy_ObjFanin1(pObj), vLeaves, vVolume, pPivot ); 00245 if ( !RetValue0 && !RetValue1 ) 00246 return 0; 00247 // add new leaves 00248 if ( !RetValue0 ) 00249 { 00250 Vec_PtrPushUnique( vLeaves, Ivy_ObjFanin0(pObj) ); 00251 Vec_PtrPushUnique( vVolume, Ivy_ObjFanin0(pObj) ); 00252 } 00253 if ( !RetValue1 ) 00254 { 00255 Vec_PtrPushUnique( vLeaves, Ivy_ObjFanin1(pObj) ); 00256 Vec_PtrPushUnique( vVolume, Ivy_ObjFanin1(pObj) ); 00257 } 00258 Vec_PtrPushUnique( vVolume, pObj ); 00259 return 1; 00260 }
int Ivy_ManFindBoolCutCost | ( | Ivy_Obj_t * | pObj | ) |
Function*************************************************************
Synopsis [Returns the cost of one node (how many new nodes are added.]
Description []
SideEffects []
SeeAlso []
Definition at line 273 of file ivyCut.c.
00274 { 00275 int Cost; 00276 // make sure the node is in the construction zone 00277 assert( pObj->fMarkA == 1 ); 00278 // cannot expand over the PI node 00279 if ( Ivy_ObjIsCi(pObj) ) 00280 return 999; 00281 // always expand over the buffer 00282 if ( Ivy_ObjIsBuf(pObj) ) 00283 return !Ivy_ObjFanin0(pObj)->fMarkA; 00284 // get the cost of the cone 00285 Cost = (!Ivy_ObjFanin0(pObj)->fMarkA) + (!Ivy_ObjFanin1(pObj)->fMarkA); 00286 // return the number of nodes to be added to the leaves if this node is removed 00287 return Cost; 00288 }
void Ivy_ManSeqFindCut | ( | Ivy_Man_t * | p, | |
Ivy_Obj_t * | pRoot, | |||
Vec_Int_t * | vFront, | |||
Vec_Int_t * | vInside, | |||
int | nSize | |||
) |
Function*************************************************************
Synopsis [Computes one sequential cut of the given size.]
Description []
SideEffects []
SeeAlso []
Definition at line 180 of file ivyCut.c.
00181 { 00182 assert( !Ivy_IsComplement(pRoot) ); 00183 assert( Ivy_ObjIsNode(pRoot) ); 00184 assert( Ivy_ObjFaninId0(pRoot) ); 00185 assert( Ivy_ObjFaninId1(pRoot) ); 00186 00187 // start the cut 00188 Vec_IntClear( vFront ); 00189 Vec_IntPush( vFront, Ivy_LeafCreate(Ivy_ObjFaninId0(pRoot), 0) ); 00190 Vec_IntPush( vFront, Ivy_LeafCreate(Ivy_ObjFaninId1(pRoot), 0) ); 00191 00192 // start the visited nodes 00193 Vec_IntClear( vInside ); 00194 Vec_IntPush( vInside, Ivy_LeafCreate(pRoot->Id, 0) ); 00195 Vec_IntPush( vInside, Ivy_LeafCreate(Ivy_ObjFaninId0(pRoot), 0) ); 00196 Vec_IntPush( vInside, Ivy_LeafCreate(Ivy_ObjFaninId1(pRoot), 0) ); 00197 00198 // compute the cut 00199 while ( Ivy_ManSeqFindCut_int( p, vFront, vInside, nSize ) ); 00200 assert( Vec_IntSize(vFront) <= nSize ); 00201 }
int Ivy_ManSeqFindCut_int | ( | Ivy_Man_t * | p, | |
Vec_Int_t * | vFront, | |||
Vec_Int_t * | vInside, | |||
int | nSizeLimit | |||
) |
Function*************************************************************
Synopsis [Builds reconvergence-driven cut by changing one leaf at a time.]
Description [This procedure looks at the current leaves and tries to change one leaf at a time in such a way that the cut grows as little as possible. In evaluating the fanins, this procedure looks only at their immediate predecessors (this is why it is called a one-level construction procedure).]
SideEffects []
SeeAlso []
Definition at line 87 of file ivyCut.c.
00088 { 00089 Ivy_Obj_t * pNode; 00090 int CostBest, CostCur, Leaf, LeafBest, Next, nLatches, i; 00091 int LeavesBest[10]; 00092 int Counter; 00093 00094 // add random selection of the best fanin!!! 00095 00096 // find the best fanin 00097 CostBest = 99; 00098 LeafBest = -1; 00099 Counter = -1; 00100 //printf( "Evaluating fanins of the cut:\n" ); 00101 Vec_IntForEachEntry( vFront, Leaf, i ) 00102 { 00103 CostCur = Ivy_NodeGetLeafCostOne( p, Leaf, vInside ); 00104 //printf( " Fanin %s has cost %d.\n", Ivy_ObjName(pNode), CostCur ); 00105 if ( CostBest > CostCur ) 00106 { 00107 CostBest = CostCur; 00108 LeafBest = Leaf; 00109 LeavesBest[0] = Leaf; 00110 Counter = 1; 00111 } 00112 else if ( CostBest == CostCur ) 00113 LeavesBest[Counter++] = Leaf; 00114 00115 if ( CostBest <= 1 ) // can be if ( CostBest <= 1 ) 00116 break; 00117 } 00118 if ( CostBest == 99 ) 00119 return 0; 00120 // return Ivy_NodeBuildCutLevelTwo_int( vInside, vFront, nFaninLimit ); 00121 00122 assert( CostBest < 3 ); 00123 if ( Vec_IntSize(vFront) - 1 + CostBest > nSizeLimit ) 00124 return 0; 00125 // return Ivy_NodeBuildCutLevelTwo_int( vInside, vFront, nFaninLimit ); 00126 00127 assert( Counter > 0 ); 00128 printf( "%d", Counter ); 00129 00130 LeafBest = LeavesBest[rand() % Counter]; 00131 00132 // remove the node from the array 00133 assert( LeafBest >= 0 ); 00134 Vec_IntRemove( vFront, LeafBest ); 00135 //printf( "Removing fanin %s.\n", Ivy_ObjName(pNode) ); 00136 00137 // get the node and its latches 00138 pNode = Ivy_ManObj( p, Ivy_LeafId(LeafBest) ); 00139 nLatches = Ivy_LeafLat(LeafBest) + Ivy_ObjIsLatch(pNode); 00140 assert( Ivy_ObjIsNode(pNode) || Ivy_ObjIsLatch(pNode) || Ivy_ObjIsBuf(pNode) ); 00141 00142 // add the left child to the fanins 00143 Next = Ivy_LeafCreate( Ivy_ObjFaninId0(pNode), nLatches ); 00144 if ( Next && Vec_IntFind(vInside, Next) == -1 ) 00145 { 00146 //printf( "Adding fanin %s.\n", Ivy_ObjName(pNext) ); 00147 Vec_IntPush( vFront, Next ); 00148 Vec_IntPush( vInside, Next ); 00149 } 00150 00151 // quit if this is the one fanin node 00152 if ( Ivy_ObjIsLatch(pNode) || Ivy_ObjIsBuf(pNode) ) 00153 return 1; 00154 assert( Ivy_ObjIsNode(pNode) ); 00155 00156 // add the right child to the fanins 00157 Next = Ivy_LeafCreate( Ivy_ObjFaninId1(pNode), nLatches ); 00158 if ( Next && Vec_IntFind(vInside, Next) == -1 ) 00159 { 00160 //printf( "Adding fanin %s.\n", Ivy_ObjName(pNext) ); 00161 Vec_IntPush( vFront, Next ); 00162 Vec_IntPush( vInside, Next ); 00163 } 00164 assert( Vec_IntSize(vFront) <= nSizeLimit ); 00165 // keep doing this 00166 return 1; 00167 }
void Ivy_ManTestCutsAll | ( | Ivy_Man_t * | p | ) |
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 964 of file ivyCut.c.
00965 { 00966 Ivy_Obj_t * pObj; 00967 int i, nCutsCut, nCutsTotal, nNodeTotal, nNodeOver; 00968 int clk = clock(); 00969 nNodeTotal = nNodeOver = 0; 00970 nCutsTotal = -Ivy_ManNodeNum(p); 00971 Ivy_ManForEachObj( p, pObj, i ) 00972 { 00973 if ( !Ivy_ObjIsNode(pObj) ) 00974 continue; 00975 nCutsCut = Ivy_NodeFindCutsAll( p, pObj, 5 )->nCuts; 00976 nCutsTotal += nCutsCut; 00977 nNodeOver += (nCutsCut == IVY_CUT_LIMIT); 00978 nNodeTotal++; 00979 } 00980 printf( "Total cuts = %6d. Trivial = %6d. Nodes = %6d. Satur = %6d. ", 00981 nCutsTotal, Ivy_ManPiNum(p) + Ivy_ManNodeNum(p), nNodeTotal, nNodeOver ); 00982 PRT( "Time", clock() - clk ); 00983 }
void Ivy_ManTestCutsBool | ( | Ivy_Man_t * | p | ) |
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 467 of file ivyCut.c.
00468 { 00469 Vec_Ptr_t * vFront, * vVolume, * vLeaves; 00470 Ivy_Obj_t * pObj;//, * pTemp; 00471 int i, RetValue;//, k; 00472 vFront = Vec_PtrAlloc( 100 ); 00473 vVolume = Vec_PtrAlloc( 100 ); 00474 vLeaves = Vec_PtrAlloc( 100 ); 00475 Ivy_ManForEachObj( p, pObj, i ) 00476 { 00477 if ( !Ivy_ObjIsNode(pObj) ) 00478 continue; 00479 if ( Ivy_ObjIsMuxType(pObj) ) 00480 { 00481 printf( "m" ); 00482 continue; 00483 } 00484 if ( Ivy_ObjIsExor(pObj) ) 00485 printf( "x" ); 00486 RetValue = Ivy_ManFindBoolCut( p, pObj, vFront, vVolume, vLeaves ); 00487 if ( RetValue == 0 ) 00488 printf( "- " ); 00489 else 00490 printf( "%d ", Vec_PtrSize(vLeaves) ); 00491 /* 00492 printf( "( " ); 00493 Vec_PtrForEachEntry( vFront, pTemp, k ) 00494 printf( "%d ", Ivy_ObjRefs(Ivy_Regular(pTemp)) ); 00495 printf( ")\n" ); 00496 */ 00497 } 00498 printf( "\n" ); 00499 Vec_PtrFree( vFront ); 00500 Vec_PtrFree( vVolume ); 00501 Vec_PtrFree( vLeaves ); 00502 }
void Ivy_NodeCompactCuts | ( | Ivy_Store_t * | pCutStore | ) |
Function*************************************************************
Synopsis [Print the cut.]
Description []
SideEffects []
SeeAlso []
static int Ivy_NodeCutDeriveNew | ( | Ivy_Cut_t * | pCut, | |
Ivy_Cut_t * | pCutNew, | |||
int | IdOld, | |||
int | IdNew0, | |||
int | IdNew1 | |||
) | [inline, static] |
Function*************************************************************
Synopsis [Derives new cut.]
Description []
SideEffects []
SeeAlso []
Definition at line 616 of file ivyCut.c.
00617 { 00618 unsigned uHash = 0; 00619 int i, k; 00620 assert( pCut->nSize > 0 ); 00621 assert( IdNew0 < IdNew1 ); 00622 for ( i = k = 0; i < pCut->nSize; i++ ) 00623 { 00624 if ( pCut->pArray[i] == IdOld ) 00625 continue; 00626 if ( IdNew0 <= pCut->pArray[i] ) 00627 { 00628 if ( IdNew0 < pCut->pArray[i] ) 00629 { 00630 pCutNew->pArray[ k++ ] = IdNew0; 00631 uHash |= Ivy_NodeCutHashValue( IdNew0 ); 00632 } 00633 IdNew0 = 0x7FFFFFFF; 00634 } 00635 if ( IdNew1 <= pCut->pArray[i] ) 00636 { 00637 if ( IdNew1 < pCut->pArray[i] ) 00638 { 00639 pCutNew->pArray[ k++ ] = IdNew1; 00640 uHash |= Ivy_NodeCutHashValue( IdNew1 ); 00641 } 00642 IdNew1 = 0x7FFFFFFF; 00643 } 00644 pCutNew->pArray[ k++ ] = pCut->pArray[i]; 00645 uHash |= Ivy_NodeCutHashValue( pCut->pArray[i] ); 00646 } 00647 if ( IdNew0 < 0x7FFFFFFF ) 00648 { 00649 pCutNew->pArray[ k++ ] = IdNew0; 00650 uHash |= Ivy_NodeCutHashValue( IdNew0 ); 00651 } 00652 if ( IdNew1 < 0x7FFFFFFF ) 00653 { 00654 pCutNew->pArray[ k++ ] = IdNew1; 00655 uHash |= Ivy_NodeCutHashValue( IdNew1 ); 00656 } 00657 pCutNew->nSize = k; 00658 pCutNew->uHash = uHash; 00659 assert( pCutNew->nSize <= pCut->nSizeMax ); 00660 // for ( i = 1; i < pCutNew->nSize; i++ ) 00661 // assert( pCutNew->pArray[i-1] < pCutNew->pArray[i] ); 00662 return 1; 00663 }
static int Ivy_NodeCutExtend | ( | Ivy_Cut_t * | pCut, | |
int | iNew | |||
) | [inline, static] |
Function*************************************************************
Synopsis [Adds one node to the cut.]
Description [Returns 1 if the cuts is still okay.]
SideEffects []
SeeAlso []
Definition at line 560 of file ivyCut.c.
00561 { 00562 int i; 00563 for ( i = 0; i < pCut->nSize; i++ ) 00564 if ( pCut->pArray[i] == iNew ) 00565 return 1; 00566 // check if there is room 00567 if ( pCut->nSize == pCut->nSizeMax ) 00568 return 0; 00569 // add the new one 00570 for ( i = pCut->nSize - 1; i >= 0; i-- ) 00571 if ( pCut->pArray[i] > iNew ) 00572 pCut->pArray[i+1] = pCut->pArray[i]; 00573 else 00574 { 00575 assert( pCut->pArray[i] < iNew ); 00576 break; 00577 } 00578 pCut->pArray[i+1] = iNew; 00579 pCut->nSize++; 00580 return 1; 00581 }
int Ivy_NodeCutFindOrAdd | ( | Ivy_Store_t * | pCutStore, | |
Ivy_Cut_t * | pCutNew | |||
) |
Function*************************************************************
Synopsis [Check if the cut exists.]
Description [Returns 1 if the cut exists.]
SideEffects []
SeeAlso []
Definition at line 676 of file ivyCut.c.
00677 { 00678 Ivy_Cut_t * pCut; 00679 int i, k; 00680 assert( pCutNew->uHash ); 00681 // try to find the cut 00682 for ( i = 0; i < pCutStore->nCuts; i++ ) 00683 { 00684 pCut = pCutStore->pCuts + i; 00685 if ( pCut->uHash == pCutNew->uHash && pCut->nSize == pCutNew->nSize ) 00686 { 00687 for ( k = 0; k < pCutNew->nSize; k++ ) 00688 if ( pCut->pArray[k] != pCutNew->pArray[k] ) 00689 break; 00690 if ( k == pCutNew->nSize ) 00691 return 1; 00692 } 00693 } 00694 assert( pCutStore->nCuts < pCutStore->nCutsMax ); 00695 // add the cut 00696 pCut = pCutStore->pCuts + pCutStore->nCuts++; 00697 *pCut = *pCutNew; 00698 return 0; 00699 }
int Ivy_NodeCutFindOrAddFilter | ( | Ivy_Store_t * | pCutStore, | |
Ivy_Cut_t * | pCutNew | |||
) |
Function*************************************************************
Synopsis [Check if the cut exists.]
Description [Returns 1 if the cut exists.]
SideEffects []
SeeAlso []
Definition at line 738 of file ivyCut.c.
00739 { 00740 Ivy_Cut_t * pCut; 00741 int i, k; 00742 assert( pCutNew->uHash ); 00743 // try to find the cut 00744 for ( i = 0; i < pCutStore->nCuts; i++ ) 00745 { 00746 pCut = pCutStore->pCuts + i; 00747 if ( pCut->nSize == 0 ) 00748 continue; 00749 if ( pCut->nSize == pCutNew->nSize ) 00750 { 00751 if ( pCut->uHash == pCutNew->uHash ) 00752 { 00753 for ( k = 0; k < pCutNew->nSize; k++ ) 00754 if ( pCut->pArray[k] != pCutNew->pArray[k] ) 00755 break; 00756 if ( k == pCutNew->nSize ) 00757 return 1; 00758 } 00759 continue; 00760 } 00761 if ( pCut->nSize < pCutNew->nSize ) 00762 { 00763 // skip the non-contained cuts 00764 if ( (pCut->uHash & pCutNew->uHash) != pCut->uHash ) 00765 continue; 00766 // check containment seriously 00767 if ( Ivy_CutCheckDominance( pCut, pCutNew ) ) 00768 return 1; 00769 continue; 00770 } 00771 // check potential containment of other cut 00772 00773 // skip the non-contained cuts 00774 if ( (pCut->uHash & pCutNew->uHash) != pCutNew->uHash ) 00775 continue; 00776 // check containment seriously 00777 if ( Ivy_CutCheckDominance( pCutNew, pCut ) ) 00778 { 00779 // remove the current cut 00780 // --pCutStore->nCuts; 00781 // for ( k = i; k < pCutStore->nCuts; k++ ) 00782 // pCutStore->pCuts[k] = pCutStore->pCuts[k+1]; 00783 // i--; 00784 pCut->nSize = 0; 00785 } 00786 } 00787 assert( pCutStore->nCuts < pCutStore->nCutsMax ); 00788 // add the cut 00789 pCut = pCutStore->pCuts + pCutStore->nCuts++; 00790 *pCut = *pCutNew; 00791 return 0; 00792 }
static unsigned Ivy_NodeCutHash | ( | Ivy_Cut_t * | pCut | ) | [inline, static] |
Function*************************************************************
Synopsis [Find the hash value of the cut.]
Description []
SideEffects []
SeeAlso []
static int Ivy_NodeCutHashValue | ( | int | NodeId | ) | [inline, static] |
CFile****************************************************************
FileName [ivyCut.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [And-Inverter Graph package.]
Synopsis [Computes reconvergence driven sequential cut.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - May 11, 2006.]
Revision [
] DECLARATIONS ///
static int Ivy_NodeCutPrescreen | ( | Ivy_Cut_t * | pCut, | |
int | Id0, | |||
int | Id1 | |||
) | [inline, static] |
Function*************************************************************
Synopsis [Returns 1 if the cut can be constructed; 0 otherwise.]
Description []
SideEffects []
SeeAlso []
static void Ivy_NodeCutShrink | ( | Ivy_Cut_t * | pCut, | |
int | iOld | |||
) | [inline, static] |
Function*************************************************************
Synopsis [Removes one node to the cut.]
Description []
SideEffects []
SeeAlso []
Ivy_Store_t* Ivy_NodeFindCutsAll | ( | Ivy_Man_t * | p, | |
Ivy_Obj_t * | pObj, | |||
int | nLeaves | |||
) |
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 888 of file ivyCut.c.
00889 { 00890 static Ivy_Store_t CutStore, * pCutStore = &CutStore; 00891 Ivy_Cut_t CutNew, * pCutNew = &CutNew, * pCut; 00892 Ivy_Obj_t * pLeaf; 00893 int i, k, iLeaf0, iLeaf1; 00894 00895 assert( nLeaves <= IVY_CUT_INPUT ); 00896 00897 // start the structure 00898 pCutStore->nCuts = 0; 00899 pCutStore->nCutsMax = IVY_CUT_LIMIT; 00900 // start the trivial cut 00901 pCutNew->uHash = 0; 00902 pCutNew->nSize = 1; 00903 pCutNew->nSizeMax = nLeaves; 00904 pCutNew->pArray[0] = pObj->Id; 00905 Ivy_NodeCutHash( pCutNew ); 00906 // add the trivial cut 00907 Ivy_NodeCutFindOrAdd( pCutStore, pCutNew ); 00908 assert( pCutStore->nCuts == 1 ); 00909 00910 // explore the cuts 00911 for ( i = 0; i < pCutStore->nCuts; i++ ) 00912 { 00913 // expand this cut 00914 pCut = pCutStore->pCuts + i; 00915 if ( pCut->nSize == 0 ) 00916 continue; 00917 for ( k = 0; k < pCut->nSize; k++ ) 00918 { 00919 pLeaf = Ivy_ManObj( p, pCut->pArray[k] ); 00920 if ( Ivy_ObjIsCi(pLeaf) ) 00921 continue; 00922 /* 00923 *pCutNew = *pCut; 00924 Ivy_NodeCutShrink( pCutNew, pLeaf->Id ); 00925 if ( !Ivy_NodeCutExtend( pCutNew, Ivy_ObjFaninId0(pLeaf) ) ) 00926 continue; 00927 if ( Ivy_ObjIsNode(pLeaf) && !Ivy_NodeCutExtend( pCutNew, Ivy_ObjFaninId1(pLeaf) ) ) 00928 continue; 00929 Ivy_NodeCutHash( pCutNew ); 00930 */ 00931 iLeaf0 = Ivy_ObjId( Ivy_ObjRealFanin(Ivy_ObjFanin0(pLeaf)) ); 00932 iLeaf1 = Ivy_ObjId( Ivy_ObjRealFanin(Ivy_ObjFanin1(pLeaf)) ); 00933 // if ( iLeaf0 == iLeaf1 ) // strange situation observed on Jan 18, 2007 00934 // continue; 00935 if ( !Ivy_NodeCutPrescreen( pCut, iLeaf0, iLeaf1 ) ) 00936 continue; 00937 if ( iLeaf0 > iLeaf1 ) 00938 Ivy_NodeCutDeriveNew( pCut, pCutNew, pCut->pArray[k], iLeaf1, iLeaf0 ); 00939 else 00940 Ivy_NodeCutDeriveNew( pCut, pCutNew, pCut->pArray[k], iLeaf0, iLeaf1 ); 00941 Ivy_NodeCutFindOrAddFilter( pCutStore, pCutNew ); 00942 if ( pCutStore->nCuts == IVY_CUT_LIMIT ) 00943 break; 00944 } 00945 if ( pCutStore->nCuts == IVY_CUT_LIMIT ) 00946 break; 00947 } 00948 Ivy_NodeCompactCuts( pCutStore ); 00949 // Ivy_NodePrintCuts( pCutStore ); 00950 return pCutStore; 00951 }
FUNCTION DEFINITIONS ///Function*************************************************************
Synopsis [Evaluate the cost of removing the node from the set of leaves.]
Description [Returns the number of new leaves that will be brought in. Returns large number if the node cannot be removed from the set of leaves.]
SideEffects []
SeeAlso []
Definition at line 45 of file ivyCut.c.
00046 { 00047 Ivy_Obj_t * pNode; 00048 int nLatches, FaninLeaf, Cost; 00049 // make sure leaf is not a contant node 00050 assert( Leaf > 0 ); 00051 // get the node 00052 pNode = Ivy_ManObj( p, Ivy_LeafId(Leaf) ); 00053 // cannot expand over the PI node 00054 if ( Ivy_ObjIsPi(pNode) || Ivy_ObjIsConst1(pNode) ) 00055 return 999; 00056 // get the number of latches 00057 nLatches = Ivy_LeafLat(Leaf) + Ivy_ObjIsLatch(pNode); 00058 if ( nLatches > 15 ) 00059 return 999; 00060 // get the first fanin 00061 FaninLeaf = Ivy_LeafCreate( Ivy_ObjFaninId0(pNode), nLatches ); 00062 Cost = FaninLeaf && (Vec_IntFind(vInside, FaninLeaf) == -1); 00063 // quit if this is the one fanin node 00064 if ( Ivy_ObjIsLatch(pNode) || Ivy_ObjIsBuf(pNode) ) 00065 return Cost; 00066 assert( Ivy_ObjIsNode(pNode) ); 00067 // get the second fanin 00068 FaninLeaf = Ivy_LeafCreate( Ivy_ObjFaninId1(pNode), nLatches ); 00069 Cost += FaninLeaf && (Vec_IntFind(vInside, FaninLeaf) == -1); 00070 return Cost; 00071 }
void Ivy_NodePrintCut | ( | Ivy_Cut_t * | pCut | ) |
Function*************************************************************
Synopsis [Print the cut.]
Description []
SideEffects []
SeeAlso []
void Ivy_NodePrintCuts | ( | Ivy_Store_t * | pCutStore | ) |
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 851 of file ivyCut.c.
00852 { 00853 int i; 00854 printf( "Node %d\n", pCutStore->pCuts[0].pArray[0] ); 00855 for ( i = 0; i < pCutStore->nCuts; i++ ) 00856 Ivy_NodePrintCut( pCutStore->pCuts + i ); 00857 }
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 870 of file ivyCut.c.
00871 { 00872 if ( !Ivy_ObjIsBuf(pObj) ) 00873 return pObj; 00874 return Ivy_ObjRealFanin( Ivy_ObjFanin0(pObj) ); 00875 }