From 2a08824ae9b201ae4aa73db09e516266d113f05d Mon Sep 17 00:00:00 2001 From: steve Date: Sat, 15 Jul 2000 05:13:43 +0000 Subject: [PATCH] Detect muxing Vz as a bufufN. --- cprop.cc | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++- elab_net.cc | 30 ++++++++++++++++---- functor.cc | 15 +++++++++- functor.h | 8 +++++- netlist.h | 6 +++- 5 files changed, 131 insertions(+), 10 deletions(-) diff --git a/cprop.cc b/cprop.cc index c0af893783..6cead55b2e 100644 --- a/cprop.cc +++ b/cprop.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: cprop.cc,v 1.12 2000/06/25 19:59:41 steve Exp $" +#ident "$Id: cprop.cc,v 1.13 2000/07/15 05:13:43 steve Exp $" #endif # include "netlist.h" @@ -41,6 +41,7 @@ struct cprop_functor : public functor_t { virtual void lpm_add_sub(Design*des, NetAddSub*obj); virtual void lpm_ff(Design*des, NetFF*obj); virtual void lpm_logic(Design*des, NetLogic*obj); + virtual void lpm_mux(Design*des, NetMux*obj); }; void cprop_functor::lpm_add_sub(Design*des, NetAddSub*obj) @@ -226,6 +227,82 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj) } } +/* + * This detects the case where the mux selects between a value an + * Vz. In this case, replace the device with a bufif with the sel + * input used to enable the output. + */ +void cprop_functor::lpm_mux(Design*des, NetMux*obj) +{ + if (obj->size() != 2) + return; + if (obj->sel_width() != 1) + return; + + /* If the first input is all constant Vz, then replace the + NetMux with an array of BUFIF1 devices, with the enable + connected to the select input. */ + bool flag = true; + for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) { + if (! link_drivers_constant(obj->pin_Data(idx, 0))) { + flag = false; + break; + } + + if (driven_value(obj->pin_Data(idx, 0)) != verinum::Vz) { + flag = false; + break; + } + } + + if (flag) { + for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) { + NetLogic*tmp = new NetLogic(des->local_symbol(obj->name()), + 3, NetLogic::BUFIF1); + + connect(obj->pin_Result(idx), tmp->pin(0)); + connect(obj->pin_Data(idx,1), tmp->pin(1)); + connect(obj->pin_Sel(0), tmp->pin(2)); + des->add_node(tmp); + } + + count += 1; + delete obj; + return; + } + + /* If instead the second input is all constant Vz, replace the + NetMux with an array of BUFIF0 devices. */ + flag = true; + for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) { + if (! link_drivers_constant(obj->pin_Data(idx, 1))) { + flag = false; + break; + } + + if (driven_value(obj->pin_Data(idx, 1)) != verinum::Vz) { + flag = false; + break; + } + } + + if (flag) { + for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) { + NetLogic*tmp = new NetLogic(des->local_symbol(obj->name()), + 3, NetLogic::BUFIF1); + + connect(obj->pin_Result(idx), tmp->pin(0)); + connect(obj->pin_Data(idx,0), tmp->pin(1)); + connect(obj->pin_Sel(0), tmp->pin(2)); + des->add_node(tmp); + } + + count += 1; + delete obj; + return; + } +} + /* * This functor looks to see if the constant is connected to nothing * but signals. If that is the case, delete the dangling constant and @@ -286,6 +363,9 @@ void cprop(Design*des) /* * $Log: cprop.cc,v $ + * Revision 1.13 2000/07/15 05:13:43 steve + * Detect muxing Vz as a bufufN. + * * Revision 1.12 2000/06/25 19:59:41 steve * Redesign Links to include the Nexus class that * carries properties of the connected set of links. diff --git a/elab_net.cc b/elab_net.cc index 8df10643dd..21ec21096a 100644 --- a/elab_net.cc +++ b/elab_net.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: elab_net.cc,v 1.41 2000/07/08 04:59:20 steve Exp $" +#ident "$Id: elab_net.cc,v 1.42 2000/07/15 05:13:43 steve Exp $" #endif # include "PExpr.h" @@ -996,9 +996,15 @@ NetNet* PEIdent::elaborate_net(Design*des, const string&path, unsigned midx = sig->sb_to_idx(mval->as_long()); unsigned lidx = sig->sb_to_idx(lval->as_long()); + /* This is a part select, create a new NetNet object + that connects to just the desired parts of the + identifier. Make sure the NetNet::Type is compatible + with the sig type. */ + if (midx >= lidx) { - NetTmp*tmp = new NetTmp(scope, des->local_symbol(path), - midx-lidx+1); + NetNet*tmp = new NetNet(scope, des->local_symbol(path), + sig->type(), midx-lidx+1); + tmp->local_flag(true); if (tmp->pin_count() > sig->pin_count()) { cerr << get_line() << ": bit select out of " << "range for " << sig->name() << endl; @@ -1011,8 +1017,10 @@ NetNet* PEIdent::elaborate_net(Design*des, const string&path, sig = tmp; } else { - NetTmp*tmp = new NetTmp(scope, des->local_symbol(path), - lidx-midx+1); + NetNet*tmp = new NetNet(scope, des->local_symbol(path), + sig->type(), midx-lidx+1); + tmp->local_flag(true); + assert(tmp->pin_count() <= sig->pin_count()); for (unsigned idx = lidx ; idx >= midx ; idx -= 1) connect(tmp->pin(idx-midx), sig->pin(idx)); @@ -1037,7 +1045,14 @@ NetNet* PEIdent::elaborate_net(Design*des, const string&path, des->errors += 1; idx = 0; } - NetTmp*tmp = new NetTmp(scope, des->local_symbol(path), 1); + + /* This is a bit select, create a compatible NetNet with + a single bit that links to the selected bit of the + expression. */ + NetNet*tmp = new NetNet(scope, des->local_symbol(path), + sig->type(), 1); + tmp->local_flag(true); + connect(tmp->pin(0), sig->pin(idx)); sig = tmp; } @@ -1604,6 +1619,9 @@ NetNet* PEUnary::elaborate_net(Design*des, const string&path, /* * $Log: elab_net.cc,v $ + * Revision 1.42 2000/07/15 05:13:43 steve + * Detect muxing Vz as a bufufN. + * * Revision 1.41 2000/07/08 04:59:20 steve * Eleminate reduction gate for 1-bit compares. * diff --git a/functor.cc b/functor.cc index bf353ad60f..0492f2024d 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.18 2000/05/02 00:58:12 steve Exp $" +#ident "$Id: functor.cc,v 1.19 2000/07/15 05:13:43 steve Exp $" #endif # include "functor.h" @@ -67,6 +67,11 @@ void functor_t::lpm_mult(class Design*, class NetMult*) { } +void functor_t::lpm_mux(class Design*, class NetMux*) +{ +} + + void NetScope::run_functor(Design*des, functor_t*fun) { for (NetScope*cur = sub_ ; cur ; cur = cur->sib_) { @@ -154,6 +159,11 @@ void NetMult::functor_node(Design*des, functor_t*fun) fun->lpm_mult(des, this); } +void NetMux::functor_node(Design*des, functor_t*fun) +{ + fun->lpm_mux(des, this); +} + proc_match_t::~proc_match_t() { } @@ -217,6 +227,9 @@ int proc_match_t::event_wait(NetEvWait*) /* * $Log: functor.cc,v $ + * Revision 1.19 2000/07/15 05:13:43 steve + * Detect muxing Vz as a bufufN. + * * Revision 1.18 2000/05/02 00:58:12 steve * Move signal tables to the NetScope class. * diff --git a/functor.h b/functor.h index a10b8eafb5..bc3090acf5 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.13 2000/04/20 00:28:03 steve Exp $" +#ident "$Id: functor.h,v 1.14 2000/07/15 05:13:44 steve Exp $" #endif /* @@ -64,6 +64,9 @@ struct functor_t { /* This method is called for each multiplier. */ virtual void lpm_mult(class Design*des, class NetMult*); + + /* This method is called for each MUX. */ + virtual void lpm_mux(class Design*des, class NetMux*); }; struct proc_match_t { @@ -79,6 +82,9 @@ struct proc_match_t { /* * $Log: functor.h,v $ + * Revision 1.14 2000/07/15 05:13:44 steve + * Detect muxing Vz as a bufufN. + * * Revision 1.13 2000/04/20 00:28:03 steve * Catch some simple identity compareoptimizations. * diff --git a/netlist.h b/netlist.h index ea3bed87fd..58decd43f9 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.145 2000/07/14 06:12:57 steve Exp $" +#ident "$Id: netlist.h,v 1.146 2000/07/15 05:13:44 steve Exp $" #endif /* @@ -690,6 +690,7 @@ class NetMux : public NetNode { virtual void dump_node(ostream&, unsigned ind) const; virtual void emit_node(ostream&, struct target_t*) const; + virtual void functor_node(Design*des, functor_t*fun); private: unsigned width_; @@ -2658,6 +2659,9 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.146 2000/07/15 05:13:44 steve + * Detect muxing Vz as a bufufN. + * * Revision 1.145 2000/07/14 06:12:57 steve * Move inital value handling from NetNet to Nexus * objects. This allows better propogation of inital