All events now use the NetEvent class.

This commit is contained in:
steve 2000-04-10 05:26:05 +00:00
parent 72b3508911
commit 8dbd64121f
14 changed files with 485 additions and 204 deletions

View File

@ -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.73 2000/04/04 03:20:15 steve Exp $"
#ident "$Id: design_dump.cc,v 1.74 2000/04/10 05:26:05 steve Exp $"
#endif
/*
@ -527,6 +527,26 @@ void NetCondit::dump(ostream&o, unsigned ind) const
}
}
void NetEvProbe::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "";
switch (edge_) {
case ANYEDGE:
o << "anyedge ";
break;
case POSEDGE:
o << "posedge ";
break;
case NEGEDGE:
o << "negedge ";
break;
}
o << setw(ind) << "" << "-> " << event_->full_name() << "; " << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
}
void NetEvTrig::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "-> " << event_->name() << "; "
@ -928,6 +948,9 @@ void Design::dump(ostream&o) const
/*
* $Log: design_dump.cc,v $
* Revision 1.74 2000/04/10 05:26:05 steve
* All events now use the NetEvent class.
*
* Revision 1.73 2000/04/04 03:20:15 steve
* Simulate named event trigger and waits.
*

View File

@ -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.156 2000/04/09 17:44:30 steve Exp $"
#ident "$Id: elaborate.cc,v 1.157 2000/04/10 05:26:06 steve Exp $"
#endif
/*
@ -34,13 +34,6 @@
# include "netlist.h"
# include "netmisc.h"
string Design::local_symbol(const string&path)
{
strstream res;
res << "_L" << (lcounter_++) << ends;
return path + "." + res.str();
}
// Urff, I don't like this global variable. I *will* figure out a
// way to get rid of it. But, for now the PGModule::elaborate method
@ -1529,14 +1522,30 @@ NetProc* PDelayStatement::elaborate(Design*des, const string&path) const
}
/*
* An event statement gets elaborated as a gate net that drives a
* special node, the NetPEvent. The NetPEvent is also a NetProc class
* because execution flows through it. Thus, the NetPEvent connects
* the structural and the behavioral.
* An event statement is an event delay of some sort, attached to a
* statement. Some Verilog examples are:
*
* Note that it is possible for the statement_ pointer to be 0. This
* happens when the source has something like "@(E) ;". Note the null
* statement.
* @(posedge CLK) $display("clock rise");
* @event_1 $display("event triggered.");
* @(data or negedge clk) $display("data or clock fall.");
*
* The elaborated netlist uses the NetEvent, NetEvWait and NetEvProbe
* classes. The NetEvWait class represents the part of the netlist
* that is executed by behavioral code. The process starts waiting on
* the NetEvent when it executes the NetEvWait step. Net NetEvProbe
* and NetEvTrig are structural and behavioral equivilents that
* trigger the event, and awakens any processes blocking in the
* associated wait.
*
* The basic data structure is:
*
* NetEvWait ---/---> NetEvent <----\---- NetEvProbe
* ... | | ...
* NetEvWait ---+ +-----NetEvProbe
*
* That is, many NetEvWait statements may wait on a single NetEvent
* object, and Many NetEvProbe objects may trigger the NetEvent
* object.
*/
NetProc* PEventStatement::elaborate_st(Design*des, const string&path,
NetProc*enet) const
@ -1544,11 +1553,62 @@ NetProc* PEventStatement::elaborate_st(Design*des, const string&path,
NetScope*scope = des->find_scope(path);
assert(scope);
/* Handle as a special case the block on an event. In this
case I generate a NetEvWait object to represent me.
XXXX Do I want to move all event handling to NetEvent style
event support? I think I do. */
/* The Verilog wait (<expr>) <statement> statement is a level
sensitive wait. Handle this special case by elaborating
something like this:
begin
if (! <expr>) @(posedge <expr>)
<statement>
end
This is equivilent, and uses the existing capapilities of
the netlist format. The resulting netlist should look like
this:
NetBlock ---+---> NetCondit --+--> <expr>
| |
| +--> NetEvWait--> NetEvent
|
+---> <statement>
This is quite a mouthful */
if ((expr_.count() == 1) && (expr_[0]->type() == NetNEvent::POSITIVE)) {
NetBlock*bl = new NetBlock(NetBlock::SEQU);
NetNet*ex = expr_[0]->expr()->elaborate_net(des, path,
1, 0, 0, 0);
if (ex == 0) {
expr_[0]->dump(cerr);
cerr << endl;
des->errors += 1;
return 0;
}
NetEvent*ev = new NetEvent(scope->local_symbol());
scope->add_event(ev);
NetEvWait*we = new NetEvWait(ev, 0);
NetEvProbe*po = new NetEvProbe(path+"."+scope->local_symbol(),
ev, NetEvProbe::POSEDGE, 1);
connect(po->pin(0), ex->pin(0));
des->add_node(po);
NetESignal*ce = new NetESignal(ex);
NetCondit*co = new NetCondit(new NetEUnary('!', ce), we, 0);
bl->append(co);
bl->append(enet);
return bl;
}
/* Handle as a special case the block on an event. In this
case I generate a NetEvWait object to represent me. */
if ((expr_.count() == 1) && (expr_[0]->expr() == 0)) {
string ename = expr_[0]->name();
@ -1577,12 +1637,16 @@ NetProc* PEventStatement::elaborate_st(Design*des, const string&path,
}
}
/* Create a single NetPEvent, and a unique NetNEvent for each
conjuctive event. An NetNEvent can have many pins only if
it is an ANYEDGE detector. Otherwise, only connect to the
least significant bit of the expression. */
/* Create A single NetEvent and NetEvWait. Then, create a
NetEvProbe for each conjunctive event in the event
list. The NetEvProbe object al refer back to the NetEvent
object. */
NetEvent*ev = new NetEvent(scope->local_symbol());
scope->add_event(ev);
NetEvWait*wa = new NetEvWait(ev, enet);
NetPEvent*pe = new NetPEvent(des->local_symbol(path), enet);
for (unsigned idx = 0 ; idx < expr_.count() ; idx += 1) {
if (expr_[idx]->expr() == 0) {
cerr << get_line() << ": sorry: block on named events "
@ -1604,7 +1668,7 @@ NetProc* PEventStatement::elaborate_st(Design*des, const string&path,
NetNet*expr = expr_[idx]->expr()->elaborate_net(des, path,
0, 0, 0, 0);
if (expr == 0) {
expr_[0]->dump(cerr);
expr_[idx]->dump(cerr);
cerr << endl;
des->errors += 1;
continue;
@ -1613,16 +1677,35 @@ NetProc* PEventStatement::elaborate_st(Design*des, const string&path,
unsigned pins = (expr_[idx]->type() == NetNEvent::ANYEDGE)
? expr->pin_count() : 1;
NetNEvent*ne = new NetNEvent(des->local_symbol(path),
pins, expr_[idx]->type(), pe);
for (unsigned p = 0 ; p < pins ; p += 1)
connect(ne->pin(p), expr->pin(p));
NetEvProbe*pr;
switch (expr_[idx]->type()) {
case NetNEvent::POSEDGE:
pr = new NetEvProbe(des->local_symbol(path), ev,
NetEvProbe::POSEDGE, pins);
break;
des->add_node(ne);
case NetNEvent::NEGEDGE:
pr = new NetEvProbe(des->local_symbol(path), ev,
NetEvProbe::NEGEDGE, pins);
break;
case NetNEvent::ANYEDGE:
pr = new NetEvProbe(des->local_symbol(path), ev,
NetEvProbe::ANYEDGE, pins);
break;
default:
assert(0);
}
for (unsigned p = 0 ; p < pr->pin_count() ; p += 1)
connect(pr->pin(p), expr->pin(p));
des->add_node(pr);
}
return pe;
return wa;
}
NetProc* PEventStatement::elaborate(Design*des, const string&path) const
@ -2078,6 +2161,9 @@ Design* elaborate(const map<string,Module*>&modules,
/*
* $Log: elaborate.cc,v $
* Revision 1.157 2000/04/10 05:26:06 steve
* All events now use the NetEvent class.
*
* Revision 1.156 2000/04/09 17:44:30 steve
* Catch event declarations during scope elaborate.
*

11
emit.cc
View File

@ -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.37 2000/04/04 03:20:15 steve Exp $"
#ident "$Id: emit.cc,v 1.38 2000/04/10 05:26:06 steve Exp $"
#endif
/*
@ -248,6 +248,11 @@ void NetCondit::emit_recurse_else(ostream&o, struct target_t*tgt) const
else_->emit_proc(o, tgt);
}
void NetEvProbe::emit_node(ostream&o, struct target_t*tgt) const
{
tgt->net_probe(o, this);
}
bool NetEvTrig::emit_proc(ostream&o, struct target_t*tgt) const
{
return tgt->proc_trigger(o, this);
@ -260,6 +265,7 @@ bool NetEvWait::emit_proc(ostream&o, struct target_t*tgt) const
bool NetEvWait::emit_recurse(ostream&o, struct target_t*tgt) const
{
if (!statement_) return true;
return statement_->emit_proc(o, tgt);
}
@ -426,6 +432,9 @@ bool emit(ostream&o, const Design*des, const char*type)
/*
* $Log: emit.cc,v $
* Revision 1.38 2000/04/10 05:26:06 steve
* All events now use the NetEvent class.
*
* Revision 1.37 2000/04/04 03:20:15 steve
* Simulate named event trigger and waits.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: net_design.cc,v 1.3 2000/03/11 03:25:52 steve Exp $"
#ident "$Id: net_design.cc,v 1.4 2000/04/10 05:26:06 steve Exp $"
#endif
/*
@ -26,6 +26,7 @@
*/
# include "netlist.h"
# include <strstream>
static string parse_first_name(string&path)
{
@ -64,6 +65,14 @@ Design::~Design()
{
}
string Design::local_symbol(const string&path)
{
strstream res;
res << "_L" << (lcounter_++) << ends;
return path + "." + res.str();
}
NetScope* Design::make_root_scope(const string&root)
{
assert(root_scope_ == 0);
@ -539,6 +548,9 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*))
/*
* $Log: net_design.cc,v $
* Revision 1.4 2000/04/10 05:26:06 steve
* All events now use the NetEvent class.
*
* Revision 1.3 2000/03/11 03:25:52 steve
* Locate scopes in statements.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: net_event.cc,v 1.1 2000/04/04 03:20:15 steve Exp $"
#ident "$Id: net_event.cc,v 1.2 2000/04/10 05:26:06 steve Exp $"
#endif
# include "netlist.h"
@ -58,6 +58,30 @@ const NetEvent* NetEvTrig::event() const
return event_;
}
NetEvProbe::NetEvProbe(const string&n, NetEvent*tgt,
edge_t t, unsigned p)
: NetNode(n, p), event_(tgt), edge_(t)
{
for (unsigned idx = 0 ; idx < p ; idx += 1) {
pin(idx).set_dir(Link::INPUT);
pin(idx).set_name("P", idx);
}
}
NetEvProbe::~NetEvProbe()
{
}
NetEvProbe::edge_t NetEvProbe::edge() const
{
return edge_;
}
const NetEvent* NetEvProbe::event() const
{
return event_;
}
NetEvWait::NetEvWait(NetEvent*ev, NetProc*pr)
: event_(ev), statement_(pr)
{
@ -75,6 +99,9 @@ const NetEvent* NetEvWait::event() const
/*
* $Log: net_event.cc,v $
* Revision 1.2 2000/04/10 05:26:06 steve
* All events now use the NetEvent class.
*
* Revision 1.1 2000/04/04 03:20:15 steve
* Simulate named event trigger and waits.
*

View File

@ -17,10 +17,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: net_scope.cc,v 1.2 2000/04/09 17:04:56 steve Exp $"
#ident "$Id: net_scope.cc,v 1.3 2000/04/10 05:26:06 steve Exp $"
#endif
# include "netlist.h"
# include <strstream>
/*
* The NetScope class keeps a scope tree organized. Each node of the
@ -34,6 +35,7 @@ NetScope::NetScope(const string&n)
: type_(NetScope::MODULE), name_(n), up_(0), sib_(0), sub_(0)
{
events_ = 0;
lcounter_ = 0;
}
NetScope::NetScope(NetScope*up, const string&n, NetScope::TYPE t)
@ -48,6 +50,7 @@ NetScope::~NetScope()
{
assert(sib_ == 0);
assert(sub_ == 0);
lcounter_ = 0;
}
NetExpr* NetScope::set_parameter(const string&key, NetExpr*expr)
@ -151,9 +154,19 @@ const NetScope* NetScope::parent() const
return up_;
}
string NetScope::local_symbol()
{
strstream res;
res << "_l" << (lcounter_++) << ends;
return res.str();
}
/*
* $Log: net_scope.cc,v $
* Revision 1.3 2000/04/10 05:26:06 steve
* All events now use the NetEvent class.
*
* Revision 1.2 2000/04/09 17:04:56 steve
* uninitialized event_ list.
*

View File

@ -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.118 2000/04/04 03:20:15 steve Exp $"
#ident "$Id: netlist.h,v 1.119 2000/04/10 05:26:06 steve Exp $"
#endif
/*
@ -1262,6 +1262,11 @@ class NetCondit : public NetProc {
* The NetEvTrig class represents trigger statements. Executing this
* statement causes the referenced event to be triggered, which it
* turn awakens the waiting threads.
*
* The NetEvProbe class is the structural equivilent of the NetEvTrig,
* in that it is a node and watches bit values that it receives. It
* checks for edges then if appropriate triggers the associated
* NetEvent.
*/
class NetEvent : public LineInfo {
@ -1321,6 +1326,26 @@ class NetEvWait : public NetProc {
NetProc*statement_;
};
class NetEvProbe : public NetNode {
public:
enum edge_t { ANYEDGE, POSEDGE, NEGEDGE };
explicit NetEvProbe(const string&n, NetEvent*tgt,
edge_t t, unsigned p);
~NetEvProbe();
edge_t edge() const;
const NetEvent* event() const;
virtual void emit_node(ostream&, struct target_t*) const;
virtual void dump_node(ostream&, unsigned ind) const;
private:
NetEvent*event_;
edge_t edge_;
};
/*
* A forever statement is executed over and over again forever. Or
* until its block is disabled.
@ -2181,6 +2206,10 @@ class NetScope {
void run_defparams(class Design*);
void evaluate_parameters(class Design*);
/* This method generates a non-hierarchical name that is
guaranteed to be unique within this scope. */
string local_symbol();
void dump(ostream&) const;
void emit_scope(ostream&o, struct target_t*tgt) const;
@ -2203,6 +2232,8 @@ class NetScope {
NetScope*up_;
NetScope*sib_;
NetScope*sub_;
unsigned lcounter_;
};
/*
@ -2368,6 +2399,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
* Revision 1.119 2000/04/10 05:26:06 steve
* All events now use the NetEvent class.
*
* Revision 1.118 2000/04/04 03:20:15 steve
* Simulate named event trigger and waits.
*

108
t-vvm.cc
View File

@ -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.131 2000/04/09 16:55:42 steve Exp $"
#ident "$Id: t-vvm.cc,v 1.132 2000/04/10 05:26:06 steve Exp $"
#endif
# include <iostream>
@ -81,6 +81,7 @@ class target_vvm : public target_t {
virtual void net_case_cmp(ostream&os, const NetCaseCmp*);
virtual void net_const(ostream&os, const NetConst*);
virtual void net_event(ostream&os, const NetNEvent*);
virtual void net_probe(ostream&os, const NetEvProbe*);
virtual bool process(ostream&os, const NetProcTop*);
virtual void proc_assign(ostream&os, const NetAssign*);
virtual void proc_assign_mem(ostream&os, const NetAssignMem*);
@ -1760,6 +1761,7 @@ void target_vvm::net_const(ostream&os, const NetConst*gate)
*/
void target_vvm::net_event(ostream&os, const NetNEvent*gate)
{
string gname = mangle(gate->name());
string pevent = mangle(gate->pevent()->name());
os << " /* " << gate->name() << " */" << endl;
@ -1769,21 +1771,28 @@ void target_vvm::net_event(ostream&os, const NetNEvent*gate)
os << "static vvm_sync " << pevent << ";" << endl;
}
os << "static vvm_pevent<" << gate->pin_count() << "> " <<
mangle(gate->name()) << "(&" << pevent << ", ";
switch (gate->type()) {
case NetNEvent::POSEDGE:
case NetNEvent::POSITIVE:
os << "vvm_pevent<" << gate->pin_count() << ">::POSEDGE";
assert(gate->pin_count() == 1);
os << "static vvm_posedge " << gname
<< "(&" << pevent << ");" << endl;
break;
case NetNEvent::NEGEDGE:
os << "vvm_pevent<"<< gate->pin_count() << ">::NEGEDGE";
assert(gate->pin_count() == 1);
os << "static vvm_negedge " << gname
<< "(&" << pevent << ");" << endl;
break;
case NetNEvent::ANYEDGE:
os << "vvm_pevent<" << gate->pin_count() << ">::ANYEDGE";
assert(gate->pin_count() == 1);
os << "static vvm_anyedge " << gname
<< "(&" << pevent << ");" << endl;
break;
}
os << ");" << endl;
/* Connect this device as a receiver to the nexus that is my
@ -1798,6 +1807,44 @@ void target_vvm::net_event(ostream&os, const NetNEvent*gate)
}
}
void target_vvm::net_probe(ostream&os, const NetEvProbe*net)
{
string mname = mangle(net->name());
string mevent = mangle(net->event()->full_name());
switch (net->edge()) {
case NetEvProbe::POSEDGE:
assert(net->pin_count() == 1);
os << "static vvm_posedge " << mname
<< "(&" << mevent << ");" << endl;
break;
case NetNEvent::NEGEDGE:
assert(net->pin_count() == 1);
os << "static vvm_negedge " << mname
<< "(&" << mevent << ");" << endl;
break;
case NetNEvent::ANYEDGE:
os << "static vvm_anyedge " << mname
<< "(&" << mevent << ", " << net->pin_count() << ");" << endl;
break;
}
/* Connect this device as a receiver to the nexus that is my
source. Write the connect calls into the init code. */
for (unsigned idx = 0 ; idx < net->pin_count() ; idx += 1) {
string nexus = nexus_from_link(&net->pin(idx));
unsigned ncode = nexus_wire_map[nexus];
init_code << " nexus_wire_table["<<ncode<<"].connect(&" <<
mangle(net->name()) << ", " << idx << ");" << endl;
}
}
void target_vvm::start_process(ostream&os, const NetProcTop*proc)
{
process_counter += 1;
@ -2582,6 +2629,9 @@ extern const struct target tgt_vvm = {
};
/*
* $Log: t-vvm.cc,v $
* Revision 1.132 2000/04/10 05:26:06 steve
* All events now use the NetEvent class.
*
* Revision 1.131 2000/04/09 16:55:42 steve
* Donot create tables that have no entries.
*
@ -2624,49 +2674,5 @@ extern const struct target tgt_vvm = {
*
* Revision 1.119 2000/03/20 17:40:33 steve
* Do not link adder pins that ar unconnected.
*
* Revision 1.118 2000/03/18 23:22:37 steve
* Update the FF device to nexus style.
*
* Revision 1.117 2000/03/18 02:26:02 steve
* Update bufz to nexus style.
*
* Revision 1.116 2000/03/18 01:26:59 steve
* Generate references into a table of nexus objects instead of
* generating lots of isolated nexus objects. Easier on linkers
* and compilers,
*
* Add missing nexus support for l-value bit selects,
*
* Detemplatize the vvm_mux type.
*
* Fix up the vvm_nexus destructor to disconnect from drivers.
*
* Revision 1.115 2000/03/17 20:21:14 steve
* Detemplatize the vvm_signal_t class.
*
* Revision 1.114 2000/03/17 19:23:59 steve
* nor2 and and2 optimized gates.
*
* Revision 1.113 2000/03/17 17:25:53 steve
* Adder and comparator in nexus style.
*
* Revision 1.112 2000/03/17 03:05:13 steve
* Update vvm_mult to nexus style.
*
* Revision 1.111 2000/03/17 02:22:03 steve
* vvm_clshift implementation without templates.
*
* Revision 1.110 2000/03/16 23:13:49 steve
* Update LPM_MUX to nexus style.
*
* Revision 1.109 2000/03/16 21:47:27 steve
* Update LMP_CLSHIFT to use nexus interface.
*
* Revision 1.108 2000/03/16 19:03:03 steve
* Revise the VVM backend to use nexus objects so that
* drivers and resolution functions can be used, and
* the t-vvm module doesn't need to write a zillion
* output functions.
*/

View File

@ -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.33 2000/04/04 03:20:15 steve Exp $"
#ident "$Id: target.cc,v 1.34 2000/04/10 05:26:06 steve Exp $"
#endif
# include "target.h"
@ -162,6 +162,13 @@ void target_t::net_event(ostream&os, const NetNEvent*net)
net->dump_node(cerr, 4);
}
void target_t::net_probe(ostream&os, const NetEvProbe*net)
{
cerr << "target (" << typeid(*this).name() << "): "
"Unhandled probe trigger node" << endl;
net->dump_node(cerr, 4);
}
bool target_t::process(ostream&os, const NetProcTop*top)
{
return top->statement()->emit_proc(os, this);
@ -346,6 +353,9 @@ void expr_scan_t::expr_binary(const NetEBinary*ex)
/*
* $Log: target.cc,v $
* Revision 1.34 2000/04/10 05:26:06 steve
* All events now use the NetEvent class.
*
* Revision 1.33 2000/04/04 03:20:15 steve
* Simulate named event trigger and waits.
*

View File

@ -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.32 2000/04/04 03:20:15 steve Exp $"
#ident "$Id: target.h,v 1.33 2000/04/10 05:26:06 steve Exp $"
#endif
# include "netlist.h"
@ -92,6 +92,7 @@ struct target_t {
virtual void net_case_cmp(ostream&os, const NetCaseCmp*);
virtual void net_const(ostream&os, const NetConst*);
virtual void net_event(ostream&os, const NetNEvent*);
virtual void net_probe(ostream&os, const NetEvProbe*);
/* Output a process (called for each process). It is up to the
target to recurse if desired. */
@ -154,6 +155,9 @@ extern const struct target *target_table[];
/*
* $Log: target.h,v $
* Revision 1.33 2000/04/10 05:26:06 steve
* All events now use the NetEvent class.
*
* Revision 1.32 2000/04/04 03:20:15 steve
* Simulate named event trigger and waits.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: vvm.h,v 1.35 2000/03/26 16:55:41 steve Exp $"
#ident "$Id: vvm.h,v 1.36 2000/04/10 05:26:06 steve Exp $"
#endif
# include <cassert>
@ -90,6 +90,11 @@ inline vpip_bit_t B_NOT(vpip_bit_t l)
return StX;
}
/*
* These functions return true if the transition from A to B is a
* Verilog type of negedge of posedge.
*/
extern bool negedge(vpip_bit_t from, vpip_bit_t to);
extern bool posedge(vpip_bit_t from, vpip_bit_t to);
extern ostream& b_output (ostream&os, vpip_bit_t);
@ -121,6 +126,9 @@ class vvm_event {
/*
* $Log: vvm.h,v $
* Revision 1.36 2000/04/10 05:26:06 steve
* All events now use the NetEvent class.
*
* Revision 1.35 2000/03/26 16:55:41 steve
* Remove the vvm_bits_t abstract class.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: vvm_bit.cc,v 1.11 2000/03/26 16:55:41 steve Exp $"
#ident "$Id: vvm_bit.cc,v 1.12 2000/04/10 05:26:07 steve Exp $"
#endif
# include "vvm.h"
@ -48,6 +48,20 @@ ostream& b_output (ostream&os, vpip_bit_t bit)
return os;
}
bool negedge(vpip_bit_t from, vpip_bit_t to)
{
if (B_IS0(from))
return false;
if (B_ISX(from) || B_ISZ(from))
return B_IS0(to);
if (B_IS1(from))
return ! B_IS1(to);
return false;
}
bool posedge(vpip_bit_t from, vpip_bit_t to)
{
if (B_IS1(from))
@ -100,6 +114,9 @@ vpip_bit_t add_with_carry(vpip_bit_t l, vpip_bit_t r, vpip_bit_t&carry)
/*
* $Log: vvm_bit.cc,v $
* Revision 1.12 2000/04/10 05:26:07 steve
* All events now use the NetEvent class.
*
* Revision 1.11 2000/03/26 16:55:41 steve
* Remove the vvm_bits_t abstract class.
*

View File

@ -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.55 2000/04/08 05:49:59 steve Exp $"
#ident "$Id: vvm_gates.h,v 1.56 2000/04/10 05:26:07 steve Exp $"
#endif
# include "vvm.h"
@ -793,13 +793,8 @@ class vvm_bufz : public vvm_nexus::recvr_t, public vvm_nexus::drive_t {
/*
* Threads use the vvm_sync to wait for something to happen. This
* class cooperates with the vvm_pevent class that is the actual gates
* that receive signals. By handling the suspension and the awakening
* separately, I can trivially handle event OR expressions.
*
* When there is an event expression in the source, the elaborator
* makes NetNEvent objects, which are approximately represented by the
* vvm_pevent class.
* class cooperates with the various event source classes that receive
* events and trigger the associated vvm_sync object.
*/
class vvm_sync {
@ -817,56 +812,70 @@ class vvm_sync {
vvm_sync& operator= (const vvm_sync&);
};
template <unsigned WIDTH> class vvm_pevent : public vvm_nexus::recvr_t {
class vvm_anyedge : public vvm_nexus::recvr_t {
public:
enum EDGE { ANYEDGE, POSEDGE, NEGEDGE };
explicit vvm_anyedge(vvm_sync*tgt, unsigned n);
~vvm_anyedge();
explicit vvm_pevent(vvm_sync*tgt, EDGE e)
: target_(tgt), edge_(e)
{ for (unsigned idx = 0 ; idx < WIDTH ; idx += 1)
value_[idx] = HiZ;
}
vpip_bit_t get(unsigned idx) const { return value_[idx]; }
void init_P(int idx, vpip_bit_t val)
{ assert(idx < WIDTH);
value_[idx] = val;
}
void init_P(unsigned idx, vpip_bit_t val);
private:
void take_value(unsigned key, vpip_bit_t val) { set_P(key, val); }
void take_value(unsigned key, vpip_bit_t val);
void set_P(unsigned idx, vpip_bit_t val)
{ if (value_[idx] == val) return;
switch (edge_) {
case ANYEDGE:
target_->wakeup();
break;
case POSEDGE:
if (B_IS1(val))
target_->wakeup();
break;
case NEGEDGE:
if (B_IS0(val))
target_->wakeup();
break;
}
value_[idx] = val;
}
vpip_bit_t*val_;
unsigned nval_;
private:
vvm_sync*target_;
vpip_bit_t value_[WIDTH];
EDGE edge_;
vvm_sync*sync_;
private: // not implemented
vvm_pevent(const vvm_pevent&);
vvm_pevent& operator= (const vvm_pevent&);
vvm_anyedge(const vvm_anyedge&);
vvm_anyedge& operator= (const vvm_anyedge&);
};
class vvm_negedge : public vvm_nexus::recvr_t {
public:
explicit vvm_negedge(vvm_sync*tgt);
~vvm_negedge();
void init_P(int idx, vpip_bit_t val);
private:
void take_value(unsigned key, vpip_bit_t val);
vpip_bit_t val_;
vvm_sync*sync_;
private: // not implemented
vvm_negedge(const vvm_negedge&);
vvm_negedge& operator= (const vvm_negedge&);
};
class vvm_posedge : public vvm_nexus::recvr_t {
public:
explicit vvm_posedge(vvm_sync*tgt);
~vvm_posedge();
void init_P(int idx, vpip_bit_t val);
private:
void take_value(unsigned key, vpip_bit_t val);
vpip_bit_t val_;
vvm_sync*sync_;
private: // not implemented
vvm_posedge(const vvm_posedge&);
vvm_posedge& operator= (const vvm_posedge&);
};
/*
* $Log: vvm_gates.h,v $
* Revision 1.56 2000/04/10 05:26:07 steve
* All events now use the NetEvent class.
*
* Revision 1.55 2000/04/08 05:49:59 steve
* Fix memory object compile problems.
*
@ -890,70 +899,5 @@ template <unsigned WIDTH> class vvm_pevent : public vvm_nexus::recvr_t {
* Replace the vpip_bit_t with a typedef and
* define values for all the different bit
* values, including strengths.
*
* Revision 1.48 2000/03/18 23:22:37 steve
* Update the FF device to nexus style.
*
* Revision 1.47 2000/03/18 02:26:02 steve
* Update bufz to nexus style.
*
* Revision 1.46 2000/03/18 01:27:00 steve
* Generate references into a table of nexus objects instead of
* generating lots of isolated nexus objects. Easier on linkers
* and compilers,
*
* Add missing nexus support for l-value bit selects,
*
* Detemplatize the vvm_mux type.
*
* Fix up the vvm_nexus destructor to disconnect from drivers.
*
* Revision 1.45 2000/03/17 19:24:00 steve
* nor2 and and2 optimized gates.
*
* Revision 1.44 2000/03/17 17:25:53 steve
* Adder and comparator in nexus style.
*
* Revision 1.43 2000/03/17 03:36:07 steve
* Remove some useless template parameters.
*
* Revision 1.42 2000/03/17 03:05:13 steve
* Update vvm_mult to nexus style.
*
* Revision 1.41 2000/03/17 02:22:03 steve
* vvm_clshift implementation without templates.
*
* Revision 1.40 2000/03/16 23:13:49 steve
* Update LPM_MUX to nexus style.
*
* Revision 1.39 2000/03/16 21:47:27 steve
* Update LMP_CLSHIFT to use nexus interface.
*
* Revision 1.38 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
* the t-vvm module doesn't need to write a zillion
* output functions.
*
* Revision 1.37 2000/02/23 04:43:43 steve
* Some compilers do not accept the not symbol.
*
* Revision 1.36 2000/02/23 02:56:57 steve
* Macintosh compilers do not support ident.
*
* Revision 1.35 2000/01/13 03:35:35 steve
* Multiplication all the way to simulation.
*
* Revision 1.34 1999/12/19 20:57:07 steve
* Proper init_ method prototype.
*
* Revision 1.33 1999/12/16 02:42:15 steve
* Simulate carry output on adders.
*
* Revision 1.32 1999/12/12 19:47:54 steve
* Remove the useless vvm_simulation class.
*
* Revision 1.31 1999/12/05 02:24:09 steve
* Synthesize LPM_RAM_DQ for writes into memories.
*/
#endif

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: vvm_pevent.cc,v 1.5 2000/02/23 02:56:57 steve Exp $"
#ident "$Id: vvm_pevent.cc,v 1.6 2000/04/10 05:26:07 steve Exp $"
#endif
# include "vvm.h"
@ -43,8 +43,96 @@ void vvm_sync::wakeup()
}
vvm_posedge::vvm_posedge(vvm_sync*tgt)
: sync_(tgt)
{
val_ = StX;
}
vvm_posedge::~vvm_posedge()
{
}
void vvm_posedge::init_P(int, vpip_bit_t val)
{
val_ = val;
}
void vvm_posedge::take_value(unsigned, vpip_bit_t val)
{
if (val == val_)
return;
if (posedge(val_, val))
sync_->wakeup();
val_ = val;
}
vvm_negedge::vvm_negedge(vvm_sync*tgt)
: sync_(tgt)
{
val_ = StX;
}
vvm_negedge::~vvm_negedge()
{
}
void vvm_negedge::init_P(int, vpip_bit_t val)
{
val_ = val;
}
void vvm_negedge::take_value(unsigned, vpip_bit_t val)
{
if (val == val_)
return;
if (negedge(val_, val))
sync_->wakeup();
val_ = val;
}
vvm_anyedge::vvm_anyedge(vvm_sync*tgt, unsigned n)
: nval_(n), sync_(tgt)
{
val_ = new vpip_bit_t[nval_];
for (unsigned idx = 0 ; idx < nval_ ; idx += 1)
val_[idx] = StX;
}
vvm_anyedge::~vvm_anyedge()
{
delete[]val_;
}
void vvm_anyedge::init_P(unsigned key, vpip_bit_t val)
{
assert(key < nval_);
val_[key] = val;
}
void vvm_anyedge::take_value(unsigned key, vpip_bit_t val)
{
assert(key < nval_);
if (val == val_[key])
return;
if (! B_EQ(val, val_[key]))
sync_->wakeup();
val_[key] = val;
}
/*
* $Log: vvm_pevent.cc,v $
* Revision 1.6 2000/04/10 05:26:07 steve
* All events now use the NetEvent class.
*
* Revision 1.5 2000/02/23 02:56:57 steve
* Macintosh compilers do not support ident.
*