Fix the memsynth1 case.
This commit is contained in:
parent
79cb8c883a
commit
b8bc531f05
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: design_dump.cc,v 1.149.2.2 2006/02/19 00:11:31 steve Exp $"
|
||||
#ident "$Id: design_dump.cc,v 1.149.2.3 2006/03/12 07:34:16 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -219,7 +219,7 @@ void NetCompare::dump_node(ostream&o, unsigned ind) const
|
|||
void NetDecode::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "LPM_DECODE (NetDecode): " << name()
|
||||
<< " ff=" << ff_->name() << endl;
|
||||
<< " ff=" << ff_->name() << ", word width=" << width() << endl;
|
||||
dump_node_pins(o, ind+4);
|
||||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
|
|
@ -369,7 +369,11 @@ void NetRamDq::dump_node(ostream&o, unsigned ind) const
|
|||
{
|
||||
o << setw(ind) << "" << "LPM_RAM_DQ (";
|
||||
|
||||
if (mem_) o << "mem=" << mem_->name();
|
||||
if (mem_)
|
||||
if (NetNet*tmp = mem_->reg_from_explode())
|
||||
o << "exploded mem=" << tmp->name();
|
||||
else
|
||||
o << "mem=" << mem_->name();
|
||||
|
||||
o << "): " << name() << endl;
|
||||
|
||||
|
|
@ -1105,6 +1109,9 @@ void Design::dump(ostream&o) const
|
|||
|
||||
/*
|
||||
* $Log: design_dump.cc,v $
|
||||
* Revision 1.149.2.3 2006/03/12 07:34:16 steve
|
||||
* Fix the memsynth1 case.
|
||||
*
|
||||
* Revision 1.149.2.2 2006/02/19 00:11:31 steve
|
||||
* Handle synthesis of FF vectors with l-value decoder.
|
||||
*
|
||||
|
|
|
|||
33
ivl_target.h
33
ivl_target.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: ivl_target.h,v 1.126.2.2 2006/02/25 05:03:28 steve Exp $"
|
||||
#ident "$Id: ivl_target.h,v 1.126.2.3 2006/03/12 07:34:16 steve Exp $"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
@ -675,9 +675,16 @@ extern const char* ivl_udp_name(ivl_udp_t net);
|
|||
* - IVL_LPM_FF
|
||||
* The IVL_LPM_FF and IVL_LPM_DECODE devices are closely related. If
|
||||
* the ivl_lpm_decode function returns a non-nil value, then the
|
||||
* decoder represents an extra ENABLE-like input, where exactly one(1)
|
||||
* bit of the width of the FF is enabled. The decoder inputs are and
|
||||
* address that selects the FF to be enabled.
|
||||
* decoder represents an extra ENABLE-like input, where exactly <N>
|
||||
* bits of the width of the FF is enabled. The ivl_lpm_width of the
|
||||
* decoder defines <N>.
|
||||
*
|
||||
* The decoder inputs are the address that selects the FF to be
|
||||
* enabled, and the ivl_lpm_selects for the decoder gives the width of
|
||||
* the address. The address of the LSB of the memory, then, is the
|
||||
* word width times the input address. For a simple l-value bit
|
||||
* select, the word width <N> will be 1, and the address goes directly
|
||||
* to the bit. Otherwise, <N>*address gets to the first bit of the word.
|
||||
*
|
||||
* The core compiler generates these attributes in certain cases:
|
||||
*
|
||||
|
|
@ -685,6 +692,19 @@ extern const char* ivl_udp_name(ivl_udp_t net);
|
|||
* If present, the string value can be "INVERT". That indicates
|
||||
* that the clock is negedge sensitive instead of the default
|
||||
* posedge sensitive.
|
||||
*
|
||||
* - IVL_LPM_RAM
|
||||
* The IVL_LPM_RAM may also appear as a READ port for a FF array. In
|
||||
* this case, the IVL_LPM_RAM device has an ivl_lpm_width that is the
|
||||
* width of the word, and an ivl_lpm_size that is the number of words
|
||||
* in the array. In effect, the IVL_LPM_RAM reorganizes a vector into
|
||||
* an array of words. If this is happening, then the ivl_lpm_memory
|
||||
* will return 0.
|
||||
*
|
||||
* The ivl_lpm_q function gets the output nexa of the read port. The
|
||||
* "q" port has as many bits as the width. The ivl_lpm_data2 function
|
||||
* gets the nexa of the input, with the sdx the word address and the
|
||||
* idx the bit within the word.
|
||||
*/
|
||||
|
||||
extern const char* ivl_lpm_name(ivl_lpm_t net); /* (Obsolete) */
|
||||
|
|
@ -727,7 +747,7 @@ extern ivl_nexus_t ivl_lpm_q(ivl_lpm_t net, unsigned idx);
|
|||
extern unsigned ivl_lpm_selects(ivl_lpm_t net);
|
||||
/* IVL_LPM_MUX IVL_LPM_DECODE IVL_LPM_RAM */
|
||||
extern ivl_nexus_t ivl_lpm_select(ivl_lpm_t net, unsigned idx);
|
||||
/* IVL_LPM_MUX */
|
||||
/* IVL_LPM_MUX, IVL_LPM_RAM */
|
||||
extern unsigned ivl_lpm_size(ivl_lpm_t net);
|
||||
/* IVL_LPM_RAM */
|
||||
extern ivl_memory_t ivl_lpm_memory(ivl_lpm_t net);
|
||||
|
|
@ -1268,6 +1288,9 @@ _END_DECL
|
|||
|
||||
/*
|
||||
* $Log: ivl_target.h,v $
|
||||
* Revision 1.126.2.3 2006/03/12 07:34:16 steve
|
||||
* Fix the memsynth1 case.
|
||||
*
|
||||
* Revision 1.126.2.2 2006/02/25 05:03:28 steve
|
||||
* Add support for negedge FFs by using attributes.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: net_assign.cc,v 1.18 2004/08/28 15:08:31 steve Exp $"
|
||||
#ident "$Id: net_assign.cc,v 1.18.2.1 2006/03/12 07:34:17 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -71,6 +71,14 @@ NetAssign_::~NetAssign_()
|
|||
sig_->type(NetNet::WIRE);
|
||||
}
|
||||
|
||||
if (mem_) {
|
||||
NetNet*exp = mem_->reg_from_explode();
|
||||
if (exp) {
|
||||
exp->decr_lref();
|
||||
if (turn_sig_to_wire_on_release_ && exp->peek_lref() == 0)
|
||||
exp->type(NetNet::WIRE);
|
||||
}
|
||||
}
|
||||
assert( more == 0 );
|
||||
if (bmux_) delete bmux_;
|
||||
}
|
||||
|
|
@ -111,7 +119,10 @@ perm_string NetAssign_::name() const
|
|||
|
||||
NetNet* NetAssign_::sig() const
|
||||
{
|
||||
return sig_;
|
||||
if (mem_)
|
||||
return 0;
|
||||
else
|
||||
return sig_;
|
||||
}
|
||||
|
||||
NetMemory* NetAssign_::mem() const
|
||||
|
|
@ -261,6 +272,9 @@ NetAssignNB::~NetAssignNB()
|
|||
|
||||
/*
|
||||
* $Log: net_assign.cc,v $
|
||||
* Revision 1.18.2.1 2006/03/12 07:34:17 steve
|
||||
* Fix the memsynth1 case.
|
||||
*
|
||||
* Revision 1.18 2004/08/28 15:08:31 steve
|
||||
* Do not change reg to wire in NetAssign_ unless synthesizing.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.1 2006/01/18 01:23:23 steve Exp $"
|
||||
#ident "$Id: net_nex_output.cc,v 1.11.2.2 2006/03/12 07:34:17 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -47,18 +47,42 @@ void NetAssignBase::nex_output(NexusSet&out)
|
|||
{
|
||||
for (NetAssign_*cur = lval_ ; cur ; cur = cur->more) {
|
||||
if (NetNet*lsig = cur->sig()) {
|
||||
#if 0
|
||||
if (cur->bmux()) {
|
||||
cerr << get_line() << ": internal error: "
|
||||
<< "L-Value mux not supported by nex_output: ";
|
||||
cur->dump_lval(cerr);
|
||||
cerr << endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* 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
|
||||
decoder between the expression and the signal. */
|
||||
for (unsigned idx = 0 ; idx < cur->lwidth() ; idx += 1) {
|
||||
unsigned off = cur->get_loff() + idx;
|
||||
out.add(lsig->pin(off).nexus());
|
||||
}
|
||||
|
||||
} else if (NetMemory*lmem = cur->mem()) {
|
||||
|
||||
/* Memories here are treated as a bunch of reg
|
||||
devices. Use the explode_to_reg method to get
|
||||
access to the FF version of the memory and use
|
||||
that in our l-value management. */
|
||||
NetNet*tmp = lmem->explode_to_reg();
|
||||
|
||||
if (NetEConst*ae = dynamic_cast<NetEConst*>(cur->bmux())) {
|
||||
/* The address is constant, so simply
|
||||
connect to the right pins and we are
|
||||
done. */
|
||||
long adr= ae->value().as_long();
|
||||
adr = lmem->index_to_address(adr) * lmem->width();
|
||||
|
||||
for (unsigned idx = 0; idx < cur->lwidth(); idx += 1)
|
||||
out.add(tmp->pin(adr+idx).nexus());
|
||||
|
||||
} else {
|
||||
/* Fake an address of 0. The context will
|
||||
actually shove a decoder in place here. */
|
||||
long adr= 0;
|
||||
for (unsigned idx = 0; idx < cur->lwidth(); idx += 1)
|
||||
out.add(tmp->pin(adr+idx).nexus());
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Quoting from netlist.h comments for class NetMemory:
|
||||
* "This is not a node because memory objects can only be
|
||||
|
|
@ -130,6 +154,9 @@ void NetWhile::nex_output(NexusSet&out)
|
|||
|
||||
/*
|
||||
* $Log: net_nex_output.cc,v $
|
||||
* Revision 1.11.2.2 2006/03/12 07:34:17 steve
|
||||
* Fix the memsynth1 case.
|
||||
*
|
||||
* Revision 1.11.2.1 2006/01/18 01:23:23 steve
|
||||
* Rework l-value handling to allow for more l-value type flexibility.
|
||||
*
|
||||
|
|
|
|||
34
netlist.cc
34
netlist.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: netlist.cc,v 1.226.2.2 2006/02/19 00:11:32 steve Exp $"
|
||||
#ident "$Id: netlist.cc,v 1.226.2.3 2006/03/12 07:34:17 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -686,6 +686,11 @@ const verinum& NetFF::sset_value() const
|
|||
return sset_value_;
|
||||
}
|
||||
|
||||
unsigned NetDecode::width() const
|
||||
{
|
||||
return width_;
|
||||
}
|
||||
|
||||
unsigned NetDecode::awidth() const
|
||||
{
|
||||
return pin_count();
|
||||
|
|
@ -1076,9 +1081,13 @@ const Link& NetCompare::pin_DataB(unsigned idx) const
|
|||
return pin(8+width_+idx);
|
||||
}
|
||||
|
||||
NetDecode::NetDecode(NetScope*s, perm_string name, NetFF*mem, unsigned awid)
|
||||
NetDecode::NetDecode(NetScope*s, perm_string name, NetFF*mem,
|
||||
unsigned awid, unsigned word_width)
|
||||
: NetNode(s, name, awid)
|
||||
{
|
||||
width_ = word_width;
|
||||
assert( mem->width() % width_ == 0 );
|
||||
|
||||
ff_ = mem;
|
||||
ff_->demux_ = this;
|
||||
make_pins_(awid);
|
||||
|
|
@ -2057,6 +2066,7 @@ NetMemory::NetMemory(NetScope*sc, perm_string n, long w, long s, long e)
|
|||
: width_(w), idxh_(s), idxl_(e), ram_list_(0), scope_(sc)
|
||||
{
|
||||
name_ = n;
|
||||
explode_ = 0;
|
||||
scope_->add_memory(this);
|
||||
}
|
||||
|
||||
|
|
@ -2087,7 +2097,24 @@ unsigned NetMemory::index_to_address(long idx) const
|
|||
return idx - idxl_;
|
||||
}
|
||||
|
||||
NetNet* NetMemory::explode_to_reg()
|
||||
{
|
||||
if (explode_)
|
||||
return explode_;
|
||||
|
||||
explode_ = new NetNet(scope_, name_, NetNet::REG, count()*width_);
|
||||
return explode_;
|
||||
}
|
||||
|
||||
NetNet* NetMemory::reg_from_explode()
|
||||
{
|
||||
return explode_;
|
||||
}
|
||||
|
||||
const NetNet* NetMemory::reg_from_explode() const
|
||||
{
|
||||
return explode_;
|
||||
}
|
||||
|
||||
NetEMemory* NetEMemory::dup_expr() const
|
||||
{
|
||||
|
|
@ -2335,6 +2362,9 @@ const NetProc*NetTaskDef::proc() const
|
|||
|
||||
/*
|
||||
* $Log: netlist.cc,v $
|
||||
* Revision 1.226.2.3 2006/03/12 07:34:17 steve
|
||||
* Fix the memsynth1 case.
|
||||
*
|
||||
* Revision 1.226.2.2 2006/02/19 00:11:32 steve
|
||||
* Handle synthesis of FF vectors with l-value decoder.
|
||||
*
|
||||
|
|
|
|||
24
netlist.h
24
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.10 2006/02/19 00:11:32 steve Exp $"
|
||||
#ident "$Id: netlist.h,v 1.321.2.11 2006/03/12 07:34:17 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -599,9 +599,15 @@ class NetCompare : public NetNode {
|
|||
class NetDecode : public NetNode {
|
||||
|
||||
public:
|
||||
NetDecode(NetScope*s, perm_string name, NetFF*mem, unsigned awid);
|
||||
NetDecode(NetScope*s, perm_string name, NetFF*mem,
|
||||
unsigned awid, unsigned word_width);
|
||||
~NetDecode();
|
||||
|
||||
// This is the width of the word. The width of the NetFF mem
|
||||
// is an even multiple of this.
|
||||
unsigned width() const;
|
||||
// This is the width of the address. The address value for the
|
||||
// base of a word is the address * width().
|
||||
unsigned awidth() const;
|
||||
|
||||
const NetFF*ff() const;
|
||||
|
|
@ -615,6 +621,7 @@ class NetDecode : public NetNode {
|
|||
virtual bool emit_node(struct target_t*) const;
|
||||
|
||||
private:
|
||||
unsigned width_;
|
||||
NetFF* ff_;
|
||||
|
||||
private:
|
||||
|
|
@ -784,6 +791,7 @@ class NetMemory {
|
|||
|
||||
// NetScope*scope();
|
||||
const NetScope*scope() const { return scope_; };
|
||||
NetScope*scope() { return scope_; };
|
||||
|
||||
// This is the number of memory positions.
|
||||
unsigned count() const;
|
||||
|
|
@ -793,6 +801,13 @@ class NetMemory {
|
|||
// that are not zero based.
|
||||
unsigned index_to_address(long idx) const;
|
||||
|
||||
// This method returns a NetNet::REG that has the same number
|
||||
// of bits as the memory as a whole. This is used to represent
|
||||
// memories that are synthesized to individual bits.
|
||||
NetNet* explode_to_reg();
|
||||
NetNet* reg_from_explode();
|
||||
const NetNet* reg_from_explode() const;
|
||||
|
||||
void dump(ostream&o, unsigned lm) const;
|
||||
|
||||
private:
|
||||
|
|
@ -808,6 +823,8 @@ class NetMemory {
|
|||
NetMemory*snext_, *sprev_;
|
||||
NetScope*scope_;
|
||||
|
||||
NetNet*explode_;
|
||||
|
||||
private: // not implemented
|
||||
NetMemory(const NetMemory&);
|
||||
NetMemory& operator= (const NetMemory&);
|
||||
|
|
@ -3439,6 +3456,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
|||
|
||||
/*
|
||||
* $Log: netlist.h,v $
|
||||
* Revision 1.321.2.11 2006/03/12 07:34:17 steve
|
||||
* Fix the memsynth1 case.
|
||||
*
|
||||
* Revision 1.321.2.10 2006/02/19 00:11:32 steve
|
||||
* Handle synthesis of FF vectors with l-value decoder.
|
||||
*
|
||||
|
|
|
|||
62
synth2.cc
62
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.22 2006/02/25 05:03:29 steve Exp $"
|
||||
#ident "$Id: synth2.cc,v 1.39.2.23 2006/03/12 07:34:18 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -105,6 +105,44 @@ bool NetAssignBase::synth_async(Design*des, NetScope*scope, bool sync_flag,
|
|||
|
||||
for (NetAssign_*cur = lval_ ; cur ; cur = cur->more) {
|
||||
|
||||
NetMemory*lmem = cur->mem();
|
||||
if (lmem && !sync_flag) {
|
||||
cerr << get_line() << ": error: Cannot synthesize memory "
|
||||
<< "assignment is asynchronous logic." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Is this an assignment to a memory? If so, then
|
||||
explode the memory to an array of reg bits. The
|
||||
context that is calling this will attach a decoder
|
||||
between the ff and the r-val. In fact, the memory at
|
||||
this point has already been scanned and exploded, so
|
||||
the explode_to_reg method below will return a
|
||||
pre-existing vector.
|
||||
|
||||
Note that this is only workable if we are in the
|
||||
asynchronous path of a synchronous thread. The
|
||||
sync_flag must be true in this case. */
|
||||
if (lmem) {
|
||||
assert(sync_flag);
|
||||
NetNet*msig = lmem->explode_to_reg();
|
||||
msig->incr_lref();
|
||||
|
||||
if (NetEConst*ae = dynamic_cast<NetEConst*>(cur->bmux())) {
|
||||
long adr= ae->value().as_long();
|
||||
adr = lmem->index_to_address(adr) * lmem->width();
|
||||
for (unsigned idx = 0 ; idx < cur->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(roff+idx));
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
NetNet*lsig = cur->sig();
|
||||
if (!lsig) {
|
||||
cerr << get_line() << ": error: NetAssignBase::synth_async "
|
||||
|
|
@ -851,6 +889,8 @@ bool NetAssignBase::synth_sync(Design*des, NetScope*scope,
|
|||
for (NetAssign_*cur = lval_ ; cur ; cur = cur->more) {
|
||||
if (cur->bmux())
|
||||
demux = cur;
|
||||
if (cur->mem())
|
||||
demux = cur;
|
||||
|
||||
count_lval += 1;
|
||||
}
|
||||
|
|
@ -872,7 +912,8 @@ bool NetAssignBase::synth_sync(Design*des, NetScope*scope,
|
|||
|
||||
NetNet*adr = demux->bmux()->synthesize(des);
|
||||
NetDecode*dq = new NetDecode(scope, scope->local_symbol(),
|
||||
nex_ff[0].ff, adr->pin_count());
|
||||
nex_ff[0].ff, adr->pin_count(),
|
||||
lval_->lwidth());
|
||||
des->add_node(dq);
|
||||
dq->set_line(*this);
|
||||
|
||||
|
|
@ -880,11 +921,16 @@ bool NetAssignBase::synth_sync(Design*des, NetScope*scope,
|
|||
connect(dq->pin_Address(idx), adr->pin(idx));
|
||||
|
||||
NetNet*rsig = rval_->synthesize(des);
|
||||
assert(rsig->pin_count() == 1);
|
||||
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(0));
|
||||
connect(nex_ff[0].ff->pin_Data(idx), rsig->pin(idx%lval_->lwidth()));
|
||||
|
||||
if (lval_->mem()) {
|
||||
NetNet*exp = lval_->mem()->reg_from_explode();
|
||||
assert(exp);
|
||||
exp->incr_lref();
|
||||
}
|
||||
lval_->turn_sig_to_wire_on_release();
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1269,7 +1315,10 @@ bool NetCondit::synth_sync(Design*des, NetScope*scope,
|
|||
|
||||
Also, we will not allow both Sset and Sclr to be used on a
|
||||
single LPM_FF (due to unclear priority issues) so don't try
|
||||
if either are already connected. */
|
||||
if either are already connected.
|
||||
|
||||
XXXX This should be disabled if there is a memory involved
|
||||
in any sub-statements? */
|
||||
assert(if_ != 0);
|
||||
NexusSet*a_set = if_->nex_input();
|
||||
|
||||
|
|
@ -1639,6 +1688,9 @@ void synth2(Design*des)
|
|||
|
||||
/*
|
||||
* $Log: synth2.cc,v $
|
||||
* Revision 1.39.2.23 2006/03/12 07:34:18 steve
|
||||
* Fix the memsynth1 case.
|
||||
*
|
||||
* Revision 1.39.2.22 2006/02/25 05:03:29 steve
|
||||
* Add support for negedge FFs by using attributes.
|
||||
*
|
||||
|
|
|
|||
26
t-dll-api.cc
26
t-dll-api.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-api.cc,v 1.108.2.2 2006/02/25 05:03:29 steve Exp $"
|
||||
#ident "$Id: t-dll-api.cc,v 1.108.2.3 2006/03/12 07:34:19 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -826,6 +826,22 @@ extern "C" ivl_nexus_t ivl_lpm_data2(ivl_lpm_t net, unsigned sdx, unsigned idx)
|
|||
return net->u_.ufunc.pins[base+idx];
|
||||
}
|
||||
|
||||
case IVL_LPM_RAM:
|
||||
if (net->u_.ff.a.mem == 0) {
|
||||
// This is an exploded RAM, so we use sdx and idx
|
||||
// to address a nexa into the exploded ram.
|
||||
if (sdx >= net->u_.ff.scnt)
|
||||
return 0;
|
||||
if (idx >= net->u_.ff.width)
|
||||
return 0;
|
||||
unsigned adr = sdx * net->u_.ff.width + idx;
|
||||
return net->u_.ff.d.pins[adr];
|
||||
|
||||
} else {
|
||||
// Normal RAM port does not have data2 nexa
|
||||
return 0;
|
||||
}
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
return 0;
|
||||
|
|
@ -1025,6 +1041,8 @@ extern "C" unsigned ivl_lpm_size(ivl_lpm_t net)
|
|||
switch (net->type) {
|
||||
case IVL_LPM_MUX:
|
||||
return net->u_.mux.size;
|
||||
case IVL_LPM_RAM:
|
||||
return net->u_.ff.scnt;
|
||||
case IVL_LPM_UFUNC:
|
||||
return net->u_.ufunc.ports - 1;
|
||||
default:
|
||||
|
|
@ -1045,6 +1063,7 @@ extern "C" unsigned ivl_lpm_width(ivl_lpm_t net)
|
|||
case IVL_LPM_FF:
|
||||
case IVL_LPM_RAM:
|
||||
return net->u_.ff.width;
|
||||
case IVL_LPM_DECODE:
|
||||
case IVL_LPM_MUX:
|
||||
return net->u_.mux.width;
|
||||
case IVL_LPM_ADD:
|
||||
|
|
@ -1062,8 +1081,6 @@ extern "C" unsigned ivl_lpm_width(ivl_lpm_t net)
|
|||
return net->u_.shift.width;
|
||||
case IVL_LPM_UFUNC:
|
||||
return net->u_.ufunc.port_wid[0];
|
||||
case IVL_LPM_DECODE:
|
||||
return 1;
|
||||
default:
|
||||
assert(0);
|
||||
return 0;
|
||||
|
|
@ -1964,6 +1981,9 @@ extern "C" ivl_variable_type_t ivl_variable_type(ivl_variable_t net)
|
|||
|
||||
/*
|
||||
* $Log: t-dll-api.cc,v $
|
||||
* Revision 1.108.2.3 2006/03/12 07:34:19 steve
|
||||
* Fix the memsynth1 case.
|
||||
*
|
||||
* Revision 1.108.2.2 2006/02/25 05:03:29 steve
|
||||
* Add support for negedge FFs by using attributes.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: t-dll-expr.cc,v 1.39 2004/06/17 16:06:19 steve Exp $"
|
||||
#ident "$Id: t-dll-expr.cc,v 1.39.2.1 2006/03/12 07:34:19 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -222,12 +222,58 @@ void dll_target::expr_memory(const NetEMemory*net)
|
|||
ivl_expr_t cur = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
|
||||
assert(cur);
|
||||
|
||||
cur->type_ = IVL_EX_MEMORY;
|
||||
cur->value_ = IVL_VT_VECTOR;
|
||||
cur->width_= net->expr_width();
|
||||
cur->signed_ = net->has_sign()? 1 : 0;
|
||||
cur->u_.memory_.mem_ = find_memory(des_, net->memory());
|
||||
cur->u_.memory_.idx_ = expr_;
|
||||
const NetMemory*mem = net->memory();
|
||||
|
||||
if (const NetNet*reg = mem->reg_from_explode()) {
|
||||
|
||||
cur->type_ = IVL_EX_SELECT;
|
||||
cur->value_ = IVL_VT_VECTOR;
|
||||
cur->width_ = net->expr_width();
|
||||
cur->signed_ = net->has_sign()? 1 : 0;
|
||||
|
||||
// Create an expression form of the exploded
|
||||
// memory. This is what the select will apply to.
|
||||
ivl_expr_t sig = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
|
||||
sig->type_ = IVL_EX_SIGNAL;
|
||||
sig->value_ = IVL_VT_VECTOR;
|
||||
sig->width_ = reg->pin_count();
|
||||
sig->signed_ = 0;
|
||||
sig->u_.signal_.sig = find_signal(des_, reg);
|
||||
sig->u_.signal_.lsi = 0;
|
||||
sig->u_.signal_.msi = reg->pin_count()-1;
|
||||
cur->u_.binary_.lef_ = sig;
|
||||
|
||||
// Create an expression of the address calculation.
|
||||
cur->u_.binary_.rig_ = expr_;
|
||||
|
||||
if (cur->width_ > 1) {
|
||||
ivl_expr_t mul = (ivl_expr_t)calloc(2, sizeof(struct ivl_expr_s));
|
||||
ivl_expr_t fac = mul+1;
|
||||
|
||||
fac->type_ = IVL_EX_ULONG;
|
||||
fac->value_ = IVL_VT_VECTOR;
|
||||
fac->width_ = 8*sizeof(cur->width_);
|
||||
fac->signed_= 0;
|
||||
fac->u_.ulong_.value = cur->width_;
|
||||
|
||||
mul->type_ = IVL_EX_BINARY;
|
||||
mul->value_ = IVL_VT_VECTOR;
|
||||
mul->width_ = fac->width_;
|
||||
mul->signed_= 0;
|
||||
mul->u_.binary_.op_ = '*';
|
||||
mul->u_.binary_.lef_ = cur->u_.binary_.rig_;
|
||||
mul->u_.binary_.rig_ = fac;
|
||||
cur->u_.binary_.rig_ = mul;
|
||||
}
|
||||
|
||||
} else {
|
||||
cur->type_ = IVL_EX_MEMORY;
|
||||
cur->value_ = IVL_VT_VECTOR;
|
||||
cur->width_= net->expr_width();
|
||||
cur->signed_ = net->has_sign()? 1 : 0;
|
||||
cur->u_.memory_.mem_ = find_memory(des_, net->memory());
|
||||
cur->u_.memory_.idx_ = expr_;
|
||||
}
|
||||
|
||||
expr_ = cur;
|
||||
}
|
||||
|
|
@ -604,6 +650,9 @@ void dll_target::expr_variable(const NetEVariable*net)
|
|||
|
||||
/*
|
||||
* $Log: t-dll-expr.cc,v $
|
||||
* Revision 1.39.2.1 2006/03/12 07:34:19 steve
|
||||
* Fix the memsynth1 case.
|
||||
*
|
||||
* Revision 1.39 2004/06/17 16:06:19 steve
|
||||
* Help system function signedness survive elaboration.
|
||||
*
|
||||
|
|
|
|||
32
t-dll.cc
32
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.4 2006/02/25 05:03:29 steve Exp $"
|
||||
#ident "$Id: t-dll.cc,v 1.131.2.5 2006/03/12 07:34:19 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -1522,7 +1522,7 @@ ivl_lpm_t dll_target::lpm_decode_ff_(const NetDecode*net)
|
|||
|
||||
obj->u_.mux.swid = net->awidth();
|
||||
obj->u_.mux.size = 0;
|
||||
obj->u_.mux.width = 0;
|
||||
obj->u_.mux.width = net->width();
|
||||
obj->u_.mux.d = 0;
|
||||
|
||||
if (obj->u_.mux.swid > 1) {
|
||||
|
|
@ -1671,18 +1671,23 @@ void dll_target::lpm_ff(const NetFF*net)
|
|||
|
||||
void dll_target::lpm_ram_dq(const NetRamDq*net)
|
||||
{
|
||||
ivl_memory_t mem = find_memory(des_, net->mem());
|
||||
assert(mem);
|
||||
|
||||
const NetNet*ereg = net->mem()->reg_from_explode();
|
||||
|
||||
ivl_lpm_t obj = new struct ivl_lpm_s;
|
||||
obj->type = IVL_LPM_RAM;
|
||||
obj->name = net->name();
|
||||
obj->attr = 0;
|
||||
obj->nattr = 0;
|
||||
obj->u_.ff.a.mem = find_memory(des_, net->mem());
|
||||
assert(obj->u_.ff.a.mem);
|
||||
obj->u_.ff.a.mem = ereg? 0 : mem;
|
||||
obj->scope = find_scope(des_, net->mem()->scope());
|
||||
assert(obj->scope);
|
||||
|
||||
obj->u_.ff.width = net->width();
|
||||
obj->u_.ff.swid = net->awidth();
|
||||
obj->u_.ff.scnt = net->mem()->count();
|
||||
|
||||
scope_add_lpm(obj->scope, obj);
|
||||
|
||||
|
|
@ -1692,6 +1697,7 @@ void dll_target::lpm_ram_dq(const NetRamDq*net)
|
|||
// the clock input.
|
||||
|
||||
bool has_write_port = net->pin_InClock().is_linked();
|
||||
assert( ereg? !has_write_port : 1 );
|
||||
|
||||
// Connect the write clock and write enable
|
||||
|
||||
|
|
@ -1783,6 +1789,21 @@ void dll_target::lpm_ram_dq(const NetRamDq*net)
|
|||
IVL_DR_STRONG, IVL_DR_STRONG);
|
||||
}
|
||||
}
|
||||
|
||||
if (ereg) {
|
||||
unsigned count = obj->u_.ff.width * obj->u_.ff.scnt;
|
||||
assert(ereg->pin_count() == count);
|
||||
|
||||
obj->u_.ff.d.pins = new ivl_nexus_t [count];
|
||||
|
||||
for (unsigned idx = 0 ; idx < count ; idx += 1) {
|
||||
nex = ereg->pin(idx).nexus();
|
||||
assert(nex->t_cookie());
|
||||
obj->u_.ff.d.pins[idx] = (ivl_nexus_t) nex->t_cookie();
|
||||
nexus_lpm_add(obj->u_.ff.d.pins[idx], obj, 0,
|
||||
IVL_DR_HiZ, IVL_DR_HiZ);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dll_target::lpm_mult(const NetMult*net)
|
||||
|
|
@ -2250,6 +2271,9 @@ extern const struct target tgt_dll = { "dll", &dll_target_obj };
|
|||
|
||||
/*
|
||||
* $Log: t-dll.cc,v $
|
||||
* Revision 1.131.2.5 2006/03/12 07:34:19 steve
|
||||
* Fix the memsynth1 case.
|
||||
*
|
||||
* Revision 1.131.2.4 2006/02/25 05:03:29 steve
|
||||
* Add support for negedge FFs by using attributes.
|
||||
*
|
||||
|
|
|
|||
6
t-dll.h
6
t-dll.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: t-dll.h,v 1.115.2.2 2006/02/25 05:03:30 steve Exp $"
|
||||
#ident "$Id: t-dll.h,v 1.115.2.3 2006/03/12 07:34:19 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "target.h"
|
||||
|
|
@ -300,6 +300,7 @@ struct ivl_lpm_s {
|
|||
struct ivl_lpm_ff_s {
|
||||
unsigned width;
|
||||
unsigned swid; // ram only
|
||||
unsigned scnt;
|
||||
ivl_nexus_t clk;
|
||||
ivl_nexus_t we;
|
||||
ivl_nexus_t aclr;
|
||||
|
|
@ -693,6 +694,9 @@ struct ivl_variable_s {
|
|||
|
||||
/*
|
||||
* $Log: t-dll.h,v $
|
||||
* Revision 1.115.2.3 2006/03/12 07:34:19 steve
|
||||
* Fix the memsynth1 case.
|
||||
*
|
||||
* Revision 1.115.2.2 2006/02/25 05:03:30 steve
|
||||
* Add support for negedge FFs by using attributes.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.6 2006/02/25 05:03:30 steve Exp $"
|
||||
#ident "$Id: stub.c,v 1.90.2.7 2006/03/12 07:34:20 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -112,6 +112,12 @@ static void show_expression(ivl_expr_t net, unsigned ind)
|
|||
break;
|
||||
}
|
||||
|
||||
case IVL_EX_ULONG: {
|
||||
fprintf(out, "%*s<ulong=%u'd%lu, %s>\n",
|
||||
ind, "", width, ivl_expr_uvalue(net), sign);
|
||||
break;
|
||||
}
|
||||
|
||||
case IVL_EX_SELECT:
|
||||
/* The SELECT expression can be used to express part
|
||||
select, or if the base is null vector extension. */
|
||||
|
|
@ -198,6 +204,35 @@ static void show_expression(ivl_expr_t net, unsigned ind)
|
|||
}
|
||||
}
|
||||
|
||||
static void show_lpm_ram(ivl_lpm_t net)
|
||||
{
|
||||
unsigned width = ivl_lpm_width(net);
|
||||
unsigned count = ivl_lpm_size(net);
|
||||
|
||||
unsigned idx, sdx;
|
||||
|
||||
fprintf(out, " LPM_RAM_DQ %s (word-width=%u, count=%u)\n",
|
||||
ivl_lpm_basename(net), ivl_lpm_width(net), count);
|
||||
for (idx = 0 ; idx < ivl_lpm_selects(net) ; idx += 1) {
|
||||
ivl_nexus_t nex = ivl_lpm_select(net, idx);
|
||||
fprintf(out, " Address %u: %s\n", idx,
|
||||
nex? ivl_nexus_name(nex) : "");
|
||||
}
|
||||
|
||||
for (idx = 0 ; idx < width ; idx += 1) {
|
||||
ivl_nexus_t nex = ivl_lpm_q(net, idx);
|
||||
fprintf(out, " Q %u: %s\n", idx, nex? ivl_nexus_name(nex) : "");
|
||||
}
|
||||
|
||||
for (sdx = 0 ; sdx < count ; sdx += 1) {
|
||||
for (idx = 0 ; idx < width ; idx += 1) {
|
||||
ivl_nexus_t nex = ivl_lpm_data2(net, sdx, idx);
|
||||
fprintf(out, " Word%u %u: %s\n",
|
||||
sdx, idx, nex? ivl_nexus_name(nex) : "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void show_lpm(ivl_lpm_t net)
|
||||
{
|
||||
unsigned idx;
|
||||
|
|
@ -296,7 +331,8 @@ static void show_lpm(ivl_lpm_t net)
|
|||
}
|
||||
|
||||
case IVL_LPM_DECODE: {
|
||||
fprintf(out, " LPM_DECODE %s\n", ivl_lpm_basename(net));
|
||||
fprintf(out, " LPM_DECODE %s (word-width=%u)\n",
|
||||
ivl_lpm_basename(net), ivl_lpm_width(net));
|
||||
for (idx = 0 ; idx < ivl_lpm_selects(net) ; idx += 1) {
|
||||
ivl_nexus_t nex = ivl_lpm_select(net, idx);
|
||||
fprintf(out, " Address %u: %s\n", idx,
|
||||
|
|
@ -305,6 +341,10 @@ static void show_lpm(ivl_lpm_t net)
|
|||
break;
|
||||
}
|
||||
|
||||
case IVL_LPM_RAM:
|
||||
show_lpm_ram(net);
|
||||
break;
|
||||
|
||||
case IVL_LPM_SHIFTL: {
|
||||
fprintf(out, " LPM_SHIFTL %s: <width=%u, selects=%u %s>\n",
|
||||
ivl_lpm_basename(net), width, ivl_lpm_selects(net),
|
||||
|
|
@ -1033,6 +1073,9 @@ int target_design(ivl_design_t des)
|
|||
|
||||
/*
|
||||
* $Log: stub.c,v $
|
||||
* Revision 1.90.2.7 2006/03/12 07:34:20 steve
|
||||
* Fix the memsynth1 case.
|
||||
*
|
||||
* Revision 1.90.2.6 2006/02/25 05:03:30 steve
|
||||
* Add support for negedge FFs by using attributes.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: eval_expr.c,v 1.110 2004/10/04 01:10:57 steve Exp $"
|
||||
#ident "$Id: eval_expr.c,v 1.110.2.1 2006/03/12 07:34:20 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vvp_priv.h"
|
||||
|
|
@ -1841,6 +1841,40 @@ static struct vector_info draw_ufunc_expr(ivl_expr_t exp, unsigned wid)
|
|||
return res;
|
||||
}
|
||||
|
||||
static struct vector_info draw_ulong_expr(ivl_expr_t exp, unsigned wid)
|
||||
{
|
||||
unsigned long idx;
|
||||
struct vector_info res;
|
||||
unsigned long uval = ivl_expr_uvalue(exp);
|
||||
|
||||
if (uval == 0) {
|
||||
res.wid = wid;
|
||||
res.base = 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
res.base = allocate_vector(wid);
|
||||
res.wid = wid;
|
||||
|
||||
idx = 0;
|
||||
while (idx < wid) {
|
||||
unsigned long cnt;
|
||||
|
||||
int bit = 1 & (uval >> idx);
|
||||
for (cnt = 1 ; idx+cnt < wid ; cnt += 1) {
|
||||
int tmp = 1 & (uval >> (idx+cnt));
|
||||
if (tmp != bit)
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf(vvp_out, " %%mov %u, %d, %lu;\n",
|
||||
res.base+idx, bit, cnt);
|
||||
idx += cnt;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static struct vector_info draw_unary_expr(ivl_expr_t exp, unsigned wid)
|
||||
{
|
||||
struct vector_info res;
|
||||
|
|
@ -2120,6 +2154,10 @@ struct vector_info draw_eval_expr_wid(ivl_expr_t exp, unsigned wid,
|
|||
res = draw_ufunc_expr(exp, wid);
|
||||
break;
|
||||
|
||||
case IVL_EX_ULONG:
|
||||
res = draw_ulong_expr(exp, wid);
|
||||
break;
|
||||
|
||||
case IVL_EX_UNARY:
|
||||
res = draw_unary_expr(exp, wid);
|
||||
break;
|
||||
|
|
@ -2139,6 +2177,9 @@ struct vector_info draw_eval_expr(ivl_expr_t exp, int stuff_ok_flag)
|
|||
|
||||
/*
|
||||
* $Log: eval_expr.c,v $
|
||||
* Revision 1.110.2.1 2006/03/12 07:34:20 steve
|
||||
* Fix the memsynth1 case.
|
||||
*
|
||||
* Revision 1.110 2004/10/04 01:10:57 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: vvp_scope.c,v 1.103.2.3 2006/02/25 05:03:30 steve Exp $"
|
||||
#ident "$Id: vvp_scope.c,v 1.103.2.4 2006/03/12 07:34:20 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vvp_priv.h"
|
||||
|
|
@ -411,7 +411,29 @@ static const char* draw_net_input_drive(ivl_nexus_t nex, ivl_nexus_ptr_t nptr)
|
|||
}
|
||||
break;
|
||||
|
||||
/* The output for a RAM depends on whether it is
|
||||
exploded or not. If it is, treat is like a MUX. If it
|
||||
is not, treat it like an arithmetic LPM. */
|
||||
case IVL_LPM_RAM:
|
||||
if (ivl_lpm_memory(lpm)) {
|
||||
for (idx = 0 ; idx < ivl_lpm_width(lpm) ; idx += 1) {
|
||||
if (ivl_lpm_q(lpm, idx) == nex) {
|
||||
sprintf(result, "L_%p[%u]", lpm, idx);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (idx = 0 ; idx < ivl_lpm_width(lpm) ; idx += 1) {
|
||||
if (ivl_lpm_q(lpm, idx) == nex) {
|
||||
sprintf(result, "L_%s.%s/%u",
|
||||
vvp_mangle_id(ivl_scope_name(ivl_lpm_scope(lpm))),
|
||||
vvp_mangle_id(ivl_lpm_basename(lpm)), idx);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IVL_LPM_ADD:
|
||||
case IVL_LPM_SHIFTL:
|
||||
case IVL_LPM_SHIFTR:
|
||||
|
|
@ -1105,7 +1127,13 @@ static void draw_event_in_scope(ivl_event_t obj)
|
|||
}
|
||||
}
|
||||
|
||||
inline static void draw_lpm_ram(ivl_lpm_t net)
|
||||
static void draw_lpm_ram_exploded(ivl_lpm_t net)
|
||||
{
|
||||
fprintf(vvp_out, "; exploded ram port!\n");
|
||||
draw_lpm_mux(net);
|
||||
}
|
||||
|
||||
static void draw_lpm_ram(ivl_lpm_t net)
|
||||
{
|
||||
unsigned idx;
|
||||
unsigned width = ivl_lpm_width(net);
|
||||
|
|
@ -1114,6 +1142,11 @@ inline static void draw_lpm_ram(ivl_lpm_t net)
|
|||
ivl_nexus_t clk = ivl_lpm_clk(net);
|
||||
ivl_nexus_t pin;
|
||||
|
||||
if (mem == 0) {
|
||||
draw_lpm_ram_exploded(net);
|
||||
return;
|
||||
}
|
||||
|
||||
if (clk) {
|
||||
fprintf(vvp_out, "CLK_%p .event posedge, ", net);
|
||||
draw_input_from_net(clk);
|
||||
|
|
@ -1317,6 +1350,7 @@ static void draw_lpm_ff(ivl_lpm_t net)
|
|||
|
||||
unsigned width, idx;
|
||||
ivl_attribute_t clock_pol = find_lpm_attr(net, "ivl:clock_polarity");
|
||||
ivl_lpm_t decode = ivl_lpm_decode(net);
|
||||
|
||||
width = ivl_lpm_width(net);
|
||||
|
||||
|
|
@ -1408,23 +1442,34 @@ static void draw_lpm_ff(ivl_lpm_t net)
|
|||
}
|
||||
|
||||
/* If there is a decoder for this FF, then create a
|
||||
decoder enable node. */
|
||||
if (ivl_lpm_decode(net)) {
|
||||
decoder enable node. The .decode/en arguments are the
|
||||
label for the .decode/adr, a .decoder/en slice
|
||||
number (the address it responds to), the label for a
|
||||
decoder enable, and the label for a mass-write enable. */
|
||||
if (decode) {
|
||||
ivl_lpm_t dec = ivl_lpm_decode(net);
|
||||
fprintf(vvp_out, "L_%s.%s/dec/%u .decode/en L_%s.%s, %u",
|
||||
vvp_mangle_id(ivl_scope_name(ivl_lpm_scope(net))),
|
||||
vvp_mangle_id(ivl_lpm_basename(net)), idx,
|
||||
vvp_mangle_id(ivl_lpm_basename(net)),
|
||||
idx,
|
||||
vvp_mangle_id(ivl_scope_name(ivl_lpm_scope(dec))),
|
||||
vvp_mangle_id(ivl_lpm_basename(dec)), idx);
|
||||
vvp_mangle_id(ivl_lpm_basename(dec)),
|
||||
idx / ivl_lpm_width(decode));
|
||||
|
||||
tmp = ivl_lpm_enable(net);
|
||||
if (tmp && (ivl_lpm_sync_clr(net)||ivl_lpm_sync_set(net))) {
|
||||
fprintf(vvp_out, ", L_%s.%s/en",
|
||||
vvp_mangle_id(ivl_scope_name(ivl_lpm_scope(net))),
|
||||
vvp_mangle_id(ivl_lpm_basename(net)));
|
||||
} else if (tmp) {
|
||||
if (tmp) {
|
||||
fprintf(vvp_out, ", ");
|
||||
draw_input_from_net(tmp);
|
||||
} else {
|
||||
fprintf(vvp_out, ", C<1> ");
|
||||
}
|
||||
fprintf(vvp_out, ", ");
|
||||
if (ivl_lpm_sync_clr(net)) {
|
||||
draw_input_from_net(ivl_lpm_sync_clr(net));
|
||||
} else if (ivl_lpm_sync_set(net)) {
|
||||
draw_input_from_net(ivl_lpm_sync_set(net));
|
||||
} else {
|
||||
fprintf(vvp_out, "C<0>");
|
||||
}
|
||||
fprintf(vvp_out, ";\n");
|
||||
}
|
||||
|
|
@ -1776,6 +1821,9 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent)
|
|||
|
||||
/*
|
||||
* $Log: vvp_scope.c,v $
|
||||
* Revision 1.103.2.4 2006/03/12 07:34:20 steve
|
||||
* Fix the memsynth1 case.
|
||||
*
|
||||
* Revision 1.103.2.3 2006/02/25 05:03:30 steve
|
||||
* Add support for negedge FFs by using attributes.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: compile.h,v 1.56.2.1 2006/02/19 00:11:35 steve Exp $"
|
||||
#ident "$Id: compile.h,v 1.56.2.2 2006/03/12 07:34:21 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <stdio.h>
|
||||
|
|
@ -118,7 +118,8 @@ extern void compile_cmp_gt(char*label, long width, bool signed_flag,
|
|||
extern void compile_decode_adr(char*label,
|
||||
unsigned argc, struct symb_s*argv);
|
||||
extern void compile_decode_en(char*label, char*decoder, int slice,
|
||||
struct symb_s enable);
|
||||
struct symb_s enable,
|
||||
struct symb_s mass_enable);
|
||||
extern void compile_shiftl(char*label, long width,
|
||||
unsigned argc, struct symb_s*argv);
|
||||
extern void compile_shiftr(char*label, long width,
|
||||
|
|
@ -272,6 +273,9 @@ extern void compile_net(char*label, char*name,
|
|||
|
||||
/*
|
||||
* $Log: compile.h,v $
|
||||
* Revision 1.56.2.2 2006/03/12 07:34:21 steve
|
||||
* Fix the memsynth1 case.
|
||||
*
|
||||
* Revision 1.56.2.1 2006/02/19 00:11:35 steve
|
||||
* Handle synthesis of FF vectors with l-value decoder.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ident "$Id: decoder.cc,v 1.1.2.1 2006/02/19 00:11:36 steve Exp $"
|
||||
#ident "$Id: decoder.cc,v 1.1.2.2 2006/03/12 07:34:21 steve Exp $"
|
||||
|
||||
# include "compile.h"
|
||||
# include "functor.h"
|
||||
|
|
@ -86,6 +86,8 @@ struct vvp_decode_en_s : public functor_s {
|
|||
bool decode_en;
|
||||
// This is the enable that arrives from the extra input.
|
||||
bool extra_en;
|
||||
// This is the mass-enable that enables independent of address
|
||||
bool mass_en;
|
||||
};
|
||||
|
||||
vvp_decode_adr_s::vvp_decode_adr_s(vvp_ipoint_t me, unsigned w)
|
||||
|
|
@ -119,6 +121,7 @@ vvp_decode_en_s::vvp_decode_en_s(vvp_decode_adr_s*dec, unsigned s)
|
|||
enable_next = 0;
|
||||
decode_en = false;
|
||||
extra_en = true;
|
||||
mass_en = false;
|
||||
|
||||
decoder = dec;
|
||||
enable_next = decoder->enable_list;
|
||||
|
|
@ -132,13 +135,25 @@ void vvp_decode_en_s::set(vvp_ipoint_t i, bool push,
|
|||
ifu->put(i, val);
|
||||
|
||||
int abval = functor_get_input(i);
|
||||
if (abval == 1) {
|
||||
extra_en = true;
|
||||
} else {
|
||||
extra_en = false;
|
||||
unsigned port = ipoint_port(i);
|
||||
switch (port) {
|
||||
case 0: // regular enable
|
||||
if (abval == 1) {
|
||||
extra_en = true;
|
||||
} else {
|
||||
extra_en = false;
|
||||
}
|
||||
break;
|
||||
case 1: // mass enable
|
||||
if (abval == 1) {
|
||||
mass_en = true;
|
||||
} else {
|
||||
mass_en = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (extra_en && decode_en)
|
||||
if (extra_en && decode_en || mass_en)
|
||||
put_oval(1, true);
|
||||
else
|
||||
put_oval(0, true);
|
||||
|
|
@ -183,7 +198,8 @@ void compile_decode_adr(char*label, unsigned argc, struct symb_s*argv)
|
|||
}
|
||||
|
||||
void compile_decode_en(char*label, char*decoder, int slice,
|
||||
struct symb_s enable)
|
||||
struct symb_s enable,
|
||||
struct symb_s mass_enable)
|
||||
{
|
||||
vvp_decode_adr_s*adr = decoder_find(decoder);
|
||||
vvp_decode_en_s*a = new struct vvp_decode_en_s(adr, slice);
|
||||
|
|
@ -191,9 +207,10 @@ void compile_decode_en(char*label, char*decoder, int slice,
|
|||
vvp_ipoint_t ix = functor_allocate(1);
|
||||
functor_define(ix, a);
|
||||
|
||||
if (enable.text) {
|
||||
inputs_connect(ix, 1, &enable);
|
||||
}
|
||||
symb_s argv[2];
|
||||
argv[0] = enable;
|
||||
argv[1] = mass_enable;
|
||||
inputs_connect(ix, 2, argv);
|
||||
|
||||
define_functor_symbol(label, ix);
|
||||
free(label);
|
||||
|
|
@ -201,6 +218,9 @@ void compile_decode_en(char*label, char*decoder, int slice,
|
|||
|
||||
/*
|
||||
* $Log: decoder.cc,v $
|
||||
* Revision 1.1.2.2 2006/03/12 07:34:21 steve
|
||||
* Fix the memsynth1 case.
|
||||
*
|
||||
* Revision 1.1.2.1 2006/02/19 00:11:36 steve
|
||||
* Handle synthesis of FF vectors with l-value decoder.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: parse.y,v 1.60.2.1 2006/02/19 00:11:36 steve Exp $"
|
||||
#ident "$Id: parse.y,v 1.60.2.2 2006/03/12 07:34:21 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "parse_misc.h"
|
||||
|
|
@ -270,8 +270,8 @@ statement
|
|||
compile_decode_adr($1, obj.cnt, obj.vect);
|
||||
}
|
||||
|
||||
| T_LABEL K_DECODE_EN T_SYMBOL ',' T_NUMBER ',' symbol ';'
|
||||
{ compile_decode_en($1, $3, $5, $7);
|
||||
| T_LABEL K_DECODE_EN T_SYMBOL ',' T_NUMBER ',' symbol ',' symbol ';'
|
||||
{ compile_decode_en($1, $3, $5, $7, $9);
|
||||
}
|
||||
|
||||
/* Event statements take a label, a type (the first T_SYMBOL) and a
|
||||
|
|
@ -646,6 +646,9 @@ int compile_design(const char*path)
|
|||
|
||||
/*
|
||||
* $Log: parse.y,v $
|
||||
* Revision 1.60.2.2 2006/03/12 07:34:21 steve
|
||||
* Fix the memsynth1 case.
|
||||
*
|
||||
* Revision 1.60.2.1 2006/02/19 00:11:36 steve
|
||||
* Handle synthesis of FF vectors with l-value decoder.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue