source: vis_dev/vl2mv-2.3/src/parser/util.c @ 18

Last change on this file since 18 was 18, checked in by cecile, 13 years ago

vl2mv added

File size: 15.0 KB
Line 
1/*
2
3  Copyright (c) 1992, 1993
4        Regents of the University of California
5  All rights reserved.
6
7  Use and copying of this software and preparation of derivative works
8  based upon this software are permitted.  However, any distribution of
9  this software or derivative works must include the above copyright
10  notice.
11
12  This software is made available AS IS, and neither the Electronics
13  Research Laboratory or the Universify of California make any
14  warranty about the software, its performance or its conformity to
15  any specification.
16
17  Author: Szu-Tsung Cheng, stcheng@ic.Berkeley.EDU
18          10/92
19          10/93
20
21  $Header: /projects/development/hsv/CVSRepository/vl2mv/src/parser/util.c,v 1.4 2009/03/09 20:25:57 fabio Exp $
22
23
24*/
25
26
27#include <stdio.h>
28#include "util.h"
29#include "st.h"
30#include "list.h"
31#include "array.h"
32#include "set.h"
33#include "vl_defs.h"
34#include "vl_types.h"
35#include "vlr_int.h"
36#include "verilog_yacc.h"
37#include "vl_create.h"
38#include "vl_write.h"
39#include "vl_write_util.h"
40#include "verilog.h"
41
42void chk_error(str)
43char *str;
44{
45    fprintf(stderr, "internal utility error:%s\n", str);
46    vl_exit(ERR_CHK);
47}
48
49char *chk_malloc(unsigned n)
50{
51    char *retval;
52    if ((retval=(char*)malloc((n==0)?1:n)) == NIL(char))
53        chk_error("can't allocate memory ");
54    memset(retval, 0, n);
55    return retval;
56}
57
58void vl_chk_free(lsGeneric p)
59{
60    free((char *)p);
61}
62
63
64char* vlStrdup(char *str)
65{
66    char *retval;
67    unsigned length;
68
69    length = strlen(str)+1;
70    retval = (char*)chk_malloc(length);
71    strcpy(retval, str);
72    return retval;
73}
74
75
76void compile_error(char* str)
77{
78    extern int yylineno;
79
80    if (yylineno >=0)
81        fprintf(stderr, "line %d %s\n", yylineno, str);
82    else
83        fprintf(stderr, "%s\n", str);
84    vl_exit(ERR_COMPILE);
85}
86
87void semantic_error(char *str)
88{
89    fprintf(stderr, "semantic error: %s\n", str);
90    vl_exit(ERR_SEMANTIC);
91}
92
93void internal_error(char *str)
94{
95    fprintf(stderr, "internal error: %s\n", str);
96    vl_exit(ERR_INTERNAL);
97}
98
99void Translate_Warning(char *str)
100{
101    fprintf(stderr, "%s, translation might be imprecise\n",
102            str);
103    vl_exit(ERR_SEMANTIC);
104}
105
106void Translate_Notice(char *str)
107{
108    fprintf(stderr, "%s\n", str);
109}
110
111int drive_strength(int strength0, int strength1)
112{
113    int retval = -1;
114
115    switch(strength0) {
116    case YYSUPPLY0:
117        switch(strength1) {
118        case YYSUPPLY1:retval = Supply1Supply0; break;
119        case YYSTRONG1:retval = Strong1Supply0; break;
120        case YYPULL1:  retval = Pull1Supply0; break;
121        case YYWEAK1:  retval = Weak1Supply0; break;
122        case YYHIGHZ1: retval = HighZ1Supply0; break;
123        default: compile_error("illegal strength0/strength1");
124        }
125        break;
126    case YYSTRONG0:
127        switch(strength1) {
128        case YYSUPPLY1:retval = Supply1Strong0; break;
129        case YYSTRONG1:retval = Strong1Strong0; break;
130        case YYPULL1:  retval = Pull1Strong0; break;
131        case YYWEAK1:  retval = Weak1Strong0; break;
132        case YYHIGHZ1: retval = HighZ1Strong0; break;
133        default: compile_error("illegal strength0/strength1");
134        }
135        break;
136    case YYPULL0:
137        switch(strength1) {
138        case YYSUPPLY1:retval = Supply1Pull0; break;
139        case YYSTRONG1:retval = Strong1Pull0; break;
140        case YYPULL1:  retval = Pull1Pull0; break;
141        case YYWEAK1:  retval = Weak1Pull0; break;
142        case YYHIGHZ1: retval = HighZ1Pull0; break;
143        default: compile_error("illegal strength0/strength1");
144        }
145        break;
146    case YYWEAK0:
147        switch(strength1) {
148        case YYSUPPLY1:retval = Supply1Weak0; break;
149        case YYSTRONG1:retval = Strong1Weak0; break;
150        case YYPULL1:  retval = Pull1Weak0; break;
151        case YYWEAK1:  retval = Weak1Weak0; break;
152        case YYHIGHZ1: retval = HighZ1Weak0; break;
153        default: compile_error("illegal strength0/strength1");
154        }
155        break;
156    case YYHIGHZ0:
157        switch(strength1) {
158        case YYSUPPLY1:retval = Supply1HighZ0; break;
159        case YYSTRONG1:retval = Strong1HighZ0; break;
160        case YYPULL1:  retval = Pull1HighZ0; break;
161        case YYWEAK1:  retval = Weak1HighZ0; break;
162        case YYHIGHZ1: retval = HighZ1HighZ0; break;
163        default: compile_error("illegal strength0/strength1");
164        }
165        break;
166    default: compile_error("illegal strength0/strength1");
167    }
168
169    return retval;
170}
171
172
173void insert_instances(lsList inst_list, void *inst_master)
174{
175    lsHandle handle;
176    extern int Warn_DuplicateInst;
177
178
179    if (vl_currentModule == NIL(vl_module)) {
180        compile_error("instantiate mod/prim/gate not within module");
181    } else {
182        lsGen gen;
183        typestruct *mpg;
184
185        for (gen = lsStart(inst_list);
186             lsNext(gen, (lsGeneric*)&mpg, &handle) != LS_NOMORE; ) {
187            if (((vl_mod_prim_inst*)mpg)->name) {
188                if (st_lookup(vl_currentModule->inst_st,
189                              ((vl_mod_prim_inst*)mpg)->name->name,
190                              (char**)&mpg)) {
191                    if (Warn_DuplicateInst) {
192                        char buf[MAXSTRLEN];
193                        sprintf(buf, "%s:%s:Duplicated instance name",
194                                vl_currentModule->name->name,
195                                ((vl_mod_prim_inst*)mpg)->name->name);
196                        Translate_Notice(buf);
197                    }
198                }
199                st_insert(vl_currentModule->inst_st,
200                          ((vl_mod_prim_inst*)mpg)->name->name, (char*)mpg);
201                ((vl_mod_prim_inst*)mpg)->name->mpg_master_exp = inst_master;
202            }
203        }
204        (void) lsFinish(gen);
205    }
206}
207
208
209void collect_latch(char *name)
210{
211    extern int rst_ckt;
212    extern int in_reset_stmt;
213    vl_id_range *id_sym, *latch_sym;
214    blif_latch *latch;
215    char latch_name[MAXSTRLEN];
216
217    if (!st_lookup(vl_currentModule->latch_st, name, (char**)&latch)) {
218        if (!st_lookup(vl_currentModule->sig_st, name, (char**)&id_sym)) {
219            char buf[MAXSTRLEN];
220
221            yylineno = -1;
222            sprintf(buf, "%s %s", name, "undefined and used as latch");
223            compile_error(buf);
224            id_sym = vl_create_id_range(name, NIL(vl_range));
225            st_insert(vl_currentModule->sig_st, name, (char*)id_sym);
226        }
227        sprintf(latch_name, "%s%s", name, SEP_LATCH);
228        latch_sym = vl_copy_id_range(id_sym);
229        latch_sym->flags = id_sym->flags;
230        latch_sym->syndrome_expr_list = lsCreate();
231        latch_sym->initial = lsCreate();
232        free(latch_sym->name);
233        latch_sym->name = vlStrdup(latch_name);
234        st_insert(vl_currentModule->sig_st,
235                  vlStrdup(latch_name), (char*)latch_sym);
236        latch = create_latch(id_sym, NIL(vl_term), NIL(vl_term));
237        latch->flags |= (rst_ckt || in_reset_stmt) ?
238            NBASSIGN_IN_INITIAL : NBASSIGN_IN_ALWAYS;
239        st_insert(vl_currentModule->latch_st, name, (char*)latch);
240    } else {
241        latch->flags |= (rst_ckt || in_reset_stmt) ?
242            NBASSIGN_IN_INITIAL : NBASSIGN_IN_ALWAYS;
243    }
244}
245
246
247void collect_quasi(char *name)
248{
249    vl_id_range *id_sym, *quasi_sym;
250    int dummy;
251    char quasi_name[MAXSTRLEN];
252
253    if (!st_lookup(vl_currentModule->quasi_st, name, (char**)&dummy)) {
254        if (!st_lookup(vl_currentModule->sig_st, name, (char**)&id_sym)) {
255            char buf[MAXSTRLEN];
256
257            yylineno = -1;
258            sprintf(buf,
259                "%s undefined and used as lhs of quasi-continuous assignment",
260                    name);
261            compile_error(buf);
262            id_sym = vl_create_id_range(name, NIL(vl_range));
263            st_insert(vl_currentModule->sig_st, name, (char*)id_sym);
264        }
265        sprintf(quasi_name, "%s%s", name, SEP_QUASI);
266        quasi_sym = vl_copy_id_range(id_sym);
267        quasi_sym->flags = id_sym->flags;
268        quasi_sym->syndrome_expr_list = lsCreate();
269        free(quasi_sym->name);
270        quasi_sym->name = vlStrdup(quasi_name);
271        st_insert(vl_currentModule->sig_st,
272                  vlStrdup(quasi_name), (char*)quasi_sym);
273        st_insert(vl_currentModule->quasi_st, name, (char*)0);
274    }
275}
276
277
278void extract_delay_strength(lsList delay_strength,
279                            vl_delay **delay,
280                            int *strength)
281{
282    int head, tail;
283
284    switch (lsLength(delay_strength)) {
285    case 0: break;
286    case 1:
287        lsFirstItem(delay_strength, (lsGeneric*)&head, 0);
288        if (head & LEAST_SB)
289            *delay = (vl_delay*)(head & (~LEAST_SB));
290        else
291            *strength = (head >> 2);
292        break;
293    case 2:
294        lsFirstItem(delay_strength, (lsGeneric*)&head, 0);
295        lsLastItem(delay_strength, (lsGeneric*)&tail, 0);
296        if (head & LEAST_SB || !(tail & LEAST_SB))
297            compile_error("mod/prim/gate illegal drive_strength | delay");
298        *strength = (head >> 2);
299        *delay = (vl_delay*)(tail & (~LEAST_SB));
300        break;
301    default: compile_error("too many drive_strength | delay");
302    }
303}
304
305
306void associate_symbolic_value(vl_lval *lval, vl_expr *expr)
307{
308    vl_id_range *id_sym;
309    char *mbody;
310    extern char last_macro[];
311    extern st_table *macros;
312
313    if (expr->type==IntExpr || expr->type==BitExpr)
314        if (*last_macro &&  lval->type!=ConcatExpr) {
315            if (st_lookup(vl_currentModule->sig_st,
316                          lval->name->name, (char**)&id_sym)) {
317                if (!st_lookup(id_sym->symbolic_values, last_macro, &mbody)) {
318                    st_lookup(macros, last_macro, &mbody);
319                    st_insert(id_sym->symbolic_values,
320                              vlStrdup(last_macro), vlStrdup(mbody));
321                }
322            }
323        }
324}
325
326
327void dup_info_var_in_st(st_table *vars)
328{
329    st_generator *gen;
330    char *key;
331    var_info *cur_var;
332
333    gen = st_init_gen(vars);
334    while (st_gen(gen, &key, (char**)&cur_var)) {
335        st_insert(vars, key, (char*)copy_var_info(cur_var));
336    }
337    st_free_gen(gen);
338}
339
340void reset_cond_list_in_st(st_table *vars)
341{
342    st_generator *gen;
343    char *key;
344    var_info *cur_var;
345
346    gen = st_init_gen(vars);
347    while (st_gen(gen, &key, (char**)&cur_var)) {
348        lsDestroy(cur_var->cond_list,0);
349        cur_var->cond_list = lsCreate();
350    }
351    st_free_gen(gen);
352}
353
354int data_width(vl_expr *expr)
355{
356    int retval = 0, v;
357
358    switch(expr->type) {
359    case IntExpr:
360        for (retval=0, v=expr->u.intval; v>0; v >>= 1) retval++;
361        break;
362    case RealExpr:
363        for (retval=0, v=(int)expr->u.realval; v>0; v >>= 1) retval++;
364        break;
365    case BitExpr: break;
366    }
367
368    return retval;
369}
370
371char *strappend(char *str1, char *str2)
372{
373    char *retval;
374    strcat(str1, str2);
375    retval = str1 + strlen(str2);
376    return retval;
377}
378
379char *strappendS(char *str1, char *str2)
380{
381    strcat(str1, str2);
382    strcat(str1, " ");
383    return (str1 + strlen(str2)+1);
384}
385
386char *WRT_BLIF_DC(FILE *file)
387{
388    char *retval;
389
390    retval = vlStrdup(new_termname());
391    fprintf(file, ".names %s\n-\n", retval);
392    return retval;
393}
394
395char *WRT_BLIF_MV_DC(FILE *file, lsList domain)
396{
397    char *retval;
398    lsGen enum_gen;
399    lsHandle enum_handle;
400    vl_enumerator *enum_elt;
401    int i;
402
403    retval = vlStrdup(new_termname());
404
405    fprintf(file, ".mv %s %d ", retval, lsLength(domain));
406    for (enum_gen=lsStart(domain), i=0;
407         lsNext(enum_gen,(lsGeneric*)&enum_elt,&enum_handle)!=LS_NOMORE;
408         i++) {
409        fprintf(file, "%s ", enum_elt->name);
410    }
411    lsFinish(enum_gen);
412    fprintf(file, "\n");
413
414    fprintf(file, ".names %s\n-\n", retval);
415    return retval;
416}
417
418char *WRT_BLIF_GND(FILE *file)
419{
420    char *retval;
421
422    retval = vlStrdup(new_termname());
423    fprintf(file, ".names %s\n", retval);
424    fprintf(file, "0\n");
425    return retval;
426}
427
428char *WRT_BLIF_SUP(file)
429FILE *file;
430{
431    char *retval;
432
433    retval = vlStrdup(new_termname());
434    fprintf(file, ".names %s\n", retval);
435    fprintf(file, "1\n");
436    return retval;
437}
438
439vl_term *true_term(file)
440FILE *file;
441{
442    vl_term *retval;
443
444    retval = vl_create_term(vl_create_id_range(vlStrdup(new_termname()),NIL(vl_range)),
445                               0, -1);
446    fprintf(file, ".names %s\n", retval->name->name);
447    fprintf(file, "1\n");
448    return retval;
449}
450
451vl_term *false_term(file)
452FILE *file;
453{
454    vl_term *retval;
455
456    retval = vl_create_term(vl_create_id_range(vlStrdup(new_termname()),NIL(vl_range)),
457                               0, -1);
458    fprintf(file, ".names %s\n", retval->name->name);
459    fprintf(file, "0\n");
460    return retval;
461}
462
463int ptrcmp(ptr1, ptr2)
464const char *ptr1;
465const char *ptr2;
466{
467    if (ptr1==ptr2) return 0;
468    if (ptr1 < ptr2) return -1;
469    if (ptr1 > ptr2) return 1;
470
471    return 0;
472}
473
474int ptrhash(key, modulus)
475char *key;
476int modulus;
477{
478    return ((int)key % modulus);
479}
480
481
482int declcmp(char *ptr1, char *ptr2)
483{
484    int l1, l2;
485    int r1, r2;
486
487    l1 = vl_eval_expr(get_decl_range_left(ptr1));
488    r1 = vl_eval_expr(get_decl_range_right(ptr1));
489    l2 = vl_eval_expr(get_decl_range_left(ptr2));
490    r2 = vl_eval_expr(get_decl_range_right(ptr2));
491
492    if (l1==l2 && r1==r2)
493        return 0;
494    else
495        return 1;
496}
497
498int declhash(key, modulus)
499char *key;
500int modulus;
501{
502    return ((int)key % modulus);
503}
504
505int str_matchtail(char *str, char *pat)
506{
507    char *cp;
508
509    if (strlen(str) < strlen(pat)) return 0;
510
511    cp = &str[strlen(str)-strlen(pat)];
512    return !strcmp(cp, pat);
513}
514
515char *strip_char (str, ch)
516char *str;
517char *ch;
518{
519    char *cp;
520
521    if (strlen(str) >= strlen(ch)) {
522        cp = &str[strlen(str)-strlen(ch)];
523        if (!strcmp(cp,ch)) *cp = '\0';
524    }
525    return str;
526}
527
528FILE *open_file(name, mode)
529char *name;
530char *mode;
531{
532    FILE *retval;
533
534    retval = fopen(name, mode);
535    if (!retval) {
536        char msg[MAXSTRLEN];
537
538        sprintf(msg, "can't open file %s", name);
539        chk_error(msg);
540    }
541    return retval;
542}
543
544void close_file(file)
545FILE *file;
546{
547    fclose(file);
548}
549
550char *num_to_binstr(num, width)
551int num, width;
552{
553    static char retval[MAXSTRLEN];
554    int i;
555
556    for (i=0; i<width; i++) {
557        retval[width-i-1] = (char)('0'+(num & 1));
558        num = (num >> 1);
559    }
560    retval[width] = '\0';
561
562    return retval;
563}
564
565
566int min_bit_width(a)
567int a;
568{
569    int retval;
570    int largest_num;
571
572
573    for (retval=1, largest_num=1;
574         largest_num < a;
575         largest_num = (largest_num << 1) | 1) retval++;
576
577    return retval;
578}
579
580
581st_table *st_union(st1, st2)
582st_table *st1;
583st_table *st2;
584{
585    st_generator *gen;
586    char *key;
587    var_info *vinfo, *vinfo1;
588
589    gen = st_init_gen(st2);
590    while (st_gen(gen, &key, (char**)&vinfo)) {
591        if (!st_lookup(st1, key, (char**)&vinfo1)) {
592            st_insert(st1, key, (char*)vinfo);
593        }
594    }
595    st_free_gen(gen);
596
597    return st1;
598}
599
600
601char *sys_lib_encode(type, widthi, widtho)
602int type;
603int widthi, widtho;
604{
605    static char retval[MAXSTRLEN];
606
607    if (type == LIBplus || type == LIBminus) {
608        sprintf(retval, "%s%s_%d_%d", HSIS_LIB_HEADER, SYS_LIB_NAME(type),
609                widthi, widtho);
610    } else {
611        sprintf(retval, "%s%s_%d", HSIS_LIB_HEADER,SYS_LIB_NAME(type),widthi);
612    }
613    return retval;
614}
615
616
617char *lib_encode(type, width)
618int type;
619int width;
620{
621    static char retval[MAXSTRLEN];
622
623    sprintf(retval, "%s%d", LIB_NAME(type), width);
624    return retval;
625}
626
627
628char *gen_lib_encode(type, args)
629int type;
630lsList args;
631{
632    static char retval[MAXSTRLEN];
633    char *arg;
634    int i;
635    lsGen gen;
636    lsHandle handle;
637
638    sprintf(retval, "%s%s", LIB_NAME(type), SEP_LTRANGE);
639    for (gen=lsStart(args), i=0;
640         lsNext(gen,(lsGeneric*)&arg,&handle)!=LS_NOMORE; i++) {
641        strcat(retval, arg);
642        if (i < lsLength(args)-1) strcat(retval, SEP_GATEPIN);
643    }
644    strcat(retval, SEP_RTRANGE);
645    lsFinish(gen);
646    return retval;
647}
648
649
650int ipower(base, power)
651int base;
652int power;
653{
654    register int i, retval;
655
656    for (retval=1, i=0; i<power; i++)
657        retval *= base;
658
659    return retval;
660}
661
662
663void chk_mp_definitions(st_table *undefined)
664{
665    if (st_count(undefined)>0) {
666        st_generator *gen;
667        char *key;
668        vl_id_range *id_sym;
669
670        gen = st_init_gen(undefined);
671        while (st_gen(gen, &key, (char**)&id_sym)) {
672            fprintf(stderr, "undefined module/primitive: %s\n", key);
673        }
674        st_free_gen(gen);
675        vl_exit(1);
676    }
677}
678
679
680char *basename(filename)
681char *filename;
682{
683    char *retval;
684    int i;
685
686    retval = vlStrdup(filename);
687    for (i=strlen(retval)-1; i>0 && retval[i] != '/'; i--)
688        if (retval[i] == '.') {
689            retval[i]='\0';
690            break;
691        }
692    return retval;
693}
694
695
696char *extname(char *filename)
697{
698    char *retval;
699
700    retval = vlStrdup(filename);
701    return retval;
702}
703
704
705int gcd(int u, int v)
706{
707    int t;
708    while (u > 0) {
709        if (u < v) {
710            t = u; u = v; v = t;
711        }
712        u = u-v;
713    }
714    return v;
715}
716
717
718int lcm(int u, int v)
719{
720    return ( u * v / gcd(u,v));
721}
Note: See TracBrowser for help on using the repository browser.