From 30a3953c85d3377821fd261672f18629872d73fa Mon Sep 17 00:00:00 2001 From: steve Date: Mon, 8 Feb 1999 02:49:56 +0000 Subject: [PATCH] Turn the NetESignal into a NetNode so that it can connect to the netlist. Implement the case statement. Convince t-vvm to output code for the case statement. --- design_dump.cc | 18 ++++++- elaborate.cc | 13 ++++- emit.cc | 19 ++++++- netlist.cc | 19 ++++++- netlist.h | 27 +++++++--- t-vvm.cc | 131 ++++++++++++++++++++++++++++++++++++++++++------- target.cc | 22 ++++++++- target.h | 11 ++++- 8 files changed, 225 insertions(+), 35 deletions(-) diff --git a/design_dump.cc b/design_dump.cc index 52b85a249..81d56b4f2 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.11 1999/02/03 04:20:11 steve Exp $" +#ident "$Id: design_dump.cc,v 1.12 1999/02/08 02:49:56 steve Exp $" #endif /* @@ -445,7 +445,14 @@ void NetEIdent::dump(ostream&o) const void NetESignal::dump(ostream&o) const { - o << sig_->name(); + o << name(); +} + +void NetESignal::dump_node(ostream&o, unsigned ind) const +{ + o << setw(ind) << "" << "Expression Node: " << name() << endl; + + dump_node_pins(o, ind+4); } void NetEUnary::dump(ostream&o) const @@ -490,6 +497,13 @@ void Design::dump(ostream&o) const /* * $Log: design_dump.cc,v $ + * Revision 1.12 1999/02/08 02:49:56 steve + * Turn the NetESignal into a NetNode so + * that it can connect to the netlist. + * Implement the case statement. + * Convince t-vvm to output code for + * the case statement. + * * Revision 1.11 1999/02/03 04:20:11 steve * Parse and elaborate the Verilog CASE statement. * diff --git a/elaborate.cc b/elaborate.cc index 936499a4d..7aaa93220 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.13 1999/02/03 04:20:11 steve Exp $" +#ident "$Id: elaborate.cc,v 1.14 1999/02/08 02:49:56 steve Exp $" #endif /* @@ -572,7 +572,9 @@ NetExpr*PEIdent::elaborate_expr(Design*des, const string&path) const string name = path+"."+text_; NetNet*net = des->find_signal(name); assert(net); - return new NetESignal(net); + NetESignal*node = new NetESignal(net); + des->add_node(node); + return node; } } @@ -871,6 +873,13 @@ Design* elaborate(const map&modules, /* * $Log: elaborate.cc,v $ + * Revision 1.14 1999/02/08 02:49:56 steve + * Turn the NetESignal into a NetNode so + * that it can connect to the netlist. + * Implement the case statement. + * Convince t-vvm to output code for + * the case statement. + * * Revision 1.13 1999/02/03 04:20:11 steve * Parse and elaborate the Verilog CASE statement. * diff --git a/emit.cc b/emit.cc index a196255b8..91bb7af76 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.5 1999/02/01 00:26:49 steve Exp $" +#ident "$Id: emit.cc,v 1.6 1999/02/08 02:49:56 steve Exp $" #endif /* @@ -90,6 +90,11 @@ void NetBlock::emit_proc(ostream&o, struct target_t*tgt) const tgt->proc_block(o, this); } +void NetCase::emit_proc(ostream&o, struct target_t*tgt) const +{ + tgt->proc_case(o, this); +} + void NetCondit::emit_proc(ostream&o, struct target_t*tgt) const { tgt->proc_condit(o, this); @@ -205,6 +210,11 @@ void NetESignal::expr_scan(struct expr_scan_t*tgt) const tgt->expr_signal(this); } +void NetESignal::emit_node(ostream&o, struct target_t*tgt) const +{ + tgt->net_esignal(o, this); +} + void NetEUnary::expr_scan(struct expr_scan_t*tgt) const { tgt->expr_unary(this); @@ -224,6 +234,13 @@ void emit(ostream&o, const Design*des, const char*type) /* * $Log: emit.cc,v $ + * Revision 1.6 1999/02/08 02:49:56 steve + * Turn the NetESignal into a NetNode so + * that it can connect to the netlist. + * Implement the case statement. + * Convince t-vvm to output code for + * the case statement. + * * Revision 1.5 1999/02/01 00:26:49 steve * Carry some line info to the netlist, * Dump line numbers for processes. diff --git a/netlist.cc b/netlist.cc index 671618f23..17af09026 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.15 1999/02/03 04:20:11 steve Exp $" +#ident "$Id: netlist.cc,v 1.16 1999/02/08 02:49:56 steve Exp $" #endif # include @@ -423,13 +423,21 @@ void NetEConst::set_width(unsigned w) expr_width(w); } +NetESignal::NetESignal(NetNet*n) +: NetExpr(n->pin_count()), NetNode(n->name(), n->pin_count()) +{ + for (unsigned idx = 0 ; idx < n->pin_count() ; idx += 1) { + connect(pin(idx), n->pin(idx)); + } +} + NetESignal::~NetESignal() { } void NetESignal::set_width(unsigned w) { - assert(w == sig_->pin_count()); + assert(w == pin_count()); expr_width(w); } @@ -873,6 +881,13 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*)) /* * $Log: netlist.cc,v $ + * Revision 1.16 1999/02/08 02:49:56 steve + * Turn the NetESignal into a NetNode so + * that it can connect to the netlist. + * Implement the case statement. + * Convince t-vvm to output code for + * the case statement. + * * Revision 1.15 1999/02/03 04:20:11 steve * Parse and elaborate the Verilog CASE statement. * diff --git a/netlist.h b/netlist.h index f817b1939..f2f5509e3 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.17 1999/02/03 04:20:11 steve Exp $" +#ident "$Id: netlist.h,v 1.18 1999/02/08 02:49:56 steve Exp $" #endif /* @@ -543,7 +543,13 @@ class NetCase : public NetProc { void set_case(unsigned idx, NetExpr*ex, NetProc*st); - //virtual void emit_proc(ostream&, struct target_t*) const; + const NetExpr*expr() const { return expr_; } + unsigned nitems() const { return nitems_; } + + const NetExpr*expr(unsigned idx) const { return items_[idx].guard; } + const NetProc*stat(unsigned idx) const { return items_[idx].statement; } + + virtual void emit_proc(ostream&, struct target_t*) const; virtual void dump(ostream&, unsigned ind) const; private: @@ -823,22 +829,22 @@ class NetEIdent : public NetExpr { /* When a signal shows up in an expression, this type represents it. From this the expression can get any kind of access to the structural signal. */ -class NetESignal : public NetExpr { +class NetESignal : public NetExpr, public NetNode { public: - NetESignal(NetNet*n) - : NetExpr(n->pin_count()), sig_(n) { } + NetESignal(NetNet*n); ~NetESignal(); - const string& name() const { return sig_->name(); } + const string& name() const { return NetNode::name(); } virtual void set_width(unsigned); virtual void expr_scan(struct expr_scan_t*) const; + virtual void emit_node(ostream&, struct target_t*) const; virtual void dump(ostream&) const; + virtual void dump_node(ostream&, unsigned ind) const; private: - NetNet*sig_; }; /* @@ -953,6 +959,13 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.18 1999/02/08 02:49:56 steve + * Turn the NetESignal into a NetNode so + * that it can connect to the netlist. + * Implement the case statement. + * Convince t-vvm to output code for + * the case statement. + * * Revision 1.17 1999/02/03 04:20:11 steve * Parse and elaborate the Verilog CASE statement. * diff --git a/t-vvm.cc b/t-vvm.cc index 24b91bc89..4d90ecce9 100644 --- a/t-vvm.cc +++ b/t-vvm.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: t-vvm.cc,v 1.9 1999/01/01 01:46:01 steve Exp $" +#ident "$Id: t-vvm.cc,v 1.10 1999/02/08 02:49:56 steve Exp $" #endif # include @@ -45,10 +45,12 @@ class target_vvm : public target_t { virtual void bufz(ostream&os, const NetBUFZ*); virtual void udp(ostream&os, const NetUDP*); virtual void net_const(ostream&os, const NetConst*); + virtual void net_esignal(ostream&os, const NetESignal*); virtual void net_pevent(ostream&os, const NetPEvent*); virtual void start_process(ostream&os, const NetProcTop*); virtual void proc_assign(ostream&os, const NetAssign*); virtual void proc_block(ostream&os, const NetBlock*); + virtual void proc_case(ostream&os, const NetCase*net); virtual void proc_condit(ostream&os, const NetCondit*); virtual void proc_task(ostream&os, const NetTask*); virtual void proc_while(ostream&os, const NetWhile*); @@ -307,10 +309,10 @@ void target_vvm::signal(ostream&os, const NetNet*sig) if (sig->get_ival(idx) == verinum::Vz) continue; - for (NetObj::Link*lnk = sig->pin(0).next_link() + for (const NetObj::Link*lnk = sig->pin(0).next_link() ; (*lnk) != sig->pin(0) ; lnk = lnk->next_link()) { const NetNode*net; - if (net = dynamic_cast(lnk->get_obj())) { + if ((net = dynamic_cast(lnk->get_obj()))) { init_code << " " << mangle(lnk->get_obj()->name()) << ".init(" << lnk->get_pin() << ", V" << @@ -520,6 +522,10 @@ void target_vvm::net_const(ostream&os, const NetConst*gate) emit_gate_outputfun_(gate); } +void target_vvm::net_esignal(ostream&, const NetESignal*) +{ +} + /* * The net_pevent device is a synthetic device type--a fabrication of * the elaboration phase. An event device receives value changes from @@ -574,18 +580,17 @@ void target_vvm::proc_assign(ostream&os, const NetAssign*net) net->find_lval_range(lval, msb, lsb); if ((lsb == 0) && (msb == (lval->pin_count()-1))) { - os << setw(indent_) << "" << "// " << lval->name() - << " = "; + os << " // " << lval->name() << " = "; net->rval()->dump(os); os << endl; - os << setw(indent_) << "" << mangle(lval->name()) + os << " " << mangle(lval->name()) << " = " << rval << ";" << endl; } else { assert(0); } - os << setw(indent_) << "" << mangle(lval->name()) << + os << " " << mangle(lval->name()) << "_mon.trigger(sim_);" << endl; @@ -603,15 +608,20 @@ void target_vvm::proc_assign(ostream&os, const NetAssign*net) if (dynamic_cast(cur)) continue; + // Skip NetESignal nodes. They are handled as + // expressions. + if (dynamic_cast(cur)) + continue; + if (const NetNet*sig = dynamic_cast(cur)) { - os << setw(indent_) << "" << mangle(sig->name()) + os << " " << mangle(sig->name()) << "[" << pin << "] = " << rval << "[" << idx << "];" << endl; - os <name()) + os << " " << mangle(sig->name()) << "_mon.trigger(sim_);" << endl; } else { - os << setw(indent_) << "" << mangle(cur->name()) << + os << " " << mangle(cur->name()) << ".set(sim_, " << pin << ", " << rval << "[" << idx << "]);" << endl; } @@ -624,19 +634,95 @@ void target_vvm::proc_block(ostream&os, const NetBlock*net) net->emit_recurse(os, this); } +/* + * The code for a case statement introduces basic blocks so causes + * steps to be created. There is a step for each case, and the + * out. For example: + * + * case (foo) + * 1 : X; + * 2 : Y; + * endcase + * Z; + * + * causes code for Z to be generated, and also code for X and Y that + * each branch to Z when they finish. X, Y and Z all generate at least + * one step. + */ +void target_vvm::proc_case(ostream&os, const NetCase*net) +{ + string expr = emit_proc_rval(os, indent_, net->expr()); + + ostrstream sc; + unsigned default_step_ = thread_step_ + 1; + thread_step_ += 1; + + /* Handle the case statement like a computed goto, where the + result of the case statements is the next state to go + to. Once that is done, return true so that statement is + executed. */ + for (unsigned idx = 0 ; idx < net->nitems() ; idx += 1) { + string guard = emit_proc_rval(os, indent_, net->expr(idx)); + + thread_step_ += 1; + + os << " if (" << expr << ".eequal(" << guard << + "))" << endl; + os << " step_ = &step_" << + thread_step_ << "_;" << endl; + + { unsigned save_indent = indent_; + indent_ = 8; + sc << " bool step_" << thread_step_ << "_()" << endl; + sc << " {" << endl; + net->stat(idx)->emit_proc(sc, this); + sc << " step_ = &step_" << default_step_ << "_;" << endl; + sc << " return true;" << endl; + sc << " }" << endl; + indent_ = save_indent; + } + } + + os << " else" << endl; + os << " step_ = &step_" << default_step_ << "_;" << endl; + os << " return true;" << endl; + os << " }" << endl; + os << sc.str(); + os << " bool step_" << default_step_ << "_()" << endl; + os << " {" << endl; +} + void target_vvm::proc_condit(ostream&os, const NetCondit*net) { - unsigned ind = indent_; - indent_ += 4; - string expr = emit_proc_rval(os, indent_, net->expr()); - os << setw(ind) << "" << "if (" << expr << "[0] == V1) {" << endl; - net->emit_recurse_if(os, this); - os << setw(ind) << "" << "} else {" << endl; - net->emit_recurse_else(os, this); - os << setw(ind) << "" << "}" << endl; - indent_ = ind; + unsigned if_step = ++thread_step_; + unsigned else_step = ++thread_step_; + unsigned out_step = ++thread_step_; + + os << " if (" << expr << "[0] == V1)" << endl; + os << " step_ = &step_" << if_step << "_;" << endl; + os << " else" << endl; + os << " step_ = &step_" << else_step << "_;" << endl; + os << " return true;" << endl; + os << " };" << endl; + + os << " bool step_" << if_step << "_()" << endl; + os << " {" << endl; + net->emit_recurse_if(os, this); + os << " step_ = &step_" << out_step << "_;" << endl; + os << " return true;" << endl; + os << " }" << endl; + + os << " bool step_" << else_step << "_()" << endl; + os << " {" << endl; + net->emit_recurse_else(os, this); + os << " step_ = &step_" << out_step << "_;" << endl; + os << " return true;" << endl; + os << " }" << endl; + + os << " bool step_" << out_step << "_()" << endl; + os << " {" << endl; } void target_vvm::proc_task(ostream&os, const NetTask*net) @@ -778,6 +864,13 @@ extern const struct target tgt_vvm = { }; /* * $Log: t-vvm.cc,v $ + * Revision 1.10 1999/02/08 02:49:56 steve + * Turn the NetESignal into a NetNode so + * that it can connect to the netlist. + * Implement the case statement. + * Convince t-vvm to output code for + * the case statement. + * * Revision 1.9 1999/01/01 01:46:01 steve * Add startup after initialization. * diff --git a/target.cc b/target.cc index feee41188..9051c63f0 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.4 1998/12/01 00:42:15 steve Exp $" +#ident "$Id: target.cc,v 1.5 1999/02/08 02:49:56 steve Exp $" #endif # include "target.h" @@ -61,6 +61,12 @@ void target_t::net_const(ostream&os, const NetConst*) "Unhandled CONSTANT node." << endl; } +void target_t::net_esignal(ostream&os, const NetESignal*) +{ + cerr << "target (" << typeid(*this).name() << "): " + "Unhandled Expression Signal node." << endl; +} + void target_t::net_pevent(ostream&os, const NetPEvent*) { cerr << "target (" << typeid(*this).name() << "): " @@ -79,6 +85,13 @@ void target_t::proc_block(ostream&os, const NetBlock*) { } +void target_t::proc_case(ostream&os, const NetCase*cur) +{ + cerr << "target (" << typeid(*this).name() << "): " + "Unhandled case:" << endl; + cur->dump(cerr, 6); +} + void target_t::proc_condit(ostream&os, const NetCondit*condit) { cerr << "target (" << typeid(*this).name() << "): " @@ -153,6 +166,13 @@ void expr_scan_t::expr_binary(const NetEBinary*ex) /* * $Log: target.cc,v $ + * Revision 1.5 1999/02/08 02:49:56 steve + * Turn the NetESignal into a NetNode so + * that it can connect to the netlist. + * Implement the case statement. + * Convince t-vvm to output code for + * the case statement. + * * Revision 1.4 1998/12/01 00:42:15 steve * Elaborate UDP devices, * Support UDP type attributes, and diff --git a/target.h b/target.h index 115250ae6..d8acbf889 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.4 1998/12/01 00:42:15 steve Exp $" +#ident "$Id: target.h,v 1.5 1999/02/08 02:49:56 steve Exp $" #endif # include "netlist.h" @@ -64,6 +64,7 @@ struct target_t { virtual void udp(ostream&os, const NetUDP*); virtual void net_assign(ostream&os, const NetAssign*); virtual void net_const(ostream&os, const NetConst*); + virtual void net_esignal(ostream&os, const NetESignal*); virtual void net_pevent(ostream&os, const NetPEvent*); /* Output a process (called for each process) */ @@ -72,6 +73,7 @@ struct target_t { /* Various kinds of process nodes are dispatched through these. */ virtual void proc_assign(ostream&os, const NetAssign*); virtual void proc_block(ostream&os, const NetBlock*); + virtual void proc_case(ostream&os, const NetCase*); virtual void proc_condit(ostream&os, const NetCondit*); virtual void proc_task(ostream&os, const NetTask*); virtual void proc_while(ostream&os, const NetWhile*); @@ -114,6 +116,13 @@ extern const struct target *target_table[]; /* * $Log: target.h,v $ + * Revision 1.5 1999/02/08 02:49:56 steve + * Turn the NetESignal into a NetNode so + * that it can connect to the netlist. + * Implement the case statement. + * Convince t-vvm to output code for + * the case statement. + * * Revision 1.4 1998/12/01 00:42:15 steve * Elaborate UDP devices, * Support UDP type attributes, and