1 /*
2 * Copyright (c) 2011-2013 Stephen Williams (steve@icarus.com)
3 * Copyright CERN 2012-2015 / Stephen Williams (steve@icarus.com)
4 * @author Maciej Suminski (maciej.suminski@cern.ch)
5 *
6 * This source code is free software; you can redistribute it
7 * and/or modify it in source code form under the terms of the GNU
8 * General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 */
21
22 # include "expression.h"
23 # include "vtype.h"
24 # include "architec.h"
25 # include "package.h"
26 # include "std_funcs.h"
27 # include "std_types.h"
28 # include "parse_types.h"
29 # include <typeinfo>
30 # include <iostream>
31 # include <cstdlib>
32 # include <cstring>
33 # include "ivl_assert.h"
34 # include <cassert>
35
36 using namespace std;
37
emit_logic(char val,ostream & out,const VTypePrimitive::type_t type)38 inline static int emit_logic(char val, ostream& out, const VTypePrimitive::type_t type)
39 {
40 // TODO case 'W': case 'L': case 'H':
41
42 switch (val) {
43 case '-': case 'U':
44 val = 'x';
45 /* fall through */
46
47 case 'X': case 'Z':
48 assert(type == VTypePrimitive::STDLOGIC);
49 /* fall through */
50
51 case '0':
52 case '1':
53 out << (char) tolower(val);
54 break;
55
56 default:
57 assert(false);
58 out << "x";
59 return 1;
60 }
61
62 return 0;
63 }
64
emit(ostream & out,Entity *,ScopeBase *) const65 int Expression::emit(ostream&out, Entity*, ScopeBase*) const
66 {
67 out << " /* " << get_fileline() << ": internal error: "
68 << "I don't know how to emit this expression! "
69 << "type=" << typeid(*this).name() << " */ ";
70 return 1;
71 }
72
emit_package(ostream & out) const73 int Expression::emit_package(ostream&out) const
74 {
75 out << " /* " << get_fileline() << ": internal error: "
76 << "I don't know how to emit_package this expression! "
77 << "type=" << typeid(*this).name() << " */ ";
78 return 1;
79 }
80
is_primary(void) const81 bool Expression::is_primary(void) const
82 {
83 return false;
84 }
85
emit_operand1(ostream & out,Entity * ent,ScopeBase * scope) const86 int ExpBinary::emit_operand1(ostream&out, Entity*ent, ScopeBase*scope) const
87 {
88 int errors = 0;
89 bool oper_primary = operand1_->is_primary();
90 if (! oper_primary) out << "(";
91 errors += operand1_->emit(out, ent, scope);
92 if (! oper_primary) out << ")";
93 return errors;
94 }
95
emit_operand2(ostream & out,Entity * ent,ScopeBase * scope) const96 int ExpBinary::emit_operand2(ostream&out, Entity*ent, ScopeBase*scope) const
97 {
98 int errors = 0;
99 bool oper_primary = operand2_->is_primary();
100 if (! oper_primary) out << "(";
101 errors += operand2_->emit(out, ent, scope);
102 if (! oper_primary) out << ")";
103 return errors;
104 }
105
emit_operand1(ostream & out,Entity * ent,ScopeBase * scope) const106 int ExpUnary::emit_operand1(ostream&out, Entity*ent, ScopeBase*scope) const
107 {
108 int errors = 0;
109 errors += operand1_->emit(out, ent, scope);
110 return errors;
111 }
112
emit(ostream & out,Entity * ent,ScopeBase * scope) const113 int ExpAggregate::emit(ostream&out, Entity*ent, ScopeBase*scope) const
114 {
115 if (peek_type() == 0) {
116 out << "/* " << get_fileline() << ": internal error: "
117 << "Aggregate literal needs well defined type." << endl;
118 return 1;
119 }
120
121 const VType*use_type = peek_type();
122 while (const VTypeDef*def = dynamic_cast<const VTypeDef*> (use_type)) {
123 use_type = def->peek_definition();
124 }
125
126 if (const VTypeArray*atype = dynamic_cast<const VTypeArray*> (use_type))
127 return emit_array_(out, ent, scope, atype);
128 else if (const VTypeRecord*arecord = dynamic_cast<const VTypeRecord*> (use_type))
129 return emit_record_(out, ent, scope, arecord);
130
131 out << "/* " << get_fileline() << ": internal error: "
132 << "I don't know how to elab/emit aggregate in " << typeid(use_type).name()
133 << " type context. */";
134 return 1;
135 }
136
emit_array_(ostream & out,Entity * ent,ScopeBase * scope,const VTypeArray * atype) const137 int ExpAggregate::emit_array_(ostream&out, Entity*ent, ScopeBase*scope, const VTypeArray*atype) const
138 {
139 int errors = 0;
140
141 // Special case: The aggregate is a single "others" item.
142 if (aggregate_.size() == 1 && aggregate_[0].choice->others()) {
143 assert(atype->dimensions().size() == 1);
144
145 const VTypeArray::range_t&rang = atype->dimension(0);
146 assert(! rang.is_box());
147
148 int64_t use_msb;
149 int64_t use_lsb;
150 bool rc_msb, rc_lsb;
151 rc_msb = rang.msb()->evaluate(ent, scope, use_msb);
152 rc_lsb = rang.lsb()->evaluate(ent, scope, use_lsb);
153
154 if (rc_msb && rc_lsb) {
155 int asize = (use_msb >= use_lsb) ? (use_msb - use_lsb) + 1 :
156 (use_lsb - use_msb) + 1;
157 out << "{" << asize << "{";
158 errors += aggregate_[0].expr->emit(out, ent, scope);
159 out << "}}";
160 } else {
161 out << "{(";
162 if (rc_msb) {
163 out << use_msb;
164 } else {
165 out << "(";
166 errors += rang.msb()->emit(out, ent, scope);
167 out << ")";
168 }
169 if (rc_lsb && use_lsb==0) {
170 } else if (rc_lsb) {
171 out << "-" << use_lsb;
172 } else {
173 out << "-(";
174 errors += rang.lsb()->emit(out, ent, scope);
175 out << ")";
176 }
177 out << "+1){";
178 errors += aggregate_[0].expr->emit(out, ent, scope);
179 out << "}}";
180 }
181 return errors;
182 }
183
184 const VTypeArray::range_t&rang = atype->dimension(0);
185 assert(! rang.is_box());
186
187 // Fully calculate the range numbers.
188 int64_t use_msb, use_lsb;
189 bool rc;
190 rc = rang.msb()->evaluate(ent, scope, use_msb);
191 ivl_assert(*this, rc);
192 rc = rang.lsb()->evaluate(ent, scope, use_lsb);
193 ivl_assert(*this, rc);
194 if(use_msb < use_lsb)
195 swap(use_msb, use_lsb);
196
197 map<int64_t,const choice_element*> element_map;
198 const choice_element*element_other = 0;
199
200 bool positional_section = true;
201 int64_t positional_idx = use_msb;
202
203 for (size_t idx = 0 ; idx < aggregate_.size() ; idx += 1) {
204
205 if (aggregate_[idx].choice == 0) {
206 // positional association!
207 if (!positional_section) {
208 cerr << get_fileline() << ": error: "
209 << "All positional associations must be before"
210 << " any named associations." << endl;
211 errors += 1;
212 }
213 element_map[positional_idx] = &aggregate_[idx];
214 positional_idx -= 1;
215 continue;
216 }
217
218 if (aggregate_[idx].choice->others()) {
219 ivl_assert(*this, element_other == 0);
220 element_other = &aggregate_[idx];
221 continue;
222 }
223
224 // If this is a range choice, then calculate the bounds
225 // of the range and scan through the values, mapping the
226 // value to the aggregate_[idx] element.
227 if (ExpRange*range = aggregate_[idx].choice->range_expressions()) {
228 int64_t begin_val, end_val;
229
230 if (! range->msb()->evaluate(ent, scope, begin_val)) {
231 cerr << range->msb()->get_fileline() << ": error: "
232 << "Unable to evaluate aggregate choice expression." << endl;
233 errors += 1;
234 continue;
235 }
236
237 if (! range->lsb()->evaluate(ent, scope, end_val)) {
238 cerr << range->msb()->get_fileline() << ": error: "
239 << "Unable to evaluate aggregate choice expression." << endl;
240 errors += 1;
241 continue;
242 }
243
244 if (begin_val < end_val) {
245 int64_t tmp = begin_val;
246 begin_val = end_val;
247 end_val = tmp;
248 }
249
250 while (begin_val >= end_val) {
251 element_map[begin_val] = &aggregate_[idx];
252 begin_val -= 1;
253 }
254
255 continue;
256 }
257
258 int64_t tmp_val;
259 Expression*tmp = aggregate_[idx].choice->simple_expression(false);
260 ivl_assert(*this, tmp);
261
262 // Named aggregate element. Once we see one of
263 // these, we can no longer accept positional
264 // elements so disable further positional
265 // processing.
266 positional_section = false;
267 if (! tmp->evaluate(ent, scope, tmp_val)) {
268 cerr << tmp->get_fileline() << ": error: "
269 << "Unable to evaluate aggregate choice expression." << endl;
270 errors += 1;
271 continue;
272 }
273
274 element_map[tmp_val] = &aggregate_[idx];
275 }
276
277 // Emit the elements as a concatenation. This works great for
278 // vectors of bits. We implement VHDL arrays as packed arrays,
279 // so this should be generally correct.
280 // TODO uncomment this once ivl supports assignments of '{}
281 /*if(!peek_type()->can_be_packed())
282 out << "'";*/
283
284 out << "{";
285 for (int64_t idx = use_msb ; idx >= use_lsb ; idx -= 1) {
286 const choice_element*cur = element_map[idx];
287 if (cur == 0)
288 cur = element_other;
289
290 if (idx < use_msb)
291 out << ", ";
292 if (cur == 0) {
293 out << "/* Missing element " << idx << " */";
294 cerr << get_fileline() << ": error: "
295 << "Missing element " << idx << "." << endl;
296 errors += 1;
297 } else {
298 errors += cur->expr->emit(out, ent, scope);
299 }
300 }
301 out << "}";
302
303 return errors;
304 }
305
emit_record_(ostream & out,Entity * ent,ScopeBase * scope,const VTypeRecord *) const306 int ExpAggregate::emit_record_(ostream&out, Entity*ent, ScopeBase*scope, const VTypeRecord*) const
307 {
308 int errors = 0;
309
310 out << "{";
311
312 for (size_t idx = 0 ; idx < aggregate_.size() ; idx += 1) {
313 ivl_assert(*this, !aggregate_[idx].choice->others());
314 ivl_assert(*this, !aggregate_[idx].choice->range_expressions());
315
316 //Expression*name = aggregate_[idx].choice->simple_expression(false);
317 //ivl_assert(*this, name);
318 Expression*val = aggregate_[idx].expr;
319 ivl_assert(*this, val);
320
321 if(idx != 0)
322 out << ",";
323
324 //errors += name->emit(out, ent, scope);
325 //out << ": ";
326 errors += val->emit(out, ent, scope);
327 }
328
329 out << "}";
330
331 return errors;
332 }
333
emit(ostream & out,Entity * ent,ScopeBase * scope) const334 int ExpObjAttribute::emit(ostream&out, Entity*ent, ScopeBase*scope) const
335 {
336 int errors = 0;
337
338 // Try to evaluate first
339 int64_t val;
340 if(evaluate(ent, scope, val)) {
341 out << val;
342 return 0;
343 }
344
345 if (name_ == "event") {
346 out << "$ivlh_attribute_event(";
347 errors += base_->emit(out, ent, scope);
348 out << ")";
349 return errors;
350 }
351
352 /* Special Case: The length,left & right attributes can be calculated
353 all the down to a literal integer at compile time, and all it
354 needs is the type of the base expression. (The base
355 expression doesn't even need to be evaluated.) */
356 if (name_=="length") {
357 out << "$bits(";
358 errors += base_->emit(out, ent, scope);
359 out << ")";
360 return errors;
361 } else if (name_=="left" || name_=="right") {
362 out << "$" << name_ << "(";
363 errors += base_->emit(out, ent, scope);
364 out << ")";
365 return errors;
366 }
367
368 // Fallback
369 out << "$ivl_attribute(";
370 errors += base_->emit(out, ent, scope);
371 out << ", \"" << name_ << "\")";
372 return errors;
373 }
374
emit(ostream & out,Entity * ent,ScopeBase * scope) const375 int ExpTypeAttribute::emit(ostream&out, Entity*ent, ScopeBase*scope) const
376 {
377 int errors = 0;
378
379 // Special case: The image attribute
380 if (name_=="image") {
381 if(!args_ || args_->size() != 1) {
382 out << "/* Invalid 'image attribute */" << endl;
383 cerr << get_fileline() << ": error: 'image attribute takes "
384 << "exactly one argument." << endl;
385 ++errors;
386 } else {
387 out << "$sformatf(\"";
388
389 if(base_->type_match(&primitive_INTEGER))
390 out << "%0d";
391 else if(base_->type_match(&primitive_REAL))
392 out << "%f";
393 else if(base_->type_match(&primitive_CHARACTER))
394 out << "'%c'";
395 else if(base_->type_match(&primitive_TIME))
396 out << "%+0t";
397
398 out << "\",";
399 args_->front()->emit(out, ent, scope);
400 out << ")";
401 }
402 return errors;
403 }
404
405 // Fallback
406 out << "$ivl_attribute(";
407 errors += base_->emit_def(out, empty_perm_string);
408 out << ", \"" << name_ << "\")";
409 return errors;
410 }
411
emit(ostream & out,Entity * ent,ScopeBase * scope) const412 int ExpArithmetic::emit(ostream&out, Entity*ent, ScopeBase*scope) const
413 {
414 int errors = 0;
415
416 if(fun_ == REM) {
417 // Special case: division remainder, defined in the VHDL standard 1076-2008/9.2.7
418 // there is no direct counterpart, therefore output the formula to
419 // compute a remainder: A rem B = A - (A/B) * B;
420 out << "((";
421 errors += emit_operand1(out, ent, scope);
422 out << ")-((";
423 errors += emit_operand1(out, ent, scope);
424 out << ")/(";
425 errors += emit_operand2(out, ent, scope);
426 out << "))*(";
427 errors += emit_operand2(out, ent, scope);
428 out << "))";
429 return errors;
430 }
431
432 errors += emit_operand1(out, ent, scope);
433
434 switch (fun_) {
435 case PLUS:
436 out << " + ";
437 break;
438 case MINUS:
439 out << " - ";
440 break;
441 case MULT:
442 out << " * ";
443 break;
444 case DIV:
445 out << " / ";
446 break;
447 case MOD:
448 out << " % ";
449 break;
450 case POW:
451 out << " ** ";
452 break;
453 case REM: // should not happen as it is handled above, suppress warnings
454 ivl_assert(*this, 0);
455 case xCONCAT:
456 ivl_assert(*this, 0);
457 out << " /* ?concat? */ ";
458 break;
459 }
460
461 errors += emit_operand2(out, ent, scope);
462
463 return errors;
464 }
465
emit(ostream & out,Entity *,ScopeBase *) const466 int ExpBitstring::emit(ostream&out, Entity*, ScopeBase*) const
467 {
468 int errors = 0;
469
470 out << value_.size() << "'b";
471 for (size_t idx = 0 ; idx < value_.size() ; idx += 1)
472 out << value_[value_.size()-idx-1];
473
474 return errors;
475 }
476
emit_primitive_bit_(ostream & out,Entity *,ScopeBase *,const VTypePrimitive * etype) const477 int ExpCharacter::emit_primitive_bit_(ostream&out, Entity*, ScopeBase*,
478 const VTypePrimitive*etype) const
479 {
480 out << "1'b";
481 int res = emit_logic(value_, out, etype->type());
482
483 if(res)
484 cerr << get_fileline() << ": internal error: "
485 << "Don't know how to handle bit " << value_
486 << " with etype==" << etype->type() << endl;
487
488 return res;
489 }
490
emit(ostream & out,Entity * ent,ScopeBase * scope) const491 int ExpCharacter::emit(ostream&out, Entity*ent, ScopeBase*scope) const
492 {
493 const VType*etype = peek_type();
494 const VTypeArray*array;
495
496 if (etype != &primitive_CHARACTER && (array = dynamic_cast<const VTypeArray*>(etype))) {
497 etype = array->element_type();
498 }
499
500 if (const VTypePrimitive*use_type = dynamic_cast<const VTypePrimitive*>(etype)) {
501 return emit_primitive_bit_(out, ent, scope, use_type);
502 }
503
504 out << "\"" << value_ << "\"";
505 return 0;
506 }
507
is_primary(void) const508 bool ExpCharacter::is_primary(void) const
509 {
510 return true;
511 }
512
513 /*
514 * This is not exactly a "primary", but it is wrapped in its own
515 * parentheses (braces) so we return true here.
516 */
is_primary(void) const517 bool ExpConcat::is_primary(void) const
518 {
519 return true;
520 }
521
emit(ostream & out,Entity * ent,ScopeBase * scope) const522 int ExpConcat::emit(ostream&out, Entity*ent, ScopeBase*scope) const
523 {
524 int errors = 0;
525 out << "{";
526 errors += operand1_->emit(out, ent, scope);
527 out << ", ";
528 errors += operand2_->emit(out, ent, scope);
529 out << "}";
530 return errors;
531 }
532
emit(ostream & out,Entity * ent,ScopeBase * scope) const533 int ExpConditional::emit(ostream&out, Entity*ent, ScopeBase*scope) const
534 {
535 int errors = 0;
536 out << "(";
537
538 // Draw out any when-else expressions. These are all the else_
539 // clauses besides the last.
540 if (options_.size() > 1) {
541 list<case_t*>::const_iterator last = options_.end();
542 --last;
543
544 for (list<case_t*>::const_iterator cur = options_.begin()
545 ; cur != last ; ++cur) {
546 errors += (*cur)->emit_option(out, ent, scope);
547 }
548 }
549
550 errors += options_.back()->emit_default(out, ent, scope);
551 out << ")";
552
553 // The emit_option() functions do not close the last
554 // parentheses so that the following expression can be
555 // nested. But that means come the end, we have some
556 // expressions to close.
557 for (size_t idx = 1 ; idx < options_.size() ; idx += 1)
558 out << ")";
559
560 return errors;
561 }
562
emit_option(ostream & out,Entity * ent,ScopeBase * scope) const563 int ExpConditional::case_t::emit_option(ostream&out, Entity*ent, ScopeBase*scope) const
564 {
565 int errors = 0;
566 assert(cond_ != 0);
567
568 out << "(";
569 errors += cond_->emit(out, ent, scope);
570 out << ")? (";
571
572 if (true_clause_.size() > 1) {
573 cerr << get_fileline() << ": sorry: Multiple expression waveforms not supported here." << endl;
574 errors += 1;
575 }
576
577 Expression*tmp = true_clause_.front();
578 errors += tmp->emit(out, ent, scope);
579
580 out << ") : (";
581
582 return errors;
583 }
584
emit_default(ostream & out,Entity * ent,ScopeBase * scope) const585 int ExpConditional::case_t::emit_default(ostream&out, Entity*ent, ScopeBase*scope) const
586 {
587 int errors = 0;
588 // Trailing else must have no condition.
589 assert(cond_ == 0);
590
591 if (true_clause_.size() > 1) {
592 cerr << get_fileline() << ": sorry: Multiple expression waveforms not supported here." << endl;
593 errors += 1;
594 }
595
596 Expression*tmp = true_clause_.front();
597 errors += tmp->emit(out, ent, scope);
598
599 return errors;
600 }
601
emit(ostream & out,Entity * ent,ScopeBase * scope) const602 int ExpEdge::emit(ostream&out, Entity*ent, ScopeBase*scope) const
603 {
604 int errors = 0;
605 switch (fun_) {
606 case NEGEDGE:
607 out << "negedge ";
608 break;
609 case POSEDGE:
610 out << "posedge ";
611 break;
612 case ANYEDGE:
613 break;
614 }
615 errors += emit_operand1(out, ent, scope);
616 return errors;
617 }
618
emit(ostream & out,Entity * ent,ScopeBase * scope) const619 int ExpFunc::emit(ostream&out, Entity*ent, ScopeBase*scope) const
620 {
621 int errors = 0;
622
623 if(!def_) {
624 cerr << get_fileline() << ": error: unknown function: " << name_ << endl;
625 return 1;
626 }
627
628 def_->emit_full_name(argv_, out, ent, scope);
629 out << " (";
630 def_->emit_args(argv_, out, ent, scope);
631 out << ")";
632
633 return errors;
634 }
635
emit(ostream & out,Entity *,ScopeBase *) const636 int ExpInteger::emit(ostream&out, Entity*, ScopeBase*) const
637 {
638 out << "32'd" << value_;
639 return 0;
640 }
641
emit_package(ostream & out) const642 int ExpInteger::emit_package(ostream&out) const
643 {
644 out << value_;
645 return 0;
646 }
647
emit(ostream & out,Entity *,ScopeBase *) const648 int ExpReal::emit(ostream&out, Entity*, ScopeBase*) const
649 {
650 out << value_;
651 return 0;
652 }
653
emit_package(ostream & out) const654 int ExpReal::emit_package(ostream&out) const
655 {
656 out << value_;
657 return 0;
658 }
659
is_primary(void) const660 bool ExpReal::is_primary(void) const
661 {
662 return true;
663 }
664
emit(ostream & out,Entity * ent,ScopeBase * scope) const665 int ExpLogical::emit(ostream&out, Entity*ent, ScopeBase*scope) const
666 {
667 int errors = 0;
668
669 errors += emit_operand1(out, ent, scope);
670
671 switch (fun_) {
672 case AND:
673 out << " & ";
674 break;
675 case OR:
676 out << " | ";
677 break;
678 case XOR:
679 out << " ^ ";
680 break;
681 case NAND:
682 out << " ~& ";
683 break;
684 case NOR:
685 out << " ~| ";
686 break;
687 case XNOR:
688 out << " ~^ ";
689 break;
690 }
691
692 errors += emit_operand2(out, ent, scope);
693
694 return errors;
695 }
696
emit_indices(ostream & out,Entity * ent,ScopeBase * scope) const697 int ExpName::emit_indices(ostream&out, Entity*ent, ScopeBase*scope) const
698 {
699 int errors = 0;
700
701 if (indices_) {
702 for(list<Expression*>::const_iterator it = indices_->begin();
703 it != indices_->end(); ++it) {
704 out << "[";
705 errors += (*it)->emit(out, ent, scope);
706 out << "]";
707 }
708 }
709
710 return errors;
711 }
712
emit_as_prefix_(ostream & out,Entity * ent,ScopeBase * scope) const713 int ExpName::emit_as_prefix_(ostream&out, Entity*ent, ScopeBase*scope) const
714 {
715 int errors = 0;
716 if (prefix_.get()) {
717 errors += prefix_->emit_as_prefix_(out, ent, scope);
718 }
719
720 out << "\\" << name_ << " ";
721 errors += emit_indices(out, ent, scope);
722 out << ".";
723 return errors;
724 }
725
emit(ostream & out,Entity * ent,ScopeBase * scope) const726 int ExpName::emit(ostream&out, Entity*ent, ScopeBase*scope) const
727 {
728 int errors = 0;
729 int field_size = 0;
730 list<index_t*> indices;
731
732 if(try_workarounds_(out, ent, scope, indices, field_size)) {
733 emit_workaround_(out, ent, scope, indices, field_size);
734 for(list<index_t*>::iterator it = indices.begin();
735 it != indices.end(); ++it)
736 {
737 delete *it;
738 }
739 return 0;
740 }
741
742 if (prefix_.get()) {
743 errors += prefix_->emit_as_prefix_(out, ent, scope);
744 }
745
746 const GenerateStatement*gs = 0;
747 Architecture*arc = dynamic_cast<Architecture*>(scope);
748 if (arc && (gs = arc->probe_genvar_emit(name_)))
749 out << "\\" << gs->get_name() << ":" << name_ << " ";
750 else
751 out << "\\" << name_ << " ";
752
753 errors += emit_indices(out, ent, scope);
754
755 return errors;
756 }
757
try_workarounds_(ostream & out,Entity * ent,ScopeBase * scope,list<index_t * > & indices,int & data_size) const758 bool ExpName::try_workarounds_(ostream&out, Entity*ent, ScopeBase*scope,
759 list<index_t*>& indices, int& data_size) const
760 {
761 Expression*exp = NULL;
762 bool wrkand_required = false;
763 const VType*type = NULL;
764 Expression*idx = index(0);
765 ExpRange*range = dynamic_cast<ExpRange*>(idx);
766
767 if(!scope)
768 return false;
769
770 if(prefix_.get())
771 prefix_->try_workarounds_(out, ent, scope, indices, data_size);
772
773 if(idx && !range && scope->find_constant(name_, type, exp)) {
774 while(const VTypeDef*type_def = dynamic_cast<const VTypeDef*>(type)) {
775 type = type_def->peek_definition();
776 }
777
778 const VTypeArray*arr = dynamic_cast<const VTypeArray*>(type);
779 assert(arr);
780 wrkand_required |= check_const_array_workaround_(arr, scope, indices, data_size);
781 }
782
783 if(prefix_.get() && scope->find_constant(prefix_->name_, type, exp)) {
784 // Handle the case of array of records
785 if(prefix_->index(0)) {
786 const VTypeArray*arr = dynamic_cast<const VTypeArray*>(type);
787 assert(arr);
788 type = arr->element_type();
789 data_size = type->get_width(scope);
790 }
791
792 while(const VTypeDef*type_def = dynamic_cast<const VTypeDef*>(type)) {
793 type = type_def->peek_definition();
794 }
795
796 const VTypeRecord*rec = dynamic_cast<const VTypeRecord*>(type);
797 assert(rec);
798
799 wrkand_required |= check_const_record_workaround_(rec, scope, indices, data_size);
800 }
801
802 // Workarounds are currently implemented only for one-dimensional arrays
803 assert(!indices_ || indices_->size() == 1 || !wrkand_required);
804
805 return wrkand_required;
806 }
807
check_const_array_workaround_(const VTypeArray * arr,ScopeBase * scope,list<index_t * > & indices,int & data_size) const808 bool ExpName::check_const_array_workaround_(const VTypeArray*arr,
809 ScopeBase*scope, list<index_t*>&indices, int&data_size) const
810 {
811 assert(indices_ && indices_->size() == 1);
812
813 const VType*element = arr->element_type();
814 data_size = element->get_width(scope);
815 if(data_size < 0)
816 return false;
817
818 indices.push_back(new index_t(index(0)->clone(), new ExpInteger(data_size)));
819
820 return true;
821 }
822
check_const_record_workaround_(const VTypeRecord * rec,ScopeBase * scope,list<index_t * > & indices,int & data_size) const823 bool ExpName::check_const_record_workaround_(const VTypeRecord*rec,
824 ScopeBase*scope, list<index_t*>&indices, int&data_size) const
825 {
826 int tmp_offset = 0;
827 const vector<VTypeRecord::element_t*>& elements = rec->get_elements();
828
829 for(vector<VTypeRecord::element_t*>::const_reverse_iterator it = elements.rbegin();
830 it != elements.rend(); ++it) {
831 VTypeRecord::element_t* el = (*it);
832
833 if(el->peek_name() == name_) {
834 const VType*type = el->peek_type();
835
836 int tmp_field = type->get_width(scope);
837 if(tmp_field < 0)
838 return false;
839
840 data_size = tmp_field;
841 indices.push_back(new index_t(NULL, NULL, new ExpInteger(tmp_offset)));
842
843 if(index(0)) {
844 const VTypeArray*arr = dynamic_cast<const VTypeArray*>(type);
845 assert(arr);
846 return check_const_array_workaround_(arr, scope, indices, data_size);
847 }
848
849 return true;
850 }
851
852 int w = el->peek_type()->get_width(scope);
853
854 if(w < 0)
855 return false;
856
857 tmp_offset += w;
858 }
859
860 return false;
861 }
862
emit_workaround_(ostream & out,Entity * ent,ScopeBase * scope,const list<index_t * > & indices,int field_size) const863 int ExpName::emit_workaround_(ostream&out, Entity*ent, ScopeBase*scope,
864 const list<index_t*>& indices, int field_size) const
865 {
866 int errors = 0;
867
868 out << "\\" << (prefix_.get() ? prefix_->name_ : name_) << " [";
869
870 for(list<index_t*>::const_iterator it = indices.begin();
871 it != indices.end(); ++it) {
872 errors += (*it)->emit(out, ent, scope);
873 out << "+";
874 }
875
876 out << ":" << field_size << "]";
877
878 return errors;
879 }
880
is_primary(void) const881 bool ExpName::is_primary(void) const
882 {
883 return true;
884 }
885
emit(ostream & out,Entity * ent,ScopeBase * scope) const886 int ExpRelation::emit(ostream&out, Entity*ent, ScopeBase*scope) const
887 {
888 int errors = 0;
889 errors += emit_operand1(out, ent, scope);
890
891 const VType*type1 = peek_operand1()->probe_type(ent, scope);
892 const VType*type2 = peek_operand2()->probe_type(ent, scope);
893 bool logical_compare = false;
894
895 // Apply case equality operator if any of the operands is of logic type
896 if(((type1 && (type1->type_match(&primitive_STDLOGIC) ||
897 type1->type_match(&primitive_STDLOGIC_VECTOR)))
898 || (type2 && (type2->type_match(&primitive_STDLOGIC) ||
899 type2->type_match(&primitive_STDLOGIC_VECTOR))))) {
900 logical_compare = true;
901 }
902
903 switch (fun_) {
904 case EQ:
905 out << (logical_compare ? " === " : " == ");
906 break;
907 case LT:
908 out << " < ";
909 break;
910 case GT:
911 out << " > ";
912 break;
913 case NEQ:
914 out << (logical_compare ? " !== " : " != ");
915 break;
916 case LE:
917 out << " <= ";
918 break;
919 case GE:
920 out << " >= ";
921 break;
922 }
923
924 errors += emit_operand2(out, ent, scope);
925 return errors;
926 }
927
emit(ostream & out,Entity * ent,ScopeBase * scope) const928 int ExpShift::emit(ostream&out, Entity*ent, ScopeBase*scope) const
929 {
930 int errors = 0;
931
932 errors += emit_operand1(out, ent, scope);
933
934 switch (shift_) {
935 case SRL:
936 out << " >> ";
937 break;
938 case SLL:
939 out << " << ";
940 break;
941 case SRA:
942 out << " >>> ";
943 break;
944 case SLA:
945 out << " <<< ";
946 break;
947 case ROR:
948 case ROL:
949 out << " /* ?ror/rol? */ ";
950 break;
951 }
952
953 errors += emit_operand2(out, ent, scope);
954
955 return errors;
956 }
957
is_primary(void) const958 bool ExpString::is_primary(void) const
959 {
960 return true;
961 }
962
emit(ostream & out,Entity * ent,ScopeBase * scope) const963 int ExpString::emit(ostream& out, Entity*ent, ScopeBase*scope) const
964 {
965 const VTypeArray*arr;
966 const VType*type = peek_type();
967 assert(type != 0);
968
969 if (type != &primitive_STRING && (arr = dynamic_cast<const VTypeArray*>(type))) {
970 return emit_as_array_(out, ent, scope, arr);
971 }
972
973 out << "\"" << escape_quot(value_) << "\"";
974
975 return 0;
976 }
977
emit_as_array_(ostream & out,Entity *,ScopeBase *,const VTypeArray * arr) const978 int ExpString::emit_as_array_(ostream& out, Entity*, ScopeBase*, const VTypeArray*arr) const
979 {
980 int errors = 0;
981 assert(arr->dimensions().size() == 1);
982
983 const VTypePrimitive*etype = dynamic_cast<const VTypePrimitive*> (arr->basic_type());
984 assert(etype);
985
986 // Detect the special case that this is an array of
987 // CHARACTER. In this case, emit at a Verilog string.
988 if (arr->element_type() == &primitive_CHARACTER) {
989 vector<char> tmp (value_.size() + 3);
990 tmp[0] = '"';
991 memcpy(&tmp[1], &value_[0], value_.size());
992 tmp[value_.size()+1] = '"';
993 tmp[value_.size()+2] = 0;
994 out << &tmp[0];
995 return errors;
996 }
997
998 assert(etype->type() != VTypePrimitive::INTEGER);
999 out << value_.size() << "'b";
1000 for (size_t idx = 0 ; idx < value_.size() ; idx += 1) {
1001 int res = emit_logic(value_[idx], out, etype->type());
1002 errors += res;
1003
1004 if(res)
1005 cerr << get_fileline() << ": internal error: "
1006 << "Don't know how to handle bit " << value_[idx]
1007 << " with etype==" << etype->type() << endl;
1008 }
1009
1010 return errors;
1011 }
1012
escape_quot(const std::string & str)1013 std::string ExpString::escape_quot(const std::string& str)
1014 {
1015 size_t idx = 0;
1016 string result(str);
1017
1018 while((idx = result.find('"', idx)) != string::npos) {
1019 result.replace(idx, 1, "\\\"");
1020 idx += 2;
1021 }
1022
1023 return result;
1024 }
1025
emit(ostream & out,Entity * ent,ScopeBase * scope) const1026 int ExpUAbs::emit(ostream&out, Entity*ent, ScopeBase*scope) const
1027 {
1028 int errors = 0;
1029 out << "abs(";
1030 errors += emit_operand1(out, ent, scope);
1031 out << ")";
1032 return errors;
1033 }
1034
emit(ostream & out,Entity * ent,ScopeBase * scope) const1035 int ExpUNot::emit(ostream&out, Entity*ent, ScopeBase*scope) const
1036 {
1037 int errors = 0;
1038
1039 const VType*op_type = peek_operand()->probe_type(ent, scope);
1040
1041 if(op_type && op_type->type_match(&type_BOOLEAN))
1042 out << "!(";
1043 else
1044 out << "~(";
1045
1046 errors += emit_operand1(out, ent, scope);
1047 out << ")";
1048 return errors;
1049 }
1050
emit(ostream & out,Entity * ent,ScopeBase * scope) const1051 int ExpUMinus::emit(ostream&out, Entity*ent, ScopeBase*scope) const
1052 {
1053 int errors = 0;
1054 out << "-(";
1055 errors += emit_operand1(out, ent, scope);
1056 out << ")";
1057 return errors;
1058 }
1059
emit(ostream & out,Entity * ent,ScopeBase * scope) const1060 int ExpCast::emit(ostream&out, Entity*ent, ScopeBase*scope) const
1061 {
1062 int errors = 0;
1063 errors += type_->emit_def(out, empty_perm_string);
1064 out << "'(";
1065 errors += base_->emit(out, ent, scope);
1066 out << ")";
1067 return errors;
1068 }
1069
emit(ostream & out,Entity * ent,ScopeBase * scope) const1070 int ExpNew::emit(ostream&out, Entity*ent, ScopeBase*scope) const
1071 {
1072 int errors = 0;
1073 out << "new[";
1074 errors += size_->emit(out, ent, scope);
1075 out << "]";
1076 return errors;
1077 }
1078
emit(ostream & out,Entity *,ScopeBase *) const1079 int ExpTime::emit(ostream&out, Entity*, ScopeBase*) const
1080 {
1081 out << amount_;
1082
1083 switch(unit_) {
1084 case FS: out << "fs"; break;
1085 case PS: out << "ps"; break;
1086 case NS: out << "ns"; break;
1087 case US: out << "us"; break;
1088 case MS: out << "ms"; break;
1089 case S: out << "s"; break;
1090 }
1091
1092 return 0;
1093 }
1094
emit(ostream & out,Entity * ent,ScopeBase * scope) const1095 int ExpRange::emit(ostream&out, Entity*ent, ScopeBase*scope) const
1096 {
1097 int errors = 0;
1098
1099 if(range_expr_) {
1100 out << "$left(";
1101 errors += range_base_->emit(out, ent, scope);
1102 out << "):$right(";
1103 errors += range_base_->emit(out, ent, scope);
1104 out << ")";
1105 } else if(direction_ == AUTO) {
1106 ivl_assert(*this, false);
1107 out << "/* auto dir */";
1108 } else {
1109 errors += left_->emit(out, ent, scope);
1110 out << ":";
1111 errors += right_->emit(out, ent, scope);
1112 }
1113
1114 return errors;
1115 }
1116
emit(ostream & out,Entity * ent,ScopeBase * scope) const1117 int ExpDelay::emit(ostream&out, Entity*ent, ScopeBase*scope) const
1118 {
1119 int errors = 0;
1120
1121 out << "#(";
1122 errors += delay_->emit(out, ent, scope);
1123 out << ") ";
1124 errors += expr_->emit(out, ent, scope);
1125
1126 return errors;
1127 }
1128