Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add support for force assignment.

  • Loading branch information...
commit 44838f89739bd6246720fde9caa5919d780d55a0 1 parent ad88112
steve authored
View
26 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,
View
32 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 <string>
@@ -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,
View
17 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,
View
38 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<string,Module*>&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.
*
View
15 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,
View
24 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 <cassert>
@@ -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<NetNet*>&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.
*
View
32 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
/*
@@ -1402,6 +1402,33 @@ class NetEvProbe : public NetNode {
};
/*
+ * 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.
*
View
14 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);
View
17 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,
View
42 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 <iostream>
@@ -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["<<ncode<<"].connect(&"
+ << mname << ", " << idx << ");" << endl;
+ }
+
+ return true;
+}
+
void target_vvm::net_probe(ostream&os, const NetEvProbe*net)
{
string mname = mangle(net->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("<<idx<<", "
+ << "nexus_wire_table+"<<ncode << ");" << endl;
+ }
+
+ return true;
+}
+
/*
* The forever loop is implemented by starting a basic block, handing
* the statement, and putting in a goto to the beginning of the block.
@@ -2626,6 +2661,9 @@ extern const struct target tgt_vvm = {
};
/*
* $Log: t-vvm.cc,v $
+ * Revision 1.138 2000/04/22 04:20:19 steve
+ * Add support for force assignment.
+ *
* Revision 1.137 2000/04/15 19:51:30 steve
* fork-join support in vvm.
*
View
19 target.cc
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
-#ident "$Id: target.cc,v 1.35 2000/04/12 04:23:58 steve Exp $"
+#ident "$Id: target.cc,v 1.36 2000/04/22 04:20:19 steve Exp $"
#endif
# include "target.h"
@@ -155,6 +155,13 @@ void target_t::net_const(ostream&os, const NetConst*)
"Unhandled CONSTANT node." << endl;
}
+bool target_t::net_force(ostream&os, const NetForce*dev)
+{
+ cerr << "target (" << typeid(*this).name() << "): "
+ "Unhandled NetForce node." << endl;
+ return false;
+}
+
void target_t::net_probe(ostream&os, const NetEvProbe*net)
{
cerr << "target (" << typeid(*this).name() << "): "
@@ -218,6 +225,13 @@ void target_t::proc_delay(ostream&os, const NetPDelay*)
"Unhandled proc_delay." << endl;
}
+bool target_t::proc_force(ostream&os, const NetForce*dev)
+{
+ cerr << "target (" << typeid(*this).name() << "): "
+ "Unhandled proc_force." << endl;
+ return false;
+}
+
void target_t::proc_forever(ostream&os, const NetForever*)
{
cerr << "target (" << typeid(*this).name() << "): "
@@ -339,6 +353,9 @@ void expr_scan_t::expr_binary(const NetEBinary*ex)
/*
* $Log: target.cc,v $
+ * Revision 1.36 2000/04/22 04:20:19 steve
+ * Add support for force assignment.
+ *
* Revision 1.35 2000/04/12 04:23:58 steve
* Named events really should be expressed with PEIdent
* objects in the pform,
View
7 target.h
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
-#ident "$Id: target.h,v 1.34 2000/04/12 04:23:58 steve Exp $"
+#ident "$Id: target.h,v 1.35 2000/04/22 04:20:20 steve Exp $"
#endif
# include "netlist.h"
@@ -91,6 +91,7 @@ struct 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*);
/* Output a process (called for each process). It is up to the
@@ -105,6 +106,7 @@ struct target_t {
virtual bool proc_block(ostream&os, const NetBlock*);
virtual void proc_case(ostream&os, const NetCase*);
virtual void proc_condit(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 bool proc_trigger(ostream&os, const NetEvTrig*);
@@ -152,6 +154,9 @@ extern const struct target *target_table[];
/*
* $Log: target.h,v $
+ * Revision 1.35 2000/04/22 04:20:20 steve
+ * Add support for force assignment.
+ *
* Revision 1.34 2000/04/12 04:23:58 steve
* Named events really should be expressed with PEIdent
* objects in the pform,
View
4 vvm/Makefile.in
@@ -18,7 +18,7 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
-#ident "$Id: Makefile.in,v 1.28 2000/04/01 21:40:23 steve Exp $"
+#ident "$Id: Makefile.in,v 1.29 2000/04/22 04:20:20 steve Exp $"
#
#
SHELL = /bin/sh
@@ -59,7 +59,7 @@ all: libvvm.a
mv $*.d dep
O = vvm_add_sub.o vvm_bit.o vvm_calltf.o vvm_clshift.o vvm_compare.o \
-vvm_event.o vvm_ff.o \
+vvm_event.o vvm_ff.o vvm_force.o \
vvm_func.o vvm_gates.o vvm_idiv.o vvm_mult.o vvm_mux.o \
vvm_nexus.o vvm_pevent.o vvm_signal.o vvm_thread.o vvm_udp.o vpip.o
View
7 vvm/vpi_priv.h
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
-#ident "$Id: vpi_priv.h,v 1.14 2000/03/31 07:08:39 steve Exp $"
+#ident "$Id: vpi_priv.h,v 1.15 2000/04/22 04:20:20 steve Exp $"
#endif
/*
@@ -51,6 +51,8 @@ struct __vpirt;
* 1xxx0xxx - Logic X
* 00001000 - Logic Z
*
+ * 00000000 - Invalid/No signal
+ *
* So as you can see, logic values can be quickly compared by masking
* the strength bits.
*
@@ -342,6 +344,9 @@ extern int vpip_finished();
/*
* $Log: vpi_priv.h,v $
+ * Revision 1.15 2000/04/22 04:20:20 steve
+ * Add support for force assignment.
+ *
* Revision 1.14 2000/03/31 07:08:39 steve
* allow cancelling of cbValueChange events.
*
View
72 vvm/vvm_force.cc
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2000 Stephen Williams (steve@icarus.com)
+ *
+ * This source code is free software; you can redistribute it
+ * and/or modify it in source code form under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+#if !defined(WINNT) && !defined(macintosh)
+#ident "$Id: vvm_force.cc,v 1.1 2000/04/22 04:20:20 steve Exp $"
+#endif
+
+# include "vvm_gates.h"
+# include <assert.h>
+
+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.
+ *
+ */
+
View
34 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"
@@ -280,6 +280,35 @@ class vvm_ff : public vvm_nexus::recvr_t {
};
/*
+ * 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
* that includes a / operator in structural contexts.
@@ -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.
*
View
30 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.
*
View
29 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
Please sign in to comment.
Something went wrong with that request. Please try again.