From bb87c368b82d5c7dbdf870a2cd6c6de6bc4b308f Mon Sep 17 00:00:00 2001 From: steve Date: Mon, 29 Jul 2002 00:00:28 +0000 Subject: [PATCH] Asynchronous synthesis of sequential blocks. --- net_nex_output.cc | 17 +++++++++++++++- netlist.h | 11 ++++++++++- synth2.cc | 50 ++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 75 insertions(+), 3 deletions(-) diff --git a/net_nex_output.cc b/net_nex_output.cc index 540c281ac..730f5cba3 100644 --- a/net_nex_output.cc +++ b/net_nex_output.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: net_nex_output.cc,v 1.3 2002/07/07 22:32:15 steve Exp $" +#ident "$Id: net_nex_output.cc,v 1.4 2002/07/29 00:00:28 steve Exp $" #endif # include "config.h" @@ -47,6 +47,18 @@ void NetAssignBase::nex_output(NexusSet&out) } +void NetBlock::nex_output(NexusSet&out) +{ + if (last_ == 0) + return; + + NetProc*cur = last_; + do { + cur = cur->next_; + cur->nex_output(out); + } while (cur != last_); +} + void NetCase::nex_output(NexusSet&out) { for (unsigned idx = 0 ; idx < nitems_ ; idx += 1) { @@ -73,6 +85,9 @@ void NetEvWait::nex_output(NexusSet&out) /* * $Log: net_nex_output.cc,v $ + * Revision 1.4 2002/07/29 00:00:28 steve + * Asynchronous synthesis of sequential blocks. + * * Revision 1.3 2002/07/07 22:32:15 steve * Asynchronous synthesis of case statements. * diff --git a/netlist.h b/netlist.h index 038bcdbae..24c438b52 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.253 2002/07/24 16:24:45 steve Exp $" +#ident "$Id: netlist.h,v 1.254 2002/07/29 00:00:28 steve Exp $" #endif /* @@ -1381,12 +1381,18 @@ class NetBlock : public NetProc { const NetProc*proc_first() const; const NetProc*proc_next(const NetProc*cur) const; + + // synthesize as asynchronous logic, and return true. + bool synth_async(Design*des, NetScope*scope, + const NetNet*nex_map, NetNet*nex_out); + // This version of emit_recurse scans all the statements of // the begin-end block sequentially. It is typically of use // for sequential blocks. void emit_recurse(struct target_t*) const; virtual NexusSet* nex_input(); + virtual void nex_output(NexusSet&); virtual bool emit_proc(struct target_t*) const; virtual int match_proc(struct proc_match_t*); virtual void dump(ostream&, unsigned ind) const; @@ -3000,6 +3006,9 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.254 2002/07/29 00:00:28 steve + * Asynchronous synthesis of sequential blocks. + * * Revision 1.253 2002/07/24 16:24:45 steve * Rewrite find_similar_event to support doing * all event matching and replacement in one diff --git a/synth2.cc b/synth2.cc index 50f8bed26..406392805 100644 --- a/synth2.cc +++ b/synth2.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: synth2.cc,v 1.4 2002/07/16 04:40:48 steve Exp $" +#ident "$Id: synth2.cc,v 1.5 2002/07/29 00:00:28 steve Exp $" #endif # include "config.h" @@ -68,6 +68,51 @@ bool NetAssignBase::synth_async(Design*des, NetScope*scope, return true; } +/* + * Sequential blocks are translated to asynchronous logic by + * translating each statement of the block, in order, into gates. The + * nex_out for the block is the union of the nex_out for all the + * substatements. + */ +bool NetBlock::synth_async(Design*des, NetScope*scope, + const NetNet*nex_map, NetNet*nex_out) +{ + if (last_ == 0) + return true; + + bool flag = true; + NetProc*cur = last_; + do { + cur = cur->next_; + + /* Create a temporary nex_out for the substatement. */ + NexusSet tmp_set; + cur->nex_output(tmp_set); + NetNet*tmp_out = new NetNet(scope, "tmp", NetNet::WIRE, + tmp_set.count()); + for (unsigned idx = 0 ; idx < tmp_out->pin_count() ; idx += 1) + connect(tmp_set[idx], tmp_out->pin(idx)); + + bool ok_flag = cur->synth_async(des, scope, tmp_out, tmp_out); + flag = flag && ok_flag; + + if (ok_flag == false) + continue; + + /* Use tne nex_map to link up the output from the + substatement to the output of the block as a whole. */ + for (unsigned idx = 0 ; idx < tmp_out->pin_count() ; idx += 1) { + unsigned ptr = find_nexus_in_set(nex_map, tmp_set[idx]); + connect(nex_out->pin(ptr), tmp_out->pin(idx)); + } + + delete tmp_out; + + } while (cur != last_); + + return flag; +} + bool NetCase::synth_async(Design*des, NetScope*scope, const NetNet*nex_map, NetNet*nex_out) { @@ -259,6 +304,9 @@ void synth2(Design*des) /* * $Log: synth2.cc,v $ + * Revision 1.5 2002/07/29 00:00:28 steve + * Asynchronous synthesis of sequential blocks. + * * Revision 1.4 2002/07/16 04:40:48 steve * Allow wide rvalues assigned to narrow nex_out. *