You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1641 lines
48 KiB

  1. /**CFile**********************************************************************
  2. FileName [dddmpStoreMisc.c]
  3. PackageName [dddmp]
  4. Synopsis [Functions to write out bdds to file in prefixed
  5. and in Blif form.]
  6. Description [Functions to write out bdds to file.
  7. BDDs are represended on file in text format.
  8. Each node is stored as a multiplexer in a prefix notation format for
  9. the prefix notation file or in PLA format for the blif file.
  10. ]
  11. Author [Gianpiero Cabodi and Stefano Quer]
  12. Copyright [
  13. Copyright (c) 2004 by Politecnico di Torino.
  14. All Rights Reserved. This software is for educational purposes only.
  15. Permission is given to academic institutions to use, copy, and modify
  16. this software and its documentation provided that this introductory
  17. message is not removed, that this software and its documentation is
  18. used for the institutions' internal research and educational purposes,
  19. and that no monies are exchanged. No guarantee is expressed or implied
  20. by the distribution of this code.
  21. Send bug-reports and/or questions to:
  22. {gianpiero.cabodi,stefano.quer}@polito.it.
  23. ]
  24. ******************************************************************************/
  25. #include "dddmpInt.h"
  26. /*---------------------------------------------------------------------------*/
  27. /* Stucture declarations */
  28. /*---------------------------------------------------------------------------*/
  29. /*---------------------------------------------------------------------------*/
  30. /* Type declarations */
  31. /*---------------------------------------------------------------------------*/
  32. /*---------------------------------------------------------------------------*/
  33. /* Variable declarations */
  34. /*---------------------------------------------------------------------------*/
  35. /*---------------------------------------------------------------------------*/
  36. /* Macro declarations */
  37. /*---------------------------------------------------------------------------*/
  38. /**AutomaticStart*************************************************************/
  39. /*---------------------------------------------------------------------------*/
  40. /* Static function prototypes */
  41. /*---------------------------------------------------------------------------*/
  42. static int DddmpCuddDdArrayStorePrefix(DdManager *ddMgr, int n, DdNode **f, char **inputNames, char **outputNames, char *modelName, FILE *fp);
  43. static int DddmpCuddDdArrayStorePrefixBody(DdManager *ddMgr, int n, DdNode **f, char **inputNames, char **outputNames, FILE *fp);
  44. static int DddmpCuddDdArrayStorePrefixStep(DdManager * ddMgr, DdNode * f, FILE * fp, st_table * visited, char ** names);
  45. static int DddmpCuddDdArrayStoreBlif(DdManager *ddMgr, int n, DdNode **f, char **inputNames, char **outputNames, char *modelName, FILE *fp);
  46. static int DddmpCuddDdArrayStoreBlifBody(DdManager *ddMgr, int n, DdNode **f, char **inputNames, char **outputNames, FILE *fp);
  47. static int DddmpCuddDdArrayStoreBlifStep(DdManager *ddMgr, DdNode *f, FILE *fp, st_table *visited, char **names);
  48. static int DddmpCuddDdArrayStoreSmv(DdManager *ddMgr, int n, DdNode **f, char **inputNames, char **outputNames, char *modelName, FILE *fp);
  49. static int DddmpCuddDdArrayStoreSmvBody(DdManager *ddMgr, int n, DdNode **f, char **inputNames, char **outputNames, FILE *fp);
  50. static int DddmpCuddDdArrayStoreSmvStep(DdManager * ddMgr, DdNode * f, FILE * fp, st_table * visited, char ** names);
  51. /**AutomaticEnd***************************************************************/
  52. /*---------------------------------------------------------------------------*/
  53. /* Definition of exported functions */
  54. /*---------------------------------------------------------------------------*/
  55. /**Function********************************************************************
  56. Synopsis [Writes a dump file representing the argument BDD in
  57. a prefix notation.]
  58. Description [Dumps the argument BDD to file.
  59. Dumping is done through Dddmp_cuddBddArrayStorePrefix.
  60. A dummy array of 1 BDD root is used for this purpose.
  61. ]
  62. SideEffects []
  63. SeeAlso [Dddmp_cuddBddStore]
  64. ******************************************************************************/
  65. int
  66. Dddmp_cuddBddStorePrefix (
  67. DdManager *ddMgr /* IN: DD Manager */,
  68. int nRoots /* IN: Number of BDD roots */,
  69. DdNode *f /* IN: BDD root to be stored */,
  70. char **inputNames /* IN: Array of variable names */,
  71. char **outputNames /* IN: Array of root names */,
  72. char *modelName /* IN: Model Name */,
  73. char *fileName /* IN: File name */,
  74. FILE *fp /* IN: File pointer to the store file */
  75. )
  76. {
  77. int retValue;
  78. DdNode *tmpArray[1];
  79. tmpArray[0] = f;
  80. retValue = Dddmp_cuddBddArrayStorePrefix (ddMgr, 1, tmpArray,
  81. inputNames, outputNames, modelName, fileName, fp);
  82. return (retValue);
  83. }
  84. /**Function********************************************************************
  85. Synopsis [Writes a dump file representing the argument BDD in
  86. a prefix notation.]
  87. Description [Dumps the argument BDD to file.
  88. Dumping is done through Dddmp_cuddBddArrayStorePrefix.
  89. A dummy array of 1 BDD root is used for this purpose.
  90. ]
  91. SideEffects []
  92. SeeAlso [Dddmp_cuddBddArrayStore]
  93. ******************************************************************************/
  94. int
  95. Dddmp_cuddBddArrayStorePrefix (
  96. DdManager *ddMgr /* IN: DD Manager */,
  97. int nroots /* IN: number of output BDD roots to be stored */,
  98. DdNode **f /* IN: array of BDD roots to be stored */,
  99. char **inputNames /* IN: array of variable names (or NULL) */,
  100. char **outputNames /* IN: array of root names (or NULL) */,
  101. char *modelName /* IN: Model Name */,
  102. char *fname /* IN: File name */,
  103. FILE *fp /* IN: File pointer to the store file */
  104. )
  105. {
  106. int retValue;
  107. int fileToClose = 0;
  108. #ifdef DDDMP_DEBUG
  109. #ifndef __alpha__
  110. int retValueBis;
  111. retValueBis = Cudd_DebugCheck (ddMgr);
  112. if (retValueBis == 1) {
  113. fprintf (stderr, "Inconsistency Found During BDD Store.\n");
  114. fflush (stderr);
  115. } else {
  116. if (retValueBis == CUDD_OUT_OF_MEM) {
  117. fprintf (stderr, "Out of Memory During BDD Store.\n");
  118. fflush (stderr);
  119. }
  120. }
  121. #endif
  122. #endif
  123. /*
  124. * Check if File needs to be opened in the proper mode.
  125. */
  126. if (fp == NULL) {
  127. fp = fopen (fname, "w");
  128. Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.",
  129. failure);
  130. fileToClose = 1;
  131. }
  132. retValue = DddmpCuddDdArrayStorePrefix (ddMgr, nroots, f,
  133. inputNames, outputNames, modelName, fp);
  134. if (fileToClose) {
  135. fclose (fp);
  136. }
  137. #ifdef DDDMP_DEBUG
  138. #ifndef __alpha__
  139. retValueBis = Cudd_DebugCheck (ddMgr);
  140. if (retValueBis == 1) {
  141. fprintf (stderr, "Inconsistency Found During BDD Store.\n");
  142. fflush (stderr);
  143. } else {
  144. if (retValueBis == CUDD_OUT_OF_MEM) {
  145. fprintf (stderr, "Out of Memory During BDD Store.\n");
  146. fflush (stderr);
  147. }
  148. }
  149. #endif
  150. #endif
  151. return (retValue);
  152. failure:
  153. return (DDDMP_FAILURE);
  154. }
  155. /**Function********************************************************************
  156. Synopsis [Writes a dump file representing the argument BDD in
  157. a Blif/Exlif notation.]
  158. Description [Dumps the argument BDD to file.
  159. Dumping is done through Dddmp_cuddBddArrayStoreBlif.
  160. A dummy array of 1 BDD root is used for this purpose.
  161. ]
  162. SideEffects []
  163. SeeAlso [Dddmp_cuddBddStorePrefix]
  164. ******************************************************************************/
  165. int
  166. Dddmp_cuddBddStoreBlif (
  167. DdManager *ddMgr /* IN: DD Manager */,
  168. int nRoots /* IN: Number of BDD roots */,
  169. DdNode *f /* IN: BDD root to be stored */,
  170. char **inputNames /* IN: Array of variable names */,
  171. char **outputNames /* IN: Array of root names */,
  172. char *modelName /* IN: Model Name */,
  173. char *fileName /* IN: File name */,
  174. FILE *fp /* IN: File pointer to the store file */
  175. )
  176. {
  177. int retValue;
  178. DdNode *tmpArray[1];
  179. tmpArray[0] = f;
  180. retValue = Dddmp_cuddBddArrayStoreBlif (ddMgr, 1, tmpArray,
  181. inputNames, outputNames, modelName, fileName, fp);
  182. return (retValue);
  183. }
  184. /**Function********************************************************************
  185. Synopsis [Writes a dump file representing the argument BDD in
  186. a Blif/Exlif notation.]
  187. Description [Dumps the argument BDD to file.
  188. Dumping is done through Dddmp_cuddBddArrayStoreBLif.
  189. A dummy array of 1 BDD root is used for this purpose.
  190. ]
  191. SideEffects []
  192. SeeAlso [Dddmp_cuddBddArrayStorePrefix]
  193. ******************************************************************************/
  194. int
  195. Dddmp_cuddBddArrayStoreBlif (
  196. DdManager *ddMgr /* IN: DD Manager */,
  197. int nroots /* IN: number of output BDD roots to be stored */,
  198. DdNode **f /* IN: array of BDD roots to be stored */,
  199. char **inputNames /* IN: array of variable names (or NULL) */,
  200. char **outputNames /* IN: array of root names (or NULL) */,
  201. char *modelName /* IN: Model Name */,
  202. char *fname /* IN: File name */,
  203. FILE *fp /* IN: File pointer to the store file */
  204. )
  205. {
  206. int retValue;
  207. int fileToClose = 0;
  208. #ifdef DDDMP_DEBUG
  209. #ifndef __alpha__
  210. int retValueBis;
  211. retValueBis = Cudd_DebugCheck (ddMgr);
  212. if (retValueBis == 1) {
  213. fprintf (stderr, "Inconsistency Found During BDD Store.\n");
  214. fflush (stderr);
  215. } else {
  216. if (retValueBis == CUDD_OUT_OF_MEM) {
  217. fprintf (stderr, "Out of Memory During BDD Store.\n");
  218. fflush (stderr);
  219. }
  220. }
  221. #endif
  222. #endif
  223. /*
  224. * Check if File needs to be opened in the proper mode.
  225. */
  226. if (fp == NULL) {
  227. fp = fopen (fname, "w");
  228. Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.",
  229. failure);
  230. fileToClose = 1;
  231. }
  232. retValue = DddmpCuddDdArrayStoreBlif (ddMgr, nroots, f,
  233. inputNames, outputNames, modelName, fp);
  234. if (fileToClose) {
  235. fclose (fp);
  236. }
  237. #ifdef DDDMP_DEBUG
  238. #ifndef __alpha__
  239. retValueBis = Cudd_DebugCheck (ddMgr);
  240. if (retValueBis == 1) {
  241. fprintf (stderr, "Inconsistency Found During BDD Store.\n");
  242. fflush (stderr);
  243. } else {
  244. if (retValueBis == CUDD_OUT_OF_MEM) {
  245. fprintf (stderr, "Out of Memory During BDD Store.\n");
  246. fflush (stderr);
  247. }
  248. }
  249. #endif
  250. #endif
  251. return (retValue);
  252. failure:
  253. return (DDDMP_FAILURE);
  254. }
  255. /**Function********************************************************************
  256. Synopsis [Writes a dump file representing the argument BDD in
  257. a prefix notation.]
  258. Description [Dumps the argument BDD to file.
  259. Dumping is done through Dddmp_cuddBddArrayStorePrefix.
  260. A dummy array of 1 BDD root is used for this purpose.
  261. ]
  262. SideEffects []
  263. SeeAlso [Dddmp_cuddBddStore]
  264. ******************************************************************************/
  265. int
  266. Dddmp_cuddBddStoreSmv (
  267. DdManager *ddMgr /* IN: DD Manager */,
  268. int nRoots /* IN: Number of BDD roots */,
  269. DdNode *f /* IN: BDD root to be stored */,
  270. char **inputNames /* IN: Array of variable names */,
  271. char **outputNames /* IN: Array of root names */,
  272. char *modelName /* IN: Model Name */,
  273. char *fileName /* IN: File name */,
  274. FILE *fp /* IN: File pointer to the store file */
  275. )
  276. {
  277. int retValue;
  278. DdNode *tmpArray[1];
  279. tmpArray[0] = f;
  280. retValue = Dddmp_cuddBddArrayStoreSmv (ddMgr, 1, tmpArray,
  281. inputNames, outputNames, modelName, fileName, fp);
  282. return (retValue);
  283. }
  284. /**Function********************************************************************
  285. Synopsis [Writes a dump file representing the argument BDD in
  286. a prefix notation.]
  287. Description [Dumps the argument BDD to file.
  288. Dumping is done through Dddmp_cuddBddArrayStorePrefix.
  289. A dummy array of 1 BDD root is used for this purpose.
  290. ]
  291. SideEffects []
  292. SeeAlso [Dddmp_cuddBddArrayStore]
  293. ******************************************************************************/
  294. int
  295. Dddmp_cuddBddArrayStoreSmv (
  296. DdManager *ddMgr /* IN: DD Manager */,
  297. int nroots /* IN: number of output BDD roots to be stored */,
  298. DdNode **f /* IN: array of BDD roots to be stored */,
  299. char **inputNames /* IN: array of variable names (or NULL) */,
  300. char **outputNames /* IN: array of root names (or NULL) */,
  301. char *modelName /* IN: Model Name */,
  302. char *fname /* IN: File name */,
  303. FILE *fp /* IN: File pointer to the store file */
  304. )
  305. {
  306. int retValue;
  307. int fileToClose = 0;
  308. #ifdef DDDMP_DEBUG
  309. #ifndef __alpha__
  310. int retValueBis;
  311. retValueBis = Cudd_DebugCheck (ddMgr);
  312. if (retValueBis == 1) {
  313. fprintf (stderr, "Inconsistency Found During BDD Store.\n");
  314. fflush (stderr);
  315. } else {
  316. if (retValueBis == CUDD_OUT_OF_MEM) {
  317. fprintf (stderr, "Out of Memory During BDD Store.\n");
  318. fflush (stderr);
  319. }
  320. }
  321. #endif
  322. #endif
  323. /*
  324. * Check if File needs to be opened in the proper mode.
  325. */
  326. if (fp == NULL) {
  327. fp = fopen (fname, "w");
  328. Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.",
  329. failure);
  330. fileToClose = 1;
  331. }
  332. retValue = DddmpCuddDdArrayStoreSmv (ddMgr, nroots, f,
  333. inputNames, outputNames, modelName, fp);
  334. if (fileToClose) {
  335. fclose (fp);
  336. }
  337. #ifdef DDDMP_DEBUG
  338. #ifndef __alpha__
  339. retValueBis = Cudd_DebugCheck (ddMgr);
  340. if (retValueBis == 1) {
  341. fprintf (stderr, "Inconsistency Found During BDD Store.\n");
  342. fflush (stderr);
  343. } else {
  344. if (retValueBis == CUDD_OUT_OF_MEM) {
  345. fprintf (stderr, "Out of Memory During BDD Store.\n");
  346. fflush (stderr);
  347. }
  348. }
  349. #endif
  350. #endif
  351. return (retValue);
  352. failure:
  353. return (DDDMP_FAILURE);
  354. }
  355. /*---------------------------------------------------------------------------*/
  356. /* Definition of static functions */
  357. /*---------------------------------------------------------------------------*/
  358. /**Function********************************************************************
  359. Synopsis [Internal function to writes a dump file representing the
  360. argument BDD in a prefix notation.]
  361. Description [One multiplexer is written for each BDD node.
  362. It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file
  363. system full, or an ADD with constants different from 0 and 1).
  364. It does not close the file: This is the caller responsibility.
  365. It uses a minimal unique subset of the hexadecimal address of a node as
  366. name for it.
  367. If the argument inputNames is non-null, it is assumed to hold the
  368. pointers to the names of the inputs. Similarly for outputNames.
  369. For each BDD node of function f, variable v, then child T, and else
  370. child E it stores:
  371. f = v * T + v' * E
  372. that is
  373. (OR f (AND v T) (AND (NOT v) E))
  374. If E is a complemented child this results in the following
  375. (OR f (AND v T) (AND (NOT v) (NOT E)))
  376. Comments (COMMENT) are added at the beginning of the description to
  377. describe inputs and outputs of the design.
  378. A buffer (BUF) is add on the output to cope with complemented functions.
  379. ]
  380. SideEffects [None]
  381. SeeAlso [DddmpCuddDdArrayStoreBlif]
  382. ******************************************************************************/
  383. static int
  384. DddmpCuddDdArrayStorePrefix (
  385. DdManager *ddMgr /* IN: Manager */,
  386. int n /* IN: Number of output nodes to be dumped */,
  387. DdNode **f /* IN: Array of output nodes to be dumped */,
  388. char **inputNames /* IN: Array of input names (or NULL) */,
  389. char **outputNames /* IN: Array of output names (or NULL) */,
  390. char *modelName /* IN: Model name (or NULL) */,
  391. FILE *fp /* IN: Pointer to the dump file */
  392. )
  393. {
  394. DdNode *support = NULL;
  395. DdNode *scan;
  396. int *sorted = NULL;
  397. int nVars = ddMgr->size;
  398. int retValue;
  399. int i;
  400. /* Build a bit array with the support of f. */
  401. sorted = ALLOC(int, nVars);
  402. if (sorted == NULL) {
  403. ddMgr->errorCode = CUDD_MEMORY_OUT;
  404. Dddmp_CheckAndGotoLabel (1, "Allocation Error.", failure);
  405. }
  406. for (i = 0; i < nVars; i++) {
  407. sorted[i] = 0;
  408. }
  409. /* Take the union of the supports of each output function. */
  410. support = Cudd_VectorSupport(ddMgr,f,n);
  411. Dddmp_CheckAndGotoLabel (support==NULL,
  412. "Error in function Cudd_VectorSupport.", failure);
  413. cuddRef(support);
  414. scan = support;
  415. while (!cuddIsConstant(scan)) {
  416. sorted[scan->index] = 1;
  417. scan = cuddT(scan);
  418. }
  419. Cudd_RecursiveDeref(ddMgr,support);
  420. /* so that we do not try to free it in case of failure */
  421. support = NULL;
  422. /* Write the header (.model .inputs .outputs). */
  423. if (modelName == NULL) {
  424. retValue = fprintf (fp, "(COMMENT - model name: Unknown )\n");
  425. } else {
  426. retValue = fprintf (fp, "(COMMENT - model name: %s )\n", modelName);
  427. }
  428. if (retValue == EOF) {
  429. return(0);
  430. }
  431. retValue = fprintf(fp, "(COMMENT - input names: ");
  432. if (retValue == EOF) {
  433. return(0);
  434. }
  435. /* Write the input list by scanning the support array. */
  436. for (i = 0; i < nVars; i++) {
  437. if (sorted[i]) {
  438. if (inputNames == NULL) {
  439. retValue = fprintf(fp," inNode%d", i);
  440. } else {
  441. retValue = fprintf(fp," %s", inputNames[i]);
  442. }
  443. Dddmp_CheckAndGotoLabel (retValue==EOF,
  444. "Error during file store.", failure);
  445. }
  446. }
  447. FREE(sorted);
  448. sorted = NULL;
  449. retValue = fprintf(fp, " )\n");
  450. if (retValue == EOF) {
  451. return(0);
  452. }
  453. /* Write the .output line. */
  454. retValue = fprintf(fp,"(COMMENT - output names: ");
  455. if (retValue == EOF) {
  456. return(0);
  457. }
  458. for (i = 0; i < n; i++) {
  459. if (outputNames == NULL) {
  460. retValue = fprintf (fp," outNode%d", i);
  461. } else {
  462. retValue = fprintf (fp," %s", outputNames[i]);
  463. }
  464. Dddmp_CheckAndGotoLabel (retValue==EOF,
  465. "Error during file store.", failure);
  466. }
  467. retValue = fprintf(fp, " )\n");
  468. Dddmp_CheckAndGotoLabel (retValue==EOF,
  469. "Error during file store.", failure);
  470. retValue = DddmpCuddDdArrayStorePrefixBody (ddMgr, n, f, inputNames,
  471. outputNames, fp);
  472. Dddmp_CheckAndGotoLabel (retValue==0,
  473. "Error in function DddmpCuddDdArrayStorePrefixBody.", failure);
  474. return(1);
  475. failure:
  476. if (sorted != NULL) {
  477. FREE(sorted);
  478. }
  479. if (support != NULL) {
  480. Cudd_RecursiveDeref(ddMgr,support);
  481. }
  482. return(0);
  483. }
  484. /**Function********************************************************************
  485. Synopsis [Internal function to writes a dump file representing the
  486. argument BDD in a prefix notation. Writes the body of the file.]
  487. Description [One multiplexer is written for each BDD node.
  488. It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file
  489. system full, or an ADD with constants different from 0 and 1).
  490. It does not close the file: This is the caller responsibility.
  491. It uses a minimal unique subset of the hexadecimal address of a node as
  492. name for it.
  493. If the argument inputNames is non-null, it is assumed to hold the
  494. pointers to the names of the inputs. Similarly for outputNames.
  495. For each BDD node of function f, variable v, then child T, and else
  496. child E it stores:
  497. f = v * T + v' * E
  498. that is
  499. (OR f (AND v T) (AND (NOT v) E))
  500. If E is a complemented child this results in the following
  501. (OR f (AND v T) (AND (NOT v) (NOT E)))
  502. ]
  503. SideEffects [None]
  504. SeeAlso [DddmpCuddDdArrayStoreBlif]
  505. ******************************************************************************/
  506. static int
  507. DddmpCuddDdArrayStorePrefixBody (
  508. DdManager *ddMgr /* IN: Manager */,
  509. int n /* IN: Number of output nodes to be dumped */,
  510. DdNode **f /* IN: Array of output nodes to be dumped */,
  511. char **inputNames /* IN: Array of input names (or NULL) */,
  512. char **outputNames /* IN: Array of output names (or NULL) */,
  513. FILE *fp /* IN: Pointer to the dump file */
  514. )
  515. {
  516. st_table *visited = NULL;
  517. int retValue;
  518. int i;
  519. /* Initialize symbol table for visited nodes. */
  520. visited = st_init_table(st_ptrcmp, st_ptrhash);
  521. Dddmp_CheckAndGotoLabel (visited==NULL,
  522. "Error if function st_init_table.", failure);
  523. /* Call the function that really gets the job done. */
  524. for (i = 0; i < n; i++) {
  525. retValue = DddmpCuddDdArrayStorePrefixStep (ddMgr, Cudd_Regular(f[i]),
  526. fp, visited, inputNames);
  527. Dddmp_CheckAndGotoLabel (retValue==0,
  528. "Error if function DddmpCuddDdArrayStorePrefixStep.", failure);
  529. }
  530. /* To account for the possible complement on the root,
  531. ** we put either a buffer or an inverter at the output of
  532. ** the multiplexer representing the top node.
  533. */
  534. for (i=0; i<n; i++) {
  535. if (outputNames == NULL) {
  536. retValue = fprintf (fp, "(BUF outNode%d ", i);
  537. } else {
  538. retValue = fprintf (fp, "(BUF %s ", outputNames[i]);
  539. }
  540. Dddmp_CheckAndGotoLabel (retValue==EOF,
  541. "Error during file store.", failure);
  542. if (Cudd_IsComplement(f[i])) {
  543. #if SIZEOF_VOID_P == 8
  544. retValue = fprintf (fp, "(NOT node%lx))\n",
  545. (unsigned long) f[i] / (unsigned long) sizeof(DdNode));
  546. #else
  547. retValue = fprintf (fp, "(NOT node%x))\n",
  548. (unsigned) f[i] / (unsigned) sizeof(DdNode));
  549. #endif
  550. } else {
  551. #if SIZEOF_VOID_P == 8
  552. retValue = fprintf (fp, "node%lx)\n",
  553. (unsigned long) f[i] / (unsigned long) sizeof(DdNode));
  554. #else
  555. retValue = fprintf (fp, "node%x)\n",
  556. (unsigned) f[i] / (unsigned) sizeof(DdNode));
  557. #endif
  558. }
  559. Dddmp_CheckAndGotoLabel (retValue==EOF,
  560. "Error during file store.", failure);
  561. }
  562. st_free_table (visited);
  563. return(1);
  564. failure:
  565. if (visited != NULL) st_free_table(visited);
  566. return(0);
  567. }
  568. /**Function********************************************************************
  569. Synopsis [Performs the recursive step of
  570. DddmpCuddDdArrayStorePrefixBody.]
  571. Description [Performs the recursive step of
  572. DddmpCuddDdArrayStorePrefixBody.
  573. Traverses the BDD f and writes a multiplexer-network description to the
  574. file pointed by fp.
  575. For each BDD node of function f, variable v, then child T, and else
  576. child E it stores:
  577. f = v * T + v' * E
  578. that is
  579. (OR f (AND v T) (AND (NOT v) E))
  580. If E is a complemented child this results in the following
  581. (OR f (AND v T) (AND (NOT v) (NOT E)))
  582. f is assumed to be a regular pointer and the function guarantees this
  583. assumption in the recursive calls.
  584. ]
  585. SideEffects [None]
  586. SeeAlso []
  587. ******************************************************************************/
  588. static int
  589. DddmpCuddDdArrayStorePrefixStep (
  590. DdManager * ddMgr,
  591. DdNode * f,
  592. FILE * fp,
  593. st_table * visited,
  594. char ** names
  595. )
  596. {
  597. DdNode *T, *E;
  598. int retValue;
  599. #ifdef DDDMP_DEBUG
  600. assert(!Cudd_IsComplement(f));
  601. #endif
  602. /* If already visited, nothing to do. */
  603. if (st_is_member(visited, (char *) f) == 1) {
  604. return(1);
  605. }
  606. /* Check for abnormal condition that should never happen. */
  607. if (f == NULL) {
  608. return(0);
  609. }
  610. /* Mark node as visited. */
  611. if (st_insert(visited, (char *) f, NULL) == ST_OUT_OF_MEM) {
  612. return(0);
  613. }
  614. /* Check for special case: If constant node, generate constant 1. */
  615. if (f == DD_ONE (ddMgr)) {
  616. #if SIZEOF_VOID_P == 8
  617. retValue = fprintf (fp,
  618. "(OR node%lx vss vdd)\n",
  619. (unsigned long) f / (unsigned long) sizeof(DdNode));
  620. #else
  621. retValue = fprintf (fp,
  622. "(OR node%x vss vdd)\n",
  623. (unsigned) f / (unsigned) sizeof(DdNode));
  624. #endif
  625. if (retValue == EOF) {
  626. return(0);
  627. } else {
  628. return(1);
  629. }
  630. }
  631. /*
  632. * Check whether this is an ADD. We deal with 0-1 ADDs, but not
  633. * with the general case.
  634. */
  635. if (f == DD_ZERO(ddMgr)) {
  636. #if SIZEOF_VOID_P == 8
  637. retValue = fprintf (fp,
  638. "(AND node%lx vss vdd)\n",
  639. (unsigned long) f / (unsigned long) sizeof(DdNode));
  640. #else
  641. retValue = fprintf (fp,
  642. "(AND node%x vss vdd)\n",
  643. (unsigned) f / (unsigned) sizeof(DdNode));
  644. #endif
  645. if (retValue == EOF) {
  646. return(0);
  647. } else {
  648. return(1);
  649. }
  650. }
  651. if (cuddIsConstant(f)) {
  652. return(0);
  653. }
  654. /* Recursive calls. */
  655. T = cuddT(f);
  656. retValue = DddmpCuddDdArrayStorePrefixStep (ddMgr,T,fp,visited,names);
  657. if (retValue != 1) {
  658. return(retValue);
  659. }
  660. E = Cudd_Regular(cuddE(f));
  661. retValue = DddmpCuddDdArrayStorePrefixStep (ddMgr,E,fp,visited,names);
  662. if (retValue != 1) {
  663. return(retValue);
  664. }
  665. /* Write multiplexer taking complement arc into account. */
  666. #if SIZEOF_VOID_P == 8
  667. retValue = fprintf (fp, "(OR node%lx (AND ",
  668. (unsigned long) f / (unsigned long) sizeof(DdNode));
  669. #else
  670. retValue = fprintf (fp, "(OR node%x (AND ",
  671. (unsigned) f / (unsigned) sizeof(DdNode));
  672. #endif
  673. if (retValue == EOF) {
  674. return(0);
  675. }
  676. if (names != NULL) {
  677. retValue = fprintf(fp, "%s ", names[f->index]);
  678. } else {
  679. retValue = fprintf(fp, "inNode%d ", f->index);
  680. }
  681. if (retValue == EOF) {
  682. return(0);
  683. }
  684. #if SIZEOF_VOID_P == 8
  685. retValue = fprintf (fp, "node%lx) (AND (NOT ",
  686. (unsigned long) T / (unsigned long) sizeof(DdNode));
  687. #else
  688. retValue = fprintf (fp, "node%x) (AND (NOT ",
  689. (unsigned) T / (unsigned) sizeof(DdNode));
  690. #endif
  691. if (retValue == EOF) {
  692. return(0);
  693. }
  694. if (names != NULL) {
  695. retValue = fprintf (fp, "%s", names[f->index]);
  696. } else {
  697. retValue = fprintf (fp, "inNode%d", f->index);
  698. }
  699. if (retValue == EOF) {
  700. return(0);
  701. }
  702. #if SIZEOF_VOID_P == 8
  703. if (Cudd_IsComplement(cuddE(f))) {
  704. retValue = fprintf (fp, ") (NOT node%lx)))\n",
  705. (unsigned long) E / (unsigned long) sizeof(DdNode));
  706. } else {
  707. retValue = fprintf (fp, ") node%lx))\n",
  708. (unsigned long) E / (unsigned long) sizeof(DdNode));
  709. }
  710. #else
  711. if (Cudd_IsComplement(cuddE(f))) {
  712. retValue = fprintf (fp, ") (NOT node%x)))\n",
  713. (unsigned) E / (unsigned) sizeof(DdNode));
  714. } else {
  715. retValue = fprintf (fp, ") node%x))\n",
  716. (unsigned) E / (unsigned) sizeof(DdNode));
  717. }
  718. #endif
  719. if (retValue == EOF) {
  720. return(0);
  721. } else {
  722. return(1);
  723. }
  724. }
  725. /**Function********************************************************************
  726. Synopsis [Writes a blif file representing the argument BDDs.]
  727. Description [Writes a blif file representing the argument BDDs as a
  728. network of multiplexers. One multiplexer is written for each BDD
  729. node. It returns 1 in case of success; 0 otherwise (e.g.,
  730. out-of-memory, file system full, or an ADD with constants different
  731. from 0 and 1).
  732. DddmpCuddDdArrayStoreBlif does not close the file: This is the
  733. caller responsibility.
  734. DddmpCuddDdArrayStoreBlif uses a minimal unique subset of
  735. the hexadecimal address of a node as name for it. If the argument
  736. inames is non-null, it is assumed to hold the pointers to the names
  737. of the inputs. Similarly for outputNames.
  738. It prefixes the string "NODE" to each nome to have "regular" names
  739. for each elements.
  740. ]
  741. SideEffects [None]
  742. SeeAlso [DddmpCuddDdArrayStoreBlifBody,Cudd_DumpBlif]
  743. ******************************************************************************/
  744. static int
  745. DddmpCuddDdArrayStoreBlif (
  746. DdManager *ddMgr /* IN: Manager */,
  747. int n /* IN: Number of output nodes to be dumped */,
  748. DdNode **f /* IN: Array of output nodes to be dumped */,
  749. char **inputNames /* IN: Array of input names (or NULL) */,
  750. char **outputNames /* IN: Array of output names (or NULL) */,
  751. char *modelName /* IN: Model name (or NULL) */,
  752. FILE *fp /* IN: Pointer to the dump file */
  753. )
  754. {
  755. DdNode *support = NULL;
  756. DdNode *scan;
  757. int *sorted = NULL;
  758. int nVars = ddMgr->size;
  759. int retValue;
  760. int i;
  761. /* Build a bit array with the support of f. */
  762. sorted = ALLOC (int, nVars);
  763. if (sorted == NULL) {
  764. ddMgr->errorCode = CUDD_MEMORY_OUT;
  765. Dddmp_CheckAndGotoLabel (1, "Allocation Error.", failure);
  766. }
  767. for (i = 0; i < nVars; i++) {
  768. sorted[i] = 0;
  769. }
  770. /* Take the union of the supports of each output function. */
  771. support = Cudd_VectorSupport(ddMgr,f,n);
  772. Dddmp_CheckAndGotoLabel (support==NULL,
  773. "Error in function Cudd_VectorSupport.", failure);
  774. cuddRef(support);
  775. scan = support;
  776. while (!cuddIsConstant(scan)) {
  777. sorted[scan->index] = 1;
  778. scan = cuddT(scan);
  779. }
  780. Cudd_RecursiveDeref(ddMgr,support);
  781. support = NULL;
  782. /* so that we do not try to free it in case of failure */
  783. /* Write the header (.model .inputs .outputs). */
  784. if (modelName == NULL) {
  785. retValue = fprintf(fp,".model DD\n.inputs");
  786. } else {
  787. retValue = fprintf(fp,".model %s\n.inputs", modelName);
  788. }
  789. if (retValue == EOF) {
  790. return(0);
  791. }
  792. /* Write the input list by scanning the support array. */
  793. for (i = 0; i < nVars; i++) {
  794. if (sorted[i]) {
  795. if (inputNames == NULL || (inputNames[i] == NULL)) {
  796. retValue = fprintf(fp," inNode%d", i);
  797. } else {
  798. retValue = fprintf(fp," %s", inputNames[i]);
  799. }
  800. Dddmp_CheckAndGotoLabel (retValue==EOF,
  801. "Error during file store.", failure);
  802. }
  803. }
  804. FREE(sorted);
  805. sorted = NULL;
  806. /* Write the .output line. */
  807. retValue = fprintf(fp,"\n.outputs");
  808. Dddmp_CheckAndGotoLabel (retValue==EOF,
  809. "Error during file store.", failure);
  810. for (i = 0; i < n; i++) {
  811. if (outputNames == NULL || (outputNames[i] == NULL)) {
  812. retValue = fprintf(fp," outNode%d", i);
  813. } else {
  814. retValue = fprintf(fp," %s", outputNames[i]);
  815. }
  816. Dddmp_CheckAndGotoLabel (retValue==EOF,
  817. "Error during file store.", failure);
  818. }
  819. retValue = fprintf(fp,"\n");
  820. Dddmp_CheckAndGotoLabel (retValue==EOF,
  821. "Error during file store.", failure);
  822. retValue = DddmpCuddDdArrayStoreBlifBody(ddMgr, n, f, inputNames,
  823. outputNames, fp);
  824. Dddmp_CheckAndGotoLabel (retValue==0,
  825. "Error if function DddmpCuddDdArrayStoreBlifBody.", failure);
  826. /* Write trailer and return. */
  827. retValue = fprintf (fp, ".end\n");
  828. Dddmp_CheckAndGotoLabel (retValue==EOF,
  829. "Error during file store.", failure);
  830. return(1);
  831. failure:
  832. if (sorted != NULL) {
  833. FREE(sorted);
  834. }
  835. if (support != NULL) {
  836. Cudd_RecursiveDeref(ddMgr,support);
  837. }
  838. return(0);
  839. }
  840. /**Function********************************************************************
  841. Synopsis [Writes a blif body representing the argument BDDs.]
  842. Description [Writes a blif body representing the argument BDDs as a
  843. network of multiplexers. One multiplexer is written for each BDD
  844. node. It returns 1 in case of success; 0 otherwise (e.g.,
  845. out-of-memory, file system full, or an ADD with constants different
  846. from 0 and 1).
  847. DddmpCuddDdArrayStoreBlif does not close the file: This is the
  848. caller responsibility.
  849. DddmpCuddDdArrayStoreBlif uses a minimal unique subset of
  850. the hexadecimal address of a node as name for it. If the argument
  851. inputNames is non-null, it is assumed to hold the pointers to the names
  852. of the inputs. Similarly for outputNames. This function prints out only
  853. .names part.
  854. ]
  855. SideEffects [None]
  856. SeeAlso []
  857. ******************************************************************************/
  858. static int
  859. DddmpCuddDdArrayStoreBlifBody (
  860. DdManager *ddMgr /* IN: Manager */,
  861. int n /* IN: Number of output nodes to be dumped */,
  862. DdNode **f /* IN: Array of output nodes to be dumped */,
  863. char **inputNames /* IN: Array of input names (or NULL) */,
  864. char **outputNames /* IN: Array of output names (or NULL) */,
  865. FILE *fp /* IN: Pointer to the dump file */
  866. )
  867. {
  868. st_table *visited = NULL;
  869. int retValue;
  870. int i;
  871. /* Initialize symbol table for visited nodes. */
  872. visited = st_init_table(st_ptrcmp, st_ptrhash);
  873. Dddmp_CheckAndGotoLabel (visited==NULL,
  874. "Error if function st_init_table.", failure);
  875. /* Call the function that really gets the job done. */
  876. for (i = 0; i < n; i++) {
  877. retValue = DddmpCuddDdArrayStoreBlifStep (ddMgr, Cudd_Regular(f[i]),
  878. fp, visited, inputNames);
  879. Dddmp_CheckAndGotoLabel (retValue==0,
  880. "Error if function DddmpCuddDdArrayStoreBlifStep.", failure);
  881. }
  882. /*
  883. * To account for the possible complement on the root,
  884. * we put either a buffer or an inverter at the output of
  885. * the multiplexer representing the top node.
  886. */
  887. for (i = 0; i < n; i++) {
  888. if (outputNames == NULL) {
  889. retValue = fprintf(fp,
  890. #if SIZEOF_VOID_P == 8
  891. ".names node%lx outNode%d\n",
  892. (unsigned long) f[i] / (unsigned long) sizeof(DdNode), i);
  893. #else
  894. ".names node%x outNode%d\n",
  895. (unsigned) f[i] / (unsigned) sizeof(DdNode), i);
  896. #endif
  897. } else {
  898. retValue = fprintf(fp,
  899. #if SIZEOF_VOID_P == 8
  900. ".names node%lx %s\n",
  901. (unsigned long) f[i] / (unsigned long) sizeof(DdNode), outputNames[i]);
  902. #else
  903. ".names node%x %s\n",
  904. (unsigned) f[i] / (unsigned) sizeof(DdNode), outputNames[i]);
  905. #endif
  906. }
  907. Dddmp_CheckAndGotoLabel (retValue==EOF,
  908. "Error during file store.", failure);
  909. if (Cudd_IsComplement(f[i])) {
  910. retValue = fprintf(fp,"0 1\n");
  911. } else {
  912. retValue = fprintf(fp,"1 1\n");
  913. }
  914. Dddmp_CheckAndGotoLabel (retValue==EOF,
  915. "Error during file store.", failure);
  916. }
  917. st_free_table(visited);
  918. return(1);
  919. failure:
  920. if (visited != NULL) {
  921. st_free_table(visited);
  922. }
  923. return(0);
  924. }
  925. /**Function********************************************************************
  926. Synopsis [Performs the recursive step of DddmpCuddDdArrayStoreBlif.]
  927. Description [Performs the recursive step of DddmpCuddDdArrayStoreBlif.
  928. Traverses the BDD f and writes a multiplexer-network description to
  929. the file pointed by fp in blif format.
  930. f is assumed to be a regular pointer and DddmpCuddDdArrayStoreBlifStep
  931. guarantees this assumption in the recursive calls.
  932. ]
  933. SideEffects [None]
  934. SeeAlso []
  935. ******************************************************************************/
  936. static int
  937. DddmpCuddDdArrayStoreBlifStep (
  938. DdManager *ddMgr,
  939. DdNode *f,
  940. FILE *fp,
  941. st_table *visited,
  942. char **names
  943. )
  944. {
  945. DdNode *T, *E;
  946. int retValue;
  947. #ifdef DDDMP_DEBUG
  948. assert(!Cudd_IsComplement(f));
  949. #endif
  950. /* If already visited, nothing to do. */
  951. if (st_is_member(visited, (char *) f) == 1) {
  952. return(1);
  953. }
  954. /* Check for abnormal condition that should never happen. */
  955. if (f == NULL) {
  956. return(0);
  957. }
  958. /* Mark node as visited. */
  959. if (st_insert(visited, (char *) f, NULL) == ST_OUT_OF_MEM) {
  960. return(0);
  961. }
  962. /* Check for special case: If constant node, generate constant 1. */
  963. if (f == DD_ONE(ddMgr)) {
  964. #if SIZEOF_VOID_P == 8
  965. retValue = fprintf(fp, ".names node%lx\n1\n",
  966. (unsigned long) f / (unsigned long) sizeof(DdNode));
  967. #else
  968. retValue = fprintf(fp, ".names node%x\n1\n",
  969. (unsigned) f / (unsigned) sizeof(DdNode));
  970. #endif
  971. if (retValue == EOF) {
  972. return(0);
  973. } else {
  974. return(1);
  975. }
  976. }
  977. /* Check whether this is an ADD. We deal with 0-1 ADDs, but not
  978. ** with the general case.
  979. */
  980. if (f == DD_ZERO(ddMgr)) {
  981. #if SIZEOF_VOID_P == 8
  982. retValue = fprintf(fp, ".names node%lx\n",
  983. (unsigned long) f / (unsigned long) sizeof(DdNode));
  984. #else
  985. retValue = fprintf(fp, ".names node%x\n",
  986. (unsigned) f / (unsigned) sizeof(DdNode));
  987. #endif
  988. if (retValue == EOF) {
  989. return(0);
  990. } else {
  991. return(1);
  992. }
  993. }
  994. if (cuddIsConstant(f)) {
  995. return(0);
  996. }
  997. /* Recursive calls. */
  998. T = cuddT(f);
  999. retValue = DddmpCuddDdArrayStoreBlifStep(ddMgr,T,fp,visited,names);
  1000. if (retValue != 1) return(retValue);
  1001. E = Cudd_Regular(cuddE(f));
  1002. retValue = DddmpCuddDdArrayStoreBlifStep(ddMgr,E,fp,visited,names);
  1003. if (retValue != 1) return(retValue);
  1004. /* Write multiplexer taking complement arc into account. */
  1005. if (names != NULL) {
  1006. retValue = fprintf(fp,".names %s", names[f->index]);
  1007. } else {
  1008. retValue = fprintf(fp,".names inNode%d", f->index);
  1009. }
  1010. if (retValue == EOF) {
  1011. return(0);
  1012. }
  1013. #if SIZEOF_VOID_P == 8
  1014. if (Cudd_IsComplement(cuddE(f))) {
  1015. retValue = fprintf(fp," node%lx node%lx node%lx\n11- 1\n0-0 1\n",
  1016. (unsigned long) T / (unsigned long) sizeof(DdNode),
  1017. (unsigned long) E / (unsigned long) sizeof(DdNode),
  1018. (unsigned long) f / (unsigned long) sizeof(DdNode));
  1019. } else {
  1020. retValue = fprintf(fp," node%lx node%lx node%lx\n11- 1\n0-1 1\n",
  1021. (unsigned long) T / (unsigned long) sizeof(DdNode),
  1022. (unsigned long) E / (unsigned long) sizeof(DdNode),
  1023. (unsigned long) f / (unsigned long) sizeof(DdNode));
  1024. }
  1025. #else
  1026. if (Cudd_IsComplement(cuddE(f))) {
  1027. retValue = fprintf(fp," node%x node%x node%x\n11- 1\n0-0 1\n",
  1028. (unsigned) T / (unsigned) sizeof(DdNode),
  1029. (unsigned) E / (unsigned) sizeof(DdNode),
  1030. (unsigned) f / (unsigned) sizeof(DdNode));
  1031. } else {
  1032. retValue = fprintf(fp," node%x node%x node%x\n11- 1\n0-1 1\n",
  1033. (unsigned) T / (unsigned) sizeof(DdNode),
  1034. (unsigned) E / (unsigned) sizeof(DdNode),
  1035. (unsigned) f / (unsigned) sizeof(DdNode));
  1036. }
  1037. #endif
  1038. if (retValue == EOF) {
  1039. return(0);
  1040. } else {
  1041. return(1);
  1042. }
  1043. }
  1044. /**Function********************************************************************
  1045. Synopsis [Internal function to writes a dump file representing the
  1046. argument BDD in a SMV notation.]
  1047. Description [One multiplexer is written for each BDD node.
  1048. It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file
  1049. system full, or an ADD with constants different from 0 and 1).
  1050. It does not close the file: This is the caller responsibility.
  1051. It uses a minimal unique subset of the hexadecimal address of a node as
  1052. name for it.
  1053. If the argument inputNames is non-null, it is assumed to hold the
  1054. pointers to the names of the inputs. Similarly for outputNames.
  1055. For each BDD node of function f, variable v, then child T, and else
  1056. child E it stores:
  1057. f = v * T + v' * E
  1058. that is
  1059. (OR f (AND v T) (AND (NOT v) E))
  1060. If E is a complemented child this results in the following
  1061. (OR f (AND v T) (AND (NOT v) (NOT E)))
  1062. Comments (COMMENT) are added at the beginning of the description to
  1063. describe inputs and outputs of the design.
  1064. A buffer (BUF) is add on the output to cope with complemented functions.
  1065. ]
  1066. SideEffects [None]
  1067. SeeAlso [DddmpCuddDdArrayStoreBlif]
  1068. ******************************************************************************/
  1069. static int
  1070. DddmpCuddDdArrayStoreSmv (
  1071. DdManager *ddMgr /* IN: Manager */,
  1072. int n /* IN: Number of output nodes to be dumped */,
  1073. DdNode **f /* IN: Array of output nodes to be dumped */,
  1074. char **inputNames /* IN: Array of input names (or NULL) */,
  1075. char **outputNames /* IN: Array of output names (or NULL) */,
  1076. char *modelName /* IN: Model name (or NULL) */,
  1077. FILE *fp /* IN: Pointer to the dump file */
  1078. )
  1079. {
  1080. DdNode *support = NULL;
  1081. DdNode *scan;
  1082. int *sorted = NULL;
  1083. int nVars = ddMgr->size;
  1084. int retValue;
  1085. int i;
  1086. /* Build a bit array with the support of f. */
  1087. sorted = ALLOC(int, nVars);
  1088. if (sorted == NULL) {
  1089. ddMgr->errorCode = CUDD_MEMORY_OUT;
  1090. Dddmp_CheckAndGotoLabel (1, "Allocation Error.", failure);
  1091. }
  1092. for (i = 0; i < nVars; i++) {
  1093. sorted[i] = 0;
  1094. }
  1095. /* Take the union of the supports of each output function. */
  1096. support = Cudd_VectorSupport(ddMgr,f,n);
  1097. Dddmp_CheckAndGotoLabel (support==NULL,
  1098. "Error in function Cudd_VectorSupport.", failure);
  1099. cuddRef(support);
  1100. scan = support;
  1101. while (!cuddIsConstant(scan)) {
  1102. sorted[scan->index] = 1;
  1103. scan = cuddT(scan);
  1104. }
  1105. Cudd_RecursiveDeref(ddMgr,support);
  1106. /* so that we do not try to free it in case of failure */
  1107. support = NULL;
  1108. /* Write the header */
  1109. if (modelName == NULL) {
  1110. retValue = fprintf (fp, "MODULE main -- Unknown\n");
  1111. } else {
  1112. retValue = fprintf (fp, "MODULE main -- %s\n", modelName);
  1113. }
  1114. if (retValue == EOF) {
  1115. return(0);
  1116. }
  1117. retValue = fprintf(fp, "IVAR\n");
  1118. if (retValue == EOF) {
  1119. return(0);
  1120. }
  1121. /* Write the input list by scanning the support array. */
  1122. for (i=0; i<nVars; i++) {
  1123. if (sorted[i]) {
  1124. if (inputNames == NULL) {
  1125. retValue = fprintf (fp, " inNode%d : boolean;\n", i);
  1126. } else {
  1127. retValue = fprintf (fp, " %s : boolean;\n", inputNames[i]);
  1128. }
  1129. Dddmp_CheckAndGotoLabel (retValue==EOF,
  1130. "Error during file store.", failure);
  1131. }
  1132. }
  1133. FREE(sorted);
  1134. sorted = NULL;
  1135. retValue = fprintf (fp, "\nDEFINE\n");
  1136. retValue = DddmpCuddDdArrayStoreSmvBody (ddMgr, n, f, inputNames,
  1137. outputNames, fp);
  1138. Dddmp_CheckAndGotoLabel (retValue==0,
  1139. "Error in function DddmpCuddDdArrayStoreSmvBody.", failure);
  1140. return(1);
  1141. failure:
  1142. if (sorted != NULL) {
  1143. FREE(sorted);
  1144. }
  1145. if (support != NULL) {
  1146. Cudd_RecursiveDeref(ddMgr,support);
  1147. }
  1148. return(0);
  1149. }
  1150. /**Function********************************************************************
  1151. Synopsis [Internal function to writes a dump file representing the
  1152. argument BDD in a SMV notation. Writes the body of the file.]
  1153. Description [One multiplexer is written for each BDD node.
  1154. It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file
  1155. system full, or an ADD with constants different from 0 and 1).
  1156. It does not close the file: This is the caller responsibility.
  1157. It uses a minimal unique subset of the hexadecimal address of a node as
  1158. name for it.
  1159. If the argument inputNames is non-null, it is assumed to hold the
  1160. pointers to the names of the inputs. Similarly for outputNames.
  1161. For each BDD node of function f, variable v, then child T, and else
  1162. child E it stores:
  1163. f = v * T + v' * E
  1164. that is
  1165. (OR f (AND v T) (AND (NOT v) E))
  1166. If E is a complemented child this results in the following
  1167. (OR f (AND v T) (AND (NOT v) (NOT E)))
  1168. ]
  1169. SideEffects [None]
  1170. SeeAlso [DddmpCuddDdArrayStoreBlif]
  1171. ******************************************************************************/
  1172. static int
  1173. DddmpCuddDdArrayStoreSmvBody (
  1174. DdManager *ddMgr /* IN: Manager */,
  1175. int n /* IN: Number of output nodes to be dumped */,
  1176. DdNode **f /* IN: Array of output nodes to be dumped */,
  1177. char **inputNames /* IN: Array of input names (or NULL) */,
  1178. char **outputNames /* IN: Array of output names (or NULL) */,
  1179. FILE *fp /* IN: Pointer to the dump file */
  1180. )
  1181. {
  1182. st_table *visited = NULL;
  1183. int retValue;
  1184. int i;
  1185. /* Initialize symbol table for visited nodes. */
  1186. visited = st_init_table(st_ptrcmp, st_ptrhash);
  1187. Dddmp_CheckAndGotoLabel (visited==NULL,
  1188. "Error if function st_init_table.", failure);
  1189. /* Call the function that really gets the job done. */
  1190. for (i = 0; i < n; i++) {
  1191. retValue = DddmpCuddDdArrayStoreSmvStep (ddMgr, Cudd_Regular(f[i]),
  1192. fp, visited, inputNames);
  1193. Dddmp_CheckAndGotoLabel (retValue==0,
  1194. "Error if function DddmpCuddDdArrayStoreSmvStep.", failure);
  1195. }
  1196. /*
  1197. * To account for the possible complement on the root,
  1198. * we put either a buffer or an inverter at the output of
  1199. * the multiplexer representing the top node.
  1200. */
  1201. for (i=0; i<n; i++) {
  1202. if (outputNames == NULL) {
  1203. retValue = fprintf (fp, "outNode%d := ", i);
  1204. } else {
  1205. retValue = fprintf (fp, "%s := ", outputNames[i]);
  1206. }
  1207. Dddmp_CheckAndGotoLabel (retValue==EOF,
  1208. "Error during file store.", failure);
  1209. if (Cudd_IsComplement(f[i])) {
  1210. #if SIZEOF_VOID_P == 8
  1211. retValue = fprintf (fp, "!node%lx\n",
  1212. (unsigned long) f[i] / (unsigned long) sizeof(DdNode));
  1213. #else
  1214. retValue = fprintf (fp, "!node%x\n",
  1215. (unsigned) f[i] / (unsigned) sizeof(DdNode));
  1216. #endif
  1217. } else {
  1218. #if SIZEOF_VOID_P == 8
  1219. retValue = fprintf (fp, "node%lx\n",
  1220. (unsigned long) f[i] / (unsigned long) sizeof(DdNode));
  1221. #else
  1222. retValue = fprintf (fp, "node%x\n",
  1223. (unsigned) f[i] / (unsigned) sizeof(DdNode));
  1224. #endif
  1225. }
  1226. Dddmp_CheckAndGotoLabel (retValue==EOF,
  1227. "Error during file store.", failure);
  1228. }
  1229. st_free_table (visited);
  1230. return(1);
  1231. failure:
  1232. if (visited != NULL) st_free_table(visited);
  1233. return(0);
  1234. }
  1235. /**Function********************************************************************
  1236. Synopsis [Performs the recursive step of
  1237. DddmpCuddDdArrayStoreSmvBody.]
  1238. Description [Performs the recursive step of
  1239. DddmpCuddDdArrayStoreSmvBody.
  1240. Traverses the BDD f and writes a multiplexer-network description to the
  1241. file pointed by fp.
  1242. For each BDD node of function f, variable v, then child T, and else
  1243. child E it stores:
  1244. f = v * T + v' * E
  1245. that is
  1246. (OR f (AND v T) (AND (NOT v) E))
  1247. If E is a complemented child this results in the following
  1248. (OR f (AND v T) (AND (NOT v) (NOT E)))
  1249. f is assumed to be a regular pointer and the function guarantees this
  1250. assumption in the recursive calls.
  1251. ]
  1252. SideEffects [None]
  1253. SeeAlso []
  1254. ******************************************************************************/
  1255. static int
  1256. DddmpCuddDdArrayStoreSmvStep (
  1257. DdManager * ddMgr,
  1258. DdNode * f,
  1259. FILE * fp,
  1260. st_table * visited,
  1261. char ** names
  1262. )
  1263. {
  1264. DdNode *T, *E;
  1265. int retValue;
  1266. #ifdef DDDMP_DEBUG
  1267. assert(!Cudd_IsComplement(f));
  1268. #endif
  1269. /* If already visited, nothing to do. */
  1270. if (st_is_member(visited, (char *) f) == 1) {
  1271. return(1);
  1272. }
  1273. /* Check for abnormal condition that should never happen. */
  1274. if (f == NULL) {
  1275. return(0);
  1276. }
  1277. /* Mark node as visited. */
  1278. if (st_insert(visited, (char *) f, NULL) == ST_OUT_OF_MEM) {
  1279. return(0);
  1280. }
  1281. /* Check for special case: If constant node, generate constant 1. */
  1282. if (f == DD_ONE (ddMgr)) {
  1283. #if SIZEOF_VOID_P == 8
  1284. retValue = fprintf (fp,
  1285. "node%lx := 1;\n",
  1286. (unsigned long) f / (unsigned long) sizeof(DdNode));
  1287. #else
  1288. retValue = fprintf (fp,
  1289. "node%x := 1;\n",
  1290. (unsigned) f / (unsigned) sizeof(DdNode));
  1291. #endif
  1292. if (retValue == EOF) {
  1293. return(0);
  1294. } else {
  1295. return(1);
  1296. }
  1297. }
  1298. /*
  1299. * Check whether this is an ADD. We deal with 0-1 ADDs, but not
  1300. * with the general case.
  1301. */
  1302. if (f == DD_ZERO(ddMgr)) {
  1303. #if SIZEOF_VOID_P == 8
  1304. retValue = fprintf (fp,
  1305. "node%lx := 0;\n",
  1306. (unsigned long) f / (unsigned long) sizeof(DdNode));
  1307. #else
  1308. retValue = fprintf (fp,
  1309. "node%x := 0;\n",
  1310. (unsigned) f / (unsigned) sizeof(DdNode));
  1311. #endif
  1312. if (retValue == EOF) {
  1313. return(0);
  1314. } else {
  1315. return(1);
  1316. }
  1317. }
  1318. if (cuddIsConstant(f)) {
  1319. return(0);
  1320. }
  1321. /* Recursive calls. */
  1322. T = cuddT(f);
  1323. retValue = DddmpCuddDdArrayStoreSmvStep (ddMgr,T,fp,visited,names);
  1324. if (retValue != 1) {
  1325. return(retValue);
  1326. }
  1327. E = Cudd_Regular(cuddE(f));
  1328. retValue = DddmpCuddDdArrayStoreSmvStep (ddMgr,E,fp,visited,names);
  1329. if (retValue != 1) {
  1330. return(retValue);
  1331. }
  1332. /* Write multiplexer taking complement arc into account. */
  1333. #if SIZEOF_VOID_P == 8
  1334. retValue = fprintf (fp, "node%lx := ",
  1335. (unsigned long) f / (unsigned long) sizeof(DdNode));
  1336. #else
  1337. retValue = fprintf (fp, "node%x := ",
  1338. (unsigned) f / (unsigned) sizeof(DdNode));
  1339. #endif
  1340. if (retValue == EOF) {
  1341. return(0);
  1342. }
  1343. if (names != NULL) {
  1344. retValue = fprintf(fp, "%s ", names[f->index]);
  1345. } else {
  1346. retValue = fprintf(fp, "inNode%d ", f->index);
  1347. }
  1348. if (retValue == EOF) {
  1349. return(0);
  1350. }
  1351. #if SIZEOF_VOID_P == 8
  1352. retValue = fprintf (fp, "& node%lx | ",
  1353. (unsigned long) T / (unsigned long) sizeof(DdNode));
  1354. #else
  1355. retValue = fprintf (fp, "& node%x | ",
  1356. (unsigned) T / (unsigned) sizeof(DdNode));
  1357. #endif
  1358. if (retValue == EOF) {
  1359. return(0);
  1360. }
  1361. if (names != NULL) {
  1362. retValue = fprintf (fp, "!%s ", names[f->index]);
  1363. } else {
  1364. retValue = fprintf (fp, "!inNode%d ", f->index);
  1365. }
  1366. if (retValue == EOF) {
  1367. return(0);
  1368. }
  1369. #if SIZEOF_VOID_P == 8
  1370. if (Cudd_IsComplement(cuddE(f))) {
  1371. retValue = fprintf (fp, "& !node%lx\n",
  1372. (unsigned long) E / (unsigned long) sizeof(DdNode));
  1373. } else {
  1374. retValue = fprintf (fp, "& node%lx\n",
  1375. (unsigned long) E / (unsigned long) sizeof(DdNode));
  1376. }
  1377. #else
  1378. if (Cudd_IsComplement(cuddE(f))) {
  1379. retValue = fprintf (fp, "& !node%x\n",
  1380. (unsigned) E / (unsigned) sizeof(DdNode));
  1381. } else {
  1382. retValue = fprintf (fp, "& node%x\n",
  1383. (unsigned) E / (unsigned) sizeof(DdNode));
  1384. }
  1385. #endif
  1386. if (retValue == EOF) {
  1387. return(0);
  1388. } else {
  1389. return(1);
  1390. }
  1391. }