Detect asynchronous FF inputs that are expressions.
This commit is contained in:
parent
b6c3f94d52
commit
fff8278eb4
104
synth2.cc
104
synth2.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: synth2.cc,v 1.27 2003/06/23 00:14:44 steve Exp $"
|
#ident "$Id: synth2.cc,v 1.28 2003/08/10 17:04:23 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -481,61 +481,75 @@ bool NetCondit::synth_sync(Design*des, NetScope*scope, NetFF*ff,
|
||||||
const NetNet*nex_map, NetNet*nex_out,
|
const NetNet*nex_map, NetNet*nex_out,
|
||||||
const svector<NetEvProbe*>&events_in)
|
const svector<NetEvProbe*>&events_in)
|
||||||
{
|
{
|
||||||
|
/* First try to turn the condition expression into an
|
||||||
|
asynchronous set/reset. If the condition expression has
|
||||||
|
inputs that are included in the sensitivity list, then it
|
||||||
|
is likely intended as an asynchronous input. */
|
||||||
|
|
||||||
/* Synthesize the enable expression. */
|
NexusSet*expr_input = expr_->nex_input();
|
||||||
NetNet*ce = expr_->synthesize(des);
|
assert(expr_input);
|
||||||
assert(ce->pin_count() == 1);
|
|
||||||
|
|
||||||
/* Try first to turn the ce into an asynchronous set/reset
|
|
||||||
input. If the ce is linked to a probe, then that probe is a
|
|
||||||
set/reset input. */
|
|
||||||
for (unsigned idx = 0 ; idx < events_in.count() ; idx += 1) {
|
for (unsigned idx = 0 ; idx < events_in.count() ; idx += 1) {
|
||||||
|
|
||||||
NetEvProbe*ev = events_in[idx];
|
NetEvProbe*ev = events_in[idx];
|
||||||
|
NexusSet pin_set;
|
||||||
|
pin_set.add(ev->pin(0).nexus());
|
||||||
|
|
||||||
if (connected(ce->pin(0), ev->pin(0))) {
|
if (! expr_input->contains(pin_set))
|
||||||
|
continue;
|
||||||
|
|
||||||
bool flag = true;
|
/* Ah, this edge is in the sensitivity list for the
|
||||||
assert(ev->edge() == NetEvProbe::POSEDGE);
|
expression, so we have an asynchronous
|
||||||
|
input. Synthesize the set/reset input expression. */
|
||||||
|
|
||||||
/* Synthesize the true clause to figure out what
|
NetNet*rst = expr_->synthesize(des);
|
||||||
kind of set/reset we have. */
|
assert(rst->pin_count() == 1);
|
||||||
NetNet*asig = new NetNet(scope, scope->local_symbol(),
|
|
||||||
NetNet::WIRE, nex_map->pin_count());
|
|
||||||
asig->local_flag(true);
|
|
||||||
flag = if_->synth_async(des, scope, nex_map, asig) && flag;
|
|
||||||
|
|
||||||
assert(asig->pin_count() == ff->width());
|
/* XXXX I really should find a way to check that the
|
||||||
|
edge used on the reset input is correct. This would
|
||||||
|
involve interpreting the exression that is fed by the
|
||||||
|
reset expression. */
|
||||||
|
//assert(ev->edge() == NetEvProbe::POSEDGE);
|
||||||
|
|
||||||
/* Collect the set/reset value into a verinum. If
|
/* Synthesize the true clause to figure out what
|
||||||
this turns out to be entirely 0 values, then
|
kind of set/reset we have. */
|
||||||
use the Aclr input. Otherwise, use the Aset
|
NetNet*asig = new NetNet(scope, scope->local_symbol(),
|
||||||
input and save the set value. */
|
NetNet::WIRE, nex_map->pin_count());
|
||||||
verinum tmp (verinum::V0, ff->width());
|
asig->local_flag(true);
|
||||||
for (unsigned bit = 0 ; bit < ff->width() ; bit += 1) {
|
bool flag = if_->synth_async(des, scope, nex_map, asig);
|
||||||
|
|
||||||
assert(asig->pin(bit).nexus()->drivers_constant());
|
assert(asig->pin_count() == ff->width());
|
||||||
tmp.set(bit, asig->pin(bit).nexus()->driven_value());
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(tmp.is_defined());
|
/* Collect the set/reset value into a verinum. If
|
||||||
if (tmp.is_zero()) {
|
this turns out to be entirely 0 values, then
|
||||||
connect(ff->pin_Aclr(), ce->pin(0));
|
use the Aclr input. Otherwise, use the Aset
|
||||||
|
input and save the set value. */
|
||||||
|
verinum tmp (verinum::V0, ff->width());
|
||||||
|
for (unsigned bit = 0 ; bit < ff->width() ; bit += 1) {
|
||||||
|
|
||||||
} else {
|
assert(asig->pin(bit).nexus()->drivers_constant());
|
||||||
connect(ff->pin_Aset(), ce->pin(0));
|
tmp.set(bit, asig->pin(bit).nexus()->driven_value());
|
||||||
ff->aset_value(tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete asig;
|
|
||||||
|
|
||||||
assert(events_in.count() == 1);
|
|
||||||
return else_->synth_sync(des, scope, ff, nex_map,
|
|
||||||
nex_out, svector<NetEvProbe*>(0))
|
|
||||||
&& flag;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert(tmp.is_defined());
|
||||||
|
if (tmp.is_zero()) {
|
||||||
|
connect(ff->pin_Aclr(), rst->pin(0));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
connect(ff->pin_Aset(), rst->pin(0));
|
||||||
|
ff->aset_value(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete asig;
|
||||||
|
delete expr_input;
|
||||||
|
|
||||||
|
assert(events_in.count() == 1);
|
||||||
|
return else_->synth_sync(des, scope, ff, nex_map,
|
||||||
|
nex_out, svector<NetEvProbe*>(0))
|
||||||
|
&& flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete expr_input;
|
||||||
|
|
||||||
/* Failed to find an asynchronous set/reset, so any events
|
/* Failed to find an asynchronous set/reset, so any events
|
||||||
input are probably in error. */
|
input are probably in error. */
|
||||||
if (events_in.count() > 0) {
|
if (events_in.count() > 0) {
|
||||||
|
|
@ -544,6 +558,11 @@ bool NetCondit::synth_sync(Design*des, NetScope*scope, NetFF*ff,
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Synthesize the enable expression. */
|
||||||
|
NetNet*ce = expr_->synthesize(des);
|
||||||
|
assert(ce->pin_count() == 1);
|
||||||
|
|
||||||
|
|
||||||
/* If this is an if/then/else, then it is likely a
|
/* If this is an if/then/else, then it is likely a
|
||||||
combinational if, and I should synthesize it that way. */
|
combinational if, and I should synthesize it that way. */
|
||||||
if (if_ && else_) {
|
if (if_ && else_) {
|
||||||
|
|
@ -784,6 +803,9 @@ void synth2(Design*des)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: synth2.cc,v $
|
* $Log: synth2.cc,v $
|
||||||
|
* Revision 1.28 2003/08/10 17:04:23 steve
|
||||||
|
* Detect asynchronous FF inputs that are expressions.
|
||||||
|
*
|
||||||
* Revision 1.27 2003/06/23 00:14:44 steve
|
* Revision 1.27 2003/06/23 00:14:44 steve
|
||||||
* ivl_synthesis_cell cuts off synthesis within a module.
|
* ivl_synthesis_cell cuts off synthesis within a module.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue