1998-11-04 00:28:49 +01:00
|
|
|
#ifndef __PExpr_H
|
|
|
|
|
#define __PExpr_H
|
|
|
|
|
/*
|
2000-02-16 04:58:27 +01:00
|
|
|
* Copyright (c) 1998-2000 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
|
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
# include <string>
|
2006-02-02 03:43:57 +01:00
|
|
|
# include <vector>
|
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;
|
1998-11-04 00:28:49 +01:00
|
|
|
class NetNet;
|
|
|
|
|
class NetExpr;
|
2000-03-08 05:36:53 +01:00
|
|
|
class NetScope;
|
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.
|
|
|
|
|
*
|
|
|
|
|
* The elaborate_net method is used by structural elaboration to build
|
|
|
|
|
* up a netlist interpretation of the expression.
|
|
|
|
|
*/
|
|
|
|
|
|
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:
|
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
|
|
|
|
2006-10-30 06:44:49 +01:00
|
|
|
// This method tests the width that the expression wants to
|
|
|
|
|
// be. It is used by elaboration of assignments to figure out
|
|
|
|
|
// the width of the expression.
|
|
|
|
|
//
|
|
|
|
|
// The "min" is the width of the local context, so it the
|
|
|
|
|
// minimum width that this function should return. Initially
|
|
|
|
|
// this is the same as the lval width.
|
|
|
|
|
//
|
|
|
|
|
// The "lval" is the width of the destination where this
|
|
|
|
|
// result is going to go. This can be used to constrain the
|
|
|
|
|
// amount that an expression can reasonably expand. For
|
|
|
|
|
// example, there is no point expanding an addition to beyond
|
|
|
|
|
// the lval. This extra bit of information allows the
|
|
|
|
|
// expression to optimize itself a bit. If the lval==0, then
|
|
|
|
|
// the subexpression should not make l-value related
|
|
|
|
|
// optimizations.
|
|
|
|
|
//
|
|
|
|
|
// The unsigned_flag is set to true if the expression is
|
|
|
|
|
// unsized and therefore expandable. This happens if a
|
|
|
|
|
// sub-expression is an unsized literal. Some expressions make
|
|
|
|
|
// special use of that.
|
2006-11-04 07:19:24 +01:00
|
|
|
virtual unsigned test_width(Design*des, NetScope*scope,
|
|
|
|
|
unsigned min, unsigned lval,
|
|
|
|
|
bool&unsized_flag) const;
|
2006-10-30 06:44:49 +01:00
|
|
|
|
2006-06-02 06:48:49 +02:00
|
|
|
// Procedural elaboration of the expression. The expr_width is
|
|
|
|
|
// the width of the context of the expression (i.e. the
|
2007-06-28 07:05:36 +02:00
|
|
|
// l-value width of an assignment),
|
|
|
|
|
//
|
|
|
|
|
// ... or -1 if the expression is self-determined. or
|
|
|
|
|
// ... or -2 if the expression is losslessly
|
|
|
|
|
// self-determined. This can happen in situations where the
|
|
|
|
|
// result is going to a pseudo-infinitely wide context.
|
|
|
|
|
//
|
|
|
|
|
// 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,
|
2006-06-02 06:48:49 +02:00
|
|
|
int expr_width, bool sys_task_arg) const;
|
2000-03-08 05:36:53 +01:00
|
|
|
|
|
|
|
|
// Elaborate expressions that are the r-value of parameter
|
|
|
|
|
// assignments. This elaboration follows the restrictions of
|
|
|
|
|
// constant expressions and supports later overriding and
|
|
|
|
|
// evaluation of parameters.
|
|
|
|
|
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
|
1999-09-15 06:17:52 +02:00
|
|
|
|
|
|
|
|
// This method elaborate the expression as gates, for use in a
|
1999-10-31 05:11:27 +01:00
|
|
|
// continuous assign or other wholly structural context.
|
2001-11-08 06:15:50 +01:00
|
|
|
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
1999-10-31 05:11:27 +01:00
|
|
|
unsigned lwidth,
|
2006-01-02 06:33:19 +01:00
|
|
|
const NetExpr* rise,
|
|
|
|
|
const NetExpr* fall,
|
|
|
|
|
const NetExpr* decay,
|
2000-05-07 06:37:55 +02:00
|
|
|
Link::strength_t drive0 =Link::STRONG,
|
|
|
|
|
Link::strength_t drive1 =Link::STRONG)
|
|
|
|
|
const;
|
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.
|
2002-11-09 20:20:48 +01:00
|
|
|
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
|
|
|
|
|
bool implicit_net_ok =false) 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
|
|
|
|
|
// is slightly modified to accomodate the Verilog force
|
|
|
|
|
// 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
|
|
|
|
|
|
|
|
// 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
|
|
|
|
|
|
|
|
// Return true if this expression is a valid constant
|
|
|
|
|
// expression. the Module pointer is needed to find parameter
|
|
|
|
|
// identifiers and any other module specific interpretations
|
2003-01-30 17:23:07 +01:00
|
|
|
// of expressions.
|
1999-05-16 07:08:42 +02:00
|
|
|
virtual bool is_constant(Module*) const;
|
1999-10-31 21:08:24 +01: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:
|
2000-04-12 06:23:57 +02:00
|
|
|
PEConcat(const svector<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
|
|
|
|
2002-11-09 20:20:48 +01:00
|
|
|
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
|
|
|
|
|
bool implicit_net_ok =false) const;
|
2006-04-28 06:28:35 +02:00
|
|
|
virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const;
|
2001-11-08 06:15:50 +01:00
|
|
|
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
1999-10-31 05:11:27 +01:00
|
|
|
unsigned width,
|
2006-01-02 06:33:19 +01:00
|
|
|
const NetExpr* rise,
|
|
|
|
|
const NetExpr* fall,
|
|
|
|
|
const NetExpr* decay,
|
2000-05-07 06:37:55 +02:00
|
|
|
Link::strength_t drive0,
|
|
|
|
|
Link::strength_t drive1) const;
|
2002-04-13 04:33:17 +02:00
|
|
|
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
2006-06-02 06:48:49 +02:00
|
|
|
int expr_width, bool sys_task_arg) const;
|
2000-06-13 07:22:16 +02:00
|
|
|
virtual NetEConcat*elaborate_pexpr(Design*des, NetScope*) const;
|
2004-12-30 00:55:43 +01:00
|
|
|
virtual NetAssign_* elaborate_lval(Design*des,
|
|
|
|
|
NetScope*scope,
|
|
|
|
|
bool is_force) const;
|
1999-07-22 04:05:20 +02:00
|
|
|
virtual bool is_constant(Module*) const;
|
1999-05-10 02:16:57 +02:00
|
|
|
|
2006-04-28 06:28:35 +02:00
|
|
|
private:
|
|
|
|
|
NetNet* elaborate_lnet_common_(Design*des, NetScope*scope,
|
|
|
|
|
bool implicit_net_ok,
|
|
|
|
|
bool bidirectional_flag) const;
|
1999-05-10 02:16:57 +02:00
|
|
|
private:
|
|
|
|
|
svector<PExpr*>parms_;
|
1999-06-10 06:03:52 +02:00
|
|
|
PExpr*repeat_;
|
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;
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
2001-01-15 00:04:55 +01:00
|
|
|
/* A PEFNumber is a constant, so this returns true. */
|
|
|
|
|
virtual bool is_constant(Module*) const;
|
|
|
|
|
|
2002-04-13 04:33:17 +02:00
|
|
|
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
2006-06-02 06:48:49 +02:00
|
|
|
int expr_width, bool sys_task_arg) const;
|
2001-01-15 00:04:55 +01:00
|
|
|
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
|
|
|
|
|
|
2005-07-07 18:22:49 +02:00
|
|
|
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
|
|
|
|
unsigned lwidth,
|
2006-01-02 06:33:19 +01:00
|
|
|
const NetExpr* rise,
|
|
|
|
|
const NetExpr* fall,
|
|
|
|
|
const NetExpr* decay,
|
2005-07-07 18:22:49 +02:00
|
|
|
Link::strength_t drive0,
|
|
|
|
|
Link::strength_t drive1) const;
|
|
|
|
|
|
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:
|
2007-05-24 06:07:11 +02:00
|
|
|
explicit PEIdent(perm_string);
|
|
|
|
|
explicit PEIdent(const pform_name_t&);
|
2000-04-12 06:23:57 +02:00
|
|
|
~PEIdent();
|
1998-11-04 00:28:49 +01:00
|
|
|
|
2007-05-24 06:07:11 +02:00
|
|
|
// Add another name to the string of heirarchy that is the
|
|
|
|
|
// current identifier.
|
|
|
|
|
void append_name(perm_string);
|
|
|
|
|
|
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,
|
|
|
|
|
unsigned min, unsigned lval,
|
|
|
|
|
bool&unsized_flag) const;
|
1999-09-15 06:17:52 +02:00
|
|
|
|
|
|
|
|
// Identifiers are allowed (with restrictions) is assign l-values.
|
2002-11-09 20:20:48 +01:00
|
|
|
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
|
|
|
|
|
bool implicit_net_ok =false) 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
|
|
|
|
1999-09-15 06:17:52 +02:00
|
|
|
// Structural r-values are OK.
|
2001-11-08 06:15:50 +01:00
|
|
|
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
1999-10-31 05:11:27 +01:00
|
|
|
unsigned lwidth,
|
2006-01-02 06:33:19 +01:00
|
|
|
const NetExpr* rise,
|
|
|
|
|
const NetExpr* fall,
|
|
|
|
|
const NetExpr* decay,
|
2000-05-07 06:37:55 +02:00
|
|
|
Link::strength_t drive0,
|
|
|
|
|
Link::strength_t drive1) const;
|
1999-09-15 06:17:52 +02:00
|
|
|
|
2002-04-13 04:33:17 +02:00
|
|
|
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
2006-06-02 06:48:49 +02:00
|
|
|
int expr_width, bool sys_task_arg) const;
|
2000-03-12 05:35:22 +01:00
|
|
|
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) 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.
|
|
|
|
|
NetNet* elaborate_port(Design*des, NetScope*sc) const;
|
|
|
|
|
|
1999-05-16 07:08:42 +02:00
|
|
|
virtual bool is_constant(Module*) const;
|
2007-06-04 21:14:06 +02:00
|
|
|
verinum* eval_const(Design*des, NetScope*sc) const;
|
1998-11-04 00:28:49 +01:00
|
|
|
|
2007-05-24 06:07:11 +02:00
|
|
|
const pform_name_t& path() const { return path_; }
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
pform_name_t path_;
|
1998-11-04 00:28:49 +01:00
|
|
|
|
2006-11-04 07:19:24 +01:00
|
|
|
private:
|
|
|
|
|
// Common functions to calculate parts of part/bit selects.
|
|
|
|
|
bool calculate_parts_(Design*, NetScope*, long&msb, long&lsb) const;
|
|
|
|
|
bool calculate_up_do_width_(Design*, NetScope*, unsigned long&wid) const;
|
|
|
|
|
|
2006-04-16 02:15:43 +02:00
|
|
|
private:
|
2007-01-16 06:44:14 +01:00
|
|
|
NetAssign_*elaborate_lval_net_word_(Design*, NetScope*, NetNet*) const;
|
|
|
|
|
bool elaborate_lval_net_part_(Design*, NetScope*, NetAssign_*) const;
|
|
|
|
|
bool elaborate_lval_net_idx_up_(Design*, NetScope*, NetAssign_*) const;
|
|
|
|
|
bool elaborate_lval_net_idx_do_(Design*, NetScope*, NetAssign_*) const;
|
2006-04-16 02:15:43 +02:00
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
private:
|
2005-10-04 06:09:25 +02:00
|
|
|
NetExpr*elaborate_expr_param(Design*des,
|
|
|
|
|
NetScope*scope,
|
|
|
|
|
const NetExpr*par,
|
2005-11-27 06:56:20 +01:00
|
|
|
NetScope*found,
|
|
|
|
|
const NetExpr*par_msb,
|
|
|
|
|
const NetExpr*par_lsb) 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,
|
|
|
|
|
bool sys_task_arg) const;
|
|
|
|
|
NetExpr*elaborate_expr_net_word_(Design*des,
|
|
|
|
|
NetScope*scope,
|
|
|
|
|
NetNet*net,
|
|
|
|
|
NetScope*found,
|
|
|
|
|
bool sys_task_arg) const;
|
2005-11-10 14:28:11 +01:00
|
|
|
NetExpr*elaborate_expr_net_part_(Design*des,
|
|
|
|
|
NetScope*scope,
|
2007-01-16 06:44:14 +01:00
|
|
|
NetESignal*net,
|
2005-11-10 14:28:11 +01:00
|
|
|
NetScope*found) const;
|
|
|
|
|
NetExpr*elaborate_expr_net_idx_up_(Design*des,
|
|
|
|
|
NetScope*scope,
|
2007-01-16 06:44:14 +01:00
|
|
|
NetESignal*net,
|
2005-11-10 14:28:11 +01:00
|
|
|
NetScope*found) const;
|
|
|
|
|
NetExpr*elaborate_expr_net_idx_do_(Design*des,
|
|
|
|
|
NetScope*scope,
|
2007-01-16 06:44:14 +01:00
|
|
|
NetESignal*net,
|
2005-11-10 14:28:11 +01:00
|
|
|
NetScope*found) const;
|
|
|
|
|
NetExpr*elaborate_expr_net_bit_(Design*des,
|
|
|
|
|
NetScope*scope,
|
2007-01-16 06:44:14 +01:00
|
|
|
NetESignal*net,
|
2005-11-10 14:28:11 +01:00
|
|
|
NetScope*found) const;
|
1998-11-04 00:28:49 +01:00
|
|
|
|
|
|
|
|
public:
|
2007-05-24 06:07:11 +02:00
|
|
|
|
2007-01-16 06:44:14 +01:00
|
|
|
NetNet* elaborate_net_array_(Design*des, NetScope*scope,
|
|
|
|
|
NetNet*sig, unsigned lwidth,
|
|
|
|
|
const NetExpr* rise,
|
|
|
|
|
const NetExpr* fall,
|
|
|
|
|
const NetExpr* decay,
|
|
|
|
|
Link::strength_t drive0,
|
|
|
|
|
Link::strength_t drive1) const;
|
2002-04-23 05:53:59 +02:00
|
|
|
|
2007-07-03 05:53:02 +02:00
|
|
|
NetNet* elaborate_net_net_(Design*des, NetScope*scope,
|
|
|
|
|
NetNet*sig, unsigned lwidth,
|
|
|
|
|
const NetExpr* rise,
|
|
|
|
|
const NetExpr* fall,
|
|
|
|
|
const NetExpr* decay,
|
|
|
|
|
Link::strength_t drive0,
|
|
|
|
|
Link::strength_t drive1) const;
|
|
|
|
|
NetNet* elaborate_net_net_idx_up_(Design*des, NetScope*scope,
|
|
|
|
|
NetNet*sig, unsigned lwidth,
|
|
|
|
|
const NetExpr* rise,
|
|
|
|
|
const NetExpr* fall,
|
|
|
|
|
const NetExpr* decay,
|
|
|
|
|
Link::strength_t drive0,
|
|
|
|
|
Link::strength_t drive1) const;
|
2002-04-23 05:53:59 +02:00
|
|
|
NetNet* elaborate_net_bitmux_(Design*des, NetScope*scope,
|
|
|
|
|
NetNet*sig,
|
2006-01-02 06:33:19 +01:00
|
|
|
const NetExpr* rise,
|
|
|
|
|
const NetExpr* fall,
|
|
|
|
|
const NetExpr* decay,
|
2002-04-23 05:53:59 +02:00
|
|
|
Link::strength_t drive0,
|
|
|
|
|
Link::strength_t drive1) 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 implicit_net_ok,
|
|
|
|
|
bool bidirectional_flag) const;
|
|
|
|
|
|
|
|
|
|
NetNet*make_implicit_net_(Design*des, NetScope*scope) const;
|
|
|
|
|
|
2005-01-09 21:16:00 +01:00
|
|
|
bool eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
|
|
|
|
unsigned&midx, unsigned&lidx) const;
|
2007-06-04 04:19:07 +02:00
|
|
|
NetNet*process_select_(Design*des, NetScope*scope, NetNet*sig) const;
|
2005-01-09 21:16:00 +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,
|
|
|
|
|
unsigned min, unsigned lval,
|
|
|
|
|
bool&unsized_flag) const;
|
2006-10-30 06:44:49 +01:00
|
|
|
|
2001-11-08 06:15:50 +01:00
|
|
|
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
1999-10-31 05:11:27 +01:00
|
|
|
unsigned lwidth,
|
2006-01-02 06:33:19 +01:00
|
|
|
const NetExpr* rise,
|
|
|
|
|
const NetExpr* fall,
|
|
|
|
|
const NetExpr* decay,
|
2000-05-07 06:37:55 +02:00
|
|
|
Link::strength_t drive0,
|
|
|
|
|
Link::strength_t drive1) const;
|
2002-04-13 04:33:17 +02:00
|
|
|
virtual NetEConst*elaborate_expr(Design*des, NetScope*,
|
2006-06-02 06:48:49 +02:00
|
|
|
int expr_width, bool) const;
|
2000-03-08 05:36:53 +01:00
|
|
|
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) 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;
|
1999-05-16 07:08:42 +02:00
|
|
|
virtual bool is_constant(Module*) const;
|
1998-11-11 01:01:51 +01:00
|
|
|
|
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,
|
|
|
|
|
unsigned min, unsigned lval,
|
|
|
|
|
bool&unsized_flag) const;
|
|
|
|
|
|
2001-12-30 22:32:03 +01:00
|
|
|
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
|
|
|
|
unsigned width,
|
2006-01-02 06:33:19 +01:00
|
|
|
const NetExpr* rise,
|
|
|
|
|
const NetExpr* fall,
|
|
|
|
|
const NetExpr* decay,
|
2001-12-30 22:32:03 +01:00
|
|
|
Link::strength_t drive0,
|
|
|
|
|
Link::strength_t drive1) const;
|
2002-04-13 04:33:17 +02:00
|
|
|
virtual NetEConst*elaborate_expr(Design*des, NetScope*,
|
2006-06-02 06:48:49 +02:00
|
|
|
int expr_width, bool) const;
|
2000-06-01 04:31:39 +02:00
|
|
|
virtual NetEConst*elaborate_pexpr(Design*des, NetScope*sc) const;
|
2007-06-04 21:14:06 +02:00
|
|
|
verinum* eval_const(Design*, NetScope*) const;
|
1998-11-04 00:28:49 +01:00
|
|
|
|
1999-05-16 07:08:42 +02:00
|
|
|
virtual bool is_constant(Module*) 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
|
|
|
|
2001-11-08 06:15:50 +01:00
|
|
|
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
1999-10-31 05:11:27 +01:00
|
|
|
unsigned width,
|
2006-01-02 06:33:19 +01:00
|
|
|
const NetExpr* rise,
|
|
|
|
|
const NetExpr* fall,
|
|
|
|
|
const NetExpr* decay,
|
2000-05-07 06:37:55 +02:00
|
|
|
Link::strength_t drive0,
|
|
|
|
|
Link::strength_t drive1) const;
|
2002-04-14 05:55:25 +02:00
|
|
|
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
2006-06-02 06:48:49 +02:00
|
|
|
int expr_width, bool sys_task_arg) const;
|
2000-03-12 19:22:11 +01:00
|
|
|
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) 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
|
|
|
|
2000-06-30 17:50:20 +02:00
|
|
|
virtual bool is_constant(Module*) const;
|
|
|
|
|
|
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
|
|
|
|
1999-06-16 05:13:29 +02:00
|
|
|
virtual bool is_constant(Module*) const;
|
|
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
virtual void dump(ostream&out) const;
|
2006-10-30 06:44:49 +01:00
|
|
|
|
2006-11-04 07:19:24 +01:00
|
|
|
virtual unsigned test_width(Design*des, NetScope*scope,
|
|
|
|
|
unsigned min, unsigned lval,
|
|
|
|
|
bool&unsized_flag) const;
|
2006-10-30 06:44:49 +01:00
|
|
|
|
2001-11-08 06:15:50 +01:00
|
|
|
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
1999-10-31 05:11:27 +01:00
|
|
|
unsigned width,
|
2006-01-02 06:33:19 +01:00
|
|
|
const NetExpr* rise,
|
|
|
|
|
const NetExpr* fall,
|
|
|
|
|
const NetExpr* decay,
|
2000-05-07 06:37:55 +02:00
|
|
|
Link::strength_t drive0,
|
|
|
|
|
Link::strength_t drive1) const;
|
2002-04-13 04:33:17 +02:00
|
|
|
virtual NetEBinary*elaborate_expr(Design*des, NetScope*,
|
2006-06-02 06:48:49 +02:00
|
|
|
int expr_width, bool sys_task_arg) const;
|
2000-03-12 19:22:11 +01:00
|
|
|
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) 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
|
|
|
|
2006-11-04 07:19:24 +01:00
|
|
|
NetEBinary*elaborate_expr_base_(Design*, NetExpr*lp, NetExpr*rp, int use_wid) const;
|
|
|
|
|
NetEBinary*elaborate_eval_expr_base_(Design*, NetExpr*lp, NetExpr*rp, int use_wid) const;
|
2000-03-12 19:22:11 +01:00
|
|
|
|
2006-10-30 06:44:49 +01:00
|
|
|
private:
|
2001-11-08 06:15:50 +01:00
|
|
|
NetNet* elaborate_net_add_(Design*des, NetScope*scope,
|
1999-10-31 21:08:24 +01:00
|
|
|
unsigned lwidth,
|
2006-01-02 06:33:19 +01:00
|
|
|
const NetExpr* rise,
|
|
|
|
|
const NetExpr* fall,
|
|
|
|
|
const NetExpr* decay) const;
|
2001-11-08 06:15:50 +01:00
|
|
|
NetNet* elaborate_net_bit_(Design*des, NetScope*scope,
|
2000-02-16 04:58:27 +01:00
|
|
|
unsigned lwidth,
|
2006-01-02 06:33:19 +01:00
|
|
|
const NetExpr* rise,
|
|
|
|
|
const NetExpr* fall,
|
|
|
|
|
const NetExpr* decay) const;
|
2001-11-08 06:15:50 +01:00
|
|
|
NetNet* elaborate_net_cmp_(Design*des, NetScope*scope,
|
1999-11-05 22:45:19 +01:00
|
|
|
unsigned lwidth,
|
2006-01-02 06:33:19 +01:00
|
|
|
const NetExpr* rise,
|
|
|
|
|
const NetExpr* fall,
|
|
|
|
|
const NetExpr* decay) const;
|
2001-11-08 06:15:50 +01:00
|
|
|
NetNet* elaborate_net_div_(Design*des, NetScope*scope,
|
2000-04-01 23:40:22 +02:00
|
|
|
unsigned lwidth,
|
2006-01-02 06:33:19 +01:00
|
|
|
const NetExpr* rise,
|
|
|
|
|
const NetExpr* fall,
|
|
|
|
|
const NetExpr* decay) const;
|
2001-11-08 06:15:50 +01:00
|
|
|
NetNet* elaborate_net_mod_(Design*des, NetScope*scope,
|
2000-09-17 23:26:15 +02:00
|
|
|
unsigned lwidth,
|
2006-01-02 06:33:19 +01:00
|
|
|
const NetExpr* rise,
|
|
|
|
|
const NetExpr* fall,
|
|
|
|
|
const NetExpr* decay) const;
|
2001-11-08 06:15:50 +01:00
|
|
|
NetNet* elaborate_net_log_(Design*des, NetScope*scope,
|
1999-12-16 04:46:39 +01:00
|
|
|
unsigned lwidth,
|
2006-01-02 06:33:19 +01:00
|
|
|
const NetExpr* rise,
|
|
|
|
|
const NetExpr* fall,
|
|
|
|
|
const NetExpr* decay) const;
|
2001-11-08 06:15:50 +01:00
|
|
|
NetNet* elaborate_net_mul_(Design*des, NetScope*scope,
|
2000-01-13 04:35:35 +01:00
|
|
|
unsigned lwidth,
|
2006-01-02 06:33:19 +01:00
|
|
|
const NetExpr* rise,
|
|
|
|
|
const NetExpr* fall,
|
|
|
|
|
const NetExpr* decay) const;
|
2001-11-08 06:15:50 +01:00
|
|
|
NetNet* elaborate_net_shift_(Design*des, NetScope*scope,
|
1999-11-14 21:24:28 +01:00
|
|
|
unsigned lwidth,
|
2006-01-02 06:33:19 +01:00
|
|
|
const NetExpr* rise,
|
|
|
|
|
const NetExpr* fall,
|
|
|
|
|
const NetExpr* decay) const;
|
1998-11-04 00:28:49 +01:00
|
|
|
};
|
|
|
|
|
|
2006-10-30 06:44:49 +01:00
|
|
|
/*
|
|
|
|
|
* Here are a few specilized classes for handling specific binary
|
|
|
|
|
* operators.
|
|
|
|
|
*/
|
|
|
|
|
class PEBComp : public PEBinary {
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
explicit PEBComp(char op, PExpr*l, PExpr*r);
|
|
|
|
|
~PEBComp();
|
|
|
|
|
|
2006-11-04 07:19:24 +01:00
|
|
|
virtual unsigned test_width(Design*des, NetScope*scope,
|
|
|
|
|
unsigned min, unsigned lval,
|
|
|
|
|
bool&flag) const;
|
2006-10-30 06:44:49 +01:00
|
|
|
|
|
|
|
|
NetEBinary* elaborate_expr(Design*des, NetScope*scope,
|
|
|
|
|
int expr_width, bool sys_task_arg) const;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class PEBShift : public PEBinary {
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
explicit PEBShift(char op, PExpr*l, PExpr*r);
|
|
|
|
|
~PEBShift();
|
|
|
|
|
|
2006-11-04 07:19:24 +01:00
|
|
|
virtual unsigned test_width(Design*des, NetScope*scope,
|
|
|
|
|
unsigned min, unsigned lval, bool&flag) 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 bool is_constant(Module*) const;
|
|
|
|
|
|
|
|
|
|
virtual void dump(ostream&out) const;
|
2006-11-10 05:54:26 +01:00
|
|
|
virtual unsigned test_width(Design*des, NetScope*scope,
|
|
|
|
|
unsigned min, unsigned lval,
|
|
|
|
|
bool&unsized_flag) const;
|
|
|
|
|
|
2001-11-08 06:15:50 +01:00
|
|
|
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
1999-10-31 05:11:27 +01:00
|
|
|
unsigned width,
|
2006-01-02 06:33:19 +01:00
|
|
|
const NetExpr* rise,
|
|
|
|
|
const NetExpr* fall,
|
|
|
|
|
const NetExpr* decay,
|
2000-05-07 06:37:55 +02:00
|
|
|
Link::strength_t drive0,
|
|
|
|
|
Link::strength_t drive1) const;
|
2002-04-13 04:33:17 +02:00
|
|
|
virtual NetETernary*elaborate_expr(Design*des, NetScope*,
|
2006-06-02 06:48:49 +02:00
|
|
|
int expr_width, bool sys_task_arg) const;
|
2000-12-16 20:03:30 +01:00
|
|
|
virtual NetETernary*elaborate_pexpr(Design*des, NetScope*sc) 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
|
|
|
|
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:
|
2007-05-24 06:07:11 +02:00
|
|
|
explicit PECallFunction(const pform_name_t&n, const svector<PExpr *> &parms);
|
|
|
|
|
// Call of system function (name is not heirarchical)
|
|
|
|
|
explicit PECallFunction(perm_string n, const svector<PExpr *> &parms);
|
|
|
|
|
explicit PECallFunction(perm_string n);
|
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
|
|
|
|
2002-03-09 03:10:22 +01:00
|
|
|
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
|
|
|
|
unsigned width,
|
2006-01-02 06:33:19 +01:00
|
|
|
const NetExpr* rise,
|
|
|
|
|
const NetExpr* fall,
|
|
|
|
|
const NetExpr* decay,
|
2002-03-09 03:10:22 +01:00
|
|
|
Link::strength_t drive0,
|
|
|
|
|
Link::strength_t drive1) const;
|
2002-04-13 04:33:17 +02:00
|
|
|
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
2006-06-02 06:48:49 +02:00
|
|
|
int expr_wid, bool sys_task_arg) 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,
|
|
|
|
|
unsigned min, unsigned lval,
|
|
|
|
|
bool&unsized_flag) const;
|
|
|
|
|
|
1999-09-25 04:57:29 +02:00
|
|
|
private:
|
2007-05-24 06:07:11 +02:00
|
|
|
pform_name_t path_;
|
1999-07-31 21:14:47 +02:00
|
|
|
svector<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;
|
|
|
|
|
|
2007-10-10 05:46:17 +02:00
|
|
|
NetExpr* elaborate_sfunc_(Design*des, NetScope*scope, int expr_wid) const;
|
2006-06-18 06:15:50 +02:00
|
|
|
NetNet* elaborate_net_sfunc_(Design*des, NetScope*scope,
|
|
|
|
|
unsigned width,
|
|
|
|
|
const NetExpr* rise,
|
|
|
|
|
const NetExpr* fall,
|
|
|
|
|
const NetExpr* decay,
|
|
|
|
|
Link::strength_t drive0,
|
|
|
|
|
Link::strength_t drive1) const;
|
2007-10-02 05:38:20 +02:00
|
|
|
unsigned test_width_sfunc_(Design*des, NetScope*scope,
|
|
|
|
|
unsigned min, unsigned lval,
|
|
|
|
|
bool&unsized_flag) const;
|
1999-07-31 21:14:47 +02:00
|
|
|
};
|
|
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
#endif
|