Synthesize LPM_RAM_DQ for writes into memories.

This commit is contained in:
steve 1999-12-05 02:24:08 +00:00
parent 22d89c5984
commit 3e2bb85f58
10 changed files with 273 additions and 34 deletions

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: design_dump.cc,v 1.61 1999/11/28 23:42:02 steve Exp $"
#ident "$Id: design_dump.cc,v 1.62 1999/12/05 02:24:08 steve Exp $"
#endif
/*
@ -428,9 +428,7 @@ void NetAssignMem::dump(ostream&o, unsigned ind) const
o << setw(ind) << "";
o << "/* " << get_line() << " */" << endl;
o << setw(ind) << "";
o << memory()->name() << "[";
index()->dump(o);
o << "] = ";
o << memory()->name() << "[" << index()->name() << "] = ";
rval()->dump(o);
o << ";" << endl;
}
@ -440,9 +438,7 @@ void NetAssignMemNB::dump(ostream&o, unsigned ind) const
o << setw(ind) << "";
o << "/* " << get_line() << " */" << endl;
o << setw(ind) << "";
o << memory()->name() << "[";
index()->dump(o);
o << "] <= ";
o << memory()->name() << "[" << index()->name() << "] <= ";
rval()->dump(o);
o << ";" << endl;
}
@ -866,6 +862,9 @@ void Design::dump(ostream&o) const
/*
* $Log: design_dump.cc,v $
* Revision 1.62 1999/12/05 02:24:08 steve
* Synthesize LPM_RAM_DQ for writes into memories.
*
* Revision 1.61 1999/11/28 23:42:02 steve
* NetESignal object no longer need to be NetNode
* objects. Let them keep a pointer to NetNet objects.

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: elaborate.cc,v 1.132 1999/12/02 04:08:10 steve Exp $"
#ident "$Id: elaborate.cc,v 1.133 1999/12/05 02:24:08 steve Exp $"
#endif
/*
@ -860,7 +860,7 @@ NetProc* PAssign::assign_to_memory_(NetMemory*mem, PExpr*ix,
assert(rv);
rv->set_width(mem->width());
NetExpr*idx = ix->elaborate_expr(des, path);
NetNet*idx = ix->elaborate_net(des, path, 0, 0, 0, 0);
assert(idx);
NetAssignMem*am = new NetAssignMem(mem, idx, rv);
@ -1170,7 +1170,7 @@ NetProc* PAssignNB::assign_to_memory_(NetMemory*mem, PExpr*ix,
rv->set_width(mem->width());
/* Elaborate the expression to calculate the index, ... */
NetExpr*idx = ix->elaborate_expr(des, path);
NetNet*idx = ix->elaborate_net(des, path, 0, 0, 0, 0);
assert(idx);
/* And connect them together in an assignment NetProc. */
@ -2090,6 +2090,9 @@ Design* elaborate(const map<string,Module*>&modules,
/*
* $Log: elaborate.cc,v $
* Revision 1.133 1999/12/05 02:24:08 steve
* Synthesize LPM_RAM_DQ for writes into memories.
*
* Revision 1.132 1999/12/02 04:08:10 steve
* Elaborate net repeat concatenations.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: functor.cc,v 1.5 1999/12/01 06:06:16 steve Exp $"
#ident "$Id: functor.cc,v 1.6 1999/12/05 02:24:08 steve Exp $"
#endif
# include "functor.h"
@ -99,6 +99,16 @@ int NetAssign::match_proc(proc_match_t*that)
return that->assign(this);
}
int proc_match_t::assign_mem(NetAssignMem*)
{
return 0;
}
int NetAssignMem::match_proc(proc_match_t*that)
{
return that->assign_mem(this);
}
int proc_match_t::condit(NetCondit*)
{
return 0;
@ -121,6 +131,9 @@ int NetPEvent::match_proc(proc_match_t*that)
/*
* $Log: functor.cc,v $
* Revision 1.6 1999/12/05 02:24:08 steve
* Synthesize LPM_RAM_DQ for writes into memories.
*
* Revision 1.5 1999/12/01 06:06:16 steve
* Redo synth to use match_proc_t scanner.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: functor.h,v 1.3 1999/12/01 06:06:16 steve Exp $"
#ident "$Id: functor.h,v 1.4 1999/12/05 02:24:08 steve Exp $"
#endif
/*
@ -50,6 +50,7 @@ struct proc_match_t {
virtual ~proc_match_t();
virtual int assign(class NetAssign*);
virtual int assign_mem(class NetAssignMem*);
virtual int condit(class NetCondit*);
virtual int pevent(class NetPEvent*);
};
@ -57,6 +58,9 @@ struct proc_match_t {
/*
* $Log: functor.h,v $
* Revision 1.4 1999/12/05 02:24:08 steve
* Synthesize LPM_RAM_DQ for writes into memories.
*
* Revision 1.3 1999/12/01 06:06:16 steve
* Redo synth to use match_proc_t scanner.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: netlist.cc,v 1.97 1999/12/02 16:58:58 steve Exp $"
#ident "$Id: netlist.cc,v 1.98 1999/12/05 02:24:09 steve Exp $"
#endif
# include <cassert>
@ -1052,10 +1052,25 @@ NetRamDq::NetRamDq(const string&n, NetMemory*mem, unsigned awid)
pin(3+awidth_+width()+idx).set_dir(NetObj::Link::OUTPUT);
pin(3+awidth_+width()+idx).set_name("Q", idx);
}
next_ = mem_->ram_list_;
mem_->ram_list_ = this;
}
NetRamDq::~NetRamDq()
{
if (mem_->ram_list_ == this) {
mem_->ram_list_ = next_;
} else {
NetRamDq*cur = mem_->ram_list_;
while (cur->next_ != this) {
assert(cur->next_);
cur = cur->next_;
}
assert(cur->next_ == this);
cur->next_ = next_;
}
}
unsigned NetRamDq::width() const
@ -1078,6 +1093,73 @@ const NetMemory* NetRamDq::mem() const
return mem_;
}
void NetRamDq::absorb_partners()
{
NetRamDq*cur, *tmp;
for (cur = mem_->ram_list_, tmp = 0
; cur||tmp ; cur = cur? cur->next_ : tmp) {
tmp = 0;
if (cur == this) continue;
bool ok_flag = true;
for (unsigned idx = 0 ; idx < awidth() ; idx += 1)
ok_flag &= pin_Address(idx).is_linked(cur->pin_Address(idx));
if (!ok_flag) continue;
if (pin_InClock().is_linked()
&& cur->pin_InClock().is_linked()
&& ! pin_InClock().is_linked(cur->pin_InClock()))
continue;
if (pin_OutClock().is_linked()
&& cur->pin_OutClock().is_linked()
&& ! pin_OutClock().is_linked(cur->pin_OutClock()))
continue;
if (pin_WE().is_linked()
&& cur->pin_WE().is_linked()
&& ! pin_WE().is_linked(cur->pin_WE()))
continue;
for (unsigned idx = 0 ; idx < width() ; idx += 1) {
if (!pin_Data(idx).is_linked()) continue;
if (! cur->pin_Data(idx).is_linked()) continue;
ok_flag &= pin_Data(idx).is_linked(cur->pin_Data(idx));
}
if (! ok_flag) continue;
for (unsigned idx = 0 ; idx < width() ; idx += 1) {
if (!pin_Q(idx).is_linked()) continue;
if (! cur->pin_Q(idx).is_linked()) continue;
ok_flag &= pin_Q(idx).is_linked(cur->pin_Q(idx));
}
if (! ok_flag) continue;
// I see no other reason to reject cur, so link up all
// my pins and delete it.
connect(pin_InClock(), cur->pin_InClock());
connect(pin_OutClock(), cur->pin_OutClock());
connect(pin_WE(), cur->pin_WE());
for (unsigned idx = 0 ; idx < awidth() ; idx += 1)
connect(pin_Address(idx), cur->pin_Address(idx));
for (unsigned idx = 0 ; idx < width() ; idx += 1) {
connect(pin_Data(idx), cur->pin_Data(idx));
connect(pin_Q(idx), cur->pin_Q(idx));
}
tmp = cur->next_;
delete cur;
cur = 0;
}
}
NetObj::Link& NetRamDq::pin_InClock()
{
return pin(0);
@ -1249,16 +1331,18 @@ NetAssignNB::~NetAssignNB()
}
NetAssignMem_::NetAssignMem_(NetMemory*m, NetExpr*i, NetExpr*r)
NetAssignMem_::NetAssignMem_(NetMemory*m, NetNet*i, NetExpr*r)
: mem_(m), index_(i), rval_(r)
{
index_->incr_eref();
}
NetAssignMem_::~NetAssignMem_()
{
index_->decr_eref();
}
NetAssignMem::NetAssignMem(NetMemory*m, NetExpr*i, NetExpr*r)
NetAssignMem::NetAssignMem(NetMemory*m, NetNet*i, NetExpr*r)
: NetAssignMem_(m, i, r)
{
}
@ -1267,7 +1351,7 @@ NetAssignMem::~NetAssignMem()
{
}
NetAssignMemNB::NetAssignMemNB(NetMemory*m, NetExpr*i, NetExpr*r)
NetAssignMemNB::NetAssignMemNB(NetMemory*m, NetNet*i, NetExpr*r)
: NetAssignMem_(m, i, r)
{
}
@ -1757,7 +1841,7 @@ NetEMemory::~NetEMemory()
}
NetMemory::NetMemory(const string&n, long w, long s, long e)
: name_(n), width_(w), idxh_(s), idxl_(e)
: name_(n), width_(w), idxh_(s), idxl_(e), ram_list_(0)
{
}
@ -2641,6 +2725,9 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*))
/*
* $Log: netlist.cc,v $
* Revision 1.98 1999/12/05 02:24:09 steve
* Synthesize LPM_RAM_DQ for writes into memories.
*
* Revision 1.97 1999/12/02 16:58:58 steve
* Update case comparison (Eric Aardoom).
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: netlist.h,v 1.97 1999/12/01 06:06:16 steve Exp $"
#ident "$Id: netlist.h,v 1.98 1999/12/05 02:24:09 steve Exp $"
#endif
/*
@ -480,6 +480,9 @@ class NetMemory {
long idxl_;
map<string,string> attributes_;
friend class NetRamDq;
NetRamDq* ram_list_;
};
/*
@ -561,8 +564,12 @@ class NetRamDq : public NetNode {
virtual void dump_node(ostream&, unsigned ind) const;
virtual void emit_node(ostream&, struct target_t*) const;
// Use this method to absorb other NetRamDq objects that are
// connected to the same memory, and have compatible pin
// connections.
void absorb_partners();
private:
friend class NetMemory;
NetMemory*mem_;
NetRamDq*next_;
unsigned awidth_;
@ -957,25 +964,29 @@ class NetAssignNB : public NetAssign_ {
class NetAssignMem_ : public NetProc {
public:
explicit NetAssignMem_(NetMemory*, NetExpr*idx, NetExpr*rv);
explicit NetAssignMem_(NetMemory*, NetNet*idx, NetExpr*rv);
~NetAssignMem_();
NetMemory*memory() { return mem_; }
NetNet*index() { return index_; }
const NetMemory*memory()const { return mem_; }
const NetExpr*index()const { return index_; }
const NetExpr*rval()const { return rval_; }
const NetNet*index()const { return index_; }
const NetExpr*rval()const { return rval_; }
private:
NetMemory*mem_;
NetExpr* index_;
NetNet * index_;
NetExpr* rval_;
};
class NetAssignMem : public NetAssignMem_ {
public:
explicit NetAssignMem(NetMemory*, NetExpr*idx, NetExpr*rv);
explicit NetAssignMem(NetMemory*, NetNet*idx, NetExpr*rv);
~NetAssignMem();
virtual int match_proc(struct proc_match_t*);
virtual bool emit_proc(ostream&, struct target_t*) const;
virtual void dump(ostream&, unsigned ind) const;
@ -985,7 +996,7 @@ class NetAssignMem : public NetAssignMem_ {
class NetAssignMemNB : public NetAssignMem_ {
public:
explicit NetAssignMemNB(NetMemory*, NetExpr*idx, NetExpr*rv);
explicit NetAssignMemNB(NetMemory*, NetNet*idx, NetExpr*rv);
~NetAssignMemNB();
virtual bool emit_proc(ostream&, struct target_t*) const;
@ -2051,6 +2062,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
* Revision 1.98 1999/12/05 02:24:09 steve
* Synthesize LPM_RAM_DQ for writes into memories.
*
* Revision 1.97 1999/12/01 06:06:16 steve
* Redo synth to use match_proc_t scanner.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: synth.cc,v 1.3 1999/12/01 06:06:16 steve Exp $"
#ident "$Id: synth.cc,v 1.4 1999/12/05 02:24:09 steve Exp $"
#endif
/*
@ -39,6 +39,14 @@
* always @(posedge CLK) if (CE) Q = D;
* always @(negedge CLK) if (CE) Q = D;
*
* These are memory assignments:
*
* always @(posedge CLK) M[a] = D
* always @(negedge CLK) M[a] = D
*
* always @(posedge CLK) if (CE) M[a] = D;
* always @(negedge CLK) if (CE) M[a] = D;
*
* The r-value of the assignments must be identifiers (i.e. wires or
* registers) and the CE must be single-bit identifiers. The generated
* device will be wide enough to accomodate Q and D.
@ -48,7 +56,7 @@ class match_dff : public proc_match_t {
public:
match_dff(Design*d, NetProcTop*t)
: des_(d), top_(t), pclk_(0), nclk_(0), con_(0), ce_(0),
asn_(0), d_(0)
asn_(0), asm_(0), d_(0)
{ }
~match_dff() { }
@ -56,7 +64,11 @@ class match_dff : public proc_match_t {
void make_it();
private:
void make_dff_();
void make_ram_();
virtual int assign(NetAssign*);
virtual int assign_mem(NetAssignMem*);
virtual int condit(NetCondit*);
virtual int pevent(NetPEvent*);
@ -67,7 +79,9 @@ class match_dff : public proc_match_t {
NetCondit *con_;
NetNet*ce_;
NetAssign *asn_;
NetAssignMem*asm_;
NetNet*d_;
};
@ -76,7 +90,7 @@ int match_dff::assign(NetAssign*as)
{
if (!pclk_)
return 0;
if (asn_)
if (asn_ || asm_)
return 0;
asn_ = as;
@ -87,11 +101,26 @@ int match_dff::assign(NetAssign*as)
return 1;
}
int match_dff::assign_mem(NetAssignMem*as)
{
if (!pclk_)
return 0;
if (asn_ || asm_)
return 0;
asm_ = as;
d_ = asm_->rval()->synthesize(des_);
if (d_ == 0)
return 0;
return 1;
}
int match_dff::condit(NetCondit*co)
{
if (!pclk_)
return 0;
if (con_ || asn_)
if (con_ || asn_ || asm_)
return 0;
con_ = co;
@ -106,7 +135,7 @@ int match_dff::condit(NetCondit*co)
int match_dff::pevent(NetPEvent*pe)
{
if (pclk_ || con_ || asn_)
if (pclk_ || con_ || asn_ || asm_)
return 0;
pclk_ = pe;
@ -125,6 +154,17 @@ int match_dff::pevent(NetPEvent*pe)
}
void match_dff::make_it()
{
if (asn_) {
assert(asm_ == 0);
make_dff_();
} else {
assert(asm_);
make_ram_();
}
}
void match_dff::make_dff_()
{
NetFF*ff = new NetFF(asn_->name(), asn_->pin_count());
@ -143,6 +183,28 @@ void match_dff::make_it()
des_->add_node(ff);
}
void match_dff::make_ram_()
{
NetMemory*mem = asm_->memory();
NetNet*adr = asm_->index();
NetRamDq*ram = new NetRamDq(des_->local_symbol(mem->name()), mem,
adr->pin_count());
for (unsigned idx = 0 ; idx < adr->pin_count() ; idx += 1)
connect(adr->pin(idx), ram->pin_Address(idx));
for (unsigned idx = 0 ; idx < ram->width() ; idx += 1)
connect(ram->pin_Data(idx), d_->pin(idx));
if (ce_)
connect(ram->pin_WE(), ce_->pin(0));
assert(nclk_->type() == NetNEvent::POSEDGE);
connect(ram->pin_InClock(), nclk_->pin(0));
ram->absorb_partners();
des_->add_node(ram);
}
class synth_f : public functor_t {
public:
@ -191,6 +253,9 @@ void synth(Design*des)
/*
* $Log: synth.cc,v $
* Revision 1.4 1999/12/05 02:24:09 steve
* Synthesize LPM_RAM_DQ for writes into memories.
*
* Revision 1.3 1999/12/01 06:06:16 steve
* Redo synth to use match_proc_t scanner.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: t-vvm.cc,v 1.87 1999/12/02 16:58:58 steve Exp $"
#ident "$Id: t-vvm.cc,v 1.88 1999/12/05 02:24:09 steve Exp $"
#endif
# include <iostream>
@ -1466,7 +1466,7 @@ void target_vvm::proc_assign(ostream&os, const NetAssign*net)
*/
void target_vvm::proc_assign_mem(ostream&os, const NetAssignMem*amem)
{
string index = emit_proc_rval(defn, 8, amem->index());
string index = mangle(amem->index()->name()) + "_bits";
string rval = emit_proc_rval(defn, 8, amem->rval());
const NetMemory*mem = amem->memory();
@ -1958,6 +1958,9 @@ extern const struct target tgt_vvm = {
};
/*
* $Log: t-vvm.cc,v $
* Revision 1.88 1999/12/05 02:24:09 steve
* Synthesize LPM_RAM_DQ for writes into memories.
*
* Revision 1.87 1999/12/02 16:58:58 steve
* Update case comparison (Eric Aardoom).
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: vvm.h,v 1.24 1999/12/02 03:36:01 steve Exp $"
#ident "$Id: vvm.h,v 1.25 1999/12/05 02:24:09 steve Exp $"
#endif
# include <cassert>
@ -271,6 +271,14 @@ class vvm_memory_t : public __vpiMemory {
call_list_(sim, addr);
}
void set_word(vvm_simulation*sim, unsigned addr,
const vpip_bit_t val[WIDTH])
{ unsigned base = WIDTH * addr;
for (unsigned idx = 0 ; idx < WIDTH ; idx += 1)
bits[base+idx] = val[idx];
call_list_(sim, addr);
}
vvm_bitset_t<WIDTH> get_word(unsigned addr) const
{ vvm_bitset_t<WIDTH> val;
unsigned base = WIDTH * addr;
@ -294,6 +302,9 @@ class vvm_memory_t : public __vpiMemory {
/*
* $Log: vvm.h,v $
* Revision 1.25 1999/12/05 02:24:09 steve
* Synthesize LPM_RAM_DQ for writes into memories.
*
* Revision 1.24 1999/12/02 03:36:01 steve
* shiftl and shiftr take unsized second parameter.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: vvm_gates.h,v 1.30 1999/12/02 16:58:58 steve Exp $"
#ident "$Id: vvm_gates.h,v 1.31 1999/12/05 02:24:09 steve Exp $"
#endif
# include "vvm.h"
@ -504,6 +504,15 @@ class vvm_nor : private vvm_1bit_out {
vpip_bit_t input_[WIDTH];
};
/*
* This object implements a LPM_RAM_DQ device, except for the actual
* contents of the memory, which are stored in a vvm_memory_t
* object. Note that there may be many vvm_ram_dq items referencing
* the same memory.
*
* XXXX Only asynchronous reads are supported.
* XXXX Only *synchronous* writes with WE are supported.
*/
template <unsigned WIDTH, unsigned AWIDTH, unsigned SIZE>
class vvm_ram_dq : protected vvm_ram_callback {
@ -520,6 +529,15 @@ class vvm_ram_dq : protected vvm_ram_callback {
void init_Address(unsigned idx, vpip_bit_t val)
{ addr_[idx] = val; }
void init_Data(unsigned idx, vpip_bit_t val)
{ data_[idx] = val; }
void init_WE(unsigned, vpip_bit_t val)
{ we_ = val; }
void init_InClock(unsigned, vpip_bit_t val)
{ iclk_ = val; }
void set_Address(vvm_simulation*sim, unsigned idx, vpip_bit_t val)
{ if (addr_[idx] == val) return;
addr_[idx] = val;
@ -527,6 +545,20 @@ class vvm_ram_dq : protected vvm_ram_callback {
send_out_(sim);
}
void set_Data(vvm_simulation*, unsigned idx, vpip_bit_t val)
{ data_[idx] = val; }
void set_WE(vvm_simulation*, unsigned, vpip_bit_t val)
{ we_ = val; }
void set_InClock(vvm_simulation*sim, unsigned, vpip_bit_t val)
{ if (val == iclk_) return;
vpip_bit_t tmp = iclk_;
iclk_ = val;
if (we_ != V1) return;
if (posedge(tmp, val)) mem_->set_word(sim, addr_val_, data_);
}
void handle_write(vvm_simulation*sim, unsigned idx)
{ if (idx == addr_val_) send_out_(sim); }
@ -535,7 +567,12 @@ class vvm_ram_dq : protected vvm_ram_callback {
private:
vvm_memory_t<WIDTH,SIZE>*mem_;
vpip_bit_t addr_[AWIDTH];
vpip_bit_t data_[WIDTH];
vpip_bit_t we_;
vpip_bit_t iclk_;
vvm_out_event::action_t out_[WIDTH];
unsigned long addr_val_;
@ -897,6 +934,9 @@ template <unsigned WIDTH> class vvm_pevent {
/*
* $Log: vvm_gates.h,v $
* Revision 1.31 1999/12/05 02:24:09 steve
* Synthesize LPM_RAM_DQ for writes into memories.
*
* Revision 1.30 1999/12/02 16:58:58 steve
* Update case comparison (Eric Aardoom).
*