diff --git a/eval_tree.cc b/eval_tree.cc index a8c597de6..5591e31a5 100644 --- a/eval_tree.cc +++ b/eval_tree.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: eval_tree.cc,v 1.31 2001/12/30 00:39:25 steve Exp $" +#ident "$Id: eval_tree.cc,v 1.32 2002/01/22 01:40:04 steve Exp $" #endif # include "config.h" @@ -758,6 +758,50 @@ NetEConst* NetEConcat::eval_tree() return res; } +/* + * There are limits to our ability to evaluate a memory reference + * expression, because the content of a memory is never + * constant. However, the index expression may be precalculated, and + * there are certain index values that do give us constant results. + */ +NetExpr* NetEMemory::eval_tree() +{ + /* Attempt to evaluate the index expression to a constant, if + it is not already. */ + if (idx_ && !dynamic_cast(idx_)) { + NetExpr* tmp = idx_->eval_tree(); + if (tmp) { + delete idx_; + idx_ = tmp; + } + } + + NetEConst*itmp = dynamic_cast(idx_); + if (itmp == 0) + return 0; + + verinum ival = itmp->value(); + + /* If the index expression has any x or z bits, then we know + already that the expression result is a constant x. */ + if (! ival.is_defined()) { + verinum xres (verinum::Vx, mem_->width(), false); + NetEConst*res = new NetEConst(xres); + return res; + } + + /* If the index expression is outside the range of the memory, + then the result is a constant x. */ + unsigned norm_idx = mem_->index_to_address(ival.as_long()); + if (norm_idx >= mem_->count()) { + verinum xres (verinum::Vx, mem_->width(), false); + NetEConst*res = new NetEConst(xres); + return res; + } + + return 0; +} + NetExpr* NetEParam::eval_tree() { if (des_ == 0) @@ -1019,6 +1063,9 @@ NetEConst* NetEUReduce::eval_tree() /* * $Log: eval_tree.cc,v $ + * Revision 1.32 2002/01/22 01:40:04 steve + * Precalculate constant results of memory index expressions. + * * Revision 1.31 2001/12/30 00:39:25 steve * Evaluate constant unary minus. * diff --git a/netlist.cc b/netlist.cc index e413b9326..a26237987 100644 --- a/netlist.cc +++ b/netlist.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: netlist.cc,v 1.179 2001/12/31 00:08:14 steve Exp $" +#ident "$Id: netlist.cc,v 1.180 2002/01/22 01:40:04 steve Exp $" #endif # include "config.h" @@ -2084,6 +2084,16 @@ NetEMemory::~NetEMemory() { } +const string& NetEMemory::name() const +{ + return mem_->name(); +} + +const NetExpr* NetEMemory::index() const +{ + return idx_; +} + NetMemory::NetMemory(NetScope*sc, const string&n, long w, long s, long e) : name_(n), width_(w), idxh_(s), idxl_(e), ram_list_(0), scope_(sc) { @@ -2405,6 +2415,9 @@ const NetProc*NetTaskDef::proc() const /* * $Log: netlist.cc,v $ + * Revision 1.180 2002/01/22 01:40:04 steve + * Precalculate constant results of memory index expressions. + * * Revision 1.179 2001/12/31 00:08:14 steve * Support $signed cast of expressions. * diff --git a/netlist.h b/netlist.h index 1addf73de..cfa989b6d 100644 --- a/netlist.h +++ b/netlist.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: netlist.h,v 1.229 2002/01/19 19:02:08 steve Exp $" +#ident "$Id: netlist.h,v 1.230 2002/01/22 01:40:04 steve Exp $" #endif /* @@ -2467,11 +2467,12 @@ class NetEMemory : public NetExpr { NetEMemory(NetMemory*mem, NetExpr*idx =0); virtual ~NetEMemory(); - const string& name () const { return mem_->name(); } - const NetExpr* index() const { return idx_; } + const string& name () const; + const NetExpr* index() const; virtual bool set_width(unsigned); + NetExpr* eval_tree(); virtual NetEMemory*dup_expr() const; virtual void expr_scan(struct expr_scan_t*) const; @@ -2864,6 +2865,9 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.230 2002/01/22 01:40:04 steve + * Precalculate constant results of memory index expressions. + * * Revision 1.229 2002/01/19 19:02:08 steve * Pass back target errors processing conditionals. *