From a9931e7a58e513ec087ea015bb22485e60a2fa22 Mon Sep 17 00:00:00 2001 From: steve Date: Thu, 18 May 2006 01:47:12 +0000 Subject: [PATCH] Fix synthesis of l-value bit select in block. --- net_nex_output.cc | 12 +++++++++++- synth2.cc | 36 ++++++++++++++++++++++++++++-------- 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/net_nex_output.cc b/net_nex_output.cc index a915e8c18..d9c7677ae 100644 --- a/net_nex_output.cc +++ b/net_nex_output.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: net_nex_output.cc,v 1.11.2.4 2006/05/05 01:56:36 steve Exp $" +#ident "$Id: net_nex_output.cc,v 1.11.2.5 2006/05/18 01:47:12 steve Exp $" #endif # include "config.h" @@ -48,6 +48,13 @@ void NetAssignBase::nex_output(NexusSet&out) for (NetAssign_*cur = lval_ ; cur ; cur = cur->more) { if (NetNet*lsig = cur->sig()) { + if (cur->bmux()) { + for (unsigned idx = 0; idx < lsig->pin_count(); idx += 1) { + out.add(lsig->pin(idx).nexus()); + } + continue; + } + /* Handle l-value signals. We don't need to worry here about whether there is a bmux, because the synthesizer will detect that mux and create a @@ -160,6 +167,9 @@ void NetWhile::nex_output(NexusSet&out) /* * $Log: net_nex_output.cc,v $ + * Revision 1.11.2.5 2006/05/18 01:47:12 steve + * Fix synthesis of l-value bit select in block. + * * Revision 1.11.2.4 2006/05/05 01:56:36 steve * Handle memory assignments out of range during synthesis * diff --git a/synth2.cc b/synth2.cc index 977888866..106f85db5 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.30 2006/05/05 01:56:36 steve Exp $" +#ident "$Id: synth2.cc,v 1.39.2.31 2006/05/18 01:47:12 steve Exp $" #endif # include "config.h" @@ -158,6 +158,9 @@ bool NetAssignBase::synth_async(Design*des, NetScope*scope, bool sync_flag, NetNet*adr = cur->bmux()->synthesize(des); + /* Create a NetEemux wide enough to connect to all + the bits of the lvalue signal (generally more + then the bits of lwidth). */ NetDemux*dq = new NetDemux(scope, scope->local_symbol(), lsig->pin_count(), adr->pin_count(), @@ -165,21 +168,31 @@ bool NetAssignBase::synth_async(Design*des, NetScope*scope, bool sync_flag, des->add_node(dq); dq->set_line(*this); + /* The bmux expression connects to the address of + the Demux device. */ for (unsigned idx = 0; idx < adr->pin_count() ; idx += 1) connect(dq->pin_Address(idx), adr->pin(idx)); assert(cur->lwidth() == 1); + /* Cycle the associated FF Data and Q through the + demux to make synchronous "latches" that the + Demux modifies. */ + assert(nex_ff[0].ff->width() >= lsig->pin_count()); + for (unsigned idx = 0; idx < lsig->pin_count(); idx += 1) { + unsigned off = cur->get_loff()+idx; + connect(nex_ff[0].ff->pin_Q(off), dq->pin_Data(idx)); + } + for (unsigned idx = 0; idx < lsig->pin_count(); idx += 1) { unsigned off = cur->get_loff()+idx; unsigned ptr = find_nexus_in_set(nex_map, lsig->pin(off).nexus()); - assert(ptr <= nex_map->pin_count()); + assert(ptr < nex_out->pin_count()); connect(nex_out->pin(ptr), dq->pin_Q(idx)); } - for (unsigned idx = 0 ; idx < lsig->pin_count(); idx += 1) - connect(dq->pin_Data(idx), nex_map->pin(roff+idx)); - + /* The r-value (1 bit) connects to the WriteData + input of the demux. */ connect(dq->pin_WriteData(0), rsig->pin(roff)); roff += cur->lwidth(); @@ -197,6 +210,7 @@ bool NetAssignBase::synth_async(Design*des, NetScope*scope, bool sync_flag, for (unsigned idx = 0 ; idx < cur->lwidth() ; idx += 1) { unsigned off = cur->get_loff()+idx; unsigned ptr = find_nexus_in_set(nex_map, lsig->pin(off).nexus()); + assert(ptr <= nex_map->pin_count()); connect(nex_out->pin(ptr), rsig->pin(roff+idx)); } @@ -300,12 +314,16 @@ bool NetBlock::synth_async(Design*des, NetScope*scope, bool sync_flag, struct sync_accounting_cell*nex_ff, NetNet*nex_map, NetNet*nex_out, NetNet*accum_in) { - DEBUG_SYNTH2_ENTRY("NetBlock") if (last_ == 0) { - DEBUG_SYNTH2_EXIT("NetBlock",true) return true; } + if (debug_synth) { + cerr << get_line() << ": debug: " + << (sync_flag?"sync":"async") + << " synthesis of statement block." << endl; + } + const perm_string tmp1 = perm_string::literal("tmp1"); const perm_string tmp2 = perm_string::literal("tmp2"); const perm_string tmp3 = perm_string::literal("tmp3"); @@ -408,7 +426,6 @@ bool NetBlock::synth_async(Design*des, NetScope*scope, bool sync_flag, delete accum_out; - DEBUG_SYNTH2_EXIT("NetBlock",flag) return flag; } @@ -1819,6 +1836,9 @@ void synth2(Design*des) /* * $Log: synth2.cc,v $ + * Revision 1.39.2.31 2006/05/18 01:47:12 steve + * Fix synthesis of l-value bit select in block. + * * Revision 1.39.2.30 2006/05/05 01:56:36 steve * Handle memory assignments out of range during synthesis *