Rewrite delay statement elaboration of handle real expressions.
This commit is contained in:
parent
f8d1e15a27
commit
55af069fe8
108
elaborate.cc
108
elaborate.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: elaborate.cc,v 1.271 2003/01/30 16:23:07 steve Exp $"
|
#ident "$Id: elaborate.cc,v 1.272 2003/02/07 02:49:24 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -1574,80 +1574,81 @@ NetProc* PDelayStatement::elaborate(Design*des, NetScope*scope) const
|
||||||
{
|
{
|
||||||
assert(scope);
|
assert(scope);
|
||||||
|
|
||||||
/* Catch the special case that the delay is given as a
|
NetExpr*dex = delay_->elaborate_expr(des, scope);
|
||||||
floating point number. In this case, we need to scale the
|
if (NetExpr*tmp = dex->eval_tree()) {
|
||||||
delay to the units of the design. */
|
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();
|
||||||
|
|
||||||
if (verireal*fn = delay_? delay_->eval_rconst(des, scope) : 0) {
|
|
||||||
int shift = scope->time_unit() - des->get_precision();
|
int shift = scope->time_unit() - des->get_precision();
|
||||||
|
long delay = fn.as_long(shift);
|
||||||
long delay = fn->as_long(shift);
|
|
||||||
if (delay < 0)
|
if (delay < 0)
|
||||||
delay = 0;
|
delay = 0;
|
||||||
|
|
||||||
delete fn;
|
delete tmp;
|
||||||
|
|
||||||
if (statement_)
|
if (statement_)
|
||||||
return new NetPDelay(delay, statement_->elaborate(des, scope));
|
return new NetPDelay(delay, statement_->elaborate(des, scope));
|
||||||
else
|
else
|
||||||
return new NetPDelay(delay, 0);
|
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)) {
|
||||||
|
verinum fn = tmp->value();
|
||||||
|
|
||||||
verinum*num = delay_->eval_const(des, scope);
|
unsigned long delay =
|
||||||
if (num == 0) {
|
des->scale_to_precision(fn.as_ulong(), scope);
|
||||||
/* Ah, the delay is not constant. OK, elaborate the
|
|
||||||
expression and let the run-time handle it. */
|
|
||||||
NetExpr*dex = delay_->elaborate_expr(des, scope);
|
|
||||||
|
|
||||||
/* If the local scope units are different from the
|
delete tmp;
|
||||||
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_)
|
if (statement_)
|
||||||
return new NetPDelay(dex, statement_->elaborate(des, scope));
|
return new NetPDelay(delay, statement_->elaborate(des, scope));
|
||||||
else
|
else
|
||||||
return new NetPDelay(dex, 0);
|
return new NetPDelay(delay, 0);
|
||||||
}
|
}
|
||||||
assert(num);
|
|
||||||
|
|
||||||
/* Convert the delay in the units of the scope to the
|
|
||||||
precision of the design as a whole. */
|
|
||||||
unsigned long val = des->scale_to_precision(num->as_ulong(), scope);
|
|
||||||
delete num;
|
|
||||||
|
|
||||||
/* If there is a statement, then elaborate it and create a
|
/* Ah well, the delay is not constant. OK, elaborate the
|
||||||
NetPDelay statement to contain it. Note that we create a
|
expression and let the run-time handle it. */
|
||||||
NetPDelay statement even if the value is 0 because #0 does
|
|
||||||
in fact have a well defined meaning in Verilog. */
|
|
||||||
|
|
||||||
if (statement_) {
|
|
||||||
NetProc*stmt = statement_->elaborate(des, scope);
|
|
||||||
return new NetPDelay(val, stmt);
|
|
||||||
|
|
||||||
} else {
|
/* If the local scope units are different from the
|
||||||
return new NetPDelay(val, 0);
|
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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -2507,6 +2508,9 @@ Design* elaborate(list<const char*>roots)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: elaborate.cc,v $
|
* $Log: elaborate.cc,v $
|
||||||
|
* Revision 1.272 2003/02/07 02:49:24 steve
|
||||||
|
* Rewrite delay statement elaboration of handle real expressions.
|
||||||
|
*
|
||||||
* Revision 1.271 2003/01/30 16:23:07 steve
|
* Revision 1.271 2003/01/30 16:23:07 steve
|
||||||
* Spelling fixes.
|
* Spelling fixes.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue