From 5de9b7c9f17ebbbd559ce5dcf892851cef46392a Mon Sep 17 00:00:00 2001 From: steve Date: Mon, 10 May 1999 00:16:57 +0000 Subject: [PATCH] Parse and elaborate the concatenate operator in structural contexts, Replace vector and list with svector, evaluate constant expressions with parameters, handle memories as lvalues. Parse task declarations, integer types. --- PExpr.h | 31 +++++++++-- PGate.h | 27 ++++++---- Statement.cc | 20 +++++--- Statement.h | 43 ++++++++++------ design_dump.cc | 23 ++++++++- elaborate.cc | 137 +++++++++++++++++++++++++++++++++++++++++-------- eval.cc | 54 +++++++++++++++++-- netlist.cc | 21 +++++++- netlist.h | 29 ++++++++++- parse.y | 102 +++++++++++++++++++++++------------- pform.cc | 86 +++++++++++++++---------------- pform.h | 18 +++++-- pform_dump.cc | 31 +++++++++-- 13 files changed, 468 insertions(+), 154 deletions(-) diff --git a/PExpr.h b/PExpr.h index 1095795bd8..148ec5d9f3 100644 --- a/PExpr.h +++ b/PExpr.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: PExpr.h,v 1.7 1999/05/01 02:57:52 steve Exp $" +#ident "$Id: PExpr.h,v 1.8 1999/05/10 00:16:57 steve Exp $" #endif # include @@ -51,7 +51,7 @@ class PExpr : public LineInfo { // This attempts to evaluate a constant expression, and return // a verinum as a result. If the expression cannot be // evaluated, return 0. - virtual verinum* eval_const() const; + virtual verinum* eval_const(const Design*des, const string&path) const; // This method returns true if that expression is the same as // this expression. This method is used for comparing @@ -61,6 +61,18 @@ class PExpr : public LineInfo { ostream& operator << (ostream&, const PExpr&); +class PEConcat : public PExpr { + + public: + PEConcat(const svector&p) : parms_(p) { } + + virtual void dump(ostream&) const; + virtual NetNet* elaborate_net(Design*des, const string&path) const; + + private: + svectorparms_; +}; + class PEEvent : public PExpr { public: @@ -87,7 +99,10 @@ class PEIdent : public PExpr { virtual void dump(ostream&) const; virtual NetNet* elaborate_net(Design*des, const string&path) const; virtual NetExpr*elaborate_expr(Design*des, const string&path) const; + verinum* eval_const(const Design*des, const string&path) const; + // XXXX + string name() const { return text_; } private: string text_; @@ -114,7 +129,7 @@ class PENumber : public PExpr { virtual void dump(ostream&) const; virtual NetNet* elaborate_net(Design*des, const string&path) const; virtual NetExpr*elaborate_expr(Design*des, const string&path) const; - virtual verinum* eval_const() const; + virtual verinum* eval_const(const Design*des, const string&path) const; virtual bool is_the_same(const PExpr*that) const; @@ -160,6 +175,7 @@ class PEBinary : public PExpr { virtual void dump(ostream&out) const; virtual NetNet* elaborate_net(Design*des, const string&path) const; virtual NetExpr*elaborate_expr(Design*des, const string&path) const; + virtual verinum* eval_const(const Design*des, const string&path) const; private: char op_; @@ -169,6 +185,15 @@ class PEBinary : public PExpr { /* * $Log: PExpr.h,v $ + * Revision 1.8 1999/05/10 00:16:57 steve + * Parse and elaborate the concatenate operator + * in structural contexts, Replace vector + * and list with svector, evaluate + * constant expressions with parameters, handle + * memories as lvalues. + * + * Parse task declarations, integer types. + * * Revision 1.7 1999/05/01 02:57:52 steve * Handle much more complex event expressions. * diff --git a/PGate.h b/PGate.h index b9ab567494..4a36b105c4 100644 --- a/PGate.h +++ b/PGate.h @@ -19,10 +19,10 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: PGate.h,v 1.4 1999/02/15 02:06:15 steve Exp $" +#ident "$Id: PGate.h,v 1.5 1999/05/10 00:16:58 steve Exp $" #endif -# include +# include "svector.h" # include "LineInfo.h" class PExpr; class PUdp; @@ -41,7 +41,7 @@ class Module; class PGate : public LineInfo { public: - explicit PGate(const string&name, const vector&pins, long del) + explicit PGate(const string&name, const svector&pins, long del) : name_(name), delay_(del), pins_(pins) { } virtual ~PGate() { } @@ -50,7 +50,7 @@ class PGate : public LineInfo { long get_delay() const { return delay_; } - unsigned pin_count() const { return pins_.size(); } + unsigned pin_count() const { return pins_.count(); } const PExpr*pin(unsigned idx) const { return pins_[idx]; } virtual void dump(ostream&out) const; @@ -62,7 +62,7 @@ class PGate : public LineInfo { private: const string name_; const unsigned long delay_; - const vector pins_; + svector pins_; private: // not implemented PGate(const PGate&); @@ -76,8 +76,8 @@ class PGate : public LineInfo { class PGAssign : public PGate { public: - explicit PGAssign(const vector&pins) - : PGate("", pins, 0) { assert(pins.size() == 2); } + explicit PGAssign(const svector&pins) + : PGate("", pins, 0) { assert(pins.count() == 2); } void dump(ostream&out) const; virtual void elaborate(Design*des, const string&path) const; @@ -106,7 +106,7 @@ class PGBuiltin : public PGate { public: explicit PGBuiltin(Type t, const string&name, - const vector&pins, long del = 0) + const svector&pins, long del = 0) : PGate(name, pins, del), type_(t), msb_(0), lsb_(0) { } @@ -133,7 +133,7 @@ class PGModule : public PGate { public: explicit PGModule(const string&type, const string&name, - const vector&pins) + const svector&pins) : PGate(name, pins, 0), type_(type) { } virtual void dump(ostream&out) const; @@ -148,6 +148,15 @@ class PGModule : public PGate { /* * $Log: PGate.h,v $ + * Revision 1.5 1999/05/10 00:16:58 steve + * Parse and elaborate the concatenate operator + * in structural contexts, Replace vector + * and list with svector, evaluate + * constant expressions with parameters, handle + * memories as lvalues. + * + * Parse task declarations, integer types. + * * Revision 1.4 1999/02/15 02:06:15 steve * Elaborate gate ranges. * diff --git a/Statement.cc b/Statement.cc index 80296b5864..cb3906aad4 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.5 1999/02/03 04:20:11 steve Exp $" +#ident "$Id: Statement.cc,v 1.6 1999/05/10 00:16:58 steve Exp $" #endif # include "Statement.h" @@ -47,14 +47,9 @@ PBlock::~PBlock() delete[]list_; } -PCallTask::PCallTask(const string&n, const list&p) -: name_(n), nparms_(p.size()), parms_(nparms_?new PExpr*[nparms_]:0) +PCallTask::PCallTask(const string&n, const svector&p) +: name_(n), parms_(p) { - list::const_iterator s = p.begin(); - for (unsigned idx = 0 ; s != p.end() ; s++, idx += 1) { - parms_[idx] = *s; - } - } PCase::PCase(PExpr*ex, list*l) @@ -104,6 +99,15 @@ PWhile::~PWhile() /* * $Log: Statement.cc,v $ + * Revision 1.6 1999/05/10 00:16:58 steve + * Parse and elaborate the concatenate operator + * in structural contexts, Replace vector + * and list with svector, evaluate + * constant expressions with parameters, handle + * memories as lvalues. + * + * Parse task declarations, integer types. + * * Revision 1.5 1999/02/03 04:20:11 steve * Parse and elaborate the Verilog CASE statement. * diff --git a/Statement.h b/Statement.h index 749195e294..fb0e1b2d37 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.7 1999/04/29 02:16:26 steve Exp $" +#ident "$Id: Statement.h,v 1.8 1999/05/10 00:16:58 steve Exp $" #endif # include @@ -79,18 +79,21 @@ class Statement : public LineInfo { class PAssign : public Statement { public: - explicit PAssign(const string&name, PExpr*ex) - : to_name_(name), expr_(ex) { } + explicit PAssign(PExpr*lval, PExpr*ex) + : lval_(lval), expr_(ex) { } - string lval() const { return to_name_; } + 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: - const string to_name_; - PExpr*const expr_; + PExpr* lval_; + PExpr* expr_; + + NetProc*assign_to_memory_(class NetMemory*, PExpr*, + Design*des, const string&path) const; }; /* @@ -125,19 +128,19 @@ class PBlock : public Statement { class PCallTask : public Statement { public: - explicit PCallTask(const string&n, const list&parms); + explicit PCallTask(const string&n, const svector&parms); string name() const { return name_; } - unsigned nparms() const { return nparms_; } + unsigned nparms() const { return parms_.count(); } PExpr*&parm(unsigned idx) - { assert(idx < nparms_); + { assert(idx < parms_.count()); return parms_[idx]; } PExpr* parm(unsigned idx) const - { assert(idx < nparms_); + { assert(idx < parms_.count()); return parms_[idx]; } @@ -146,8 +149,7 @@ class PCallTask : public Statement { private: const string name_; - const unsigned nparms_; - PExpr**const parms_; + svector parms_; }; class PCase : public Statement { @@ -232,8 +234,8 @@ class PEventStatement : public Statement { class PForStatement : public Statement { public: - PForStatement(const string&n1, PExpr*e1, PExpr*cond, - const string&n2, PExpr*e2, Statement*st) + PForStatement(PExpr*n1, PExpr*e1, PExpr*cond, + PExpr*n2, PExpr*e2, Statement*st) : name1_(n1), expr1_(e1), cond_(cond), name2_(n2), expr2_(e2), statement_(st) { } @@ -242,12 +244,12 @@ class PForStatement : public Statement { virtual void dump(ostream&out, unsigned ind) const; private: - string name1_; + PExpr* name1_; PExpr* expr1_; PExpr*cond_; - string name2_; + PExpr* name2_; PExpr* expr2_; Statement*statement_; @@ -276,6 +278,15 @@ class PWhile : public Statement { /* * $Log: Statement.h,v $ + * Revision 1.8 1999/05/10 00:16:58 steve + * Parse and elaborate the concatenate operator + * in structural contexts, Replace vector + * and list with svector, evaluate + * constant expressions with parameters, handle + * memories as lvalues. + * + * Parse task declarations, integer types. + * * Revision 1.7 1999/04/29 02:16:26 steve * Parse OR of event expressions. * diff --git a/design_dump.cc b/design_dump.cc index 8ab363d1b9..515bd70a68 100644 --- a/design_dump.cc +++ b/design_dump.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: design_dump.cc,v 1.22 1999/05/06 02:29:32 steve Exp $" +#ident "$Id: design_dump.cc,v 1.23 1999/05/10 00:16:58 steve Exp $" #endif /* @@ -300,6 +300,18 @@ void NetAssign::dump(ostream&o, unsigned ind) const o << ";" << endl; } +void NetAssignMem::dump(ostream&o, unsigned ind) const +{ + o << setw(ind) << ""; + o << "/* " << get_line() << " */" << endl; + o << setw(ind) << ""; + o << mem_->name() << "["; + index_->dump(o); + o << "] = "; + rval_->dump(o); + o << ";" << endl; +} + /* Dump a block statement */ void NetBlock::dump(ostream&o, unsigned ind) const { @@ -568,6 +580,15 @@ void Design::dump(ostream&o) const /* * $Log: design_dump.cc,v $ + * Revision 1.23 1999/05/10 00:16:58 steve + * Parse and elaborate the concatenate operator + * in structural contexts, Replace vector + * and list with svector, evaluate + * constant expressions with parameters, handle + * memories as lvalues. + * + * Parse task declarations, integer types. + * * Revision 1.22 1999/05/06 02:29:32 steve * Excesss endl. * diff --git a/elaborate.cc b/elaborate.cc index 27c5a60af5..833c51870b 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.24 1999/05/05 03:04:46 steve Exp $" +#ident "$Id: elaborate.cc,v 1.25 1999/05/10 00:16:58 steve Exp $" #endif /* @@ -109,10 +109,22 @@ void PWire::elaborate(Design*des, const string&path) const /* Wires, registers and memories can have a width, expressed as the msb index and lsb index. */ if (msb && lsb) { - verinum*mval = msb->eval_const(); - assert(mval); - verinum*lval = lsb->eval_const(); - assert(lval); + verinum*mval = msb->eval_const(des, path); + if (mval == 0) { + cerr << msb->get_line() << ": Unable to evaluate " + "constant expression ``" << *msb << "''." << + endl; + des->errors += 1; + return; + } + verinum*lval = lsb->eval_const(des, path); + if (mval == 0) { + cerr << lsb->get_line() << ": Unable to evaluate " + "constant expression ``" << *lsb << "''." << + endl; + des->errors += 1; + return; + } long mnum = mval->as_long(); long lnum = lval->as_long(); @@ -125,7 +137,7 @@ void PWire::elaborate(Design*des, const string&path) const wid = lnum - mnum + 1; } else if (msb) { - verinum*val = msb->eval_const(); + verinum*val = msb->eval_const(des, path); assert(val); assert(val->as_ulong() > 0); wid = val->as_ulong(); @@ -134,9 +146,9 @@ void PWire::elaborate(Design*des, const string&path) const if (lidx || ridx) { // If the register has indices, then this is a // memory. Create the memory object. - verinum*lval = lidx->eval_const(); + verinum*lval = lidx->eval_const(des, path); assert(lval); - verinum*rval = ridx->eval_const(); + verinum*rval = ridx->eval_const(des, path); assert(rval); long lnum = lval->as_long(); @@ -188,8 +200,8 @@ void PGBuiltin::elaborate(Design*des, const string&path) const gates, then I am expected to make more then one gate. Figure out how many are desired. */ if (msb_) { - verinum*msb = msb_->eval_const(); - verinum*lsb = lsb_->eval_const(); + verinum*msb = msb_->eval_const(des, path); + verinum*lsb = lsb_->eval_const(des, path); if (msb == 0) { cerr << get_line() << ": Unable to evaluate expression " @@ -563,20 +575,61 @@ NetNet* PEBinary::elaborate_net(Design*des, const string&path) const return osig; } +/* + * The concatenation operator, as a net, is a wide signal that is + * connected to all the pins of the elaborated expression nets. + */ +NetNet* PEConcat::elaborate_net(Design*des, const string&path) const +{ + svectornets (parms_.count()); + unsigned pins = 0; + + /* Elaborate the operands of the concatenation. */ + for (unsigned idx = 0 ; idx < nets.count() ; idx += 1) { + nets[idx] = parms_[idx]->elaborate_net(des, path); + pins += nets[idx]->pin_count(); + } + + /* Make the temporary signal that connects to all the + operands, and connect it up. Scan the operands of the + concat operator from least significant to most significant, + which is opposite from how they are given in the list. */ + NetNet*osig = new NetNet(des->local_symbol(path), + NetNet::IMPLICIT, pins); + pins = 0; + for (unsigned idx = nets.count() ; idx > 0 ; idx -= 1) { + NetNet*cur = nets[idx-1]; + for (unsigned pin = 0 ; pin < cur->pin_count() ; pin += 1) { + connect(osig->pin(pins), cur->pin(pin)); + pins += 1; + } + } + + osig->local_flag(true); + des->add_signal(osig); + return osig; +} + NetNet* PEIdent::elaborate_net(Design*des, const string&path) const { NetNet*sig = des->find_signal(path+"."+text_); if (msb_ && lsb_) { - verinum*mval = msb_->eval_const(); + verinum*mval = msb_->eval_const(des, path); assert(mval); - verinum*lval = lsb_->eval_const(); + verinum*lval = lsb_->eval_const(des, path); assert(lval); unsigned midx = sig->sb_to_idx(mval->as_long()); unsigned lidx = sig->sb_to_idx(lval->as_long()); if (midx >= lidx) { NetTmp*tmp = new NetTmp(midx-lidx+1); + if (tmp->pin_count() > sig->pin_count()) { + cerr << get_line() << ": bit select out of " + << "range for " << sig->name() << endl; + return sig; + } + for (unsigned idx = lidx ; idx <= midx ; idx += 1) connect(tmp->pin(idx-lidx), sig->pin(idx)); @@ -584,6 +637,7 @@ NetNet* PEIdent::elaborate_net(Design*des, const string&path) const } else { NetTmp*tmp = new NetTmp(lidx-midx+1); + assert(tmp->pin_count() <= sig->pin_count()); for (unsigned idx = lidx ; idx >= midx ; idx -= 1) connect(tmp->pin(idx-midx), sig->pin(idx)); @@ -591,7 +645,7 @@ NetNet* PEIdent::elaborate_net(Design*des, const string&path) const } } else if (msb_) { - verinum*mval = msb_->eval_const(); + verinum*mval = msb_->eval_const(des, path); assert(mval); unsigned idx = sig->sb_to_idx(mval->as_long()); NetTmp*tmp = new NetTmp(1); @@ -751,12 +805,41 @@ NetProc* Statement::elaborate(Design*des, const string&path) const return cur; } +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) { + cerr << get_line() << ": " << "failed to elaborate expression." + << endl; + return 0; + } + assert(rval); + + NetExpr*idx = ix->elaborate_expr(des, path); + assert(idx); + + NetAssignMem*am = new NetAssignMem(mem, idx, rval); + am->set_line(*this); + return am; +} + NetProc* PAssign::elaborate(Design*des, const string&path) const { - NetNet*reg = des->find_signal(path+"."+lval()); + 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); + + + NetNet*reg = des->find_signal(path+"."+id->name()); + if (reg == 0) { cerr << get_line() << ": Could not match signal: " << - lval() << endl; + id->name() << endl; return 0; } assert(reg); @@ -856,7 +939,7 @@ NetProc* PCallTask::elaborate(Design*des, const string&path) const NetProc* PDelayStatement::elaborate(Design*des, const string&path) const { - verinum*num = delay_->eval_const(); + verinum*num = delay_->eval_const(des, path); assert(num); unsigned long val = num->as_ulong(); @@ -897,8 +980,8 @@ NetProc* PEventStatement::elaborate(Design*des, const string&path) const cerr << get_line() << ": Failed to elaborate expression: "; expr_[0]->dump(cerr); cerr << endl; - delete pe; - return 0; + des->errors += 1; + continue; } assert(expr); @@ -930,8 +1013,13 @@ NetProc* PEventStatement::elaborate(Design*des, const string&path) const */ NetProc* PForStatement::elaborate(Design*des, const string&path) const { + const PEIdent*id1 = dynamic_cast(name1_); + assert(id1); + const PEIdent*id2 = dynamic_cast(name2_); + assert(id2); + NetBlock*top = new NetBlock(NetBlock::SEQU); - NetNet*sig = des->find_signal(path+"."+name1_); + NetNet*sig = des->find_signal(path+"."+id1->name()); assert(sig); NetAssign*init = new NetAssign(sig, expr1_->elaborate_expr(des, path)); top->append(init); @@ -940,7 +1028,7 @@ NetProc* PForStatement::elaborate(Design*des, const string&path) const body->append(statement_->elaborate(des, path)); - sig = des->find_signal(path+"."+name2_); + sig = des->find_signal(path+"."+id2->name()); assert(sig); NetAssign*step = new NetAssign(sig, expr2_->elaborate_expr(des, path)); body->append(step); @@ -1060,6 +1148,15 @@ Design* elaborate(const map&modules, /* * $Log: elaborate.cc,v $ + * Revision 1.25 1999/05/10 00:16:58 steve + * Parse and elaborate the concatenate operator + * in structural contexts, Replace vector + * and list with svector, evaluate + * constant expressions with parameters, handle + * memories as lvalues. + * + * Parse task declarations, integer types. + * * Revision 1.24 1999/05/05 03:04:46 steve * Fix handling of null delay statements. * diff --git a/eval.cc b/eval.cc index b80f695811..9959285677 100644 --- a/eval.cc +++ b/eval.cc @@ -17,23 +17,71 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: eval.cc,v 1.1 1998/11/03 23:28:58 steve Exp $" +#ident "$Id: eval.cc,v 1.2 1999/05/10 00:16:58 steve Exp $" #endif # include "PExpr.h" +# include "netlist.h" -verinum* PExpr::eval_const() const +verinum* PExpr::eval_const(const Design*, const string&) const { return 0; } -verinum* PENumber::eval_const() const +verinum* PEBinary::eval_const(const Design*des, const string&path) const +{ + verinum*l = left_->eval_const(des, path); + if (l == 0) return 0; + verinum*r = right_->eval_const(des, path); + if (r == 0) { + delete l; + return 0; + } + + verinum*res; + + switch (op_) { + case '-': { + long lv = l->as_long(); + long rv = r->as_long(); + res = new verinum(lv-rv, l->len()); + break; + } + default: + delete l; + delete r; + return 0; + } + + return res; +} + +verinum* PEIdent::eval_const(const Design*des, const string&path) const +{ + assert(msb_ == 0); + NetExpr*expr = des->get_parameter(path + "." + text_); + if (expr == 0) return 0; + NetEConst*eval = dynamic_cast(expr); + assert(eval); + return new verinum(eval->value()); +} + +verinum* PENumber::eval_const(const Design*, const string&) const { return new verinum(value()); } /* * $Log: eval.cc,v $ + * Revision 1.2 1999/05/10 00:16:58 steve + * Parse and elaborate the concatenate operator + * in structural contexts, Replace vector + * and list with svector, evaluate + * constant expressions with parameters, handle + * memories as lvalues. + * + * Parse task declarations, integer types. + * * Revision 1.1 1998/11/03 23:28:58 steve * Introduce verilog to CVS. * diff --git a/netlist.cc b/netlist.cc index cbfcbb33ad..13efce97aa 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.22 1999/05/01 02:57:53 steve Exp $" +#ident "$Id: netlist.cc,v 1.23 1999/05/10 00:16:58 steve Exp $" #endif # include @@ -284,6 +284,16 @@ NetAssign::~NetAssign() { } +NetAssignMem::NetAssignMem(NetMemory*m, NetExpr*i, NetExpr*r) +: mem_(m), index_(i), rval_(r) +{ +} + +NetAssignMem::~NetAssignMem() +{ +} + + /* * This method looks at the objects connected to me, and searches for * a signal that I am fully connected to. Return that signal, and the @@ -1040,6 +1050,15 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*)) /* * $Log: netlist.cc,v $ + * Revision 1.23 1999/05/10 00:16:58 steve + * Parse and elaborate the concatenate operator + * in structural contexts, Replace vector + * and list with svector, evaluate + * constant expressions with parameters, handle + * memories as lvalues. + * + * Parse task declarations, integer types. + * * Revision 1.22 1999/05/01 02:57:53 steve * Handle much more complex event expressions. * diff --git a/netlist.h b/netlist.h index e3b1bc6a7f..a4fc5dc6c8 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.28 1999/05/01 20:43:55 steve Exp $" +#ident "$Id: netlist.h,v 1.29 1999/05/10 00:16:58 steve Exp $" #endif /* @@ -614,6 +614,24 @@ class NetAssign : public NetProc, public NetNode, public LineInfo { NetExpr::REF rval_; }; +/* + * Assignment to memory is handled separately because memory is + * not a node. + */ +class NetAssignMem : public NetProc, public LineInfo { + + public: + explicit NetAssignMem(NetMemory*, NetExpr*idx, NetExpr*rv); + ~NetAssignMem(); + + virtual void dump(ostream&, unsigned ind) const; + + private: + NetMemory*mem_; + NetExpr::REF index_; + NetExpr::REF rval_; +}; + /* A block is stuff line begin-end blocks, that contain and ordered list of NetProc statements. @@ -1155,6 +1173,15 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.29 1999/05/10 00:16:58 steve + * Parse and elaborate the concatenate operator + * in structural contexts, Replace vector + * and list with svector, evaluate + * constant expressions with parameters, handle + * memories as lvalues. + * + * Parse task declarations, integer types. + * * Revision 1.28 1999/05/01 20:43:55 steve * Handle wide events, such as @(a) where a has * many bits in it. diff --git a/parse.y b/parse.y index 88d22333fe..3dd785a7a8 100644 --- a/parse.y +++ b/parse.y @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: parse.y,v 1.24 1999/05/08 20:19:20 steve Exp $" +#ident "$Id: parse.y,v 1.25 1999/05/10 00:16:58 steve Exp $" #endif # include "parse_misc.h" @@ -41,7 +41,7 @@ extern void lex_end_table(); svector*gates; PExpr*expr; - list*exprs; + svector*exprs; svector*event_expr; @@ -88,7 +88,7 @@ extern void lex_end_table(); %type udp_port_decl udp_port_decls %type udp_initial udp_init_opt -%type identifier lpvalue register_variable +%type identifier register_variable %type register_variable_list %type list_of_variables @@ -102,7 +102,7 @@ extern void lex_end_table(); %type gate_instance_list %type bitsel delay delay_opt expression expr_primary const_expression -%type lavalue +%type lavalue lpvalue %type expression_list %type range range_opt @@ -182,12 +182,18 @@ const_expression yyerror(@1, "XXXX internal error: const_expression."); $$ = 0; } else { - $$ = new PENumber(tmp); + PENumber*tmp = new PENumber($1); + tmp->set_file(@1.text); + tmp->set_lineno(@1.first_line); + $$ = tmp; } } | STRING - { $$ = new PEString(*$1); + { PEString*tmp = new PEString(*$1); + tmp->set_file(@2.text); + tmp->set_lineno(@2.first_line); delete $1; + $$ = tmp; } | IDENTIFIER { if (!pform_is_parameter(*$1)) { @@ -204,7 +210,10 @@ const_expression } } | const_expression '-' const_expression - { $$ = new PEBinary('-', $1, $3); + { PEBinary*tmp = new PEBinary('-', $1, $3); + tmp->set_file(@2.text); + tmp->set_lineno(@2.first_line); + $$ = tmp; } ; @@ -307,8 +316,9 @@ expression | '(' expression ')' { $$ = $2; } | '{' expression_list '}' - { yyerror(@1, "Sorry, concatenation operator not supported."); - $$ = 0; + { PEConcat*tmp = new PEConcat(*$2); + delete $2; + $$ = tmp; } | '~' expression %prec UNARY_PREC { $$ = new PEUnary('~', $2); @@ -363,18 +373,18 @@ expression expression_list : expression_list ',' expression - { list*tmp = $1; - tmp->push_back($3); + { svector*tmp = new svector(*$1, $3); + delete $1; $$ = tmp; } | expression - { list*tmp = new list; - tmp->push_back($1); + { svector*tmp = new svector(1); + (*tmp)[0] = $1; $$ = tmp; } | expression_list ',' - { list*tmp = $1; - tmp->push_back(0); + { svector*tmp = new svector(*$1, 0); + delete $1; $$ = tmp; } ; @@ -437,13 +447,11 @@ gate_instance } | IDENTIFIER range '(' expression_list ')' { lgate*tmp = new lgate; - list*rng = $2; + svector*rng = $2; tmp->name = *$1; tmp->parms = $4; - tmp->range[0] = rng->front(); - rng->pop_front(); - tmp->range[1] = rng->front(); - rng->pop_front(); + tmp->range[0] = (*rng)[0]; + tmp->range[1] = (*rng)[1]; tmp->file = @1.text; tmp->lineno = @1.first_line; delete $1; @@ -566,18 +574,24 @@ list_of_variables lavalue : IDENTIFIER { PEIdent*tmp = new PEIdent(*$1); + tmp->set_file(@1.text); + tmp->set_lineno(@1.first_line); delete $1; $$ = tmp; } | IDENTIFIER bitsel { PEIdent*tmp = new PEIdent(*$1); tmp->msb_ = $2; + tmp->set_file(@1.text); + tmp->set_lineno(@1.first_line); delete $1; $$ = tmp; } | IDENTIFIER range { PEIdent*tmp = new PEIdent(*$1); yyerror(@3, "Sorry, lvalue bit range not supported."); + tmp->set_file(@1.text); + tmp->set_lineno(@1.first_line); delete $1; delete $2; $$ = tmp; @@ -593,12 +607,21 @@ lavalue /* An lpvalue is the expression that can go on the left side of a procedural assignment. This rule handles only procedural assignments. */ lpvalue - : identifier { $$ = $1; } + : identifier + { PEIdent*tmp = new PEIdent(*$1); + tmp->set_file(@1.text); + tmp->set_lineno(@1.first_line); + delete $1; + $$ = tmp; + } | identifier '[' expression ']' - { yyerror(@2, "Sorry, bit/memory selects " - "not supported in lvalue."); - $$ = $1; - delete $3; + { PEIdent*tmp = new PEIdent(*$1); + tmp->msb_ = $3; + tmp->set_file(@1.text); + tmp->set_lineno(@1.first_line); + delete $1; + + $$ = tmp; } | '{' expression_list '}' { yyerror(@1, "Sorry, concatenation expressions" @@ -753,9 +776,9 @@ port_type range : '[' const_expression ':' const_expression ']' - { list*tmp = new list; - tmp->push_back($2); - tmp->push_back($4); + { svector*tmp = new svector (2); + (*tmp)[0] = $2; + (*tmp)[1] = $4; $$ = tmp; } ; @@ -830,9 +853,7 @@ statement } | K_for '(' lpvalue '=' expression ';' expression ';' lpvalue '=' expression ')' statement - { $$ = new PForStatement(*$3, $5, $7, *$9, $11, $13); - delete $3; - delete $9; + { $$ = new PForStatement($3, $5, $7, $9, $11, $13); } | K_for '(' lpvalue '=' expression ';' expression ';' error ')' statement @@ -873,18 +894,24 @@ statement } } | lpvalue '=' expression ';' - { Statement*tmp = pform_make_assignment($1, $3); + { PAssign*tmp = new PAssign($1,$3); tmp->set_file(@1.text); tmp->set_lineno(@1.first_line); $$ = tmp; } | lpvalue K_LE expression ';' - { $$ = pform_make_assignment($1, $3); - yyerror(@1, "Sorry, non-blocking assignment not implemented."); + { yyerror(@1, "Sorry, non-blocking assignment not implemented."); + PAssign*tmp = new PAssign($1,$3); + tmp->set_file(@1.text); + tmp->set_lineno(@1.first_line); + $$ = tmp; } | lpvalue '=' delay expression ';' - { $$ = pform_make_assignment($1, $3); - yyerror(@1, "Sorry, assignment timing control not implemented."); + { yyerror(@1, "Sorry, assignment timing control not implemented."); + PAssign*tmp = new PAssign($1,$3); + tmp->set_file(@1.text); + tmp->set_lineno(@1.first_line); + $$ = tmp; } | K_wait '(' expression ')' statement_opt { PEventStatement*tmp; @@ -995,7 +1022,8 @@ udp_sequ_entry udp_initial : K_initial IDENTIFIER '=' NUMBER ';' { PExpr*etmp = new PENumber($4); - PAssign*atmp = new PAssign(*$2, etmp); + PEIdent*itmp = new PEIdent(*$2); + PAssign*atmp = new PAssign(itmp, etmp); atmp->set_file(@2.text); atmp->set_lineno(@2.first_line); delete $2; diff --git a/pform.cc b/pform.cc index da22356799..0497d97e04 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.16 1999/05/08 20:19:20 steve Exp $" +#ident "$Id: pform.cc,v 1.17 1999/05/10 00:16:58 steve Exp $" #endif # include "pform.h" @@ -186,8 +186,11 @@ void pform_make_udp(string*name, list*parms, PAssign*pa = dynamic_cast(init_expr); assert(pa); + const PEIdent*id = dynamic_cast(pa->lval()); + assert(id); + // XXXX - assert(pa->lval() == pins[0]->name); + assert(id->name() == pins[0]->name); const PENumber*np = dynamic_cast(pa->get_expr()); assert(np); @@ -236,14 +239,7 @@ void pform_makegate(PGBuiltin::Type type, unsigned long delay_val, const lgate&info) { - vectorwires (info.parms->size()); - for (unsigned idx = 0 ; idx < wires.size() ; idx += 1) { - PExpr*ep = info.parms->front(); - info.parms->pop_front(); - wires[idx] = ep; - } - - PGBuiltin*cur = new PGBuiltin(type, info.name, wires, delay_val); + PGBuiltin*cur = new PGBuiltin(type, info.name, *info.parms, delay_val); if (info.range[0]) cur->set_range(info.range[0], info.range[1]); @@ -266,10 +262,10 @@ void pform_makegates(PGBuiltin::Type type, delete gates; } -void pform_make_modgate(const string&type, - const string&name, - const vector&wires, - const string&fn, unsigned ln) +static void pform_make_modgate(const string&type, + const string&name, + const svector&wires, + const string&fn, unsigned ln) { if (name == "") { cerr << fn << ":" << ln << ": Instantiation of " << type @@ -289,15 +285,15 @@ void pform_make_modgates(const string&type, svector*gates) for (unsigned idx = 0 ; idx < gates->count() ; idx += 1) { lgate cur = (*gates)[idx]; - vectorwires (cur.parms? cur.parms->size() : 0); - for (unsigned idx = 0 ; idx < wires.size() ; idx += 1) { - PExpr*ep = cur.parms->front(); - cur.parms->pop_front(); - - wires[idx] = ep; + if (cur.parms) { + svectorwires = *cur.parms; + pform_make_modgate(type, cur.name, wires, cur.file, + cur.lineno); + } else { + svectorwires (0); + pform_make_modgate(type, cur.name, wires, cur.file, + cur.lineno); } - - pform_make_modgate(type, cur.name, wires, cur.file, cur.lineno); } delete gates; @@ -305,7 +301,7 @@ void pform_make_modgates(const string&type, svector*gates) void pform_make_pgassign(PExpr*lval, PExpr*rval) { - vector wires (2); + svector wires (2); wires[0] = lval; wires[1] = rval; PGAssign*cur = new PGAssign(wires); @@ -391,9 +387,9 @@ void pform_set_reg_idx(const string&name, PExpr*l, PExpr*r) cur->ridx = r; } -static void pform_set_net_range(const string&name, list*range) +static void pform_set_net_range(const string&name, const svector*range) { - assert(range->size() == 2); + assert(range->count() == 2); PWire*cur = cur_module->get_wire(name); if (cur == 0) { @@ -402,15 +398,11 @@ static void pform_set_net_range(const string&name, list*range) } if ((cur->msb == 0) && (cur->lsb == 0)){ - list::const_iterator idx = range->begin(); - cur->msb = *idx; - idx ++; - cur->lsb = *idx; + cur->msb = (*range)[0]; + cur->lsb = (*range)[1]; } else { - list::const_iterator idx = range->begin(); - PExpr*msb = *idx; - idx ++; - PExpr*lsb = *idx; + PExpr*msb = (*range)[0]; + PExpr*lsb = (*range)[1]; if (msb == 0) { VLerror(yylloc, "failed to parse msb of range."); } else if (lsb == 0) { @@ -419,8 +411,8 @@ static void pform_set_net_range(const string&name, list*range) cur->lsb->is_the_same(lsb))) { VLerror(yylloc, "net ranges are not identical."); } - delete msb; - delete lsb; + //delete msb; + //delete lsb; } } @@ -445,9 +437,9 @@ void pform_set_port_type(list*names, NetNet::PortType pt) } } -void pform_set_net_range(list*names, list*range) +void pform_set_net_range(list*names, const svector*range) { - assert(range->size() == 2); + assert(range->count() == 2); for (list::const_iterator cur = names->begin() ; cur != names->end() @@ -489,17 +481,10 @@ Statement* pform_make_block(PBlock::BL_TYPE type, list*sl) return bl; } -Statement* pform_make_assignment(string*text, PExpr*ex) -{ - PAssign*st = new PAssign (*text, ex); - delete text; - return st; -} - -Statement* pform_make_calltask(string*name, list*parms) +Statement* pform_make_calltask(string*name, svector*parms) { if (parms == 0) - parms = new list; + parms = new svector(0); PCallTask*ct = new PCallTask(*name, *parms); delete name; @@ -533,6 +518,15 @@ int pform_parse(const char*path, map&modules, /* * $Log: pform.cc,v $ + * Revision 1.17 1999/05/10 00:16:58 steve + * Parse and elaborate the concatenate operator + * in structural contexts, Replace vector + * and list with svector, evaluate + * constant expressions with parameters, handle + * memories as lvalues. + * + * Parse task declarations, integer types. + * * Revision 1.16 1999/05/08 20:19:20 steve * Parse more things. * diff --git a/pform.h b/pform.h index 59e73fc118..b97b4c8b5b 100644 --- a/pform.h +++ b/pform.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: pform.h,v 1.12 1999/05/07 04:26:49 steve Exp $" +#ident "$Id: pform.h,v 1.13 1999/05/10 00:16:58 steve Exp $" #endif # include "netlist.h" @@ -70,7 +70,7 @@ struct lgate { } string name; - list*parms; + svector*parms; PExpr*range[2]; @@ -100,7 +100,7 @@ extern void pform_make_udp(string*name, list*parms, extern void pform_makewire(const string&name, NetNet::Type type = NetNet::IMPLICIT); extern void pform_makewire(const list*names, NetNet::Type type); extern void pform_set_port_type(list*names, NetNet::PortType); -extern void pform_set_net_range(list*names, list*); +extern void pform_set_net_range(list*names, const svector*); extern void pform_set_reg_idx(const string&name, PExpr*l, PExpr*r); extern void pform_set_attrib(const string&name, const string&key, const string&value); @@ -110,8 +110,7 @@ extern void pform_set_parameter(const string&name, PExpr*expr); extern bool pform_is_parameter(const string&name); extern PProcess* pform_make_behavior(PProcess::Type, Statement*); extern Statement* pform_make_block(PBlock::BL_TYPE, list*); -extern Statement* pform_make_assignment(string*t, PExpr*e); -extern Statement* pform_make_calltask(string*t, list* =0); +extern Statement* pform_make_calltask(string*t, svector* =0); extern list* pform_make_udp_input_ports(list*); @@ -140,6 +139,15 @@ extern void pform_dump(ostream&out, Module*mod); /* * $Log: pform.h,v $ + * Revision 1.13 1999/05/10 00:16:58 steve + * Parse and elaborate the concatenate operator + * in structural contexts, Replace vector + * and list with svector, evaluate + * constant expressions with parameters, handle + * memories as lvalues. + * + * Parse task declarations, integer types. + * * Revision 1.12 1999/05/07 04:26:49 steve * Parse more complex continuous assign lvalues. * diff --git a/pform_dump.cc b/pform_dump.cc index 6e54531240..578e53944d 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.15 1999/05/05 03:04:46 steve Exp $" +#ident "$Id: pform_dump.cc,v 1.16 1999/05/10 00:16:58 steve Exp $" #endif /* @@ -42,6 +42,20 @@ void PExpr::dump(ostream&out) const out << typeid(*this).name(); } +void PEConcat::dump(ostream&out) const +{ + if (parms_.count() == 0) { + out << "{}"; + return; + } + + out << "{" << *parms_[0]; + for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) + out << ", " << *parms_[idx]; + + out << "}"; +} + void PEEvent::dump(ostream&out) const { switch (type_) { @@ -229,7 +243,7 @@ void Statement::dump(ostream&out, unsigned ind) const void PAssign::dump(ostream&out, unsigned ind) const { out << setw(ind) << ""; - out << to_name_ << " = " << *expr_ << ";"; + out << *lval_ << " = " << *expr_ << ";"; out << " /* " << get_line() << " */" << endl; } @@ -248,12 +262,12 @@ void PCallTask::dump(ostream&out, unsigned ind) const { out << setw(ind) << "" << name_; - if (nparms_) { + if (parms_.count() > 0) { out << "("; if (parms_[0]) out << *parms_[0]; - for (unsigned idx = 1 ; idx < nparms_ ; idx += 1) { + for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) { out << ", "; if (parms_[idx]) out << *parms_[idx]; @@ -440,6 +454,15 @@ void PUdp::dump(ostream&out) const /* * $Log: pform_dump.cc,v $ + * Revision 1.16 1999/05/10 00:16:58 steve + * Parse and elaborate the concatenate operator + * in structural contexts, Replace vector + * and list with svector, evaluate + * constant expressions with parameters, handle + * memories as lvalues. + * + * Parse task declarations, integer types. + * * Revision 1.15 1999/05/05 03:04:46 steve * Fix handling of null delay statements. *