Exploded memories accessed by constant indices.

This commit is contained in:
steve 2006-04-10 03:43:39 +00:00
parent ce4e21a962
commit 058dac4290
3 changed files with 104 additions and 7 deletions

View File

@ -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.
*

View File

@ -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.
*

View File

@ -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<NetEConst*>(demux->bmux())) {
NetMemory*lmem = demux->mem();
NetNet*msig = lmem->explode_to_reg();
msig->incr_lref();
NetEConst*ae = dynamic_cast<NetEConst*>(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.
*