Properly pad vector widths in pgassign.
This commit is contained in:
parent
8c18c9152d
commit
4d139b58aa
57
elaborate.cc
57
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(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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue