diff --git a/Statement.cc b/Statement.cc index e6f6875c2..fd2cf6ae0 100644 --- a/Statement.cc +++ b/Statement.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: Statement.cc,v 1.7 1999/06/06 20:45:38 steve Exp $" +#ident "$Id: Statement.cc,v 1.8 1999/06/13 23:51:16 steve Exp $" #endif # include "Statement.h" @@ -27,16 +27,33 @@ Statement::~Statement() { } -PAssign::~PAssign() +PAssign_::PAssign_(PExpr*lval, PExpr*ex) +: lval_(lval), rval_(ex) +{ +} + +PAssign_::~PAssign_() { delete lval_; - delete expr_; + delete rval_; +} + +PAssign::PAssign(PExpr*lval, PExpr*ex) +: PAssign_(lval, ex) +{ +} + +PAssign::~PAssign() +{ +} + +PAssignNB::PAssignNB(PExpr*lval, PExpr*ex) +: PAssign_(lval, ex) +{ } PAssignNB::~PAssignNB() { - delete lval_; - delete rval_; } PBlock::PBlock(BL_TYPE t, const list&st) @@ -100,6 +117,9 @@ PWhile::~PWhile() /* * $Log: Statement.cc,v $ + * Revision 1.8 1999/06/13 23:51:16 steve + * l-value part select for procedural assignments. + * * Revision 1.7 1999/06/06 20:45:38 steve * Add parse and elaboration of non-blocking assignments, * Replace list with an svector version, diff --git a/Statement.h b/Statement.h index ff2a704b5..1f2528ea5 100644 --- a/Statement.h +++ b/Statement.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: Statement.h,v 1.9 1999/06/06 20:45:38 steve Exp $" +#ident "$Id: Statement.h,v 1.10 1999/06/13 23:51:16 steve Exp $" #endif # include @@ -76,46 +76,50 @@ class Statement : public LineInfo { * type. The rvalue is an expression. The lvalue needs to be figured * out by the parser as much as possible. */ -class PAssign : public Statement { - +class PAssign_ : public Statement { public: - explicit PAssign(PExpr*lval, PExpr*ex) - : lval_(lval), expr_(ex) { } - - ~PAssign(); - - const PExpr* lval() const { return lval_; } - const PExpr* get_expr() const { return expr_; } - - virtual void dump(ostream&out, unsigned ind) const; - virtual NetProc* elaborate(Design*des, const string&path) const; - - private: - PExpr* lval_; - PExpr* expr_; - - NetProc*assign_to_memory_(class NetMemory*, PExpr*, - Design*des, const string&path) const; -}; - -class PAssignNB : public Statement { - - public: - explicit PAssignNB(PExpr*lval, PExpr*ex) - : lval_(lval), rval_(ex) { } - ~PAssignNB(); + explicit PAssign_(PExpr*lval, PExpr*ex); + virtual ~PAssign_() =0; const PExpr* lval() const { return lval_; } const PExpr* rval() const { return rval_; } - virtual void dump(ostream&out, unsigned ind) const; - virtual NetProc* elaborate(Design*des, const string&path) const; + protected: + NetNet*elaborate_lval(Design*, const string&path, + unsigned&lsb, unsigned&msb, + NetExpr*&mux) const; private: PExpr* lval_; PExpr* rval_; }; +class PAssign : public PAssign_ { + + public: + explicit PAssign(PExpr*lval, PExpr*ex); + ~PAssign(); + + virtual void dump(ostream&out, unsigned ind) const; + virtual NetProc* elaborate(Design*des, const string&path) const; + + private: + NetProc*assign_to_memory_(class NetMemory*, PExpr*, + Design*des, const string&path) const; +}; + +class PAssignNB : public PAssign_ { + + public: + explicit PAssignNB(PExpr*lval, PExpr*ex); + ~PAssignNB(); + + virtual void dump(ostream&out, unsigned ind) const; + virtual NetProc* elaborate(Design*des, const string&path) const; + + private: +}; + /* * A block statement is an ordered list of statements that make up the * block. The block can be sequential or parallel, which only affects @@ -297,6 +301,9 @@ class PWhile : public Statement { /* * $Log: Statement.h,v $ + * Revision 1.10 1999/06/13 23:51:16 steve + * l-value part select for procedural assignments. + * * Revision 1.9 1999/06/06 20:45:38 steve * Add parse and elaboration of non-blocking assignments, * Replace list with an svector version, diff --git a/elaborate.cc b/elaborate.cc index 7439c5617..3d3e3ccbe 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.42 1999/06/13 16:30:06 steve Exp $" +#ident "$Id: elaborate.cc,v 1.43 1999/06/13 23:51:16 steve Exp $" #endif /* @@ -996,88 +996,28 @@ NetProc* Statement::elaborate(Design*des, const string&path) const NetProc* PAssign::assign_to_memory_(NetMemory*mem, PExpr*ix, Design*des, const string&path) const { - NetExpr*rval = expr_->elaborate_expr(des, path); - if (rval == 0) { + NetExpr*rv = rval()->elaborate_expr(des, path); + if (rv == 0) { cerr << get_line() << ": " << "failed to elaborate expression." << endl; return 0; } - assert(rval); + assert(rv); NetExpr*idx = ix->elaborate_expr(des, path); assert(idx); - NetAssignMem*am = new NetAssignMem(mem, idx, rval); + NetAssignMem*am = new NetAssignMem(mem, idx, rv); am->set_line(*this); return am; } -NetProc* PAssign::elaborate(Design*des, const string&path) const -{ - const PEIdent*id = dynamic_cast(lval_); - assert(id); - - /* Catch the case where the lvalue is a reference to a memory - item. These are handled differently. */ - if (NetMemory*mem = des->find_memory(path+"."+id->name())) - return assign_to_memory_(mem, id->msb_, des, path); - - - if (id->lsb_ || id->msb_) { - cerr << get_line() << ": Sorry, cannot elaborate part/bit" - " selects in l-value." << endl; - des->errors += 1; - return 0; - } - - NetNet*reg = des->find_signal(path+"."+id->name()); - - if (reg == 0) { - cerr << get_line() << ": Could not match signal: " << - id->name() << endl; - des->errors += 1; - return 0; - } - assert(reg); - - if (reg->type() != NetNet::REG) { - cerr << get_line() << ": " << *lval() << " is not a register." - << endl; - return 0; - } - assert(reg->type() == NetNet::REG); - assert(expr_); - - NetExpr*rval = expr_->elaborate_expr(des, path); - if (rval == 0) { - cerr << get_line() << ": failed to elaborate expression." - << endl; - return 0; - } - assert(rval); - - NetAssign*cur = new NetAssign("@assign", des, reg, rval); - for (unsigned idx = 0 ; idx < cur->pin_count() ; idx += 1) - connect(cur->pin(idx), reg->pin(idx)); - - cur->set_line(*this); - des->add_node(cur); - - return cur; -} - -/* - * The l-value of a procedural assignment is a very much constrained - * expression. To wit, only identifiers, bit selects and part selects - * are allowed. I therefore can elaborate the l-value by hand, without - * the help of recursive elaboration. - * - * (For now, this does not yet support concatenation in the l-value.) - */ -NetProc* PAssignNB::elaborate(Design*des, const string&path) const +NetNet* PAssign_::elaborate_lval(Design*des, const string&path, + unsigned&msb, unsigned&lsb, + NetExpr*&mux) const { /* Get the l-value, and assume that it is an identifier. */ - const PEIdent*id = dynamic_cast(lval_); + const PEIdent*id = dynamic_cast(lval()); assert(id); /* Get the signal referenced by the identifier, and make sure @@ -1097,22 +1037,7 @@ NetProc* PAssignNB::elaborate(Design*des, const string&path) const return 0; } assert(reg->type() == NetNet::REG); - assert(rval_); - /* Elaborate the r-value expression. This generates a - procedural expression that I attach to the assignment. */ - NetExpr*rval = rval_->elaborate_expr(des, path); - if (rval == 0) { - cerr << get_line() << ": " << "failed to elaborate expression." - << endl; - return 0; - } - assert(rval); - - /* Notice and handle bit selects of the signal. This is done - by making a mux expression to attach to the assignment - node. */ - NetAssignNB*cur; if (id->msb_ && id->lsb_) { verinum*vl = id->lsb_->eval_const(des, path); if (vl == 0) { @@ -1129,11 +1054,9 @@ NetProc* PAssignNB::elaborate(Design*des, const string&path) const return 0; } - unsigned wid = vm->as_ulong()-vl->as_ulong()+1; - cur = new NetAssignNB(des->local_symbol(path), des, wid, rval); - for (unsigned idx = 0 ; idx < wid ; idx += 1) - connect(cur->pin(idx), reg->pin(idx+vl->as_ulong())); - + msb = vm->as_ulong(); + lsb = vl->as_ulong(); + mux = 0; } else if (id->msb_) { assert(id->lsb_ == 0); @@ -1141,24 +1064,121 @@ NetProc* PAssignNB::elaborate(Design*des, const string&path) const if (v == 0) { NetExpr*m = id->msb_->elaborate_expr(des, path); assert(m); - cur = new NetAssignNB(des->local_symbol(path), des, - reg->pin_count(), m, rval); - - for (unsigned idx = 0 ; idx < cur->pin_count() ; idx += 1) - connect(cur->pin(idx), reg->pin(idx)); + msb = 0; + lsb = 0; + mux = m; } else { - cur = new NetAssignNB(des->local_symbol(path), des, 1, rval); - connect(cur->pin(0), reg->pin(v->as_ulong())); + msb = v->as_ulong(); + lsb = v->as_ulong(); + mux = 0; } } else { - cur = new NetAssignNB(des->local_symbol(path), des, - reg->pin_count(), rval); + assert(id->msb_ == 0); + assert(id->lsb_ == 0); + msb = reg->pin_count() - 1; + lsb = 0; + mux = 0; + } - for (unsigned idx = 0 ; idx < cur->pin_count() ; idx += 1) - connect(cur->pin(idx), reg->pin(idx)); + return reg; +} + +NetProc* PAssign::elaborate(Design*des, const string&path) const +{ + /* Catch the case where the lvalue is a reference to a memory + item. These are handled differently. */ + do { + const PEIdent*id = dynamic_cast(lval()); + if (id == 0) break; + + if (NetMemory*mem = des->find_memory(path+"."+id->name())) + return assign_to_memory_(mem, id->msb_, des, path); + + } while(0); + + unsigned lsb, msb; + NetExpr*mux; + NetNet*reg = elaborate_lval(des, path, msb, lsb, mux); + if (reg == 0) return 0; + + assert(rval()); + + NetExpr*rv = rval()->elaborate_expr(des, path); + if (rv == 0) { + cerr << get_line() << ": failed to elaborate expression." + << endl; + return 0; + } + assert(rv); + + NetAssign*cur; + if (mux == 0) { + unsigned wid = msb - lsb + 1; + cur = new NetAssign(des->local_symbol(path), des, wid, rv); + for (unsigned idx = 0 ; idx < wid ; idx += 1) + connect(cur->pin(idx), reg->pin(idx+lsb)); + + } else { + assert(reg->pin_count() == 1); + cerr << get_line() << ": Sorry, l-value bit select expression" + " must be constant." << endl; + delete reg; + delete rv; + return 0; +#if 0 + cur = new NetAssign(des->local_symbol(path), des, 1, mux, rv); + connect(cur->pin(0), reg->pin(0)); +#endif + } + + + cur->set_line(*this); + des->add_node(cur); + + return cur; +} + +/* + * The l-value of a procedural assignment is a very much constrained + * expression. To wit, only identifiers, bit selects and part selects + * are allowed. I therefore can elaborate the l-value by hand, without + * the help of recursive elaboration. + * + * (For now, this does not yet support concatenation in the l-value.) + */ +NetProc* PAssignNB::elaborate(Design*des, const string&path) const +{ + unsigned lsb, msb; + NetExpr*mux; + NetNet*reg = elaborate_lval(des, path, msb, lsb, mux); + if (reg == 0) return 0; + + assert(rval()); + + /* Elaborate the r-value expression. This generates a + procedural expression that I attach to the assignment. */ + NetExpr*rv = rval()->elaborate_expr(des, path); + if (rv == 0) { + cerr << get_line() << ": " << "failed to elaborate expression." + << endl; + return 0; + } + assert(rv); + + NetAssignNB*cur; + if (mux == 0) { + unsigned wid = msb - lsb + 1; + cur = new NetAssignNB(des->local_symbol(path), des, wid, rv); + for (unsigned idx = 0 ; idx < wid ; idx += 1) + connect(cur->pin(idx), reg->pin(idx+lsb)); + + } else { + assert(reg->pin_count() == 1); + cur = new NetAssignNB(des->local_symbol(path), des, 1, mux, rv); + connect(cur->pin(0), reg->pin(0)); } @@ -1372,7 +1392,7 @@ NetProc* PForStatement::elaborate(Design*des, const string&path) const return 0; } assert(sig); - NetAssign*init = new NetAssign("@for-assign", des, sig, + NetAssign*init = new NetAssign("@for-assign", des, sig->pin_count(), expr1_->elaborate_expr(des, path)); for (unsigned idx = 0 ; idx < init->pin_count() ; idx += 1) connect(init->pin(idx), sig->pin(idx)); @@ -1385,7 +1405,7 @@ NetProc* PForStatement::elaborate(Design*des, const string&path) const sig = des->find_signal(path+"."+id2->name()); assert(sig); - NetAssign*step = new NetAssign("@for-assign", des, sig, + NetAssign*step = new NetAssign("@for-assign", des, sig->pin_count(), expr2_->elaborate_expr(des, path)); for (unsigned idx = 0 ; idx < step->pin_count() ; idx += 1) connect(step->pin(idx), sig->pin(idx)); @@ -1507,6 +1527,9 @@ Design* elaborate(const map&modules, /* * $Log: elaborate.cc,v $ + * Revision 1.43 1999/06/13 23:51:16 steve + * l-value part select for procedural assignments. + * * Revision 1.42 1999/06/13 16:30:06 steve * Unify the NetAssign constructors a bit. * diff --git a/netlist.cc b/netlist.cc index 7d8b6f3d0..fcb745e74 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.36 1999/06/13 16:30:06 steve Exp $" +#ident "$Id: netlist.cc,v 1.37 1999/06/13 23:51:16 steve Exp $" #endif # include @@ -285,10 +285,10 @@ NetAssign_::~NetAssign_() { } -NetAssign::NetAssign(const string&n, Design*des, NetNet*lv, NetExpr*rv) -: NetAssign_(n, lv->pin_count()), rval_(rv) +NetAssign::NetAssign(const string&n, Design*des, unsigned w, NetExpr*rv) +: NetAssign_(n, w), rval_(rv) { - bool flag = rval_->set_width(lv->pin_count()); + bool flag = rval_->set_width(w); if (flag == false) { cerr << rv->get_line() << ": Expression bit width" << " conflicts with l-value bit width." << endl; @@ -1202,6 +1202,9 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*)) /* * $Log: netlist.cc,v $ + * Revision 1.37 1999/06/13 23:51:16 steve + * l-value part select for procedural assignments. + * * Revision 1.36 1999/06/13 16:30:06 steve * Unify the NetAssign constructors a bit. * diff --git a/netlist.h b/netlist.h index 8fbbbdebe..5c1ad0fd6 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.39 1999/06/13 17:30:23 steve Exp $" +#ident "$Id: netlist.h,v 1.40 1999/06/13 23:51:16 steve Exp $" #endif /* @@ -576,7 +576,7 @@ class NetAssign_ : public NetProc, public NetNode, public LineInfo { class NetAssign : public NetAssign_ { public: - explicit NetAssign(const string&, Design*des, NetNet*lv, NetExpr*rv); + explicit NetAssign(const string&, Design*des, unsigned w, NetExpr*rv); ~NetAssign(); const NetExpr*rval() const { return rval_; } @@ -1252,6 +1252,9 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.40 1999/06/13 23:51:16 steve + * l-value part select for procedural assignments. + * * Revision 1.39 1999/06/13 17:30:23 steve * More unary operators. * diff --git a/pform.cc b/pform.cc index 46c560f4c..33f54261f 100644 --- a/pform.cc +++ b/pform.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: pform.cc,v 1.25 1999/06/12 20:35:27 steve Exp $" +#ident "$Id: pform.cc,v 1.26 1999/06/13 23:51:16 steve Exp $" #endif # include "compiler.h" @@ -192,7 +192,7 @@ void pform_make_udp(string*name, list*parms, // XXXX assert(id->name() == pins[0]->name); - const PENumber*np = dynamic_cast(pa->get_expr()); + const PENumber*np = dynamic_cast(pa->rval()); assert(np); init = np->value()[0]; @@ -590,6 +590,9 @@ int pform_parse(const char*path, map&modules, /* * $Log: pform.cc,v $ + * Revision 1.26 1999/06/13 23:51:16 steve + * l-value part select for procedural assignments. + * * Revision 1.25 1999/06/12 20:35:27 steve * parse more verilog. * diff --git a/pform_dump.cc b/pform_dump.cc index 64cbd55af..3970e8da4 100644 --- a/pform_dump.cc +++ b/pform_dump.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: pform_dump.cc,v 1.19 1999/06/10 04:03:53 steve Exp $" +#ident "$Id: pform_dump.cc,v 1.20 1999/06/13 23:51:16 steve Exp $" #endif /* @@ -262,14 +262,14 @@ void Statement::dump(ostream&out, unsigned ind) const void PAssign::dump(ostream&out, unsigned ind) const { out << setw(ind) << ""; - out << *lval_ << " = " << *expr_ << ";"; + out << *lval() << " = " << *rval() << ";"; out << " /* " << get_line() << " */" << endl; } void PAssignNB::dump(ostream&out, unsigned ind) const { out << setw(ind) << ""; - out << *lval_ << " <= " << *rval_ << ";"; + out << *lval() << " <= " << *rval() << ";"; out << " /* " << get_line() << " */" << endl; } @@ -480,6 +480,9 @@ void PUdp::dump(ostream&out) const /* * $Log: pform_dump.cc,v $ + * Revision 1.20 1999/06/13 23:51:16 steve + * l-value part select for procedural assignments. + * * Revision 1.19 1999/06/10 04:03:53 steve * Add support for the Ternary operator, * Add support for repeat concatenation,