1 /* 10/26/95 Cone Netlist Structure functions: coneexpr.c */
5 static chain_list
*getSwitchExpr(link_list
*ptlink
)
10 if ((ptlink
->TYPE
& CNS_TNLINK
) == CNS_TNLINK
) {
11 ptuser
= getptype(ptlink
->ULINK
.LOTRS
->USER
, CNS_DRIVINGCONE
);
12 if (ptuser
== NULL
) return NULL
;
13 if (ptuser
->DATA
== NULL
) return NULL
;
14 return (createAtom(((cone_list
*)ptuser
->DATA
)->NAME
));
17 ptuser
= getptype(ptlink
->ULINK
.LOTRS
->USER
, CNS_SWITCH
);
18 if (ptuser
== NULL
) return NULL
;
19 ptlotrs
= (lotrs_list
*)ptuser
->DATA
;
20 ptuser
= getptype(ptlotrs
->USER
, CNS_DRIVINGCONE
);
21 if (ptuser
== NULL
) return NULL
;
22 if (ptuser
->DATA
== NULL
) return NULL
;
23 return (createAtom(((cone_list
*)ptuser
->DATA
)->NAME
));
27 static int isSwitchOn(link_list
*ptlink
)
33 ptlotrs
= ptlink
->ULINK
.LOTRS
;
34 ptuser
= getptype(ptlotrs
->USER
, CNS_DRIVINGCONE
);
35 if (ptuser
!= NULL
&& ptuser
->DATA
!= NULL
) {
36 ptcone
= (cone_list
*)ptuser
->DATA
;
37 if ((ptlotrs
->TYPE
& CNS_TN
) == CNS_TN
&& (ptcone
->TYPE
& CNS_VDD
) == CNS_VDD
) {
40 if ((ptlotrs
->TYPE
& CNS_TP
) == CNS_TP
&& (ptcone
->TYPE
& CNS_VSS
) == CNS_VSS
) {
44 ptuser
= getptype(ptlink
->ULINK
.LOTRS
->USER
, CNS_SWITCH
);
46 ptlotrs
= (lotrs_list
*)ptuser
->DATA
;
47 ptuser
= getptype(ptlotrs
->USER
, CNS_DRIVINGCONE
);
48 if (ptuser
!= NULL
&& ptuser
->DATA
!= NULL
) {
49 ptcone
= (cone_list
*)ptuser
->DATA
;
50 if ((ptlotrs
->TYPE
& CNS_TN
) == CNS_TN
&& (ptcone
->TYPE
& CNS_VDD
) == CNS_VDD
) {
53 if ((ptlotrs
->TYPE
& CNS_TP
) == CNS_TP
&& (ptcone
->TYPE
& CNS_VSS
) == CNS_VSS
) {
61 static int isTransOn(link_list
*ptlink
)
67 ptlotrs
= ptlink
->ULINK
.LOTRS
;
68 ptuser
= getptype(ptlotrs
->USER
, CNS_DRIVINGCONE
);
69 if (ptuser
!= NULL
&& ptuser
->DATA
!= NULL
) {
70 ptcone
= (cone_list
*)ptuser
->DATA
;
71 if ((ptlotrs
->TYPE
& CNS_TN
) == CNS_TN
&& (ptcone
->TYPE
& CNS_VDD
) == CNS_VDD
) {
74 if ((ptlotrs
->TYPE
& CNS_TP
) == CNS_TP
&& (ptcone
->TYPE
& CNS_VSS
) == CNS_VSS
) {
81 static int isTransOff(link_list
*ptlink
)
87 ptlotrs
= ptlink
->ULINK
.LOTRS
;
88 ptuser
= getptype(ptlotrs
->USER
, CNS_DRIVINGCONE
);
89 if (ptuser
!= NULL
&& ptuser
->DATA
!= NULL
) {
90 ptcone
= (cone_list
*)ptuser
->DATA
;
91 if ((ptlotrs
->TYPE
& CNS_TN
) == CNS_TN
&& (ptcone
->TYPE
& CNS_VSS
) == CNS_VSS
) {
94 if ((ptlotrs
->TYPE
& CNS_TP
) == CNS_TP
&& (ptcone
->TYPE
& CNS_VDD
) == CNS_VDD
) {
101 /****************************************************************************
102 * function cnsAddConeInversion(); *
103 ****************************************************************************/
104 /*----------------------------------------------------*
105 | Mechanism to substitute inversion function for a |
106 | cone (used for switches in YAGLE) |
107 *----------------------------------------------------*/
109 void cnsAddConeInversion(cone_list
*ptexprcone
, cone_list
*ptcone
)
114 ptuser
= getptype(ptexprcone
->USER
, CNS_INVCONE
);
115 if (ptuser
== NULL
|| ptuser
->DATA
!= ptcone
) {
116 if ((ptuser
= getptype(ptcone
->USER
, CNS_INVCONE
)) != NULL
) {
117 ptchain
= (chain_list
*)ptuser
->DATA
;
118 if (getchain(ptchain
, ptexprcone
) == NULL
) {
119 ptuser
->DATA
= addchain(ptchain
, ptexprcone
);
122 else ptcone
->USER
= addptype(ptcone
->USER
, CNS_INVCONE
, addchain(NULL
, ptexprcone
));
127 /****************************************************************************
128 * function cnsMakeBranchExpr(); *
129 ****************************************************************************/
130 /*----------------------------------------------------*
131 | Returns the ABL of a branch |
132 | N.B. Does not verify the functionality |
133 *----------------------------------------------------*/
135 chain_list
*cnsMakeBranchExpr(branch_list
*ptbranch
, long linkmask
, int simplify
)
139 link_list
*ptfirstlink
;
148 ptfirstlink
= ptbranch
->LINK
;
149 while (ptfirstlink
&& (ptfirstlink
->TYPE
& linkmask
) != 0)
150 ptfirstlink
= ptfirstlink
->NEXT
;
152 if (ptfirstlink
== NULL
) return NULL
;
154 /*--------------------------------*
156 *--------------------------------*/
157 if(ptfirstlink
->NEXT
== NULL
) {
158 /*-------------------*
160 *-------------------*/
162 if ((ptfirstlink
->TYPE
& CNS_RESIST
) == CNS_RESIST
) {
163 ptbranch
->TYPE
|= CNS_RESBRANCH
;
164 if (simplify
&& isTransOn(ptfirstlink
)) {
165 abl
= createAtom("'1'");
170 /*-------------------*
172 *-------------------*/
174 if (simplify
&& (ptfirstlink
->TYPE
& CNS_SWITCH
) == CNS_SWITCH
) {
175 if (isSwitchOn(ptfirstlink
)) {
176 abl
= createAtom("'1'");
179 else return getSwitchExpr(ptfirstlink
);
182 /*-------------------*
184 *-------------------*/
186 if ((ptfirstlink
->TYPE
& CNS_DIODE_UP
) == CNS_DIODE_UP
187 || (ptfirstlink
->TYPE
& CNS_DIODE_DOWN
) == CNS_DIODE_DOWN
) {
188 ptbranch
->TYPE
|= CNS_RESBRANCH
;
189 abl
= createAtom("'1'");
193 if ((ptfirstlink
->TYPE
& CNS_SHORT
) == CNS_SHORT
) {
195 abl
= createAtom("'1'");
201 if (isTransOn(ptfirstlink
)) {
202 abl
= createAtom("'1'");
205 if (isTransOff(ptfirstlink
)) {
206 abl
= createAtom("'0'");
210 if ((ptfirstlink
->TYPE
& CNS_TNLINK
) == CNS_TNLINK
) {
211 ptuser
= getptype(ptfirstlink
->ULINK
.LOTRS
->USER
, CNS_DRIVINGCONE
);
212 if (ptuser
== NULL
|| ptuser
->DATA
== NULL
) {
216 else ptcone
= (cone_list
*)ptuser
->DATA
;
217 abl
= createAtom(ptcone
->NAME
);
220 else if ((ptfirstlink
->TYPE
& CNS_TPLINK
) == CNS_TPLINK
) {
221 ptuser
= getptype(ptfirstlink
->ULINK
.LOTRS
->USER
, CNS_DRIVINGCONE
);
222 if (ptuser
== NULL
|| ptuser
->DATA
== NULL
) {
226 else ptcone
= (cone_list
*)ptuser
->DATA
;
227 abl
= createAtom(ptcone
->NAME
);
228 return(notExpr(abl
));
232 /*----------------------------*
233 | Multiple link branch |
234 *----------------------------*/
236 abl
= createExpr(AND
);
238 for (ptlink
= ptfirstlink
; ptlink
; ptlink
= ptlink
->NEXT
) {
240 if ((ptlink
->TYPE
& CNS_RESIST
) == CNS_RESIST
) {
243 atom
= createAtom("'1'");
248 if (simplify
&& (ptlink
->TYPE
& CNS_SWITCH
) == CNS_SWITCH
) {
249 if (isSwitchOn(ptlink
)) {
250 atom
= createAtom("'1'");
254 atom
= getSwitchExpr(ptlink
);
264 if ((ptlink
->TYPE
& CNS_SHORT
) == CNS_SHORT
) {
265 atom
= createAtom("'1'");
270 if ((ptlink
->TYPE
& CNS_DIODE_UP
) == CNS_DIODE_UP
271 || (ptlink
->TYPE
& CNS_DIODE_DOWN
) == CNS_DIODE_DOWN
) {
273 atom
= createAtom("'1'");
278 ptuser
= getptype(ptlink
->ULINK
.LOTRS
->USER
, CNS_DRIVINGCONE
);
279 if (ptuser
== NULL
|| ptuser
->DATA
== NULL
) {
283 else ptcone
= (cone_list
*)ptuser
->DATA
;
286 if (isTransOn(ptlink
)) {
287 atom
= createAtom("'1'");
291 if (isTransOff(ptlink
)) {
292 atom
= createAtom("'0'");
297 if ((ptlink
->TYPE
& CNS_TNLINK
) == CNS_TNLINK
) {
298 atom
= createAtom(ptcone
->NAME
);
301 else if ((ptlink
->TYPE
& CNS_TPLINK
) == CNS_TPLINK
) {
302 atom
= createAtom(ptcone
->NAME
);
303 addQExpr(abl
,notExpr(atom
));
307 if (n_resist
== n_link
) ptbranch
->TYPE
|= CNS_RESBRANCH
;
314 /****************************************************************************
315 * function cnsMakeExtBranchExpr(); *
316 ****************************************************************************/
317 /*----------------------------------------------------*
318 | Returns the ABLs of an external branch |
319 | N.B. Does not verify the functionality |
320 | Two values given to an external connector |
321 *----------------------------------------------------*/
323 void cnsMakeExtBranchExpr(branch_list
*ptbranch
, abl_pair
*branch_abl
, long linkmask
, int simplify
)
325 link_list
*ptfirstlink
, *ptlink
;
334 branch_abl
->UP
= NULL
;
336 ptlink
= ptbranch
->LINK
;
338 ptfirstlink
= ptbranch
->LINK
;
339 while ((ptfirstlink
->TYPE
& linkmask
) != 0)
340 ptfirstlink
= ptfirstlink
->NEXT
;
342 /*--------------------------------*
344 *--------------------------------*/
345 if(ptfirstlink
->NEXT
== NULL
) {
346 branch_abl
->UP
= createAtom(ptfirstlink
->ULINK
.LOCON
->NAME
);
347 branch_abl
->DN
= notExpr(copyExpr(branch_abl
->UP
));
350 /*----------------------------------------*
351 | EXT branch with multiple links |
352 *----------------------------------------*/
355 ablUp
= createExpr(AND
);
357 for (ptlink
= ptfirstlink
; ptlink
->NEXT
!= NULL
; ptlink
= ptlink
->NEXT
) {
359 if ((ptlink
->TYPE
& CNS_RESIST
) == CNS_RESIST
) {
362 atom
= createAtom("'1'");
363 addQExpr(ablUp
,atom
);
367 if (simplify
&& (ptlink
->TYPE
& CNS_SWITCH
) == CNS_SWITCH
) {
368 if (isSwitchOn(ptlink
)) {
369 atom
= createAtom("'1'");
370 addQExpr(ablUp
,atom
);
373 atom
= getSwitchExpr(ptlink
);
378 addQExpr(ablUp
, atom
);
383 if ((ptlink
->TYPE
& CNS_SHORT
) == CNS_SHORT
) {
384 atom
= createAtom("'1'");
385 addQExpr(ablUp
,atom
);
389 if ((ptlink
->TYPE
& CNS_DIODE_UP
) == CNS_DIODE_UP
390 || (ptlink
->TYPE
& CNS_DIODE_DOWN
) == CNS_DIODE_DOWN
) {
392 atom
= createAtom("'1'");
393 addQExpr(ablUp
,atom
);
397 ptuser
= getptype(ptlink
->ULINK
.LOTRS
->USER
, CNS_DRIVINGCONE
);
398 if (ptuser
== NULL
|| ptuser
->DATA
== NULL
) {
402 else ptcone
= (cone_list
*)ptuser
->DATA
;
405 if (isTransOn(ptlink
)) {
406 atom
= createAtom("'1'");
407 addQExpr(ablUp
,atom
);
410 if (isTransOff(ptlink
)) {
411 atom
= createAtom("'0'");
412 addQExpr(ablUp
,atom
);
416 if ((ptlink
->TYPE
& CNS_TNLINK
) == CNS_TNLINK
) {
417 atom
= createAtom(ptcone
->NAME
);
418 addQExpr(ablUp
,atom
);
420 else if ((ptlink
->TYPE
& CNS_TPLINK
) == CNS_TPLINK
) {
421 atom
= createAtom(ptcone
->NAME
);
422 addQExpr(ablUp
,notExpr(atom
));
426 /* Treatment of connector link */
427 if (n_link
== n_resist
) {
429 branch_abl
->UP
= createAtom(ptlink
->ULINK
.LOCON
->NAME
);
430 branch_abl
->DN
= notExpr(createAtom(ptlink
->ULINK
.LOCON
->NAME
));
433 ablDn
= copyExpr(ablUp
);
434 atom
= createAtom(ptlink
->ULINK
.LOCON
->NAME
);
435 addQExpr(ablUp
,atom
);
436 atom
= createAtom(ptlink
->ULINK
.LOCON
->NAME
);
437 addQExpr(ablDn
,notExpr(atom
));
438 branch_abl
->UP
= ablUp
;
439 branch_abl
->DN
= ablDn
;
444 /****************************************************************************
445 * function cnsMakeConeExpr(); *
446 ****************************************************************************/
448 void cnsMakeConeExpr(cone_list
*ptcone
, abl_pair
*cone_abl
, long branchmask
, long linkmask
, int simplify
)
450 branch_list
*ptbranch
;
459 /*-------------------------*
460 | Count the branches |
461 *-------------------------*/
462 for (ptbranch
= ptcone
->BRVSS
; ptbranch
!= NULL
; ptbranch
= ptbranch
->NEXT
) {
463 if ((ptbranch
->TYPE
& branchmask
) == 0) n_dn
++;
465 for (ptbranch
= ptcone
->BRVDD
; ptbranch
!= NULL
; ptbranch
= ptbranch
->NEXT
) {
466 if ((ptbranch
->TYPE
& branchmask
) == 0) n_up
++;
468 for (ptbranch
= ptcone
->BREXT
; ptbranch
!= NULL
; ptbranch
= ptbranch
->NEXT
) {
469 /* ignore external connector branch */
470 if (ptbranch
->LINK
->NEXT
== NULL
) continue;
471 if ((ptbranch
->TYPE
& branchmask
) == 0) {
472 if ((ptbranch
->TYPE
& CNS_NOT_UP
) == 0) n_up
++;
473 if ((ptbranch
->TYPE
& CNS_NOT_DOWN
) == 0)n_dn
++;
476 n_branch
= n_up
+ n_dn
;
478 /* external input only cone */
479 if ((ptcone
->TYPE
& CNS_EXT
) != 0 && n_branch
== 0) return;
481 /*--------------------------*
482 | Single branch case |
483 *--------------------------*/
485 for (ptbranch
= ptcone
->BRVSS
; ptbranch
!= NULL
; ptbranch
= ptbranch
->NEXT
) {
486 if ((ptbranch
->TYPE
& branchmask
) == 0) {
487 cone_abl
->DN
= cnsMakeBranchExpr(ptbranch
, linkmask
, simplify
);
491 for (ptbranch
= ptcone
->BRVDD
; ptbranch
!= NULL
; ptbranch
= ptbranch
->NEXT
) {
492 if ((ptbranch
->TYPE
& branchmask
) == 0) {
493 cone_abl
->UP
= cnsMakeBranchExpr(ptbranch
, linkmask
, simplify
);
499 /*--------------------------*
500 | Multiple branches |
501 *--------------------------*/
502 else if (n_branch
>=2) {
504 if (n_up
>= 2) cone_abl
->UP
= createExpr(OR
);
505 if (n_dn
>= 2) cone_abl
->DN
= createExpr(OR
);
507 /*-------------------------------------------*
508 | Create intermediary ABLs |
509 *-------------------------------------------*/
510 for (ptbranch
= ptcone
->BRVSS
; ptbranch
; ptbranch
= ptbranch
->NEXT
) {
511 if((ptbranch
->TYPE
& branchmask
) != 0) continue;
512 if (n_dn
>= 2) addQExpr(cone_abl
->DN
, cnsMakeBranchExpr(ptbranch
, linkmask
, simplify
));
513 else cone_abl
->DN
= cnsMakeBranchExpr(ptbranch
, 0, simplify
);
516 for (ptbranch
= ptcone
->BRVDD
; ptbranch
; ptbranch
= ptbranch
->NEXT
) {
517 if((ptbranch
->TYPE
& branchmask
) != 0) continue;
518 if (n_up
>= 2) addQExpr(cone_abl
->UP
, cnsMakeBranchExpr(ptbranch
, linkmask
, simplify
));
519 else cone_abl
->UP
= cnsMakeBranchExpr(ptbranch
, linkmask
, simplify
);
522 for (ptbranch
= ptcone
->BREXT
; ptbranch
; ptbranch
= ptbranch
->NEXT
) {
523 /* ignore external connector branch */
524 if (ptbranch
->LINK
->NEXT
== NULL
) continue;
525 if((ptbranch
->TYPE
& branchmask
) != 0) continue;
526 cnsMakeExtBranchExpr(ptbranch
, &ablXt
, linkmask
, simplify
);
527 if ((ptbranch
->TYPE
& CNS_NOT_UP
) == 0) {
528 if (n_up
>= 2) addQExpr(cone_abl
->UP
, ablXt
.UP
);
529 else cone_abl
->UP
= ablXt
.UP
;
531 else freeExpr(ablXt
.UP
);
532 if ((ptbranch
->TYPE
& CNS_NOT_DOWN
) == 0) {
533 if (n_dn
>= 2) addQExpr(cone_abl
->DN
, ablXt
.DN
);
534 else cone_abl
->DN
= ablXt
.DN
;
536 else freeExpr(ablXt
.DN
);
541 /****************************************************************************
542 * function cnsConeFunction(); *
543 ****************************************************************************/
544 /*--------------------------------------------+
545 | Calculates the local cone function and puts |
546 | the required abl pointers in the USER field |
547 +--------------------------------------------*/
549 void cnsConeFunction(cone_list
*ptcone
, int simplify
)
553 chain_list
*sw_chain
, *pairlist
;
555 lotrs_list
*ptlotrs1
, *ptlotrs2
;
556 cone_list
*ptcone1
, *ptcone2
;
560 ptcone
->USER
=testanddelptype(ptcone
->USER
, CNS_CONEFUNCTION_SIMPLIFIED
);
562 user
= getptype(ptcone
->USER
, CNS_UPEXPR
);
564 freeExpr((chain_list
*)user
->DATA
);
565 ptcone
->USER
= delptype(ptcone
->USER
, CNS_UPEXPR
);
567 user
= getptype(ptcone
->USER
, CNS_DNEXPR
);
569 freeExpr((chain_list
*)user
->DATA
);
570 ptcone
->USER
= delptype(ptcone
->USER
, CNS_DNEXPR
);
573 cnsMakeConeExpr(ptcone
, &cone_abl
, CNS_NOT_FUNCTIONAL
|CNS_MASK_PARA
|CNS_IGNORE
, 0, simplify
);
575 ptcone
->USER
= addptype(ptcone
->USER
, CNS_UPEXPR
, (void *)cone_abl
.UP
);
576 ptcone
->USER
= addptype(ptcone
->USER
, CNS_DNEXPR
, (void *)cone_abl
.DN
);
578 if (simplify
&& (ptuser
= getptype(ptcone
->USER
, CNS_SWITCH
)) != NULL
) {
579 sw_chain
= (chain_list
*)ptuser
->DATA
;
580 for (ptchain
= sw_chain
; ptchain
; ptchain
= ptchain
->NEXT
) {
581 pairlist
= (chain_list
*)ptchain
->DATA
;
582 ptlotrs1
= (lotrs_list
*)pairlist
->DATA
;
583 ptcone1
= (cone_list
*)getptype(ptlotrs1
->USER
, CNS_DRIVINGCONE
)->DATA
;
584 ptlotrs2
= (lotrs_list
*)pairlist
->NEXT
->DATA
;
585 ptcone2
= (cone_list
*)getptype(ptlotrs2
->USER
, CNS_DRIVINGCONE
)->DATA
;
586 for (ptinput
= ptcone
->INCONE
; ptinput
; ptinput
= ptinput
->NEXT
) {
587 if (ptinput
->UEDGE
.CONE
== ptcone1
&& getptype(ptinput
->USER
, CNS_SWITCHPAIR
) == NULL
) {
588 ptinput
->USER
= addptype(ptinput
->USER
, CNS_SWITCHPAIR
, ptcone2
);
590 else if (ptinput
->UEDGE
.CONE
== ptcone2
&& getptype(ptinput
->USER
, CNS_SWITCHPAIR
) == NULL
) {
591 ptinput
->USER
= addptype(ptinput
->USER
, CNS_SWITCHPAIR
, ptcone1
);
598 void cnsConeFunction_once(cone_list
*ptcone
, int simplify
)
601 if ((pt
=getptype(ptcone
->USER
, CNS_CONEFUNCTION_SIMPLIFIED
))!=NULL
&& (int)(long)pt
->DATA
==simplify
) return;
602 cnsConeFunction(ptcone
, simplify
);
603 ptcone
->USER
=addptype(ptcone
->USER
, CNS_CONEFUNCTION_SIMPLIFIED
, (void *)(long)simplify
);
606 /****************************************************************************
607 * function cnsCalcConeState(); *
608 ****************************************************************************/
609 /*----------------------------------------------+
610 | Calculates the local cone state as a function |
611 | of the input states |
612 +----------------------------------------------*/
614 static pCircuit
cnsBuildDirectCct(cone_list
*ptcone
)
621 numinputs
= countchain((chain_list
*)ptcone
->INCONE
);
622 circuit
= initializeCct(ptcone
->NAME
, numinputs
, 10);
624 for (ptedge
= ptcone
->INCONE
; ptedge
; ptedge
= ptedge
->NEXT
) {
625 if ((ptedge
->TYPE
& CNS_IGNORE
) != 0) continue;
626 if ((ptedge
->TYPE
& CNS_BLEEDER
) != 0) continue;
627 if ((ptedge
->TYPE
& CNS_EXT
) != CNS_EXT
) {
628 name
= ptedge
->UEDGE
.CONE
->NAME
;
630 else name
= ptedge
->UEDGE
.LOCON
->NAME
;
631 addInputCct_no_NA(circuit
, name
);
638 cnsCalcConeState(cone_list
*ptcone
, long defaultstate
)
643 pNode upbdd
, dnbdd
, ptconstraintbdd
;
645 locon_list
*ptinlocon
;
646 chain_list
*ptupexpr
;
647 chain_list
*ptdnexpr
;
648 chain_list
*ptconstraint
;
649 long oldstate
, newstate
;
650 char freeup
= FALSE
, freedown
= FALSE
;
652 /* stuck cones have state set accordingly and register a change on first visit */
653 if ((ptcone
->TECTYPE
& CNS_ONE
) == CNS_ONE
) {
654 if ((ptcone
->TECTYPE
& CNS_STATE_ONE
) != CNS_STATE_ONE
) {
655 ptcone
->TECTYPE
|= CNS_STATE_ONE
;
660 if ((ptcone
->TECTYPE
& CNS_ZERO
) == CNS_ZERO
) {
661 if ((ptcone
->TECTYPE
& CNS_STATE_ZERO
) != CNS_STATE_ZERO
) {
662 ptcone
->TECTYPE
|= CNS_STATE_ZERO
;
668 oldstate
= ptcone
->TECTYPE
& (CNS_STATE_ONE
|CNS_STATE_ZERO
);
669 ptcone
->TECTYPE
&= ~(CNS_STATE_UNKNOWN
|CNS_STATE_ONE
|CNS_STATE_ZERO
);
670 if (defaultstate
== CNS_STATE_UNKNOWN
&& oldstate
!= 0) defaultstate
= oldstate
;
672 cnsConeFunction_once(ptcone
, 1);
673 if ((ptuser
= getptype(ptcone
->USER
, CNS_UPEXPR
)) != NULL
) {
674 ptupexpr
= (chain_list
*)ptuser
->DATA
;
676 ptupexpr
= createAtom("'0'");
681 if ((ptuser
= getptype(ptcone
->USER
, CNS_DNEXPR
)) != NULL
) {
682 ptdnexpr
= (chain_list
*)ptuser
->DATA
;
684 ptdnexpr
= createAtom("'0'");
690 circuit
= cnsBuildDirectCct(ptcone
);
691 upbdd
= ablToBddCct(circuit
, ptupexpr
);
692 dnbdd
= ablToBddCct(circuit
, ptdnexpr
);
694 for (ptedge
= ptcone
->INCONE
; ptedge
; ptedge
= ptedge
->NEXT
) {
696 if ((ptedge
->TYPE
& CNS_EXT
) == CNS_EXT
) {
697 ptinlocon
= ptedge
->UEDGE
.LOCON
;
698 ptuser
= getptype(ptinlocon
->USER
, CNS_TYPELOCON
);
699 if (ptuser
== NULL
) continue;
700 if (((long)ptuser
->DATA
& (CNS_ZERO
|CNS_STATE_ZERO
)) != 0) {
701 ptconstraint
= createAtom(ptinlocon
->NAME
);
702 ptconstraintbdd
= notBdd(ablToBddCct(circuit
, ptconstraint
));
704 else if (((long)ptuser
->DATA
& (CNS_ONE
|CNS_STATE_ONE
)) != 0) {
705 ptconstraint
= createAtom(ptinlocon
->NAME
);
706 ptconstraintbdd
= ablToBddCct(circuit
, ptconstraint
);
710 ptincone
= ptedge
->UEDGE
.CONE
;
711 if ((ptincone
->TECTYPE
& (CNS_ZERO
|CNS_STATE_ZERO
)) != 0) {
712 ptconstraint
= createAtom(ptincone
->NAME
);
713 ptconstraintbdd
= notBdd(ablToBddCct(circuit
, ptconstraint
));
715 else if ((ptincone
->TECTYPE
& (CNS_ONE
|CNS_STATE_ONE
)) != 0) {
716 ptconstraint
= createAtom(ptincone
->NAME
);
717 ptconstraintbdd
= ablToBddCct(circuit
, ptconstraint
);
720 if (ptconstraint
!= NULL
) {
721 upbdd
= constraintBdd(upbdd
, ptconstraintbdd
);
722 if (ptdnexpr
) dnbdd
= constraintBdd(dnbdd
, ptconstraintbdd
);
723 freeExpr(ptconstraint
);
727 if (upbdd
== BDD_one
&& (dnbdd
== BDD_zero
|| dnbdd
== NULL
)) {
728 ptcone
->TECTYPE
|= CNS_STATE_ONE
;
730 else if (upbdd
== BDD_zero
&& (dnbdd
== BDD_one
|| dnbdd
== NULL
)) {
731 ptcone
->TECTYPE
|= CNS_STATE_ZERO
;
733 else ptcone
->TECTYPE
|= defaultstate
;
735 newstate
= ptcone
->TECTYPE
& (CNS_STATE_ONE
|CNS_STATE_ZERO
);
738 if (freeup
) freeExpr(ptupexpr
);
739 if (freedown
) freeExpr(ptdnexpr
);
740 if (newstate
!= oldstate
) return 1;
744 /****************************************************************************
745 * function cnsCalcFigState(); *
746 ****************************************************************************/
747 /*------------------------------------------------+
748 | Calculates the local cnsfig state as a function |
749 | of the input connector states |
750 +------------------------------------------------*/
753 cnsFIFOPush(chain_list
**ptpthead
, void *ptdata
)
757 if (*ptpthead
== NULL
) {
758 *ptpthead
= addchain(NULL
, ptdata
);
761 for (ptchain
= *ptpthead
; ptchain
->NEXT
; ptchain
= ptchain
->NEXT
) {
762 if (ptchain
->DATA
== ptdata
) return;
764 ptchain
->NEXT
= addchain(NULL
, ptdata
);
768 cnsFIFOPop(chain_list
**ptpthead
)
772 ptdata
= (*ptpthead
)->DATA
;
773 *ptpthead
= delchain(*ptpthead
, *ptpthead
);
778 cnsCalcLatchCbhState(cone_list
*ptcone
, cbhseq
*ptcbhseq
, long cbhseq_state
)
782 if (ptcone
->NAME
!= ptcbhseq
->LATCHNAME
&& ptcone
->NAME
!= ptcbhseq
->SLAVENAME
) {
783 return CNS_STATE_UNKNOWN
;
785 if (ptcbhseq
->POLARITY
!= CBH_INVERT
&& ptcbhseq
->POLARITY
!= CBH_NONINVERT
) {
786 return CNS_STATE_UNKNOWN
;
788 if (ptcbhseq
->POLARITY
!= CBH_INVERT
&& ptcbhseq
->POLARITY
!= CBH_NONINVERT
) {
789 return CNS_STATE_UNKNOWN
;
792 if (ptcbhseq
->STATEPIN
== ptcbhseq
->NEGPIN
|| ptcbhseq
->STATEPIN
== ptcbhseq
->HZNEGPIN
) {
796 if (invert
&& ptcbhseq
->POLARITY
== CBH_INVERT
) invert
= FALSE
;
797 else if (!invert
&& ptcbhseq
->POLARITY
== CBH_INVERT
) invert
= TRUE
;
799 if (ptcone
->NAME
== ptcbhseq
->SLAVENAME
) {
800 if (invert
&& ptcbhseq
->MSPOLARITY
== CBH_INVERT
) invert
= FALSE
;
801 else if (!invert
&& ptcbhseq
->MSPOLARITY
== CBH_INVERT
) invert
= TRUE
;
804 if ((cbhseq_state
& (CNS_ZERO
|CNS_STATE_ZERO
)) != 0) {
805 if (invert
) return CNS_STATE_ONE
;
806 else return CNS_STATE_ZERO
;
808 if ((cbhseq_state
& (CNS_ONE
|CNS_STATE_ONE
)) != 0) {
809 if (invert
) return CNS_STATE_ZERO
;
810 else return CNS_STATE_ONE
;
812 return CNS_STATE_UNKNOWN
;
816 cnsCalcFigState(cnsfig_list
*ptcnsfig
, cbhseq
*ptcbhseq
)
819 cone_list
*ptloconcone
, *ptcone
, *ptoutcone
;
822 chain_list
*ptFIFO
= NULL
;
825 long cbhseq_state
= 0;
830 /* Initialize cones to unknown until we can say otherwise */
831 for (ptcone
= ptcnsfig
->CONE
; ptcone
; ptcone
= ptcone
->NEXT
) {
832 ptcone
->TECTYPE
|= CNS_STATE_UNKNOWN
;
835 /* Initialize FIFO with cone driven by input connectors */
836 for (ptlocon
= ptcnsfig
->LOCON
; ptlocon
; ptlocon
= ptlocon
->NEXT
) {
837 ptuser
= getptype(ptlocon
->USER
, CNS_TYPELOCON
);
838 if (ptuser
== NULL
) continue;
839 state_type
= ((long)ptuser
->DATA
) & (CNS_ZERO
|CNS_INIT_ZERO
|CNS_ONE
|CNS_INIT_ONE
);
840 if (state_type
!= 0) {
841 if ((state_type
& CNS_INIT_ONE
) != 0) state_type
|= CNS_STATE_ONE
;
842 if ((state_type
& CNS_INIT_ZERO
) != 0) state_type
|= CNS_STATE_ZERO
;
843 state_type
&= (CNS_ZERO
|CNS_STATE_ZERO
|CNS_ONE
|CNS_STATE_ONE
);
844 ptuser
->DATA
= (void *)((long)ptuser
->DATA
| state_type
);
846 if ((ptuser
= getptype(ptlocon
->USER
, CNS_EXT
)) != NULL
) {
847 ptloconcone
= (cone_list
*)ptuser
->DATA
;
848 ptloconcone
->TECTYPE
&= ~CNS_STATE_UNKNOWN
;
849 ptloconcone
->TECTYPE
|= state_type
;
850 for (ptedge
= ptloconcone
->OUTCONE
; ptedge
; ptedge
= ptedge
->NEXT
) {
851 if ((ptedge
->TYPE
& CNS_EXT
) == 0) {
852 cnsFIFOPush(&ptFIFO
, ptedge
->UEDGE
.CONE
);
856 if ((ptuser
= getptype(ptlocon
->USER
, CNS_CONE
)) != NULL
) {
857 for (ptchain
= (chain_list
*)ptuser
->DATA
; ptchain
; ptchain
= ptchain
->NEXT
) {
858 ptcone
= (cone_list
*)ptchain
->DATA
;
859 if (ptcone
!= ptloconcone
) cnsFIFOPush(&ptFIFO
, ptcone
);
862 if (ptcbhseq
&& ptlocon
->NAME
== ptcbhseq
->STATEPIN
) cbhseq_state
= state_type
;
866 /* run until the FIFO is empty */
867 while (ptFIFO
!= NULL
) {
868 ptcone
= (cone_list
*)cnsFIFOPop(&ptFIFO
);
869 if (ptcbhseq
&& (ptcone
->NAME
== ptcbhseq
->LATCHNAME
|| ptcone
->NAME
== ptcbhseq
->SLAVENAME
)) {
870 default_state
= cnsCalcLatchCbhState(ptcone
, ptcbhseq
, cbhseq_state
);
872 else default_state
= CNS_STATE_UNKNOWN
;
873 changed
= cnsCalcConeState(ptcone
, default_state
);
874 state_type
= ptcone
->TECTYPE
& (CNS_ZERO
|CNS_STATE_ZERO
|CNS_ONE
|CNS_STATE_ONE
);
875 if (changed
&& state_type
!= 0) {
876 for (ptedge
= ptcone
->OUTCONE
; ptedge
; ptedge
= ptedge
->NEXT
) {
877 if ((ptedge
->TYPE
& CNS_EXT
) == 0) {
878 ptoutcone
= ptedge
->UEDGE
.CONE
;
879 cnsFIFOPush(&ptFIFO
, ptedge
->UEDGE
.CONE
);
882 ptlocon
= ptedge
->UEDGE
.LOCON
;
883 if ((ptuser
= getptype(ptlocon
->USER
, CNS_TYPELOCON
)) != NULL
) {
884 ptuser
->DATA
= (void *)((long)ptuser
->DATA
| state_type
);
886 else ptlocon
->USER
= addptype(ptlocon
->USER
, CNS_TYPELOCON
, (void *)state_type
);
893 /****************************************************************************
894 * function cnsCleanFigState(); *
895 ****************************************************************************/
896 /*------------------------------------------------+
897 | Removes thee calculated state markings leaving |
898 | just those of the input connectors |
899 +------------------------------------------------*/
902 cnsCleanFigState(cnsfig_list
*ptcnsfig
, cbhseq
*ptcbhseq
)
908 for (ptlocon
= ptcnsfig
->LOCON
; ptlocon
; ptlocon
= ptlocon
->NEXT
) {
909 if (ptlocon
->DIRECTION
== CNS_I
|| ptlocon
->DIRECTION
== CNS_T
) continue;
910 if (ptcbhseq
&& ptlocon
->NAME
== ptcbhseq
->STATEPIN
) continue;
911 if ((ptuser
= getptype(ptlocon
->USER
, CNS_TYPELOCON
)) != NULL
) {
912 ptuser
->DATA
= (void *)((long)ptuser
->DATA
& ~(CNS_STATE_ZERO
|CNS_STATE_ONE
));
913 if (ptuser
->DATA
== NULL
) {
914 ptlocon
->USER
= delptype(ptlocon
->USER
, CNS_TYPELOCON
);
918 for (ptcone
= ptcnsfig
->CONE
; ptcone
; ptcone
= ptcone
->NEXT
) {
919 ptcone
->TECTYPE
&= ~(CNS_STATE_ZERO
|CNS_STATE_ONE
|CNS_STATE_UNKNOWN
);