diff --git a/Statement.cc b/Statement.cc index 60de14180..3abbad389 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) && !defined(macintosh) -#ident "$Id: Statement.cc,v 1.19 2000/04/12 04:23:57 steve Exp $" +#ident "$Id: Statement.cc,v 1.20 2000/04/22 04:20:19 steve Exp $" #endif # include "Statement.h" @@ -167,6 +167,17 @@ void PEventStatement::set_statement(Statement*st) statement_ = st; } +PForce::PForce(PExpr*l, PExpr*r) +: lval_(l), expr_(r) +{ +} + +PForce::~PForce() +{ + delete lval_; + delete expr_; +} + PForever::PForever(Statement*s) : statement_(s) { @@ -182,6 +193,16 @@ PProcess::~PProcess() delete statement_; } +PRelease::PRelease(PExpr*l) +: lval_(l) +{ +} + +PRelease::~PRelease() +{ + delete lval_; +} + PRepeat::PRepeat(PExpr*e, Statement*s) : expr_(e), statement_(s) { @@ -210,6 +231,9 @@ PWhile::~PWhile() /* * $Log: Statement.cc,v $ + * Revision 1.20 2000/04/22 04:20:19 steve + * Add support for force assignment. + * * Revision 1.19 2000/04/12 04:23:57 steve * Named events really should be expressed with PEIdent * objects in the pform, diff --git a/Statement.h b/Statement.h index 36ca71e39..b2dfe9c04 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) && !defined(macintosh) -#ident "$Id: Statement.h,v 1.24 2000/04/12 04:23:57 steve Exp $" +#ident "$Id: Statement.h,v 1.25 2000/04/22 04:20:19 steve Exp $" #endif # include @@ -288,6 +288,20 @@ class PEventStatement : public Statement { Statement*statement_; }; +class PForce : public Statement { + + public: + explicit PForce(PExpr*l, PExpr*r); + ~PForce(); + + virtual NetProc* elaborate(Design*des, const string&path) const; + virtual void dump(ostream&out, unsigned ind) const; + + private: + PExpr*lval_; + PExpr*expr_; +}; + class PForever : public Statement { public: explicit PForever(Statement*s); @@ -346,6 +360,19 @@ class PRepeat : public Statement { Statement*statement_; }; +class PRelease : public Statement { + + public: + explicit PRelease(PExpr*l); + ~PRelease(); + + virtual NetProc* elaborate(Design*des, const string&path) const; + virtual void dump(ostream&out, unsigned ind) const; + + private: + PExpr*lval_; +}; + /* * The PTrigger statement sends a trigger to a named event. Take the * name here. @@ -381,6 +408,9 @@ class PWhile : public Statement { /* * $Log: Statement.h,v $ + * Revision 1.25 2000/04/22 04:20:19 steve + * Add support for force assignment. + * * Revision 1.24 2000/04/12 04:23:57 steve * Named events really should be expressed with PEIdent * objects in the pform, diff --git a/design_dump.cc b/design_dump.cc index 94e276aaa..b80925b15 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) && !defined(macintosh) -#ident "$Id: design_dump.cc,v 1.76 2000/04/12 20:02:52 steve Exp $" +#ident "$Id: design_dump.cc,v 1.77 2000/04/22 04:20:19 steve Exp $" #endif /* @@ -154,6 +154,12 @@ void NetDivide::dump_node(ostream&o, unsigned ind) const dump_obj_attr(o, ind+4); } +void NetForce::dump_node(ostream&o, unsigned ind) const +{ + o << setw(ind) << "" << "force " << lval_->name() << endl; + dump_node_pins(o, ind+4); +} + void NetMult::dump_node(ostream&o, unsigned ind) const { o << setw(ind) << "" << "LPM_MULT (NetMult): " << name() << endl; @@ -546,6 +552,12 @@ void NetEvWait::dump(ostream&o, unsigned ind) const o << setw(ind+2) << "" << "/* noop */ ;" << endl; } +void NetForce::dump(ostream&o, unsigned ind) const +{ + o << setw(ind) << "" << "force " << lval_->name() << " = " + << name() << ";" << endl; +} + void NetForever::dump(ostream&o, unsigned ind) const { o << setw(ind) << "" << "forever" << endl; @@ -890,6 +902,9 @@ void Design::dump(ostream&o) const /* * $Log: design_dump.cc,v $ + * Revision 1.77 2000/04/22 04:20:19 steve + * Add support for force assignment. + * * Revision 1.76 2000/04/12 20:02:52 steve * Finally remove the NetNEvent and NetPEvent classes, * Get synthesis working with the NetEvWait class, diff --git a/elaborate.cc b/elaborate.cc index c415d6568..c7274d424 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) && !defined(macintosh) -#ident "$Id: elaborate.cc,v 1.160 2000/04/21 04:38:15 steve Exp $" +#ident "$Id: elaborate.cc,v 1.161 2000/04/22 04:20:19 steve Exp $" #endif /* @@ -1802,6 +1802,32 @@ NetProc* PForever::elaborate(Design*des, const string&path) const return proc; } +NetProc* PForce::elaborate(Design*des, const string&path) const +{ + NetScope*scope = des->find_scope(path); + assert(scope); + + NetNet*lval = lval_->elaborate_net(des, path, 0, 0, 0, 0); + if (lval == 0) + return 0; + + NetNet*rval = expr_->elaborate_net(des, path, lval->pin_count(), + 0, 0, 0); + if (rval == 0) + return 0; + + if (rval->pin_count() < lval->pin_count()) + rval = pad_to_width(des, path, rval, lval->pin_count()); + + NetForce* dev = new NetForce(des->local_symbol(path), lval); + des->add_node(dev); + + for (unsigned idx = 0 ; idx < dev->pin_count() ; idx += 1) + connect(dev->pin(idx), rval->pin(idx)); + + return dev; +} + /* * elaborate the for loop as the equivalent while loop. This eases the * task for the target code generator. The structure is: @@ -1941,6 +1967,13 @@ void PFunction::elaborate_2(Design*des, NetScope*scope) const def->set_proc(st); } +NetProc* PRelease::elaborate(Design*des, const string&path) const +{ + cerr << get_line() << ": sorry: I do not elaborate release yet." + << endl; + return 0; +} + NetProc* PRepeat::elaborate(Design*des, const string&path) const { NetScope*scope = des->find_scope(path); @@ -2228,6 +2261,9 @@ Design* elaborate(const map&modules, /* * $Log: elaborate.cc,v $ + * Revision 1.161 2000/04/22 04:20:19 steve + * Add support for force assignment. + * * Revision 1.160 2000/04/21 04:38:15 steve * Bit padding in assignment to memory. * diff --git a/emit.cc b/emit.cc index a41c9e133..bc20b0d85 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) && !defined(macintosh) -#ident "$Id: emit.cc,v 1.39 2000/04/12 04:23:58 steve Exp $" +#ident "$Id: emit.cc,v 1.40 2000/04/22 04:20:19 steve Exp $" #endif /* @@ -95,6 +95,11 @@ void NetFF::emit_node(ostream&o, struct target_t*tgt) const tgt->lpm_ff(o, this); } +void NetForce::emit_node(ostream&o, struct target_t*tgt) const +{ + tgt->net_force(o, this); +} + void NetMult::emit_node(ostream&o, struct target_t*tgt) const { tgt->lpm_mult(o, this); @@ -167,6 +172,11 @@ bool NetCondit::emit_proc(ostream&o, struct target_t*tgt) const return true; } +bool NetForce::emit_proc(ostream&o, struct target_t*tgt) const +{ + return tgt->proc_force(o, this); +} + bool NetForever::emit_proc(ostream&o, struct target_t*tgt) const { tgt->proc_forever(o, this); @@ -416,6 +426,9 @@ bool emit(ostream&o, const Design*des, const char*type) /* * $Log: emit.cc,v $ + * Revision 1.40 2000/04/22 04:20:19 steve + * Add support for force assignment. + * * Revision 1.39 2000/04/12 04:23:58 steve * Named events really should be expressed with PEIdent * objects in the pform, diff --git a/netlist.cc b/netlist.cc index 3c16ee2d5..e96f39822 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) && !defined(macintosh) -#ident "$Id: netlist.cc,v 1.116 2000/04/18 01:02:54 steve Exp $" +#ident "$Id: netlist.cc,v 1.117 2000/04/22 04:20:19 steve Exp $" #endif # include @@ -1735,6 +1735,25 @@ verinum::V NetConst::value(unsigned idx) const return value_[idx]; } +NetForce::NetForce(const string&n, NetNet*l) +: NetNode(n, l->pin_count()), lval_(l) +{ + for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) { + pin(idx).set_dir(Link::INPUT); + pin(idx).set_name("I", idx); + } +} + +NetForce::~NetForce() +{ +} + +const NetObj::Link& NetForce::lval_pin(unsigned idx) const +{ + assert(idx < lval_->pin_count()); + return lval_->pin(idx); +} + NetFuncDef::NetFuncDef(NetScope*s, const svector&po) : scope_(s), statement_(0), ports_(po) { @@ -2483,6 +2502,9 @@ bool NetUDP::sequ_glob_(string input, char output) /* * $Log: netlist.cc,v $ + * Revision 1.117 2000/04/22 04:20:19 steve + * Add support for force assignment. + * * Revision 1.116 2000/04/18 01:02:54 steve * Minor cleanup of NetTaskDef. * diff --git a/netlist.h b/netlist.h index 2a1cd9b9b..1ad7735c6 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) && !defined(macintosh) -#ident "$Id: netlist.h,v 1.126 2000/04/20 00:28:03 steve Exp $" +#ident "$Id: netlist.h,v 1.127 2000/04/22 04:20:19 steve Exp $" #endif /* @@ -1401,6 +1401,33 @@ class NetEvProbe : public NetNode { NetEvProbe*enext_; }; +/* + * The force statement causes the r-val net to be forced onto the + * l-val net when it is executed. The code generator is expected to + * know what that means. All the expressions are structural and behave + * like nets. + * + * This class is a NetProc because it it turned on by procedural + * behavior. However, it is also a NetNode because it connects to + * nets, and when activated follows the net values. + */ +class NetForce : public NetProc, public NetNode { + + public: + explicit NetForce(const string&n, NetNet*l); + ~NetForce(); + + const NetObj::Link& lval_pin(unsigned) const; + + virtual void dump(ostream&, unsigned ind) const; + virtual bool emit_proc(ostream&, struct target_t*) const; + virtual void dump_node(ostream&, unsigned ind) const; + virtual void emit_node(ostream&, struct target_t*) const; + + private: + NetNet*lval_; +}; + /* * A forever statement is executed over and over again forever. Or * until its block is disabled. @@ -2391,6 +2418,9 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.127 2000/04/22 04:20:19 steve + * Add support for force assignment. + * * Revision 1.126 2000/04/20 00:28:03 steve * Catch some simple identity compareoptimizations. * diff --git a/parse.y b/parse.y index 52de566f1..4c59205a9 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) && !defined(macintosh) -#ident "$Id: parse.y,v 1.91 2000/04/21 03:22:18 steve Exp $" +#ident "$Id: parse.y,v 1.92 2000/04/22 04:20:19 steve Exp $" #endif # include "parse_misc.h" @@ -1671,8 +1671,10 @@ statement $$ = 0; } | K_force lavalue '=' expression ';' - { yyerror(@1, "sorry: procedural force assign not supported."); - $$ = 0; + { PForce*tmp = new PForce($2, $4); + tmp->set_file(@1.text); + tmp->set_lineno(@1.first_line); + $$ = tmp; } | K_TRIGGER IDENTIFIER ';' { PTrigger*tmp = new PTrigger($2); @@ -1718,8 +1720,10 @@ statement $$ = tmp; } | K_release lavalue ';' - { yyerror(@1, "sorry: release not supported."); - $$ = 0; + { PRelease*tmp = new PRelease($2); + tmp->set_file(@1.text); + tmp->set_lineno(@1.first_line); + $$ = tmp; } | K_repeat '(' expression ')' statement { PRepeat*tmp = new PRepeat($3, $5); diff --git a/pform_dump.cc b/pform_dump.cc index 1957f6164..7262f971c 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) && !defined(macintosh) -#ident "$Id: pform_dump.cc,v 1.54 2000/04/12 20:02:53 steve Exp $" +#ident "$Id: pform_dump.cc,v 1.55 2000/04/22 04:20:19 steve Exp $" #endif /* @@ -483,6 +483,12 @@ void PEventStatement::dump(ostream&out, unsigned ind) const } } +void PForce::dump(ostream&out, unsigned ind) const +{ + out << setw(ind) << "" << "force " << *lval_ << " = " << *expr_ + << "; /* " << get_line() << " */" << endl; +} + void PForever::dump(ostream&out, unsigned ind) const { out << setw(ind) << "" << "forever /* " << get_line() << " */" << endl; @@ -512,6 +518,12 @@ void PFunction::dump(ostream&out, unsigned ind) const out << setw(ind) << "" << "/* NOOP */" << endl; } +void PRelease::dump(ostream&out, unsigned ind) const +{ + out << setw(ind) << "" << "release " << *lval_ << "; /* " + << get_line() << " */" << endl; +} + void PRepeat::dump(ostream&out, unsigned ind) const { out << setw(ind) << "" << "repeat (" << *expr_ << ")" << endl; @@ -733,6 +745,9 @@ void PUdp::dump(ostream&out) const /* * $Log: pform_dump.cc,v $ + * Revision 1.55 2000/04/22 04:20:19 steve + * Add support for force assignment. + * * Revision 1.54 2000/04/12 20:02:53 steve * Finally remove the NetNEvent and NetPEvent classes, * Get synthesis working with the NetEvWait class, diff --git a/t-vvm.cc b/t-vvm.cc index c384421e1..24fe460d1 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) && !defined(macintosh) -#ident "$Id: t-vvm.cc,v 1.137 2000/04/15 19:51:30 steve Exp $" +#ident "$Id: t-vvm.cc,v 1.138 2000/04/22 04:20:19 steve Exp $" #endif # include @@ -80,6 +80,7 @@ class target_vvm : public target_t { virtual void net_assign_nb(ostream&os, const NetAssignNB*); virtual void net_case_cmp(ostream&os, const NetCaseCmp*); virtual void net_const(ostream&os, const NetConst*); + virtual bool net_force(ostream&os, const NetForce*); virtual void net_probe(ostream&os, const NetEvProbe*); virtual bool process(ostream&os, const NetProcTop*); virtual void proc_assign(ostream&os, const NetAssign*); @@ -91,6 +92,7 @@ class target_vvm : public target_t { void proc_case_fun(ostream&os, const NetCase*net); virtual void proc_condit(ostream&os, const NetCondit*); void proc_condit_fun(ostream&os, const NetCondit*); + virtual bool proc_force(ostream&os, const NetForce*); virtual void proc_forever(ostream&os, const NetForever*); virtual void proc_repeat(ostream&os, const NetRepeat*); virtual void proc_stask(ostream&os, const NetSTask*); @@ -802,7 +804,7 @@ void target_vvm::end_design(ostream&os, const Design*mod) os << "static struct __vpiNumberConst number_table[" << number_counter+1 << "];" << endl; if (nexus_wire_counter > 0) - os << "static vvm_nexus_wire nexus_wire_table[" << + os << "static vvm_nexus nexus_wire_table[" << nexus_wire_counter << "];" << endl; if (signal_bit_counter > 0) os << "static vpip_bit_t signal_bit_table[" << @@ -1734,6 +1736,24 @@ void target_vvm::net_const(ostream&os, const NetConst*gate) } +bool target_vvm::net_force(ostream&os, const NetForce*dev) +{ + string mname = mangle(dev->name()); + + os << "static vvm_force " << mname << "(" << dev->pin_count() + << ");" << endl; + + for (unsigned idx = 0 ; idx < dev->pin_count() ; idx += 1) { + string nexus = nexus_from_link(&dev->pin(idx)); + unsigned ncode = nexus_wire_map[nexus]; + + init_code << " nexus_wire_table["<name()); @@ -2310,6 +2330,21 @@ void target_vvm::proc_condit_fun(ostream&os, const NetCondit*net) defn << " }" << endl; } +bool target_vvm::proc_force(ostream&os, const NetForce*dev) +{ + const string mname = mangle(dev->name()); + + for (unsigned idx = 0 ; idx < dev->pin_count() ; idx += 1) { + string nexus = nexus_from_link(&dev->lval_pin(idx)); + unsigned ncode = nexus_wire_map[nexus]; + + defn << " " << mname << ".force("< + +vvm_force::vvm_force(unsigned w) +: width_(w) +{ + bits_ = new vpip_bit_t[width_]; + target_ = new vvm_nexus*[width_]; + for (unsigned idx = 0 ; idx < width_ ; idx += 1) + target_[idx] = 0; +} + +vvm_force::~vvm_force() +{ + delete[]bits_; + delete[]target_; +} + +void vvm_force::init_I(unsigned key, vpip_bit_t val) +{ + assert(key < width_); + bits_[key] = val; +} + +void vvm_force::take_value(unsigned key, vpip_bit_t val) +{ + assert(key < width_); + if (bits_[key] == val) + return; + + bits_[key] = val; + target_[key]->force_assign(val); +} + +void vvm_force::force(unsigned key, vvm_nexus*tgt) +{ + assert(key < width_); + assert(target_[key] == 0); + target_[key] = tgt; + target_[key]->force_assign(bits_[key]); +} + + +/* + * $Log: vvm_force.cc,v $ + * Revision 1.1 2000/04/22 04:20:20 steve + * Add support for force assignment. + * + */ + diff --git a/vvm/vvm_gates.h b/vvm/vvm_gates.h index e1f0b1511..78129f3a8 100644 --- a/vvm/vvm_gates.h +++ b/vvm/vvm_gates.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: vvm_gates.h,v 1.57 2000/04/15 02:25:32 steve Exp $" +#ident "$Id: vvm_gates.h,v 1.58 2000/04/22 04:20:20 steve Exp $" #endif # include "vvm.h" @@ -279,6 +279,35 @@ class vvm_ff : public vvm_nexus::recvr_t { vvm_ff& operator= (const vvm_ff&); }; +/* + * This class supports the handling of the procedural force + * assignment. It is a device on the netlist that receives a bit value + * and forces it onto the target vvm_nexus. That target is enabled by + * the execution of the force statement in behavioral code. + */ +class vvm_force : public vvm_nexus::recvr_t { + + public: + explicit vvm_force(unsigned w); + ~vvm_force(); + + void init_I(unsigned key, vpip_bit_t val); + + void force(unsigned key, vvm_nexus*tgt); + void release(); + + private: + void take_value(unsigned key, vpip_bit_t val); + + unsigned width_; + vpip_bit_t*bits_; + vvm_nexus**target_; + + private: // not implemented + vvm_force(const vvm_force&); + vvm_force& operator= (const vvm_force&); +}; + /* * This class behaves like a combinational divider. There isn't really * such a practical device, but this is useful for simulating code @@ -887,6 +916,9 @@ class vvm_posedge : public vvm_nexus::recvr_t { /* * $Log: vvm_gates.h,v $ + * Revision 1.58 2000/04/22 04:20:20 steve + * Add support for force assignment. + * * Revision 1.57 2000/04/15 02:25:32 steve * Support chained events. * diff --git a/vvm/vvm_nexus.cc b/vvm/vvm_nexus.cc index 591ffaff3..04546d178 100644 --- a/vvm/vvm_nexus.cc +++ b/vvm/vvm_nexus.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: vvm_nexus.cc,v 1.5 2000/03/22 05:16:38 steve Exp $" +#ident "$Id: vvm_nexus.cc,v 1.6 2000/04/22 04:20:20 steve Exp $" #endif # include "vvm_nexus.h" @@ -128,10 +128,20 @@ void vvm_nexus::reg_assign(vpip_bit_t val) { assert(drivers_ == 0); value_ = val; + if (force_ != 0) + return; + for (recvr_cell*cur = recvrs_; cur ; cur = cur->next) cur->dev->take_value(cur->key, value_); } +void vvm_nexus::force_assign(vpip_bit_t val) +{ + force_ = val; + for (recvr_cell*cur = recvrs_; cur ; cur = cur->next) + cur->dev->take_value(cur->key, force_); +} + /* * This method is invoked when something interesting happens at one of * the drivers. It collects all the driver values, resolves them into @@ -159,6 +169,9 @@ void vvm_nexus::run_values() if (value_ == val) return; value_ = val; + if (force_ != 0) + return; + /* Now deliver that output value to all the receivers connected to this nexus. */ for (recvr_cell*cur = recvrs_; cur ; cur = cur->next) @@ -197,16 +210,8 @@ vvm_nexus::recvr_t::~recvr_t() { } -vvm_nexus_wire::vvm_nexus_wire() -{ -} - -vvm_nexus_wire::~vvm_nexus_wire() -{ -} - -vpip_bit_t vvm_nexus_wire::resolution_function(const vpip_bit_t*bits, - unsigned nbits) const +vpip_bit_t vvm_nexus::resolution_function(const vpip_bit_t*bits, + unsigned nbits) const { if (nbits == 0) return HiZ; return vpip_bits_resolve(bits, nbits); @@ -233,6 +238,9 @@ void vvm_delayed_assign(vvm_nexus&l_val, vpip_bit_t r_val, /* * $Log: vvm_nexus.cc,v $ + * Revision 1.6 2000/04/22 04:20:20 steve + * Add support for force assignment. + * * Revision 1.5 2000/03/22 05:16:38 steve * Integrate drive resolution function. * diff --git a/vvm/vvm_nexus.h b/vvm/vvm_nexus.h index 3aab38b07..bc59f8d9a 100644 --- a/vvm/vvm_nexus.h +++ b/vvm/vvm_nexus.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: vvm_nexus.h,v 1.1 2000/03/16 19:03:04 steve Exp $" +#ident "$Id: vvm_nexus.h,v 1.2 2000/04/22 04:20:20 steve Exp $" #endif # include "vvm.h" @@ -85,7 +85,7 @@ class vvm_nexus { public: vvm_nexus(); - virtual ~vvm_nexus() =0; + ~vvm_nexus(); // These methods support connecting the receiver and driver to // the nexus. @@ -100,12 +100,17 @@ class vvm_nexus { // to procedural assignments to the node, as if it where a reg. void reg_assign(vpip_bit_t val); + // This method causes the specified value to be forced onto + // the nexus. This overrides all drivers that are attached. + void force_assign(vpip_bit_t val); + void release(); + // The run_values() method collects all the current driver // values and, with the aid of the resolution_function, // generates the current value for the nexus. It also passes // that value on to the receuvers. void run_values(); - virtual vpip_bit_t resolution_function(const vpip_bit_t*, unsigned) const =0; + vpip_bit_t resolution_function(const vpip_bit_t*, unsigned) const; private: vpip_bit_t value_; @@ -119,31 +124,27 @@ class vvm_nexus { vpip_bit_t*ival_; unsigned nival_; + vpip_bit_t force_; + private: // not implemented vvm_nexus(const vvm_nexus&); vvm_nexus& operator= (const vvm_nexus&); }; -class vvm_nexus_wire : public vvm_nexus { - - public: - vvm_nexus_wire(); - ~vvm_nexus_wire(); - vpip_bit_t resolution_function(const vpip_bit_t*, unsigned) const; -}; - - /* * This function arranges for a non-blocking reg_assign to a nexus. It * creates all the events needed to make it happen after the specified * delay. */ -void vvm_delayed_assign(vvm_nexus&l_val, vpip_bit_t r_val, - unsigned long delay); +extern void vvm_delayed_assign(vvm_nexus&l_val, vpip_bit_t r_val, + unsigned long delay); /* * $Log: vvm_nexus.h,v $ + * Revision 1.2 2000/04/22 04:20:20 steve + * Add support for force assignment. + * * Revision 1.1 2000/03/16 19:03:04 steve * Revise the VVM backend to use nexus objects so that * drivers and resolution functions can be used, and