Fix async blocks to take accumulated input.

This commit is contained in:
steve 2006-11-11 23:10:20 +00:00
parent 2fc9413d1f
commit 04ef0b7d80
1 changed files with 64 additions and 42 deletions

106
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.46 2006/11/02 02:13:15 steve Exp $"
#ident "$Id: synth2.cc,v 1.39.2.47 2006/11/11 23:10:20 steve Exp $"
#endif
# include "config.h"
@ -418,6 +418,14 @@ bool NetBlock::synth_async(Design*des, NetScope*scope, bool sync_flag,
nex_out->pin_count());
accum_out->local_flag(true);
/* Output that ultimately have not been driven should collect
their value from the accumulated input. */
assert(accum_out->pin_count() == accum_in->pin_count());
for (unsigned idx = 0 ; idx < accum_out->pin_count() ; idx += 1) {
if (accum_in->pin(idx).nexus()->is_driven())
connect(accum_out->pin(idx), accum_in->pin(idx));
}
bool flag = true;
NetProc*cur = last_;
do {
@ -453,7 +461,7 @@ bool NetBlock::synth_async(Design*des, NetScope*scope, bool sync_flag,
tmp_set[idx]);
assert(tmp >= 0);
unsigned ptr = tmp;
if (accum_out->pin(ptr).is_linked())
if (accum_out->pin(ptr).nexus()->is_driven())
connect(new_accum->pin(idx), accum_out->pin(ptr));
}
@ -514,12 +522,7 @@ bool NetBlock::synth_async(Design*des, NetScope*scope, bool sync_flag,
previous statements. Thus, the current statement can
*override* the outputs of any previous statements. */
for (unsigned idx = 0; idx < new_accum->pin_count(); idx += 1) {
#if 0
cerr << cur->get_line() << ": XXXX: "
<< "Bit " << idx << " new_accum has "
<< new_accum->pin(idx).nexus()->is_driven()
<< " drivers." << endl;
#endif
if (new_accum->pin(idx).nexus()->is_driven())
continue;
@ -530,6 +533,20 @@ bool NetBlock::synth_async(Design*des, NetScope*scope, bool sync_flag,
} while (cur != last_);
/* Output that ultimately have not been driven should collect
their value from the accumulated input. Do this only for
asynchronous blocks, because synchronous blocks are handled
else where (from the context) where unaccounted inputs are
connected to the output to feedback. */
if (!sync_flag) {
assert(accum_out->pin_count() == accum_in->pin_count());
for (unsigned idx = 0; idx < accum_out->pin_count(); idx += 1) {
if (! accum_out->pin(idx).is_linked())
connect(accum_out->pin(idx), accum_in->pin(idx));
}
}
/* Now bind the accumulated output values to the nex_out
passed in. Note that each previous step has already did the
pin mapping, so just connect. */
@ -544,12 +561,7 @@ bool NetBlock::synth_async(Design*des, NetScope*scope, bool sync_flag,
cerr << get_line() << ": debug: "
<< (sync_flag?"sync":"async")
<< " synthesis of statement block complete. " << endl;
#if 0
for (unsigned idx = 0 ; idx < nex_out->pin_count() ; idx += 1)
cerr << get_line() << ": XXXX: Bit " << idx
<< " has " << nex_out->pin(idx).nexus()->is_driven()
<< " drivers." << endl;
#endif
}
return flag;
}
@ -612,11 +624,16 @@ bool NetCase::synth_async(Design*des, NetScope*scope, bool sync_flag,
}
/* Handle the special case that this can be done it a smaller
1-hot MUX. */
if (nondefault_items < sel_pins)
1-hot MUX. If there are fewer active cases then there are
select pins, then a 1-hot encoding should be better. */
if (nondefault_items < sel_pins) {
if (debug_synth)
cerr << get_line() << ": debug: "
<< "Implement case statement as 1-hot MUX." << endl;
return synth_async_1hot_(des, scope, sync_flag, nex_ff,
nex_map, nex_out, accum,
esig, nondefault_items);
}
NetMux*mux = new NetMux(scope, scope->local_symbol(),
nex_out->pin_count(),
@ -804,39 +821,41 @@ bool NetCase::synth_async(Design*des, NetScope*scope, bool sync_flag,
<< " zero in combinational process." << endl;
}
} else if (statement_map[item] == 0) {
continue;
}
/* If this is an unspecified case, then get the
input from the synchronous output. Note that we
know by design that there is no relevent
default or accum input to use here, as those
cases are handled above. */
/* If after all this is an unspecified case, then get the
input from the synchronous output. Note that we know
by design that there is no relevent default or accum
input to use here, as those cases are handled above. */
if (statement_map[item] == 0) {
for (unsigned idx=0; idx < mux->width(); idx += 1)
connect(mux->pin_Data(idx,item), nex_map->pin(idx));
} else {
/* Synthesize this specified case. The synth_async will
connect all the output bits it knows how to the
sig net. */
statement_map[item]->synth_async(des, scope, sync_flag,
nex_ff,
nex_map, sig, accum);
continue;
}
for (unsigned idx = 0 ; idx < mux->width() ; idx += 1) {
if (sig->pin(idx).is_linked())
connect(mux->pin_Data(idx,item), sig->pin(idx));
else if (accum->pin(idx).is_linked())
connect(mux->pin_Data(idx,item), accum->pin(idx));
else if (sync_flag)
connect(mux->pin_Data(idx,item), nex_map->pin(idx));
else {
/* No likely input for this bit. So
leave it. The connectivity test
below will determine if this is an
error or not. */
}
/* Synthesize this specified case. The synth_async will
connect all the output bits it knows how to the sig net. */
statement_map[item]->synth_async(des, scope, sync_flag,
nex_ff,
nex_map, sig, accum);
for (unsigned idx = 0 ; idx < mux->width() ; idx += 1) {
if (sig->pin(idx).is_linked())
connect(mux->pin_Data(idx,item), sig->pin(idx));
else if (accum->pin(idx).is_linked())
connect(mux->pin_Data(idx,item), accum->pin(idx));
else if (sync_flag)
connect(mux->pin_Data(idx,item), nex_map->pin(idx));
else {
/* No likely input for this bit. So
leave it. The connectivity test
below will determine if this is an
error or not. */
}
}
}
@ -2538,6 +2557,9 @@ void synth2(Design*des)
/*
* $Log: synth2.cc,v $
* Revision 1.39.2.47 2006/11/11 23:10:20 steve
* Fix async blocks to take accumulated input.
*
* Revision 1.39.2.46 2006/11/02 02:13:15 steve
* Error message for condit expression not synthesized.
*