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 structu[re |
||
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 | } |