1998-11-04 00:28:49 +01:00
|
|
|
#ifndef __PExpr_H
|
|
|
|
|
#define __PExpr_H
|
|
|
|
|
/*
|
2011-02-26 23:59:52 +01:00
|
|
|
* Copyright (c) 1998-2011 Stephen Williams <steve@icarus.com>
|
2013-02-17 23:42:07 +01:00
|
|
|
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
|
1998-11-04 00:28:49 +01:00
|
|
|
*
|
|
|
|
|
* This source code is free software; you can redistribute it
|
|
|
|
|
* and/or modify it in source code form under the terms of the GNU
|
|
|
|
|
* General Public License as published by the Free Software
|
|
|
|
|
* Foundation; either version 2 of the License, or (at your option)
|
|
|
|
|
* any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program; if not, write to the Free Software
|
2012-08-29 03:41:23 +02:00
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
1998-11-04 00:28:49 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
# include <string>
|
2006-02-02 03:43:57 +01:00
|
|
|
# include <vector>
|
2008-11-19 01:52:05 +01:00
|
|
|
# include <valarray>
|
1999-04-29 04:16:26 +02:00
|
|
|
# include "netlist.h"
|
1998-11-04 00:28:49 +01:00
|
|
|
# include "verinum.h"
|
1999-04-19 03:59:36 +02:00
|
|
|
# include "LineInfo.h"
|
2007-05-24 06:07:11 +02:00
|
|
|
# include "pform_types.h"
|
1998-11-04 00:28:49 +01:00
|
|
|
|
|
|
|
|
class Design;
|
1999-05-16 07:08:42 +02:00
|
|
|
class Module;
|
2010-01-12 21:11:01 +01:00
|
|
|
class LexicalScope;
|
1998-11-04 00:28:49 +01:00
|
|
|
class NetNet;
|
|
|
|
|
class NetExpr;
|
2000-03-08 05:36:53 +01:00
|
|
|
class NetScope;
|
2013-02-17 23:42:07 +01:00
|
|
|
class PPackage;
|
1998-11-04 00:28:49 +01:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* The PExpr class hierarchy supports the description of
|
|
|
|
|
* expressions. The parser can generate expression objects from the
|
|
|
|
|
* source, possibly reducing things that it knows how to reduce.
|
|
|
|
|
*/
|
|
|
|
|
|
1999-04-19 03:59:36 +02:00
|
|
|
class PExpr : public LineInfo {
|
2000-04-12 06:23:57 +02:00
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
public:
|
2011-02-26 23:59:52 +01:00
|
|
|
enum width_mode_t { SIZED, EXPAND, LOSSLESS, UNSIZED };
|
|
|
|
|
|
2011-03-27 12:08:33 +02:00
|
|
|
// Flag values that can be passed to elaborate_expr.
|
|
|
|
|
static const unsigned NO_FLAGS = 0x0;
|
|
|
|
|
static const unsigned NEED_CONST = 0x1;
|
|
|
|
|
static const unsigned SYS_TASK_ARG = 0x2;
|
2012-05-07 00:11:26 +02:00
|
|
|
static const unsigned ANNOTATABLE = 0x4;
|
2011-03-27 12:08:33 +02:00
|
|
|
|
2000-04-12 06:23:57 +02:00
|
|
|
PExpr();
|
1998-11-04 00:28:49 +01:00
|
|
|
virtual ~PExpr();
|
|
|
|
|
|
|
|
|
|
virtual void dump(ostream&) const;
|
1999-09-15 06:17:52 +02:00
|
|
|
|
2010-01-12 21:11:01 +01:00
|
|
|
// This method tests whether the expression contains any identifiers
|
|
|
|
|
// that have not been previously declared in the specified scope or
|
|
|
|
|
// in any containing scope. Any such identifiers are added to the
|
|
|
|
|
// specified scope as scalar nets of the specified type.
|
|
|
|
|
//
|
|
|
|
|
// This operation must be performed by the parser, to ensure that
|
|
|
|
|
// subsequent declarations do not affect the decision to create an
|
|
|
|
|
// implicit net.
|
|
|
|
|
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
|
|
|
|
|
|
2008-11-09 01:26:55 +01:00
|
|
|
// This method tests whether the expression contains any
|
|
|
|
|
// references to automatically allocated variables.
|
|
|
|
|
virtual bool has_aa_term(Design*des, NetScope*scope) const;
|
|
|
|
|
|
2011-02-26 23:59:52 +01:00
|
|
|
// This method tests the type and width that the expression wants
|
|
|
|
|
// to be. It should be called before elaborating an expression to
|
|
|
|
|
// figure out the type and width of the expression. It also figures
|
|
|
|
|
// out the minimum width that can be used to evaluate the expression
|
|
|
|
|
// without changing the result. This allows the expression width to
|
|
|
|
|
// be pruned when not all bits of the result are used.
|
2006-10-30 06:44:49 +01:00
|
|
|
//
|
2011-02-26 23:59:52 +01:00
|
|
|
// Normally mode should be initialised to SIZED before starting to
|
|
|
|
|
// test the width of an expression. In SIZED mode the expression
|
|
|
|
|
// width will be calculated strictly according to the IEEE standard
|
|
|
|
|
// rules for expression width.
|
|
|
|
|
// If the expression contains an unsized literal, mode will be
|
|
|
|
|
// changed to LOSSLESS. In LOSSLESS mode the expression width will
|
|
|
|
|
// be calculated as the minimum width necessary to avoid arithmetic
|
|
|
|
|
// overflow or underflow.
|
|
|
|
|
// If the expression both contains an unsized literal and contains
|
|
|
|
|
// an operation that coerces a vector operand to a different type
|
|
|
|
|
// (signed <-> unsigned), mode is changed to UNSIZED. UNSIZED mode
|
|
|
|
|
// is the same as LOSSLESS, except that the final expression width
|
|
|
|
|
// will be forced to be at least integer_width. This is necessary
|
|
|
|
|
// to ensure compatibility with the IEEE standard, which requires
|
|
|
|
|
// unsized literals to be treated as having the same width as an
|
|
|
|
|
// integer. The lossless width calculation is inadequate in this
|
|
|
|
|
// case because coercing an operand to a different type means that
|
|
|
|
|
// the expression no longer obeys the normal rules of arithmetic.
|
2006-10-30 06:44:49 +01:00
|
|
|
//
|
2011-02-26 23:59:52 +01:00
|
|
|
// If mode is initialised to EXPAND instead of SIZED, the expression
|
|
|
|
|
// width will be calculated as the minimum width necessary to avoid
|
|
|
|
|
// arithmetic overflow or underflow, even if it contains no unsized
|
|
|
|
|
// literals. mode will be changed LOSSLESS or UNSIZED as described
|
|
|
|
|
// above. This supports a non-standard mode of expression width
|
|
|
|
|
// calculation.
|
2008-09-27 07:20:11 +02:00
|
|
|
//
|
2011-02-26 23:59:52 +01:00
|
|
|
// When the final value of mode is UNSIZED, the width returned by
|
|
|
|
|
// this method is the calculated lossless width, but the width
|
|
|
|
|
// returned by a subsequent call to the expr_width method will be
|
|
|
|
|
// the final expression width.
|
2011-03-03 05:23:02 +01:00
|
|
|
virtual unsigned test_width(Design*des, NetScope*scope,
|
2011-02-26 23:59:52 +01:00
|
|
|
width_mode_t&mode);
|
2008-10-11 05:42:07 +02:00
|
|
|
|
|
|
|
|
// After the test_width method is complete, these methods
|
|
|
|
|
// return valid results.
|
|
|
|
|
ivl_variable_type_t expr_type() const { return expr_type_; }
|
|
|
|
|
unsigned expr_width() const { return expr_width_; }
|
2011-02-26 23:59:52 +01:00
|
|
|
unsigned min_width() const { return min_width_; }
|
|
|
|
|
bool has_sign() const { return signed_flag_; }
|
|
|
|
|
|
|
|
|
|
// This method allows the expression type (signed/unsigned)
|
|
|
|
|
// to be propagated down to any context-dependant operands.
|
|
|
|
|
void cast_signed(bool flag) { signed_flag_ = flag; }
|
2006-10-30 06:44:49 +01:00
|
|
|
|
2012-10-01 03:03:10 +02:00
|
|
|
// This is the more generic form of the elaborate_expr method
|
|
|
|
|
// below. The plan is to replace the simpler elaborate_expr
|
|
|
|
|
// method with this version, which can handle more advanced
|
|
|
|
|
// types. But for now, this is only implemented in special cases.
|
|
|
|
|
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
|
|
|
|
ivl_type_t type, unsigned flags) const;
|
|
|
|
|
|
2006-06-02 06:48:49 +02:00
|
|
|
// Procedural elaboration of the expression. The expr_width is
|
2011-02-26 23:59:52 +01:00
|
|
|
// the required width of the expression.
|
2007-06-28 07:05:36 +02:00
|
|
|
//
|
|
|
|
|
// The sys_task_arg flag is true if expressions are allowed to
|
|
|
|
|
// be incomplete.
|
2002-04-13 04:33:17 +02:00
|
|
|
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
2011-02-26 23:59:52 +01:00
|
|
|
unsigned expr_wid,
|
2011-03-27 12:08:33 +02:00
|
|
|
unsigned flags) const;
|
2000-03-08 05:36:53 +01:00
|
|
|
|
1999-09-15 06:17:52 +02:00
|
|
|
// This method elaborates the expression as gates, but
|
|
|
|
|
// restricted for use as l-values of continuous assignments.
|
2008-03-19 04:50:40 +01:00
|
|
|
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
|
1998-11-04 00:28:49 +01:00
|
|
|
|
2005-08-06 19:58:16 +02:00
|
|
|
// This is similar to elaborate_lnet, except that the
|
|
|
|
|
// expression is evaluated to be bi-directional. This is
|
|
|
|
|
// useful for arguments to inout ports of module instances and
|
|
|
|
|
// ports of tran primitives.
|
|
|
|
|
virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const;
|
|
|
|
|
|
2000-09-09 17:21:26 +02:00
|
|
|
// Expressions that can be in the l-value of procedural
|
2004-12-30 00:55:43 +01:00
|
|
|
// assignments can be elaborated with this method. If the
|
|
|
|
|
// is_force flag is true, then the set of valid l-value types
|
2008-01-25 22:34:51 +01:00
|
|
|
// is slightly modified to accommodate the Verilog force
|
2004-12-30 00:55:43 +01:00
|
|
|
// statement
|
|
|
|
|
virtual NetAssign_* elaborate_lval(Design*des,
|
|
|
|
|
NetScope*scope,
|
|
|
|
|
bool is_force) const;
|
2000-09-09 17:21:26 +02:00
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
// This attempts to evaluate a constant expression, and return
|
|
|
|
|
// a verinum as a result. If the expression cannot be
|
|
|
|
|
// evaluated, return 0.
|
2007-06-04 21:14:06 +02:00
|
|
|
virtual verinum* eval_const(Design*des, NetScope*sc) const;
|
1998-11-11 01:01:51 +01:00
|
|
|
|
2011-03-13 14:29:42 +01:00
|
|
|
// This method returns true if the expression represents a
|
|
|
|
|
// structural net that can have multiple drivers. This is
|
|
|
|
|
// used to test whether an input port connection can be
|
|
|
|
|
// collapsed to a single wire.
|
|
|
|
|
virtual bool is_collapsible_net(Design*des, NetScope*scope) const;
|
|
|
|
|
|
1998-11-11 01:01:51 +01:00
|
|
|
// This method returns true if that expression is the same as
|
|
|
|
|
// this expression. This method is used for comparing
|
|
|
|
|
// expressions that must be structurally "identical".
|
|
|
|
|
virtual bool is_the_same(const PExpr*that) const;
|
1999-05-16 07:08:42 +02:00
|
|
|
|
2008-10-11 05:42:07 +02:00
|
|
|
protected:
|
2011-02-26 23:59:52 +01:00
|
|
|
unsigned fix_width_(width_mode_t mode);
|
|
|
|
|
|
2008-10-11 05:42:07 +02:00
|
|
|
// The derived class test_width methods should fill these in.
|
|
|
|
|
ivl_variable_type_t expr_type_;
|
|
|
|
|
unsigned expr_width_;
|
2011-02-26 23:59:52 +01:00
|
|
|
unsigned min_width_;
|
|
|
|
|
bool signed_flag_;
|
2008-10-11 05:42:07 +02:00
|
|
|
|
2000-04-12 06:23:57 +02:00
|
|
|
private: // not implemented
|
|
|
|
|
PExpr(const PExpr&);
|
|
|
|
|
PExpr& operator= (const PExpr&);
|
1998-11-04 00:28:49 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
ostream& operator << (ostream&, const PExpr&);
|
|
|
|
|
|
1999-05-10 02:16:57 +02:00
|
|
|
class PEConcat : public PExpr {
|
|
|
|
|
|
|
|
|
|
public:
|
2010-10-26 04:36:44 +02:00
|
|
|
PEConcat(const list<PExpr*>&p, PExpr*r =0);
|
1999-06-10 06:03:52 +02:00
|
|
|
~PEConcat();
|
1999-05-10 02:16:57 +02:00
|
|
|
|
2007-06-04 21:14:06 +02:00
|
|
|
virtual verinum* eval_const(Design*des, NetScope*sc) const;
|
1999-05-10 02:16:57 +02:00
|
|
|
virtual void dump(ostream&) const;
|
2000-12-06 07:31:09 +01:00
|
|
|
|
2010-01-12 21:11:01 +01:00
|
|
|
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
|
|
|
|
|
|
2008-11-09 01:26:55 +01:00
|
|
|
virtual bool has_aa_term(Design*des, NetScope*scope) const;
|
|
|
|
|
|
2008-10-19 07:00:22 +02:00
|
|
|
virtual unsigned test_width(Design*des, NetScope*scope,
|
2011-02-26 23:59:52 +01:00
|
|
|
width_mode_t&mode);
|
2008-10-19 07:00:22 +02:00
|
|
|
|
2008-03-19 04:50:40 +01:00
|
|
|
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
|
2006-04-28 06:28:35 +02:00
|
|
|
virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const;
|
2002-04-13 04:33:17 +02:00
|
|
|
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
2011-02-26 23:59:52 +01:00
|
|
|
unsigned expr_wid,
|
2011-03-27 12:08:33 +02:00
|
|
|
unsigned flags) const;
|
2004-12-30 00:55:43 +01:00
|
|
|
virtual NetAssign_* elaborate_lval(Design*des,
|
|
|
|
|
NetScope*scope,
|
|
|
|
|
bool is_force) const;
|
2011-03-13 14:29:42 +01:00
|
|
|
virtual bool is_collapsible_net(Design*des, NetScope*scope) const;
|
2006-04-28 06:28:35 +02:00
|
|
|
private:
|
|
|
|
|
NetNet* elaborate_lnet_common_(Design*des, NetScope*scope,
|
|
|
|
|
bool bidirectional_flag) const;
|
1999-05-10 02:16:57 +02:00
|
|
|
private:
|
2010-10-26 04:36:44 +02:00
|
|
|
vector<PExpr*>parms_;
|
2011-02-26 23:59:52 +01:00
|
|
|
std::valarray<width_mode_t>width_modes_;
|
2008-11-19 01:52:05 +01:00
|
|
|
|
1999-06-10 06:03:52 +02:00
|
|
|
PExpr*repeat_;
|
2011-02-26 23:59:52 +01:00
|
|
|
NetScope*tested_scope_;
|
|
|
|
|
unsigned repeat_count_;
|
1999-05-10 02:16:57 +02:00
|
|
|
};
|
|
|
|
|
|
2000-04-01 21:31:57 +02:00
|
|
|
/*
|
|
|
|
|
* Event expressions are expressions that can be combined with the
|
|
|
|
|
* event "or" operator. These include "posedge foo" and similar, and
|
|
|
|
|
* also include named events. "edge" events are associated with an
|
|
|
|
|
* expression, whereas named events simply have a name, which
|
|
|
|
|
* represents an event variable.
|
|
|
|
|
*/
|
1999-04-29 04:16:26 +02:00
|
|
|
class PEEvent : public PExpr {
|
|
|
|
|
|
|
|
|
|
public:
|
2000-04-12 06:23:57 +02:00
|
|
|
enum edge_t {ANYEDGE, POSEDGE, NEGEDGE, POSITIVE};
|
|
|
|
|
|
2000-04-01 21:31:57 +02:00
|
|
|
// Use this constructor to create events based on edges or levels.
|
2000-04-12 06:23:57 +02:00
|
|
|
PEEvent(edge_t t, PExpr*e);
|
2000-04-01 21:31:57 +02:00
|
|
|
|
|
|
|
|
~PEEvent();
|
1999-04-29 04:16:26 +02:00
|
|
|
|
2000-04-12 06:23:57 +02:00
|
|
|
edge_t type() const;
|
|
|
|
|
PExpr* expr() const;
|
2004-10-04 03:10:51 +02:00
|
|
|
|
1999-04-29 04:16:26 +02:00
|
|
|
virtual void dump(ostream&) const;
|
|
|
|
|
|
2008-11-09 01:26:55 +01:00
|
|
|
virtual bool has_aa_term(Design*des, NetScope*scope) const;
|
|
|
|
|
|
1999-04-29 04:16:26 +02:00
|
|
|
private:
|
2000-04-12 06:23:57 +02:00
|
|
|
edge_t type_;
|
|
|
|
|
PExpr *expr_;
|
1999-04-29 04:16:26 +02:00
|
|
|
};
|
|
|
|
|
|
2000-12-10 23:01:35 +01:00
|
|
|
/*
|
|
|
|
|
* This holds a floating point constant in the source.
|
|
|
|
|
*/
|
|
|
|
|
class PEFNumber : public PExpr {
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
explicit PEFNumber(verireal*vp);
|
|
|
|
|
~PEFNumber();
|
|
|
|
|
|
|
|
|
|
const verireal& value() const;
|
|
|
|
|
|
|
|
|
|
/* The eval_const method as applied to a floating point number
|
|
|
|
|
gets the *integer* value of the number. This accounts for
|
|
|
|
|
any rounding that is needed to get the value. */
|
2007-06-04 21:14:06 +02:00
|
|
|
virtual verinum* eval_const(Design*des, NetScope*sc) const;
|
2000-12-10 23:01:35 +01:00
|
|
|
|
2008-09-26 05:37:18 +02:00
|
|
|
virtual unsigned test_width(Design*des, NetScope*scope,
|
2011-02-26 23:59:52 +01:00
|
|
|
width_mode_t&mode);
|
2002-04-13 04:33:17 +02:00
|
|
|
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
2011-02-26 23:59:52 +01:00
|
|
|
unsigned expr_wid,
|
2011-03-27 12:08:33 +02:00
|
|
|
unsigned flags) const;
|
2001-01-15 00:04:55 +01:00
|
|
|
|
2000-12-10 23:01:35 +01:00
|
|
|
virtual void dump(ostream&) const;
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
verireal*value_;
|
|
|
|
|
};
|
|
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
class PEIdent : public PExpr {
|
|
|
|
|
|
|
|
|
|
public:
|
2009-11-26 07:10:53 +01:00
|
|
|
explicit PEIdent(perm_string, bool no_implicit_sig=false);
|
2013-02-17 23:42:07 +01:00
|
|
|
explicit PEIdent(PPackage*pkg, perm_string name);
|
2007-05-24 06:07:11 +02:00
|
|
|
explicit PEIdent(const pform_name_t&);
|
2000-04-12 06:23:57 +02:00
|
|
|
~PEIdent();
|
1998-11-04 00:28:49 +01:00
|
|
|
|
2008-01-25 22:34:51 +01:00
|
|
|
// Add another name to the string of hierarchy that is the
|
2007-05-24 06:07:11 +02:00
|
|
|
// current identifier.
|
|
|
|
|
void append_name(perm_string);
|
|
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
virtual void dump(ostream&) const;
|
2008-11-09 01:26:55 +01:00
|
|
|
|
2010-01-12 21:11:01 +01:00
|
|
|
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
|
|
|
|
|
|
2008-11-09 01:26:55 +01:00
|
|
|
virtual bool has_aa_term(Design*des, NetScope*scope) const;
|
|
|
|
|
|
2006-11-04 07:19:24 +01:00
|
|
|
virtual unsigned test_width(Design*des, NetScope*scope,
|
2011-02-26 23:59:52 +01:00
|
|
|
width_mode_t&mode);
|
1999-09-15 06:17:52 +02:00
|
|
|
|
|
|
|
|
// Identifiers are allowed (with restrictions) is assign l-values.
|
2008-03-19 04:50:40 +01:00
|
|
|
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
|
1999-09-15 06:17:52 +02:00
|
|
|
|
2005-08-06 19:58:16 +02:00
|
|
|
virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const;
|
|
|
|
|
|
2000-09-09 17:21:26 +02:00
|
|
|
// Identifiers are also allowed as procedural assignment l-values.
|
2004-12-30 00:55:43 +01:00
|
|
|
virtual NetAssign_* elaborate_lval(Design*des,
|
|
|
|
|
NetScope*scope,
|
|
|
|
|
bool is_force) const;
|
2000-09-09 17:21:26 +02:00
|
|
|
|
2012-11-22 20:08:13 +01:00
|
|
|
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
|
|
|
|
ivl_type_t type, unsigned flags) const;
|
2002-04-13 04:33:17 +02:00
|
|
|
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
2011-02-26 23:59:52 +01:00
|
|
|
unsigned expr_wid,
|
2011-03-27 12:08:33 +02:00
|
|
|
unsigned flags) const;
|
1999-09-15 06:17:52 +02:00
|
|
|
|
2000-05-16 06:05:15 +02:00
|
|
|
// Elaborate the PEIdent as a port to a module. This method
|
|
|
|
|
// only applies to Ident expressions.
|
2012-06-04 21:43:33 +02:00
|
|
|
NetNet* elaborate_subport(Design*des, NetScope*sc) const;
|
2000-05-16 06:05:15 +02:00
|
|
|
|
2007-06-04 21:14:06 +02:00
|
|
|
verinum* eval_const(Design*des, NetScope*sc) const;
|
1998-11-04 00:28:49 +01:00
|
|
|
|
2011-03-13 14:29:42 +01:00
|
|
|
virtual bool is_collapsible_net(Design*des, NetScope*scope) const;
|
|
|
|
|
|
2007-05-24 06:07:11 +02:00
|
|
|
const pform_name_t& path() const { return path_; }
|
|
|
|
|
|
|
|
|
|
private:
|
2013-02-17 23:42:07 +01:00
|
|
|
PPackage*package_;
|
2007-05-24 06:07:11 +02:00
|
|
|
pform_name_t path_;
|
2009-11-26 07:10:53 +01:00
|
|
|
bool no_implicit_sig_;
|
1998-11-04 00:28:49 +01:00
|
|
|
|
2006-11-04 07:19:24 +01:00
|
|
|
private:
|
2009-01-02 01:20:41 +01:00
|
|
|
// Common functions to calculate parts of part/bit
|
|
|
|
|
// selects. These methods return true if the expressions
|
|
|
|
|
// elaborate/calculate, or false if there is some sort of
|
|
|
|
|
// source error.
|
|
|
|
|
|
2012-04-30 20:48:33 +02:00
|
|
|
bool calculate_bits_(Design*, NetScope*, long&msb, bool&defined) const;
|
|
|
|
|
|
2009-01-02 01:20:41 +01:00
|
|
|
// The calculate_parts_ method calculates the range
|
|
|
|
|
// expressions of a part select for the current object. The
|
|
|
|
|
// part select expressions are elaborated and evaluated, and
|
|
|
|
|
// the values written to the msb/lsb arguments. If there are
|
|
|
|
|
// invalid bits (xz) in either expression, then the defined
|
|
|
|
|
// flag is set to *false*.
|
|
|
|
|
bool calculate_parts_(Design*, NetScope*, long&msb, long&lsb, bool&defined) const;
|
2011-03-27 12:08:33 +02:00
|
|
|
NetExpr* calculate_up_do_base_(Design*, NetScope*, bool need_const) const;
|
2008-06-08 16:34:45 +02:00
|
|
|
bool calculate_param_range_(Design*, NetScope*,
|
|
|
|
|
const NetExpr*msb_ex, long&msb,
|
2010-01-10 04:57:01 +01:00
|
|
|
const NetExpr*lsb_ex, long&lsb,
|
|
|
|
|
long length) const;
|
2008-06-08 16:34:45 +02:00
|
|
|
|
2006-11-04 07:19:24 +01:00
|
|
|
bool calculate_up_do_width_(Design*, NetScope*, unsigned long&wid) const;
|
|
|
|
|
|
2012-02-11 02:17:59 +01:00
|
|
|
// Evaluate the prefix indices. All but the final index in a
|
|
|
|
|
// chain of indices must be a single value and must evaluate
|
|
|
|
|
// to constants at compile time. For example:
|
|
|
|
|
// [x] - OK
|
|
|
|
|
// [1][2][x] - OK
|
|
|
|
|
// [1][x:y] - OK
|
|
|
|
|
// [2:0][x] - BAD
|
|
|
|
|
// [y][x] - BAD
|
|
|
|
|
// Leave the last index for special handling.
|
|
|
|
|
bool calculate_packed_indices_(Design*des, NetScope*scope, NetNet*net,
|
|
|
|
|
std::list<long>&prefix_indices) const;
|
|
|
|
|
|
2006-04-16 02:15:43 +02:00
|
|
|
private:
|
2013-03-15 04:08:32 +01:00
|
|
|
NetAssign_*elaborate_lval_method_class_member_(Design*, NetScope*) const;
|
2007-01-16 06:44:14 +01:00
|
|
|
NetAssign_*elaborate_lval_net_word_(Design*, NetScope*, NetNet*) const;
|
2008-06-15 06:22:55 +02:00
|
|
|
bool elaborate_lval_net_bit_(Design*, NetScope*, NetAssign_*) const;
|
2007-01-16 06:44:14 +01:00
|
|
|
bool elaborate_lval_net_part_(Design*, NetScope*, NetAssign_*) const;
|
2007-11-07 20:26:56 +01:00
|
|
|
bool elaborate_lval_net_idx_(Design*, NetScope*, NetAssign_*,
|
|
|
|
|
index_component_t::ctype_t) const;
|
2012-11-25 19:13:05 +01:00
|
|
|
bool elaborate_lval_net_class_member_(Design*, NetScope*,
|
|
|
|
|
NetAssign_*,
|
|
|
|
|
const perm_string&) const;
|
2012-01-04 02:38:08 +01:00
|
|
|
bool elaborate_lval_net_packed_member_(Design*, NetScope*,
|
|
|
|
|
NetAssign_*,
|
|
|
|
|
const perm_string&) const;
|
2012-07-21 17:59:29 +02:00
|
|
|
bool elaborate_lval_darray_bit_(Design*, NetScope*,
|
|
|
|
|
NetAssign_*) const;
|
2006-04-16 02:15:43 +02:00
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
private:
|
2008-09-21 04:23:54 +02:00
|
|
|
NetExpr*elaborate_expr_param_(Design*des,
|
|
|
|
|
NetScope*scope,
|
|
|
|
|
const NetExpr*par,
|
2012-01-02 19:11:56 +01:00
|
|
|
NetScope*found_in,
|
2008-09-21 04:23:54 +02:00
|
|
|
const NetExpr*par_msb,
|
|
|
|
|
const NetExpr*par_lsb,
|
2011-03-27 12:08:33 +02:00
|
|
|
unsigned expr_wid,
|
|
|
|
|
unsigned flags) const;
|
2008-06-08 16:34:45 +02:00
|
|
|
NetExpr*elaborate_expr_param_part_(Design*des,
|
|
|
|
|
NetScope*scope,
|
|
|
|
|
const NetExpr*par,
|
2012-01-02 19:11:56 +01:00
|
|
|
NetScope*found_in,
|
2008-06-08 16:34:45 +02:00
|
|
|
const NetExpr*par_msb,
|
2011-02-26 23:59:52 +01:00
|
|
|
const NetExpr*par_lsb,
|
|
|
|
|
unsigned expr_wid) const;
|
2008-06-09 04:29:00 +02:00
|
|
|
NetExpr*elaborate_expr_param_idx_up_(Design*des,
|
|
|
|
|
NetScope*scope,
|
|
|
|
|
const NetExpr*par,
|
2012-01-02 19:11:56 +01:00
|
|
|
NetScope*found_in,
|
2008-06-09 04:29:00 +02:00
|
|
|
const NetExpr*par_msb,
|
2011-03-27 12:08:33 +02:00
|
|
|
const NetExpr*par_lsb,
|
|
|
|
|
bool need_const) const;
|
2009-08-29 01:50:59 +02:00
|
|
|
NetExpr*elaborate_expr_param_idx_do_(Design*des,
|
|
|
|
|
NetScope*scope,
|
|
|
|
|
const NetExpr*par,
|
2012-01-02 19:11:56 +01:00
|
|
|
NetScope*found_in,
|
2009-08-29 01:50:59 +02:00
|
|
|
const NetExpr*par_msb,
|
2011-03-27 12:08:33 +02:00
|
|
|
const NetExpr*par_lsb,
|
|
|
|
|
bool need_const) const;
|
2005-11-10 14:28:11 +01:00
|
|
|
NetExpr*elaborate_expr_net(Design*des,
|
2007-01-16 06:44:14 +01:00
|
|
|
NetScope*scope,
|
|
|
|
|
NetNet*net,
|
|
|
|
|
NetScope*found,
|
2011-02-26 23:59:52 +01:00
|
|
|
unsigned expr_wid,
|
2011-03-27 12:08:33 +02:00
|
|
|
unsigned flags) const;
|
2007-01-16 06:44:14 +01:00
|
|
|
NetExpr*elaborate_expr_net_word_(Design*des,
|
|
|
|
|
NetScope*scope,
|
|
|
|
|
NetNet*net,
|
|
|
|
|
NetScope*found,
|
2011-02-26 23:59:52 +01:00
|
|
|
unsigned expr_wid,
|
2011-03-27 12:08:33 +02:00
|
|
|
unsigned flags) const;
|
2005-11-10 14:28:11 +01:00
|
|
|
NetExpr*elaborate_expr_net_part_(Design*des,
|
2011-02-26 23:59:52 +01:00
|
|
|
NetScope*scope,
|
|
|
|
|
NetESignal*net,
|
|
|
|
|
NetScope*found,
|
|
|
|
|
unsigned expr_wid) const;
|
2005-11-10 14:28:11 +01:00
|
|
|
NetExpr*elaborate_expr_net_idx_up_(Design*des,
|
2011-02-26 23:59:52 +01:00
|
|
|
NetScope*scope,
|
|
|
|
|
NetESignal*net,
|
2011-03-27 12:08:33 +02:00
|
|
|
NetScope*found,
|
|
|
|
|
bool need_const) const;
|
2005-11-10 14:28:11 +01:00
|
|
|
NetExpr*elaborate_expr_net_idx_do_(Design*des,
|
2011-02-26 23:59:52 +01:00
|
|
|
NetScope*scope,
|
|
|
|
|
NetESignal*net,
|
2011-03-27 12:08:33 +02:00
|
|
|
NetScope*found,
|
|
|
|
|
bool need_const) const;
|
2005-11-10 14:28:11 +01:00
|
|
|
NetExpr*elaborate_expr_net_bit_(Design*des,
|
2011-02-26 23:59:52 +01:00
|
|
|
NetScope*scope,
|
|
|
|
|
NetESignal*net,
|
2011-03-27 12:08:33 +02:00
|
|
|
NetScope*found,
|
|
|
|
|
bool need_const) const;
|
1998-11-04 00:28:49 +01:00
|
|
|
|
2013-03-15 04:08:32 +01:00
|
|
|
NetExpr*elaborate_expr_class_member_(Design*des,
|
|
|
|
|
NetScope*scope,
|
|
|
|
|
unsigned expr_wid,
|
|
|
|
|
unsigned flags) const;
|
|
|
|
|
|
2002-06-04 07:38:43 +02:00
|
|
|
private:
|
2005-08-06 19:58:16 +02:00
|
|
|
NetNet* elaborate_lnet_common_(Design*des, NetScope*scope,
|
|
|
|
|
bool bidirectional_flag) const;
|
|
|
|
|
|
2005-01-09 21:16:00 +01:00
|
|
|
bool eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
2008-05-10 02:42:37 +02:00
|
|
|
long&midx, long&lidx) const;
|
1998-11-04 00:28:49 +01:00
|
|
|
};
|
|
|
|
|
|
2012-07-14 03:41:41 +02:00
|
|
|
class PENew : public PExpr {
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
explicit PENew (PExpr*s);
|
|
|
|
|
~PENew();
|
|
|
|
|
|
|
|
|
|
virtual void dump(ostream&) const;
|
2012-07-16 05:44:07 +02:00
|
|
|
virtual unsigned test_width(Design*des, NetScope*scope,
|
|
|
|
|
width_mode_t&mode);
|
2012-10-01 03:03:10 +02:00
|
|
|
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
|
|
|
|
ivl_type_t type, unsigned flags) const;
|
2012-07-16 05:44:07 +02:00
|
|
|
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
|
|
|
|
unsigned expr_wid,
|
|
|
|
|
unsigned flags) const;
|
2012-07-14 03:41:41 +02:00
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
PExpr*size_;
|
|
|
|
|
};
|
|
|
|
|
|
2012-11-12 02:42:31 +01:00
|
|
|
class PENewClass : public PExpr {
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
explicit PENewClass ();
|
|
|
|
|
~PENewClass();
|
|
|
|
|
virtual void dump(ostream&) const;
|
|
|
|
|
// Class objects don't have a useful width, but the expression
|
|
|
|
|
// is IVL_VT_CLASS.
|
|
|
|
|
virtual unsigned test_width(Design*des, NetScope*scope,
|
|
|
|
|
width_mode_t&mode);
|
|
|
|
|
// Note that class (new) expressions only appear in context
|
|
|
|
|
// that uses this form of the elaborate_expr method. In fact,
|
|
|
|
|
// the type argument is going to be a netclas_t object.
|
|
|
|
|
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
|
|
|
|
ivl_type_t type, unsigned flags) const;
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
};
|
|
|
|
|
|
2012-11-04 01:41:11 +01:00
|
|
|
class PENull : public PExpr {
|
|
|
|
|
public:
|
|
|
|
|
explicit PENull();
|
|
|
|
|
~PENull();
|
|
|
|
|
|
|
|
|
|
virtual void dump(ostream&) const;
|
2012-11-12 02:42:31 +01:00
|
|
|
virtual unsigned test_width(Design*des, NetScope*scope,
|
|
|
|
|
width_mode_t&mode);
|
2012-11-22 02:48:46 +01:00
|
|
|
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
|
|
|
|
ivl_type_t type, unsigned flags) const;
|
2012-11-12 02:42:31 +01:00
|
|
|
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
|
|
|
|
unsigned expr_wid,
|
|
|
|
|
unsigned flags) const;
|
2012-11-04 01:41:11 +01:00
|
|
|
};
|
|
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
class PENumber : public PExpr {
|
|
|
|
|
|
|
|
|
|
public:
|
2000-04-12 06:23:57 +02:00
|
|
|
explicit PENumber(verinum*vp);
|
|
|
|
|
~PENumber();
|
1998-11-04 00:28:49 +01:00
|
|
|
|
2000-04-12 06:23:57 +02:00
|
|
|
const verinum& value() const;
|
1998-11-04 00:28:49 +01:00
|
|
|
|
|
|
|
|
virtual void dump(ostream&) const;
|
2006-11-04 07:19:24 +01:00
|
|
|
virtual unsigned test_width(Design*des, NetScope*scope,
|
2011-02-26 23:59:52 +01:00
|
|
|
width_mode_t&mode);
|
2006-10-30 06:44:49 +01:00
|
|
|
|
2013-01-27 21:30:38 +01:00
|
|
|
virtual NetEConst*elaborate_expr(Design*des, NetScope*scope,
|
|
|
|
|
ivl_type_t type, unsigned flags) const;
|
2002-04-13 04:33:17 +02:00
|
|
|
virtual NetEConst*elaborate_expr(Design*des, NetScope*,
|
2011-03-27 12:08:33 +02:00
|
|
|
unsigned expr_wid, unsigned) const;
|
2004-12-30 00:55:43 +01:00
|
|
|
virtual NetAssign_* elaborate_lval(Design*des,
|
|
|
|
|
NetScope*scope,
|
|
|
|
|
bool is_force) const;
|
2002-03-09 05:02:26 +01:00
|
|
|
|
2007-06-04 21:14:06 +02:00
|
|
|
virtual verinum* eval_const(Design*des, NetScope*sc) const;
|
1998-11-04 00:28:49 +01:00
|
|
|
|
1998-11-11 01:01:51 +01:00
|
|
|
virtual bool is_the_same(const PExpr*that) const;
|
|
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
private:
|
|
|
|
|
verinum*const value_;
|
|
|
|
|
};
|
|
|
|
|
|
2001-12-30 22:32:03 +01:00
|
|
|
/*
|
|
|
|
|
* This represents a string constant in an expression.
|
|
|
|
|
*
|
|
|
|
|
* The s parameter to the PEString constructor is a C string that this
|
|
|
|
|
* class instance will take for its own. The caller should not delete
|
|
|
|
|
* the string, the destructor will do it.
|
|
|
|
|
*/
|
1998-11-04 00:28:49 +01:00
|
|
|
class PEString : public PExpr {
|
|
|
|
|
|
|
|
|
|
public:
|
2001-12-30 22:32:03 +01:00
|
|
|
explicit PEString(char*s);
|
2000-04-12 06:23:57 +02:00
|
|
|
~PEString();
|
1998-11-04 00:28:49 +01:00
|
|
|
|
2000-04-12 06:23:57 +02:00
|
|
|
string value() const;
|
1998-11-04 00:28:49 +01:00
|
|
|
virtual void dump(ostream&) const;
|
2006-10-30 06:44:49 +01:00
|
|
|
|
2006-11-10 05:54:26 +01:00
|
|
|
virtual unsigned test_width(Design*des, NetScope*scope,
|
2011-02-26 23:59:52 +01:00
|
|
|
width_mode_t&mode);
|
2006-11-10 05:54:26 +01:00
|
|
|
|
2002-04-13 04:33:17 +02:00
|
|
|
virtual NetEConst*elaborate_expr(Design*des, NetScope*,
|
2011-03-27 12:08:33 +02:00
|
|
|
unsigned expr_wid, unsigned) const;
|
2007-06-04 21:14:06 +02:00
|
|
|
verinum* eval_const(Design*, NetScope*) const;
|
1998-11-04 00:28:49 +01:00
|
|
|
|
|
|
|
|
private:
|
2001-12-30 22:32:03 +01:00
|
|
|
char*text_;
|
1998-11-04 00:28:49 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class PEUnary : public PExpr {
|
|
|
|
|
|
|
|
|
|
public:
|
2000-06-30 17:50:20 +02:00
|
|
|
explicit PEUnary(char op, PExpr*ex);
|
|
|
|
|
~PEUnary();
|
1998-11-04 00:28:49 +01:00
|
|
|
|
|
|
|
|
virtual void dump(ostream&out) const;
|
2006-10-30 06:44:49 +01:00
|
|
|
|
2010-01-12 21:11:01 +01:00
|
|
|
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
|
|
|
|
|
|
2008-11-09 01:26:55 +01:00
|
|
|
virtual bool has_aa_term(Design*des, NetScope*scope) const;
|
|
|
|
|
|
2008-08-16 07:03:19 +02:00
|
|
|
virtual unsigned test_width(Design*des, NetScope*scope,
|
2011-02-26 23:59:52 +01:00
|
|
|
width_mode_t&mode);
|
2008-08-16 07:03:19 +02:00
|
|
|
|
2002-04-14 05:55:25 +02:00
|
|
|
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
2011-02-26 23:59:52 +01:00
|
|
|
unsigned expr_wid,
|
2011-03-27 12:08:33 +02:00
|
|
|
unsigned flags) const;
|
2007-06-04 21:14:06 +02:00
|
|
|
virtual verinum* eval_const(Design*des, NetScope*sc) const;
|
1998-11-04 00:28:49 +01:00
|
|
|
|
2012-02-20 03:54:58 +01:00
|
|
|
public:
|
|
|
|
|
inline char get_op() const { return op_; }
|
|
|
|
|
inline PExpr*get_expr() const { return expr_; }
|
|
|
|
|
|
2008-10-13 06:38:07 +02:00
|
|
|
private:
|
2011-02-26 23:59:52 +01:00
|
|
|
NetExpr* elaborate_expr_bits_(NetExpr*operand, unsigned expr_wid) const;
|
2008-10-13 06:38:07 +02:00
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
private:
|
|
|
|
|
char op_;
|
|
|
|
|
PExpr*expr_;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class PEBinary : public PExpr {
|
|
|
|
|
|
|
|
|
|
public:
|
2001-11-06 07:11:55 +01:00
|
|
|
explicit PEBinary(char op, PExpr*l, PExpr*r);
|
|
|
|
|
~PEBinary();
|
1998-11-04 00:28:49 +01:00
|
|
|
|
|
|
|
|
virtual void dump(ostream&out) const;
|
2006-10-30 06:44:49 +01:00
|
|
|
|
2010-01-12 21:11:01 +01:00
|
|
|
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
|
|
|
|
|
|
2008-11-09 01:26:55 +01:00
|
|
|
virtual bool has_aa_term(Design*des, NetScope*scope) const;
|
|
|
|
|
|
2006-11-04 07:19:24 +01:00
|
|
|
virtual unsigned test_width(Design*des, NetScope*scope,
|
2011-02-26 23:59:52 +01:00
|
|
|
width_mode_t&mode);
|
2006-10-30 06:44:49 +01:00
|
|
|
|
2008-04-22 20:23:24 +02:00
|
|
|
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
2011-02-26 23:59:52 +01:00
|
|
|
unsigned expr_wid,
|
2011-03-27 12:08:33 +02:00
|
|
|
unsigned flags) const;
|
2007-06-04 21:14:06 +02:00
|
|
|
virtual verinum* eval_const(Design*des, NetScope*sc) const;
|
1998-11-04 00:28:49 +01:00
|
|
|
|
2006-10-30 06:44:49 +01:00
|
|
|
protected:
|
1998-11-04 00:28:49 +01:00
|
|
|
char op_;
|
|
|
|
|
PExpr*left_;
|
|
|
|
|
PExpr*right_;
|
1999-10-31 21:08:24 +01:00
|
|
|
|
2008-12-19 06:33:31 +01:00
|
|
|
NetExpr*elaborate_expr_base_(Design*, NetExpr*lp, NetExpr*rp,
|
2011-02-26 23:59:52 +01:00
|
|
|
unsigned expr_wid) const;
|
2008-12-19 06:33:31 +01:00
|
|
|
NetExpr*elaborate_eval_expr_base_(Design*, NetExpr*lp, NetExpr*rp,
|
2011-02-26 23:59:52 +01:00
|
|
|
unsigned expr_wid) const;
|
2000-03-12 19:22:11 +01:00
|
|
|
|
2010-12-05 23:35:30 +01:00
|
|
|
NetExpr*elaborate_expr_base_bits_(Design*, NetExpr*lp, NetExpr*rp,
|
2011-02-26 23:59:52 +01:00
|
|
|
unsigned expr_wid) const;
|
2008-12-19 06:33:31 +01:00
|
|
|
NetExpr*elaborate_expr_base_div_(Design*, NetExpr*lp, NetExpr*rp,
|
2011-02-26 23:59:52 +01:00
|
|
|
unsigned expr_wid) const;
|
2008-12-19 06:33:31 +01:00
|
|
|
NetExpr*elaborate_expr_base_mult_(Design*, NetExpr*lp, NetExpr*rp,
|
2011-02-26 23:59:52 +01:00
|
|
|
unsigned expr_wid) const;
|
2008-12-19 06:33:31 +01:00
|
|
|
NetExpr*elaborate_expr_base_add_(Design*, NetExpr*lp, NetExpr*rp,
|
2011-02-26 23:59:52 +01:00
|
|
|
unsigned expr_wid) const;
|
2008-08-21 06:47:07 +02:00
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
};
|
|
|
|
|
|
2006-10-30 06:44:49 +01:00
|
|
|
/*
|
2008-01-25 22:34:51 +01:00
|
|
|
* Here are a few specialized classes for handling specific binary
|
2006-10-30 06:44:49 +01:00
|
|
|
* operators.
|
|
|
|
|
*/
|
|
|
|
|
class PEBComp : public PEBinary {
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
explicit PEBComp(char op, PExpr*l, PExpr*r);
|
|
|
|
|
~PEBComp();
|
|
|
|
|
|
2008-10-30 04:31:26 +01:00
|
|
|
virtual unsigned test_width(Design*des, NetScope*scope,
|
2011-02-26 23:59:52 +01:00
|
|
|
width_mode_t&mode);
|
2008-10-30 04:31:26 +01:00
|
|
|
|
|
|
|
|
NetExpr* elaborate_expr(Design*des, NetScope*scope,
|
2011-03-27 12:08:33 +02:00
|
|
|
unsigned expr_wid, unsigned flags) const;
|
2010-04-27 20:55:59 +02:00
|
|
|
|
|
|
|
|
private:
|
2011-02-26 23:59:52 +01:00
|
|
|
unsigned l_width_;
|
|
|
|
|
unsigned r_width_;
|
2008-10-30 04:31:26 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* This derived class is for handling logical expressions: && and ||.
|
|
|
|
|
*/
|
|
|
|
|
class PEBLogic : public PEBinary {
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
explicit PEBLogic(char op, PExpr*l, PExpr*r);
|
|
|
|
|
~PEBLogic();
|
|
|
|
|
|
2006-11-04 07:19:24 +01:00
|
|
|
virtual unsigned test_width(Design*des, NetScope*scope,
|
2011-02-26 23:59:52 +01:00
|
|
|
width_mode_t&mode);
|
2006-10-30 06:44:49 +01:00
|
|
|
|
2008-04-22 20:23:24 +02:00
|
|
|
NetExpr* elaborate_expr(Design*des, NetScope*scope,
|
2011-03-27 12:08:33 +02:00
|
|
|
unsigned expr_wid, unsigned flags) const;
|
2006-10-30 06:44:49 +01:00
|
|
|
};
|
|
|
|
|
|
2008-11-28 23:40:25 +01:00
|
|
|
/*
|
|
|
|
|
* A couple of the binary operands have a special sub-expression rule
|
|
|
|
|
* where the expression width is carried entirely by the left
|
|
|
|
|
* expression, and the right operand is self-determined.
|
|
|
|
|
*/
|
|
|
|
|
class PEBLeftWidth : public PEBinary {
|
2006-10-30 06:44:49 +01:00
|
|
|
|
|
|
|
|
public:
|
2008-11-28 23:40:25 +01:00
|
|
|
explicit PEBLeftWidth(char op, PExpr*l, PExpr*r);
|
|
|
|
|
~PEBLeftWidth() =0;
|
|
|
|
|
|
|
|
|
|
virtual NetExpr*elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp,
|
2011-02-26 23:59:52 +01:00
|
|
|
unsigned expr_wid) const =0;
|
2006-10-30 06:44:49 +01:00
|
|
|
|
2008-11-28 23:40:25 +01:00
|
|
|
protected:
|
2006-11-04 07:19:24 +01:00
|
|
|
virtual unsigned test_width(Design*des, NetScope*scope,
|
2011-02-26 23:59:52 +01:00
|
|
|
width_mode_t&mode);
|
2008-11-28 23:40:25 +01:00
|
|
|
|
|
|
|
|
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
2011-02-26 23:59:52 +01:00
|
|
|
unsigned expr_wid,
|
2011-03-27 12:08:33 +02:00
|
|
|
unsigned flags) const;
|
2008-11-28 23:40:25 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class PEBPower : public PEBLeftWidth {
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
explicit PEBPower(char op, PExpr*l, PExpr*r);
|
|
|
|
|
~PEBPower();
|
|
|
|
|
|
|
|
|
|
NetExpr*elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp,
|
2011-02-26 23:59:52 +01:00
|
|
|
unsigned expr_wid) const;
|
2008-11-28 23:40:25 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class PEBShift : public PEBLeftWidth {
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
explicit PEBShift(char op, PExpr*l, PExpr*r);
|
|
|
|
|
~PEBShift();
|
|
|
|
|
|
|
|
|
|
NetExpr*elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp,
|
2011-02-26 23:59:52 +01:00
|
|
|
unsigned expr_wid) const;
|
2006-10-30 06:44:49 +01:00
|
|
|
};
|
|
|
|
|
|
1999-06-10 06:03:52 +02:00
|
|
|
/*
|
|
|
|
|
* This class supports the ternary (?:) operator. The operator takes
|
|
|
|
|
* three expressions, the test, the true result and the false result.
|
|
|
|
|
*/
|
|
|
|
|
class PETernary : public PExpr {
|
|
|
|
|
|
|
|
|
|
public:
|
1999-07-17 21:50:59 +02:00
|
|
|
explicit PETernary(PExpr*e, PExpr*t, PExpr*f);
|
1999-06-10 06:03:52 +02:00
|
|
|
~PETernary();
|
|
|
|
|
|
1999-07-17 21:50:59 +02:00
|
|
|
virtual void dump(ostream&out) const;
|
2008-11-09 01:26:55 +01:00
|
|
|
|
2010-01-12 21:11:01 +01:00
|
|
|
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
|
|
|
|
|
|
2008-11-09 01:26:55 +01:00
|
|
|
virtual bool has_aa_term(Design*des, NetScope*scope) const;
|
|
|
|
|
|
2006-11-10 05:54:26 +01:00
|
|
|
virtual unsigned test_width(Design*des, NetScope*scope,
|
2011-02-26 23:59:52 +01:00
|
|
|
width_mode_t&mode);
|
2006-11-10 05:54:26 +01:00
|
|
|
|
2008-08-23 19:50:24 +02:00
|
|
|
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
2011-02-26 23:59:52 +01:00
|
|
|
unsigned expr_wid,
|
2011-03-27 12:08:33 +02:00
|
|
|
unsigned flags) const;
|
2007-06-04 21:14:06 +02:00
|
|
|
virtual verinum* eval_const(Design*des, NetScope*sc) const;
|
1999-07-17 21:50:59 +02:00
|
|
|
|
2009-01-06 04:44:52 +01:00
|
|
|
private:
|
|
|
|
|
NetExpr* elab_and_eval_alternative_(Design*des, NetScope*scope,
|
2011-03-27 12:08:33 +02:00
|
|
|
PExpr*expr, unsigned expr_wid,
|
2013-03-02 00:01:15 +01:00
|
|
|
unsigned flags, bool short_cct) const;
|
2009-01-06 04:44:52 +01:00
|
|
|
|
1999-06-10 06:03:52 +02:00
|
|
|
private:
|
|
|
|
|
PExpr*expr_;
|
|
|
|
|
PExpr*tru_;
|
|
|
|
|
PExpr*fal_;
|
|
|
|
|
};
|
|
|
|
|
|
1999-09-25 04:57:29 +02:00
|
|
|
/*
|
2000-05-04 05:37:58 +02:00
|
|
|
* This class represents a parsed call to a function, including calls
|
2002-03-09 03:10:22 +01:00
|
|
|
* to system functions. The parameters in the parms list are the
|
|
|
|
|
* expressions that are passed as input to the ports of the function.
|
1999-09-25 04:57:29 +02:00
|
|
|
*/
|
1999-07-31 21:14:47 +02:00
|
|
|
class PECallFunction : public PExpr {
|
1999-09-25 04:57:29 +02:00
|
|
|
public:
|
2008-07-27 23:22:19 +02:00
|
|
|
explicit PECallFunction(const pform_name_t&n, const vector<PExpr *> &parms);
|
2008-01-25 22:34:51 +01:00
|
|
|
// Call of system function (name is not hierarchical)
|
2008-07-27 23:22:19 +02:00
|
|
|
explicit PECallFunction(perm_string n, const vector<PExpr *> &parms);
|
2007-05-24 06:07:11 +02:00
|
|
|
explicit PECallFunction(perm_string n);
|
2008-07-27 23:22:19 +02:00
|
|
|
|
|
|
|
|
// svector versions. Should be removed!
|
2010-10-26 04:36:44 +02:00
|
|
|
explicit PECallFunction(const pform_name_t&n, const list<PExpr *> &parms);
|
|
|
|
|
explicit PECallFunction(perm_string n, const list<PExpr *> &parms);
|
2008-07-27 23:22:19 +02:00
|
|
|
|
1999-09-25 04:57:29 +02:00
|
|
|
~PECallFunction();
|
1999-07-31 21:14:47 +02:00
|
|
|
|
|
|
|
|
virtual void dump(ostream &) const;
|
2006-10-30 06:44:49 +01:00
|
|
|
|
2010-01-12 21:11:01 +01:00
|
|
|
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
|
|
|
|
|
|
2008-11-09 01:26:55 +01:00
|
|
|
virtual bool has_aa_term(Design*des, NetScope*scope) const;
|
|
|
|
|
|
|
|
|
|
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
2011-02-26 23:59:52 +01:00
|
|
|
unsigned expr_wid,
|
2011-03-27 12:08:33 +02:00
|
|
|
unsigned flags) const;
|
1999-07-31 21:14:47 +02:00
|
|
|
|
2007-10-02 05:38:20 +02:00
|
|
|
virtual unsigned test_width(Design*des, NetScope*scope,
|
2011-02-26 23:59:52 +01:00
|
|
|
width_mode_t&mode);
|
2007-10-02 05:38:20 +02:00
|
|
|
|
1999-09-25 04:57:29 +02:00
|
|
|
private:
|
2007-05-24 06:07:11 +02:00
|
|
|
pform_name_t path_;
|
2008-07-27 23:22:19 +02:00
|
|
|
vector<PExpr *> parms_;
|
1999-09-25 04:57:29 +02:00
|
|
|
|
2002-03-09 03:10:22 +01:00
|
|
|
bool check_call_matches_definition_(Design*des, NetScope*dscope) const;
|
|
|
|
|
|
2012-07-01 02:05:25 +02:00
|
|
|
|
2011-02-26 23:59:52 +01:00
|
|
|
NetExpr* cast_to_width_(NetExpr*expr, unsigned wid) const;
|
2010-01-17 15:20:18 +01:00
|
|
|
|
2012-07-14 03:41:41 +02:00
|
|
|
NetExpr*elaborate_expr_method_(Design*des, NetScope*scope,
|
|
|
|
|
unsigned expr_wid) const;
|
|
|
|
|
#if 0
|
|
|
|
|
NetExpr*elaborate_expr_string_method_(Design*des, NetScope*scope) const;
|
2012-07-01 02:05:25 +02:00
|
|
|
NetExpr*elaborate_expr_enum_method_(Design*des, NetScope*scope,
|
|
|
|
|
unsigned expr_wid) const;
|
2012-07-14 03:41:41 +02:00
|
|
|
#endif
|
2012-07-01 02:05:25 +02:00
|
|
|
|
2011-02-26 23:59:52 +01:00
|
|
|
NetExpr* elaborate_sfunc_(Design*des, NetScope*scope,
|
2011-03-27 12:08:33 +02:00
|
|
|
unsigned expr_wid,
|
|
|
|
|
unsigned flags) const;
|
2011-02-26 23:59:52 +01:00
|
|
|
NetExpr* elaborate_access_func_(Design*des, NetScope*scope, ivl_nature_t,
|
|
|
|
|
unsigned expr_wid) const;
|
2007-10-02 05:38:20 +02:00
|
|
|
unsigned test_width_sfunc_(Design*des, NetScope*scope,
|
2011-02-26 23:59:52 +01:00
|
|
|
width_mode_t&mode);
|
2012-07-14 03:41:41 +02:00
|
|
|
unsigned test_width_method_(Design*des, NetScope*scope,
|
|
|
|
|
width_mode_t&mode);
|
2011-02-26 23:59:52 +01:00
|
|
|
};
|
|
|
|
|
|
2011-09-19 04:21:46 +02:00
|
|
|
/*
|
|
|
|
|
* Support the SystemVerilog cast to size.
|
|
|
|
|
*/
|
|
|
|
|
class PECastSize : public PExpr {
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
explicit PECastSize(unsigned expr_wid, PExpr*base);
|
|
|
|
|
~PECastSize();
|
|
|
|
|
|
|
|
|
|
void dump(ostream &out) const;
|
|
|
|
|
|
|
|
|
|
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
|
|
|
|
unsigned expr_wid,
|
|
|
|
|
unsigned flags) const;
|
|
|
|
|
|
|
|
|
|
virtual unsigned test_width(Design*des, NetScope*scope,
|
|
|
|
|
width_mode_t&mode);
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
unsigned size_;
|
|
|
|
|
PExpr* base_;
|
|
|
|
|
};
|
|
|
|
|
|
2011-02-26 23:59:52 +01:00
|
|
|
/*
|
|
|
|
|
* This class is used for error recovery. All methods do nothing and return
|
|
|
|
|
* null or default values.
|
|
|
|
|
*/
|
|
|
|
|
class PEVoid : public PExpr {
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
explicit PEVoid();
|
|
|
|
|
~PEVoid();
|
|
|
|
|
|
|
|
|
|
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
|
|
|
|
unsigned expr_wid,
|
2011-03-27 12:08:33 +02:00
|
|
|
unsigned flags) const;
|
1999-07-31 21:14:47 +02:00
|
|
|
};
|
|
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
#endif
|