PageRenderTime 31ms CodeModel.GetById 31ms RepoModel.GetById 1ms app.codeStats 0ms

/src/base/io/ioWriteBlif.c

https://bitbucket.org/alanmi/abc/
C | 1410 lines | 919 code | 100 blank | 391 comment | 200 complexity | 3243c85058d3f48aead4d746e4eb1db3 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. /**CFile****************************************************************
  2. FileName [ioWriteBlif.c]
  3. SystemName [ABC: Logic synthesis and verification system.]
  4. PackageName [Command processing package.]
  5. Synopsis [Procedures to write BLIF files.]
  6. Author [Alan Mishchenko]
  7. Affiliation [UC Berkeley]
  8. Date [Ver. 1.0. Started - June 20, 2005.]
  9. Revision [$Id: ioWriteBlif.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
  10. ***********************************************************************/
  11. #include "ioAbc.h"
  12. #include "base/main/main.h"
  13. #include "map/mio/mio.h"
  14. #include "bool/kit/kit.h"
  15. #include "map/if/if.h"
  16. ABC_NAMESPACE_IMPL_START
  17. ////////////////////////////////////////////////////////////////////////
  18. /// DECLARATIONS ///
  19. ////////////////////////////////////////////////////////////////////////
  20. static void Io_NtkWrite( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches, int fBb2Wb, int fSeq );
  21. static void Io_NtkWriteOne( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches, int fBb2Wb, int fSeq );
  22. static void Io_NtkWritePis( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches );
  23. static void Io_NtkWritePos( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches );
  24. static void Io_NtkWriteSubckt( FILE * pFile, Abc_Obj_t * pNode );
  25. static void Io_NtkWriteAsserts( FILE * pFile, Abc_Ntk_t * pNtk );
  26. static void Io_NtkWriteNodeFanins( FILE * pFile, Abc_Obj_t * pNode );
  27. static int Io_NtkWriteNode( FILE * pFile, Abc_Obj_t * pNode, int Length );
  28. static void Io_NtkWriteLatch( FILE * pFile, Abc_Obj_t * pLatch );
  29. ////////////////////////////////////////////////////////////////////////
  30. /// FUNCTION DEFINITIONS ///
  31. ////////////////////////////////////////////////////////////////////////
  32. /**Function*************************************************************
  33. Synopsis [Write the network into a BLIF file with the given name.]
  34. Description []
  35. SideEffects []
  36. SeeAlso []
  37. ***********************************************************************/
  38. void Io_WriteBlifLogic( Abc_Ntk_t * pNtk, char * FileName, int fWriteLatches )
  39. {
  40. Abc_Ntk_t * pNtkTemp;
  41. // derive the netlist
  42. pNtkTemp = Abc_NtkToNetlist(pNtk);
  43. if ( pNtkTemp == NULL )
  44. {
  45. fprintf( stdout, "Writing BLIF has failed.\n" );
  46. return;
  47. }
  48. Io_WriteBlif( pNtkTemp, FileName, fWriteLatches, 0, 0 );
  49. Abc_NtkDelete( pNtkTemp );
  50. }
  51. /**Function*************************************************************
  52. Synopsis [Write the network into a BLIF file with the given name.]
  53. Description []
  54. SideEffects []
  55. SeeAlso []
  56. ***********************************************************************/
  57. void Io_WriteBlif( Abc_Ntk_t * pNtk, char * FileName, int fWriteLatches, int fBb2Wb, int fSeq )
  58. {
  59. FILE * pFile;
  60. Abc_Ntk_t * pNtkTemp;
  61. int i;
  62. assert( Abc_NtkIsNetlist(pNtk) );
  63. // start writing the file
  64. pFile = fopen( FileName, "w" );
  65. if ( pFile == NULL )
  66. {
  67. fprintf( stdout, "Io_WriteBlif(): Cannot open the output file.\n" );
  68. return;
  69. }
  70. fprintf( pFile, "# Benchmark \"%s\" written by ABC on %s\n", pNtk->pName, Extra_TimeStamp() );
  71. // write the master network
  72. Io_NtkWrite( pFile, pNtk, fWriteLatches, fBb2Wb, fSeq );
  73. // make sure there is no logic hierarchy
  74. // assert( Abc_NtkWhiteboxNum(pNtk) == 0 );
  75. // write the hierarchy if present
  76. if ( Abc_NtkBlackboxNum(pNtk) > 0 || Abc_NtkWhiteboxNum(pNtk) > 0 )
  77. {
  78. Vec_PtrForEachEntry( Abc_Ntk_t *, pNtk->pDesign->vModules, pNtkTemp, i )
  79. {
  80. if ( pNtkTemp == pNtk )
  81. continue;
  82. fprintf( pFile, "\n\n" );
  83. Io_NtkWrite( pFile, pNtkTemp, fWriteLatches, fBb2Wb, fSeq );
  84. }
  85. }
  86. fclose( pFile );
  87. }
  88. /**Function*************************************************************
  89. Synopsis [Write the network into a BLIF file with the given name.]
  90. Description []
  91. SideEffects []
  92. SeeAlso []
  93. ***********************************************************************/
  94. void Io_NtkWrite( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches, int fBb2Wb, int fSeq )
  95. {
  96. Abc_Ntk_t * pExdc;
  97. assert( Abc_NtkIsNetlist(pNtk) );
  98. // write the model name
  99. fprintf( pFile, ".model %s\n", Abc_NtkName(pNtk) );
  100. // write the network
  101. Io_NtkWriteOne( pFile, pNtk, fWriteLatches, fBb2Wb, fSeq );
  102. // write EXDC network if it exists
  103. pExdc = Abc_NtkExdc( pNtk );
  104. if ( pExdc )
  105. {
  106. fprintf( pFile, "\n" );
  107. fprintf( pFile, ".exdc\n" );
  108. Io_NtkWriteOne( pFile, pExdc, fWriteLatches, fBb2Wb, fSeq );
  109. }
  110. // finalize the file
  111. fprintf( pFile, ".end\n" );
  112. }
  113. /**Function*************************************************************
  114. Synopsis [Write one network.]
  115. Description []
  116. SideEffects []
  117. SeeAlso []
  118. ***********************************************************************/
  119. void Io_NtkWriteConvertedBox( FILE * pFile, Abc_Ntk_t * pNtk, int fSeq )
  120. {
  121. Abc_Obj_t * pObj;
  122. int i, v;
  123. if ( fSeq )
  124. {
  125. fprintf( pFile, ".attrib white box seq\n" );
  126. }
  127. else
  128. {
  129. fprintf( pFile, ".attrib white box comb\n" );
  130. fprintf( pFile, ".delay 1\n" );
  131. }
  132. Abc_NtkForEachPo( pNtk, pObj, i )
  133. {
  134. // write the .names line
  135. fprintf( pFile, ".names" );
  136. Io_NtkWritePis( pFile, pNtk, 1 );
  137. if ( fSeq )
  138. fprintf( pFile, " %s_in\n", Abc_ObjName(Abc_ObjFanin0(pObj)) );
  139. else
  140. fprintf( pFile, " %s\n", Abc_ObjName(Abc_ObjFanin0(pObj)) );
  141. for ( v = 0; v < Abc_NtkPiNum(pNtk); v++ )
  142. fprintf( pFile, "1" );
  143. fprintf( pFile, " 1\n" );
  144. if ( fSeq )
  145. fprintf( pFile, ".latch %s_in %s 1\n", Abc_ObjName(Abc_ObjFanin0(pObj)), Abc_ObjName(Abc_ObjFanin0(pObj)) );
  146. }
  147. }
  148. /**Function*************************************************************
  149. Synopsis [Write one network.]
  150. Description []
  151. SideEffects []
  152. SeeAlso []
  153. ***********************************************************************/
  154. void Io_NtkWriteOne( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches, int fBb2Wb, int fSeq )
  155. {
  156. ProgressBar * pProgress;
  157. Abc_Obj_t * pNode, * pLatch;
  158. int i, Length;
  159. // write the PIs
  160. fprintf( pFile, ".inputs" );
  161. Io_NtkWritePis( pFile, pNtk, fWriteLatches );
  162. fprintf( pFile, "\n" );
  163. // write the POs
  164. fprintf( pFile, ".outputs" );
  165. Io_NtkWritePos( pFile, pNtk, fWriteLatches );
  166. fprintf( pFile, "\n" );
  167. // write the blackbox
  168. if ( Abc_NtkHasBlackbox( pNtk ) )
  169. {
  170. if ( fBb2Wb )
  171. Io_NtkWriteConvertedBox( pFile, pNtk, fSeq );
  172. else
  173. fprintf( pFile, ".blackbox\n" );
  174. return;
  175. }
  176. // write the timing info
  177. Io_WriteTimingInfo( pFile, pNtk );
  178. // write the latches
  179. if ( fWriteLatches && !Abc_NtkIsComb(pNtk) )
  180. {
  181. fprintf( pFile, "\n" );
  182. Abc_NtkForEachLatch( pNtk, pLatch, i )
  183. Io_NtkWriteLatch( pFile, pLatch );
  184. fprintf( pFile, "\n" );
  185. }
  186. // write the subcircuits
  187. // assert( Abc_NtkWhiteboxNum(pNtk) == 0 );
  188. if ( Abc_NtkBlackboxNum(pNtk) > 0 || Abc_NtkWhiteboxNum(pNtk) > 0 )
  189. {
  190. fprintf( pFile, "\n" );
  191. Abc_NtkForEachBlackbox( pNtk, pNode, i )
  192. Io_NtkWriteSubckt( pFile, pNode );
  193. fprintf( pFile, "\n" );
  194. Abc_NtkForEachWhitebox( pNtk, pNode, i )
  195. Io_NtkWriteSubckt( pFile, pNode );
  196. fprintf( pFile, "\n" );
  197. }
  198. // write each internal node
  199. Length = Abc_NtkHasMapping(pNtk)? Mio_LibraryReadGateNameMax((Mio_Library_t *)pNtk->pManFunc) : 0;
  200. pProgress = Extra_ProgressBarStart( stdout, Abc_NtkObjNumMax(pNtk) );
  201. Abc_NtkForEachNode( pNtk, pNode, i )
  202. {
  203. Extra_ProgressBarUpdate( pProgress, i, NULL );
  204. if ( Io_NtkWriteNode( pFile, pNode, Length ) ) // skip the next node
  205. i++;
  206. }
  207. Extra_ProgressBarStop( pProgress );
  208. }
  209. /**Function*************************************************************
  210. Synopsis [Writes the primary input list.]
  211. Description []
  212. SideEffects []
  213. SeeAlso []
  214. ***********************************************************************/
  215. void Io_NtkWritePis( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches )
  216. {
  217. Abc_Obj_t * pTerm, * pNet;
  218. int LineLength;
  219. int AddedLength;
  220. int NameCounter;
  221. int i;
  222. LineLength = 7;
  223. NameCounter = 0;
  224. if ( fWriteLatches )
  225. {
  226. Abc_NtkForEachPi( pNtk, pTerm, i )
  227. {
  228. pNet = Abc_ObjFanout0(pTerm);
  229. // get the line length after this name is written
  230. AddedLength = strlen(Abc_ObjName(pNet)) + 1;
  231. if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
  232. { // write the line extender
  233. fprintf( pFile, " \\\n" );
  234. // reset the line length
  235. LineLength = 0;
  236. NameCounter = 0;
  237. }
  238. fprintf( pFile, " %s", Abc_ObjName(pNet) );
  239. LineLength += AddedLength;
  240. NameCounter++;
  241. }
  242. }
  243. else
  244. {
  245. Abc_NtkForEachCi( pNtk, pTerm, i )
  246. {
  247. pNet = Abc_ObjFanout0(pTerm);
  248. // get the line length after this name is written
  249. AddedLength = strlen(Abc_ObjName(pNet)) + 1;
  250. if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
  251. { // write the line extender
  252. fprintf( pFile, " \\\n" );
  253. // reset the line length
  254. LineLength = 0;
  255. NameCounter = 0;
  256. }
  257. fprintf( pFile, " %s", Abc_ObjName(pNet) );
  258. LineLength += AddedLength;
  259. NameCounter++;
  260. }
  261. }
  262. }
  263. /**Function*************************************************************
  264. Synopsis [Writes the primary input list.]
  265. Description []
  266. SideEffects []
  267. SeeAlso []
  268. ***********************************************************************/
  269. void Io_NtkWritePos( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches )
  270. {
  271. Abc_Obj_t * pTerm, * pNet;
  272. int LineLength;
  273. int AddedLength;
  274. int NameCounter;
  275. int i;
  276. LineLength = 8;
  277. NameCounter = 0;
  278. if ( fWriteLatches )
  279. {
  280. Abc_NtkForEachPo( pNtk, pTerm, i )
  281. {
  282. pNet = Abc_ObjFanin0(pTerm);
  283. // get the line length after this name is written
  284. AddedLength = strlen(Abc_ObjName(pNet)) + 1;
  285. if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
  286. { // write the line extender
  287. fprintf( pFile, " \\\n" );
  288. // reset the line length
  289. LineLength = 0;
  290. NameCounter = 0;
  291. }
  292. fprintf( pFile, " %s", Abc_ObjName(pNet) );
  293. LineLength += AddedLength;
  294. NameCounter++;
  295. }
  296. }
  297. else
  298. {
  299. Abc_NtkForEachCo( pNtk, pTerm, i )
  300. {
  301. pNet = Abc_ObjFanin0(pTerm);
  302. // get the line length after this name is written
  303. AddedLength = strlen(Abc_ObjName(pNet)) + 1;
  304. if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
  305. { // write the line extender
  306. fprintf( pFile, " \\\n" );
  307. // reset the line length
  308. LineLength = 0;
  309. NameCounter = 0;
  310. }
  311. fprintf( pFile, " %s", Abc_ObjName(pNet) );
  312. LineLength += AddedLength;
  313. NameCounter++;
  314. }
  315. }
  316. }
  317. /**Function*************************************************************
  318. Synopsis [Write the latch into a file.]
  319. Description []
  320. SideEffects []
  321. SeeAlso []
  322. ***********************************************************************/
  323. void Io_NtkWriteSubckt( FILE * pFile, Abc_Obj_t * pNode )
  324. {
  325. Abc_Ntk_t * pModel = (Abc_Ntk_t *)pNode->pData;
  326. Abc_Obj_t * pTerm;
  327. int i;
  328. // write the subcircuit
  329. // fprintf( pFile, ".subckt %s %s", Abc_NtkName(pModel), Abc_ObjName(pNode) );
  330. fprintf( pFile, ".subckt %s", Abc_NtkName(pModel) );
  331. // write pairs of the formal=actual names
  332. Abc_NtkForEachPi( pModel, pTerm, i )
  333. {
  334. fprintf( pFile, " %s", Abc_ObjName(Abc_ObjFanout0(pTerm)) );
  335. pTerm = Abc_ObjFanin( pNode, i );
  336. fprintf( pFile, "=%s", Abc_ObjName(Abc_ObjFanin0(pTerm)) );
  337. }
  338. Abc_NtkForEachPo( pModel, pTerm, i )
  339. {
  340. fprintf( pFile, " %s", Abc_ObjName(Abc_ObjFanin0(pTerm)) );
  341. pTerm = Abc_ObjFanout( pNode, i );
  342. fprintf( pFile, "=%s", Abc_ObjName(Abc_ObjFanout0(pTerm)) );
  343. }
  344. fprintf( pFile, "\n" );
  345. }
  346. /**Function*************************************************************
  347. Synopsis [Write the latch into a file.]
  348. Description []
  349. SideEffects []
  350. SeeAlso []
  351. ***********************************************************************/
  352. void Io_NtkWriteLatch( FILE * pFile, Abc_Obj_t * pLatch )
  353. {
  354. Abc_Obj_t * pNetLi, * pNetLo;
  355. int Reset;
  356. pNetLi = Abc_ObjFanin0( Abc_ObjFanin0(pLatch) );
  357. pNetLo = Abc_ObjFanout0( Abc_ObjFanout0(pLatch) );
  358. Reset = (int)(ABC_PTRUINT_T)Abc_ObjData( pLatch );
  359. // write the latch line
  360. fprintf( pFile, ".latch" );
  361. fprintf( pFile, " %10s", Abc_ObjName(pNetLi) );
  362. fprintf( pFile, " %10s", Abc_ObjName(pNetLo) );
  363. fprintf( pFile, " %d\n", Reset-1 );
  364. }
  365. /**Function*************************************************************
  366. Synopsis [Writes the primary input list.]
  367. Description []
  368. SideEffects []
  369. SeeAlso []
  370. ***********************************************************************/
  371. void Io_NtkWriteNodeFanins( FILE * pFile, Abc_Obj_t * pNode )
  372. {
  373. Abc_Obj_t * pNet;
  374. int LineLength;
  375. int AddedLength;
  376. int NameCounter;
  377. char * pName;
  378. int i;
  379. LineLength = 6;
  380. NameCounter = 0;
  381. Abc_ObjForEachFanin( pNode, pNet, i )
  382. {
  383. // get the fanin name
  384. pName = Abc_ObjName(pNet);
  385. // get the line length after the fanin name is written
  386. AddedLength = strlen(pName) + 1;
  387. if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
  388. { // write the line extender
  389. fprintf( pFile, " \\\n" );
  390. // reset the line length
  391. LineLength = 0;
  392. NameCounter = 0;
  393. }
  394. fprintf( pFile, " %s", pName );
  395. LineLength += AddedLength;
  396. NameCounter++;
  397. }
  398. // get the output name
  399. pName = Abc_ObjName(Abc_ObjFanout0(pNode));
  400. // get the line length after the output name is written
  401. AddedLength = strlen(pName) + 1;
  402. if ( NameCounter && LineLength + AddedLength > 75 )
  403. { // write the line extender
  404. fprintf( pFile, " \\\n" );
  405. // reset the line length
  406. LineLength = 0;
  407. NameCounter = 0;
  408. }
  409. fprintf( pFile, " %s", pName );
  410. }
  411. /**Function*************************************************************
  412. Synopsis [Writes the primary input list.]
  413. Description []
  414. SideEffects []
  415. SeeAlso []
  416. ***********************************************************************/
  417. void Io_NtkWriteSubcktFanins( FILE * pFile, Abc_Obj_t * pNode )
  418. {
  419. Abc_Obj_t * pNet;
  420. int LineLength;
  421. int AddedLength;
  422. int NameCounter;
  423. char * pName;
  424. int i;
  425. LineLength = 6;
  426. NameCounter = 0;
  427. // get the output name
  428. pName = Abc_ObjName(Abc_ObjFanout0(pNode));
  429. // get the line length after the output name is written
  430. AddedLength = strlen(pName) + 1;
  431. fprintf( pFile, " m%d", Abc_ObjId(pNode) );
  432. // get the input names
  433. Abc_ObjForEachFanin( pNode, pNet, i )
  434. {
  435. // get the fanin name
  436. pName = Abc_ObjName(pNet);
  437. // get the line length after the fanin name is written
  438. AddedLength = strlen(pName) + 3;
  439. if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
  440. { // write the line extender
  441. fprintf( pFile, " \\\n" );
  442. // reset the line length
  443. LineLength = 0;
  444. NameCounter = 0;
  445. }
  446. fprintf( pFile, " %c=%s", 'a'+i, pName );
  447. LineLength += AddedLength;
  448. NameCounter++;
  449. }
  450. // get the output name
  451. pName = Abc_ObjName(Abc_ObjFanout0(pNode));
  452. // get the line length after the output name is written
  453. AddedLength = strlen(pName) + 3;
  454. if ( NameCounter && LineLength + AddedLength > 75 )
  455. { // write the line extender
  456. fprintf( pFile, " \\\n" );
  457. // reset the line length
  458. LineLength = 0;
  459. NameCounter = 0;
  460. }
  461. fprintf( pFile, " %c=%s", 'o', pName );
  462. }
  463. /**Function*************************************************************
  464. Synopsis [Writes the primary input list.]
  465. Description []
  466. SideEffects []
  467. SeeAlso []
  468. ***********************************************************************/
  469. int Io_NtkWriteNodeGate( FILE * pFile, Abc_Obj_t * pNode, int Length )
  470. {
  471. static int fReport = 0;
  472. Mio_Gate_t * pGate = (Mio_Gate_t *)pNode->pData;
  473. Mio_Pin_t * pGatePin;
  474. Abc_Obj_t * pNode2;
  475. int i;
  476. fprintf( pFile, " %-*s ", Length, Mio_GateReadName(pGate) );
  477. for ( pGatePin = Mio_GateReadPins(pGate), i = 0; pGatePin; pGatePin = Mio_PinReadNext(pGatePin), i++ )
  478. fprintf( pFile, "%s=%s ", Mio_PinReadName(pGatePin), Abc_ObjName( Abc_ObjFanin(pNode,i) ) );
  479. assert ( i == Abc_ObjFaninNum(pNode) );
  480. fprintf( pFile, "%s=%s", Mio_GateReadOutName(pGate), Abc_ObjName( Abc_ObjFanout0(pNode) ) );
  481. if ( Mio_GateReadTwin(pGate) == NULL )
  482. return 0;
  483. pNode2 = Abc_NtkFetchTwinNode( pNode );
  484. if ( pNode2 == NULL )
  485. {
  486. if ( !fReport )
  487. fReport = 1, printf( "Warning: Missing second output of gate(s) \"%s\".\n", Mio_GateReadName(pGate) );
  488. return 0;
  489. }
  490. fprintf( pFile, " %s=%s", Mio_GateReadOutName((Mio_Gate_t *)pNode2->pData), Abc_ObjName( Abc_ObjFanout0(pNode2) ) );
  491. return 1;
  492. }
  493. /**Function*************************************************************
  494. Synopsis [Write the node into a file.]
  495. Description []
  496. SideEffects []
  497. SeeAlso []
  498. ***********************************************************************/
  499. int Io_NtkWriteNode( FILE * pFile, Abc_Obj_t * pNode, int Length )
  500. {
  501. int RetValue = 0;
  502. if ( Abc_NtkHasMapping(pNode->pNtk) )
  503. {
  504. // write the .gate line
  505. if ( Abc_ObjIsBarBuf(pNode) )
  506. {
  507. fprintf( pFile, ".barbuf " );
  508. fprintf( pFile, "%s %s", Abc_ObjName(Abc_ObjFanin0(pNode)), Abc_ObjName(Abc_ObjFanout0(pNode)) );
  509. fprintf( pFile, "\n" );
  510. }
  511. else
  512. {
  513. fprintf( pFile, ".gate" );
  514. RetValue = Io_NtkWriteNodeGate( pFile, pNode, Length );
  515. fprintf( pFile, "\n" );
  516. }
  517. }
  518. else
  519. {
  520. // write the .names line
  521. fprintf( pFile, ".names" );
  522. Io_NtkWriteNodeFanins( pFile, pNode );
  523. fprintf( pFile, "\n" );
  524. // write the cubes
  525. fprintf( pFile, "%s", (char*)Abc_ObjData(pNode) );
  526. }
  527. return RetValue;
  528. }
  529. /**Function*************************************************************
  530. Synopsis [Write the node into a file.]
  531. Description []
  532. SideEffects []
  533. SeeAlso []
  534. ***********************************************************************/
  535. int Io_NtkWriteNodeSubckt( FILE * pFile, Abc_Obj_t * pNode, int Length )
  536. {
  537. int RetValue = 0;
  538. fprintf( pFile, ".subckt" );
  539. Io_NtkWriteSubcktFanins( pFile, pNode );
  540. fprintf( pFile, "\n" );
  541. return RetValue;
  542. }
  543. /**Function*************************************************************
  544. Synopsis [Writes the timing info.]
  545. Description []
  546. SideEffects []
  547. SeeAlso []
  548. ***********************************************************************/
  549. void Io_WriteTimingInfo( FILE * pFile, Abc_Ntk_t * pNtk )
  550. {
  551. Abc_Obj_t * pNode;
  552. Abc_Time_t * pTime, * pTimeDefIn, * pTimeDefOut;
  553. int i;
  554. if ( pNtk->pManTime == NULL )
  555. return;
  556. fprintf( pFile, "\n" );
  557. if ( pNtk->AndGateDelay != 0.0 )
  558. fprintf( pFile, ".and_gate_delay %g\n", pNtk->AndGateDelay );
  559. pTimeDefIn = Abc_NtkReadDefaultArrival( pNtk );
  560. //if ( pTimeDefIn->Rise != 0.0 || pTimeDefIn->Fall != 0.0 )
  561. fprintf( pFile, ".default_input_arrival %g %g\n", pTimeDefIn->Rise, pTimeDefIn->Fall );
  562. pTimeDefOut = Abc_NtkReadDefaultRequired( pNtk );
  563. //if ( pTimeDefOut->Rise != ABC_INFINITY || pTimeDefOut->Fall != ABC_INFINITY )
  564. fprintf( pFile, ".default_output_required %g %g\n", pTimeDefOut->Rise, pTimeDefOut->Fall );
  565. fprintf( pFile, "\n" );
  566. Abc_NtkForEachPi( pNtk, pNode, i )
  567. {
  568. pTime = Abc_NodeReadArrival(pNode);
  569. if ( pTime->Rise == pTimeDefIn->Rise && pTime->Fall == pTimeDefIn->Fall )
  570. continue;
  571. fprintf( pFile, ".input_arrival %s %g %g\n", Abc_ObjName(Abc_ObjFanout0(pNode)), pTime->Rise, pTime->Fall );
  572. }
  573. Abc_NtkForEachPo( pNtk, pNode, i )
  574. {
  575. pTime = Abc_NodeReadRequired(pNode);
  576. if ( pTime->Rise == pTimeDefOut->Rise && pTime->Fall == pTimeDefOut->Fall )
  577. continue;
  578. fprintf( pFile, ".output_required %s %g %g\n", Abc_ObjName(Abc_ObjFanin0(pNode)), pTime->Rise, pTime->Fall );
  579. }
  580. fprintf( pFile, "\n" );
  581. pTimeDefIn = Abc_NtkReadDefaultInputDrive( pNtk );
  582. if ( pTimeDefIn->Rise != 0.0 || pTimeDefIn->Fall != 0.0 )
  583. fprintf( pFile, ".default_input_drive %g %g\n", pTimeDefIn->Rise, pTimeDefIn->Fall );
  584. if ( Abc_NodeReadInputDrive( pNtk, 0 ) )
  585. Abc_NtkForEachPi( pNtk, pNode, i )
  586. {
  587. pTime = Abc_NodeReadInputDrive( pNtk, i );
  588. if ( pTime->Rise == pTimeDefIn->Rise && pTime->Fall == pTimeDefIn->Fall )
  589. continue;
  590. fprintf( pFile, ".input_drive %s %g %g\n", Abc_ObjName(Abc_ObjFanout0(pNode)), pTime->Rise, pTime->Fall );
  591. }
  592. pTimeDefOut = Abc_NtkReadDefaultOutputLoad( pNtk );
  593. if ( pTimeDefOut->Rise != 0.0 || pTimeDefOut->Fall != 0.0 )
  594. fprintf( pFile, ".default_output_load %g %g\n", pTimeDefOut->Rise, pTimeDefOut->Fall );
  595. if ( Abc_NodeReadOutputLoad( pNtk, 0 ) )
  596. Abc_NtkForEachPo( pNtk, pNode, i )
  597. {
  598. pTime = Abc_NodeReadOutputLoad( pNtk, i );
  599. if ( pTime->Rise == pTimeDefOut->Rise && pTime->Fall == pTimeDefOut->Fall )
  600. continue;
  601. fprintf( pFile, ".output_load %s %g %g\n", Abc_ObjName(Abc_ObjFanin0(pNode)), pTime->Rise, pTime->Fall );
  602. }
  603. fprintf( pFile, "\n" );
  604. }
  605. /**Function*************************************************************
  606. Synopsis []
  607. Description []
  608. SideEffects []
  609. SeeAlso []
  610. ***********************************************************************/
  611. void Abc_NtkConvertBb2Wb( char * pFileNameIn, char * pFileNameOut, int fSeq, int fVerbose )
  612. {
  613. FILE * pFile;
  614. Abc_Ntk_t * pNetlist;
  615. // check the files
  616. pFile = fopen( pFileNameIn, "rb" );
  617. if ( pFile == NULL )
  618. {
  619. printf( "Input file \"%s\" cannot be opened.\n", pFileNameIn );
  620. return;
  621. }
  622. fclose( pFile );
  623. // check the files
  624. pFile = fopen( pFileNameOut, "wb" );
  625. if ( pFile == NULL )
  626. {
  627. printf( "Output file \"%s\" cannot be opened.\n", pFileNameOut );
  628. return;
  629. }
  630. fclose( pFile );
  631. // derive AIG for signal correspondence
  632. pNetlist = Io_ReadNetlist( pFileNameIn, Io_ReadFileType(pFileNameIn), 1 );
  633. if ( pNetlist == NULL )
  634. {
  635. printf( "Reading input file \"%s\" has failed.\n", pFileNameIn );
  636. return;
  637. }
  638. Io_WriteBlif( pNetlist, pFileNameOut, 1, 1, fSeq );
  639. Abc_NtkDelete( pNetlist );
  640. }
  641. /**Function*************************************************************
  642. Synopsis [Transforms truth table into an SOP.]
  643. Description []
  644. SideEffects []
  645. SeeAlso []
  646. ***********************************************************************/
  647. char * Io_NtkDeriveSop( Mem_Flex_t * pMem, word uTruth, int nVars, Vec_Int_t * vCover )
  648. {
  649. char * pSop;
  650. int RetValue = Kit_TruthIsop( (unsigned *)&uTruth, nVars, vCover, 1 );
  651. assert( RetValue == 0 || RetValue == 1 );
  652. // check the case of constant cover
  653. if ( Vec_IntSize(vCover) == 0 || (Vec_IntSize(vCover) == 1 && Vec_IntEntry(vCover,0) == 0) )
  654. {
  655. char * pStr0 = " 0\n", * pStr1 = " 1\n";
  656. assert( RetValue == 0 );
  657. return Vec_IntSize(vCover) == 0 ? pStr0 : pStr1;
  658. }
  659. // derive the AIG for that tree
  660. pSop = Abc_SopCreateFromIsop( pMem, nVars, vCover );
  661. if ( RetValue )
  662. Abc_SopComplement( pSop );
  663. return pSop;
  664. }
  665. /**Function*************************************************************
  666. Synopsis [Write the node into a file.]
  667. Description []
  668. SideEffects []
  669. SeeAlso []
  670. ***********************************************************************/
  671. void Io_NtkWriteNodeInt( FILE * pFile, Abc_Obj_t * pNode, Vec_Int_t * vCover )
  672. {
  673. Abc_Obj_t * pNet;
  674. int i, nVars = Abc_ObjFaninNum(pNode);
  675. if ( nVars > 7 )
  676. {
  677. printf( "Node \"%s\" has more than 7 inputs. Writing BLIF has failed.\n", Abc_ObjName(Abc_ObjFanout0(pNode)) );
  678. return;
  679. }
  680. fprintf( pFile, "\n" );
  681. if ( nVars <= 4 )
  682. {
  683. // write the .names line
  684. fprintf( pFile, ".names" );
  685. Abc_ObjForEachFanin( pNode, pNet, i )
  686. fprintf( pFile, " %s", Abc_ObjName(pNet) );
  687. // get the output name
  688. fprintf( pFile, " %s\n", Abc_ObjName(Abc_ObjFanout0(pNode)) );
  689. // write the cubes
  690. fprintf( pFile, "%s", (char*)Abc_ObjData(pNode) );
  691. }
  692. else
  693. {
  694. extern int If_Dec6PickBestMux( word t, word Cofs[2] );
  695. extern int If_Dec7PickBestMux( word t[2], word c0r[2], word c1r[2] );
  696. extern word If_Dec6MinimumBase( word uTruth, int * pSupp, int nVarsAll, int * pnVars );
  697. extern void If_Dec7MinimumBase( word uTruth[2], int * pSupp, int nVarsAll, int * pnVars );
  698. extern word If_Dec6Perform( word t, int fDerive );
  699. extern word If_Dec7Perform( word t[2], int fDerive );
  700. char * pSop;
  701. word z, uTruth6 = 0, uTruth7[2], Cofs6[2], Cofs7[2][2];
  702. int c, iVar, nVarsMin[2], pVars[2][10];
  703. // collect variables
  704. Abc_ObjForEachFanin( pNode, pNet, i )
  705. pVars[0][i] = pVars[1][i] = i;
  706. // derive truth table
  707. if ( nVars == 7 )
  708. {
  709. Abc_SopToTruth7( (char*)Abc_ObjData(pNode), nVars, uTruth7 );
  710. iVar = If_Dec7PickBestMux( uTruth7, Cofs7[0], Cofs7[1] );
  711. }
  712. else
  713. {
  714. uTruth6 = Abc_SopToTruth( (char*)Abc_ObjData(pNode), nVars );
  715. iVar = If_Dec6PickBestMux( uTruth6, Cofs6 );
  716. }
  717. // perform MUX decomposition
  718. if ( iVar >= 0 )
  719. {
  720. if ( nVars == 7 )
  721. {
  722. If_Dec7MinimumBase( Cofs7[0], pVars[0], nVars, &nVarsMin[0] );
  723. If_Dec7MinimumBase( Cofs7[1], pVars[1], nVars, &nVarsMin[1] );
  724. }
  725. else
  726. {
  727. Cofs6[0] = If_Dec6MinimumBase( Cofs6[0], pVars[0], nVars, &nVarsMin[0] );
  728. Cofs6[1] = If_Dec6MinimumBase( Cofs6[1], pVars[1], nVars, &nVarsMin[1] );
  729. }
  730. assert( nVarsMin[0] < 5 );
  731. assert( nVarsMin[1] < 5 );
  732. // write MUX
  733. fprintf( pFile, ".names" );
  734. fprintf( pFile, " %s", Abc_ObjName(Abc_ObjFanin(pNode,iVar)) );
  735. fprintf( pFile, " %s_cascade0", Abc_ObjName(Abc_ObjFanout0(pNode)) );
  736. fprintf( pFile, " %s_cascade1", Abc_ObjName(Abc_ObjFanout0(pNode)) );
  737. fprintf( pFile, " %s\n", Abc_ObjName(Abc_ObjFanout0(pNode)) );
  738. fprintf( pFile, "1-1 1\n01- 1\n" );
  739. // write cofactors
  740. for ( c = 0; c < 2; c++ )
  741. {
  742. pSop = Io_NtkDeriveSop( (Mem_Flex_t *)Abc_ObjNtk(pNode)->pManFunc,
  743. (word)(nVars == 7 ? Cofs7[c][0] : Cofs6[c]), nVarsMin[c], vCover );
  744. fprintf( pFile, ".names" );
  745. for ( i = 0; i < nVarsMin[c]; i++ )
  746. fprintf( pFile, " %s", Abc_ObjName(Abc_ObjFanin(pNode,pVars[c][i])) );
  747. fprintf( pFile, " %s_cascade%d\n", Abc_ObjName(Abc_ObjFanout0(pNode)), c );
  748. fprintf( pFile, "%s", pSop );
  749. }
  750. return;
  751. }
  752. assert( nVars == 6 || nVars == 7 );
  753. // try cascade decomposition
  754. if ( nVars == 7 )
  755. {
  756. z = If_Dec7Perform( uTruth7, 1 );
  757. //If_Dec7Verify( uTruth7, z );
  758. }
  759. else
  760. {
  761. z = If_Dec6Perform( uTruth6, 1 );
  762. //If_Dec6Verify( uTruth6, z );
  763. }
  764. if ( z == 0 )
  765. {
  766. printf( "Node \"%s\" is not decomposable. Writing BLIF has failed.\n", Abc_ObjName(Abc_ObjFanout0(pNode)) );
  767. return;
  768. }
  769. // derive nodes
  770. for ( c = 1; c >= 0; c-- )
  771. {
  772. // collect fanins
  773. uTruth7[c] = ((c ? z >> 32 : z) & 0xffff);
  774. uTruth7[c] |= (uTruth7[c] << 16);
  775. uTruth7[c] |= (uTruth7[c] << 32);
  776. for ( i = 0; i < 4; i++ )
  777. pVars[c][i] = (z >> (c*32+16+4*i)) & 7;
  778. // minimize truth table
  779. Cofs6[c] = If_Dec6MinimumBase( uTruth7[c], pVars[c], 4, &nVarsMin[c] );
  780. // write the nodes
  781. fprintf( pFile, ".names" );
  782. for ( i = 0; i < nVarsMin[c]; i++ )
  783. if ( pVars[c][i] == 7 )
  784. fprintf( pFile, " %s_cascade", Abc_ObjName(Abc_ObjFanout0(pNode)) );
  785. else
  786. fprintf( pFile, " %s", Abc_ObjName(Abc_ObjFanin(pNode,pVars[c][i])) );
  787. fprintf( pFile, " %s%s\n", Abc_ObjName(Abc_ObjFanout0(pNode)), c? "" : "_cascade" );
  788. // write SOP
  789. pSop = Io_NtkDeriveSop( (Mem_Flex_t *)Abc_ObjNtk(pNode)->pManFunc,
  790. (word)Cofs6[c], nVarsMin[c], vCover );
  791. fprintf( pFile, "%s", pSop );
  792. }
  793. }
  794. }
  795. /**Function*************************************************************
  796. Synopsis [Write the node into a file.]
  797. Description []
  798. SideEffects []
  799. SeeAlso []
  800. ***********************************************************************/
  801. void Io_NtkWriteNodeIntStruct( FILE * pFile, Abc_Obj_t * pNode, Vec_Int_t * vCover, char * pStr )
  802. {
  803. Abc_Obj_t * pNet;
  804. int nLeaves = Abc_ObjFaninNum(pNode);
  805. int i, nLutLeaf, nLutLeaf2, nLutRoot, Length;
  806. // quit if parameters are wrong
  807. Length = strlen(pStr);
  808. if ( Length != 2 && Length != 3 )
  809. {
  810. printf( "Wrong LUT struct (%s)\n", pStr );
  811. return;
  812. }
  813. for ( i = 0; i < Length; i++ )
  814. if ( pStr[i] - '0' < 3 || pStr[i] - '0' > 6 )
  815. {
  816. printf( "The LUT size (%d) should belong to {3,4,5,6}.\n", pStr[i] - '0' );
  817. return;
  818. }
  819. nLutLeaf = pStr[0] - '0';
  820. nLutLeaf2 = ( Length == 3 ) ? pStr[1] - '0' : 0;
  821. nLutRoot = pStr[Length-1] - '0';
  822. if ( nLeaves > nLutLeaf - 1 + (nLutLeaf2 ? nLutLeaf2 - 1 : 0) + nLutRoot )
  823. {
  824. printf( "The node size (%d) is too large for the LUT structure %s.\n", nLeaves, pStr );
  825. return;
  826. }
  827. // consider easy case
  828. fprintf( pFile, "\n" );
  829. if ( nLeaves <= Abc_MaxInt( nLutLeaf2, Abc_MaxInt(nLutLeaf, nLutRoot) ) )
  830. {
  831. // write the .names line
  832. fprintf( pFile, ".names" );
  833. Abc_ObjForEachFanin( pNode, pNet, i )
  834. fprintf( pFile, " %s", Abc_ObjName(pNet) );
  835. // get the output name
  836. fprintf( pFile, " %s\n", Abc_ObjName(Abc_ObjFanout0(pNode)) );
  837. // write the cubes
  838. fprintf( pFile, "%s", (char*)Abc_ObjData(pNode) );
  839. return;
  840. }
  841. else
  842. {
  843. extern int If_CluMinimumBase( word * t, int * pSupp, int nVarsAll, int * pnVars );
  844. static word TruthStore[16][1<<10] = {{0}}, * pTruths[16];
  845. word pCube[1<<10], pRes[1<<10], Func0, Func1, Func2;
  846. char pLut0[32], pLut1[32], pLut2[32] = {0}, * pSop;
  847. // int nVarsMin[3], pVars[3][20];
  848. if ( TruthStore[0][0] == 0 )
  849. {
  850. static word Truth6[6] = {
  851. ABC_CONST(0xAAAAAAAAAAAAAAAA),
  852. ABC_CONST(0xCCCCCCCCCCCCCCCC),
  853. ABC_CONST(0xF0F0F0F0F0F0F0F0),
  854. ABC_CONST(0xFF00FF00FF00FF00),
  855. ABC_CONST(0xFFFF0000FFFF0000),
  856. ABC_CONST(0xFFFFFFFF00000000)
  857. };
  858. int nVarsMax = 16;
  859. int nWordsMax = (1 << 10);
  860. int i, k;
  861. assert( nVarsMax <= 16 );
  862. for ( i = 0; i < nVarsMax; i++ )
  863. pTruths[i] = TruthStore[i];
  864. for ( i = 0; i < 6; i++ )
  865. for ( k = 0; k < nWordsMax; k++ )
  866. pTruths[i][k] = Truth6[i];
  867. for ( i = 6; i < nVarsMax; i++ )
  868. for ( k = 0; k < nWordsMax; k++ )
  869. pTruths[i][k] = ((k >> (i-6)) & 1) ? ~(word)0 : 0;
  870. }
  871. // collect variables
  872. // Abc_ObjForEachFanin( pNode, pNet, i )
  873. // pVars[0][i] = pVars[1][i] = pVars[2][i] = i;
  874. // derive truth table
  875. Abc_SopToTruthBig( (char*)Abc_ObjData(pNode), nLeaves, pTruths, pCube, pRes );
  876. if ( Kit_TruthIsConst0((unsigned *)pRes, nLeaves) || Kit_TruthIsConst1((unsigned *)pRes, nLeaves) )
  877. {
  878. fprintf( pFile, ".names %s\n %d\n", Abc_ObjName(Abc_ObjFanout0(pNode)), Kit_TruthIsConst1((unsigned *)pRes, nLeaves) );
  879. return;
  880. }
  881. // Extra_PrintHex( stdout, (unsigned *)pRes, nLeaves ); printf( " " );
  882. // Kit_DsdPrintFromTruth( (unsigned*)pRes, nLeaves ); printf( "\n" );
  883. // perform decomposition
  884. if ( Length == 2 )
  885. {
  886. if ( !If_CluCheckExt( NULL, pRes, nLeaves, nLutLeaf, nLutRoot, pLut0, pLut1, &Func0, &Func1 ) )
  887. {
  888. Extra_PrintHex( stdout, (unsigned *)pRes, nLeaves ); printf( " " );
  889. Kit_DsdPrintFromTruth( (unsigned*)pRes, nLeaves ); printf( "\n" );
  890. printf( "Node \"%s\" is not decomposable. Writing BLIF has failed.\n", Abc_ObjName(Abc_ObjFanout0(pNode)) );
  891. return;
  892. }
  893. }
  894. else
  895. {
  896. if ( !If_CluCheckExt3( NULL, pRes, nLeaves, nLutLeaf, nLutLeaf2, nLutRoot, pLut0, pLut1, pLut2, &Func0, &Func1, &Func2 ) )
  897. {
  898. Extra_PrintHex( stdout, (unsigned *)pRes, nLeaves ); printf( " " );
  899. Kit_DsdPrintFromTruth( (unsigned*)pRes, nLeaves ); printf( "\n" );
  900. printf( "Node \"%s\" is not decomposable. Writing BLIF has failed.\n", Abc_ObjName(Abc_ObjFanout0(pNode)) );
  901. return;
  902. }
  903. }
  904. // write leaf node
  905. fprintf( pFile, ".names" );
  906. for ( i = 0; i < pLut1[0]; i++ )
  907. fprintf( pFile, " %s", Abc_ObjName(Abc_ObjFanin(pNode,pLut1[2+i])) );
  908. fprintf( pFile, " %s_lut1\n", Abc_ObjName(Abc_ObjFanout0(pNode)) );
  909. // write SOP
  910. pSop = Io_NtkDeriveSop( (Mem_Flex_t *)Abc_ObjNtk(pNode)->pManFunc, Func1, pLut1[0], vCover );
  911. fprintf( pFile, "%s", pSop );
  912. if ( Length == 3 && pLut2[0] > 0 )
  913. {
  914. // write leaf node
  915. fprintf( pFile, ".names" );
  916. for ( i = 0; i < pLut2[0]; i++ )
  917. if ( pLut2[2+i] == nLeaves )
  918. fprintf( pFile, " %s_lut1", Abc_ObjName(Abc_ObjFanout0(pNode)) );
  919. else
  920. fprintf( pFile, " %s", Abc_ObjName(Abc_ObjFanin(pNode,pLut2[2+i])) );
  921. fprintf( pFile, " %s_lut2\n", Abc_ObjName(Abc_ObjFanout0(pNode)) );
  922. // write SOP
  923. pSop = Io_NtkDeriveSop( (Mem_Flex_t *)Abc_ObjNtk(pNode)->pManFunc, Func2, pLut2[0], vCover );
  924. fprintf( pFile, "%s", pSop );
  925. }
  926. // write root node
  927. fprintf( pFile, ".names" );
  928. for ( i = 0; i < pLut0[0]; i++ )
  929. if ( pLut0[2+i] == nLeaves )
  930. fprintf( pFile, " %s_lut1", Abc_ObjName(Abc_ObjFanout0(pNode)) );
  931. else if ( pLut0[2+i] == nLeaves+1 )
  932. fprintf( pFile, " %s_lut2", Abc_ObjName(Abc_ObjFanout0(pNode)) );
  933. else
  934. fprintf( pFile, " %s", Abc_ObjName(Abc_ObjFanin(pNode,pLut0[2+i])) );
  935. fprintf( pFile, " %s\n", Abc_ObjName(Abc_ObjFanout0(pNode)) );
  936. // write SOP
  937. pSop = Io_NtkDeriveSop( (Mem_Flex_t *)Abc_ObjNtk(pNode)->pManFunc, Func0, pLut0[0], vCover );
  938. fprintf( pFile, "%s", pSop );
  939. }
  940. }
  941. /**Function*************************************************************
  942. Synopsis [Write the node into a file.]
  943. Description []
  944. SideEffects []
  945. SeeAlso []
  946. ***********************************************************************/
  947. void Io_NtkWriteModelIntStruct( FILE * pFile, Abc_Obj_t * pNode, Vec_Int_t * vCover, char * pStr )
  948. {
  949. Abc_Obj_t * pNet;
  950. int nLeaves = Abc_ObjFaninNum(pNode);
  951. int i, nLutLeaf, nLutLeaf2, nLutRoot, Length;
  952. // write the header
  953. fprintf( pFile, "\n" );
  954. fprintf( pFile, ".model m%d\n", Abc_ObjId(pNode) );
  955. fprintf( pFile, ".inputs" );
  956. for ( i = 0; i < Abc_ObjFaninNum(pNode); i++ )
  957. fprintf( pFile, " %c", 'a' + i );
  958. fprintf( pFile, "\n" );
  959. fprintf( pFile, ".outputs o\n" );
  960. // quit if parameters are wrong
  961. Length = strlen(pStr);
  962. if ( Length != 2 && Length != 3 )
  963. {
  964. printf( "Wrong LUT struct (%s)\n", pStr );
  965. return;
  966. }
  967. for ( i = 0; i < Length; i++ )
  968. if ( pStr[i] - '0' < 3 || pStr[i] - '0' > 6 )
  969. {
  970. printf( "The LUT size (%d) should belong to {3,4,5,6}.\n", pStr[i] - '0' );
  971. return;
  972. }
  973. nLutLeaf = pStr[0] - '0';
  974. nLutLeaf2 = ( Length == 3 ) ? pStr[1] - '0' : 0;
  975. nLutRoot = pStr[Length-1] - '0';
  976. if ( nLeaves > nLutLeaf - 1 + (nLutLeaf2 ? nLutLeaf2 - 1 : 0) + nLutRoot )
  977. {
  978. printf( "The node size (%d) is too large for the LUT structure %s.\n", nLeaves, pStr );
  979. return;
  980. }
  981. // consider easy case
  982. if ( nLeaves <= Abc_MaxInt( nLutLeaf2, Abc_MaxInt(nLutLeaf, nLutRoot) ) )
  983. {
  984. // write the .names line
  985. fprintf( pFile, ".names" );
  986. Abc_ObjForEachFanin( pNode, pNet, i )
  987. fprintf( pFile, " %c", 'a' + i );
  988. // get the output name
  989. fprintf( pFile, " %s\n", "o" );
  990. // write the cubes
  991. fprintf( pFile, "%s", (char*)Abc_ObjData(pNode) );
  992. fprintf( pFile, ".end\n" );
  993. return;
  994. }
  995. else
  996. {
  997. extern int If_CluMinimumBase( word * t, int * pSupp, int nVarsAll, int * pnVars );
  998. static word TruthStore[16][1<<10] = {{0}}, * pTruths[16];
  999. word pCube[1<<10], pRes[1<<10], Func0, Func1, Func2;
  1000. char pLut0[32], pLut1[32], pLut2[32] = {0}, * pSop;
  1001. // int nVarsMin[3], pVars[3][20];
  1002. if ( TruthStore[0][0] == 0 )
  1003. {
  1004. static word Truth6[6] = {
  1005. ABC_CONST(0xAAAAAAAAAAAAAAAA),
  1006. ABC_CONST(0xCCCCCCCCCCCCCCCC),
  1007. ABC_CONST(0xF0F0F0F0F0F0F0F0),
  1008. ABC_CONST(0xFF00FF00FF00FF00),
  1009. ABC_CONST(0xFFFF0000FFFF0000),
  1010. ABC_CONST(0xFFFFFFFF00000000)
  1011. };
  1012. int nVarsMax = 16;
  1013. int nWordsMax = (1 << 10);
  1014. int i, k;
  1015. assert( nVarsMax <= 16 );
  1016. for ( i = 0; i < nVarsMax; i++ )
  1017. pTruths[i] = TruthStore[i];
  1018. for ( i = 0; i < 6; i++ )
  1019. for ( k = 0; k < nWordsMax; k++ )
  1020. pTruths[i][k] = Truth6[i];
  1021. for ( i = 6; i < nVarsMax; i++ )
  1022. for ( k = 0; k < nWordsMax; k++ )
  1023. pTruths[i][k] = ((k >> (i-6)) & 1) ? ~(word)0 : 0;
  1024. }
  1025. // collect variables
  1026. // Abc_ObjForEachFanin( pNode, pNet, i )
  1027. // pVars[0][i] = pVars[1][i] = pVars[2][i] = i;
  1028. // derive truth table
  1029. Abc_SopToTruthBig( (char*)Abc_ObjData(pNode), nLeaves, pTruths, pCube, pRes );
  1030. if ( Kit_TruthIsConst0((unsigned *)pRes, nLeaves) || Kit_TruthIsConst1((unsigned *)pRes, nLeaves) )
  1031. {
  1032. fprintf( pFile, ".names %s\n %d\n", "o", Kit_TruthIsConst1((unsigned *)pRes, nLeaves) );
  1033. fprintf( pFile, ".end\n" );
  1034. return;
  1035. }
  1036. // Extra_PrintHex( stdout, (unsigned *)pRes, nLeaves ); printf( " " );
  1037. // Kit_DsdPrintFromTruth( (unsigned*)pRes, nLeaves ); printf( "\n" );
  1038. // perform decomposition
  1039. if ( Length == 2 )
  1040. {
  1041. if ( !If_CluCheckExt( NULL, pRes, nLeaves, nLutLeaf, nLutRoot, pLut0, pLut1, &Func0, &Func1 ) )
  1042. {
  1043. Extra_PrintHex( stdout, (unsigned *)pRes, nLeaves ); printf( " " );
  1044. Kit_DsdPrintFromTruth( (unsigned*)pRes, nLeaves ); printf( "\n" );
  1045. printf( "Node \"%s\" is not decomposable. Writing BLIF has failed.\n", Abc_ObjName(Abc_ObjFanout0(pNode)) );
  1046. return;
  1047. }
  1048. }
  1049. else
  1050. {
  1051. if ( !If_CluCheckExt3( NULL, pRes, nLeaves, nLutLeaf, nLutLeaf2, nLutRoot, pLut0, pLut1, pLut2, &Func0, &Func1, &Func2 ) )
  1052. {
  1053. Extra_PrintHex( stdout, (unsigned *)pRes, nLeaves ); printf( " " );
  1054. Kit_DsdPrintFromTruth( (unsigned*)pRes, nLeaves ); printf( "\n" );
  1055. printf( "Node \"%s\" is not decomposable. Writing BLIF has failed.\n", Abc_ObjName(Abc_ObjFanout0(pNode)) );
  1056. return;
  1057. }
  1058. }
  1059. // write leaf node
  1060. fprintf( pFile, ".names" );
  1061. for ( i = 0; i < pLut1[0]; i++ )
  1062. fprintf( pFile, " %c", 'a' + pLut1[2+i] );
  1063. fprintf( pFile, " lut1\n" );
  1064. // write SOP
  1065. pSop = Io_NtkDeriveSop( (Mem_Flex_t *)Abc_ObjNtk(pNode)->pManFunc, Func1, pLut1[0], vCover );
  1066. fprintf( pFile, "%s", pSop );
  1067. if ( Length == 3 && pLut2[0] > 0 )
  1068. {
  1069. // write leaf node
  1070. fprintf( pFile, ".names" );
  1071. for ( i = 0; i < pLut2[0]; i++ )
  1072. if ( pLut2[2+i] == nLeaves )
  1073. fprintf( pFile, " lut1" );
  1074. else
  1075. fprintf( pFile, " %c", 'a' + pLut2[2+i] );
  1076. fprintf( pFile, " lut2\n" );
  1077. // write SOP
  1078. pSop = Io_NtkDeriveSop( (Mem_Flex_t *)Abc_ObjNtk(pNode)->pManFunc, Func2, pLut2[0], vCover );
  1079. fprintf( pFile, "%s", pSop );
  1080. }
  1081. // write root node
  1082. fprintf( pFile, ".names" );
  1083. for ( i = 0; i < pLut0[0]; i++ )
  1084. if ( pLut0[2+i] == nLeaves )
  1085. fprintf( pFile, " lut1" );
  1086. else if ( pLut0[2+i] == nLeaves+1 )
  1087. fprintf( pFile, " lut2" );
  1088. else
  1089. fprintf( pFile, " %c", 'a' + pLut0[2+i] );
  1090. fprintf( pFile, " %s\n", "o" );
  1091. // write SOP
  1092. pSop = Io_NtkDeriveSop( (Mem_Flex_t *)Abc_ObjNtk(pNode)->pManFunc, Func0, pLut0[0], vCover );
  1093. fprintf( pFile, "%s", pSop );
  1094. fprintf( pFile, ".end\n" );
  1095. }
  1096. }
  1097. /**Function*************************************************************
  1098. Synopsis [Write the network into a BLIF file with the given name.]
  1099. Description []
  1100. SideEffects []
  1101. SeeAlso []
  1102. ***********************************************************************/
  1103. void Io_WriteBlifInt( Abc_Ntk_t * pNtk, char * FileName, char * pLutStruct, int fUseHie )
  1104. {
  1105. FILE * pFile;
  1106. Vec_Int_t * vCover;
  1107. Abc_Obj_t * pNode, * pLatch;
  1108. int i;
  1109. assert( Abc_NtkIsNetlist(pNtk) );
  1110. // start writing the file
  1111. pFile = fopen( FileName, "w" );
  1112. if ( pFile == NULL )
  1113. {
  1114. fprintf( stdout, "Io_WriteBlifInt(): Cannot open the output file.\n" );
  1115. return;
  1116. }
  1117. fprintf( pFile, "# Benchmark \"%s\" written by ABC on %s\n", pNtk->pName, Extra_TimeStamp() );
  1118. // write the model name
  1119. fprintf( pFile, ".model %s\n", Abc_NtkName(pNtk) );
  1120. // write the PIs
  1121. fprintf( pFile, ".inputs" );
  1122. Io_NtkWritePis( pFile, pNtk, 1 );
  1123. fprintf( pFile, "\n" );
  1124. // write the POs
  1125. fprintf( pFile, ".outputs" );
  1126. Io_NtkWritePos( pFile, pNtk, 1 );
  1127. fprintf( pFile, "\n" );
  1128. // write the latches
  1129. if ( Abc_NtkLatchNum(pNtk) )
  1130. fprintf( pFile, "\n" );
  1131. Abc_NtkForEachLatch( pNtk, pLatch, i )
  1132. Io_NtkWriteLatch( pFile, pLatch );
  1133. if ( Abc_NtkLatchNum(pNtk) )
  1134. fprintf( pFile, "\n" );
  1135. // write the hierarchy
  1136. vCover = Vec_IntAlloc( (1<<16) );
  1137. if ( fUseHie )
  1138. {
  1139. // write each internal node
  1140. fprintf( pFile, "\n" );
  1141. Abc_NtkForEachNode( pNtk, pNode, i )
  1142. Io_NtkWriteNodeSubckt( pFile, pNode, 0 );
  1143. fprintf( pFile, ".end\n\n" );
  1144. // write models
  1145. Abc_NtkForEachNode( pNtk, pNode, i )
  1146. Io_NtkWriteModelIntStruct( pFile, pNode, vCover, pLutStruct );
  1147. fprintf( pFile, "\n" );
  1148. }
  1149. else
  1150. {
  1151. // write each internal node
  1152. Abc_NtkForEachNode( pNtk, pNode, i )
  1153. {
  1154. if ( pLutStruct )
  1155. Io_NtkWriteNodeIntStruct( pFile, pNode, vCover, pLutStruct );
  1156. else
  1157. Io_NtkWriteNodeInt( pFile, pNode, vCover );
  1158. }
  1159. fprintf( pFile, ".end\n\n" );
  1160. }
  1161. Vec_IntFree( vCover );
  1162. fclose( pFile );
  1163. }
  1164. /**Function*************************************************************
  1165. Synopsis [Write the network into a BLIF file with the given name.]
  1166. Description []
  1167. SideEffects []
  1168. SeeAlso []
  1169. ***********************************************************************/
  1170. void Io_WriteBlifSpecial( Abc_Ntk_t * pNtk, char * FileName, char * pLutStruct, int fUseHie )
  1171. {
  1172. Abc_Ntk_t * pNtkTemp;
  1173. assert( Abc_NtkIsLogic(pNtk) );
  1174. Abc_NtkToSop( pNtk, -1, ABC_INFINITY );
  1175. // derive the netlist
  1176. pNtkTemp = Abc_NtkToNetlist(pNtk);
  1177. if ( pNtkTemp == NULL )
  1178. {
  1179. fprintf( stdout, "Writing BLIF has failed.\n" );
  1180. return;
  1181. }
  1182. if ( pLutStruct && fUseHie )
  1183. Io_WriteBlifInt( pNtkTemp, FileName, pLutStruct, 1 );
  1184. else
  1185. Io_WriteBlifInt( pNtkTemp, FileName, pLutStruct, 0 );
  1186. Abc_NtkDelete( pNtkTemp );
  1187. }
  1188. ////////////////////////////////////////////////////////////////////////
  1189. /// END OF FILE ///
  1190. ////////////////////////////////////////////////////////////////////////
  1191. ABC_NAMESPACE_IMPL_END