diff --git a/elaborate.cc b/elaborate.cc index 0086d1168..7d77263b0 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.313 2005/01/09 20:16:01 steve Exp $" +#ident "$Id: elaborate.cc,v 1.314 2005/01/12 03:17:36 steve Exp $" #endif # include "config.h" @@ -94,7 +94,7 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const assert(lval->pin_count() == 1); if (debug_elaborate) { - cerr << lval->get_line() << ": debug: Elaborated l-value " + cerr << lval->get_line() << ": debug: PGassign elaborated l-value " << "width=" << lval->vector_width() << endl; } @@ -126,7 +126,7 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const unsigned cnt = lval->vector_width(); if (rid->vector_width() < cnt) - cnt = rid->pin_count(); + cnt = rid->vector_width(); bool need_driver_flag = false; @@ -153,41 +153,37 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const if (rid->pin(0).drive1() != drive1) need_driver_flag = true; + /* If the r-value is more narrow then the l-value, pad + it to the desired width. */ + if (cnt < lval->vector_width()) { + if (lval->get_signed() && rid->get_signed()) { + cerr << get_line() << ": internal error: " + << "Forgot how to sign-extend r-value " + << "to l-value." << endl; + } else { + + if (debug_elaborate) + cerr << get_line() << ": debug: PGAssign " + << "Unsigned pad r-value from " + << cnt << " bits to " + << lval->vector_width() << " bits." << endl; + + NetNet*tmp = pad_to_width(des, rid, + lval->vector_width()); + rid = tmp; + } + } if (! need_driver_flag) { + /* Don't need a driver, presumably because the r-value already has the needed drivers. Just 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. */ + connect(lval->pin(0), rid->pin(0)); - if (cnt < lval->pin_count()) { -#if 0 - 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 - cerr << get_line() << ": internal error: " - << "Forgot how to handle mismatched widths." - << endl; -#endif - } - } else { /* Do need a driver. Use BUFZ objects to carry the strength and delays. */ @@ -2890,6 +2886,9 @@ Design* elaborate(listroots) /* * $Log: elaborate.cc,v $ + * Revision 1.314 2005/01/12 03:17:36 steve + * Properly pad vector widths in pgassign. + * * Revision 1.313 2005/01/09 20:16:01 steve * Use PartSelect/PV and VP to handle part selects through ports. * diff --git a/netlist.h b/netlist.h index 6f8cc206a..52ba91928 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.324 2005/01/09 20:16:01 steve Exp $" +#ident "$Id: netlist.h,v 1.325 2005/01/12 03:17:37 steve Exp $" #endif /* @@ -593,7 +593,7 @@ class NetCompare : public NetNode { * for the code generators. * * When constructing the node, the width is the vector_width of the - * output, and the cnt is the number of pins. (1 + the number of input + * output, and the cnt is the number of pins. (the number of input * vectors.) */ class NetConcat : public NetNode { @@ -3411,6 +3411,9 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.325 2005/01/12 03:17:37 steve + * Properly pad vector widths in pgassign. + * * Revision 1.324 2005/01/09 20:16:01 steve * Use PartSelect/PV and VP to handle part selects through ports. * diff --git a/pad_to_width.cc b/pad_to_width.cc index 053b47165..bcecf6620 100644 --- a/pad_to_width.cc +++ b/pad_to_width.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2004 Stephen Williams (steve@icarus.com) + * Copyright (c) 1999-2005 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 @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: pad_to_width.cc,v 1.15 2004/02/18 17:11:57 steve Exp $" +#ident "$Id: pad_to_width.cc,v 1.16 2005/01/12 03:17:37 steve Exp $" #endif # include "config.h" @@ -70,33 +70,51 @@ NetExpr*pad_to_width(NetExpr*expr, unsigned wid) return expr; } +/* + * Pad a NetNet to the desired vector width by concatenating a + * NetConst of constant zeros. Use a NetConcat node to do the + * concatenation. + */ NetNet*pad_to_width(Design*des, NetNet*net, unsigned wid) { NetScope*scope = net->scope(); - const string path = scope->name(); - assert(scope); - if (net->pin_count() >= wid) + if (net->vector_width() >= wid) return net; - verinum pad(verinum::V0, wid - net->pin_count()); + // Make the NetConcat and connect the input net to the lsb input. + NetConcat*cc = new NetConcat(scope, scope->local_symbol(), wid, 2); + des->add_node(cc); + connect(cc->pin(1), net->pin(0)); + + // Make a NetConst of the desired width and connect in to the + // lsb input of the NetConcat. + verinum pad(verinum::V0, wid - net->vector_width()); NetConst*con = new NetConst(scope, scope->local_symbol(), pad); des->add_node(con); + connect(cc->pin(2), con->pin(0)); + // Make a NetNet for the NetConst to NetConcat link. NetNet*tmp = new NetNet(scope, scope->local_symbol(), - NetNet::WIRE, wid); + NetNet::WIRE, wid - net->vector_width()); tmp->local_flag(true); + connect(cc->pin(2), tmp->pin(0)); - for (unsigned idx = 0 ; idx < net->pin_count() ; idx += 1) - connect(tmp->pin(idx), net->pin(idx)); - for (unsigned idx = net->pin_count() ; idx < wid ; idx += 1) - connect(tmp->pin(idx), con->pin(idx-net->pin_count())); + // Create a NetNet of the output width and connect it to the + // NetConcat node output pin. + tmp = new NetNet(scope, scope->local_symbol(), + NetNet::WIRE, wid); + tmp->local_flag(true); + connect(cc->pin(0), tmp->pin(0)); return tmp; } /* * $Log: pad_to_width.cc,v $ + * Revision 1.16 2005/01/12 03:17:37 steve + * Properly pad vector widths in pgassign. + * * Revision 1.15 2004/02/18 17:11:57 steve * Use perm_strings for named langiage items. *