Support for wide modulus operations.
[iverilog.git] / PExpr.h
blob1beb01f6b1faf90eadbb5f1b8fe0877ca0b85a2b
1 #ifndef __PExpr_H
2 #define __PExpr_H
3 /*
4 * Copyright (c) 1998-2000 Stephen Williams <steve@icarus.com>
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.
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.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
22 # include <string>
23 # include <vector>
24 # include "netlist.h"
25 # include "verinum.h"
26 # include "LineInfo.h"
27 # include "pform_types.h"
29 class Design;
30 class Module;
31 class NetNet;
32 class NetExpr;
33 class NetScope;
36 * The PExpr class hierarchy supports the description of
37 * expressions. The parser can generate expression objects from the
38 * source, possibly reducing things that it knows how to reduce.
40 * The elaborate_net method is used by structural elaboration to build
41 * up a netlist interpretation of the expression.
44 class PExpr : public LineInfo {
46 public:
47 PExpr();
48 virtual ~PExpr();
50 virtual void dump(ostream&) const;
52 // This method tests the width that the expression wants to
53 // be. It is used by elaboration of assignments to figure out
54 // the width of the expression.
56 // The "min" is the width of the local context, so it the
57 // minimum width that this function should return. Initially
58 // this is the same as the lval width.
60 // The "lval" is the width of the destination where this
61 // result is going to go. This can be used to constrain the
62 // amount that an expression can reasonably expand. For
63 // example, there is no point expanding an addition to beyond
64 // the lval. This extra bit of information allows the
65 // expression to optimize itself a bit. If the lval==0, then
66 // the subexpression should not make l-value related
67 // optimizations.
69 // The unsigned_flag is set to true if the expression is
70 // unsized and therefore expandable. This happens if a
71 // sub-expression is an unsized literal. Some expressions make
72 // special use of that.
73 virtual unsigned test_width(Design*des, NetScope*scope,
74 unsigned min, unsigned lval,
75 bool&unsized_flag) const;
77 // Procedural elaboration of the expression. The expr_width is
78 // the width of the context of the expression (i.e. the
79 // l-value width of an assignment),
81 // ... or -1 if the expression is self-determined. or
82 // ... or -2 if the expression is losslessly
83 // self-determined. This can happen in situations where the
84 // result is going to a pseudo-infinitely wide context.
86 // The sys_task_arg flag is true if expressions are allowed to
87 // be incomplete.
88 virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
89 int expr_width, bool sys_task_arg) const;
91 // Elaborate expressions that are the r-value of parameter
92 // assignments. This elaboration follows the restrictions of
93 // constant expressions and supports later overriding and
94 // evaluation of parameters.
95 virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
97 // This method elaborate the expression as gates, for use in a
98 // continuous assign or other wholly structural context.
99 virtual NetNet* elaborate_net(Design*des, NetScope*scope,
100 unsigned lwidth,
101 const NetExpr* rise,
102 const NetExpr* fall,
103 const NetExpr* decay,
104 Link::strength_t drive0 =Link::STRONG,
105 Link::strength_t drive1 =Link::STRONG)
106 const;
108 // This method elaborates the expression as gates, but
109 // restricted for use as l-values of continuous assignments.
110 virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
111 bool implicit_net_ok =false) const;
113 // This is similar to elaborate_lnet, except that the
114 // expression is evaluated to be bi-directional. This is
115 // useful for arguments to inout ports of module instances and
116 // ports of tran primitives.
117 virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const;
119 // Expressions that can be in the l-value of procedural
120 // assignments can be elaborated with this method. If the
121 // is_force flag is true, then the set of valid l-value types
122 // is slightly modified to accomodate the Verilog force
123 // statement
124 virtual NetAssign_* elaborate_lval(Design*des,
125 NetScope*scope,
126 bool is_force) const;
128 // This attempts to evaluate a constant expression, and return
129 // a verinum as a result. If the expression cannot be
130 // evaluated, return 0.
131 virtual verinum* eval_const(Design*des, NetScope*sc) const;
133 // This method returns true if that expression is the same as
134 // this expression. This method is used for comparing
135 // expressions that must be structurally "identical".
136 virtual bool is_the_same(const PExpr*that) const;
138 // Return true if this expression is a valid constant
139 // expression. the Module pointer is needed to find parameter
140 // identifiers and any other module specific interpretations
141 // of expressions.
142 virtual bool is_constant(Module*) const;
144 private: // not implemented
145 PExpr(const PExpr&);
146 PExpr& operator= (const PExpr&);
149 ostream& operator << (ostream&, const PExpr&);
151 class PEConcat : public PExpr {
153 public:
154 PEConcat(const svector<PExpr*>&p, PExpr*r =0);
155 ~PEConcat();
157 virtual verinum* eval_const(Design*des, NetScope*sc) const;
158 virtual void dump(ostream&) const;
160 virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
161 bool implicit_net_ok =false) const;
162 virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const;
163 virtual NetNet* elaborate_net(Design*des, NetScope*scope,
164 unsigned width,
165 const NetExpr* rise,
166 const NetExpr* fall,
167 const NetExpr* decay,
168 Link::strength_t drive0,
169 Link::strength_t drive1) const;
170 virtual NetExpr*elaborate_expr(Design*des, NetScope*,
171 int expr_width, bool sys_task_arg) const;
172 virtual NetEConcat*elaborate_pexpr(Design*des, NetScope*) const;
173 virtual NetAssign_* elaborate_lval(Design*des,
174 NetScope*scope,
175 bool is_force) const;
176 virtual bool is_constant(Module*) const;
178 private:
179 NetNet* elaborate_lnet_common_(Design*des, NetScope*scope,
180 bool implicit_net_ok,
181 bool bidirectional_flag) const;
182 private:
183 svector<PExpr*>parms_;
184 PExpr*repeat_;
188 * Event expressions are expressions that can be combined with the
189 * event "or" operator. These include "posedge foo" and similar, and
190 * also include named events. "edge" events are associated with an
191 * expression, whereas named events simply have a name, which
192 * represents an event variable.
194 class PEEvent : public PExpr {
196 public:
197 enum edge_t {ANYEDGE, POSEDGE, NEGEDGE, POSITIVE};
199 // Use this constructor to create events based on edges or levels.
200 PEEvent(edge_t t, PExpr*e);
202 ~PEEvent();
204 edge_t type() const;
205 PExpr* expr() const;
207 virtual void dump(ostream&) const;
209 private:
210 edge_t type_;
211 PExpr *expr_;
215 * This holds a floating point constant in the source.
217 class PEFNumber : public PExpr {
219 public:
220 explicit PEFNumber(verireal*vp);
221 ~PEFNumber();
223 const verireal& value() const;
225 /* The eval_const method as applied to a floating point number
226 gets the *integer* value of the number. This accounts for
227 any rounding that is needed to get the value. */
228 virtual verinum* eval_const(Design*des, NetScope*sc) const;
230 /* A PEFNumber is a constant, so this returns true. */
231 virtual bool is_constant(Module*) const;
233 virtual NetExpr*elaborate_expr(Design*des, NetScope*,
234 int expr_width, bool sys_task_arg) const;
235 virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
237 virtual NetNet* elaborate_net(Design*des, NetScope*scope,
238 unsigned lwidth,
239 const NetExpr* rise,
240 const NetExpr* fall,
241 const NetExpr* decay,
242 Link::strength_t drive0,
243 Link::strength_t drive1) const;
245 virtual void dump(ostream&) const;
247 private:
248 verireal*value_;
251 class PEIdent : public PExpr {
253 public:
254 explicit PEIdent(perm_string);
255 explicit PEIdent(const pform_name_t&);
256 ~PEIdent();
258 // Add another name to the string of heirarchy that is the
259 // current identifier.
260 void append_name(perm_string);
262 virtual void dump(ostream&) const;
263 virtual unsigned test_width(Design*des, NetScope*scope,
264 unsigned min, unsigned lval,
265 bool&unsized_flag) const;
267 // Identifiers are allowed (with restrictions) is assign l-values.
268 virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
269 bool implicit_net_ok =false) const;
271 virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const;
273 // Identifiers are also allowed as procedural assignment l-values.
274 virtual NetAssign_* elaborate_lval(Design*des,
275 NetScope*scope,
276 bool is_force) const;
278 // Structural r-values are OK.
279 virtual NetNet* elaborate_net(Design*des, NetScope*scope,
280 unsigned lwidth,
281 const NetExpr* rise,
282 const NetExpr* fall,
283 const NetExpr* decay,
284 Link::strength_t drive0,
285 Link::strength_t drive1) const;
287 virtual NetExpr*elaborate_expr(Design*des, NetScope*,
288 int expr_width, bool sys_task_arg) const;
289 virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
291 // Elaborate the PEIdent as a port to a module. This method
292 // only applies to Ident expressions.
293 NetNet* elaborate_port(Design*des, NetScope*sc) const;
295 virtual bool is_constant(Module*) const;
296 verinum* eval_const(Design*des, NetScope*sc) const;
298 const pform_name_t& path() const { return path_; }
300 private:
301 pform_name_t path_;
303 private:
304 // Common functions to calculate parts of part/bit selects.
305 bool calculate_parts_(Design*, NetScope*, long&msb, long&lsb) const;
306 bool calculate_up_do_width_(Design*, NetScope*, unsigned long&wid) const;
308 private:
309 NetAssign_*elaborate_lval_net_word_(Design*, NetScope*, NetNet*) const;
310 bool elaborate_lval_net_part_(Design*, NetScope*, NetAssign_*) const;
311 bool elaborate_lval_net_idx_up_(Design*, NetScope*, NetAssign_*) const;
312 bool elaborate_lval_net_idx_do_(Design*, NetScope*, NetAssign_*) const;
314 private:
315 NetExpr*elaborate_expr_param(Design*des,
316 NetScope*scope,
317 const NetExpr*par,
318 NetScope*found,
319 const NetExpr*par_msb,
320 const NetExpr*par_lsb) const;
321 NetExpr*elaborate_expr_net(Design*des,
322 NetScope*scope,
323 NetNet*net,
324 NetScope*found,
325 bool sys_task_arg) const;
326 NetExpr*elaborate_expr_net_word_(Design*des,
327 NetScope*scope,
328 NetNet*net,
329 NetScope*found,
330 bool sys_task_arg) const;
331 NetExpr*elaborate_expr_net_part_(Design*des,
332 NetScope*scope,
333 NetESignal*net,
334 NetScope*found) const;
335 NetExpr*elaborate_expr_net_idx_up_(Design*des,
336 NetScope*scope,
337 NetESignal*net,
338 NetScope*found) const;
339 NetExpr*elaborate_expr_net_idx_do_(Design*des,
340 NetScope*scope,
341 NetESignal*net,
342 NetScope*found) const;
343 NetExpr*elaborate_expr_net_bit_(Design*des,
344 NetScope*scope,
345 NetESignal*net,
346 NetScope*found) const;
348 public:
350 NetNet* elaborate_net_array_(Design*des, NetScope*scope,
351 NetNet*sig, unsigned lwidth,
352 const NetExpr* rise,
353 const NetExpr* fall,
354 const NetExpr* decay,
355 Link::strength_t drive0,
356 Link::strength_t drive1) const;
358 NetNet* elaborate_net_net_(Design*des, NetScope*scope,
359 NetNet*sig, unsigned lwidth,
360 const NetExpr* rise,
361 const NetExpr* fall,
362 const NetExpr* decay,
363 Link::strength_t drive0,
364 Link::strength_t drive1) const;
365 NetNet* elaborate_net_net_idx_up_(Design*des, NetScope*scope,
366 NetNet*sig, unsigned lwidth,
367 const NetExpr* rise,
368 const NetExpr* fall,
369 const NetExpr* decay,
370 Link::strength_t drive0,
371 Link::strength_t drive1) const;
372 NetNet* elaborate_net_bitmux_(Design*des, NetScope*scope,
373 NetNet*sig,
374 const NetExpr* rise,
375 const NetExpr* fall,
376 const NetExpr* decay,
377 Link::strength_t drive0,
378 Link::strength_t drive1) const;
380 private:
381 NetNet* elaborate_lnet_common_(Design*des, NetScope*scope,
382 bool implicit_net_ok,
383 bool bidirectional_flag) const;
385 NetNet*make_implicit_net_(Design*des, NetScope*scope) const;
387 bool eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
388 unsigned&midx, unsigned&lidx) const;
389 NetNet*process_select_(Design*des, NetScope*scope, NetNet*sig) const;
393 class PENumber : public PExpr {
395 public:
396 explicit PENumber(verinum*vp);
397 ~PENumber();
399 const verinum& value() const;
401 virtual void dump(ostream&) const;
402 virtual unsigned test_width(Design*des, NetScope*scope,
403 unsigned min, unsigned lval,
404 bool&unsized_flag) const;
406 virtual NetNet* elaborate_net(Design*des, NetScope*scope,
407 unsigned lwidth,
408 const NetExpr* rise,
409 const NetExpr* fall,
410 const NetExpr* decay,
411 Link::strength_t drive0,
412 Link::strength_t drive1) const;
413 virtual NetEConst*elaborate_expr(Design*des, NetScope*,
414 int expr_width, bool) const;
415 virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
416 virtual NetAssign_* elaborate_lval(Design*des,
417 NetScope*scope,
418 bool is_force) const;
420 virtual verinum* eval_const(Design*des, NetScope*sc) const;
422 virtual bool is_the_same(const PExpr*that) const;
423 virtual bool is_constant(Module*) const;
425 private:
426 verinum*const value_;
430 * This represents a string constant in an expression.
432 * The s parameter to the PEString constructor is a C string that this
433 * class instance will take for its own. The caller should not delete
434 * the string, the destructor will do it.
436 class PEString : public PExpr {
438 public:
439 explicit PEString(char*s);
440 ~PEString();
442 string value() const;
443 virtual void dump(ostream&) const;
445 virtual unsigned test_width(Design*des, NetScope*scope,
446 unsigned min, unsigned lval,
447 bool&unsized_flag) const;
449 virtual NetNet* elaborate_net(Design*des, NetScope*scope,
450 unsigned width,
451 const NetExpr* rise,
452 const NetExpr* fall,
453 const NetExpr* decay,
454 Link::strength_t drive0,
455 Link::strength_t drive1) const;
456 virtual NetEConst*elaborate_expr(Design*des, NetScope*,
457 int expr_width, bool) const;
458 virtual NetEConst*elaborate_pexpr(Design*des, NetScope*sc) const;
459 verinum* eval_const(Design*, NetScope*) const;
461 virtual bool is_constant(Module*) const;
463 private:
464 char*text_;
467 class PEUnary : public PExpr {
469 public:
470 explicit PEUnary(char op, PExpr*ex);
471 ~PEUnary();
473 virtual void dump(ostream&out) const;
475 virtual NetNet* elaborate_net(Design*des, NetScope*scope,
476 unsigned width,
477 const NetExpr* rise,
478 const NetExpr* fall,
479 const NetExpr* decay,
480 Link::strength_t drive0,
481 Link::strength_t drive1) const;
482 virtual NetExpr*elaborate_expr(Design*des, NetScope*,
483 int expr_width, bool sys_task_arg) const;
484 virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
485 virtual verinum* eval_const(Design*des, NetScope*sc) const;
487 virtual bool is_constant(Module*) const;
489 private:
490 char op_;
491 PExpr*expr_;
494 class PEBinary : public PExpr {
496 public:
497 explicit PEBinary(char op, PExpr*l, PExpr*r);
498 ~PEBinary();
500 virtual bool is_constant(Module*) const;
502 virtual void dump(ostream&out) const;
504 virtual unsigned test_width(Design*des, NetScope*scope,
505 unsigned min, unsigned lval,
506 bool&unsized_flag) const;
508 virtual NetNet* elaborate_net(Design*des, NetScope*scope,
509 unsigned width,
510 const NetExpr* rise,
511 const NetExpr* fall,
512 const NetExpr* decay,
513 Link::strength_t drive0,
514 Link::strength_t drive1) const;
515 virtual NetEBinary*elaborate_expr(Design*des, NetScope*,
516 int expr_width, bool sys_task_arg) const;
517 virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
518 virtual verinum* eval_const(Design*des, NetScope*sc) const;
520 protected:
521 char op_;
522 PExpr*left_;
523 PExpr*right_;
525 NetEBinary*elaborate_expr_base_(Design*, NetExpr*lp, NetExpr*rp, int use_wid) const;
526 NetEBinary*elaborate_eval_expr_base_(Design*, NetExpr*lp, NetExpr*rp, int use_wid) const;
528 private:
529 NetNet* elaborate_net_add_(Design*des, NetScope*scope,
530 unsigned lwidth,
531 const NetExpr* rise,
532 const NetExpr* fall,
533 const NetExpr* decay) const;
534 NetNet* elaborate_net_bit_(Design*des, NetScope*scope,
535 unsigned lwidth,
536 const NetExpr* rise,
537 const NetExpr* fall,
538 const NetExpr* decay) const;
539 NetNet* elaborate_net_cmp_(Design*des, NetScope*scope,
540 unsigned lwidth,
541 const NetExpr* rise,
542 const NetExpr* fall,
543 const NetExpr* decay) const;
544 NetNet* elaborate_net_div_(Design*des, NetScope*scope,
545 unsigned lwidth,
546 const NetExpr* rise,
547 const NetExpr* fall,
548 const NetExpr* decay) const;
549 NetNet* elaborate_net_mod_(Design*des, NetScope*scope,
550 unsigned lwidth,
551 const NetExpr* rise,
552 const NetExpr* fall,
553 const NetExpr* decay) const;
554 NetNet* elaborate_net_log_(Design*des, NetScope*scope,
555 unsigned lwidth,
556 const NetExpr* rise,
557 const NetExpr* fall,
558 const NetExpr* decay) const;
559 NetNet* elaborate_net_mul_(Design*des, NetScope*scope,
560 unsigned lwidth,
561 const NetExpr* rise,
562 const NetExpr* fall,
563 const NetExpr* decay) const;
564 NetNet* elaborate_net_shift_(Design*des, NetScope*scope,
565 unsigned lwidth,
566 const NetExpr* rise,
567 const NetExpr* fall,
568 const NetExpr* decay) const;
572 * Here are a few specilized classes for handling specific binary
573 * operators.
575 class PEBComp : public PEBinary {
577 public:
578 explicit PEBComp(char op, PExpr*l, PExpr*r);
579 ~PEBComp();
581 virtual unsigned test_width(Design*des, NetScope*scope,
582 unsigned min, unsigned lval,
583 bool&flag) const;
585 NetEBinary* elaborate_expr(Design*des, NetScope*scope,
586 int expr_width, bool sys_task_arg) const;
589 class PEBShift : public PEBinary {
591 public:
592 explicit PEBShift(char op, PExpr*l, PExpr*r);
593 ~PEBShift();
595 virtual unsigned test_width(Design*des, NetScope*scope,
596 unsigned min, unsigned lval, bool&flag) const;
600 * This class supports the ternary (?:) operator. The operator takes
601 * three expressions, the test, the true result and the false result.
603 class PETernary : public PExpr {
605 public:
606 explicit PETernary(PExpr*e, PExpr*t, PExpr*f);
607 ~PETernary();
609 virtual bool is_constant(Module*) const;
611 virtual void dump(ostream&out) const;
612 virtual unsigned test_width(Design*des, NetScope*scope,
613 unsigned min, unsigned lval,
614 bool&unsized_flag) const;
616 virtual NetNet* elaborate_net(Design*des, NetScope*scope,
617 unsigned width,
618 const NetExpr* rise,
619 const NetExpr* fall,
620 const NetExpr* decay,
621 Link::strength_t drive0,
622 Link::strength_t drive1) const;
623 virtual NetETernary*elaborate_expr(Design*des, NetScope*,
624 int expr_width, bool sys_task_arg) const;
625 virtual NetETernary*elaborate_pexpr(Design*des, NetScope*sc) const;
626 virtual verinum* eval_const(Design*des, NetScope*sc) const;
628 private:
629 PExpr*expr_;
630 PExpr*tru_;
631 PExpr*fal_;
635 * This class represents a parsed call to a function, including calls
636 * to system functions. The parameters in the parms list are the
637 * expressions that are passed as input to the ports of the function.
639 class PECallFunction : public PExpr {
640 public:
641 explicit PECallFunction(const pform_name_t&n, const svector<PExpr *> &parms);
642 // Call of system function (name is not heirarchical)
643 explicit PECallFunction(perm_string n, const svector<PExpr *> &parms);
644 explicit PECallFunction(perm_string n);
645 ~PECallFunction();
647 virtual void dump(ostream &) const;
649 virtual NetNet* elaborate_net(Design*des, NetScope*scope,
650 unsigned width,
651 const NetExpr* rise,
652 const NetExpr* fall,
653 const NetExpr* decay,
654 Link::strength_t drive0,
655 Link::strength_t drive1) const;
656 virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
657 int expr_wid, bool sys_task_arg) const;
659 virtual unsigned test_width(Design*des, NetScope*scope,
660 unsigned min, unsigned lval,
661 bool&unsized_flag) const;
663 private:
664 pform_name_t path_;
665 svector<PExpr *> parms_;
667 bool check_call_matches_definition_(Design*des, NetScope*dscope) const;
669 NetExpr* elaborate_sfunc_(Design*des, NetScope*scope, int expr_wid) const;
670 NetNet* elaborate_net_sfunc_(Design*des, NetScope*scope,
671 unsigned width,
672 const NetExpr* rise,
673 const NetExpr* fall,
674 const NetExpr* decay,
675 Link::strength_t drive0,
676 Link::strength_t drive1) const;
677 unsigned test_width_sfunc_(Design*des, NetScope*scope,
678 unsigned min, unsigned lval,
679 bool&unsized_flag) const;
682 #endif