PageRenderTime 29ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/src/base/abci/abcExtract.c

https://bitbucket.org/alanmi/abc/
C | 752 lines | 548 code | 62 blank | 142 comment | 89 complexity | 5e2f0c7cdfd3d60ddf6910b8bd82d68f MD5 | raw file
Possible License(s): BSD-3-Clause
  1. /**CFile****************************************************************
  2. FileName [abcShare.c]
  3. SystemName [ABC: Logic synthesis and verification system.]
  4. PackageName [Network and node package.]
  5. Synopsis [Shared logic extraction.]
  6. Author [Alan Mishchenko]
  7. Affiliation [UC Berkeley]
  8. Date [Ver. 1.0. Started - June 20, 2005.]
  9. Revision [$Id: abcShare.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
  10. ***********************************************************************/
  11. #include "base/abc/abc.h"
  12. ABC_NAMESPACE_IMPL_START
  13. ////////////////////////////////////////////////////////////////////////
  14. /// DECLARATIONS ///
  15. ////////////////////////////////////////////////////////////////////////
  16. #define SHARE_NUM 2
  17. typedef struct Abc_ShaMan_t_ Abc_ShaMan_t;
  18. struct Abc_ShaMan_t_
  19. {
  20. int nMultiSize;
  21. int fVerbose;
  22. Abc_Ntk_t * pNtk;
  23. Vec_Ptr_t * vBuckets;
  24. Vec_Int_t * vObj2Lit;
  25. int nStartCols;
  26. int nCountGates;
  27. int nFoundGates;
  28. };
  29. static inline word Abc_NtkSharePack( int Lev, int Id ) { return (((word)Lev) << 32) | Id; }
  30. static inline int Abc_NtkShareUnpackLev( word Num ) { return (Num >> 32); }
  31. static inline int Abc_NtkShareUnpackId( word Num ) { return Num & 0xFFFFFFFF; }
  32. ////////////////////////////////////////////////////////////////////////
  33. /// FUNCTION DEFINITIONS ///
  34. ////////////////////////////////////////////////////////////////////////
  35. /**Function*************************************************************
  36. Synopsis [Working with the manager.]
  37. Description []
  38. SideEffects []
  39. SeeAlso []
  40. ***********************************************************************/
  41. Abc_ShaMan_t * Abc_ShaManStart( Abc_Ntk_t * pNtk )
  42. {
  43. Abc_ShaMan_t * p;
  44. p = ABC_CALLOC( Abc_ShaMan_t, 1 );
  45. p->pNtk = pNtk;
  46. p->vObj2Lit = Vec_IntAlloc( 1000 );
  47. return p;
  48. }
  49. void Abc_ShaManStop( Abc_ShaMan_t * p )
  50. {
  51. Vec_Ptr_t * vBucket;
  52. int i;
  53. Vec_PtrForEachEntry( Vec_Ptr_t *, p->vBuckets, vBucket, i )
  54. Vec_VecFree( (Vec_Vec_t *)vBucket );
  55. Vec_PtrFreeP( &p->vBuckets );
  56. Vec_IntFreeP( &p->vObj2Lit );
  57. ABC_FREE( p );
  58. }
  59. /**Function*************************************************************
  60. Synopsis [Collects one multi-input gate.]
  61. Description []
  62. SideEffects []
  63. SeeAlso []
  64. ***********************************************************************/
  65. Vec_Wrd_t * Abc_NtkShareSuperXor( Abc_Obj_t * pObj, int * pfCompl, int * pCounter )
  66. {
  67. Abc_Ntk_t * pNtk = Abc_ObjNtk(pObj);
  68. Abc_Obj_t * pObjC, * pObj0, * pObj1, * pRoot = NULL;
  69. Vec_Wrd_t * vSuper;
  70. word Num, NumNext;
  71. int i, k, fCompl = 0;
  72. assert( !Abc_ObjIsComplement(pObj) );
  73. assert( Abc_NodeIsExorType(pObj) );
  74. // start iteration
  75. vSuper = Vec_WrdAlloc( 10 );
  76. Vec_WrdPush( vSuper, Abc_NtkSharePack(Abc_ObjLevel(pObj), Abc_ObjId(pObj)) );
  77. while ( Vec_WrdSize(vSuper) > 0 )
  78. {
  79. // make sure there are no duplicates
  80. Num = Vec_WrdEntry( vSuper, 0 );
  81. Vec_WrdForEachEntryStart( vSuper, NumNext, i, 1 )
  82. {
  83. assert( Num < NumNext );
  84. Num = NumNext;
  85. }
  86. // extract XOR gate decomposable on the topmost level
  87. Vec_WrdForEachEntryReverse( vSuper, Num, i )
  88. {
  89. pRoot = Abc_NtkObj( pNtk, Abc_NtkShareUnpackId(Num) );
  90. if ( Abc_NodeIsExorType(pRoot) )
  91. {
  92. Vec_WrdRemove( vSuper, Num );
  93. break;
  94. }
  95. }
  96. if ( i == -1 )
  97. break;
  98. // extract
  99. pObjC = Abc_NodeRecognizeMux( pRoot, &pObj1, &pObj0 );
  100. assert( pObj1 == Abc_ObjNot(pObj0) );
  101. fCompl ^= Abc_ObjIsComplement(pObjC); pObjC = Abc_ObjRegular(pObjC);
  102. fCompl ^= Abc_ObjIsComplement(pObj0); pObj0 = Abc_ObjRegular(pObj0);
  103. Vec_WrdPushOrder( vSuper, Abc_NtkSharePack(Abc_ObjLevel(pObjC), Abc_ObjId(pObjC)) );
  104. Vec_WrdPushOrder( vSuper, Abc_NtkSharePack(Abc_ObjLevel(pObj0), Abc_ObjId(pObj0)) );
  105. (*pCounter)++;
  106. // remove duplicates
  107. k = 0;
  108. Vec_WrdForEachEntry( vSuper, Num, i )
  109. {
  110. if ( i + 1 == Vec_WrdSize(vSuper) )
  111. {
  112. Vec_WrdWriteEntry( vSuper, k++, Num );
  113. break;
  114. }
  115. NumNext = Vec_WrdEntry( vSuper, i+1 );
  116. assert( Num <= NumNext );
  117. if ( Num == NumNext )
  118. i++;
  119. else
  120. Vec_WrdWriteEntry( vSuper, k++, Num );
  121. }
  122. Vec_WrdShrink( vSuper, k );
  123. }
  124. *pfCompl = fCompl;
  125. Vec_WrdForEachEntry( vSuper, Num, i )
  126. Vec_WrdWriteEntry( vSuper, i, Abc_NtkShareUnpackId(Num) );
  127. return vSuper;
  128. }
  129. Vec_Wrd_t * Abc_NtkShareSuperAnd( Abc_Obj_t * pObj, int * pCounter )
  130. {
  131. Abc_Ntk_t * pNtk = Abc_ObjNtk(pObj);
  132. Abc_Obj_t * pObj0, * pObj1, * pRoot = NULL;
  133. Vec_Wrd_t * vSuper;
  134. word Num, NumNext;
  135. int i, k;
  136. assert( !Abc_ObjIsComplement(pObj) );
  137. // start iteration
  138. vSuper = Vec_WrdAlloc( 10 );
  139. Vec_WrdPush( vSuper, Abc_NtkSharePack(Abc_ObjLevel(pObj), Abc_ObjToLit(pObj)) );
  140. while ( Vec_WrdSize(vSuper) > 0 )
  141. {
  142. // make sure there are no duplicates
  143. Num = Vec_WrdEntry( vSuper, 0 );
  144. Vec_WrdForEachEntryStart( vSuper, NumNext, i, 1 )
  145. {
  146. assert( Num < NumNext );
  147. Num = NumNext;
  148. }
  149. // extract AND gate decomposable on the topmost level
  150. Vec_WrdForEachEntryReverse( vSuper, Num, i )
  151. {
  152. pRoot = Abc_ObjFromLit( pNtk, Abc_NtkShareUnpackId(Num) );
  153. if ( !Abc_ObjIsComplement(pRoot) && Abc_ObjIsNode(pRoot) )
  154. {
  155. Vec_WrdRemove( vSuper, Num );
  156. break;
  157. }
  158. }
  159. if ( i == -1 )
  160. break;
  161. assert( Abc_ObjIsNode(pRoot) );
  162. // extract
  163. pObj0 = Abc_ObjChild0(pRoot);
  164. pObj1 = Abc_ObjChild1(pRoot);
  165. assert( Abc_ObjIsNode(Abc_ObjRegular(pObj0)) || Abc_ObjIsCi(Abc_ObjRegular(pObj0)) );
  166. assert( Abc_ObjIsNode(Abc_ObjRegular(pObj1)) || Abc_ObjIsCi(Abc_ObjRegular(pObj1)) );
  167. Vec_WrdPushOrder( vSuper, Abc_NtkSharePack(Abc_ObjLevel(Abc_ObjRegular(pObj0)), Abc_ObjToLit(pObj0)) );
  168. Vec_WrdPushOrder( vSuper, Abc_NtkSharePack(Abc_ObjLevel(Abc_ObjRegular(pObj1)), Abc_ObjToLit(pObj1)) );
  169. (*pCounter)++;
  170. // remove duplicates
  171. k = 0;
  172. Vec_WrdForEachEntry( vSuper, Num, i )
  173. {
  174. if ( i + 1 == Vec_WrdSize(vSuper) )
  175. {
  176. Vec_WrdWriteEntry( vSuper, k++, Num );
  177. break;
  178. }
  179. NumNext = Vec_WrdEntry( vSuper, i+1 );
  180. assert( Num <= NumNext );
  181. if ( Num + 1 == NumNext && (NumNext & 1) ) // pos_lit & neg_lit = 0
  182. {
  183. Vec_WrdClear( vSuper );
  184. return vSuper;
  185. }
  186. if ( Num < NumNext )
  187. Vec_WrdWriteEntry( vSuper, k++, Num );
  188. }
  189. Vec_WrdShrink( vSuper, k );
  190. }
  191. Vec_WrdForEachEntry( vSuper, Num, i )
  192. Vec_WrdWriteEntry( vSuper, i, Abc_NtkShareUnpackId(Num) );
  193. return vSuper;
  194. }
  195. /**Function*************************************************************
  196. Synopsis [Creates multi-input XOR representation for the nodes.]
  197. Description []
  198. SideEffects []
  199. SeeAlso []
  200. ***********************************************************************/
  201. void Abc_NtkTraverseSupersXor_rec( Abc_ShaMan_t * p, Abc_Obj_t * pObj, Vec_Ptr_t * vInputs )
  202. {
  203. if ( Abc_NodeIsTravIdCurrent( pObj ) )
  204. return;
  205. Abc_NodeSetTravIdCurrent( pObj );
  206. if ( Abc_ObjIsCi(pObj) )
  207. return;
  208. assert( Abc_ObjIsNode(pObj) );
  209. if ( Abc_NodeIsExorType(pObj) )
  210. {
  211. Vec_Wrd_t * vSuper;
  212. int k, fCompl;
  213. word Num;
  214. vSuper = Abc_NtkShareSuperXor( pObj, &fCompl, &p->nFoundGates );
  215. if ( Vec_WrdSize(vSuper) <= 1 || Vec_WrdSize(vSuper) >= p->nMultiSize )
  216. {
  217. Vec_WrdForEachEntry( vSuper, Num, k )
  218. {
  219. Vec_Int_t * vInput = (Vec_Int_t *)Vec_PtrEntry( vInputs, (int)Num );
  220. if ( vInput == NULL )
  221. {
  222. vInput = Vec_IntAlloc( 10 );
  223. Vec_IntPush( vInput, Abc_Var2Lit((int)Num, 0) );
  224. Vec_IntPush( vInput, Abc_ObjLevel(Abc_NtkObj(p->pNtk, (int)Num)) );
  225. assert( SHARE_NUM == Vec_IntSize(vInput) );
  226. Vec_PtrWriteEntry( vInputs, (int)Num, vInput );
  227. }
  228. Vec_IntPush( vInput, Vec_IntSize(p->vObj2Lit) );
  229. }
  230. Vec_IntPush( p->vObj2Lit, Abc_Var2Lit(Abc_ObjId(pObj), fCompl) );
  231. }
  232. // call recursively
  233. Vec_WrdForEachEntry( vSuper, Num, k )
  234. Abc_NtkTraverseSupersXor_rec( p, Abc_NtkObj(p->pNtk, (int)Num), vInputs );
  235. Vec_WrdFree( vSuper );
  236. }
  237. else
  238. {
  239. Abc_NtkTraverseSupersXor_rec( p, Abc_ObjFanin0(pObj), vInputs );
  240. Abc_NtkTraverseSupersXor_rec( p, Abc_ObjFanin1(pObj), vInputs );
  241. }
  242. }
  243. void Abc_NtkTraverseSupersAnd_rec( Abc_ShaMan_t * p, Abc_Obj_t * pObj, Vec_Ptr_t * vInputs )
  244. {
  245. Vec_Wrd_t * vSuper;
  246. word Num;
  247. int k;
  248. if ( Abc_NodeIsTravIdCurrent( pObj ) )
  249. return;
  250. Abc_NodeSetTravIdCurrent( pObj );
  251. if ( Abc_ObjIsCi(pObj) )
  252. return;
  253. assert( Abc_ObjIsNode(pObj) );
  254. vSuper = Abc_NtkShareSuperAnd( pObj, &p->nFoundGates );
  255. if ( Vec_WrdSize(vSuper) <= 1 || Vec_WrdSize(vSuper) >= p->nMultiSize )
  256. {
  257. Vec_WrdForEachEntry( vSuper, Num, k )
  258. {
  259. Vec_Int_t * vInput = (Vec_Int_t *)Vec_PtrEntry( vInputs, (int)Num );
  260. if ( vInput == NULL )
  261. {
  262. vInput = Vec_IntAlloc( 10 );
  263. Vec_IntPush( vInput, (int)Num );
  264. Vec_IntPush( vInput, Abc_ObjLevel(Abc_NtkObj(p->pNtk, Abc_Lit2Var((int)Num))) );
  265. assert( SHARE_NUM == Vec_IntSize(vInput) );
  266. Vec_PtrWriteEntry( vInputs, (int)Num, vInput );
  267. }
  268. Vec_IntPush( vInput, Vec_IntSize(p->vObj2Lit) );
  269. }
  270. Vec_IntPush( p->vObj2Lit, Abc_ObjToLit(pObj) );
  271. }
  272. // call recursively
  273. Vec_WrdForEachEntry( vSuper, Num, k )
  274. Abc_NtkTraverseSupersAnd_rec( p, Abc_NtkObj(p->pNtk, Abc_Lit2Var((int)Num)), vInputs );
  275. Vec_WrdFree( vSuper );
  276. }
  277. void Abc_NtkTraverseSupers( Abc_ShaMan_t * p, int fAnd )
  278. {
  279. Vec_Ptr_t * vInputs;
  280. Vec_Int_t * vInput;
  281. Abc_Obj_t * pObj;
  282. int i, nOnesMax;
  283. // create mapping of nodes into their column vectors
  284. vInputs = Vec_PtrStart( Abc_NtkObjNumMax(p->pNtk) * (1 + fAnd) );
  285. Abc_NtkIncrementTravId( p->pNtk );
  286. if ( fAnd )
  287. {
  288. Abc_NtkForEachCo( p->pNtk, pObj, i )
  289. if ( Abc_ObjIsNode(Abc_ObjFanin0(pObj)) )
  290. Abc_NtkTraverseSupersAnd_rec( p, Abc_ObjFanin0(pObj), vInputs );
  291. }
  292. else
  293. {
  294. Abc_NtkForEachCo( p->pNtk, pObj, i )
  295. if ( Abc_ObjIsNode(Abc_ObjFanin0(pObj)) )
  296. Abc_NtkTraverseSupersXor_rec( p, Abc_ObjFanin0(pObj), vInputs );
  297. }
  298. p->nStartCols = Vec_IntSize(p->vObj2Lit);
  299. // find the largest number of 1s
  300. nOnesMax = 0;
  301. Vec_PtrForEachEntry( Vec_Int_t *, vInputs, vInput, i )
  302. if ( vInput )
  303. nOnesMax = Abc_MaxInt( nOnesMax, Vec_IntSize(vInput)-SHARE_NUM );
  304. // create buckets
  305. assert( p->vBuckets == NULL );
  306. p->vBuckets = Vec_PtrAlloc( nOnesMax + 1 );
  307. for ( i = 0; i <= nOnesMax; i++ )
  308. Vec_PtrPush( p->vBuckets, Vec_PtrAlloc(10) );
  309. // load vectors into buckets
  310. Vec_PtrForEachEntry( Vec_Int_t *, vInputs, vInput, i )
  311. if ( vInput )
  312. Vec_PtrPush( (Vec_Ptr_t *)Vec_PtrEntry(p->vBuckets, Vec_IntSize(vInput)-SHARE_NUM), vInput );
  313. Vec_PtrFree( vInputs );
  314. }
  315. /**Function*************************************************************
  316. Synopsis []
  317. Description []
  318. SideEffects []
  319. SeeAlso []
  320. ***********************************************************************/
  321. void Abc_NtkSharePrint( Abc_ShaMan_t * p )
  322. {
  323. Vec_Ptr_t * vBucket;
  324. Vec_Int_t * vInput;
  325. int i, k, j, ObjId;
  326. char * pBuffer = ABC_ALLOC( char, Vec_IntSize(p->vObj2Lit) + 1 );
  327. int * pCounters = ABC_CALLOC( int, Vec_IntSize(p->vObj2Lit) + 1 );
  328. int nTotal = 0;
  329. Vec_PtrForEachEntry( Vec_Ptr_t *, p->vBuckets, vBucket, i )
  330. Vec_PtrForEachEntry( Vec_Int_t *, vBucket, vInput, j )
  331. {
  332. for ( k = 0; k < Vec_IntSize(p->vObj2Lit); k++ )
  333. pBuffer[k] = '0';
  334. pBuffer[k] = 0;
  335. Vec_IntForEachEntryStart( vInput, ObjId, k, SHARE_NUM )
  336. {
  337. assert( ObjId < Vec_IntSize(p->vObj2Lit) );
  338. pBuffer[ObjId] = '1';
  339. pCounters[ObjId]++;
  340. }
  341. printf( "%4d%3d: %s\n", Vec_IntEntry(vInput, 0), Vec_IntEntry(vInput, 1), pBuffer );
  342. }
  343. for ( i = 0; i < Vec_IntSize(p->vObj2Lit); i++ )
  344. if ( pCounters[i] > 0 )
  345. printf( "%d=%d ", i, pCounters[i] );
  346. printf( "\n" );
  347. nTotal = 0;
  348. for ( i = 0; i < p->nStartCols; i++ )
  349. nTotal += pCounters[i] - 1;
  350. printf( "Total = %d. ", nTotal );
  351. printf( "Gates = %d.\n", Vec_IntSize(p->vObj2Lit) - p->nStartCols + nTotal );
  352. ABC_FREE( pCounters );
  353. ABC_FREE( pBuffer );
  354. printf( "Bucket contents: " );
  355. Vec_PtrForEachEntry( Vec_Ptr_t *, p->vBuckets, vBucket, i )
  356. printf( "%d ", Vec_PtrSize(vBucket) );
  357. printf( "\n" );
  358. }
  359. /**Function*************************************************************
  360. Synopsis []
  361. Description []
  362. SideEffects []
  363. SeeAlso []
  364. ***********************************************************************/
  365. void Abc_NtkDumpBlif( Abc_Ntk_t * p )
  366. {
  367. FILE * pFile;
  368. Vec_Ptr_t * vSupp;
  369. Abc_Obj_t * pObj;
  370. int i, k;
  371. pFile = fopen( "multi_and.blif", "wb" );
  372. if ( pFile == NULL )
  373. {
  374. printf( "Cannot open output file.\n" );
  375. return;
  376. }
  377. fprintf( pFile, ".model %s\n", "multi_and" );
  378. fprintf( pFile, ".inputs" );
  379. for ( i = 0; i < Abc_NtkCiNum(p); i++ )
  380. fprintf( pFile, " i%d", i );
  381. fprintf( pFile, "\n" );
  382. fprintf( pFile, ".outputs" );
  383. for ( i = 0; i < Abc_NtkCoNum(p); i++ )
  384. fprintf( pFile, " o%d", i );
  385. fprintf( pFile, "\n" );
  386. Abc_NtkForEachCi( p, pObj, i )
  387. pObj->iTemp = i;
  388. for ( i = 0; i < Abc_NtkCoNum(p); i++ )
  389. {
  390. pObj = Abc_NtkCo( p, i );
  391. vSupp = Abc_NtkNodeSupport( p, &pObj, 1 );
  392. fprintf( pFile, ".names" );
  393. Vec_PtrForEachEntry( Abc_Obj_t *, vSupp, pObj, k )
  394. fprintf( pFile, " i%d", pObj->iTemp );
  395. fprintf( pFile, " o%d\n", i );
  396. Vec_PtrForEachEntry( Abc_Obj_t *, vSupp, pObj, k )
  397. fprintf( pFile, "1" );
  398. fprintf( pFile, " 1\n" );
  399. Vec_PtrFree( vSupp );
  400. }
  401. fprintf( pFile, ".end\n\n" );
  402. fclose( pFile );
  403. }
  404. /**Function*************************************************************
  405. Synopsis []
  406. Description []
  407. SideEffects []
  408. SeeAlso []
  409. ***********************************************************************/
  410. void Abc_NtkShareFindBestMatch( Vec_Ptr_t * vBuckets, Vec_Int_t ** pvInput, Vec_Int_t ** pvInput2 )
  411. {
  412. int nPoolSize = 40;
  413. Vec_Ptr_t * vPool = Vec_PtrAlloc( nPoolSize );
  414. Vec_Ptr_t * vBucket;
  415. Vec_Int_t * vInput, * vInput2, * vInputBest = NULL, * vInputBest2 = NULL;
  416. int i, k, Cost, CostBest = 0, Delay, DelayBest = 0;
  417. Vec_PtrForEachEntryReverse( Vec_Ptr_t *, vBuckets, vBucket, i )
  418. Vec_PtrForEachEntry( Vec_Int_t *, vBucket, vInput, k )
  419. {
  420. Vec_PtrPush( vPool, vInput );
  421. if ( Vec_PtrSize(vPool) == nPoolSize )
  422. goto outside;
  423. }
  424. outside:
  425. Vec_PtrForEachEntryReverse( Vec_Int_t *, vPool, vInput, i )
  426. Vec_PtrForEachEntryReverse( Vec_Int_t *, vPool, vInput2, k )
  427. {
  428. if ( i == k )
  429. continue;
  430. vInput->pArray += SHARE_NUM;
  431. vInput2->pArray += SHARE_NUM;
  432. vInput->nSize -= SHARE_NUM;
  433. vInput2->nSize -= SHARE_NUM;
  434. Cost = Vec_IntTwoCountCommon(vInput, vInput2);
  435. vInput->pArray -= SHARE_NUM;
  436. vInput2->pArray -= SHARE_NUM;
  437. vInput->nSize += SHARE_NUM;
  438. vInput2->nSize += SHARE_NUM;
  439. if ( Cost < 2 )
  440. continue;
  441. Delay = Abc_MaxInt( Vec_IntEntry(vInput, 1), Vec_IntEntry(vInput2, 1) );
  442. if ( CostBest < Cost || (CostBest == Cost && (DelayBest > Delay)) )
  443. {
  444. CostBest = Cost;
  445. DelayBest = Delay;
  446. vInputBest = vInput;
  447. vInputBest2 = vInput2;
  448. }
  449. }
  450. Vec_PtrFree( vPool );
  451. *pvInput = vInputBest;
  452. *pvInput2 = vInputBest2;
  453. if ( vInputBest == NULL )
  454. return;
  455. Vec_PtrRemove( (Vec_Ptr_t *)Vec_PtrEntry(vBuckets, Vec_IntSize(vInputBest)-SHARE_NUM), (Vec_Int_t *)vInputBest );
  456. Vec_PtrRemove( (Vec_Ptr_t *)Vec_PtrEntry(vBuckets, Vec_IntSize(vInputBest2)-SHARE_NUM), (Vec_Int_t *)vInputBest2 );
  457. }
  458. void Abc_NtkShareOptimize( Abc_ShaMan_t * p, int fAnd )
  459. {
  460. Abc_Obj_t * pObj, * pObj0, * pObj1;
  461. Vec_Int_t * vInput, * vInput2;
  462. Vec_Int_t * vNew, * vOld1, * vOld2;
  463. int i;
  464. for ( i = 0; ; i++ )
  465. {
  466. Abc_NtkShareFindBestMatch( p->vBuckets, &vInput, &vInput2 );
  467. if ( vInput == NULL )
  468. break;
  469. // create new node
  470. pObj0 = Abc_ObjFromLit( p->pNtk, Vec_IntEntry(vInput, 0) );
  471. pObj1 = Abc_ObjFromLit( p->pNtk, Vec_IntEntry(vInput2, 0) );
  472. if ( fAnd )
  473. pObj = Abc_AigAnd( (Abc_Aig_t *)p->pNtk->pManFunc, pObj0, pObj1 );
  474. else
  475. pObj = Abc_AigXor( (Abc_Aig_t *)p->pNtk->pManFunc, pObj0, pObj1 );
  476. p->nCountGates++;
  477. // save new node
  478. vOld1 = Vec_IntAlloc( 16 ); Vec_IntPush( vOld1, Vec_IntEntry(vInput, 0) ); Vec_IntPush( vOld1, Vec_IntEntry(vInput, 1) );
  479. vOld2 = Vec_IntAlloc( 16 ); Vec_IntPush( vOld2, Vec_IntEntry(vInput2, 0) ); Vec_IntPush( vOld2, Vec_IntEntry(vInput2, 1) );
  480. vNew = Vec_IntAlloc( 16 ); Vec_IntPush( vNew, Abc_ObjToLit(pObj) ); Vec_IntPush( vNew, Abc_ObjLevel(Abc_ObjRegular(pObj)) );
  481. // compute new arrays
  482. vInput->pArray += SHARE_NUM;
  483. vInput2->pArray += SHARE_NUM;
  484. vInput->nSize -= SHARE_NUM;
  485. vInput2->nSize -= SHARE_NUM;
  486. Vec_IntTwoSplit( vInput, vInput2, vNew, vOld1, vOld2 );
  487. vInput->pArray -= SHARE_NUM;
  488. vInput2->pArray -= SHARE_NUM;
  489. vInput->nSize += SHARE_NUM;
  490. vInput2->nSize += SHARE_NUM;
  491. // add to the old ones
  492. Vec_IntPush( vOld1, Vec_IntSize(p->vObj2Lit) );
  493. Vec_IntPush( vOld2, Vec_IntSize(p->vObj2Lit) );
  494. Vec_IntPush( p->vObj2Lit, Abc_ObjToLit(pObj) );
  495. Vec_PtrPush( (Vec_Ptr_t *)Vec_PtrEntry(p->vBuckets, Vec_IntSize(vOld1)-SHARE_NUM), vOld1 );
  496. Vec_PtrPush( (Vec_Ptr_t *)Vec_PtrEntry(p->vBuckets, Vec_IntSize(vOld2)-SHARE_NUM), vOld2 );
  497. Vec_PtrPush( (Vec_Ptr_t *)Vec_PtrEntry(p->vBuckets, Vec_IntSize(vNew)-SHARE_NUM), vNew );
  498. Vec_IntFree( vInput );
  499. Vec_IntFree( vInput2 );
  500. }
  501. }
  502. /**Function*************************************************************
  503. Synopsis []
  504. Description []
  505. SideEffects []
  506. SeeAlso []
  507. ***********************************************************************/
  508. Abc_Ntk_t * Abc_NtkUpdateNetwork( Abc_ShaMan_t * p, int fAnd )
  509. {
  510. Abc_Ntk_t * pNtk;
  511. Vec_Int_t * vInput, * vMap2Repl;
  512. Vec_Ptr_t * vOrig, * vRepl, * vBucket;
  513. Abc_Obj_t * pObj, * pNew;
  514. int i, j, k, ObjId, iLit;
  515. int iLitConst1 = Abc_ObjToLit( Abc_AigConst1(p->pNtk) );
  516. vOrig = Vec_PtrAlloc( p->nStartCols );
  517. vRepl = Vec_PtrAlloc( p->nStartCols );
  518. for ( i = 0; i < p->nStartCols; i++ )
  519. {
  520. iLit = Vec_IntEntry( p->vObj2Lit, i );
  521. assert( !fAnd || !Abc_LitIsCompl(iLit) );
  522. pObj = Abc_NtkObj( p->pNtk, Abc_Lit2Var(iLit) );
  523. if ( fAnd )
  524. pNew = Abc_AigConst1(p->pNtk);
  525. else
  526. pNew = Abc_ObjNotCond( Abc_AigConst1(p->pNtk), !Abc_LitIsCompl(iLit) );
  527. Vec_PtrPush( vOrig, pObj );
  528. Vec_PtrPush( vRepl, pNew );
  529. p->nCountGates--;
  530. }
  531. // go through the columns
  532. Vec_PtrForEachEntry( Vec_Ptr_t *, p->vBuckets, vBucket, i )
  533. Vec_PtrForEachEntry( Vec_Int_t *, vBucket, vInput, j )
  534. {
  535. Vec_IntForEachEntryStart( vInput, ObjId, k, SHARE_NUM )
  536. {
  537. assert( ObjId < Vec_IntSize(p->vObj2Lit) );
  538. if ( ObjId >= p->nStartCols )
  539. break;
  540. assert( ObjId < p->nStartCols );
  541. iLit = Vec_IntEntry( vInput, 0 );
  542. pNew = (Abc_Obj_t *)Vec_PtrEntry( vRepl, ObjId );
  543. if ( fAnd )
  544. pNew = Abc_AigAnd( (Abc_Aig_t *)p->pNtk->pManFunc, pNew, Abc_ObjFromLit(p->pNtk, iLit) );
  545. else
  546. pNew = Abc_AigXor( (Abc_Aig_t *)p->pNtk->pManFunc, pNew, Abc_ObjFromLit(p->pNtk, iLit) );
  547. Vec_PtrWriteEntry( vRepl, ObjId, pNew );
  548. p->nCountGates++;
  549. }
  550. }
  551. if ( p->fVerbose )
  552. printf( "Total gates collected = %d. Total gates constructed = %d.\n", p->nFoundGates, p->nCountGates );
  553. // create map of originals
  554. vMap2Repl = Vec_IntStartFull( Abc_NtkObjNumMax(p->pNtk) );
  555. Vec_PtrForEachEntry( Abc_Obj_t *, vOrig, pObj, i )
  556. {
  557. // printf( "Replacing %d by %d.\n", Abc_ObjId(pObj), Abc_ObjToLit((Abc_Obj_t *)Vec_PtrEntry(vRepl, i)) );
  558. Vec_IntWriteEntry( vMap2Repl, Abc_ObjId(pObj), Abc_ObjToLit((Abc_Obj_t *)Vec_PtrEntry(vRepl, i)) );
  559. }
  560. Vec_PtrFree( vOrig );
  561. Vec_PtrFree( vRepl );
  562. // update fanin pointers
  563. Abc_NtkForEachObj( p->pNtk, pObj, i )
  564. {
  565. if ( Abc_ObjIsCo(pObj) || Abc_ObjIsNode(pObj) )
  566. {
  567. iLit = Vec_IntEntry( vMap2Repl, Abc_ObjFaninId0(pObj) );
  568. if ( iLit >= 0 )
  569. {
  570. if ( iLit == iLitConst1 && fAnd )
  571. {
  572. pObj->fCompl0 ^= 1;
  573. Vec_IntWriteEntry( &pObj->vFanins, 0, Abc_Lit2Var(iLitConst1) );
  574. }
  575. else
  576. {
  577. pObj->fCompl0 ^= Abc_LitIsCompl(iLit);
  578. Vec_IntWriteEntry( &pObj->vFanins, 0, Abc_Lit2Var(iLit) );
  579. }
  580. }
  581. }
  582. if ( Abc_ObjIsNode(pObj) )
  583. {
  584. iLit = Vec_IntEntry( vMap2Repl, Abc_ObjFaninId1(pObj) );
  585. if ( iLit >= 0 )
  586. {
  587. if ( iLit == iLitConst1 && fAnd )
  588. {
  589. pObj->fCompl1 ^= 1;
  590. Vec_IntWriteEntry( &pObj->vFanins, 1, Abc_Lit2Var(iLitConst1) );
  591. }
  592. else
  593. {
  594. pObj->fCompl1 ^= Abc_LitIsCompl(iLit);
  595. Vec_IntWriteEntry( &pObj->vFanins, 1, Abc_Lit2Var(iLit) );
  596. }
  597. }
  598. }
  599. }
  600. Vec_IntFree( vMap2Repl );
  601. // pNtk = Abc_NtkRestrash( p->pNtk, 1 );
  602. if ( fAnd )
  603. pNtk = Abc_NtkBalance( p->pNtk, 0, 0, 1 );
  604. else
  605. pNtk = Abc_NtkBalanceExor( p->pNtk, 1, 0 );
  606. return pNtk;
  607. }
  608. /**Function*************************************************************
  609. Synopsis [Extracts one multi-output XOR.]
  610. Description []
  611. SideEffects []
  612. SeeAlso []
  613. ***********************************************************************/
  614. Abc_Ntk_t * Abc_NtkShareXor( Abc_Ntk_t * pNtk, int nMultiSize, int fAnd, int fVerbose )
  615. {
  616. Abc_Ntk_t * pNtkNew;
  617. Abc_ShaMan_t * p;
  618. assert( Abc_NtkIsStrash(pNtk) );
  619. // Abc_NtkDumpBlif( pNtk );
  620. p = Abc_ShaManStart( pNtk );
  621. p->nMultiSize = nMultiSize;
  622. p->fVerbose = fVerbose;
  623. Abc_NtkTraverseSupers( p, fAnd );
  624. if ( p->nStartCols < 2 )
  625. {
  626. Abc_ShaManStop( p );
  627. return Abc_NtkDup( pNtk );
  628. }
  629. if ( fVerbose )
  630. Abc_NtkSharePrint( p );
  631. Abc_NtkShareOptimize( p, fAnd );
  632. if ( fVerbose )
  633. Abc_NtkSharePrint( p );
  634. pNtkNew = Abc_NtkUpdateNetwork( p, fAnd );
  635. Abc_ShaManStop( p );
  636. return pNtkNew;
  637. }
  638. ////////////////////////////////////////////////////////////////////////
  639. /// END OF FILE ///
  640. ////////////////////////////////////////////////////////////////////////
  641. ABC_NAMESPACE_IMPL_END