1 /*
2 * Copyright (c) 2011-2013 Stephen Williams (steve@icarus.com)
3 * Copyright CERN 2012-2013 / Stephen Williams (steve@icarus.com)
4 * Copyright CERN 2016
5 * @author Maciej Suminski (maciej.suminski@cern.ch)
6 *
7 * This source code is free software; you can redistribute it
8 * and/or modify it in source code form under the terms of the GNU
9 * General Public License as published by the Free Software
10 * Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 * Picture Elements, Inc., 777 Panoramic Way, Berkeley, CA 94704.
22 */
23
24 # include "expression.h"
25 # include "architec.h"
26 # include "entity.h"
27 # include "vsignal.h"
28 # include "subprogram.h"
29 # include "std_types.h"
30 # include <iostream>
31 # include <typeinfo>
32 # include "parse_types.h"
33 # include "compiler.h"
34 # include "ivl_assert.h"
35
36 using namespace std;
37
elaborate_lval(Entity *,ScopeBase *,bool)38 int Expression::elaborate_lval(Entity*, ScopeBase*, bool)
39 {
40 cerr << get_fileline() << ": error: Expression is not a valid l-value." << endl;
41 return 1;
42 }
43
probe_type(Entity *,ScopeBase *) const44 const VType* Expression::probe_type(Entity*, ScopeBase*) const
45 {
46 return 0;
47 }
48
fit_type(Entity * ent,ScopeBase * scope,const VTypeArray *) const49 const VType* Expression::fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*) const
50 {
51 const VType*res = probe_type(ent,scope);
52 if (res == 0) {
53 cerr << get_fileline() << ": internal error: "
54 << "fit_type for " << typeid(*this).name()
55 << " is not implemented." << endl;
56 }
57
58 return res;
59 }
60
elaborate_adjust_type_with_range_(Entity * ent,ScopeBase * scope,const VType * type)61 const VType*ExpName::elaborate_adjust_type_with_range_(Entity*ent, ScopeBase*scope,
62 const VType*type)
63 {
64 // Unfold typedefs
65 while (const VTypeDef*tdef = dynamic_cast<const VTypeDef*>(type)) {
66 type = tdef->peek_definition();
67 }
68
69 if (const VTypeArray*array = dynamic_cast<const VTypeArray*>(type)) {
70 Expression*idx = index(0);
71
72 if (ExpRange*range = dynamic_cast<ExpRange*>(idx)) {
73 // If the name is an array, then a part select is
74 // also an array, but with different bounds.
75 int64_t use_msb, use_lsb;
76 bool flag = true;
77
78 flag &= range->msb()->evaluate(ent, scope, use_msb);
79 flag &= range->lsb()->evaluate(ent, scope, use_lsb);
80
81 if(flag)
82 type = new VTypeArray(array->element_type(), use_msb, use_lsb);
83 }
84 else if(idx) {
85 // If the name is an array or a vector, then an
86 // indexed name has the type of the element.
87 type = array->element_type();
88 }
89 }
90
91 return type;
92 }
93
elaborate_lval_(Entity * ent,ScopeBase * scope,bool is_sequ,ExpName * suffix)94 int ExpName::elaborate_lval_(Entity*ent, ScopeBase*scope, bool is_sequ, ExpName*suffix)
95 {
96 int errors = 0;
97
98 if (debug_elaboration) {
99 debug_log_file << get_fileline() << ": ExpName::elaborate_lval_: "
100 << "name_=" << name_
101 << ", suffix->name()=" << suffix->name();
102 if (indices_) {
103 for(list<Expression*>::const_iterator it = indices_->begin();
104 it != indices_->end(); ++it) {
105 debug_log_file << "[";
106 debug_log_file << **it;
107 debug_log_file << "]";
108 }
109 }
110 debug_log_file << endl;
111 }
112
113 if (prefix_.get()) {
114 cerr << get_fileline() << ": sorry: I don't know how to elaborate "
115 << "ExpName prefix of " << name_
116 << " in l-value expressions." << endl;
117 errors += 1;
118 }
119
120 const VType*found_type = 0;
121
122 if (const InterfacePort*cur = ent->find_port(name_)) {
123 if (cur->mode != PORT_OUT && cur->mode != PORT_INOUT) {
124 cerr << get_fileline() << ": error: Assignment to "
125 "input port " << name_ << "." << endl;
126 return errors + 1;
127 }
128
129 if (is_sequ)
130 ent->set_declaration_l_value(name_, is_sequ);
131
132 found_type = cur->type;
133
134 } else if (ent->find_generic(name_)) {
135
136 cerr << get_fileline() << ": error: Assignment to generic "
137 << name_ << " from entity "
138 << ent->get_name() << "." << endl;
139 return errors + 1;
140
141 } else if (Signal*sig = scope->find_signal(name_)) {
142 // Tell the target signal that this may be a sequential l-value.
143 if (is_sequ) sig->count_ref_sequ();
144
145 found_type = sig->peek_type();
146
147 } else if (Variable*var = scope->find_variable(name_)) {
148 // Tell the target signal that this may be a sequential l-value.
149 if (is_sequ) var->count_ref_sequ();
150
151 found_type = var->peek_type();
152 }
153
154 // Resolve type definition to get an actual type.
155 while (const VTypeDef*tdef = dynamic_cast<const VTypeDef*> (found_type)) {
156 found_type = tdef->peek_definition();
157
158 if (debug_elaboration) {
159 debug_log_file << get_fileline() << ": ExpName::elaborate_lval_: "
160 << "Resolve typedef " << tdef->peek_name()
161 << " to defined type=" << typeid(*found_type).name()
162 << endl;
163 }
164 }
165
166 ivl_assert(*this, found_type);
167
168 // If the prefix type is an array, then we may actually have a
169 // case of an array of structs. For example:
170 // foo(n).bar
171 // where foo is an array, (n) is an array index and foo(n) is
172 // something that takes a suffix. For the purpose of our
173 // expression type calculations, we need the element type.
174 if (const VTypeArray*array = dynamic_cast<const VTypeArray*> (found_type)) {
175 found_type = array->element_type();
176
177 while (const VTypeDef*tdef = dynamic_cast<const VTypeDef*> (found_type)) {
178 found_type = tdef->peek_definition();
179 }
180
181 if (debug_elaboration) {
182 debug_log_file << get_fileline() << ": ExpName::elaborate_lval_: "
183 << "Extract array element type=" << typeid(*found_type).name()
184 << endl;
185 }
186 }
187
188 const VType*suffix_type = 0;
189
190 if (const VTypeRecord*record = dynamic_cast<const VTypeRecord*> (found_type)) {
191 const VTypeRecord::element_t*element = record->element_by_name(suffix->name_);
192 ivl_assert(*this, element);
193
194 const VType*element_type = element->peek_type();
195 ivl_assert(*this, element_type);
196
197 suffix_type = element_type;
198
199 }
200
201 if (suffix_type == 0) {
202 cerr << get_fileline() << ": error: I don't know how to handle prefix " << name_
203 << " with suffix " << suffix->name_ << endl;
204 errors += 1;
205 return errors;
206 }
207
208 suffix_type = suffix->elaborate_adjust_type_with_range_(ent, scope, suffix_type);
209
210 ivl_assert(*this, suffix_type);
211 suffix->set_type(suffix_type);
212
213 return errors;
214 }
215
elaborate_lval(Entity * ent,ScopeBase * scope,bool is_sequ)216 int ExpName::elaborate_lval(Entity*ent, ScopeBase*scope, bool is_sequ)
217 {
218 int errors = 0;
219
220 if (prefix_.get()) {
221 return prefix_->elaborate_lval_(ent, scope, is_sequ, this);
222 }
223
224 const VType*found_type = 0;
225
226 if (ent) {
227 if (const InterfacePort*cur = ent->find_port(name_)) {
228 if (cur->mode != PORT_OUT && cur->mode != PORT_INOUT) {
229 cerr << get_fileline() << ": error: Assignment to "
230 "input port " << name_ << "." << endl;
231 return errors += 1;
232 }
233
234 if (is_sequ)
235 ent->set_declaration_l_value(name_, is_sequ);
236
237 found_type = cur->type;
238
239 } else if (ent->find_generic(name_)) {
240
241 cerr << get_fileline() << ": error: Assignment to generic "
242 << name_ << " from entity "
243 << ent->get_name() << "." << endl;
244 return 1;
245 }
246 }
247
248 if (!found_type && scope) {
249 if (Signal*sig = scope->find_signal(name_)) {
250 // Tell the target signal that this may be a sequential l-value.
251 if (is_sequ) sig->count_ref_sequ();
252
253 found_type = sig->peek_type();
254
255 } else if (Variable*var = scope->find_variable(name_)) {
256 // Tell the target signal that this may be a sequential l-value.
257 if (is_sequ) var->count_ref_sequ();
258
259 found_type = var->peek_type();
260
261 } else if (const InterfacePort*port = scope->find_param(name_)) {
262 found_type = port->type;
263 }
264 }
265
266 if (found_type == 0) {
267 cerr << get_fileline() << ": error: Signal/variable " << name_
268 << " not found in this context." << endl;
269 return errors + 1;
270 }
271
272 found_type = elaborate_adjust_type_with_range_(ent, scope, found_type);
273
274 set_type(found_type);
275 return errors;
276 }
277
elaborate_rval(Entity * ent,ScopeBase * scope,const InterfacePort * lval)278 int ExpName::elaborate_rval(Entity*ent, ScopeBase*scope, const InterfacePort*lval)
279 {
280 int errors = 0;
281
282 if (prefix_.get()) {
283 cerr << get_fileline() << ": sorry: I don't know how to elaborate "
284 << "ExpName prefix parts in r-value expressions." << endl;
285 errors += 1;
286 }
287
288 const VType*dummy_type;
289 Expression*dummy_expr;
290
291 if (const InterfacePort*cur = ent->find_port(name_)) {
292 /* IEEE 1076-2008, p.80:
293 * For a formal port IN, associated port should be IN, OUT, INOUT or BUFFER
294 * For a formal port OUT, associated port should be OUT, INOUT or BUFFER
295 * For a formal port INOUT, associated port should be OUT, INOUT or BUFFER
296 * For a formal port BUFFER, associated port should be OUT, INOUT or BUFFER
297 */
298 switch(lval->mode) {
299 case PORT_OUT:
300 //case PORT_INOUT:
301 if (cur->mode == PORT_IN) {
302 cerr << get_fileline() << ": error: Connecting "
303 "formal output port " << lval->name << " to actual input port "
304 << name_ << "." << endl;
305 errors += 1;
306 }
307 break;
308 case PORT_IN:
309 case PORT_NONE:
310 default:
311 break;
312 }
313 } else if (scope->find_signal(name_)) {
314 /* OK */
315
316 } else if (ent->find_generic(name_)) {
317 /* OK */
318
319 } else if (scope->find_constant(name_, dummy_type, dummy_expr)) {
320 /* OK */
321
322 } else if (scope->is_enum_name(name_)) {
323 /* OK */
324
325 } else {
326 cerr << get_fileline() << ": error: No port, signal or constant " << name_
327 << " to be used as r-value." << endl;
328 errors += 1;
329 }
330
331 return errors;
332 }
333
elaborate_expr(Entity *,ScopeBase *,const VType *)334 int Expression::elaborate_expr(Entity*, ScopeBase*, const VType*)
335 {
336 cerr << get_fileline() << ": internal error: I don't know how to "
337 << "elaborate expression type=" << typeid(*this).name() << endl;
338 return 1;
339 }
340
probe_type(Entity * ent,ScopeBase * scope) const341 const VType* ExpBinary::probe_type(Entity*ent, ScopeBase*scope) const
342 {
343 const VType*t1 = operand1_->probe_type(ent, scope);
344 const VType*t2 = operand2_->probe_type(ent, scope);
345
346 if (t1 == 0)
347 return t2;
348 if (t2 == 0)
349 return t1;
350
351 if (t1->type_match(t2))
352 return t1;
353 if (t2->type_match(t1))
354 return t2;
355
356 if (const VType*tb = resolve_operand_types_(t1, t2))
357 return tb;
358
359 // FIXME: I should at this point try harder to find an
360 // operator that has the proper argument list and use this
361 // here, but for now we leave it for the back-end to figure out.
362 #if 0
363 cerr << get_fileline() << ": internal error: I don't know how to resolve types of generic binary expressions." << endl;
364 #endif
365 return 0;
366 }
367
resolve_operand_types_(const VType *,const VType *) const368 const VType*ExpBinary::resolve_operand_types_(const VType*, const VType*) const
369 {
370 return 0;
371 }
372
elaborate_exprs(Entity * ent,ScopeBase * scope,const VType * ltype)373 int ExpBinary::elaborate_exprs(Entity*ent, ScopeBase*scope, const VType*ltype)
374 {
375 int errors = 0;
376
377 errors += operand1_->elaborate_expr(ent, scope, ltype);
378 errors += operand2_->elaborate_expr(ent, scope, ltype);
379 return errors;
380 }
381
382 /*
383 * the default fit_type method for unary operator expressions is to
384 * return the fit_type for the operand. The assumption is that the
385 * operator doesn't change the type.
386 */
fit_type(Entity * ent,ScopeBase * scope,const VTypeArray * atype) const387 const VType*ExpUnary::fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*atype) const
388 {
389 return operand1_->fit_type(ent, scope, atype);
390 }
391
probe_type(Entity * ent,ScopeBase * scope) const392 const VType*ExpUnary::probe_type(Entity*ent, ScopeBase*scope) const
393 {
394 return operand1_->probe_type(ent, scope);
395 }
396
elaborate_expr(Entity * ent,ScopeBase * scope,const VType * ltype)397 int ExpUnary::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype)
398 {
399 ivl_assert(*this, ltype != 0);
400 set_type(ltype);
401 return operand1_->elaborate_expr(ent, scope, ltype);
402 }
403
fit_type(Entity *,ScopeBase *,const VTypeArray * host) const404 const VType*ExpAggregate::fit_type(Entity*, ScopeBase*, const VTypeArray*host) const
405 {
406 ivl_assert(*this, elements_.size() == 1);
407 size_t choice_count = elements_[0]->count_choices();
408
409 ivl_assert(*this, choice_count > 0);
410 vector<choice_element> ce (choice_count);
411 elements_[0]->map_choices(&ce[0]);
412
413 ivl_assert(*this, ce.size() == 1);
414 ExpRange*prange = ce[0].choice->range_expressions();
415 ivl_assert(*this, prange);
416
417 Expression*use_msb = prange->msb();
418 Expression*use_lsb = prange->lsb();
419
420 ivl_assert(*this, host->dimensions().size() == 1);
421 vector<VTypeArray::range_t> range (1);
422
423 range[0] = VTypeArray::range_t(use_msb, use_lsb);
424
425 const VTypeArray*res = new VTypeArray(host->element_type(), range);
426
427 return res;
428 }
429
elaborate_expr(Entity * ent,ScopeBase * scope,const VType * ltype)430 int ExpAggregate::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype)
431 {
432 if (ltype == 0) {
433 cerr << get_fileline() << ": error: Elaboration of aggregate types needs well known type context?" << endl;
434 return 1;
435 }
436
437 set_type(ltype);
438
439 while (const VTypeDef*cur = dynamic_cast<const VTypeDef*>(ltype)) {
440 ltype = cur->peek_definition();
441 }
442
443 if (const VTypeArray*larray = dynamic_cast<const VTypeArray*>(ltype)) {
444 return elaborate_expr_array_(ent, scope, larray);
445 }
446 else if(const VTypeRecord*lrecord = dynamic_cast<const VTypeRecord*>(ltype)) {
447 return elaborate_expr_record_(ent, scope, lrecord);
448 }
449
450 cerr << get_fileline() << ": internal error: I don't know how to elaborate aggregate expressions. type=" << typeid(*ltype).name() << endl;
451 return 1;
452 }
453
454 /*
455 * Elaboration of array aggregates is elaboration of the element
456 * expressions (the elements_ member) using the element type as the
457 * ltype for the subexpression.
458 */
elaborate_expr_array_(Entity * ent,ScopeBase * scope,const VTypeArray * ltype)459 int ExpAggregate::elaborate_expr_array_(Entity*ent, ScopeBase*scope, const VTypeArray*ltype)
460 {
461 const VType*element_type = ltype->element_type();
462 int errors = 0;
463 size_t choice_count = 0;
464
465 // Figure out how many total elements we have here. Note that
466 // each parsed element may be bound to multiple choices, so
467 // account for that.
468 for (size_t edx = 0 ; edx < elements_.size() ; edx += 1) {
469 element_t*ecur = elements_[edx];
470 if (ecur->count_choices() == 0)
471 choice_count += 1;
472 else
473 choice_count += ecur->count_choices();
474 }
475
476 aggregate_.resize(choice_count);
477
478 // Translate the elements_ array to the aggregate_ array. In
479 // the target array, each expression is attached to a single
480 // choice.
481 size_t cdx = 0;
482 for (size_t edx = 0 ; edx < elements_.size() ; edx += 1) {
483 element_t*ecur = elements_[edx];
484 if (ecur->count_choices() == 0) {
485 // positional associations have no "choice"
486 // associated with them.
487 aggregate_[cdx].choice = 0;
488 aggregate_[cdx].expr = ecur->extract_expression();
489 aggregate_[cdx].alias_flag = false;
490 cdx += 1;
491 } else {
492 ecur->map_choices(&aggregate_[cdx]);
493 cdx += ecur->count_choices();
494 }
495 }
496
497 ivl_assert(*this, cdx == choice_count);
498
499 // Now run through the more convenient mapping and elaborate
500 // all the expressions that I find.
501 for (size_t idx = 0 ; idx < aggregate_.size() ; idx += 1) {
502 if (aggregate_[idx].alias_flag)
503 continue;
504
505 errors += aggregate_[idx].expr->elaborate_expr(ent, scope, element_type);
506 }
507
508 // done with the obsolete elements_ vector.
509 elements_.clear();
510
511 return errors;
512 }
513
elaborate_expr_record_(Entity * ent,ScopeBase * scope,const VTypeRecord * ltype)514 int ExpAggregate::elaborate_expr_record_(Entity*ent, ScopeBase*scope, const VTypeRecord*ltype)
515 {
516 int errors = 0;
517
518 aggregate_.resize(elements_.size());
519 choice_element tmp;
520 int idx;
521
522 // Translate the elements_ array to the aggregate_ array. In
523 // the target array, each expression is attached to a single
524 // choice.
525 for (size_t edx = 0 ; edx < elements_.size() ; edx += 1) {
526 element_t*ecur = elements_[edx];
527
528 // it is invalid to have more than one choice in record assignment
529 ivl_assert(*this, ecur->count_choices() == 1);
530
531 ecur->map_choices(&tmp);
532 choice_t*ch = tmp.choice;
533
534 ivl_assert(*this, !ch->others());
535 ivl_assert(*this, !tmp.alias_flag);
536
537 // Get the appropriate type for a field
538 const ExpName*field = dynamic_cast<const ExpName*>(ch->simple_expression(false));
539 ivl_assert(*this, field);
540
541 perm_string field_name = field->peek_name();
542 idx = -1;
543 const VTypeRecord::element_t*el = ltype->element_by_name(field_name, &idx);
544 ivl_assert(*this, idx >= 0);
545
546 aggregate_[idx] = tmp;
547 errors += aggregate_[idx].expr->elaborate_expr(ent, scope, el->peek_type());
548 }
549
550 // done with the obsolete elements_ vector.
551 elements_.clear();
552
553 return errors;
554 }
555
map_choices(ExpAggregate::choice_element * dst)556 void ExpAggregate::element_t::map_choices(ExpAggregate::choice_element*dst)
557 {
558 for (size_t idx = 0 ; idx < fields_.size() ; idx += 1) {
559 dst->choice = fields_[idx];
560 dst->expr = val_;
561 dst->alias_flag = (idx != 0);
562 dst += 1;
563 }
564 }
565
elaborate_expr(Entity * ent,ScopeBase * scope,const VType * ltype)566 int ExpArithmetic::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype)
567 {
568 int errors = 0;
569
570 if (ltype == 0) {
571 ltype = probe_type(ent, scope);
572 }
573
574 ivl_assert(*this, ltype != 0);
575 errors += elaborate_exprs(ent, scope, ltype);
576 return errors;
577 }
578
resolve_operand_types_(const VType * t1,const VType * t2) const579 const VType* ExpArithmetic::resolve_operand_types_(const VType*t1, const VType*t2) const
580 {
581 // Ranges
582 while (const VTypeRange*tmp = dynamic_cast<const VTypeRange*> (t1))
583 t1 = tmp->base_type();
584 while (const VTypeRange*tmp = dynamic_cast<const VTypeRange*> (t2))
585 t2 = tmp->base_type();
586
587 if (t1->type_match(t2))
588 return t1;
589
590 // Signed & unsigned (resized to the widest argument)
591 const VTypeArray*t1_arr = dynamic_cast<const VTypeArray*>(t1);
592 const VTypeArray*t2_arr = dynamic_cast<const VTypeArray*>(t2);
593
594 if(t1_arr && t2_arr) {
595 const VTypeArray*t1_parent = t1_arr->get_parent_type();
596 const VTypeArray*t2_parent = t2_arr->get_parent_type();
597
598 if(t1_parent == t2_parent
599 && (t1_parent == &primitive_SIGNED || t1_parent == &primitive_UNSIGNED)) {
600 int t1_size = t1_arr->get_width(NULL);
601 int t2_size = t2_arr->get_width(NULL);
602
603 // Easy, the same sizes, so we do not need to resize
604 if(t1_size == t2_size && t1_size > 0)
605 return t1; // == t2
606
607 VTypeArray*resolved = new VTypeArray(t1_parent->element_type(),
608 std::max(t1_size, t2_size) - 1, 0, t1_parent->signed_vector());
609 resolved->set_parent_type(t1_parent);
610
611 return resolved;
612 }
613
614 } else if(t1_arr) {
615 if(const VTypePrimitive*prim = dynamic_cast<const VTypePrimitive*>(t2)) {
616 const VTypeArray*t1_parent = t1_arr->get_parent_type();
617 VTypePrimitive::type_t t2_type = prim->type();
618
619 if((t2_type == VTypePrimitive::NATURAL || t2_type == VTypePrimitive::INTEGER)
620 && t1_parent == &primitive_SIGNED)
621 return t1;
622
623 if((t2_type == VTypePrimitive::NATURAL) && t1_parent == &primitive_UNSIGNED)
624 return t1;
625 }
626
627 } else if(t2_arr) {
628 if(const VTypePrimitive*prim = dynamic_cast<const VTypePrimitive*>(t1)) {
629 const VTypeArray*t2_parent = t2_arr->get_parent_type();
630 VTypePrimitive::type_t t1_type = prim->type();
631
632 if((t1_type == VTypePrimitive::NATURAL || t1_type == VTypePrimitive::INTEGER)
633 && t2_parent == &primitive_SIGNED)
634 return t2;
635
636 if((t1_type == VTypePrimitive::NATURAL) && t2_parent == &primitive_UNSIGNED)
637 return t2;
638 }
639 }
640
641 return 0;
642 }
643
elaborate_args(Entity * ent,ScopeBase * scope,const VType * ltype)644 int ExpAttribute::elaborate_args(Entity*ent, ScopeBase*scope, const VType*ltype)
645 {
646 int errors = 0;
647
648 if(args_) {
649 for(list<Expression*>::iterator it = args_->begin();
650 it != args_->end(); ++it) {
651 errors += (*it)->elaborate_expr(ent, scope, ltype);
652 }
653 }
654
655 return errors;
656 }
657
elaborate_expr(Entity * ent,ScopeBase * scope,const VType *)658 int ExpObjAttribute::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*)
659 {
660 int errors = 0;
661 const VType*sub_type = base_->probe_type(ent, scope);
662
663 errors += elaborate_args(ent, scope, sub_type);
664 errors += base_->elaborate_expr(ent, scope, sub_type);
665
666 return errors;
667 }
668
probe_type(Entity *,ScopeBase *) const669 const VType* ExpObjAttribute::probe_type(Entity*, ScopeBase*) const
670 {
671 if (name_ == "length" || name_ == "left" || name_ == "right")
672 return &primitive_NATURAL;
673
674 return NULL;
675 }
676
elaborate_expr(Entity * ent,ScopeBase * scope,const VType * ltype)677 int ExpTypeAttribute::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype)
678 {
679 return elaborate_args(ent, scope, ltype);
680 }
681
probe_type(Entity *,ScopeBase *) const682 const VType* ExpTypeAttribute::probe_type(Entity*, ScopeBase*) const
683 {
684 if(name_ == "image")
685 return &primitive_STRING;
686
687 return NULL;
688 }
689
fit_type(Entity *,ScopeBase *,const VTypeArray * atype) const690 const VType*ExpBitstring::fit_type(Entity*, ScopeBase*, const VTypeArray*atype) const
691 {
692 // Really should check that this string can work with the
693 // array element type?
694 return atype->element_type();
695 }
696
elaborate_expr(Entity *,ScopeBase *,const VType *)697 int ExpBitstring::elaborate_expr(Entity*, ScopeBase*, const VType*)
698 {
699 int errors = 0;
700 const VTypeArray*type = new VTypeArray(&primitive_STDLOGIC, value_.size() - 1, 0);
701 set_type(type);
702 return errors;
703 }
704
fit_type(Entity *,ScopeBase *,const VTypeArray * atype) const705 const VType*ExpCharacter::fit_type(Entity*, ScopeBase*, const VTypeArray*atype) const
706 {
707 // Really should check that this character can work with the
708 // array element type?
709 return atype->element_type();
710 }
711
elaborate_expr(Entity *,ScopeBase *,const VType * ltype)712 int ExpCharacter::elaborate_expr(Entity*, ScopeBase*, const VType*ltype)
713 {
714 ivl_assert(*this, ltype != 0);
715 set_type(ltype);
716 return 0;
717 }
718
fit_type(Entity * ent,ScopeBase * scope,const VTypeArray * atype) const719 const VType*ExpConcat::fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*atype) const
720 {
721 Expression*operands[2] = {operand1_, operand2_};
722 const VType*types[2] = {NULL, NULL};
723 Expression*sizes[2] = {NULL, NULL};
724
725 // determine the type and size of concatenated expressions
726 for(int i = 0; i < 2; ++i) {
727 types[i] = operands[i]->fit_type(ent, scope, atype);
728
729 if(const VTypeArray*arr = dynamic_cast<const VTypeArray*>(types[i])) {
730 types[i] = arr->element_type();
731 ivl_assert(*this, arr->dimensions().size() == 1);
732 const VTypeArray::range_t&dim = arr->dimension(0);
733 sizes[i] = new ExpArithmetic(ExpArithmetic::MINUS, dim.msb(), dim.lsb());
734 } else {
735 sizes[i] = new ExpInteger(0);
736 }
737 }
738
739 // the range of the concatenated expression is (size1 + size2 + 1):0
740 // note that each of the sizes are already decreased by one,
741 // e.g. 3:0 <=> size == 3 even though there are 4 bits
742 Expression*size = new ExpArithmetic(ExpArithmetic::PLUS,
743 new ExpArithmetic(ExpArithmetic::PLUS, sizes[0], sizes[1]),
744 new ExpInteger(1));
745
746 std::list<ExpRange*> ranges;
747 ranges.push_front(new ExpRange(size, new ExpInteger(0), ExpRange::DOWNTO));
748 const VType*array = new VTypeArray(types[1], &ranges);
749
750 return array;
751 }
752 /*
753 * I don't know how to probe the type of a concatenation, quite yet.
754 */
probe_type(Entity *,ScopeBase *) const755 const VType*ExpConcat::probe_type(Entity*, ScopeBase*) const
756 {
757 ivl_assert(*this, 0);
758 return 0;
759 }
760
elaborate_expr(Entity * ent,ScopeBase * scope,const VType * ltype)761 int ExpConcat::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype)
762 {
763 int errors = 0;
764
765 if (ltype == 0) {
766 ltype = probe_type(ent, scope);
767 }
768
769 ivl_assert(*this, ltype != 0);
770
771 if (const VTypeArray*atype = dynamic_cast<const VTypeArray*>(ltype)) {
772 errors += elaborate_expr_array_(ent, scope, atype);
773 } else {
774 errors += operand1_->elaborate_expr(ent, scope, ltype);
775 errors += operand2_->elaborate_expr(ent, scope, ltype);
776 }
777
778 return errors;
779 }
780
elaborate_expr_array_(Entity * ent,ScopeBase * scope,const VTypeArray * atype)781 int ExpConcat::elaborate_expr_array_(Entity*ent, ScopeBase*scope, const VTypeArray*atype)
782 {
783 int errors = 0;
784
785 // For now, only support single-dimension arrays here.
786 ivl_assert(*this, atype->dimensions().size() == 1);
787
788 const VType*type1 = operand1_->fit_type(ent, scope, atype);
789 ivl_assert(*this, type1);
790
791 const VType*type2 = operand2_->fit_type(ent, scope, atype);
792 ivl_assert(*this, type2);
793
794 errors += operand1_->elaborate_expr(ent, scope, type1);
795 errors += operand2_->elaborate_expr(ent, scope, type2);
796
797 return errors;
798 }
799
probe_type(Entity *,ScopeBase *) const800 const VType* ExpConditional::probe_type(Entity*, ScopeBase*) const
801 {
802 return 0;
803 }
804
elaborate_expr(Entity * ent,ScopeBase * scope,const VType * ltype)805 int ExpConditional::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype)
806 {
807 int errors = 0;
808
809 if (ltype == 0)
810 ltype = probe_type(ent, scope);
811
812 ivl_assert(*this, ltype);
813
814 set_type(ltype);
815
816 /* Note that the type for the condition expression need not
817 have anything to do with the type of this expression. */
818
819 for (list<case_t*>::const_iterator cur = options_.begin()
820 ; cur != options_.end() ; ++cur) {
821 errors += (*cur)->elaborate_expr(ent, scope, ltype);
822 }
823
824 return errors;
825 }
826
elaborate_expr(Entity * ent,ScopeBase * scope,const VType * ltype)827 int ExpConditional::case_t::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype)
828 {
829 int errors = 0;
830
831 if (cond_)
832 errors += cond_->elaborate_expr(ent, scope, 0);
833
834 for (list<Expression*>::const_iterator cur = true_clause_.begin()
835 ; cur != true_clause_.end() ; ++cur) {
836 errors += (*cur)->elaborate_expr(ent, scope, ltype);
837 }
838
839 return errors;
840 }
841
probe_type(Entity * ent,ScopeBase * scope) const842 const VType*ExpFunc::probe_type(Entity*ent, ScopeBase*scope) const
843 {
844 if(!def_)
845 def_ = match_signature(ent, scope);
846
847 return def_ ? def_->exact_return_type(argv_, ent, scope) : NULL;
848 }
849
elaborate_expr(Entity * ent,ScopeBase * scope,const VType *)850 int ExpFunc::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*)
851 {
852 int errors = 0;
853
854 if(def_)
855 return 0;
856
857 def_ = match_signature(ent, scope);
858
859 if(!def_)
860 return 1;
861
862 // Elaborate arguments
863 for (size_t idx = 0; idx < argv_.size(); ++idx) {
864 errors += def_->elaborate_argument(argv_[idx], idx, ent, scope);
865 }
866
867 // SystemVerilog functions work only with defined size data types, therefore
868 // if header does not specify argument or return type size, create a function
869 // instance that work with this particular size.
870 if(def_ && !def_->is_std() && def_->unbounded()) {
871 def_ = def_->make_instance(argv_, scope);
872 name_ = def_->name(); // TODO necessary?
873 }
874
875 return errors;
876 }
877
fit_type(Entity * ent,ScopeBase * scope,const VTypeArray *) const878 const VType* ExpFunc::fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*) const
879 {
880 return probe_type(ent, scope);
881 }
882
probe_type(Entity *,ScopeBase *) const883 const VType* ExpInteger::probe_type(Entity*, ScopeBase*) const
884 {
885 if(value_ >= 0)
886 return &primitive_NATURAL;
887 else
888 return &primitive_INTEGER;
889 }
890
elaborate_expr(Entity * ent,ScopeBase * scope,const VType * ltype)891 int ExpInteger::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype)
892 {
893 int errors = 0;
894
895 if (ltype == 0) {
896 ltype = probe_type(ent, scope);
897 }
898
899 ivl_assert(*this, ltype != 0);
900
901 return errors;
902 }
903
probe_type(Entity *,ScopeBase *) const904 const VType* ExpReal::probe_type(Entity*, ScopeBase*) const
905 {
906 return &primitive_REAL;
907 }
908
elaborate_expr(Entity * ent,ScopeBase * scope,const VType * ltype)909 int ExpReal::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype)
910 {
911 int errors = 0;
912
913 if (ltype == 0) {
914 ltype = probe_type(ent, scope);
915 }
916
917 ivl_assert(*this, ltype != 0);
918
919 return errors;
920 }
921
elaborate_expr(Entity * ent,ScopeBase * scope,const VType * ltype)922 int ExpLogical::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype)
923 {
924 int errors = 0;
925
926 if (ltype == 0) {
927 ltype = probe_type(ent, scope);
928 }
929
930 ivl_assert(*this, ltype != 0);
931 errors += elaborate_exprs(ent, scope, ltype);
932 return errors;
933 }
934
probe_prefix_type_(Entity * ent,ScopeBase * scope) const935 const VType* ExpName::probe_prefix_type_(Entity*ent, ScopeBase*scope) const
936 {
937 if (prefix_.get()) {
938 cerr << get_fileline() << ": sorry: I do not know how to support nested prefix parts." << endl;
939 return 0;
940 }
941
942 const VType*type = probe_type(ent, scope);
943 return type;
944 }
945
946 /*
947 * This method is the probe_type() implementation for ExpName objects
948 * that have prefix parts. In this case we try to get the type of the
949 * prefix and interpret the name in that context.
950 */
probe_prefixed_type_(Entity * ent,ScopeBase * scope) const951 const VType* ExpName::probe_prefixed_type_(Entity*ent, ScopeBase*scope) const
952 {
953 // First, get the type of the prefix.
954 const VType*prefix_type = prefix_->probe_prefix_type_(ent, scope);
955 if (prefix_type == 0) {
956 return 0;
957 }
958
959 while (const VTypeDef*def = dynamic_cast<const VTypeDef*> (prefix_type)) {
960 prefix_type = def->peek_definition();
961 }
962
963 const VType*element_type = prefix_type;
964 bool type_changed = true;
965
966 // Keep unwinding the type until we find the basic element type
967 while (type_changed) {
968 type_changed = false;
969
970 // If the prefix type is a record, then the current name is
971 // the name of a member.
972 if (const VTypeRecord*pref_record = dynamic_cast<const VTypeRecord*>(element_type)) {
973 const VTypeRecord::element_t*element = pref_record->element_by_name(name_);
974 ivl_assert(*this, element);
975
976 element_type = element->peek_type();
977 ivl_assert(*this, element_type);
978 type_changed = true;
979 }
980
981 if (const VTypeArray*pref_array = dynamic_cast<const VTypeArray*>(element_type)) {
982 element_type = pref_array->basic_type(false);
983 ivl_assert(*this, element_type);
984 type_changed = true;
985 }
986 }
987
988 if(!element_type) {
989 cerr << get_fileline() << ": sorry: I don't know how to probe "
990 << "prefix type " << typeid(*prefix_type).name()
991 << " of " << name_ << "." << endl;
992 return NULL;
993 }
994
995 return element_type;
996 }
997
probe_type(Entity * ent,ScopeBase * scope) const998 const VType* ExpName::probe_type(Entity*ent, ScopeBase*scope) const
999 {
1000 if (prefix_.get())
1001 return probe_prefixed_type_(ent, scope);
1002
1003 if(ent) {
1004 if (const InterfacePort*cur = ent->find_port(name_)) {
1005 ivl_assert(*this, cur->type);
1006 return cur->type;
1007 }
1008
1009 if (const InterfacePort*cur = ent->find_generic(name_)) {
1010 ivl_assert(*this, cur->type);
1011 return cur->type;
1012 }
1013 }
1014
1015 if(scope) {
1016 if (Signal*sig = scope->find_signal(name_))
1017 return sig->peek_type();
1018
1019 if (Variable*var = scope->find_variable(name_))
1020 return var->peek_type();
1021
1022 const VType*type = 0;
1023 Expression*cval = 0;
1024 if (scope->find_constant(name_, type, cval))
1025 return type;
1026
1027 Architecture*arc = dynamic_cast<Architecture*>(scope);
1028 if (arc && (type = arc->probe_genvar_type(name_))) {
1029 return type;
1030 }
1031
1032 if (const InterfacePort*port = scope->find_param(name_)) {
1033 return port->type;
1034 }
1035
1036 if ((type = scope->is_enum_name(name_))) {
1037 return type;
1038 }
1039 }
1040
1041 if(ent || scope) {
1042 // Do not display error messages if there was no entity or scope
1043 // specified. There are functions that are called without any specific
1044 // context and they still may want to probe the expression type.
1045 cerr << get_fileline() << ": error: Signal/variable " << name_
1046 << " not found in this context." << endl;
1047 }
1048
1049 return 0;
1050 }
1051
fit_type(Entity * ent,ScopeBase * scope,const VTypeArray *) const1052 const VType* ExpName::fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*)const
1053 {
1054 return probe_type(ent, scope);
1055 }
1056
elaborate_expr(Entity * ent,ScopeBase * scope,const VType * ltype)1057 int ExpName::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype)
1058 {
1059 if (ltype) {
1060 ivl_assert(*this, ltype != 0);
1061 set_type(ltype);
1062 }
1063
1064 if(prefix_.get())
1065 prefix_.get()->elaborate_expr(ent, scope, NULL);
1066
1067 if (indices_) {
1068 for(list<Expression*>::const_iterator it = indices_->begin();
1069 it != indices_->end(); ++it) {
1070 (*it)->elaborate_expr(ent, scope, &primitive_INTEGER);
1071 }
1072 }
1073
1074 return 0;
1075 }
1076
probe_type(Entity *,ScopeBase *) const1077 const VType* ExpNameALL::probe_type(Entity*, ScopeBase*) const
1078 {
1079 return 0;
1080 }
1081
probe_type(Entity *,ScopeBase *) const1082 const VType* ExpRelation::probe_type(Entity*, ScopeBase*) const
1083 {
1084 return &type_BOOLEAN;
1085 }
1086
elaborate_expr(Entity * ent,ScopeBase * scope,const VType * ltype)1087 int ExpRelation::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype)
1088 {
1089 int errors = 0;
1090
1091 if (ltype == 0) {
1092 ltype = probe_type(ent, scope);
1093 }
1094
1095 ivl_assert(*this, ltype != 0);
1096
1097 // The type of the operands must match, but need not match the
1098 // type for the ExpRelation itself. So get the operand type
1099 // separately.
1100 const VType*otype = ExpBinary::probe_type(ent, scope);
1101 errors += elaborate_exprs(ent, scope, otype);
1102
1103 return errors;
1104 }
1105
elaborate_expr(Entity * ent,ScopeBase * scope,const VType * ltype)1106 int ExpShift::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype)
1107 {
1108 int errors = 0;
1109
1110 if (ltype == 0) {
1111 ltype = probe_type(ent, scope);
1112 }
1113
1114 ivl_assert(*this, ltype != 0);
1115 errors += elaborate_exprs(ent, scope, ltype);
1116 return errors;
1117 }
1118
1119 /*
1120 * When a string appears in a concatenation, then the type of the
1121 * string is an array with the same element type of the concatenation,
1122 * but with elements for each character of the string.
1123 */
fit_type(Entity *,ScopeBase *,const VTypeArray * atype) const1124 const VType*ExpString::fit_type(Entity*, ScopeBase*, const VTypeArray*atype) const
1125 {
1126 vector<VTypeArray::range_t> range (atype->dimensions());
1127
1128 // Generate an array range for this string
1129 ivl_assert(*this, range.size() == 1);
1130
1131 VTypeArray*type = new VTypeArray(atype->element_type(), value_.size(), 0);
1132 return type;
1133 }
1134
elaborate_expr(Entity *,ScopeBase *,const VType * ltype)1135 int ExpString::elaborate_expr(Entity*, ScopeBase*, const VType*ltype)
1136 {
1137 ivl_assert(*this, ltype != 0);
1138 set_type(ltype);
1139 return 0;
1140 }
1141
elaborate_expr(Entity *,ScopeBase *,const VType *)1142 int ExpTime::elaborate_expr(Entity*, ScopeBase*, const VType*)
1143 {
1144 set_type(&primitive_INTEGER);
1145 return 0;
1146 }
1147
elaborate_expr(Entity * ent,ScopeBase * scope,const VType *)1148 int ExpRange::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*)
1149 {
1150 int errors = 0;
1151
1152 if(left_)
1153 errors += left_->elaborate_expr(ent, scope, &primitive_INTEGER);
1154
1155 if(right_)
1156 errors += right_->elaborate_expr(ent, scope, &primitive_INTEGER);
1157
1158 return errors;
1159 }
1160
elaborate_expr(Entity * ent,ScopeBase * scope,const VType * ltype)1161 int ExpDelay::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype)
1162 {
1163 int errors = 0;
1164
1165 errors += expr_->elaborate_expr(ent, scope, ltype);
1166 errors += delay_->elaborate_expr(ent, scope, ltype);
1167
1168 return errors;
1169 }
1170