Finally remove the NetNEvent and NetPEvent classes,
Get synthesis working with the NetEvWait class, and get started supporting multiple events in a wait in vvm.
This commit is contained in:
parent
59bbc27268
commit
4493e968da
|
|
@ -18,7 +18,7 @@
|
|||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.43 2000/04/04 03:20:15 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.44 2000/04/12 20:02:52 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
|
@ -67,7 +67,7 @@ distclean: clean
|
|||
rm -f Makefile
|
||||
|
||||
TT = t-null.o t-verilog.o t-vvm.o t-xnf.o
|
||||
FF = nobufz.o nodangle.o propinit.o synth.o xnfio.o xnfsyn.o
|
||||
FF = nobufz.o nodangle.o propinit.o synth.o xnfio.o
|
||||
|
||||
O = main.o cprop.o design_dump.o dup_expr.o elaborate.o elab_expr.o \
|
||||
elab_net.o elab_pexpr.o elab_scope.o emit.o eval.o eval_tree.o \
|
||||
|
|
|
|||
|
|
@ -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.75 2000/04/12 04:23:57 steve Exp $"
|
||||
#ident "$Id: design_dump.cc,v 1.76 2000/04/12 20:02:52 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -370,29 +370,6 @@ void NetUDP_COMB::dump_node(ostream&o, unsigned ind) const
|
|||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
|
||||
void NetNEvent::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "event: ";
|
||||
switch (edge_) {
|
||||
case ANYEDGE:
|
||||
o << "anyedge ";
|
||||
break;
|
||||
case POSEDGE:
|
||||
o << "posedge ";
|
||||
break;
|
||||
case NEGEDGE:
|
||||
o << "negedge ";
|
||||
break;
|
||||
case POSITIVE:
|
||||
o << "positive ";
|
||||
break;
|
||||
}
|
||||
|
||||
o << name() << " --> " << event_->name() << endl;
|
||||
|
||||
dump_node_pins(o, ind+4);
|
||||
}
|
||||
|
||||
void NetProcTop::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
switch (type_) {
|
||||
|
|
@ -595,47 +572,6 @@ void NetPDelay::dump(ostream&o, unsigned ind) const
|
|||
}
|
||||
}
|
||||
|
||||
void NetPEvent::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "@(";
|
||||
|
||||
if (src_) {
|
||||
const NetNEvent*cur = src_;
|
||||
for (cur = src_->next_ ; cur ; cur = cur->next_) {
|
||||
o << " or ";
|
||||
cur->dump_proc(o);
|
||||
}
|
||||
}
|
||||
|
||||
o << ") /* " << name_ << " */";
|
||||
|
||||
if (statement_) {
|
||||
o << endl;
|
||||
statement_->dump(o, ind+2);
|
||||
} else {
|
||||
o << " /* noop */;" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
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 NetRepeat::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "repeat (" << *expr_ << ")" << endl;
|
||||
|
|
@ -954,6 +890,12 @@ void Design::dump(ostream&o) const
|
|||
|
||||
/*
|
||||
* $Log: design_dump.cc,v $
|
||||
* Revision 1.76 2000/04/12 20:02:52 steve
|
||||
* Finally remove the NetNEvent and NetPEvent classes,
|
||||
* Get synthesis working with the NetEvWait class,
|
||||
* and get started supporting multiple events in a
|
||||
* wait in vvm.
|
||||
*
|
||||
* Revision 1.75 2000/04/12 04:23:57 steve
|
||||
* Named events really should be expressed with PEIdent
|
||||
* objects in the pform,
|
||||
|
|
|
|||
20
functor.cc
20
functor.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: functor.cc,v 1.13 2000/04/01 21:40:22 steve Exp $"
|
||||
#ident "$Id: functor.cc,v 1.14 2000/04/12 20:02:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "functor.h"
|
||||
|
|
@ -177,18 +177,24 @@ int NetCondit::match_proc(proc_match_t*that)
|
|||
return that->condit(this);
|
||||
}
|
||||
|
||||
int proc_match_t::pevent(NetPEvent*)
|
||||
int NetEvWait::match_proc(proc_match_t*that)
|
||||
{
|
||||
return that->event_wait(this);
|
||||
}
|
||||
|
||||
int proc_match_t::event_wait(NetEvWait*)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int NetPEvent::match_proc(proc_match_t*that)
|
||||
{
|
||||
return that->pevent(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: functor.cc,v $
|
||||
* Revision 1.14 2000/04/12 20:02:53 steve
|
||||
* Finally remove the NetNEvent and NetPEvent classes,
|
||||
* Get synthesis working with the NetEvWait class,
|
||||
* and get started supporting multiple events in a
|
||||
* wait in vvm.
|
||||
*
|
||||
* Revision 1.13 2000/04/01 21:40:22 steve
|
||||
* Add support for integer division.
|
||||
*
|
||||
|
|
|
|||
10
functor.h
10
functor.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: functor.h,v 1.10 2000/04/01 21:40:22 steve Exp $"
|
||||
#ident "$Id: functor.h,v 1.11 2000/04/12 20:02:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -67,13 +67,19 @@ struct proc_match_t {
|
|||
virtual int assign(class NetAssign*);
|
||||
virtual int assign_mem(class NetAssignMem*);
|
||||
virtual int condit(class NetCondit*);
|
||||
virtual int pevent(class NetPEvent*);
|
||||
virtual int event_wait(class NetEvWait*);
|
||||
virtual int block(class NetBlock*);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* $Log: functor.h,v $
|
||||
* Revision 1.11 2000/04/12 20:02:53 steve
|
||||
* Finally remove the NetNEvent and NetPEvent classes,
|
||||
* Get synthesis working with the NetEvWait class,
|
||||
* and get started supporting multiple events in a
|
||||
* wait in vvm.
|
||||
*
|
||||
* Revision 1.10 2000/04/01 21:40:22 steve
|
||||
* Add support for integer division.
|
||||
*
|
||||
|
|
|
|||
10
main.cc
10
main.cc
|
|
@ -19,7 +19,7 @@ const char COPYRIGHT[] =
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: main.cc,v 1.30 2000/03/17 21:50:25 steve Exp $"
|
||||
#ident "$Id: main.cc,v 1.31 2000/04/12 20:02:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
const char NOTICE[] =
|
||||
|
|
@ -92,7 +92,6 @@ extern void synth(Design*des);
|
|||
extern void nobufz(Design*des);
|
||||
extern void nodangle(Design*des);
|
||||
extern void xnfio(Design*des);
|
||||
extern void xnfsyn(Design*des);
|
||||
|
||||
typedef void (*net_func)(Design*);
|
||||
static struct net_func_map {
|
||||
|
|
@ -105,7 +104,6 @@ static struct net_func_map {
|
|||
{ "propinit",&propinit },
|
||||
{ "synth", &synth },
|
||||
{ "xnfio", &xnfio },
|
||||
{ "xnfsyn", &xnfsyn },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
|
|
@ -307,6 +305,12 @@ int main(int argc, char*argv[])
|
|||
|
||||
/*
|
||||
* $Log: main.cc,v $
|
||||
* Revision 1.31 2000/04/12 20:02:53 steve
|
||||
* Finally remove the NetNEvent and NetPEvent classes,
|
||||
* Get synthesis working with the NetEvWait class,
|
||||
* and get started supporting multiple events in a
|
||||
* wait in vvm.
|
||||
*
|
||||
* Revision 1.30 2000/03/17 21:50:25 steve
|
||||
* Switch to control warnings.
|
||||
*
|
||||
|
|
|
|||
45
net_event.cc
45
net_event.cc
|
|
@ -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.3 2000/04/12 04:23:58 steve Exp $"
|
||||
#ident "$Id: net_event.cc,v 1.4 2000/04/12 20:02:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "netlist.h"
|
||||
|
|
@ -27,6 +27,7 @@ NetEvent::NetEvent(const string&n)
|
|||
{
|
||||
scope_ = 0;
|
||||
snext_ = 0;
|
||||
probes_ = 0;
|
||||
}
|
||||
|
||||
NetEvent::~NetEvent()
|
||||
|
|
@ -44,6 +45,28 @@ string NetEvent::full_name() const
|
|||
return scope_->name() + "." + name_;
|
||||
}
|
||||
|
||||
unsigned NetEvent::nprobe() const
|
||||
{
|
||||
unsigned cnt = 0;
|
||||
NetEvProbe*cur = probes_;
|
||||
while (cur) {
|
||||
cnt += 1;
|
||||
cur = cur->enext_;
|
||||
}
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
NetEvProbe* NetEvent::probe(unsigned idx)
|
||||
{
|
||||
NetEvProbe*cur = probes_;
|
||||
while (cur && idx) {
|
||||
cur = cur->enext_;
|
||||
idx -= 1;
|
||||
}
|
||||
return cur;
|
||||
}
|
||||
|
||||
NetEvTrig::NetEvTrig(NetEvent*ev)
|
||||
: event_(ev)
|
||||
{
|
||||
|
|
@ -66,6 +89,9 @@ NetEvProbe::NetEvProbe(const string&n, NetEvent*tgt,
|
|||
pin(idx).set_dir(Link::INPUT);
|
||||
pin(idx).set_name("P", idx);
|
||||
}
|
||||
|
||||
enext_ = event_->probes_;
|
||||
event_->probes_ = this;
|
||||
}
|
||||
|
||||
NetEvProbe::~NetEvProbe()
|
||||
|
|
@ -124,8 +150,25 @@ const NetEvent* NetEvWait::event(unsigned idx) const
|
|||
return events_[idx];
|
||||
}
|
||||
|
||||
NetEvent* NetEvWait::event(unsigned idx)
|
||||
{
|
||||
assert(idx < nevents_);
|
||||
return events_[idx];
|
||||
}
|
||||
|
||||
NetProc* NetEvWait::statement()
|
||||
{
|
||||
return statement_;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: net_event.cc,v $
|
||||
* Revision 1.4 2000/04/12 20:02:53 steve
|
||||
* Finally remove the NetNEvent and NetPEvent classes,
|
||||
* Get synthesis working with the NetEvWait class,
|
||||
* and get started supporting multiple events in a
|
||||
* wait in vvm.
|
||||
*
|
||||
* Revision 1.3 2000/04/12 04:23:58 steve
|
||||
* Named events really should be expressed with PEIdent
|
||||
* objects in the pform,
|
||||
|
|
|
|||
94
netlist.cc
94
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.112 2000/04/04 03:20:15 steve Exp $"
|
||||
#ident "$Id: netlist.cc,v 1.113 2000/04/12 20:02:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <cassert>
|
||||
|
|
@ -1461,7 +1461,7 @@ NetAssign_::~NetAssign_()
|
|||
|
||||
void NetAssign_::set_rval(NetExpr*r)
|
||||
{
|
||||
assert(rval_ == 0);
|
||||
if (rval_) delete rval_;
|
||||
rval_ = r;
|
||||
}
|
||||
|
||||
|
|
@ -1755,90 +1755,6 @@ const NetNet* NetFuncDef::port(unsigned idx) const
|
|||
return ports_[idx];
|
||||
}
|
||||
|
||||
NetNEvent::NetNEvent(const string&ev, unsigned wid, Type e, NetPEvent*pe)
|
||||
: NetNode(ev, wid), edge_(e)
|
||||
{
|
||||
event_ = pe;
|
||||
next_ = pe->src_;
|
||||
pe->src_ = this;
|
||||
|
||||
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
|
||||
pin(idx).set_name("P", idx);
|
||||
}
|
||||
}
|
||||
|
||||
NetNEvent::~NetNEvent()
|
||||
{
|
||||
}
|
||||
|
||||
NetNEvent::Type NetNEvent::type() const
|
||||
{
|
||||
return edge_;
|
||||
}
|
||||
|
||||
const NetPEvent* NetNEvent::pevent() const
|
||||
{
|
||||
return event_;
|
||||
}
|
||||
|
||||
NetPEvent::NetPEvent(const string&n, NetProc*st)
|
||||
: name_(n), statement_(st), src_(0)
|
||||
{
|
||||
idx_ = 0;
|
||||
}
|
||||
|
||||
NetPEvent::~NetPEvent()
|
||||
{
|
||||
while (src_) {
|
||||
NetNEvent*cur = src_;
|
||||
src_ = src_->next_;
|
||||
delete cur;
|
||||
}
|
||||
|
||||
delete statement_;
|
||||
}
|
||||
|
||||
string NetPEvent::name() const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
NetProc* NetPEvent::statement()
|
||||
{
|
||||
return statement_;
|
||||
}
|
||||
|
||||
const NetProc* NetPEvent::statement() const
|
||||
{
|
||||
return statement_;
|
||||
}
|
||||
|
||||
NetNEvent* NetPEvent::first()
|
||||
{
|
||||
idx_ = src_;
|
||||
return idx_;
|
||||
}
|
||||
|
||||
NetNEvent* NetPEvent::next()
|
||||
{
|
||||
assert(idx_);
|
||||
idx_ = idx_->next_;
|
||||
return idx_;
|
||||
}
|
||||
|
||||
const NetNEvent* NetPEvent::first() const
|
||||
{
|
||||
idx_ = src_;
|
||||
return idx_;
|
||||
}
|
||||
|
||||
const NetNEvent* NetPEvent::next() const
|
||||
{
|
||||
assert(idx_);
|
||||
idx_ = idx_->next_;
|
||||
return idx_;
|
||||
}
|
||||
|
||||
NetSTask::NetSTask(const string&na, const svector<NetExpr*>&pa)
|
||||
: name_(na), parms_(pa)
|
||||
{
|
||||
|
|
@ -2530,6 +2446,12 @@ bool NetUDP::sequ_glob_(string input, char output)
|
|||
|
||||
/*
|
||||
* $Log: netlist.cc,v $
|
||||
* Revision 1.113 2000/04/12 20:02:53 steve
|
||||
* Finally remove the NetNEvent and NetPEvent classes,
|
||||
* Get synthesis working with the NetEvWait class,
|
||||
* and get started supporting multiple events in a
|
||||
* wait in vvm.
|
||||
*
|
||||
* Revision 1.112 2000/04/04 03:20:15 steve
|
||||
* Simulate named event trigger and waits.
|
||||
*
|
||||
|
|
|
|||
99
netlist.h
99
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.120 2000/04/12 04:23:58 steve Exp $"
|
||||
#ident "$Id: netlist.h,v 1.121 2000/04/12 20:02:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -1044,11 +1044,12 @@ class NetAssign_ : public NetProc, public NetNode {
|
|||
// the pin that gets the value.
|
||||
const NetExpr*bmux() const;
|
||||
|
||||
void set_rval(NetExpr*);
|
||||
|
||||
protected:
|
||||
NetAssign_(const string&n, unsigned w);
|
||||
virtual ~NetAssign_() =0;
|
||||
|
||||
void set_rval(NetExpr*);
|
||||
void set_bmux(NetExpr*);
|
||||
|
||||
private:
|
||||
|
|
@ -1271,6 +1272,7 @@ class NetCondit : public NetProc {
|
|||
class NetEvent : public LineInfo {
|
||||
|
||||
friend class NetScope;
|
||||
friend class NetEvProbe;
|
||||
|
||||
public:
|
||||
explicit NetEvent (const string&n);
|
||||
|
|
@ -1279,6 +1281,10 @@ class NetEvent : public LineInfo {
|
|||
string name() const;
|
||||
string full_name() const;
|
||||
|
||||
// Get information about probes connected to me.
|
||||
unsigned nprobe() const;
|
||||
NetEvProbe* probe(unsigned);
|
||||
|
||||
NetScope* scope();
|
||||
const NetScope* scope() const;
|
||||
|
||||
|
|
@ -1289,6 +1295,9 @@ class NetEvent : public LineInfo {
|
|||
NetScope*scope_;
|
||||
NetEvent*snext_;
|
||||
|
||||
// Use these methods to list the probes attached to me.
|
||||
NetEvProbe*probes_;
|
||||
|
||||
private: // not implemented
|
||||
NetEvent(const NetEvent&);
|
||||
NetEvent& operator= (const NetEvent&);
|
||||
|
|
@ -1319,9 +1328,13 @@ class NetEvWait : public NetProc {
|
|||
|
||||
unsigned nevents() const;
|
||||
const NetEvent*event(unsigned) const;
|
||||
NetEvent*event(unsigned);
|
||||
|
||||
NetProc*statement();
|
||||
|
||||
virtual bool emit_proc(ostream&, struct target_t*) const;
|
||||
bool emit_recurse(ostream&, struct target_t*) const;
|
||||
virtual int match_proc(struct proc_match_t*);
|
||||
virtual void dump(ostream&, unsigned ind) const;
|
||||
|
||||
private:
|
||||
|
|
@ -1333,6 +1346,8 @@ class NetEvWait : public NetProc {
|
|||
|
||||
class NetEvProbe : public NetNode {
|
||||
|
||||
friend class NetEvent;
|
||||
|
||||
public:
|
||||
enum edge_t { ANYEDGE, POSEDGE, NEGEDGE };
|
||||
|
||||
|
|
@ -1349,6 +1364,8 @@ class NetEvProbe : public NetNode {
|
|||
private:
|
||||
NetEvent*event_;
|
||||
edge_t edge_;
|
||||
// The NetEvent class uses this to list me.
|
||||
NetEvProbe*enext_;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -1417,78 +1434,6 @@ class NetPDelay : public NetProc {
|
|||
NetProc*statement_;
|
||||
};
|
||||
|
||||
/*
|
||||
* The NetPEvent is associated with NetNEvents. The NetPEvent receives
|
||||
* events 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.
|
||||
*
|
||||
* The NetPEvent is the procedural part of the event.
|
||||
*/
|
||||
class NetPEvent : public NetProc {
|
||||
|
||||
friend class NetNEvent;
|
||||
|
||||
public:
|
||||
NetPEvent(const string&n, NetProc*st);
|
||||
~NetPEvent();
|
||||
|
||||
string name() const;
|
||||
NetProc* statement();
|
||||
const NetProc* statement() const;
|
||||
|
||||
NetNEvent* first();
|
||||
NetNEvent* next();
|
||||
|
||||
const NetNEvent* first() const;
|
||||
const NetNEvent* next() const;
|
||||
|
||||
virtual int match_proc(struct proc_match_t*);
|
||||
virtual void dump(ostream&, unsigned ind) const;
|
||||
|
||||
private:
|
||||
string name_;
|
||||
NetProc*statement_;
|
||||
// This is a list of the source events that can trigger me.
|
||||
NetNEvent*src_;
|
||||
mutable NetNEvent*idx_;
|
||||
};
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* The NetNEvent may have wide input if is is an ANYEDGE type
|
||||
* device. This allows detecting changes in wide expressions.
|
||||
*/
|
||||
class NetNEvent : public NetNode {
|
||||
|
||||
friend class NetPEvent;
|
||||
|
||||
public:
|
||||
enum Type { ANYEDGE, POSEDGE, NEGEDGE, POSITIVE };
|
||||
|
||||
// Use this constructor to create NEvent objects that receive
|
||||
// their status from the structural netlist.
|
||||
NetNEvent(const string&ev, unsigned wid, Type e, NetPEvent*pe);
|
||||
|
||||
~NetNEvent();
|
||||
|
||||
Type type() const;
|
||||
const NetPEvent*pevent() const;
|
||||
|
||||
void dump_proc(ostream&) const;
|
||||
virtual void dump_node(ostream&, unsigned ind) const;
|
||||
|
||||
private:
|
||||
Type edge_;
|
||||
NetPEvent*event_;
|
||||
NetNEvent*next_;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* A repeat statement is executed some fixed number of times.
|
||||
*/
|
||||
|
|
@ -2399,6 +2344,12 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
|||
|
||||
/*
|
||||
* $Log: netlist.h,v $
|
||||
* Revision 1.121 2000/04/12 20:02:53 steve
|
||||
* Finally remove the NetNEvent and NetPEvent classes,
|
||||
* Get synthesis working with the NetEvWait class,
|
||||
* and get started supporting multiple events in a
|
||||
* wait in vvm.
|
||||
*
|
||||
* Revision 1.120 2000/04/12 04:23:58 steve
|
||||
* Named events really should be expressed with PEIdent
|
||||
* objects in the pform,
|
||||
|
|
|
|||
|
|
@ -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.53 2000/04/12 04:23:58 steve Exp $"
|
||||
#ident "$Id: pform_dump.cc,v 1.54 2000/04/12 20:02:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -82,15 +82,15 @@ void PECallFunction::dump(ostream &out) const
|
|||
void PEEvent::dump(ostream&out) const
|
||||
{
|
||||
switch (type_) {
|
||||
case NetNEvent::ANYEDGE:
|
||||
case PEEvent::ANYEDGE:
|
||||
break;
|
||||
case NetNEvent::POSEDGE:
|
||||
case PEEvent::POSEDGE:
|
||||
out << "posedge ";
|
||||
break;
|
||||
case NetNEvent::NEGEDGE:
|
||||
case PEEvent::NEGEDGE:
|
||||
out << "negedge ";
|
||||
break;
|
||||
case NetNEvent::POSITIVE:
|
||||
case PEEvent::POSITIVE:
|
||||
out << "positive ";
|
||||
break;
|
||||
}
|
||||
|
|
@ -733,6 +733,12 @@ void PUdp::dump(ostream&out) const
|
|||
|
||||
/*
|
||||
* $Log: pform_dump.cc,v $
|
||||
* Revision 1.54 2000/04/12 20:02:53 steve
|
||||
* Finally remove the NetNEvent and NetPEvent classes,
|
||||
* Get synthesis working with the NetEvWait class,
|
||||
* and get started supporting multiple events in a
|
||||
* wait in vvm.
|
||||
*
|
||||
* Revision 1.53 2000/04/12 04:23:58 steve
|
||||
* Named events really should be expressed with PEIdent
|
||||
* objects in the pform,
|
||||
|
|
|
|||
95
synth.cc
95
synth.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: synth.cc,v 1.7 2000/04/02 04:26:07 steve Exp $"
|
||||
#ident "$Id: synth.cc,v 1.8 2000/04/12 20:02:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -30,6 +30,55 @@
|
|||
# include "functor.h"
|
||||
# include "netlist.h"
|
||||
|
||||
/*
|
||||
* This functor scans the behavioral code, looking for expressions to
|
||||
* synthesize. Although it uses the proc_match_t class, it doesn't
|
||||
* actually match anything, but transforms expressions into structural
|
||||
* netlists. The product of this should be a process where all the
|
||||
* expressions have been reduced to a signal ident, which references
|
||||
* the NetNet of the now synthesized expression.
|
||||
*/
|
||||
class do_expr : public proc_match_t {
|
||||
|
||||
public:
|
||||
do_expr(Design*d)
|
||||
: des_(d) { }
|
||||
|
||||
private:
|
||||
|
||||
Design*des_;
|
||||
|
||||
virtual int assign(NetAssign*);
|
||||
virtual int event_wait(NetEvWait*);
|
||||
//virtual int assign_mem(NetAssignMem*);
|
||||
//virtual int condit(NetCondit*);
|
||||
};
|
||||
|
||||
|
||||
int do_expr::assign(NetAssign*stmt)
|
||||
{
|
||||
if (dynamic_cast<NetESignal*>(stmt->rval()))
|
||||
return 0;
|
||||
|
||||
NetNet*tmp = stmt->rval()->synthesize(des_);
|
||||
if (tmp == 0)
|
||||
return 0;
|
||||
|
||||
NetESignal*tmpe = new NetESignal(tmp);
|
||||
stmt->set_rval(tmpe);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int do_expr::event_wait(NetEvWait*stmt)
|
||||
{
|
||||
NetProc*tmp = stmt->statement();
|
||||
if (tmp)
|
||||
return tmp->match_proc(this);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This transform recognizes the following patterns:
|
||||
*
|
||||
|
|
@ -55,7 +104,7 @@ class match_dff : public proc_match_t {
|
|||
|
||||
public:
|
||||
match_dff(Design*d, NetProcTop*t)
|
||||
: des_(d), top_(t), pclk_(0), nclk_(0), con_(0), ce_(0),
|
||||
: des_(d), top_(t), wclk_(0), eclk_(0), pclk_(0), con_(0), ce_(0),
|
||||
asn_(0), asm_(0), d_(0)
|
||||
{ }
|
||||
|
||||
|
|
@ -70,12 +119,14 @@ class match_dff : public proc_match_t {
|
|||
virtual int assign(NetAssign*);
|
||||
virtual int assign_mem(NetAssignMem*);
|
||||
virtual int condit(NetCondit*);
|
||||
virtual int pevent(NetPEvent*);
|
||||
virtual int event_wait(NetEvWait*);
|
||||
|
||||
Design*des_;
|
||||
NetProcTop*top_;
|
||||
NetPEvent*pclk_;
|
||||
NetNEvent*nclk_;
|
||||
|
||||
NetEvWait*wclk_;
|
||||
NetEvent *eclk_;
|
||||
NetEvProbe*pclk_;
|
||||
|
||||
NetCondit *con_;
|
||||
NetNet*ce_;
|
||||
|
|
@ -133,21 +184,20 @@ int match_dff::condit(NetCondit*co)
|
|||
return con_->if_clause()->match_proc(this);
|
||||
}
|
||||
|
||||
int match_dff::pevent(NetPEvent*pe)
|
||||
int match_dff::event_wait(NetEvWait*evw)
|
||||
{
|
||||
if (pclk_ || con_ || asn_ || asm_)
|
||||
if (evw->nevents() != 1)
|
||||
return 0;
|
||||
|
||||
pclk_ = pe;
|
||||
wclk_ = evw;
|
||||
eclk_ = evw->event(0);
|
||||
|
||||
NetNEvent*tmp = pclk_->first();
|
||||
if (tmp == 0)
|
||||
return 0;
|
||||
if (pclk_->next())
|
||||
if (eclk_->nprobe() != 1)
|
||||
return 0;
|
||||
|
||||
nclk_ = tmp;
|
||||
return pclk_->statement()->match_proc(this);
|
||||
pclk_ = eclk_->probe(0);
|
||||
|
||||
return wclk_->statement()->match_proc(this);
|
||||
}
|
||||
|
||||
void match_dff::make_it()
|
||||
|
|
@ -170,11 +220,11 @@ void match_dff::make_dff_()
|
|||
connect(ff->pin_Q(idx), asn_->pin(idx));
|
||||
}
|
||||
|
||||
connect(ff->pin_Clock(), nclk_->pin(0));
|
||||
connect(ff->pin_Clock(), pclk_->pin(0));
|
||||
if (ce_) connect(ff->pin_Enable(), ce_->pin(0));
|
||||
|
||||
ff->attribute("LPM_FFType", "DFF");
|
||||
if (nclk_->type() == NetNEvent::NEGEDGE)
|
||||
if (pclk_->edge() == NetEvProbe::NEGEDGE)
|
||||
ff->attribute("Clock:LPM_Polarity", "INVERT");
|
||||
|
||||
des_->add_node(ff);
|
||||
|
|
@ -195,8 +245,8 @@ void match_dff::make_ram_()
|
|||
if (ce_)
|
||||
connect(ram->pin_WE(), ce_->pin(0));
|
||||
|
||||
assert(nclk_->type() == NetNEvent::POSEDGE);
|
||||
connect(ram->pin_InClock(), nclk_->pin(0));
|
||||
assert(pclk_->edge() == NetEvProbe::POSEDGE);
|
||||
connect(ram->pin_InClock(), pclk_->pin(0));
|
||||
|
||||
ram->absorb_partners();
|
||||
des_->add_node(ram);
|
||||
|
|
@ -248,6 +298,9 @@ void synth_f::process(class Design*des, class NetProcTop*top)
|
|||
*/
|
||||
void synth_f::proc_always_(class Design*des)
|
||||
{
|
||||
do_expr expr_pat(des);
|
||||
top_->statement()->match_proc(&expr_pat);
|
||||
|
||||
match_dff dff_pat(des, top_);
|
||||
if (top_->statement()->match_proc(&dff_pat)) {
|
||||
dff_pat.make_it();
|
||||
|
|
@ -270,6 +323,12 @@ void synth(Design*des)
|
|||
|
||||
/*
|
||||
* $Log: synth.cc,v $
|
||||
* Revision 1.8 2000/04/12 20:02:53 steve
|
||||
* Finally remove the NetNEvent and NetPEvent classes,
|
||||
* Get synthesis working with the NetEvWait class,
|
||||
* and get started supporting multiple events in a
|
||||
* wait in vvm.
|
||||
*
|
||||
* Revision 1.7 2000/04/02 04:26:07 steve
|
||||
* Remove the useless sref template.
|
||||
*
|
||||
|
|
|
|||
12
t-vvm.cc
12
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.133 2000/04/12 04:23:58 steve Exp $"
|
||||
#ident "$Id: t-vvm.cc,v 1.134 2000/04/12 20:02:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <iostream>
|
||||
|
|
@ -1760,14 +1760,14 @@ void target_vvm::net_probe(ostream&os, const NetEvProbe*net)
|
|||
<< "(&" << mevent << ");" << endl;
|
||||
break;
|
||||
|
||||
case NetNEvent::NEGEDGE:
|
||||
case NetEvProbe::NEGEDGE:
|
||||
assert(net->pin_count() == 1);
|
||||
os << "static vvm_negedge " << mname
|
||||
<< "(&" << mevent << ");" << endl;
|
||||
break;
|
||||
|
||||
|
||||
case NetNEvent::ANYEDGE:
|
||||
case NetEvProbe::ANYEDGE:
|
||||
os << "static vvm_anyedge " << mname
|
||||
<< "(&" << mevent << ", " << net->pin_count() << ");" << endl;
|
||||
break;
|
||||
|
|
@ -2509,6 +2509,12 @@ extern const struct target tgt_vvm = {
|
|||
};
|
||||
/*
|
||||
* $Log: t-vvm.cc,v $
|
||||
* Revision 1.134 2000/04/12 20:02:53 steve
|
||||
* Finally remove the NetNEvent and NetPEvent classes,
|
||||
* Get synthesis working with the NetEvWait class,
|
||||
* and get started supporting multiple events in a
|
||||
* wait in vvm.
|
||||
*
|
||||
* Revision 1.133 2000/04/12 04:23:58 steve
|
||||
* Named events really should be expressed with PEIdent
|
||||
* objects in the pform,
|
||||
|
|
|
|||
253
xnfsyn.cc
253
xnfsyn.cc
|
|
@ -1,253 +0,0 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* 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: xnfsyn.cc,v 1.5 2000/04/02 04:26:07 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The xnfsyn function searches the behavioral description for
|
||||
* patterns that are known to represent XNF library components. This
|
||||
* is especially interesting for the sequential components such as
|
||||
* flip flops and latches. As threads are transformed into components,
|
||||
* the design is rewritten.
|
||||
*
|
||||
* Currently, this transform recognizes the following patterns:
|
||||
*
|
||||
* always @(posedge CLK) Q = D // DFF:D,Q,C
|
||||
* always @(negedge CLK) Q = D // DFF:D,Q,~C
|
||||
*
|
||||
* always @(posedge CLK) if (CE) Q = D;
|
||||
* always @(negedge CLK) if (CE) Q = D;
|
||||
*
|
||||
* The r-value of the assignments must be identifiers (i.e. wires or
|
||||
* registers) and the CE must be single-bine identifiers. Enough
|
||||
* devices will be created to accommodate the width of Q and D, though
|
||||
* the CLK and CE will be shared by all the devices.
|
||||
*/
|
||||
# include "functor.h"
|
||||
# include "netlist.h"
|
||||
|
||||
class xnfsyn_f : public functor_t {
|
||||
|
||||
public:
|
||||
void process(class Design*, class NetProcTop*);
|
||||
|
||||
private:
|
||||
void proc_always_(class Design*);
|
||||
void proc_casn_(class Design*);
|
||||
void proc_ccon_(class Design*);
|
||||
|
||||
// The matcher does something like a recursive descent search
|
||||
// for the templates. These variables are filled in as the
|
||||
// searcher finds them.
|
||||
|
||||
class NetProcTop*top_;
|
||||
|
||||
class NetPEvent *pclk_;
|
||||
class NetNEvent *nclk_;
|
||||
|
||||
class NetCondit *con_;
|
||||
class NetAssign *asn_;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Look at a process, and divide the problem into always and initial
|
||||
* threads.
|
||||
*/
|
||||
void xnfsyn_f::process(class Design*des, class NetProcTop*top)
|
||||
{
|
||||
switch (top->type()) {
|
||||
case NetProcTop::KALWAYS:
|
||||
top_ = top;
|
||||
proc_always_(des);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* An "always ..." statement has been found.
|
||||
*/
|
||||
void xnfsyn_f::proc_always_(class Design*des)
|
||||
{
|
||||
// The statement must be a NetPEvent, ...
|
||||
pclk_ = dynamic_cast<class NetPEvent*>(top_->statement());
|
||||
if (pclk_ == 0)
|
||||
return;
|
||||
|
||||
NetNEvent*tmp = pclk_->first();
|
||||
if (tmp == 0)
|
||||
return;
|
||||
if (pclk_->next())
|
||||
return;
|
||||
nclk_ = tmp;
|
||||
|
||||
// ... the event must be an edge, ...
|
||||
switch (nclk_->type()) {
|
||||
case NetNEvent::POSEDGE:
|
||||
case NetNEvent::NEGEDGE:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
// Is this a clocked assignment?
|
||||
asn_ = dynamic_cast<NetAssign*>(pclk_->statement());
|
||||
if (asn_) {
|
||||
proc_casn_(des);
|
||||
return;
|
||||
}
|
||||
|
||||
con_ = dynamic_cast<NetCondit*>(pclk_->statement());
|
||||
if (con_) {
|
||||
proc_ccon_(des);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The process so far has been matched as:
|
||||
*
|
||||
* always @(posedge nclk_) asn_ = <r>;
|
||||
* always @(negedge nclk_) asn_ = <r>;
|
||||
*/
|
||||
void xnfsyn_f::proc_casn_(class Design*des)
|
||||
{
|
||||
|
||||
// ... and the rval must be a simple signal.
|
||||
NetESignal*sig = dynamic_cast<NetESignal*>(asn_->rval());
|
||||
if (sig == 0) {
|
||||
cerr << "Noted complex rval in DFF, name " << asn_->name() <<
|
||||
", not yet implemented" << endl;
|
||||
return ;
|
||||
}
|
||||
|
||||
// The signal and the assignment must be the same width...
|
||||
assert(asn_->pin_count() == sig->pin_count());
|
||||
|
||||
// Generate enough DFF objects to handle the entire width.
|
||||
for (unsigned idx = 0 ; idx < asn_->pin_count() ; idx += 1) {
|
||||
|
||||
// XXXX FIXME: Objects need unique names!
|
||||
NetUDP*dff = new NetUDP(asn_->name(), 3, true);
|
||||
|
||||
connect(dff->pin(0), asn_->pin(idx));
|
||||
connect(dff->pin(1), sig->pin(idx));
|
||||
connect(dff->pin(2), nclk_->pin(0));
|
||||
|
||||
switch (nclk_->type()) {
|
||||
case NetNEvent::POSEDGE:
|
||||
dff->attribute("XNF-LCA", "DFF:Q,D,C");
|
||||
break;
|
||||
case NetNEvent::NEGEDGE:
|
||||
dff->attribute("XNF-LCA", "DFF:Q,D,~C");
|
||||
break;
|
||||
}
|
||||
|
||||
des->add_node(dff);
|
||||
}
|
||||
|
||||
// This process is matched and replaced with a DFF. Get
|
||||
// rid of the now useless NetProcTop.
|
||||
des->delete_process(top_);
|
||||
}
|
||||
|
||||
/*
|
||||
* The process so far has been matched as:
|
||||
*
|
||||
* always @(posedge nclk_) if ...;
|
||||
* always @(negedge nclk_) if ...;
|
||||
*/
|
||||
void xnfsyn_f::proc_ccon_(class Design*des)
|
||||
{
|
||||
if (con_->else_clause())
|
||||
return;
|
||||
|
||||
asn_ = dynamic_cast<NetAssign*>(con_->if_clause());
|
||||
if (asn_ == 0)
|
||||
return;
|
||||
|
||||
NetESignal*sig = dynamic_cast<NetESignal*>(asn_->rval());
|
||||
if (sig == 0)
|
||||
return;
|
||||
|
||||
// The signal and the assignment must be the same width...
|
||||
assert(asn_->pin_count() == sig->pin_count());
|
||||
|
||||
NetESignal*ce = dynamic_cast<NetESignal*>(con_->expr());
|
||||
if (ce == 0)
|
||||
return;
|
||||
if (ce->pin_count() != 1)
|
||||
return;
|
||||
|
||||
// Generate enough DFF objects to handle the entire width.
|
||||
for (unsigned idx = 0 ; idx < asn_->pin_count() ; idx += 1) {
|
||||
|
||||
// XXXX FIXME: Objects need unique names!
|
||||
NetUDP*dff = new NetUDP(asn_->name(), 4, true);
|
||||
|
||||
connect(dff->pin(0), asn_->pin(idx));
|
||||
connect(dff->pin(1), sig->pin(idx));
|
||||
connect(dff->pin(2), nclk_->pin(0));
|
||||
connect(dff->pin(3), ce->pin(0));
|
||||
|
||||
switch (nclk_->type()) {
|
||||
case NetNEvent::POSEDGE:
|
||||
dff->attribute("XNF-LCA", "DFF:Q,D,C,CE");
|
||||
break;
|
||||
case NetNEvent::NEGEDGE:
|
||||
dff->attribute("XNF-LCA", "DFF:Q,D,~C,CE");
|
||||
break;
|
||||
}
|
||||
|
||||
des->add_node(dff);
|
||||
}
|
||||
|
||||
// This process is matched and replaced with a DFF. Get
|
||||
// rid of the now useless NetProcTop.
|
||||
des->delete_process(top_);
|
||||
}
|
||||
|
||||
void xnfsyn(Design*des)
|
||||
{
|
||||
xnfsyn_f xnfsyn_obj;
|
||||
des->functor(&xnfsyn_obj);
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: xnfsyn.cc,v $
|
||||
* Revision 1.5 2000/04/02 04:26:07 steve
|
||||
* Remove the useless sref template.
|
||||
*
|
||||
* Revision 1.4 2000/02/23 02:56:56 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
* Revision 1.3 1999/08/18 04:00:02 steve
|
||||
* Fixup spelling and some error messages. <LRDoolittle@lbl.gov>
|
||||
*
|
||||
* Revision 1.2 1999/07/18 21:17:51 steve
|
||||
* Add support for CE input to XNF DFF, and do
|
||||
* complete cleanup of replaced design nodes.
|
||||
*
|
||||
* Revision 1.1 1999/07/18 05:52:47 steve
|
||||
* xnfsyn generates DFF objects for XNF output, and
|
||||
* properly rewrites the Design netlist in the process.
|
||||
*
|
||||
*/
|
||||
|
||||
Loading…
Reference in New Issue