diff --git a/net_link.cc b/net_link.cc index cb5143e1c..fda43e7c6 100644 --- a/net_link.cc +++ b/net_link.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: net_link.cc,v 1.14.2.2 2006/01/27 02:05:46 steve Exp $" +#ident "$Id: net_link.cc,v 1.14.2.3 2006/07/23 19:42:33 steve Exp $" #endif # include "config.h" @@ -244,6 +244,18 @@ verinum::V Nexus::get_init() const return verinum::Vz; } +int Nexus::is_driven() const +{ + int count = 0; + + for (Link*cur = list_ ; cur ; cur = cur->next_) { + if (cur->get_dir() == Link::OUTPUT) + count += 1; + } + + return count; +} + void Nexus::unlink(Link*that) { if (name_) { @@ -501,6 +513,9 @@ bool NexusSet::intersect(const NexusSet&that) const /* * $Log: net_link.cc,v $ + * Revision 1.14.2.3 2006/07/23 19:42:33 steve + * Handle statement output override better in blocks. + * * Revision 1.14.2.2 2006/01/27 02:05:46 steve * Speed up processing of connect when one side is empty. * diff --git a/netlist.h b/netlist.h index 6eff4a0ad..bb5d4f6e1 100644 --- a/netlist.h +++ b/netlist.h @@ -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.20 2006/07/10 00:21:51 steve Exp $" +#ident "$Id: netlist.h,v 1.321.2.21 2006/07/23 19:42:33 steve Exp $" #endif /* @@ -264,6 +264,9 @@ class Nexus { Link*first_nlink(); const Link* first_nlink()const; + /* Return the number of drivers, or 0 if undriven. */ + int is_driven() const; + /* This method returns true if all the possible drivers of this nexus are constant. It will also return true if there are no drivers at all. */ @@ -3537,6 +3540,9 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.321.2.21 2006/07/23 19:42:33 steve + * Handle statement output override better in blocks. + * * Revision 1.321.2.20 2006/07/10 00:21:51 steve * Add support for full_case attribute. * diff --git a/synth2.cc b/synth2.cc index c909ce3de..7c14b832f 100644 --- a/synth2.cc +++ b/synth2.cc @@ -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.39 2006/07/10 00:21:54 steve Exp $" +#ident "$Id: synth2.cc,v 1.39.2.40 2006/07/23 19:42:34 steve Exp $" #endif # include "config.h" @@ -328,7 +328,8 @@ bool NetBlock::synth_async(Design*des, NetScope*scope, bool sync_flag, if (debug_synth) { cerr << get_line() << ": debug: " << (sync_flag?"sync":"async") - << " synthesis of statement block." << endl; + << " synthesis of statement block. " + << "pin_count=" << nex_out->pin_count() << endl; } const perm_string tmp1 = perm_string::literal("tmp1"); @@ -391,6 +392,7 @@ bool NetBlock::synth_async(Design*des, NetScope*scope, bool sync_flag, new_accum = new NetNet(scope, tmp3, NetNet::WIRE, nex_out->pin_count()); new_accum->set_line(*this); + new_accum->local_flag(true); /* Use the nex_map to link up the output from the substatement to the output of the block as a whole. */ @@ -410,11 +412,20 @@ bool NetBlock::synth_async(Design*des, NetScope*scope, bool sync_flag, delete tmp_map; delete tmp_out; + assert(new_accum->pin_count() == accum_out->pin_count()); + /* Anything that is not redriven by the current statement inherits the value that was driven from any - previous statements. */ + 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 (new_accum->pin(idx).is_linked()) +#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; connect(new_accum->pin(idx), accum_out->pin(idx)); @@ -424,15 +435,27 @@ bool NetBlock::synth_async(Design*des, NetScope*scope, bool sync_flag, } while (cur != last_); - /* Now bind the accumulated output valies to the nex_out + /* 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. */ + assert(nex_out->pin_count() == accum_out->pin_count()); for (unsigned idx = 0 ; idx < accum_out->pin_count() ; idx += 1) { connect(nex_out->pin(idx), accum_out->pin(idx)); } delete accum_out; + if (debug_synth) { + 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; } @@ -1029,6 +1052,12 @@ bool NetCondit::synth_async(Design*des, NetScope*scope, bool sync_flag, mux_width, 2, 1); mux->set_line(*this); + if (debug_synth) { + cerr << get_line() << ": debug: Condit synth to MUX " + << " width=" << mux_width + << " sel_width=1" << endl; + } + connect(mux->pin_Sel(0), ssig->pin(0)); /* Connected the clauses to the data inputs of the @@ -1046,6 +1075,7 @@ bool NetCondit::synth_async(Design*des, NetScope*scope, bool sync_flag, flag |= 0010; if (accum->pin(idx).is_linked()) flag |= 0001; + switch (flag) { case 0111: case 0110: @@ -1328,10 +1358,13 @@ bool NetBlock::synth_sync(Design*des, NetScope*scope, } NetFF*ff = nex_ff[0].ff; - assert(ff->width() == nex_out->pin_count()); + unsigned block_width = nex_out->pin_count(); + verinum tmp_aset = ff->aset_value(); + verinum tmp_sset = ff->sset_value(); + bool flag = true; const perm_string tmp1 = perm_string::literal("tmp1"); @@ -1361,9 +1394,6 @@ bool NetBlock::synth_sync(Design*des, NetScope*scope, NetNet*tmp_out = new NetNet(scope, tmp2, NetNet::WIRE, tmp_map->pin_count()); - verinum tmp_aset = ff->aset_value(); - verinum tmp_sset = ff->sset_value(); - /* Create a new DFF to handle this part of the begin-end block. Connect this NetFF to the associated pins of the existing wide NetFF device. While I'm at it, also @@ -2211,6 +2241,9 @@ void synth2(Design*des) /* * $Log: synth2.cc,v $ + * Revision 1.39.2.40 2006/07/23 19:42:34 steve + * Handle statement output override better in blocks. + * * Revision 1.39.2.39 2006/07/10 00:21:54 steve * Add support for full_case attribute. * diff --git a/t-dll.cc b/t-dll.cc index bc3b86646..7ed54a170 100644 --- a/t-dll.cc +++ b/t-dll.cc @@ -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.7 2006/04/16 19:26:40 steve Exp $" +#ident "$Id: t-dll.cc,v 1.131.2.8 2006/07/23 19:42:35 steve Exp $" #endif # include "config.h" @@ -1573,10 +1573,12 @@ bool dll_target::lpm_demux(const NetDemux*net) for (idx = 0 ; idx < width ; idx += 1) { const Nexus*nex = net->pin_Q(idx).nexus(); - assert(nex->t_cookie()); obj->u_.demux.q[idx] = (ivl_nexus_t) nex->t_cookie(); - nexus_lpm_add(obj->u_.demux.q[idx], obj, idx, - IVL_DR_STRONG, IVL_DR_STRONG); + + /* It is possible, but unlikely, that the Q is unused. */ + if (obj->u_.demux.q[idx]) + nexus_lpm_add(obj->u_.demux.q[idx], obj, idx, + IVL_DR_STRONG, IVL_DR_STRONG); } for (idx = 0 ; idx < width ; idx += 1) { @@ -1982,10 +1984,34 @@ void dll_target::lpm_mux(const NetMux*net) for (unsigned idx = 0 ; idx < obj->u_.mux.width ; idx += 1) { nex = net->pin_Result(idx).nexus(); - assert(nex->t_cookie()); +#if 0 + if (! nex->t_cookie()) { + cerr << net->get_line() << ": internal error: " + << "broken mux. name=" << net->name() + << ", width=" << obj->u_.mux.width + << ", swid=" << obj->u_.mux.swid << endl; + for (unsigned tmp = 0; tmp < obj->u_.mux.width; tmp += 1) { + const Nexus*tmpn = net->pin_Result(tmp).nexus(); + if (tmpn->t_cookie() == 0) + continue; + + cerr << net->get_line() << ": XXXX " + << "Result(" << tmp << ") : " + << tmpn->name() << endl; + } + } +#endif obj->u_.mux.q.pins[idx] = (ivl_nexus_t) nex->t_cookie(); - nexus_lpm_add(obj->u_.mux.q.pins[idx], obj, 0, - IVL_DR_STRONG, IVL_DR_STRONG); + + /* It is possible (although unlikely) that the + result bit of the mux is not used. This can + happen, for example, if the output is + overridden in the HDL. In that case, skip + it. But if the bit is used, then add it to the + nexus. */ + if (obj->u_.mux.q.pins[idx]) + nexus_lpm_add(obj->u_.mux.q.pins[idx], obj, 0, + IVL_DR_STRONG, IVL_DR_STRONG); } } @@ -2334,6 +2360,9 @@ extern const struct target tgt_dll = { "dll", &dll_target_obj }; /* * $Log: t-dll.cc,v $ + * Revision 1.131.2.8 2006/07/23 19:42:35 steve + * Handle statement output override better in blocks. + * * Revision 1.131.2.7 2006/04/16 19:26:40 steve * Fix handling of exploded memories with partial or missing resets. * diff --git a/tgt-stub/stub.c b/tgt-stub/stub.c index 804e8dd33..a00084283 100644 --- a/tgt-stub/stub.c +++ b/tgt-stub/stub.c @@ -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.9 2006/04/16 19:26:41 steve Exp $" +#ident "$Id: stub.c,v 1.90.2.10 2006/07/23 19:42:35 steve Exp $" #endif # include "config.h" @@ -247,9 +247,11 @@ static void show_lpm_demux(ivl_lpm_t net) fprintf(out, " ERROR: width %% size == %u\n", width%size); } - for (idx = 0 ; idx < width ; idx += 1) + for (idx = 0 ; idx < width ; idx += 1) { + ivl_nexus_t nex = ivl_lpm_q(net, idx); fprintf(out, " Q %u: %s\n", idx, - ivl_nexus_name(ivl_lpm_q(net, idx))); + nex? ivl_nexus_name(nex) : ""); + } for (idx = 0 ; idx < width ; idx += 1) { ivl_nexus_t nex = ivl_lpm_data(net, idx); fprintf(out, " Data %u: %s\n", idx, @@ -509,9 +511,11 @@ static void show_lpm(ivl_lpm_t net) ivl_lpm_basename(net), width, ivl_lpm_size(net), ivl_lpm_selects(net)); - for (idx = 0 ; idx < width ; idx += 1) + for (idx = 0 ; idx < width ; idx += 1) { + ivl_nexus_t nex = ivl_lpm_q(net, idx); fprintf(out, " Q %u: %s\n", idx, - ivl_nexus_name(ivl_lpm_q(net, idx))); + nex? ivl_nexus_name(nex) : ""); + } for (idx = 0 ; idx < ivl_lpm_selects(net) ; idx += 1) fprintf(out, " S %u: %s\n", idx, @@ -1114,6 +1118,9 @@ int target_design(ivl_design_t des) /* * $Log: stub.c,v $ + * Revision 1.90.2.10 2006/07/23 19:42:35 steve + * Handle statement output override better in blocks. + * * Revision 1.90.2.9 2006/04/16 19:26:41 steve * Fix handling of exploded memories with partial or missing resets. *