When mux has wide select but sparse choices, use 1hot translation.

This commit is contained in:
steve 2006-01-21 21:42:31 +00:00
parent e80138ec8c
commit eb0a78e9ce
4 changed files with 156 additions and 4 deletions

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: netlist.h,v 1.321.2.8 2006/01/18 01:23:24 steve Exp $"
#ident "$Id: netlist.h,v 1.321.2.9 2006/01/21 21:42:31 steve Exp $"
#endif
/*
@ -1647,6 +1647,10 @@ class NetCase : public NetProc {
virtual bool emit_proc(struct target_t*) const;
virtual void dump(ostream&, unsigned ind) const;
private:
bool synth_async_1hot_(Design*des, NetScope*scope, bool sync_flag,
NetNet*nex_map, NetNet*nex_out, NetNet*accum_in,
NetNet*esig, unsigned hot_items);
private:
TYPE type_;
@ -3398,6 +3402,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
* Revision 1.321.2.9 2006/01/21 21:42:31 steve
* When mux has wide select but sparse choices, use 1hot translation.
*
* Revision 1.321.2.8 2006/01/18 01:23:24 steve
* Rework l-value handling to allow for more l-value type flexibility.
*

133
synth2.cc
View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: synth2.cc,v 1.39.2.17 2006/01/18 06:16:11 steve Exp $"
#ident "$Id: synth2.cc,v 1.39.2.18 2006/01/21 21:42:32 steve Exp $"
#endif
# include "config.h"
@ -354,6 +354,19 @@ bool NetCase::synth_async(Design*des, NetScope*scope, bool sync_flag,
}
assert(cur == (1U << sel_pins));
unsigned nondefault_items = 0;
for (unsigned item = 0 ; item < nitems_ ; item += 1) {
if (items_[item].guard != 0)
nondefault_items += 1;
}
/* Handle the special case that this can be done it a smaller
1-hot MUX. */
if (nondefault_items < sel_pins)
return synth_async_1hot_(des, scope, sync_flag,
nex_map, nex_out, accum,
esig, nondefault_items);
NetMux*mux = new NetMux(scope, scope->local_symbol(),
nex_out->pin_count(),
1U << sel_pins, sel_pins);
@ -499,6 +512,121 @@ bool NetCase::synth_async(Design*des, NetScope*scope, bool sync_flag,
return return_flag;
}
bool NetCase::synth_async_1hot_(Design*des, NetScope*scope, bool sync_flag,
NetNet*nex_map, NetNet*nex_out, NetNet*accum,
NetNet*esig, unsigned hot_items)
{
unsigned sel_pins = hot_items;
NetMux*mux = new NetMux(scope, scope->local_symbol(),
nex_out->pin_count(),
1U << sel_pins, sel_pins);
mux->set_line(*this);
/* Hook up the output of the mux to the mapped output pins. */
for (unsigned idx = 0 ; idx < mux->width() ; idx += 1)
connect(nex_out->pin(idx), mux->pin_Result(idx));
NetNet*tmps = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, sel_pins);
for (unsigned idx = 0 ; idx < sel_pins ; idx += 1)
connect(tmps->pin(idx), mux->pin_Sel(idx));
NetProc*default_statement = 0;
unsigned use_item = 0;
for (unsigned item = 0 ; item < nitems_ ; item += 1) {
if (items_[item].guard == 0) {
default_statement = items_[item].statement;
continue;
}
NetNet*tmp1 = items_[item].guard->synthesize(des);
assert(tmp1);
NetLogic*reduc = new NetLogic(scope, scope->local_symbol(),
1 + esig->pin_count(),
NetLogic::AND);
des->add_node(reduc);
tmps = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, esig->pin_count());
for (unsigned idx = 0 ; idx < tmps->pin_count() ; idx += 1)
connect(tmps->pin(idx), reduc->pin(idx+1));
assert(tmp1->pin_count() == esig->pin_count());
for (unsigned idx = 0 ; idx < tmp1->pin_count() ; idx += 1) {
NetCaseCmp*cmp = new NetCaseCmp(scope,scope->local_symbol());
des->add_node(cmp);
connect(cmp->pin(0), reduc->pin(1+idx));
connect(cmp->pin(1), esig->pin(idx));
connect(cmp->pin(2), tmp1->pin(idx));
}
connect(mux->pin_Sel(item), reduc->pin(0));
NetNet*item_sig = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, nex_map->pin_count());
assert(items_[item].statement);
items_[item].statement->synth_async(des, scope, sync_flag,
nex_map, item_sig, accum);
for (unsigned idx = 0 ; idx < item_sig->pin_count() ; idx += 1)
connect(mux->pin_Data(idx, 1<<use_item), item_sig->pin(idx));
use_item += 1;
}
assert(use_item == hot_items);
/* Set up a default default_sig that uses the accumulated
input pins. This binding is suppressed by an actual default
statement if one exists. */
NetNet*default_sig = 0;
if (default_statement) {
default_sig = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, nex_map->pin_count());
default_statement->synth_async(des, scope, sync_flag,
nex_map, default_sig, accum);
}
if (default_sig == 0 && default_statement == 0) {
default_sig = accum;
for (unsigned idx = 0 ; idx < accum->pin_count() ; idx += 1) {
if (! accum->pin(idx).is_linked()) {
default_sig = 0;
break;
}
}
}
/* No explicit sig, so if this is a synchronous process,
connect the input to the output. */
if (default_sig == 0 && sync_flag) {
default_sig = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, nex_map->pin_count());
for (unsigned idx = 0; idx < default_sig->pin_count() ; idx += 1)
connect(default_sig->pin(idx), nex_map->pin(idx));
}
for (unsigned item = 0 ; item < (1UL<<sel_pins) ; item += 1) {
unsigned count_bits = 0;
for (unsigned idx = 0 ; idx < sel_pins ; idx += 1) {
if (item & (1<<idx))
count_bits += 1;
}
if (count_bits == 1)
continue;
for (unsigned idx = 0 ; idx < mux->width() ; idx += 1)
connect(mux->pin_Data(idx,item), default_sig->pin(idx));
}
des->add_node(mux);
return true;
}
/*
* If the synth_async method is called without an accumulated input
* (in other words not from within a block) then stub the input signal
@ -1446,6 +1574,9 @@ void synth2(Design*des)
/*
* $Log: synth2.cc,v $
* Revision 1.39.2.18 2006/01/21 21:42:32 steve
* When mux has wide select but sparse choices, use 1hot translation.
*
* Revision 1.39.2.17 2006/01/18 06:16:11 steve
* Restrict DFF to only one of Sset and Sclr.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: t-dll.cc,v 1.131.2.1 2005/02/19 16:39:31 steve Exp $"
#ident "$Id: t-dll.cc,v 1.131.2.2 2006/01/21 21:42:33 steve Exp $"
#endif
# include "config.h"
@ -940,6 +940,8 @@ void dll_target::net_case_cmp(const NetCaseCmp*net)
obj->delay[1] = net->fall_time();
obj->delay[2] = net->decay_time();
logic_attributes(obj,net);
scope_add_logic(scope, obj);
}
@ -2180,6 +2182,9 @@ extern const struct target tgt_dll = { "dll", &dll_target_obj };
/*
* $Log: t-dll.cc,v $
* Revision 1.131.2.2 2006/01/21 21:42:33 steve
* When mux has wide select but sparse choices, use 1hot translation.
*
* Revision 1.131.2.1 2005/02/19 16:39:31 steve
* Spellig fixes.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: stub.c,v 1.90.2.3 2006/01/14 20:13:22 steve Exp $"
#ident "$Id: stub.c,v 1.90.2.4 2006/01/21 21:42:33 steve Exp $"
#endif
# include "config.h"
@ -844,6 +844,12 @@ static void show_logic(ivl_net_logic_t net)
name,
ivl_nexus_name(ivl_logic_pin(net, 0)));
break;
case IVL_LO_EEQ:
fprintf(out, " EEQ %s (%s", name,
ivl_nexus_name(ivl_logic_pin(net,0)));
break;
case IVL_LO_NOT:
fprintf(out, " not #(%u) %s (%s",
ivl_logic_delay(net, 0),
@ -1001,6 +1007,9 @@ int target_design(ivl_design_t des)
/*
* $Log: stub.c,v $
* Revision 1.90.2.4 2006/01/21 21:42:33 steve
* When mux has wide select but sparse choices, use 1hot translation.
*
* Revision 1.90.2.3 2006/01/14 20:13:22 steve
* Show synchronous set/clr of FF.
*