iverilog/PExpr.h

517 lines
16 KiB
C
Raw Normal View History

1998-11-04 00:28:49 +01:00
#ifndef __PExpr_H
#define __PExpr_H
/*
* 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
*/
#if !defined(WINNT) && !defined(macintosh)
2002-03-09 03:10:22 +01:00
#ident "$Id: PExpr.h,v 1.55 2002/03/09 02:10:22 steve Exp $"
1998-11-04 00:28:49 +01:00
#endif
# include <string>
1999-04-29 04:16:26 +02:00
# include "netlist.h"
1998-11-04 00:28:49 +01:00
# include "verinum.h"
1999-06-15 04:50:02 +02:00
# include "verireal.h"
# include "LineInfo.h"
1998-11-04 00:28:49 +01:00
class Design;
class Module;
1998-11-04 00:28:49 +01:00
class NetNet;
class NetExpr;
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.
*/
class PExpr : public LineInfo {
1998-11-04 00:28:49 +01:00
public:
PExpr();
1998-11-04 00:28:49 +01:00
virtual ~PExpr();
virtual void dump(ostream&) const;
// Procedural elaboration of the expression.
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope) const;
// 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;
// This method elaborate the expression as gates, for use in a
// continuous assign or other wholly structural context.
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay,
Link::strength_t drive0 =Link::STRONG,
Link::strength_t drive1 =Link::STRONG)
const;
// This method elaborates the expression as NetNet objects. It
// only allows regs suitable for procedural continuous assignments.
virtual NetNet* elaborate_anet(Design*des, NetScope*scope) const;
// This method elaborates the expression as gates, but
// restricted for use as l-values of continuous assignments.
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
1998-11-04 00:28:49 +01:00
// Expressions that can be in the l-value of procedural
// assignments can be elaborated with this method.
virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope) const;
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.
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
1998-11-11 01:01:51 +01:00
// This attempts to evaluate a constant expression as a
// decimal floating point. This is used when calculating delay
// constants.
virtual verireal* eval_rconst(const Design*, const NetScope*) 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;
// 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
// of expresions.
virtual bool is_constant(Module*) const;
private: // not implemented
PExpr(const PExpr&);
PExpr& operator= (const PExpr&);
1998-11-04 00:28:49 +01:00
};
ostream& operator << (ostream&, const PExpr&);
class PEConcat : public PExpr {
public:
PEConcat(const svector<PExpr*>&p, PExpr*r =0);
~PEConcat();
virtual void dump(ostream&) const;
// Concatenated Regs can be on the left of procedural
// continuous assignments.
virtual NetNet* elaborate_anet(Design*des, NetScope*scope) const;
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
unsigned long rise,
unsigned long fall,
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*) const;
virtual NetEConcat*elaborate_pexpr(Design*des, NetScope*) const;
virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope) const;
1999-07-22 04:05:20 +02:00
virtual bool is_constant(Module*) const;
private:
svector<PExpr*>parms_;
PExpr*repeat_;
};
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:
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.
PEEvent(edge_t t, PExpr*e);
2000-04-01 21:31:57 +02:00
~PEEvent();
1999-04-29 04:16:26 +02:00
edge_t type() const;
PExpr* expr() const;
2000-09-17 23:26:15 +02:00
1999-04-29 04:16:26 +02:00
virtual void dump(ostream&) const;
private:
edge_t type_;
PExpr *expr_;
1999-04-29 04:16:26 +02: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. */
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
/* This method returns the full floating point value. */
virtual verireal* eval_rconst(const Design*, const NetScope*) const;
/* A PEFNumber is a constant, so this returns true. */
virtual bool is_constant(Module*) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual void dump(ostream&) const;
private:
verireal*value_;
};
1998-11-04 00:28:49 +01:00
class PEIdent : public PExpr {
public:
explicit PEIdent(const hname_t&s);
~PEIdent();
1998-11-04 00:28:49 +01:00
virtual void dump(ostream&) const;
// Regs can be on the left of procedural continuous assignments
virtual NetNet* elaborate_anet(Design*des, NetScope*scope) const;
// Identifiers are allowed (with restrictions) is assign l-values.
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
// Identifiers are also allowed as procedural assignment l-values.
virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope) const;
// Structural r-values are OK.
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
// Elaborate the PEIdent as a port to a module. This method
// only applies to Ident expressions.
NetNet* elaborate_port(Design*des, NetScope*sc) const;
virtual bool is_constant(Module*) const;
verinum* eval_const(const Design*des, const NetScope*sc) const;
verireal*eval_rconst(const Design*des, const NetScope*sc) const;
1998-11-04 00:28:49 +01:00
const hname_t& path() const;
1998-11-04 00:28:49 +01:00
private:
hname_t path_;
1998-11-04 00:28:49 +01:00
public:
// Use these to support bit- and part-select operators.
PExpr*msb_;
PExpr*lsb_;
// If this is a reference to a memory, this is the index
// expression.
PExpr*idx_;
NetNet* elaborate_net_ram_(Design*des, NetScope*scope,
NetMemory*mem, unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
1998-11-04 00:28:49 +01:00
};
class PENumber : public PExpr {
public:
explicit PENumber(verinum*vp);
~PENumber();
1998-11-04 00:28:49 +01:00
const verinum& value() const;
1998-11-04 00:28:49 +01:00
virtual void dump(ostream&) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetEConst*elaborate_expr(Design*des, NetScope*) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
virtual verireal*eval_rconst(const Design*, const NetScope*) 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;
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_;
};
/*
* 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:
explicit PEString(char*s);
~PEString();
1998-11-04 00:28:49 +01:00
string value() const;
1998-11-04 00:28:49 +01:00
virtual void dump(ostream&) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
unsigned long rise,
unsigned long fall,
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetEConst*elaborate_expr(Design*des, NetScope*) const;
2000-06-01 04:31:39 +02:00
virtual NetEConst*elaborate_pexpr(Design*des, NetScope*sc) const;
1998-11-04 00:28:49 +01:00
virtual bool is_constant(Module*) const;
1998-11-04 00:28:49 +01:00
private:
char*text_;
1998-11-04 00:28:49 +01:00
};
class PEUnary : public PExpr {
public:
explicit PEUnary(char op, PExpr*ex);
~PEUnary();
1998-11-04 00:28:49 +01:00
virtual void dump(ostream&out) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
unsigned long rise,
unsigned long fall,
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetEUnary*elaborate_expr(Design*des, NetScope*) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
1998-11-04 00:28:49 +01: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:
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;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
unsigned long rise,
unsigned long fall,
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetEBinary*elaborate_expr(Design*des, NetScope*) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
virtual verireal*eval_rconst(const Design*des, const NetScope*sc) const;
1998-11-04 00:28:49 +01:00
private:
char op_;
PExpr*left_;
PExpr*right_;
NetEBinary*elaborate_expr_base_(Design*, NetExpr*lp, NetExpr*rp) const;
NetNet* elaborate_net_add_(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_bit_(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_cmp_(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_div_(Design*des, NetScope*scope,
2000-04-01 23:40:22 +02:00
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_mod_(Design*des, NetScope*scope,
2000-09-17 23:26:15 +02:00
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_log_(Design*des, NetScope*scope,
1999-12-16 04:46:39 +01:00
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_mul_(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_shift_(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
1998-11-04 00:28:49 +01: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);
~PETernary();
1999-07-17 21:50:59 +02:00
virtual bool is_constant(Module*) const;
virtual void dump(ostream&out) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
unsigned long rise,
unsigned long fall,
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetETernary*elaborate_expr(Design*des, NetScope*) const;
virtual NetETernary*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
1999-07-17 21:50:59 +02:00
private:
PExpr*expr_;
PExpr*tru_;
PExpr*fal_;
};
1999-09-25 04:57:29 +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
*/
class PECallFunction : public PExpr {
1999-09-25 04:57:29 +02:00
public:
explicit PECallFunction(const hname_t&n, const svector<PExpr *> &parms);
explicit PECallFunction(const hname_t&n);
1999-09-25 04:57:29 +02:00
~PECallFunction();
virtual void dump(ostream &) const;
2002-03-09 03:10:22 +01:00
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
unsigned long rise,
unsigned long fall,
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope) const;
1999-09-25 04:57:29 +02:00
private:
hname_t path_;
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;
NetExpr* elaborate_sfunc_(Design*des, NetScope*scope) const;
};
1998-11-04 00:28:49 +01:00
/*
* $Log: PExpr.h,v $
2002-03-09 03:10:22 +01:00
* Revision 1.55 2002/03/09 02:10:22 steve
* Add the NetUserFunc netlist node.
*
* Revision 1.54 2001/12/30 21:32:03 steve
* Support elaborate_net for PEString objects.
*
* Revision 1.53 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.52 2001/11/08 05:15:50 steve
* Remove string paths from PExpr elaboration.
*
* Revision 1.51 2001/11/07 04:26:46 steve
* elaborate_lnet uses scope instead of string path.
*
* Revision 1.50 2001/11/07 04:01:59 steve
* eval_const uses scope instead of a string path.
*
* Revision 1.49 2001/11/06 06:11:55 steve
* Support more real arithmetic in delay constants.
*
* Revision 1.48 2001/01/14 23:04:55 steve
* Generalize the evaluation of floating point delays, and
* get it working with delay assignment statements.
*
* Allow parameters to be referenced by hierarchical name.
*
* Revision 1.47 2000/12/16 19:03:30 steve
* Evaluate <= and ?: in parameter expressions (PR#81)
*
* Revision 1.46 2000/12/10 22:01:35 steve
* Support decimal constants in behavioral delays.
*
* Revision 1.45 2000/12/06 06:31:09 steve
* Check lvalue of procedural continuous assign (PR#29)
*
2000-09-17 23:26:15 +02:00
* Revision 1.44 2000/09/17 21:26:15 steve
* Add support for modulus (Eric Aardoom)
1998-11-04 00:28:49 +01:00
*/
#endif