Simplified NetMult and IVL_LPM_MULT.

This commit is contained in:
steve 2005-01-28 05:39:33 +00:00
parent 6be34bba4d
commit 99ace10774
6 changed files with 100 additions and 205 deletions

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: elab_net.cc,v 1.144 2005/01/22 18:16:00 steve Exp $"
#ident "$Id: elab_net.cc,v 1.145 2005/01/28 05:39:33 steve Exp $"
#endif
# include "config.h"
@ -972,40 +972,26 @@ NetNet* PEBinary::elaborate_net_mul_(Design*des, NetScope*scope,
unsigned rwidth = lwidth;
if (rwidth == 0) {
rwidth = lsig->pin_count() + rsig->pin_count();
lwidth = rwidth;
}
NetMult*mult = new NetMult(scope, scope->local_symbol(), rwidth,
lsig->pin_count(),
rsig->pin_count());
lsig->vector_width(),
rsig->vector_width());
mult->set_line(*this);
des->add_node(mult);
// The mult is signed if both its operands are signed.
mult->set_signed( lsig->get_signed() && rsig->get_signed() );
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));
connect(mult->pin_DataA(), lsig->pin(0));
connect(mult->pin_DataB(), rsig->pin(0));
if (lwidth == 0) lwidth = rwidth;
// Make a signal to carry the output from the multiply.
NetNet*osig = new NetNet(scope, scope->local_symbol(),
NetNet::IMPLICIT, lwidth);
NetNet::IMPLICIT, rwidth);
osig->local_flag(true);
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(scope, scope->local_symbol(),
verinum::V0);
des->add_node(tmp);
for (unsigned idx = cnt ; idx < osig->pin_count() ; idx += 1)
connect(osig->pin(idx), tmp->pin(0));
}
connect(mult->pin_Result(), osig->pin(0));
return osig;
}
@ -2451,6 +2437,9 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
/*
* $Log: elab_net.cc,v $
* Revision 1.145 2005/01/28 05:39:33 steve
* Simplified NetMult and IVL_LPM_MULT.
*
* Revision 1.144 2005/01/22 18:16:00 steve
* Remove obsolete NetSubnet class.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: expr_synth.cc,v 1.61 2005/01/16 04:20:32 steve Exp $"
#ident "$Id: expr_synth.cc,v 1.62 2005/01/28 05:39:33 steve Exp $"
#endif
# include "config.h"
@ -336,25 +336,21 @@ NetNet* NetEBMult::synthesize(Design*des)
NetMult*mult = new NetMult(scope, scope->local_symbol(),
expr_width(),
lsig->pin_count(),
rsig->pin_count());
lsig->vector_width(),
rsig->vector_width());
des->add_node(mult);
mult->set_signed( has_sign() );
mult->set_line(*this);
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));
connect(mult->pin_DataA(), lsig->pin(0));
connect(mult->pin_DataB(), rsig->pin(0));
NetNet*osig = new NetNet(scope, scope->local_symbol(),
NetNet::IMPLICIT, expr_width());
osig->local_flag(true);
for (unsigned idx = 0 ; idx < osig->pin_count() ; idx += 1)
connect(mult->pin_Result(idx), osig->pin(idx));
connect(mult->pin_Result(), osig->pin(0));
return osig;
}
@ -856,6 +852,9 @@ NetNet* NetESignal::synthesize(Design*des)
/*
* $Log: expr_synth.cc,v $
* Revision 1.62 2005/01/28 05:39:33 steve
* Simplified NetMult and IVL_LPM_MULT.
*
* Revision 1.61 2005/01/16 04:20:32 steve
* Implement LPM_COMPARE nodes as two-input vector functors.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: ivl_target.h,v 1.134 2005/01/24 05:28:30 steve Exp $"
#ident "$Id: ivl_target.h,v 1.135 2005/01/28 05:39:33 steve Exp $"
#endif
#ifdef __cplusplus
@ -748,6 +748,20 @@ extern const char* ivl_udp_name(ivl_udp_t net);
* the concatentation. The ivl_lpm_size function returns the number of
* inputs help by the device.
*
* - Multiply (IVL_LPM_MULT)
* The multiply takes two inputs and generates an output. Unlike other
* arithmetic nodes, the width only refers to the output. The inputs
* have independent widths, to reflect the arithmetic truth that the
* width of a general multiply is the sum of the widths of the
* inputs. In fact, the compiler doesn't assure that the widths of the
* inputs add up to the width of the output, but the possibility
* exists. It is *not* an error for the sum of the input widths to be
* more then the width of the output, although the possibility of
* overflow exists at run time.
*
* Multiply may be signed. If so, the output should be sign extended
* to fill in its result.
*
* - Part Select (IVL_LPM_PART_VP and IVL_LPM_PART_PV)
* There are two part select devices, one that extracts a part from a
* vector, and another that writes a part of a vector. The _VP is
@ -1444,6 +1458,9 @@ _END_DECL
/*
* $Log: ivl_target.h,v $
* Revision 1.135 2005/01/28 05:39:33 steve
* Simplified NetMult and IVL_LPM_MULT.
*
* Revision 1.134 2005/01/24 05:28:30 steve
* Remove the NetEBitSel and combine all bit/part select
* behavior into the NetESelect node and IVL_EX_SELECT

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: netlist.cc,v 1.233 2005/01/24 05:28:30 steve Exp $"
#ident "$Id: netlist.cc,v 1.234 2005/01/28 05:39:33 steve Exp $"
#endif
# include "config.h"
@ -1176,31 +1176,16 @@ const Link& NetDivide::pin_DataB(unsigned idx) const
}
NetMult::NetMult(NetScope*sc, perm_string n, unsigned wr,
unsigned wa, unsigned wb, unsigned ws)
: NetNode(sc, n, 2+wr+wa+wb+ws),
signed_(false), width_r_(wr), width_a_(wa), width_b_(wb), width_s_(ws)
unsigned wa, unsigned wb)
: NetNode(sc, n, 3),
signed_(false), width_r_(wr), width_a_(wa), width_b_(wb)
{
pin(0).set_dir(Link::INPUT); pin(0).set_name(perm_string::literal("Aclr"), 0);
pin(1).set_dir(Link::INPUT); pin(1).set_name(perm_string::literal("Clock"), 0);
unsigned p = 2;
for (unsigned idx = 0 ; idx < width_r_ ; idx += 1, p += 1) {
pin(p).set_dir(Link::OUTPUT);
pin(p).set_name(perm_string::literal("Result"), idx);
}
for (unsigned idx = 0 ; idx < width_a_ ; idx += 1, p += 1) {
pin(p).set_dir(Link::INPUT);
pin(p).set_name(perm_string::literal("DataA"), idx);
}
for (unsigned idx = 0 ; idx < width_b_ ; idx += 1, p += 1) {
pin(p).set_dir(Link::INPUT);
pin(p).set_name(perm_string::literal("DataB"), idx);
}
for (unsigned idx = 0 ; idx < width_s_ ; idx += 1, p += 1) {
pin(p).set_dir(Link::INPUT);
pin(p).set_name(perm_string::literal("Sum"), idx);
}
pin(0).set_dir(Link::OUTPUT);
pin(0).set_name(perm_string::literal("Result"), 0);
pin(1).set_dir(Link::INPUT);
pin(1).set_name(perm_string::literal("DataA"), 0);
pin(2).set_dir(Link::INPUT);
pin(2).set_name(perm_string::literal("DataB"), 0);
}
NetMult::~NetMult()
@ -1232,77 +1217,34 @@ unsigned NetMult::width_b() const
return width_b_;
}
unsigned NetMult::width_s() const
{
return width_s_;
}
Link& NetMult::pin_Aclr()
Link& NetMult::pin_Result()
{
return pin(0);
}
const Link& NetMult::pin_Aclr() const
const Link& NetMult::pin_Result() const
{
return pin(0);
}
Link& NetMult::pin_Clock()
Link& NetMult::pin_DataA()
{
return pin(1);
}
const Link& NetMult::pin_Clock() const
const Link& NetMult::pin_DataA() const
{
return pin(1);
}
Link& NetMult::pin_Result(unsigned idx)
Link& NetMult::pin_DataB()
{
assert(idx < width_r_);
return pin(idx+2);
return pin(2);
}
const Link& NetMult::pin_Result(unsigned idx) const
const Link& NetMult::pin_DataB() const
{
assert(idx < width_r_);
return pin(idx+2);
}
Link& NetMult::pin_DataA(unsigned idx)
{
assert(idx < width_a_);
return pin(idx+2+width_r_);
}
const Link& NetMult::pin_DataA(unsigned idx) const
{
assert(idx < width_a_);
return pin(idx+2+width_r_);
}
Link& NetMult::pin_DataB(unsigned idx)
{
assert(idx < width_b_);
return pin(idx+2+width_r_+width_a_);
}
const Link& NetMult::pin_DataB(unsigned idx) const
{
assert(idx < width_b_);
return pin(idx+2+width_r_+width_a_);
}
Link& NetMult::pin_Sum(unsigned idx)
{
assert(idx < width_s_);
return pin(idx+2+width_r_+width_a_+width_b_);
}
const Link& NetMult::pin_Sum(unsigned idx) const
{
assert(idx < width_s_);
return pin(idx+2+width_r_+width_a_+width_b_);
return pin(2);
}
/*
@ -2307,6 +2249,9 @@ const NetProc*NetTaskDef::proc() const
/*
* $Log: netlist.cc,v $
* Revision 1.234 2005/01/28 05:39:33 steve
* Simplified NetMult and IVL_LPM_MULT.
*
* Revision 1.233 2005/01/24 05:28:30 steve
* Remove the NetEBitSel and combine all bit/part select
* behavior into the NetESelect node and IVL_EX_SELECT

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: netlist.h,v 1.329 2005/01/24 05:28:31 steve Exp $"
#ident "$Id: netlist.h,v 1.330 2005/01/28 05:39:33 steve Exp $"
#endif
/*
@ -796,18 +796,19 @@ 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.
* This class implements a basic LPM_MULT combinational multiplier. It
* is used as a structural representation of the * operator. The
* device has inputs A and B and output Result all with independent
* widths.
*
* NOTE: Check this width thing. I think that the independence of the
* widths is not necessary or even useful.
*/
class NetMult : public NetNode {
public:
NetMult(NetScope*sc, perm_string n, unsigned width,
unsigned wa, unsigned wb, unsigned width_s =0);
unsigned wa, unsigned wb);
~NetMult();
bool get_signed() const;
@ -818,23 +819,14 @@ class NetMult : public NetNode {
unsigned width_r() const; // Result
unsigned width_a() const; // DataA
unsigned width_b() const; // DataB
unsigned width_s() const; // Sum (my be 0)
Link& pin_Aclr();
Link& pin_Clock();
Link& pin_DataA();
Link& pin_DataB();
Link& pin_Result();
Link& pin_DataA(unsigned idx);
Link& pin_DataB(unsigned idx);
Link& pin_Result(unsigned idx);
Link& pin_Sum(unsigned idx);
const Link& pin_Aclr() const;
const Link& pin_Clock() const;
const Link& pin_DataA(unsigned idx) const;
const Link& pin_DataB(unsigned idx) const;
const Link& pin_Result(unsigned idx) const;
const Link& pin_Sum(unsigned idx) const;
const Link& pin_DataA() const;
const Link& pin_DataB() const;
const Link& pin_Result() const;
virtual void dump_node(ostream&, unsigned ind) const;
virtual bool emit_node(struct target_t*) const;
@ -845,7 +837,6 @@ class NetMult : public NetNode {
unsigned width_r_;
unsigned width_a_;
unsigned width_b_;
unsigned width_s_;
};
@ -3376,6 +3367,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
* Revision 1.330 2005/01/28 05:39:33 steve
* Simplified NetMult and IVL_LPM_MULT.
*
* Revision 1.329 2005/01/24 05:28:31 steve
* Remove the NetEBitSel and combine all bit/part select
* behavior into the NetESelect node and IVL_EX_SELECT

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: t-dll.cc,v 1.136 2005/01/22 01:06:55 steve Exp $"
#ident "$Id: t-dll.cc,v 1.137 2005/01/28 05:39:33 steve Exp $"
#endif
# include "config.h"
@ -1136,20 +1136,7 @@ void dll_target::lpm_add_sub(const NetAddSub*net)
/* If the carry output is connected, then connect the extra Q
pin to the carry nexus and zero the a and b inputs. */
if (net->pin_Cout().is_linked()) {
#if 0
unsigned carry = obj->u_.arith.width - 1;
const Nexus*nex = net->pin_Cout().nexus();
assert(nex->t_cookie());
obj->u_.arith.q[carry] = (ivl_nexus_t) nex->t_cookie();
nexus_lpm_add(obj->u_.arith.q[carry], obj, 0,
IVL_DR_STRONG, IVL_DR_STRONG);
obj->u_.arith.a[carry] = 0;
obj->u_.arith.b[carry] = 0;
#else
cerr << "XXXX: t-dll.cc: Forgot how to connect cout." << endl;
#endif
}
scope_add_lpm(obj->scope, obj);
@ -1700,6 +1687,9 @@ void dll_target::lpm_ram_dq(const NetRamDq*net)
}
}
/*
* Make the NetMult object into an IVL_LPM_MULT node.
*/
void dll_target::lpm_mult(const NetMult*net)
{
ivl_lpm_t obj = new struct ivl_lpm_s;
@ -1713,69 +1703,27 @@ void dll_target::lpm_mult(const NetMult*net)
obj->u_.arith.width = wid;
#if 0
obj->u_.arith.q = new ivl_nexus_t[3 * obj->u_.arith.width];
obj->u_.arith.a = obj->u_.arith.q + obj->u_.arith.width;
obj->u_.arith.b = obj->u_.arith.a + obj->u_.arith.width;
const Nexus*nex;
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
const Nexus*nex;
nex = net->pin_Result().nexus();
assert(nex->t_cookie());
nex = net->pin_Result(idx).nexus();
assert(nex->t_cookie());
obj->u_.arith.q = (ivl_nexus_t) nex->t_cookie();
nexus_lpm_add(obj->u_.arith.q, obj, 0, IVL_DR_STRONG, IVL_DR_STRONG);
obj->u_.arith.q[idx] = (ivl_nexus_t) nex->t_cookie();
nexus_lpm_add(obj->u_.arith.q[idx], obj, 0,
IVL_DR_STRONG, IVL_DR_STRONG);
nex = net->pin_DataA().nexus();
assert(nex->t_cookie());
if (idx < net->width_a()) {
nex = net->pin_DataA(idx).nexus();
assert(nex);
assert(nex->t_cookie());
obj->u_.arith.a = (ivl_nexus_t) nex->t_cookie();
nexus_lpm_add(obj->u_.arith.a, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ);
obj->u_.arith.a[idx] = (ivl_nexus_t) nex->t_cookie();
nexus_lpm_add(obj->u_.arith.a[idx], obj, 0,
IVL_DR_HiZ, IVL_DR_HiZ);
nex = net->pin_DataB().nexus();
assert(nex->t_cookie());
} else if (net->get_signed()) {
/* Beyond the width of input a, but if the mult is
signed, then sign extend the input. */
nex = net->pin_DataA(net->width_a()-1).nexus();
obj->u_.arith.a[idx] = (ivl_nexus_t) nex->t_cookie();
nexus_lpm_add(obj->u_.arith.a[idx], obj, 0,
IVL_DR_HiZ, IVL_DR_HiZ);
} else {
obj->u_.arith.a[idx] = 0;
}
obj->u_.arith.b = (ivl_nexus_t) nex->t_cookie();
nexus_lpm_add(obj->u_.arith.b, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ);
if (idx < net->width_b()) {
nex = net->pin_DataB(idx).nexus();
assert(nex);
assert(nex->t_cookie());
obj->u_.arith.b[idx] = (ivl_nexus_t) nex->t_cookie();
nexus_lpm_add(obj->u_.arith.b[idx], obj, 0,
IVL_DR_HiZ, IVL_DR_HiZ);
} else if (net->get_signed()) {
/* Beyond the width of input b, but if the mult is
signed, then sign extend the input. */
nex = net->pin_DataB(net->width_b()-1).nexus();
obj->u_.arith.b[idx] = (ivl_nexus_t) nex->t_cookie();
nexus_lpm_add(obj->u_.arith.b[idx], obj, 0,
IVL_DR_HiZ, IVL_DR_HiZ);
} else {
obj->u_.arith.b[idx] = 0;
}
}
#else
cerr << "XXXX: t-dll.cc: Forgot how to handle lpm_mult." << endl;
#endif
scope_add_lpm(obj->scope, obj);
}
@ -2226,6 +2174,9 @@ extern const struct target tgt_dll = { "dll", &dll_target_obj };
/*
* $Log: t-dll.cc,v $
* Revision 1.137 2005/01/28 05:39:33 steve
* Simplified NetMult and IVL_LPM_MULT.
*
* Revision 1.136 2005/01/22 01:06:55 steve
* Change case compare from logic to an LPM node.
*