PageRenderTime 51ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/src/base/abc/abcUtil.c

https://bitbucket.org/alanmi/abc/
C | 2935 lines | 1741 code | 122 blank | 1072 comment | 313 complexity | aac5066405751703941b7c80364bff0e MD5 | raw file
Possible License(s): BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

  1. /**CFile****************************************************************
  2. FileName [abcUtil.c]
  3. SystemName [ABC: Logic synthesis and verification system.]
  4. PackageName [Network and node package.]
  5. Synopsis [Various utilities.]
  6. Author [Alan Mishchenko]
  7. Affiliation [UC Berkeley]
  8. Date [Ver. 1.0. Started - June 20, 2005.]
  9. Revision [$Id: abcUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
  10. ***********************************************************************/
  11. #include "abc.h"
  12. #include "base/main/main.h"
  13. #include "map/mio/mio.h"
  14. #include "bool/dec/dec.h"
  15. #include "opt/fxu/fxu.h"
  16. #ifdef ABC_USE_CUDD
  17. #include "bdd/extrab/extraBdd.h"
  18. #endif
  19. ABC_NAMESPACE_IMPL_START
  20. ////////////////////////////////////////////////////////////////////////
  21. /// DECLARATIONS ///
  22. ////////////////////////////////////////////////////////////////////////
  23. ////////////////////////////////////////////////////////////////////////
  24. /// FUNCTION DEFINITIONS ///
  25. ////////////////////////////////////////////////////////////////////////
  26. /**Function*************************************************************
  27. Synopsis [Frees one attribute manager.]
  28. Description []
  29. SideEffects []
  30. SeeAlso []
  31. ***********************************************************************/
  32. void * Abc_NtkAttrFree( Abc_Ntk_t * pNtk, int Attr, int fFreeMan )
  33. {
  34. void * pUserMan;
  35. Vec_Att_t * pAttrMan;
  36. pAttrMan = (Vec_Att_t *)Vec_PtrEntry( pNtk->vAttrs, Attr );
  37. Vec_PtrWriteEntry( pNtk->vAttrs, Attr, NULL );
  38. pUserMan = Vec_AttFree( pAttrMan, fFreeMan );
  39. return pUserMan;
  40. }
  41. /**Function*************************************************************
  42. Synopsis [Order CI/COs.]
  43. Description []
  44. SideEffects []
  45. SeeAlso []
  46. ***********************************************************************/
  47. void Abc_NtkOrderCisCos( Abc_Ntk_t * pNtk )
  48. {
  49. Abc_Obj_t * pObj, * pTerm;
  50. int i, k;
  51. Vec_PtrClear( pNtk->vCis );
  52. Vec_PtrClear( pNtk->vCos );
  53. Abc_NtkForEachPi( pNtk, pObj, i )
  54. Vec_PtrPush( pNtk->vCis, pObj );
  55. Abc_NtkForEachPo( pNtk, pObj, i )
  56. Vec_PtrPush( pNtk->vCos, pObj );
  57. Abc_NtkForEachBox( pNtk, pObj, i )
  58. {
  59. if ( Abc_ObjIsLatch(pObj) )
  60. continue;
  61. Abc_ObjForEachFanin( pObj, pTerm, k )
  62. Vec_PtrPush( pNtk->vCos, pTerm );
  63. Abc_ObjForEachFanout( pObj, pTerm, k )
  64. Vec_PtrPush( pNtk->vCis, pTerm );
  65. }
  66. Abc_NtkForEachBox( pNtk, pObj, i )
  67. {
  68. if ( !Abc_ObjIsLatch(pObj) )
  69. continue;
  70. Abc_ObjForEachFanin( pObj, pTerm, k )
  71. Vec_PtrPush( pNtk->vCos, pTerm );
  72. Abc_ObjForEachFanout( pObj, pTerm, k )
  73. Vec_PtrPush( pNtk->vCis, pTerm );
  74. }
  75. }
  76. /**Function*************************************************************
  77. Synopsis [Reads the number of cubes of the node.]
  78. Description []
  79. SideEffects []
  80. SeeAlso []
  81. ***********************************************************************/
  82. int Abc_NtkGetCubeNum( Abc_Ntk_t * pNtk )
  83. {
  84. Abc_Obj_t * pNode;
  85. int i, nCubes = 0;
  86. assert( Abc_NtkHasSop(pNtk) );
  87. Abc_NtkForEachNode( pNtk, pNode, i )
  88. {
  89. if ( Abc_NodeIsConst(pNode) )
  90. continue;
  91. assert( pNode->pData );
  92. nCubes += Abc_SopGetCubeNum( (char *)pNode->pData );
  93. }
  94. return nCubes;
  95. }
  96. /**Function*************************************************************
  97. Synopsis [Reads the number of cubes of the node.]
  98. Description []
  99. SideEffects []
  100. SeeAlso []
  101. ***********************************************************************/
  102. int Abc_NtkGetCubePairNum( Abc_Ntk_t * pNtk )
  103. {
  104. Abc_Obj_t * pNode;
  105. int i;
  106. word nCubes, nCubePairs = 0;
  107. assert( Abc_NtkHasSop(pNtk) );
  108. Abc_NtkForEachNode( pNtk, pNode, i )
  109. {
  110. if ( Abc_NodeIsConst(pNode) )
  111. continue;
  112. assert( pNode->pData );
  113. nCubes = (word)Abc_SopGetCubeNum( (char *)pNode->pData );
  114. if ( nCubes > 1 )
  115. nCubePairs += nCubes * (nCubes - 1) / 2;
  116. }
  117. return (int)(nCubePairs > (1<<30) ? (1<<30) : nCubePairs);
  118. }
  119. /**Function*************************************************************
  120. Synopsis [Reads the number of literals in the SOPs of the nodes.]
  121. Description []
  122. SideEffects []
  123. SeeAlso []
  124. ***********************************************************************/
  125. int Abc_NtkGetLitNum( Abc_Ntk_t * pNtk )
  126. {
  127. Abc_Obj_t * pNode;
  128. int i, nLits = 0;
  129. assert( Abc_NtkHasSop(pNtk) );
  130. Abc_NtkForEachNode( pNtk, pNode, i )
  131. {
  132. assert( pNode->pData );
  133. nLits += Abc_SopGetLitNum( (char *)pNode->pData );
  134. }
  135. return nLits;
  136. }
  137. /**Function*************************************************************
  138. Synopsis [Counts the number of literals in the factored forms.]
  139. Description []
  140. SideEffects []
  141. SeeAlso []
  142. ***********************************************************************/
  143. int Abc_NtkGetLitFactNum( Abc_Ntk_t * pNtk )
  144. {
  145. Dec_Graph_t * pFactor;
  146. Abc_Obj_t * pNode;
  147. int nNodes, i;
  148. assert( Abc_NtkHasSop(pNtk) );
  149. nNodes = 0;
  150. Abc_NtkForEachNode( pNtk, pNode, i )
  151. {
  152. if ( Abc_NodeIsConst(pNode) )
  153. continue;
  154. pFactor = Dec_Factor( (char *)pNode->pData );
  155. nNodes += 1 + Dec_GraphNodeNum(pFactor);
  156. Dec_GraphFree( pFactor );
  157. }
  158. return nNodes;
  159. }
  160. /**Function*************************************************************
  161. Synopsis [Counts the number of nodes with more than 1 reference.]
  162. Description []
  163. SideEffects []
  164. SeeAlso []
  165. ***********************************************************************/
  166. int Abc_NtkGetMultiRefNum( Abc_Ntk_t * pNtk )
  167. {
  168. Abc_Obj_t * pNode;
  169. int nNodes, i;
  170. assert( Abc_NtkIsStrash(pNtk) );
  171. nNodes = 0;
  172. Abc_NtkForEachNode( pNtk, pNode, i )
  173. nNodes += (int)(Abc_ObjFanoutNum(pNode) > 1);
  174. return nNodes;
  175. }
  176. /**Function*************************************************************
  177. Synopsis [Reads the number of BDD nodes.]
  178. Description []
  179. SideEffects []
  180. SeeAlso []
  181. ***********************************************************************/
  182. int Abc_NtkGetBddNodeNum( Abc_Ntk_t * pNtk )
  183. {
  184. int nNodes = 0;
  185. #ifdef ABC_USE_CUDD
  186. Abc_Obj_t * pNode;
  187. int i;
  188. assert( Abc_NtkIsBddLogic(pNtk) );
  189. Abc_NtkForEachNode( pNtk, pNode, i )
  190. {
  191. assert( pNode->pData );
  192. if ( Abc_ObjFaninNum(pNode) < 2 )
  193. continue;
  194. nNodes += pNode->pData? -1 + Cudd_DagSize( (DdNode *)pNode->pData ) : 0;
  195. }
  196. #endif
  197. return nNodes;
  198. }
  199. /**Function*************************************************************
  200. Synopsis [Reads the number of BDD nodes.]
  201. Description []
  202. SideEffects []
  203. SeeAlso []
  204. ***********************************************************************/
  205. int Abc_NtkGetAigNodeNum( Abc_Ntk_t * pNtk )
  206. {
  207. Abc_Obj_t * pNode;
  208. int i, nNodes = 0;
  209. assert( Abc_NtkIsAigLogic(pNtk) );
  210. Abc_NtkForEachNode( pNtk, pNode, i )
  211. {
  212. assert( pNode->pData );
  213. if ( Abc_ObjFaninNum(pNode) < 2 )
  214. continue;
  215. //printf( "%d ", Hop_DagSize( pNode->pData ) );
  216. nNodes += pNode->pData? Hop_DagSize( (Hop_Obj_t *)pNode->pData ) : 0;
  217. }
  218. return nNodes;
  219. }
  220. /**Function*************************************************************
  221. Synopsis [Reads the number of BDD nodes.]
  222. Description []
  223. SideEffects []
  224. SeeAlso []
  225. ***********************************************************************/
  226. int Abc_NtkGetClauseNum( Abc_Ntk_t * pNtk )
  227. {
  228. int nClauses = 0;
  229. #ifdef ABC_USE_CUDD
  230. extern int Abc_CountZddCubes( DdManager * dd, DdNode * zCover );
  231. Abc_Obj_t * pNode;
  232. DdNode * bCover, * zCover, * bFunc;
  233. DdManager * dd = (DdManager *)pNtk->pManFunc;
  234. int i;
  235. assert( Abc_NtkIsBddLogic(pNtk) );
  236. Abc_NtkForEachNode( pNtk, pNode, i )
  237. {
  238. assert( pNode->pData );
  239. bFunc = (DdNode *)pNode->pData;
  240. bCover = Cudd_zddIsop( dd, bFunc, bFunc, &zCover );
  241. Cudd_Ref( bCover );
  242. Cudd_Ref( zCover );
  243. nClauses += Abc_CountZddCubes( dd, zCover );
  244. Cudd_RecursiveDeref( dd, bCover );
  245. Cudd_RecursiveDerefZdd( dd, zCover );
  246. bCover = Cudd_zddIsop( dd, Cudd_Not(bFunc), Cudd_Not(bFunc), &zCover );
  247. Cudd_Ref( bCover );
  248. Cudd_Ref( zCover );
  249. nClauses += Abc_CountZddCubes( dd, zCover );
  250. Cudd_RecursiveDeref( dd, bCover );
  251. Cudd_RecursiveDerefZdd( dd, zCover );
  252. }
  253. #endif
  254. return nClauses;
  255. }
  256. /**Function*************************************************************
  257. Synopsis [Computes the area of the mapped circuit.]
  258. Description []
  259. SideEffects []
  260. SeeAlso []
  261. ***********************************************************************/
  262. double Abc_NtkGetMappedArea( Abc_Ntk_t * pNtk )
  263. {
  264. Abc_Obj_t * pObj;
  265. double TotalArea;
  266. int i;
  267. assert( Abc_NtkHasMapping(pNtk) );
  268. TotalArea = 0.0;
  269. Abc_NtkForEachNode( pNtk, pObj, i )
  270. {
  271. if ( Abc_ObjIsBarBuf(pObj) )
  272. continue;
  273. // assert( pObj->pData );
  274. if ( pObj->pData == NULL )
  275. {
  276. printf( "Node without mapping is encountered.\n" );
  277. continue;
  278. }
  279. TotalArea += Mio_GateReadArea( (Mio_Gate_t *)pObj->pData );
  280. // assuming that twin gates follow each other
  281. if ( Abc_NtkFetchTwinNode(pObj) )
  282. i++;
  283. }
  284. return TotalArea;
  285. }
  286. /**Function*************************************************************
  287. Synopsis [Counts the number of exors.]
  288. Description []
  289. SideEffects []
  290. SeeAlso []
  291. ***********************************************************************/
  292. int Abc_NtkGetExorNum( Abc_Ntk_t * pNtk )
  293. {
  294. Abc_Obj_t * pNode;
  295. int i, Counter = 0;
  296. Abc_NtkForEachNode( pNtk, pNode, i )
  297. Counter += pNode->fExor;
  298. return Counter;
  299. }
  300. /**Function*************************************************************
  301. Synopsis [Counts the number of exors.]
  302. Description []
  303. SideEffects []
  304. SeeAlso []
  305. ***********************************************************************/
  306. int Abc_NtkGetMuxNum( Abc_Ntk_t * pNtk )
  307. {
  308. Abc_Obj_t * pNode;
  309. int i, Counter = 0;
  310. Abc_NtkForEachNode( pNtk, pNode, i )
  311. Counter += Abc_NodeIsMuxType(pNode);
  312. return Counter;
  313. }
  314. /**Function*************************************************************
  315. Synopsis [Counts the number of exors.]
  316. Description []
  317. SideEffects []
  318. SeeAlso []
  319. ***********************************************************************/
  320. int Abc_NtkGetBufNum( Abc_Ntk_t * pNtk )
  321. {
  322. Abc_Obj_t * pNode;
  323. int i, Counter = 0;
  324. Abc_NtkForEachNode( pNtk, pNode, i )
  325. Counter += (Abc_ObjFaninNum(pNode) == 1);
  326. return Counter;
  327. }
  328. /**Function*************************************************************
  329. Synopsis [Counts the number of exors.]
  330. Description []
  331. SideEffects []
  332. SeeAlso []
  333. ***********************************************************************/
  334. int Abc_NtkGetLargeNodeNum( Abc_Ntk_t * pNtk )
  335. {
  336. Abc_Obj_t * pNode;
  337. int i, Counter = 0;
  338. Abc_NtkForEachNode( pNtk, pNode, i )
  339. Counter += (Abc_ObjFaninNum(pNode) > 1);
  340. return Counter;
  341. }
  342. /**Function*************************************************************
  343. Synopsis [Returns 1 if it is an AIG with choice nodes.]
  344. Description []
  345. SideEffects []
  346. SeeAlso []
  347. ***********************************************************************/
  348. int Abc_NtkGetChoiceNum( Abc_Ntk_t * pNtk )
  349. {
  350. Abc_Obj_t * pNode;
  351. int i, Counter;
  352. if ( !Abc_NtkIsStrash(pNtk) )
  353. return 0;
  354. Counter = 0;
  355. Abc_NtkForEachNode( pNtk, pNode, i )
  356. Counter += Abc_AigNodeIsChoice( pNode );
  357. return Counter;
  358. }
  359. /**Function*************************************************************
  360. Synopsis [Reads the maximum number of fanins.]
  361. Description []
  362. SideEffects []
  363. SeeAlso []
  364. ***********************************************************************/
  365. int Abc_NtkGetFaninMax( Abc_Ntk_t * pNtk )
  366. {
  367. Abc_Obj_t * pNode;
  368. int i, nFaninsMax = 0;
  369. Abc_NtkForEachNode( pNtk, pNode, i )
  370. {
  371. if ( nFaninsMax < Abc_ObjFaninNum(pNode) )
  372. nFaninsMax = Abc_ObjFaninNum(pNode);
  373. }
  374. return nFaninsMax;
  375. }
  376. int Abc_NtkGetFanoutMax( Abc_Ntk_t * pNtk )
  377. {
  378. Abc_Obj_t * pNode;
  379. int i, nFaninsMax = 0;
  380. Abc_NtkForEachNode( pNtk, pNode, i )
  381. {
  382. if ( nFaninsMax < Abc_ObjFanoutNum(pNode) )
  383. nFaninsMax = Abc_ObjFanoutNum(pNode);
  384. }
  385. return nFaninsMax;
  386. }
  387. /**Function*************************************************************
  388. Synopsis [Reads the total number of all fanins.]
  389. Description []
  390. SideEffects []
  391. SeeAlso []
  392. ***********************************************************************/
  393. int Abc_NtkGetTotalFanins( Abc_Ntk_t * pNtk )
  394. {
  395. Abc_Obj_t * pNode;
  396. int i, nFanins = 0;
  397. Abc_NtkForEachNode( pNtk, pNode, i )
  398. nFanins += Abc_ObjFaninNum(pNode);
  399. return nFanins;
  400. }
  401. /**Function*************************************************************
  402. Synopsis [Cleans the copy field of all objects.]
  403. Description []
  404. SideEffects []
  405. SeeAlso []
  406. ***********************************************************************/
  407. void Abc_NtkCleanCopy( Abc_Ntk_t * pNtk )
  408. {
  409. Abc_Obj_t * pObj;
  410. int i;
  411. Abc_NtkForEachObj( pNtk, pObj, i )
  412. pObj->pCopy = NULL;
  413. }
  414. void Abc_NtkCleanCopy_rec( Abc_Ntk_t * pNtk )
  415. {
  416. Abc_Obj_t * pObj;
  417. int i;
  418. Abc_NtkCleanCopy( pNtk );
  419. Abc_NtkForEachBox( pNtk, pObj, i )
  420. Abc_NtkCleanCopy_rec( Abc_ObjModel(pObj) );
  421. }
  422. /**Function*************************************************************
  423. Synopsis [Cleans the copy field of all objects.]
  424. Description []
  425. SideEffects []
  426. SeeAlso []
  427. ***********************************************************************/
  428. void Abc_NtkCleanData( Abc_Ntk_t * pNtk )
  429. {
  430. Abc_Obj_t * pObj;
  431. int i;
  432. Abc_NtkForEachObj( pNtk, pObj, i )
  433. pObj->pData = NULL;
  434. }
  435. /**Function*************************************************************
  436. Synopsis [Cleans the copy field of all objects.]
  437. Description []
  438. SideEffects []
  439. SeeAlso []
  440. ***********************************************************************/
  441. void Abc_NtkFillTemp( Abc_Ntk_t * pNtk )
  442. {
  443. Abc_Obj_t * pObj;
  444. int i;
  445. Abc_NtkForEachObj( pNtk, pObj, i )
  446. pObj->iTemp = -1;
  447. }
  448. /**Function*************************************************************
  449. Synopsis [Counts the number of nodes having non-trivial copies.]
  450. Description []
  451. SideEffects []
  452. SeeAlso []
  453. ***********************************************************************/
  454. int Abc_NtkCountCopy( Abc_Ntk_t * pNtk )
  455. {
  456. Abc_Obj_t * pObj;
  457. int i, Counter = 0;
  458. Abc_NtkForEachObj( pNtk, pObj, i )
  459. {
  460. if ( Abc_ObjIsNode(pObj) )
  461. Counter += (pObj->pCopy != NULL);
  462. }
  463. return Counter;
  464. }
  465. /**Function*************************************************************
  466. Synopsis [Saves copy field of the objects.]
  467. Description []
  468. SideEffects []
  469. SeeAlso []
  470. ***********************************************************************/
  471. Vec_Ptr_t * Abc_NtkSaveCopy( Abc_Ntk_t * pNtk )
  472. {
  473. Vec_Ptr_t * vCopies;
  474. Abc_Obj_t * pObj;
  475. int i;
  476. vCopies = Vec_PtrStart( Abc_NtkObjNumMax(pNtk) );
  477. Abc_NtkForEachObj( pNtk, pObj, i )
  478. Vec_PtrWriteEntry( vCopies, i, pObj->pCopy );
  479. return vCopies;
  480. }
  481. /**Function*************************************************************
  482. Synopsis [Loads copy field of the objects.]
  483. Description []
  484. SideEffects []
  485. SeeAlso []
  486. ***********************************************************************/
  487. void Abc_NtkLoadCopy( Abc_Ntk_t * pNtk, Vec_Ptr_t * vCopies )
  488. {
  489. Abc_Obj_t * pObj;
  490. int i;
  491. Abc_NtkForEachObj( pNtk, pObj, i )
  492. pObj->pCopy = (Abc_Obj_t *)Vec_PtrEntry( vCopies, i );
  493. }
  494. /**Function*************************************************************
  495. Synopsis [Cleans the copy field of all objects.]
  496. Description []
  497. SideEffects []
  498. SeeAlso []
  499. ***********************************************************************/
  500. void Abc_NtkCleanNext( Abc_Ntk_t * pNtk )
  501. {
  502. Abc_Obj_t * pObj;
  503. int i;
  504. Abc_NtkForEachObj( pNtk, pObj, i )
  505. pObj->pNext = NULL;
  506. }
  507. void Abc_NtkCleanNext_rec( Abc_Ntk_t * pNtk )
  508. {
  509. Abc_Obj_t * pObj;
  510. int i;
  511. Abc_NtkCleanNext( pNtk );
  512. Abc_NtkForEachBox( pNtk, pObj, i )
  513. Abc_NtkCleanNext_rec( Abc_ObjModel(pObj) );
  514. }
  515. /**Function*************************************************************
  516. Synopsis [Cleans the copy field of all objects.]
  517. Description []
  518. SideEffects []
  519. SeeAlso []
  520. ***********************************************************************/
  521. void Abc_NtkCleanMarkA( Abc_Ntk_t * pNtk )
  522. {
  523. Abc_Obj_t * pObj;
  524. int i;
  525. Abc_NtkForEachObj( pNtk, pObj, i )
  526. pObj->fMarkA = 0;
  527. }
  528. /**Function*************************************************************
  529. Synopsis [Cleans the copy field of all objects.]
  530. Description []
  531. SideEffects []
  532. SeeAlso []
  533. ***********************************************************************/
  534. void Abc_NtkCleanMarkB( Abc_Ntk_t * pNtk )
  535. {
  536. Abc_Obj_t * pObj;
  537. int i;
  538. Abc_NtkForEachObj( pNtk, pObj, i )
  539. pObj->fMarkB = 0;
  540. }
  541. /**Function*************************************************************
  542. Synopsis [Cleans the copy field of all objects.]
  543. Description []
  544. SideEffects []
  545. SeeAlso []
  546. ***********************************************************************/
  547. void Abc_NtkCleanMarkC( Abc_Ntk_t * pNtk )
  548. {
  549. Abc_Obj_t * pObj;
  550. int i;
  551. Abc_NtkForEachObj( pNtk, pObj, i )
  552. pObj->fMarkC = 0;
  553. }
  554. /**Function*************************************************************
  555. Synopsis [Cleans the copy field of all objects.]
  556. Description []
  557. SideEffects []
  558. SeeAlso []
  559. ***********************************************************************/
  560. void Abc_NtkCleanMarkAB( Abc_Ntk_t * pNtk )
  561. {
  562. Abc_Obj_t * pObj;
  563. int i;
  564. Abc_NtkForEachObj( pNtk, pObj, i )
  565. pObj->fMarkA = pObj->fMarkB = 0;
  566. }
  567. /**Function*************************************************************
  568. Synopsis [Cleans the copy field of all objects.]
  569. Description []
  570. SideEffects []
  571. SeeAlso []
  572. ***********************************************************************/
  573. void Abc_NtkCleanMarkABC( Abc_Ntk_t * pNtk )
  574. {
  575. Abc_Obj_t * pObj;
  576. int i;
  577. Abc_NtkForEachObj( pNtk, pObj, i )
  578. pObj->fMarkA = pObj->fMarkB = pObj->fMarkC = 0;
  579. }
  580. /**Function*************************************************************
  581. Synopsis [Returns the index of the given fanin.]
  582. Description []
  583. SideEffects []
  584. SeeAlso []
  585. ***********************************************************************/
  586. int Abc_NodeFindFanin( Abc_Obj_t * pNode, Abc_Obj_t * pFanin )
  587. {
  588. Abc_Obj_t * pThis;
  589. int i;
  590. Abc_ObjForEachFanin( pNode, pThis, i )
  591. if ( pThis == pFanin )
  592. return i;
  593. return -1;
  594. }
  595. /**Function*************************************************************
  596. Synopsis [Checks if the internal node has CO fanout.]
  597. Description []
  598. SideEffects []
  599. SeeAlso []
  600. ***********************************************************************/
  601. Abc_Obj_t * Abc_NodeFindCoFanout( Abc_Obj_t * pNode )
  602. {
  603. Abc_Obj_t * pFanout;
  604. int i;
  605. Abc_ObjForEachFanout( pNode, pFanout, i )
  606. if ( Abc_ObjIsCo(pFanout) )
  607. return pFanout;
  608. return NULL;
  609. }
  610. /**Function*************************************************************
  611. Synopsis [Checks if the internal node has CO fanout.]
  612. Description []
  613. SideEffects []
  614. SeeAlso []
  615. ***********************************************************************/
  616. Abc_Obj_t * Abc_NodeFindNonCoFanout( Abc_Obj_t * pNode )
  617. {
  618. Abc_Obj_t * pFanout;
  619. int i;
  620. Abc_ObjForEachFanout( pNode, pFanout, i )
  621. if ( !Abc_ObjIsCo(pFanout) )
  622. return pFanout;
  623. return NULL;
  624. }
  625. /**Function*************************************************************
  626. Synopsis [Checks if the internal node has CO drivers with the same name.]
  627. Description [Checks if the internal node can borrow its name from CO fanouts.
  628. This is possible if all COs with non-complemented fanin edge pointing to this
  629. node have the same name.]
  630. SideEffects []
  631. SeeAlso []
  632. ***********************************************************************/
  633. Abc_Obj_t * Abc_NodeHasUniqueCoFanout( Abc_Obj_t * pNode )
  634. {
  635. Abc_Obj_t * pFanout, * pFanoutCo;
  636. int i;
  637. pFanoutCo = NULL;
  638. Abc_ObjForEachFanout( pNode, pFanout, i )
  639. {
  640. if ( !Abc_ObjIsCo(pFanout) )
  641. continue;
  642. if ( Abc_ObjFaninC0(pFanout) )
  643. continue;
  644. if ( pFanoutCo == NULL )
  645. {
  646. assert( Abc_ObjFaninNum(pFanout) == 1 );
  647. assert( Abc_ObjFanin0(pFanout) == pNode );
  648. pFanoutCo = pFanout;
  649. continue;
  650. }
  651. if ( strcmp( Abc_ObjName(pFanoutCo), Abc_ObjName(pFanout) ) ) // they have diff names
  652. return NULL;
  653. }
  654. return pFanoutCo;
  655. }
  656. /**Function*************************************************************
  657. Synopsis [Fixes the CO driver problem.]
  658. Description []
  659. SideEffects []
  660. SeeAlso []
  661. ***********************************************************************/
  662. void Abc_NtkFixCoDriverProblem( Abc_Obj_t * pDriver, Abc_Obj_t * pNodeCo, int fDuplicate )
  663. {
  664. Abc_Ntk_t * pNtk = pDriver->pNtk;
  665. Abc_Obj_t * pDriverNew, * pFanin;
  666. int k;
  667. if ( fDuplicate && !Abc_ObjIsCi(pDriver) )
  668. {
  669. pDriverNew = Abc_NtkDupObj( pNtk, pDriver, 0 );
  670. Abc_ObjForEachFanin( pDriver, pFanin, k )
  671. Abc_ObjAddFanin( pDriverNew, pFanin );
  672. if ( Abc_ObjFaninC0(pNodeCo) )
  673. {
  674. // change polarity of the duplicated driver
  675. Abc_NodeComplement( pDriverNew );
  676. Abc_ObjXorFaninC( pNodeCo, 0 );
  677. }
  678. }
  679. else
  680. {
  681. // add inverters and buffers when necessary
  682. if ( Abc_ObjFaninC0(pNodeCo) )
  683. {
  684. pDriverNew = Abc_NtkCreateNodeInv( pNtk, pDriver );
  685. Abc_ObjXorFaninC( pNodeCo, 0 );
  686. }
  687. else
  688. pDriverNew = Abc_NtkCreateNodeBuf( pNtk, pDriver );
  689. }
  690. // update the fanin of the PO node
  691. Abc_ObjPatchFanin( pNodeCo, pDriver, pDriverNew );
  692. assert( Abc_ObjFanoutNum(pDriverNew) == 1 );
  693. // remove the old driver if it dangles
  694. // (this happens when the duplicated driver had only one complemented fanout)
  695. if ( Abc_ObjFanoutNum(pDriver) == 0 )
  696. Abc_NtkDeleteObj( pDriver );
  697. }
  698. /**Function*************************************************************
  699. Synopsis [Returns 1 if COs of a logic network are simple.]
  700. Description [The COs of a logic network are simple under three conditions:
  701. (1) The edge from CO to its driver is not complemented.
  702. (2) If CI is a driver of a CO, they have the same name.]
  703. (3) If two COs share the same driver, they have the same name.]
  704. SideEffects []
  705. SeeAlso []
  706. ***********************************************************************/
  707. int Abc_NtkLogicHasSimpleCos( Abc_Ntk_t * pNtk )
  708. {
  709. Abc_Obj_t * pNode, * pDriver;
  710. int i;
  711. assert( Abc_NtkIsLogic(pNtk) );
  712. Abc_NtkIncrementTravId( pNtk );
  713. Abc_NtkForEachCo( pNtk, pNode, i )
  714. {
  715. // if the driver is complemented, this is an error
  716. pDriver = Abc_ObjFanin0(pNode);
  717. if ( Abc_ObjFaninC0(pNode) )
  718. return 0;
  719. // if the driver is a CI and has different name, this is an error
  720. if ( Abc_ObjIsCi(pDriver) && strcmp(Abc_ObjName(pDriver), Abc_ObjName(pNode)) )
  721. return 0;
  722. // if the driver is visited for the first time, remember the CO name
  723. if ( !Abc_NodeIsTravIdCurrent(pDriver) )
  724. {
  725. pDriver->pNext = (Abc_Obj_t *)Abc_ObjName(pNode);
  726. Abc_NodeSetTravIdCurrent(pDriver);
  727. continue;
  728. }
  729. // the driver has second CO - if they have different name, this is an error
  730. if ( strcmp((char *)pDriver->pNext, Abc_ObjName(pNode)) ) // diff names
  731. return 0;
  732. }
  733. return 1;
  734. }
  735. /**Function*************************************************************
  736. Synopsis [Transforms the network to have simple COs.]
  737. Description [The COs of a logic network are simple under three conditions:
  738. (1) The edge from CO to its driver is not complemented.
  739. (2) If CI is a driver of a CO, they have the same name.]
  740. (3) If two COs share the same driver, they have the same name.
  741. In some cases, such as FPGA mapping, we prevent the increase in delay
  742. by duplicating the driver nodes, rather than adding invs/bufs.]
  743. SideEffects []
  744. SeeAlso []
  745. ***********************************************************************/
  746. int Abc_NtkLogicMakeSimpleCos2( Abc_Ntk_t * pNtk, int fDuplicate )
  747. {
  748. Abc_Obj_t * pNode, * pDriver;
  749. int i, nDupGates = 0;
  750. assert( Abc_NtkIsLogic(pNtk) );
  751. Abc_NtkIncrementTravId( pNtk );
  752. Abc_NtkForEachCo( pNtk, pNode, i )
  753. {
  754. // if the driver is complemented, this is an error
  755. pDriver = Abc_ObjFanin0(pNode);
  756. if ( Abc_ObjFaninC0(pNode) )
  757. {
  758. Abc_NtkFixCoDriverProblem( pDriver, pNode, fDuplicate );
  759. nDupGates++;
  760. continue;
  761. }
  762. // if the driver is a CI and has different name, this is an error
  763. if ( Abc_ObjIsCi(pDriver) && strcmp(Abc_ObjName(pDriver), Abc_ObjName(pNode)) )
  764. {
  765. Abc_NtkFixCoDriverProblem( pDriver, pNode, fDuplicate );
  766. nDupGates++;
  767. continue;
  768. }
  769. // if the driver is visited for the first time, remember the CO name
  770. if ( !Abc_NodeIsTravIdCurrent(pDriver) )
  771. {
  772. pDriver->pNext = (Abc_Obj_t *)Abc_ObjName(pNode);
  773. Abc_NodeSetTravIdCurrent(pDriver);
  774. continue;
  775. }
  776. // the driver has second CO - if they have different name, this is an error
  777. if ( strcmp((char *)pDriver->pNext, Abc_ObjName(pNode)) ) // diff names
  778. {
  779. Abc_NtkFixCoDriverProblem( pDriver, pNode, fDuplicate );
  780. nDupGates++;
  781. continue;
  782. }
  783. }
  784. assert( Abc_NtkLogicHasSimpleCos(pNtk) );
  785. return nDupGates;
  786. }
  787. /**Function*************************************************************
  788. Synopsis [Transforms the network to have simple COs.]
  789. Description []
  790. SideEffects []
  791. SeeAlso []
  792. ***********************************************************************/
  793. void Abc_NtkLogicMakeSimpleCosTest( Abc_Ntk_t * pNtk, int fDuplicate )
  794. {
  795. int nObjs = Abc_NtkObjNumMax(pNtk);
  796. unsigned * pType = ABC_CALLOC( unsigned, nObjs );
  797. Abc_Obj_t * pNode;
  798. int i, Counts[4] = {0}, Consts[2] = {0}, Inputs[2] = {0};
  799. // collect info
  800. Abc_NtkForEachCo( pNtk, pNode, i )
  801. {
  802. if ( Abc_ObjFaninId0(pNode) == 0 )
  803. Consts[Abc_ObjFaninC0(pNode)]++;
  804. if ( Abc_ObjIsCi(Abc_ObjFanin0(pNode)) )
  805. Inputs[Abc_ObjFaninC0(pNode)]++;
  806. pType[Abc_ObjFaninId0(pNode)] |= (1 << Abc_ObjFaninC0(pNode));
  807. }
  808. // count the numbers
  809. for ( i = 0; i < nObjs; i++ )
  810. Counts[pType[i]]++;
  811. for ( i = 0; i < 4; i++ )
  812. printf( "%d = %d ", i, Counts[i] );
  813. for ( i = 0; i < 2; i++ )
  814. printf( "c%d = %d ", i, Consts[i] );
  815. for ( i = 0; i < 2; i++ )
  816. printf( "i%d = %d ", i, Inputs[i] );
  817. printf( "\n" );
  818. ABC_FREE( pType );
  819. }
  820. /**Function*************************************************************
  821. Synopsis [Transforms the network to have simple COs.]
  822. Description []
  823. SideEffects []
  824. SeeAlso []
  825. ***********************************************************************/
  826. int Abc_NtkLogicMakeSimpleCos( Abc_Ntk_t * pNtk, int fDuplicate )
  827. {
  828. Vec_Ptr_t * vDrivers, * vCoTerms;
  829. Abc_Obj_t * pNode, * pDriver, * pDriverNew, * pFanin;
  830. int i, k, LevelMax, nTotal = 0;
  831. assert( Abc_NtkIsLogic(pNtk) );
  832. LevelMax = Abc_NtkLevel(pNtk);
  833. // Abc_NtkLogicMakeSimpleCosTest( pNtk, fDuplicate );
  834. // fix constant drivers
  835. Abc_NtkForEachCo( pNtk, pNode, i )
  836. {
  837. pDriver = Abc_ObjFanin0(pNode);
  838. if ( !Abc_NodeIsConst(pDriver) )
  839. continue;
  840. pDriverNew = (Abc_ObjFaninC0(pNode) == Abc_NodeIsConst0(pDriver)) ? Abc_NtkCreateNodeConst1(pNtk) : Abc_NtkCreateNodeConst0(pNtk);
  841. if ( Abc_ObjFaninC0(pNode) )
  842. Abc_ObjXorFaninC( pNode, 0 );
  843. Abc_ObjPatchFanin( pNode, pDriver, pDriverNew );
  844. if ( Abc_ObjFanoutNum(pDriver) == 0 )
  845. Abc_NtkDeleteObj( pDriver );
  846. }
  847. // collect drivers pointed by complemented edges
  848. vDrivers = Vec_PtrAlloc( 100 );
  849. Abc_NtkIncrementTravId( pNtk );
  850. Abc_NtkForEachCo( pNtk, pNode, i )
  851. {
  852. if ( !Abc_ObjFaninC0(pNode) )
  853. continue;
  854. pDriver = Abc_ObjFanin0(pNode);
  855. if ( Abc_NodeIsTravIdCurrent(pDriver) )
  856. continue;
  857. Abc_NodeSetTravIdCurrent(pDriver);
  858. Vec_PtrPush( vDrivers, pDriver );
  859. }
  860. // fix complemented drivers
  861. if ( Vec_PtrSize(vDrivers) > 0 )
  862. {
  863. int nDupGates = 0, nDupInvs = 0, nDupChange = 0;
  864. Vec_Ptr_t * vFanouts = Vec_PtrAlloc( 100 );
  865. Vec_PtrForEachEntry( Abc_Obj_t *, vDrivers, pDriver, i )
  866. {
  867. int fHasDir = 0, fHasInv = 0, fHasOther = 0;
  868. Abc_ObjForEachFanout( pDriver, pNode, k )
  869. {
  870. if ( !Abc_ObjIsCo(pNode) )
  871. {
  872. assert( !Abc_ObjFaninC0(pNode) );
  873. fHasOther = 1;
  874. continue;
  875. }
  876. if ( Abc_ObjFaninC0(pNode) )
  877. fHasInv = 1;
  878. else //if ( Abc_ObjFaninC0(pNode) )
  879. fHasDir = 1;
  880. }
  881. assert( fHasInv );
  882. if ( Abc_ObjIsCi(pDriver) || fHasDir || (fHasOther && Abc_NtkHasMapping(pNtk)) ) // cannot change
  883. {
  884. // duplicate if critical
  885. if ( fDuplicate && Abc_ObjIsNode(pDriver) && Abc_ObjLevel(pDriver) == LevelMax )
  886. {
  887. pDriverNew = Abc_NtkDupObj( pNtk, pDriver, 0 );
  888. Abc_ObjForEachFanin( pDriver, pFanin, k )
  889. Abc_ObjAddFanin( pDriverNew, pFanin );
  890. Abc_NodeComplement( pDriverNew );
  891. nDupGates++;
  892. }
  893. else // add inverter
  894. {
  895. pDriverNew = Abc_NtkCreateNodeInv( pNtk, pDriver );
  896. nDupInvs++;
  897. }
  898. // collect CO fanouts to be redirected to the new node
  899. Vec_PtrClear( vFanouts );
  900. Abc_ObjForEachFanout( pDriver, pNode, k )
  901. if ( Abc_ObjIsCo(pNode) && Abc_ObjFaninC0(pNode) )
  902. Vec_PtrPush( vFanouts, pNode );
  903. assert( Vec_PtrSize(vFanouts) > 0 );
  904. Vec_PtrForEachEntry( Abc_Obj_t *, vFanouts, pNode, k )
  905. {
  906. Abc_ObjXorFaninC( pNode, 0 );
  907. Abc_ObjPatchFanin( pNode, pDriver, pDriverNew );
  908. assert( Abc_ObjIsCi(pDriver) || Abc_ObjFanoutNum(pDriver) > 0 );
  909. }
  910. }
  911. else // can change
  912. {
  913. // change polarity of the driver
  914. assert( Abc_ObjIsNode(pDriver) );
  915. Abc_NodeComplement( pDriver );
  916. Abc_ObjForEachFanout( pDriver, pNode, k )
  917. {
  918. if ( Abc_ObjIsCo(pNode) )
  919. {
  920. assert( Abc_ObjFaninC0(pNode) );
  921. Abc_ObjXorFaninC( pNode, 0 );
  922. }
  923. else if ( Abc_ObjIsNode(pNode) )
  924. Abc_NodeComplementInput( pNode, pDriver );
  925. else assert( 0 );
  926. }
  927. nDupChange++;
  928. }
  929. }
  930. Vec_PtrFree( vFanouts );
  931. // printf( "Resolving inverted CO drivers: Invs = %d. Dups = %d. Changes = %d.\n",
  932. // nDupInvs, nDupGates, nDupChange );
  933. nTotal += nDupInvs + nDupGates;
  934. }
  935. Vec_PtrFree( vDrivers );
  936. // collect COs that needs fixing by adding buffers or duplicating
  937. vCoTerms = Vec_PtrAlloc( 100 );
  938. Abc_NtkIncrementTravId( pNtk );
  939. Abc_NtkForEachCo( pNtk, pNode, i )
  940. {
  941. // if the driver is a CI and has different name, this is an error
  942. pDriver = Abc_ObjFanin0(pNode);
  943. if ( Abc_ObjIsCi(pDriver) && strcmp(Abc_ObjName(pDriver), Abc_ObjName(pNode)) )
  944. {
  945. Vec_PtrPush( vCoTerms, pNode );
  946. continue;
  947. }
  948. // if the driver is visited for the first time, remember the CO name
  949. if ( !Abc_NodeIsTravIdCurrent(pDriver) )
  950. {
  951. pDriver->pNext = (Abc_Obj_t *)Abc_ObjName(pNode);
  952. Abc_NodeSetTravIdCurrent(pDriver);
  953. continue;
  954. }
  955. // the driver has second CO - if they have different name, this is an error
  956. if ( strcmp((char *)pDriver->pNext, Abc_ObjName(pNode)) ) // diff names
  957. {
  958. Vec_PtrPush( vCoTerms, pNode );
  959. continue;
  960. }
  961. }
  962. // fix duplication problem
  963. if ( Vec_PtrSize(vCoTerms) > 0 )
  964. {
  965. int nDupBufs = 0, nDupGates = 0;
  966. Vec_PtrForEachEntry( Abc_Obj_t *, vCoTerms, pNode, i )
  967. {
  968. pDriver = Abc_ObjFanin0(pNode);
  969. // duplicate if critical
  970. if ( fDuplicate && Abc_ObjIsNode(pDriver) && (Abc_NtkHasMapping(pNtk) || Abc_ObjLevel(pDriver) == LevelMax) )
  971. {
  972. pDriverNew = Abc_NtkDupObj( pNtk, pDriver, 0 );
  973. Abc_ObjForEachFanin( pDriver, pFanin, k )
  974. Abc_ObjAddFanin( pDriverNew, pFanin );
  975. nDupGates++;
  976. }
  977. else // add buffer
  978. {
  979. pDriverNew = Abc_NtkCreateNodeBuf( pNtk, pDriver );
  980. Abc_ObjAssignName( pDriverNew, Abc_ObjName(pDriver), "_buf" );
  981. nDupBufs++;
  982. }
  983. // swing the PO
  984. Abc_ObjPatchFanin( pNode, pDriver, pDriverNew );
  985. assert( Abc_ObjIsCi(pDriver) || Abc_ObjFanoutNum(pDriver) > 0 );
  986. }
  987. // printf( "Resolving shared CO drivers: Bufs = %d. Dups = %d.\n", nDupBufs, nDupGates );
  988. nTotal += nDupBufs + nDupGates;
  989. }
  990. Vec_PtrFree( vCoTerms );
  991. return nTotal;
  992. }
  993. /**Function*************************************************************
  994. Synopsis [Inserts a new node in the order by levels.]
  995. Description []
  996. SideEffects []
  997. SeeAlso []
  998. ***********************************************************************/
  999. void Abc_VecObjPushUniqueOrderByLevel( Vec_Ptr_t * p, Abc_Obj_t * pNode )
  1000. {
  1001. Abc_Obj_t * pNode1, * pNode2;
  1002. int i;
  1003. if ( Vec_PtrPushUnique(p, pNode) )
  1004. return;
  1005. // find the p of the node
  1006. for ( i = p->nSize-1; i > 0; i-- )
  1007. {
  1008. pNode1 = (Abc_Obj_t *)p->pArray[i ];
  1009. pNode2 = (Abc_Obj_t *)p->pArray[i-1];
  1010. if ( Abc_ObjRegular(pNode1)->Level <= Abc_ObjRegular(pNode2)->Level )
  1011. break;
  1012. p->pArray[i ] = pNode2;
  1013. p->pArray[i-1] = pNode1;
  1014. }
  1015. }
  1016. /**Function*************************************************************
  1017. Synopsis [Returns 1 if the node is the root of EXOR/NEXOR.]
  1018. Description []
  1019. SideEffects []
  1020. SeeAlso []
  1021. ***********************************************************************/
  1022. int Abc_NodeIsExorType( Abc_Obj_t * pNode )
  1023. {
  1024. Abc_Obj_t * pNode0, * pNode1;
  1025. // check that the node is regular
  1026. assert( !Abc_ObjIsComplement(pNode) );
  1027. // if the node is not AND, this is not EXOR
  1028. if ( !Abc_AigNodeIsAnd(pNode) )
  1029. return 0;
  1030. // if the children are not complemented, this is not EXOR
  1031. if ( !Abc_ObjFaninC0(pNode) || !Abc_ObjFaninC1(pNode) )
  1032. return 0;
  1033. // get children
  1034. pNode0 = Abc_ObjFanin0(pNode);
  1035. pNode1 = Abc_ObjFanin1(pNode);
  1036. // if the children are not ANDs, this is not EXOR
  1037. if ( Abc_ObjFaninNum(pNode0) != 2 || Abc_ObjFaninNum(pNode1) != 2 )
  1038. return 0;
  1039. // this is AIG, which means the fanins should be ordered
  1040. assert( Abc_ObjFaninId0(pNode0) != Abc_ObjFaninId1(pNode1) ||
  1041. Abc_ObjFaninId0(pNode1) != Abc_ObjFaninId1(pNode0) );
  1042. // if grand children are not the same, this is not EXOR
  1043. if ( Abc_ObjFaninId0(pNode0) != Abc_ObjFaninId0(pNode1) ||
  1044. Abc_ObjFaninId1(pNode0) != Abc_ObjFaninId1(pNode1) )
  1045. return 0;
  1046. // finally, if the complemented edges are matched, this is not EXOR
  1047. if ( Abc_ObjFaninC0(pNode0) == Abc_ObjFaninC0(pNode1) ||
  1048. Abc_ObjFaninC1(pNode0) == Abc_ObjFaninC1(pNode1) )
  1049. return 0;
  1050. return 1;
  1051. }
  1052. /**Function*************************************************************
  1053. Synopsis [Returns 1 if the node is the root of MUX or EXOR/NEXOR.]
  1054. Description []
  1055. SideEffects []
  1056. SeeAlso []
  1057. ***********************************************************************/
  1058. int Abc_NodeIsMuxType( Abc_Obj_t * pNode )
  1059. {
  1060. Abc_Obj_t * pNode0, * pNode1;
  1061. // check that the node is regular
  1062. assert( !Abc_ObjIsComplement(pNode) );
  1063. // if the node is not AND, this is not MUX
  1064. if ( !Abc_AigNodeIsAnd(pNode) )
  1065. return 0;
  1066. // if the children are not complemented, this is not MUX
  1067. if ( !Abc_ObjFaninC0(pNode) || !Abc_ObjFaninC1(pNode) )
  1068. return 0;
  1069. // get children
  1070. pNode0 = Abc_ObjFanin0(pNode);
  1071. pNode1 = Abc_ObjFanin1(pNode);
  1072. // if the children are not ANDs, this is not MUX
  1073. if ( !Abc_AigNodeIsAnd(pNode0) || !Abc_AigNodeIsAnd(pNode1) )
  1074. return 0;
  1075. // otherwise the node is MUX iff it has a pair of equal grandchildren with opposite polarity
  1076. return (Abc_ObjFaninId0(pNode0) == Abc_ObjFaninId0(pNode1) && (Abc_ObjFaninC0(pNode0) ^ Abc_ObjFaninC0(pNode1))) ||
  1077. (Abc_ObjFaninId0(pNode0) == Abc_ObjFaninId1(pNode1) && (Abc_ObjFaninC0(pNode0) ^ Abc_ObjFaninC1(pNode1))) ||
  1078. (Abc_ObjFaninId1(pNode0) == Abc_ObjFaninId0(pNode1) && (Abc_ObjFaninC1(pNode0) ^ Abc_ObjFaninC0(pNode1))) ||
  1079. (Abc_ObjFaninId1(pNode0) == Abc_ObjFaninId1(pNode1) && (Abc_ObjFaninC1(pNode0) ^ Abc_ObjFaninC1(pNode1)));
  1080. }
  1081. /**Function*************************************************************
  1082. Synopsis [Returns 1 if the node is the root of MUX or EXOR/NEXOR.]
  1083. Description []
  1084. SideEffects []
  1085. SeeAlso []
  1086. ***********************************************************************/
  1087. int Abc_NtkCountMuxes( Abc_Ntk_t * pNtk )
  1088. {
  1089. Abc_Obj_t * pNode;
  1090. int i;
  1091. int Counter = 0;
  1092. Abc_NtkForEachNode( pNtk, pNode, i )
  1093. Counter += Abc_NodeIsMuxType( pNode );
  1094. return Counter;
  1095. }
  1096. /**Function*************************************************************
  1097. Synopsis [Returns 1 if the node is the control type of the MUX.]
  1098. Description []
  1099. SideEffects []
  1100. SeeAlso []
  1101. ***********************************************************************/
  1102. int Abc_NodeIsMuxControlType( Abc_Obj_t * pNode )
  1103. {
  1104. Abc_Obj_t * pNode0, * pNode1;
  1105. // check that the node is regular
  1106. assert( !Abc_ObjIsComplement(pNode) );
  1107. // skip the node that do not have two fanouts
  1108. if ( Abc_ObjFanoutNum(pNode) != 2 )
  1109. return 0;
  1110. // get the fanouts
  1111. pNode0 = Abc_ObjFanout( pNode, 0 );
  1112. pNode1 = Abc_ObjFanout( pNode, 1 );
  1113. // if they have more than one fanout, we are not interested
  1114. if ( Abc_ObjFanoutNum(pNode0) != 1 || Abc_ObjFanoutNum(pNode1) != 1 )
  1115. return 0;
  1116. // if the fanouts have the same fanout, this is MUX or EXOR (or a redundant gate (CA)(CB))
  1117. return Abc_ObjFanout0(pNode0) == Abc_ObjFanout0(pNode1);
  1118. }
  1119. /**Function*************************************************************
  1120. Synopsis [Recognizes what nodes are control and data inputs of a MUX.]
  1121. Description [If the node is a MUX, returns the control variable C.
  1122. Assigns nodes T and E to be the then and else variables of the MUX.
  1123. Node C is never complemented. Nodes T and E can be complemented.
  1124. This function also recognizes EXOR/NEXOR gates as MUXes.]
  1125. SideEffects []
  1126. SeeAlso []
  1127. ***********************************************************************/
  1128. Abc_Obj_t * Abc_NodeRecognizeMux( Abc_Obj_t * pNode, Abc_Obj_t ** ppNodeT, Abc_Obj_t ** ppNodeE )
  1129. {
  1130. Abc_Obj_t * pNode0, * pNode1;
  1131. assert( !Abc_ObjIsComplement(pNode) );
  1132. assert( Abc_NodeIsMuxType(pNode) );
  1133. // get children
  1134. pNode0 = Abc_ObjFanin0(pNode);
  1135. pNode1 = Abc_ObjFanin1(pNode);
  1136. // find the control variable
  1137. // if ( pNode1->p1 == Fraig_Not(pNode2->p1) )
  1138. if ( Abc_ObjFaninId0(pNode0) == Abc_ObjFaninId0(pNode1) && (Abc_ObjFaninC0(pNode0) ^ Abc_ObjFaninC0(pNode1)) )
  1139. {
  1140. // if ( Fraig_IsComplement(pNode1->p1) )
  1141. if ( Abc_ObjFaninC0(pNode0) )
  1142. { // pNode2->p1 is positive phase of C
  1143. *ppNodeT = Abc_ObjNot(Abc_ObjChild1(pNode1));//pNode2->p2);
  1144. *ppNodeE = Abc_ObjNot(Abc_ObjChild1(pNode0));//pNode1->p2);
  1145. return Abc_ObjChild0(pNode1);//pNode2->p1;
  1146. }
  1147. else
  1148. { // pNode1->p1 is positive phase of C
  1149. *ppNodeT = Abc_ObjNot(Abc_ObjChild1(pNode0));//pNode1->p2);
  1150. *ppNodeE = Abc_ObjNot(Abc_ObjChild1(pNode1));//pNode2->p2);
  1151. return Abc_ObjChild0(pNode0);//pNode1->p1;
  1152. }
  1153. }
  1154. // else if ( pNode1->p1 == Fraig_Not(pNode2->p2) )
  1155. else if ( Abc_ObjFaninId0(pNode0) == Abc_ObjFaninId1(pNode1) && (Abc_ObjFaninC0(pNode0) ^ Abc_ObjFaninC1(pNode1)) )
  1156. {
  1157. // if ( Fraig_IsComplement(pNode1->p1) )
  1158. if ( Abc_ObjFaninC0(pNode0) )
  1159. { // pNode2->p2 is positive phase of C
  1160. *ppNodeT = Abc_ObjNot(Abc_ObjChild0(pNode1));//pNode2->p1);
  1161. *ppNodeE = Abc_ObjNot(Abc_ObjChild1(pNode0));//pNode1->p2);
  1162. return Abc_ObjChild1(pNode1);//pNode2->p2;
  1163. }
  1164. else
  1165. { // pNode1->p1 is positive phase of C
  1166. *ppNodeT = Abc_ObjNot(Abc_ObjChild1(pNode0));//pNode1->p2);
  1167. *ppNodeE = Abc_ObjNot(Abc_ObjChild0(pNode1));//pNode2->p1);
  1168. return Abc_ObjChild0(pNode0);//pNode1->p1;
  1169. }
  1170. }
  1171. // else if ( pNode1->p2 == Fraig_Not(pNode2->p1) )
  1172. else if ( Abc_ObjFaninId1(pNode0) == Abc_ObjFaninId0(pNode1) && (Abc_ObjFaninC1(pNode0) ^ Abc_ObjFaninC0(pNode1)) )
  1173. {
  1174. // if ( Fraig_IsComplement(pNode1->p2) )
  1175. if ( Abc_ObjFaninC1(pNode0) )
  1176. { // pNode2->p1 is positive phase of C
  1177. *ppNodeT = Abc_ObjNot(Abc_ObjChild1(pNode1));//pNode2->p2);
  1178. *ppNodeE = Abc_ObjNot(Abc_ObjChild0(pNode0));//pNode1->p1);
  1179. return Abc_ObjChild0(pNode1);//pNode2->p1;
  1180. }
  1181. else
  1182. { // pNode1->p2 is positive phase of C
  1183. *ppNodeT = Abc_ObjNot(Abc_ObjChild0(pNode0));//pNode1->p1);
  1184. *ppNodeE = Abc_ObjNot(Abc_ObjChild1(pNode1));//pNode2->p2);
  1185. return Abc_ObjChild1(pNode0);//pNode1->p2;
  1186. }
  1187. }
  1188. // else if ( pNode1->p2 == Fraig_Not(pNode2->p2) )
  1189. else if ( Abc_ObjFaninId1(pNode0) == Abc_ObjFaninId1(pNode1) && (Abc_ObjFaninC1(pNode0) ^ Abc_ObjFaninC1(pNode1)) )
  1190. {
  1191. // if ( Fraig_IsComplement(pNode1->p2) )
  1192. if ( Abc_ObjFaninC1(pNode0) )
  1193. { // pNode2->p2 is positive phase of C
  1194. *ppNodeT = Abc_ObjNot(Abc_ObjChild0(pNode1));//pNode2->p1);
  1195. *ppNodeE = Abc_ObjNot(Abc_ObjChild0(pNode0));//pNode1->p1);
  1196. return Abc_ObjChild1(pNode1);//pNode2->p2;
  1197. }
  1198. else
  1199. { // pNode1->p2 is positive phase of C
  1200. *ppNodeT = Abc_ObjNot(Abc_ObjChild0(pNode0));//pNode1->p1);
  1201. *ppNodeE = Abc_ObjNot(Abc_ObjChild0(pNode1));//pNode2->p1);
  1202. return Abc_ObjChild1(pNode0);//pNode1->p2;
  1203. }
  1204. }
  1205. assert( 0 ); // this is not MUX
  1206. return NULL;
  1207. }
  1208. /**Function*************************************************************
  1209. Synopsis [Prepares two network for a two-argument command similar to "verify".]
  1210. Description []
  1211. SideEffects []
  1212. SeeAlso []
  1213. ***********************************************************************/
  1214. int Abc_NtkPrepareTwoNtks( FILE * pErr, Abc_Ntk_t * pNtk, char ** argv, int argc,
  1215. Abc_Ntk_t ** ppNtk1, Abc_Ntk_t ** ppNtk2, int * pfDelete1, int * pfDelete2 )
  1216. {
  1217. int fCheck = 1;
  1218. FILE * pFile;
  1219. Abc_Ntk_t * pNtk1, * pNtk2, * pNtkTemp;
  1220. int util_optind = 0;
  1221. *pfDelete1 = 0;
  1222. *pfDelete2 = 0;
  1223. if ( argc == util_optind )
  1224. { // use the spec
  1225. if ( pNtk == NULL )
  1226. {
  1227. fprintf( pErr, "Empty current network.\n" );
  1228. return 0;
  1229. }
  1230. if ( pNtk->pSpec == NULL )
  1231. {
  1232. fprintf( pErr, "The external spec is not given.\n" );
  1233. return 0;
  1234. }
  1235. pFile = fopen( pNtk->pSpec, "r" );
  1236. if ( pFile == NULL )
  1237. {
  1238. fprintf( pErr, "Cannot open the external spec file \"%s\".\n", pNtk->pSpec );
  1239. return 0;
  1240. }
  1241. else
  1242. fclose( pFile );
  1243. pNtk1 = Abc_NtkDup(pNtk);
  1244. pNtk2 = Io_Read( pNtk->pSpec, Io_ReadFileType(pNtk->pSpec), fCheck, 0 );
  1245. if ( pNtk2 == NULL )
  1246. return 0;
  1247. *pfDelete1 = 1;
  1248. *pfDelete2 = 1;
  1249. }
  1250. else if ( argc == util_optind + 1 )
  1251. {
  1252. if ( pNtk == NULL )
  1253. {
  1254. fprintf( pErr, "Empty current network.\n" );
  1255. return 0;
  1256. }
  1257. pNtk1 = Abc_NtkDup(pNtk);
  1258. pNtk2 = Io_Read( argv[util_optind], Io_ReadFileType(argv[util_optind]), fCheck, 0 );
  1259. if ( pNtk2 == NULL )
  1260. return 0;
  1261. *pfDelete1 = 1;
  1262. *pfDelete2 = 1;
  1263. }
  1264. else if ( argc == util_optind + 2 )
  1265. {
  1266. pNtk1 = Io_Read( argv[util_optind], Io_ReadFileType(argv[util_optind]), fCheck, 0 );
  1267. if ( pNtk1 == NULL )
  1268. return 0;
  1269. pNtk2 = Io_Read( argv[util_optind+1], Io_ReadFileType(argv[util_optind+1]), fCheck, 0 );
  1270. if ( pNtk2 == NULL )
  1271. {
  1272. Abc_NtkDelete( pNtk1 );
  1273. return 0;
  1274. }
  1275. *pfDelete1 = 1;
  1276. *pfDelete2 = 1;
  1277. }
  1278. else
  1279. {
  1280. fprintf( pErr, "Wrong number of arguments.\n" );
  1281. return 0;
  1282. }
  1283. // make sure the networks are strashed
  1284. if ( !Abc_NtkIsStrash(pNtk1) )
  1285. {
  1286. pNtkTemp = Abc_NtkStrash( pNtk1, 0, 1, 0 );
  1287. if ( *pfDelete1 )
  1288. Abc_NtkDelete( pNtk1 );
  1289. pNtk1 = pNtkTemp;
  1290. *pfDelete1 = 1;
  1291. }
  1292. if ( !Abc_NtkIsStrash(pNtk2) )
  1293. {
  1294. pNtkTemp = Abc_NtkStrash( pNtk2, 0, 1, 0 );
  1295. if ( *pfDelete2 )
  1296. Abc_NtkDelete( pNtk2 );
  1297. pNtk2 = pNtkTemp;
  1298. *pfDelete2 = 1;
  1299. }
  1300. *ppNtk1 = pNtk1;
  1301. *ppNtk2 = pNtk2;
  1302. return 1;
  1303. }
  1304. /**Function*************************************************************
  1305. Synopsis [Returns 1 if it is an AIG with choice nodes.]
  1306. Description []
  1307. SideEffects []
  1308. SeeAlso []
  1309. ***********************************************************************/
  1310. void Abc_NodeCollectFanins( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
  1311. {
  1312. Abc_Obj_t * pFanin;
  1313. int i;
  1314. Vec_PtrClear(vNodes);
  1315. Abc_ObjForEachFanin( pNode, pFanin, i )
  1316. Vec_PtrPush( vNodes, pFanin );
  1317. }
  1318. /**Function*************************************************************
  1319. Synopsis [Returns 1 if it is an AIG with choice nodes.]
  1320. Description []
  1321. SideEffects []
  1322. SeeAlso []
  1323. ***********************************************************************/
  1324. void Abc_NodeCollectFanouts( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
  1325. {
  1326. Abc_Obj_t * pFanout;
  1327. int i;
  1328. Vec_PtrClear(vNodes);
  1329. Abc_ObjForEachFanout( pNode, pFanout, i )
  1330. Vec_PtrPush( vNodes, pFanout );
  1331. }
  1332. /**Function*************************************************************
  1333. Synopsis [Collects all latches in the network.]
  1334. Description []
  1335. SideEffects []
  1336. SeeAlso []
  1337. ***********************************************************************/
  1338. Vec_Ptr_t * Abc_NtkCollectLatches( Abc_Ntk_t * pNtk )
  1339. {
  1340. Vec_Ptr_t * vLatches;
  1341. Abc_Obj_t * pObj;
  1342. int i;
  1343. vLatches = Vec_PtrAlloc( 10 );
  1344. Abc_NtkForEachObj( pNtk, pObj, i )
  1345. Vec_PtrPush( vLatches, pObj );
  1346. return vLatches;
  1347. }
  1348. /**Function*************************************************************
  1349. Synopsis [Procedure used for sorting the nodes in increasing order of levels.]
  1350. Description []
  1351. SideEffects []
  1352. SeeAlso []
  1353. ***********************************************************************/
  1354. int Abc_NodeCompareLevelsIncrease( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 )
  1355. {
  1356. int Diff = Abc_ObjRegular(*pp1)->Level - Abc_ObjRegular(*pp2)->Level;
  1357. if ( Diff < 0 )
  1358. return -1;
  1359. if ( Diff > 0 )
  1360. return 1;
  1361. Diff = Abc_ObjRegular(*pp1)->Id - Abc_ObjRegular(*pp2)->Id;
  1362. if ( Diff < 0 )
  1363. return -1;
  1364. if ( Diff > 0 )
  1365. return 1;
  1366. return 0;
  1367. }
  1368. /**Function*************************************************************
  1369. Syno…

Large files files are truncated, but you can click here to view the full file