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.
This commit is contained in:
steve 1999-02-08 02:49:56 +00:00
parent 8bdd381cdf
commit 30a3953c85
8 changed files with 225 additions and 35 deletions

View File

@ -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.
*

View File

@ -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<string,Module*>&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.
*

19
emit.cc
View File

@ -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.

View File

@ -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 <cassert>
@ -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.
*

View File

@ -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.
*

131
t-vvm.cc
View File

@ -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 <iostream>
@ -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<const NetNode*>(lnk->get_obj())) {
if ((net = dynamic_cast<const NetNode*>(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<const NetAssign*>(cur))
continue;
// Skip NetESignal nodes. They are handled as
// expressions.
if (dynamic_cast<const NetESignal*>(cur))
continue;
if (const NetNet*sig = dynamic_cast<const NetNet*>(cur)) {
os << setw(indent_) << "" << mangle(sig->name())
os << " " << mangle(sig->name())
<< "[" << pin << "] = " << rval << "[" << idx
<< "];" << endl;
os <<setw(indent_) << "" << mangle(sig->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.
*

View File

@ -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

View File

@ -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