From 1a21d2fe9db066b8dff07686b8831a8488272c2b Mon Sep 17 00:00:00 2001 From: steve Date: Thu, 23 Sep 1999 03:56:57 +0000 Subject: [PATCH] Support shift operators. --- elaborate.cc | 11 ++++++++++- eval_tree.cc | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- netlist.cc | 15 ++++++++++++++- netlist.h | 25 ++++++++++++++++++++++++- set_width.cc | 17 ++++++++++++++++- t-vvm.cc | 17 +++++++++++++++-- 6 files changed, 128 insertions(+), 7 deletions(-) diff --git a/elaborate.cc b/elaborate.cc index ba341ecd7..87fcb0f5c 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.98 1999/09/23 02:28:27 steve Exp $" +#ident "$Id: elaborate.cc,v 1.99 1999/09/23 03:56:57 steve Exp $" #endif /* @@ -1339,6 +1339,12 @@ NetExpr* PEBinary::elaborate_expr(Design*des, const string&path) const tmp->set_line(*this); break; + case 'l': + case 'r': + tmp = new NetEBShift(op_, lp, rp); + tmp->set_line(*this); + break; + case '^': case '&': case '|': @@ -2631,6 +2637,9 @@ Design* elaborate(const map&modules, /* * $Log: elaborate.cc,v $ + * Revision 1.99 1999/09/23 03:56:57 steve + * Support shift operators. + * * Revision 1.98 1999/09/23 02:28:27 steve * internal error message for funky comparison width. * diff --git a/eval_tree.cc b/eval_tree.cc index 2ce28b989..a16dbc71f 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) -#ident "$Id: eval_tree.cc,v 1.3 1999/09/23 00:21:54 steve Exp $" +#ident "$Id: eval_tree.cc,v 1.4 1999/09/23 03:56:57 steve Exp $" #endif # include "netlist.h" @@ -108,9 +108,54 @@ NetExpr* NetEBComp::eval_tree() NetExpr* NetEBLogic::eval_tree() { + eval_sub_tree_(); return 0; } +/* + * Evaluate the shift operator if possible. For this to work, both + * operands must be constant. + */ +NetExpr* NetEBShift::eval_tree() +{ + eval_sub_tree_(); + NetEConst*re = dynamic_cast(right_); + if (re == 0) + return 0; + + NetEConst*le = dynamic_cast(left_); + if (le == 0) + return 0; + + NetEConst*res; + + verinum rv = re->value(); + verinum lv = le->value(); + if (rv.is_defined()) { + + unsigned wid = expr_width(); + unsigned shift = rv.as_ulong(); + + verinum nv (verinum::V0, wid); + + if (op() == 'r') + for (unsigned idx = 0 ; idx < (wid-shift) ; idx += 1) + nv.set(idx, lv[idx+shift]); + + else + for (unsigned idx = 0 ; idx < (wid-shift) ; idx += 1) + nv.set(idx+shift, lv[idx]); + + res = new NetEConst(nv); + + } else { + verinum nv (verinum::Vx, expr_width()); + res = new NetEConst(nv); + } + + return res; +} + NetExpr* NetEConcat::eval_tree() { for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) { @@ -191,6 +236,9 @@ NetExpr* NetEParam::eval_tree() /* * $Log: eval_tree.cc,v $ + * Revision 1.4 1999/09/23 03:56:57 steve + * Support shift operators. + * * Revision 1.3 1999/09/23 00:21:54 steve * Move set_width methods into a single file, * Add the NetEBLogic class for logic expressions, diff --git a/netlist.cc b/netlist.cc index 327d2524b..a4cf7dd86 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.68 1999/09/23 00:21:54 steve Exp $" +#ident "$Id: netlist.cc,v 1.69 1999/09/23 03:56:57 steve Exp $" #endif # include @@ -819,6 +819,16 @@ NetEBLogic::~NetEBLogic() { } +NetEBShift::NetEBShift(char op, NetExpr*l, NetExpr*r) +: NetEBinary(op, l, r) +{ + expr_width(l->expr_width()); +} + +NetEBShift::~NetEBShift() +{ +} + NetEConcat::NetEConcat(unsigned cnt, unsigned r) : parms_(cnt), repeat_(r) { @@ -1621,6 +1631,9 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*)) /* * $Log: netlist.cc,v $ + * Revision 1.69 1999/09/23 03:56:57 steve + * Support shift operators. + * * Revision 1.68 1999/09/23 00:21:54 steve * Move set_width methods into a single file, * Add the NetEBLogic class for logic expressions, diff --git a/netlist.h b/netlist.h index 9ab93ca6c..e16522388 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.70 1999/09/23 00:21:55 steve Exp $" +#ident "$Id: netlist.h,v 1.71 1999/09/23 03:56:57 steve Exp $" #endif /* @@ -1249,6 +1249,26 @@ class NetEBLogic : public NetEBinary { }; +/* + * The binary logical operators are those that return boolean + * results. The supported operators are: + * + * l -- left shift (<<) + * r -- right shift (>>) + */ +class NetEBShift : public NetEBinary { + + public: + NetEBShift(char op, NetExpr*l, NetExpr*r); + ~NetEBShift(); + + virtual bool set_width(unsigned w); + virtual NetExpr* eval_tree(); + + private: +}; + + /* * This expression node supports the concat expression. This is an * operator that just glues the results of many expressions into a @@ -1637,6 +1657,9 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.71 1999/09/23 03:56:57 steve + * Support shift operators. + * * Revision 1.70 1999/09/23 00:21:55 steve * Move set_width methods into a single file, * Add the NetEBLogic class for logic expressions, diff --git a/set_width.cc b/set_width.cc index 573f0fe65..5f05e6792 100644 --- a/set_width.cc +++ b/set_width.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: set_width.cc,v 1.2 1999/09/23 02:27:50 steve Exp $" +#ident "$Id: set_width.cc,v 1.3 1999/09/23 03:56:57 steve Exp $" #endif /* @@ -128,6 +128,18 @@ bool NetEBLogic::set_width(unsigned w) return (w == 1); } +/* + * The shift operator allows the shift amount to have its own + * natural width. The width of the operator result is the width of the + * left operand, the value that is to be shifted. + */ +bool NetEBShift::set_width(unsigned w) +{ + bool flag; + flag = left_->set_width(w); + return flag; +} + /* * Add up the widths from all the expressions that are concatenated * together. This is the width of the expression, tough luck if you @@ -239,6 +251,9 @@ bool NetEUnary::set_width(unsigned w) /* * $Log: set_width.cc,v $ + * Revision 1.3 1999/09/23 03:56:57 steve + * Support shift operators. + * * Revision 1.2 1999/09/23 02:27:50 steve * comparison parameter width is self determined. * diff --git a/t-vvm.cc b/t-vvm.cc index 924f1ec4c..2eea5442b 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.44 1999/09/22 16:57:24 steve Exp $" +#ident "$Id: t-vvm.cc,v 1.45 1999/09/23 03:56:57 steve Exp $" #endif # include @@ -286,6 +286,8 @@ void vvm_proc_rval::expr_unary(const NetEUnary*expr) default: cerr << "vvm: Unhandled unary op `" << expr->op() << "'" << endl; + os_ << "#error \"" << expr->get_line() << ": vvm error: " + "Unhandled unary op: " << *expr << "\"" << endl; os_ << result << ";" << endl; break; } @@ -317,6 +319,10 @@ void vvm_proc_rval::expr_binary(const NetEBinary*expr) os_ << setw(indent_) << "" << result << " = vvm_binop_eq(" << lres << "," << rres << ");" << endl; break; + case 'l': // left shift(<<) + os_ << setw(indent_) << "" << result << " = vvm_binop_shiftl(" + << lres << "," << rres << ");" << endl; + break; case 'L': // <= os_ << setw(indent_) << "" << result << " = vvm_binop_le(" << lres << "," << rres << ");" << endl; @@ -336,6 +342,9 @@ void vvm_proc_rval::expr_binary(const NetEBinary*expr) case 'o': // logical or (||) os_ << setw(indent_) << "" << result << " = vvm_binop_lor(" << lres << "," << rres << ");" << endl; + case 'r': // right shift(>>) + os_ << setw(indent_) << "" << result << " = vvm_binop_shiftr(" + << lres << "," << rres << ");" << endl; break; case '+': os_ << setw(indent_) << "" << result << " = vvm_binop_plus(" @@ -360,7 +369,8 @@ void vvm_proc_rval::expr_binary(const NetEBinary*expr) default: cerr << "vvm: Unhandled binary op `" << expr->op() << "': " << *expr << endl; - os_ << lres << ";" << endl; + os_ << "#error \"" << expr->get_line() << ": vvm error: " + "Unhandled binary op: " << *expr << "\"" << endl; result = lres; break; } @@ -1448,6 +1458,9 @@ extern const struct target tgt_vvm = { }; /* * $Log: t-vvm.cc,v $ + * Revision 1.45 1999/09/23 03:56:57 steve + * Support shift operators. + * * Revision 1.44 1999/09/22 16:57:24 steve * Catch parallel blocks in vvm emit. *