PageRenderTime 56ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/src/opt/lpk/lpkCore.c

https://bitbucket.org/alanmi/abc/
C | 694 lines | 402 code | 59 blank | 233 comment | 89 complexity | f0fc5b9de1e72ab634053f2ee322ecb6 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. /**CFile****************************************************************
  2. FileName [lpkCore.c]
  3. SystemName [ABC: Logic synthesis and verification system.]
  4. PackageName [Fast Boolean matching for LUT structures.]
  5. Synopsis []
  6. Author [Alan Mishchenko]
  7. Affiliation [UC Berkeley]
  8. Date [Ver. 1.0. Started - April 28, 2007.]
  9. Revision [$Id: lpkCore.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
  10. ***********************************************************************/
  11. #include "lpkInt.h"
  12. #include "bool/kit/cloud.h"
  13. #include "base/main/main.h"
  14. ABC_NAMESPACE_IMPL_START
  15. ////////////////////////////////////////////////////////////////////////
  16. /// DECLARATIONS ///
  17. ////////////////////////////////////////////////////////////////////////
  18. ////////////////////////////////////////////////////////////////////////
  19. /// FUNCTION DEFINITIONS ///
  20. ////////////////////////////////////////////////////////////////////////
  21. /**Function*************************************************************
  22. Synopsis [Prepares the mapping manager.]
  23. Description []
  24. SideEffects []
  25. SeeAlso []
  26. ***********************************************************************/
  27. void Lpk_IfManStart( Lpk_Man_t * p )
  28. {
  29. If_Par_t * pPars;
  30. assert( p->pIfMan == NULL );
  31. // set defaults
  32. pPars = ABC_ALLOC( If_Par_t, 1 );
  33. memset( pPars, 0, sizeof(If_Par_t) );
  34. // user-controlable paramters
  35. pPars->nLutSize = p->pPars->nLutSize;
  36. pPars->nCutsMax = 16;
  37. pPars->nFlowIters = 0; // 1
  38. pPars->nAreaIters = 0; // 1
  39. pPars->DelayTarget = -1;
  40. pPars->Epsilon = (float)0.005;
  41. pPars->fPreprocess = 0;
  42. pPars->fArea = 1;
  43. pPars->fFancy = 0;
  44. pPars->fExpRed = 0; //
  45. pPars->fLatchPaths = 0;
  46. pPars->fVerbose = 0;
  47. // internal parameters
  48. pPars->fTruth = 1;
  49. pPars->fUsePerm = 0;
  50. pPars->nLatchesCi = 0;
  51. pPars->nLatchesCo = 0;
  52. pPars->pLutLib = NULL; // Abc_FrameReadLibLut();
  53. pPars->pTimesArr = NULL;
  54. pPars->pTimesArr = NULL;
  55. pPars->fUseBdds = 0;
  56. pPars->fUseSops = 0;
  57. pPars->fUseCnfs = 0;
  58. pPars->fUseMv = 0;
  59. // start the mapping manager and set its parameters
  60. p->pIfMan = If_ManStart( pPars );
  61. If_ManSetupSetAll( p->pIfMan, 1000 );
  62. p->pIfMan->pPars->pTimesArr = ABC_ALLOC( float, 32 );
  63. }
  64. /**Function*************************************************************
  65. Synopsis [Returns 1 if at least one entry has changed.]
  66. Description []
  67. SideEffects []
  68. SeeAlso []
  69. ***********************************************************************/
  70. int Lpk_NodeHasChanged( Lpk_Man_t * p, int iNode )
  71. {
  72. Vec_Ptr_t * vNodes;
  73. Abc_Obj_t * pTemp;
  74. int i;
  75. vNodes = Vec_VecEntry( p->vVisited, iNode );
  76. if ( Vec_PtrSize(vNodes) == 0 )
  77. return 1;
  78. Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pTemp, i )
  79. {
  80. // check if the node has changed
  81. pTemp = Abc_NtkObj( p->pNtk, (int)(ABC_PTRUINT_T)pTemp );
  82. if ( pTemp == NULL )
  83. return 1;
  84. // check if the number of fanouts has changed
  85. // if ( Abc_ObjFanoutNum(pTemp) != (int)Vec_PtrEntry(vNodes, i+1) )
  86. // return 1;
  87. i++;
  88. }
  89. return 0;
  90. }
  91. /**Function*************************************************************
  92. Synopsis [Prepares the mapping manager.]
  93. Description []
  94. SideEffects []
  95. SeeAlso []
  96. ***********************************************************************/
  97. int Lpk_ExploreCut( Lpk_Man_t * p, Lpk_Cut_t * pCut, Kit_DsdNtk_t * pNtk )
  98. {
  99. extern Abc_Obj_t * Abc_NodeFromIf_rec( Abc_Ntk_t * pNtkNew, If_Man_t * pIfMan, If_Obj_t * pIfObj, Vec_Int_t * vCover );
  100. Kit_DsdObj_t * pRoot;
  101. If_Obj_t * pDriver, * ppLeaves[16];
  102. Abc_Obj_t * pLeaf, * pObjNew;
  103. int nGain, i;
  104. abctime clk;
  105. int nNodesBef;
  106. // int nOldShared;
  107. // check special cases
  108. pRoot = Kit_DsdNtkRoot( pNtk );
  109. if ( pRoot->Type == KIT_DSD_CONST1 )
  110. {
  111. if ( Abc_LitIsCompl(pNtk->Root) )
  112. pObjNew = Abc_NtkCreateNodeConst0( p->pNtk );
  113. else
  114. pObjNew = Abc_NtkCreateNodeConst1( p->pNtk );
  115. Abc_NtkUpdate( p->pObj, pObjNew, p->vLevels );
  116. p->nGainTotal += pCut->nNodes - pCut->nNodesDup;
  117. return 1;
  118. }
  119. if ( pRoot->Type == KIT_DSD_VAR )
  120. {
  121. pObjNew = Abc_NtkObj( p->pNtk, pCut->pLeaves[ Abc_Lit2Var(pRoot->pFans[0]) ] );
  122. if ( Abc_LitIsCompl(pNtk->Root) ^ Abc_LitIsCompl(pRoot->pFans[0]) )
  123. pObjNew = Abc_NtkCreateNodeInv( p->pNtk, pObjNew );
  124. Abc_NtkUpdate( p->pObj, pObjNew, p->vLevels );
  125. p->nGainTotal += pCut->nNodes - pCut->nNodesDup;
  126. return 1;
  127. }
  128. assert( pRoot->Type == KIT_DSD_AND || pRoot->Type == KIT_DSD_XOR || pRoot->Type == KIT_DSD_PRIME );
  129. // start the mapping manager
  130. if ( p->pIfMan == NULL )
  131. Lpk_IfManStart( p );
  132. // prepare the mapping manager
  133. If_ManRestart( p->pIfMan );
  134. // create the PI variables
  135. for ( i = 0; i < p->pPars->nVarsMax; i++ )
  136. ppLeaves[i] = If_ManCreateCi( p->pIfMan );
  137. // set the arrival times
  138. Lpk_CutForEachLeaf( p->pNtk, pCut, pLeaf, i )
  139. p->pIfMan->pPars->pTimesArr[i] = (float)pLeaf->Level;
  140. // prepare the PI cuts
  141. If_ManSetupCiCutSets( p->pIfMan );
  142. // create the internal nodes
  143. p->fCalledOnce = 0;
  144. p->nCalledSRed = 0;
  145. pDriver = Lpk_MapTree_rec( p, pNtk, ppLeaves, pNtk->Root, NULL );
  146. if ( pDriver == NULL )
  147. return 0;
  148. // create the PO node
  149. If_ManCreateCo( p->pIfMan, If_Regular(pDriver) );
  150. // perform mapping
  151. p->pIfMan->pPars->fAreaOnly = 1;
  152. clk = Abc_Clock();
  153. If_ManPerformMappingComb( p->pIfMan );
  154. p->timeMap += Abc_Clock() - clk;
  155. // compute the gain in area
  156. nGain = pCut->nNodes - pCut->nNodesDup - (int)p->pIfMan->AreaGlo;
  157. if ( p->pPars->fVeryVerbose )
  158. printf( " Mffc = %2d. Mapped = %2d. Gain = %3d. Depth increase = %d. SReds = %d.\n",
  159. pCut->nNodes - pCut->nNodesDup, (int)p->pIfMan->AreaGlo, nGain, (int)p->pIfMan->RequiredGlo - (int)p->pObj->Level, p->nCalledSRed );
  160. // quit if there is no gain
  161. if ( !(nGain > 0 || (p->pPars->fZeroCost && nGain == 0)) )
  162. return 0;
  163. // quit if depth increases too much
  164. if ( (int)p->pIfMan->RequiredGlo > Abc_ObjRequiredLevel(p->pObj) )
  165. return 0;
  166. // perform replacement
  167. p->nGainTotal += nGain;
  168. p->nChanges++;
  169. if ( p->nCalledSRed )
  170. p->nBenefited++;
  171. nNodesBef = Abc_NtkNodeNum(p->pNtk);
  172. // prepare the mapping manager
  173. If_ManCleanNodeCopy( p->pIfMan );
  174. If_ManCleanCutData( p->pIfMan );
  175. // set the PIs of the cut
  176. Lpk_CutForEachLeaf( p->pNtk, pCut, pLeaf, i )
  177. If_ObjSetCopy( If_ManCi(p->pIfMan, i), pLeaf );
  178. // get the area of mapping
  179. pObjNew = Abc_NodeFromIf_rec( p->pNtk, p->pIfMan, If_Regular(pDriver), p->vCover );
  180. pObjNew->pData = Hop_NotCond( (Hop_Obj_t *)pObjNew->pData, If_IsComplement(pDriver) );
  181. // perform replacement
  182. Abc_NtkUpdate( p->pObj, pObjNew, p->vLevels );
  183. //printf( "%3d : %d-%d=%d(%d) \n", p->nChanges, nNodesBef, Abc_NtkNodeNum(p->pNtk), nNodesBef-Abc_NtkNodeNum(p->pNtk), nGain );
  184. return 1;
  185. }
  186. /**Function*************************************************************
  187. Synopsis [Performs resynthesis for one node.]
  188. Description []
  189. SideEffects []
  190. SeeAlso []
  191. ***********************************************************************/
  192. int Lpk_ResynthesizeNode( Lpk_Man_t * p )
  193. {
  194. // static int Count = 0;
  195. Kit_DsdNtk_t * pDsdNtk;
  196. Lpk_Cut_t * pCut;
  197. unsigned * pTruth;
  198. int i, k, nSuppSize, nCutNodes, RetValue;
  199. abctime clk;
  200. // compute the cuts
  201. clk = Abc_Clock();
  202. if ( !Lpk_NodeCuts( p ) )
  203. {
  204. p->timeCuts += Abc_Clock() - clk;
  205. return 0;
  206. }
  207. p->timeCuts += Abc_Clock() - clk;
  208. //return 0;
  209. if ( p->pPars->fVeryVerbose )
  210. printf( "Node %5d : Mffc size = %5d. Cuts = %5d.\n", p->pObj->Id, p->nMffc, p->nEvals );
  211. // try the good cuts
  212. p->nCutsTotal += p->nCuts;
  213. p->nCutsUseful += p->nEvals;
  214. for ( i = 0; i < p->nEvals; i++ )
  215. {
  216. // get the cut
  217. pCut = p->pCuts + p->pEvals[i];
  218. if ( p->pPars->fFirst && i == 1 )
  219. break;
  220. // skip bad cuts
  221. // printf( "Mffc size = %d. ", Abc_NodeMffcLabel(p->pObj) );
  222. for ( k = 0; k < (int)pCut->nLeaves; k++ )
  223. Abc_NtkObj(p->pNtk, pCut->pLeaves[k])->vFanouts.nSize++;
  224. nCutNodes = Abc_NodeMffcLabel(p->pObj);
  225. // printf( "Mffc with cut = %d. ", nCutNodes );
  226. for ( k = 0; k < (int)pCut->nLeaves; k++ )
  227. Abc_NtkObj(p->pNtk, pCut->pLeaves[k])->vFanouts.nSize--;
  228. // printf( "Mffc cut = %d. ", (int)pCut->nNodes - (int)pCut->nNodesDup );
  229. // printf( "\n" );
  230. if ( nCutNodes != (int)pCut->nNodes - (int)pCut->nNodesDup )
  231. continue;
  232. // compute the truth table
  233. clk = Abc_Clock();
  234. pTruth = Lpk_CutTruth( p, pCut, 0 );
  235. nSuppSize = Extra_TruthSupportSize(pTruth, pCut->nLeaves);
  236. p->timeTruth += Abc_Clock() - clk;
  237. pDsdNtk = Kit_DsdDecompose( pTruth, pCut->nLeaves );
  238. // Kit_DsdVerify( pDsdNtk, pTruth, pCut->nLeaves );
  239. // skip 16-input non-DSD because ISOP will not work
  240. if ( Kit_DsdNtkRoot(pDsdNtk)->nFans == 16 )
  241. {
  242. Kit_DsdNtkFree( pDsdNtk );
  243. continue;
  244. }
  245. // if DSD has nodes that require splitting to fit them into LUTs
  246. // we can skip those cuts that cannot lead to improvement
  247. // (a full DSD network requires V = Nmin * (K-1) + 1 for improvement)
  248. if ( Kit_DsdNonDsdSizeMax(pDsdNtk) > p->pPars->nLutSize &&
  249. nSuppSize >= ((int)pCut->nNodes - (int)pCut->nNodesDup - 1) * (p->pPars->nLutSize - 1) + 1 )
  250. {
  251. Kit_DsdNtkFree( pDsdNtk );
  252. continue;
  253. }
  254. if ( p->pPars->fVeryVerbose )
  255. {
  256. // char * pFileName;
  257. printf( " C%02d: L= %2d/%2d V= %2d/%d N= %d W= %4.2f ",
  258. i, pCut->nLeaves, nSuppSize, pCut->nNodes, pCut->nNodesDup, pCut->nLuts, pCut->Weight );
  259. Kit_DsdPrint( stdout, pDsdNtk );
  260. Kit_DsdPrintFromTruth( pTruth, pCut->nLeaves );
  261. // pFileName = Kit_TruthDumpToFile( pTruth, pCut->nLeaves, Count++ );
  262. // printf( "Saved truth table in file \"%s\".\n", pFileName );
  263. }
  264. // update the network
  265. clk = Abc_Clock();
  266. RetValue = Lpk_ExploreCut( p, pCut, pDsdNtk );
  267. p->timeEval += Abc_Clock() - clk;
  268. Kit_DsdNtkFree( pDsdNtk );
  269. if ( RetValue )
  270. break;
  271. }
  272. return 1;
  273. }
  274. /**Function*************************************************************
  275. Synopsis [Computes supports of the cofactors of the function.]
  276. Description [This procedure should be called after Lpk_CutTruth(p,pCut,0)]
  277. SideEffects []
  278. SeeAlso []
  279. ***********************************************************************/
  280. void Lpk_ComputeSupports( Lpk_Man_t * p, Lpk_Cut_t * pCut, unsigned * pTruth )
  281. {
  282. unsigned * pTruthInv;
  283. int RetValue1, RetValue2;
  284. pTruthInv = Lpk_CutTruth( p, pCut, 1 );
  285. RetValue1 = Kit_CreateCloudFromTruth( p->pDsdMan->dd, pTruth, pCut->nLeaves, p->vBddDir );
  286. RetValue2 = Kit_CreateCloudFromTruth( p->pDsdMan->dd, pTruthInv, pCut->nLeaves, p->vBddInv );
  287. if ( RetValue1 && RetValue2 && Vec_IntSize(p->vBddDir) > 1 && Vec_IntSize(p->vBddInv) > 1 )
  288. Kit_TruthCofSupports( p->vBddDir, p->vBddInv, pCut->nLeaves, p->vMemory, p->puSupps );
  289. else
  290. p->puSupps[0] = p->puSupps[1] = 0;
  291. }
  292. /**Function*************************************************************
  293. Synopsis [Performs resynthesis for one node.]
  294. Description []
  295. SideEffects []
  296. SeeAlso []
  297. ***********************************************************************/
  298. int Lpk_ResynthesizeNodeNew( Lpk_Man_t * p )
  299. {
  300. // static int Count = 0;
  301. Abc_Obj_t * pObjNew, * pLeaf;
  302. Lpk_Cut_t * pCut;
  303. unsigned * pTruth;
  304. int nNodesBef, nNodesAft, nCutNodes;
  305. int i, k;
  306. abctime clk;
  307. int Required = Abc_ObjRequiredLevel(p->pObj);
  308. // CloudNode * pFun2;//, * pFun1;
  309. // compute the cuts
  310. clk = Abc_Clock();
  311. if ( !Lpk_NodeCuts( p ) )
  312. {
  313. p->timeCuts += Abc_Clock() - clk;
  314. return 0;
  315. }
  316. p->timeCuts += Abc_Clock() - clk;
  317. if ( p->pPars->fVeryVerbose )
  318. printf( "Node %5d : Mffc size = %5d. Cuts = %5d. Level = %2d. Req = %2d.\n",
  319. p->pObj->Id, p->nMffc, p->nEvals, p->pObj->Level, Required );
  320. // try the good cuts
  321. p->nCutsTotal += p->nCuts;
  322. p->nCutsUseful += p->nEvals;
  323. for ( i = 0; i < p->nEvals; i++ )
  324. {
  325. // get the cut
  326. pCut = p->pCuts + p->pEvals[i];
  327. if ( p->pPars->fFirst && i == 1 )
  328. break;
  329. // if ( pCut->Weight < 1.05 )
  330. // continue;
  331. // skip bad cuts
  332. // printf( "Mffc size = %d. ", Abc_NodeMffcLabel(p->pObj) );
  333. for ( k = 0; k < (int)pCut->nLeaves; k++ )
  334. Abc_NtkObj(p->pNtk, pCut->pLeaves[k])->vFanouts.nSize++;
  335. nCutNodes = Abc_NodeMffcLabel(p->pObj);
  336. // printf( "Mffc with cut = %d. ", nCutNodes );
  337. for ( k = 0; k < (int)pCut->nLeaves; k++ )
  338. Abc_NtkObj(p->pNtk, pCut->pLeaves[k])->vFanouts.nSize--;
  339. // printf( "Mffc cut = %d. ", (int)pCut->nNodes - (int)pCut->nNodesDup );
  340. // printf( "\n" );
  341. if ( nCutNodes != (int)pCut->nNodes - (int)pCut->nNodesDup )
  342. continue;
  343. // collect nodes into the array
  344. Vec_PtrClear( p->vLeaves );
  345. for ( k = 0; k < (int)pCut->nLeaves; k++ )
  346. Vec_PtrPush( p->vLeaves, Abc_NtkObj(p->pNtk, pCut->pLeaves[k]) );
  347. // compute the truth table
  348. clk = Abc_Clock();
  349. pTruth = Lpk_CutTruth( p, pCut, 0 );
  350. p->timeTruth += Abc_Clock() - clk;
  351. clk = Abc_Clock();
  352. Lpk_ComputeSupports( p, pCut, pTruth );
  353. p->timeSupps += Abc_Clock() - clk;
  354. //clk = Abc_Clock();
  355. // pFun1 = Lpk_CutTruthBdd( p, pCut );
  356. //p->timeTruth2 += Abc_Clock() - clk;
  357. /*
  358. clk = Abc_Clock();
  359. Cloud_Restart( p->pDsdMan->dd );
  360. pFun2 = Kit_TruthToCloud( p->pDsdMan->dd, pTruth, pCut->nLeaves );
  361. RetValue = Kit_CreateCloud( p->pDsdMan->dd, pFun2, p->vBddNodes );
  362. p->timeTruth3 += Abc_Clock() - clk;
  363. */
  364. // if ( pFun1 != pFun2 )
  365. // printf( "Truth tables do not agree!\n" );
  366. // else
  367. // printf( "Fine!\n" );
  368. if ( p->pPars->fVeryVerbose )
  369. {
  370. // char * pFileName;
  371. int nSuppSize = Extra_TruthSupportSize( pTruth, pCut->nLeaves );
  372. printf( " C%02d: L= %2d/%2d V= %2d/%d N= %d W= %4.2f ",
  373. i, pCut->nLeaves, nSuppSize, pCut->nNodes, pCut->nNodesDup, pCut->nLuts, pCut->Weight );
  374. Vec_PtrForEachEntry( Abc_Obj_t *, p->vLeaves, pLeaf, k )
  375. printf( "%c=%d ", 'a'+k, Abc_ObjLevel(pLeaf) );
  376. printf( "\n" );
  377. Kit_DsdPrintFromTruth( pTruth, pCut->nLeaves );
  378. // pFileName = Kit_TruthDumpToFile( pTruth, pCut->nLeaves, Count++ );
  379. // printf( "Saved truth table in file \"%s\".\n", pFileName );
  380. }
  381. // update the network
  382. nNodesBef = Abc_NtkNodeNum(p->pNtk);
  383. clk = Abc_Clock();
  384. pObjNew = Lpk_Decompose( p, p->pNtk, p->vLeaves, pTruth, p->puSupps, p->pPars->nLutSize,
  385. (int)pCut->nNodes - (int)pCut->nNodesDup - 1 + (int)(p->pPars->fZeroCost > 0), Required );
  386. p->timeEval += Abc_Clock() - clk;
  387. nNodesAft = Abc_NtkNodeNum(p->pNtk);
  388. // perform replacement
  389. if ( pObjNew )
  390. {
  391. int nGain = (int)pCut->nNodes - (int)pCut->nNodesDup - (nNodesAft - nNodesBef);
  392. assert( nGain >= 1 - p->pPars->fZeroCost );
  393. assert( Abc_ObjLevel(pObjNew) <= Required );
  394. /*
  395. if ( nGain <= 0 )
  396. {
  397. int x = 0;
  398. }
  399. if ( Abc_ObjLevel(pObjNew) > Required )
  400. {
  401. int x = 0;
  402. }
  403. */
  404. p->nGainTotal += nGain;
  405. p->nChanges++;
  406. if ( p->pPars->fVeryVerbose )
  407. printf( "Performed resynthesis: Gain = %2d. Level = %2d. Req = %2d.\n", nGain, Abc_ObjLevel(pObjNew), Required );
  408. Abc_NtkUpdate( p->pObj, pObjNew, p->vLevels );
  409. //printf( "%3d : %d-%d=%d(%d) \n", p->nChanges, nNodesBef, Abc_NtkNodeNum(p->pNtk), nNodesBef-Abc_NtkNodeNum(p->pNtk), nGain );
  410. break;
  411. }
  412. }
  413. return 1;
  414. }
  415. /**Function*************************************************************
  416. Synopsis [Performs resynthesis for one network.]
  417. Description []
  418. SideEffects []
  419. SeeAlso []
  420. ***********************************************************************/
  421. int Lpk_Resynthesize( Abc_Ntk_t * pNtk, Lpk_Par_t * pPars )
  422. {
  423. ProgressBar * pProgress = NULL; // Suppress "might be used uninitialized"
  424. Lpk_Man_t * p;
  425. Abc_Obj_t * pObj;
  426. double Delta;
  427. // int * pnFanouts, nObjMax;
  428. int i, Iter, nNodes, nNodesPrev;
  429. abctime clk = Abc_Clock();
  430. assert( Abc_NtkIsLogic(pNtk) );
  431. // sweep dangling nodes as a preprocessing step
  432. Abc_NtkSweep( pNtk, 0 );
  433. // get the number of inputs
  434. if ( Abc_FrameReadLibLut() )
  435. pPars->nLutSize = ((If_LibLut_t *)Abc_FrameReadLibLut())->LutMax;
  436. else
  437. pPars->nLutSize = Abc_NtkGetFaninMax( pNtk );
  438. if ( pPars->nLutSize > 6 )
  439. pPars->nLutSize = 6;
  440. if ( pPars->nLutSize < 3 )
  441. pPars->nLutSize = 3;
  442. // adjust the number of crossbars based on LUT size
  443. if ( pPars->nVarsShared > pPars->nLutSize - 2 )
  444. pPars->nVarsShared = pPars->nLutSize - 2;
  445. // get the max number of LUTs tried
  446. pPars->nVarsMax = pPars->nLutsMax * (pPars->nLutSize - 1) + 1; // V = N * (K-1) + 1
  447. while ( pPars->nVarsMax > 16 )
  448. {
  449. pPars->nLutsMax--;
  450. pPars->nVarsMax = pPars->nLutsMax * (pPars->nLutSize - 1) + 1;
  451. }
  452. if ( pPars->fVerbose )
  453. {
  454. printf( "Resynthesis for %d %d-LUTs with %d non-MFFC LUTs, %d crossbars, and %d-input cuts.\n",
  455. pPars->nLutsMax, pPars->nLutSize, pPars->nLutsOver, pPars->nVarsShared, pPars->nVarsMax );
  456. }
  457. // convert into the AIG
  458. if ( !Abc_NtkToAig(pNtk) )
  459. {
  460. fprintf( stdout, "Converting to BDD has failed.\n" );
  461. return 0;
  462. }
  463. assert( Abc_NtkHasAig(pNtk) );
  464. // set the number of levels
  465. Abc_NtkLevel( pNtk );
  466. Abc_NtkStartReverseLevels( pNtk, pPars->nGrowthLevel );
  467. // start the manager
  468. p = Lpk_ManStart( pPars );
  469. p->pNtk = pNtk;
  470. p->nNodesTotal = Abc_NtkNodeNum(pNtk);
  471. p->vLevels = Vec_VecStart( pNtk->LevelMax );
  472. if ( p->pPars->fSatur )
  473. p->vVisited = Vec_VecStart( 0 );
  474. if ( pPars->fVerbose )
  475. {
  476. p->nTotalNets = Abc_NtkGetTotalFanins(pNtk);
  477. p->nTotalNodes = Abc_NtkNodeNum(pNtk);
  478. }
  479. /*
  480. // save the number of fanouts of all objects
  481. nObjMax = Abc_NtkObjNumMax( pNtk );
  482. pnFanouts = ABC_ALLOC( int, nObjMax );
  483. memset( pnFanouts, 0, sizeof(int) * nObjMax );
  484. Abc_NtkForEachObj( pNtk, pObj, i )
  485. pnFanouts[pObj->Id] = Abc_ObjFanoutNum(pObj);
  486. */
  487. // iterate over the network
  488. nNodesPrev = p->nNodesTotal;
  489. for ( Iter = 1; ; Iter++ )
  490. {
  491. // expand storage for changed nodes
  492. if ( p->pPars->fSatur )
  493. Vec_VecExpand( p->vVisited, Abc_NtkObjNumMax(pNtk) + 1 );
  494. // consider all nodes
  495. nNodes = Abc_NtkObjNumMax(pNtk);
  496. if ( !pPars->fVeryVerbose )
  497. pProgress = Extra_ProgressBarStart( stdout, nNodes );
  498. Abc_NtkForEachNode( pNtk, pObj, i )
  499. {
  500. // skip all except the final node
  501. if ( pPars->fFirst )
  502. {
  503. if ( !Abc_ObjIsCo(Abc_ObjFanout0(pObj)) )
  504. continue;
  505. }
  506. if ( i >= nNodes )
  507. break;
  508. if ( !pPars->fVeryVerbose )
  509. Extra_ProgressBarUpdate( pProgress, i, NULL );
  510. // skip the nodes that did not change
  511. if ( p->pPars->fSatur && !Lpk_NodeHasChanged(p, pObj->Id) )
  512. continue;
  513. // resynthesize
  514. p->pObj = pObj;
  515. if ( p->pPars->fOldAlgo )
  516. Lpk_ResynthesizeNode( p );
  517. else
  518. Lpk_ResynthesizeNodeNew( p );
  519. }
  520. if ( !pPars->fVeryVerbose )
  521. Extra_ProgressBarStop( pProgress );
  522. // check the increase
  523. Delta = 100.00 * (nNodesPrev - Abc_NtkNodeNum(pNtk)) / p->nNodesTotal;
  524. if ( Delta < 0.05 )
  525. break;
  526. nNodesPrev = Abc_NtkNodeNum(pNtk);
  527. if ( !p->pPars->fSatur )
  528. break;
  529. if ( pPars->fFirst )
  530. break;
  531. }
  532. Abc_NtkStopReverseLevels( pNtk );
  533. /*
  534. // report the fanout changes
  535. Abc_NtkForEachObj( pNtk, pObj, i )
  536. {
  537. if ( i >= nObjMax )
  538. continue;
  539. if ( Abc_ObjFanoutNum(pObj) - pnFanouts[pObj->Id] == 0 )
  540. continue;
  541. printf( "%d ", Abc_ObjFanoutNum(pObj) - pnFanouts[pObj->Id] );
  542. }
  543. printf( "\n" );
  544. */
  545. if ( pPars->fVerbose )
  546. {
  547. // Cloud_PrintInfo( p->pDsdMan->dd );
  548. p->nTotalNets2 = Abc_NtkGetTotalFanins(pNtk);
  549. p->nTotalNodes2 = Abc_NtkNodeNum(pNtk);
  550. printf( "Node gain = %5d. (%.2f %%) ",
  551. p->nTotalNodes-p->nTotalNodes2, 100.0*(p->nTotalNodes-p->nTotalNodes2)/p->nTotalNodes );
  552. printf( "Edge gain = %5d. (%.2f %%) ",
  553. p->nTotalNets-p->nTotalNets2, 100.0*(p->nTotalNets-p->nTotalNets2)/p->nTotalNets );
  554. printf( "Muxes = %4d. Dsds = %4d.", p->nMuxes, p->nDsds );
  555. printf( "\n" );
  556. printf( "Nodes = %5d (%3d) Cuts = %5d (%4d) Changes = %5d Iter = %2d Benefit = %d.\n",
  557. p->nNodesTotal, p->nNodesOver, p->nCutsTotal, p->nCutsUseful, p->nChanges, Iter, p->nBenefited );
  558. printf( "Non-DSD:" );
  559. for ( i = 3; i <= pPars->nVarsMax; i++ )
  560. if ( p->nBlocks[i] )
  561. printf( " %d=%d", i, p->nBlocks[i] );
  562. printf( "\n" );
  563. p->timeTotal = Abc_Clock() - clk;
  564. p->timeEval = p->timeEval - p->timeMap;
  565. p->timeOther = p->timeTotal - p->timeCuts - p->timeTruth - p->timeEval - p->timeMap;
  566. ABC_PRTP( "Cuts ", p->timeCuts, p->timeTotal );
  567. ABC_PRTP( "Truth ", p->timeTruth, p->timeTotal );
  568. ABC_PRTP( "CSupps", p->timeSupps, p->timeTotal );
  569. ABC_PRTP( "Eval ", p->timeEval, p->timeTotal );
  570. ABC_PRTP( " MuxAn", p->timeEvalMuxAn, p->timeEval );
  571. ABC_PRTP( " MuxSp", p->timeEvalMuxSp, p->timeEval );
  572. ABC_PRTP( " DsdAn", p->timeEvalDsdAn, p->timeEval );
  573. ABC_PRTP( " DsdSp", p->timeEvalDsdSp, p->timeEval );
  574. ABC_PRTP( " Other", p->timeEval-p->timeEvalMuxAn-p->timeEvalMuxSp-p->timeEvalDsdAn-p->timeEvalDsdSp, p->timeEval );
  575. ABC_PRTP( "Map ", p->timeMap, p->timeTotal );
  576. ABC_PRTP( "Other ", p->timeOther, p->timeTotal );
  577. ABC_PRTP( "TOTAL ", p->timeTotal, p->timeTotal );
  578. }
  579. Lpk_ManStop( p );
  580. // check the resulting network
  581. if ( !Abc_NtkCheck( pNtk ) )
  582. {
  583. printf( "Lpk_Resynthesize: The network check has failed.\n" );
  584. return 0;
  585. }
  586. return 1;
  587. }
  588. ////////////////////////////////////////////////////////////////////////
  589. /// END OF FILE ///
  590. ////////////////////////////////////////////////////////////////////////
  591. ABC_NAMESPACE_IMPL_END