Initial version of donated sources by Avertec, 3.4p5.
[tas-yagle.git] / distrib / sources / behsystemc / bsc_util.c
1 /****************************************************************************/
2 /* */
3 /* file : bsc_drive.c */
4 /* date : March 2003 */
5 /* version : v100 */
6 /* author(s) : PINTO A. */
7 /* */
8 /* description : Utilities for SystemC HDL driver */
9 /* */
10 /****************************************************************************/
11
12 #include <stdio.h>
13 #include <string.h>
14 #include <stdlib.h>
15 #include <stdarg.h>
16 #include MUT_H
17 #include LOG_H
18 #include BEH_H
19 #include BEG_H
20 #include "bsc_utype.h"
21 #include "bsc_util.h"
22 #include "bsc_utdef.h"
23
24
25 char *bsc_getBitStr(char *str);
26 static int bsc_2puiss(int exp);
27 char *bsc_bitToHex(char *str);
28
29 /****************************************************************************/
30 /*{{{ bgl_mystrcat() */
31 /* */
32 /* */
33 /****************************************************************************/
34 static char *bsc_mystrcat(char *str1, char *str2, ... )
35 {
36 va_list arg;
37 char buf[64];
38
39 va_start(arg,str2);
40 vsprintf(buf,str2,arg);
41 va_end (arg);
42 return strcat(str1,buf);
43 }
44
45 /*}}}************************************************************************/
46 /*{{{ bsc_name() */
47 /* */
48 /* */
49 /****************************************************************************/
50 static struct beden **namtab=NULL;
51
52 void bsc_freenames(void)
53 {
54 beh_fretab(namtab);
55 namtab = NULL;
56 }
57
58 char *bsc_name (char *name)
59 {
60 char *new_name;
61 char *prv_name;
62 char *tmp_name;
63 char buffer[200];
64 int i,j,flag,number;
65 static char *keywrd [] =
66 {
67 "abs" , "access" , "after" , "alias" ,
68 "all" , "and" , "architecture", "array" ,
69 "assert" , "attribute" , "begin" , "bit" ,
70 "bit_vector" , "block" , "body" , "buffer" ,
71 "bus" , "case" , "component" , "configuration",
72 "constant" , "disconnect" , "downto" , "else" ,
73 "elsif" , "end" , "entity" , "error" ,
74 "exit" , "file" , "for" , "function" ,
75 "generate" , "generic" , "guarded" , "if" ,
76 "in" , "inout" , "is" , "label" ,
77 "library" , "linkage" , "loop" , "map" ,
78 "mod" , "mux_bit" , "mux_vector" , "nand" ,
79 "natural" , "new" , "next" , "nor" ,
80 "not" , "null" , "of" , "on" ,
81 "open" , "or" , "others" , "out" ,
82 "package" , "port" , "procedure" , "process" ,
83 "range" , "record" , "reg_bit" , "reg_vector" ,
84 "register" , "rem" , "report" , "return" ,
85 "select" , "severity" , "signal" , "stable" ,
86 "subtype" , "then" , "to" , "transport" ,
87 "type" , "units" , "until" , "use" ,
88 "variable" , "wait" , "warning" , "when" ,
89 "while" , "with" , "wor_bit" , "wor_vector" ,
90 "xor"
91 };
92
93 if (namtab == NULL)
94 {
95 namtab = beh_initab ();
96 for (i = 0; i < 93; i ++)
97 beh_addtab (namtab, namealloc (keywrd [i]), NULL, BSC_NEWDFN , 1);
98 }
99
100 tmp_name = namealloc (name);
101 new_name = (char *) beh_chktab (namtab,tmp_name,NULL,BSC_PNTDFN);
102
103 if (beh_chktab (namtab,tmp_name,NULL,BSC_NAMDFN) == 0)
104 {
105 i = 0;
106 j = 0;
107 number = 0;
108 flag = 1;
109 while (tmp_name[i] != '\0')
110 {
111 buffer[j] = tmp_name[i];
112 if ( ((tmp_name[i] >= 'a') && (tmp_name[i] <= 'z')) ||
113 ((tmp_name[i] >= 'A') && (tmp_name[i] <= 'Z')) ||
114 ((tmp_name[i] >= '0') && (tmp_name[i] <= '9') && (i != 0)))
115 flag = 0;
116 else
117 {
118 if (flag == 1)
119 buffer[j++] = 'v';
120 buffer[j] = '_';
121 flag = 1;
122 }
123 i ++;
124 j ++;
125 }
126 if (buffer[j-1] == '_')
127 buffer[j++] = '0';
128 buffer[j] = '\0';
129 new_name = namealloc (buffer);
130
131 prv_name = new_name;
132 while (beh_chktab (namtab,new_name,NULL,BSC_NEWDFN) != 0)
133 {
134 new_name = prv_name;
135 sprintf (buffer,"%s_%d",new_name,number++);
136 prv_name = new_name;
137 new_name = namealloc (buffer);
138 }
139 beh_addtab (namtab,new_name,NULL,BSC_NEWDFN,1);
140 beh_addtab (namtab,tmp_name,NULL,BSC_PNTDFN,(long)new_name);
141 beh_addtab (namtab,tmp_name,NULL,BSC_NAMDFN,1);
142 }
143
144 return (new_name);
145 }
146
147 /*}}}************************************************************************/
148 /*{{{ bsc_vectorize() */
149 /* */
150 /* description : put parenthesis on element of bussed signals */
151 /* */
152 /****************************************************************************/
153 char *bsc_vectorize(char *name)
154 {
155 char *new_name ;
156 char tmp1 [256];
157 int i = 0;
158 int j = 0;
159 int left;
160 int right;
161 static struct beden **tab = NULL;
162
163 if (tab == NULL)
164 tab = beh_initab ();
165
166 new_name = (char *) beh_chktab (tab, name, NULL, BSC_PNTDFN);
167 if (new_name == NULL)
168 {
169 strcpy (tmp1, name);
170
171 while ((name [i] != '\0') && (name [i] != ' ' ) && (name [i] != '\''))
172 i ++;
173
174 tmp1 [i] = '\0';
175 new_name = bsc_name (tmp1);
176
177 if (name [i] != '\0')
178 {
179 if (name [i] == ' ')
180 {
181 //// added by anto
182 j = i;
183 while ((name[j]!='\0')&&(name[j]!=':'))
184 j++;
185 if (name[j]!='\0')
186 {
187 left = atoi(&name[i+1]);
188 right = atoi(&name[j+1]);
189 sprintf (tmp1,"%s(%d %s %d)",new_name,
190 left,(left<right)?"TO":"DOWNTO",right);
191 }
192 ////
193 else
194 sprintf (tmp1, "%s(%s)", new_name, &name[i+1]);
195 }
196 else
197 sprintf (tmp1, "%s'%s" , new_name, &name[i+1]);
198 new_name = namealloc (tmp1);
199 }
200 beh_addtab (tab, name, NULL, BSC_PNTDFN, (long)new_name);
201 }
202
203 return (new_name);
204 }
205
206 /*}}}************************************************************************/
207 /*{{{ bsc_vectnam() */
208 /* */
209 /* analyze a list of signal and return the bounds of the vectorised */
210 /* signals, if they occure. */
211 /* attention !!! cette fonction part du principe que ->NAME est toujours */
212 /* le 2 eme champs de chaque structure beXXX */
213 /* */
214 /****************************************************************************/
215 void *bsc_vectnam(void *pt_list, int *left, int *right, char **name, char type)
216 /* If type = 0 bepor_list, type = 1 bebux_list*/
217 /* If type = 2 bereg_list, type = 3 beaux_list*/
218 {
219 char *blank_space;
220 char *sig_name;
221 char name_tmp[200];
222 char number[200];
223 bepor_list *ptpor;
224 bebux_list *ptbux;
225 beaux_list *ptaux;
226 bereg_list *ptreg;
227 char END = 0;
228
229 /* Case bepor_list */
230 if(type == 0)
231 {
232 ptpor = (bepor_list *)pt_list;
233 *left = *right = -1;
234 sig_name = ptpor->NAME;
235 *name = (char*)mbkalloc(strlen(sig_name) + 1);
236 strcpy(*name,sig_name);
237 blank_space = strchr(*name,' ');
238 if (blank_space != NULL)
239 {
240 strcpy(number,blank_space);
241 *left = atoi(number);
242 *right = *left;
243 *blank_space = '\0';
244 }
245
246 while(!END)
247 {
248 if(ptpor->NEXT != NULL)
249 {
250 strcpy(name_tmp,(ptpor->NEXT)->NAME);
251 blank_space = strchr(name_tmp,' ');
252 if(blank_space!=NULL)
253 {
254 strcpy(number,blank_space);
255 *blank_space = '\0';
256 if(!strcmp(*name,name_tmp))
257 {
258 *right = atoi(number);
259 ptpor = ptpor->NEXT;
260 }
261 else
262 END = 1;
263 }
264 else
265 END = 1;
266 }
267 else
268 END = 1;
269 }
270 return(ptpor);
271 }
272
273 /*case bebux_list */
274 if(type==1)
275 {
276 ptbux = (bebux_list *)pt_list;
277 /* Extract the name and number of an element */
278 *left = *right = -1;
279 sig_name = ptbux->NAME;
280 *name = (char *)mbkalloc(strlen(sig_name) + 1);
281 strcpy(*name,sig_name);
282 blank_space = strchr(*name,' ');
283 if (blank_space != NULL)
284 {
285 strcpy(number,blank_space);
286 *right = atoi(number);
287 *left = *right;
288 *blank_space = '\0';
289 }
290
291 while(END != 1)
292 {
293 if(ptbux->NEXT != NULL)
294 {
295 strcpy(name_tmp,ptbux->NEXT->NAME);
296 blank_space = strchr(name_tmp,' ');
297 if(blank_space!=NULL)
298 {
299 strcpy(number,blank_space);
300 *blank_space = '\0';
301 if(!strcmp(*name,name_tmp))
302 {
303 *right = atoi(number);
304 ptbux = ptbux->NEXT;
305 }
306 else
307 END = 1;
308 }
309 else
310 END = 1;
311 }
312 else
313 END = 1;
314 }
315 return(ptbux);
316 }
317
318 /*case bereg_list */
319 if(type==2)
320 {
321 ptreg = (bereg_list *)pt_list;
322 /* Extract the name and number of an element */
323 *left = *right = -1;
324 sig_name = ptreg->NAME;
325 *name = (char *)mbkalloc(strlen(sig_name) + 1);
326 strcpy(*name,sig_name);
327 blank_space = strchr(*name,' ');
328 if (blank_space != NULL)
329 {
330 strcpy(number,blank_space);
331 *right = atoi(number);
332 *left = *right;
333 *blank_space = '\0';
334 }
335
336 while(END != 1)
337 {
338 if(ptreg->NEXT != NULL)
339 {
340 strcpy(name_tmp,ptreg->NEXT->NAME);
341 blank_space = strchr(name_tmp,' ');
342 if(blank_space!=NULL)
343 {
344 strcpy(number,blank_space);
345 *blank_space = '\0';
346 if(!strcmp(*name,name_tmp))
347 {
348 *right = atoi(number);
349 ptreg = ptreg->NEXT;
350 }
351 else
352 END = 1;
353 }
354 else
355 END = 1;
356 }
357 else
358 END = 1;
359 }
360 return(ptreg);
361 }
362
363 /*case beaux_list */
364 if(type==3)
365 {
366 ptaux = (beaux_list *)pt_list;
367 /* Extract the name and number of an element */
368 *left = *right = -1;
369 sig_name = ptaux->NAME;
370 *name = (char *)mbkalloc(strlen(sig_name) + 1);
371 strcpy(*name,sig_name);
372 blank_space = strchr(*name,' ');
373 if (blank_space != NULL)
374 {
375 strcpy(number,blank_space);
376 *right = atoi(number);
377 *left = *right;
378 *blank_space = '\0';
379 }
380
381 while(END != 1)
382 {
383 if(ptaux->NEXT != NULL)
384 {
385 strcpy(name_tmp,ptaux->NEXT->NAME);
386 blank_space = strchr(name_tmp,' ');
387 if(blank_space!=NULL)
388 {
389 strcpy(number,blank_space);
390 *blank_space = '\0';
391 if(!strcmp(*name,name_tmp))
392 {
393 *right = atoi(number);
394 ptaux = ptaux->NEXT;
395 }
396 else
397 END = 1;
398 }
399 else
400 END = 1;
401 }
402 else
403 END = 1;
404 }
405 return(ptaux);
406 }
407
408 return NULL;
409 }
410
411 /*}}}************************************************************************/
412 /*{{{ bsc_printabl() */
413 /* */
414 /* put a \n for a better presentation of an abl */
415 /* */
416 /****************************************************************************/
417 char *bsc_printabl(char *chaine)
418 {
419 char *chaine_tmp = NULL;
420 char *blanc = NULL;
421
422 chaine_tmp = chaine;
423 while (strlen(chaine_tmp)>60)
424 {
425 chaine_tmp = &chaine_tmp[60];
426 do
427 {
428 blanc = strchr(chaine_tmp,' ');
429 if (blanc != NULL) chaine_tmp = blanc+1;
430 }
431 while ( blanc &&
432 ( *(blanc-1) == '=' || *(blanc+1) == '=' || *(blanc+1) == '('));
433
434 if (blanc)
435 *blanc = '\n';
436 }
437 return (chaine);
438 }
439
440 /*}}}************************************************************************/
441 /*{{{ bsc_abl2str() */
442 /* */
443 /* return a string corresponding to an expression */
444 /* */
445 /****************************************************************************/
446 char *bsc_abl2str (chain_list *expr, char *chaine, int *size_pnt)
447 {
448 char *oper ;
449 struct chain *operand ;
450 char *tmp;
451 int i;
452
453
454 /* ###--------------------------------------------------------### */
455 /* if there is not enough space left allocate a bigger block*/
456 /* ###--------------------------------------------------------### */
457
458 if ((size_t)*size_pnt < (strlen (chaine) + 256))
459 {
460 *size_pnt = *size_pnt + 512;
461 chaine = (char *) mbkrealloc (chaine, *size_pnt);
462 }
463
464 /* ###------------------------------------------------------### */
465 /* if the expression is a terminal (atom) add its name to */
466 /* the previous string */
467 /* ###------------------------------------------------------### */
468
469 if (expr->NEXT == NULL)
470 {
471 if (isBitStr(expr->DATA))
472 {
473 tmp = bsc_getBitStr(expr->DATA);
474 strcat (chaine, tmp);
475 mbkfree(tmp);
476 }
477 else
478 strcat (chaine, bsc_vectorize (expr->DATA));
479 }
480
481 else
482 {
483 /* ###------------------------------------------------------### */
484 /* if the expression is not a terminal : */
485 /* - for unary operators (not, stable) add */
486 /* "operator ( operand )" to the previous string */
487 /* */
488 /* - for binary operators (and, or, nor, xor, ...) add */
489 /* "(operand operator operand operator operand ...)" */
490 /* ###------------------------------------------------------### */
491
492 operand = (struct chain *)expr->NEXT->DATA;
493
494 switch (OPER(expr))
495 {
496 case STABLE :
497 bsc_mystrcat(chaine,"%s'STABLE",bsc_vectorize (operand->DATA));
498 break;
499 // added by anto to compute vectabl
500 case REPLICATE:
501 strcat (chaine,"(");
502 for (i = 0; i < REP_NB(expr); i ++)
503 {
504 strcat(chaine,bsc_vectorize (operand->DATA));
505 if (i != REP_NB(expr)-1)
506 strcat(chaine," & ");
507 }
508 strcat (chaine, ")");
509 break;
510 case NOT :
511 strcat (chaine, "not (");
512 chaine = bsc_abl2str (operand, chaine, size_pnt);
513 strcat (chaine, ")");
514 break;
515 default :
516 oper = operToChar (OPER(expr));
517 strcat (chaine,"(");
518 while ( (expr = expr->NEXT) )
519 {
520 chaine = bsc_abl2str (expr->DATA, chaine, size_pnt);
521 if (expr->NEXT)
522 bsc_mystrcat(chaine, " %s ",oper);
523 }
524 strcat (chaine, ")");
525 }
526 }
527
528 return (chaine);
529 }
530
531 /*}}}************************************************************************/
532 /*{{{ bsc_getBitStr() */
533 /* */
534 /* create an easy to drive copy of the bitstring */
535 /* */
536 /****************************************************************************/
537 char *bsc_getBitStr(char *str)
538 {
539 char buf [4096];
540 int i, n, j;
541
542 n = strlen(str);
543 for (i = j = n; i >= 0; i --)
544 {
545 switch (str[i])
546 {
547 case 'u' : buf[j--] = 'U'; break;
548 case 'z' : buf[j--] = 'Z'; break;
549 case 'd' : buf[j--] = 'D'; break;
550 default : buf[j--] = str[i]; break;
551 }
552 }
553 if (n > 18)
554 return bsc_bitToHex(buf);
555 else
556 return mbkstrdup(buf);
557 }
558
559 /*}}}************************************************************************/
560 /*{{{ bsc_2puiss() */
561 /* */
562 /* */
563 /****************************************************************************/
564 static int bsc_2puiss(int exp)
565 {
566 if (exp)
567 return 2 * bsc_2puiss(exp - 1);
568 else
569 return 1;
570 }
571
572 /*}}}************************************************************************/
573 /*{{{ bsc_bitToHex() */
574 /* */
575 /* */
576 /****************************************************************************/
577 char *bsc_bitToHex(char *str)
578 {
579 char buf [512];
580 int i, n, j;
581 char tmp, pos, go;
582
583 n = strlen(str);
584 j = (n - 2) / 4 + 3 + (((n - 2) % 4) ? 1 : 0);
585
586 buf[0] = 'X';
587 tmp = 0;
588 for (i = n; i >= 0; i --)
589 {
590 switch (str[i])
591 {
592 case 'u' : case 'z' : case 'd' : case '\'' :
593 return str;
594 case '"' :
595 if ((n-1) - i)
596 buf[j--] = (tmp < 10) ? '0' + tmp : 'A' + tmp % 10 ;
597 else
598 go = 0;
599 buf[j--] = '"';
600 break;
601 case '\0' :
602 buf[j--] = str[i];
603 break;
604 default :
605 if (!(pos = (n - (i+2))% 4))
606 {
607 if (go)
608 {
609 buf[j--] = (tmp < 10) ? '0' + tmp : 'A' + tmp % 10 ;
610 tmp = 0;
611 }
612 else
613 go = 1;
614 }
615 tmp += (str[i] - '0') * bsc_2puiss(pos);
616 }
617 }
618 return mbkstrdup(buf);
619 }
620
621 /*}}}************************************************************************/
622 /*{{{ bsc_abl2strbool() */
623 /* */
624 /* This is a modified version of the previous function that is meant */
625 /* to be synopsys compliant regarding the boolean nature of a number */
626 /* of variables and signals. */
627 /* */
628 /****************************************************************************/
629 char *bsc_abl2strbool (chain_list *expr, char *chaine, int *size_pnt)
630 {
631 char *oper ;
632 struct chain *operand ;
633 int size;
634
635 /* ###------------------------------------------------------### */
636 /* if there is not enough space left allocate a bigger block */
637 /* ###------------------------------------------------------### */
638
639 if ((size_t)*size_pnt < (strlen (chaine) + 256))
640 {
641 *size_pnt = *size_pnt + 512;
642 chaine = (char *) mbkrealloc (chaine, *size_pnt);
643 }
644
645 /* ###------------------------------------------------------### */
646 /* if the expression is a terminal (atom) add its name to */
647 /* the previous string */
648 /* ###------------------------------------------------------### */
649
650 if (ATOM(expr))
651 {
652 // added by anto to compute vectabl
653 if (isBitStr(expr->DATA))
654 strcat (chaine, expr->DATA);
655 else
656 {
657 size = getAtomSize(expr);
658 bsc_mystrcat( chaine,"%s = %s", bsc_vectorize (expr->DATA),
659 genOneBitStr(size));
660 }
661 }
662 else
663 {
664 /* ###------------------------------------------------------### */
665 /* if the expression is not a terminal : */
666 /* - for unary operators (not, stable) add */
667 /* "operator ( operand )" to the previous string */
668 /* */
669 /* - for binary operators (and, or, nor, xor, ...) add */
670 /* "(operand operator operand operator operand ...)" */
671 /* ###------------------------------------------------------### */
672
673 operand = (struct chain *)expr->NEXT->DATA;
674
675 switch (OPER(expr))
676 {
677 case STABLE :
678 bsc_mystrcat(chaine, "not (%s'EVENT)",
679 bsc_vectorize (operand->DATA));
680 break;
681 case NOT :
682 if (operand->NEXT != NULL
683 && (long)((chain_list * )operand->DATA)->DATA == STABLE)
684 {
685 strcat (chaine,
686 bsc_vectorize (((chain_list * )operand->NEXT->DATA)->DATA));
687 strcat (chaine, "'EVENT");
688 }
689 // added by anto to compute vectabl
690 else if (isBitStr(operand->DATA))
691 strcat (chaine, operand->DATA);
692 else
693 {
694 char *buf;
695 int bufsize = 512;
696 char buffer[128];
697
698 size = getAtomSize(operand);
699
700 buf = mbkalloc(bufsize);
701 buf[0] = '\0';
702 bsc_abl2str(operand,buf,&bufsize);
703 sprintf(buffer, "%s = %s", buf, genZeroBitStr(size));
704 mbkfree(buf);
705 strcat (chaine, buffer);
706 }
707 break;
708 // added by anto to compute vectabl
709 case CAT :
710 {
711 char *bitstr;
712 char *buf;
713 int bufsize = 512;
714 chain_list *tmpExpr;
715
716 buf = mbkalloc(bufsize);
717 bitstr = beg_boolDelNot(expr,&tmpExpr);
718
719 buf[0] = '\0';
720 bsc_abl2str(tmpExpr,buf,&bufsize);
721 bsc_mystrcat(chaine, "STD_LOGIC_VECTOR'%s = %s",buf,bitstr);
722 mbkfree(buf);
723 freeExpr(tmpExpr);
724 }
725 break ;
726 default :
727 oper = operToChar (OPER(expr));
728 strcat (chaine, "(");
729 while ((expr = expr->NEXT))
730 {
731 chaine = bsc_abl2strbool (expr->DATA, chaine, size_pnt);
732 if (expr->NEXT)
733 bsc_mystrcat(chaine, " %s ", oper);
734 }
735 strcat (chaine, ")");
736 }
737 }
738 return (chaine);
739 }
740
741 /*}}}************************************************************************/