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