From 4493e968da1c631e6f3cb1bd20a1f996adc0a43a Mon Sep 17 00:00:00 2001 From: steve Date: Wed, 12 Apr 2000 20:02:52 +0000 Subject: [PATCH] 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. --- Makefile.in | 4 +- design_dump.cc | 72 ++------------ functor.cc | 20 ++-- functor.h | 10 +- main.cc | 10 +- net_event.cc | 45 ++++++++- netlist.cc | 94 ++---------------- netlist.h | 99 +++++-------------- pform_dump.cc | 16 +++- synth.cc | 95 +++++++++++++++---- t-vvm.cc | 12 ++- xnfsyn.cc | 253 ------------------------------------------------- 12 files changed, 211 insertions(+), 519 deletions(-) delete mode 100644 xnfsyn.cc diff --git a/Makefile.in b/Makefile.in index 1f1c357b9..fb0918669 100644 --- a/Makefile.in +++ b/Makefile.in @@ -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 \ diff --git a/design_dump.cc b/design_dump.cc index 836880d11..94e276aaa 100644 --- a/design_dump.cc +++ b/design_dump.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: design_dump.cc,v 1.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, diff --git a/functor.cc b/functor.cc index 3c3fca1e9..283b51a45 100644 --- a/functor.cc +++ b/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. * diff --git a/functor.h b/functor.h index 56ac6dd62..d8c7f2feb 100644 --- a/functor.h +++ b/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. * diff --git a/main.cc b/main.cc index 624b26a3a..484c04f7b 100644 --- a/main.cc +++ b/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. * diff --git a/net_event.cc b/net_event.cc index ff84782e5..174105787 100644 --- a/net_event.cc +++ b/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, diff --git a/netlist.cc b/netlist.cc index 906aec99f..61a8e0de2 100644 --- a/netlist.cc +++ b/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 @@ -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&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. * diff --git a/netlist.h b/netlist.h index ccf719038..3912d011c 100644 --- a/netlist.h +++ b/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, diff --git a/pform_dump.cc b/pform_dump.cc index b7dc541b3..1957f6164 100644 --- a/pform_dump.cc +++ b/pform_dump.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: pform_dump.cc,v 1.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, diff --git a/synth.cc b/synth.cc index 1b1fd2fb5..0bcc14257 100644 --- a/synth.cc +++ b/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(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. * diff --git a/t-vvm.cc b/t-vvm.cc index a1f960eb6..6d56aca0c 100644 --- a/t-vvm.cc +++ b/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 @@ -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, diff --git a/xnfsyn.cc b/xnfsyn.cc deleted file mode 100644 index cb40d99f1..000000000 --- a/xnfsyn.cc +++ /dev/null @@ -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(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(pclk_->statement()); - if (asn_) { - proc_casn_(des); - return; - } - - con_ = dynamic_cast(pclk_->statement()); - if (con_) { - proc_ccon_(des); - return; - } -} - -/* - * The process so far has been matched as: - * - * always @(posedge nclk_) asn_ = ; - * always @(negedge nclk_) asn_ = ; - */ -void xnfsyn_f::proc_casn_(class Design*des) -{ - - // ... and the rval must be a simple signal. - NetESignal*sig = dynamic_cast(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(con_->if_clause()); - if (asn_ == 0) - return; - - NetESignal*sig = dynamic_cast(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(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. - * - * 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. - * - */ -