Add support for the LPM_CLSHIFT device.

This commit is contained in:
steve 1999-11-14 20:24:28 +00:00
parent 0eb6056ea6
commit 1624afe1ba
10 changed files with 406 additions and 14 deletions

10
PExpr.h
View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: PExpr.h,v 1.23 1999/11/05 21:45:19 steve Exp $"
#ident "$Id: PExpr.h,v 1.24 1999/11/14 20:24:28 steve Exp $"
#endif
# include <string>
@ -253,6 +253,11 @@ class PEBinary : public PExpr {
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_shift_(Design*des, const string&path,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
};
/*
@ -302,6 +307,9 @@ class PECallFunction : public PExpr {
/*
* $Log: PExpr.h,v $
* Revision 1.24 1999/11/14 20:24:28 steve
* Add support for the LPM_CLSHIFT device.
*
* Revision 1.23 1999/11/05 21:45:19 steve
* Fix NetConst being set to zero width, and clean
* up elaborate_set_cmp_ for NetEBinary.

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.55 1999/11/04 03:53:26 steve Exp $"
#ident "$Id: design_dump.cc,v 1.56 1999/11/14 20:24:28 steve Exp $"
#endif
/*
@ -130,6 +130,14 @@ void NetAddSub::dump_node(ostream&o, unsigned ind) const
dump_obj_attr(o, ind+4);
}
void NetCLShift::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "Combinatorial shift (NetCLShift): " <<
name() << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
}
void NetMux::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "Multiplexer (NetMux): " << name() << endl;
@ -818,6 +826,9 @@ void Design::dump(ostream&o) const
/*
* $Log: design_dump.cc,v $
* Revision 1.56 1999/11/14 20:24:28 steve
* Add support for the LPM_CLSHIFT device.
*
* Revision 1.55 1999/11/04 03:53:26 steve
* Patch to synthesize unary ~ and the ternary operator.
* Thanks to Larry Doolittle <LRDoolittle@lbl.gov>.

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: elab_net.cc,v 1.4 1999/11/05 23:36:31 steve Exp $"
#ident "$Id: elab_net.cc,v 1.5 1999/11/14 20:24:28 steve Exp $"
#endif
# include "PExpr.h"
@ -42,6 +42,9 @@ NetNet* PEBinary::elaborate_net(Design*des, const string&path,
case 'e':
case 'n':
return elaborate_net_cmp_(des, path, width, rise, fall, decay);
case 'l': // <<
case 'r': // >>
return elaborate_net_shift_(des, path, width, rise, fall, decay);
}
NetNet*lsig = left_->elaborate_net(des, path, width, 0, 0, 0),
@ -171,10 +174,7 @@ NetNet* PEBinary::elaborate_net(Design*des, const string&path,
case 'l':
case 'r':
cerr << get_line() << ": sorry: combinational shift"
" not supported here." << endl;
des->errors += 1;
osig = 0;
assert(0);
break;
default:
cerr << get_line() << ": internal error: unsupported"
@ -372,6 +372,91 @@ NetNet* PEBinary::elaborate_net_cmp_(Design*des, const string&path,
return osig;
}
NetNet* PEBinary::elaborate_net_shift_(Design*des, const string&path,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const
{
NetNet*lsig = left_->elaborate_net(des, path, lwidth, 0, 0, 0);
if (lsig == 0) return 0;
/* Handle the special case of a constant shift amount. There
is no reason in this case to create a gate at all, just
connect the lsig to the osig with the bit positions
shifted. */
if (verinum*rval = right_->eval_const(des, path)) {
assert(rval->is_defined());
unsigned dist = rval->as_ulong();
if (dist > lsig->pin_count())
dist = lsig->pin_count();
/* Very special case, constant 0 shift. */
if (dist == 0) return lsig;
NetNet*osig = new NetNet(des->local_symbol(path), NetNet::WIRE,
lsig->pin_count());
osig->local_flag(true);
NetConst*zero = new NetConst(des->local_symbol(path), verinum::V0);
des->add_node(zero);
if (op_ == 'l') {
unsigned idx;
for (idx = 0 ; idx < dist ; idx += 1)
connect(osig->pin(idx), zero->pin(0));
for (idx = dist ; idx < lsig->pin_count() ; idx += 1)
connect(osig->pin(idx), lsig->pin(idx-dist));
} else {
assert(op_ == 'r');
unsigned idx;
unsigned keep = lsig->pin_count()-dist;
for (idx = 0 ; idx < keep ; idx += 1)
connect(osig->pin(idx), lsig->pin(idx+dist));
for (idx = keep ; idx < lsig->pin_count() ; idx += 1)
connect(osig->pin(idx), zero->pin(0));
}
des->add_signal(osig);
return osig;
}
unsigned dwid = 0;
while ((1 << dwid) < lsig->pin_count())
dwid += 1;
NetNet*rsig = right_->elaborate_net(des, path, dwid, 0, 0, 0);
if (rsig == 0) return 0;
NetCLShift*gate = new NetCLShift(des->local_symbol(path),
lsig->pin_count(),
rsig->pin_count());
NetNet*osig = new NetNet(des->local_symbol(path), NetNet::WIRE,
lsig->pin_count());
osig->local_flag(true);
for (unsigned idx = 0 ; idx < osig->pin_count() ; idx += 1) {
connect(osig->pin(idx), gate->pin_Result(idx));
connect(lsig->pin(idx), gate->pin_Data(idx));
}
for (unsigned idx = 0 ; idx < rsig->pin_count() ; idx += 1)
connect(rsig->pin(idx), gate->pin_Distance(idx));
if (op_ == 'r') {
NetConst*dir = new NetConst(des->local_symbol(path), verinum::V1);
connect(dir->pin(0), gate->pin_Direction());
des->add_node(dir);
}
des->add_signal(osig);
des->add_node(gate);
return osig;
}
/*
* Elaborate a number as a NetConst object.
*/
@ -443,6 +528,9 @@ NetNet* PETernary::elaborate_net(Design*des, const string&path,
/*
* $Log: elab_net.cc,v $
* Revision 1.5 1999/11/14 20:24:28 steve
* Add support for the LPM_CLSHIFT device.
*
* Revision 1.4 1999/11/05 23:36:31 steve
* Forgot to return the mux for use after elaboration.
*

10
emit.cc
View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: emit.cc,v 1.26 1999/11/04 03:53:26 steve Exp $"
#ident "$Id: emit.cc,v 1.27 1999/11/14 20:24:28 steve Exp $"
#endif
/*
@ -65,6 +65,11 @@ void NetCaseCmp::emit_node(ostream&o, struct target_t*tgt) const
tgt->net_case_cmp(o, this);
}
void NetCLShift::emit_node(ostream&o, struct target_t*tgt) const
{
tgt->lpm_clshift(o, this);
}
void NetConst::emit_node(ostream&o, struct target_t*tgt) const
{
tgt->net_const(o, this);
@ -367,6 +372,9 @@ bool emit(ostream&o, const Design*des, const char*type)
/*
* $Log: emit.cc,v $
* Revision 1.27 1999/11/14 20:24:28 steve
* Add support for the LPM_CLSHIFT device.
*
* Revision 1.26 1999/11/04 03:53:26 steve
* Patch to synthesize unary ~ and the ternary operator.
* Thanks to Larry Doolittle <LRDoolittle@lbl.gov>.

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.84 1999/11/13 03:46:52 steve Exp $"
#ident "$Id: netlist.cc,v 1.85 1999/11/14 20:24:28 steve Exp $"
#endif
# include <cassert>
@ -590,6 +590,116 @@ const NetObj::Link& NetAddSub::pin_Result(unsigned idx) const
return pin(idx);
}
/*
* The pinout for the NetCLShift is:
* 0 -- Direction
* 1 -- Underflow
* 2 -- Overflow
* 3 -- Data(0)
* 3+W -- Result(0)
* 3+2W -- Distance(0)
*/
NetCLShift::NetCLShift(const string&n, unsigned width, unsigned width_dist)
: NetNode(n, 3+2*width+width_dist), width_(width), width_dist_(width_dist)
{
pin(0).set_dir(NetObj::Link::INPUT); pin(0).set_name("Direction", 0);
pin(1).set_dir(NetObj::Link::OUTPUT); pin(1).set_name("Underflow", 0);
pin(2).set_dir(NetObj::Link::OUTPUT); pin(2).set_name("Overflow", 0);
for (unsigned idx = 0 ; idx < width_ ; idx += 1) {
pin(3+idx).set_dir(NetObj::Link::INPUT);
pin(3+idx).set_name("Data", idx);
pin(3+width_+idx).set_dir(NetObj::Link::OUTPUT);
pin(3+width_+idx).set_name("Result", idx);
}
for (unsigned idx = 0 ; idx < width_dist_ ; idx += 1) {
pin(3+2*width_+idx).set_dir(NetObj::Link::INPUT);
pin(3+2*width_+idx).set_name("Distance", idx);
}
}
NetCLShift::~NetCLShift()
{
}
unsigned NetCLShift::width() const
{
return width_;
}
unsigned NetCLShift::width_dist() const
{
return width_dist_;
}
NetObj::Link& NetCLShift::pin_Direction()
{
return pin(0);
}
const NetObj::Link& NetCLShift::pin_Direction() const
{
return pin(0);
}
NetObj::Link& NetCLShift::pin_Underflow()
{
return pin(1);
}
const NetObj::Link& NetCLShift::pin_Underflow() const
{
return pin(1);
}
NetObj::Link& NetCLShift::pin_Overflow()
{
return pin(2);
}
const NetObj::Link& NetCLShift::pin_Overflow() const
{
return pin(2);
}
NetObj::Link& NetCLShift::pin_Data(unsigned idx)
{
assert(idx < width_);
return pin(3+idx);
}
const NetObj::Link& NetCLShift::pin_Data(unsigned idx) const
{
assert(idx < width_);
return pin(3+idx);
}
NetObj::Link& NetCLShift::pin_Result(unsigned idx)
{
assert(idx < width_);
return pin(3+width_+idx);
}
const NetObj::Link& NetCLShift::pin_Result(unsigned idx) const
{
assert(idx < width_);
return pin(3+width_+idx);
}
NetObj::Link& NetCLShift::pin_Distance(unsigned idx)
{
assert(idx < width_dist_);
return pin(3+2*width_+idx);
}
const NetObj::Link& NetCLShift::pin_Distance(unsigned idx) const
{
assert(idx < width_dist_);
return pin(3+2*width_+idx);
}
/*
* The NetMux class represents an LPM_MUX device. The pinout is assigned
* like so:
@ -2104,6 +2214,9 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*))
/*
* $Log: netlist.cc,v $
* Revision 1.85 1999/11/14 20:24:28 steve
* Add support for the LPM_CLSHIFT device.
*
* Revision 1.84 1999/11/13 03:46:52 steve
* Support the LPM_MUX in vvm.
*

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.86 1999/11/05 04:40:40 steve Exp $"
#ident "$Id: netlist.h,v 1.87 1999/11/14 20:24:28 steve Exp $"
#endif
/*
@ -325,6 +325,40 @@ class NetAddSub : public NetNode {
virtual void emit_node(ostream&, struct target_t*) const;
};
/*
* This type represents the LPM_CLSHIFT device.
*/
class NetCLShift : public NetNode {
public:
NetCLShift(const string&n, unsigned width, unsigned width_dist);
~NetCLShift();
unsigned width() const;
unsigned width_dist() const;
NetObj::Link& pin_Direction();
NetObj::Link& pin_Underflow();
NetObj::Link& pin_Overflow();
NetObj::Link& pin_Data(unsigned idx);
NetObj::Link& pin_Result(unsigned idx);
NetObj::Link& pin_Distance(unsigned idx);
const NetObj::Link& pin_Direction() const;
const NetObj::Link& pin_Underflow() const;
const NetObj::Link& pin_Overflow() const;
const NetObj::Link& pin_Data(unsigned idx) const;
const NetObj::Link& pin_Result(unsigned idx) const;
const NetObj::Link& pin_Distance(unsigned idx) const;
virtual void dump_node(ostream&, unsigned ind) const;
virtual void emit_node(ostream&, struct target_t*) const;
private:
unsigned width_;
unsigned width_dist_;
};
/*
* This class represents an LPM_FF device. There is no literal gate
* type in Verilog that maps, but gates of this type can be inferred.
@ -1858,6 +1892,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
* Revision 1.87 1999/11/14 20:24:28 steve
* Add support for the LPM_CLSHIFT device.
*
* Revision 1.86 1999/11/05 04:40:40 steve
* Patch to synthesize LPM_ADD_SUB from expressions,
* Thanks to Larry Doolittle. Also handle constants

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.74 1999/11/13 03:46:52 steve Exp $"
#ident "$Id: t-vvm.cc,v 1.75 1999/11/14 20:24:28 steve Exp $"
#endif
# include <iostream>
@ -60,6 +60,7 @@ class target_vvm : public target_t {
virtual void func_def(ostream&os, const NetFuncDef*);
virtual void lpm_add_sub(ostream&os, const NetAddSub*);
virtual void lpm_clshift(ostream&os, const NetCLShift*);
virtual void lpm_ff(ostream&os, const NetFF*);
virtual void lpm_mux(ostream&os, const NetMux*);
@ -868,6 +869,21 @@ void target_vvm::lpm_add_sub(ostream&os, const NetAddSub*gate)
}
}
void target_vvm::lpm_clshift(ostream&os, const NetCLShift*gate)
{
os << "static vvm_clshift<" << gate->width() << "," <<
gate->width_dist() << "> " << mangle(gate->name()) << ";"
<< endl;
for (unsigned idx = 0 ; idx < gate->width() ; idx += 1) {
unsigned pin = gate->pin_Result(idx).get_pin();
string outfun = defn_gate_outputfun_(os, gate, pin);
init_code << " " << mangle(gate->name()) <<
".config_rout(" << idx << ", &" << outfun << ");" << endl;
emit_gate_outputfun_(gate, pin);
}
}
void target_vvm::lpm_ff(ostream&os, const NetFF*gate)
{
string mname = mangle(gate->name());
@ -1863,6 +1879,9 @@ extern const struct target tgt_vvm = {
};
/*
* $Log: t-vvm.cc,v $
* Revision 1.75 1999/11/14 20:24:28 steve
* Add support for the LPM_CLSHIFT device.
*
* Revision 1.74 1999/11/13 03:46:52 steve
* Support the LPM_MUX in vvm.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: target.cc,v 1.23 1999/11/04 03:53:26 steve Exp $"
#ident "$Id: target.cc,v 1.24 1999/11/14 20:24:28 steve Exp $"
#endif
# include "target.h"
@ -75,6 +75,12 @@ void target_t::lpm_add_sub(ostream&, const NetAddSub*)
"Unhandled NetAddSub." << endl;
}
void target_t::lpm_clshift(ostream&, const NetCLShift*)
{
cerr << "target (" << typeid(*this).name() << "): "
"Unhandled NetCLShift." << endl;
}
void target_t::lpm_ff(ostream&, const NetFF*)
{
cerr << "target (" << typeid(*this).name() << "): "
@ -287,6 +293,9 @@ void expr_scan_t::expr_binary(const NetEBinary*ex)
/*
* $Log: target.cc,v $
* Revision 1.24 1999/11/14 20:24:28 steve
* Add support for the LPM_CLSHIFT device.
*
* Revision 1.23 1999/11/04 03:53:26 steve
* Patch to synthesize unary ~ and the ternary operator.
* Thanks to Larry Doolittle <LRDoolittle@lbl.gov>.

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: target.h,v 1.22 1999/11/04 03:53:26 steve Exp $"
#ident "$Id: target.h,v 1.23 1999/11/14 20:24:28 steve Exp $"
#endif
# include "netlist.h"
@ -67,6 +67,7 @@ struct target_t {
/* LPM style components are handled here. */
virtual void lpm_add_sub(ostream&os, const NetAddSub*);
virtual void lpm_clshift(ostream&os, const NetCLShift*);
virtual void lpm_ff(ostream&os, const NetFF*);
virtual void lpm_mux(ostream&os, const NetMux*);
@ -139,6 +140,9 @@ extern const struct target *target_table[];
/*
* $Log: target.h,v $
* Revision 1.23 1999/11/14 20:24:28 steve
* Add support for the LPM_CLSHIFT device.
*
* Revision 1.22 1999/11/04 03:53:26 steve
* Patch to synthesize unary ~ and the ternary operator.
* Thanks to Larry Doolittle <LRDoolittle@lbl.gov>.

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.20 1999/11/14 18:22:12 steve Exp $"
#ident "$Id: vvm_gates.h,v 1.21 1999/11/14 20:24:28 steve Exp $"
#endif
# include "vvm.h"
@ -152,6 +152,98 @@ template <unsigned WIDTH, unsigned long DELAY> class vvm_and {
vvm_out_event::action_t output_;
};
template <unsigned WIDTH, unsigned WDIST> class vvm_clshift {
public:
explicit vvm_clshift()
{ dir_ = V0;
dist_val_ = WIDTH;
for (unsigned idx = 0 ; idx < WIDTH ; idx += 1)
data_[idx] = Vx;
for (unsigned idx = 0 ; idx < WIDTH ; idx += 1)
out_[idx] = 0;
for (unsigned idx = 0 ; idx < WDIST ; idx += 1)
dist_[idx] = Vx;
}
~vvm_clshift() { }
void init_Data(unsigned idx, vpip_bit_t val)
{ data_[idx] = val;
}
void init_Distance(unsigned idx, vpip_bit_t val)
{ dist_[idx] = val;
calculate_dist_();
}
void set_Data(vvm_simulation*sim, unsigned idx, vpip_bit_t val)
{ if (data_[idx] == val) return;
data_[idx] = val;
if ((dist_val_ + idx) >= WIDTH) return;
vvm_out_event::action_t out = out_[dist_val_+idx];
if (out == 0) return;
vvm_event*ev = new vvm_out_event(sim, val, out);
sim->active_event(ev);
}
void set_Distance(vvm_simulation*sim, unsigned idx, vpip_bit_t val)
{ if (dist_[idx] == val) return;
dist_[idx] = val;
calculate_dist_();
compute_(sim);
}
void config_rout(unsigned idx, vvm_out_event::action_t o)
{ out_[idx] = o;
}
private:
vpip_bit_t dir_;
vpip_bit_t data_[WIDTH];
vpip_bit_t dist_[WDIST];
vvm_out_event::action_t out_[WIDTH];
unsigned dist_val_;
void calculate_dist_()
{ unsigned tmp = 0;
for (unsigned idx = 0 ; idx < WDIST ; idx += 1)
switch (dist_[idx]) {
case V0:
break;
case V1:
tmp |= 1<<idx;
break;
default:
tmp = WIDTH;
}
if (tmp > WIDTH) tmp = WIDTH;
dist_val_ = tmp;
}
void compute_(vvm_simulation*sim)
{ vvm_event*ev;
if (dist_val_ == WIDTH) {
for (unsigned idx = 0 ; idx < WIDTH ; idx += 1) {
if (out_[idx] == 0) continue;
ev = new vvm_out_event(sim, Vx, out_[idx]);
sim->active_event(ev);
}
return;
}
for (unsigned idx = 0 ; idx < dist_val_ ; idx += 1) {
if (out_[idx] == 0) continue;
ev = new vvm_out_event(sim, V0, out_[idx]);
sim->active_event(ev);
}
for (unsigned idx = dist_val_ ; idx < WIDTH ; idx += 1) {
if (out_[idx] == 0) continue;
ev = new vvm_out_event(sim, data_[idx-dist_val_],
out_[idx]);
sim->active_event(ev);
}
}
};
/*
* This class simulates the LPM flip-flop device.
* XXXX Inverted clock not yet supported.
@ -740,6 +832,9 @@ template <unsigned WIDTH> class vvm_pevent {
/*
* $Log: vvm_gates.h,v $
* Revision 1.21 1999/11/14 20:24:28 steve
* Add support for the LPM_CLSHIFT device.
*
* Revision 1.20 1999/11/14 18:22:12 steve
* Fix NAND gate support to use named pins.
*