Multiplication all the way to simulation.

This commit is contained in:
steve 2000-01-13 03:35:35 +00:00
parent 3d1ffced57
commit aa8908c52f
18 changed files with 570 additions and 34 deletions

10
PExpr.h
View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
# include <string> # include <string>
@ -264,6 +264,11 @@ class PEBinary : public PExpr {
unsigned long rise, unsigned long rise,
unsigned long fall, unsigned long fall,
unsigned long decay) const; 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, NetNet* elaborate_net_shift_(Design*des, const string&path,
unsigned lwidth, unsigned lwidth,
unsigned long rise, unsigned long rise,
@ -318,6 +323,9 @@ class PECallFunction : public PExpr {
/* /*
* $Log: PExpr.h,v $ * $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 * Revision 1.26 1999/12/16 03:46:39 steve
* Structural logical or. * Structural logical or.
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
/* /*
@ -142,8 +142,14 @@ void NetCLShift::dump_node(ostream&o, unsigned ind) const
void NetCompare::dump_node(ostream&o, unsigned ind) const void NetCompare::dump_node(ostream&o, unsigned ind) const
{ {
o << setw(ind) << "" << "LPM_COMPARE (NetCompare): " << o << setw(ind) << "" << "LPM_COMPARE (NetCompare): " << name() << endl;
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_node_pins(o, ind+4);
dump_obj_attr(o, ind+4); dump_obj_attr(o, ind+4);
} }
@ -865,6 +871,9 @@ void Design::dump(ostream&o) const
/* /*
* $Log: design_dump.cc,v $ * $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 * Revision 1.65 2000/01/10 01:35:23 steve
* Elaborate parameters afer binding of overrides. * Elaborate parameters afer binding of overrides.
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
@ -68,6 +68,11 @@ NetExpr* PEBinary::elaborate_expr(Design*des, const string&path) const
tmp->set_line(*this); tmp->set_line(*this);
break; break;
case '*':
tmp = new NetEBMult(op_, lp, rp);
tmp->set_line(*this);
break;
case 'l': case 'l':
case 'r': case 'r':
tmp = new NetEBShift(op_, lp, rp); 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 $ * $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 * Revision 1.14 2000/01/01 06:18:00 steve
* Handle synthesis of concatenation. * Handle synthesis of concatenation.
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
# include "PExpr.h" # include "PExpr.h"
@ -35,6 +35,10 @@ NetNet* PEBinary::elaborate_net(Design*des, const string&path,
unsigned long decay) const unsigned long decay) const
{ {
switch (op_) { switch (op_) {
case '*':
//case '/':
//case '%':
return elaborate_net_mul_(des, path, width, rise, fall, decay);
case '+': case '+':
case '-': case '-':
return elaborate_net_add_(des, path, width, rise, fall, decay); 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; 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(); unsigned dwidth = lsig->pin_count();
if (rsig->pin_count() > dwidth) dwidth = rsig->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; 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, NetNet* PEBinary::elaborate_net_shift_(Design*des, const string&path,
unsigned lwidth, unsigned lwidth,
unsigned long rise, unsigned long rise,
@ -1224,6 +1262,9 @@ NetNet* PEUnary::elaborate_net(Design*des, const string&path,
/* /*
* $Log: elab_net.cc,v $ * $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 * Revision 1.18 2000/01/11 04:20:57 steve
* Elaborate net widths of constants to as small * Elaborate net widths of constants to as small
* as is possible, obeying context constraints. * as is possible, obeying context constraints.

10
emit.cc
View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
/* /*
@ -85,6 +85,11 @@ void NetFF::emit_node(ostream&o, struct target_t*tgt) const
tgt->lpm_ff(o, this); 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 void NetMux::emit_node(ostream&o, struct target_t*tgt) const
{ {
tgt->lpm_mux(o, this); tgt->lpm_mux(o, this);
@ -389,6 +394,9 @@ bool emit(ostream&o, const Design*des, const char*type)
/* /*
* $Log: emit.cc,v $ * $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 * Revision 1.31 1999/11/28 23:42:02 steve
* NetESignal object no longer need to be NetNode * NetESignal object no longer need to be NetNode
* objects. Let them keep a pointer to NetNet objects. * 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 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
# include "netlist.h" # include "netlist.h"
@ -138,6 +138,12 @@ NetEConst* NetEBLogic::eval_tree()
return 0; return 0;
} }
NetEConst* NetEBMult::eval_tree()
{
eval_sub_tree_();
return 0;
}
/* /*
* Evaluate the shift operator if possible. For this to work, both * Evaluate the shift operator if possible. For this to work, both
* operands must be constant. * operands must be constant.
@ -262,6 +268,9 @@ NetExpr* NetEParam::eval_tree()
/* /*
* $Log: eval_tree.cc,v $ * $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 * Revision 1.6 1999/10/22 23:57:53 steve
* do the <= in bits, not numbers. * do the <= in bits, not numbers.
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
# include "functor.h" # 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) void Design::functor(functor_t*fun)
{ {
// apply to signals // apply to signals
@ -107,6 +111,11 @@ void NetLogic::functor_node(Design*des, functor_t*fun)
fun->lpm_logic(des, this); 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() proc_match_t::~proc_match_t()
{ {
} }
@ -158,6 +167,9 @@ int NetPEvent::match_proc(proc_match_t*that)
/* /*
* $Log: functor.cc,v $ * $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 * Revision 1.9 2000/01/02 17:57:20 steve
* Handle nodes running out during node scan. * Handle nodes running out during node scan.
* *

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
/* /*
@ -53,6 +53,9 @@ struct functor_t {
/* Handle LPM combinational logic devices. */ /* Handle LPM combinational logic devices. */
virtual void lpm_logic(class Design*des, class NetLogic*); 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 { struct proc_match_t {
@ -67,6 +70,9 @@ struct proc_match_t {
/* /*
* $Log: functor.h,v $ * $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 * Revision 1.6 1999/12/30 04:19:12 steve
* Propogate constant 0 in low bits of adders. * Propogate constant 0 in low bits of adders.
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
# include <cassert> # include <cassert>
@ -932,6 +932,126 @@ const NetObj::Link& NetCompare::pin_DataB(unsigned idx) const
return pin(8+width_+idx); 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 * The NetMux class represents an LPM_MUX device. The pinout is assigned
* like so: * like so:
@ -1798,6 +1918,23 @@ NetEBLogic* NetEBLogic::dup_expr() const
return result; 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) NetEBShift::NetEBShift(char op, NetExpr*l, NetExpr*r)
: NetEBinary(op, l, r) : NetEBinary(op, l, r)
{ {
@ -2775,6 +2912,9 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*))
/* /*
* $Log: netlist.cc,v $ * $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 * Revision 1.103 2000/01/10 01:35:24 steve
* Elaborate parameters afer binding of overrides. * Elaborate parameters afer binding of overrides.
* *

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
/* /*
@ -487,6 +487,56 @@ class NetMemory {
NetRamDq* ram_list_; NetRamDq* ram_list_;
}; };
/*
* 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 * This class represents an LPM_MUX device. This device has some
* number of Result points (the width of the device) and some number * number of Result points (the width of the device) and some number
@ -1583,6 +1633,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 * The binary logical operators are those that return boolean
* results. The supported operators are: * results. The supported operators are:
@ -2084,6 +2151,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
/* /*
* $Log: netlist.h,v $ * $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 * Revision 1.107 2000/01/10 01:35:24 steve
* Elaborate parameters afer binding of overrides. * Elaborate parameters afer binding of overrides.
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
/* /*
@ -126,7 +126,6 @@ bool NetEBBits::set_width(unsigned w)
*/ */
bool NetEBComp::set_width(unsigned w) bool NetEBComp::set_width(unsigned w)
{ {
bool flag = true;
return (w == 1); return (w == 1);
} }
@ -139,6 +138,15 @@ bool NetEBLogic::set_width(unsigned w)
return (w == 1); return (w == 1);
} }
/*
* 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 * The shift operator allows the shift amount to have its own
* natural width. The width of the operator result is the width of the * natural width. The width of the operator result is the width of the
@ -266,6 +274,9 @@ bool NetEUnary::set_width(unsigned w)
/* /*
* $Log: set_width.cc,v $ * $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 * Revision 1.7 2000/01/01 19:56:51 steve
* Properly expand/shrink constants in expressions. * Properly expand/shrink constants in expressions.
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
# include <iostream> # include <iostream>
@ -64,6 +64,7 @@ class target_vvm : public target_t {
virtual void lpm_clshift(ostream&os, const NetCLShift*); virtual void lpm_clshift(ostream&os, const NetCLShift*);
virtual void lpm_compare(ostream&os, const NetCompare*); virtual void lpm_compare(ostream&os, const NetCompare*);
virtual void lpm_ff(ostream&os, const NetFF*); 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_mux(ostream&os, const NetMux*);
virtual void lpm_ram_dq(ostream&os, const NetRamDq*); 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(" os_ << setw(indent_) << "" << result << " = vvm_binop_xor("
<< lres << "," << rres << ");" << endl; << lres << "," << rres << ");" << endl;
break; 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: default:
cerr << "vvm: Unhandled binary op `" << expr->op() << "': " cerr << "vvm: Unhandled binary op `" << expr->op() << "': "
<< *expr << endl; << *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) void target_vvm::lpm_mux(ostream&os, const NetMux*mux)
{ {
string mname = mangle(mux->name()); string mname = mangle(mux->name());
@ -1993,6 +2023,9 @@ extern const struct target tgt_vvm = {
}; };
/* /*
* $Log: t-vvm.cc,v $ * $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 * Revision 1.94 2000/01/08 03:09:14 steve
* Non-blocking memory writes. * Non-blocking memory writes.
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
# include "target.h" # include "target.h"
@ -97,6 +97,12 @@ void target_t::lpm_ff(ostream&, const NetFF*)
"Unhandled NetFF." << endl; "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*) void target_t::lpm_mux(ostream&, const NetMux*)
{ {
cerr << "target (" << typeid(*this).name() << "): " cerr << "target (" << typeid(*this).name() << "): "
@ -308,6 +314,9 @@ void expr_scan_t::expr_binary(const NetEBinary*ex)
/* /*
* $Log: target.cc,v $ * $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 * Revision 1.28 1999/11/28 23:42:03 steve
* NetESignal object no longer need to be NetNode * NetESignal object no longer need to be NetNode
* objects. Let them keep a pointer to NetNet objects. * objects. Let them keep a pointer to NetNet objects.

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
# include "netlist.h" # include "netlist.h"
@ -74,6 +74,7 @@ struct target_t {
virtual void lpm_clshift(ostream&os, const NetCLShift*); virtual void lpm_clshift(ostream&os, const NetCLShift*);
virtual void lpm_compare(ostream&os, const NetCompare*); virtual void lpm_compare(ostream&os, const NetCompare*);
virtual void lpm_ff(ostream&os, const NetFF*); 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_mux(ostream&os, const NetMux*);
virtual void lpm_ram_dq(ostream&os, const NetRamDq*); virtual void lpm_ram_dq(ostream&os, const NetRamDq*);
@ -146,6 +147,9 @@ extern const struct target *target_table[];
/* /*
* $Log: target.h,v $ * $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 * Revision 1.27 1999/11/28 23:42:03 steve
* NetESignal object no longer need to be NetNode * NetESignal object no longer need to be NetNode
* objects. Let them keep a pointer to NetNet objects. * objects. Let them keep a pointer to NetNet objects.

View File

@ -18,7 +18,7 @@
# 59 Temple Place - Suite 330 # 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA # 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 SHELL = /bin/sh
@ -58,8 +58,8 @@ all: libvvm.a
$(CC) -Wall $(CFLAGS) -MD -c $< -o $*.o $(CC) -Wall $(CFLAGS) -MD -c $< -o $*.o
mv $*.d dep mv $*.d dep
O = vvm_bit.o vvm_calltf.o vvm_event.o vvm_gates.o vvm_pevent.o \ O = vvm_bit.o vvm_calltf.o vvm_event.o vvm_gates.o vvm_mult.o \
vvm_thread.o vpip.o vvm_pevent.o vvm_thread.o vpip.o
P = vpi_callback.o \ P = vpi_callback.o \
vpi_const.o vpi_iter.o vpi_memory.o vpi_null.o \ vpi_const.o vpi_iter.o vpi_memory.o vpi_null.o \

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
# include "vvm.h" # include "vvm.h"
@ -195,6 +195,24 @@ vvm_bitset_t<WIDTH> vvm_binop_minus(const vvm_bitset_t<WIDTH>&l,
return res; return res;
} }
/*
* 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 * The binary ^ (xor) operator is a bitwise XOR of equal width inputs
* to generate the corresponsing output. * 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 $ * $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 * Revision 1.16 1999/12/02 03:36:01 steve
* shiftl and shiftr take unsized second parameter. * 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 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
# include "vvm.h" # include "vvm.h"
@ -408,6 +408,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 * 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 * (or bus) path, SIZE is the number of alternative inputs and SELWID
@ -933,6 +963,9 @@ template <unsigned WIDTH> class vvm_pevent {
/* /*
* $Log: vvm_gates.h,v $ * $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 * Revision 1.34 1999/12/19 20:57:07 steve
* Proper init_ method prototype. * Proper init_ method prototype.
* *

114
vvm/vvm_mult.cc Normal file
View File

@ -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.
*
*/