diff --git a/PExpr.h b/PExpr.h index 06b863621..18e0080a9 100644 --- a/PExpr.h +++ b/PExpr.h @@ -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 @@ -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. diff --git a/design_dump.cc b/design_dump.cc index d5f445f78..dc2986caf 100644 --- a/design_dump.cc +++ b/design_dump.cc @@ -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 . diff --git a/elab_net.cc b/elab_net.cc index c699f5436..24c2c75bc 100644 --- a/elab_net.cc +++ b/elab_net.cc @@ -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. * diff --git a/emit.cc b/emit.cc index 814c37127..61ac4ae19 100644 --- a/emit.cc +++ b/emit.cc @@ -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 . diff --git a/netlist.cc b/netlist.cc index fe56bf5a5..8882d642c 100644 --- a/netlist.cc +++ b/netlist.cc @@ -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 @@ -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. * diff --git a/netlist.h b/netlist.h index a505d94e2..0fbf663d0 100644 --- a/netlist.h +++ b/netlist.h @@ -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 diff --git a/t-vvm.cc b/t-vvm.cc index 0155a318b..4626d40f4 100644 --- a/t-vvm.cc +++ b/t-vvm.cc @@ -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 @@ -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. * diff --git a/target.cc b/target.cc index 3a88ea948..7d0a5ae81 100644 --- a/target.cc +++ b/target.cc @@ -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 . diff --git a/target.h b/target.h index e35d91622..8f1ac6bdb 100644 --- a/target.h +++ b/target.h @@ -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 . diff --git a/vvm/vvm_gates.h b/vvm/vvm_gates.h index eb9812740..2893570d1 100644 --- a/vvm/vvm_gates.h +++ b/vvm/vvm_gates.h @@ -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 class vvm_and { vvm_out_event::action_t output_; }; +template 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< 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 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. *