Handle much more complex event expressions.

This commit is contained in:
steve 1999-05-01 02:57:52 +00:00
parent 046a6ba576
commit 41f9a84a4b
18 changed files with 390 additions and 133 deletions

11
PExpr.h
View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: PExpr.h,v 1.6 1999/04/29 02:16:26 steve Exp $"
#ident "$Id: PExpr.h,v 1.7 1999/05/01 02:57:52 steve Exp $"
#endif
# include <string>
@ -64,17 +64,17 @@ ostream& operator << (ostream&, const PExpr&);
class PEEvent : public PExpr {
public:
PEEvent(NetPEvent::Type t, PExpr*e)
PEEvent(NetNEvent::Type t, PExpr*e)
: type_(t), expr_(e)
{ }
NetPEvent::Type type() const { return type_; }
NetNEvent::Type type() const { return type_; }
PExpr* expr() const { return expr_; }
virtual void dump(ostream&) const;
private:
NetPEvent::Type type_;
NetNEvent::Type type_;
PExpr*expr_;
};
@ -169,6 +169,9 @@ class PEBinary : public PExpr {
/*
* $Log: PExpr.h,v $
* Revision 1.7 1999/05/01 02:57:52 steve
* Handle much more complex event expressions.
*
* Revision 1.6 1999/04/29 02:16:26 steve
* Parse OR of event expressions.
*

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.18 1999/04/25 00:44:10 steve Exp $"
#ident "$Id: design_dump.cc,v 1.19 1999/05/01 02:57:52 steve Exp $"
#endif
/*
@ -246,7 +246,7 @@ void NetUDP::dump_node(ostream&o, unsigned ind) const
dump_comb_(o, ind);
}
void NetPEvent::dump_node(ostream&o, unsigned ind) const
void NetNEvent::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "event: ";
switch (edge_) {
@ -360,21 +360,15 @@ void NetPDelay::dump(ostream&o, unsigned ind) const
void NetPEvent::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "" ;
switch (edge_) {
case NEGEDGE:
o << "@" << "(negedge " << name() << ")";
break;
case POSEDGE:
o << "@" << "(posedge " << name() << ")";
break;
case ANYEDGE:
o << "@" << name();
break;
case POSITIVE:
o << "wait (" << name() << ")";
break;
o << setw(ind) << "" << "@(";
svector<const NetNEvent*>*list = back_list();
(*list)[0]->dump_proc(o);
for (unsigned idx = 1 ; idx < list->count() ; idx += 1) {
o << " or ";
(*list)[idx]->dump_proc(o);
}
delete list;
o << ") /* " << name_ << " */";
if (statement_) {
o << endl;
@ -384,7 +378,24 @@ void NetPEvent::dump(ostream&o, unsigned ind) const
}
}
void NetNEvent::dump_proc(ostream&o) const
{
switch (edge_) {
case ANYEDGE:
o << "anyedge ";
break;
case POSEDGE:
o << "posedge ";
break;
case NEGEDGE:
o << "negedge ";
break;
case POSITIVE:
o << "positive ";
break;
}
o << name();
}
void NetTask::dump(ostream&o, unsigned ind) const
{
@ -551,6 +562,9 @@ void Design::dump(ostream&o) const
/*
* $Log: design_dump.cc,v $
* Revision 1.19 1999/05/01 02:57:52 steve
* Handle much more complex event expressions.
*
* Revision 1.18 1999/04/25 00:44:10 steve
* Core handles subsignal expressions.
*

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.21 1999/04/29 02:16:26 steve Exp $"
#ident "$Id: elaborate.cc,v 1.22 1999/05/01 02:57:53 steve Exp $"
#endif
/*
@ -882,29 +882,28 @@ NetProc* PEventStatement::elaborate(Design*des, const string&path) const
return 0;
}
if (expr_.count() != 1) {
cerr << get_line() << ": Sorry, unable to elaborate event "
"OR expressions." << endl;
des->errors += 1;
return 0;
/* Create a single NetPEvent, and a unique NetNEvent for each
conjuctive event. */
NetPEvent*pe = new NetPEvent(des->local_symbol(path), enet);
for (unsigned idx = 0 ; idx < expr_.count() ; idx += 1) {
NetNet*expr = expr_[idx]->expr()->elaborate_net(des, path);
if (expr == 0) {
cerr << get_line() << ": Failed to elaborate expression: ";
expr_[0]->dump(cerr);
cerr << endl;
delete pe;
return 0;
}
assert(expr);
NetNEvent*ne = new NetNEvent(des->local_symbol(path),
expr_[idx]->type(), pe);
connect(ne->pin(0), expr->pin(0));
des->add_node(ne);
}
NetPEvent*ev = new NetPEvent(des->local_symbol(path),
expr_[0]->type(), enet);
NetNet*expr = expr_[0]->expr()->elaborate_net(des, path);
if (expr == 0) {
cerr << get_line() << ": Failed to elaborate expression: ";
expr_[0]->dump(cerr);
cerr << endl;
delete ev;
return 0;
}
assert(expr);
connect(ev->pin(0), expr->pin(0));
des->add_node(ev);
return ev;
return pe;
}
/*
@ -1051,6 +1050,9 @@ Design* elaborate(const map<string,Module*>&modules,
/*
* $Log: elaborate.cc,v $
* Revision 1.22 1999/05/01 02:57:53 steve
* Handle much more complex event expressions.
*
* Revision 1.21 1999/04/29 02:16:26 steve
* Parse OR of event expressions.
*

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.8 1999/04/25 00:44:10 steve Exp $"
#ident "$Id: emit.cc,v 1.9 1999/05/01 02:57:53 steve Exp $"
#endif
/*
@ -55,9 +55,9 @@ void NetConst::emit_node(ostream&o, struct target_t*tgt) const
tgt->net_const(o, this);
}
void NetPEvent::emit_node(ostream&o, struct target_t*tgt) const
void NetNEvent::emit_node(ostream&o, struct target_t*tgt) const
{
tgt->net_pevent(o, this);
tgt->net_event(o, this);
}
void NetBUFZ::emit_node(ostream&o, struct target_t*tgt) const
@ -253,6 +253,9 @@ void emit(ostream&o, const Design*des, const char*type)
/*
* $Log: emit.cc,v $
* Revision 1.9 1999/05/01 02:57:53 steve
* Handle much more complex event expressions.
*
* Revision 1.8 1999/04/25 00:44:10 steve
* Core handles subsignal expressions.
*

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-1999 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
@ -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.21 1999/04/25 00:44:10 steve Exp $"
#ident "$Id: netlist.cc,v 1.22 1999/05/01 02:57:53 steve Exp $"
#endif
# include <cassert>
@ -480,6 +480,7 @@ void NetEBinary::set_width(unsigned w)
case '+':
case '-':
case '^':
left_->set_width(w);
right_->set_width(w);
expr_width(w);
@ -532,6 +533,11 @@ NetESignal::~NetESignal()
void NetESignal::set_width(unsigned w)
{
if (w != pin_count()) {
cerr << "Width of " << w << " does not match " << *this <<
endl;
abort();
}
assert(w == pin_count());
expr_width(w);
}
@ -553,7 +559,15 @@ NetEUnary::~NetEUnary()
void NetEUnary::set_width(unsigned w)
{
expr_->set_width(w);
switch (op_) {
case '&':
assert(w == 1);
break;
default:
case '~':
expr_->set_width(w);
break;
}
expr_width(w);
}
@ -1026,6 +1040,9 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*))
/*
* $Log: netlist.cc,v $
* Revision 1.22 1999/05/01 02:57:53 steve
* Handle much more complex event expressions.
*
* Revision 1.21 1999/04/25 00:44:10 steve
* Core handles subsignal expressions.
*

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.26 1999/04/25 22:52:32 steve Exp $"
#ident "$Id: netlist.h,v 1.27 1999/05/01 02:57:53 steve Exp $"
#endif
/*
@ -31,6 +31,7 @@
# include <string>
# include <map>
# include "verinum.h"
# include "sref.h"
# include "LineInfo.h"
class NetNode;
@ -715,33 +716,55 @@ class NetPDelay : public NetProc {
};
/*
* The NetPEvent is a NetNode that connects to the structural part of
* the design. It has only inputs, which cause the side effect of
* triggering an event that the procedural part of the design can use.
* The NetPEvent is associated with NetNEvents. The NetPEvent receives
* eventss from any one of the associated NetNEvents and in response
* causes the attached statement to be executed. Objects of this type
* are not nodes, but require a name anyhow so that backends can
* generate objects to refer to it.
*/
class NetPEvent : public NetProc, public NetNode {
class NetNEvent;
class NetPEvent : public NetProc, public sref_back<NetPEvent,NetNEvent> {
public:
enum Type { ANYEDGE, POSEDGE, NEGEDGE, POSITIVE };
NetPEvent(const string&n, NetProc*st)
: name_(n), statement_(st) { }
public:
NetPEvent(const string&ev, Type ed, NetProc*st)
: NetNode(ev, 1), edge_(ed), statement_(st) { }
Type edge() const { return edge_; }
string name() const { return name_; }
virtual void emit_proc(ostream&, struct target_t*) const;
virtual void emit_node(ostream&, struct target_t*) const;
virtual void dump(ostream&, unsigned ind) const;
virtual void dump_node(ostream&, unsigned ind) const;
void emit_proc_recurse(ostream&, struct target_t*) const;
private:
Type edge_;
string name_;
NetProc*statement_;
};
/*
* The NetNEvent is a NetNode that connects to the structural part of
* the design. It has only inputs, which cause the side effect of
* triggering an event that the procedural part of the design can use.
*/
class NetNEvent : public NetNode, public sref<NetPEvent,NetNEvent> {
public:
enum Type { ANYEDGE, POSEDGE, NEGEDGE, POSITIVE };
NetNEvent(const string&ev, Type e, NetPEvent*pe)
: NetNode(ev, 1), sref<NetPEvent,NetNEvent>(pe), edge_(e) { }
Type type() const { return edge_; }
virtual void emit_node(ostream&, struct target_t*) const;
void dump_proc(ostream&) const;
virtual void dump_node(ostream&, unsigned ind) const;
private:
Type edge_;
};
/* The elaborator should expand all the user defined tasks in line, so
this leaves the NetTask to represent activations of system tasks,
@ -1129,6 +1152,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
* Revision 1.27 1999/05/01 02:57:53 steve
* Handle much more complex event expressions.
*
* Revision 1.26 1999/04/25 22:52:32 steve
* Generate SubSignal refrences in vvm.
*

10
parse.y
View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: parse.y,v 1.18 1999/04/29 02:16:26 steve Exp $"
#ident "$Id: parse.y,v 1.19 1999/05/01 02:57:53 steve Exp $"
#endif
# include "parse_misc.h"
@ -241,7 +241,7 @@ event_control
event_expression
: K_posedge expression
{ PEEvent*tmp = new PEEvent(NetPEvent::POSEDGE, $2);
{ PEEvent*tmp = new PEEvent(NetNEvent::POSEDGE, $2);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
svector<PEEvent*>*tl = new svector<PEEvent*>(1);
@ -249,7 +249,7 @@ event_expression
$$ = tl;
}
| K_negedge expression
{ PEEvent*tmp = new PEEvent(NetPEvent::NEGEDGE, $2);
{ PEEvent*tmp = new PEEvent(NetNEvent::NEGEDGE, $2);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
svector<PEEvent*>*tl = new svector<PEEvent*>(1);
@ -257,7 +257,7 @@ event_expression
$$ = tl;
}
| expression
{ PEEvent*tmp = new PEEvent(NetPEvent::ANYEDGE, $1);
{ PEEvent*tmp = new PEEvent(NetNEvent::ANYEDGE, $1);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
svector<PEEvent*>*tl = new svector<PEEvent*>(1);
@ -776,7 +776,7 @@ statement
}
| K_wait '(' expression ')' statement_opt
{ PEventStatement*tmp;
PEEvent*etmp = new PEEvent(NetPEvent::POSITIVE, $3);
PEEvent*etmp = new PEEvent(NetNEvent::POSITIVE, $3);
tmp = new PEventStatement(etmp);
tmp->set_statement($5);
$$ = tmp;

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: pform_dump.cc,v 1.13 1999/04/29 02:16:26 steve Exp $"
#ident "$Id: pform_dump.cc,v 1.14 1999/05/01 02:57:53 steve Exp $"
#endif
/*
@ -45,15 +45,15 @@ void PExpr::dump(ostream&out) const
void PEEvent::dump(ostream&out) const
{
switch (type_) {
case NetPEvent::ANYEDGE:
case NetNEvent::ANYEDGE:
break;
case NetPEvent::POSEDGE:
case NetNEvent::POSEDGE:
out << "posedge ";
break;
case NetPEvent::NEGEDGE:
case NetNEvent::NEGEDGE:
out << "negedge ";
break;
case NetPEvent::POSITIVE:
case NetNEvent::POSITIVE:
out << "positive ";
break;
}
@ -434,6 +434,9 @@ void PUdp::dump(ostream&out) const
/*
* $Log: pform_dump.cc,v $
* Revision 1.14 1999/05/01 02:57:53 steve
* Handle much more complex event expressions.
*
* Revision 1.13 1999/04/29 02:16:26 steve
* Parse OR of event expressions.
*

111
sref.h Normal file
View File

@ -0,0 +1,111 @@
#ifndef __sref_H
#define __sref_H
/*
* Copyright (c) 1999 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. In order to redistribute the software in
* binary form, you will need a Picture Elements Binary Software
* License.
*
* 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)
#ident "$Id: sref.h,v 1.1 1999/05/01 02:57:53 steve Exp $"
#endif
# include <assert.h>
# include "svector.h"
/*
* The sref class is a reference with automatic reference counting. It
* implementes a many-to-one linkage where T1 is the many type and T2
* is the one type.
*/
template <class T1, class T2> class sref;
template <class T1, class T2> class sref_back;
template <class T1, class T2> class sref_back {
friend class sref<T1,T2>;
public:
sref_back() : sback_(0) { }
~sref_back() { assert(sback_ == 0); }
svector<const T2*>* back_list() const;
private:
sref<T1,T2>*sback_;
};
template <class T1, class T2> class sref {
friend class sref_back<T1,T2>;
public:
sref(T1*d) : dest_(d) { insert_(); }
virtual ~sref() { desert_(); }
T1*fore_ptr() { return dest_; }
const T1*fore_ptr() const { return dest_; }
private:
T1*dest_;
sref<T1,T2>*next_;
void insert_()
{ if (dest_->sback_ == 0) {
next_ = this;
dest_->sback_ = this;
} else {
next_ = dest_->sback_->next_;
dest_->sback_->next_ = this;
}
}
// Not implemented yet.
void desert_() { assert(0); }
};
template <class T1,class T2>
svector<const T2*>* sref_back<T1,T2>::back_list() const
{
if (sback_ == 0) return 0;
unsigned cnt = 1;
sref<T1,T2>*cur = sback_->next_;
while (cur != sback_) {
cnt += 1;
cur = cur->next_;
}
svector<const T2*>* result = new svector<const T2*>(cnt);
(*result)[0] = dynamic_cast<const T2*>(sback_);
cur = sback_->next_;
cnt = 1;
while (cur != sback_) {
(*result)[cnt] = dynamic_cast<const T2*>(cur);
cnt += 1;
cur = cur->next_;
}
return result;
}
/*
* $Log: sref.h,v $
* Revision 1.1 1999/05/01 02:57:53 steve
* Handle much more complex event expressions.
*
*/
#endif

View File

@ -1,8 +1,7 @@
#ifndef __svector_H
#define __svector_H
/*
* Copyright (c) 1999 Picture Elements, Inc.
* Stephen Williams (steve@picturel.com)
* Copyright (c) 1999 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
@ -20,15 +19,9 @@
* 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
* ---
* You should also have recieved a copy of the Picture Elements
* Binary Software License offer along with the source. This offer
* allows you to obtain the right to redistribute the software in
* binary (compiled) form. If you have not received it, contact
* Picture Elements, Inc., 777 Panoramic Way, Berkeley, CA 94704.
*/
#if !defined(WINNT)
#ident "$Id: svector.h,v 1.1 1999/04/29 02:16:26 steve Exp $"
#ident "$Id: svector.h,v 1.2 1999/05/01 02:57:53 steve Exp $"
#endif
# include <assert.h>
@ -87,6 +80,9 @@ template <class TYPE> class svector {
/*
* $Log: svector.h,v $
* Revision 1.2 1999/05/01 02:57:53 steve
* Handle much more complex event expressions.
*
* Revision 1.1 1999/04/29 02:16:26 steve
* Parse OR of event expressions.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: t-verilog.cc,v 1.3 1998/12/01 00:42:15 steve Exp $"
#ident "$Id: t-verilog.cc,v 1.4 1999/05/01 02:57:53 steve Exp $"
#endif
/*
@ -222,21 +222,25 @@ void target_verilog::proc_event(ostream&os, const NetPEvent*net)
{
os << setw(indent_) << "" << "@";
#if 0
unsigned sidx;
const NetNet*sig = find_link_signal(net, 0, sidx);
switch (net->edge()) {
case NetPEvent::ANYEDGE:
case NetNEvent::ANYEDGE:
os << mangle(sig->name()) << "[" << sidx << "]";
break;
case NetPEvent::POSEDGE:
case NetNEvent::POSEDGE:
os << "(posedge " << mangle(sig->name()) << "[" << sidx << "])";
break;
case NetPEvent::NEGEDGE:
case NetNEvent::NEGEDGE:
os << "(negedge " << mangle(sig->name()) << "[" << sidx << "])";
break;
}
#else
os << endl;
os << "#error \"proc_event temporarily out of order\"";
#endif
os << endl;
indent_ += 4;
@ -294,6 +298,9 @@ const struct target tgt_verilog = {
/*
* $Log: t-verilog.cc,v $
* Revision 1.4 1999/05/01 02:57:53 steve
* Handle much more complex event expressions.
*
* Revision 1.3 1998/12/01 00:42:15 steve
* Elaborate UDP devices,
* Support UDP type attributes, and

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.17 1999/04/25 22:52:32 steve Exp $"
#ident "$Id: t-vvm.cc,v 1.18 1999/05/01 02:57:53 steve Exp $"
#endif
# include <iostream>
@ -47,7 +47,7 @@ class target_vvm : public target_t {
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 net_event(ostream&os, const NetNEvent*);
virtual void start_process(ostream&os, const NetProcTop*);
virtual void proc_assign(ostream&os, const NetAssign*);
virtual void proc_block(ostream&os, const NetBlock*);
@ -584,7 +584,7 @@ void target_vvm::net_esignal(ostream&os, const NetESignal*net)
}
/*
* The net_pevent device is a synthetic device type--a fabrication of
* The net_event device is a synthetic device type--a fabrication of
* the elaboration phase. An event device receives value changes from
* the attached signal. It is an input only device, its only value
* being the side-effects that threads waiting on events can be
@ -593,10 +593,32 @@ void target_vvm::net_esignal(ostream&os, const NetESignal*net)
* The proc_event method handles the other half of this, the process
* that blocks on the event.
*/
void target_vvm::net_pevent(ostream&os, const NetPEvent*gate)
void target_vvm::net_event(ostream&os, const NetNEvent*gate)
{
os << "static vvm_pevent " << mangle(gate->name()) << ";"
" /* " << gate->name() << " */" << endl;
string pevent = mangle(gate->fore_ptr()->name());
os << " /* " << gate->name() << " */" << endl;
os << "#ifndef PEVENT_" << pevent << endl;
os << "#define PEVENT_" << pevent << endl;
os << "static vvm_sync " << pevent << ";" << endl;
os << "#endif" << endl;
os << "static vvm_pevent " << mangle(gate->name()) << "(&" <<
pevent << ", ";
switch (gate->type()) {
case NetNEvent::POSEDGE:
os << "vvm_pevent::POSEDGE";
break;
case NetNEvent::NEGEDGE:
os << "vvm_pevent::NEGEDGE";
break;
case NetNEvent::ANYEDGE:
os << "vvm_pevent::ANYEDGE";
break;
default:
assert(0);
}
os << ");" << endl;
}
void target_vvm::start_process(ostream&os, const NetProcTop*proc)
@ -829,6 +851,7 @@ void target_vvm::proc_event(ostream&os, const NetPEvent*proc)
thread_step_ += 1;
os << " step_ = &step_" << thread_step_ << "_;" << endl;
#if 0
/* POSITIVE is for the wait construct, and needs to be handled
specially. The structure of the generated code is:
@ -879,7 +902,18 @@ void target_vvm::proc_event(ostream&os, const NetPEvent*proc)
os << " }" << endl;
os << " bool step_" << thread_step_ << "_()" << endl;
os << " {" << endl;
#else
/* The canonical wait for an edge puts the thread into the
correct wait object, then returns false from the thread to
suspend execution. When things are ready to proceed, the
correct vvm_pevent will send a wakeup to start the next
basic block. */
os << " " << mangle(proc->name()) << ".wait(this);" << endl;
os << " return false;" << endl;
os << " }" << endl;
os << " bool step_" << thread_step_ << "_()" << endl;
os << " {" << endl;
#endif
proc->emit_proc_recurse(os, this);
}
@ -923,6 +957,9 @@ extern const struct target tgt_vvm = {
};
/*
* $Log: t-vvm.cc,v $
* Revision 1.18 1999/05/01 02:57:53 steve
* Handle much more complex event expressions.
*
* Revision 1.17 1999/04/25 22:52:32 steve
* Generate SubSignal refrences in vvm.
*

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.7 1999/04/25 00:44:10 steve Exp $"
#ident "$Id: target.cc,v 1.8 1999/05/01 02:57:53 steve Exp $"
#endif
# include "target.h"
@ -73,10 +73,10 @@ void target_t::net_esignal(ostream&os, const NetESignal*)
"Unhandled Expression Signal node." << endl;
}
void target_t::net_pevent(ostream&os, const NetPEvent*)
void target_t::net_event(ostream&os, const NetNEvent*)
{
cerr << "target (" << typeid(*this).name() << "): "
"Unhandled EVENT node." << endl;
"Unhandled EVENT net node." << endl;
}
void target_t::start_process(ostream&os, const NetProcTop*)
@ -184,6 +184,9 @@ void expr_scan_t::expr_binary(const NetEBinary*ex)
/*
* $Log: target.cc,v $
* Revision 1.8 1999/05/01 02:57:53 steve
* Handle much more complex event expressions.
*
* Revision 1.7 1999/04/25 00:44:10 steve
* Core handles subsignal expressions.
*

View File

@ -1,7 +1,7 @@
#ifndef __target_H
#define __target_H
/*
* Copyright (c) 1998 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-1999 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
@ -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.7 1999/04/25 00:44:10 steve Exp $"
#ident "$Id: target.h,v 1.8 1999/05/01 02:57:53 steve Exp $"
#endif
# include "netlist.h"
@ -68,7 +68,7 @@ struct target_t {
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*);
virtual void net_event(ostream&os, const NetNEvent*);
/* Output a process (called for each process) */
virtual void start_process(ostream&os, const NetProcTop*);
@ -121,6 +121,9 @@ extern const struct target *target_table[];
/*
* $Log: target.h,v $
* Revision 1.8 1999/05/01 02:57:53 steve
* Handle much more complex event expressions.
*
* Revision 1.7 1999/04/25 00:44:10 steve
* Core handles subsignal expressions.
*

View File

@ -17,19 +17,19 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: targets.cc,v 1.3 1999/01/24 01:35:36 steve Exp $"
#ident "$Id: targets.cc,v 1.4 1999/05/01 02:57:53 steve Exp $"
#endif
# include "target.h"
extern const struct target tgt_null;
extern const struct target tgt_verilog;
//extern const struct target tgt_verilog;
extern const struct target tgt_vvm;
extern const struct target tgt_xnf;
const struct target *target_table[] = {
&tgt_null,
&tgt_verilog,
//&tgt_verilog,
&tgt_vvm,
&tgt_xnf,
0
@ -37,6 +37,9 @@ const struct target *target_table[] = {
/*
* $Log: targets.cc,v $
* Revision 1.4 1999/05/01 02:57:53 steve
* Handle much more complex event expressions.
*
* Revision 1.3 1999/01/24 01:35:36 steve
* Support null target for generating no output.
*

View File

@ -1 +1,2 @@
dep
Makefile

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: vvm_gates.h,v 1.7 1999/02/15 05:52:50 steve Exp $"
#ident "$Id: vvm_gates.h,v 1.8 1999/05/01 02:57:53 steve Exp $"
#endif
# include "vvm.h"
@ -341,20 +341,45 @@ class vvm_bufz {
vvm_out_event::action_t output_;
};
/*
* 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 vvm_sync {
public:
vvm_sync();
void wait(vvm_thread*);
void wakeup(vvm_simulation*sim);
private:
vvm_thread*hold_;
private: // not implemented
vvm_sync(const vvm_sync&);
vvm_sync& operator= (const vvm_sync&);
};
class vvm_pevent {
public:
enum EDGE { ANYEDGE, POSEDGE, NEGEDGE };
explicit vvm_pevent();
void wait(EDGE, vvm_thread*);
explicit vvm_pevent(vvm_sync*tgt, EDGE e);
void set(vvm_simulation*sim, unsigned, vvm_bit_t val);
vvm_bit_t get() const { return value_; }
private:
vvm_sync*target_;
vvm_bit_t value_;
vvm_thread*hold_;
EDGE hold_edge_;
EDGE edge_;
private: // not implemented
vvm_pevent(const vvm_pevent&);
@ -363,6 +388,9 @@ class vvm_pevent {
/*
* $Log: vvm_gates.h,v $
* Revision 1.8 1999/05/01 02:57:53 steve
* Handle much more complex event expressions.
*
* Revision 1.7 1999/02/15 05:52:50 steve
* Mangle that handles device instance numbers.
*

View File

@ -17,52 +17,49 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: vvm_pevent.cc,v 1.1 1998/11/09 23:44:11 steve Exp $"
#ident "$Id: vvm_pevent.cc,v 1.2 1999/05/01 02:57:53 steve Exp $"
#endif
# include "vvm.h"
# include "vvm_gates.h"
vvm_pevent::vvm_pevent()
: value_(V0), hold_(0)
vvm_sync::vvm_sync()
: hold_(0)
{
}
void vvm_pevent::wait(EDGE edge, vvm_thread*thr)
void vvm_sync::wait(vvm_thread*thr)
{
assert(hold_ == 0);
hold_ = thr;
hold_edge_ = edge;
}
void vvm_sync::wakeup(vvm_simulation*sim)
{
vvm_thread*tmp = hold_;
hold_ = 0;
if (tmp) sim->thread_active(tmp);
}
vvm_pevent::vvm_pevent(vvm_sync*tgt, EDGE e)
: target_(tgt), value_(V0), edge_(e)
{
}
void vvm_pevent::set(vvm_simulation*sim, unsigned, vvm_bit_t val)
{
if (hold_ == 0) {
value_ = val;
return;
}
if (value_ != val) {
vvm_thread*tmp;
switch (hold_edge_) {
switch (edge_) {
case ANYEDGE:
tmp = hold_;
hold_ = 0;
sim->thread_active(tmp);
target_->wakeup(sim);
break;
case POSEDGE:
if (val == V1) {
tmp = hold_;
hold_ = 0;
sim->thread_active(tmp);
}
if (val == V1)
target_->wakeup(sim);
break;
case NEGEDGE:
if (val == V0) {
tmp = hold_;
hold_ = 0;
sim->thread_active(tmp);
}
if (val == V0)
target_->wakeup(sim);
break;
}
value_ = val;
@ -71,6 +68,9 @@ void vvm_pevent::set(vvm_simulation*sim, unsigned, vvm_bit_t val)
/*
* $Log: vvm_pevent.cc,v $
* Revision 1.2 1999/05/01 02:57:53 steve
* Handle much more complex event expressions.
*
* Revision 1.1 1998/11/09 23:44:11 steve
* Add vvm library.
*