2 * This file is part of the Alliance CAD System
3 * Copyright (C) Laboratoire LIP6 - Département ASIM
4 * Universite Pierre et Marie Curie
6 * Home page : http://www-asim.lip6.fr/alliance/
7 * E-mail support : mailto:alliance-support@asim.lip6.fr
9 * This progam is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
14 * Alliance VLSI CAD System is distributed in the hope that it will be
15 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
17 * Public License for more details.
19 * You should have received a copy of the GNU General Public License along
20 * with the GNU C Library; see the file COPYING. If not, write to the Free
21 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 * Tool : ABL, BDD, HT Librarie
28 * Modified by Czo <Olivier.Sirol@lip6.fr> 1996,97
34 #ident "$Id: log_bdd1.c,v 1.18 2008/03/03 14:27:54 gregoire Exp $"
37 /****************************************************************************/
38 /* Produit : librairie BDD - Gestion de BDD */
39 /****************************************************************************/
49 /*------------------------------------------------------------------------------
50 initializeCct :cree un circuit .
51 -------------------------------------------------------
52 parametres :nom du circuit, nombre d'entrees et nombre de sorties .
53 -------------------------------------------------------
54 return :pointeur de circuit.
55 ------------------------------------------------------------------------------*/
57 initializeCct (name
, nbI
, nbO
)
68 pC
= (pCircuit
) mbkalloc (sizeof (struct circuit
));
70 pC
->pTI
= createTH (2 * nbI
);
71 pC
->pTO
= createTH (2 * nbO
);
72 pC
->pNameI
= (char **) mbkalloc (sizeof (char *) * 2 * nbI
);
74 for (i
= 0; i
< 2 * nbI
; i
++)
82 /*------------------------------------------------------------------------------
83 resetCct :vide un circuit .
84 -------------------------------------------------------
85 parametres :pointeur de circuit.
86 -------------------------------------------------------
88 ------------------------------------------------------------------------------*/
97 pEl
= (pC
->pTI
)->pElem
;
98 for (i
= 0; i
< (pC
->pTI
)->length
; i
++)
100 pEl
->value
= EMPTYTH
;
103 pEl
= (pC
->pTO
)->pElem
;
104 for (i
= 0; i
< (pC
->pTO
)->length
; i
++)
106 pEl
->value
= EMPTYTH
;
110 for (i
= 0; i
< (pC
->pTI
)->length
; i
++)
118 /*------------------------------------------------------------------------------
119 destroyCct :desalloue un circuit .
120 -------------------------------------------------------
121 parametres :pointeur de circuit.
122 -------------------------------------------------------
124 ------------------------------------------------------------------------------*/
131 mbkfree (pC
->pNameI
);
134 /*------------------------------------------------------------------------------
135 searchOutputCct :recherche le GDB associe a une sortie .
136 -------------------------------------------------------
137 parametres :un pointeur sur le circuit, et le nom de la sortie.
138 -------------------------------------------------------
139 return :pointeur de GDB ou null.
140 ------------------------------------------------------------------------------*/
142 searchOutputCct_no_NA (pC
, name
)
148 if (name
!=namefind(name
)) exit(10);
150 if ((res
= searchTH (pC
->pTO
, name
)) != EMPTYTH
)
151 return ((pNode
) res
);
157 searchOutputCct (pC
, name
)
161 return searchOutputCct_no_NA (pC
, namealloc (name
));
163 /*------------------------------------------------------------------------------
164 addOutputCct :ajoute un GDB associe a une sortie .
165 -------------------------------------------------------
166 parametres :un pointeur sur le GDB,un pointeur de circuit, et le nom
168 -------------------------------------------------------
170 ------------------------------------------------------------------------------*/
172 addOutputCct_no_NA (pC
, name
, pt
)
178 if (name
!=namefind(name
)) exit(10);
180 addTH (pC
->pTO
, name
, (long)pt
);
184 addOutputCct (pC
, name
, pt
)
189 addOutputCct_no_NA (pC
, namealloc(name
), pt
);
191 /*------------------------------------------------------------------------------
192 searchIndexCct :recherche entree associe a un index .
193 -------------------------------------------------------
194 parametres :un pointeur sur le circuit, et l'index
195 -------------------------------------------------------
196 return : NULL ou le pointeur namealloc
197 ------------------------------------------------------------------------------*/
199 searchIndexCct (pC
, index
)
203 if (index
<= pC
->countI
)
204 return (*(pC
->pNameI
+ index
- 2));
208 /*------------------------------------------------------------------------------
209 searchInputCct :recherche index associe a une entree .
210 -------------------------------------------------------
211 parametres :un pointeur sur le circuit, et le nom de l' entree.
212 -------------------------------------------------------
213 return :index ou EMPTYTH.
214 ------------------------------------------------------------------------------*/
216 searchInputCct_no_NA (pC
, name
)
224 if (name
!=namefind(name
)) exit(10);
226 reallocTH
= (pC
->pTI
)->length
;
227 resul
= searchTH (pC
->pTI
, name
);
229 /* on doit reallouer pNameI */
231 if (reallocTH
!= (pC
->pTI
)->length
)
234 char **pOldName
= pC
->pNameI
;
235 char **pOldSave
= pC
->pNameI
;
238 pC
->pNameI
= (char **) mbkalloc (sizeof (char *) * (pC
->pTI
)->length
);
240 for (i
= 0; i
< reallocTH
&& *pOldName
!= NULL
; i
++)
247 /* mise a null du reste de la table */
249 for (j
= i
; j
< (pC
->pTI
)->length
; j
++)
260 searchInputCct (pC
, name
)
264 return searchInputCct_no_NA (pC
, namealloc(name
));
266 /*------------------------------------------------------------------------------
267 addInputCct :ajoute une entree dans la table des var_index.
268 -------------------------------------------------------
269 parametres :un pointeur de circuit, et le nom de la variable
270 -------------------------------------------------------
272 ------------------------------------------------------------------------------*/
274 addInputCct_no_NA (pC
, name
)
282 if (name
!=namefind(name
)) exit(10);
284 if ((index
= searchInputCct_no_NA (pC
, name
)) != EMPTYTH
)
286 createNodeTermBdd (index
);
294 reallocTH
= (pC
->pTI
)->length
;
295 addTH (pC
->pTI
, name
, index
);
297 /* on doit reallouer pNameI */
299 if (reallocTH
!= (pC
->pTI
)->length
)
302 char **pOldName
= pC
->pNameI
;
303 char **pOldSave
= pC
->pNameI
;
306 pC
->pNameI
= (char **) mbkalloc (sizeof (char *) * (pC
->pTI
)->length
);
308 for (i
= 0; i
< (pC
->pTI
)->length
&& *pOldName
!= NULL
; i
++)
315 /* mise a null du reste de la table */
317 for (j
= i
; j
< (pC
->pTI
)->length
; j
++)
324 ptName
= pC
->pNameI
+ pC
->countI
- 2; /* ajout du nom d'INPUT */
326 if (pC
->countI
== SHRT_MAX
) {
327 avt_errmsg(LOG_ERRMSG
,"001",AVT_FATAL
);
328 // fprintf(stderr, "[LOG ERR] Maximum number of variables for BDDs reached\n");
332 createNodeTermBdd (index
);
338 addInputCct (pC
, name
)
342 return addInputCct_no_NA (pC
, namealloc(name
));
344 /*------------------------------------------------------------------------------
345 delInputCct :detruit une entree dans la table des var_index.
346 -------------------------------------------------------
347 parametres :un pointeur de circuit, et le nom de la variable
348 -------------------------------------------------------
350 ------------------------------------------------------------------------------*/
352 delInputCct (pC
, name
)
356 deleteTH (pC
->pTI
, name
);
359 /*------------------------------------------------------------------------------
360 displayCct :visualise le circuit .
361 -------------------------------------------------------
362 parametres :un pointeur de circuit.
363 -------------------------------------------------------
365 ------------------------------------------------------------------------------*/
367 displayCct (pCircuit pC
, int mode
)
373 pEl
= (pC
->pTI
)->pElem
;
375 printf("******* DISPLAY %s *******\n", pC
->name
);
376 for (i
= 0; i
< (pC
->pTI
)->length
; i
++)
378 if (pEl
->value
!= EMPTYTH
&& pEl
->value
!= DELETETH
)
379 printf("INPUT = %s INDEX = %ld\n",(char*) pEl
->key
, pEl
->value
);
383 printf("------------- NUMBER OF INPUTS : %d\n\n", (pC
->countI
) - 2);
384 pEl
= (pC
->pTO
)->pElem
;
385 for (i
= 0; i
< (pC
->pTO
)->length
; i
++)
387 if (pEl
->value
!= EMPTYTH
&& pEl
->value
!= DELETETH
)
388 markBdd ((pNode
)pEl
->value
, 0);
391 pEl
= (pC
->pTO
)->pElem
;
392 for (i
= 0; i
< (pC
->pTO
)->length
; i
++)
394 if (pEl
->value
!= EMPTYTH
&& pEl
->value
!= DELETETH
)
397 printf("OUTPUT = %s",(char*) pEl
->key
);
400 printf(" BDD = %ld\n", pEl
->value
);
401 displayBddName (TRUE
, (pNode
)pEl
->value
, pC
->pNameI
);
406 printf("%s = ",(char*) pEl
->key
);
407 displayExpr (tempabl
=bddToAbl ((pNode
)pEl
->value
, pC
->pNameI
));
414 pEl
= (pC
->pTO
)->pElem
;
415 for (i
= 0; i
< (pC
->pTO
)->length
; i
++)
417 if (pEl
->value
!= EMPTYTH
&& pEl
->value
!= DELETETH
)
418 markBdd ((pNode
)pEl
->value
, 0);
421 printf("------------- NUMBER OF OUTPUTS : %d\n", cpt
);
422 printf("**************************************\n\n");
426 displayCctLog (int lib
, int loglevel
, pCircuit pC
, int mode
)
432 pEl
= (pC
->pTI
)->pElem
;
433 avt_log(lib
,loglevel
,"\n");
434 avt_log(lib
,loglevel
,"******* DISPLAY %s *******\n", pC
->name
);
435 for (i
= 0; i
< (pC
->pTI
)->length
; i
++)
437 if (pEl
->value
!= EMPTYTH
&& pEl
->value
!= DELETETH
)
438 avt_log(lib
,loglevel
,"INPUT = %s INDEX = %ld\n",(char*) pEl
->key
, pEl
->value
);
441 avt_log(lib
,loglevel
,"\n");
442 avt_log(lib
,loglevel
,"------------- NUMBER OF INPUTS : %d\n\n", (pC
->countI
) - 2);
443 pEl
= (pC
->pTO
)->pElem
;
444 for (i
= 0; i
< (pC
->pTO
)->length
; i
++)
446 if (pEl
->value
!= EMPTYTH
&& pEl
->value
!= DELETETH
)
447 markBdd ((pNode
)pEl
->value
, 0);
450 pEl
= (pC
->pTO
)->pElem
;
451 for (i
= 0; i
< (pC
->pTO
)->length
; i
++)
453 if (pEl
->value
!= EMPTYTH
&& pEl
->value
!= DELETETH
)
456 avt_log(lib
,loglevel
,"OUTPUT = %s",(char*) pEl
->key
);
459 avt_log(lib
,loglevel
," BDD = %ld\n", pEl
->value
);
460 displayBddNameLog (lib
, loglevel
, TRUE
, (pNode
)pEl
->value
, pC
->pNameI
);
464 avt_log(lib
,loglevel
,"\n");
465 avt_log(lib
,loglevel
,"%s = ",(char*) pEl
->key
);
466 displayExprLog(lib
, loglevel
, tempabl
=bddToAbl ((pNode
)pEl
->value
, pC
->pNameI
));
469 avt_log(lib
,loglevel
,"\n");
473 pEl
= (pC
->pTO
)->pElem
;
474 for (i
= 0; i
< (pC
->pTO
)->length
; i
++)
476 if (pEl
->value
!= EMPTYTH
&& pEl
->value
!= DELETETH
)
477 markBdd ((pNode
)pEl
->value
, 0);
480 avt_log(lib
,2,"------------- NUMBER OF OUTPUTS : %d\n", cpt
);
481 avt_log(lib
,2,"**************************************\n\n");
484 /*------------------------------------------------------------------------------
485 composeCct :compose tous les GDB de pC en expansant l'entree name .
486 -------------------------------------------------------
487 parametres :un pointeur de circuit,nom d'entree,le GDB associe.
488 -------------------------------------------------------
490 ------------------------------------------------------------------------------*/
492 composeCct (pC
, name
, pt
)
501 pEl
= (pC
->pTO
)->pElem
; /* pointeur courant de la table pTI */
502 index
= searchInputCct (pC
, name
);
503 if (index
== EMPTYTH
)
505 avt_errmsg(LOG_ERRMSG
,"000",AVT_FATAL
,"178");
506 // printf ("bdd1-composeCct : la variable a expanser n'est pas une entree\n");
509 for (i
= 0; i
< (pC
->pTO
)->length
; i
++)
511 if (pEl
->value
!= EMPTYTH
&& pEl
->value
!= DELETETH
)
512 pEl
->value
= (long) composeBdd ((pNode
)pEl
->value
, pt
, index
);
515 deleteTH (pC
->pTI
, name
); /* on elimine name des INPUT */
518 /*------------------------------------------------------------------------------
519 constraintCct :contraint tous les GDB de pC avec le GDB pointe par pt .
520 -------------------------------------------------------
521 parametres :un pointeur de circuit,le GDB .
522 -------------------------------------------------------
524 ------------------------------------------------------------------------------*/
526 constraintCct (pC
, pt
)
533 pEl
= (pC
->pTO
)->pElem
; /* pointeur courant de la table pTO */
534 for (i
= 0; i
< (pC
->pTO
)->length
; i
++)
536 if (pEl
->value
!= EMPTYTH
&& pEl
->value
!= DELETETH
)
537 pEl
->value
= (long) constraintBdd ((pNode
)pEl
->value
, pt
);
541 /*------------------------------------------------------------------------------
542 proofCct :preuve formelle de circuits .
543 -------------------------------------------------------
544 parametres :deux pointeurs de circuits .
545 -------------------------------------------------------
547 ------------------------------------------------------------------------------*/
558 printf("\n\n******* PROOF between %s & %s *******\n", pC1
->name
, pC2
->name
);
559 pEl
= (pC1
->pTI
)->pElem
; /* pointeur courant de la table pTI */
560 for (i
= 0; i
< (pC1
->pTI
)->length
; i
++)
562 if (pEl
->value
!= EMPTYTH
&& pEl
->value
!= DELETETH
)
564 /* recherche dans CC2 */
566 indexCC2
= searchTH (pC2
->pTI
, pEl
->key
);
569 if (pEl
->value
!= indexCC2
)
571 printf("INDEX (%s) differents pour les deux circuits\n",(char*) pEl
->key
);
572 printf("********** END OF PROOF **********\n\n");
578 pEl
= (pC1
->pTO
)->pElem
; /* pointeur courant de la table CC1 */
580 for (i
= 0; i
< (pC1
->pTO
)->length
; i
++)
582 if (pEl
->value
!= EMPTYTH
&& pEl
->value
!= DELETETH
)
584 /* recherche dans CC2 */
586 noeudCC2
= (pNode
) searchTH (pC2
->pTO
, pEl
->key
);
589 if (noeudCC2
!= (pNode
) EMPTYTH
)
591 printf("OUTPUT %s ",(char*) pEl
->key
);
592 if (noeudCC2
== (pNode
) pEl
->value
)
593 printf("is equal\n");
596 printf("is different\n");
597 printf("%s = ",(char*) pEl
->key
);
598 expr
= bddToAbl ((pNode
) pEl
->value
, pC1
->pNameI
);
599 if (numberAtomExpr (expr
) < 50)
602 printf("too small...");
604 printf("%s = ",(char*) pEl
->key
);
605 expr
= bddToAbl (noeudCC2
, pC2
->pNameI
);
606 if (numberAtomExpr (expr
) < 50)
609 printf("too small...");
616 printf("********** END OF PROOF **********\n\n");
619 /*------------------------------------------------------------------------------
620 ablToBddCct :traduit la forme prefixee ABL en un GDB .
621 -------------------------------------------------------
622 parametres : un circuit et un pointeur d'ABL .
623 -------------------------------------------------------
625 ------------------------------------------------------------------------------*/
627 ablToBddCct (pC
, expr
)
637 if ((pt
= searchOutputCct_no_NA (pC
, VALUE_ATOM (expr
))) != NULL
)
641 if (!strcmp (VALUE_ATOM (expr
), "'0'"))
643 if (!strcmp (VALUE_ATOM (expr
), "'d'"))
645 if (!strcmp (VALUE_ATOM (expr
), "'1'"))
647 pt
= createNodeTermBdd (addInputCct_no_NA (pC
, VALUE_ATOM (expr
)));
655 while ((expr
= CDR (expr
)))
656 lstGdb
= addListBdd (lstGdb
, ablToBddCct (pC
, CAR (expr
)));
657 pt
= applyBdd (oper
, lstGdb
);
662 /*------------------------------------------------------------------------------
663 cpOrderCct :copie la table des index de CC1 dans CC2 .
664 -------------------------------------------------------
665 parametres :deux pointeurs de circuits.
667 -------------------------------------------------------
669 ------------------------------------------------------------------------------*/
671 cpOrderCct (CC1
, CC2
)
680 if (CC2
->pTI
->length
!= CC1
->pTI
->length
)
682 tab
= createTH ((CC1
->pTI
->length
));
683 destroyTH (CC2
->pTI
);
686 pEl1
= (CC1
->pTI
)->pElem
;
687 pEl2
= (CC2
->pTI
)->pElem
;
688 for (i
= 0; i
< (CC1
->pTI
)->length
; i
++)
690 pEl2
->value
= pEl1
->value
;
691 pEl2
->key
= pEl1
->key
;
695 CC2
->pTI
->count
= CC1
->pTI
->count
;
696 CC2
->countI
= CC1
->countI
;
699 for (i
= 0; i
< CC1
->countI
; i
++)
707 /*-------------------------------------------------------------------------
708 upVarCct : remontee d'une variable dans un circuit
709 ---------------------------------------------------------------------------
711 ---------------------------------------------------------------------------*/
714 upVarCct (pC
, ptOldIndex
, newIndex
)
722 pEl
= (pC
->pTO
)->pElem
;
723 for (i
= 0; i
< (pC
->pTO
)->length
; i
++)
725 if (pEl
->value
!= EMPTYTH
&& pEl
->value
!= DELETETH
)
726 pEl
->value
= (long) upVarBdd ((pNode
)pEl
->value
, ptOldIndex
, newIndex
);
729 deleteTH (pC
->pTI
, *(pC
->pNameI
+ newIndex
- 2));
730 *(pC
->pNameI
+ newIndex
- 2) = *(pC
->pNameI
+ ptOldIndex
->index
- 2);
731 addTH (pC
->pTI
, *(pC
->pNameI
+ ptOldIndex
->index
- 2), newIndex
);
734 /*-------------------------------------------------------------------------
735 numberNodeCct : calcule le nombre de noeud d'un circuit
736 ---------------------------------------------------------------------------
738 ---------------------------------------------------------------------------*/
749 pEl
= (pC
->pTO
)->pElem
;
750 for (i
= 0; i
< (pC
->pTO
)->length
; i
++)
752 if (pEl
->value
!= EMPTYTH
&& pEl
->value
!= DELETETH
)
754 number_node
= number_node
+ countNode ((pNode
) pEl
->value
);
759 return (number_node
);
762 /*-------------------------------------------------------------------------
763 numberNodeTdgCct : calcule le nombre de noeud equivalent TDG d'un circuit
764 ---------------------------------------------------------------------------
766 ---------------------------------------------------------------------------*/
769 numberNodeTdgCct (pC
)
777 pEl
= (pC
->pTO
)->pElem
;
778 for (i
= 0; i
< (pC
->pTO
)->length
; i
++)
780 if (pEl
->value
!= EMPTYTH
&& pEl
->value
!= DELETETH
)
782 number_node
= number_node
+ countNodeTdg ((pNode
) pEl
->value
);
787 return (number_node
);
790 /*------------------------------------------------------------------------------
791 bddToAblCct :traduit un BDD en ABL d'une maniere simplifie.
792 -------------------------------------------------------
793 parametres :un pointeur de NODE.
794 -------------------------------------------------------
795 return :une pointeur de CHAIN_LIST.
796 ------------------------------------------------------------------------------*/
798 bddToAblCct (pC
, pBdd
)
802 return (bddToAbl (pBdd
, pC
->pNameI
));
805 /*------------------------------------------------------------------------------
806 gcNodeCct :effectue un garbage collecteur sur tous les noeuds de systeme
807 en sauvegardant les noeuds pointes par les pNode(s) du circuit.
808 -------------------------------------------------------
809 parametres : pointeur de chain_list.
810 -------------------------------------------------------
813 ------------------------------------------------------------------------------*/
818 struct systemBdd sysBddAux
;
819 pNode zeroAux
, oneAux
;
824 pTHNode
= createTH (MEDIUM
);
825 sysBddAux
.pRT
= createTableBdd (MEDIUM
);
826 sysBddAux
.pMC
= createTabLoc (MEDIUM
);
827 sysBddAux
.indiceAT
= MAX_PACK
;
828 sysBddAux
.lpAT
= NULL
;
829 zeroAux
= initVertexBddAux (0, (pNode
) 0, (pNode
) 1, &sysBddAux
);
830 oneAux
= initVertexBddAux (1, (pNode
) 0, (pNode
) 1, &sysBddAux
);
831 addTH (pTHNode
, (char *)BDD_zero
, (long) zeroAux
);
832 addTH (pTHNode
, (char *)BDD_one
, (long) oneAux
);
835 /* on regenere les graphes */
837 pEl
= (pC
->pTO
)->pElem
;
838 for (j
= 0; j
< (pC
->pTO
)->length
; j
++)
840 if (pEl
->value
!= EMPTYTH
&& pEl
->value
!= DELETETH
)
841 pEl
->value
= (long) regenereBdd ((pNode
) pEl
->value
, &sysBddAux
, pTHNode
);
847 sysBdd
.pRT
= sysBddAux
.pRT
;
848 sysBdd
.pMC
= sysBddAux
.pMC
;
849 sysBdd
.indiceAT
= sysBddAux
.indiceAT
;
850 sysBdd
.lpAT
= sysBddAux
.lpAT
;
851 sysBdd
.pAT
= sysBddAux
.pAT
;
856 chain_list
*supportChain_listBddExpr(pCircuit circuit
, pNode bdd
)
858 chain_list
*cl
, *ch
=NULL
, *abl
;
860 if (bdd
!=BDD_zero
&& bdd
!=BDD_one
)
862 cl
=supportIndexBdd(bdd
, 0);
865 var
=searchIndexCct(circuit
, (short)(long)cl
->DATA
);
866 ch
=addchain(ch
, var
);