Calculate delay statement delays using elaborated
expressions instead of pre-elaborated expression trees. Remove the eval_pexpr methods from PExpr.
This commit is contained in:
parent
26b755d544
commit
e571dd90d8
|
|
@ -16,7 +16,7 @@
|
||||||
# 59 Temple Place - Suite 330
|
# 59 Temple Place - Suite 330
|
||||||
# Boston, MA 02111-1307, USA
|
# 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
|
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 \
|
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_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 \
|
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 \
|
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 \
|
net_design.o net_event.o net_expr.o net_force.o net_func.o \
|
||||||
|
|
|
||||||
72
PDelays.cc
72
PDelays.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#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
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -62,34 +62,51 @@ void PDelays::set_delays(const svector<PExpr*>*del, bool df)
|
||||||
delete_flag_ = 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)
|
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()) {
|
||||||
if (verireal*dr = expr->eval_rconst(des, scope)) {
|
delete dex;
|
||||||
val = dr->as_long(shift);
|
dex = tmp;
|
||||||
delete dr;
|
|
||||||
|
|
||||||
} 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(dv);
|
|
||||||
val = dv->as_ulong();
|
|
||||||
val = des->scale_to_precision(val, scope);
|
|
||||||
delete dv;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return val;
|
/* 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. */
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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,
|
void PDelays::eval_delays(Design*des, NetScope*scope,
|
||||||
|
|
@ -131,6 +148,13 @@ void PDelays::eval_delays(Design*des, NetScope*scope,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: PDelays.cc,v $
|
* $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
|
* Revision 1.9 2002/08/12 01:34:58 steve
|
||||||
* conditional ident string using autoconfig.
|
* conditional ident string using autoconfig.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
21
PExpr.h
21
PExpr.h
|
|
@ -19,13 +19,12 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#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
|
#endif
|
||||||
|
|
||||||
# include <string>
|
# include <string>
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
# include "verinum.h"
|
# include "verinum.h"
|
||||||
# include "verireal.h"
|
|
||||||
# include "LineInfo.h"
|
# include "LineInfo.h"
|
||||||
|
|
||||||
class Design;
|
class Design;
|
||||||
|
|
@ -92,11 +91,6 @@ class PExpr : public LineInfo {
|
||||||
// evaluated, return 0.
|
// evaluated, return 0.
|
||||||
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
|
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 method returns true if that expression is the same as
|
||||||
// this expression. This method is used for comparing
|
// this expression. This method is used for comparing
|
||||||
// expressions that must be structurally "identical".
|
// expressions that must be structurally "identical".
|
||||||
|
|
@ -190,9 +184,6 @@ class PEFNumber : public PExpr {
|
||||||
any rounding that is needed to get the value. */
|
any rounding that is needed to get the value. */
|
||||||
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
|
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. */
|
/* A PEFNumber is a constant, so this returns true. */
|
||||||
virtual bool is_constant(Module*) const;
|
virtual bool is_constant(Module*) const;
|
||||||
|
|
||||||
|
|
@ -243,7 +234,6 @@ class PEIdent : public PExpr {
|
||||||
|
|
||||||
virtual bool is_constant(Module*) const;
|
virtual bool is_constant(Module*) const;
|
||||||
verinum* eval_const(const Design*des, const NetScope*sc) 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;
|
const hname_t& path() const;
|
||||||
|
|
||||||
|
|
@ -301,7 +291,6 @@ class PENumber : public PExpr {
|
||||||
virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope) const;
|
virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope) const;
|
||||||
|
|
||||||
virtual verinum* eval_const(const Design*des, const NetScope*sc) 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_the_same(const PExpr*that) const;
|
||||||
virtual bool is_constant(Module*) const;
|
virtual bool is_constant(Module*) const;
|
||||||
|
|
@ -389,7 +378,6 @@ class PEBinary : public PExpr {
|
||||||
bool sys_task_arg =false) const;
|
bool sys_task_arg =false) const;
|
||||||
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
|
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
|
||||||
virtual verinum* eval_const(const Design*des, const 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:
|
private:
|
||||||
char op_;
|
char op_;
|
||||||
|
|
@ -504,6 +492,13 @@ class PECallFunction : public PExpr {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: PExpr.h,v $
|
* $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
|
* Revision 1.64 2003/01/30 16:23:07 steve
|
||||||
* Spelling fixes.
|
* Spelling fixes.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
139
elaborate.cc
139
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
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* 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
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#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
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# 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)
|
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();
|
int shift = scope->time_unit() - des->get_precision();
|
||||||
long val = dr->as_long(shift);
|
long delay = fn.as_long(shift);
|
||||||
delete dr;
|
if (delay < 0)
|
||||||
return new NetEConst(verinum(val));
|
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();
|
int shift = scope->time_unit() - des->get_precision();
|
||||||
if (shift > 0) {
|
if (shift > 0) {
|
||||||
unsigned long scale = 1;
|
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));
|
NetExpr*scal_val = new NetEConst(verinum(scale));
|
||||||
delay = new NetEBMult('*', delay, scal_val);
|
dex = new NetEBMult('*', dex, scal_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shift < 0) {
|
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));
|
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
|
NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
|
||||||
|
|
@ -1574,81 +1594,27 @@ NetProc* PDelayStatement::elaborate(Design*des, NetScope*scope) const
|
||||||
{
|
{
|
||||||
assert(scope);
|
assert(scope);
|
||||||
|
|
||||||
NetExpr*dex = delay_->elaborate_expr(des, scope);
|
/* This call evaluates the delay expression to a NetEConst, if
|
||||||
if (NetExpr*tmp = dex->eval_tree()) {
|
possible. This includes transforming NetECReal values to
|
||||||
delete dex;
|
integers, and applying the proper scaling. */
|
||||||
dex = tmp;
|
NetExpr*dex = elaborate_delay_expr(delay_, des, scope);
|
||||||
}
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
|
|
||||||
if (statement_)
|
|
||||||
return new NetPDelay(delay, statement_->elaborate(des, scope));
|
|
||||||
else
|
|
||||||
return new NetPDelay(delay, 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)) {
|
if (NetEConst*tmp = dynamic_cast<NetEConst*>(dex)) {
|
||||||
verinum fn = tmp->value();
|
|
||||||
|
|
||||||
unsigned long delay =
|
|
||||||
des->scale_to_precision(fn.as_ulong(), scope);
|
|
||||||
|
|
||||||
delete tmp;
|
|
||||||
|
|
||||||
if (statement_)
|
if (statement_)
|
||||||
return new NetPDelay(delay, statement_->elaborate(des, scope));
|
return new NetPDelay(tmp->value().as_ulong(),
|
||||||
|
statement_->elaborate(des, scope));
|
||||||
else
|
else
|
||||||
return new NetPDelay(delay, 0);
|
return new NetPDelay(tmp->value().as_ulong(), 0);
|
||||||
|
|
||||||
|
delete dex;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (statement_)
|
||||||
|
return new NetPDelay(dex, statement_->elaborate(des, scope));
|
||||||
|
else
|
||||||
|
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 $
|
* $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
|
* Revision 1.272 2003/02/07 02:49:24 steve
|
||||||
* Rewrite delay statement elaboration of handle real expressions.
|
* Rewrite delay statement elaboration of handle real expressions.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
127
eval_rconst.cc
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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
Loading…
Reference in New Issue