Initial version of donated sources by Avertec, 3.4p5.
[tas-yagle.git] / distrib / sources / mbkvrlog / mgl_util.c
1 /****************************************************************************/
2 /* */
3 /* Chaine de CAO & VLSI AVERTEC */
4 /* */
5 /* Produit : Structural Verilog Compiler */
6 /* Fichier : mgl_util.c */
7 /* */
8 /* (c) copyright 2000 AVERTEC */
9 /* Tous droits reserves */
10 /* */
11 /* Auteur(s) : Anthony LESTER */
12 /* */
13 /* */
14 /****************************************************************************/
15
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <ctype.h>
20 #include MUT_H
21 #include AVT_H
22 #include MLO_H
23 #include RCN_H
24 #include "mgl_type.h"
25 #include "mgl_parse.h"
26 #include "mgl_util.h"
27 #include "mgl_error.h"
28
29 static struct dct_entry *MGL_DCEHED; /* free dct_entry's head */
30 static struct dct_recrd *MGL_DCRHED; /* free dct_recrd's head */
31
32 static struct dct_entry *mgl_addent(struct dct_entry *head, char *key);
33 static struct dct_recrd *mgl_addrcd(struct dct_recrd *head, char *key);
34
35 // copie de mbk_util.c
36 #define HASH_MULT 314159
37 #define HASH_PRIME 516595003
38
39 static int HASH_FUNC(char *inputname, char *name, int code)
40 {
41 do {
42 while (*inputname) {
43 /*if (CASE_SENSITIVE == 'N') *name = tolowertable[(int)*inputname++];
44 else*/ *name = *inputname++;
45 code += (code ^ (code >> 1)) + HASH_MULT * (unsigned char) *name++;
46 while (code >= HASH_PRIME)
47 code -= HASH_PRIME;
48 }
49 *name = '\0';
50 code %= MGL_HSZDFN;
51 } while (0);
52
53 return code;
54 }
55
56
57 /* ###--------------------------------------------------------------### */
58 /* function : mgl_deltab */
59 /* ###--------------------------------------------------------------### */
60
61 void
62 mgl_deltab(struct dct_entry **head, char *key_str, char *ctx_str)
63 {
64 int found = 0;
65 int index;
66 struct dct_entry *entry_pnt;
67 struct dct_entry *last_entry = NULL;
68 struct dct_recrd *recrd_pnt;
69 struct dct_recrd *last_recrd = NULL;
70 char name[500];
71
72 // par Fabrice le 11/2/2002
73 //index = (int) key_str % MGL_HSZDFN;
74 index=HASH_FUNC(key_str, name, 0);
75 entry_pnt = head[index];
76
77 while (entry_pnt != NULL) {
78 if (entry_pnt->key == key_str) {
79 found = 1;
80 break;
81 }
82 last_entry = entry_pnt;
83 entry_pnt = entry_pnt->next;
84 }
85
86 if (found == 1) {
87 found = 0;
88 recrd_pnt = entry_pnt->data;
89 while (recrd_pnt != NULL) {
90 if (recrd_pnt->key == ctx_str) {
91 found = 1;
92 break;
93 }
94 last_recrd = recrd_pnt;
95 recrd_pnt = recrd_pnt->next;
96 }
97
98 if (found == 1) {
99 if (last_recrd == NULL)
100 entry_pnt->data = recrd_pnt->next;
101 else
102 last_recrd->next = recrd_pnt->next;
103
104 recrd_pnt->next = MGL_DCRHED;
105 MGL_DCRHED = recrd_pnt;
106
107 if (entry_pnt->data == NULL) {
108 if (last_entry == NULL)
109 head[index] = entry_pnt->next;
110 else
111 last_entry->next = entry_pnt->next;
112
113 entry_pnt->next = MGL_DCEHED;
114 MGL_DCEHED = entry_pnt;
115 }
116 }
117 }
118 }
119
120 /* ###--------------------------------------------------------------### */
121 /* function : mgl_initab */
122 /* ###--------------------------------------------------------------### */
123 struct dct_entry **
124 mgl_initab()
125 {
126 struct dct_entry **head;
127 int i;
128
129 head = (struct dct_entry **)
130 mbkalloc(sizeof(struct dct_entry *) * MGL_HSZDFN);
131
132 for (i = 0; i < MGL_HSZDFN; i++)
133 head[i] = NULL;
134
135 return (head);
136 }
137
138 /* ###--------------------------------------------------------------### */
139 /* function : mgl_addtab */
140 /* ###--------------------------------------------------------------### */
141 void
142 mgl_addtab(struct dct_entry **head, char *key_str, char *ctx_str, int field, long valu)
143 {
144 int found = 0;
145 int index;
146 struct dct_entry *entry_pnt;
147 struct dct_recrd *recrd_pnt;
148 char name[500];
149
150 // par Fabrice le 11/2/2002
151 //index = (int) key_str % MGL_HSZDFN;
152 index=HASH_FUNC(key_str, name, 0);
153
154 entry_pnt = head[index];
155
156 while (entry_pnt != NULL) {
157 if (entry_pnt->key == key_str) {
158 found = 1;
159 break;
160 }
161 entry_pnt = entry_pnt->next;
162 }
163
164 if (found == 0) {
165 head[index] = mgl_addent(head[index], key_str);
166 entry_pnt = head[index];
167 }
168
169 found = 0;
170 recrd_pnt = entry_pnt->data;
171 while (recrd_pnt != NULL) {
172 if (recrd_pnt->key == ctx_str) {
173 found = 1;
174 break;
175 }
176 recrd_pnt = recrd_pnt->next;
177 }
178
179 if (found == 0) {
180 entry_pnt->data = mgl_addrcd(entry_pnt->data, ctx_str);
181 recrd_pnt = entry_pnt->data;
182 }
183
184 switch (field) {
185 case 0:
186 recrd_pnt->fd0_val = valu;
187 break;
188 case 1:
189 recrd_pnt->fd1_val = valu;
190 break;
191 case 2:
192 recrd_pnt->fd2_val = valu;
193 break;
194 case 3:
195 recrd_pnt->fd3_val = valu;
196 break;
197 case 4:
198 recrd_pnt->fd4_val = valu;
199 break;
200 case 5:
201 recrd_pnt->fd5_val = valu;
202 break;
203 case 6:
204 recrd_pnt->fd6_val = valu;
205 break;
206 case 7:
207 recrd_pnt->pnt_val = valu;
208 break;
209 }
210
211 }
212
213 /* ###--------------------------------------------------------------### */
214 /* function : mgl_chktab */
215 /* ###--------------------------------------------------------------### */
216 long
217 mgl_chktab(struct dct_entry **head, char *key_str, char *ctx_str, int field)
218 {
219 int found = 0;
220 long valu = 0;
221 struct dct_entry *entry_pnt;
222 struct dct_recrd *recrd_pnt;
223 char name[500];
224
225 // par Fabrice le 11/2/2002
226 // entry_pnt = head[(int) key_str % MGL_HSZDFN];
227 entry_pnt = head[HASH_FUNC(key_str, name, 0)];
228
229 while (entry_pnt != NULL) {
230 if (entry_pnt->key == key_str) {
231 found = 1;
232 break;
233 }
234 entry_pnt = entry_pnt->next;
235 }
236
237 if (found == 1) {
238 found = 0;
239 recrd_pnt = entry_pnt->data;
240 while (recrd_pnt != NULL) {
241 if (recrd_pnt->key == ctx_str) {
242 found = 1;
243 break;
244 }
245 recrd_pnt = recrd_pnt->next;
246 }
247 if (found == 1) {
248 switch (field) {
249 case 0:
250 valu = recrd_pnt->fd0_val;
251 break;
252 case 1:
253 valu = recrd_pnt->fd1_val;
254 break;
255 case 2:
256 valu = recrd_pnt->fd2_val;
257 break;
258 case 3:
259 valu = recrd_pnt->fd3_val;
260 break;
261 case 4:
262 valu = recrd_pnt->fd4_val;
263 break;
264 case 5:
265 valu = recrd_pnt->fd5_val;
266 break;
267 case 6:
268 valu = recrd_pnt->fd6_val;
269 break;
270 case 7:
271 valu = recrd_pnt->pnt_val;
272 break;
273 }
274 }
275 }
276
277 return (valu);
278 }
279
280 /* ###--------------------------------------------------------------### */
281 /* function : mgl_fretab */
282 /* ###--------------------------------------------------------------### */
283 void
284 mgl_fretab(struct dct_entry **pt_hash)
285 {
286 struct dct_entry *pt_entry;
287 struct dct_entry *pt_nxtentry;
288 struct dct_recrd *pt_record;
289 int i;
290
291 if (pt_hash != NULL) {
292 for (i = 0; i < MGL_HSZDFN; i++) {
293 if ((pt_entry = pt_hash[i]) != NULL) {
294 while (pt_entry != NULL) {
295 pt_record = pt_entry->data;
296
297 while (pt_record->next != NULL)
298 pt_record = pt_record->next;
299
300 pt_record->next = MGL_DCRHED;
301 MGL_DCRHED = pt_entry->data;
302
303 pt_nxtentry = pt_entry->next;
304 pt_entry->next = MGL_DCEHED;
305 MGL_DCEHED = pt_entry;
306 pt_entry = pt_nxtentry;
307 }
308 }
309 }
310 mbkfree(pt_hash);
311 }
312 }
313
314 /* ###--------------------------------------------------------------### */
315 /* function : mgl_addent */
316 /* ###--------------------------------------------------------------### */
317 static struct dct_entry *
318 mgl_addent(struct dct_entry *head, char *key)
319 {
320 struct dct_entry *entry;
321 int i;
322
323 if (MGL_DCEHED == NULL) {
324 MGL_DCEHED = (struct dct_entry *) mbkalloc(sizeof(struct dct_entry) * MGL_ALODFN);
325
326 entry = MGL_DCEHED;
327 for (i = 1; i < MGL_ALODFN; i++) {
328 entry->next = entry + 1;
329 entry++;
330 }
331 entry->next = NULL;
332 }
333
334 entry = MGL_DCEHED;
335 MGL_DCEHED = MGL_DCEHED->next;
336
337 entry->next = head;
338 entry->data = NULL;
339 entry->key = key;
340
341 return (entry);
342 }
343
344 /* ###--------------------------------------------------------------### */
345 /* function : mgl_addrcd */
346 /* ###--------------------------------------------------------------### */
347 static struct dct_recrd *
348 mgl_addrcd(struct dct_recrd *head, char *key)
349 {
350 struct dct_recrd *recrd;
351 int i;
352
353 if (MGL_DCRHED == NULL) {
354 MGL_DCRHED = (struct dct_recrd *) mbkalloc(sizeof(struct dct_recrd) * MGL_ALODFN);
355
356 recrd = MGL_DCRHED;
357 for (i = 1; i < MGL_ALODFN; i++) {
358 recrd->next = recrd + 1;
359 recrd++;
360 }
361 recrd->next = NULL;
362 }
363
364 recrd = MGL_DCRHED;
365 MGL_DCRHED = MGL_DCRHED->next;
366
367 recrd->next = head;
368 recrd->fd0_val = 0;
369 recrd->fd1_val = 0;
370 recrd->fd2_val = 0;
371 recrd->fd3_val = 0;
372 recrd->fd4_val = 0;
373 recrd->fd5_val = 0;
374 recrd->fd6_val = 0;
375 recrd->pnt_val = 0;
376 recrd->key = key;
377
378 return (recrd);
379 }
380
381 /* ###--------------------------------------------------------------### */
382 /* function : mgl_avers */
383 /* ###--------------------------------------------------------------### */
384 char *
385 mgl_avers()
386 {
387 return ("-- V 1.0 --");
388 }
389
390 /* ###--------------------------------------------------------------### */
391 /* function : mgl_vlgname */
392 /* ###--------------------------------------------------------------### */
393 char *
394 mgl_vlgname(char *name)
395 {
396 char *new_name;
397 char *prv_name;
398 char *tmp_name;
399 char buffer[200];
400 int i, j, flag, number;
401 static struct dct_entry **namtab = NULL;
402
403 if (namtab == NULL)
404 namtab = mgl_initab();
405
406 tmp_name = namealloc(name);
407 new_name = (char *) mgl_chktab(namtab, tmp_name, NULL, MGL_PNTDFN);
408
409 if (mgl_chktab(namtab, tmp_name, NULL, MGL_NAMDFN) == 0) {
410 i = 0;
411 j = 0;
412 number = 0;
413 flag = 1;
414 while (tmp_name[i] != '\0') {
415 buffer[j] = tmp_name[i];
416 if (((tmp_name[i] >= 'a') && (tmp_name[i] <= 'z')) ||
417 ((tmp_name[i] >= 'A') && (tmp_name[i] <= 'Z')) ||
418 ((tmp_name[i] >= '0') && (tmp_name[i] <= '9') && (i != 0)) ||
419 ((tmp_name[i] == '(') || (tmp_name[i] == ')'))) {
420 flag = 0;
421 }
422 else if ((tmp_name[i] >= '0') && (tmp_name[i] <= '9') && (i == 0)) {
423 strcpy(&buffer[j], "noname");
424 j += 6;
425 buffer[j] = tmp_name[i];
426 }
427 else {
428 if (flag == 1)
429 buffer[j++] = 'v';
430 buffer[j] = '_';
431 flag = 1;
432 }
433 i++;
434 j++;
435 }
436 if (buffer[j - 1] == '_')
437 j--;
438 buffer[j] = '\0';
439 new_name = namealloc(buffer);
440
441 prv_name = new_name;
442 while (mgl_chktab(namtab, new_name, NULL, MGL_NEWDFN) != 0) {
443 new_name = prv_name;
444 sprintf(buffer, "%s_%d", new_name, number++);
445 prv_name = new_name;
446 new_name = namealloc(buffer);
447 }
448 mgl_addtab(namtab, new_name, NULL, MGL_NEWDFN, 1);
449 mgl_addtab(namtab, tmp_name, NULL, MGL_PNTDFN, (long) new_name);
450 mgl_addtab(namtab, tmp_name, NULL, MGL_NAMDFN, 1);
451 }
452
453 return (new_name);
454 }
455
456
457 /* ###--------------------------------------------------------------### */
458 /* function : mgl_treatname */
459 /* ###--------------------------------------------------------------### */
460 void
461 mgl_treatname(char *name, char *new_name)
462 {
463 char *blank_space;
464
465 /* Transformation des blancs en parentheses */
466 strcpy(new_name, name);
467 blank_space = strchr(new_name, ' ');
468 if (blank_space != NULL) {
469 *blank_space = '(';
470 blank_space = strchr(new_name, '\0');
471 /* Transformation du dernier caractere en ) */
472 if (blank_space != NULL) {
473 *blank_space = ')';
474 blank_space++;
475 *blank_space = '\0';
476 }
477 }
478 strcpy(new_name, mgl_vlgname(new_name));
479 }
480
481 /* ###--------------------------------------------------------------### */
482 /* function : mgl_vectnam */
483 /* ###--------------------------------------------------------------### */
484 void *
485 mgl_vectnam(void *pt_list, int *left, int *right, char **name, char type)
486 {
487 char *blank_space;
488 char *sig_name;
489 char name_tmp[200];
490 char number[200];
491 losig_list *ptsig;
492 locon_list *ptcon;
493 char END = 0;
494
495 /* Case losig_list */
496 if (type == 0) {
497 ptsig = (losig_list *) pt_list;
498 if (ptsig->TYPE == 'I') {
499 *left = *right = -1;
500 sig_name = getsigname(ptsig);
501 *name = (char *) mbkalloc(strlen(sig_name) + 1);
502 strcpy(*name, sig_name);
503 blank_space = strchr(*name, ' ');
504 if (blank_space != NULL) {
505 strcpy(number, blank_space);
506 *right = atoi(number);
507 *left = *right;
508 *blank_space = '\0';
509 }
510
511 while (!END) {
512 if (ptsig->NEXT != NULL) {
513 strcpy(name_tmp, getsigname(ptsig->NEXT));
514 blank_space = strchr(name_tmp, ' ');
515 if (blank_space != NULL) {
516 strcpy(number, blank_space);
517 *blank_space = '\0';
518 if (!strcmp(*name, name_tmp)) {
519 *left = atoi(number);
520 ptsig = ptsig->NEXT;
521 }
522 else END = 1;
523 }
524 else END = 1;
525 }
526 else END = 1;
527 }
528 return (ptsig);
529 }
530 else {
531 *name = NULL;
532 return (ptsig);
533 }
534 }
535
536 /*case locon_list */
537 if (type == 1) {
538 ptcon = (locon_list *) pt_list;
539 /* Extract the name and number of an element */
540 *left = *right = -1;
541 sig_name = ptcon->NAME;
542 *name = (char *) mbkalloc(strlen(sig_name) + 1);
543 strcpy(*name, sig_name);
544 blank_space = strchr(*name, ' ');
545 if (blank_space != NULL) {
546 strcpy(number, blank_space);
547 *right = atoi(number);
548 *left = *right;
549 *blank_space = '\0';
550 }
551
552 while (END != 1) {
553 if (ptcon->NEXT != NULL) {
554 strcpy(name_tmp, ptcon->NEXT->NAME);
555 blank_space = strchr(name_tmp, ' ');
556 if (blank_space != NULL) {
557 strcpy(number, blank_space);
558 *blank_space = '\0';
559 if (!strcmp(*name, name_tmp)) {
560 *right = atoi(number);
561 ptcon = ptcon->NEXT;
562 }
563 else END = 1;
564 }
565 else END = 1;
566 }
567 else END = 1;
568 }
569 return (ptcon);
570 }
571 /* To avoid Warning from GCC */
572 return (NULL);
573 }
574
575 /* ###--------------------------------------------------------------### */
576 /* function : mgl_fill */
577 /* content : Fill a lofig of mode 'P' with another lofig of mode 'A' */
578 /* ###--------------------------------------------------------------### */
579 struct lofig *
580 mgl_fill(struct lofig *lofig_P, struct lofig *lofig_A)
581 {
582 struct locon *ptlocon_P, *ptlocon_A;
583 struct chain *ptchain;
584 struct lofig *ptlofig;
585 struct losig *ptlosig;
586
587 /* MODELCHAIN */
588 ptchain = lofig_P->MODELCHAIN;
589 lofig_P->MODELCHAIN = lofig_A->MODELCHAIN;
590
591 /* LOCON */
592 ptlocon_P = lofig_P->LOCON;
593 ptlocon_A = lofig_A->LOCON;
594
595 while (ptlocon_A != NULL) {
596 if (ptlocon_A->NAME == ptlocon_P->NAME) {
597 ptlocon_P->SIG = ptlocon_A->SIG;
598 }
599 else {
600
601 fprintf(stderr,
602 "\n*** mbk error *** bad consistency in figure %s,\n external interface are different\n",
603 lofig_P->NAME);
604 }
605 ptlocon_A = ptlocon_A->NEXT;
606 ptlocon_P = ptlocon_P->NEXT;
607 }
608
609 /* LOSIG */
610 ptlosig = lofig_P->LOSIG;
611 lofig_P->LOSIG = lofig_A->LOSIG;
612
613 /* LOINS */
614 lofig_P->LOINS = lofig_A->LOINS;
615
616 /* LOTRS */
617 lofig_P->LOTRS = lofig_A->LOTRS;
618
619 /* USER */
620 lofig_P->USER = lofig_A->USER;
621
622 /* MODE */
623 lofig_P->MODE = 'A';
624
625 /* Freeing the memory zone unusable */
626
627 freechain(ptchain);
628
629 while (lofig_A->LOCON != NULL) {
630 dellocon(lofig_A, lofig_A->LOCON->NAME);
631 }
632
633 ptlofig = addlofig(" bidon");
634 ptlofig->LOSIG = ptlosig;
635 dellofig(ptlofig->NAME);
636
637 return (lofig_P);
638 }
639
640 /* ###--------------------------------------------------------------### */
641 /* function : mgl_addlosig */
642 /* description : create one or more losig structures (for an array a */
643 /* losig is created for each bit) */
644 /* called func. : addlosig, addchain */
645 /* ###--------------------------------------------------------------### */
646
647 losig_list *
648 mgl_addlosig(lofig_list *ptfig, int index, char type, char ptype, char *name, int left, int right)
649 {
650 char extname[1024];
651 short i;
652 short inc = 1;
653 struct chain *pt_chlst;
654 struct losig *ptsig;
655
656 if ((left == -1) && (right == -1)) {
657 pt_chlst = addchain(NULL, name);
658 ptsig = addlosig(ptfig, index, pt_chlst, type);
659
660 if (ptype != '0')
661 ptsig->USER = addptype(ptsig->USER, ptype, NULL);
662 }
663 else {
664 if (left >= right) /* array */
665 inc = -1;
666
667 for (i = left; i != (right + inc); i += inc) {
668 if (MBK_DEVECT) sprintf(extname, "%s %d", name, i);
669 else sprintf(extname, "%s[%d]", name, i);
670 pt_chlst = addchain(NULL, extname);
671 ptsig = addlosig(ptfig, index, pt_chlst, type);
672
673 if (ptype != '0')
674 ptsig->USER = addptype(ptsig->USER, ptype, NULL);
675
676 index++;
677 }
678 }
679 return (ptsig);
680 }
681
682 /* ###--------------------------------------------------------------### */
683 /* function : mgl_addlocon */
684 /* description : create one or more locon structures (for an array a */
685 /* locon is created for each bit) */
686 /* called func. : addlocon, addchain */
687 /* ###--------------------------------------------------------------### */
688
689 locon_list *
690 mgl_addlocon(lofig_list *ptfig, losig_list *ptsig, char dir, char *name, int left, int right)
691 {
692 char extname[1024];
693 short i;
694 short inc = 1;
695 struct locon *ptcon;
696 struct locon *ptcontmp;
697
698 if ((left == -1) && (right == -1)) {
699 ptcon = addlocon(ptfig, name, ptsig, dir);
700 }
701 else {
702 if (left >= right)
703 inc = -1;
704
705 for (i = left; i != (right + inc); i += inc) {
706 if (MBK_DEVECT) sprintf(extname, "%s %d", name, i);
707 else sprintf(extname, "%s[%d]", name, i);
708 ptcon = addlocon(ptfig, extname, NULL, dir);
709 }
710
711 if (ptsig != NULL) {
712 ptcontmp = ptcon;
713 for (i = left; i != (right + inc); i += inc) {
714 ptcontmp->SIG = ptsig;
715 ptcontmp = ptcontmp->NEXT;
716 ptsig = ptsig->NEXT;
717 }
718 }
719 }
720 return (ptcon);
721 }
722
723 /* ###--------------------------------------------------------------### */
724 /* function : mgl_orientlocon */
725 /* description : create one or more locon structures (for an array a */
726 /* locon is created for each bit) */
727 /* called func. : addlocon, addchain */
728 /* ###--------------------------------------------------------------### */
729
730 void mgl_clean_lorcnet(lofig_list *ptfig)
731 {
732 losig_list *ls;
733
734 for (ls=ptfig->LOSIG; ls!=NULL; ls=ls->NEXT)
735 {
736 if (ls->PRCN) freelorcnet(ls);
737 }
738 }
739
740
741 locon_list *
742 mgl_orientlocon(lofig_list *ptfig, char dir, char *name, int left, int right)
743 {
744 char extname[1024];
745 short i;
746 short inc = 1;
747 struct locon *ptcon;
748
749 if ((left == -1) && (right == -1)) {
750 ptcon = getlocon(ptfig, name);
751 ptcon->DIRECTION = dir;
752 }
753 else {
754 if (left >= right)
755 inc = -1;
756
757 for (i = left; i != (right + inc); i += inc) {
758 if (MBK_DEVECT) sprintf(extname, "%s %d", name, i);
759 else sprintf(extname, "%s[%d]", name, i);
760 ptcon = getlocon(ptfig, extname);
761 ptcon->DIRECTION = dir;
762 }
763 }
764 return (ptcon);
765 }
766
767 /* ###--------------------------------------------------------------### */
768 /* function : mgl_getlosig */
769 /* ###--------------------------------------------------------------### */
770
771 losig_list *
772 mgl_getlosig(lofig_list *ptfig, char *name, struct dct_entry **hshtab, mgl_scompcontext *context)
773 {
774 char extname[1024];
775 losig_list *ptlosig;
776 locon_list *ptcon;
777 char *radical;
778 int left, right, index;
779 int count;
780
781 if ((radical = vectorradical(name)) == name) {
782 ptlosig = (losig_list *)mgl_chktab(hshtab, name, ptfig->NAME, MGL_PNTDFN);
783 }
784 else {
785 ptlosig = (losig_list *)mgl_chktab(hshtab, radical, ptfig->NAME, MGL_PNTDFN);
786 left = mgl_chktab(hshtab, radical, ptfig->NAME, MGL_LFTDFN);
787 right = mgl_chktab(hshtab, radical, ptfig->NAME, MGL_RGTDFN);
788 index = vectorindex(name);
789 if (!MBK_DEVECT) {
790 sprintf(extname, "%s[%d]", radical, index);
791 name = namealloc(extname);
792 }
793 if ((index <= left && index >= right) || (index <= right && index >= left)) {
794 count = abs(index - right);
795 while (count-- > 0 && ptlosig != NULL) ptlosig = ptlosig->NEXT;
796 }
797 else avt_errmsg(MGL_ERRMSG, "005", AVT_ERROR, name, context->LINENUM);
798 if (ptlosig == NULL || ptlosig->NAMECHAIN->DATA != name) {
799 ptcon = getlocon(ptfig, name);
800 if (ptcon != NULL) {
801 ptlosig = ptcon->SIG;
802 }
803 else ptlosig = mbk_quickly_getlosigbyname(ptfig, name);
804 }
805 }
806 return ptlosig;
807 }
808
809 /* ###--------------------------------------------------------------### */
810 /* function : mgl_addloins */
811 /* ###--------------------------------------------------------------### */
812
813 loins_list *
814 mgl_addloins(struct lofig *ptfig, char *modelname, char *insname, chain_list *loconnames, chain_list *sigchain)
815 {
816 loins_list *ptloins;
817 locon_list *ptlocon;
818 chain_list *ptchain, *ptchain1;
819
820 ptloins = (loins_list *)mbkalloc(sizeof(loins_list));
821
822 ptloins->INSNAME = insname;
823 ptloins->FIGNAME = modelname;
824 ptloins->LOCON = NULL;
825 ptloins->USER = NULL;
826 ptloins->NEXT = ptfig->LOINS;
827 ptfig->LOINS = ptloins;
828
829 /* update model list */
830 for (ptchain = ptfig->MODELCHAIN; ptchain; ptchain = ptchain->NEXT)
831 if (ptchain->DATA == (void *)modelname)
832 break;
833
834 if (!ptchain)
835 ptfig->MODELCHAIN = addchain(ptfig->MODELCHAIN, (void *)modelname);
836
837 for (ptchain = sigchain, ptchain1 = loconnames; ptchain && ptchain1; ptchain = ptchain->NEXT, ptchain1 = ptchain1->NEXT) {
838 ptlocon = (locon_list *)mbkalloc(sizeof(locon_list));
839 ptlocon->NAME = (char *)ptchain1->DATA;
840 ptlocon->DIRECTION = UNKNOWN;
841 ptlocon->TYPE = 'I';
842 ptlocon->SIG = (losig_list *)ptchain->DATA;
843 ptlocon->ROOT = ptloins;
844 ptlocon->USER = NULL;
845 ptlocon->PNODE = NULL;
846 ptlocon->NEXT = ptloins->LOCON;
847 ptloins->LOCON = ptlocon;
848 }
849
850 return ptloins;
851 }
852
853 /* ###--------------------------------------------------------------### */
854 /* function : mgl_assign */
855 /* ###--------------------------------------------------------------### */
856
857 void
858 mgl_assign(lofig_list *ptfig, char *lident, char *rident, struct dct_entry **hshtab, mgl_scompcontext *context)
859 {
860 losig_list *ptlsig;
861 losig_list *ptrsig;
862 losig_list *pttempsig;
863 ptype_list *ptluser;
864 ptype_list *ptruser;
865 chain_list *ptchain;
866
867 ptlsig = (losig_list *)mgl_getlosig(ptfig, lident, hshtab, context);
868 ptrsig = (losig_list *)mgl_getlosig(ptfig, rident, hshtab, context);
869 /* quietly give-up if signal does not exist */
870 if (ptlsig == NULL || ptrsig == NULL) return;
871
872 if (ptrsig->TYPE == EXTERNAL && ptlsig->TYPE == EXTERNAL) {
873 fprintf(stderr, "Warning : external signals '%s' and '%s' have been merged\n", lident, rident);
874 ptrsig->NAMECHAIN = append(ptrsig->NAMECHAIN, ptlsig->NAMECHAIN);
875 ptlsig->NAMECHAIN = NULL;
876 }
877 else {
878 /* swap if rhs is external */
879 if (ptrsig->TYPE == EXTERNAL) {
880 pttempsig = ptrsig;
881 ptrsig = ptlsig;
882 ptlsig = pttempsig;
883 }
884
885 /* change rsig to external if lsig external */
886 if (ptlsig->TYPE == EXTERNAL) ptrsig->TYPE = EXTERNAL;
887
888 /* merge names unless external */
889 if (ptrsig->TYPE == EXTERNAL) {
890 freechain(ptrsig->NAMECHAIN);
891 ptrsig->NAMECHAIN = ptlsig->NAMECHAIN;
892 }
893 else {
894 ptrsig->NAMECHAIN = append(ptrsig->NAMECHAIN, ptlsig->NAMECHAIN);
895 }
896 ptlsig->NAMECHAIN = NULL;
897 }
898
899 /* merge connectors */
900 ptluser = getptype(ptlsig->USER, LOFIGCHAIN);
901 if (ptluser != NULL) {
902 for (ptchain = (chain_list *)ptluser->DATA; ptchain; ptchain = ptchain->NEXT) {
903 ((locon_list *)ptchain->DATA)->SIG = ptrsig;
904 }
905 ptruser = getptype(ptrsig->USER, LOFIGCHAIN);
906 ptruser->DATA = append((chain_list *)ptruser->DATA, (chain_list *)ptluser->DATA);
907 ptlsig->USER = delptype(ptlsig->USER, LOFIGCHAIN);
908 }
909
910 ptlsig->INDEX = 0;
911 }
912
913 /* ###--------------------------------------------------------------### */
914 /* function : mgl_sortsig */
915 /* ###--------------------------------------------------------------### */
916
917 /* Reorder signals to match model. First try order or reverse order */
918 /* matching. If that fails then we apply the popular n^2 technique */
919
920 chain_list *
921 mgl_sortsig(lofig_list *ptmodel, char *insname, chain_list *loconnames, chain_list *sigchain, lofig_list *ptfig, int *ptindex)
922 {
923 locon_list *ptmodelcon;
924 losig_list *ptnewsig;
925 chain_list *ptchain, *ptchain1;
926 chain_list *reschain = NULL;
927 char buffer[1024];
928 int i=0, j=0, reversed=0;
929
930 for (ptchain = sigchain; ptchain != NULL; ptchain = ptchain->NEXT) i++;
931 for (ptchain = loconnames; ptchain != NULL; ptchain = ptchain->NEXT) {
932 j++;
933 }
934 if (i != j) {
935 fflush(stdout);
936 fputs("*** mbk error ***\n", stderr);
937 fputs("mgl_sortsig : inconsistency between connectors", stderr);
938 fprintf(stderr, " and signals in instance '%s'\n", insname);
939 EXIT(1);
940 }
941 i = 0;
942 j = 0;
943
944 if (sigchain != NULL) {
945 if (ptmodel->LOCON != NULL && ptmodel->LOCON->NAME != (char *)loconnames->DATA) {
946 loconnames = reverse(loconnames);
947 sigchain = reverse(sigchain);
948 reversed=1;
949 }
950 }
951
952 for (ptmodelcon = ptmodel->LOCON, ptchain = loconnames;
953 ptmodelcon != NULL && ptchain != NULL;
954 ptmodelcon = ptmodelcon->NEXT, ptchain = ptchain->NEXT) {
955 if (ptmodelcon->NAME != (char *)ptchain->DATA) break;
956 }
957
958 /* order matching fails so try name matching */
959 if (ptmodelcon != NULL || ptchain != NULL) {
960 for (ptmodelcon = ptmodel->LOCON; ptmodelcon != NULL; ptmodelcon = ptmodelcon->NEXT) i++;
961 for (ptchain = loconnames; ptchain != NULL; ptchain = ptchain->NEXT) j++;
962 if (i < j) {
963 fflush(stdout);
964 fputs("*** mbk error ***\n", stderr);
965 fputs("mgl_sortsig : connector number inconsistency between model", stderr);
966 fprintf(stderr, " '%s' and instance '%s'\n", ptmodel->NAME, insname);
967 EXIT(1);
968 }
969 for (ptmodelcon = ptmodel->LOCON; ptmodelcon != NULL; ptmodelcon = ptmodelcon->NEXT) {
970 for (ptchain = loconnames, ptchain1 = sigchain; ptchain; ptchain = ptchain->NEXT, ptchain1 = ptchain1->NEXT) {
971 if ((char *)ptchain->DATA == ptmodelcon->NAME) {
972 reschain = addchain(reschain, ptchain1->DATA);
973 break;
974 }
975 }
976 if (ptchain == NULL) {
977 sprintf(buffer, "%s_%s", insname, ptmodelcon->NAME);
978 ptnewsig = addlosig(ptfig, *ptindex, addchain(NULL, namealloc(buffer)), 'I');
979 (*ptindex)++;
980 reschain = addchain(reschain, ptnewsig);
981 }
982 }
983 freechain(sigchain);
984 reschain = reverse(reschain);
985 }
986 else reschain = sigchain;
987
988 if (reversed)
989 {
990 loconnames = reverse(loconnames);
991 }
992 return reschain;
993 }
994
995 /* ###--------------------------------------------------------------### */
996 /* function : mgl_getloconrange */
997 /* ###--------------------------------------------------------------### */
998
999 void
1000 mgl_getloconrange(locon_list *ptheadlocon, char *name, int *left, int *right)
1001 {
1002 locon_list *ptlocon;
1003 int index, match;
1004
1005 *left = -1;
1006 *right = -1;
1007 for (ptlocon = ptheadlocon; ptlocon; ptlocon = ptlocon->NEXT) {
1008 if (strcmp(vectorradical(ptlocon->NAME), name) == 0) match = 1;
1009 else match = 0;
1010 if (match) {
1011 index = vectorindex(ptlocon->NAME);
1012 if (*right == -1) *right = index;
1013 *left = index;
1014 }
1015 }
1016 }
1017
1018 /* ###--------------------------------------------------------------### */
1019 /* function : mgl_givevdd */
1020 /* ###--------------------------------------------------------------### */
1021
1022 /* Identify a VDD signal on module interface or create a VDD local */
1023 /* to the instance */
1024
1025 losig_list *
1026 mgl_givevdd(lofig_list *ptfig, char *insname, int *ptindex)
1027 {
1028 locon_list *ptlocon;
1029 losig_list *ptnewsig;
1030 char buffer[1024];
1031
1032 for (ptlocon = ptfig->LOCON; ptlocon; ptlocon = ptlocon->NEXT) {
1033 if (mbk_LosigIsVDD(ptlocon->SIG)) return ptlocon->SIG;
1034 }
1035
1036 sprintf(buffer, "%s_vdd", insname);
1037 ptnewsig = addlosig(ptfig, *ptindex, addchain(NULL, namealloc(buffer)), 'I');
1038 mbk_SetLosigVDD(ptnewsig);
1039 (*ptindex)++;
1040
1041 return ptnewsig;
1042 }
1043
1044 /* ###--------------------------------------------------------------### */
1045 /* function : mgl_givevss */
1046 /* ###--------------------------------------------------------------### */
1047
1048 /* Identify a VSS signal on module interface or create a VDD local */
1049 /* to the instance */
1050
1051 losig_list *
1052 mgl_givevss(lofig_list *ptfig, char *insname, int *ptindex)
1053 {
1054 locon_list *ptlocon;
1055 losig_list *ptnewsig;
1056 char buffer[1024];
1057
1058 for (ptlocon = ptfig->LOCON; ptlocon; ptlocon = ptlocon->NEXT) {
1059 if (mbk_LosigIsVSS(ptlocon->SIG)) return ptlocon->SIG;
1060 }
1061
1062 sprintf(buffer, "%s_vss", insname);
1063 ptnewsig = addlosig(ptfig, *ptindex, addchain(NULL, namealloc(buffer)), 'I');
1064 mbk_SetLosigVSS(ptnewsig);
1065 (*ptindex)++;
1066
1067 return ptnewsig;
1068 }
1069