1 /****************************************************************************/
3 /* Chaine de CAO & VLSI Alliance */
5 /* Produit : YAGLE v3.0 */
6 /* Fichier : yag_resolve.c */
8 /* (c) copyright 1997 Laboratoire MASI equipe CAO & VLSI */
9 /* Tous droits reserves */
10 /* Support : e-mail cao-vlsi@masi.ibp.fr */
12 /* Auteur(s) : Anthony LESTER le : 04/09/1997 */
14 /* Modifie par : le : ../../.... */
15 /* Modifie par : le : ../../.... */
16 /* Modifie par : le : ../../.... */
18 /****************************************************************************/
20 #include "yag_headers.h"
22 static pNode mintermResolveBdd
__P((pNode bdd
));
23 static pNode mintermTraverse
__P((pNode bdd
, pNode resbdd
));
24 static pNode enumResolveBdd
__P((pNode bdd
, pNode resbdd
));
25 static pNode enumerateTraverse
__P((chain_list
*varlist
, pNode enumbdd
, pNode resbdd
));
26 static pNode electricResolve
__P((pNode inbdd
, pNode sumbdd
));
27 static int calcLevel
__P((pNode inbdd
));
29 //static pNode unexpand __P((pNode ptbdd, int curindex));
31 static pCircuit PRIMARY_CCT
;
32 static pCircuit DIRECT_CCT
;
34 static cone_list
*RESCONE
;
36 static pNode CONFLICT
;
39 /*************************************************************************
40 * function yagResolveConflicts() *
41 *************************************************************************/
43 /* takes a bdd of the conditions for electrical conflict */
44 /* for a cone and returns bdd representing the conditions */
45 /* for which the conflict resolves to one */
48 yagResolveConflicts(directCct
, primaryCct
, pConflictBdd
, ptcone
)
57 PRIMARY_CCT
= primaryCct
;
58 DIRECT_CCT
= directCct
;
64 res
= mintermResolveBdd(*pConflictBdd
);
66 *pConflictBdd
= CONFLICT
;
70 static chain_list
*ABL
;
72 /*************************************************************************
73 * function mintermResolveBdd() *
74 *************************************************************************/
76 /* minterm traversal of a given Bdd for conflict resolution */
79 mintermResolveBdd(bdd
)
86 if (bdd
== BDD_one
) resbdd
= enumResolveBdd(BDD_one
, resbdd
);
87 else if (bdd
!= BDD_zero
) {
88 ABL
= createExpr(AND
);
89 addQExpr(ABL
, createAtom("'1'"));
90 resbdd
= mintermTraverse(bdd
, resbdd
);
91 if (!ABL
->NEXT
) { freechain(ABL
->DATA
); freechain(ABL
); }
92 else { freeExpr(ABL
); }
98 mintermTraverse(bdd
, resbdd
)
104 if (bdd
== BDD_one
) resbdd
= enumResolveBdd(ablToBddCct(DIRECT_CCT
, ABL
), resbdd
);
105 else if (bdd
!= BDD_zero
) {
106 addHExpr(ABL
, notExpr(createAtom(searchIndexCct(DIRECT_CCT
, bdd
->index
))));
107 resbdd
= mintermTraverse(bdd
->low
, resbdd
);
108 addHExpr(ABL
, createAtom(searchIndexCct(DIRECT_CCT
, bdd
->index
)));
109 resbdd
= mintermTraverse(bdd
->high
, resbdd
);
112 ABL
->NEXT
= ABL
->NEXT
->NEXT
;
114 freeExpr(toDel
->DATA
);
120 /*************************************************************************
121 * function enumResolveBdd() *
122 *************************************************************************/
124 /* Dont Care enumeration of a given BDD for conflict resolution */
127 enumResolveBdd(bdd
, resbdd
)
132 chain_list
*dontcare
= NULL
;
138 support
= supportChain_listBdd(bdd
);
139 for (ptroot
= YAG_CONTEXT
->YAG_CONE_GRAPH
->ROOTNODES
; ptroot
; ptroot
= ptroot
->NEXT
) {
140 ptnode
= (gnode_list
*)ptroot
->DATA
;
141 if ((ptnode
->TYPE
& CONE_TYPE
) != 0) {
142 name
= ptnode
->OBJECT
.CONE
->NAME
;
145 /* node is an external connector */
146 name
= ptnode
->OBJECT
.LOCON
->NAME
;
148 index
= searchInputCct_no_NA(DIRECT_CCT
, name
);
149 if (index
<= 1) continue;
150 if (yagSearchBddList(support
, index
) == NULL
) {
151 dontcare
= addchain(dontcare
, createNodeTermBdd(index
));
155 if (dontcare
!= NULL
) {
156 resbdd
= enumerateTraverse(dontcare
, bdd
, resbdd
);
160 resbdd
= electricResolve(bdd
, resbdd
);
168 yagSearchBddList(ptlist
, index
)
175 for (ptchain
= ptlist
; ptchain
; ptchain
= ptchain
->NEXT
) {
176 ptbdd
= (pNode
)ptchain
->DATA
;
177 if (ptbdd
->index
== index
) break;
179 if (ptchain
!= NULL
) return ptbdd
;
184 enumerateTraverse(varlist
, enumbdd
, resbdd
)
191 nextenum
= applyBinBdd(AND
, enumbdd
, notBdd((pNode
)varlist
->DATA
));
193 if (varlist
->NEXT
!= NULL
) {
194 resbdd
= enumerateTraverse(varlist
->NEXT
, nextenum
, resbdd
);
197 resbdd
= electricResolve(nextenum
, resbdd
);
200 nextenum
= applyBinBdd(AND
, enumbdd
, (pNode
)varlist
->DATA
);
202 if (varlist
->NEXT
!= NULL
) {
203 resbdd
= enumerateTraverse(varlist
->NEXT
, nextenum
, resbdd
);
206 resbdd
= electricResolve(nextenum
, resbdd
);
213 electricResolve(inbdd
, sumbdd
)
220 /* check that condition is functionally possible */
221 inabl
= bddToAblCct(DIRECT_CCT
, inbdd
);
222 primbdd
= ablToBddCct(PRIMARY_CCT
, inabl
);
223 /* apply the contraints */
224 primbdd
= yagApplyConstraints(primbdd
, NULL
);
226 if (primbdd
!= BDD_zero
) {
227 if (calcLevel(inbdd
) == TRUE
) {
228 return applyBinBdd(OR
, inbdd
, sumbdd
);
239 branch_list
*ptbranch
;
241 chain_list
*upList
= NULL
;
242 chain_list
*downList
= NULL
;
245 pNode extupbdd
, extdnbdd
;
247 float downresistance
;
248 int stmresult
= FALSE
;
250 for (ptbranch
= RESCONE
->BRVDD
; ptbranch
; ptbranch
= ptbranch
->NEXT
) {
251 if ((ptbranch
->TYPE
& (CNS_NOT_FUNCTIONAL
|CNS_IGNORE
)) != 0) continue;
252 abl
= cnsMakeBranchExpr(ptbranch
, 0, FALSE
);
253 branchbdd
= ablToBddCct(DIRECT_CCT
, abl
);
254 if (applyBinBdd(AND
, branchbdd
, inbdd
) != BDD_zero
) {
255 upList
= addchain(upList
, ptbranch
);
260 for (ptbranch
= RESCONE
->BRVSS
; ptbranch
; ptbranch
= ptbranch
->NEXT
) {
261 if ((ptbranch
->TYPE
& (CNS_NOT_FUNCTIONAL
|CNS_IGNORE
)) != 0) continue;
262 abl
= cnsMakeBranchExpr(ptbranch
, 0, FALSE
);
263 branchbdd
= ablToBddCct(DIRECT_CCT
, abl
);
264 if (applyBinBdd(AND
, branchbdd
, inbdd
) != BDD_zero
) {
265 downList
= addchain(downList
, ptbranch
);
270 for (ptbranch
= RESCONE
->BREXT
; ptbranch
; ptbranch
= ptbranch
->NEXT
) {
271 if ((ptbranch
->TYPE
& (CNS_NOT_FUNCTIONAL
|CNS_IGNORE
)) != 0) continue;
272 cnsMakeExtBranchExpr(ptbranch
, &extabl
, 0, FALSE
);
273 extupbdd
= ablToBddCct(DIRECT_CCT
, extabl
.UP
);
274 extdnbdd
= ablToBddCct(DIRECT_CCT
, extabl
.DN
);
275 if (applyBinBdd(AND
, extupbdd
, inbdd
) != BDD_zero
) {
276 upList
= addchain(upList
, ptbranch
);
278 else if (applyBinBdd(AND
, extdnbdd
, inbdd
) != BDD_zero
) {
279 downList
= addchain(downList
, ptbranch
);
286 if (YAG_CONTEXT
->YAG_USESTMSOLVER
) {
287 stmresult
= yagCalcStmResPair(upList
, downList
, RESCONE
, &upresistance
, &downresistance
);
292 upresistance
= yagCalcParallelResistance(upList
);
293 downresistance
= yagCalcParallelResistance(downList
);
298 if ( avt_islog(3,LOGYAG
) || YAG_CONTEXT
->YAG_DEBUG_CONE
== YAG_CONTEXT
->YAG_CURCIRCUIT
->name
) {
299 avt_log(LOGYAG
,1,"Input '");
300 abl
= bddToAblCct(DIRECT_CCT
, inbdd
);
301 displayInfExprLog(LOGYAG
, 1, abl
);
303 avt_log(LOGYAG
,1,"' resolves to %.2f", downresistance
/(downresistance
+upresistance
));
305 if (downresistance
>= YAG_CONTEXT
->YAG_THRESHOLD
*upresistance
) {
306 if ( avt_islog(3,LOGYAG
) || YAG_CONTEXT
->YAG_DEBUG_CONE
== YAG_CONTEXT
->YAG_CURCIRCUIT
->name
) {
307 avt_log(LOGYAG
,1, " (\"1\")\n");
311 if (upresistance
>= YAG_CONTEXT
->YAG_THRESHOLD
*downresistance
) {
312 if ( avt_islog(3,LOGYAG
) || YAG_CONTEXT
->YAG_DEBUG_CONE
== YAG_CONTEXT
->YAG_CURCIRCUIT
->name
) {
313 avt_log(LOGYAG
,1, " (\"0\")\n");
317 CONFLICT
= applyBinBdd(OR
, CONFLICT
, inbdd
);
318 if ( avt_islog(3,LOGYAG
) || YAG_CONTEXT
->YAG_DEBUG_CONE
== YAG_CONTEXT
->YAG_CURCIRCUIT
->name
) {
319 avt_log(LOGYAG
,1, "\n");
321 if (downresistance
> upresistance
) return TRUE
;