1 #ifndef IVL_expression_H
2 #define IVL_expression_H
3 /*
4 * Copyright (c) 2011-2018 Stephen Williams (steve@icarus.com)
5 * Copyright CERN 2015 / Stephen Williams (steve@icarus.com),
6 * Copyright CERN 2016
7 * @author Maciej Suminski (maciej.suminski@cern.ch)
8 *
9 * This source code is free software; you can redistribute it
10 * and/or modify it in source code form under the terms of the GNU
11 * General Public License as published by the Free Software
12 * Foundation; either version 2 of the License, or (at your option)
13 * any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 */
24
25 # include "StringHeap.h"
26 # include "LineInfo.h"
27 # include "entity.h"
28 # include <inttypes.h>
29 # include <list>
30 # include <memory>
31 # include <vector>
32 # include <cassert>
33
34 class ExpRange;
35 class ScopeBase;
36 class SubprogramHeader;
37 class VType;
38 class VTypeArray;
39 class VTypePrimitive;
40 class ExpName;
41
42 #if __cplusplus < 201103L
43 #define unique_ptr auto_ptr
44 #endif
45
46 /*
47 * Helper class to recursively traverse an expression tree
48 * (i.e. complex expressions).
49 */
50 struct ExprVisitor {
ExprVisitorExprVisitor51 ExprVisitor() : level_(0) {}
~ExprVisitorExprVisitor52 virtual ~ExprVisitor() {}
53 virtual void operator() (Expression*s) = 0;
54
55 // Methods to manage recursion depth. Every Expression::visit() method
56 // should call down() in the beginning and up() in the end.
downExprVisitor57 inline void down() { ++level_; }
upExprVisitor58 inline void up() { --level_; assert(level_ >= 0); }
59
60 protected:
levelExprVisitor61 int level() const { return level_; }
62
63 private:
64 int level_;
65 };
66
67 /*
68 * The Expression class represents parsed expressions from the parsed
69 * VHDL input. The Expression class is a virtual class that holds more
70 * specific derived expression types.
71 */
72 class Expression : public LineInfo {
73
74 public:
75 Expression();
76 virtual ~Expression() =0;
77
78 // Returns a deep copy of the expression.
79 virtual Expression*clone() const =0;
80
81 // This virtual method handles the special case of elaborating
82 // an expression that is the l-value of a sequential variable
83 // assignment. This generates an error for most cases, but
84 // expressions that are valid l-values return 0 and set any
85 // flags needed to indicate their status as writable variables.
86 virtual int elaborate_lval(Entity*ent, ScopeBase*scope,
87 bool is_sequ);
88
89 // This virtual method probes the expression to get the most
90 // constrained type for the expression. For a given instance,
91 // this may be called before the elaborate_expr method.
92 virtual const VType*probe_type(Entity*ent, ScopeBase*scope) const;
93
94 // The fit_type virtual method is used by the ExpConcat class
95 // to probe the type of operands. The atype argument is the
96 // type of the ExpConcat expression itself. This expression
97 // returns its type as interpreted in this context. Really,
98 // this is mostly about helping aggregate expressions within
99 // concatenations to figure out their type.
100 virtual const VType*fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*atype) const;
101
102 // This virtual method elaborates an expression. The ltype is
103 // the type of the lvalue expression, if known, and can be
104 // used to calculate the type for the expression being
105 // elaborated.
106 virtual int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
107
108 // Return the type that this expression would be if it were an
109 // l-value. This should only be called after elaborate_lval is
110 // called and only if elaborate_lval succeeded.
peek_type(void)111 inline const VType*peek_type(void) const { return type_; }
112
113 // This virtual method writes a VHDL-accurate representation
114 // of this expression to the designated stream. This is used
115 // for writing parsed types to library files.
116 virtual void write_to_stream(std::ostream&fd) const =0;
117
118 // The emit virtual method is called by architecture emit to
119 // output the generated code for the expression. The derived
120 // class fills in the details of what exactly happened.
121 virtual int emit(ostream&out, Entity*ent, ScopeBase*scope) const =0;
122
123 // The emit_package virtual message is similar, but is called
124 // in a package context and to emit SV packages.
125 virtual int emit_package(std::ostream&out) const;
126
127 // The evaluate virtual method tries to evaluate expressions
128 // to constant literal values. Return true and set the val
129 // argument if the evaluation works, or return false if it
130 // cannot be done.
evaluate(Entity *,ScopeBase *,int64_t &)131 virtual bool evaluate(Entity*, ScopeBase*, int64_t&) const { return false; }
evaluate(ScopeBase * scope,int64_t & val)132 bool evaluate(ScopeBase*scope, int64_t&val) const { return evaluate(NULL, scope, val); }
133
134 // The symbolic compare returns true if the two expressions
135 // are equal without actually calculating the value.
136 virtual bool symbolic_compare(const Expression*that) const;
137
138 // This method returns true if the drawn Verilog for this
139 // expression is a primary. A containing expression can use
140 // this method to know if it needs to wrap parentheses. This
141 // is somewhat optional, so it is better to return false if
142 // not certain. The default implementation does return false.
143 virtual bool is_primary(void) const;
144
145 // Debug dump of the expression.
146 virtual void dump(ostream&out, int indent = 0) const =0;
147 virtual ostream& dump_inline(ostream&out) const;
148
149 // Recursively visits a tree of expressions (useful for complex expressions).
visit(ExprVisitor & func)150 virtual void visit(ExprVisitor& func) { func.down(); func(this); func.up(); }
151
152 protected:
153 // This function is called by the derived class during
154 // elaboration to set the type of the current expression that
155 // elaboration assigns to this expression.
156 void set_type(const VType*);
157
158 private:
159 const VType*type_;
160
161 private: // Not implemented
162 Expression(const Expression&);
163 Expression& operator = (const Expression&);
164 };
165
166 /*
167 * Checks before cloning if the other expression actually exists (!=NULL).
168 */
safe_clone(const Expression * other)169 static inline Expression*safe_clone(const Expression*other) {
170 return (other ? other->clone() : NULL);
171 }
172
FILE_NAME(Expression * tgt,const LineInfo * src)173 static inline void FILE_NAME(Expression*tgt, const LineInfo*src)
174 {
175 tgt->set_line(*src);
176 }
177
178 static inline ostream& operator <<(ostream&out, const Expression&exp)
179 {
180 return exp.dump_inline(out);
181 }
182
183 class ExpUnary : public Expression {
184
185 public:
186 explicit ExpUnary(Expression*op1);
187 virtual ~ExpUnary() =0;
188
peek_operand()189 inline const Expression*peek_operand() const { return operand1_; }
190
191 const VType*fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*atype) const;
192 const VType*probe_type(Entity*ent, ScopeBase*scope) const;
193 int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
194 void visit(ExprVisitor& func);
195
196 protected:
write_to_stream_operand1(std::ostream & fd)197 inline void write_to_stream_operand1(std::ostream&fd) const
198 { operand1_->write_to_stream(fd); }
199
200 int emit_operand1(ostream&out, Entity*ent, ScopeBase*scope) const;
201 void dump_operand1(ostream&out, int indent = 0) const;
202
203 private:
204 Expression*operand1_;
205 };
206
207 /*
208 * This is an abstract class that collects some of the common features
209 * of binary operators.
210 */
211 class ExpBinary : public Expression {
212
213 public:
214 ExpBinary(Expression*op1, Expression*op2);
215 virtual ~ExpBinary() =0;
216
peek_operand1(void)217 inline const Expression* peek_operand1(void) const { return operand1_; }
peek_operand2(void)218 inline const Expression* peek_operand2(void) const { return operand2_; }
219
220 const VType*probe_type(Entity*ent, ScopeBase*scope) const;
221 void visit(ExprVisitor& func);
222
223 protected:
224
225 int elaborate_exprs(Entity*, ScopeBase*, const VType*);
226 int emit_operand1(ostream&out, Entity*ent, ScopeBase*scope) const;
227 int emit_operand2(ostream&out, Entity*ent, ScopeBase*scope) const;
228
229 bool eval_operand1(Entity*ent, ScopeBase*scope, int64_t&val) const;
230 bool eval_operand2(Entity*ent, ScopeBase*scope, int64_t&val) const;
231
write_to_stream_operand1(std::ostream & out)232 inline void write_to_stream_operand1(std::ostream&out) const
233 { operand1_->write_to_stream(out); }
write_to_stream_operand2(std::ostream & out)234 inline void write_to_stream_operand2(std::ostream&out) const
235 { operand2_->write_to_stream(out); }
236
237 void dump_operands(ostream&out, int indent = 0) const;
238
239 private:
240 virtual const VType*resolve_operand_types_(const VType*t1, const VType*t2) const;
241
242 private:
243 Expression*operand1_;
244 Expression*operand2_;
245 };
246
247 class ExpAggregate : public Expression {
248
249 public:
250 // A "choice" is only part of an element. It is the thing that
251 // is used to identify an element of the aggregate. It can
252 // represent the index (or range) of an array, or the name of
253 // a record member.
254 class choice_t {
255 public:
256 // Create an "others" choice
257 choice_t();
258 // Create a simple_expression choice
259 explicit choice_t(Expression*exp);
260 // Create a named choice
261 explicit choice_t(perm_string name);
262 // discreate_range choice
263 explicit choice_t(ExpRange*ran);
264
265 choice_t(const choice_t&other);
266
267 ~choice_t();
268
269 // true if this represents an "others" choice
270 bool others() const;
271 // Return expression if this represents a simple_expression.
272 Expression*simple_expression(bool detach_flag =true);
273 // Return ExpRange if this represents a range_expression
274 ExpRange*range_expressions(void);
275
276 void write_to_stream(std::ostream&fd);
277 void dump(ostream&out, int indent) const;
278
279 private:
280 std::unique_ptr<Expression>expr_;
281 std::unique_ptr<ExpRange> range_;
282 private: // not implemented
283 choice_t& operator= (const choice_t&);
284 };
285
286 struct choice_element {
choice_elementchoice_element287 choice_element() : choice(), expr() {}
288
choice_elementchoice_element289 choice_element(const choice_element&other) {
290 choice = other.choice ? new choice_t(*other.choice) : NULL;
291 expr = safe_clone(other.expr);
292 }
293
294 choice_t*choice;
295 Expression*expr;
296 bool alias_flag;
297 };
298
299 // Elements are the syntactic items in an aggregate
300 // expression. Each element expressions a bunch of fields
301 // (choices) and binds them to a single expression
302 class element_t {
303 public:
304 explicit element_t(std::list<choice_t*>*fields, Expression*val);
305 element_t(const element_t&other);
306 ~element_t();
307
count_choices()308 size_t count_choices() const { return fields_.size(); }
309 void map_choices(choice_element*dst);
310
extract_expression()311 inline Expression* extract_expression() { return val_; }
312 void write_to_stream(std::ostream&fd) const;
313
314 void dump(ostream&out, int indent) const;
315
316 private:
317 std::vector<choice_t*>fields_;
318 Expression*val_;
319 private: // not implemented
320 element_t& operator = (const element_t&);
321 };
322
323 public:
324 explicit ExpAggregate(std::list<element_t*>*el);
325 ~ExpAggregate();
326
327 Expression*clone() const;
328
329 const VType*fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*atype) const;
330 int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
331 void write_to_stream(std::ostream&fd) const;
332 int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
333 void dump(ostream&out, int indent = 0) const;
334 void visit(ExprVisitor& func);
335
336 private:
337 int elaborate_expr_array_(Entity*ent, ScopeBase*scope, const VTypeArray*ltype);
338 int elaborate_expr_record_(Entity*ent, ScopeBase*scope, const VTypeRecord*ltype);
339 int emit_array_(ostream&out, Entity*ent, ScopeBase*scope, const VTypeArray*ltype) const;
340 int emit_record_(ostream&out, Entity*ent, ScopeBase*scope, const VTypeRecord*ltype) const;
341
342 private:
343 // This is the elements as directly parsed.
344 std::vector<element_t*> elements_;
345
346 // These are the elements after elaboration. This form is
347 // easier to check and emit.
348 std::vector<choice_element> aggregate_;
349 };
350
351 class ExpArithmetic : public ExpBinary {
352
353 public:
354 enum fun_t { PLUS, MINUS, MULT, DIV, MOD, REM, POW, xCONCAT };
355
356 public:
357 ExpArithmetic(ExpArithmetic::fun_t op, Expression*op1, Expression*op2);
358 ~ExpArithmetic();
359
clone()360 Expression*clone() const {
361 return new ExpArithmetic(fun_, peek_operand1()->clone(), peek_operand2()->clone());
362 }
363
364 int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
365 void write_to_stream(std::ostream&fd) const;
366 int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
367 virtual bool evaluate(Entity*ent, ScopeBase*scope, int64_t&val) const;
368 void dump(ostream&out, int indent = 0) const;
369
370 private:
371 const VType* resolve_operand_types_(const VType*t1, const VType*t2) const;
372
373 private:
374 fun_t fun_;
375 };
376
377 class ExpAttribute : public Expression {
378
379 public:
380 ExpAttribute(perm_string name,std::list<Expression*>*args);
381 virtual ~ExpAttribute();
382
peek_attribute()383 inline perm_string peek_attribute() const { return name_; }
384
385 // Constants for the standard attributes
386 static const perm_string LEFT;
387 static const perm_string RIGHT;
388
389 protected:
390 std::list<Expression*>*clone_args() const;
391 int elaborate_args(Entity*ent, ScopeBase*scope, const VType*ltype);
392 void visit_args(ExprVisitor& func);
393
394 bool evaluate_type_attr(const VType*type, Entity*ent, ScopeBase*scope, int64_t&val) const;
395 bool test_array_type(const VType*type) const;
396
397 perm_string name_;
398 std::list<Expression*>*args_;
399 };
400
401 class ExpObjAttribute : public ExpAttribute {
402 public:
403 ExpObjAttribute(ExpName*base, perm_string name, std::list<Expression*>*args);
404 ~ExpObjAttribute();
405
406 Expression*clone() const;
407
peek_base()408 inline const ExpName* peek_base() const { return base_; }
409
410 int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
411 const VType*probe_type(Entity*ent, ScopeBase*scope) const;
412 int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
413 void write_to_stream(std::ostream&fd) const;
414 // Some attributes can be evaluated at compile time
415 bool evaluate(Entity*ent, ScopeBase*scope, int64_t&val) const;
416 void dump(ostream&out, int indent = 0) const;
417 void visit(ExprVisitor& func);
418
419 private:
420 ExpName*base_;
421 };
422
423 class ExpTypeAttribute : public ExpAttribute {
424 public:
425 ExpTypeAttribute(const VType*base, perm_string name, std::list<Expression*>*args);
426 // no destructor - VType objects (base_) are shared between many expressions
427
428 Expression*clone() const;
429
peek_base()430 inline const VType* peek_base() const { return base_; }
431
432 int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
433 const VType*probe_type(Entity*ent, ScopeBase*scope) const;
434 int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
435 void write_to_stream(std::ostream&fd) const;
436 // Some attributes can be evaluated at compile time
437 bool evaluate(ScopeBase*scope, int64_t&val) const;
438 bool evaluate(Entity*ent, ScopeBase*scope, int64_t&val) const;
439 void dump(ostream&out, int indent = 0) const;
440 void visit(ExprVisitor& func);
441
442 private:
443 const VType*base_;
444 };
445
446 class ExpBitstring : public Expression {
447
448 public:
449 explicit ExpBitstring(const char*);
ExpBitstring(const ExpBitstring & other)450 ExpBitstring(const ExpBitstring&other) : Expression() { value_ = other.value_; }
451 ~ExpBitstring();
452
clone()453 Expression*clone() const { return new ExpBitstring(*this); }
454
455 const VType*fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*atype) const;
456 int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
457 void write_to_stream(std::ostream&fd) const;
458 int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
459 void dump(ostream&out, int indent = 0) const;
460
461 private:
462 std::vector<char>value_;
463 };
464
465
466 class ExpCharacter : public Expression {
467
468 public:
469 explicit ExpCharacter(char val);
ExpCharacter(const ExpCharacter & other)470 ExpCharacter(const ExpCharacter&other) : Expression() { value_ = other.value_; }
471 ~ExpCharacter();
472
clone()473 Expression*clone() const { return new ExpCharacter(*this); }
474
475 const VType*fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*atype) const;
476 int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
477 void write_to_stream(std::ostream&fd) const;
478 int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
479 bool is_primary(void) const;
480 void dump(ostream&out, int indent = 0) const;
481
value()482 char value() const { return value_; }
483
484 private:
485 int emit_primitive_bit_(ostream&out, Entity*ent, ScopeBase*scope,
486 const VTypePrimitive*etype) const;
487
488 private:
489 char value_;
490 };
491
492 class ExpConcat : public Expression {
493
494 public:
495 ExpConcat(Expression*op1, Expression*op2);
496 ~ExpConcat();
497
clone()498 Expression*clone() const {
499 return new ExpConcat(operand1_->clone(), operand2_->clone());
500 }
501
502 const VType*probe_type(Entity*ent, ScopeBase*scope) const;
503 const VType*fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*atype) const;
504 int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
505 void write_to_stream(std::ostream&fd) const;
506 int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
507 bool is_primary(void) const;
508 void dump(ostream&out, int indent = 0) const;
509 void visit(ExprVisitor& func);
510
511 private:
512 int elaborate_expr_array_(Entity*ent, ScopeBase*scope, const VTypeArray*ltype);
513
514 private:
515 Expression*operand1_;
516 Expression*operand2_;
517 };
518
519 /*
520 * The conditional expression represents the VHDL when-else
521 * expressions. Note that by the VHDL syntax rules, these cannot show
522 * up other than at the root of an expression.
523 */
524 class ExpConditional : public Expression {
525
526 public:
527 class case_t : public LineInfo {
528 public:
529 case_t(Expression*cond, std::list<Expression*>*tru);
530 case_t(const case_t&other);
531 ~case_t();
532
condition()533 inline Expression*condition() const { return cond_; }
set_condition(Expression * cond)534 inline void set_condition(Expression*cond) { cond_ = cond; }
true_clause()535 inline const std::list<Expression*>& true_clause() const { return true_clause_; }
536
537 int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*lt);
538 int emit_option(ostream&out, Entity*ent, ScopeBase*scope) const;
539 int emit_default(ostream&out, Entity*ent, ScopeBase*scope) const;
540 void dump(ostream&out, int indent = 0) const;
extract_true_clause()541 std::list<Expression*>& extract_true_clause() { return true_clause_; }
542 void visit(ExprVisitor& func);
543
544 private:
545 Expression*cond_;
546 std::list<Expression*> true_clause_;
547 };
548
549 public:
550 ExpConditional(Expression*cond, std::list<Expression*>*tru,
551 std::list<case_t*>*options);
552 virtual ~ExpConditional();
553
554 virtual Expression*clone() const;
555
556 const VType*probe_type(Entity*ent, ScopeBase*scope) const;
557 int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
558 void write_to_stream(std::ostream&fd) const;
559 int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
560 void dump(ostream&out, int indent = 0) const;
561 void visit(ExprVisitor& func);
562
563 protected:
564 std::list<case_t*> options_;
565 };
566
567 /*
568 * Expression to handle selected assignments (with .. select target <= value when ..)
569 */
570 class ExpSelected : public ExpConditional {
571 public:
572 ExpSelected(Expression*selector, std::list<case_t*>*options);
573 ~ExpSelected();
574
575 Expression*clone() const;
576
577 private:
578 Expression*selector_;
579 };
580
581 /*
582 * This is a special expression type that represents posedge/negedge
583 * expressions in sensitivity lists.
584 */
585 class ExpEdge : public ExpUnary {
586
587 public:
588 enum fun_t { NEGEDGE, ANYEDGE, POSEDGE };
589
590 public:
591 explicit ExpEdge(ExpEdge::fun_t ty, Expression*op);
592 ~ExpEdge();
593
clone()594 Expression*clone() const { return new ExpEdge(fun_, peek_operand()->clone()); }
595
edge_fun()596 inline fun_t edge_fun() const { return fun_; }
597
598 void write_to_stream(std::ostream&fd) const;
599 int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
600 void dump(ostream&out, int indent = 0) const;
601
602 private:
603 fun_t fun_;
604 };
605
606 class ExpFunc : public Expression {
607
608 public:
609 explicit ExpFunc(perm_string nn);
610 ExpFunc(perm_string nn, std::list<Expression*>*args);
611 ~ExpFunc();
612
613 Expression*clone() const;
614
615 const VType*fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*atype) const;
func_name()616 inline perm_string func_name() const { return name_; }
func_args()617 inline size_t func_args() const { return argv_.size(); }
func_arg(size_t idx)618 inline const Expression*func_arg(size_t idx) const { return argv_[idx]; }
619 const VType*func_ret_type() const;
620
621 public: // Base methods
622 const VType*probe_type(Entity*ent, ScopeBase*scope) const;
623 int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
624 void write_to_stream(std::ostream&fd) const;
625 int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
626 void dump(ostream&out, int indent = 0) const;
627 void visit(ExprVisitor& func); // NOTE: does not handle expressions in subprogram body
628
629 // Returns a subprogram header that matches the function call
630 SubprogramHeader*match_signature(Entity*ent, ScopeBase*scope) const;
631
632 private:
633 perm_string name_;
634 std::vector<Expression*> argv_;
635 mutable SubprogramHeader*def_;
636 };
637
638 class ExpInteger : public Expression {
639
640 public:
641 explicit ExpInteger(int64_t val);
ExpInteger(const ExpInteger & other)642 ExpInteger(const ExpInteger&other) : Expression(), value_(other.value_) {}
643 ~ExpInteger();
644
clone()645 Expression*clone() const { return new ExpInteger(*this); }
646
647 const VType*probe_type(Entity*ent, ScopeBase*scope) const;
648 int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
649 void write_to_stream(std::ostream&fd) const;
650 int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
651 int emit_package(std::ostream&out) const;
is_primary(void)652 bool is_primary(void) const { return true; }
653 bool evaluate(Entity*ent, ScopeBase*scope, int64_t&val) const;
654 void dump(ostream&out, int indent = 0) const;
655 virtual ostream& dump_inline(ostream&out) const;
656
657 private:
658 int64_t value_;
659 };
660
661 class ExpReal : public Expression {
662
663 public:
664 explicit ExpReal(double val);
ExpReal(const ExpReal & other)665 ExpReal(const ExpReal&other) : Expression(), value_(other.value_) {}
666 ~ExpReal();
667
clone()668 Expression*clone() const { return new ExpReal(*this); }
669
670 const VType*probe_type(Entity*ent, ScopeBase*scope) const;
671 int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
672 void write_to_stream(std::ostream&fd) const;
673 int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
674 int emit_package(std::ostream&out) const;
675 bool is_primary(void) const;
676 void dump(ostream&out, int indent = 0) const;
677 virtual ostream& dump_inline(ostream&out) const;
678
679 private:
680 double value_;
681 };
682
683 class ExpLogical : public ExpBinary {
684
685 public:
686 enum fun_t { AND, OR, NAND, NOR, XOR, XNOR };
687
688 public:
689 ExpLogical(ExpLogical::fun_t ty, Expression*op1, Expression*op2);
690 ~ExpLogical();
691
clone()692 Expression*clone() const {
693 return new ExpLogical(fun_, peek_operand1()->clone(), peek_operand2()->clone());
694 }
695
logic_fun()696 inline fun_t logic_fun() const { return fun_; }
697
698 int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
699 void write_to_stream(std::ostream&fd) const;
700 int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
701 void dump(ostream&out, int indent = 0) const;
702
703 private:
704 fun_t fun_;
705 };
706
707 /*
708 * The ExpName class represents an expression that is an identifier or
709 * other sort of name. The ExpNameALL is a special case of ExpName
710 * that represents the "all" keyword is contexts that can handle it.
711 */
712 class ExpName : public Expression {
713
714 public:
715 explicit ExpName(perm_string nn);
716 ExpName(perm_string nn, std::list<Expression*>*indices);
717 ExpName(ExpName*prefix, perm_string nn, std::list<Expression*>*indices = NULL);
718 virtual ~ExpName();
719
720 public: // Base methods
721 Expression*clone() const;
722 int elaborate_lval(Entity*ent, ScopeBase*scope, bool);
723 int elaborate_rval(Entity*ent, ScopeBase*scope, const InterfacePort*);
724 const VType* probe_type(Entity*ent, ScopeBase*scope) const;
725 const VType* fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*host) const;
726 int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
727 void write_to_stream(std::ostream&fd) const;
728 int emit_indices(ostream&out, Entity*ent, ScopeBase*scope) const;
729 int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
730 bool is_primary(void) const;
731 bool evaluate(Entity*ent, ScopeBase*scope, int64_t&val) const;
732 bool symbolic_compare(const Expression*that) const;
733 void dump(ostream&out, int indent = 0) const;
name()734 inline const char* name() const { return name_; }
peek_name()735 inline const perm_string& peek_name() const { return name_; }
736 void add_index(std::list<Expression*>*idx);
737 void visit(ExprVisitor& func);
738
739 private:
740 class index_t {
741 public:
742 index_t(Expression*idx, Expression*size, Expression*offset = NULL) :
idx_(idx)743 idx_(idx), size_(size), offset_(offset) {}
~index_t()744 ~index_t() {
745 delete idx_;
746 delete size_;
747 delete offset_;
748 }
749
750 int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
751
752 private:
753 Expression*idx_;
754 Expression*size_;
755 Expression*offset_;
756 };
757
758 const VType* elaborate_adjust_type_with_range_(Entity*ent, ScopeBase*scope, const VType*type);
759
760 int elaborate_lval_(Entity*ent, ScopeBase*scope, bool, ExpName*suffix);
761 const VType* probe_prefix_type_(Entity*ent, ScopeBase*scope) const;
762 const VType* probe_prefixed_type_(Entity*ent, ScopeBase*scope) const;
763
764 int emit_as_prefix_(ostream&out, Entity*ent, ScopeBase*scope) const;
765
766 // There are some workarounds required for constant arrays/records, as
767 // they are currently emitted as flat localparams (without any type
768 // information). The following workarounds adjust the access indices
769 // to select appropriate parts of the localparam.
770 bool try_workarounds_(ostream&out, Entity*ent, ScopeBase*scope,
771 list<index_t*>&indices, int&data_size) const;
772
773 bool check_const_array_workaround_(const VTypeArray*arr, ScopeBase*scope,
774 list<index_t*>&indices, int&data_size) const;
775
776 bool check_const_record_workaround_(const VTypeRecord*rec, ScopeBase*scope,
777 list<index_t*>&indices, int&data_size) const;
778
779 int emit_workaround_(ostream&out, Entity*ent, ScopeBase*scope,
780 const list<index_t*>&indices, int field_size) const;
781
782 private:
783 Expression*index(unsigned int number) const;
784
785 std::unique_ptr<ExpName> prefix_;
786 perm_string name_;
787 std::list<Expression*>*indices_;
788 };
789
790 class ExpNameALL : public ExpName {
791
792 public:
ExpNameALL()793 ExpNameALL() : ExpName(empty_perm_string) { }
794
795 public:
796 const VType* probe_type(Entity*ent, ScopeBase*scope) const;
797 void dump(ostream&out, int indent =0) const;
798 };
799
800 class ExpRelation : public ExpBinary {
801
802 public:
803 enum fun_t { EQ, LT, GT, NEQ, LE, GE };
804
relation_fun(void)805 inline fun_t relation_fun(void) const { return fun_; }
806
807 public:
808 ExpRelation(ExpRelation::fun_t ty, Expression*op1, Expression*op2);
809 ~ExpRelation();
810
clone()811 Expression*clone() const {
812 return new ExpRelation(fun_, peek_operand1()->clone(), peek_operand2()->clone());
813 }
814
815 const VType* probe_type(Entity*ent, ScopeBase*scope) const;
816 int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
817 void write_to_stream(std::ostream&fd) const;
818 int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
819 void dump(ostream&out, int indent = 0) const;
820
821 private:
822 fun_t fun_;
823 };
824
825 /*
826 * Helper class to handle name expressions coming from another scope. As such,
827 * we get more information regarding their type, etc. from the associated scope.
828 */
829 class ExpScopedName : public Expression {
830 public:
831 ExpScopedName(perm_string scope, ExpName*exp);
832 ~ExpScopedName();
833
clone()834 Expression*clone() const
835 { return new ExpScopedName(scope_name_, static_cast<ExpName*>(name_->clone())); }
836
elaborate_lval(Entity * ent,ScopeBase * scope,bool is_sequ)837 int elaborate_lval(Entity*ent, ScopeBase*scope, bool is_sequ)
838 { return name_->elaborate_lval(ent, get_scope(scope), is_sequ); }
839
elaborate_rval(Entity * ent,ScopeBase * scope,const InterfacePort * lval)840 int elaborate_rval(Entity*ent, ScopeBase*scope, const InterfacePort*lval)
841 { return name_->elaborate_rval(ent, get_scope(scope), lval); }
842
probe_type(Entity * ent,ScopeBase * scope)843 const VType* probe_type(Entity*ent, ScopeBase*scope) const
844 { return name_->probe_type(ent, get_scope(scope)); }
845
fit_type(Entity * ent,ScopeBase * scope,const VTypeArray * host)846 const VType* fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*host) const
847 { return name_->fit_type(ent, get_scope(scope), host); }
848
elaborate_expr(Entity * ent,ScopeBase * scope,const VType * ltype)849 int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype)
850 { return name_->elaborate_expr(ent, get_scope(scope), ltype); }
851
write_to_stream(std::ostream & fd)852 void write_to_stream(std::ostream&fd) const
853 { name_->write_to_stream(fd); }
854
emit(ostream & out,Entity * ent,ScopeBase * scope)855 int emit(ostream&out, Entity*ent, ScopeBase*scope) const {
856 out << scope_name_ << ".";
857 return name_->emit(out, ent, scope);
858 }
859
is_primary(void)860 bool is_primary(void) const
861 { return name_->is_primary(); }
862
evaluate(Entity * ent,ScopeBase *,int64_t & val)863 bool evaluate(Entity*ent, ScopeBase*, int64_t&val) const
864 { return name_->evaluate(ent, scope_, val); }
865
symbolic_compare(const Expression * that)866 bool symbolic_compare(const Expression*that) const
867 { return name_->symbolic_compare(that); }
868
869 void dump(ostream&out, int indent = 0) const;
870
871 void visit(ExprVisitor&func);
872
873 private:
874 // Functions that resolve the origin scope for the name expression
875 ScopeBase*get_scope(const ScopeBase*scope);
876 ScopeBase*get_scope(const ScopeBase*scope) const;
877
878 perm_string scope_name_;
879 ScopeBase*scope_;
880 ExpName*name_;
881 };
882
883 class ExpShift : public ExpBinary {
884 public:
885 enum shift_t { SRL, SLL, SRA, SLA, ROL, ROR };
886
887 public:
888 ExpShift(ExpShift::shift_t op, Expression*op1, Expression*op2);
889
clone()890 Expression*clone() const {
891 return new ExpShift(shift_, peek_operand1()->clone(), peek_operand2()->clone());
892 }
893
894 int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
895 void write_to_stream(std::ostream&fd) const;
896 int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
897 bool evaluate(Entity*ent, ScopeBase*scope, int64_t&val) const;
898 void dump(ostream&out, int indent = 0) const;
899
900 private:
901 shift_t shift_;
902 };
903
904 class ExpString : public Expression {
905
906 public:
907 explicit ExpString(const char*);
ExpString(const ExpString & other)908 ExpString(const ExpString&other) : Expression(), value_(other.value_) {}
909 ~ExpString();
910
clone()911 Expression*clone() const { return new ExpString(*this); }
912
913 const VType*fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*atype) const;
914 int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
915 void write_to_stream(std::ostream&fd) const;
916 int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
917 bool is_primary(void) const;
918 void dump(ostream&out, int indent = 0) const;
get_value()919 const std::string& get_value() const { return value_; }
920
921 // Converts quotation marks (") to its escaped
922 // counterpart in SystemVerilog (\")
923 static std::string escape_quot(const std::string& str);
924
925 private:
926 int emit_as_array_(ostream&out, Entity*ent, ScopeBase*scope, const VTypeArray*arr) const;
927
928 private:
929 std::string value_;
930 };
931
932 class ExpUAbs : public ExpUnary {
933
934 public:
935 explicit ExpUAbs(Expression*op1);
936 ~ExpUAbs();
937
clone()938 Expression*clone() const { return new ExpUAbs(peek_operand()->clone()); }
939
940 void write_to_stream(std::ostream&fd) const;
941 int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
942 void dump(ostream&out, int indent = 0) const;
943 };
944
945 class ExpUNot : public ExpUnary {
946
947 public:
948 explicit ExpUNot(Expression*op1);
949 ~ExpUNot();
950
clone()951 Expression*clone() const { return new ExpUNot(peek_operand()->clone()); }
952
953 void write_to_stream(std::ostream&fd) const;
954 int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
955 void dump(ostream&out, int indent = 0) const;
956 };
957
958 class ExpUMinus : public ExpUnary {
959
960 public:
961 explicit ExpUMinus(Expression*op1);
962 ~ExpUMinus();
963
clone()964 Expression*clone() const { return new ExpUMinus(peek_operand()->clone()); }
965
966 void write_to_stream(std::ostream&fd) const;
967 int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
968 void dump(ostream&out, int indent = 0) const;
969 };
970
971 /*
972 * Class that wraps other expressions to cast them to other types.
973 */
974 class ExpCast : public Expression {
975
976 public:
977 ExpCast(Expression*base, const VType*type);
978 ~ExpCast();
979
clone()980 Expression*clone() const { return new ExpCast(base_->clone(), type_->clone()); }
981
elaborate_expr(Entity * ent,ScopeBase * scope,const VType *)982 inline int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*) {
983 return base_->elaborate_expr(ent, scope, type_);
984 }
985 void write_to_stream(std::ostream&fd) const;
986 int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
987 void dump(ostream&out, int indent = 0) const;
988 void visit(ExprVisitor& func);
989
990 private:
991 Expression*base_;
992 const VType*type_;
993 };
994
995 /*
996 * Class that handles 'new' statement. VHDL is not capable of dynamic memory
997 * allocation, but it is useful for emitting some cases.
998 */
999 class ExpNew : public Expression {
1000
1001 public:
1002 explicit ExpNew(Expression*size);
1003 ~ExpNew();
1004
clone()1005 Expression*clone() const { return new ExpNew(size_->clone()); }
1006
1007 // There is no 'new' in VHDL - do not emit anything
write_to_stream(std::ostream &)1008 void write_to_stream(std::ostream&) const {};
1009 int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
1010 void dump(ostream&out, int indent = 0) const;
1011 void visit(ExprVisitor& func);
1012
1013 private:
1014 Expression*size_;
1015 };
1016
1017 class ExpTime : public Expression {
1018 public:
1019 typedef enum { FS, PS, NS, US, MS, S } timeunit_t;
1020
1021 ExpTime(uint64_t amount, timeunit_t unit);
1022
clone()1023 Expression*clone() const { return new ExpTime(amount_, unit_); }
1024
1025 int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
1026 void write_to_stream(std::ostream&) const;
1027 int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
1028 //bool evaluate(Entity*ent, ScopeBase*scope, int64_t&val) const;
1029 void dump(ostream&out, int indent = 0) const;
1030
1031 private:
1032 // Returns the time value expressed in femtoseconds
1033 double to_fs() const;
1034 uint64_t amount_;
1035 timeunit_t unit_;
1036 };
1037
1038 class ExpRange : public Expression {
1039 public:
1040 typedef enum { DOWNTO, TO, AUTO } range_dir_t;
1041
1042 // Regular range
1043 ExpRange(Expression*left_idx, Expression*right_idx, range_dir_t dir);
1044 // 'range/'reverse range attribute
1045 ExpRange(ExpName*base, bool reverse_range);
1046 ~ExpRange();
1047
1048 Expression*clone() const;
1049
1050 // Returns the upper boundary
1051 Expression*msb();
1052 // Returns the lower boundary
1053 Expression*lsb();
1054
1055 Expression*left();
1056 Expression*right();
1057
direction()1058 range_dir_t direction() const { return direction_; }
1059
1060 int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
1061 void write_to_stream(std::ostream&) const;
1062 int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
1063 void dump(ostream&out, int indent = 0) const;
1064 private:
1065 // Regular range related fields
1066 Expression*left_, *right_;
1067 range_dir_t direction_;
1068
1069 // 'range/'reverse_range attribute related fields
1070 // Flag to indicate it is a 'range/'reverse_range expression
1071 bool range_expr_;
1072 // Object name to which the attribute is applied
1073 ExpName*range_base_;
1074 // Flag to distinguish between 'range & 'reverse_range
1075 bool range_reverse_;
1076 };
1077
1078 // Helper class that wraps other expression to specify delay.
1079 class ExpDelay : public Expression {
1080 public:
1081 ExpDelay(Expression*expr, Expression*delay);
1082 ~ExpDelay();
1083
clone()1084 Expression*clone() const { return new ExpDelay(expr_->clone(), delay_->clone()); }
1085
1086 int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
1087 void write_to_stream(std::ostream&) const;
1088 int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
1089 void dump(ostream&out, int indent = 0) const;
1090 void visit(ExprVisitor& func);
1091
peek_expr()1092 const Expression*peek_expr() const { return expr_; }
peek_delay()1093 const Expression*peek_delay() const { return delay_; }
1094
1095 private:
1096 Expression*expr_;
1097 Expression*delay_;
1098 };
1099
1100 #if __cplusplus < 201103L
1101 #undef unique_ptr
1102 #endif
1103
1104 #endif /* IVL_expression_H */
1105