Properly pad vector widths in pgassign.

This commit is contained in:
steve 2005-01-12 03:17:36 +00:00
parent 8c18c9152d
commit 4d139b58aa
3 changed files with 62 additions and 42 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: 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(list<perm_string>roots)
/*
* $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.
*

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

View File

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