Initial version of donated sources by Avertec, 3.4p5.
[tas-yagle.git] / distrib / sources / yagle / fcl / fcl_matrix.c
1 /****************************************************************************/
2 /* */
3 /* Chaine de CAO & VLSI Alliance */
4 /* */
5 /* Produit : FCL v1.02 */
6 /* Fichier : fcl_matrix.c */
7 /* */
8 /* (c) copyright 1996 Laboratoire MASI equipe CAO & VLSI */
9 /* Tous droits reserves */
10 /* Support : e-mail alliance-support@asim.lip6.fr */
11 /* */
12 /* */
13 /****************************************************************************/
14
15 #include "fcl_headers.h"
16
17 static int identique_sig(losig_list *ptsig, losig_list *ptmodelsig, fcl_label model_label);
18 static int identique_trs(lotrs_list *pttrans, lotrs_list *ptmodeltrans);
19 static int identique_ins(loins_list *ptloins, loins_list *ptmodelloins);
20 static int check_loop(matrice_list *ptm, void *ptdata, int looplevel);
21 static int check_not_loopsig(matrice_list *ptm, losig_list *ptmodelsig, losig_list *ptsig, int looplevel);
22 static int check_not_loop(matrice_list *ptm, void *ptdata, int looplevel, ht *matchht);
23 static int same_supply(losig_list *ptsig, losig_list *ptmodelsig);
24
25 static int
26 check_loop(matrice_list *ptm, void *ptdata, int looplevel)
27 {
28 if (looplevel == -1) return TRUE;
29 else if (ptm->tab[looplevel] == ptdata) return TRUE;
30
31 return FALSE;
32 }
33
34 static int
35 check_not_loop(matrice_list *ptm, void *ptdata, int looplevel, ht *matchht)
36 {
37 int i;
38
39 if (looplevel != -1) return TRUE;
40 if (matchht) {
41 if (gethtitem(matchht, ptdata) != EMPTYHT) return FALSE;
42 else return TRUE;
43 }
44 for (i = 0; i < niveau_last; i++) {
45 if (ptm->tab[i] == ptdata) return FALSE;
46 }
47 return TRUE;
48 }
49
50 static int
51 check_not_loopsig(matrice_list *ptm, losig_list *ptmodelsig, losig_list *ptsig, int looplevel)
52 {
53 int i;
54
55 if (looplevel != -1) return TRUE;
56 if (ptmodelsig->TYPE != INTERNAL) return TRUE;
57 for (i = 0; i < niveau_last; i++) {
58 if (ptm->tab[i] == ptsig) return FALSE;
59 }
60 return TRUE;
61 }
62
63 static int
64 same_supply(losig_list *ptsig, losig_list *ptmodelsig)
65 {
66 if (ptsig == NULL || ptmodelsig == NULL) return FALSE;
67 if (ptsig->TYPE == CNS_SIGVDD && ptmodelsig->TYPE == CNS_SIGVDD) return TRUE;
68 if (ptsig->TYPE == CNS_SIGVSS && ptmodelsig->TYPE == CNS_SIGVSS) return TRUE;
69 return FALSE;
70 }
71
72 /*
73 ####====================================================================####
74 ## ##
75 ## fclFindCorrespondingLosig ##
76 ## ##
77 ####====================================================================####
78 ## Cherche des signaux ayant des poids de connecteur donnee pour chacune ##
79 ## des solutions. ##
80 ## Ces signaux doivent avoir les memes caracteristiques que le signal du ##
81 ## sous-graphe : rebouclage ou pas, alimentation ou pas ##
82 ####====================================================================####
83 */
84 int
85 fclFindCorrespondingLosig(matrice_list *ptmatrice, int niveau, int connecteur, fcl_label prevcon, int precniveau, int loop, int niveau_donedrainsource)
86 {
87 matrice_list *ptm;
88 lotrs_list *ptlotrs;
89 loins_list *ptloins;
90 losig_list *ptlosig;
91 losig_list *ptlosig_model;
92 locon_list *ptlocon;
93 losig_list *done_drainsource;
94 losig_list *from_drainsource;
95 int first;
96 fcl_label model_label;
97
98 ptlosig_model = (losig_list *) (ptmatrice->tab)[niveau_last];
99 model_label = getlabelsig(ptlosig_model);
100
101 if (connecteur == POID_GRID) {
102 /* On cherche des signaux sur les GRID */
103
104 for (ptm = ptmatrice->NEXT->NEXT; ptm; ptm = ptm->NEXT) {
105 /* On parcourt tous les signaux de la GRILLE du dernier */
106 /* transistor de chaque solution */
107 ptlotrs = (lotrs_list *) ((ptm->tab)[niveau]);
108 ptlosig = ptlotrs->GRID->SIG;
109
110 if (same_supply(ptlosig, ptlosig_model)
111 || (identique_sig(ptlosig, ptlosig_model, model_label) && check_loop(ptm, ptlosig, loop) && check_not_loopsig(ptm, ptlosig_model, ptlosig, loop))) {
112 tab_ajoute(ptm, niveau_last, ptlosig);
113 }
114 else {
115 /* Il n'existe pas de solution dans la ligne courrante */
116 ptm = tab_del(ptmatrice->NEXT, ptm);
117 if (ptmatrice->NEXT->NEXT == NULL) return 0;
118 }
119 }
120 }
121 else if (connecteur == POID_BULK) {
122 /* On cherche des signaux sur les BULK */
123
124 for (ptm = ptmatrice->NEXT->NEXT; ptm; ptm = ptm->NEXT) {
125 /* On parcourt tous les signaux de la BULK du dernier */
126 /* transistor de chaque solution */
127 ptlotrs = (lotrs_list *) ((ptm->tab)[niveau]);
128 ptlosig = ptlotrs->BULK->SIG;
129
130 if (same_supply(ptlosig, ptlosig_model)
131 || (identique_sig(ptlosig, ptlosig_model, model_label) && check_loop(ptm, ptlosig, loop) && check_not_loopsig(ptm, ptlosig_model, ptlosig, loop))) {
132 tab_ajoute(ptm, niveau_last, (void *)ptlosig);
133 }
134 else {
135 /* Il n'existe pas de solution dans la ligne courrante */
136 ptm = tab_del(ptmatrice->NEXT, ptm);
137 if (ptmatrice->NEXT->NEXT == NULL) return 0;
138 }
139 }
140 }
141 else if (connecteur == POID_SOURCE || connecteur == POID_DRAIN) {
142 /* On cherche un signal sur le SOURCE ou sur le DRAIN */
143 /* comme ces deux connecteurs ne peuvent etre differencies */
144 /* Les recherches doivent avoir lieu sur les deux */
145 /* connecteurs */
146
147 for (ptm = ptmatrice->NEXT->NEXT; ptm; ptm = ptm->NEXT) {
148 done_drainsource = NULL;
149 from_drainsource = NULL;
150 first = TRUE;
151
152 ptlotrs = (lotrs_list *) ((ptm->tab)[niveau]);
153 if (niveau_donedrainsource != -1) {
154 done_drainsource = (losig_list *) ((ptm->tab)[niveau_donedrainsource]);
155 }
156 if (prevcon == POID_SOURCE || prevcon == POID_DRAIN) {
157 from_drainsource = (losig_list *) ((ptm->tab)[precniveau]);
158 }
159
160 ptlosig = ptlotrs->SOURCE->SIG;
161 if ((ptlosig != done_drainsource && ptlosig != from_drainsource) || ptlosig == ptlotrs->DRAIN->SIG) {
162 if (same_supply(ptlosig, ptlosig_model)
163 || (identique_sig(ptlosig, ptlosig_model, model_label) && check_loop(ptm, ptlosig, loop) && check_not_loopsig(ptm, ptlosig_model, ptlosig, loop))) {
164 tab_ajoute(ptm, niveau_last, (void *)ptlosig);
165 first = FALSE;
166 }
167 }
168
169 ptlosig = ptlotrs->DRAIN->SIG;
170 if (ptlosig != done_drainsource && ptlosig != from_drainsource && ptlosig != ptlotrs->SOURCE->SIG) {
171 if (same_supply(ptlosig, ptlosig_model)
172 || (identique_sig(ptlosig, ptlosig_model, model_label) && check_loop(ptm, ptlosig, loop) && check_not_loopsig(ptm, ptlosig_model, ptlosig, loop))) {
173 if (first == FALSE) {
174 /* Il y a deux solutions DRAIN + SOURCE */
175 tab_ajoute(tab_copy (ptmatrice->NEXT, ptm, niveau_last), niveau_last, ptlosig);
176 }
177 else {
178 tab_ajoute(ptm, niveau_last, ptlosig);
179 first = FALSE;
180 }
181 }
182 }
183 if (first == TRUE) {
184 /* Il n'existe pas de solution dans la ligne courrante */
185 ptm = tab_del(ptmatrice->NEXT, ptm);
186 if (ptmatrice->NEXT->NEXT == NULL) return 0;
187 }
188 }
189 }
190 else if (connecteur >= POID_INS) {
191 for (ptm = ptmatrice->NEXT->NEXT; ptm; ptm = ptm->NEXT) {
192 first = TRUE;
193
194 ptloins = (loins_list *) ((ptm->tab)[niveau]);
195 /* For each connector with the given weight */
196 for (ptlocon = ptloins->LOCON; ptlocon; ptlocon = ptlocon->NEXT) {
197 if (getlabellocon(ptlocon) != connecteur) continue;
198 ptlosig = ptlocon->SIG;
199 if (same_supply(ptlosig, ptlosig_model)
200 || (identique_sig(ptlosig, ptlosig_model, model_label) && check_loop(ptm, ptlosig, loop) && check_not_loopsig(ptm, ptlosig_model, ptlosig, loop))) {
201 if (first == FALSE) {
202 tab_ajoute(tab_copy (ptmatrice->NEXT, ptm, niveau_last), niveau_last, (void *)ptlosig);
203 }
204 else {
205 tab_ajoute(ptm, niveau_last, (void *)(ptlocon->SIG));
206 first = FALSE;
207 }
208 }
209 }
210 if (first == TRUE) {
211 /* Il n'existe pas de solution dans la ligne courrante */
212 ptm = tab_del(ptmatrice->NEXT, ptm);
213 if (ptmatrice->NEXT->NEXT == NULL) return 0;
214 }
215 }
216 }
217
218 return 1;
219 }
220
221 /*
222 ####====================================================================####
223 ## ##
224 ## IDENTIQUE_SIG ##
225 ## ##
226 ####====================================================================####
227 */
228 static int
229 identique_sig(losig_list *ptsig, losig_list *ptmodelsig, fcl_label model_label)
230 {
231 char *refname;
232 chain_list *ptchain;
233 ptype_list *ptuser;
234 fcl_label label;
235
236 if (ptsig == NULL || ptmodelsig == NULL) return FALSE;
237 if (ptsig->TYPE == CNS_SIGVDD && ptmodelsig->TYPE == CNS_SIGVDD) return TRUE;
238 if (ptsig->TYPE == CNS_SIGVSS && ptmodelsig->TYPE == CNS_SIGVSS) return TRUE;
239 if ((ptmodelsig->TYPE != ptsig->TYPE) && (ptmodelsig->TYPE != EXTERNAL)) return FALSE;
240
241 label = getlabelsig(ptsig);
242 if (!((model_label == label && ptmodelsig->TYPE == INTERNAL) || (model_label <= label && ptmodelsig->TYPE == EXTERNAL))) return FALSE;
243
244 if (FCL_REAL_CORRESP_HT != NULL) {
245 if ((refname = (char *)gethtitem(FCL_REAL_CORRESP_HT, ptmodelsig->NAMECHAIN->DATA)) != (char *)EMPTYHT) {
246 for (ptchain = ptsig->NAMECHAIN; ptchain; ptchain = ptchain->NEXT) {
247 if (refname == (char *) ptchain->DATA) return TRUE;
248 }
249 return FALSE;
250 }
251 }
252
253 if ((ptuser = getptype(ptmodelsig->USER, FCL_TRANSFER_PTYPE)) != NULL) {
254 if (((long) ptuser->DATA & FCL_MATCHNAME) != FCL_MATCHNAME) return TRUE;
255 }
256 else return TRUE;
257
258 refname = ptmodelsig->NAMECHAIN->DATA;
259 for (ptchain = ptsig->NAMECHAIN; ptchain; ptchain = ptchain->NEXT) {
260 if (refname == (char *) ptchain->DATA) return TRUE;
261 }
262 return FALSE;
263 }
264
265 /*
266 ####====================================================================####
267 ## ##
268 ## fclFindCorrespondingLotrs ##
269 ## ##
270 ####====================================================================####
271 ## Cherche un transistor avec un poid de connecteur donnee pour chaque ##
272 ## solution retenue ##
273 ####====================================================================####
274 */
275 int
276 fclFindCorrespondingLotrs(matrice_list *ptmatrice, int niveau, int connecteur, int loop)
277 {
278 losig_list *ptlosig;
279 locon_list *ptlocon;
280 lotrs_list *pttrans, *ptmodeltrans;
281 chain_list *ptchain;
282 chain_list *ptc;
283 matrice_list *ptm, *ptnextm;
284 char first;
285
286 ptmodeltrans = (lotrs_list *) (ptmatrice->tab)[niveau_last];
287
288 for (ptm = ptmatrice->NEXT->NEXT; ptm; ptm = ptnextm) {
289 ptnextm = ptm->NEXT;
290 ptlosig = (losig_list *) ((ptm->tab)[niveau]);
291
292 ptchain = getptype(ptlosig->USER, (long) LOFIGCHAIN)->DATA;
293
294 first = TRUE;
295
296 for (ptc = ptchain; ptc; ptc = ptc->NEXT) {
297 ptlocon = (locon_list *) (ptc->DATA);
298 if (ptlocon->TYPE != 'T') continue;
299
300 /* Chercher des connecteurs identiques */
301 if (getlabellocon(ptlocon) == connecteur) {
302 pttrans = (lotrs_list *) ptlocon->ROOT;
303 /* Le transistor est-il identique */
304 if (identique_trs(pttrans, ptmodeltrans) && check_loop(ptm, pttrans, loop) && check_not_loop(ptm, pttrans, loop, NULL)) {
305 if (first == FALSE) {
306 tab_ajoute(tab_copy(ptmatrice->NEXT, ptm, niveau_last), niveau_last, ptlocon->ROOT);
307 }
308 else tab_ajoute(ptm, niveau_last, ptlocon->ROOT);
309 first = FALSE;
310 }
311 }
312 }
313
314 if (first == TRUE) {
315 /* Il n'existe pas de solution dans la ligne courrante */
316 ptm = tab_del(ptmatrice->NEXT, ptm);
317 if (ptmatrice->NEXT->NEXT == NULL) return 0;
318 }
319 }
320
321 return 1;
322 }
323
324 /*
325 ####====================================================================####
326 ## ##
327 ## IDENTIQUE_TRS ##
328 ## ##
329 ####====================================================================####
330 */
331 static int
332 identique_trs(lotrs_list *pttrans, lotrs_list *ptmodeltrans)
333 {
334 ptype_list *ptuser;
335 long mark = 0;
336 int usegrid = FALSE;
337 int usebulk = FALSE;
338 int usesource = FALSE;
339 int usedrain = FALSE;
340 int vddmatch = 0, vssmatch = 0;
341 int source, drain;
342 int modelsource, modeldrain;
343
344 ptuser = getptype(pttrans->USER, FCL_MARK_PTYPE);
345 if (ptuser != NULL)
346 mark = (long) ptuser->DATA;
347 if ((mark & FCL_NOSHARE) == FCL_NOSHARE) {
348 return FALSE;
349 }
350
351 if ((pttrans->TYPE & (TRANSN | TRANSP)) !=
352 (ptmodeltrans->TYPE & (TRANSN | TRANSP))) return FALSE;
353 if (ptmodeltrans->MODINDEX != (short) EMPTYHT
354 && getnum(FCL_ANY_NMOS_IDX, (long)ptmodeltrans->MODINDEX) == NULL
355 && getnum(FCL_ANY_PMOS_IDX, (long)ptmodeltrans->MODINDEX) == NULL
356 && pttrans->MODINDEX != ptmodeltrans->MODINDEX) return FALSE;
357
358 if ((ptuser = getptype(ptmodeltrans->USER, FCL_TRANSFER_PTYPE)) != NULL) {
359 if (((long) ptuser->DATA & FCL_MATCHSIZE) != 0) {
360 if (FCL_SIZE_TOLERANCE == 0) {
361 if (pttrans->WIDTH != ptmodeltrans->WIDTH
362 || pttrans->LENGTH != pttrans->LENGTH) {
363 return FALSE;
364 }
365 }
366 else {
367 if (abs(pttrans->WIDTH - ptmodeltrans->WIDTH) <
368 ((FCL_SIZE_TOLERANCE * ptmodeltrans->WIDTH) / 100)
369 || abs(pttrans->LENGTH - ptmodeltrans->LENGTH) <
370 ((FCL_SIZE_TOLERANCE * ptmodeltrans->LENGTH) / 100)) {
371 return FALSE;
372 }
373 }
374 }
375 }
376
377 if (ptmodeltrans->GRID->SIG->TYPE == 'I')
378 usegrid = TRUE;
379 else {
380 if (ptmodeltrans->GRID->SIG->TYPE == CNS_SIGVSS
381 && pttrans->GRID->SIG->TYPE != CNS_SIGVSS)
382 return FALSE;
383 if (ptmodeltrans->GRID->SIG->TYPE == CNS_SIGVDD
384 && pttrans->GRID->SIG->TYPE != CNS_SIGVDD)
385 return FALSE;
386 }
387
388 if (ptmodeltrans->BULK && pttrans->BULK && ptmodeltrans->BULK->SIG
389 && pttrans->BULK->SIG) {
390 if (ptmodeltrans->BULK->SIG->TYPE == 'I')
391 usebulk = TRUE;
392 else {
393 if (ptmodeltrans->BULK->SIG->TYPE == CNS_SIGVSS
394 && pttrans->BULK->SIG->TYPE != CNS_SIGVSS)
395 return FALSE;
396 if (ptmodeltrans->BULK->SIG->TYPE == CNS_SIGVDD
397 && pttrans->BULK->SIG->TYPE != CNS_SIGVDD)
398 return FALSE;
399 }
400 }
401
402 source = getlabelsig(pttrans->SOURCE->SIG);
403 modelsource = getlabelsig(ptmodeltrans->SOURCE->SIG);
404 if (ptmodeltrans->SOURCE->SIG->TYPE == 'I')
405 usesource = TRUE;
406 else if (ptmodeltrans->SOURCE->SIG->TYPE == CNS_SIGVDD)
407 vddmatch++;
408 else if (ptmodeltrans->SOURCE->SIG->TYPE == CNS_SIGVSS)
409 vssmatch++;
410
411 drain = getlabelsig(pttrans->DRAIN->SIG);
412 modeldrain = getlabelsig(ptmodeltrans->DRAIN->SIG);
413 if (ptmodeltrans->DRAIN->SIG->TYPE == 'I')
414 usedrain = TRUE;
415 else if (ptmodeltrans->DRAIN->SIG->TYPE == CNS_SIGVDD)
416 vddmatch++;
417 else if (ptmodeltrans->DRAIN->SIG->TYPE == CNS_SIGVSS)
418 vssmatch++;
419
420 if (vddmatch != 0) {
421 if (vddmatch !=
422 (pttrans->DRAIN->SIG->TYPE ==
423 CNS_SIGVDD) + (pttrans->SOURCE->SIG->TYPE == CNS_SIGVDD))
424 return FALSE;
425 }
426 if (vssmatch != 0) {
427 if (vssmatch !=
428 (pttrans->DRAIN->SIG->TYPE ==
429 CNS_SIGVSS) + (pttrans->SOURCE->SIG->TYPE == CNS_SIGVSS))
430 return FALSE;
431 }
432
433 if (usegrid) {
434 if (getlabelsig(ptmodeltrans->GRID->SIG) !=
435 getlabelsig(pttrans->GRID->SIG)) return FALSE;
436 }
437
438 if (usebulk) {
439 if (getlabelsig(ptmodeltrans->BULK->SIG) !=
440 getlabelsig(pttrans->BULK->SIG)) return FALSE;
441 }
442
443 if (usesource && usedrain) {
444 if ((source == modelsource && drain == modeldrain)
445 || (source == modeldrain && drain == modelsource))
446 return TRUE;
447 }
448 else if (usesource) {
449 if (modelsource == source || modelsource == drain)
450 return TRUE;
451 }
452 else if (usedrain) {
453 if (modeldrain == drain || modeldrain == source)
454 return TRUE;
455 }
456 else
457 return TRUE;
458
459 return FALSE;
460 }
461
462 /*
463 ####====================================================================####
464 ## ##
465 ## fclFindCorrespondingLoins ##
466 ## ##
467 ####====================================================================####
468 ## Cherche une instance avec un poid de connecteur donnee pour chaque ##
469 ## solution retenue ##
470 ####====================================================================####
471 */
472 int
473 fclFindCorrespondingLoins(matrice_list *ptmatrice, int niveau, int connecteur, int loop)
474 {
475 losig_list *ptlosig;
476 locon_list *ptlocon;
477 loins_list *ptloins, *ptmodelloins;
478 chain_list *ptchain;
479 chain_list *ptc;
480 matrice_list *ptm, *ptnextm;
481 ht *matchht = NULL;
482 int useht;
483 int i;
484 char first;
485
486 ptmodelloins = (loins_list *)(ptmatrice->tab)[niveau_last];
487
488 for (ptm = ptmatrice->NEXT->NEXT; ptm; ptm = ptnextm) {
489 ptnextm = ptm->NEXT;
490 ptlosig = (losig_list *) ((ptm->tab)[niveau]);
491 ptchain = getptype(ptlosig->USER, (long) LOFIGCHAIN)->DATA;
492 if (getlabelsig(ptlosig) > 10 && niveau_last > 10) useht = TRUE;
493 else useht = FALSE;
494 first = TRUE;
495
496 if (useht) {
497 matchht = addht(niveau_last*5);
498 for (i = 0; i < niveau_last; i++) addhtitem(matchht, ptm->tab[i], 0);
499 }
500
501 for (ptc = ptchain; ptc; ptc = ptc->NEXT) {
502 ptlocon = (locon_list *) (ptc->DATA);
503 if (ptlocon->TYPE != 'I') continue;
504
505 /* Chercher des connecteurs identiques */
506 if (getlabellocon(ptlocon) == connecteur) {
507 ptloins = (loins_list *) ptlocon->ROOT;
508 /* Instance est-il identique */
509 if (identique_ins(ptloins, ptmodelloins) && check_loop(ptm, ptloins, loop) && check_not_loop(ptm, ptloins, loop, matchht)) {
510 if (first == FALSE) {
511 tab_ajoute(tab_copy(ptmatrice->NEXT, ptm, niveau_last), niveau_last, ptlocon->ROOT);
512 }
513 else tab_ajoute(ptm, niveau_last, ptlocon->ROOT);
514 first = FALSE;
515 }
516 }
517 }
518 if (useht) {
519 delht(matchht);
520 matchht = NULL;
521 }
522
523 if (first == TRUE) {
524 /* Il n'existe pas de solution dans la ligne courrante */
525 ptm = tab_del(ptmatrice->NEXT, ptm);
526 if (ptmatrice->NEXT->NEXT == NULL) return 0;
527 }
528 }
529
530 return 1;
531 }
532
533 /*
534 ####====================================================================####
535 ## ##
536 ## IDENTIQUE_INS ##
537 ## ##
538 ####====================================================================####
539 */
540 static int
541 identique_ins(loins_list *ptloins, loins_list *ptmodelloins)
542 {
543 char *refname;
544
545 if (FCL_REAL_CORRESP_HT != NULL) {
546 if ((refname = (char *)gethtitem(FCL_REAL_CORRESP_HT, ptmodelloins->INSNAME)) != (char *)EMPTYHT) {
547 if (refname == ptloins->INSNAME) return TRUE;
548 else return FALSE;
549 }
550 }
551
552 if (ptloins->FIGNAME == ptmodelloins->FIGNAME) return 1;
553 return 0;
554 }
555
556 /*
557 ####====================================================================####
558 ## ##
559 ## TAB_AJOUTE ##
560 ## ##
561 ####====================================================================####
562 ## Ajoute un element dans le tableau indique ##
563 ####====================================================================####
564 */
565
566 void
567 tab_ajoute(ptmatrice, niveau, ptdata)
568 matrice_list *ptmatrice;
569 int niveau;
570 void *ptdata;
571 {
572 if (niveau % BUFFER == 0) {
573 /* On est en fin de tableau on realloue de la place */
574 ptmatrice->tab = mbkrealloc(ptmatrice->tab, (niveau + BUFFER) * sizeof(void *));
575 }
576
577 (ptmatrice->tab)[niveau] = ptdata;
578 }
579
580 /*
581 ####====================================================================####
582 ## ##
583 ## TAB_DEL ##
584 ## ##
585 ####====================================================================####
586 ## Supprime une ligne de la matrice ##
587 ####====================================================================####
588 */
589 matrice_list *
590 tab_del(ptmatrice_begin, ptmatrice)
591 matrice_list *ptmatrice_begin;
592 matrice_list *ptmatrice;
593 {
594 matrice_list *ptm;
595 #ifndef __ALL__WARNING__
596 ptmatrice_begin = NULL;
597 #endif
598 /* never delete the first two rows */
599 ptmatrice->PREV->NEXT = ptmatrice->NEXT;
600 if (ptmatrice->NEXT) ptmatrice->NEXT->PREV = ptmatrice->PREV;
601 ptm = ptmatrice->PREV;
602 mbkfree(ptmatrice->tab);
603 mbkfree(ptmatrice);
604
605 return ptm;
606 }
607
608 /*
609 ####====================================================================####
610 ## ##
611 ## TAB_INIT ##
612 ## ##
613 ####====================================================================####
614 ## Initialise la matrice ##
615 ####====================================================================####
616 */
617 matrice_list *
618 tab_init()
619 {
620 matrice_list *ptmatrice;
621
622 ptmatrice = (matrice_list *) mbkalloc(sizeof(matrice_list));
623 ptmatrice->NEXT = (matrice_list *) mbkalloc(sizeof(matrice_list));
624 ptmatrice->PREV = NULL;
625 ptmatrice->NEXT->NEXT = (matrice_list *) mbkalloc(sizeof(matrice_list));
626 ptmatrice->NEXT->PREV = ptmatrice;
627 ptmatrice->NEXT->NEXT->NEXT = (matrice_list *) NULL;
628 ptmatrice->NEXT->NEXT->PREV = ptmatrice->NEXT;
629
630 ptmatrice->tab = mbkalloc(sizeof(void *) * BUFFER);
631 ptmatrice->NEXT->tab = mbkalloc(BUFFER * sizeof(void *));
632 ptmatrice->NEXT->NEXT->tab = mbkalloc(BUFFER * sizeof(void *));
633
634 return ptmatrice;
635 }
636
637 /*
638 ####====================================================================####
639 ## ##
640 ## TAB_COPY ##
641 ## ##
642 ####====================================================================####
643 ## Recopie une ligne de la matrice sur une nouvelle ligne ##
644 ####====================================================================####
645 */
646 matrice_list *
647 tab_copy(ptmatrice_begin, ptmatrice, niveau)
648 matrice_list *ptmatrice_begin;
649 matrice_list *ptmatrice;
650 int niveau;
651 {
652 matrice_list *ptmatrice_new;
653
654 #ifndef __ALL__WARNING__
655 ptmatrice_begin = NULL;
656 #endif
657 ptmatrice_new = (matrice_list *) mbkalloc(sizeof(matrice_list));
658 ptmatrice_new->NEXT = ptmatrice;
659 ptmatrice_new->PREV = ptmatrice->PREV;
660 ptmatrice_new->tab = mbkalloc(((niveau / BUFFER) + 1) * BUFFER * sizeof(void *));
661 memcpy(ptmatrice_new->tab, ptmatrice->tab, ((niveau / BUFFER) + 1) * BUFFER * sizeof(void *));
662
663 ptmatrice->PREV->NEXT = ptmatrice_new;
664 ptmatrice->PREV = ptmatrice_new;
665
666 return ptmatrice_new;
667 }
668
669 /*
670 ####====================================================================####
671 ## ##
672 ## TAB_FREE ##
673 ## ##
674 ####====================================================================####
675 ## Libere la matrice ##
676 ####====================================================================####
677 */
678 void
679 tab_free(ptmatrice)
680 matrice_list *ptmatrice;
681 {
682 matrice_list *ptm;
683
684 for (ptm = ptmatrice->NEXT; ptm; ptm = ptm->NEXT) {
685 mbkfree(ptmatrice->tab);
686 mbkfree(ptmatrice);
687 ptmatrice = ptm;
688 }
689
690 mbkfree(ptmatrice->tab);
691 mbkfree(ptmatrice);
692 }
693
694 /*
695 ####====================================================================####
696 ## ##
697 ## FILS_SIG ##
698 ## ##
699 ####====================================================================####
700 ## Cherche les transistors et instances d'un signal ##
701 ####====================================================================####
702 */
703 chain_list *
704 fils_sig(ptlosig, ptlocon)
705 losig_list *ptlosig;
706 locon_list *ptlocon;
707 {
708 chain_list *ptchain;
709 chain_list *ptchain_debut = NULL;
710 ptype_list *ptptype;
711 lotrs_list *ptlotrs;
712 loins_list *ptloins;
713 locon_list *ptnextlocon;
714
715 ptptype = getptype(ptlosig->USER, LOFIGCHAIN);
716
717 for (ptchain = ptptype->DATA; ptchain; ptchain = ptchain->NEXT) {
718 ptnextlocon = (locon_list *)ptchain->DATA;
719 if (ptnextlocon == ptlocon) continue;
720 if (ptnextlocon->TYPE == 'T') {
721 ptlotrs = (lotrs_list *)ptnextlocon->ROOT;
722
723 /* Le transistor est il MATCH */
724 if (getptype(ptlotrs->USER, FCL_MATCH_PTYPE) == NULL) {
725 ptchain_debut = addchain(ptchain_debut, ptnextlocon);
726 }
727 }
728 if (ptnextlocon->TYPE == 'I') {
729 ptloins = (loins_list *)ptnextlocon->ROOT;
730
731 /* L'instance est il MATCH */
732 if (getptype(ptloins->USER, FCL_MATCH_PTYPE) == NULL) {
733 ptchain_debut = addchain(ptchain_debut, ptnextlocon);
734 }
735 }
736 }
737
738 for (ptchain = ptptype->DATA; ptchain; ptchain = ptchain->NEXT) {
739 ptnextlocon = (locon_list *)ptchain->DATA;
740 if (ptnextlocon == ptlocon) continue;
741 if (ptnextlocon->TYPE == 'T') {
742 ptlotrs = (lotrs_list *)ptnextlocon->ROOT;
743
744 /* Le transistor est il MATCH */
745 if (getptype(ptlotrs->USER, FCL_MATCH_PTYPE) != NULL) {
746 ptchain_debut = addchain(ptchain_debut, ptnextlocon);
747 }
748 }
749 if (ptnextlocon->TYPE == 'I') {
750 ptloins = (loins_list *)ptnextlocon->ROOT;
751
752 /* L'instance est il MATCH */
753 if (getptype(ptloins->USER, FCL_MATCH_PTYPE) != NULL) {
754 ptchain_debut = addchain(ptchain_debut, ptnextlocon);
755 }
756 }
757 }
758
759 return ptchain_debut;
760
761 }
762
763 /*
764 ####====================================================================####
765 ## ##
766 ## PRINT_MATRICE ##
767 ## ##
768 ####====================================================================####
769 */
770 void
771 printmatrice(ptmatrice, niveau)
772 matrice_list *ptmatrice;
773 int niveau;
774 {
775 int i;
776 matrice_list *ptm;
777
778 printf("matrice:\n");
779 for (ptm = ptmatrice; ptm; ptm = ptm->NEXT) {
780 for (i = 0; i <= niveau; i++)
781 printf("%6x ", (int)(long)(ptm->tab)[i]);
782 printf("\n");
783 }
784
785 }
786
787 /*
788 ####====================================================================####
789 ## ##
790 ## DISPLAY_MATRICE ##
791 ## ##
792 ####====================================================================####
793 */
794 void
795 displaymatrice(ptmatrice, niveau, full)
796 matrice_list *ptmatrice;
797 int niveau;
798 int full;
799 {
800 int i, num = 0;
801 losig_list *ptlosig;
802 lotrs_list *pttrans;
803 loins_list *ptloins;
804 ptype_list *ptuser;
805 num_list *ptnum;
806 matrice_list *ptm;
807
808 printf("matrice:\n\n");
809 printf("Model :-\n");
810 for (i = 0; i <= niveau; i++) {
811 if ((ptmatrice->NEXT->tab)[i] == (void *) TYPE_S) {
812 ptlosig = (losig_list *) (ptmatrice->tab)[i];
813 if (ptlosig->NAMECHAIN == NULL) {
814 printf("\tmbk_sig%ld", ptlosig->INDEX);
815 }
816 else printf("\t%s", (char *) ptlosig->NAMECHAIN->DATA);
817 if ((ptuser = getptype(ptlosig->USER, FCL_COUP_LIST_PTYPE)) != NULL) {
818 printf("\t coupling list ( ");
819 for (ptnum = (num_list *)ptuser->DATA; ptnum; ptnum = ptnum->NEXT) {
820 printf("%ld ", ptnum->DATA);
821 }
822 printf(")");
823 }
824 printf("\n");
825 }
826 else if ((ptmatrice->NEXT->tab)[i] == (void *) TYPE_I) {
827 ptloins = (loins_list *) (ptmatrice->tab)[i];
828 printf("\t%s\n", ptloins->INSNAME);
829 }
830 else {
831 pttrans = (lotrs_list *) (ptmatrice->tab)[i];
832 printf("\t%s\n", pttrans->TRNAME);
833 }
834 }
835 printf("\n");
836
837 if (full) {
838 for (ptm = ptmatrice->NEXT->NEXT; ptm; ptm = ptm->NEXT) {
839 num++;
840 printf("Solution number %d :-\n", num);
841 for (i = 0; i <= niveau; i++) {
842 if ((ptmatrice->NEXT->tab)[i] == (void *) TYPE_S) {
843 ptlosig = (losig_list *) (ptm->tab)[i];
844 printf("\t%s", (char *) ptlosig->NAMECHAIN->DATA);
845 if ((ptuser = getptype(ptlosig->USER, FCL_COUP_LIST_PTYPE)) != NULL) {
846 printf("\t coupling list ( ");
847 for (ptnum = (num_list *)ptuser->DATA; ptnum; ptnum = ptnum->NEXT) {
848 printf("%ld ", ptnum->DATA);
849 }
850 printf(")");
851 }
852 printf("\n");
853 }
854 else if ((ptmatrice->NEXT->tab)[i] == (void *) TYPE_I) {
855 ptloins = (loins_list *) (ptm->tab)[i];
856 printf("\t%s\n", (char *) ptloins->INSNAME);
857 }
858 else {
859 pttrans = (lotrs_list *) (ptm->tab)[i];
860 if (pttrans->TRNAME != NULL) {
861 printf("\t%s\n", pttrans->TRNAME);
862 }
863 else {
864 printf("\tD-%ld,G-%ld,S-%ld\n",
865 pttrans->DRAIN->SIG->INDEX,
866 pttrans->GRID->SIG->INDEX,
867 pttrans->SOURCE->SIG->INDEX);
868 }
869 }
870 }
871 printf("\n");
872 }
873 }
874 }