Optimize a full L-value indexed part select, etc.

This patch adds an optimization when a constant indexed part
select covers the entire L-value. It also fixes a few issues
in the code generator related to part selects.
(cherry picked from commit 09fa57742a)
This commit is contained in:
Cary R 2009-09-17 19:06:40 -07:00 committed by Stephen Williams
parent fb01245501
commit e7815c3984
2 changed files with 10 additions and 4 deletions

View File

@ -491,9 +491,11 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des,
offset = -wid + 1; offset = -wid + 1;
} }
delete base; delete base;
base = new NetEConst(verinum(reg->sb_to_idx(lsv) + offset)); long rel_base = reg->sb_to_idx(lsv) + offset;
/* If we cover the entire lvalue just skip the select. */
if (rel_base == 0 && wid == reg->vector_width()) return true;
base = new NetEConst(verinum(rel_base));
if (warn_ob_select) { if (warn_ob_select) {
long rel_base = reg->sb_to_idx(lsv) + offset;
if (rel_base < 0) { if (rel_base < 0) {
cerr << get_fileline() << ": warning: " << reg->name(); cerr << get_fileline() << ": warning: " << reg->name();
if (reg->array_dimensions() > 0) cerr << "[]"; if (reg->array_dimensions() > 0) cerr << "[]";

View File

@ -1139,7 +1139,6 @@ static void force_vector_to_lval(ivl_statement_t net, struct vector_info rvec)
} else { } else {
/* Do not support bit or part selects of l-values yet. */ /* Do not support bit or part selects of l-values yet. */
assert(ivl_lval_mux(lval) == 0); assert(ivl_lval_mux(lval) == 0);
assert(ivl_lval_part_off(lval) == 0);
assert(ivl_lval_width(lval) == ivl_signal_width(lsig)); assert(ivl_lval_width(lval) == ivl_signal_width(lsig));
assert((roff + use_wid) <= rvec.wid); assert((roff + use_wid) <= rvec.wid);
@ -1188,8 +1187,13 @@ static void force_link_rval(ivl_statement_t net, ivl_expr_t rval)
/* We do not currently support driving a signal to a bit or /* We do not currently support driving a signal to a bit or
* part select (this could give us multiple drivers). */ * part select (this could give us multiple drivers). */
part_off_ex = ivl_lval_part_off(lval); part_off_ex = ivl_lval_part_off(lval);
/* This should be verified in force_vector_to_lval() which is called
* before this procedure. */
if (part_off_ex) {
assert(number_is_immediate(part_off_ex, IMM_WID, 0));
assert(! number_is_unknown(part_off_ex));
}
if (ivl_signal_width(lsig) > ivl_signal_width(rsig) || if (ivl_signal_width(lsig) > ivl_signal_width(rsig) ||
// Do we need checks for number_is{immediate,unknown} of part_of_ex?
(part_off_ex && get_number_immediate(part_off_ex) != 0)) { (part_off_ex && get_number_immediate(part_off_ex) != 0)) {
fprintf(stderr, "%s:%u: vvp-tgt sorry: cannot %s signal to " fprintf(stderr, "%s:%u: vvp-tgt sorry: cannot %s signal to "
"a bit/part select.\n", ivl_expr_file(rval), "a bit/part select.\n", ivl_expr_file(rval),