Permalink
Browse files

Multiplication all the way to simulation.

  • Loading branch information...
1 parent 3d1ffce commit aa8908c52f2ddcb0ee4d209eabaa38a82a922a67 steve committed Jan 13, 2000
Showing with 570 additions and 34 deletions.
  1. +9 −1 PExpr.h
  2. +12 −3 design_dump.cc
  3. +9 −1 elab_expr.cc
  4. +54 −13 elab_net.cc
  5. +9 −1 emit.cc
  6. +10 −1 eval_tree.cc
  7. +13 −1 functor.cc
  8. +7 −1 functor.h
  9. +141 −1 netlist.cc
  10. +71 −1 netlist.h
  11. +13 −2 set_width.cc
  12. +34 −1 t-vvm.cc
  13. +10 −1 target.cc
  14. +5 −1 target.h
  15. +3 −3 vvm/Makefile.in
  16. +22 −1 vvm/vvm_func.h
  17. +34 −1 vvm/vvm_gates.h
  18. +114 −0 vvm/vvm_mult.cc
View
10 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.26 1999/12/16 03:46:39 steve Exp $"
+#ident "$Id: PExpr.h,v 1.27 2000/01/13 03:35:35 steve Exp $"
#endif
# include <string>
@@ -264,6 +264,11 @@ class PEBinary : public PExpr {
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
+ NetNet* elaborate_net_mul_(Design*des, const string&path,
+ unsigned lwidth,
+ unsigned long rise,
+ unsigned long fall,
+ unsigned long decay) const;
NetNet* elaborate_net_shift_(Design*des, const string&path,
unsigned lwidth,
unsigned long rise,
@@ -318,6 +323,9 @@ class PECallFunction : public PExpr {
/*
* $Log: PExpr.h,v $
+ * Revision 1.27 2000/01/13 03:35:35 steve
+ * Multiplication all the way to simulation.
+ *
* Revision 1.26 1999/12/16 03:46:39 steve
* Structural logical or.
*
View
15 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.65 2000/01/10 01:35:23 steve Exp $"
+#ident "$Id: design_dump.cc,v 1.66 2000/01/13 03:35:35 steve Exp $"
#endif
/*
@@ -142,8 +142,14 @@ void NetCLShift::dump_node(ostream&o, unsigned ind) const
void NetCompare::dump_node(ostream&o, unsigned ind) const
{
- o << setw(ind) << "" << "LPM_COMPARE (NetCompare): " <<
- name() << endl;
+ o << setw(ind) << "" << "LPM_COMPARE (NetCompare): " << name() << endl;
+ dump_node_pins(o, ind+4);
+ dump_obj_attr(o, ind+4);
+}
+
+void NetMult::dump_node(ostream&o, unsigned ind) const
+{
+ o << setw(ind) << "" << "LPM_MULT (NetMult): " << name() << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
}
@@ -865,6 +871,9 @@ void Design::dump(ostream&o) const
/*
* $Log: design_dump.cc,v $
+ * Revision 1.66 2000/01/13 03:35:35 steve
+ * Multiplication all the way to simulation.
+ *
* Revision 1.65 2000/01/10 01:35:23 steve
* Elaborate parameters afer binding of overrides.
*
View
10 elab_expr.cc
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
-#ident "$Id: elab_expr.cc,v 1.14 2000/01/01 06:18:00 steve Exp $"
+#ident "$Id: elab_expr.cc,v 1.15 2000/01/13 03:35:35 steve Exp $"
#endif
@@ -68,6 +68,11 @@ NetExpr* PEBinary::elaborate_expr(Design*des, const string&path) const
tmp->set_line(*this);
break;
+ case '*':
+ tmp = new NetEBMult(op_, lp, rp);
+ tmp->set_line(*this);
+ break;
+
case 'l':
case 'r':
tmp = new NetEBShift(op_, lp, rp);
@@ -373,6 +378,9 @@ NetExpr*PETernary::elaborate_expr(Design*des, const string&path) const
/*
* $Log: elab_expr.cc,v $
+ * Revision 1.15 2000/01/13 03:35:35 steve
+ * Multiplication all the way to simulation.
+ *
* Revision 1.14 2000/01/01 06:18:00 steve
* Handle synthesis of concatenation.
*
View
67 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.18 2000/01/11 04:20:57 steve Exp $"
+#ident "$Id: elab_net.cc,v 1.19 2000/01/13 03:35:35 steve Exp $"
#endif
# include "PExpr.h"
@@ -35,6 +35,10 @@ NetNet* PEBinary::elaborate_net(Design*des, const string&path,
unsigned long decay) const
{
switch (op_) {
+ case '*':
+ //case '/':
+ //case '%':
+ return elaborate_net_mul_(des, path, width, rise, fall, decay);
case '+':
case '-':
return elaborate_net_add_(des, path, width, rise, fall, decay);
@@ -272,18 +276,6 @@ NetNet* PEBinary::elaborate_net_cmp_(Design*des, const string&path,
return 0;
}
-#if 0
- if (lsig->pin_count() != rsig->pin_count()) {
- cerr << get_line() << ": internal error: Cannot match "
- "structural net widths " << lsig->pin_count() <<
- " and " << rsig->pin_count() << "." << endl;
- delete lsig;
- delete rsig;
- des->errors += 1;
- return 0;
- }
-#endif
-
unsigned dwidth = lsig->pin_count();
if (rsig->pin_count() > dwidth) dwidth = rsig->pin_count();
@@ -508,6 +500,52 @@ NetNet* PEBinary::elaborate_net_log_(Design*des, const string&path,
return osig;
}
+NetNet* PEBinary::elaborate_net_mul_(Design*des, const string&path,
+ unsigned lwidth,
+ unsigned long rise,
+ unsigned long fall,
+ unsigned long decay) const
+{
+ NetNet*lsig = left_->elaborate_net(des, path, 0, 0, 0, 0);
+ if (lsig == 0) return 0;
+ NetNet*rsig = right_->elaborate_net(des, path, 0, 0, 0, 0);
+ if (rsig == 0) return 0;
+
+ unsigned rwidth = lsig->pin_count() + rsig->pin_count();
+ NetMult*mult = new NetMult(des->local_symbol(path), rwidth,
+ lsig->pin_count(),
+ rsig->pin_count());
+ des->add_node(mult);
+
+ for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1)
+ connect(mult->pin_DataA(idx), lsig->pin(idx));
+ for (unsigned idx = 0 ; idx < rsig->pin_count() ; idx += 1)
+ connect(mult->pin_DataB(idx), rsig->pin(idx));
+
+ if (lwidth == 0) lwidth = rwidth;
+ NetNet*osig = new NetNet(0, des->local_symbol(path),
+ NetNet::IMPLICIT, lwidth);
+ osig->local_flag(true);
+ des->add_signal(osig);
+
+ unsigned cnt = osig->pin_count();
+ if (cnt > rwidth) cnt = rwidth;
+
+ for (unsigned idx = 0 ; idx < cnt ; idx += 1)
+ connect(mult->pin_Result(idx), osig->pin(idx));
+
+ /* If the lvalue is larger then the result, then pad the
+ output with constant 0. */
+ if (cnt < osig->pin_count()) {
+ NetConst*tmp = new NetConst(des->local_symbol(path), verinum::V0);
+ des->add_node(tmp);
+ for (unsigned idx = cnt ; idx < osig->pin_count() ; idx += 1)
+ connect(osig->pin(idx), tmp->pin(0));
+ }
+
+ return osig;
+}
+
NetNet* PEBinary::elaborate_net_shift_(Design*des, const string&path,
unsigned lwidth,
unsigned long rise,
@@ -1224,6 +1262,9 @@ NetNet* PEUnary::elaborate_net(Design*des, const string&path,
/*
* $Log: elab_net.cc,v $
+ * Revision 1.19 2000/01/13 03:35:35 steve
+ * Multiplication all the way to simulation.
+ *
* Revision 1.18 2000/01/11 04:20:57 steve
* Elaborate net widths of constants to as small
* as is possible, obeying context constraints.
View
10 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.31 1999/11/28 23:42:02 steve Exp $"
+#ident "$Id: emit.cc,v 1.32 2000/01/13 03:35:35 steve Exp $"
#endif
/*
@@ -85,6 +85,11 @@ void NetFF::emit_node(ostream&o, struct target_t*tgt) const
tgt->lpm_ff(o, this);
}
+void NetMult::emit_node(ostream&o, struct target_t*tgt) const
+{
+ tgt->lpm_mult(o, this);
+}
+
void NetMux::emit_node(ostream&o, struct target_t*tgt) const
{
tgt->lpm_mux(o, this);
@@ -389,6 +394,9 @@ bool emit(ostream&o, const Design*des, const char*type)
/*
* $Log: emit.cc,v $
+ * Revision 1.32 2000/01/13 03:35:35 steve
+ * Multiplication all the way to simulation.
+ *
* Revision 1.31 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
11 eval_tree.cc
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
-#ident "$Id: eval_tree.cc,v 1.6 1999/10/22 23:57:53 steve Exp $"
+#ident "$Id: eval_tree.cc,v 1.7 2000/01/13 03:35:35 steve Exp $"
#endif
# include "netlist.h"
@@ -138,6 +138,12 @@ NetEConst* NetEBLogic::eval_tree()
return 0;
}
+NetEConst* NetEBMult::eval_tree()
+{
+ eval_sub_tree_();
+ return 0;
+}
+
/*
* Evaluate the shift operator if possible. For this to work, both
* operands must be constant.
@@ -262,6 +268,9 @@ NetExpr* NetEParam::eval_tree()
/*
* $Log: eval_tree.cc,v $
+ * Revision 1.7 2000/01/13 03:35:35 steve
+ * Multiplication all the way to simulation.
+ *
* Revision 1.6 1999/10/22 23:57:53 steve
* do the <= in bits, not numbers.
*
View
14 functor.cc
@@ -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.9 2000/01/02 17:57:20 steve Exp $"
+#ident "$Id: functor.cc,v 1.10 2000/01/13 03:35:35 steve Exp $"
#endif
# include "functor.h"
@@ -51,6 +51,10 @@ void functor_t::lpm_logic(class Design*, class NetLogic*)
{
}
+void functor_t::lpm_mult(class Design*, class NetMult*)
+{
+}
+
void Design::functor(functor_t*fun)
{
// apply to signals
@@ -107,6 +111,11 @@ void NetLogic::functor_node(Design*des, functor_t*fun)
fun->lpm_logic(des, this);
}
+void NetMult::functor_node(Design*des, functor_t*fun)
+{
+ fun->lpm_mult(des, this);
+}
+
proc_match_t::~proc_match_t()
{
}
@@ -158,6 +167,9 @@ int NetPEvent::match_proc(proc_match_t*that)
/*
* $Log: functor.cc,v $
+ * Revision 1.10 2000/01/13 03:35:35 steve
+ * Multiplication all the way to simulation.
+ *
* Revision 1.9 2000/01/02 17:57:20 steve
* Handle nodes running out during node scan.
*
View
8 functor.h
@@ -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.6 1999/12/30 04:19:12 steve Exp $"
+#ident "$Id: functor.h,v 1.7 2000/01/13 03:35:35 steve Exp $"
#endif
/*
@@ -53,6 +53,9 @@ struct functor_t {
/* Handle LPM combinational logic devices. */
virtual void lpm_logic(class Design*des, class NetLogic*);
+
+ /* This method is called for each multiplier. */
+ virtual void lpm_mult(class Design*des, class NetMult*);
};
struct proc_match_t {
@@ -67,6 +70,9 @@ struct proc_match_t {
/*
* $Log: functor.h,v $
+ * Revision 1.7 2000/01/13 03:35:35 steve
+ * Multiplication all the way to simulation.
+ *
* Revision 1.6 1999/12/30 04:19:12 steve
* Propogate constant 0 in low bits of adders.
*
View
142 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.103 2000/01/10 01:35:24 steve Exp $"
+#ident "$Id: netlist.cc,v 1.104 2000/01/13 03:35:35 steve Exp $"
#endif
# include <cassert>
@@ -932,6 +932,126 @@ const NetObj::Link& NetCompare::pin_DataB(unsigned idx) const
return pin(8+width_+idx);
}
+NetMult::NetMult(const string&n, unsigned wr, unsigned wa, unsigned wb,
+ unsigned ws)
+: NetNode(n, 2+wr+wa+wb+ws), width_r_(wr), width_a_(wa), width_b_(wb),
+ width_s_(ws)
+{
+ pin(0).set_dir(NetObj::Link::INPUT); pin(0).set_name("Aclr", 0);
+ pin(1).set_dir(NetObj::Link::INPUT); pin(1).set_name("Clock", 0);
+
+
+ unsigned p = 2;
+ for (unsigned idx = 0 ; idx < width_r_ ; idx += 1, p += 1) {
+ pin(p).set_dir(NetObj::Link::OUTPUT);
+ pin(p).set_name("Result", idx);
+ }
+ for (unsigned idx = 0 ; idx < width_a_ ; idx += 1, p += 1) {
+ pin(p).set_dir(NetObj::Link::INPUT);
+ pin(p).set_name("DataA", idx);
+ }
+ for (unsigned idx = 0 ; idx < width_b_ ; idx += 1, p += 1) {
+ pin(p).set_dir(NetObj::Link::INPUT);
+ pin(p).set_name("DataB", idx);
+ }
+ for (unsigned idx = 0 ; idx < width_s_ ; idx += 1, p += 1) {
+ pin(p).set_dir(NetObj::Link::INPUT);
+ pin(p).set_name("Sum", idx);
+ }
+}
+
+NetMult::~NetMult()
+{
+}
+
+unsigned NetMult::width_r() const
+{
+ return width_r_;
+}
+
+unsigned NetMult::width_a() const
+{
+ return width_a_;
+}
+
+unsigned NetMult::width_b() const
+{
+ return width_b_;
+}
+
+unsigned NetMult::width_s() const
+{
+ return width_s_;
+}
+
+NetObj::Link& NetMult::pin_Aclr()
+{
+ return pin(0);
+}
+
+const NetObj::Link& NetMult::pin_Aclr() const
+{
+ return pin(0);
+}
+
+NetObj::Link& NetMult::pin_Clock()
+{
+ return pin(1);
+}
+
+const NetObj::Link& NetMult::pin_Clock() const
+{
+ return pin(1);
+}
+
+NetObj::Link& NetMult::pin_Result(unsigned idx)
+{
+ assert(idx < width_r_);
+ return pin(idx+2);
+}
+
+const NetObj::Link& NetMult::pin_Result(unsigned idx) const
+{
+ assert(idx < width_r_);
+ return pin(idx+2);
+}
+
+NetObj::Link& NetMult::pin_DataA(unsigned idx)
+{
+ assert(idx < width_a_);
+ return pin(idx+2+width_r_);
+}
+
+const NetObj::Link& NetMult::pin_DataA(unsigned idx) const
+{
+ assert(idx < width_a_);
+ return pin(idx+2+width_r_);
+}
+
+NetObj::Link& NetMult::pin_DataB(unsigned idx)
+{
+ assert(idx < width_b_);
+ return pin(idx+2+width_r_+width_a_);
+}
+
+const NetObj::Link& NetMult::pin_DataB(unsigned idx) const
+{
+ assert(idx < width_b_);
+ return pin(idx+2+width_r_+width_a_);
+}
+
+NetObj::Link& NetMult::pin_Sum(unsigned idx)
+{
+ assert(idx < width_s_);
+ return pin(idx+2+width_r_+width_a_+width_b_);
+}
+
+const NetObj::Link& NetMult::pin_Sum(unsigned idx) const
+{
+ assert(idx < width_s_);
+ return pin(idx+2+width_r_+width_a_+width_b_);
+}
+
/*
* The NetMux class represents an LPM_MUX device. The pinout is assigned
* like so:
@@ -1798,6 +1918,23 @@ NetEBLogic* NetEBLogic::dup_expr() const
return result;
}
+NetEBMult::NetEBMult(char op, NetExpr*l, NetExpr*r)
+: NetEBinary(op, l, r)
+{
+ expr_width(l->expr_width() + r->expr_width());
+}
+
+NetEBMult::~NetEBMult()
+{
+}
+
+NetEBMult* NetEBMult::dup_expr() const
+{
+ NetEBMult*result = new NetEBMult(op_, left_->dup_expr(),
+ right_->dup_expr());
+ return result;
+}
+
NetEBShift::NetEBShift(char op, NetExpr*l, NetExpr*r)
: NetEBinary(op, l, r)
{
@@ -2775,6 +2912,9 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*))
/*
* $Log: netlist.cc,v $
+ * Revision 1.104 2000/01/13 03:35:35 steve
+ * Multiplication all the way to simulation.
+ *
* Revision 1.103 2000/01/10 01:35:24 steve
* Elaborate parameters afer binding of overrides.
*
View
72 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.107 2000/01/10 01:35:24 steve Exp $"
+#ident "$Id: netlist.h,v 1.108 2000/01/13 03:35:35 steve Exp $"
#endif
/*
@@ -488,6 +488,56 @@ class NetMemory {
};
/*
+ * This class implements the LPM_MULT component as described in the
+ * EDIF LPM Version 2 1 0 standard. It is used as a structural
+ * implementation of the * operator. The device has inputs DataA and
+ * DataB that can have independent widths, as can the result. If the
+ * result is smaller then the widths of a and b together, then the
+ * device drops the least significant bits of the product.
+ */
+class NetMult : public NetNode {
+
+ public:
+ NetMult(const string&n, unsigned width, unsigned wa, unsigned wb,
+ unsigned width_s =0);
+ ~NetMult();
+
+ // Get the width of the device bussed inputs. There are these
+ // parameterized widths:
+ unsigned width_r() const; // Result
+ unsigned width_a() const; // DataA
+ unsigned width_b() const; // DataB
+ unsigned width_s() const; // Sum (my be 0)
+
+ NetObj::Link& pin_Aclr();
+ NetObj::Link& pin_Clock();
+
+ NetObj::Link& pin_DataA(unsigned idx);
+ NetObj::Link& pin_DataB(unsigned idx);
+ NetObj::Link& pin_Result(unsigned idx);
+ NetObj::Link& pin_Sum(unsigned idx);
+
+ const NetObj::Link& pin_Aclr() const;
+ const NetObj::Link& pin_Clock() const;
+
+ const NetObj::Link& pin_DataA(unsigned idx) const;
+ const NetObj::Link& pin_DataB(unsigned idx) const;
+ const NetObj::Link& pin_Result(unsigned idx) const;
+ const NetObj::Link& pin_Sum(unsigned idx) const;
+
+ virtual void dump_node(ostream&, unsigned ind) const;
+ virtual void emit_node(ostream&, struct target_t*) const;
+ virtual void functor_node(Design*des, functor_t*fun);
+
+ private:
+ unsigned width_r_;
+ unsigned width_a_;
+ unsigned width_b_;
+ unsigned width_s_;
+};
+
+
+/*
* This class represents an LPM_MUX device. This device has some
* number of Result points (the width of the device) and some number
* of input choices. There is also a selector of some width. The
@@ -1584,6 +1634,23 @@ class NetEBLogic : public NetEBinary {
/*
+ * Support the binary multiplication (*) operator.
+ */
+class NetEBMult : public NetEBinary {
+
+ public:
+ NetEBMult(char op, NetExpr*l, NetExpr*r);
+ ~NetEBMult();
+
+ virtual bool set_width(unsigned w);
+ virtual NetEBMult* dup_expr() const;
+ virtual NetEConst* eval_tree();
+
+ private:
+};
+
+
+/*
* The binary logical operators are those that return boolean
* results. The supported operators are:
*
@@ -2084,6 +2151,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
+ * Revision 1.108 2000/01/13 03:35:35 steve
+ * Multiplication all the way to simulation.
+ *
* Revision 1.107 2000/01/10 01:35:24 steve
* Elaborate parameters afer binding of overrides.
*
View
15 set_width.cc
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
-#ident "$Id: set_width.cc,v 1.7 2000/01/01 19:56:51 steve Exp $"
+#ident "$Id: set_width.cc,v 1.8 2000/01/13 03:35:35 steve Exp $"
#endif
/*
@@ -126,7 +126,6 @@ bool NetEBBits::set_width(unsigned w)
*/
bool NetEBComp::set_width(unsigned w)
{
- bool flag = true;
return (w == 1);
}
@@ -140,6 +139,15 @@ bool NetEBLogic::set_width(unsigned w)
}
/*
+ * There is nothing we can do to the operands of a multiply to make it
+ * confirm to the requested width. Force the context to pad or truncate.
+ */
+bool NetEBMult::set_width(unsigned w)
+{
+ return w == expr_width();
+}
+
+/*
* The shift operator allows the shift amount to have its own
* natural width. The width of the operator result is the width of the
* left operand, the value that is to be shifted.
@@ -266,6 +274,9 @@ bool NetEUnary::set_width(unsigned w)
/*
* $Log: set_width.cc,v $
+ * Revision 1.8 2000/01/13 03:35:35 steve
+ * Multiplication all the way to simulation.
+ *
* Revision 1.7 2000/01/01 19:56:51 steve
* Properly expand/shrink constants in expressions.
*
View
35 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.94 2000/01/08 03:09:14 steve Exp $"
+#ident "$Id: t-vvm.cc,v 1.95 2000/01/13 03:35:35 steve Exp $"
#endif
# include <iostream>
@@ -64,6 +64,7 @@ class target_vvm : public target_t {
virtual void lpm_clshift(ostream&os, const NetCLShift*);
virtual void lpm_compare(ostream&os, const NetCompare*);
virtual void lpm_ff(ostream&os, const NetFF*);
+ virtual void lpm_mult(ostream&os, const NetMult*);
virtual void lpm_mux(ostream&os, const NetMux*);
virtual void lpm_ram_dq(ostream&os, const NetRamDq*);
@@ -452,6 +453,18 @@ void vvm_proc_rval::expr_binary(const NetEBinary*expr)
os_ << setw(indent_) << "" << result << " = vvm_binop_xor("
<< lres << "," << rres << ");" << endl;
break;
+ case '*':
+ os_ << setw(indent_) << "" << "vvm_binop_mult(" << result
+ << "," << lres << "," << rres << ");" << endl;
+ break;
+ case '/':
+ os_ << setw(indent_) << "" << result << " = vvm_binop_idiv("
+ << lres << "," << rres << ");" << endl;
+ break;
+ case '%':
+ os_ << setw(indent_) << "" << result << " = vvm_binop_imod("
+ << lres << "," << rres << ");" << endl;
+ break;
default:
cerr << "vvm: Unhandled binary op `" << expr->op() << "': "
<< *expr << endl;
@@ -1017,6 +1030,23 @@ void target_vvm::lpm_ff(ostream&os, const NetFF*gate)
}
}
+void target_vvm::lpm_mult(ostream&os, const NetMult*mul)
+{
+ string mname = mangle(mul->name());
+ os << "static vvm_mult " << mname << "(" << mul->width_r() <<
+ "," << mul->width_a() << "," << mul->width_b() << "," <<
+ mul->width_s() << ");" << endl;
+
+ // Write the output functions for the multiplier device.
+ for (unsigned idx = 0 ; idx < mul->width_r() ; idx += 1) {
+ unsigned pin = mul->pin_Result(idx).get_pin();
+ string outfun = defn_gate_outputfun_(os, mul, pin);
+ init_code << " " << mangle(mul->name()) <<
+ ".config_rout(" << idx << ", &" << outfun << ");" << endl;
+ emit_gate_outputfun_(mul, pin);
+ }
+}
+
void target_vvm::lpm_mux(ostream&os, const NetMux*mux)
{
string mname = mangle(mux->name());
@@ -1993,6 +2023,9 @@ extern const struct target tgt_vvm = {
};
/*
* $Log: t-vvm.cc,v $
+ * Revision 1.95 2000/01/13 03:35:35 steve
+ * Multiplication all the way to simulation.
+ *
* Revision 1.94 2000/01/08 03:09:14 steve
* Non-blocking memory writes.
*
View
11 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.28 1999/11/28 23:42:03 steve Exp $"
+#ident "$Id: target.cc,v 1.29 2000/01/13 03:35:35 steve Exp $"
#endif
# include "target.h"
@@ -97,6 +97,12 @@ void target_t::lpm_ff(ostream&, const NetFF*)
"Unhandled NetFF." << endl;
}
+void target_t::lpm_mult(ostream&, const NetMult*)
+{
+ cerr << "target (" << typeid(*this).name() << "): "
+ "Unhandled NetMult." << endl;
+}
+
void target_t::lpm_mux(ostream&, const NetMux*)
{
cerr << "target (" << typeid(*this).name() << "): "
@@ -308,6 +314,9 @@ void expr_scan_t::expr_binary(const NetEBinary*ex)
/*
* $Log: target.cc,v $
+ * Revision 1.29 2000/01/13 03:35:35 steve
+ * Multiplication all the way to simulation.
+ *
* Revision 1.28 1999/11/28 23:42:03 steve
* NetESignal object no longer need to be NetNode
* objects. Let them keep a pointer to NetNet objects.
View
6 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.27 1999/11/28 23:42:03 steve Exp $"
+#ident "$Id: target.h,v 1.28 2000/01/13 03:35:35 steve Exp $"
#endif
# include "netlist.h"
@@ -74,6 +74,7 @@ struct target_t {
virtual void lpm_clshift(ostream&os, const NetCLShift*);
virtual void lpm_compare(ostream&os, const NetCompare*);
virtual void lpm_ff(ostream&os, const NetFF*);
+ virtual void lpm_mult(ostream&os, const NetMult*);
virtual void lpm_mux(ostream&os, const NetMux*);
virtual void lpm_ram_dq(ostream&os, const NetRamDq*);
@@ -146,6 +147,9 @@ extern const struct target *target_table[];
/*
* $Log: target.h,v $
+ * Revision 1.28 2000/01/13 03:35:35 steve
+ * Multiplication all the way to simulation.
+ *
* Revision 1.27 1999/11/28 23:42:03 steve
* NetESignal object no longer need to be NetNode
* objects. Let them keep a pointer to NetNet objects.
View
6 vvm/Makefile.in
@@ -18,7 +18,7 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
-#ident "$Id: Makefile.in,v 1.15 1999/12/12 19:47:54 steve Exp $"
+#ident "$Id: Makefile.in,v 1.16 2000/01/13 03:35:35 steve Exp $"
#
#
SHELL = /bin/sh
@@ -58,8 +58,8 @@ all: libvvm.a
$(CC) -Wall $(CFLAGS) -MD -c $< -o $*.o
mv $*.d dep
-O = vvm_bit.o vvm_calltf.o vvm_event.o vvm_gates.o vvm_pevent.o \
-vvm_thread.o vpip.o
+O = vvm_bit.o vvm_calltf.o vvm_event.o vvm_gates.o vvm_mult.o \
+vvm_pevent.o vvm_thread.o vpip.o
P = vpi_callback.o \
vpi_const.o vpi_iter.o vpi_memory.o vpi_null.o \
View
23 vvm/vvm_func.h
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
-#ident "$Id: vvm_func.h,v 1.16 1999/12/02 03:36:01 steve Exp $"
+#ident "$Id: vvm_func.h,v 1.17 2000/01/13 03:35:35 steve Exp $"
#endif
# include "vvm.h"
@@ -196,6 +196,24 @@ vvm_bitset_t<WIDTH> vvm_binop_minus(const vvm_bitset_t<WIDTH>&l,
}
/*
+ * The multiply binary operator takes an A and B parameter and returns
+ * the result in the vpip_bit_t array. The template form arranges for
+ * the right parameters to be passed to the extern form.
+ */
+extern void vvm_binop_mult(vpip_bit_t*res, unsigned nres,
+ const vpip_bit_t*a, unsigned na,
+ const vpip_bit_t*b, unsigned nb);
+
+template <unsigned WR, unsigned WA, unsigned WB>
+void vvm_binop_mult(vvm_bitset_t<WR>&r,
+ const vvm_bitset_t<WA>&a,
+ const vvm_bitset_t<WB>&b)
+{
+ vvm_binop_mult(r.bits, WR, a.bits, WA, b.bits, WB);
+}
+
+
+/*
* The binary ^ (xor) operator is a bitwise XOR of equal width inputs
* to generate the corresponsing output.
*/
@@ -608,6 +626,9 @@ vvm_bitset_t<W> vvm_ternary(vpip_bit_t c, const vvm_bitset_t<W>&t,
/*
* $Log: vvm_func.h,v $
+ * Revision 1.17 2000/01/13 03:35:35 steve
+ * Multiplication all the way to simulation.
+ *
* Revision 1.16 1999/12/02 03:36:01 steve
* shiftl and shiftr take unsized second parameter.
*
View
35 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.34 1999/12/19 20:57:07 steve Exp $"
+#ident "$Id: vvm_gates.h,v 1.35 2000/01/13 03:35:35 steve Exp $"
#endif
# include "vvm.h"
@@ -409,6 +409,36 @@ template <unsigned WIDTH> class vvm_ff {
};
/*
+ * This class behaves like a combinational multiplier. The device
+ * behaves like the LPM_MULT device.
+ */
+class vvm_mult {
+
+ public:
+ explicit vvm_mult(unsigned rwid, unsigned awid,
+ unsigned bwid, unsigned swid);
+ ~vvm_mult();
+
+ void init_DataA(unsigned idx, vpip_bit_t val);
+ void init_DataB(unsigned idx, vpip_bit_t val);
+ void init_Sum(unsigned idx, vpip_bit_t val);
+
+ void set_DataA(unsigned idx, vpip_bit_t val);
+ void set_DataB(unsigned idx, vpip_bit_t val);
+ void set_Sum(unsigned idx, vpip_bit_t val);
+
+ void config_rout(unsigned idx, vvm_out_event::action_t o);
+
+ private:
+ unsigned rwid_;
+ unsigned awid_;
+ unsigned bwid_;
+ unsigned swid_;
+ vpip_bit_t*bits_;
+ vvm_out_event::action_t*out_;
+};
+
+/*
* This class supports mux devices. The width is the width of the data
* (or bus) path, SIZE is the number of alternative inputs and SELWID
* is the size (in bits) of the selector input.
@@ -933,6 +963,9 @@ template <unsigned WIDTH> class vvm_pevent {
/*
* $Log: vvm_gates.h,v $
+ * Revision 1.35 2000/01/13 03:35:35 steve
+ * Multiplication all the way to simulation.
+ *
* Revision 1.34 1999/12/19 20:57:07 steve
* Proper init_ method prototype.
*
View
114 vvm/vvm_mult.cc
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2000 Stephen Williams (steve@icarus.com)
+ *
+ * This source code is free software; you can redistribute it
+ * and/or modify it in source code form under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+#if !defined(WINNT)
+#ident "$Id: vvm_mult.cc,v 1.1 2000/01/13 03:35:36 steve Exp $"
+#endif
+
+# include "vvm_gates.h"
+# include <assert.h>
+
+void vvm_binop_mult(vpip_bit_t*r, unsigned nr,
+ const vpip_bit_t*a, unsigned na,
+ const vpip_bit_t*b, unsigned nb)
+{
+ assert(nr >= (na+nb));
+
+ for (unsigned idx = 0 ; idx < nr ; idx += 1)
+ r[idx] = V0;
+
+ for (unsigned bdx = 0 ; bdx < nb ; bdx += 1) {
+ unsigned rdx = bdx;
+ vpip_bit_t c = V0;
+ for (unsigned idx = 0 ; idx < na ; idx += 1) {
+ r[rdx] = add_with_carry(r[rdx],a[idx]&b[bdx],c);
+ rdx += 1;
+ }
+ if (rdx < nr) r[rdx] = add_with_carry(r[rdx],c,c);
+ }
+}
+
+vvm_mult::vvm_mult(unsigned rwid, unsigned awid,
+ unsigned bwid, unsigned swid)
+: rwid_(rwid), awid_(awid), bwid_(bwid), swid_(swid)
+{
+ bits_ = new vpip_bit_t[rwid_+awid_+bwid_+swid_];
+ out_ = new vvm_out_event::action_t[rwid_];
+
+ for (unsigned idx = 0 ; idx < rwid_+awid_+bwid_+swid_ ; idx += 1)
+ bits_[idx] = Vx;
+
+ for (unsigned idx = 0 ; idx < rwid_ ; idx += 1)
+ out_[idx] = 0;
+}
+
+vvm_mult::~vvm_mult()
+{
+ delete[]bits_;
+ delete[]out_;
+}
+
+void vvm_mult::config_rout(unsigned idx, vvm_out_event::action_t o)
+{
+ assert(o);
+ assert(idx < rwid_);
+ out_[idx] = o;
+}
+
+void vvm_mult::init_DataA(unsigned idx, vpip_bit_t val)
+{
+ assert(idx < awid_);
+ bits_[rwid_+idx] = val;
+}
+
+void vvm_mult::set_DataA(unsigned idx, vpip_bit_t val)
+{
+ assert(idx < awid_);
+ bits_[rwid_+idx] = val;
+ vvm_binop_mult(bits_, rwid_,
+ bits_+rwid_, awid_,
+ bits_+rwid_+awid_, bwid_);
+ for (unsigned idx = 0 ; idx < rwid_ ; idx += 1)
+ if (out_[idx]) (out_[idx])(bits_[idx]);
+}
+
+void vvm_mult::init_DataB(unsigned idx, vpip_bit_t val)
+{
+ assert(idx < bwid_);
+ bits_[rwid_+awid_+idx] = val;
+}
+
+void vvm_mult::set_DataB(unsigned idx, vpip_bit_t val)
+{
+ assert(idx < bwid_);
+ bits_[rwid_+awid_+idx] = val;
+ vvm_binop_mult(bits_, rwid_,
+ bits_+rwid_, awid_,
+ bits_+rwid_+awid_, bwid_);
+ for (unsigned idx = 0 ; idx < rwid_ ; idx += 1)
+ if (out_[idx]) (out_[idx])(bits_[idx]);
+}
+
+
+/*
+ * $Log: vvm_mult.cc,v $
+ * Revision 1.1 2000/01/13 03:35:36 steve
+ * Multiplication all the way to simulation.
+ *
+ */
+

0 comments on commit aa8908c

Please sign in to comment.