Calculate expression widths at elaboration time.

This commit is contained in:
steve 1998-11-07 19:17:10 +00:00
parent b118634189
commit 47a444fb92
3 changed files with 121 additions and 29 deletions

View File

@ -17,10 +17,11 @@
* 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.2 1998/11/07 17:05:05 steve Exp $" #ident "$Id: netlist.cc,v 1.3 1998/11/07 19:17:10 steve Exp $"
#endif #endif
# include <cassert> # include <cassert>
# include <typeinfo>
# include "netlist.h" # include "netlist.h"
void connect(NetObj::Link&l, NetObj::Link&r) void connect(NetObj::Link&l, NetObj::Link&r)
@ -98,6 +99,8 @@ NetAssign::NetAssign(NetNet*lv, NetExpr*rv)
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) { for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
connect(pin(idx), lv->pin(idx)); connect(pin(idx), lv->pin(idx));
} }
rval_->set_width(lval_->pin_count());
} }
NetAssign::~NetAssign() NetAssign::~NetAssign()
@ -129,28 +132,89 @@ NetExpr::~NetExpr()
{ {
} }
void NetExpr::set_width(unsigned w)
{
cerr << typeid(*this).name() << ": set_width(unsigned) "
"not implemented." << endl;
expr_width(w);
}
NetEBinary::~NetEBinary() NetEBinary::~NetEBinary()
{ {
} }
NetEConst::~NetEConst()
{
}
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)
{ {
switch (op_) { switch (op_) {
case 'e': case 'e':
natural_width(1); expr_width(1);
break; break;
default: default:
natural_width(left_->natural_width() > right_->natural_width() expr_width(left_->expr_width() > right_->expr_width()
? left_->natural_width() : right_->natural_width()); ? left_->expr_width() : right_->expr_width());
break; break;
} }
} }
void NetEBinary::set_width(unsigned w)
{
switch (op_) {
/* Comparison operators allow the subexpressions to have
their own natural width. Do not recurse the
set_width(). */
case 'e':
assert(w == 1);
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:
cerr << "NetEBinary::set_width(): Using default for " <<
op_ << "." << endl;
case '+':
left_->set_width(w);
right_->set_width(w);
expr_width(w);
break;
}
}
NetEConst::~NetEConst()
{
}
void NetEConst::set_width(unsigned w)
{
assert(w <= value_.len());
expr_width(w);
}
NetESignal::~NetESignal()
{
}
void NetESignal::set_width(unsigned w)
{
assert(w == sig_->pin_count());
expr_width(w);
}
NetEUnary::~NetEUnary()
{
}
void NetEUnary::set_width(unsigned w)
{
expr_->set_width(w);
expr_width(w);
}
void Design::add_signal(NetNet*net) void Design::add_signal(NetNet*net)
{ {
assert(net->design_ == 0); assert(net->design_ == 0);
@ -253,6 +317,9 @@ void Design::add_process(NetProcTop*pro)
/* /*
* $Log: netlist.cc,v $ * $Log: netlist.cc,v $
* Revision 1.3 1998/11/07 19:17:10 steve
* Calculate expression widths at elaboration time.
*
* Revision 1.2 1998/11/07 17:05:05 steve * Revision 1.2 1998/11/07 17:05:05 steve
* Handle procedural conditional, and some * Handle procedural conditional, and some
* of the conditional expressions. * of the conditional expressions.

View File

@ -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.2 1998/11/07 17:05:05 steve Exp $" #ident "$Id: netlist.h,v 1.3 1998/11/07 19:17:10 steve Exp $"
#endif #endif
/* /*
@ -475,6 +475,13 @@ class NetProcTop {
/* ========= /* =========
* There are cases where expressions need to be represented. The * There are cases where expressions need to be represented. The
* NetExpr class is the root of a heirarchy that serves that purpose. * NetExpr class is the root of a heirarchy that serves that purpose.
*
* The expr_width() is the width of the expression, that accounts
* for the widths of the sub-expressions I might have. It is up to the
* derived classes to properly set the expr width, if need be. The
* set_width() method is used to compel an expression to have a
* certain width, and is used particulary when the expression is an
* rvalue in an assignment statement.
*/ */
class NetExpr { class NetExpr {
public: public:
@ -484,10 +491,11 @@ class NetExpr {
virtual void expr_scan(struct expr_scan_t*) const =0; virtual void expr_scan(struct expr_scan_t*) const =0;
virtual void dump(ostream&) const; virtual void dump(ostream&) const;
unsigned natural_width() const { return width_; } unsigned expr_width() const { return width_; }
virtual void set_width(unsigned);
protected: protected:
void natural_width(unsigned w) { width_ = w; } void expr_width(unsigned w) { width_ = w; }
private: private:
unsigned width_; unsigned width_;
@ -508,6 +516,8 @@ class NetEBinary : public NetExpr {
char op() const { return op_; } char op() const { return op_; }
void set_width(unsigned w);
virtual void expr_scan(struct expr_scan_t*) const; virtual void expr_scan(struct expr_scan_t*) const;
virtual void dump(ostream&) const; virtual void dump(ostream&) const;
@ -526,6 +536,7 @@ class NetEConst : public NetExpr {
const verinum&value() const { return value_; } const verinum&value() const { return value_; }
virtual void set_width(unsigned w);
virtual void expr_scan(struct expr_scan_t*) const; virtual void expr_scan(struct expr_scan_t*) const;
virtual void dump(ostream&) const; virtual void dump(ostream&) const;
@ -537,11 +548,14 @@ class NetEUnary : public NetExpr {
public: public:
NetEUnary(char op, NetExpr*ex) NetEUnary(char op, NetExpr*ex)
: NetExpr(ex->natural_width()), op_(op), expr_(ex) { } : NetExpr(ex->expr_width()), op_(op), expr_(ex) { }
~NetEUnary();
char op() const { return op_; } char op() const { return op_; }
const NetExpr* expr() const { return expr_; } const NetExpr* expr() const { return expr_; }
void set_width(unsigned w);
virtual void expr_scan(struct expr_scan_t*) const; virtual void expr_scan(struct expr_scan_t*) const;
virtual void dump(ostream&) const; virtual void dump(ostream&) const;
@ -574,9 +588,12 @@ class NetESignal : public NetExpr {
public: public:
NetESignal(NetNet*n) NetESignal(NetNet*n)
: NetExpr(n->pin_count()), sig_(n) { } : NetExpr(n->pin_count()), sig_(n) { }
~NetESignal();
const string& name() const { return sig_->name(); } const string& name() const { return sig_->name(); }
virtual void set_width(unsigned);
virtual void expr_scan(struct expr_scan_t*) const; virtual void expr_scan(struct expr_scan_t*) const;
virtual void dump(ostream&) const; virtual void dump(ostream&) const;
@ -653,6 +670,9 @@ inline ostream& operator << (ostream&o, const NetExpr&exp)
/* /*
* $Log: netlist.h,v $ * $Log: netlist.h,v $
* Revision 1.3 1998/11/07 19:17:10 steve
* Calculate expression widths at elaboration time.
*
* Revision 1.2 1998/11/07 17:05:05 steve * Revision 1.2 1998/11/07 17:05:05 steve
* Handle procedural conditional, and some * Handle procedural conditional, and some
* of the conditional expressions. * of the conditional expressions.

View File

@ -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: t-vvm.cc,v 1.2 1998/11/07 17:05:06 steve Exp $" #ident "$Id: t-vvm.cc,v 1.3 1998/11/07 19:17:10 steve Exp $"
#endif #endif
# include <iostream> # include <iostream>
@ -69,14 +69,13 @@ class target_vvm : public target_t {
class vvm_proc_rval : public expr_scan_t { class vvm_proc_rval : public expr_scan_t {
public: public:
explicit vvm_proc_rval(ostream&os, unsigned width) explicit vvm_proc_rval(ostream&os)
: result(""), os_(os), width_(width) { } : result(""), os_(os) { }
string result; string result;
private: private:
ostream&os_; ostream&os_;
unsigned width_;
private: private:
virtual void expr_const(const NetEConst*); virtual void expr_const(const NetEConst*);
@ -89,8 +88,9 @@ class vvm_proc_rval : public expr_scan_t {
void vvm_proc_rval::expr_const(const NetEConst*expr) void vvm_proc_rval::expr_const(const NetEConst*expr)
{ {
string tname = make_temp(); string tname = make_temp();
os_ << " vvm_bitset_t<" << width_ << "> " << tname << ";" << endl; os_ << " vvm_bitset_t<" << expr->expr_width() << "> "
for (unsigned idx = 0 ; idx < width_ ; idx += 1) { << tname << ";" << endl;
for (unsigned idx = 0 ; idx < expr->expr_width() ; idx += 1) {
os_ << " " << tname << "[" << idx << "] = "; os_ << " " << tname << "[" << idx << "] = ";
switch (expr->value().get(idx)) { switch (expr->value().get(idx)) {
case verinum::V0: case verinum::V0:
@ -127,7 +127,8 @@ void vvm_proc_rval::expr_unary(const NetEUnary*expr)
expr->expr()->expr_scan(this); expr->expr()->expr_scan(this);
string tname = make_temp(); string tname = make_temp();
os_ << " vvm_bitset_t<" << width_ << "> " << tname << " = "; os_ << " vvm_bitset_t<" << expr->expr_width() << "> "
<< tname << " = ";
switch (expr->op()) { switch (expr->op()) {
case '~': case '~':
os_ << "vvm_unop_not(" << result << ");" os_ << "vvm_unop_not(" << result << ");"
@ -145,22 +146,23 @@ void vvm_proc_rval::expr_unary(const NetEUnary*expr)
void vvm_proc_rval::expr_binary(const NetEBinary*expr) void vvm_proc_rval::expr_binary(const NetEBinary*expr)
{ {
if (width_ == 0) {
width_ = expr->left()->natural_width();
}
expr->left()->expr_scan(this); expr->left()->expr_scan(this);
string lres = result; string lres = result;
expr->right()->expr_scan(this); expr->right()->expr_scan(this);
string rres = result; string rres = result;
result = make_temp();
os_ << " vvm_bitset_t<" << expr->expr_width() << ">" <<
result << ";" << endl;
switch (expr->op()) { switch (expr->op()) {
case 'e': case 'e':
result = string("vvm_binop_eq(") + lres + "," + rres + ")"; os_ << " " << result << " = vvm_binop_eq(" << lres
<< "," << rres << ");" << endl;
break; break;
case '+': case '+':
result = string("vvm_binop_plus(") + lres + "," + rres + ")"; os_ << " " << result << " = vvm_binop_plus(" << lres
<< "," << rres << ");" << endl;
break; break;
default: default:
cerr << "vvm: Unhandled binary op `" << expr->op() << "': " cerr << "vvm: Unhandled binary op `" << expr->op() << "': "
@ -171,9 +173,9 @@ void vvm_proc_rval::expr_binary(const NetEBinary*expr)
} }
} }
static string emit_proc_rval(ostream&os, unsigned width, const NetExpr*expr) static string emit_proc_rval(ostream&os, const NetExpr*expr)
{ {
vvm_proc_rval scan (os, width); vvm_proc_rval scan (os);
expr->expr_scan(&scan); expr->expr_scan(&scan);
return scan.result; return scan.result;
} }
@ -400,7 +402,7 @@ void target_vvm::start_process(ostream&os, const NetProcTop*proc)
*/ */
void target_vvm::proc_assign(ostream&os, const NetAssign*net) void target_vvm::proc_assign(ostream&os, const NetAssign*net)
{ {
string rval = emit_proc_rval(os, net->lval()->pin_count(), net->rval()); string rval = emit_proc_rval(os, net->rval());
os << " // " << net->lval()->name() << " = "; os << " // " << net->lval()->name() << " = ";
net->rval()->dump(os); net->rval()->dump(os);
@ -419,7 +421,7 @@ void target_vvm::proc_assign(ostream&os, const NetAssign*net)
for (unsigned idx = 0 ; idx < net->pin_count() ; idx += 1) { for (unsigned idx = 0 ; idx < net->pin_count() ; idx += 1) {
const NetObj*cur; const NetObj*cur;
unsigned pin; unsigned pin;
for (net->lval()->pin(0).next_link(cur, pin) for (net->lval()->pin(idx).next_link(cur, pin)
; cur != net->lval() ; cur != net->lval()
; cur->pin(pin).next_link(cur, pin)) { ; cur->pin(pin).next_link(cur, pin)) {
@ -450,7 +452,7 @@ void target_vvm::proc_block(ostream&os, const NetBlock*net)
void target_vvm::proc_condit(ostream&os, const NetCondit*net) void target_vvm::proc_condit(ostream&os, const NetCondit*net)
{ {
string expr = emit_proc_rval(os, 0, net->expr()); string expr = emit_proc_rval(os, net->expr());
os << " if (" << expr << "[0] == V1) {" << endl; os << " if (" << expr << "[0] == V1) {" << endl;
net->emit_recurse_if(os, this); net->emit_recurse_if(os, this);
os << " } else {" << endl; os << " } else {" << endl;
@ -543,6 +545,9 @@ extern const struct target tgt_vvm = {
}; };
/* /*
* $Log: t-vvm.cc,v $ * $Log: t-vvm.cc,v $
* Revision 1.3 1998/11/07 19:17:10 steve
* Calculate expression widths at elaboration time.
*
* Revision 1.2 1998/11/07 17:05:06 steve * Revision 1.2 1998/11/07 17:05:06 steve
* Handle procedural conditional, and some * Handle procedural conditional, and some
* of the conditional expressions. * of the conditional expressions.