Elaborate dynamic array expressions (lval/rval) down to ivl_target.h
This commit is contained in:
parent
18714e2efd
commit
fdc92ea464
2
PExpr.h
2
PExpr.h
|
|
@ -367,6 +367,8 @@ class PEIdent : public PExpr {
|
|||
bool elaborate_lval_net_packed_member_(Design*, NetScope*,
|
||||
NetAssign_*,
|
||||
const perm_string&) const;
|
||||
bool elaborate_lval_darray_bit_(Design*, NetScope*,
|
||||
NetAssign_*) const;
|
||||
|
||||
private:
|
||||
NetExpr*elaborate_expr_param_(Design*des,
|
||||
|
|
|
|||
33
elab_expr.cc
33
elab_expr.cc
|
|
@ -29,6 +29,7 @@
|
|||
# include "netenum.h"
|
||||
# include "discipline.h"
|
||||
# include "netmisc.h"
|
||||
# include "netdarray.h"
|
||||
# include "netstruct.h"
|
||||
# include "util.h"
|
||||
# include "ivl_assert.h"
|
||||
|
|
@ -2308,6 +2309,21 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode)
|
|||
ivl_assert(*this, 0);
|
||||
}
|
||||
|
||||
if (netdarray_t*darray = net? net->darray_type() : 0) {
|
||||
if (use_sel == index_component_t::SEL_BIT) {
|
||||
expr_type_ = darray->data_type();
|
||||
expr_width_ = darray->vector_width();
|
||||
min_width_ = expr_width_;
|
||||
signed_flag_ = net->get_signed();
|
||||
} else {
|
||||
expr_type_ = net->data_type();
|
||||
expr_width_ = net->vector_width();
|
||||
min_width_ = expr_width_;
|
||||
signed_flag_ = net->get_signed();
|
||||
}
|
||||
return expr_width_;
|
||||
}
|
||||
|
||||
if (use_width != UINT_MAX) {
|
||||
expr_type_ = IVL_VT_LOGIC; // Assume bit/parts selects are logic
|
||||
expr_width_ = use_width;
|
||||
|
|
@ -2322,8 +2338,7 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode)
|
|||
expr_type_ = net->data_type();
|
||||
expr_width_ = net->vector_width();
|
||||
min_width_ = expr_width_;
|
||||
signed_flag_ = net->get_signed();
|
||||
|
||||
signed_flag_ = net->get_signed();
|
||||
return expr_width_;
|
||||
}
|
||||
|
||||
|
|
@ -3739,6 +3754,20 @@ NetExpr* PEIdent::elaborate_expr_net_bit_(Design*des, NetScope*scope,
|
|||
return res;
|
||||
}
|
||||
|
||||
if (netdarray_t*darray = net->sig()->darray_type()) {
|
||||
// Special case: This is a select of a dynamic
|
||||
// array. Generate a NetESelect ant attach it to
|
||||
// the NetESignal. This should be interpreted as
|
||||
// an array word select downstream.
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": debug: "
|
||||
<< "Bit select of a dynamic array becomes NetESelect." << endl;
|
||||
}
|
||||
NetESelect*res = new NetESelect(net, mux, darray->vector_width());
|
||||
res->set_line(*net);
|
||||
return res;
|
||||
}
|
||||
|
||||
long idx = net->sig()->sb_to_idx(prefix_indices,msv);
|
||||
|
||||
if (idx >= (long)net->vector_width() || idx < 0) {
|
||||
|
|
|
|||
32
elab_lval.cc
32
elab_lval.cc
|
|
@ -257,9 +257,15 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
|
|||
|
||||
|
||||
if (use_sel == index_component_t::SEL_BIT) {
|
||||
NetAssign_*lv = new NetAssign_(reg);
|
||||
elaborate_lval_net_bit_(des, scope, lv);
|
||||
return lv;
|
||||
if (reg->darray_type()) {
|
||||
NetAssign_*lv = new NetAssign_(reg);
|
||||
elaborate_lval_darray_bit_(des, scope, lv);
|
||||
return lv;
|
||||
} else {
|
||||
NetAssign_*lv = new NetAssign_(reg);
|
||||
elaborate_lval_net_bit_(des, scope, lv);
|
||||
return lv;
|
||||
}
|
||||
}
|
||||
|
||||
ivl_assert(*this, use_sel == index_component_t::SEL_NONE);
|
||||
|
|
@ -458,6 +464,26 @@ bool PEIdent::elaborate_lval_net_bit_(Design*des,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool PEIdent::elaborate_lval_darray_bit_(Design*des, NetScope*scope, NetAssign_*lv)const
|
||||
{
|
||||
const name_component_t&name_tail = path_.back();
|
||||
ivl_assert(*this, !name_tail.index.empty());
|
||||
|
||||
// For now, only support single-dimension dynamic arrays.
|
||||
ivl_assert(*this, name_tail.index.size() == 1);
|
||||
|
||||
const index_component_t&index_tail = name_tail.index.back();
|
||||
ivl_assert(*this, index_tail.msb != 0);
|
||||
ivl_assert(*this, index_tail.lsb == 0);
|
||||
|
||||
// Evaluate the select expression...
|
||||
NetExpr*mux = elab_and_eval(des, scope, index_tail.msb, -1);
|
||||
|
||||
lv->set_word(mux);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PEIdent::elaborate_lval_net_part_(Design*des,
|
||||
NetScope*scope,
|
||||
NetAssign_*lv) const
|
||||
|
|
|
|||
|
|
@ -1063,7 +1063,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
|||
// put all the packed dimensions there.
|
||||
if (use_lidx==0 && use_ridx==0) {
|
||||
ivl_assert(*this, netarray==0);
|
||||
netarray = new netdarray_t(packed_dimensions, data_type_);
|
||||
netarray = new netdarray_t(packed_dimensions, data_type_, wid);
|
||||
packed_dimensions.clear();
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
# include "config.h"
|
||||
|
||||
# include "netlist.h"
|
||||
# include "netdarray.h"
|
||||
|
||||
/*
|
||||
* NetAssign
|
||||
|
|
@ -84,13 +85,25 @@ ivl_select_type_t NetAssign_::select_type() const
|
|||
|
||||
unsigned NetAssign_::lwidth() const
|
||||
{
|
||||
if (netdarray_t*darray = sig_->darray_type()) {
|
||||
if (word_ == 0)
|
||||
return 1;
|
||||
else
|
||||
return darray->vector_width();
|
||||
}
|
||||
|
||||
return lwid_;
|
||||
}
|
||||
|
||||
ivl_variable_type_t NetAssign_::expr_type() const
|
||||
{
|
||||
if (sig_->darray_type())
|
||||
return IVL_VT_DARRAY;
|
||||
if (netdarray_t*darray = sig_->darray_type()) {
|
||||
if (word_ == 0)
|
||||
return IVL_VT_DARRAY;
|
||||
else
|
||||
return darray->data_type();
|
||||
}
|
||||
|
||||
return sig_->data_type();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@
|
|||
using namespace std;
|
||||
|
||||
netdarray_t::netdarray_t(const std::list<netrange_t>&packed,
|
||||
ivl_variable_type_t type)
|
||||
: packed_dims_(packed), type_(type)
|
||||
ivl_variable_type_t type, unsigned long wid)
|
||||
: packed_dims_(packed), type_(type), width_(wid)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,14 +27,17 @@ class netdarray_t : public nettype_base_t {
|
|||
|
||||
public:
|
||||
explicit netdarray_t(const std::list<netrange_t>&packed,
|
||||
ivl_variable_type_t type);
|
||||
ivl_variable_type_t type,
|
||||
unsigned long wid);
|
||||
~netdarray_t();
|
||||
|
||||
ivl_variable_type_t data_type() const { return type_; }
|
||||
inline ivl_variable_type_t data_type() const { return type_; }
|
||||
inline unsigned long vector_width(void) const { return width_; }
|
||||
|
||||
private:
|
||||
std::list<netrange_t> packed_dims_;
|
||||
ivl_variable_type_t type_;
|
||||
unsigned long width_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -21,10 +21,36 @@
|
|||
# include "priv.h"
|
||||
# include <assert.h>
|
||||
|
||||
/*
|
||||
* If the l-value signal is a darray object, then the ivl_lval_mux()
|
||||
* gets you the array index expression.
|
||||
*/
|
||||
static unsigned show_assign_lval_darray(ivl_lval_t lval, unsigned ind)
|
||||
{
|
||||
ivl_signal_t sig = ivl_lval_sig(lval);
|
||||
assert(sig);
|
||||
|
||||
if (ivl_lval_idx(lval)) {
|
||||
fprintf(out, "%*sAddress-0 select of dynamic array:\n", ind+4, "");
|
||||
show_expression(ivl_lval_idx(lval), ind+6);
|
||||
}
|
||||
|
||||
if (ivl_lval_mux(lval)) {
|
||||
fprintf(out, "%*sERROR: unexpected ivl_lval_mux() expression:\n", ind+4, "");
|
||||
stub_errors += 1;
|
||||
show_expression(ivl_lval_mux(lval), ind+6);
|
||||
}
|
||||
if (ivl_lval_part_off(lval)) {
|
||||
fprintf(out, "%*sERROR: unexpected Part select expression:\n", ind+4, "");
|
||||
stub_errors += 1;
|
||||
show_expression(ivl_lval_part_off(lval), ind+8);
|
||||
}
|
||||
|
||||
return ivl_lval_width(lval);
|
||||
}
|
||||
|
||||
static unsigned show_assign_lval(ivl_lval_t lval, unsigned ind)
|
||||
{
|
||||
unsigned wid = 0;
|
||||
|
||||
ivl_signal_t sig = ivl_lval_sig(lval);
|
||||
assert(sig);
|
||||
|
||||
|
|
@ -34,6 +60,10 @@ static unsigned show_assign_lval(ivl_lval_t lval, unsigned ind)
|
|||
ivl_signal_width(sig),
|
||||
ivl_lval_width(lval));
|
||||
|
||||
/* Special case: target signal is a darray. */
|
||||
if (ivl_signal_data_type(sig) == IVL_VT_DARRAY)
|
||||
return show_assign_lval_darray(lval, ind);
|
||||
|
||||
if (ivl_lval_idx(lval)) {
|
||||
fprintf(out, "%*sAddress-0 select expression:\n", ind+4, "");
|
||||
show_expression(ivl_lval_idx(lval), ind+6);
|
||||
|
|
@ -59,9 +89,7 @@ static unsigned show_assign_lval(ivl_lval_t lval, unsigned ind)
|
|||
show_expression(ivl_lval_part_off(lval), ind+8);
|
||||
}
|
||||
|
||||
wid = ivl_lval_width(lval);
|
||||
|
||||
return wid;
|
||||
return ivl_lval_width(lval);
|
||||
}
|
||||
|
||||
static void show_stmt_cassign(ivl_statement_t net, unsigned ind)
|
||||
|
|
|
|||
Loading…
Reference in New Issue