diff --git a/expr_synth.cc b/expr_synth.cc index 90ad297f4..4213442dd 100644 --- a/expr_synth.cc +++ b/expr_synth.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: expr_synth.cc,v 1.59.2.3 2006/03/16 05:39:20 steve Exp $" +#ident "$Id: expr_synth.cc,v 1.59.2.4 2006/04/10 03:43:39 steve Exp $" #endif # include "config.h" @@ -26,12 +26,14 @@ # include "netlist.h" # include "netmisc.h" +# include "compiler.h" NetNet* NetExpr::synthesize(Design*des) { cerr << get_line() << ": internal error: cannot synthesize expression: " << *this << endl; des->errors += 1; + return 0; } @@ -639,6 +641,53 @@ NetNet* NetEConst::synthesize(Design*des) return osig; } +NetNet* NetEMemory::synthesize(Design*des) +{ + NetScope*scope = mem_->scope(); + + NetNet*explode = mem_->reg_from_explode(); + unsigned width = expr_width(); + + assert(idx_); + NetNet*addr = idx_->synthesize(des); + + NetNet*osig = new NetNet(scope, scope->local_symbol(), + NetNet::IMPLICIT, + width); + osig->set_line(*this); + + if (explode) { + if (debug_synth) + cerr << get_line() << ": debug: synthesize read of " + << explode->pin_count() << " bit exploded memory." << endl; + /* This is a reference to an exploded memory. So locate + the reg vector and use the addr expression as a + select into a MUX. */ + NetMux*mux = new NetMux(scope, scope->local_symbol(), + width, mem_->count(), addr->pin_count()); + des->add_node(mux); + mux->set_line(*this); + + for (unsigned idx = 0 ; idx < width ; idx += 1) + connect(mux->pin_Result(idx), osig->pin(idx)); + for (unsigned idx = 0 ; idx < mux->sel_width() ; idx += 1) + connect(mux->pin_Sel(idx), addr->pin(idx)); + + for (unsigned wrd = 0 ; wrd < mem_->count() ; wrd += 1) + for (unsigned idx = 0 ; idx < width ; idx += 1) { + unsigned bit = wrd*width + idx; + connect(mux->pin_Data(idx, wrd), explode->pin(bit)); + } + + } else { + cerr << get_line() << ": internal error: Synthesize memory " + << "expression that is not exploded?" << endl; + des->errors += 1; + } + + return osig; +} + NetNet* NetECReal::synthesize(Design*des) { cerr << get_line() << ": error: Real constants are " @@ -875,6 +924,9 @@ NetNet* NetESignal::synthesize(Design*des) /* * $Log: expr_synth.cc,v $ + * Revision 1.59.2.4 2006/04/10 03:43:39 steve + * Exploded memories accessed by constant indices. + * * Revision 1.59.2.3 2006/03/16 05:39:20 steve * Right shifts really are allowed. * diff --git a/netlist.h b/netlist.h index c595bd8fe..cee3b1f11 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.14 2006/03/26 23:09:23 steve Exp $" +#ident "$Id: netlist.h,v 1.321.2.15 2006/04/10 03:43:39 steve Exp $" #endif /* @@ -3079,7 +3079,7 @@ class NetEMemory : public NetExpr { const NetExpr* index() const; virtual bool set_width(unsigned); - + virtual NetNet* synthesize(Design*); NetExpr* eval_tree(); virtual NetEMemory*dup_expr() const; @@ -3512,6 +3512,9 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.321.2.15 2006/04/10 03:43:39 steve + * Exploded memories accessed by constant indices. + * * Revision 1.321.2.14 2006/03/26 23:09:23 steve * Handle asynchronous demux/bit replacements. * diff --git a/synth2.cc b/synth2.cc index fc0d847da..b1d54ecce 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.27 2006/04/01 01:37:58 steve Exp $" +#ident "$Id: synth2.cc,v 1.39.2.28 2006/04/10 03:43:40 steve Exp $" #endif # include "config.h" @@ -941,6 +941,34 @@ bool NetAssignBase::synth_sync(Design*des, NetScope*scope, assert(demux->bmux() != 0); + /* Obviously, we need the r-value synthesized to connect it up. */ + NetNet*rsig = rval_->synthesize(des); + assert(rsig->pin_count() == lval_->lwidth()); + + /* Detect and handle the special case that the l-value is an + assign to a constant bit. We don't need a demux in that + case. */ + if (demux->mem() && dynamic_cast(demux->bmux())) { + NetMemory*lmem = demux->mem(); + NetNet*msig = lmem->explode_to_reg(); + msig->incr_lref(); + + NetEConst*ae = dynamic_cast(demux->bmux()); + long adr = ae->value().as_long(); + adr = lmem->index_to_address(adr) * lmem->width(); + + for (unsigned idx = 0 ; idx < demux->lwidth() ; idx += 1) { + unsigned off = adr+idx; + unsigned ptr = find_nexus_in_set(nex_map, msig->pin(off).nexus()); + assert(ptr <= nex_map->pin_count()); + connect(nex_out->pin(ptr), rsig->pin(idx)); + } + lval_->turn_sig_to_wire_on_release(); + return true; + } + + /* We also need the address (now known to be non-constant) + synthesized and connected to a decoder. */ NetNet*adr = demux->bmux()->synthesize(des); NetDecode*dq = new NetDecode(scope, scope->local_symbol(), nex_ff[0].ff, adr->pin_count(), @@ -951,9 +979,6 @@ bool NetAssignBase::synth_sync(Design*des, NetScope*scope, for (unsigned idx = 0 ; idx < adr->pin_count() ; idx += 1) connect(dq->pin_Address(idx), adr->pin(idx)); - NetNet*rsig = rval_->synthesize(des); - assert(rsig->pin_count() == lval_->lwidth()); - for (unsigned idx = 0 ; idx < nex_ff[0].ff->width() ; idx += 1) connect(nex_ff[0].ff->pin_Data(idx), rsig->pin(idx%lval_->lwidth())); @@ -1098,6 +1123,20 @@ bool NetBlock::synth_sync(Design*des, NetScope*scope, } } + if (tmp_sset.len() == ff->width()) { + + if (sset_value2.is_zero() + && ff2->pin_Sset().is_linked() + && !ff2->pin_Sclr().is_linked()) { + + ff2->pin_Sset().unlink(); + connect(ff2->pin_Sclr(), ff->pin_Sset()); + + } else { + ff2->sset_value(sset_value2); + } + } + /* Now go on with the synchronous synthesis for this statement of the block. The tmp_map is the output nexa that we expect, and the tmp_out is where we want @@ -1709,6 +1748,9 @@ void synth2(Design*des) /* * $Log: synth2.cc,v $ + * Revision 1.39.2.28 2006/04/10 03:43:40 steve + * Exploded memories accessed by constant indices. + * * Revision 1.39.2.27 2006/04/01 01:37:58 steve * Punt on set/reset if some sources are unconnected. *