Get arrayed property expressions down to the ivl_target API.

This commit is contained in:
Stephen Williams 2014-09-12 13:07:34 -07:00
parent acce9fc2a0
commit ea4b000be6
13 changed files with 137 additions and 33 deletions

View File

@ -1734,6 +1734,8 @@ void NetENull::dump(ostream&o) const
void NetEProperty::dump(ostream&o) const
{
o << net_->name() << ".<" << pidx_ << ">";
if (index_)
o << "[" << *index_ << "]";
}
void NetEScope::dump(ostream&o) const

View File

@ -3298,7 +3298,9 @@ NetExpr* PEIdent::elaborate_expr_class_member_(Design*des, NetScope*scope,
if (class_type == 0)
return 0;
perm_string member_name = peek_tail_name(path_);
const name_component_t&name_comp = path_.back();
perm_string member_name = name_comp.name;
int pidx = class_type->property_idx_from_name(member_name);
if (pidx < 0)
return 0;
@ -3336,14 +3338,40 @@ NetExpr* PEIdent::elaborate_expr_class_member_(Design*des, NetScope*scope,
return class_static_property_expression(this, class_type, member_name);
}
NetExpr*canon_index = 0;
ivl_type_t tmp_type = class_type->get_prop_type(pidx);
if (/* const netuarray_t*tmp_ua =*/ dynamic_cast<const netuarray_t*>(tmp_type)) {
cerr << get_fileline() << ": sorry: "
<< "Unpacked array properties not supported yet." << endl;
des->errors += 1;
if (const netuarray_t*tmp_ua = dynamic_cast<const netuarray_t*>(tmp_type)) {
const std::vector<netrange_t>&dims = tmp_ua->static_dimensions();
if (debug_elaborate) {
cerr << get_fileline() << ": PEIdent::elaborate_expr_class_member_: "
<< "Property " << class_type->get_prop_name(pidx)
<< " has " << dims.size() << " dimensions, "
<< " got " << name_comp.index.size() << " indices." << endl;
}
NetEProperty*tmp = new NetEProperty(this_net, member_name);
if (dims.size() != name_comp.index.size()) {
cerr << get_fileline() << ": error: "
<< "Got " << name_comp.index.size() << " indices, "
<< "expecting " << dims.size()
<< " to index the property " << class_type->get_prop_name(pidx) << "." << endl;
des->errors += 1;
} else {
canon_index = make_canonical_index(des, scope, this,
name_comp.index, tmp_ua, false);
}
}
if (debug_elaborate && canon_index) {
cerr << get_fileline() << ": PEIdent::elaborate_expr_class_member_: "
<< "Property " << class_type->get_prop_name(pidx)
<< " canonical index: " << *canon_index << endl;
}
NetEProperty*tmp = new NetEProperty(this_net, member_name, canon_index);
tmp->set_line(*this);
return tmp;
}

View File

@ -425,27 +425,8 @@ NetAssign_* PEIdent::elaborate_lval_method_class_member_(Design*des,
ivl_type_t property_type = class_type->get_prop_type(pidx);
if (const netsarray_t* stype = dynamic_cast<const netsarray_t*> (property_type)) {
list<long> indices_const;
list<NetExpr*> indices_expr;
indices_flags flags;
indices_to_expressions(des, scope, this,
name_comp.index, name_comp.index.size(),
false, flags,
indices_expr, indices_const);
if (flags.undefined) {
cerr << get_fileline() << ": warning: "
<< "ignoring undefined l-value array access "
<< member_name
<< " (" << path_ << ")"
<< "." << endl;
} else if (flags.variable) {
canon_index = normalize_variable_unpacked(*this, stype, indices_expr);
} else {
canon_index = normalize_variable_unpacked(stype, indices_const);
}
canon_index = make_canonical_index(des, scope, this,
name_comp.index, stype, false);
} else {
cerr << get_fileline() << ": error: "
@ -490,10 +471,28 @@ NetAssign_* PEIdent::elaborate_lval_method_class_member_(Design*des,
ivl_type_t tmp_type = class_type->get_prop_type(pidx);
if (const netuarray_t*tmp_ua = dynamic_cast<const netuarray_t*>(tmp_type)) {
cerr << get_fileline() << ": sorry: "
<< "Unpacked array properties (l-values) not supported yet." << endl;
const std::vector<netrange_t>&dims = tmp_ua->static_dimensions();
if (debug_elaborate) {
cerr << get_fileline() << ": PEIdent::elaborate_lval_method_class_member_: "
<< "Property " << class_type->get_prop_name(pidx)
<< " has " << dims.size() << " dimensions, "
<< " got " << name_comp.index.size() << " indices." << endl;
if (canon_index) {
cerr << get_fileline() << ": PEIdent::elaborate_lval_method_class_member_: "
<< "Canonical index is:" << *canon_index << endl;
};
}
if (dims.size() != name_comp.index.size()) {
cerr << get_fileline() << ": error: "
<< "Got " << name_comp.index.size() << " indices, "
<< "expecting " << dims.size()
<< " to index the property " << class_type->get_prop_name(pidx) << "." << endl;
des->errors += 1;
}
}
NetAssign_*this_lval = new NetAssign_(this_net);
this_lval->set_property(member_name);

View File

@ -832,6 +832,10 @@ extern unsigned ivl_event_lineno(ivl_event_t net);
* table. That number can be passed to ivl_type_prop_*() functions to
* get details about the property.
*
* If the property is an array, then the ivl_expr_oper1() function
* returns the canonical expression for accessing the element of the
* property.
*
* - IVL_EX_NEW
* This expression takes one or two operands. The first operand,
* returned by ivl_expr_oper1() is the number of elements to create
@ -1499,6 +1503,11 @@ extern const char*ivl_lpm_string(ivl_lpm_t net);
* then the ivl_lval_idx expression must *not* be present.
*
* For array words, the ivl_lval_width is the width of the word.
*
* - Arrayed properties
* If the l-value is a class property, then the ivl_lval_idx function
* will return an expression if the property is in fact arrayed. The
* expression is the canonical index for elements in the property.
*/
extern unsigned ivl_lval_width(ivl_lval_t net);

View File

@ -376,8 +376,8 @@ NetENull::~NetENull()
{
}
NetEProperty::NetEProperty(NetNet*net, perm_string pnam)
: net_(net)
NetEProperty::NetEProperty(NetNet*net, perm_string pnam, NetExpr*idx)
: net_(net), index_(idx)
{
const netclass_t*use_type = dynamic_cast<const netclass_t*>(net->net_type());
assert(use_type);

View File

@ -4293,14 +4293,18 @@ class NetENull : public NetExpr {
* The NetEProperty represents a SystemVerilog property select of a
* class object. In SV, the expression would look like "a.b", where
* the "a" is the signal (the NetNet) and "b" is the property name.
*
* The canon_index is an optional expression to address an element for
* parameters that are arrays.
*/
class NetEProperty : public NetExpr {
public:
NetEProperty(NetNet*n, perm_string pname);
NetEProperty(NetNet*n, perm_string pname, NetExpr*canon_index =0);
~NetEProperty();
inline const NetNet* get_sig() const { return net_; }
inline size_t property_idx() const { return pidx_; }
inline const NetExpr*get_index() const { return index_; }
public: // Overridden methods
ivl_variable_type_t expr_type() const;
@ -4313,6 +4317,7 @@ class NetEProperty : public NetExpr {
private:
NetNet*net_;
size_t pidx_;
NetExpr*index_;
};
/*

View File

@ -667,6 +667,36 @@ NetExpr* normalize_variable_unpacked(const LineInfo&loc, const netsarray_t*stype
return normalize_variable_unpacked(loc, dims, indices);
}
NetExpr* make_canonical_index(Design*des, NetScope*scope,
const LineInfo*loc,
const std::list<index_component_t>&src,
const netsarray_t*stype,
bool need_const)
{
NetExpr*canon_index = 0;
list<long> indices_const;
list<NetExpr*> indices_expr;
indices_flags flags;
indices_to_expressions(des, scope, loc,
src, src.size(),
need_const, flags,
indices_expr, indices_const);
if (flags.undefined) {
cerr << loc->get_fileline() << ": warning: "
<< "ignoring undefined value array access." << endl;
} else if (flags.variable) {
canon_index = normalize_variable_unpacked(*loc, stype, indices_expr);
} else {
canon_index = normalize_variable_unpacked(stype, indices_const);
}
return canon_index;
}
NetEConst* make_const_x(unsigned long wid)
{
verinum xxx (verinum::Vx, wid);

View File

@ -191,6 +191,16 @@ extern NetExpr*normalize_variable_unpacked(const netsarray_t*net, list<long>&ind
extern NetExpr*normalize_variable_unpacked(const NetNet*net, list<NetExpr*>&indices);
extern NetExpr*normalize_variable_unpacked(const LineInfo&loc, const netsarray_t*net, list<NetExpr*>&indices);
extern NetExpr*make_canonical_index(Design*des, NetScope*scope,
// loc for error messages
const LineInfo*loc,
// src is the index list
const std::list<index_component_t>&src,
// This is the reference type
const netsarray_t*stype,
// True if the expression MUST be constant.
bool need_const);
/*
* This function takes as input a NetNet signal and adds a constant
* value to it. If the val is 0, then simply return sig. Otherwise,

View File

@ -485,6 +485,9 @@ extern "C" ivl_expr_t ivl_expr_oper1(ivl_expr_t net)
case IVL_EX_BINARY:
return net->u_.binary_.lef_;
case IVL_EX_PROPERTY:
return net->u_.property_.index;
case IVL_EX_SELECT:
return net->u_.select_.expr_;

View File

@ -420,6 +420,12 @@ void dll_target::expr_null(const NetENull*net)
void dll_target::expr_property(const NetEProperty*net)
{
ivl_expr_t index = 0;
if (const NetExpr*index_expr = net->get_index()) {
index_expr->expr_scan(this);
index = expr_;
expr_ = 0;
}
assert(expr_ == 0);
expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
expr_->width_ = net->expr_width();
@ -431,6 +437,7 @@ void dll_target::expr_property(const NetEProperty*net)
expr_->net_type= net->net_type();
expr_->u_.property_.sig = find_signal(des_, net->get_sig());
expr_->u_.property_.prop_idx = net->property_idx();
expr_->u_.property_.index = index;
}
void dll_target::expr_event(const NetEEvent*net)

View File

@ -346,6 +346,7 @@ struct ivl_expr_s {
struct {
ivl_signal_t sig;
unsigned prop_idx;
ivl_expr_t index;
} property_;
} u_;
};

View File

@ -232,6 +232,7 @@ static void show_property_expression(ivl_expr_t net, unsigned ind)
ivl_signal_t sig = ivl_expr_signal(net);
const char* pnam = ivl_expr_name(net);
const char*signed_flag = ivl_expr_signed(net)? "signed" : "unsigned";
ivl_expr_t index;
if (ivl_expr_value(net) == IVL_VT_REAL) {
fprintf(out, "%*s<property base=%s, prop=%s, real>\n", ind, "",
@ -243,6 +244,9 @@ static void show_property_expression(ivl_expr_t net, unsigned ind)
fprintf(out, "%*s<property base=%s, prop=%s, width=%u, %s>\n", ind, "",
ivl_signal_basename(sig), pnam, ivl_expr_width(net), signed_flag);
}
if ( (index=ivl_expr_oper1(net)) ) {
show_expression(index, ind+3);
}
if (ivl_signal_data_type(sig) != IVL_VT_CLASS) {
fprintf(out, "%*sERROR: Property signal must be IVL_VT_CLASS, got %s.\n",
ind+3, "", data_type_string(ivl_signal_data_type(sig)));

View File

@ -73,6 +73,12 @@ static unsigned show_assign_lval_class(ivl_lval_t lval, unsigned ind)
fprintf(out, "%*s{name=%s.<property-%d> l-value width=%u}\n",
ind, "", ivl_signal_name(sig), sig_prop, ivl_lval_width(lval));
if (ivl_lval_idx(lval)) {
ivl_expr_t mux = ivl_lval_idx(lval);
fprintf(out, "%*sAddress-0 select expression:\n", ind+4, "");
show_expression(mux, ind+6);
}
return ivl_lval_width(lval);
}