diff --git a/Statement.h b/Statement.h index 9206289a9..690c8014a 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.17 1999/09/04 19:11:46 steve Exp $" +#ident "$Id: Statement.h,v 1.18 1999/09/15 01:55:06 steve Exp $" #endif # include @@ -120,6 +120,10 @@ class PAssignNB : public 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; }; /* @@ -333,6 +337,9 @@ class PWhile : public Statement { /* * $Log: Statement.h,v $ + * Revision 1.18 1999/09/15 01:55:06 steve + * Elaborate non-blocking assignment to memories. + * * Revision 1.17 1999/09/04 19:11:46 steve * Add support for delayed non-blocking assignments. * diff --git a/design_dump.cc b/design_dump.cc index 7c8f25771..b2b4c0b38 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.39 1999/09/04 19:11:46 steve Exp $" +#ident "$Id: design_dump.cc,v 1.40 1999/09/15 01:55:06 steve Exp $" #endif /* @@ -369,10 +369,22 @@ 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 << memory()->name() << "["; + index()->dump(o); o << "] = "; - rval_->dump(o); + rval()->dump(o); + o << ";" << endl; +} + +void NetAssignMemNB::dump(ostream&o, unsigned ind) const +{ + o << setw(ind) << ""; + o << "/* " << get_line() << " */" << endl; + o << setw(ind) << ""; + o << memory()->name() << "["; + index()->dump(o); + o << "] <= "; + rval()->dump(o); o << ";" << endl; } @@ -733,6 +745,9 @@ void Design::dump(ostream&o) const /* * $Log: design_dump.cc,v $ + * Revision 1.40 1999/09/15 01:55:06 steve + * Elaborate non-blocking assignment to memories. + * * Revision 1.39 1999/09/04 19:11:46 steve * Add support for delayed non-blocking assignments. * diff --git a/elaborate.cc b/elaborate.cc index 207325e0d..d82025183 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.84 1999/09/14 01:50:52 steve Exp $" +#ident "$Id: elaborate.cc,v 1.85 1999/09/15 01:55:06 steve Exp $" #endif /* @@ -898,6 +898,11 @@ NetNet* PEIdent::elaborate_net(Design*des, const string&path, { NetNet*sig = des->find_signal(path, text_); if (sig == 0) { + if (des->find_memory(path+"."+text_)) { + cerr << get_line() << ": Sorry, memories not supported" + " in this context." << endl; + return 0; + } sig = new NetNet(path+"."+text_, NetNet::IMPLICIT, 1); des->add_signal(sig); cerr << get_line() << ": warning: Implicitly defining " @@ -938,6 +943,13 @@ NetNet* PEIdent::elaborate_net(Design*des, const string&path, } else if (msb_) { verinum*mval = msb_->eval_const(des, path); + if (mval == 0) { + cerr << get_line() << ": index of " << text_ << + " needs to be constant in this context." << + endl; + des->errors += 1; + return 0; + } assert(mval); unsigned idx = sig->sb_to_idx(mval->as_long()); NetTmp*tmp = new NetTmp(1); @@ -1632,6 +1644,36 @@ NetProc* PAssign::elaborate(Design*des, const string&path) const return cur; } +/* + * I do not really know how to elaborate mem[x] <= expr, so this + * method pretends it is a blocking assign and elaborates + * that. However, I report an error so that the design isn't actually + * executed by anyone. + */ +NetProc* PAssignNB::assign_to_memory_(NetMemory*mem, PExpr*ix, + Design*des, const string&path) const +{ + /* Elaborate the r-value expression, ... */ + NetExpr*rv = rval()->elaborate_expr(des, path); + if (rv == 0) { + cerr << get_line() << ": " << "failed to elaborate expression." + << endl; + return 0; + } + assert(rv); + rv->set_width(mem->width()); + + /* Elaborate the expression to calculate the index, ... */ + NetExpr*idx = ix->elaborate_expr(des, path); + assert(idx); + + /* And connect them together in an assignment NetProc. */ + NetAssignMemNB*am = new NetAssignMemNB(mem, idx, rv); + am->set_line(*this); + + return am; +} + /* * The l-value of a procedural assignment is a very much constrained * expression. To wit, only identifiers, bit selects and part selects @@ -1642,6 +1684,18 @@ NetProc* PAssign::elaborate(Design*des, const string&path) const */ NetProc* PAssignNB::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); @@ -2378,6 +2432,9 @@ Design* elaborate(const map&modules, /* * $Log: elaborate.cc,v $ + * Revision 1.85 1999/09/15 01:55:06 steve + * Elaborate non-blocking assignment to memories. + * * Revision 1.84 1999/09/14 01:50:52 steve * implicitly declare wires if needed. * diff --git a/emit.cc b/emit.cc index 5e6c4a2c3..3ef093164 100644 --- a/emit.cc +++ b/emit.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: emit.cc,v 1.20 1999/09/03 04:28:38 steve Exp $" +#ident "$Id: emit.cc,v 1.21 1999/09/15 01:55:06 steve Exp $" #endif /* @@ -100,6 +100,11 @@ void NetAssignMem::emit_proc(ostream&o, struct target_t*tgt) const tgt->proc_assign_mem(o, this); } +void NetAssignMemNB::emit_proc(ostream&o, struct target_t*tgt) const +{ + tgt->proc_assign_mem_nb(o, this); +} + void NetBlock::emit_proc(ostream&o, struct target_t*tgt) const { tgt->proc_block(o, this); @@ -326,6 +331,9 @@ void emit(ostream&o, const Design*des, const char*type) /* * $Log: emit.cc,v $ + * Revision 1.21 1999/09/15 01:55:06 steve + * Elaborate non-blocking assignment to memories. + * * Revision 1.20 1999/09/03 04:28:38 steve * elaborate the binary plus operator. * diff --git a/netlist.cc b/netlist.cc index 10e4921dd..532ab721b 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.61 1999/09/13 03:10:59 steve Exp $" +#ident "$Id: netlist.cc,v 1.62 1999/09/15 01:55:06 steve Exp $" #endif # include @@ -427,15 +427,33 @@ NetAssignNB::~NetAssignNB() } -NetAssignMem::NetAssignMem(NetMemory*m, NetExpr*i, NetExpr*r) +NetAssignMem_::NetAssignMem_(NetMemory*m, NetExpr*i, NetExpr*r) : mem_(m), index_(i), rval_(r) { } +NetAssignMem_::~NetAssignMem_() +{ +} + +NetAssignMem::NetAssignMem(NetMemory*m, NetExpr*i, NetExpr*r) +: NetAssignMem_(m, i, r) +{ +} + NetAssignMem::~NetAssignMem() { } +NetAssignMemNB::NetAssignMemNB(NetMemory*m, NetExpr*i, NetExpr*r) +: NetAssignMem_(m, i, r) +{ +} + +NetAssignMemNB::~NetAssignMemNB() +{ +} + /* * This method looks at the objects connected to me, and searches for @@ -1782,6 +1800,9 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*)) /* * $Log: netlist.cc,v $ + * Revision 1.62 1999/09/15 01:55:06 steve + * Elaborate non-blocking assignment to memories. + * * Revision 1.61 1999/09/13 03:10:59 steve * Clarify msb/lsb in context of netlist. Properly * handle part selects in lval and rval of expressions, diff --git a/netlist.h b/netlist.h index 2ec149377..9da622225 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.63 1999/09/13 03:10:59 steve Exp $" +#ident "$Id: netlist.h,v 1.64 1999/09/15 01:55:06 steve Exp $" #endif /* @@ -668,27 +668,50 @@ class NetAssignNB : public NetAssign_ { /* * Assignment to memory is handled separately because memory is - * not a node. + * not a node. There are blocking and non-blocking variants, just like + * regular assign, and the NetAssignMem_ base class takes care of all + * the common stuff. */ -class NetAssignMem : public NetProc, public LineInfo { +class NetAssignMem_ : public NetProc, public LineInfo { public: - explicit NetAssignMem(NetMemory*, NetExpr*idx, NetExpr*rv); - ~NetAssignMem(); + explicit NetAssignMem_(NetMemory*, NetExpr*idx, NetExpr*rv); + ~NetAssignMem_(); const NetMemory*memory()const { return mem_; } const NetExpr*index()const { return index_; } const NetExpr*rval()const { return rval_; } - virtual void emit_proc(ostream&, struct target_t*) const; - virtual void dump(ostream&, unsigned ind) const; - private: NetMemory*mem_; NetExpr* index_; NetExpr* rval_; }; +class NetAssignMem : public NetAssignMem_ { + + public: + explicit NetAssignMem(NetMemory*, NetExpr*idx, NetExpr*rv); + ~NetAssignMem(); + + virtual void emit_proc(ostream&, struct target_t*) const; + virtual void dump(ostream&, unsigned ind) const; + + private: +}; + +class NetAssignMemNB : public NetAssignMem_ { + + public: + explicit NetAssignMemNB(NetMemory*, NetExpr*idx, NetExpr*rv); + ~NetAssignMemNB(); + + virtual void emit_proc(ostream&, struct target_t*) const; + virtual void dump(ostream&, unsigned ind) const; + + private: +}; + /* A block is stuff line begin-end blocks, that contain and ordered list of NetProc statements. @@ -1559,6 +1582,9 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.64 1999/09/15 01:55:06 steve + * Elaborate non-blocking assignment to memories. + * * Revision 1.63 1999/09/13 03:10:59 steve * Clarify msb/lsb in context of netlist. Properly * handle part selects in lval and rval of expressions, diff --git a/pform.cc b/pform.cc index 61a7f0388..c8bedf068 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.42 1999/09/10 05:02:09 steve Exp $" +#ident "$Id: pform.cc,v 1.43 1999/09/15 01:55:06 steve Exp $" #endif # include "compiler.h" @@ -625,9 +625,14 @@ static void pform_set_reg_integer(const string&nm) { string name = scoped_name(nm); PWire*cur = pform_cur_module->get_wire(name); + if (cur == 0) { + cur = new PWire(nm, NetNet::INTEGER, NetNet::NOT_A_PORT); + pform_cur_module->add_wire(cur); + } else { + bool rc = cur->set_wire_type(NetNet::INTEGER); + assert(rc); + } assert(cur); - bool rc = cur->set_wire_type(NetNet::INTEGER); - assert(rc); cur->set_range(new PENumber(new verinum(INTEGER_WIDTH-1, INTEGER_WIDTH)), new PENumber(new verinum(0UL, INTEGER_WIDTH))); @@ -693,6 +698,9 @@ int pform_parse(const char*path, map&modules, /* * $Log: pform.cc,v $ + * Revision 1.43 1999/09/15 01:55:06 steve + * Elaborate non-blocking assignment to memories. + * * Revision 1.42 1999/09/10 05:02:09 steve * Handle integers at task parameters. * diff --git a/target.cc b/target.cc index ac43926e8..3befc401a 100644 --- a/target.cc +++ b/target.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: target.cc,v 1.18 1999/09/03 04:28:38 steve Exp $" +#ident "$Id: target.cc,v 1.19 1999/09/15 01:55:06 steve Exp $" #endif # include "target.h" @@ -128,6 +128,12 @@ void target_t::proc_assign_nb(ostream&os, const NetAssignNB*) "Unhandled non-blocking assignment." << endl; } +void target_t::proc_assign_mem_nb(ostream&os, const NetAssignMemNB*) +{ + cerr << "target (" << typeid(*this).name() << "): " + "Unhandled non-blocking memory assignment." << endl; +} + void target_t::proc_block(ostream&os, const NetBlock*) { cerr << "target (" << typeid(*this).name() << "): " @@ -262,6 +268,9 @@ void expr_scan_t::expr_binary(const NetEBinary*ex) /* * $Log: target.cc,v $ + * Revision 1.19 1999/09/15 01:55:06 steve + * Elaborate non-blocking assignment to memories. + * * Revision 1.18 1999/09/03 04:28:38 steve * elaborate the binary plus operator. * diff --git a/target.h b/target.h index e0716c1c4..8aa81b979 100644 --- a/target.h +++ b/target.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: target.h,v 1.17 1999/09/03 04:28:38 steve Exp $" +#ident "$Id: target.h,v 1.18 1999/09/15 01:55:06 steve Exp $" #endif # include "netlist.h" @@ -86,6 +86,7 @@ struct target_t { virtual void proc_assign(ostream&os, const NetAssign*); virtual void proc_assign_mem(ostream&os, const NetAssignMem*); virtual void proc_assign_nb(ostream&os, const NetAssignNB*); + virtual void proc_assign_mem_nb(ostream&os, const NetAssignMemNB*); virtual void proc_block(ostream&os, const NetBlock*); virtual void proc_case(ostream&os, const NetCase*); virtual void proc_condit(ostream&os, const NetCondit*); @@ -135,6 +136,9 @@ extern const struct target *target_table[]; /* * $Log: target.h,v $ + * Revision 1.18 1999/09/15 01:55:06 steve + * Elaborate non-blocking assignment to memories. + * * Revision 1.17 1999/09/03 04:28:38 steve * elaborate the binary plus operator. *