PageRenderTime 28ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/src/opt/dar/darBalance.c

https://bitbucket.org/alanmi/abc/
C | 761 lines | 419 code | 26 blank | 316 comment | 100 complexity | 18b1e8ad5510e7c52040f34261b7eb66 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. /**CFile****************************************************************
  2. FileName [darBalance.c]
  3. SystemName [ABC: Logic synthesis and verification system.]
  4. PackageName [DAG-aware AIG rewriting.]
  5. Synopsis [Algebraic AIG balancing.]
  6. Author [Alan Mishchenko]
  7. Affiliation [UC Berkeley]
  8. Date [Ver. 1.0. Started - April 28, 2007.]
  9. Revision [$Id: darBalance.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
  10. ***********************************************************************/
  11. #include "darInt.h"
  12. #include "misc/tim/tim.h"
  13. ABC_NAMESPACE_IMPL_START
  14. ////////////////////////////////////////////////////////////////////////
  15. /// DECLARATIONS ///
  16. ////////////////////////////////////////////////////////////////////////
  17. //#define USE_LUTSIZE_BALANCE
  18. ////////////////////////////////////////////////////////////////////////
  19. /// FUNCTION DEFINITIONS ///
  20. ////////////////////////////////////////////////////////////////////////
  21. /**Function*************************************************************
  22. Synopsis [Uniqifies the node.]
  23. Description []
  24. SideEffects []
  25. SeeAlso []
  26. ***********************************************************************/
  27. int Dar_ObjCompareLits( Aig_Obj_t ** pp1, Aig_Obj_t ** pp2 )
  28. {
  29. int Diff = Aig_ObjToLit(*pp1) - Aig_ObjToLit(*pp2);
  30. if ( Diff < 0 )
  31. return -1;
  32. if ( Diff > 0 )
  33. return 1;
  34. return 0;
  35. }
  36. void Dar_BalanceUniqify( Aig_Obj_t * pObj, Vec_Ptr_t * vNodes, int fExor )
  37. {
  38. Aig_Obj_t * pTemp, * pTempNext;
  39. int i, k;
  40. // sort the nodes by their literal
  41. Vec_PtrSort( vNodes, (int (*)())Dar_ObjCompareLits );
  42. // remove duplicates
  43. k = 0;
  44. Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pTemp, i )
  45. {
  46. if ( i + 1 == Vec_PtrSize(vNodes) )
  47. {
  48. Vec_PtrWriteEntry( vNodes, k++, pTemp );
  49. break;
  50. }
  51. pTempNext = (Aig_Obj_t *)Vec_PtrEntry( vNodes, i+1 );
  52. if ( !fExor && pTemp == Aig_Not(pTempNext) ) // pos_lit & neg_lit = 0
  53. {
  54. Vec_PtrClear( vNodes );
  55. return;
  56. }
  57. if ( pTemp != pTempNext ) // save if different
  58. Vec_PtrWriteEntry( vNodes, k++, pTemp );
  59. else if ( fExor ) // in case of XOR, remove identical
  60. i++;
  61. }
  62. Vec_PtrShrink( vNodes, k );
  63. if ( Vec_PtrSize(vNodes) < 2 )
  64. return;
  65. // check that there is no duplicates
  66. pTemp = (Aig_Obj_t *)Vec_PtrEntry( vNodes, 0 );
  67. Vec_PtrForEachEntryStart( Aig_Obj_t *, vNodes, pTempNext, i, 1 )
  68. {
  69. assert( pTemp != pTempNext );
  70. pTemp = pTempNext;
  71. }
  72. }
  73. /**Function*************************************************************
  74. Synopsis [Collects the nodes of the supergate.]
  75. Description []
  76. SideEffects []
  77. SeeAlso []
  78. ***********************************************************************/
  79. void Dar_BalanceCone_rec( Aig_Obj_t * pRoot, Aig_Obj_t * pObj, Vec_Ptr_t * vSuper )
  80. {
  81. if ( pObj != pRoot && (Aig_IsComplement(pObj) || Aig_ObjType(pObj) != Aig_ObjType(pRoot) || Aig_ObjRefs(pObj) > 1 || Vec_PtrSize(vSuper) > 10000) )
  82. Vec_PtrPush( vSuper, pObj );
  83. else
  84. {
  85. assert( !Aig_IsComplement(pObj) );
  86. assert( Aig_ObjIsNode(pObj) );
  87. // go through the branches
  88. Dar_BalanceCone_rec( pRoot, Aig_ObjReal_rec( Aig_ObjChild0(pObj) ), vSuper );
  89. Dar_BalanceCone_rec( pRoot, Aig_ObjReal_rec( Aig_ObjChild1(pObj) ), vSuper );
  90. }
  91. }
  92. Vec_Ptr_t * Dar_BalanceCone( Aig_Obj_t * pObj, Vec_Vec_t * vStore, int Level )
  93. {
  94. Vec_Ptr_t * vNodes;
  95. assert( !Aig_IsComplement(pObj) );
  96. assert( Aig_ObjIsNode(pObj) );
  97. // extend the storage
  98. if ( Vec_VecSize( vStore ) <= Level )
  99. Vec_VecPush( vStore, Level, 0 );
  100. // get the temporary array of nodes
  101. vNodes = Vec_VecEntry( vStore, Level );
  102. Vec_PtrClear( vNodes );
  103. // collect the nodes in the implication supergate
  104. Dar_BalanceCone_rec( pObj, pObj, vNodes );
  105. // remove duplicates
  106. Dar_BalanceUniqify( pObj, vNodes, Aig_ObjIsExor(pObj) );
  107. return vNodes;
  108. }
  109. /**Function*************************************************************
  110. Synopsis [Collects the nodes of the supergate.]
  111. Description []
  112. SideEffects []
  113. SeeAlso []
  114. ***********************************************************************/
  115. /*
  116. int Dar_BalanceCone_rec( Aig_Obj_t * pRoot, Aig_Obj_t * pObj, Vec_Ptr_t * vSuper )
  117. {
  118. int RetValue1, RetValue2, i;
  119. // check if the node is visited
  120. if ( Aig_Regular(pObj)->fMarkB )
  121. {
  122. if ( Aig_ObjIsExor(pRoot) )
  123. {
  124. assert( !Aig_IsComplement(pObj) );
  125. // check if the node occurs in the same polarity
  126. Vec_PtrRemove( vSuper, pObj );
  127. Aig_Regular(pObj)->fMarkB = 0;
  128. //printf( " Duplicated EXOR input!!! " );
  129. return 1;
  130. }
  131. else
  132. {
  133. // check if the node occurs in the same polarity
  134. for ( i = 0; i < vSuper->nSize; i++ )
  135. if ( vSuper->pArray[i] == pObj )
  136. return 1;
  137. // check if the node is present in the opposite polarity
  138. for ( i = 0; i < vSuper->nSize; i++ )
  139. if ( vSuper->pArray[i] == Aig_Not(pObj) )
  140. return -1;
  141. }
  142. assert( 0 );
  143. return 0;
  144. }
  145. // if the new node is complemented or a PI, another gate begins
  146. if ( pObj != pRoot && (Aig_IsComplement(pObj) || Aig_ObjType(pObj) != Aig_ObjType(pRoot) || Aig_ObjRefs(pObj) > 1 || Vec_PtrSize(vSuper) > 10000) )
  147. {
  148. Vec_PtrPush( vSuper, pObj );
  149. Aig_Regular(pObj)->fMarkB = 1;
  150. return 0;
  151. }
  152. assert( !Aig_IsComplement(pObj) );
  153. assert( Aig_ObjIsNode(pObj) );
  154. // go through the branches
  155. RetValue1 = Dar_BalanceCone_rec( pRoot, Aig_ObjReal_rec( Aig_ObjChild0(pObj) ), vSuper );
  156. RetValue2 = Dar_BalanceCone_rec( pRoot, Aig_ObjReal_rec( Aig_ObjChild1(pObj) ), vSuper );
  157. if ( RetValue1 == -1 || RetValue2 == -1 )
  158. return -1;
  159. // return 1 if at least one branch has a duplicate
  160. return RetValue1 || RetValue2;
  161. }
  162. Vec_Ptr_t * Dar_BalanceCone( Aig_Obj_t * pObj, Vec_Vec_t * vStore, int Level )
  163. {
  164. Vec_Ptr_t * vNodes;
  165. int RetValue, i;
  166. assert( !Aig_IsComplement(pObj) );
  167. // extend the storage
  168. if ( Vec_VecSize( vStore ) <= Level )
  169. Vec_VecPush( vStore, Level, 0 );
  170. // get the temporary array of nodes
  171. vNodes = Vec_VecEntry( vStore, Level );
  172. Vec_PtrClear( vNodes );
  173. // collect the nodes in the implication supergate
  174. RetValue = Dar_BalanceCone_rec( pObj, pObj, vNodes );
  175. assert( RetValue != 0 || vNodes->nSize > 1 );
  176. // unmark the visited nodes
  177. Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i )
  178. Aig_Regular(pObj)->fMarkB = 0;
  179. // if we found the node and its complement in the same implication supergate,
  180. // return empty set of nodes (meaning that we should use constant-0 node)
  181. if ( RetValue == -1 )
  182. vNodes->nSize = 0;
  183. return vNodes;
  184. }
  185. */
  186. /**Function*************************************************************
  187. Synopsis [Finds the left bound on the next candidate to be paired.]
  188. Description [The nodes in the array are in the decreasing order of levels.
  189. The last node in the array has the smallest level. By default it would be paired
  190. with the next node on the left. However, it may be possible to pair it with some
  191. other node on the left, in such a way that the new node is shared. This procedure
  192. finds the index of the left-most node, which can be paired with the last node.]
  193. SideEffects []
  194. SeeAlso []
  195. ***********************************************************************/
  196. int Dar_BalanceFindLeft( Vec_Ptr_t * vSuper )
  197. {
  198. Aig_Obj_t * pObjRight, * pObjLeft;
  199. int Current;
  200. // if two or less nodes, pair with the first
  201. if ( Vec_PtrSize(vSuper) < 3 )
  202. return 0;
  203. // set the pointer to the one before the last
  204. Current = Vec_PtrSize(vSuper) - 2;
  205. pObjRight = (Aig_Obj_t *)Vec_PtrEntry( vSuper, Current );
  206. // go through the nodes to the left of this one
  207. for ( Current--; Current >= 0; Current-- )
  208. {
  209. // get the next node on the left
  210. pObjLeft = (Aig_Obj_t *)Vec_PtrEntry( vSuper, Current );
  211. // if the level of this node is different, quit the loop
  212. if ( Aig_ObjLevel(Aig_Regular(pObjLeft)) != Aig_ObjLevel(Aig_Regular(pObjRight)) )
  213. break;
  214. }
  215. Current++;
  216. // get the node, for which the equality holds
  217. pObjLeft = (Aig_Obj_t *)Vec_PtrEntry( vSuper, Current );
  218. assert( Aig_ObjLevel(Aig_Regular(pObjLeft)) == Aig_ObjLevel(Aig_Regular(pObjRight)) );
  219. return Current;
  220. }
  221. /**Function*************************************************************
  222. Synopsis [Moves closer to the end the node that is best for sharing.]
  223. Description [If there is no node with sharing, randomly chooses one of
  224. the legal nodes.]
  225. SideEffects []
  226. SeeAlso []
  227. ***********************************************************************/
  228. void Dar_BalancePermute( Aig_Man_t * p, Vec_Ptr_t * vSuper, int LeftBound, int fExor )
  229. {
  230. Aig_Obj_t * pObj1, * pObj2, * pObj3, * pGhost;
  231. int RightBound, i;
  232. // get the right bound
  233. RightBound = Vec_PtrSize(vSuper) - 2;
  234. assert( LeftBound <= RightBound );
  235. if ( LeftBound == RightBound )
  236. return;
  237. // get the two last nodes
  238. pObj1 = (Aig_Obj_t *)Vec_PtrEntry( vSuper, RightBound + 1 );
  239. pObj2 = (Aig_Obj_t *)Vec_PtrEntry( vSuper, RightBound );
  240. if ( Aig_Regular(pObj1) == p->pConst1 || Aig_Regular(pObj2) == p->pConst1 || Aig_Regular(pObj1) == Aig_Regular(pObj2) )
  241. return;
  242. // find the first node that can be shared
  243. for ( i = RightBound; i >= LeftBound; i-- )
  244. {
  245. pObj3 = (Aig_Obj_t *)Vec_PtrEntry( vSuper, i );
  246. if ( Aig_Regular(pObj3) == p->pConst1 )
  247. {
  248. Vec_PtrWriteEntry( vSuper, i, pObj2 );
  249. Vec_PtrWriteEntry( vSuper, RightBound, pObj3 );
  250. return;
  251. }
  252. if ( Aig_Regular(pObj1) == Aig_Regular(pObj3) )
  253. {
  254. if ( pObj3 == pObj2 )
  255. return;
  256. Vec_PtrWriteEntry( vSuper, i, pObj2 );
  257. Vec_PtrWriteEntry( vSuper, RightBound, pObj3 );
  258. return;
  259. }
  260. pGhost = Aig_ObjCreateGhost( p, pObj1, pObj3, fExor? AIG_OBJ_EXOR : AIG_OBJ_AND );
  261. if ( Aig_TableLookup( p, pGhost ) )
  262. {
  263. if ( pObj3 == pObj2 )
  264. return;
  265. Vec_PtrWriteEntry( vSuper, i, pObj2 );
  266. Vec_PtrWriteEntry( vSuper, RightBound, pObj3 );
  267. return;
  268. }
  269. }
  270. /*
  271. // we did not find the node to share, randomize choice
  272. {
  273. int Choice = Aig_ManRandom(0) % (RightBound - LeftBound + 1);
  274. pObj3 = Vec_PtrEntry( vSuper, LeftBound + Choice );
  275. if ( pObj3 == pObj2 )
  276. return;
  277. Vec_PtrWriteEntry( vSuper, LeftBound + Choice, pObj2 );
  278. Vec_PtrWriteEntry( vSuper, RightBound, pObj3 );
  279. }
  280. */
  281. }
  282. /**Function*************************************************************
  283. Synopsis [Procedure used for sorting the nodes in decreasing order of levels.]
  284. Description []
  285. SideEffects []
  286. SeeAlso []
  287. ***********************************************************************/
  288. int Aig_NodeCompareLevelsDecrease( Aig_Obj_t ** pp1, Aig_Obj_t ** pp2 )
  289. {
  290. int Diff = Aig_ObjLevel(Aig_Regular(*pp1)) - Aig_ObjLevel(Aig_Regular(*pp2));
  291. if ( Diff > 0 )
  292. return -1;
  293. if ( Diff < 0 )
  294. return 1;
  295. Diff = Aig_ObjId(Aig_Regular(*pp1)) - Aig_ObjId(Aig_Regular(*pp2));
  296. if ( Diff > 0 )
  297. return -1;
  298. if ( Diff < 0 )
  299. return 1;
  300. return 0;
  301. }
  302. /**Function*************************************************************
  303. Synopsis [Inserts a new node in the order by levels.]
  304. Description []
  305. SideEffects []
  306. SeeAlso []
  307. ***********************************************************************/
  308. void Dar_BalancePushUniqueOrderByLevel( Vec_Ptr_t * vStore, Aig_Obj_t * pObj, int fExor )
  309. {
  310. Aig_Obj_t * pObj1, * pObj2;
  311. int i;
  312. if ( Vec_PtrPushUnique(vStore, pObj) )
  313. {
  314. if ( fExor )
  315. Vec_PtrRemove(vStore, pObj);
  316. return;
  317. }
  318. // find the p of the node
  319. for ( i = vStore->nSize-1; i > 0; i-- )
  320. {
  321. pObj1 = (Aig_Obj_t *)vStore->pArray[i ];
  322. pObj2 = (Aig_Obj_t *)vStore->pArray[i-1];
  323. if ( Aig_ObjLevel(Aig_Regular(pObj1)) <= Aig_ObjLevel(Aig_Regular(pObj2)) )
  324. break;
  325. vStore->pArray[i ] = pObj2;
  326. vStore->pArray[i-1] = pObj1;
  327. }
  328. }
  329. /**Function*************************************************************
  330. Synopsis [Builds implication supergate.]
  331. Description []
  332. SideEffects []
  333. SeeAlso []
  334. ***********************************************************************/
  335. Aig_Obj_t * Dar_BalanceBuildSuper( Aig_Man_t * p, Vec_Ptr_t * vSuper, Aig_Type_t Type, int fUpdateLevel )
  336. {
  337. Aig_Obj_t * pObj1, * pObj2;
  338. int LeftBound;
  339. assert( vSuper->nSize > 1 );
  340. // sort the new nodes by level in the decreasing order
  341. Vec_PtrSort( vSuper, (int (*)(void))Aig_NodeCompareLevelsDecrease );
  342. // balance the nodes
  343. while ( vSuper->nSize > 1 )
  344. {
  345. // find the left bound on the node to be paired
  346. LeftBound = (!fUpdateLevel)? 0 : Dar_BalanceFindLeft( vSuper );
  347. // find the node that can be shared (if no such node, randomize choice)
  348. Dar_BalancePermute( p, vSuper, LeftBound, Type == AIG_OBJ_EXOR );
  349. // pull out the last two nodes
  350. pObj1 = (Aig_Obj_t *)Vec_PtrPop(vSuper);
  351. pObj2 = (Aig_Obj_t *)Vec_PtrPop(vSuper);
  352. Dar_BalancePushUniqueOrderByLevel( vSuper, Aig_Oper(p, pObj1, pObj2, Type), Type == AIG_OBJ_EXOR );
  353. }
  354. return (Aig_Obj_t *)Vec_PtrEntry(vSuper, 0);
  355. }
  356. /**Function*************************************************************
  357. Synopsis [Returns affective support size.]
  358. Description []
  359. SideEffects []
  360. SeeAlso []
  361. ***********************************************************************/
  362. int Aig_BaseSize( Aig_Man_t * p, Aig_Obj_t * pObj, int nLutSize )
  363. {
  364. int nBaseSize;
  365. pObj = Aig_Regular(pObj);
  366. if ( Aig_ObjIsConst1(pObj) )
  367. return 0;
  368. if ( Aig_ObjLevel(pObj) >= nLutSize )
  369. return 1;
  370. nBaseSize = Aig_SupportSize( p, pObj );
  371. if ( nBaseSize >= nLutSize )
  372. return 1;
  373. return nBaseSize;
  374. }
  375. /**Function*************************************************************
  376. Synopsis [Builds implication supergate.]
  377. Description []
  378. SideEffects []
  379. SeeAlso []
  380. ***********************************************************************/
  381. Aig_Obj_t * Dar_BalanceBuildSuperTop( Aig_Man_t * p, Vec_Ptr_t * vSuper, Aig_Type_t Type, int fUpdateLevel, int nLutSize )
  382. {
  383. Vec_Ptr_t * vSubset;
  384. Aig_Obj_t * pObj;
  385. int i, nBaseSizeAll, nBaseSize;
  386. assert( vSuper->nSize > 1 );
  387. // sort the new nodes by level in the decreasing order
  388. Vec_PtrSort( vSuper, (int (*)(void))Aig_NodeCompareLevelsDecrease );
  389. // add one LUT at a time
  390. while ( Vec_PtrSize(vSuper) > 1 )
  391. {
  392. // isolate the group of nodes with nLutSize inputs
  393. nBaseSizeAll = 0;
  394. vSubset = Vec_PtrAlloc( nLutSize );
  395. Vec_PtrForEachEntryReverse( Aig_Obj_t *, vSuper, pObj, i )
  396. {
  397. nBaseSize = Aig_BaseSize( p, pObj, nLutSize );
  398. if ( nBaseSizeAll + nBaseSize > nLutSize && Vec_PtrSize(vSubset) > 1 )
  399. break;
  400. nBaseSizeAll += nBaseSize;
  401. Vec_PtrPush( vSubset, pObj );
  402. }
  403. // remove them from vSuper
  404. Vec_PtrShrink( vSuper, Vec_PtrSize(vSuper) - Vec_PtrSize(vSubset) );
  405. // create the new supergate
  406. pObj = Dar_BalanceBuildSuper( p, vSubset, Type, fUpdateLevel );
  407. Vec_PtrFree( vSubset );
  408. // add the new output
  409. Dar_BalancePushUniqueOrderByLevel( vSuper, pObj, Type == AIG_OBJ_EXOR );
  410. }
  411. return (Aig_Obj_t *)Vec_PtrEntry(vSuper, 0);
  412. }
  413. /**Function*************************************************************
  414. Synopsis [Returns the new node constructed.]
  415. Description []
  416. SideEffects []
  417. SeeAlso []
  418. ***********************************************************************/
  419. Aig_Obj_t * Dar_Balance_rec( Aig_Man_t * pNew, Aig_Obj_t * pObjOld, Vec_Vec_t * vStore, int Level, int fUpdateLevel )
  420. {
  421. Aig_Obj_t * pObjNew;
  422. Vec_Ptr_t * vSuper;
  423. int i;
  424. assert( !Aig_IsComplement(pObjOld) );
  425. assert( !Aig_ObjIsBuf(pObjOld) );
  426. // return if the result is known
  427. if ( pObjOld->pData )
  428. return (Aig_Obj_t *)pObjOld->pData;
  429. assert( Aig_ObjIsNode(pObjOld) );
  430. // get the implication supergate
  431. vSuper = Dar_BalanceCone( pObjOld, vStore, Level );
  432. // check if supergate contains two nodes in the opposite polarity
  433. if ( vSuper->nSize == 0 )
  434. return (Aig_Obj_t *)(pObjOld->pData = Aig_ManConst0(pNew));
  435. // for each old node, derive the new well-balanced node
  436. for ( i = 0; i < Vec_PtrSize(vSuper); i++ )
  437. {
  438. pObjNew = Dar_Balance_rec( pNew, Aig_Regular((Aig_Obj_t *)vSuper->pArray[i]), vStore, Level + 1, fUpdateLevel );
  439. if ( pObjNew == NULL )
  440. return NULL;
  441. vSuper->pArray[i] = Aig_NotCond( pObjNew, Aig_IsComplement((Aig_Obj_t *)vSuper->pArray[i]) );
  442. }
  443. // check for exactly one node
  444. if ( vSuper->nSize == 1 )
  445. return (Aig_Obj_t *)Vec_PtrEntry(vSuper, 0);
  446. // build the supergate
  447. #ifdef USE_LUTSIZE_BALANCE
  448. pObjNew = Dar_BalanceBuildSuperTop( pNew, vSuper, Aig_ObjType(pObjOld), fUpdateLevel, 6 );
  449. #else
  450. pObjNew = Dar_BalanceBuildSuper( pNew, vSuper, Aig_ObjType(pObjOld), fUpdateLevel );
  451. #endif
  452. if ( pNew->Time2Quit && !(Aig_Regular(pObjNew)->Id & 255) && Abc_Clock() > pNew->Time2Quit )
  453. return NULL;
  454. // make sure the balanced node is not assigned
  455. // assert( pObjOld->Level >= Aig_Regular(pObjNew)->Level );
  456. assert( pObjOld->pData == NULL );
  457. return (Aig_Obj_t *)(pObjOld->pData = pObjNew);
  458. }
  459. /**Function*************************************************************
  460. Synopsis [Performs algebraic balancing of the AIG.]
  461. Description []
  462. SideEffects []
  463. SeeAlso []
  464. ***********************************************************************/
  465. Aig_Man_t * Dar_ManBalance( Aig_Man_t * p, int fUpdateLevel )
  466. {
  467. Aig_Man_t * pNew;
  468. Aig_Obj_t * pObj, * pDriver, * pObjNew;
  469. Vec_Vec_t * vStore;
  470. int i;
  471. assert( Aig_ManVerifyTopoOrder(p) );
  472. // create the new manager
  473. pNew = Aig_ManStart( Aig_ManObjNumMax(p) );
  474. pNew->pName = Abc_UtilStrsav( p->pName );
  475. pNew->pSpec = Abc_UtilStrsav( p->pSpec );
  476. pNew->nAsserts = p->nAsserts;
  477. pNew->nConstrs = p->nConstrs;
  478. pNew->nBarBufs = p->nBarBufs;
  479. pNew->Time2Quit = p->Time2Quit;
  480. if ( p->vFlopNums )
  481. pNew->vFlopNums = Vec_IntDup( p->vFlopNums );
  482. // map the PI nodes
  483. Aig_ManCleanData( p );
  484. Aig_ManConst1(p)->pData = Aig_ManConst1(pNew);
  485. vStore = Vec_VecAlloc( 50 );
  486. if ( p->pManTime != NULL )
  487. {
  488. float arrTime;
  489. Tim_ManIncrementTravId( (Tim_Man_t *)p->pManTime );
  490. Aig_ManSetCioIds( p );
  491. Aig_ManForEachObj( p, pObj, i )
  492. {
  493. if ( Aig_ObjIsNode(pObj) || Aig_ObjIsConst1(pObj) )
  494. continue;
  495. if ( Aig_ObjIsCi(pObj) )
  496. {
  497. // copy the PI
  498. pObjNew = Aig_ObjCreateCi(pNew);
  499. pObj->pData = pObjNew;
  500. // set the arrival time of the new PI
  501. arrTime = Tim_ManGetCiArrival( (Tim_Man_t *)p->pManTime, Aig_ObjCioId(pObj) );
  502. pObjNew->Level = (int)arrTime;
  503. }
  504. else if ( Aig_ObjIsCo(pObj) )
  505. {
  506. // perform balancing
  507. pDriver = Aig_ObjReal_rec( Aig_ObjChild0(pObj) );
  508. pObjNew = Dar_Balance_rec( pNew, Aig_Regular(pDriver), vStore, 0, fUpdateLevel );
  509. if ( pObjNew == NULL )
  510. {
  511. Vec_VecFree( vStore );
  512. Aig_ManStop( pNew );
  513. return NULL;
  514. }
  515. pObjNew = Aig_NotCond( pObjNew, Aig_IsComplement(pDriver) );
  516. // save arrival time of the output
  517. arrTime = (float)Aig_Regular(pObjNew)->Level;
  518. Tim_ManSetCoArrival( (Tim_Man_t *)p->pManTime, Aig_ObjCioId(pObj), arrTime );
  519. // create PO
  520. pObjNew = Aig_ObjCreateCo( pNew, pObjNew );
  521. }
  522. else
  523. assert( 0 );
  524. }
  525. Aig_ManCleanCioIds( p );
  526. pNew->pManTime = Tim_ManDup( (Tim_Man_t *)p->pManTime, 0 );
  527. }
  528. else
  529. {
  530. Aig_ManForEachCi( p, pObj, i )
  531. {
  532. pObjNew = Aig_ObjCreateCi(pNew);
  533. pObjNew->Level = pObj->Level;
  534. pObj->pData = pObjNew;
  535. }
  536. if ( p->nBarBufs == 0 )
  537. {
  538. Aig_ManForEachCo( p, pObj, i )
  539. {
  540. pDriver = Aig_ObjReal_rec( Aig_ObjChild0(pObj) );
  541. pObjNew = Dar_Balance_rec( pNew, Aig_Regular(pDriver), vStore, 0, fUpdateLevel );
  542. if ( pObjNew == NULL )
  543. {
  544. Vec_VecFree( vStore );
  545. Aig_ManStop( pNew );
  546. return NULL;
  547. }
  548. pObjNew = Aig_NotCond( pObjNew, Aig_IsComplement(pDriver) );
  549. pObjNew = Aig_ObjCreateCo( pNew, pObjNew );
  550. }
  551. }
  552. else
  553. {
  554. Vec_Ptr_t * vLits = Vec_PtrStart( Aig_ManCoNum(p) );
  555. Aig_ManForEachCo( p, pObj, i )
  556. {
  557. int k = i < p->nBarBufs ? Aig_ManCoNum(p) - p->nBarBufs + i : i - p->nBarBufs;
  558. pObj = Aig_ManCo( p, k );
  559. pDriver = Aig_ObjReal_rec( Aig_ObjChild0(pObj) );
  560. pObjNew = Dar_Balance_rec( pNew, Aig_Regular(pDriver), vStore, 0, fUpdateLevel );
  561. if ( pObjNew == NULL )
  562. {
  563. Vec_VecFree( vStore );
  564. Aig_ManStop( pNew );
  565. return NULL;
  566. }
  567. pObjNew = Aig_NotCond( pObjNew, Aig_IsComplement(pDriver) );
  568. Vec_PtrWriteEntry( vLits, k, pObjNew );
  569. if ( i < p->nBarBufs )
  570. Aig_ManCi(pNew, Aig_ManCiNum(p) - p->nBarBufs + i)->Level = Aig_Regular(pObjNew)->Level;
  571. }
  572. Aig_ManForEachCo( p, pObj, i )
  573. Aig_ObjCreateCo( pNew, (Aig_Obj_t *)Vec_PtrEntry(vLits, i) );
  574. Vec_PtrFree(vLits);
  575. }
  576. }
  577. Vec_VecFree( vStore );
  578. // remove dangling nodes
  579. Aig_ManCleanup( pNew );
  580. Aig_ManSetRegNum( pNew, Aig_ManRegNum(p) );
  581. // check the resulting AIG
  582. if ( !Aig_ManCheck(pNew) )
  583. printf( "Dar_ManBalance(): The check has failed.\n" );
  584. return pNew;
  585. }
  586. /**Function*************************************************************
  587. Synopsis [Reproduces script "compress2".]
  588. Description []
  589. SideEffects []
  590. SeeAlso []
  591. ***********************************************************************/
  592. Aig_Man_t * Dar_ManBalanceXor( Aig_Man_t * pAig, int fExor, int fUpdateLevel, int fVerbose )
  593. {
  594. Aig_Man_t * pAigXor, * pRes;
  595. if ( fExor )
  596. {
  597. pAigXor = Aig_ManDupExor( pAig );
  598. if ( fVerbose )
  599. Dar_BalancePrintStats( pAigXor );
  600. pRes = Dar_ManBalance( pAigXor, fUpdateLevel );
  601. Aig_ManStop( pAigXor );
  602. }
  603. else
  604. {
  605. pRes = Dar_ManBalance( pAig, fUpdateLevel );
  606. }
  607. return pRes;
  608. }
  609. /**Function*************************************************************
  610. Synopsis [Inserts a new node in the order by levels.]
  611. Description []
  612. SideEffects []
  613. SeeAlso []
  614. ***********************************************************************/
  615. void Dar_BalancePrintStats( Aig_Man_t * p )
  616. {
  617. Vec_Ptr_t * vSuper;
  618. Aig_Obj_t * pObj, * pTemp;
  619. int i, k;
  620. if ( Aig_ManExorNum(p) == 0 )
  621. {
  622. printf( "There is no EXOR gates.\n" );
  623. return;
  624. }
  625. Aig_ManForEachExor( p, pObj, i )
  626. {
  627. Aig_ObjFanin0(pObj)->fMarkA = 1;
  628. Aig_ObjFanin1(pObj)->fMarkA = 1;
  629. assert( !Aig_ObjFaninC0(pObj) );
  630. assert( !Aig_ObjFaninC1(pObj) );
  631. }
  632. vSuper = Vec_PtrAlloc( 1000 );
  633. Aig_ManForEachExor( p, pObj, i )
  634. {
  635. if ( pObj->fMarkA && pObj->nRefs == 1 )
  636. continue;
  637. Vec_PtrClear( vSuper );
  638. Dar_BalanceCone_rec( pObj, pObj, vSuper );
  639. Vec_PtrForEachEntry( Aig_Obj_t *, vSuper, pTemp, k )
  640. pTemp->fMarkB = 0;
  641. if ( Vec_PtrSize(vSuper) < 3 )
  642. continue;
  643. printf( " %d(", Vec_PtrSize(vSuper) );
  644. Vec_PtrForEachEntry( Aig_Obj_t *, vSuper, pTemp, k )
  645. printf( " %d", pTemp->Level );
  646. printf( " )" );
  647. }
  648. Vec_PtrFree( vSuper );
  649. Aig_ManForEachObj( p, pObj, i )
  650. pObj->fMarkA = 0;
  651. printf( "\n" );
  652. }
  653. ////////////////////////////////////////////////////////////////////////
  654. /// END OF FILE ///
  655. ////////////////////////////////////////////////////////////////////////
  656. ABC_NAMESPACE_IMPL_END