Handle condit clauses with unassigned outputs.
This commit is contained in:
parent
f942657ad5
commit
dde69cebb6
|
|
@ -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: net_nex_output.cc,v 1.11.2.5 2006/05/18 01:47:12 steve Exp $"
|
#ident "$Id: net_nex_output.cc,v 1.11.2.6 2006/06/01 03:01:48 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -114,11 +114,12 @@ void NetBlock::nex_output(NexusSet&out)
|
||||||
if (last_ == 0)
|
if (last_ == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
NetProc*cur = last_;
|
NetProc*cur = last_->next_;
|
||||||
|
NexusSet accum;
|
||||||
do {
|
do {
|
||||||
cur = cur->next_;
|
|
||||||
cur->nex_output(out);
|
cur->nex_output(out);
|
||||||
} while (cur != last_);
|
cur = cur->next_;
|
||||||
|
} while (cur != last_->next_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetCase::nex_output(NexusSet&out)
|
void NetCase::nex_output(NexusSet&out)
|
||||||
|
|
@ -167,6 +168,9 @@ void NetWhile::nex_output(NexusSet&out)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: net_nex_output.cc,v $
|
* $Log: net_nex_output.cc,v $
|
||||||
|
* Revision 1.11.2.6 2006/06/01 03:01:48 steve
|
||||||
|
* Handle condit clauses with unassigned outputs.
|
||||||
|
*
|
||||||
* Revision 1.11.2.5 2006/05/18 01:47:12 steve
|
* Revision 1.11.2.5 2006/05/18 01:47:12 steve
|
||||||
* Fix synthesis of l-value bit select in block.
|
* Fix synthesis of l-value bit select in block.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
143
synth2.cc
143
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.39.2.32 2006/05/20 16:06:48 steve Exp $"
|
#ident "$Id: synth2.cc,v 1.39.2.33 2006/06/01 03:01:48 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -766,6 +766,7 @@ bool NetCase::synth_async_1hot_(Design*des, NetScope*scope, bool sync_flag,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle synthesis for an asynchronous condition statement. If we get
|
* Handle synthesis for an asynchronous condition statement. If we get
|
||||||
* here, we know that the CE of a DFF has already been filled, so the
|
* here, we know that the CE of a DFF has already been filled, so the
|
||||||
|
|
@ -871,55 +872,126 @@ bool NetCondit::synth_async(Design*des, NetScope*scope, bool sync_flag,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned mux_width = 0;
|
||||||
|
|
||||||
|
/* Figure out how many mux bits we are going to need. */
|
||||||
|
for (unsigned idx = 0 ; idx < nex_out->pin_count(); idx += 1) {
|
||||||
|
if (accum->pin(idx).is_linked() || sync_flag) {
|
||||||
|
mux_width += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (asig->pin(idx).is_linked() && bsig->pin(idx).is_linked()) {
|
||||||
|
mux_width += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a mux and hook it up. */
|
||||||
NetMux*mux = new NetMux(scope, scope->local_symbol(),
|
NetMux*mux = new NetMux(scope, scope->local_symbol(),
|
||||||
nex_out->pin_count(), 2, 1);
|
mux_width, 2, 1);
|
||||||
mux->set_line(*this);
|
mux->set_line(*this);
|
||||||
|
|
||||||
connect(mux->pin_Sel(0), ssig->pin(0));
|
connect(mux->pin_Sel(0), ssig->pin(0));
|
||||||
|
|
||||||
bool return_flag = true;
|
|
||||||
|
|
||||||
/* Connected the clauses to the data inputs of the
|
/* Connected the clauses to the data inputs of the
|
||||||
condition. If there are bits unassigned by the case, then
|
condition. If there are bits unassigned by the case, then
|
||||||
bind them from the accum bits instead. If the bit is not
|
bind them from the accum bits instead. If the bit is not
|
||||||
represented in the accum list, but this is a synchronous
|
represented in the accum list, but this is a synchronous
|
||||||
output, then get the bit from the nex_map, which is the
|
output, then get the bit from the nex_map, which is the
|
||||||
output held in the DFF. */
|
output held in the DFF. */
|
||||||
|
mux_width = 0;
|
||||||
for (unsigned idx = 0 ; idx < asig->pin_count() ; idx += 1) {
|
for (unsigned idx = 0 ; idx < nex_out->pin_count() ; idx += 1) {
|
||||||
|
int flag = 0;
|
||||||
if (asig->pin(idx).is_linked())
|
if (asig->pin(idx).is_linked())
|
||||||
connect(mux->pin_Data(idx, 1), asig->pin(idx));
|
flag |= 0100;
|
||||||
else if (accum->pin(idx).is_linked())
|
|
||||||
connect(mux->pin_Data(idx, 1), accum->pin(idx));
|
|
||||||
else if (sync_flag)
|
|
||||||
connect(mux->pin_Data(idx, 1), nex_map->pin(idx));
|
|
||||||
else {
|
|
||||||
cerr << get_line()
|
|
||||||
<< ": error: Condition true clause "
|
|
||||||
<< "does not assign expected outputs." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
return_flag = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < bsig->pin_count() ; idx += 1) {
|
|
||||||
if (bsig->pin(idx).is_linked())
|
if (bsig->pin(idx).is_linked())
|
||||||
connect(mux->pin_Data(idx, 0), bsig->pin(idx));
|
flag |= 0010;
|
||||||
else if (accum->pin(idx).is_linked())
|
if (accum->pin(idx).is_linked())
|
||||||
connect(mux->pin_Data(idx, 0), accum->pin(idx));
|
flag |= 0001;
|
||||||
else if (sync_flag)
|
switch (flag) {
|
||||||
connect(mux->pin_Data(idx, 0), nex_map->pin(idx));
|
case 0111:
|
||||||
else {
|
case 0110:
|
||||||
cerr << get_line()
|
connect(mux->pin_Data(mux_width, 1), asig->pin(idx));
|
||||||
<< ": error: Condition false clause "
|
connect(mux->pin_Data(mux_width, 0), bsig->pin(idx));
|
||||||
<< "does not assign expected outputs." << endl;
|
connect(nex_out->pin(idx), mux->pin_Result(mux_width));
|
||||||
des->errors += 1;
|
mux_width += 1;
|
||||||
return_flag = false;
|
break;
|
||||||
|
case 0101:
|
||||||
|
connect(mux->pin_Data(mux_width, 1), asig->pin(idx));
|
||||||
|
connect(mux->pin_Data(mux_width, 0), accum->pin(idx));
|
||||||
|
connect(nex_out->pin(idx), mux->pin_Result(mux_width));
|
||||||
|
mux_width += 1;
|
||||||
|
break;
|
||||||
|
case 0100:
|
||||||
|
if (sync_flag) {
|
||||||
|
connect(mux->pin_Data(mux_width, 1), asig->pin(idx));
|
||||||
|
connect(mux->pin_Data(mux_width, 0),nex_map->pin(idx));
|
||||||
|
connect(nex_out->pin(idx), mux->pin_Result(mux_width));
|
||||||
|
mux_width += 1;
|
||||||
|
} else {
|
||||||
|
#if 0
|
||||||
|
cerr << get_line()
|
||||||
|
<< ": error: Condition false clause "
|
||||||
|
<< "does not assign expected outputs." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return_flag = false;
|
||||||
|
#else
|
||||||
|
/* This should check that bsig is latched by
|
||||||
|
the condition select or is used
|
||||||
|
internally by the false clause. but since
|
||||||
|
there is no latch support, assume it is
|
||||||
|
used internally. */
|
||||||
|
connect(nex_out->pin(idx), asig->pin(idx));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0011:
|
||||||
|
connect(mux->pin_Data(mux_width, 1), accum->pin(idx));
|
||||||
|
connect(mux->pin_Data(mux_width, 0), bsig->pin(idx));
|
||||||
|
connect(nex_out->pin(idx), mux->pin_Result(mux_width));
|
||||||
|
mux_width += 1;
|
||||||
|
break;
|
||||||
|
case 0010:
|
||||||
|
if (sync_flag) {
|
||||||
|
connect(mux->pin_Data(mux_width, 1),nex_map->pin(idx));
|
||||||
|
connect(mux->pin_Data(mux_width, 0), bsig->pin(idx));
|
||||||
|
connect(nex_out->pin(idx), mux->pin_Result(mux_width));
|
||||||
|
mux_width += 1;
|
||||||
|
} else {
|
||||||
|
#if 0
|
||||||
|
cerr << get_line()
|
||||||
|
<< ": error: Condition true clause "
|
||||||
|
<< "does not assign expected outputs." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return_flag = false;
|
||||||
|
#else
|
||||||
|
/* This should check that bsig is latched by
|
||||||
|
the condition select or is used
|
||||||
|
internally by the false clause. but since
|
||||||
|
there is no latch support, assume it is
|
||||||
|
used internally. */
|
||||||
|
connect(nex_out->pin(idx), bsig->pin(idx));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0001:
|
||||||
|
connect(mux->pin_Data(mux_width, 1), accum->pin(idx));
|
||||||
|
connect(mux->pin_Data(mux_width, 0), accum->pin(idx));
|
||||||
|
connect(nex_out->pin(idx), mux->pin_Result(mux_width));
|
||||||
|
mux_width += 1;
|
||||||
|
break;
|
||||||
|
case 0000:
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < mux->width() ; idx += 1)
|
assert(mux_width == mux->width());
|
||||||
connect(nex_out->pin(idx), mux->pin_Result(idx));
|
|
||||||
|
|
||||||
des->add_node(mux);
|
des->add_node(mux);
|
||||||
|
|
||||||
|
|
@ -1854,6 +1926,9 @@ void synth2(Design*des)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: synth2.cc,v $
|
* $Log: synth2.cc,v $
|
||||||
|
* Revision 1.39.2.33 2006/06/01 03:01:48 steve
|
||||||
|
* Handle condit clauses with unassigned outputs.
|
||||||
|
*
|
||||||
* Revision 1.39.2.32 2006/05/20 16:06:48 steve
|
* Revision 1.39.2.32 2006/05/20 16:06:48 steve
|
||||||
* Replace assertions with error messages.
|
* Replace assertions with error messages.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue