1 /* attributes
2
3 Copyright (C) 1994-1997 University of Dortmund
4 Department of Electrical Engineering, AG SIV
5
6 VAUL is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Library General Public License as
8 published by the Free Software Foundation; either version 2 of the
9 License, or (at your option) any later version.
10
11 VAUL is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General
14 Public License for more details.
15
16 You should have received a copy of the GNU Library General Public
17 License along with VAUL; see the file COPYING.LIB. If not, write
18 to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
19 Boston, MA 02111-1307 USA.
20
21
22 */
23
24 #include <freehdl/vaul-parser.h>
25 #include <freehdl/vaul-chunk.h>
26 #include <freehdl/vaul-dunit.h>
27 #include <freehdl/vaul-util.h>
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <assert.h>
32
33 #define psr vaul_parser
34
35 enum attr_id {
36
37 // type prefix
38 ai_BASE, ai_IMAGE, ai_VALUE, ai_POS, ai_VAL, ai_SUCC, ai_PRED,
39 ai_LEFTOF, ai_RIGHTOF,
40
41 // type or array prefix
42 ai_LEFT, ai_RIGHT, ai_HIGH, ai_LOW, ai_ASCENDING,
43 ai_RANGE, ai_REVERSE_RANGE, ai_LENGTH,
44
45 // signal prefix
46 ai_DELAYED, ai_STABLE, ai_QUIET, ai_TRANSACTION, ai_EVENT,
47 ai_ACTIVE, ai_LAST_EVENT, ai_LAST_ACTIVE, ai_LAST_VALUE,
48 ai_DRIVING, ai_DRIVING_VALUE,
49
50 // named entity prefix
51 ai_SIMPLE_NAME, ai_INSTANCE_NAME, ai_PATH_NAME,
52
53 ai_MAX
54 };
55
56 #define AI_FIRST_TYPE ai_BASE
57 #define AI_LAST_TYPE ai_RIGHTOF
58 #define AI_FIRST_T_OR_A ai_LEFT
59 #define AI_LAST_T_OR_A ai_LENGTH
60 #define AI_FIRST_TA AI_FIRST_TYPE
61 #define AI_LAST_TA AI_LAST_T_OR_A
62 #define AI_FIRST_SIGNAL ai_DELAYED
63 #define AI_LAST_SIGNAL ai_DRIVING_VALUE
64 #define AI_FIRST_ENTITY ai_SIMPLE_NAME
65 #define AI_LAST_ENTITY ai_PATH_NAME
66
67 static const char *attr_name[] = {
68 "BASE", "IMAGE", "VALUE", "POS", "VAL", "SUCC", "PRED",
69 "LEFTOF", "RIGHTOF",
70
71 "LEFT", "RIGHT", "HIGH", "LOW", "ASCENDING",
72
73 "RANGE", "REVERSE_RANGE", "LENGTH",
74
75 "DELAYED", "STABLE", "QUIET", "TRANSACTION", "EVENT",
76 "ACTIVE", "LAST_EVENT", "LAST_ACTIVE", "LAST_VALUE",
77 "DRIVING", "DRIVING_VALUE",
78
79 "SIMPLE_NAME", "INSTANCE_NAME", "PATH_NAME"
80 };
81
82
83 pIIR
build_AttrNode(pVAUL_Name n,vaul_decl_set * set,IR_Kind basic_k)84 psr::build_AttrNode (pVAUL_Name n, vaul_decl_set *set, IR_Kind basic_k)
85 {
86 if (n->is(VAUL_ATTRIBUTE_NAME))
87 return build_AttrNode (pVAUL_AttributeName(n), set, basic_k);
88
89 if(n == set->name && tree_is (basic_k, IR_TYPE_DECLARATION))
90 {
91 pIIR_Declaration d = set->single_decl ();
92 delete set;
93 assert (d->is(IR_TYPE_DECLARATION));
94 return pIIR_TypeDeclaration(d)->type;
95 }
96
97 return build_Expr (n, set, basic_k);
98 }
99
100 pIIR
build_AttrNode(pVAUL_AttributeName n,vaul_decl_set * set,IR_Kind basic_k)101 psr::build_AttrNode (pVAUL_AttributeName n, vaul_decl_set *set, IR_Kind basic_k)
102 {
103 pIIR_Expression p = NULL;
104 bool too_many = false;
105 if (n->first_actual)
106 {
107 if (n->first_actual->next)
108 too_many = true;
109 if (n->first_actual->formal)
110 error ("%:attribute arguments do not have names", n);
111 p = n->first_actual->actual;
112 }
113
114 attr_id ai = ai_MAX;
115 for (int i = 0; i < ai_MAX; i++)
116 if(vaul_name_eq(n->attribute, attr_name[i]))
117 {
118 ai = attr_id(i);
119 break;
120 }
121
122 pIIR res = NULL;
123
124 if (ai >= AI_FIRST_TA && ai <= AI_LAST_TA)
125 {
126 pIIR pfx = build_AttrNode (n->prefix, set, basic_k);
127 if (pfx == NULL)
128 return NULL;
129
130 // T is the type we are talking about.
131 // BT is the base type of T
132 // E is an expression denoting the original prefix, or NULL
133 // when the prefix was T itself.
134
135 pIIR_Type t = NULL, base_t = NULL;
136 pIIR_Expression e = NULL;
137
138 if (pfx->is(IR_EXPRESSION))
139 {
140 e = pIIR_Expression(pfx);
141 overload_resolution (e, NULL, IR_TYPE, false, false);
142 e = make_appropriate (e);
143 if (e == NULL)
144 return NULL;
145 t = expr_type (e);
146 if (t == NULL)
147 return NULL;
148 }
149 else if (pfx->is(IR_TYPE))
150 {
151 t = pIIR_Type(pfx);
152 }
153 else
154 {
155 error ("%:prefix of '%s must be a type or object",
156 n->prefix, attr_name[ai]);
157 return NULL;
158 }
159
160 base_t = vaul_get_base (t);
161
162 if(ai >= AI_FIRST_TYPE && ai <= AI_LAST_TYPE) {
163 if(ai >= ai_IMAGE && ai <= ai_VALUE) {
164 if(!base_t->is(IR_SCALAR_TYPE)) {
165 error("%:prefix of '%s must be a scalar type", n->prefix,
166 attr_name[ai]);
167 return NULL;
168 }
169 } else if(ai >= ai_POS && ai <= ai_RIGHTOF) {
170 if(!is_discrete_type(base_t)
171 && !base_t->is(IR_PHYSICAL_TYPE)) {
172 error("%:prefix of '%s must be a discrete or"
173 " physical type", n->prefix, attr_name[ai]);
174 return NULL;
175 }
176 }
177
178 switch(ai) {
179 case ai_BASE: {
180 res = base_t;
181 } break;
182
183 case ai_IMAGE: {
184 overload_resolution (p, t);
185 res = mIIR_Attr_IMAGE (n->pos, std->predef_STRING, t, p);
186 p = NULL;
187 } break;
188
189 case ai_VALUE: {
190 overload_resolution (p, std->predef_STRING);
191 res = mIIR_Attr_VALUE (n->pos, t, t, p);
192 p = NULL;
193 } break;
194
195 case ai_POS: {
196 overload_resolution (p, t);
197 res = mIIR_Attr_POS (n->pos, std->universal_integer, t, p);
198 p = NULL;
199 } break;
200
201 case ai_VAL: {
202 overload_resolution (p, IR_INTEGER_TYPE);
203 res = mIIR_Attr_VAL (n->pos, t, t, p);
204 p = NULL;
205 } break;
206
207 case ai_SUCC: {
208 overload_resolution (p, t);
209 res = mIIR_Attr_SUCC (n->pos, t, t, p);
210 p = NULL;
211 } break;
212
213 case ai_PRED: {
214 overload_resolution (p, t);
215 res = mIIR_Attr_PRED (n->pos, t, t, p);
216 p = NULL;
217 } break;
218
219 case ai_LEFTOF: {
220 overload_resolution (p, t);
221 res = mIIR_Attr_LEFTOF (n->pos, t, t, p);
222 p = NULL;
223 } break;
224
225 case ai_RIGHTOF: {
226 overload_resolution (p, t);
227 res = mIIR_Attr_RIGHTOF (n->pos, t, t, p);
228 p = NULL;
229 } break;
230
231 default: // should be complete.
232 info("%:XXX - unimplemented type attribute %n",
233 n, n->attribute);
234 return NULL;
235 }
236
237 } else if (ai >= AI_FIRST_T_OR_A && ai <= AI_LAST_T_OR_A) {
238 int index;
239 pIIR_Expression arg = p;
240 p = NULL;
241 if (base_t->is(IR_ARRAY_TYPE))
242 {
243 if (arg)
244 {
245 overload_resolution (arg, IR_INTEGER_TYPE);
246 if (arg == NULL)
247 return NULL;
248 }
249
250 pIIR_Type it = find_array_attr_index_type (pIIR_ArrayType(base_t),
251 arg, index);
252 if (it == NULL)
253 return NULL;
254
255 switch (ai)
256 {
257 case ai_LEFT:
258 res = mIIR_Attr_ArrayLEFT (n->pos, it, e, t, index);
259 break;
260 case ai_RIGHT:
261 res = mIIR_Attr_ArrayRIGHT (n->pos, it, e, t, index);
262 break;
263 case ai_HIGH:
264 res = mIIR_Attr_ArrayHIGH (n->pos, it, e, t, index);
265 break;
266 case ai_LOW:
267 res = mIIR_Attr_ArrayLOW (n->pos, it, e, t, index);
268 break;
269 case ai_ASCENDING:
270 res = mIIR_Attr_ArrayASCENDING (n->pos,
271 std->predef_BOOLEAN,
272 e, t, index);
273 break;
274 case ai_RANGE:
275 res = mIIR_Attr_ArrayRANGE (n->pos, it, e, t, arg);
276 break;
277 case ai_REVERSE_RANGE:
278 res = mIIR_Attr_ArrayREVERSE_RANGE (n->pos, it, e, t, arg);
279 break;
280 case ai_LENGTH:
281 res = mIIR_Attr_ArrayLENGTH (n->pos,
282 std->universal_integer, e, t,
283 index);
284 break;
285 default:
286 assert (false);
287 }
288 }
289 else if (t)
290 {
291 switch (ai)
292 {
293 case ai_LEFT:
294 res = mIIR_Attr_LEFT (n->pos, t, t, arg);
295 break;
296 case ai_RIGHT:
297 res = mIIR_Attr_RIGHT (n->pos, t, t, arg);
298 break;
299 case ai_HIGH:
300 res = mIIR_Attr_HIGH (n->pos, t, t, arg);
301 break;
302 case ai_LOW:
303 res = mIIR_Attr_LOW (n->pos, t, t, arg);
304 break;
305 case ai_ASCENDING:
306 res = mIIR_Attr_ASCENDING (n->pos, std->predef_BOOLEAN,
307 t, arg);
308 break;
309 case ai_RANGE:
310 case ai_REVERSE_RANGE:
311 case ai_LENGTH:
312 error ("prefix of '%s must be an array or array type",
313 attr_name[ai]);
314 res = NULL;
315 break;
316 default:
317 assert (false);
318 }
319 }
320 else
321 {
322 error ("%:prefix of '%s must be a type or array",
323 n->prefix, attr_name[ai]);
324 return NULL;
325 }
326 }
327
328 } else if(ai >= AI_FIRST_SIGNAL && ai <= AI_LAST_SIGNAL) {
329
330 pIIR b = build_Expr (n->prefix, set, basic_k);
331 if (b == NULL)
332 return NULL;
333 if (!b->is(IR_OBJECT_REFERENCE) || !is_signal (pIIR_ObjectReference(b)))
334 {
335 error ("%:prefix of '%s must be a signal",
336 n->prefix, attr_name[ai]);
337 return NULL;
338 }
339
340 pIIR_ObjectReference r = pIIR_ObjectReference(b);
341
342 switch(ai)
343 {
344 case ai_DELAYED:
345 overload_resolution (p, std->predef_TIME);
346 res = mIIR_Attr_DELAYED (n->pos, vaul_get_type (r), r, p);
347 p = NULL;
348 break;
349
350 case ai_STABLE:
351 overload_resolution (p, std->predef_TIME);
352 res = mIIR_Attr_STABLE (n->pos, std->predef_BOOLEAN, r, p);
353 p = NULL;
354 break;
355
356 case ai_QUIET:
357 overload_resolution (p, std->predef_TIME);
358 res = mIIR_Attr_QUIET (n->pos, std->predef_BOOLEAN, r, p);
359 p = NULL;
360 break;
361
362 case ai_TRANSACTION:
363 res = mIIR_Attr_TRANSACTION (n->pos, std->predef_BIT, r);
364 break;
365
366 case ai_EVENT:
367 res = mIIR_Attr_EVENT (n->pos, std->predef_BOOLEAN, r);
368 break;
369
370 case ai_ACTIVE:
371 res = mIIR_Attr_ACTIVE (n->pos, std->predef_BOOLEAN, r);
372 break;
373
374 case ai_LAST_EVENT:
375 res = mIIR_Attr_LAST_EVENT (n->pos, std->predef_TIME, r);
376 break;
377
378 case ai_LAST_ACTIVE:
379 res = mIIR_Attr_LAST_ACTIVE (n->pos, std->predef_TIME, r);
380 break;
381
382 case ai_LAST_VALUE:
383 res = mIIR_Attr_LAST_VALUE (n->pos, vaul_get_type(r), r);
384 break;
385
386 case ai_DRIVING:
387 res = mIIR_Attr_DRIVING (n->pos, std->predef_BOOLEAN, r);
388 break;
389
390 case ai_DRIVING_VALUE:
391 res = mIIR_Attr_DRIVING_VALUE (n->pos, vaul_get_type(r), r);
392 break;
393
394 default:
395 // should be complete
396 info ("%:XXX - unimplemented signal attribute %n", n, n->attribute);
397
398 }
399
400 } else if(ai >= AI_FIRST_ENTITY && ai <= AI_LAST_ENTITY) {
401 info ("XXX - unimplemented entity attribute %n", n, n->attribute);
402 delete set;
403 res = NULL;
404 } else {
405 // user defined attributes
406 info("%:XXX - no user defined attributes", n);
407 delete set;
408 res = NULL;
409 }
410
411 if(p || too_many)
412 error ("%:too many arguments for attribute %s", n, attr_name[ai]);
413
414 return res;
415 }
416
417 pIIR_Type
find_array_attr_index_type(pIIR_ArrayType t,pIIR_Expression p,int & index)418 psr::find_array_attr_index_type (pIIR_ArrayType t, pIIR_Expression p, int &index)
419 {
420 if (p == NULL)
421 index = 1;
422 else if (!evaluate_locally_static_universal_integer(p, index))
423 return NULL;
424
425 //info ("+++ - folded %n to %d", p, index);
426
427 if (index <= 0)
428 {
429 error ("%:indices must be positive", p);
430 return NULL;
431 }
432
433 pIIR_TypeList it = pIIR_ArrayType(t)->index_types;
434 int dims = 0;
435 while(it && index != ++dims)
436 it = it->rest;
437 if (it == NULL)
438 {
439 error("%:%n has only %d dimensions, not %d", p, t,
440 dims, index);
441 return NULL;
442 }
443 return it->first;
444 }
445
446 #if 0 // not used
447
448 static pIIR_Declaration
449 find_in_decl_part (nScope part, Id id)
450 {
451 for (nDeclaration d = part->first_decl; d; d = d->next_decl) {
452 if (d->id && vaul_name_eq (d->id, id))
453 return d;
454 }
455 return NULL;
456 }
457
458 #endif
459
460 void
bind_attrspec(pVAUL_AttributeSpec s)461 psr::bind_attrspec (pVAUL_AttributeSpec s)
462 {
463 if (s == NULL || s->entities == NULL)
464 return;
465
466 pVAUL_SimpleName attr_name = mVAUL_SimpleName (s->pos, s->attr_desig);
467 pIIR_AttributeDeclaration a =
468 pIIR_AttributeDeclaration (find_single_decl (attr_name,
469 IR_ATTRIBUTE_DECLARATION,
470 "attribute"));
471 if (a == NULL)
472 return;
473
474 overload_resolution (s->value, a->subtype);
475 if (s->value == NULL)
476 return;
477
478 pVAUL_EntityNameList el = s->entities->names;
479 if (el->is(VAUL_ENTITY_NAME_LIST_IDS))
480 {
481 IR_Kind eclass = s->entities->entity_class;
482 const char *ename = tree_kind_name (eclass);
483
484 for (pVAUL_DesigList il = pVAUL_EntityNameList_Ids(el)->ids;
485 il; il = il->link)
486 {
487 pIIR_Declaration d =
488 find_single_decl (mVAUL_SimpleName(il->pos,
489 il->desig),
490 IR_DECLARATION, NULL);
491 if (d == NULL)
492 continue;
493
494 if (d->declarative_region != cur_scope
495 && d != cur_du->get_tree())
496 {
497 error ("%:only declarations in the current design unit "
498 "can be attributed", il);
499 }
500 else
501 {
502 pIIR_AttributeValue av = mIIR_AttributeValue (il->pos,
503 s->value,
504 a);
505 d->attributes =
506 mIIR_AttributeValueList (av->pos, av, d->attributes);
507 }
508 }
509 }
510 else if(el->is(VAUL_ENTITY_NAME_LIST_ALL))
511 {
512 info("%:XXX - no ALL attributions yet", el);
513 }
514 else if(el->is(VAUL_ENTITY_NAME_LIST_OTHERS))
515 {
516 info("%:XXX - no OTHERS attributions yet", el);
517 }
518 else
519 assert(false);
520 }
521