Move set_width methods into a single file,
Add the NetEBLogic class for logic expressions, Fix error setting with of && in if statements.
This commit is contained in:
parent
59b1b4c7b9
commit
1c41f8ebd2
|
|
@ -18,7 +18,7 @@
|
||||||
# 59 Temple Place - Suite 330
|
# 59 Temple Place - Suite 330
|
||||||
# Boston, MA 02111-1307, USA
|
# Boston, MA 02111-1307, USA
|
||||||
#
|
#
|
||||||
#ident "$Id: Makefile.in,v 1.17 1999/09/20 02:21:10 steve Exp $"
|
#ident "$Id: Makefile.in,v 1.18 1999/09/23 00:21:54 steve Exp $"
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
SHELL = /bin/sh
|
SHELL = /bin/sh
|
||||||
|
|
@ -63,6 +63,7 @@ FF = nobufz.o propinit.o sigfold.o xnfio.o xnfsyn.o
|
||||||
O = main.o cprop.o design_dump.o elaborate.o elab_expr.o emit.o eval.o \
|
O = main.o cprop.o design_dump.o elaborate.o elab_expr.o emit.o eval.o \
|
||||||
eval_tree.o functor.o \
|
eval_tree.o functor.o \
|
||||||
lexor.o mangle.o netlist.o parse.o parse_misc.o pform.o pform_dump.o \
|
lexor.o mangle.o netlist.o parse.o parse_misc.o pform.o pform_dump.o \
|
||||||
|
set_width.o \
|
||||||
verinum.o verireal.o target.o targets.o Module.o PDelays.o PExpr.o PGate.o \
|
verinum.o verireal.o target.o targets.o Module.o PDelays.o PExpr.o PGate.o \
|
||||||
PTask.o PFunction.o PWire.o Statement.o \
|
PTask.o PFunction.o PWire.o Statement.o \
|
||||||
$(FF) $(TT)
|
$(FF) $(TT)
|
||||||
|
|
|
||||||
13
elaborate.cc
13
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
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: elaborate.cc,v 1.96 1999/09/22 21:25:42 steve Exp $"
|
#ident "$Id: elaborate.cc,v 1.97 1999/09/23 00:21:54 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -1333,6 +1333,12 @@ NetExpr* PEBinary::elaborate_expr(Design*des, const string&path) const
|
||||||
tmp->set_line(*this);
|
tmp->set_line(*this);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'a':
|
||||||
|
case 'o':
|
||||||
|
tmp = new NetEBLogic(op_, lp, rp);
|
||||||
|
tmp->set_line(*this);
|
||||||
|
break;
|
||||||
|
|
||||||
case '^':
|
case '^':
|
||||||
case '&':
|
case '&':
|
||||||
case '|':
|
case '|':
|
||||||
|
|
@ -2625,6 +2631,11 @@ Design* elaborate(const map<string,Module*>&modules,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: elaborate.cc,v $
|
* $Log: elaborate.cc,v $
|
||||||
|
* Revision 1.97 1999/09/23 00:21:54 steve
|
||||||
|
* Move set_width methods into a single file,
|
||||||
|
* Add the NetEBLogic class for logic expressions,
|
||||||
|
* Fix error setting with of && in if statements.
|
||||||
|
*
|
||||||
* Revision 1.96 1999/09/22 21:25:42 steve
|
* Revision 1.96 1999/09/22 21:25:42 steve
|
||||||
* Expand bits in delayed assignments.
|
* Expand bits in delayed assignments.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
12
eval_tree.cc
12
eval_tree.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
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: eval_tree.cc,v 1.2 1999/09/21 00:13:40 steve Exp $"
|
#ident "$Id: eval_tree.cc,v 1.3 1999/09/23 00:21:54 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
|
|
@ -106,6 +106,11 @@ NetExpr* NetEBComp::eval_tree()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NetExpr* NetEBLogic::eval_tree()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
NetExpr* NetEConcat::eval_tree()
|
NetExpr* NetEConcat::eval_tree()
|
||||||
{
|
{
|
||||||
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
|
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
|
||||||
|
|
@ -186,6 +191,11 @@ NetExpr* NetEParam::eval_tree()
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: eval_tree.cc,v $
|
* $Log: eval_tree.cc,v $
|
||||||
|
* 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,
|
||||||
|
* Fix error setting with of && in if statements.
|
||||||
|
*
|
||||||
* Revision 1.2 1999/09/21 00:13:40 steve
|
* Revision 1.2 1999/09/21 00:13:40 steve
|
||||||
* Support parameters that reference other paramters.
|
* Support parameters that reference other paramters.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
225
netlist.cc
225
netlist.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
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: netlist.cc,v 1.67 1999/09/21 00:13:40 steve Exp $"
|
#ident "$Id: netlist.cc,v 1.68 1999/09/23 00:21:54 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include <cassert>
|
# include <cassert>
|
||||||
|
|
@ -703,17 +703,6 @@ const NetFuncDef* NetEUFunc::definition() const
|
||||||
return func_;
|
return func_;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* XXXX FIX ME: For now, just take whatever the caller says as my
|
|
||||||
* width. What I really need to do is note the width of the output
|
|
||||||
* parameter of the function definition and take that into account.
|
|
||||||
*/
|
|
||||||
bool NetEUFunc::set_width(unsigned wid)
|
|
||||||
{
|
|
||||||
expr_width(wid);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetEUFunc* NetEUFunc::dup_expr() const
|
NetEUFunc* NetEUFunc::dup_expr() const
|
||||||
{
|
{
|
||||||
assert(0);
|
assert(0);
|
||||||
|
|
@ -738,14 +727,6 @@ NetExpr::~NetExpr()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NetExpr::set_width(unsigned w)
|
|
||||||
{
|
|
||||||
cerr << typeid(*this).name() << ": set_width(unsigned) "
|
|
||||||
"not implemented." << endl;
|
|
||||||
expr_width(w);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetEBAdd::NetEBAdd(char op, NetExpr*l, NetExpr*r)
|
NetEBAdd::NetEBAdd(char op, NetExpr*l, NetExpr*r)
|
||||||
: NetEBinary(op, l, r)
|
: NetEBinary(op, l, r)
|
||||||
{
|
{
|
||||||
|
|
@ -771,29 +752,6 @@ NetEBAdd::~NetEBAdd()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* The bitwise logical operators have operands the same size as the
|
|
||||||
* result. Anything else is a mess.
|
|
||||||
*/
|
|
||||||
bool NetEBAdd::set_width(unsigned w)
|
|
||||||
{
|
|
||||||
bool flag = true;
|
|
||||||
|
|
||||||
if (left_->expr_width() > right_->expr_width())
|
|
||||||
right_->set_width(left_->expr_width());
|
|
||||||
else
|
|
||||||
left_->set_width(right_->expr_width());
|
|
||||||
|
|
||||||
if (left_->expr_width() == w)
|
|
||||||
expr_width(w);
|
|
||||||
else if (left_->expr_width() == (w-1))
|
|
||||||
expr_width(w);
|
|
||||||
else
|
|
||||||
flag = false;
|
|
||||||
|
|
||||||
return flag;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetEBBits::NetEBBits(char op, NetExpr*l, NetExpr*r)
|
NetEBBits::NetEBBits(char op, NetExpr*l, NetExpr*r)
|
||||||
: NetEBinary(op, l, r)
|
: NetEBinary(op, l, r)
|
||||||
{
|
{
|
||||||
|
|
@ -803,21 +761,6 @@ NetEBBits::~NetEBBits()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* The bitwise logical operators have operands the same size as the
|
|
||||||
* result. Anything else is a mess.
|
|
||||||
*/
|
|
||||||
bool NetEBBits::set_width(unsigned w)
|
|
||||||
{
|
|
||||||
bool flag = true;
|
|
||||||
|
|
||||||
flag = left_->set_width(w) && flag;
|
|
||||||
flag = right_->set_width(w) && flag;
|
|
||||||
expr_width(w);
|
|
||||||
|
|
||||||
return flag;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetEBComp::NetEBComp(char op, NetExpr*l, NetExpr*r)
|
NetEBComp::NetEBComp(char op, NetExpr*l, NetExpr*r)
|
||||||
: NetEBinary(op, l, r)
|
: NetEBinary(op, l, r)
|
||||||
{
|
{
|
||||||
|
|
@ -828,24 +771,6 @@ NetEBComp::~NetEBComp()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Comparison operators allow the subexpressions to have
|
|
||||||
* their own natural width. However, I do need to make
|
|
||||||
* sure that the subexpressions have the same width.
|
|
||||||
*/
|
|
||||||
bool NetEBComp::set_width(unsigned w)
|
|
||||||
{
|
|
||||||
bool flag = true;
|
|
||||||
|
|
||||||
assert(w == 1);
|
|
||||||
expr_width(w);
|
|
||||||
flag = left_->set_width(right_->expr_width());
|
|
||||||
if (!flag)
|
|
||||||
flag = right_->set_width(left_->expr_width());
|
|
||||||
|
|
||||||
return flag;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetEBinary::NetEBinary(char op, NetExpr*l, NetExpr*r)
|
NetEBinary::NetEBinary(char op, NetExpr*l, NetExpr*r)
|
||||||
: op_(op), left_(l), right_(r)
|
: op_(op), left_(l), right_(r)
|
||||||
{
|
{
|
||||||
|
|
@ -879,47 +804,21 @@ NetEBinary::~NetEBinary()
|
||||||
delete right_;
|
delete right_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NetEBinary::set_width(unsigned w)
|
|
||||||
{
|
|
||||||
bool flag = true;
|
|
||||||
switch (op_) {
|
|
||||||
case 'a': // logical and (&&)
|
|
||||||
case 'o': // logical or (||)
|
|
||||||
expr_width(1);
|
|
||||||
flag = false;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'l': // left shift (<<)
|
|
||||||
case 'r': // right shift (>>)
|
|
||||||
flag = left_->set_width(w);
|
|
||||||
expr_width(w);
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* The default rule is that the operands of the binary
|
|
||||||
operator might as well use the same width as the
|
|
||||||
output from the binary operation. */
|
|
||||||
default:
|
|
||||||
expr_width(left_->expr_width() > right_->expr_width()
|
|
||||||
? left_->expr_width() : right_->expr_width());
|
|
||||||
cerr << "NetEBinary::set_width(): Using default for " <<
|
|
||||||
op_ << "." << endl;
|
|
||||||
flag = false;
|
|
||||||
|
|
||||||
case '%':
|
|
||||||
case '/':
|
|
||||||
flag = left_->set_width(w) && flag;
|
|
||||||
flag = right_->set_width(w) && flag;
|
|
||||||
expr_width(w);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return flag;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetEBinary* NetEBinary::dup_expr() const
|
NetEBinary* NetEBinary::dup_expr() const
|
||||||
{
|
{
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NetEBLogic::NetEBLogic(char op, NetExpr*l, NetExpr*r)
|
||||||
|
: NetEBinary(op, l, r)
|
||||||
|
{
|
||||||
|
expr_width(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetEBLogic::~NetEBLogic()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
NetEConcat::NetEConcat(unsigned cnt, unsigned r)
|
NetEConcat::NetEConcat(unsigned cnt, unsigned r)
|
||||||
: parms_(cnt), repeat_(r)
|
: parms_(cnt), repeat_(r)
|
||||||
{
|
{
|
||||||
|
|
@ -940,29 +839,6 @@ void NetEConcat::set(unsigned idx, NetExpr*e)
|
||||||
expr_width( expr_width() + repeat_*e->expr_width() );
|
expr_width( expr_width() + repeat_*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)
|
|
||||||
if (parms_[idx] != 0)
|
|
||||||
sum += parms_[idx]->expr_width();
|
|
||||||
|
|
||||||
sum *= repeat_;
|
|
||||||
expr_width(sum);
|
|
||||||
if (sum != w) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetEConcat* NetEConcat::dup_expr() const
|
NetEConcat* NetEConcat::dup_expr() const
|
||||||
{
|
{
|
||||||
NetEConcat*dup = new NetEConcat(parms_.count(), repeat_);
|
NetEConcat*dup = new NetEConcat(parms_.count(), repeat_);
|
||||||
|
|
@ -986,17 +862,6 @@ NetEConst::~NetEConst()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NetEConst::set_width(unsigned w)
|
|
||||||
{
|
|
||||||
if (w > value_.len())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
assert(w <= value_.len());
|
|
||||||
value_ = verinum(value_, w);
|
|
||||||
expr_width(w);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetEConst* NetEConst::dup_expr() const
|
NetEConst* NetEConst::dup_expr() const
|
||||||
{
|
{
|
||||||
NetEConst*tmp = new NetEConst(value_);
|
NetEConst*tmp = new NetEConst(value_);
|
||||||
|
|
@ -1046,15 +911,6 @@ void NetMemory::set_attributes(const map<string,string>&attr)
|
||||||
attributes_ = attr;
|
attributes_ = attr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NetEMemory::set_width(unsigned w)
|
|
||||||
{
|
|
||||||
if (w != mem_->width())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
expr_width(w);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetEMemory* NetEMemory::dup_expr() const
|
NetEMemory* NetEMemory::dup_expr() const
|
||||||
{
|
{
|
||||||
assert(0);
|
assert(0);
|
||||||
|
|
@ -1074,11 +930,6 @@ NetEParam::~NetEParam()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NetEParam::set_width(unsigned)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetEParam* NetEParam::dup_expr() const
|
NetEParam* NetEParam::dup_expr() const
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -1103,18 +954,6 @@ NetESignal::~NetESignal()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* The signal should automatically pad with zeros to get to th desired
|
|
||||||
* width. Do not allow signal bits to be truncated, however.
|
|
||||||
*/
|
|
||||||
bool NetESignal::set_width(unsigned w)
|
|
||||||
{
|
|
||||||
if (w != pin_count())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetESignal* NetESignal::dup_expr() const
|
NetESignal* NetESignal::dup_expr() const
|
||||||
{
|
{
|
||||||
assert(0);
|
assert(0);
|
||||||
|
|
@ -1138,12 +977,6 @@ NetESubSignal* NetESubSignal::dup_expr() const
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NetESubSignal::set_width(unsigned w)
|
|
||||||
{
|
|
||||||
if (w != 1) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetETernary::NetETernary(NetExpr*c, NetExpr*t, NetExpr*f)
|
NetETernary::NetETernary(NetExpr*c, NetExpr*t, NetExpr*f)
|
||||||
: cond_(c), true_val_(t), false_val_(f)
|
: cond_(c), true_val_(t), false_val_(f)
|
||||||
{
|
{
|
||||||
|
|
@ -1177,42 +1010,11 @@ NetETernary* NetETernary::dup_expr() const
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NetETernary::set_width(unsigned w)
|
|
||||||
{
|
|
||||||
bool flag = true;
|
|
||||||
flag = flag && true_val_->set_width(w);
|
|
||||||
flag = flag && false_val_->set_width(w);
|
|
||||||
expr_width(true_val_->expr_width());
|
|
||||||
return flag;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetEUnary::~NetEUnary()
|
NetEUnary::~NetEUnary()
|
||||||
{
|
{
|
||||||
delete expr_;
|
delete expr_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NetEUnary::set_width(unsigned w)
|
|
||||||
{
|
|
||||||
bool flag = true;
|
|
||||||
switch (op_) {
|
|
||||||
case '~':
|
|
||||||
case '-':
|
|
||||||
flag = expr_->set_width(w);
|
|
||||||
break;
|
|
||||||
case '&':
|
|
||||||
case '!':
|
|
||||||
if (w != 1) {
|
|
||||||
flag = false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
flag = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
expr_width(w);
|
|
||||||
return flag;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetEUnary* NetEUnary::dup_expr() const
|
NetEUnary* NetEUnary::dup_expr() const
|
||||||
{
|
{
|
||||||
assert(0);
|
assert(0);
|
||||||
|
|
@ -1819,6 +1621,11 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: netlist.cc,v $
|
* $Log: netlist.cc,v $
|
||||||
|
* 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,
|
||||||
|
* Fix error setting with of && in if statements.
|
||||||
|
*
|
||||||
* Revision 1.67 1999/09/21 00:13:40 steve
|
* Revision 1.67 1999/09/21 00:13:40 steve
|
||||||
* Support parameters that reference other paramters.
|
* Support parameters that reference other paramters.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
26
netlist.h
26
netlist.h
|
|
@ -19,7 +19,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
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: netlist.h,v 1.69 1999/09/22 16:57:23 steve Exp $"
|
#ident "$Id: netlist.h,v 1.70 1999/09/23 00:21:55 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -1230,6 +1230,25 @@ class NetEBComp : public NetEBinary {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The binary logical operators are those that return boolean
|
||||||
|
* results. The supported operators are:
|
||||||
|
*
|
||||||
|
* a -- Logical AND (&&)
|
||||||
|
*/
|
||||||
|
class NetEBLogic : public NetEBinary {
|
||||||
|
|
||||||
|
public:
|
||||||
|
NetEBLogic(char op, NetExpr*l, NetExpr*r);
|
||||||
|
~NetEBLogic();
|
||||||
|
|
||||||
|
virtual bool set_width(unsigned w);
|
||||||
|
virtual NetExpr* eval_tree();
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This expression node supports the concat expression. This is an
|
* This expression node supports the concat expression. This is an
|
||||||
* operator that just glues the results of many expressions into a
|
* operator that just glues the results of many expressions into a
|
||||||
|
|
@ -1618,6 +1637,11 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: netlist.h,v $
|
* $Log: netlist.h,v $
|
||||||
|
* 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,
|
||||||
|
* Fix error setting with of && in if statements.
|
||||||
|
*
|
||||||
* Revision 1.69 1999/09/22 16:57:23 steve
|
* Revision 1.69 1999/09/22 16:57:23 steve
|
||||||
* Catch parallel blocks in vvm emit.
|
* Catch parallel blocks in vvm emit.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,255 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1999 Stephen Williams (steve@icarus.com)
|
||||||
|
*
|
||||||
|
* This source code is free software; you can redistribute it
|
||||||
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
* General Public License as published by the Free Software
|
||||||
|
* Foundation; either version 2 of the License, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
|
#if !defined(WINNT)
|
||||||
|
#ident "$Id: set_width.cc,v 1.1 1999/09/23 00:21:55 steve Exp $"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file contains set_width methods for the various NetExpr
|
||||||
|
* classes. The set_width method is used by elaboration to ask the
|
||||||
|
* expression to resize itself. If the expression can't, then the
|
||||||
|
* set_width method will return false and the caller will arrange for
|
||||||
|
* whatever is needed to deal with the size mismatch.
|
||||||
|
*/
|
||||||
|
# include "netlist.h"
|
||||||
|
# include <typeinfo>
|
||||||
|
|
||||||
|
|
||||||
|
bool NetExpr::set_width(unsigned w)
|
||||||
|
{
|
||||||
|
cerr << typeid(*this).name() << ": set_width(unsigned) "
|
||||||
|
"not implemented." << endl;
|
||||||
|
expr_width(w);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NetEBinary::set_width(unsigned w)
|
||||||
|
{
|
||||||
|
bool flag = true;
|
||||||
|
switch (op_) {
|
||||||
|
|
||||||
|
case 'l': // left shift (<<)
|
||||||
|
case 'r': // right shift (>>)
|
||||||
|
flag = left_->set_width(w);
|
||||||
|
expr_width(w);
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* The default rule is that the operands of the binary
|
||||||
|
operator might as well use the same width as the
|
||||||
|
output from the binary operation. */
|
||||||
|
default:
|
||||||
|
expr_width(left_->expr_width() > right_->expr_width()
|
||||||
|
? left_->expr_width() : right_->expr_width());
|
||||||
|
cerr << "NetEBinary::set_width(): Using default for " <<
|
||||||
|
op_ << "." << endl;
|
||||||
|
flag = false;
|
||||||
|
|
||||||
|
case '%':
|
||||||
|
case '/':
|
||||||
|
flag = left_->set_width(w) && flag;
|
||||||
|
flag = right_->set_width(w) && flag;
|
||||||
|
expr_width(w);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The bitwise logical operators have operands the same size as the
|
||||||
|
* result. Anything else is a mess.
|
||||||
|
*/
|
||||||
|
bool NetEBAdd::set_width(unsigned w)
|
||||||
|
{
|
||||||
|
bool flag = true;
|
||||||
|
|
||||||
|
if (left_->expr_width() > right_->expr_width())
|
||||||
|
right_->set_width(left_->expr_width());
|
||||||
|
else
|
||||||
|
left_->set_width(right_->expr_width());
|
||||||
|
|
||||||
|
if (left_->expr_width() == w)
|
||||||
|
expr_width(w);
|
||||||
|
else if (left_->expr_width() == (w-1))
|
||||||
|
expr_width(w);
|
||||||
|
else
|
||||||
|
flag = false;
|
||||||
|
|
||||||
|
return flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The bitwise logical operators have operands the same size as the
|
||||||
|
* result. Anything else is a mess.
|
||||||
|
*/
|
||||||
|
bool NetEBBits::set_width(unsigned w)
|
||||||
|
{
|
||||||
|
bool flag = true;
|
||||||
|
|
||||||
|
flag = left_->set_width(w) && flag;
|
||||||
|
flag = right_->set_width(w) && flag;
|
||||||
|
expr_width(w);
|
||||||
|
|
||||||
|
return flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Comparison operators allow the subexpressions to have
|
||||||
|
* their own natural width. However, I do need to make
|
||||||
|
* sure that the subexpressions have the same width.
|
||||||
|
*/
|
||||||
|
bool NetEBComp::set_width(unsigned w)
|
||||||
|
{
|
||||||
|
bool flag = true;
|
||||||
|
|
||||||
|
assert(w == 1);
|
||||||
|
expr_width(w);
|
||||||
|
flag = left_->set_width(right_->expr_width());
|
||||||
|
if (!flag)
|
||||||
|
flag = right_->set_width(left_->expr_width());
|
||||||
|
|
||||||
|
return flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NetEBLogic::set_width(unsigned w)
|
||||||
|
{
|
||||||
|
bool flag;
|
||||||
|
flag = left_->set_width(right_->expr_width());
|
||||||
|
if (!flag)
|
||||||
|
flag = right_->set_width(left_->expr_width());
|
||||||
|
return (w == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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)
|
||||||
|
if (parms_[idx] != 0)
|
||||||
|
sum += parms_[idx]->expr_width();
|
||||||
|
|
||||||
|
sum *= repeat_;
|
||||||
|
expr_width(sum);
|
||||||
|
if (sum != w) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NetEConst::set_width(unsigned w)
|
||||||
|
{
|
||||||
|
if (w > value_.len())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
assert(w <= value_.len());
|
||||||
|
value_ = verinum(value_, w);
|
||||||
|
expr_width(w);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NetEMemory::set_width(unsigned w)
|
||||||
|
{
|
||||||
|
if (w != mem_->width())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
expr_width(w);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NetEParam::set_width(unsigned)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The signal should automatically pad with zeros to get to th desired
|
||||||
|
* width. Do not allow signal bits to be truncated, however.
|
||||||
|
*/
|
||||||
|
bool NetESignal::set_width(unsigned w)
|
||||||
|
{
|
||||||
|
if (w != pin_count())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NetESubSignal::set_width(unsigned w)
|
||||||
|
{
|
||||||
|
if (w != 1) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NetETernary::set_width(unsigned w)
|
||||||
|
{
|
||||||
|
bool flag = true;
|
||||||
|
flag = flag && true_val_->set_width(w);
|
||||||
|
flag = flag && false_val_->set_width(w);
|
||||||
|
expr_width(true_val_->expr_width());
|
||||||
|
return flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XXXX FIX ME: For now, just take whatever the caller says as my
|
||||||
|
* width. What I really need to do is note the width of the output
|
||||||
|
* parameter of the function definition and take that into account.
|
||||||
|
*/
|
||||||
|
bool NetEUFunc::set_width(unsigned wid)
|
||||||
|
{
|
||||||
|
expr_width(wid);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NetEUnary::set_width(unsigned w)
|
||||||
|
{
|
||||||
|
bool flag = true;
|
||||||
|
switch (op_) {
|
||||||
|
case '~':
|
||||||
|
case '-':
|
||||||
|
flag = expr_->set_width(w);
|
||||||
|
break;
|
||||||
|
case '&':
|
||||||
|
case '!':
|
||||||
|
if (w != 1) {
|
||||||
|
flag = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
flag = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
expr_width(w);
|
||||||
|
return flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $Log: set_width.cc,v $
|
||||||
|
* Revision 1.1 1999/09/23 00:21:55 steve
|
||||||
|
* Move set_width methods into a single file,
|
||||||
|
* Add the NetEBLogic class for logic expressions,
|
||||||
|
* Fix error setting with of && in if statements.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
Loading…
Reference in New Issue