Handle much more complex event expressions.
This commit is contained in:
parent
046a6ba576
commit
41f9a84a4b
11
PExpr.h
11
PExpr.h
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
46
elaborate.cc
46
elaborate.cc
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
9
emit.cc
9
emit.cc
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
23
netlist.cc
23
netlist.cc
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
54
netlist.h
54
netlist.h
|
|
@ -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
10
parse.y
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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
|
||||
14
svector.h
14
svector.h
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
17
t-verilog.cc
17
t-verilog.cc
|
|
@ -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
|
||||
|
|
|
|||
51
t-vvm.cc
51
t-vvm.cc
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
9
target.h
9
target.h
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1 +1,2 @@
|
|||
dep
|
||||
Makefile
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue