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
*/
#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 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.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 File

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

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.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 File

@ -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 File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: functor.cc,v 1.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 File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: functor.h,v 1.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 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.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 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.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
/*
@ -487,6 +487,56 @@ class NetMemory {
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
* 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
* 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 File

@ -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);
}
@ -139,6 +138,15 @@ bool NetEBLogic::set_width(unsigned w)
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
* 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 $
* 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 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.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 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.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 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.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 File

@ -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 File

@ -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"
@ -195,6 +195,24 @@ vvm_bitset_t<WIDTH> vvm_binop_minus(const vvm_bitset_t<WIDTH>&l,
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
* 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 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.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"
@ -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
* (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 $
* 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.
*

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