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.

1522 lines
44 KiB

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