1 /****************************************************************************/
3 /* Chaine de CAO & VLSI Alliance */
5 /* Produit : YAGLE v3.50 */
6 /* Fichier : yag_timing.c */
8 /* (c) copyright 1991 Laboratoire MASI equipe CAO & VLSI */
9 /* Tous droits reserves */
10 /* Support : e-mail alliance-support@asim.lip6.fr */
12 /* Auteur(s) : Anthony LESTER le : ../../.... */
14 /* Modifie par : le : ../../.... */
15 /* Modifie par : le : ../../.... */
16 /* Modifie par : le : ../../.... */
18 /****************************************************************************/
21 #include "yag_headers.h"
23 static void yagTimeBefig(befig_list
*ptbefig
);
24 static void yagDetectSensitive(cnsfig_list
*ptcnsfig
);
25 static unsigned int yagGetTotalDelay(chain_list
*ptconelist
);
26 static unsigned int yagGetDelay(cone_list
*ptcone
, chain_list
*cndexpr
, chain_list
*valexpr
);
27 static int yagConstantAbl(chain_list
*ptexpr
);
28 static int yagTimeSensitiveBebux(bebux_list
*ptbebux
, cone_list
*ptcone
);
29 static int yagTimeSensitiveBereg(bereg_list
*ptbereg
, cone_list
*ptcone
);
30 static int yagTimeSensitiveBebus(bebus_list
*ptbebus
, cone_list
*ptcone
);
32 /****************************************************************************
33 * function yagPrepTiming(); *
34 ****************************************************************************/
36 yagPrepTiming(lofig_list
*ptlofig
)
41 TAS_CONTEXT
->TAS_CALCRCX
= 'Y';
42 // TAS_CONTEXT->TAS_MERGERCN = 'Y';
43 TAS_CONTEXT
->FRONT_CON
= TAS_NOFRONT
;
44 if (YAG_CONTEXT
->YAG_TAS_TIMING
== YAG_MIN_TIMING
) {
45 TAS_CONTEXT
->TAS_FIND_MIN
= 'Y';
47 TAS_CONTEXT
->TAS_SILENTMODE
= 'Y';
48 if ((ifl
=getloadedinffig(ptlofig
->NAME
))!=NULL
)
49 tas_update_mcctemp (ifl
);
50 tas_TechnoParameters();
53 static chain_list
*yag_buildminterms(cone_list
*ptcone
, chain_list
*cndabl
, chain_list
*valabl
)
55 chain_list
*support
, *list
=NULL
, *tmpexpr
, *samedelay
, *expr
, *cl
, *ch
;
62 support
=supportChain_listExpr(cndabl
);
63 nb
=countchain(support
);
67 list
=ablCreateMintermList(cndabl
);
68 /* exprbdd=ablToBddCct(cct, cndabl);
69 displayExpr(bddToAblCct(cct, exprbdd));*/
73 expr
=(chain_list
*)list
->DATA
;
74 timing
=yagGetDelay(ptcone
, expr
, valabl
);
75 if ((l
=gethtitem(ht
, (void *)timing
))==EMPTYHT
) support
=NULL
;
76 else support
=(chain_list
*)l
;
77 support
=addchain(support
, expr
);
78 addhtitem(ht
, (void *)timing
, (long)support
);
79 list
=delchain(list
, list
);
81 samedelay
=GetAllHTElems(ht
);
84 if (countchain(samedelay
)<=1)
88 for (list
=(chain_list
*)samedelay
->DATA
; list
!=NULL
; list
=list
->NEXT
)
89 freeExpr((chain_list
*)list
->DATA
);
90 freechain((chain_list
*)samedelay
->DATA
);
91 samedelay
=delchain(samedelay
, samedelay
);
99 list
=(chain_list
*)samedelay
->DATA
;
100 if (list
->NEXT
==NULL
)
101 support
=addchain(support
, list
->DATA
);
104 chain_list
*sublist
=NULL
;
105 int cnt
=countchain(list
);
106 if (cnt
<=8) {cnt
=100;}
113 cct
=initializeCct("temp",nb
, 10);
116 if (count
>=cnt
&& cl
->NEXT
!=NULL
) break;
117 tmpexpr
=(chain_list
*)cl
->DATA
;
118 ch
=addchain(ch
, ablToBddCct(cct
, tmpexpr
));
123 if (countchain(ch
)>1)
124 exprbdd
=applyBdd (OR
, ch
);
126 exprbdd
=(pNode
)ch
->DATA
;
127 sublist
=addchain(sublist
, bddToAblCct(cct
, exprbdd
));
129 // support=addchain(support, bddToAblCct(cct, exprbdd));
132 if (sublist
!=NULL
&& sublist
->NEXT
!=NULL
)
134 tmpexpr
=createExpr (OR
);
135 while (sublist
!=NULL
)
137 addQExpr(tmpexpr
, (chain_list
*)sublist
->DATA
);
138 sublist
=delchain(sublist
, sublist
);
140 support
=addchain(support
, tmpexpr
);
144 support
=addchain(support
, sublist
->DATA
);
149 samedelay
=delchain(samedelay
, samedelay
);
158 yagSplitIntoMinterms(biabl_list
**biabl
, cone_list
*ptcone
)
161 biabl_list
*ptnewbiabl
= NULL
, *tmpb
, *knext
;
164 if (!ptcone
) return FALSE
;
166 for (ptbiabl
= *biabl
; ptbiabl
; ptbiabl
= ptbiabl
->NEXT
)
168 ptchain
=yag_buildminterms(ptcone
, ptbiabl
->CNDABL
, ptbiabl
->VALABL
);
169 if (ptchain
==NULL
|| countchain(ptchain
)>V_INT_TAB
[__YAG_MAX_SPLIT_CMD_TIMING
].VALUE
)
171 knext
=ptbiabl
->NEXT
; ptbiabl
->NEXT
=NULL
;
172 tmpb
=beh_dupbiabl(ptbiabl
);
174 tmpb
->NEXT
=ptnewbiabl
;
176 while (ptchain
!=NULL
)
178 freeExpr((chain_list
*)ptchain
->DATA
);
179 ptchain
=delchain(ptchain
, ptchain
);
184 /* if (ptchain!=NULL && ptchain->NEXT!=NULL)
185 printf("split %s\n",ptcone->NAME);*/
186 while (ptchain
!=NULL
)
188 knext
=ptbiabl
->NEXT
; ptbiabl
->NEXT
=NULL
;
189 tmpb
=beh_dupbiabl(ptbiabl
);
191 tmpb
->NEXT
=ptnewbiabl
;
193 freeExpr(tmpb
->CNDABL
);
194 tmpb
->CNDABL
=(chain_list
*)ptchain
->DATA
;
195 ptchain
=delchain(ptchain
, ptchain
);
199 ptnewbiabl
= (biabl_list
*)reverse((chain_list
*)ptnewbiabl
);
200 beh_frebiabl(*biabl
);
207 yagDetectSensitive(cnsfig_list
*ptcnsfig
)
211 unsigned int upmax
, upmin
;
212 unsigned int dnmax
, dnmin
;
214 chain_list
*name_expr
;
215 chain_list
*one_expr
, *zero_expr
;
218 if (YAG_CONTEXT
->YAG_SENSITIVE_RATIO
< 1) return;
219 one_expr
= createAtom("'1'");
220 zero_expr
= createAtom("'0'");
222 for (ptcone
= ptcnsfig
->CONE
; ptcone
; ptcone
= ptcone
->NEXT
) {
223 if (YAG_CONTEXT
->YAG_SENSITIVE_MAX
> 0 && yagCountEdges(ptcone
->INCONE
) > YAG_CONTEXT
->YAG_SENSITIVE_MAX
) continue;
228 for (ptinput
= ptcone
->INCONE
; ptinput
; ptinput
= ptinput
->NEXT
) {
229 if ((ptinput
->TYPE
& CNS_EXT
) != 0) {
230 name
= ptinput
->UEDGE
.LOCON
->NAME
;
232 else name
= ptinput
->UEDGE
.CONE
->NAME
;
233 name_expr
= createAtom(mbk_devect(name
, "[", "]"));
234 delay
= yagGetDelay(ptcone
, name_expr
, createAtom("'1'"));
236 if (upmax
== 0 || delay
> upmax
) upmax
= delay
;
237 if (upmin
== 0 || delay
< upmin
) upmin
= delay
;
239 delay
= yagGetDelay(ptcone
, name_expr
, createAtom("'0'"));
241 if (dnmax
== 0 || delay
> dnmax
) dnmax
= delay
;
242 if (dnmin
== 0 || delay
< dnmin
) dnmin
= delay
;
246 if (upmax
> upmin
* YAG_CONTEXT
->YAG_SENSITIVE_RATIO
247 || dnmax
> dnmin
* YAG_CONTEXT
->YAG_SENSITIVE_RATIO
) {
248 ptcone
->TECTYPE
|= YAG_SENSITIVE
;
256 yagGetRCDelay(cone_list
*ptcone
, char *input
, int dir
)
263 int useRising
= TRUE
;
264 int useFalling
= TRUE
;
267 if (ptcone
== NULL
) return 0;
269 if (dir
==1) useFalling
= FALSE
;
270 else if (dir
==0) useRising
= FALSE
;
272 for (ptincone
= ptcone
->INCONE
; ptincone
; ptincone
= ptincone
->NEXT
) {
273 if ((ptincone
->TYPE
& CNS_EXT
) == 0) inputname
= ptincone
->UEDGE
.CONE
->NAME
;
274 else inputname
= ptincone
->UEDGE
.LOCON
->NAME
;
275 if (input
!=mbk_devect(inputname
, "[", "]")) continue;
276 ptuser
= getptype(ptincone
->USER
, TAS_DELAY_MAX
);
277 if (ptuser
!= NULL
) {
278 delay
= (delay_list
*)ptuser
->DATA
;
279 if (useRising
&& delay
->RCHH
!= TAS_NOTIME
) {
280 delaymax
+= delay
->RCHH
;
283 if (useFalling
&& delay
->RCLL
!= TAS_NOTIME
) {
284 delaymax
+= delay
->RCLL
;
288 if (n
!=0) delaymax
/=n
;
289 delaymax
=mbk_long_round(delaymax
/TTV_UNIT
);
290 if (delaymax
> 0) return ((unsigned int)delaymax
);
296 static ht
*RC_WRAP_HT
;
297 static cone_list
*RC_WRAP_CONE
;
299 static char *rc_wrap_func(char *input
)
302 int rcvalup
, rcvaldown
;
306 minrc
=mbk_long_round(V_FLOAT_TAB
[__YAG_MIN_RC
].VALUE
*1e12
);
307 if (minrc
<=0) minrc
=1;
308 rcstep
=mbk_long_round(V_FLOAT_TAB
[__YAG_RC_STEP
].VALUE
*1e12
);
309 if (rcstep
<1) rcstep
=1;
311 rcvaldown
=yagGetRCDelay(RC_WRAP_CONE
, input
, 0);
312 rcvalup
=yagGetRCDelay(RC_WRAP_CONE
, input
, 1);
313 if (rcvalup
>minrc
|| rcvaldown
>minrc
)
315 rcvalup
=mbk_long_round((float)rcvalup
/rcstep
)*rcstep
;
316 rcvaldown
=mbk_long_round((float)rcvaldown
/rcstep
)*rcstep
;
317 if (rcvalup
==0) rcvalup
=minrc
;
318 if (rcvaldown
==0) rcvaldown
=minrc
;
319 if (rcvalup
==rcvaldown
)
320 sprintf(buf
, "%s|%dps", input
, rcvalup
);
322 sprintf(buf
, "%s|%dps|%dps", input
, rcvalup
,rcvaldown
);
323 if ((c
=strchr(buf
, ' '))!=NULL
) *c
='|';
324 inputrc
=namealloc(buf
);
325 if (gethtitem(RC_WRAP_HT
, inputrc
)==EMPTYHT
)
326 addhtitem(RC_WRAP_HT
, inputrc
, (long)addptype(addptype(NULL
, rcvaldown
, input
), rcvalup
, input
));
332 static void yagCheckRCandUpdateNames(cone_list
*cn
, ht
*rcht
, chain_list
*cndexpr
, chain_list
*valexpr
)
337 if (cndexpr
!=NULL
) beh_wrapAtomExpr(cndexpr
, rc_wrap_func
);
338 if (valexpr
!=NULL
) beh_wrapAtomExpr(valexpr
, rc_wrap_func
);
341 static void yadAddRC(ht
*rcht
, befig_list
*ptbefig
)
347 allrc
=GetAllHTKeys(rcht
);
350 inputrc
=(char *)allrc
->DATA
;
351 pt
=(ptype_list
*)gethtitem(rcht
, inputrc
);
352 ptbefig
->BEAUX
= beh_addbeaux (ptbefig
->BEAUX
, inputrc
, createAtom((char *)pt
->DATA
), NULL
, 0);
353 ptbefig
->BEAUX
->TIMER
=pt
->TYPE
;
354 ptbefig
->BEAUX
->TIMEF
=pt
->NEXT
->TYPE
;
356 allrc
=delchain(allrc
, allrc
);
360 /****************************************************************************
361 * function yagAddTiming(); *
362 ****************************************************************************/
364 yagAddTiming(cnsfig_list
*ptcnsfig
, lofig_list
*ptlofig
)
373 ifl
= getloadedinffig(YAG_CONTEXT
->YAG_FIGNAME
);
375 cns_addmultivoltage(ifl
, ptcnsfig
);
377 yagChrono(&START
,&start
);
378 if (!YAG_CONTEXT
->YAG_SILENT_MODE
) yagMessage(MES_TAS_TECHNO
, NULL
);
379 if (MCC_HEADTECHNO
== NULL
&& ELP_MODEL_LIST
== NULL
) {
380 if (!YAG_CONTEXT
->YAG_SILENT_MODE
) {
381 yagChrono(&END
,&end
);
382 if (!YAG_CONTEXT
->YAG_SILENT_MODE
) yagPrintTime(&START
,&END
,start
,end
);
383 yagMessage(MES_NO_TECHNO_FILE
, NULL
);
385 YAG_CONTEXT
->YAG_TAS_TIMING
= YAG_NO_TIMING
;
388 elpLofigAddCapas (ptlofig
,( (mcc_use_multicorner() == 0 ) ? elpTYPICAL
: elpWORST
));
389 yagChrono(&END
,&end
);
390 if (!YAG_CONTEXT
->YAG_SILENT_MODE
) yagPrintTime(&START
,&END
,start
,end
);
393 if (YAG_CONTEXT
->YAG_TAS_TIMING
!= YAG_NO_TIMING
) {
394 yagChrono(&START
,&start
);
395 yagMessage(MES_TAS_TIMING
, NULL
);
396 tas_detectinout(ptcnsfig
);
397 tas_initcnsfigalloc(ptcnsfig
);
398 TAS_CONTEXT
->TAS_LOFIG
= ptlofig
;
400 tas_loconorient(ptlofig
, NULL
);
401 tas_timing(ptcnsfig
, ptlofig
, NULL
);
402 for (ptlocon
= ptlofig
->LOCON
; ptlocon
; ptlocon
= ptlocon
->NEXT
) {
403 ptlocon
->NAME
= mbk_devect(ptlocon
->NAME
, "[", "]");
405 trcflushdelaycache();
407 yagDetectSensitive(ptcnsfig
);
408 if (ptcnsfig
->BEFIG
!= NULL
) yagTimeBefig(ptcnsfig
->BEFIG
);
409 tas_freecnsfigalloc(ptcnsfig
);
410 yagChrono(&END
,&end
);
411 yagPrintTime(&START
,&END
,start
,end
);
416 already_timed(biabl_list
*ptbiabl
)
418 for (;ptbiabl
; ptbiabl
= ptbiabl
->NEXT
) {
419 if (ptbiabl
->TIME
!= 0) return TRUE
;
424 static void yag_check_single_delay(biabl_list
*BIABL
)
426 unsigned int uptime
, downtime
;
429 if (V_FLOAT_TAB
[__YAG_SINGLE_DELAY_RATIO
].VALUE
>1.0)
433 for (ptbiabl
= BIABL
; ptbiabl
; ptbiabl
= ptbiabl
->NEXT
) {
434 if (downtime
>ptbiabl
->TIME
) downtime
=ptbiabl
->TIME
;
435 if (uptime
<ptbiabl
->TIME
) uptime
=ptbiabl
->TIME
;
437 if (downtime
>0 && (float)(uptime
-downtime
)/(float)downtime
<V_FLOAT_TAB
[__YAG_SINGLE_DELAY_RATIO
].VALUE
) {
438 for (ptbiabl
= BIABL
; ptbiabl
; ptbiabl
= ptbiabl
->NEXT
) {
439 ptbiabl
->TIME
=(int)(0.5+(uptime
+downtime
)/2.0);
445 /****************************************************************************
446 * function yagTimeBefig(); *
447 ****************************************************************************/
449 yagTimeBefig(befig_list
*ptbefig
)
452 beaux_list
*ptprevbeaux
= NULL
;
453 beaux_list
*ptnextbeaux
= NULL
;
455 beout_list
*ptprevbeout
= NULL
;
456 beout_list
*ptnextbeout
= NULL
;
458 bebux_list
*ptprevbebux
= NULL
;
459 bebux_list
*ptnextbebux
= NULL
;
461 bebus_list
*ptprevbebus
= NULL
;
462 bebus_list
*ptnextbebus
= NULL
;
468 unsigned int conedelay
;
469 unsigned int uptime
, downtime
;
470 int processed
, sensitive
, split
;
471 chain_list
*oneexpr
, *zeroexpr
;
474 oneexpr
= createAtom("'1'");
475 zeroexpr
= createAtom("'0'");
480 for (ptbebux
= ptbefig
->BEBUX
; ptbebux
; ptbebux
= ptbebux
->NEXT
) {
481 if (already_timed(ptbebux
->BIABL
)) continue;
484 if (ptbebux
->BINODE
!= NULL
) ptquad
= (bequad_list
*)ptbebux
->BINODE
->VALNODE
;
486 if (ptquad
!= NULL
) {
487 ptuser
= getptype(ptquad
->USER
, YAG_CONE_PTYPE
);
488 if (ptuser
!= NULL
) {
489 ptcone
= (cone_list
*)ptuser
->DATA
;
490 if (ptcone
!= NULL
) {
491 if ((ptcone
->TECTYPE
& YAG_SENSITIVE
) == YAG_SENSITIVE
&& strchr(ptbebux
->NAME
, ' ') == NULL
) {
492 processed
= yagTimeSensitiveBebux(ptbebux
, ptcone
);
494 ptbefig
->BEREG
= beh_addbereg(ptbefig
->BEREG
, ptbebux
->NAME
, ptbebux
->BIABL
, NULL
,0);
495 ptbebux
->BIABL
= NULL
;
496 ptbebux
->NAME
= NULL
;
499 else if (V_INT_TAB
[__YAG_MAX_SPLIT_CMD_TIMING
].VALUE
>0)
500 yagSplitIntoMinterms(&ptbebux
->BIABL
, ptcone
);
503 for (ptbiabl
= ptbebux
->BIABL
; ptbiabl
; ptbiabl
= ptbiabl
->NEXT
) {
504 ptbiabl
->TIME
= yagGetDelay(ptcone
, ptbiabl
->CNDABL
, ptbiabl
->VALABL
);
507 for (ptbiabl
= ptbebux
->BIABL
; ptbiabl
; ptbiabl
= ptbiabl
->NEXT
)
508 yagCheckRCandUpdateNames(ptcone
, rcht
, ptbiabl
->CNDABL
, ptbiabl
->VALABL
);
511 ptuser
= getptype(ptquad
->USER
, YAG_CONELIST_PTYPE
);
512 if (ptuser
!= NULL
) {
513 conedelay
= yagGetTotalDelay((chain_list
*)ptuser
->DATA
);
515 if (conedelay
!= 0) {
516 for (ptbiabl
= ptbebux
->BIABL
; ptbiabl
; ptbiabl
= ptbiabl
->NEXT
) {
517 if (ptbiabl
->TIME
!= 0) continue;
518 ptbiabl
->TIME
= conedelay
;
522 if (!processed
) yag_check_single_delay(ptbebux
->BIABL
);
525 for (ptbebus
= ptbefig
->BEBUS
; ptbebus
; ptbebus
= ptbebus
->NEXT
) {
526 if (already_timed(ptbebus
->BIABL
)) continue;
528 if (ptbebus
->BINODE
!= NULL
) ptquad
= (bequad_list
*)ptbebus
->BINODE
->VALNODE
;
530 if (ptquad
!= NULL
) {
531 ptuser
= getptype(ptquad
->USER
, YAG_CONE_PTYPE
);
532 if (ptuser
!= NULL
) {
533 ptcone
= (cone_list
*)ptuser
->DATA
;
534 if (ptcone
!= NULL
) {
535 if ((ptcone
->TECTYPE
& YAG_SENSITIVE
) == YAG_SENSITIVE
&& strchr(ptbebus
->NAME
, ' ') == NULL
) {
536 processed
= yagTimeSensitiveBebus(ptbebus
, ptcone
);
538 ptbefig
->BEREG
= beh_addbereg(ptbefig
->BEREG
, ptbebus
->NAME
, ptbebus
->BIABL
, NULL
,0);
539 ptbebus
->BIABL
= NULL
;
540 ptbebus
->NAME
= NULL
;
543 else if (V_INT_TAB
[__YAG_MAX_SPLIT_CMD_TIMING
].VALUE
>0)
544 yagSplitIntoMinterms(&ptbebus
->BIABL
, ptcone
);
547 for (ptbiabl
= ptbebus
->BIABL
; ptbiabl
; ptbiabl
= ptbiabl
->NEXT
) {
548 ptbiabl
->TIME
= yagGetDelay(ptcone
, ptbiabl
->CNDABL
, ptbiabl
->VALABL
);
551 for (ptbiabl
= ptbebus
->BIABL
; ptbiabl
; ptbiabl
= ptbiabl
->NEXT
)
552 yagCheckRCandUpdateNames(ptcone
, rcht
, ptbiabl
->CNDABL
, ptbiabl
->VALABL
);
555 ptuser
= getptype(ptquad
->USER
, YAG_CONELIST_PTYPE
);
556 if (ptuser
!= NULL
) {
557 conedelay
= yagGetTotalDelay((chain_list
*)ptuser
->DATA
);
559 if (conedelay
!= 0) {
560 for (ptbiabl
= ptbebus
->BIABL
; ptbiabl
; ptbiabl
= ptbiabl
->NEXT
) {
561 if (ptbiabl
->TIME
!= 0) continue;
562 ptbiabl
->TIME
= conedelay
;
566 if (!processed
) yag_check_single_delay(ptbebus
->BIABL
);
569 for (ptbereg
= ptbefig
->BEREG
; ptbereg
; ptbereg
= ptbereg
->NEXT
) {
570 if (already_timed(ptbereg
->BIABL
)) continue;
572 if (ptbereg
->BINODE
!= NULL
) ptquad
= (bequad_list
*)ptbereg
->BINODE
->VALNODE
;
574 if (ptquad
!= NULL
) {
575 ptuser
= getptype(ptquad
->USER
, YAG_CONE_PTYPE
);
576 if (ptuser
!= NULL
) {
577 ptcone
= (cone_list
*)ptuser
->DATA
;
578 if (ptcone
!= NULL
) {
579 if ((ptcone
->TECTYPE
& YAG_SENSITIVE
) == YAG_SENSITIVE
) {
580 processed
= yagTimeSensitiveBereg(ptbereg
, ptcone
);
582 else if (V_INT_TAB
[__YAG_MAX_SPLIT_CMD_TIMING
].VALUE
>0)
583 yagSplitIntoMinterms(&ptbereg
->BIABL
, ptcone
);
586 for (ptbiabl
= ptbereg
->BIABL
; ptbiabl
; ptbiabl
= ptbiabl
->NEXT
) {
587 ptbiabl
->TIME
= yagGetDelay(ptcone
, ptbiabl
->CNDABL
, ptbiabl
->VALABL
);
590 for (ptbiabl
= ptbereg
->BIABL
; ptbiabl
; ptbiabl
= ptbiabl
->NEXT
)
591 yagCheckRCandUpdateNames(ptcone
, rcht
, ptbiabl
->CNDABL
, ptbiabl
->VALABL
);
594 ptuser
= getptype(ptquad
->USER
, YAG_CONELIST_PTYPE
);
595 if (ptuser
!= NULL
) {
596 conedelay
= yagGetTotalDelay((chain_list
*)ptuser
->DATA
);
598 if (conedelay
!= 0) {
599 for (ptbiabl
= ptbereg
->BIABL
; ptbiabl
; ptbiabl
= ptbiabl
->NEXT
) {
600 if (ptbiabl
->TIME
!= 0) continue;
601 ptbiabl
->TIME
= conedelay
;
605 if (!processed
) yag_check_single_delay(ptbereg
->BIABL
);
608 for (ptbeaux
= ptbefig
->BEAUX
; ptbeaux
; ptbeaux
= ptbeaux
->NEXT
) {
609 if (ptbeaux
->TIME
!= 0) continue;
611 if (ptbeaux
->TIME
!= 0) continue;
612 ptquad
= (bequad_list
*)ptbeaux
->NODE
;
613 if (ptquad
!= NULL
) {
614 ptuser
= getptype(ptquad
->USER
, YAG_CONE_PTYPE
);
615 if (ptuser
!= NULL
) {
616 ptcone
= (cone_list
*)ptuser
->DATA
;
617 uptime
= yagGetDelay(ptcone
, NULL
, oneexpr
);
618 downtime
= yagGetDelay(ptcone
, NULL
, zeroexpr
);
619 if (ptcone
!= NULL
) sensitive
= ((ptcone
->TECTYPE
& YAG_SENSITIVE
) == YAG_SENSITIVE
);
620 else sensitive
= FALSE
;
621 if (ptcone
!= NULL
) split
= ((ptcone
->TECTYPE
& YAG_SPLITTIMING
) == YAG_SPLITTIMING
);
623 if (((YAG_CONTEXT
->YAG_SPLITTIMING_RATIO
>= 1.0 && (uptime
> downtime
* YAG_CONTEXT
->YAG_SPLITTIMING_RATIO
|| downtime
> uptime
* YAG_CONTEXT
->YAG_SPLITTIMING_RATIO
)) || sensitive
|| split
)
624 && strchr(ptbeaux
->NAME
, ' ') == NULL
) {
625 ptbiabl
= beh_addbiabl(NULL
, "label", copyExpr(oneexpr
), createAtom(namealloc("'u'")));
626 ptbiabl
->FLAG
|= BEH_CND_PRECEDE
;
627 ptbiabl
= beh_addbiabl(ptbiabl
, "label", notExpr(copyExpr(ptbeaux
->ABL
)), copyExpr(zeroexpr
));
628 ptbiabl
->FLAG
|= BEH_CND_PRECEDE
;
629 ptbiabl
->TIME
= downtime
;
630 ptbiabl
= beh_addbiabl(ptbiabl
, "label", copyExpr(ptbeaux
->ABL
), copyExpr(oneexpr
));
631 ptbiabl
->TIME
= uptime
;
633 ptbefig
->BEREG
= beh_addbereg(ptbefig
->BEREG
, ptbeaux
->NAME
, ptbiabl
, NULL
,0);
634 processed
= yagTimeSensitiveBereg(ptbefig
->BEREG
, ptcone
);
635 if (V_INT_TAB
[__YAG_MAX_SPLIT_CMD_TIMING
].VALUE
>0)
636 yagSplitIntoMinterms(&ptbefig
->BEREG
->BIABL
, ptcone
);
637 for (ptbiabl
= ptbefig
->BEREG
->BIABL
; ptbiabl
; ptbiabl
= ptbiabl
->NEXT
)
638 yagCheckRCandUpdateNames(ptcone
, rcht
, ptbiabl
->CNDABL
, ptbiabl
->VALABL
);
641 ptbefig
->BEBUX
= beh_addbebux(ptbefig
->BEBUX
, ptbeaux
->NAME
, ptbiabl
, NULL
, 'M',0);
642 yagWarning(WAR_SPLIT_TIMING
, NULL
, ptbeaux
->NAME
, NULL
, 0);
643 if (V_INT_TAB
[__YAG_MAX_SPLIT_CMD_TIMING
].VALUE
>0)
644 yagSplitIntoMinterms(&ptbefig
->BEBUX
->BIABL
, ptcone
);
645 for (ptbiabl
= ptbefig
->BEBUX
->BIABL
; ptbiabl
; ptbiabl
= ptbiabl
->NEXT
)
646 yagCheckRCandUpdateNames(ptcone
, rcht
, ptbiabl
->CNDABL
, ptbiabl
->VALABL
);
648 ptbeaux
->NAME
= NULL
;
651 ptbeaux
->TIME
= yagGetDelay((cone_list
*)ptuser
->DATA
, NULL
, NULL
);
652 ptbeaux
->TIMER
= uptime
;
653 ptbeaux
->TIMEF
= downtime
;
654 yagCheckRCandUpdateNames(ptcone
, rcht
, NULL
, ptbeaux
->ABL
);
658 ptuser
= getptype(ptquad
->USER
, YAG_CONELIST_PTYPE
);
659 if (ptuser
!= NULL
) {
660 ptbeaux
->TIME
= yagGetTotalDelay((chain_list
*)ptuser
->DATA
);
665 for (ptbeout
= ptbefig
->BEOUT
; ptbeout
; ptbeout
= ptbeout
->NEXT
) {
666 if (ptbeout
->TIME
!= 0) continue;
668 if (ptbeout
->TIME
!= 0) continue;
669 ptquad
= (bequad_list
*)ptbeout
->NODE
;
670 if (ptquad
!= NULL
) {
671 ptuser
= getptype(ptquad
->USER
, YAG_CONE_PTYPE
);
672 if (ptuser
!= NULL
) {
673 ptcone
= (cone_list
*)ptuser
->DATA
;
674 uptime
= yagGetDelay(ptcone
, NULL
, oneexpr
);
675 downtime
= yagGetDelay(ptcone
, NULL
, zeroexpr
);
676 if (ptcone
!= NULL
) sensitive
= ((ptcone
->TECTYPE
& YAG_SENSITIVE
) == YAG_SENSITIVE
);
677 else sensitive
= FALSE
;
678 if (ptcone
!= NULL
) split
= ((ptcone
->TECTYPE
& YAG_SPLITTIMING
) == YAG_SPLITTIMING
);
680 if (((YAG_CONTEXT
->YAG_SPLITTIMING_RATIO
>= 1.0 && (uptime
> downtime
* YAG_CONTEXT
->YAG_SPLITTIMING_RATIO
|| downtime
> uptime
* YAG_CONTEXT
->YAG_SPLITTIMING_RATIO
)) || sensitive
|| split
)
681 && strchr(ptbeout
->NAME
, ' ') == NULL
) {
682 ptbiabl
= beh_addbiabl(NULL
, "label", copyExpr(oneexpr
), createAtom(namealloc("'u'")));
683 ptbiabl
->FLAG
|= BEH_CND_PRECEDE
;
684 ptbiabl
= beh_addbiabl(ptbiabl
, "label", notExpr(copyExpr(ptbeout
->ABL
)), copyExpr(zeroexpr
));
685 ptbiabl
->FLAG
|= BEH_CND_PRECEDE
;
686 ptbiabl
->TIME
= downtime
;
687 ptbiabl
= beh_addbiabl(ptbiabl
, "label", copyExpr(ptbeout
->ABL
), copyExpr(oneexpr
));
688 ptbiabl
->TIME
= uptime
;
690 ptbefig
->BEREG
= beh_addbereg(ptbefig
->BEREG
, ptbeout
->NAME
, ptbiabl
, NULL
,0);
691 processed
= yagTimeSensitiveBereg(ptbefig
->BEREG
, ptcone
);
692 if (V_INT_TAB
[__YAG_MAX_SPLIT_CMD_TIMING
].VALUE
>0)
693 yagSplitIntoMinterms(&ptbefig
->BEREG
->BIABL
, ptcone
);
694 for (ptbiabl
= ptbefig
->BEREG
->BIABL
; ptbiabl
; ptbiabl
= ptbiabl
->NEXT
)
695 yagCheckRCandUpdateNames(ptcone
, rcht
, ptbiabl
->CNDABL
, ptbiabl
->VALABL
);
698 ptbefig
->BEBUS
= beh_addbebus(ptbefig
->BEBUS
, ptbeout
->NAME
, ptbiabl
, NULL
, 'M',0);
699 yagWarning(WAR_SPLIT_TIMING
, NULL
, ptbeout
->NAME
, NULL
, 0);
700 if (V_INT_TAB
[__YAG_MAX_SPLIT_CMD_TIMING
].VALUE
>0)
701 yagSplitIntoMinterms(&ptbefig
->BEBUS
->BIABL
, ptcone
);
702 for (ptbiabl
= ptbefig
->BEBUS
->BIABL
; ptbiabl
; ptbiabl
= ptbiabl
->NEXT
)
703 yagCheckRCandUpdateNames(ptcone
, rcht
, ptbiabl
->CNDABL
, ptbiabl
->VALABL
);
705 ptbeout
->NAME
= NULL
;
708 ptbeout
->TIME
= yagGetDelay((cone_list
*)ptuser
->DATA
, NULL
, NULL
);
709 ptbeout
->TIMER
= uptime
;
710 ptbeout
->TIMEF
= downtime
;
711 yagCheckRCandUpdateNames(ptcone
, rcht
, NULL
, ptbeout
->ABL
);
715 ptuser
= getptype(ptquad
->USER
, YAG_CONELIST_PTYPE
);
716 if (ptuser
!= NULL
) {
717 ptbeout
->TIME
= yagGetTotalDelay((chain_list
*)ptuser
->DATA
);
722 for (ptbeaux
= ptbefig
->BEAUX
; ptbeaux
; ptbeaux
= ptnextbeaux
) {
723 ptnextbeaux
= ptbeaux
->NEXT
;
724 if (ptbeaux
->NAME
== NULL
) {
725 freeExpr(ptbeaux
->ABL
);
727 if (ptprevbeaux
== NULL
) {
728 ptbefig
->BEAUX
= ptnextbeaux
;
730 else ptprevbeaux
->NEXT
= ptnextbeaux
;
732 else ptprevbeaux
= ptbeaux
;
734 for (ptbeout
= ptbefig
->BEOUT
; ptbeout
; ptbeout
= ptnextbeout
) {
735 ptnextbeout
= ptbeout
->NEXT
;
736 if (ptbeout
->NAME
== NULL
) {
737 freeExpr(ptbeout
->ABL
);
739 if (ptprevbeout
== NULL
) {
740 ptbefig
->BEOUT
= ptnextbeout
;
742 else ptprevbeout
->NEXT
= ptnextbeout
;
744 else ptprevbeout
= ptbeout
;
746 for (ptbebux
= ptbefig
->BEBUX
; ptbebux
; ptbebux
= ptnextbebux
) {
747 ptnextbebux
= ptbebux
->NEXT
;
748 if (ptbebux
->NAME
== NULL
) {
750 if (ptprevbebux
== NULL
) {
751 ptbefig
->BEBUX
= ptnextbebux
;
753 else ptprevbebux
->NEXT
= ptnextbebux
;
755 else ptprevbebux
= ptbebux
;
757 for (ptbebus
= ptbefig
->BEBUS
; ptbebus
; ptbebus
= ptnextbebus
) {
758 ptnextbebus
= ptbebus
->NEXT
;
759 if (ptbebus
->NAME
== NULL
) {
761 if (ptprevbebus
== NULL
) {
762 ptbefig
->BEBUS
= ptnextbebus
;
764 else ptprevbebus
->NEXT
= ptnextbebus
;
766 else ptprevbebus
= ptbebus
;
774 // creating transmission lines
775 yadAddRC(rcht
, ptbefig
);
779 /****************************************************************************
780 * function yagGetTotalDelay(); *
781 ****************************************************************************/
783 yagGetTotalDelay(chain_list
*ptconelist
)
786 unsigned int result
= 0;
788 for (ptchain
= ptconelist
; ptchain
; ptchain
= ptchain
->NEXT
) {
789 result
+= yagGetDelay((cone_list
*)ptchain
->DATA
, NULL
, NULL
);
794 /****************************************************************************
795 * function yagGetDelay(); *
796 ****************************************************************************/
798 yagGetDelay(cone_list
*ptcone
, chain_list
*cndexpr
, chain_list
*valexpr
)
803 chain_list
*driverinputs
= NULL
;
808 int useRising
= TRUE
;
809 int useFalling
= TRUE
;
812 if (ptcone
== NULL
) return 0;
814 if (valexpr
!= NULL
) {
816 if (!strcmp (VALUE_ATOM (valexpr
), "'1'")) useFalling
= FALSE
;
817 if (!strcmp (VALUE_ATOM (valexpr
), "'0'")) useRising
= FALSE
;
818 if (!strcmp (VALUE_ATOM (valexpr
), "'z'") || !strcmp (VALUE_ATOM (valexpr
), "'u'")) {
824 if (cndexpr
!= NULL
) driverinputs
= supportChain_listExpr(cndexpr
);
825 if (valexpr
!= NULL
) driverinputs
= append(driverinputs
, supportChain_listExpr(valexpr
));
827 switch (YAG_CONTEXT
->YAG_TAS_TIMING
) {
829 for (ptincone
= ptcone
->INCONE
; ptincone
; ptincone
= ptincone
->NEXT
) {
830 if ((ptincone
->TYPE
& CNS_EXT
) == 0) inputname
= ptincone
->UEDGE
.CONE
->NAME
;
831 else inputname
= ptincone
->UEDGE
.LOCON
->NAME
;
832 if (driverinputs
!= NULL
&& yagGetChain(driverinputs
, mbk_devect(inputname
, "[", "]")) == NULL
) continue;
833 ptuser
= getptype(ptincone
->USER
, TAS_DELAY_MAX
);
834 if (ptuser
!= NULL
) {
835 delay
= (delay_list
*)ptuser
->DATA
;
836 if (useRising
&& (delay
->TPHH
!= TAS_NOTIME
) && (n
== 0 || delay
->TPHH
> delaymax
)) {
837 delaymax
= delay
->TPHH
;
840 if (useFalling
&& (delay
->TPHL
!= TAS_NOTIME
) && (n
== 0 || delay
->TPHL
> delaymax
)) {
841 delaymax
= delay
->TPHL
;
844 if (useRising
&& (delay
->TPLH
!= TAS_NOTIME
) && (n
== 0 || delay
->TPLH
> delaymax
)) {
845 delaymax
= delay
->TPLH
;
848 if (useFalling
&& (delay
->TPLL
!= TAS_NOTIME
) && (n
== 0 || delay
->TPLL
> delaymax
)) {
849 delaymax
= delay
->TPLL
;
854 delaymax
=mbk_long_round(delaymax
/TTV_UNIT
);
855 freechain(driverinputs
);
856 if (delaymax
> 0) return ((unsigned int)delaymax
);
857 else return (unsigned int)(V_FLOAT_TAB
[__YAG_DELTA_DELAY
].VALUE
*1e12
*BEH_CNV_PS
+0.5);
860 for (ptincone
= ptcone
->INCONE
; ptincone
; ptincone
= ptincone
->NEXT
) {
861 if ((ptincone
->TYPE
& CNS_EXT
) == 0) inputname
= ptincone
->UEDGE
.CONE
->NAME
;
862 else inputname
= ptincone
->UEDGE
.LOCON
->NAME
;
863 if (driverinputs
!= NULL
&& yagGetChain(driverinputs
, inputname
) == NULL
) continue;
864 ptuser
= getptype(ptincone
->USER
, TAS_DELAY_MIN
);
865 if (ptuser
!= NULL
) {
866 delay
= (delay_list
*)ptuser
->DATA
;
867 if (useRising
&& (delay
->TPHH
!= TAS_NOTIME
) && (n
== 0 || delay
->TPHH
< delaymin
)) {
868 delaymin
= delay
->TPHH
;
871 if (useFalling
&& (delay
->TPHL
!= TAS_NOTIME
) && (n
== 0 || delay
->TPHL
< delaymin
)) {
872 delaymin
= delay
->TPHL
;
875 if (useRising
&& (delay
->TPLH
!= TAS_NOTIME
) && (n
== 0 || delay
->TPLH
< delaymin
)) {
876 delaymin
= delay
->TPLH
;
879 if (useFalling
&& (delay
->TPLL
!= TAS_NOTIME
) && (n
== 0 || delay
->TPLL
< delaymin
)) {
880 delaymin
= delay
->TPLL
;
885 delaymin
=mbk_long_round(delaymin
/TTV_UNIT
);
886 freechain(driverinputs
);
887 if (delaymin
> 0) return ((unsigned int)delaymin
);
888 else return (unsigned int)(V_FLOAT_TAB
[__YAG_DELTA_DELAY
].VALUE
*1e12
*BEH_CNV_PS
+0.5);
891 for (ptincone
= ptcone
->INCONE
; ptincone
; ptincone
= ptincone
->NEXT
) {
892 if ((ptincone
->TYPE
& CNS_EXT
) == 0) inputname
= ptincone
->UEDGE
.CONE
->NAME
;
893 else inputname
= ptincone
->UEDGE
.LOCON
->NAME
;
894 if (driverinputs
!= NULL
&& yagGetChain(driverinputs
, inputname
) == NULL
) continue;
895 ptuser
= getptype(ptincone
->USER
, TAS_DELAY_MAX
);
896 if (ptuser
!= NULL
) {
897 delay
= (delay_list
*)ptuser
->DATA
;
898 if (useRising
&& delay
->TPHH
!= TAS_NOTIME
) {
899 delaysum
+= delay
->TPHH
;
902 if (useFalling
&& delay
->TPHL
!= TAS_NOTIME
) {
903 delaysum
+= delay
->TPHL
;
906 if (useRising
&& delay
->TPLH
!= TAS_NOTIME
) {
907 delaysum
+= delay
->TPLH
;
910 if (useFalling
&& delay
->TPLL
!= TAS_NOTIME
) {
911 delaysum
+= delay
->TPLL
;
916 if (n
) delaysum
=mbk_long_round(delaysum
/(TTV_UNIT
*n
));
917 freechain(driverinputs
);
918 if (delaysum
> 0) return ((unsigned int)(delaysum
));
919 else return (unsigned int)(V_FLOAT_TAB
[__YAG_DELTA_DELAY
].VALUE
*1e12
*BEH_CNV_PS
+0.5);
926 yagConstantAbl(ptexpr
)
929 if (!ATOM(ptexpr
)) return FALSE
;
930 if (!strcmp(VALUE_ATOM(ptexpr
), "'0'")
931 || !strcmp(VALUE_ATOM(ptexpr
), "'1'")
932 || !strcmp(VALUE_ATOM(ptexpr
), "'z'")
933 || !strcmp(VALUE_ATOM(ptexpr
), "'u'")) {
939 /****************************************************************************
940 * function yagTimeSensitiveBebux(); *
941 ****************************************************************************/
943 yagTimeSensitiveBebux(bebux_list
*ptbebux
, cone_list
*ptcone
)
946 biabl_list
*ptnewbiabl
= NULL
;
947 chain_list
*ptsupport
;
949 chain_list
*ptinputexpr
, *trigger
, *ptnewcnd
;
952 /* Check that all drivers are constants */
953 for (ptbiabl
= ptbebux
->BIABL
; ptbiabl
; ptbiabl
= ptbiabl
->NEXT
) {
954 if (!yagConstantAbl(ptbiabl
->VALABL
)) return FALSE
;
957 for (ptbiabl
= ptbebux
->BIABL
; ptbiabl
; ptbiabl
= ptbiabl
->NEXT
) {
958 ptsupport
= supportChain_listExpr(ptbiabl
->CNDABL
);
959 for (ptchain
= ptsupport
; ptchain
; ptchain
= ptchain
->NEXT
) {
960 ptinputexpr
= createAtom(ptchain
->DATA
);
961 delay
= yagGetDelay(ptcone
, ptinputexpr
, ptbiabl
->VALABL
);
962 trigger
= createExpr(STABLE
);
963 addQExpr(trigger
, ptinputexpr
);
964 ptnewcnd
= createExpr(AND
);
965 addQExpr(ptnewcnd
, copyExpr(ptbiabl
->CNDABL
));
966 addQExpr(ptnewcnd
, notExpr(trigger
));
967 ptnewbiabl
= beh_addbiabl(ptnewbiabl
, "label", ptnewcnd
, copyExpr(ptbiabl
->VALABL
));
968 ptnewbiabl
->TIME
= delay
;
971 ptnewbiabl
= (biabl_list
*)reverse((chain_list
*)ptnewbiabl
);
972 beh_frebiabl(ptbebux
->BIABL
);
973 ptbebux
->BIABL
= ptnewbiabl
;
977 /****************************************************************************
978 * function yagTimeSensitiveBereg(); *
979 ****************************************************************************/
981 yagTimeSensitiveBereg(bereg_list
*ptbereg
, cone_list
*ptcone
)
984 biabl_list
*ptnewbiabl
= NULL
;
985 chain_list
*ptsupport
;
987 chain_list
*ptinputexpr
, *trigger
, *ptnewcnd
;
990 /* Check that all drivers are constants */
991 for (ptbiabl
= ptbereg
->BIABL
; ptbiabl
; ptbiabl
= ptbiabl
->NEXT
) {
992 if (!yagConstantAbl(ptbiabl
->VALABL
)) return FALSE
;
995 for (ptbiabl
= ptbereg
->BIABL
; ptbiabl
; ptbiabl
= ptbiabl
->NEXT
) {
996 ptsupport
= supportChain_listExpr(ptbiabl
->CNDABL
);
997 for (ptchain
= ptsupport
; ptchain
; ptchain
= ptchain
->NEXT
) {
998 ptinputexpr
= createAtom(ptchain
->DATA
);
999 delay
= yagGetDelay(ptcone
, ptinputexpr
, ptbiabl
->VALABL
);
1000 trigger
= createExpr(STABLE
);
1001 addQExpr(trigger
, ptinputexpr
);
1002 ptnewcnd
= createExpr(AND
);
1003 addQExpr(ptnewcnd
, copyExpr(ptbiabl
->CNDABL
));
1004 addQExpr(ptnewcnd
, notExpr(trigger
));
1005 ptnewbiabl
= beh_addbiabl(ptnewbiabl
, "label", ptnewcnd
, copyExpr(ptbiabl
->VALABL
));
1006 ptnewbiabl
->TIME
= delay
;
1009 ptnewbiabl
= (biabl_list
*)reverse((chain_list
*)ptnewbiabl
);
1010 beh_frebiabl(ptbereg
->BIABL
);
1011 ptbereg
->BIABL
= ptnewbiabl
;
1015 /****************************************************************************
1016 * function yagTimeSensitiveBebus(); *
1017 ****************************************************************************/
1019 yagTimeSensitiveBebus(bebus_list
*ptbebus
, cone_list
*ptcone
)
1021 biabl_list
*ptbiabl
;
1022 biabl_list
*ptnewbiabl
= NULL
;
1023 chain_list
*ptsupport
;
1024 chain_list
*ptchain
;
1025 chain_list
*ptinputexpr
, *trigger
, *ptnewcnd
;
1028 /* Check that all drivers are constants */
1029 for (ptbiabl
= ptbebus
->BIABL
; ptbiabl
; ptbiabl
= ptbiabl
->NEXT
) {
1030 if (!yagConstantAbl(ptbiabl
->VALABL
)) return FALSE
;
1033 for (ptbiabl
= ptbebus
->BIABL
; ptbiabl
; ptbiabl
= ptbiabl
->NEXT
) {
1034 ptsupport
= supportChain_listExpr(ptbiabl
->CNDABL
);
1035 for (ptchain
= ptsupport
; ptchain
; ptchain
= ptchain
->NEXT
) {
1036 ptinputexpr
= createAtom(ptchain
->DATA
);
1037 delay
= yagGetDelay(ptcone
, ptinputexpr
, ptbiabl
->VALABL
);
1038 trigger
= createExpr(STABLE
);
1039 addQExpr(trigger
, ptinputexpr
);
1040 ptnewcnd
= createExpr(AND
);
1041 addQExpr(ptnewcnd
, copyExpr(ptbiabl
->CNDABL
));
1042 addQExpr(ptnewcnd
, notExpr(trigger
));
1043 ptnewbiabl
= beh_addbiabl(ptnewbiabl
, "label", ptnewcnd
, copyExpr(ptbiabl
->VALABL
));
1044 ptnewbiabl
->TIME
= delay
;
1047 ptnewbiabl
= (biabl_list
*)reverse((chain_list
*)ptnewbiabl
);
1048 beh_frebiabl(ptbebus
->BIABL
);
1049 ptbebus
->BIABL
= ptnewbiabl
;
1053 /****************************************************************************
1054 * function yagCalcStmResPair(); *
1055 ****************************************************************************/
1057 yagCalcStmResPair(chain_list
*uplist
, chain_list
*downlist
, cone_list
*ptcone
, float *ptupresistance
, float *ptdownresistance
)
1061 if (yagCalcStmResistance(uplist
, ptcone
, CNS_VDD
, ptupresistance
)) {
1062 result
= yagCalcStmResistance(downlist
, ptcone
, CNS_VSS
, ptdownresistance
);
1067 /****************************************************************************
1068 * function yagCalcStmResistance(); *
1069 ****************************************************************************/
1071 yagCalcStmResistance(chain_list
*ptbranchlist
, cone_list
*ptcone
, long type
, float *ptresistance
)
1073 chain_list
*ptchain
;
1074 alim_list
*powercone
;
1077 float vout
, vsupply
, vin
;
1080 powercone
=cns_get_multivoltage(ptcone
);
1081 if (powercone
== NULL
) {
1082 vout
= V_FLOAT_TAB
[__SIM_POWER_SUPPLY
].VALUE
/ 2;
1083 if (type
== CNS_VDD
) {
1084 vsupply
= V_FLOAT_TAB
[__SIM_POWER_SUPPLY
].VALUE
;
1089 vin
= V_FLOAT_TAB
[__SIM_POWER_SUPPLY
].VALUE
;
1093 vout
= powercone
->VSSMIN
+ (powercone
->VDDMAX
- powercone
->VSSMIN
) / 2;
1094 if (type
== CNS_VDD
) {
1095 vsupply
= powercone
->VDDMAX
;
1099 vsupply
= powercone
->VSSMIN
;
1100 vin
= V_FLOAT_TAB
[__SIM_POWER_SUPPLY
].VALUE
;
1103 for (ptchain
= ptbranchlist
; ptchain
; ptchain
= ptchain
->NEXT
) {
1104 result
= yagStmBranchCurrent((branch_list
*)ptchain
->DATA
, vin
, vout
, vsupply
, ¤t
);
1105 if (!result
) return FALSE
;
1108 if (type
== CNS_VSS
) sum
= -sum
;
1109 *ptresistance
= 1 / sum
;
1114 yagStmBranchCurrent(branch_list
*ptbranch
, float vin
, float vout
, float vsupply
, float *ptcurrent
)
1116 stm_solver_maillon_list
*ptstmlink
;
1119 cone_list
*prevcone
;
1120 lotrs_list
*ptparatrans
, *ptlotrs
;
1123 chain_list
*ptparachain
, *ptchain
;
1129 /* Only for non-degraded branches with at least one transistor */
1130 if ((ptbranch
->TYPE
& CNS_EXT
) == CNS_EXT
&& ptbranch
->LINK
->NEXT
== NULL
) return FALSE
;
1131 if ((ptbranch
->TYPE
& CNS_DEGRADED
) == CNS_DEGRADED
) return FALSE
;
1133 /* temporarily modify width for parallel transistors */
1134 for (ptlink
= ptbranch
->LINK
; ptlink
; ptlink
= ptlink
->NEXT
) {
1135 if ((ptlink
->TYPE
& CNS_EXT
) == 0) {
1136 ptlotrs
= ptlink
->ULINK
.LOTRS
;
1137 if ((ptuser
= getptype(ptlotrs
->USER
, MBK_TRANS_PARALLEL
)) != NULL
) {
1138 ptparachain
= (chain_list
*)ptuser
->DATA
;
1139 ptlotrs
->USER
= addptype(ptlotrs
->USER
, YAG_WIDTH_PTYPE
, (void *)ptlotrs
->WIDTH
);
1140 length
= ptlotrs
->LENGTH
;
1142 for (ptchain
= ptparachain
; ptchain
; ptchain
= ptchain
->NEXT
) {
1143 ptparatrans
= (lotrs_list
*)ptchain
->DATA
;
1144 width
+= ptparatrans
->WIDTH
* (length
/ ptparatrans
->LENGTH
);
1146 ptlotrs
->WIDTH
= width
;
1151 switch (TAS_CONTEXT
->TAS_LEVEL
) {
1154 brtype
= TAS_TRMODEL_SPICE
;
1157 brtype
= TAS_TRMODEL_MCCRSAT
;
1160 /* create tpiv style branch and set supply */
1161 ptstmbranch
= tpiv_createbranch(ptbranch
->LINK
, brtype
);
1162 for (ptstmlink
= ptstmbranch
->HEAD
; ptstmlink
->NEXT
; ptstmlink
= ptstmlink
->NEXT
);
1163 ptstmlink
->MAILLON
->VS
= vsupply
;
1165 /* fix gate and bulk voltages */
1166 for( ptstmlink
= ptstmbranch
->HEAD
, ptlink
= ptbranch
->LINK
; ptstmlink
; ptstmlink
= ptstmlink
->NEXT
, ptlink
= ptlink
->NEXT
) {
1167 if (TAS_CONTEXT
->TAS_LEVEL
== 2) {
1168 elp_lotrs_param_get(ptlink
->ULINK
.LOTRS
,NULL
,NULL
, NULL
, NULL
,NULL
, NULL
, NULL
, NULL
, NULL
, &vbulk
, NULL
, NULL
, NULL
, NULL
);
1170 else vbulk
= vsupply
;
1171 tas_tpiv_set_vb( ptstmlink
->MAILLON
, vbulk
);
1173 if ((ptlink
->ULINK
.LOTRS
->TYPE
& CNS_TN
) == CNS_TN
) {
1174 prevcone
= (cone_list
*)getptype(ptlink
->ULINK
.LOTRS
->USER
, CNS_DRIVINGCONE
)->DATA
;
1175 power
=cns_get_multivoltage(prevcone
);
1177 tas_tpiv_set_vg( ptstmlink
->MAILLON
, power
->VDDMAX
- power
->VSSMIN
);
1181 tas_tpiv_set_vg( ptstmlink
->MAILLON
, vin
);
1184 result
= stm_solver_i(ptstmbranch
->HEAD
, vout
, ptcurrent
);
1186 tpiv_freebranch(ptstmbranch
);
1189 for (ptlink
= ptbranch
->LINK
; ptlink
; ptlink
= ptlink
->NEXT
) {
1190 if ((ptlink
->TYPE
& CNS_EXT
) == 0) {
1191 ptlotrs
= ptlink
->ULINK
.LOTRS
;
1192 if ((ptuser
= getptype(ptlotrs
->USER
, YAG_WIDTH_PTYPE
)) != NULL
) {
1193 ptlotrs
->WIDTH
= (long)ptuser
->DATA
;
1194 ptlotrs
->USER
= delptype(ptlotrs
->USER
, YAG_WIDTH_PTYPE
);
1203 yagPrepStmSolver(cone_list
*ptcone
)
1207 ifl
= getloadedinffig(YAG_CONTEXT
->YAG_FIGNAME
);
1208 cns_addmultivoltage_cone(NULL
, ifl
, ptcone
);