Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Calculate delay statement delays using elaborated

 expressions instead of pre-elaborated expression
 trees.

 Remove the eval_pexpr methods from PExpr.
  • Loading branch information...
commit e571dd90d8caae26ee7b3dc3f09a68b6ff84e05c 1 parent 26b755d
steve authored
Showing with 108 additions and 243 deletions.
  1. +2 −2 Makefile.in
  2. +45 −21 PDelays.cc
  3. +8 −13 PExpr.h
  4. +53 −80 elaborate.cc
  5. +0 −127 eval_rconst.cc
View
4 Makefile.in
@@ -16,7 +16,7 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
-#ident "$Id: Makefile.in,v 1.143 2003/01/26 21:15:58 steve Exp $"
+#ident "$Id: Makefile.in,v 1.144 2003/02/08 19:49:21 steve Exp $"
#
#
SHELL = /bin/sh
@@ -123,7 +123,7 @@ FF = cprop.o nodangle.o synth.o synth2.o syn-rules.o xnfio.o
O = main.o async.o design_dump.o dup_expr.o elaborate.o elab_expr.o \
elab_lval.o elab_net.o elab_anet.o elab_pexpr.o elab_scope.o \
-elab_sig.o emit.o eval.o eval_attrib.o eval_rconst.o \
+elab_sig.o emit.o eval.o eval_attrib.o \
eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \
load_module.o netlist.o netmisc.o net_assign.o \
net_design.o net_event.o net_expr.o net_force.o net_func.o \
View
66 PDelays.cc
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
-#ident "$Id: PDelays.cc,v 1.9 2002/08/12 01:34:58 steve Exp $"
+#ident "$Id: PDelays.cc,v 1.10 2003/02/08 19:49:21 steve Exp $"
#endif
# include "config.h"
@@ -62,34 +62,51 @@ void PDelays::set_delays(const svector<PExpr*>*del, bool df)
delete_flag_ = df;
}
-static unsigned long calculate_val(Design*des, const NetScope*scope,
+static unsigned long calculate_val(Design*des, NetScope*scope,
const PExpr*expr)
{
- assert(expr);
- unsigned long val;
- int shift = scope->time_unit() - des->get_precision();
+ NetExpr*dex = expr->elaborate_expr(des, scope);
+ if (NetExpr*tmp = dex->eval_tree()) {
+ delete dex;
+ dex = tmp;
+ }
- if (verireal*dr = expr->eval_rconst(des, scope)) {
- val = dr->as_long(shift);
- delete dr;
+ /* If the delay expression is a real constant or vector
+ constant, then evaluate it, scale it to the local time
+ units, and return an adjusted value. */
- } else {
- verinum*dv = expr->eval_const(des, scope);
- if (dv == 0) {
- cerr << expr->get_line() << ": sorry: non-constant "
- << "delays not supported here: " << *expr << endl;
- des->errors += 1;
- return 0;
- }
+ if (NetECReal*tmp = dynamic_cast<NetECReal*>(dex)) {
+ verireal fn = tmp->value();
+
+ int shift = scope->time_unit() - des->get_precision();
+ long delay = fn.as_long(shift);
+ if (delay < 0)
+ delay = 0;
+
+ delete tmp;
+ return delay;
+ }
- assert(dv);
- val = dv->as_ulong();
- val = des->scale_to_precision(val, scope);
- delete dv;
+
+ if (NetEConst*tmp = dynamic_cast<NetEConst*>(dex)) {
+ verinum fn = tmp->value();
+
+ unsigned long delay =
+ des->scale_to_precision(fn.as_ulong(), scope);
+
+ delete tmp;
+ return delay;
}
- return val;
+ /* Oops, cannot evaluate down to a constant. Error message. */
+ delete dex;
+
+ cerr << expr->get_line() << ": sorry: non-constant "
+ << "delays not supported here: " << *expr << endl;
+ des->errors += 1;
+ return 0;
+
}
void PDelays::eval_delays(Design*des, NetScope*scope,
@@ -131,6 +148,13 @@ void PDelays::eval_delays(Design*des, NetScope*scope,
/*
* $Log: PDelays.cc,v $
+ * Revision 1.10 2003/02/08 19:49:21 steve
+ * Calculate delay statement delays using elaborated
+ * expressions instead of pre-elaborated expression
+ * trees.
+ *
+ * Remove the eval_pexpr methods from PExpr.
+ *
* Revision 1.9 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
View
21 PExpr.h
@@ -19,13 +19,12 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
-#ident "$Id: PExpr.h,v 1.64 2003/01/30 16:23:07 steve Exp $"
+#ident "$Id: PExpr.h,v 1.65 2003/02/08 19:49:21 steve Exp $"
#endif
# include <string>
# include "netlist.h"
# include "verinum.h"
-# include "verireal.h"
# include "LineInfo.h"
class Design;
@@ -92,11 +91,6 @@ class PExpr : public LineInfo {
// evaluated, return 0.
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
- // 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;
-
// 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".
@@ -190,9 +184,6 @@ class PEFNumber : public PExpr {
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;
@@ -243,7 +234,6 @@ class PEIdent : public PExpr {
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;
const hname_t& path() const;
@@ -301,7 +291,6 @@ class PENumber : public PExpr {
virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope) const;
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
- virtual verireal*eval_rconst(const Design*, const NetScope*) const;
virtual bool is_the_same(const PExpr*that) const;
virtual bool is_constant(Module*) const;
@@ -389,7 +378,6 @@ class PEBinary : public PExpr {
bool sys_task_arg =false) 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;
private:
char op_;
@@ -504,6 +492,13 @@ class PECallFunction : public PExpr {
/*
* $Log: PExpr.h,v $
+ * Revision 1.65 2003/02/08 19:49:21 steve
+ * Calculate delay statement delays using elaborated
+ * expressions instead of pre-elaborated expression
+ * trees.
+ *
+ * Remove the eval_pexpr methods from PExpr.
+ *
* Revision 1.64 2003/01/30 16:23:07 steve
* Spelling fixes.
*
View
133 elaborate.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2002 Stephen Williams (steve@icarus.com)
+ * Copyright (c) 1998-2003 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
-#ident "$Id: elaborate.cc,v 1.272 2003/02/07 02:49:24 steve Exp $"
+#ident "$Id: elaborate.cc,v 1.273 2003/02/08 19:49:21 steve Exp $"
#endif
# include "config.h"
@@ -868,23 +868,43 @@ NetAssign_* PAssign_::elaborate_lval(Design*des, NetScope*scope) const
static NetExpr*elaborate_delay_expr(PExpr*expr, Design*des, NetScope*scope)
{
- if (verireal*dr = expr->eval_rconst(des, scope)) {
+ NetExpr*dex = expr->elaborate_expr(des, scope);
+ if (NetExpr*tmp = dex->eval_tree()) {
+ delete dex;
+ dex = tmp;
+ }
+
+ /* If the delay expression is a real constant or vector
+ constant, then evaluate it, scale it to the local time
+ units, and return an adjusted NetEConst. */
+
+ if (NetECReal*tmp = dynamic_cast<NetECReal*>(dex)) {
+ verireal fn = tmp->value();
+
int shift = scope->time_unit() - des->get_precision();
- long val = dr->as_long(shift);
- delete dr;
- return new NetEConst(verinum(val));
+ long delay = fn.as_long(shift);
+ if (delay < 0)
+ delay = 0;
+ delete tmp;
+ return new NetEConst(verinum(delay));
}
- if (verinum*dv = expr->eval_const(des, scope)) {
- unsigned long val = dv->as_ulong();
- val = des->scale_to_precision(val, scope);
- return new NetEConst(verinum(val));
+ if (NetEConst*tmp = dynamic_cast<NetEConst*>(dex)) {
+ verinum fn = tmp->value();
+
+ unsigned long delay =
+ des->scale_to_precision(fn.as_ulong(), scope);
+
+ delete tmp;
+ return new NetEConst(verinum(delay));
}
- NetExpr*delay = expr->elaborate_expr(des, scope);
+ /* The expression is not constant, so generate an expanded
+ expression that includes the necessary scale shifts, and
+ return that expression. */
int shift = scope->time_unit() - des->get_precision();
if (shift > 0) {
unsigned long scale = 1;
@@ -894,7 +914,7 @@ static NetExpr*elaborate_delay_expr(PExpr*expr, Design*des, NetScope*scope)
}
NetExpr*scal_val = new NetEConst(verinum(scale));
- delay = new NetEBMult('*', delay, scal_val);
+ dex = new NetEBMult('*', dex, scal_val);
}
if (shift < 0) {
@@ -905,10 +925,10 @@ static NetExpr*elaborate_delay_expr(PExpr*expr, Design*des, NetScope*scope)
}
NetExpr*scal_val = new NetEConst(verinum(scale));
- delay = new NetEBDiv('/', delay, scal_val);
+ dex = new NetEBDiv('/', dex, scal_val);
}
- return delay;
+ return dex;
}
NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
@@ -1574,81 +1594,27 @@ NetProc* PDelayStatement::elaborate(Design*des, NetScope*scope) const
{
assert(scope);
- NetExpr*dex = delay_->elaborate_expr(des, scope);
- if (NetExpr*tmp = dex->eval_tree()) {
- delete dex;
- dex = tmp;
- }
-
- /* Catch the case that the expression is a constant real
- value. Scale the delay to the units of the design, and make
- the delay statement. */
- if (NetECReal*tmp = dynamic_cast<NetECReal*>(dex)) {
- verireal fn = tmp->value();
-
- int shift = scope->time_unit() - des->get_precision();
- long delay = fn.as_long(shift);
- if (delay < 0)
- delay = 0;
-
- delete tmp;
+ /* This call evaluates the delay expression to a NetEConst, if
+ possible. This includes transforming NetECReal values to
+ integers, and applying the proper scaling. */
+ NetExpr*dex = elaborate_delay_expr(delay_, des, scope);
+ if (NetEConst*tmp = dynamic_cast<NetEConst*>(dex)) {
if (statement_)
- return new NetPDelay(delay, statement_->elaborate(des, scope));
+ return new NetPDelay(tmp->value().as_ulong(),
+ statement_->elaborate(des, scope));
else
- return new NetPDelay(delay, 0);
- }
+ return new NetPDelay(tmp->value().as_ulong(), 0);
- /* OK, Maybe the expression is a constant integer. If so,
- scale the delay to simulation units and make the delay
- statement. */
- if (NetEConst*tmp = dynamic_cast<NetEConst*>(dex)) {
- verinum fn = tmp->value();
-
- unsigned long delay =
- des->scale_to_precision(fn.as_ulong(), scope);
-
- delete tmp;
+ delete dex;
+ } else {
if (statement_)
- return new NetPDelay(delay, statement_->elaborate(des, scope));
+ return new NetPDelay(dex, statement_->elaborate(des, scope));
else
- return new NetPDelay(delay, 0);
+ return new NetPDelay(dex, 0);
}
-
- /* Ah well, the delay is not constant. OK, elaborate the
- expression and let the run-time handle it. */
-
-
- /* If the local scope units are different from the
- simulation precision, then extend the expression to
- convert the delay to simulation time. */
- if (scope->time_unit() != des->get_precision()) {
- long scale = 1;
- int unit = scope->time_unit();
- int prec = des->get_precision();
- while (unit > prec) {
- scale *= 10;
- unit -= 1;
- }
-
- verinum scale_v (scale);
- NetEConst*scale_e = new NetEConst(scale_v);
- NetEBMult*scale_m = new NetEBMult('*', scale_e, dex);
- if (NetExpr*tmp = scale_m->eval_tree()) {
- dex = tmp;
- delete scale_m;
- } else {
- dex = scale_m;
- }
- }
-
- if (statement_)
- return new NetPDelay(dex, statement_->elaborate(des, scope));
- else
- return new NetPDelay(dex, 0);
-
}
/*
@@ -2508,6 +2474,13 @@ Design* elaborate(list<const char*>roots)
/*
* $Log: elaborate.cc,v $
+ * Revision 1.273 2003/02/08 19:49:21 steve
+ * Calculate delay statement delays using elaborated
+ * expressions instead of pre-elaborated expression
+ * trees.
+ *
+ * Remove the eval_pexpr methods from PExpr.
+ *
* Revision 1.272 2003/02/07 02:49:24 steve
* Rewrite delay statement elaboration of handle real expressions.
*
View
127 eval_rconst.cc
@@ -1,127 +0,0 @@
-/*
- * Copyright (c) 2001 Stephen Williams (steve@icarus.com)
- *
- * 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
- */
-#ifdef HAVE_CVS_IDENT
-#ident "$Id: eval_rconst.cc,v 1.6 2003/02/01 23:37:34 steve Exp $"
-#endif
-
-# include "config.h"
-
-# include "PExpr.h"
-# include "verireal.h"
-
-verireal* PExpr::eval_rconst(const Design*, const NetScope*) const
-{
- return 0;
-}
-
-verireal* PEFNumber::eval_rconst(const Design*, const NetScope*) const
-{
- verireal*res = new verireal;
- *res = *value_;
- return res;
-}
-
-verireal* PENumber::eval_rconst(const Design*, const NetScope*) const
-{
- verireal*res = new verireal(value_->as_long());
- return res;
-}
-
-verireal* PEBinary::eval_rconst(const Design*des, const NetScope*scope) const
-{
- verireal*lef = left_->eval_rconst(des, scope);
- verireal*rig = right_->eval_rconst(des, scope);
- verireal*res = 0;
-
- switch (op_) {
- case '*':
- if (lef == 0)
- break;
- if (rig == 0)
- break;
- res = new verireal;
- *res = (*lef) * (*rig);
- break;
-
- default:
- break;
- }
-
- delete lef;
- delete rig;
- return res;
-}
-
-
-verireal* PEIdent::eval_rconst(const Design*des, const NetScope*scope) const
-{
- assert(scope);
- const NetExpr*expr = des->find_parameter(scope, path_);
- if (expr == 0)
- return 0;
-
- /* Is this a real valued parameter? If so, then evaluate it
- as a real expression and return the resulting verireal. */
- if (expr->expr_type() == NetExpr::ET_REAL) {
- const NetECReal*ereal = dynamic_cast<const NetECReal*>(expr);
- if (ereal == 0) {
- cerr << get_line() << ": internal error: "
- << "Unable to evaluate real constant expression "
- << "(parameter=" << path_ << "): " << *expr << endl;
- return 0;
- }
-
- return new verireal(ereal->value());
- }
-
- verinum* val = eval_const(des, scope);
- if (val == 0)
- return 0;
-
- verireal*res = new verireal(val->as_long());
- delete val;
- return res;
-}
-
-/*
- * $Log: eval_rconst.cc,v $
- * Revision 1.6 2003/02/01 23:37:34 steve
- * Allow parameter expressions to be type real.
- *
- * Revision 1.5 2002/08/12 01:34:59 steve
- * conditional ident string using autoconfig.
- *
- * Revision 1.4 2001/11/07 04:01:59 steve
- * eval_const uses scope instead of a string path.
- *
- * Revision 1.3 2001/11/06 06:11:55 steve
- * Support more real arithmetic in delay constants.
- *
- * Revision 1.2 2001/07/25 03:10:49 steve
- * Create a config.h.in file to hold all the config
- * junk, and support gcc 3.0. (Stephan Boettcher)
- *
- * Revision 1.1 2001/01/14 23:04:56 steve
- * Generalize the evaluation of floating point delays, and
- * get it working with delay assignment statements.
- *
- * Allow parameters to be referenced by hierarchical name.
- *
- */
-
Please sign in to comment.
Something went wrong with that request. Please try again.