From b4baace4b1bb89dbf16e31445b5c0b0d2cbdc1c3 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 15 Feb 2016 15:12:40 +0100 Subject: [PATCH] ivl: Support for part selection in multidimensional packed ports assignment. --- elab_net.cc | 87 +++++++++++++++++++++++++++++++++++------------------ netmisc.cc | 2 +- 2 files changed, 58 insertions(+), 31 deletions(-) diff --git a/elab_net.cc b/elab_net.cc index 09a38f454..55bdbce9c 100644 --- a/elab_net.cc +++ b/elab_net.cc @@ -328,39 +328,66 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig, return false; } - long lidx_tmp = sig->sb_to_idx(prefix_indices, lsb); - long midx_tmp = sig->sb_to_idx(prefix_indices, msb); - /* Detect reversed indices of a part select. */ - if (lidx_tmp > midx_tmp) { - cerr << get_fileline() << ": error: Part select " - << sig->name() << "[" << msb << ":" - << lsb << "] indices reversed." << endl; - cerr << get_fileline() << ": : Did you mean " - << sig->name() << "[" << lsb << ":" - << msb << "]?" << endl; - long tmp = midx_tmp; - midx_tmp = lidx_tmp; - lidx_tmp = tmp; - des->errors += 1; - } + if (prefix_indices.size()+1 < sig->packed_dims().size()) { + // Here we have a slice that doesn't have enough indices + // to get to a single slice. For example: + // wire [9:0][5:1] foo + // ... foo[4:3] ... + // Make this work by finding the indexed slices and + // creating a generated slice that spans the whole + // range. + long loff, moff; + unsigned long lwid, mwid; + bool lrc; + lrc = sig->sb_to_slice(prefix_indices, lsb, loff, lwid); + ivl_assert(*this, lrc); + lrc = sig->sb_to_slice(prefix_indices, msb, moff, mwid); + ivl_assert(*this, lrc); + ivl_assert(*this, lwid == mwid); - /* Warn about a part select that is out of range. */ - if (midx_tmp >= (long)sig->vector_width() || lidx_tmp < 0) { - cerr << get_fileline() << ": warning: Part select " - << sig->name(); - if (sig->unpacked_dimensions() > 0) { - cerr << "[]"; + if (moff > loff) { + lidx = loff; + midx = moff + mwid - 1; + } else { + lidx = moff; + midx = loff + lwid - 1; } - cerr << "[" << msb << ":" << lsb - << "] is out of range." << endl; - } - /* This is completely out side the signal so just skip it. */ - if (lidx_tmp >= (long)sig->vector_width() || midx_tmp < 0) { - return false; - } + } else { + long lidx_tmp = sig->sb_to_idx(prefix_indices, lsb); + long midx_tmp = sig->sb_to_idx(prefix_indices, msb); - midx = midx_tmp; - lidx = lidx_tmp; + /* Detect reversed indices of a part select. */ + if (lidx_tmp > midx_tmp) { + cerr << get_fileline() << ": error: Part select " + << sig->name() << "[" << msb << ":" + << lsb << "] indices reversed." << endl; + cerr << get_fileline() << ": : Did you mean " + << sig->name() << "[" << lsb << ":" + << msb << "]?" << endl; + long tmp = midx_tmp; + midx_tmp = lidx_tmp; + lidx_tmp = tmp; + des->errors += 1; + } + + /* Warn about a part select that is out of range. */ + if (midx_tmp >= (long)sig->vector_width() || lidx_tmp < 0) { + cerr << get_fileline() << ": warning: Part select " + << sig->name(); + if (sig->unpacked_dimensions() > 0) { + cerr << "[]"; + } + cerr << "[" << msb << ":" << lsb + << "] is out of range." << endl; + } + /* This is completely out side the signal so just skip it. */ + if (lidx_tmp >= (long)sig->vector_width() || midx_tmp < 0) { + return false; + } + + midx = midx_tmp; + lidx = lidx_tmp; + } break; } diff --git a/netmisc.cc b/netmisc.cc index 2ced04acb..81ad82488 100644 --- a/netmisc.cc +++ b/netmisc.cc @@ -1412,7 +1412,7 @@ bool evaluate_index_prefix(Design*des, NetScope*scope, return false; } - prefix_indices .push_back(tmp); + prefix_indices.push_back(tmp); delete texpr; }