Exploded memories accessed by constant indices.
This commit is contained in:
parent
ce4e21a962
commit
058dac4290
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
50
synth2.cc
50
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<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.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue