Detect muxing Vz as a bufufN.

This commit is contained in:
steve 2000-07-15 05:13:43 +00:00
parent 42e4ff47c8
commit 2a08824ae9
5 changed files with 131 additions and 10 deletions

View File

@ -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.

View File

@ -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.
*

View File

@ -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.
*

View File

@ -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.
*

View File

@ -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