Subversion Repositories Vertical

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 mjames 1
/* generics.c */
2
/* contains the database functions for lookup of generic information  */
3
/*
4
 * $Header: c:\\cygwin\\cvsroot/Vert03/vertlib/generic.c,v 1.1.1.1 2003/11/04 23:34:57 mjames
5
 * Exp $ $Log: generic.c,v $ Revision 1.1.1.1  2003/11/04 23:34:57  mjames Imported into local
6
 * repositrory
7
 *
8
 * Revision 1.15  2002/09/30 13:27:43  MJAMES
9
 * Created function to tidy up partition generics.
10
 *
11
 * Revision 1.14  2002/09/18 08:51:33  mjames
12
 * Removed unused variables
13
 *
14
 * Revision 1.13  2002/09/09 10:27:53  mjames
15
 * Removed set generic range and replaced it with a set generic value command
16
 * that takes both integers and ranges.
17
 *
18
 * Revision 1.12  2002/01/15 12:35:23  mjames
19
 * DLL declarations put in
20
 *
21
 * Revision 1.11  2001/12/14 15:01:39  mjames
22
 * Removed unecessary 'generic_waste' function
23
 *
24
 * Revision 1.10  2001/12/13 22:20:11  mjames
25
 * Using #ident with header to identify file
26
 *
27
 * Corrected GENERIC MAP printout (partially !)
28
 *
29
 * Revision 1.9  2001/11/19 10:41:51  mjames
30
 * Merged back DTC release
31
 *
32
 * Revision 1.8.2.1  2001/11/16 15:06:57  mjames
33
 * Corrected an error in the return value of a function
34
 *
35
 * Revision 1.8  2001/11/01 11:05:32  mjames
36
 * Printing a list of generic definitiions for ACFP files: case
37
 * for handling integer constants was omitted.
38
 *
39
 * Revision 1.7  2001/10/31 22:20:07  mjames
40
 * Tidying up problematical comments caused by CVS
41
 * 'intelligent' comment guessing
42
 *
43
 * Revision 1.6  2001/10/22 10:59:57  mjames
44
 * Added IS_ATTRIBUTE : a generic attribute used for controlling VERTICAL.
45
 * Can have either string or expression here.
46
 *
47
 * Revision 1.5  2001/06/06 12:10:21  mjames
48
 * Move from HPUX
49
 *
50
 * Revision 1.4  2001/04/09 14:58:29  mjames
51
 * Added capability to delete generics from specific sockets.
52
 *
53
 * Revision 1.3  2001/04/06 22:47:02  mjames
54
 * Added doc2, the creator of documentation to Vertical scripts uses PERL
55
 *
56
 *
57
 * Also correcting generic behaviour and the printing of Verilog.
58
 *
59
 * Revision 1.2  2000/11/29 21:51:18  mjames
60
 * Fine tuning of software
61
 *
62
 * Revision 1.1.1.1  2000/10/19 21:58:38  mjames
63
 * Mike put it here
64
 *
65
 *
66
 * Revision 1.28  2000/10/12  15:32:26  15:32:26  mjames (Mike James)
67
 * Removed <cr>
68
 *
69
 * Revision 1.27  2000/10/04  10:37:06  10:37:06  mjames (Mike James)
70
 * Modified for Vertical2 : support COMPONENTS and SIGNALS
71
 *
72
 * Revision 1.27  2000/10/04  10:37:06  10:37:06  mjames (Mike James)
73
 * Part of Release PSAVAT01
74
 *
75
 * Revision 1.26  2000/10/02  11:04:14  11:04:14  mjames (Mike James)
76
 * new_vhdl
77
 *
78
 * Revision 1.25  2000/09/27  14:42:15  14:42:15  mjames (Mike James)
79
 * Part of Release Sep_27_ST_2000
80
 *
81
 * Revision 1.24  2000/09/27  10:45:43  10:45:43  mjames (Mike James)
82
 * Started using the g_class member of the generic structue
83
 *
84
 * Revision 1.23  2000/09/21  10:15:45  10:15:45  mjames (Mike James)
85
 * Part of Release Sep21Alpha
86
 *
87
 * Revision 1.22  2000/08/25  09:57:12  09:57:12  mjames (Mike James)
88
 * Part of Release Aug25_alpha
89
 *
90
 * Revision 1.21  2000/08/16  08:57:28  08:57:28  mjames (Mike James)
91
 * Part of Release CD01_Aug2000
92
 *
93
 * Revision 1.20  2000/08/14  14:45:09  14:45:09  mjames (Mike James)
94
 * Part of Release Aug_14_2000
95
 *
96
 * Revision 1.19  2000/08/11  08:30:30  08:30:30  mjames (Mike James)
97
 * Part of Release Aug_11_2000
98
 *
99
 * Revision 1.18  2000/08/09  10:31:44  10:31:44  mjames (Mike James)
100
 * Part of Release Aug__9_2000
101
 *
102
 * Revision 1.17  2000/05/31  11:42:53  11:42:53  mjames (Mike James)
103
 * Part of Release May_31_2000
104
 *
105
 * Revision 1.16  2000/05/08  17:01:35  17:01:35  mjames (Mike James)
106
 * Part of Release May__8_2000
107
 *
108
 * Revision 1.15  2000/05/08  16:59:28  16:59:28  mjames (Mike James)
109
 * Part of Release May__8_2000
110
 *
111
 * Revision 1.14  2000/05/08  16:57:05  16:57:05  mjames (Mike James)
112
 * Part of Release May__8_2000
113
 *
114
 * Revision 1.13  2000/03/08  16:19:08  16:19:08  mjames (Mike James)
115
 * New version including PC
116
 *
117
 * Revision 1.10  2000/01/20  15:58:44  15:58:44  mjames (Mike James)
118
 * Part of Release R22
119
 *
120
 * Revision 1.9  99/12/22  11:15:25  11:15:25  mjames (Mike James)
121
 * Part of Release Dec_22_1999
122
 *
123
 * Revision 1.8  99/11/23  13:52:05  13:52:05  mjames (Mike James)
124
 * Addded syntax to support special generics for Certify support
125
 *
126
 * Revision 1.7  99/06/25  14:35:35  14:35:35  mjames (Mike James)
127
 * Added in reference to expression.h, but no changes made
128
 * to the function of acfread yet.
129
 *
130
 * Revision 1.6  99/06/18  09:24:17  09:24:17  mjames (Mike James)
131
 * Added new VHDL printing of generic information
132
 *
133
 * Revision 1.5  99/05/04  09:51:21  09:51:21  mjames (Mike James)
134
 * Amended generic lookup rules
135
 *
136
 * Revision 1.4  98/08/12  14:20:50  14:20:50  mjames (Mike James)
137
 * removed bug in generic lookup.
138
 *
139
 * Revision 1.3  98/07/14  13:24:16  13:24:16  mjames (Mike James)
140
 * fixed errors in lookup of generic variables -
141
 * now works better
142
 *
143
 * Revision 1.2  98/03/16  11:37:09  11:37:09  mjames (Mike James)
144
 * Updated generic storage and lookup
145
 *
146
 * Revision 1.1  98/02/11  11:26:11  11:26:11  mjames (Mike James)
147
 * Initial revision
148
 *
149
 */
150
#include "generic.h"
151
 
152
#include "cmdlog.h"
153
#include "cmdparse.h"
154
#include "database.h"
155
#include "expression.h"
156
#include "vertcl_main.h"
157
 
158
#include <ctype.h>
159
#include <stdio.h>
160
#include <stdlib.h>
161
#include <string.h>
162
/* this is included regardless of the translator being built */
163
#include "acf_yacc.h"
164
 
165
#ident                                                                                        \
166
    "@(#)$Header: c:\\cygwin\\cvsroot/Vert03/vertlib/generic.c,v 1.1.1.1 2003/11/04 23:34:57 mjames Exp $"
167
 
168
generic_info_t *global_generics = NULL; /* list of user set generics */
169
 
170
generic_info_t *partition_generics = NULL; /* list of all unique generic names found on
171
                                              entities within a partition */
172
/* This function converts an integer value expressed in a number base
173
   e.g. 2_1010110 binary
174
        16_0xf002 hex
175
        3234      decimal */
176
int convert_num (char *string, int *value)
177
{
178
        char *endptr;
179
        int base;
180
        long val;
181
        /* identify numbers like base_nnnnnn */
182
        if (isdigit (string[0]))
183
        {
184
                val = strtol (string, &endptr, 10);
185
                if (*endptr == '_')
186
                {
187
                        base = (int) val;
188
                        endptr++;
189
                        val = (int) strtol (endptr, &endptr, base);
190
                }
191
                *value = (int) val;
192
                return 1; /* success */
193
        }
194
        else
195
        {
196
                /*    *value = 1; */
197
                return 0; /* fail */
198
        }
199
}
200
 
201
__declspec(dllexport) generic_type_t
202
    get_generic_value (generic_info_t **list, char *string, generic_info_t *result)
203
{
204
        generic_info_t *ptr;
205
        int val;
206
 
207
        if (list)
208
                ptr = *list;
209
 
210
        result->g_type = NO_VALUE; /* Unknown information */
211
        /* identify numbers like base_nnnnnn */
212
        if (convert_num (string, &val) == 1)
213
        {
214
                result->g_type = IS_INTEGER;
215
                result->expr = compile_constant (val);
216
        }
217
        else
218
        {
219
                /* look up name and see if it has an integer value */
220
                while (ptr)
221
                {
222
                        if (strcmp2 (ptr->name, string) == 0)
223
                                break;
224
                        ptr = ptr->next;
225
                }
226
                if (ptr)
227
                {
228
                        /*      printf("%s : found value = %d\n",string,ptr->value); */
229
                        *result = *ptr;
230
                        /*      printf("%s : found value = %s\n",string,ptr->name); */
231
                }
232
                /* check to see if the string returned is valid in future at this point */
233
        }
234
#if defined DEBUG_EXPRESSION
235
        if (ptr)
236
                printf ("GET %s %p looked up\n", ptr->name, ptr);
237
#endif
238
        return result->g_type;
239
}
240
 
241
__declspec(dllexport) generic_info_t *get_generic_ref (generic_info_t **list, char *string)
242
{
243
        generic_info_t *ptr;
244
        if (list)
245
        {
246
                ptr = *list;
247
        }
248
        else
249
        {
250
                return NULL;
251
        }
252
        /* look up name and see if it has an integer value */
253
        while (ptr)
254
        {
255
                if (strcmp2 (ptr->name, string) == 0)
256
                        break;
257
#if defined DEBUG_EXPRESSION
258
                if (ptr)
259
                        printf ("REF %s %p looked up\n", ptr->name, ptr);
260
#endif
261
                ptr = ptr->next;
262
        }
263
 
264
#if defined DEBUG_EXPRESSION
265
        if (ptr)
266
                printf ("REF %s %p looked up\n", ptr->name, ptr);
267
#endif
268
        return ptr;
269
}
270
 
271
/* this function makes a copy of the generic passed to it */
272
/* but it cannot make a copy of the expression because it
273
 * requires knowledge of whether this generic is local to
274
 * a component instance or global : this is done by the caller
275
 */
276
__declspec(dllexport)
277
    generic_info_t *set_generic_value (generic_info_t **list, generic_info_t *info)
278
{
279
        generic_info_t *ptr, *prev;
280
 
281
        prev = NULL;
282
        if (list)
283
                ptr = *list;
284
        else
285
                return NULL;
286
 
287
        while (ptr)
288
        {
289
                if (strcmp2 (ptr->name, info->name) == 0)
290
                        break;
291
                prev = ptr;
292
                ptr = ptr->next;
293
        }
294
 
295
        /* there is no existing generic of the appropriate name */
296
 
297
        if (!ptr)
298
        {
299
                ptr = calloc (1, sizeof (generic_info_t));
300
                if (!prev)
301
                        *list = ptr;
302
                else
303
                        prev->next = ptr;
304
                ptr->next = NULL;
305
                ptr->expr_ref = NULL;
306
                ptr->is_component_generic =
307
                    info->is_component_generic; /* allows me to find which list defined on */
308
                ptr->name = allocstr (info->name);
309
        }
310
        else
311
        {
312
                /*    free(ptr->typename);  */
313
                /*    free(ptr->valuename); */
314
        }
315
        if (ptr)
316
        {
317
#if defined DEBUG_EXPRESSION
318
                printf ("SET %s %p assign '", info->name, ptr);
319
                print_expression (stdout, info->expr, 0);
320
                printf ("'=%d was '", eval_expression (info->expr, list));
321
                print_expression (stdout, ptr->expr, 0);
322
                printf ("'\n");
323
#endif
324
                ptr->typename = allocstr (info->typename);
325
 
326
                ptr->valid = 0;
327
                ptr->expr = info->expr;
328
                ptr->g_type = info->g_type;
329
                ptr->g_class = info->g_class;
330
        }
331
        return ptr;
332
}
333
 
334
/* new delete generic call is used to clean up databases */
335
__declspec(dllexport) int del_generic_value (generic_info_t **list, generic_info_t *info)
336
{
337
        generic_info_t *ptr, *prev = NULL;
338
 
339
        if (list)
340
                ptr = *list;
341
        else
342
                return 1;
343
 
344
        while (ptr)
345
        {
346
                if (strcmp2 (ptr->name, info->name) == 0)
347
                        break;
348
                prev = ptr;
349
                ptr = ptr->next;
350
        }
351
 
352
        if (!ptr)
353
                return 1;
354
 
355
        /* we have found a generic of the appropriate name and now
356
         * it will be deleted. We cannot remove any of the expressions
357
         * or strings used as they may be shared if they were declared
358
         * with the use of a wildcard assignment. Pay the price
359
         * of a potential memory leak here ....  */
360
 
361
        if (prev)
362
                prev->next = ptr->next;
363
        else
364
                *list = ptr->next;
365
 
366
        free (ptr); /* we can be sure this is unique however */
367
 
368
        return 0;
369
}
370
 
371
#define MAXINDENT 8
372
 
373
static char linebuff[MAXIDLEN];
374
 
375
static char *escape_quote (char *str)
376
{
377
        char *f = str, *t = linebuff;
378
        while (*f)
379
        {
380
                if (*f == '\"' || *f == '\\')
381
                        *t++ = '\\';
382
                *t++ = *f++;
383
        }
384
        *t = 0;
385
        return linebuff;
386
}
387
 
388
__declspec(dllexport) void list_generic_values (FILE *f, generic_info_t **list, int indent)
389
{
390
        generic_info_t *ptr;
391
        int i;
392
        char indents[MAXINDENT + 1];
393
 
394
        if (list)
395
                ptr = *list;
396
        else
397
                ptr = NULL;
398
        /* build up the line of indents */
399
        for (i = 0; (i < indent) && (i < MAXINDENT); indents[i++] = ' ')
400
                ;
401
        indents[indent] = 0;
402
 
403
        fprintf (f, "%sGENERIC -- Generic constants \n", indents);
404
        while (ptr)
405
        {
406
                char *string = NULL;
407
                if (ptr->expr)
408
                        string = ptr->expr->left.s; /* pickup string for future use */
409
                fprintf (f, "%s  %-20s : ", indents, ptr->name); /* print its name */
410
 
411
                switch (ptr->g_type)
412
                {
413
                case NO_VALUE:
414
                case IS_STRING:
415
                case IS_ENV_VAL:
416
                        fprintf (
417
                            f,
418
                            " %-10s      := \"%s\"",
419
                            ptr->typename ? ptr->typename : "",
420
                            string ? escape_quote (string) : "");
421
                        break;
422
                case IS_ATTRIBUTE:
423
                        fprintf (f, " attribute      ");
424
                        if (ptr->g_class == DEFINED)
425
                        {
426
                                fprintf (f, " := ");
427
                                print_expression (f, ptr->expr, 0);
428
                        }
429
                        break;
430
                case IS_BOOLEAN:
431
                        fprintf (f, " boolean        ");
432
                        if (ptr->g_class == DEFINED)
433
                        {
434
                                fprintf (f, " := ");
435
                                print_expression (f, ptr->expr, 0);
436
                        }
437
                        break;
438
                case IS_INTEGER:
439
                        fprintf (f, " integer   ");
440
                        if (ptr->g_class == DEFINED)
441
                        {
442
                                fprintf (f, " := ");
443
                                print_expression (f, ptr->expr, 0);
444
                        }
445
                        break;
446
                case TO:
447
                case DOWNTO:
448
                        fprintf (f, " integer range  ");
449
                        if (ptr->g_class == DEFINED)
450
                        {
451
                                fprintf (f, " := ");
452
                                print_range_expression (f, ptr->expr, 0);
453
                        }
454
                        break;
455
 
456
                case IS_DECLARATION_DIRECTIVE:
457
                        if (!ISNULLSTR (string))
458
                                fprintf (f, " declaration  :=  \"%s\"", escape_quote (string));
459
                        else
460
                                fprintf (f, " declaration");
461
                        break;
462
                case IS_INSTANCE_DIRECTIVE:
463
                        if (!ISNULLSTR (string))
464
                                fprintf (f, " instance     :=  \"%s\"", escape_quote (string));
465
                        else
466
                                fprintf (f, " instance");
467
                        break;
468
                };
469
 
470
                if (ptr->next)
471
                        fprintf (f, ";\n");
472
                ptr = ptr->next;
473
        }
474
        fprintf (f, "\n%sEND;\n\n", indents);
475
}
476
 
477
__declspec(dllexport) void list_VHDL_generic_map_values (FILE *f, generic_info_t **list)
478
{
479
        generic_info_t *ptr = *list;
480
        if (ptr)
481
        {
482
                fprintf (f, "-- Generic constants\n");
483
                fprintf (f, " GENERIC MAP  ( \n");
484
        }
485
        while (ptr)
486
        {
487
                /* only integer and string generic constants OK */
488
                switch (ptr->g_type)
489
                {
490
                case IS_STRING:
491
                case IS_INTEGER:
492
                case IS_BOOLEAN:
493
                        fprintf (f, "    %-10s => ", ptr->name ? ptr->name : "");
494
                        print_expression (f, ptr->expr, 0);
495
                        break;
496
                default:
497
                        fprintf (f, "--  %-10s", ptr->name ? ptr->name : "");
498
                        break;
499
                }
500
 
501
                if (ptr->next)
502
                        fprintf (f, ",\n");
503
                else
504
                        fprintf (f, "\n    )\n"); /* no closing semi on GENERIC MAP */
505
                ptr = ptr->next;
506
        }
507
}
508
 
509
/********************************************************************/
510
__declspec(dllexport) int print_VHDL_constant (
511
    FILE *f, char *s, generic_info_t *ptr, generic_print_style recurse_generics)
512
{
513
        expression_t *exp;
514
        if (!ptr)
515
                return 0;
516
        exp = ptr->expr;
517
 
518
        if (exp)
519
        {
520
                switch (ptr->g_type)
521
                {
522
                case TXT_STRING:
523
                        fprintf (f, " %s  %-20s : string  := ", s, ptr->name);
524
                        print_expression (f, exp, recurse_generics);
525
                        return 1;
526
                        break;
527
                case TO:
528
                case DOWNTO:
529
                        fprintf (f, " %s  %-20s : integer range:= ", s, ptr->name);
530
                        print_range_expression (f, exp, recurse_generics);
531
                        return 1;
532
                        break;
533
 
534
                case IS_INTEGER:
535
                        fprintf (f, " %s  %-20s : integer:= ", s, ptr->name);
536
                        print_expression (f, exp, recurse_generics);
537
                        return 1;
538
                        break;
539
                case IS_BOOLEAN:
540
                        fprintf (f, " %s  %-20s : boolean:= ", s, ptr->name);
541
                        print_expression (f, exp, recurse_generics);
542
                        return 1;
543
                        break;
544
                default:
545
                        return 0;
546
                        /* nothing */
547
                };
548
        }
549
        return 0;
550
}
551
 
552
/********************************************************************/
553
__declspec(dllexport) void list_VHDL_generic_values (FILE *f, generic_info_t **list)
554
{
555
        generic_info_t *ptr;
556
        int printed;
557
        ptr = *list;
558
 
559
        if (ptr)
560
        {
561
                fprintf (f, "-- Generic constants\n");
562
                fprintf (f, "  GENERIC  ( \n");
563
        }
564
        printed = 0;
565
        while (ptr)
566
        {
567
                if (printed)
568
                        fprintf (f, ";\n");
569
                printed = print_VHDL_constant (f, "", ptr, 0);
570
                ptr = ptr->next;
571
        }
572
        if (*list)
573
                fprintf (f, ");\n"); /*  closing semi on GENERIC */
574
}
575
/********************************************************************/
576
void list_VHDL_constants (FILE *f, generic_info_t **list)
577
{
578
        generic_info_t *ptr = *list;
579
 
580
        while (ptr)
581
        { /* recursively expand generics to the full expression */
582
                if (print_VHDL_constant (f, "   CONSTANT ", ptr, 1))
583
                        fprintf (f, ";\n");
584
                ptr = ptr->next;
585
        }
586
        fprintf (f, "\n");
587
}
588
/********************************************************************/
589
/* this was used before CONSTANTS were used. Keeping it because it
590
 * will be useful when name spaces are properly implemented : if there
591
 * are any unresolved global generics then partition generics should be
592
 * created
593
 */
594
 
595
/********************************************************************/
596
 
597
void setup_generic_types (generic_info_t *list)
598
{
599
        generic_info_t *ptr = list;
600
        /* invalidate all values */
601
        while (ptr)
602
        {
603
                ptr->valid = 0;
604
                ptr = ptr->next;
605
        }
606
        ptr = list;
607
        while (ptr)
608
        {
609
                if (!ptr->valid)
610
                {
611
                        /* this simply does type extraction from the expression
612
                           component now */
613
                        eval_gen_expression (ptr);
614
                }
615
                ptr->valid = 1;
616
                ptr = ptr->next;
617
        }
618
}
619
 
620
/* if a generic has an expression which is a string or integer constant,
621
   transfer it to the other list */
622
void transfer_constant_generics (generic_info_t **src, generic_info_t **dst)
623
{
624
        generic_info_t *prev, *curr, *next;
625
        prev = NULL;
626
        curr = *src;
627
 
628
        while (curr)
629
        {
630
                expression_t *exp;
631
                exp = curr->expr;
632
                next = curr->next; /* remember the next pointer for later */
633
                if (exp && (exp->opcode == EXP_STRING || exp->opcode == EXP_CONSTANT))
634
                {
635
                        if (prev)
636
                                prev->next = curr->next; /* link over it */
637
                        if (curr == *src) /* if was first element of list, set head to next */
638
                                *src = curr->next;
639
                        curr->next = *dst; /* link to old head of destination list */
640
                        *dst = curr;       /* place on head of destination list */
641
                }
642
                else
643
                        prev = curr; /* only move on prev if we have not removed curr..*/
644
                curr = next;
645
        }
646
}
647
 
648
extern void clear_partition_generics (generic_info_t **list)
649
{
650
        generic_info_t *ptr, *prev_ptr;
651
        expr_ref_t *refs, *prev_refs;
652
        ptr = *list;
653
        while (ptr)
654
        {
655
                prev_ptr = ptr;
656
                refs = ptr->expr_ref;
657
                while (refs)
658
                {
659
                        prev_refs = refs;
660
                        if (refs->expr)
661
                        {
662
                                refs->expr->opcode = EXP_UNDEF_VAR;
663
                                refs->expr->left.g = NULL;
664
                        }
665
                        refs = refs->expr_ref;
666
                        free (prev_refs);
667
                };
668
                ptr = ptr->next;
669
                free (prev_ptr);
670
        };
671
        *list = NULL;
672
}
673
 
674
/* compute the values of all expressions */
675
 
676
void elaborate_all (void)
677
{
678
        socket_t *socket;
679
 
680
        printf ("elaborate\n");
681
        setup_generic_types (global_generics);
682
        setup_generic_types (partition_generics);
683
        transfer_constant_generics (&global_generics, &partition_generics);
684
        socket = socket_head;
685
        while (socket)
686
        {
687
                setup_generic_types (socket->generics);
688
                socket = socket->next;
689
        }
690
}
691
 
692
void copy_declaration_generics (socket_t *skt, socket_t *from)
693
{
694
        generic_info_t *src;
695
 
696
        /*  puts("copy_declaration_generics"); */
697
        src = from->generics;
698
        while (src)
699
        {
700
                if (get_generic_ref (&skt->generics, src->name))
701
                        set_generic_value (&(skt->generics), src);
702
                src = src->next;
703
        }
704
        src = skt->unrouted_generics;
705
        while (src)
706
        {
707
                if (get_generic_ref (&skt->generics, src->name))
708
                        set_generic_value (&(skt->generics), src);
709
                src = src->next;
710
        }
711
        puts ("done declaration generics");
712
}