diff --git a/PExpr.cc b/PExpr.cc index 65d21c988..abc3c1000 100644 --- a/PExpr.cc +++ b/PExpr.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: PExpr.cc,v 1.8 1999/09/15 04:17:52 steve Exp $" +#ident "$Id: PExpr.cc,v 1.9 1999/09/16 04:18:15 steve Exp $" #endif # include "PExpr.h" @@ -62,7 +62,7 @@ bool PEBinary::is_constant(Module*mod) const bool PEConcat::is_constant(Module *mod) const { - bool constant = repeat_->is_constant(mod); + bool constant = repeat_? repeat_->is_constant(mod) : true; for (unsigned i = 0; constant && i < parms_.count(); ++i) { constant = constant && parms_[i]->is_constant(mod); } @@ -119,6 +119,9 @@ bool PETernary::is_constant(Module*) const /* * $Log: PExpr.cc,v $ + * Revision 1.9 1999/09/16 04:18:15 steve + * elaborate concatenation repeats. + * * Revision 1.8 1999/09/15 04:17:52 steve * separate assign lval elaboration for error checking. * diff --git a/elaborate.cc b/elaborate.cc index e54b7341f..862f4476c 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: elaborate.cc,v 1.87 1999/09/16 00:33:45 steve Exp $" +#ident "$Id: elaborate.cc,v 1.88 1999/09/16 04:18:15 steve Exp $" #endif /* @@ -1370,17 +1370,32 @@ NetExpr* PEBinary::elaborate_expr(Design*des, const string&path) const NetExpr* PEConcat::elaborate_expr(Design*des, const string&path) const { + unsigned repeat = 1; + + /* If there is a repeat expression, then evaluate the constant + value and set the repeat count. */ if (repeat_) { - cerr << get_line() << ": Sorry, I do not know how to" - " elaborate repeat concatenation expressions." << endl; - return 0; + verinum*vrep = repeat_->eval_const(des, path); + if (vrep == 0) { + cerr << get_line() << ": concatenation repeat expression" + " cannot be evaluated." << endl; + des->errors += 1; + return 0; + } + + repeat = vrep->as_ulong(); + delete vrep; } - NetEConcat*tmp = new NetEConcat(parms_.count()); + /* Make the empty concat expression. */ + NetEConcat*tmp = new NetEConcat(parms_.count(), repeat); tmp->set_line(*this); + /* Elaborate all the parameters and attach them to the concat node. */ for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) { assert(parms_[idx]); + NetExpr*ex = parms_[idx]->elaborate_expr(des, path); + if (ex == 0) continue; tmp->set(idx, parms_[idx]->elaborate_expr(des, path)); } @@ -2585,6 +2600,9 @@ Design* elaborate(const map&modules, /* * $Log: elaborate.cc,v $ + * Revision 1.88 1999/09/16 04:18:15 steve + * elaborate concatenation repeats. + * * Revision 1.87 1999/09/16 00:33:45 steve * Handle implicit !=0 in if statements. * diff --git a/eval.cc b/eval.cc index 7a72c1f57..ab8c21768 100644 --- a/eval.cc +++ b/eval.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: eval.cc,v 1.5 1999/08/06 04:05:28 steve Exp $" +#ident "$Id: eval.cc,v 1.6 1999/09/16 04:18:15 steve Exp $" #endif # include "PExpr.h" @@ -60,7 +60,11 @@ verinum* PEIdent::eval_const(const Design*des, const string&path) const { assert(msb_ == 0); const NetExpr*expr = des->find_parameter(path, text_); - if (expr == 0) return 0; + if (expr == 0) { + cerr << get_line() << ": unable to evaluate " << text_ << + " in this context (" << path << ")." << endl; + return 0; + } const NetEConst*eval = dynamic_cast(expr); assert(eval); return new verinum(eval->value()); @@ -79,6 +83,9 @@ verinum* PETernary::eval_const(const Design*, const string&) const /* * $Log: eval.cc,v $ + * Revision 1.6 1999/09/16 04:18:15 steve + * elaborate concatenation repeats. + * * Revision 1.5 1999/08/06 04:05:28 steve * Handle scope of parameters. * diff --git a/netlist.cc b/netlist.cc index ee9616871..9ba9ea073 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) -#ident "$Id: netlist.cc,v 1.63 1999/09/16 00:33:45 steve Exp $" +#ident "$Id: netlist.cc,v 1.64 1999/09/16 04:18:15 steve Exp $" #endif # include @@ -749,6 +749,22 @@ NetExpr* NetExpr::eval_tree() NetEBAdd::NetEBAdd(char op, NetExpr*l, NetExpr*r) : NetEBinary(op, l, r) { + if (l->expr_width() > r->expr_width()) + r->set_width(l->expr_width()); + + if (r->expr_width() > l->expr_width()) + l->set_width(r->expr_width()); + + if (l->expr_width() < r->expr_width()) + r->set_width(l->expr_width()); + + if (r->expr_width() < l->expr_width()) + l->set_width(r->expr_width()); + + if (r->expr_width() != l->expr_width()) + expr_width(0); + else + expr_width(l->expr_width()); } NetEBAdd::~NetEBAdd() @@ -834,8 +850,6 @@ NetEBinary::NetEBinary(char op, NetExpr*l, NetExpr*r) : op_(op), left_(l), right_(r) { switch (op_) { - case '+': - case '-': case '^': case '&': case '|': @@ -950,8 +964,8 @@ NetExpr* NetEBinary::eval_tree() } } -NetEConcat::NetEConcat(unsigned cnt) -: parms_(cnt) +NetEConcat::NetEConcat(unsigned cnt, unsigned r) +: parms_(cnt), repeat_(r) { expr_width(0); } @@ -970,12 +984,24 @@ void NetEConcat::set(unsigned idx, NetExpr*e) expr_width( expr_width() + e->expr_width() ); } +/* + * Add up the widths from all the expressions that are concatenated + * together. This is the width of the expression, tough luck if you + * want it otherwise. + * + * If during the course of elaboration one of the sub-expressions is + * broken, then don't count it in the width. This doesn't really + * matter because the null expression is indication of an error and + * the compiler will not go beyond elaboration. + */ bool NetEConcat::set_width(unsigned w) { unsigned sum = 0; for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) - sum += parms_[idx]->expr_width(); + if (parms_[idx] != 0) + sum += parms_[idx]->expr_width(); + sum *= repeat_; expr_width(sum); if (sum != w) return false; return true; @@ -983,7 +1009,16 @@ bool NetEConcat::set_width(unsigned w) NetEConcat* NetEConcat::dup_expr() const { - assert(0); + NetEConcat*dup = new NetEConcat(parms_.count()); + for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) + if (parms_[idx]) { + assert(parms_[idx]->dup_expr()); + dup->parms_[idx] = parms_[idx]->dup_expr(); + } + + + dup->expr_width(expr_width()); + return dup; } NetEConst::~NetEConst() @@ -1801,6 +1836,9 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*)) /* * $Log: netlist.cc,v $ + * Revision 1.64 1999/09/16 04:18:15 steve + * elaborate concatenation repeats. + * * Revision 1.63 1999/09/16 00:33:45 steve * Handle implicit !=0 in if statements. * diff --git a/netlist.h b/netlist.h index 9da622225..d1dc2e635 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) -#ident "$Id: netlist.h,v 1.64 1999/09/15 01:55:06 steve Exp $" +#ident "$Id: netlist.h,v 1.65 1999/09/16 04:18:15 steve Exp $" #endif /* @@ -1236,12 +1236,13 @@ class NetEBComp : public NetEBinary { class NetEConcat : public NetExpr { public: - NetEConcat(unsigned cnt); + NetEConcat(unsigned cnt, unsigned repeat =1); ~NetEConcat(); // Manipulate the parameters. void set(unsigned idx, NetExpr*e); + unsigned repeat() const { return repeat_; } unsigned nparms() const { return parms_.count() ; } NetExpr* parm(unsigned idx) const { return parms_[idx]; } @@ -1252,6 +1253,7 @@ class NetEConcat : public NetExpr { private: svectorparms_; + unsigned repeat_; }; class NetEConst : public NetExpr { @@ -1582,6 +1584,9 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.65 1999/09/16 04:18:15 steve + * elaborate concatenation repeats. + * * Revision 1.64 1999/09/15 01:55:06 steve * Elaborate non-blocking assignment to memories. * diff --git a/t-vvm.cc b/t-vvm.cc index 705d853f7..f38b6531e 100644 --- a/t-vvm.cc +++ b/t-vvm.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: t-vvm.cc,v 1.41 1999/09/11 04:43:17 steve Exp $" +#ident "$Id: t-vvm.cc,v 1.42 1999/09/16 04:18:15 steve Exp $" #endif # include @@ -129,6 +129,7 @@ class vvm_proc_rval : public expr_scan_t { void vvm_proc_rval::expr_concat(const NetEConcat*expr) { + assert(expr->repeat() == 1); string tname = make_temp(); os_ << setw(indent_) << "" << "vvm_bitset_t<" << expr->expr_width() << "> " << tname << ";" << endl; @@ -1441,6 +1442,9 @@ extern const struct target tgt_vvm = { }; /* * $Log: t-vvm.cc,v $ + * Revision 1.42 1999/09/16 04:18:15 steve + * elaborate concatenation repeats. + * * Revision 1.41 1999/09/11 04:43:17 steve * Support ternary and <= operators in vvm. *