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