1 /**CFile**********************************************************************
3 FileName [dddmpStoreMisc.c]
7 Synopsis [Functions to write out bdds to file in prefixed
10 Description [Functions to write out bdds to file.
11 BDDs are represended on file in text format.
12 Each node is stored as a multiplexer in a prefix notation format for
13 the prefix notation file or in PLA format for the blif file.
16 Author [Gianpiero Cabodi and Stefano Quer]
19 Copyright (c) 2004 by Politecnico di Torino.
20 All Rights Reserved. This software is for educational purposes only.
21 Permission is given to academic institutions to use, copy, and modify
22 this software and its documentation provided that this introductory
23 message is not removed, that this software and its documentation is
24 used for the institutions' internal research and educational purposes,
25 and that no monies are exchanged. No guarantee is expressed or implied
26 by the distribution of this code.
27 Send bug-reports and/or questions to:
28 {gianpiero.cabodi,stefano.quer}@polito.it.
31 ******************************************************************************/
35 /*---------------------------------------------------------------------------*/
36 /* Stucture declarations */
37 /*---------------------------------------------------------------------------*/
39 /*---------------------------------------------------------------------------*/
40 /* Type declarations */
41 /*---------------------------------------------------------------------------*/
43 /*---------------------------------------------------------------------------*/
44 /* Variable declarations */
45 /*---------------------------------------------------------------------------*/
47 /*---------------------------------------------------------------------------*/
48 /* Macro declarations */
49 /*---------------------------------------------------------------------------*/
51 /**AutomaticStart*************************************************************/
53 /*---------------------------------------------------------------------------*/
54 /* Static function prototypes */
55 /*---------------------------------------------------------------------------*/
57 static int DddmpCuddDdArrayStorePrefix(DdManager
*ddMgr
, int n
, DdNode
**f
, char **inputNames
, char **outputNames
, char *modelName
, FILE *fp
);
58 static int DddmpCuddDdArrayStorePrefixBody(DdManager
*ddMgr
, int n
, DdNode
**f
, char **inputNames
, char **outputNames
, FILE *fp
);
59 static int DddmpCuddDdArrayStorePrefixStep(DdManager
* ddMgr
, DdNode
* f
, FILE * fp
, st_table
* visited
, char ** names
);
60 static int DddmpCuddDdArrayStoreBlif(DdManager
*ddMgr
, int n
, DdNode
**f
, char **inputNames
, char **outputNames
, char *modelName
, FILE *fp
);
61 static int DddmpCuddDdArrayStoreBlifBody(DdManager
*ddMgr
, int n
, DdNode
**f
, char **inputNames
, char **outputNames
, FILE *fp
);
62 static int DddmpCuddDdArrayStoreBlifStep(DdManager
*ddMgr
, DdNode
*f
, FILE *fp
, st_table
*visited
, char **names
);
63 static int DddmpCuddDdArrayStoreSmv(DdManager
*ddMgr
, int n
, DdNode
**f
, char **inputNames
, char **outputNames
, char *modelName
, FILE *fp
);
64 static int DddmpCuddDdArrayStoreSmvBody(DdManager
*ddMgr
, int n
, DdNode
**f
, char **inputNames
, char **outputNames
, FILE *fp
);
65 static int DddmpCuddDdArrayStoreSmvStep(DdManager
* ddMgr
, DdNode
* f
, FILE * fp
, st_table
* visited
, char ** names
);
67 /**AutomaticEnd***************************************************************/
69 /*---------------------------------------------------------------------------*/
70 /* Definition of exported functions */
71 /*---------------------------------------------------------------------------*/
73 /**Function********************************************************************
75 Synopsis [Writes a dump file representing the argument BDD in
78 Description [Dumps the argument BDD to file.
79 Dumping is done through Dddmp_cuddBddArrayStorePrefix.
80 A dummy array of 1 BDD root is used for this purpose.
85 SeeAlso [Dddmp_cuddBddStore]
87 ******************************************************************************/
90 Dddmp_cuddBddStorePrefix (
91 DdManager
*ddMgr
/* IN: DD Manager */,
92 int nRoots
/* IN: Number of BDD roots */,
93 DdNode
*f
/* IN: BDD root to be stored */,
94 char **inputNames
/* IN: Array of variable names */,
95 char **outputNames
/* IN: Array of root names */,
96 char *modelName
/* IN: Model Name */,
97 char *fileName
/* IN: File name */,
98 FILE *fp
/* IN: File pointer to the store file */
106 retValue
= Dddmp_cuddBddArrayStorePrefix (ddMgr
, 1, tmpArray
,
107 inputNames
, outputNames
, modelName
, fileName
, fp
);
112 /**Function********************************************************************
114 Synopsis [Writes a dump file representing the argument BDD in
117 Description [Dumps the argument BDD to file.
118 Dumping is done through Dddmp_cuddBddArrayStorePrefix.
119 A dummy array of 1 BDD root is used for this purpose.
124 SeeAlso [Dddmp_cuddBddArrayStore]
126 ******************************************************************************/
129 Dddmp_cuddBddArrayStorePrefix (
130 DdManager
*ddMgr
/* IN: DD Manager */,
131 int nroots
/* IN: number of output BDD roots to be stored */,
132 DdNode
**f
/* IN: array of BDD roots to be stored */,
133 char **inputNames
/* IN: array of variable names (or NULL) */,
134 char **outputNames
/* IN: array of root names (or NULL) */,
135 char *modelName
/* IN: Model Name */,
136 char *fname
/* IN: File name */,
137 FILE *fp
/* IN: File pointer to the store file */
147 retValueBis
= Cudd_DebugCheck (ddMgr
);
148 if (retValueBis
== 1) {
149 fprintf (stderr
, "Inconsistency Found During BDD Store.\n");
152 if (retValueBis
== CUDD_OUT_OF_MEM
) {
153 fprintf (stderr
, "Out of Memory During BDD Store.\n");
161 * Check if File needs to be opened in the proper mode.
165 fp
= fopen (fname
, "w");
166 Dddmp_CheckAndGotoLabel (fp
==NULL
, "Error opening file.",
171 retValue
= DddmpCuddDdArrayStorePrefix (ddMgr
, nroots
, f
,
172 inputNames
, outputNames
, modelName
, fp
);
180 retValueBis
= Cudd_DebugCheck (ddMgr
);
181 if (retValueBis
== 1) {
182 fprintf (stderr
, "Inconsistency Found During BDD Store.\n");
185 if (retValueBis
== CUDD_OUT_OF_MEM
) {
186 fprintf (stderr
, "Out of Memory During BDD Store.\n");
196 return (DDDMP_FAILURE
);
199 /**Function********************************************************************
201 Synopsis [Writes a dump file representing the argument BDD in
202 a Blif/Exlif notation.]
204 Description [Dumps the argument BDD to file.
205 Dumping is done through Dddmp_cuddBddArrayStoreBlif.
206 A dummy array of 1 BDD root is used for this purpose.
211 SeeAlso [Dddmp_cuddBddStorePrefix]
213 ******************************************************************************/
216 Dddmp_cuddBddStoreBlif (
217 DdManager
*ddMgr
/* IN: DD Manager */,
218 int nRoots
/* IN: Number of BDD roots */,
219 DdNode
*f
/* IN: BDD root to be stored */,
220 char **inputNames
/* IN: Array of variable names */,
221 char **outputNames
/* IN: Array of root names */,
222 char *modelName
/* IN: Model Name */,
223 char *fileName
/* IN: File name */,
224 FILE *fp
/* IN: File pointer to the store file */
232 retValue
= Dddmp_cuddBddArrayStoreBlif (ddMgr
, 1, tmpArray
,
233 inputNames
, outputNames
, modelName
, fileName
, fp
);
238 /**Function********************************************************************
240 Synopsis [Writes a dump file representing the argument BDD in
241 a Blif/Exlif notation.]
243 Description [Dumps the argument BDD to file.
244 Dumping is done through Dddmp_cuddBddArrayStoreBLif.
245 A dummy array of 1 BDD root is used for this purpose.
250 SeeAlso [Dddmp_cuddBddArrayStorePrefix]
252 ******************************************************************************/
255 Dddmp_cuddBddArrayStoreBlif (
256 DdManager
*ddMgr
/* IN: DD Manager */,
257 int nroots
/* IN: number of output BDD roots to be stored */,
258 DdNode
**f
/* IN: array of BDD roots to be stored */,
259 char **inputNames
/* IN: array of variable names (or NULL) */,
260 char **outputNames
/* IN: array of root names (or NULL) */,
261 char *modelName
/* IN: Model Name */,
262 char *fname
/* IN: File name */,
263 FILE *fp
/* IN: File pointer to the store file */
273 retValueBis
= Cudd_DebugCheck (ddMgr
);
274 if (retValueBis
== 1) {
275 fprintf (stderr
, "Inconsistency Found During BDD Store.\n");
278 if (retValueBis
== CUDD_OUT_OF_MEM
) {
279 fprintf (stderr
, "Out of Memory During BDD Store.\n");
287 * Check if File needs to be opened in the proper mode.
291 fp
= fopen (fname
, "w");
292 Dddmp_CheckAndGotoLabel (fp
==NULL
, "Error opening file.",
297 retValue
= DddmpCuddDdArrayStoreBlif (ddMgr
, nroots
, f
,
298 inputNames
, outputNames
, modelName
, fp
);
306 retValueBis
= Cudd_DebugCheck (ddMgr
);
307 if (retValueBis
== 1) {
308 fprintf (stderr
, "Inconsistency Found During BDD Store.\n");
311 if (retValueBis
== CUDD_OUT_OF_MEM
) {
312 fprintf (stderr
, "Out of Memory During BDD Store.\n");
322 return (DDDMP_FAILURE
);
325 /**Function********************************************************************
327 Synopsis [Writes a dump file representing the argument BDD in
330 Description [Dumps the argument BDD to file.
331 Dumping is done through Dddmp_cuddBddArrayStorePrefix.
332 A dummy array of 1 BDD root is used for this purpose.
337 SeeAlso [Dddmp_cuddBddStore]
339 ******************************************************************************/
342 Dddmp_cuddBddStoreSmv (
343 DdManager
*ddMgr
/* IN: DD Manager */,
344 int nRoots
/* IN: Number of BDD roots */,
345 DdNode
*f
/* IN: BDD root to be stored */,
346 char **inputNames
/* IN: Array of variable names */,
347 char **outputNames
/* IN: Array of root names */,
348 char *modelName
/* IN: Model Name */,
349 char *fileName
/* IN: File name */,
350 FILE *fp
/* IN: File pointer to the store file */
358 retValue
= Dddmp_cuddBddArrayStoreSmv (ddMgr
, 1, tmpArray
,
359 inputNames
, outputNames
, modelName
, fileName
, fp
);
364 /**Function********************************************************************
366 Synopsis [Writes a dump file representing the argument BDD in
369 Description [Dumps the argument BDD to file.
370 Dumping is done through Dddmp_cuddBddArrayStorePrefix.
371 A dummy array of 1 BDD root is used for this purpose.
376 SeeAlso [Dddmp_cuddBddArrayStore]
378 ******************************************************************************/
381 Dddmp_cuddBddArrayStoreSmv (
382 DdManager
*ddMgr
/* IN: DD Manager */,
383 int nroots
/* IN: number of output BDD roots to be stored */,
384 DdNode
**f
/* IN: array of BDD roots to be stored */,
385 char **inputNames
/* IN: array of variable names (or NULL) */,
386 char **outputNames
/* IN: array of root names (or NULL) */,
387 char *modelName
/* IN: Model Name */,
388 char *fname
/* IN: File name */,
389 FILE *fp
/* IN: File pointer to the store file */
399 retValueBis
= Cudd_DebugCheck (ddMgr
);
400 if (retValueBis
== 1) {
401 fprintf (stderr
, "Inconsistency Found During BDD Store.\n");
404 if (retValueBis
== CUDD_OUT_OF_MEM
) {
405 fprintf (stderr
, "Out of Memory During BDD Store.\n");
413 * Check if File needs to be opened in the proper mode.
417 fp
= fopen (fname
, "w");
418 Dddmp_CheckAndGotoLabel (fp
==NULL
, "Error opening file.",
423 retValue
= DddmpCuddDdArrayStoreSmv (ddMgr
, nroots
, f
,
424 inputNames
, outputNames
, modelName
, fp
);
432 retValueBis
= Cudd_DebugCheck (ddMgr
);
433 if (retValueBis
== 1) {
434 fprintf (stderr
, "Inconsistency Found During BDD Store.\n");
437 if (retValueBis
== CUDD_OUT_OF_MEM
) {
438 fprintf (stderr
, "Out of Memory During BDD Store.\n");
448 return (DDDMP_FAILURE
);
451 /*---------------------------------------------------------------------------*/
452 /* Definition of static functions */
453 /*---------------------------------------------------------------------------*/
455 /**Function********************************************************************
457 Synopsis [Internal function to writes a dump file representing the
458 argument BDD in a prefix notation.]
460 Description [One multiplexer is written for each BDD node.
461 It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file
462 system full, or an ADD with constants different from 0 and 1).
463 It does not close the file: This is the caller responsibility.
464 It uses a minimal unique subset of the hexadecimal address of a node as
466 If the argument inputNames is non-null, it is assumed to hold the
467 pointers to the names of the inputs. Similarly for outputNames.
468 For each BDD node of function f, variable v, then child T, and else
472 (OR f (AND v T) (AND (NOT v) E))
473 If E is a complemented child this results in the following
474 (OR f (AND v T) (AND (NOT v) (NOT E)))
475 Comments (COMMENT) are added at the beginning of the description to
476 describe inputs and outputs of the design.
477 A buffer (BUF) is add on the output to cope with complemented functions.
482 SeeAlso [DddmpCuddDdArrayStoreBlif]
484 ******************************************************************************/
487 DddmpCuddDdArrayStorePrefix (
488 DdManager
*ddMgr
/* IN: Manager */,
489 int n
/* IN: Number of output nodes to be dumped */,
490 DdNode
**f
/* IN: Array of output nodes to be dumped */,
491 char **inputNames
/* IN: Array of input names (or NULL) */,
492 char **outputNames
/* IN: Array of output names (or NULL) */,
493 char *modelName
/* IN: Model name (or NULL) */,
494 FILE *fp
/* IN: Pointer to the dump file */
497 DdNode
*support
= NULL
;
500 int nVars
= ddMgr
->size
;
504 /* Build a bit array with the support of f. */
505 sorted
= ALLOC(int, nVars
);
506 if (sorted
== NULL
) {
507 ddMgr
->errorCode
= CUDD_MEMORY_OUT
;
508 Dddmp_CheckAndGotoLabel (1, "Allocation Error.", failure
);
510 for (i
= 0; i
< nVars
; i
++) {
514 /* Take the union of the supports of each output function. */
515 support
= Cudd_VectorSupport(ddMgr
,f
,n
);
516 Dddmp_CheckAndGotoLabel (support
==NULL
,
517 "Error in function Cudd_VectorSupport.", failure
);
520 while (!cuddIsConstant(scan
)) {
521 sorted
[scan
->index
] = 1;
524 Cudd_RecursiveDeref(ddMgr
,support
);
525 /* so that we do not try to free it in case of failure */
528 /* Write the header (.model .inputs .outputs). */
529 if (modelName
== NULL
) {
530 retValue
= fprintf (fp
, "(COMMENT - model name: Unknown )\n");
532 retValue
= fprintf (fp
, "(COMMENT - model name: %s )\n", modelName
);
534 if (retValue
== EOF
) {
538 retValue
= fprintf(fp
, "(COMMENT - input names: ");
539 if (retValue
== EOF
) {
542 /* Write the input list by scanning the support array. */
543 for (i
= 0; i
< nVars
; i
++) {
545 if (inputNames
== NULL
) {
546 retValue
= fprintf(fp
," inNode%d", i
);
548 retValue
= fprintf(fp
," %s", inputNames
[i
]);
550 Dddmp_CheckAndGotoLabel (retValue
==EOF
,
551 "Error during file store.", failure
);
556 retValue
= fprintf(fp
, " )\n");
557 if (retValue
== EOF
) {
561 /* Write the .output line. */
562 retValue
= fprintf(fp
,"(COMMENT - output names: ");
563 if (retValue
== EOF
) {
566 for (i
= 0; i
< n
; i
++) {
567 if (outputNames
== NULL
) {
568 retValue
= fprintf (fp
," outNode%d", i
);
570 retValue
= fprintf (fp
," %s", outputNames
[i
]);
572 Dddmp_CheckAndGotoLabel (retValue
==EOF
,
573 "Error during file store.", failure
);
575 retValue
= fprintf(fp
, " )\n");
576 Dddmp_CheckAndGotoLabel (retValue
==EOF
,
577 "Error during file store.", failure
);
579 retValue
= DddmpCuddDdArrayStorePrefixBody (ddMgr
, n
, f
, inputNames
,
581 Dddmp_CheckAndGotoLabel (retValue
==0,
582 "Error in function DddmpCuddDdArrayStorePrefixBody.", failure
);
587 if (sorted
!= NULL
) {
590 if (support
!= NULL
) {
591 Cudd_RecursiveDeref(ddMgr
,support
);
596 /**Function********************************************************************
598 Synopsis [Internal function to writes a dump file representing the
599 argument BDD in a prefix notation. Writes the body of the file.]
601 Description [One multiplexer is written for each BDD node.
602 It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file
603 system full, or an ADD with constants different from 0 and 1).
604 It does not close the file: This is the caller responsibility.
605 It uses a minimal unique subset of the hexadecimal address of a node as
607 If the argument inputNames is non-null, it is assumed to hold the
608 pointers to the names of the inputs. Similarly for outputNames.
609 For each BDD node of function f, variable v, then child T, and else
613 (OR f (AND v T) (AND (NOT v) E))
614 If E is a complemented child this results in the following
615 (OR f (AND v T) (AND (NOT v) (NOT E)))
620 SeeAlso [DddmpCuddDdArrayStoreBlif]
622 ******************************************************************************/
625 DddmpCuddDdArrayStorePrefixBody (
626 DdManager
*ddMgr
/* IN: Manager */,
627 int n
/* IN: Number of output nodes to be dumped */,
628 DdNode
**f
/* IN: Array of output nodes to be dumped */,
629 char **inputNames
/* IN: Array of input names (or NULL) */,
630 char **outputNames
/* IN: Array of output names (or NULL) */,
631 FILE *fp
/* IN: Pointer to the dump file */
634 st_table
*visited
= NULL
;
638 /* Initialize symbol table for visited nodes. */
639 visited
= st_init_table(st_ptrcmp
, st_ptrhash
);
640 Dddmp_CheckAndGotoLabel (visited
==NULL
,
641 "Error if function st_init_table.", failure
);
643 /* Call the function that really gets the job done. */
644 for (i
= 0; i
< n
; i
++) {
645 retValue
= DddmpCuddDdArrayStorePrefixStep (ddMgr
, Cudd_Regular(f
[i
]),
646 fp
, visited
, inputNames
);
647 Dddmp_CheckAndGotoLabel (retValue
==0,
648 "Error if function DddmpCuddDdArrayStorePrefixStep.", failure
);
651 /* To account for the possible complement on the root,
652 ** we put either a buffer or an inverter at the output of
653 ** the multiplexer representing the top node.
655 for (i
=0; i
<n
; i
++) {
656 if (outputNames
== NULL
) {
657 retValue
= fprintf (fp
, "(BUF outNode%d ", i
);
659 retValue
= fprintf (fp
, "(BUF %s ", outputNames
[i
]);
661 Dddmp_CheckAndGotoLabel (retValue
==EOF
,
662 "Error during file store.", failure
);
664 if (Cudd_IsComplement(f
[i
])) {
665 #if SIZEOF_VOID_P == 8
666 retValue
= fprintf (fp
, "(NOT node%lx))\n",
667 (unsigned long) f
[i
] / (unsigned long) sizeof(DdNode
));
669 retValue
= fprintf (fp
, "(NOT node%x))\n",
670 (unsigned) f
[i
] / (unsigned) sizeof(DdNode
));
673 #if SIZEOF_VOID_P == 8
674 retValue
= fprintf (fp
, "node%lx)\n",
675 (unsigned long) f
[i
] / (unsigned long) sizeof(DdNode
));
677 retValue
= fprintf (fp
, "node%x)\n",
678 (unsigned) f
[i
] / (unsigned) sizeof(DdNode
));
681 Dddmp_CheckAndGotoLabel (retValue
==EOF
,
682 "Error during file store.", failure
);
685 st_free_table (visited
);
690 if (visited
!= NULL
) st_free_table(visited
);
695 /**Function********************************************************************
697 Synopsis [Performs the recursive step of
698 DddmpCuddDdArrayStorePrefixBody.]
700 Description [Performs the recursive step of
701 DddmpCuddDdArrayStorePrefixBody.
702 Traverses the BDD f and writes a multiplexer-network description to the
704 For each BDD node of function f, variable v, then child T, and else
708 (OR f (AND v T) (AND (NOT v) E))
709 If E is a complemented child this results in the following
710 (OR f (AND v T) (AND (NOT v) (NOT E)))
711 f is assumed to be a regular pointer and the function guarantees this
712 assumption in the recursive calls.
719 ******************************************************************************/
722 DddmpCuddDdArrayStorePrefixStep (
734 assert(!Cudd_IsComplement(f
));
737 /* If already visited, nothing to do. */
738 if (st_is_member(visited
, (char *) f
) == 1) {
742 /* Check for abnormal condition that should never happen. */
747 /* Mark node as visited. */
748 if (st_insert(visited
, (char *) f
, NULL
) == ST_OUT_OF_MEM
) {
752 /* Check for special case: If constant node, generate constant 1. */
753 if (f
== DD_ONE (ddMgr
)) {
754 #if SIZEOF_VOID_P == 8
755 retValue
= fprintf (fp
,
756 "(OR node%lx vss vdd)\n",
757 (unsigned long) f
/ (unsigned long) sizeof(DdNode
));
759 retValue
= fprintf (fp
,
760 "(OR node%x vss vdd)\n",
761 (unsigned) f
/ (unsigned) sizeof(DdNode
));
763 if (retValue
== EOF
) {
771 * Check whether this is an ADD. We deal with 0-1 ADDs, but not
772 * with the general case.
775 if (f
== DD_ZERO(ddMgr
)) {
776 #if SIZEOF_VOID_P == 8
777 retValue
= fprintf (fp
,
778 "(AND node%lx vss vdd)\n",
779 (unsigned long) f
/ (unsigned long) sizeof(DdNode
));
781 retValue
= fprintf (fp
,
782 "(AND node%x vss vdd)\n",
783 (unsigned) f
/ (unsigned) sizeof(DdNode
));
785 if (retValue
== EOF
) {
792 if (cuddIsConstant(f
)) {
796 /* Recursive calls. */
798 retValue
= DddmpCuddDdArrayStorePrefixStep (ddMgr
,T
,fp
,visited
,names
);
802 E
= Cudd_Regular(cuddE(f
));
803 retValue
= DddmpCuddDdArrayStorePrefixStep (ddMgr
,E
,fp
,visited
,names
);
808 /* Write multiplexer taking complement arc into account. */
809 #if SIZEOF_VOID_P == 8
810 retValue
= fprintf (fp
, "(OR node%lx (AND ",
811 (unsigned long) f
/ (unsigned long) sizeof(DdNode
));
813 retValue
= fprintf (fp
, "(OR node%x (AND ",
814 (unsigned) f
/ (unsigned) sizeof(DdNode
));
816 if (retValue
== EOF
) {
821 retValue
= fprintf(fp
, "%s ", names
[f
->index
]);
823 retValue
= fprintf(fp
, "inNode%d ", f
->index
);
825 if (retValue
== EOF
) {
829 #if SIZEOF_VOID_P == 8
830 retValue
= fprintf (fp
, "node%lx) (AND (NOT ",
831 (unsigned long) T
/ (unsigned long) sizeof(DdNode
));
833 retValue
= fprintf (fp
, "node%x) (AND (NOT ",
834 (unsigned) T
/ (unsigned) sizeof(DdNode
));
836 if (retValue
== EOF
) {
841 retValue
= fprintf (fp
, "%s", names
[f
->index
]);
843 retValue
= fprintf (fp
, "inNode%d", f
->index
);
845 if (retValue
== EOF
) {
849 #if SIZEOF_VOID_P == 8
850 if (Cudd_IsComplement(cuddE(f
))) {
851 retValue
= fprintf (fp
, ") (NOT node%lx)))\n",
852 (unsigned long) E
/ (unsigned long) sizeof(DdNode
));
854 retValue
= fprintf (fp
, ") node%lx))\n",
855 (unsigned long) E
/ (unsigned long) sizeof(DdNode
));
858 if (Cudd_IsComplement(cuddE(f
))) {
859 retValue
= fprintf (fp
, ") (NOT node%x)))\n",
860 (unsigned) E
/ (unsigned) sizeof(DdNode
));
862 retValue
= fprintf (fp
, ") node%x))\n",
863 (unsigned) E
/ (unsigned) sizeof(DdNode
));
867 if (retValue
== EOF
) {
874 /**Function********************************************************************
876 Synopsis [Writes a blif file representing the argument BDDs.]
878 Description [Writes a blif file representing the argument BDDs as a
879 network of multiplexers. One multiplexer is written for each BDD
880 node. It returns 1 in case of success; 0 otherwise (e.g.,
881 out-of-memory, file system full, or an ADD with constants different
883 DddmpCuddDdArrayStoreBlif does not close the file: This is the
884 caller responsibility.
885 DddmpCuddDdArrayStoreBlif uses a minimal unique subset of
886 the hexadecimal address of a node as name for it. If the argument
887 inames is non-null, it is assumed to hold the pointers to the names
888 of the inputs. Similarly for outputNames.
889 It prefixes the string "NODE" to each nome to have "regular" names
895 SeeAlso [DddmpCuddDdArrayStoreBlifBody,Cudd_DumpBlif]
897 ******************************************************************************/
900 DddmpCuddDdArrayStoreBlif (
901 DdManager
*ddMgr
/* IN: Manager */,
902 int n
/* IN: Number of output nodes to be dumped */,
903 DdNode
**f
/* IN: Array of output nodes to be dumped */,
904 char **inputNames
/* IN: Array of input names (or NULL) */,
905 char **outputNames
/* IN: Array of output names (or NULL) */,
906 char *modelName
/* IN: Model name (or NULL) */,
907 FILE *fp
/* IN: Pointer to the dump file */
910 DdNode
*support
= NULL
;
913 int nVars
= ddMgr
->size
;
917 /* Build a bit array with the support of f. */
918 sorted
= ALLOC (int, nVars
);
919 if (sorted
== NULL
) {
920 ddMgr
->errorCode
= CUDD_MEMORY_OUT
;
921 Dddmp_CheckAndGotoLabel (1, "Allocation Error.", failure
);
923 for (i
= 0; i
< nVars
; i
++) {
927 /* Take the union of the supports of each output function. */
928 support
= Cudd_VectorSupport(ddMgr
,f
,n
);
929 Dddmp_CheckAndGotoLabel (support
==NULL
,
930 "Error in function Cudd_VectorSupport.", failure
);
933 while (!cuddIsConstant(scan
)) {
934 sorted
[scan
->index
] = 1;
937 Cudd_RecursiveDeref(ddMgr
,support
);
939 /* so that we do not try to free it in case of failure */
941 /* Write the header (.model .inputs .outputs). */
942 if (modelName
== NULL
) {
943 retValue
= fprintf(fp
,".model DD\n.inputs");
945 retValue
= fprintf(fp
,".model %s\n.inputs", modelName
);
947 if (retValue
== EOF
) {
951 /* Write the input list by scanning the support array. */
952 for (i
= 0; i
< nVars
; i
++) {
954 if (inputNames
== NULL
|| (inputNames
[i
] == NULL
)) {
955 retValue
= fprintf(fp
," inNode%d", i
);
957 retValue
= fprintf(fp
," %s", inputNames
[i
]);
959 Dddmp_CheckAndGotoLabel (retValue
==EOF
,
960 "Error during file store.", failure
);
966 /* Write the .output line. */
967 retValue
= fprintf(fp
,"\n.outputs");
968 Dddmp_CheckAndGotoLabel (retValue
==EOF
,
969 "Error during file store.", failure
);
970 for (i
= 0; i
< n
; i
++) {
971 if (outputNames
== NULL
|| (outputNames
[i
] == NULL
)) {
972 retValue
= fprintf(fp
," outNode%d", i
);
974 retValue
= fprintf(fp
," %s", outputNames
[i
]);
976 Dddmp_CheckAndGotoLabel (retValue
==EOF
,
977 "Error during file store.", failure
);
979 retValue
= fprintf(fp
,"\n");
980 Dddmp_CheckAndGotoLabel (retValue
==EOF
,
981 "Error during file store.", failure
);
983 retValue
= DddmpCuddDdArrayStoreBlifBody(ddMgr
, n
, f
, inputNames
,
985 Dddmp_CheckAndGotoLabel (retValue
==0,
986 "Error if function DddmpCuddDdArrayStoreBlifBody.", failure
);
988 /* Write trailer and return. */
989 retValue
= fprintf (fp
, ".end\n");
990 Dddmp_CheckAndGotoLabel (retValue
==EOF
,
991 "Error during file store.", failure
);
996 if (sorted
!= NULL
) {
999 if (support
!= NULL
) {
1000 Cudd_RecursiveDeref(ddMgr
,support
);
1007 /**Function********************************************************************
1009 Synopsis [Writes a blif body representing the argument BDDs.]
1011 Description [Writes a blif body representing the argument BDDs as a
1012 network of multiplexers. One multiplexer is written for each BDD
1013 node. It returns 1 in case of success; 0 otherwise (e.g.,
1014 out-of-memory, file system full, or an ADD with constants different
1016 DddmpCuddDdArrayStoreBlif does not close the file: This is the
1017 caller responsibility.
1018 DddmpCuddDdArrayStoreBlif uses a minimal unique subset of
1019 the hexadecimal address of a node as name for it. If the argument
1020 inputNames is non-null, it is assumed to hold the pointers to the names
1021 of the inputs. Similarly for outputNames. This function prints out only
1029 ******************************************************************************/
1032 DddmpCuddDdArrayStoreBlifBody (
1033 DdManager
*ddMgr
/* IN: Manager */,
1034 int n
/* IN: Number of output nodes to be dumped */,
1035 DdNode
**f
/* IN: Array of output nodes to be dumped */,
1036 char **inputNames
/* IN: Array of input names (or NULL) */,
1037 char **outputNames
/* IN: Array of output names (or NULL) */,
1038 FILE *fp
/* IN: Pointer to the dump file */
1041 st_table
*visited
= NULL
;
1045 /* Initialize symbol table for visited nodes. */
1046 visited
= st_init_table(st_ptrcmp
, st_ptrhash
);
1047 Dddmp_CheckAndGotoLabel (visited
==NULL
,
1048 "Error if function st_init_table.", failure
);
1050 /* Call the function that really gets the job done. */
1051 for (i
= 0; i
< n
; i
++) {
1052 retValue
= DddmpCuddDdArrayStoreBlifStep (ddMgr
, Cudd_Regular(f
[i
]),
1053 fp
, visited
, inputNames
);
1054 Dddmp_CheckAndGotoLabel (retValue
==0,
1055 "Error if function DddmpCuddDdArrayStoreBlifStep.", failure
);
1059 * To account for the possible complement on the root,
1060 * we put either a buffer or an inverter at the output of
1061 * the multiplexer representing the top node.
1064 for (i
= 0; i
< n
; i
++) {
1065 if (outputNames
== NULL
) {
1066 retValue
= fprintf(fp
,
1067 #if SIZEOF_VOID_P == 8
1068 ".names node%lx outNode%d\n",
1069 (unsigned long) f
[i
] / (unsigned long) sizeof(DdNode
), i
);
1071 ".names node%x outNode%d\n",
1072 (unsigned) f
[i
] / (unsigned) sizeof(DdNode
), i
);
1075 retValue
= fprintf(fp
,
1076 #if SIZEOF_VOID_P == 8
1077 ".names node%lx %s\n",
1078 (unsigned long) f
[i
] / (unsigned long) sizeof(DdNode
), outputNames
[i
]);
1080 ".names node%x %s\n",
1081 (unsigned) f
[i
] / (unsigned) sizeof(DdNode
), outputNames
[i
]);
1084 Dddmp_CheckAndGotoLabel (retValue
==EOF
,
1085 "Error during file store.", failure
);
1086 if (Cudd_IsComplement(f
[i
])) {
1087 retValue
= fprintf(fp
,"0 1\n");
1089 retValue
= fprintf(fp
,"1 1\n");
1091 Dddmp_CheckAndGotoLabel (retValue
==EOF
,
1092 "Error during file store.", failure
);
1095 st_free_table(visited
);
1099 if (visited
!= NULL
) {
1100 st_free_table(visited
);
1105 /**Function********************************************************************
1107 Synopsis [Performs the recursive step of DddmpCuddDdArrayStoreBlif.]
1109 Description [Performs the recursive step of DddmpCuddDdArrayStoreBlif.
1110 Traverses the BDD f and writes a multiplexer-network description to
1111 the file pointed by fp in blif format.
1112 f is assumed to be a regular pointer and DddmpCuddDdArrayStoreBlifStep
1113 guarantees this assumption in the recursive calls.
1120 ******************************************************************************/
1123 DddmpCuddDdArrayStoreBlifStep (
1135 assert(!Cudd_IsComplement(f
));
1138 /* If already visited, nothing to do. */
1139 if (st_is_member(visited
, (char *) f
) == 1) {
1143 /* Check for abnormal condition that should never happen. */
1148 /* Mark node as visited. */
1149 if (st_insert(visited
, (char *) f
, NULL
) == ST_OUT_OF_MEM
) {
1153 /* Check for special case: If constant node, generate constant 1. */
1154 if (f
== DD_ONE(ddMgr
)) {
1155 #if SIZEOF_VOID_P == 8
1156 retValue
= fprintf(fp
, ".names node%lx\n1\n",
1157 (unsigned long) f
/ (unsigned long) sizeof(DdNode
));
1159 retValue
= fprintf(fp
, ".names node%x\n1\n",
1160 (unsigned) f
/ (unsigned) sizeof(DdNode
));
1162 if (retValue
== EOF
) {
1169 /* Check whether this is an ADD. We deal with 0-1 ADDs, but not
1170 ** with the general case.
1172 if (f
== DD_ZERO(ddMgr
)) {
1173 #if SIZEOF_VOID_P == 8
1174 retValue
= fprintf(fp
, ".names node%lx\n",
1175 (unsigned long) f
/ (unsigned long) sizeof(DdNode
));
1177 retValue
= fprintf(fp
, ".names node%x\n",
1178 (unsigned) f
/ (unsigned) sizeof(DdNode
));
1180 if (retValue
== EOF
) {
1186 if (cuddIsConstant(f
)) {
1190 /* Recursive calls. */
1192 retValue
= DddmpCuddDdArrayStoreBlifStep(ddMgr
,T
,fp
,visited
,names
);
1193 if (retValue
!= 1) return(retValue
);
1194 E
= Cudd_Regular(cuddE(f
));
1195 retValue
= DddmpCuddDdArrayStoreBlifStep(ddMgr
,E
,fp
,visited
,names
);
1196 if (retValue
!= 1) return(retValue
);
1198 /* Write multiplexer taking complement arc into account. */
1199 if (names
!= NULL
) {
1200 retValue
= fprintf(fp
,".names %s", names
[f
->index
]);
1202 retValue
= fprintf(fp
,".names inNode%d", f
->index
);
1204 if (retValue
== EOF
) {
1208 #if SIZEOF_VOID_P == 8
1209 if (Cudd_IsComplement(cuddE(f
))) {
1210 retValue
= fprintf(fp
," node%lx node%lx node%lx\n11- 1\n0-0 1\n",
1211 (unsigned long) T
/ (unsigned long) sizeof(DdNode
),
1212 (unsigned long) E
/ (unsigned long) sizeof(DdNode
),
1213 (unsigned long) f
/ (unsigned long) sizeof(DdNode
));
1215 retValue
= fprintf(fp
," node%lx node%lx node%lx\n11- 1\n0-1 1\n",
1216 (unsigned long) T
/ (unsigned long) sizeof(DdNode
),
1217 (unsigned long) E
/ (unsigned long) sizeof(DdNode
),
1218 (unsigned long) f
/ (unsigned long) sizeof(DdNode
));
1221 if (Cudd_IsComplement(cuddE(f
))) {
1222 retValue
= fprintf(fp
," node%x node%x node%x\n11- 1\n0-0 1\n",
1223 (unsigned) T
/ (unsigned) sizeof(DdNode
),
1224 (unsigned) E
/ (unsigned) sizeof(DdNode
),
1225 (unsigned) f
/ (unsigned) sizeof(DdNode
));
1227 retValue
= fprintf(fp
," node%x node%x node%x\n11- 1\n0-1 1\n",
1228 (unsigned) T
/ (unsigned) sizeof(DdNode
),
1229 (unsigned) E
/ (unsigned) sizeof(DdNode
),
1230 (unsigned) f
/ (unsigned) sizeof(DdNode
));
1233 if (retValue
== EOF
) {
1240 /**Function********************************************************************
1242 Synopsis [Internal function to writes a dump file representing the
1243 argument BDD in a SMV notation.]
1245 Description [One multiplexer is written for each BDD node.
1246 It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file
1247 system full, or an ADD with constants different from 0 and 1).
1248 It does not close the file: This is the caller responsibility.
1249 It uses a minimal unique subset of the hexadecimal address of a node as
1251 If the argument inputNames is non-null, it is assumed to hold the
1252 pointers to the names of the inputs. Similarly for outputNames.
1253 For each BDD node of function f, variable v, then child T, and else
1257 (OR f (AND v T) (AND (NOT v) E))
1258 If E is a complemented child this results in the following
1259 (OR f (AND v T) (AND (NOT v) (NOT E)))
1260 Comments (COMMENT) are added at the beginning of the description to
1261 describe inputs and outputs of the design.
1262 A buffer (BUF) is add on the output to cope with complemented functions.
1267 SeeAlso [DddmpCuddDdArrayStoreBlif]
1269 ******************************************************************************/
1272 DddmpCuddDdArrayStoreSmv (
1273 DdManager
*ddMgr
/* IN: Manager */,
1274 int n
/* IN: Number of output nodes to be dumped */,
1275 DdNode
**f
/* IN: Array of output nodes to be dumped */,
1276 char **inputNames
/* IN: Array of input names (or NULL) */,
1277 char **outputNames
/* IN: Array of output names (or NULL) */,
1278 char *modelName
/* IN: Model name (or NULL) */,
1279 FILE *fp
/* IN: Pointer to the dump file */
1282 DdNode
*support
= NULL
;
1285 int nVars
= ddMgr
->size
;
1289 /* Build a bit array with the support of f. */
1290 sorted
= ALLOC(int, nVars
);
1291 if (sorted
== NULL
) {
1292 ddMgr
->errorCode
= CUDD_MEMORY_OUT
;
1293 Dddmp_CheckAndGotoLabel (1, "Allocation Error.", failure
);
1295 for (i
= 0; i
< nVars
; i
++) {
1299 /* Take the union of the supports of each output function. */
1300 support
= Cudd_VectorSupport(ddMgr
,f
,n
);
1301 Dddmp_CheckAndGotoLabel (support
==NULL
,
1302 "Error in function Cudd_VectorSupport.", failure
);
1305 while (!cuddIsConstant(scan
)) {
1306 sorted
[scan
->index
] = 1;
1309 Cudd_RecursiveDeref(ddMgr
,support
);
1310 /* so that we do not try to free it in case of failure */
1313 /* Write the header */
1314 if (modelName
== NULL
) {
1315 retValue
= fprintf (fp
, "MODULE main -- Unknown\n");
1317 retValue
= fprintf (fp
, "MODULE main -- %s\n", modelName
);
1319 if (retValue
== EOF
) {
1323 retValue
= fprintf(fp
, "IVAR\n");
1324 if (retValue
== EOF
) {
1328 /* Write the input list by scanning the support array. */
1329 for (i
=0; i
<nVars
; i
++) {
1331 if (inputNames
== NULL
) {
1332 retValue
= fprintf (fp
, " inNode%d : boolean;\n", i
);
1334 retValue
= fprintf (fp
, " %s : boolean;\n", inputNames
[i
]);
1336 Dddmp_CheckAndGotoLabel (retValue
==EOF
,
1337 "Error during file store.", failure
);
1343 retValue
= fprintf (fp
, "\nDEFINE\n");
1345 retValue
= DddmpCuddDdArrayStoreSmvBody (ddMgr
, n
, f
, inputNames
,
1347 Dddmp_CheckAndGotoLabel (retValue
==0,
1348 "Error in function DddmpCuddDdArrayStoreSmvBody.", failure
);
1353 if (sorted
!= NULL
) {
1356 if (support
!= NULL
) {
1357 Cudd_RecursiveDeref(ddMgr
,support
);
1362 /**Function********************************************************************
1364 Synopsis [Internal function to writes a dump file representing the
1365 argument BDD in a SMV notation. Writes the body of the file.]
1367 Description [One multiplexer is written for each BDD node.
1368 It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file
1369 system full, or an ADD with constants different from 0 and 1).
1370 It does not close the file: This is the caller responsibility.
1371 It uses a minimal unique subset of the hexadecimal address of a node as
1373 If the argument inputNames is non-null, it is assumed to hold the
1374 pointers to the names of the inputs. Similarly for outputNames.
1375 For each BDD node of function f, variable v, then child T, and else
1379 (OR f (AND v T) (AND (NOT v) E))
1380 If E is a complemented child this results in the following
1381 (OR f (AND v T) (AND (NOT v) (NOT E)))
1386 SeeAlso [DddmpCuddDdArrayStoreBlif]
1388 ******************************************************************************/
1391 DddmpCuddDdArrayStoreSmvBody (
1392 DdManager
*ddMgr
/* IN: Manager */,
1393 int n
/* IN: Number of output nodes to be dumped */,
1394 DdNode
**f
/* IN: Array of output nodes to be dumped */,
1395 char **inputNames
/* IN: Array of input names (or NULL) */,
1396 char **outputNames
/* IN: Array of output names (or NULL) */,
1397 FILE *fp
/* IN: Pointer to the dump file */
1400 st_table
*visited
= NULL
;
1404 /* Initialize symbol table for visited nodes. */
1405 visited
= st_init_table(st_ptrcmp
, st_ptrhash
);
1406 Dddmp_CheckAndGotoLabel (visited
==NULL
,
1407 "Error if function st_init_table.", failure
);
1409 /* Call the function that really gets the job done. */
1410 for (i
= 0; i
< n
; i
++) {
1411 retValue
= DddmpCuddDdArrayStoreSmvStep (ddMgr
, Cudd_Regular(f
[i
]),
1412 fp
, visited
, inputNames
);
1413 Dddmp_CheckAndGotoLabel (retValue
==0,
1414 "Error if function DddmpCuddDdArrayStoreSmvStep.", failure
);
1418 * To account for the possible complement on the root,
1419 * we put either a buffer or an inverter at the output of
1420 * the multiplexer representing the top node.
1423 for (i
=0; i
<n
; i
++) {
1424 if (outputNames
== NULL
) {
1425 retValue
= fprintf (fp
, "outNode%d := ", i
);
1427 retValue
= fprintf (fp
, "%s := ", outputNames
[i
]);
1429 Dddmp_CheckAndGotoLabel (retValue
==EOF
,
1430 "Error during file store.", failure
);
1432 if (Cudd_IsComplement(f
[i
])) {
1433 #if SIZEOF_VOID_P == 8
1434 retValue
= fprintf (fp
, "!node%lx\n",
1435 (unsigned long) f
[i
] / (unsigned long) sizeof(DdNode
));
1437 retValue
= fprintf (fp
, "!node%x\n",
1438 (unsigned) f
[i
] / (unsigned) sizeof(DdNode
));
1441 #if SIZEOF_VOID_P == 8
1442 retValue
= fprintf (fp
, "node%lx\n",
1443 (unsigned long) f
[i
] / (unsigned long) sizeof(DdNode
));
1445 retValue
= fprintf (fp
, "node%x\n",
1446 (unsigned) f
[i
] / (unsigned) sizeof(DdNode
));
1449 Dddmp_CheckAndGotoLabel (retValue
==EOF
,
1450 "Error during file store.", failure
);
1453 st_free_table (visited
);
1458 if (visited
!= NULL
) st_free_table(visited
);
1463 /**Function********************************************************************
1465 Synopsis [Performs the recursive step of
1466 DddmpCuddDdArrayStoreSmvBody.]
1468 Description [Performs the recursive step of
1469 DddmpCuddDdArrayStoreSmvBody.
1470 Traverses the BDD f and writes a multiplexer-network description to the
1472 For each BDD node of function f, variable v, then child T, and else
1476 (OR f (AND v T) (AND (NOT v) E))
1477 If E is a complemented child this results in the following
1478 (OR f (AND v T) (AND (NOT v) (NOT E)))
1479 f is assumed to be a regular pointer and the function guarantees this
1480 assumption in the recursive calls.
1487 ******************************************************************************/
1490 DddmpCuddDdArrayStoreSmvStep (
1502 assert(!Cudd_IsComplement(f
));
1505 /* If already visited, nothing to do. */
1506 if (st_is_member(visited
, (char *) f
) == 1) {
1510 /* Check for abnormal condition that should never happen. */
1515 /* Mark node as visited. */
1516 if (st_insert(visited
, (char *) f
, NULL
) == ST_OUT_OF_MEM
) {
1520 /* Check for special case: If constant node, generate constant 1. */
1521 if (f
== DD_ONE (ddMgr
)) {
1522 #if SIZEOF_VOID_P == 8
1523 retValue
= fprintf (fp
,
1525 (unsigned long) f
/ (unsigned long) sizeof(DdNode
));
1527 retValue
= fprintf (fp
,
1529 (unsigned) f
/ (unsigned) sizeof(DdNode
));
1531 if (retValue
== EOF
) {
1539 * Check whether this is an ADD. We deal with 0-1 ADDs, but not
1540 * with the general case.
1543 if (f
== DD_ZERO(ddMgr
)) {
1544 #if SIZEOF_VOID_P == 8
1545 retValue
= fprintf (fp
,
1547 (unsigned long) f
/ (unsigned long) sizeof(DdNode
));
1549 retValue
= fprintf (fp
,
1551 (unsigned) f
/ (unsigned) sizeof(DdNode
));
1553 if (retValue
== EOF
) {
1560 if (cuddIsConstant(f
)) {
1564 /* Recursive calls. */
1566 retValue
= DddmpCuddDdArrayStoreSmvStep (ddMgr
,T
,fp
,visited
,names
);
1567 if (retValue
!= 1) {
1570 E
= Cudd_Regular(cuddE(f
));
1571 retValue
= DddmpCuddDdArrayStoreSmvStep (ddMgr
,E
,fp
,visited
,names
);
1572 if (retValue
!= 1) {
1576 /* Write multiplexer taking complement arc into account. */
1577 #if SIZEOF_VOID_P == 8
1578 retValue
= fprintf (fp
, "node%lx := ",
1579 (unsigned long) f
/ (unsigned long) sizeof(DdNode
));
1581 retValue
= fprintf (fp
, "node%x := ",
1582 (unsigned) f
/ (unsigned) sizeof(DdNode
));
1584 if (retValue
== EOF
) {
1588 if (names
!= NULL
) {
1589 retValue
= fprintf(fp
, "%s ", names
[f
->index
]);
1591 retValue
= fprintf(fp
, "inNode%d ", f
->index
);
1593 if (retValue
== EOF
) {
1597 #if SIZEOF_VOID_P == 8
1598 retValue
= fprintf (fp
, "& node%lx | ",
1599 (unsigned long) T
/ (unsigned long) sizeof(DdNode
));
1601 retValue
= fprintf (fp
, "& node%x | ",
1602 (unsigned) T
/ (unsigned) sizeof(DdNode
));
1604 if (retValue
== EOF
) {
1608 if (names
!= NULL
) {
1609 retValue
= fprintf (fp
, "!%s ", names
[f
->index
]);
1611 retValue
= fprintf (fp
, "!inNode%d ", f
->index
);
1613 if (retValue
== EOF
) {
1617 #if SIZEOF_VOID_P == 8
1618 if (Cudd_IsComplement(cuddE(f
))) {
1619 retValue
= fprintf (fp
, "& !node%lx\n",
1620 (unsigned long) E
/ (unsigned long) sizeof(DdNode
));
1622 retValue
= fprintf (fp
, "& node%lx\n",
1623 (unsigned long) E
/ (unsigned long) sizeof(DdNode
));
1626 if (Cudd_IsComplement(cuddE(f
))) {
1627 retValue
= fprintf (fp
, "& !node%x\n",
1628 (unsigned) E
/ (unsigned) sizeof(DdNode
));
1630 retValue
= fprintf (fp
, "& node%x\n",
1631 (unsigned) E
/ (unsigned) sizeof(DdNode
));
1635 if (retValue
== EOF
) {