1 #ifndef IVL_PExpr_H
2 #define IVL_PExpr_H
3 /*
4  * Copyright (c) 1998-2019 Stephen Williams <steve@icarus.com>
5  * Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
6  *
7  *    This source code is free software; you can redistribute it
8  *    and/or modify it in source code form under the terms of the GNU
9  *    General Public License as published by the Free Software
10  *    Foundation; either version 2 of the License, or (at your option)
11  *    any later version.
12  *
13  *    This program is distributed in the hope that it will be useful,
14  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *    GNU General Public License for more details.
17  *
18  *    You should have received a copy of the GNU General Public License
19  *    along with this program; if not, write to the Free Software
20  *    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21  */
22 
23 # include  <string>
24 # include  <vector>
25 # include  <valarray>
26 # include  "netlist.h"
27 # include  "verinum.h"
28 # include  "LineInfo.h"
29 # include  "pform_types.h"
30 
31 class Design;
32 class Module;
33 class LexicalScope;
34 class NetNet;
35 class NetExpr;
36 class NetScope;
37 class PPackage;
38 
39 /*
40  * The PExpr class hierarchy supports the description of
41  * expressions. The parser can generate expression objects from the
42  * source, possibly reducing things that it knows how to reduce.
43  */
44 
45 class PExpr : public LineInfo {
46 
47     public:
48 	// Mode values used by test_width() (see below for description).
49       enum width_mode_t { SIZED, UNSIZED, EXPAND, LOSSLESS, UPSIZE };
50 
51         // Flag values that can be passed to elaborate_expr().
52       static const unsigned NO_FLAGS     = 0x0;
53       static const unsigned NEED_CONST   = 0x1;
54       static const unsigned SYS_TASK_ARG = 0x2;
55       static const unsigned ANNOTATABLE  = 0x4;
56 
57 	// Convert width mode to human-readable form.
58       static const char*width_mode_name(width_mode_t mode);
59 
60       PExpr();
61       virtual ~PExpr();
62 
63       virtual void dump(ostream&) const;
64 
65         // This method tests whether the expression contains any identifiers
66         // that have not been previously declared in the specified scope or
67         // in any containing scope. Any such identifiers are added to the
68         // specified scope as scalar nets of the specified type.
69         //
70         // This operation must be performed by the parser, to ensure that
71         // subsequent declarations do not affect the decision to create an
72         // implicit net.
73       virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
74 
75         // This method tests whether the expression contains any
76         // references to automatically allocated variables.
77       virtual bool has_aa_term(Design*des, NetScope*scope) const;
78 
79 	// This method tests the type and width that the expression wants
80 	// to be. It should be called before elaborating an expression to
81 	// figure out the type and width of the expression. It also figures
82 	// out the minimum width that can be used to evaluate the expression
83 	// without changing the result. This allows the expression width to
84 	// be pruned when not all bits of the result are used.
85 	//
86 	// Normally mode should be initialized to SIZED before starting to
87 	// test the width of an expression. In SIZED mode the expression
88 	// width will be calculated strictly according to the IEEE standard
89 	// rules for expression width.
90 	//
91 	// If the expression is found to contain an unsized literal number
92 	// and gn_strict_expr_width_flag is set, mode will be changed to
93 	// UNSIZED. In UNSIZED mode the expression width will be calculated
94 	// exactly as in SIZED mode - the change in mode simply flags that
95 	// the expression contains an unsized numbers.
96 	//
97 	// If the expression is found to contain an unsized literal number
98 	// and gn_strict_expr_width_flag is not set, mode will be changed
99 	// to LOSSLESS. In LOSSLESS mode the expression width will be
100 	// calculated as the minimum width necessary to avoid arithmetic
101 	// overflow or underflow.
102 	//
103 	// Once in LOSSLESS mode, if the expression is found to contain
104 	// an operation that coerces a vector operand to a different type
105 	// (signed <-> unsigned), mode will be changed to UPSIZE. UPSIZE
106 	// mode is the same as LOSSLESS, except that the final expression
107 	// width will be forced to be at least integer_width. This is
108 	// necessary to ensure compatibility with the IEEE standard, which
109 	// requires unsized numbers to be treated as having the same width
110 	// as an integer. The lossless width calculation is inadequate in
111 	// this case because coercing an operand to a different type means
112 	// that the expression no longer obeys the normal rules of arithmetic.
113 	//
114 	// If mode is initialized to EXPAND instead of SIZED, the expression
115 	// width will be calculated as the minimum width necessary to avoid
116 	// arithmetic overflow or underflow, even if it contains no unsized
117 	// literals. mode will be changed LOSSLESS or UPSIZE as described
118 	// above. This supports a non-standard mode of expression width
119 	// calculation.
120 	//
121 	// When the final value of mode is UPSIZE, the width returned by
122 	// this method is the calculated lossless width, but the width
123 	// returned by a subsequent call to the expr_width method will be
124 	// the final expression width.
125       virtual unsigned test_width(Design*des, NetScope*scope,
126 				  width_mode_t&mode);
127 
128 	// After the test_width method is complete, these methods
129 	// return valid results.
expr_type()130       ivl_variable_type_t expr_type() const { return expr_type_; }
expr_width()131       unsigned expr_width() const           { return expr_width_; }
min_width()132       unsigned min_width() const            { return min_width_; }
has_sign()133       bool has_sign() const                 { return signed_flag_; }
134 
135         // This method allows the expression type (signed/unsigned)
136         // to be propagated down to any context-dependant operands.
cast_signed(bool flag)137       void cast_signed(bool flag) { signed_flag_ = flag; }
138 
139 	// This is the more generic form of the elaborate_expr method
140 	// below. The plan is to replace the simpler elaborate_expr
141 	// method with this version, which can handle more advanced
142 	// types. But for now, this is only implemented in special cases.
143       virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
144 				     ivl_type_t type, unsigned flags) const;
145 
146 	// Procedural elaboration of the expression. The expr_width is
147 	// the required width of the expression.
148 	//
149 	// The sys_task_arg flag is true if expressions are allowed to
150 	// be incomplete.
151       virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
152 				     unsigned expr_wid,
153                                      unsigned flags) const;
154 
155 	// This method elaborates the expression as gates, but
156 	// restricted for use as l-values of continuous assignments.
157       virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
158 
159 	// This is similar to elaborate_lnet, except that the
160 	// expression is evaluated to be bi-directional. This is
161 	// useful for arguments to inout ports of module instances and
162 	// ports of tran primitives.
163       virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const;
164 
165 	// Expressions that can be in the l-value of procedural
166 	// assignments can be elaborated with this method. If the
167 	// is_cassign or is_force flags are true, then the set of
168 	// valid l-value types is slightly modified to accommodate
169 	// the Verilog procedural continuous assignment statements.
170       virtual NetAssign_* elaborate_lval(Design*des,
171 					 NetScope*scope,
172 					 bool is_cassign,
173 					 bool is_force) const;
174 
175 	// This attempts to evaluate a constant expression, and return
176 	// a verinum as a result. If the expression cannot be
177 	// evaluated, return 0.
178       virtual verinum* eval_const(Design*des, NetScope*sc) const;
179 
180 	// This method returns true if the expression represents a
181         // structural net that can have multiple drivers. This is
182         // used to test whether an input port connection can be
183         // collapsed to a single wire.
184       virtual bool is_collapsible_net(Design*des, NetScope*scope) const;
185 
186 	// This method returns true if that expression is the same as
187 	// this expression. This method is used for comparing
188 	// expressions that must be structurally "identical".
189       virtual bool is_the_same(const PExpr*that) const;
190 
191     protected:
192       unsigned fix_width_(width_mode_t mode);
193 
194 	// The derived class test_width methods should fill these in.
195       ivl_variable_type_t expr_type_;
196       unsigned expr_width_;
197       unsigned min_width_;
198       bool signed_flag_;
199 
200     private: // not implemented
201       PExpr(const PExpr&);
202       PExpr& operator= (const PExpr&);
203 };
204 
205 ostream& operator << (ostream&, const PExpr&);
206 
207 class PEAssignPattern : public PExpr {
208     public:
209       explicit PEAssignPattern();
210       explicit PEAssignPattern(const std::list<PExpr*>&p);
211       ~PEAssignPattern();
212 
213       void dump(std::ostream&) const;
214 
215       virtual unsigned test_width(Design*des, NetScope*scope, width_mode_t&mode);
216       virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
217 				     ivl_type_t type, unsigned flags) const;
218 
219       virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
220 				     unsigned expr_wid,
221                                      unsigned flags) const;
222     private:
223       NetExpr* elaborate_expr_darray_(Design*des, NetScope*scope,
224 				      ivl_type_t type, unsigned flags) const;
225 
226     private:
227       std::vector<PExpr*>parms_;
228 };
229 
230 class PEConcat : public PExpr {
231 
232     public:
233       PEConcat(const list<PExpr*>&p, PExpr*r =0);
234       ~PEConcat();
235 
236       virtual verinum* eval_const(Design*des, NetScope*sc) const;
237       virtual void dump(ostream&) const;
238 
239       virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
240 
241       virtual bool has_aa_term(Design*des, NetScope*scope) const;
242 
243       virtual unsigned test_width(Design*des, NetScope*scope,
244 				  width_mode_t&mode);
245 
246       virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
247       virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const;
248 
249       virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
250 				     ivl_type_t type, unsigned flags) const;
251 
252       virtual NetExpr*elaborate_expr(Design*des, NetScope*,
253 				     unsigned expr_wid,
254                                      unsigned flags) const;
255       virtual NetAssign_* elaborate_lval(Design*des,
256 					 NetScope*scope,
257 					 bool is_cassign,
258 					 bool is_force) const;
259       virtual bool is_collapsible_net(Design*des, NetScope*scope) const;
260     private:
261       NetNet* elaborate_lnet_common_(Design*des, NetScope*scope,
262 				     bool bidirectional_flag) const;
263     private:
264       vector<PExpr*>parms_;
265       std::valarray<width_mode_t>width_modes_;
266 
267       PExpr*repeat_;
268       NetScope*tested_scope_;
269       unsigned repeat_count_;
270 };
271 
272 /*
273  * Event expressions are expressions that can be combined with the
274  * event "or" operator. These include "posedge foo" and similar, and
275  * also include named events. "edge" events are associated with an
276  * expression, whereas named events simply have a name, which
277  * represents an event variable.
278  */
279 class PEEvent : public PExpr {
280 
281     public:
282       enum edge_t {ANYEDGE, POSEDGE, NEGEDGE, POSITIVE};
283 
284 	// Use this constructor to create events based on edges or levels.
285       PEEvent(edge_t t, PExpr*e);
286 
287       ~PEEvent();
288 
289       edge_t type() const;
290       PExpr* expr() const;
291 
292       virtual void dump(ostream&) const;
293 
294       virtual bool has_aa_term(Design*des, NetScope*scope) const;
295 
296     private:
297       edge_t type_;
298       PExpr *expr_;
299 };
300 
301 /*
302  * This holds a floating point constant in the source.
303  */
304 class PEFNumber : public PExpr {
305 
306     public:
307       explicit PEFNumber(verireal*vp);
308       ~PEFNumber();
309 
310       const verireal& value() const;
311 
312 	/* The eval_const method as applied to a floating point number
313 	   gets the *integer* value of the number. This accounts for
314 	   any rounding that is needed to get the value. */
315       virtual verinum* eval_const(Design*des, NetScope*sc) const;
316 
317       virtual unsigned test_width(Design*des, NetScope*scope,
318 				  width_mode_t&mode);
319       virtual NetExpr*elaborate_expr(Design*des, NetScope*,
320 				     ivl_type_t type, unsigned flags) const;
321       virtual NetExpr*elaborate_expr(Design*des, NetScope*,
322 				     unsigned expr_wid,
323                                      unsigned flags) const;
324 
325       virtual void dump(ostream&) const;
326 
327     private:
328       verireal*value_;
329 };
330 
331 class PEIdent : public PExpr {
332 
333     public:
334       explicit PEIdent(perm_string, bool no_implicit_sig=false);
335       explicit PEIdent(PPackage*pkg, const pform_name_t&name);
336       explicit PEIdent(const pform_name_t&);
337       ~PEIdent();
338 
339 	// Add another name to the string of hierarchy that is the
340 	// current identifier.
341       void append_name(perm_string);
342 
343       virtual void dump(ostream&) const;
344 
345       virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
346 
347       virtual bool has_aa_term(Design*des, NetScope*scope) const;
348 
349       virtual unsigned test_width(Design*des, NetScope*scope,
350 				  width_mode_t&mode);
351 
352 	// Identifiers are allowed (with restrictions) is assign l-values.
353       virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
354 
355       virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const;
356 
357 	// Identifiers are also allowed as procedural assignment l-values.
358       virtual NetAssign_* elaborate_lval(Design*des,
359 					 NetScope*scope,
360 					 bool is_cassign,
361 					 bool is_force) const;
362 
363       virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
364 				     ivl_type_t type, unsigned flags) const;
365       virtual NetExpr*elaborate_expr(Design*des, NetScope*,
366 				     unsigned expr_wid,
367                                      unsigned flags) const;
368 
369 	// Elaborate the PEIdent as a port to a module. This method
370 	// only applies to Ident expressions.
371       NetNet* elaborate_subport(Design*des, NetScope*sc) const;
372 
373 	// Elaborate the identifier allowing for unpacked arrays. This
374 	// method only applies to Ident expressions because only Ident
375 	// expressions can can be unpacked arrays.
376       NetNet* elaborate_unpacked_net(Design*des, NetScope*sc) const;
377 
378       verinum* eval_const(Design*des, NetScope*sc) const;
379 
380       virtual bool is_collapsible_net(Design*des, NetScope*scope) const;
381 
package()382       const PPackage* package() const { return package_; }
383 
path()384       const pform_name_t& path() const { return path_; }
385 
386     private:
387       PPackage*package_;
388       pform_name_t path_;
389       bool no_implicit_sig_;
390 
391     private:
392 	// Common functions to calculate parts of part/bit
393 	// selects. These methods return true if the expressions
394 	// elaborate/calculate, or false if there is some sort of
395 	// source error.
396 
397       bool calculate_bits_(Design*, NetScope*, long&msb, bool&defined) const;
398 
399 	// The calculate_parts_ method calculates the range
400 	// expressions of a part select for the current object. The
401 	// part select expressions are elaborated and evaluated, and
402 	// the values written to the msb/lsb arguments. If there are
403 	// invalid bits (xz) in either expression, then the defined
404 	// flag is set to *false*.
405       bool calculate_parts_(Design*, NetScope*, long&msb, long&lsb, bool&defined) const;
406       NetExpr* calculate_up_do_base_(Design*, NetScope*, bool need_const) const;
407       bool calculate_param_range_(Design*, NetScope*,
408 				  const NetExpr*msb_ex, long&msb,
409 				  const NetExpr*lsb_ex, long&lsb,
410 				  long length) const;
411 
412       bool calculate_up_do_width_(Design*, NetScope*, unsigned long&wid) const;
413 
414 	// Evaluate the prefix indices. All but the final index in a
415 	// chain of indices must be a single value and must evaluate
416 	// to constants at compile time. For example:
417 	//    [x]          - OK
418 	//    [1][2][x]    - OK
419 	//    [1][x:y]     - OK
420 	//    [2:0][x]     - BAD
421 	//    [y][x]       - BAD
422 	// Leave the last index for special handling.
423       bool calculate_packed_indices_(Design*des, NetScope*scope, NetNet*net,
424 				     std::list<long>&prefix_indices) const;
425 
426     private:
427       NetAssign_*elaborate_lval_method_class_member_(Design*, NetScope*) const;
428       NetAssign_*elaborate_lval_net_word_(Design*, NetScope*, NetNet*,
429 					  bool need_const_idx) const;
430       bool elaborate_lval_net_bit_(Design*, NetScope*, NetAssign_*,
431 				   bool need_const_idx) const;
432       bool elaborate_lval_net_part_(Design*, NetScope*, NetAssign_*) const;
433       bool elaborate_lval_net_idx_(Design*, NetScope*, NetAssign_*,
434                                    index_component_t::ctype_t,
435 				   bool need_const_idx) const;
436       NetAssign_*elaborate_lval_net_class_member_(Design*, NetScope*,
437 						   NetNet*,
438 						   pform_name_t) const;
439       bool elaborate_lval_net_packed_member_(Design*, NetScope*,
440 					     NetAssign_*,
441 					     pform_name_t member_path) const;
442       bool elaborate_lval_darray_bit_(Design*, NetScope*,
443 				       NetAssign_*) const;
444 
445     private:
446       NetExpr*elaborate_expr_param_(Design*des,
447 				    NetScope*scope,
448 				    const NetExpr*par,
449 				    NetScope*found_in,
450 				    const NetExpr*par_msb,
451 				    const NetExpr*par_lsb,
452 				    unsigned expr_wid,
453                                     unsigned flags) const;
454       NetExpr*elaborate_expr_param_bit_(Design*des,
455 					NetScope*scope,
456 					const NetExpr*par,
457 					NetScope*found_in,
458 					const NetExpr*par_msb,
459 					const NetExpr*par_lsb,
460                                         bool need_const) const;
461       NetExpr*elaborate_expr_param_part_(Design*des,
462 					 NetScope*scope,
463 					 const NetExpr*par,
464 					 NetScope*found_in,
465 					 const NetExpr*par_msb,
466 					 const NetExpr*par_lsb,
467 				         unsigned expr_wid) const;
468       NetExpr*elaborate_expr_param_idx_up_(Design*des,
469 					   NetScope*scope,
470 					   const NetExpr*par,
471 					   NetScope*found_in,
472 					   const NetExpr*par_msb,
473 					   const NetExpr*par_lsb,
474                                            bool need_const) const;
475       NetExpr*elaborate_expr_param_idx_do_(Design*des,
476 					   NetScope*scope,
477 					   const NetExpr*par,
478 					   NetScope*found_in,
479 					   const NetExpr*par_msb,
480 					   const NetExpr*par_lsb,
481                                            bool need_const) const;
482       NetExpr*elaborate_expr_net(Design*des,
483 				 NetScope*scope,
484 				 NetNet*net,
485 				 NetScope*found,
486 				 unsigned expr_wid,
487 				 unsigned flags) const;
488       NetExpr*elaborate_expr_net_word_(Design*des,
489 				       NetScope*scope,
490 				       NetNet*net,
491 				       NetScope*found,
492 				       unsigned expr_wid,
493 				       unsigned flags) const;
494       NetExpr*elaborate_expr_net_part_(Design*des,
495 				       NetScope*scope,
496 				       NetESignal*net,
497 				       NetScope*found,
498 				       unsigned expr_wid) const;
499       NetExpr*elaborate_expr_net_idx_up_(Design*des,
500 				         NetScope*scope,
501 				         NetESignal*net,
502 				         NetScope*found,
503                                          bool need_const) const;
504       NetExpr*elaborate_expr_net_idx_do_(Design*des,
505 				         NetScope*scope,
506 				         NetESignal*net,
507 				         NetScope*found,
508                                          bool need_const) const;
509       NetExpr*elaborate_expr_net_bit_(Design*des,
510 				      NetScope*scope,
511 				      NetESignal*net,
512 				      NetScope*found,
513                                       bool need_const) const;
514       NetExpr*elaborate_expr_net_bit_last_(Design*des,
515 					   NetScope*scope,
516 					   NetESignal*net,
517 					   NetScope*found,
518 					   bool need_const) const;
519 
520       NetExpr*elaborate_expr_class_member_(Design*des,
521 					   NetScope*scope,
522 					   unsigned expr_wid,
523 					   unsigned flags) const;
524 
525       unsigned test_width_method_(Design*des, NetScope*scope, width_mode_t&mode);
526 
527 
528     private:
529       NetNet* elaborate_lnet_common_(Design*des, NetScope*scope,
530 				     bool bidirectional_flag) const;
531 
532 
533       bool eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
534 			     long&midx, long&lidx) const;
535 };
536 
537 class PENewArray : public PExpr {
538 
539     public:
540       explicit PENewArray (PExpr*s, PExpr*i);
541       ~PENewArray();
542 
543       virtual void dump(ostream&) const;
544       virtual unsigned test_width(Design*des, NetScope*scope,
545 				  width_mode_t&mode);
546       virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
547 				     ivl_type_t type, unsigned flags) const;
548       virtual NetExpr*elaborate_expr(Design*des, NetScope*,
549 				     unsigned expr_wid,
550                                      unsigned flags) const;
551 
552     private:
553       PExpr*size_;
554       PExpr*init_;
555 };
556 
557 class PENewClass : public PExpr {
558 
559     public:
560 	// New without (or with default) constructor
561       explicit PENewClass ();
562 	// New with constructor arguments
563       explicit PENewClass (const std::list<PExpr*>&p);
564 
565       ~PENewClass();
566 
567       virtual void dump(ostream&) const;
568 	// Class objects don't have a useful width, but the expression
569 	// is IVL_VT_CLASS.
570       virtual unsigned test_width(Design*des, NetScope*scope,
571 				  width_mode_t&mode);
572 	// Note that class (new) expressions only appear in context
573 	// that uses this form of the elaborate_expr method. In fact,
574 	// the type argument is going to be a netclass_t object.
575       virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
576 				     ivl_type_t type, unsigned flags) const;
577 
578     private:
579       NetExpr* elaborate_expr_constructor_(Design*des, NetScope*scope,
580 					   const netclass_t*ctype,
581 					   NetExpr*obj, unsigned flags) const;
582 
583     private:
584       std::vector<PExpr*>parms_;
585 };
586 
587 class PENewCopy : public PExpr {
588     public:
589       explicit PENewCopy(PExpr*src);
590       ~PENewCopy();
591 
592       virtual void dump(ostream&) const;
593 	// Class objects don't have a useful width, but the expression
594 	// is IVL_VT_CLASS.
595       virtual unsigned test_width(Design*des, NetScope*scope,
596 				  width_mode_t&mode);
597 	// Note that class (new) expressions only appear in context
598 	// that uses this form of the elaborate_expr method. In fact,
599 	// the type argument is going to be a netclass_t object.
600       virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
601 				     ivl_type_t type, unsigned flags) const;
602 
603     private:
604       PExpr*src_;
605 };
606 
607 class PENull : public PExpr {
608     public:
609       explicit PENull();
610       ~PENull();
611 
612       virtual void dump(ostream&) const;
613       virtual unsigned test_width(Design*des, NetScope*scope,
614 				  width_mode_t&mode);
615       virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
616 				     ivl_type_t type, unsigned flags) const;
617       virtual NetExpr*elaborate_expr(Design*des, NetScope*,
618 				     unsigned expr_wid,
619                                      unsigned flags) const;
620 };
621 
622 class PENumber : public PExpr {
623 
624     public:
625       explicit PENumber(verinum*vp);
626       ~PENumber();
627 
628       const verinum& value() const;
629 
630       virtual void dump(ostream&) const;
631       virtual unsigned test_width(Design*des, NetScope*scope,
632 				  width_mode_t&mode);
633 
634       virtual NetExpr  *elaborate_expr(Design*des, NetScope*scope,
635 				       ivl_type_t type, unsigned flags) const;
636       virtual NetEConst*elaborate_expr(Design*des, NetScope*,
637 				       unsigned expr_wid, unsigned) const;
638       virtual NetAssign_* elaborate_lval(Design*des,
639 					 NetScope*scope,
640 					 bool is_cassign,
641 					 bool is_force) const;
642 
643       virtual verinum* eval_const(Design*des, NetScope*sc) const;
644 
645       virtual bool is_the_same(const PExpr*that) const;
646 
647     private:
648       verinum*const value_;
649 };
650 
651 /*
652  * This represents a string constant in an expression.
653  *
654  * The s parameter to the PEString constructor is a C string that this
655  * class instance will take for its own. The caller should not delete
656  * the string, the destructor will do it.
657  */
658 class PEString : public PExpr {
659 
660     public:
661       explicit PEString(char*s);
662       ~PEString();
663 
664       string value() const;
665       virtual void dump(ostream&) const;
666 
667       virtual unsigned test_width(Design*des, NetScope*scope,
668 				  width_mode_t&mode);
669 
670       virtual NetEConst*elaborate_expr(Design*des, NetScope*scope,
671 				       ivl_type_t type, unsigned flags) const;
672 
673       virtual NetEConst*elaborate_expr(Design*des, NetScope*,
674 				       unsigned expr_wid, unsigned) const;
675       verinum* eval_const(Design*, NetScope*) const;
676 
677     private:
678       char*text_;
679 };
680 
681 class PETypename : public PExpr {
682     public:
683       explicit PETypename(data_type_t*data_type);
684       ~PETypename();
685 
686       virtual void dump(ostream&) const;
687       virtual unsigned test_width(Design*des, NetScope*scope,
688 				  width_mode_t&mode);
689       virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
690 				     ivl_type_t type, unsigned flags) const;
691 
get_type()692       inline data_type_t* get_type() const { return data_type_; }
693 
694     private:
695       data_type_t*data_type_;
696 };
697 
698 class PEUnary : public PExpr {
699 
700     public:
701       explicit PEUnary(char op, PExpr*ex);
702       ~PEUnary();
703 
704       virtual void dump(ostream&out) const;
705 
706       virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
707 
708       virtual bool has_aa_term(Design*des, NetScope*scope) const;
709 
710       virtual unsigned test_width(Design*des, NetScope*scope,
711 				  width_mode_t&mode);
712 
713       virtual NetExpr*elaborate_expr(Design*des, NetScope*,
714 				     unsigned expr_wid,
715                                      unsigned flags) const;
716       virtual verinum* eval_const(Design*des, NetScope*sc) const;
717 
718     public:
get_op()719       inline char get_op() const { return op_; }
get_expr()720       inline PExpr*get_expr() const { return expr_; }
721 
722     private:
723       NetExpr* elaborate_expr_bits_(NetExpr*operand, unsigned expr_wid) const;
724 
725     private:
726       char op_;
727       PExpr*expr_;
728 };
729 
730 class PEBinary : public PExpr {
731 
732     public:
733       explicit PEBinary(char op, PExpr*l, PExpr*r);
734       ~PEBinary();
735 
736       virtual void dump(ostream&out) const;
737 
738       virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
739 
740       virtual bool has_aa_term(Design*des, NetScope*scope) const;
741 
742       virtual unsigned test_width(Design*des, NetScope*scope,
743 				  width_mode_t&mode);
744 
745       virtual NetExpr*elaborate_expr(Design*des, NetScope*,
746 				     unsigned expr_wid,
747                                      unsigned flags) const;
748       virtual verinum* eval_const(Design*des, NetScope*sc) const;
749 
750     protected:
751       char op_;
752       PExpr*left_;
753       PExpr*right_;
754 
755       NetExpr*elaborate_expr_base_(Design*, NetExpr*lp, NetExpr*rp,
756 				   unsigned expr_wid) const;
757       NetExpr*elaborate_eval_expr_base_(Design*, NetExpr*lp, NetExpr*rp,
758 					unsigned expr_wid) const;
759 
760       NetExpr*elaborate_expr_base_bits_(Design*, NetExpr*lp, NetExpr*rp,
761                                         unsigned expr_wid) const;
762       NetExpr*elaborate_expr_base_div_(Design*, NetExpr*lp, NetExpr*rp,
763 				       unsigned expr_wid) const;
764       NetExpr*elaborate_expr_base_mult_(Design*, NetExpr*lp, NetExpr*rp,
765 					unsigned expr_wid) const;
766       NetExpr*elaborate_expr_base_add_(Design*, NetExpr*lp, NetExpr*rp,
767 				       unsigned expr_wid) const;
768 
769 };
770 
771 /*
772  * Here are a few specialized classes for handling specific binary
773  * operators.
774  */
775 class PEBComp  : public PEBinary {
776 
777     public:
778       explicit PEBComp(char op, PExpr*l, PExpr*r);
779       ~PEBComp();
780 
781       virtual unsigned test_width(Design*des, NetScope*scope,
782 				  width_mode_t&mode);
783 
784       NetExpr* elaborate_expr(Design*des, NetScope*scope,
785 			      unsigned expr_wid, unsigned flags) const;
786 
787     private:
788       unsigned l_width_;
789       unsigned r_width_;
790 };
791 
792 /*
793  * This derived class is for handling logical expressions: && and ||.
794 */
795 class PEBLogic  : public PEBinary {
796 
797     public:
798       explicit PEBLogic(char op, PExpr*l, PExpr*r);
799       ~PEBLogic();
800 
801       virtual unsigned test_width(Design*des, NetScope*scope,
802 				  width_mode_t&mode);
803 
804       NetExpr* elaborate_expr(Design*des, NetScope*scope,
805 			      unsigned expr_wid, unsigned flags) const;
806 };
807 
808 /*
809  * A couple of the binary operands have a special sub-expression rule
810  * where the expression width is carried entirely by the left
811  * expression, and the right operand is self-determined.
812  */
813 class PEBLeftWidth  : public PEBinary {
814 
815     public:
816       explicit PEBLeftWidth(char op, PExpr*l, PExpr*r);
817       ~PEBLeftWidth() =0;
818 
819       virtual NetExpr*elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp,
820 					  unsigned expr_wid) const =0;
821 
822     protected:
823       virtual unsigned test_width(Design*des, NetScope*scope,
824 				  width_mode_t&mode);
825 
826       virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
827 				     unsigned expr_wid,
828                                      unsigned flags) const;
829 };
830 
831 class PEBPower  : public PEBLeftWidth {
832 
833     public:
834       explicit PEBPower(char op, PExpr*l, PExpr*r);
835       ~PEBPower();
836 
837       NetExpr*elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp,
838 				  unsigned expr_wid) const;
839 };
840 
841 class PEBShift  : public PEBLeftWidth {
842 
843     public:
844       explicit PEBShift(char op, PExpr*l, PExpr*r);
845       ~PEBShift();
846 
847       NetExpr*elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp,
848 				  unsigned expr_wid) const;
849 };
850 
851 /*
852  * This class supports the ternary (?:) operator. The operator takes
853  * three expressions, the test, the true result and the false result.
854  */
855 class PETernary : public PExpr {
856 
857     public:
858       explicit PETernary(PExpr*e, PExpr*t, PExpr*f);
859       ~PETernary();
860 
861       virtual void dump(ostream&out) const;
862 
863       virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
864 
865       virtual bool has_aa_term(Design*des, NetScope*scope) const;
866 
867       virtual unsigned test_width(Design*des, NetScope*scope,
868 				  width_mode_t&mode);
869 
870       virtual NetExpr*elaborate_expr(Design*des, NetScope*,
871 		                     unsigned expr_wid,
872                                      unsigned flags) const;
873       virtual verinum* eval_const(Design*des, NetScope*sc) const;
874 
875     private:
876       NetExpr* elab_and_eval_alternative_(Design*des, NetScope*scope,
877 					  PExpr*expr, unsigned expr_wid,
878                                           unsigned flags, bool short_cct) const;
879 
880     private:
881       PExpr*expr_;
882       PExpr*tru_;
883       PExpr*fal_;
884 };
885 
886 /*
887  * This class represents a parsed call to a function, including calls
888  * to system functions. The parameters in the parms list are the
889  * expressions that are passed as input to the ports of the function.
890  */
891 class PECallFunction : public PExpr {
892     public:
893       explicit PECallFunction(const pform_name_t&n, const vector<PExpr *> &parms);
894 	// Call function defined in package.
895       explicit PECallFunction(PPackage*pkg, perm_string n, const std::vector<PExpr *> &parms);
896       explicit PECallFunction(PPackage*pkg, perm_string n, const std::list<PExpr *> &parms);
897 
898 	// Used to convert a user function called as a task
899       explicit PECallFunction(PPackage*pkg, const pform_name_t&n, const std::vector<PExpr *> &parms);
900 
901 	// Call of system function (name is not hierarchical)
902       explicit PECallFunction(perm_string n, const vector<PExpr *> &parms);
903       explicit PECallFunction(perm_string n);
904 
905 	// std::list versions. Should be removed!
906       explicit PECallFunction(const pform_name_t&n, const list<PExpr *> &parms);
907       explicit PECallFunction(perm_string n, const list<PExpr *> &parms);
908 
909       ~PECallFunction();
910 
911       virtual void dump(ostream &) const;
912 
913       virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
914 
915       virtual bool has_aa_term(Design*des, NetScope*scope) const;
916 
917       virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
918 				     ivl_type_t type, unsigned flags) const;
919 
920       virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
921 				     unsigned expr_wid, unsigned flags) const;
922 
923       virtual unsigned test_width(Design*des, NetScope*scope,
924 				  width_mode_t&mode);
925 
926     private:
927       PPackage*package_;
928       pform_name_t path_;
929       std::vector<PExpr *> parms_;
930 
931         // For system functions.
932       bool is_overridden_;
933 
934       bool check_call_matches_definition_(Design*des, NetScope*dscope) const;
935 
936 
937       NetExpr* cast_to_width_(NetExpr*expr, unsigned wid) const;
938 
939       NetExpr*elaborate_expr_pkg_(Design*des, NetScope*scope,
940 				  unsigned expr_wid, unsigned flags)const;
941       NetExpr*elaborate_expr_method_(Design*des, NetScope*scope,
942 				     unsigned expr_wid,
943 				     bool add_this_flag = false) const;
944 #if 0
945       NetExpr*elaborate_expr_string_method_(Design*des, NetScope*scope) const;
946       NetExpr*elaborate_expr_enum_method_(Design*des, NetScope*scope,
947 					  unsigned expr_wid) const;
948 #endif
949 
950       NetExpr* elaborate_sfunc_(Design*des, NetScope*scope,
951                                 unsigned expr_wid,
952                                 unsigned flags) const;
953       NetExpr* elaborate_access_func_(Design*des, NetScope*scope, ivl_nature_t,
954                                       unsigned expr_wid) const;
955       unsigned test_width_sfunc_(Design*des, NetScope*scope,
956 			         width_mode_t&mode);
957       unsigned test_width_method_(Design*des, NetScope*scope,
958 				  width_mode_t&mode);
959 
960       NetExpr*elaborate_base_(Design*des, NetScope*scope, NetScope*dscope,
961 			      unsigned expr_wid, unsigned flags) const;
962 
963       unsigned elaborate_arguments_(Design*des, NetScope*scope,
964 				    NetFuncDef*def, bool need_const,
965 				    std::vector<NetExpr*>&parms,
966 				    unsigned parm_off) const;
967 };
968 
969 /*
970  * Support the SystemVerilog cast to size.
971  */
972 class PECastSize  : public PExpr {
973 
974     public:
975       explicit PECastSize(PExpr*size, PExpr*base);
976       ~PECastSize();
977 
978       void dump(ostream &out) const;
979 
980       virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
981 				     unsigned expr_wid,
982                                      unsigned flags) const;
983 
984       virtual unsigned test_width(Design*des, NetScope*scope,
985 				  width_mode_t&mode);
986 
987     private:
988       PExpr* size_;
989       PExpr* base_;
990 };
991 
992 /*
993  * Support the SystemVerilog cast to a different type.
994  */
995 class PECastType  : public PExpr {
996 
997     public:
998       explicit PECastType(data_type_t*target, PExpr*base);
999       ~PECastType();
1000 
1001       void dump(ostream &out) const;
1002 
1003       virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
1004 				     ivl_type_t type, unsigned flags) const;
1005 
1006       virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
1007 				     unsigned expr_wid, unsigned flags) const;
1008 
1009       virtual unsigned test_width(Design*des, NetScope*scope,
1010 				  width_mode_t&mode);
1011 
1012     private:
1013       data_type_t* target_;
1014       PExpr* base_;
1015 };
1016 
1017 /*
1018  * This class is used for error recovery. All methods do nothing and return
1019  * null or default values.
1020  */
1021 class PEVoid : public PExpr {
1022 
1023     public:
1024       explicit PEVoid();
1025       ~PEVoid();
1026 
1027       virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
1028 				     unsigned expr_wid,
1029                                      unsigned flags) const;
1030 };
1031 
1032 #endif /* IVL_PExpr_H */
1033