Support shift operators.

This commit is contained in:
steve 1999-09-23 03:56:57 +00:00
parent 095995f09c
commit 1a21d2fe9d
6 changed files with 128 additions and 7 deletions

View File

@ -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<string,Module*>&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.
*

View File

@ -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<NetEConst*>(right_);
if (re == 0)
return 0;
NetEConst*le = dynamic_cast<NetEConst*>(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,

View File

@ -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 <cassert>
@ -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,

View File

@ -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,

View File

@ -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.
*

View File

@ -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 <iostream>
@ -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.
*