diff --git a/elab_net.cc b/elab_net.cc index e175efeea..3ba0c72d4 100644 --- a/elab_net.cc +++ b/elab_net.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: elab_net.cc,v 1.110 2003/03/26 06:16:38 steve Exp $" +#ident "$Id: elab_net.cc,v 1.111 2003/03/29 05:51:25 steve Exp $" #endif # include "config.h" @@ -864,6 +864,8 @@ NetNet* PEBinary::elaborate_net_mul_(Design*des, NetScope*scope, rsig->pin_count()); des->add_node(mult); + 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) @@ -2279,6 +2281,9 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope, /* * $Log: elab_net.cc,v $ + * Revision 1.111 2003/03/29 05:51:25 steve + * Sign extend NetMult inputs if result is signed. + * * Revision 1.110 2003/03/26 06:16:38 steve * Some better internal error messages. * diff --git a/elaborate.cc b/elaborate.cc index 3b8281730..c0eccec2f 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: elaborate.cc,v 1.277 2003/03/26 06:16:38 steve Exp $" +#ident "$Id: elaborate.cc,v 1.278 2003/03/29 05:51:25 steve Exp $" #endif # include "config.h" @@ -159,19 +159,31 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const if (! need_driver_flag) { /* Don't need a driver, presumably because the r-value already has the needed drivers. Just - hook things up. */ + hook things up. If the r-value is too narrow + for the l-value, then sign extend it or zero + extend it, whichever makes sense. */ unsigned idx; for (idx = 0 ; idx < cnt; idx += 1) connect(lval->pin(idx), rid->pin(idx)); if (cnt < lval->pin_count()) { - verinum tmpv (0UL, lval->pin_count()-cnt); - NetConst*tmp = new NetConst(scope, - scope->local_symbol(), - tmpv); - des->add_node(tmp); - for (idx = cnt ; idx < lval->pin_count() ; idx += 1) - connect(lval->pin(idx), tmp->pin(idx-cnt)); + if (lval->get_signed() && rid->get_signed()) { + for (idx = cnt + ; idx < lval->pin_count() + ; idx += 1) + connect(lval->pin(idx), rid->pin(cnt-1)); + + } else { + verinum tmpv (0UL, lval->pin_count()-cnt); + NetConst*tmp = new NetConst(scope, + scope->local_symbol(), + tmpv); + des->add_node(tmp); + for (idx = cnt + ; idx < lval->pin_count() + ; idx += 1) + connect(lval->pin(idx), tmp->pin(idx-cnt)); + } } } else { @@ -192,15 +204,25 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const } if (cnt < lval->pin_count()) { - NetConst*dev = new NetConst(scope, - scope->local_symbol(), - verinum::V0); + if (lval->get_signed() && rid->get_signed()) { + for (idx = cnt + ; idx < lval->pin_count() + ; idx += 1) + connect(lval->pin(idx), lval->pin(cnt-1)); + + } else { + NetConst*dev = new NetConst(scope, + scope->local_symbol(), + verinum::V0); - des->add_node(dev); - dev->pin(0).drive0(drive0); - dev->pin(0).drive1(drive1); - for (idx = cnt ; idx < lval->pin_count() ; idx += 1) - connect(lval->pin(idx), dev->pin(0)); + des->add_node(dev); + dev->pin(0).drive0(drive0); + dev->pin(0).drive1(drive1); + for (idx = cnt + ; idx < lval->pin_count() + ; idx += 1) + connect(lval->pin(idx), dev->pin(0)); + } } } @@ -2499,6 +2521,9 @@ Design* elaborate(listroots) /* * $Log: elaborate.cc,v $ + * Revision 1.278 2003/03/29 05:51:25 steve + * Sign extend NetMult inputs if result is signed. + * * Revision 1.277 2003/03/26 06:16:38 steve * Some better internal error messages. * diff --git a/netlist.cc b/netlist.cc index 0cf6c8741..538a94909 100644 --- a/netlist.cc +++ b/netlist.cc @@ -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.209 2003/03/15 18:08:43 steve Exp $" +#ident "$Id: netlist.cc,v 1.210 2003/03/29 05:51:25 steve Exp $" #endif # include "config.h" @@ -1052,7 +1052,7 @@ const Link& NetDivide::pin_DataB(unsigned idx) const NetMult::NetMult(NetScope*sc, const string&n, unsigned wr, unsigned wa, unsigned wb, unsigned ws) : NetNode(sc, lex_strings.add(n.c_str()), 2+wr+wa+wb+ws), - width_r_(wr), width_a_(wa), width_b_(wb), width_s_(ws) + signed_(false), width_r_(wr), width_a_(wa), width_b_(wb), width_s_(ws) { pin(0).set_dir(Link::INPUT); pin(0).set_name("Aclr", 0); pin(1).set_dir(Link::INPUT); pin(1).set_name("Clock", 0); @@ -1081,6 +1081,16 @@ NetMult::~NetMult() { } +void NetMult::set_signed(bool flag) +{ + signed_ = flag; +} + +bool NetMult::get_signed() const +{ + return signed_; +} + unsigned NetMult::width_r() const { return width_r_; @@ -2141,6 +2151,9 @@ const NetProc*NetTaskDef::proc() const /* * $Log: netlist.cc,v $ + * Revision 1.210 2003/03/29 05:51:25 steve + * Sign extend NetMult inputs if result is signed. + * * Revision 1.209 2003/03/15 18:08:43 steve * Comparison operators do have defined width. * diff --git a/netlist.h b/netlist.h index cdf77492a..fc9692101 100644 --- a/netlist.h +++ b/netlist.h @@ -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.282 2003/03/15 18:08:43 steve Exp $" +#ident "$Id: netlist.h,v 1.283 2003/03/29 05:51:25 steve Exp $" #endif /* @@ -752,6 +752,9 @@ class NetMult : public NetNode { unsigned wa, unsigned wb, unsigned width_s =0); ~NetMult(); + bool get_signed() const; + void set_signed(bool); + // Get the width of the device bussed inputs. There are these // parameterized widths: unsigned width_r() const; // Result @@ -780,6 +783,7 @@ class NetMult : public NetNode { virtual void functor_node(Design*des, functor_t*fun); private: + bool signed_; unsigned width_r_; unsigned width_a_; unsigned width_b_; @@ -3240,6 +3244,9 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.283 2003/03/29 05:51:25 steve + * Sign extend NetMult inputs if result is signed. + * * Revision 1.282 2003/03/15 18:08:43 steve * Comparison operators do have defined width. * diff --git a/t-dll.cc b/t-dll.cc index 3ab5a9980..2be71908d 100644 --- a/t-dll.cc +++ b/t-dll.cc @@ -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.108 2003/03/10 23:40:53 steve Exp $" +#ident "$Id: t-dll.cc,v 1.109 2003/03/29 05:51:25 steve Exp $" #endif # include "config.h" @@ -1685,6 +1685,15 @@ void dll_target::lpm_mult(const NetMult*net) nexus_lpm_add(obj->u_.arith.a[idx], obj, 0, IVL_DR_HiZ, IVL_DR_HiZ); + } 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; } @@ -1699,6 +1708,15 @@ void dll_target::lpm_mult(const NetMult*net) 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; } @@ -2099,6 +2117,9 @@ extern const struct target tgt_dll = { "dll", &dll_target_obj }; /* * $Log: t-dll.cc,v $ + * Revision 1.109 2003/03/29 05:51:25 steve + * Sign extend NetMult inputs if result is signed. + * * Revision 1.108 2003/03/10 23:40:53 steve * Keep parameter constants for the ivl_target API. * diff --git a/tgt-stub/stub.c b/tgt-stub/stub.c index 5be0b38d1..7a44214af 100644 --- a/tgt-stub/stub.c +++ b/tgt-stub/stub.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: stub.c,v 1.75 2003/03/10 23:40:54 steve Exp $" +#ident "$Id: stub.c,v 1.76 2003/03/29 05:51:26 steve Exp $" #endif # include "config.h" @@ -262,6 +262,25 @@ static void show_lpm(ivl_lpm_t net) break; } + case IVL_LPM_MULT: { + fprintf(out, " LPM_MULT %s: \n", + ivl_lpm_basename(net), width); + for (idx = 0 ; idx < width ; idx += 1) + fprintf(out, " Q %u: %s\n", idx, + ivl_nexus_name(ivl_lpm_q(net, idx))); + for (idx = 0 ; idx < width ; idx += 1) { + ivl_nexus_t nex = ivl_lpm_data(net, idx); + fprintf(out, " Data A %u: %s\n", idx, + nex? ivl_nexus_name(nex) : ""); + } + for (idx = 0 ; idx < width ; idx += 1) { + ivl_nexus_t nex = ivl_lpm_datab(net, idx); + fprintf(out, " Data B %u: %s\n", idx, + nex? ivl_nexus_name(nex) : ""); + } + break; + } + case IVL_LPM_MUX: { unsigned sdx; @@ -818,6 +837,9 @@ int target_design(ivl_design_t des) /* * $Log: stub.c,v $ + * Revision 1.76 2003/03/29 05:51:26 steve + * Sign extend NetMult inputs if result is signed. + * * Revision 1.75 2003/03/10 23:40:54 steve * Keep parameter constants for the ivl_target API. *