4 * Copyright (c) 1998-2008 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)
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
26 # include "LineInfo.h"
27 # include "pform_types.h"
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
{
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
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 // During the elaborate_sig phase, we may need to scan
78 // expressions to find implicit net declarations.
79 virtual bool elaborate_sig(Design
*des
, NetScope
*scope
) const;
81 // Procedural elaboration of the expression. The expr_width is
82 // the width of the context of the expression (i.e. the
83 // l-value width of an assignment),
85 // ... or -1 if the expression is self-determined. or
86 // ... or -2 if the expression is losslessly
87 // self-determined. This can happen in situations where the
88 // result is going to a pseudo-infinitely wide context.
90 // The sys_task_arg flag is true if expressions are allowed to
92 virtual NetExpr
*elaborate_expr(Design
*des
, NetScope
*scope
,
93 int expr_width
, bool sys_task_arg
) const;
95 // Elaborate expressions that are the r-value of parameter
96 // assignments. This elaboration follows the restrictions of
97 // constant expressions and supports later overriding and
98 // evaluation of parameters.
99 virtual NetExpr
*elaborate_pexpr(Design
*des
, NetScope
*sc
) const;
101 // This method elaborate the expression as gates, for use in a
102 // continuous assign or other wholly structural context.
103 virtual NetNet
* elaborate_net(Design
*des
, NetScope
*scope
,
107 const NetExpr
* decay
,
108 Link::strength_t drive0
=Link::STRONG
,
109 Link::strength_t drive1
=Link::STRONG
)
112 // This method elaborates the expression as gates, but
113 // restricted for use as l-values of continuous assignments.
114 virtual NetNet
* elaborate_lnet(Design
*des
, NetScope
*scope
) const;
116 // This is similar to elaborate_lnet, except that the
117 // expression is evaluated to be bi-directional. This is
118 // useful for arguments to inout ports of module instances and
119 // ports of tran primitives.
120 virtual NetNet
* elaborate_bi_net(Design
*des
, NetScope
*scope
) const;
122 // Expressions that can be in the l-value of procedural
123 // assignments can be elaborated with this method. If the
124 // is_force flag is true, then the set of valid l-value types
125 // is slightly modified to accommodate the Verilog force
127 virtual NetAssign_
* elaborate_lval(Design
*des
,
129 bool is_force
) const;
131 // This attempts to evaluate a constant expression, and return
132 // a verinum as a result. If the expression cannot be
133 // evaluated, return 0.
134 virtual verinum
* eval_const(Design
*des
, NetScope
*sc
) const;
136 // This method returns true if that expression is the same as
137 // this expression. This method is used for comparing
138 // expressions that must be structurally "identical".
139 virtual bool is_the_same(const PExpr
*that
) const;
141 // Return true if this expression is a valid constant
142 // expression. the Module pointer is needed to find parameter
143 // identifiers and any other module specific interpretations
145 virtual bool is_constant(Module
*) const;
147 private: // not implemented
149 PExpr
& operator= (const PExpr
&);
152 ostream
& operator << (ostream
&, const PExpr
&);
154 class PEConcat
: public PExpr
{
157 PEConcat(const svector
<PExpr
*>&p
, PExpr
*r
=0);
160 virtual verinum
* eval_const(Design
*des
, NetScope
*sc
) const;
161 virtual void dump(ostream
&) const;
163 virtual bool elaborate_sig(Design
*des
, NetScope
*scope
) const;
164 virtual NetNet
* elaborate_lnet(Design
*des
, NetScope
*scope
) const;
165 virtual NetNet
* elaborate_bi_net(Design
*des
, NetScope
*scope
) const;
166 virtual NetNet
* elaborate_net(Design
*des
, NetScope
*scope
,
170 const NetExpr
* decay
,
171 Link::strength_t drive0
,
172 Link::strength_t drive1
) const;
173 virtual NetExpr
*elaborate_expr(Design
*des
, NetScope
*,
174 int expr_width
, bool sys_task_arg
) const;
175 virtual NetEConcat
*elaborate_pexpr(Design
*des
, NetScope
*) const;
176 virtual NetAssign_
* elaborate_lval(Design
*des
,
178 bool is_force
) const;
179 virtual bool is_constant(Module
*) const;
182 NetNet
* elaborate_lnet_common_(Design
*des
, NetScope
*scope
,
183 bool bidirectional_flag
) const;
185 svector
<PExpr
*>parms_
;
190 * Event expressions are expressions that can be combined with the
191 * event "or" operator. These include "posedge foo" and similar, and
192 * also include named events. "edge" events are associated with an
193 * expression, whereas named events simply have a name, which
194 * represents an event variable.
196 class PEEvent
: public PExpr
{
199 enum edge_t
{ANYEDGE
, POSEDGE
, NEGEDGE
, POSITIVE
};
201 // Use this constructor to create events based on edges or levels.
202 PEEvent(edge_t t
, PExpr
*e
);
209 virtual void dump(ostream
&) const;
217 * This holds a floating point constant in the source.
219 class PEFNumber
: public PExpr
{
222 explicit PEFNumber(verireal
*vp
);
225 const verireal
& value() const;
227 /* The eval_const method as applied to a floating point number
228 gets the *integer* value of the number. This accounts for
229 any rounding that is needed to get the value. */
230 virtual verinum
* eval_const(Design
*des
, NetScope
*sc
) const;
232 /* A PEFNumber is a constant, so this returns true. */
233 virtual bool is_constant(Module
*) const;
235 virtual NetExpr
*elaborate_expr(Design
*des
, NetScope
*,
236 int expr_width
, bool sys_task_arg
) const;
237 virtual NetExpr
*elaborate_pexpr(Design
*des
, NetScope
*sc
) const;
239 virtual NetNet
* elaborate_net(Design
*des
, NetScope
*scope
,
243 const NetExpr
* decay
,
244 Link::strength_t drive0
,
245 Link::strength_t drive1
) const;
247 virtual void dump(ostream
&) const;
253 class PEIdent
: public PExpr
{
256 explicit PEIdent(perm_string
);
257 explicit PEIdent(const pform_name_t
&);
260 // Add another name to the string of hierarchy that is the
261 // current identifier.
262 void append_name(perm_string
);
264 virtual void dump(ostream
&) const;
265 virtual unsigned test_width(Design
*des
, NetScope
*scope
,
266 unsigned min
, unsigned lval
,
267 bool&unsized_flag
) const;
269 virtual bool elaborate_sig(Design
*des
, NetScope
*scope
) const;
271 // Identifiers are allowed (with restrictions) is assign l-values.
272 virtual NetNet
* elaborate_lnet(Design
*des
, NetScope
*scope
) const;
274 virtual NetNet
* elaborate_bi_net(Design
*des
, NetScope
*scope
) const;
276 // Identifiers are also allowed as procedural assignment l-values.
277 virtual NetAssign_
* elaborate_lval(Design
*des
,
279 bool is_force
) const;
281 // Structural r-values are OK.
282 virtual NetNet
* elaborate_net(Design
*des
, NetScope
*scope
,
286 const NetExpr
* decay
,
287 Link::strength_t drive0
,
288 Link::strength_t drive1
) const;
290 virtual NetExpr
*elaborate_expr(Design
*des
, NetScope
*,
291 int expr_width
, bool sys_task_arg
) const;
292 virtual NetExpr
*elaborate_pexpr(Design
*des
, NetScope
*sc
) const;
294 // Elaborate the PEIdent as a port to a module. This method
295 // only applies to Ident expressions.
296 NetNet
* elaborate_port(Design
*des
, NetScope
*sc
) const;
298 virtual bool is_constant(Module
*) const;
299 verinum
* eval_const(Design
*des
, NetScope
*sc
) const;
301 const pform_name_t
& path() const { return path_
; }
307 // Common functions to calculate parts of part/bit selects.
308 bool calculate_parts_(Design
*, NetScope
*, long&msb
, long&lsb
) const;
309 bool calculate_up_do_width_(Design
*, NetScope
*, unsigned long&wid
) const;
312 NetAssign_
*elaborate_lval_net_word_(Design
*, NetScope
*, NetNet
*) const;
313 bool elaborate_lval_net_part_(Design
*, NetScope
*, NetAssign_
*) const;
314 bool elaborate_lval_net_idx_(Design
*, NetScope
*, NetAssign_
*,
315 index_component_t::ctype_t
) const;
318 NetExpr
*elaborate_expr_param(Design
*des
,
322 const NetExpr
*par_msb
,
323 const NetExpr
*par_lsb
) const;
324 NetExpr
*elaborate_expr_net(Design
*des
,
328 bool sys_task_arg
) const;
329 NetExpr
*elaborate_expr_net_word_(Design
*des
,
333 bool sys_task_arg
) const;
334 NetExpr
*elaborate_expr_net_part_(Design
*des
,
337 NetScope
*found
) const;
338 NetExpr
*elaborate_expr_net_idx_up_(Design
*des
,
341 NetScope
*found
) const;
342 NetExpr
*elaborate_expr_net_idx_do_(Design
*des
,
345 NetScope
*found
) const;
346 NetExpr
*elaborate_expr_net_bit_(Design
*des
,
349 NetScope
*found
) const;
353 NetNet
* elaborate_net_array_(Design
*des
, NetScope
*scope
,
354 NetNet
*sig
, unsigned lwidth
,
357 const NetExpr
* decay
,
358 Link::strength_t drive0
,
359 Link::strength_t drive1
) const;
361 NetNet
* elaborate_net_net_(Design
*des
, NetScope
*scope
,
362 NetNet
*sig
, unsigned lwidth
,
365 const NetExpr
* decay
,
366 Link::strength_t drive0
,
367 Link::strength_t drive1
) const;
368 NetNet
* elaborate_net_net_idx_up_(Design
*des
, NetScope
*scope
,
369 NetNet
*sig
, unsigned lwidth
,
372 const NetExpr
* decay
,
373 Link::strength_t drive0
,
374 Link::strength_t drive1
) const;
375 NetNet
* elaborate_net_bitmux_(Design
*des
, NetScope
*scope
,
379 const NetExpr
* decay
,
380 Link::strength_t drive0
,
381 Link::strength_t drive1
) const;
384 NetNet
* elaborate_lnet_common_(Design
*des
, NetScope
*scope
,
385 bool bidirectional_flag
) const;
387 NetNet
*make_implicit_net_(Design
*des
, NetScope
*scope
) const;
389 bool eval_part_select_(Design
*des
, NetScope
*scope
, NetNet
*sig
,
390 long&midx
, long&lidx
) const;
391 NetNet
*process_select_(Design
*des
, NetScope
*scope
, NetNet
*sig
) const;
395 class PENumber
: public PExpr
{
398 explicit PENumber(verinum
*vp
);
401 const verinum
& value() const;
403 virtual void dump(ostream
&) const;
404 virtual unsigned test_width(Design
*des
, NetScope
*scope
,
405 unsigned min
, unsigned lval
,
406 bool&unsized_flag
) const;
408 virtual NetNet
* elaborate_net(Design
*des
, NetScope
*scope
,
412 const NetExpr
* decay
,
413 Link::strength_t drive0
,
414 Link::strength_t drive1
) const;
415 virtual NetEConst
*elaborate_expr(Design
*des
, NetScope
*,
416 int expr_width
, bool) const;
417 virtual NetExpr
*elaborate_pexpr(Design
*des
, NetScope
*sc
) const;
418 virtual NetAssign_
* elaborate_lval(Design
*des
,
420 bool is_force
) const;
422 virtual verinum
* eval_const(Design
*des
, NetScope
*sc
) const;
424 virtual bool is_the_same(const PExpr
*that
) const;
425 virtual bool is_constant(Module
*) const;
428 verinum
*const value_
;
432 * This represents a string constant in an expression.
434 * The s parameter to the PEString constructor is a C string that this
435 * class instance will take for its own. The caller should not delete
436 * the string, the destructor will do it.
438 class PEString
: public PExpr
{
441 explicit PEString(char*s
);
444 string
value() const;
445 virtual void dump(ostream
&) const;
447 virtual unsigned test_width(Design
*des
, NetScope
*scope
,
448 unsigned min
, unsigned lval
,
449 bool&unsized_flag
) const;
451 virtual NetNet
* elaborate_net(Design
*des
, NetScope
*scope
,
455 const NetExpr
* decay
,
456 Link::strength_t drive0
,
457 Link::strength_t drive1
) const;
458 virtual NetEConst
*elaborate_expr(Design
*des
, NetScope
*,
459 int expr_width
, bool) const;
460 virtual NetEConst
*elaborate_pexpr(Design
*des
, NetScope
*sc
) const;
461 verinum
* eval_const(Design
*, NetScope
*) const;
463 virtual bool is_constant(Module
*) const;
469 class PEUnary
: public PExpr
{
472 explicit PEUnary(char op
, PExpr
*ex
);
475 virtual void dump(ostream
&out
) const;
477 virtual bool elaborate_sig(Design
*des
, NetScope
*scope
) const;
479 virtual NetNet
* elaborate_net(Design
*des
, NetScope
*scope
,
483 const NetExpr
* decay
,
484 Link::strength_t drive0
,
485 Link::strength_t drive1
) const;
486 virtual NetExpr
*elaborate_expr(Design
*des
, NetScope
*,
487 int expr_width
, bool sys_task_arg
) const;
488 virtual NetExpr
*elaborate_pexpr(Design
*des
, NetScope
*sc
) const;
489 virtual verinum
* eval_const(Design
*des
, NetScope
*sc
) const;
491 virtual bool is_constant(Module
*) const;
494 NetNet
* elab_net_uminus_const_logic_(Design
*des
, NetScope
*scope
,
499 const NetExpr
* decay
,
500 Link::strength_t drive0
,
501 Link::strength_t drive1
) const;
502 NetNet
* elab_net_uminus_const_real_(Design
*des
, NetScope
*scope
,
507 const NetExpr
* decay
,
508 Link::strength_t drive0
,
509 Link::strength_t drive1
) const;
510 NetNet
* elab_net_unary_real_(Design
*des
, NetScope
*scope
,
515 const NetExpr
* decay
,
516 Link::strength_t drive0
,
517 Link::strength_t drive1
) const;
524 class PEBinary
: public PExpr
{
527 explicit PEBinary(char op
, PExpr
*l
, PExpr
*r
);
530 virtual bool is_constant(Module
*) const;
532 virtual void dump(ostream
&out
) const;
534 virtual unsigned test_width(Design
*des
, NetScope
*scope
,
535 unsigned min
, unsigned lval
,
536 bool&unsized_flag
) const;
538 virtual bool elaborate_sig(Design
*des
, NetScope
*scope
) const;
540 virtual NetNet
* elaborate_net(Design
*des
, NetScope
*scope
,
544 const NetExpr
* decay
,
545 Link::strength_t drive0
,
546 Link::strength_t drive1
) const;
547 virtual NetExpr
*elaborate_expr(Design
*des
, NetScope
*,
548 int expr_width
, bool sys_task_arg
) const;
549 virtual NetExpr
*elaborate_pexpr(Design
*des
, NetScope
*sc
) const;
550 virtual verinum
* eval_const(Design
*des
, NetScope
*sc
) const;
557 NetExpr
*elaborate_expr_base_(Design
*, NetExpr
*lp
, NetExpr
*rp
, int use_wid
) const;
558 NetExpr
*elaborate_eval_expr_base_(Design
*, NetExpr
*lp
, NetExpr
*rp
, int use_wid
) const;
560 static void suppress_operand_sign_if_needed_(NetExpr
*lp
, NetExpr
*rp
);
563 NetNet
* elaborate_net_add_(Design
*des
, NetScope
*scope
,
567 const NetExpr
* decay
) const;
568 NetNet
* elaborate_net_bit_(Design
*des
, NetScope
*scope
,
572 const NetExpr
* decay
) const;
573 NetNet
* elaborate_net_cmp_(Design
*des
, NetScope
*scope
,
577 const NetExpr
* decay
) const;
578 NetNet
* elaborate_net_div_(Design
*des
, NetScope
*scope
,
582 const NetExpr
* decay
) const;
583 NetNet
* elaborate_net_mod_(Design
*des
, NetScope
*scope
,
587 const NetExpr
* decay
) const;
588 NetNet
* elaborate_net_log_(Design
*des
, NetScope
*scope
,
592 const NetExpr
* decay
) const;
593 NetNet
* elaborate_net_mul_(Design
*des
, NetScope
*scope
,
597 const NetExpr
* decay
) const;
598 NetNet
* elaborate_net_pow_(Design
*des
, NetScope
*scope
,
602 const NetExpr
* decay
) const;
603 NetNet
* elaborate_net_shift_(Design
*des
, NetScope
*scope
,
607 const NetExpr
* decay
) const;
611 * Here are a few specialized classes for handling specific binary
614 class PEBComp
: public PEBinary
{
617 explicit PEBComp(char op
, PExpr
*l
, PExpr
*r
);
620 virtual unsigned test_width(Design
*des
, NetScope
*scope
,
621 unsigned min
, unsigned lval
,
624 NetExpr
* elaborate_expr(Design
*des
, NetScope
*scope
,
625 int expr_width
, bool sys_task_arg
) const;
628 class PEBShift
: public PEBinary
{
631 explicit PEBShift(char op
, PExpr
*l
, PExpr
*r
);
634 virtual unsigned test_width(Design
*des
, NetScope
*scope
,
635 unsigned min
, unsigned lval
, bool&flag
) const;
639 * This class supports the ternary (?:) operator. The operator takes
640 * three expressions, the test, the true result and the false result.
642 class PETernary
: public PExpr
{
645 explicit PETernary(PExpr
*e
, PExpr
*t
, PExpr
*f
);
648 virtual bool is_constant(Module
*) const;
650 virtual void dump(ostream
&out
) const;
651 virtual unsigned test_width(Design
*des
, NetScope
*scope
,
652 unsigned min
, unsigned lval
,
653 bool&unsized_flag
) const;
655 virtual bool elaborate_sig(Design
*des
, NetScope
*scope
) const;
657 virtual NetNet
* elaborate_net(Design
*des
, NetScope
*scope
,
661 const NetExpr
* decay
,
662 Link::strength_t drive0
,
663 Link::strength_t drive1
) const;
664 virtual NetETernary
*elaborate_expr(Design
*des
, NetScope
*,
665 int expr_width
, bool sys_task_arg
) const;
666 virtual NetETernary
*elaborate_pexpr(Design
*des
, NetScope
*sc
) const;
667 virtual verinum
* eval_const(Design
*des
, NetScope
*sc
) const;
676 * This class represents a parsed call to a function, including calls
677 * to system functions. The parameters in the parms list are the
678 * expressions that are passed as input to the ports of the function.
680 class PECallFunction
: public PExpr
{
682 explicit PECallFunction(const pform_name_t
&n
, const svector
<PExpr
*> &parms
);
683 // Call of system function (name is not hierarchical)
684 explicit PECallFunction(perm_string n
, const svector
<PExpr
*> &parms
);
685 explicit PECallFunction(perm_string n
);
688 virtual void dump(ostream
&) const;
690 virtual NetNet
* elaborate_net(Design
*des
, NetScope
*scope
,
694 const NetExpr
* decay
,
695 Link::strength_t drive0
,
696 Link::strength_t drive1
) const;
697 virtual NetExpr
*elaborate_expr(Design
*des
, NetScope
*scope
,
698 int expr_wid
, bool sys_task_arg
) const;
700 virtual unsigned test_width(Design
*des
, NetScope
*scope
,
701 unsigned min
, unsigned lval
,
702 bool&unsized_flag
) const;
706 svector
<PExpr
*> parms_
;
708 bool check_call_matches_definition_(Design
*des
, NetScope
*dscope
) const;
710 NetExpr
* elaborate_sfunc_(Design
*des
, NetScope
*scope
, int expr_wid
) const;
711 NetNet
* elaborate_net_sfunc_(Design
*des
, NetScope
*scope
,
715 const NetExpr
* decay
,
716 Link::strength_t drive0
,
717 Link::strength_t drive1
) const;
718 unsigned test_width_sfunc_(Design
*des
, NetScope
*scope
,
719 unsigned min
, unsigned lval
,
720 bool&unsized_flag
) const;