diff --git a/Makefile.in b/Makefile.in index 4e657e06e..9d3aea2c1 100644 --- a/Makefile.in +++ b/Makefile.in @@ -16,7 +16,7 @@ # 59 Temple Place - Suite 330 # Boston, MA 02111-1307, USA # -#ident "$Id: Makefile.in,v 1.128 2002/06/14 04:17:12 steve Exp $" +#ident "$Id: Makefile.in,v 1.129 2002/06/30 02:21:31 steve Exp $" # # SHELL = /bin/sh @@ -124,15 +124,15 @@ TT_VVM = mangle.o t-vvm.o endif TT = t-dll.o t-dll-api.o t-dll-expr.o t-dll-proc.o $(TT_VVM) t-xnf.o -FF = nodangle.o synth.o syn-rules.o xnfio.o +FF = cprop.o nodangle.o synth.o synth2.o syn-rules.o xnfio.o -O = main.o cprop.o design_dump.o dup_expr.o elaborate.o elab_expr.o \ +O = main.o async.o design_dump.o dup_expr.o elaborate.o elab_expr.o \ elab_lval.o elab_net.o elab_anet.o elab_pexpr.o elab_scope.o \ elab_sig.o emit.o eval.o eval_attrib.o eval_rconst.o \ eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \ load_module.o netlist.o netmisc.o net_assign.o \ net_design.o net_event.o net_expr.o net_force.o net_func.o \ -net_link.o net_modulo.o net_nex_input.o \ +net_link.o net_modulo.o net_nex_input.o net_nex_output.o \ net_proc.o net_scope.o net_udp.o pad_to_width.o \ parse.o parse_misc.o pform.o pform_dump.o \ set_width.o \ diff --git a/async.cc b/async.cc new file mode 100644 index 000000000..2138815f2 --- /dev/null +++ b/async.cc @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2002 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) +#ident "$Id: async.cc,v 1.1 2002/06/30 02:21:31 steve Exp $" +#endif + +# include "config.h" + +# include "functor.h" +# include "netlist.h" +# include + +bool NetAssign::is_asynchronous() +{ + return true; +} + +bool NetCondit::is_asynchronous() +{ + return false; +} + +bool NetEvWait::is_asynchronous() +{ + NexusSet*sense = new NexusSet; + for (unsigned idx = 0 ; idx < nevents_ ; idx += 1) { + NexusSet*tmp = event(idx)->nex_async_(); + if (tmp == 0) { + delete sense; + return false; + } + + sense->add(*tmp); + delete tmp; + } + + NexusSet*inputs = statement_->nex_input(); + + if (! sense->contains(*inputs)) { + delete sense; + delete inputs; + return false; + } + + delete sense; + delete inputs; + return true; +} + +bool NetProc::is_asynchronous() +{ + return false; +} + +bool NetProcTop::is_asynchronous() +{ + return statement_->is_asynchronous(); +} + +/* + * $Log: async.cc,v $ + * Revision 1.1 2002/06/30 02:21:31 steve + * Add structure for asynchronous logic synthesis. + * + */ + diff --git a/main.cc b/main.cc index 2b66c7536..8524eb996 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.60 2002/06/24 01:49:39 steve Exp $" +#ident "$Id: main.cc,v 1.61 2002/06/30 02:21:31 steve Exp $" #endif # include "config.h" @@ -193,6 +193,7 @@ extern Design* elaborate(list root); extern void cprop(Design*des); extern void synth(Design*des); +extern void synth2(Design*des); extern void syn_rules(Design*des); extern void nodangle(Design*des); extern void xnfio(Design*des); @@ -205,6 +206,7 @@ static struct net_func_map { { "cprop", &cprop }, { "nodangle",&nodangle }, { "synth", &synth }, + { "synth2", &synth2 }, { "syn-rules", &syn_rules }, { "xnfio", &xnfio }, { 0, 0 } @@ -594,6 +596,9 @@ int main(int argc, char*argv[]) /* * $Log: main.cc,v $ + * Revision 1.61 2002/06/30 02:21:31 steve + * Add structure for asynchronous logic synthesis. + * * Revision 1.60 2002/06/24 01:49:39 steve * Make link_drive_constant cache its results in * the Nexus, to improve cprop performance. diff --git a/net_event.cc b/net_event.cc index 7868f2160..9cda8f557 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.17 2002/02/02 06:13:38 steve Exp $" +#ident "$Id: net_event.cc,v 1.18 2002/06/30 02:21:31 steve Exp $" #endif # include "config.h" @@ -260,6 +260,29 @@ void NetEvent::replace_event(NetEvent*that) } } +NexusSet* NetEvent::nex_async_() +{ + /* If there are behavioral trigger statements attached to me, + then this is not an asynchronous event. */ + if (trig_ != 0) + return 0; + + + NexusSet*tmp = new NexusSet; + for (NetEvProbe*cur = probes_ ; cur != 0 ; cur = cur->enext_) { + if (cur->edge() != NetEvProbe::ANYEDGE) { + delete tmp; + return 0; + } + + for (unsigned idx = 0 ; idx < cur->pin_count() ; idx += 1) + tmp->add(cur->pin(idx).nexus()); + + } + + return tmp; +} + NetEvTrig::NetEvTrig(NetEvent*ev) : event_(ev) { @@ -456,6 +479,9 @@ NetProc* NetEvWait::statement() /* * $Log: net_event.cc,v $ + * Revision 1.18 2002/06/30 02:21:31 steve + * Add structure for asynchronous logic synthesis. + * * Revision 1.17 2002/02/02 06:13:38 steve * event find_similar should not find self. * diff --git a/net_link.cc b/net_link.cc index bb60c7b6a..2bcf01583 100644 --- a/net_link.cc +++ b/net_link.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_link.cc,v 1.7 2002/06/24 01:49:39 steve Exp $" +#ident "$Id: net_link.cc,v 1.8 2002/06/30 02:21:31 steve Exp $" #endif # include "config.h" @@ -414,13 +414,13 @@ void NexusSet::add(const NexusSet&that) add(that.items_[idx]); } -Nexus* NexusSet::operator[] (unsigned idx) +Nexus* NexusSet::operator[] (unsigned idx) const { assert(idx < nitems_); return items_[idx]; } -unsigned NexusSet::bsearch_(Nexus*that) +unsigned NexusSet::bsearch_(Nexus*that) const { for (unsigned idx = 0 ; idx < nitems_ ; idx += 1) { if (items_[idx] < that) @@ -432,9 +432,24 @@ unsigned NexusSet::bsearch_(Nexus*that) return nitems_; } +bool NexusSet::contains(const NexusSet&that) const +{ + for (unsigned idx = 0 ; idx < that.nitems_ ; idx += 1) { + unsigned where = bsearch_(that[idx]); + if (where == nitems_) + return false; + if (items_[where] != that[idx]) + return false; + } + + return true; +} /* * $Log: net_link.cc,v $ + * Revision 1.8 2002/06/30 02:21:31 steve + * Add structure for asynchronous logic synthesis. + * * Revision 1.7 2002/06/24 01:49:39 steve * Make link_drive_constant cache its results in * the Nexus, to improve cprop performance. diff --git a/net_nex_output.cc b/net_nex_output.cc new file mode 100644 index 000000000..5a0b32b15 --- /dev/null +++ b/net_nex_output.cc @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2002 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) +#ident "$Id: net_nex_output.cc,v 1.1 2002/06/30 02:21:32 steve Exp $" +#endif + +#if !defined(WINNT) +#ident "$Id: net_nex_output.cc,v 1.1 2002/06/30 02:21:32 steve Exp $" +#endif + +# include "config.h" + +# include + +# include +# include +# include "netlist.h" +# include "netmisc.h" + +void NetProc::nex_output(NexusSet&out) +{ + cerr << get_line() + << ": internal error: NetProc::nex_output not implemented" + << endl; +} + +void NetAssign::nex_output(NexusSet&out) +{ + cerr << get_line() + << ": internal error: NetProc::nex_output not implemented" + << endl; +} + +void NetCondit::nex_output(NexusSet&out) +{ + cerr << get_line() + << ": internal error: NetProc::nex_output not implemented" + << endl; +} + + +/* + * $Log: net_nex_output.cc,v $ + * Revision 1.1 2002/06/30 02:21:32 steve + * Add structure for asynchronous logic synthesis. + * + */ + diff --git a/netlist.h b/netlist.h index 34042805f..2ea2b61d1 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.247 2002/06/25 01:33:22 steve Exp $" +#ident "$Id: netlist.h,v 1.248 2002/06/30 02:21:32 steve Exp $" #endif /* @@ -285,13 +285,16 @@ class NexusSet { void add(Nexus*that); void add(const NexusSet&that); - Nexus* operator[] (unsigned idx); + Nexus* operator[] (unsigned idx) const; + + // Return true if this set contains every nexus in that set. + bool contains(const NexusSet&that) const; private: Nexus**items_; unsigned nitems_; - unsigned bsearch_(Nexus*that); + unsigned bsearch_(Nexus*that) const; private: // not implemented NexusSet(const NexusSet&); @@ -1184,6 +1187,10 @@ class NetProc : public LineInfo { // sensitivity list. virtual NexusSet* nex_input(); + // Find the nexa that are set by the statement. Add the output + // values to the set passed as a parameter. + virtual void nex_output(NexusSet&); + // This method is called to emit the statement to the // target. The target returns true if OK, false for errors. virtual bool emit_proc(struct target_t*) const; @@ -1192,6 +1199,13 @@ class NetProc : public LineInfo { // process in search of matchable patterns. virtual int match_proc(struct proc_match_t*); + // Return true if this represents the root of a combinational + // process. Most process types are not. + virtual bool is_asynchronous(); + + // synthesize as asynchronous logic, and return true. + virtual bool synth_async(Design*, NetScope*scope); + virtual void dump(ostream&, unsigned ind) const; private: @@ -1303,6 +1317,8 @@ class NetAssignBase : public NetProc { // accounts for any grouping of NetAssign_ objects that might happen. unsigned lwidth() const; + bool synth_async(Design*des, NetScope*scope); + // This dumps all the lval structures. void dump_lval(ostream&) const; @@ -1318,6 +1334,10 @@ class NetAssign : public NetAssignBase { explicit NetAssign(NetAssign_*lv, NetExpr*rv); ~NetAssign(); + bool is_asynchronous(); + + void nex_output(NexusSet&o); + virtual bool emit_proc(struct target_t*) const; virtual int match_proc(struct proc_match_t*); virtual void dump(ostream&, unsigned ind) const; @@ -1480,6 +1500,11 @@ class NetCondit : public NetProc { bool emit_recurse_else(struct target_t*) const; virtual NexusSet* nex_input(); + virtual void nex_output(NexusSet&o); + + bool is_asynchronous(); + bool synth_async(Design*des, NetScope*scope); + virtual bool emit_proc(struct target_t*) const; virtual int match_proc(struct proc_match_t*); virtual void dump(ostream&, unsigned ind) const; @@ -1610,6 +1635,11 @@ class NetEvent : public LineInfo { // located by the find_similar_event method. void replace_event(NetEvent*that); + private: + // This returns a nexus set if it represents possibly + // asynchronous inputs, otherwise 0. + NexusSet*nex_async_(); + private: char* name_; @@ -1673,6 +1703,13 @@ class NetEvWait : public NetProc { virtual bool emit_proc(struct target_t*) const; bool emit_recurse(struct target_t*) const; virtual int match_proc(struct proc_match_t*); + + // It is possible that this is the root of a combinational + // process. This method checks. + virtual bool is_asynchronous(); + + virtual bool synth_async(Design*des, NetScope*scope); + virtual void dump(ostream&, unsigned ind) const; private: @@ -2044,6 +2081,13 @@ class NetProcTop : public LineInfo, public Attrib { NetScope*scope(); const NetScope*scope() const; + /* Return true of this process represents combinational logic. */ + bool is_asynchronous(); + + /* Create asynchronous logic from this thread and return true, + or return false if that cannot be done. */ + bool synth_async(Design*des); + void dump(ostream&, unsigned ind) const; bool emit(struct target_t*tgt) const; @@ -2941,6 +2985,9 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.248 2002/06/30 02:21:32 steve + * Add structure for asynchronous logic synthesis. + * * Revision 1.247 2002/06/25 01:33:22 steve * Cache calculated driven value. * diff --git a/synth2.cc b/synth2.cc new file mode 100644 index 000000000..d2ef3f502 --- /dev/null +++ b/synth2.cc @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2002 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: synth2.cc,v 1.1 2002/06/30 02:21:32 steve Exp $" +#endif + +# include "config.h" + +# include "functor.h" +# include "netlist.h" +# include + + +/* + * Async synthesis of assignments is done by synthesizing the rvalue + * expression, then connecting the l-value directly to the output of + * the r-value. + */ +bool NetAssignBase::synth_async(Design*des, NetScope*scope) +{ + NetNet*rsig = rval_->synthesize(des); + + NetNet*lsig = lval_->sig(); + assert(lsig); + assert(lval_->more == 0); + + assert(lsig->pin_count() == rsig->pin_count()); + for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) + connect(lsig->pin(idx), rsig->pin(idx)); + + return true; +} + +bool NetCondit::synth_async(Design*des, NetScope*scope) +{ + return false; +} + +bool NetEvWait::synth_async(Design*des, NetScope*scope) +{ + return statement_->synth_async(des, scope); +} + +bool NetProc::synth_async(Design*des, NetScope*scope) +{ + return false; +} + +bool NetProcTop::synth_async(Design*des) +{ + return statement_->synth_async(des, scope()); +} + +class synth2_f : public functor_t { + + public: + void process(class Design*, class NetProcTop*); + + private: +}; + + +/* + * Look at a process, and divide the problem into always and initial + * threads. + */ +void synth2_f::process(class Design*des, class NetProcTop*top) +{ + if (! top->is_asynchronous()) + return; + + if (! top->synth_async(des)) + return; + + cerr << top->get_line() << ": info: thread is asynchronous." << endl; + des->delete_process(top); +} + +void synth2(Design*des) +{ + synth2_f synth_obj; + des->functor(&synth_obj); +} + +/* + * $Log: synth2.cc,v $ + * Revision 1.1 2002/06/30 02:21:32 steve + * Add structure for asynchronous logic synthesis. + * + */ +