Some support for unpacked arrays in class properties.
This commit is contained in:
parent
1465fd1570
commit
3b0dfaadba
52
elab_lval.cc
52
elab_lval.cc
|
|
@ -27,6 +27,7 @@
|
||||||
# include "netstruct.h"
|
# include "netstruct.h"
|
||||||
# include "netclass.h"
|
# include "netclass.h"
|
||||||
# include "netdarray.h"
|
# include "netdarray.h"
|
||||||
|
# include "netparray.h"
|
||||||
# include "netvector.h"
|
# include "netvector.h"
|
||||||
# include "compiler.h"
|
# include "compiler.h"
|
||||||
# include <cstdlib>
|
# include <cstdlib>
|
||||||
|
|
@ -259,6 +260,12 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
|
||||||
}
|
}
|
||||||
|
|
||||||
ivl_assert(*this, reg);
|
ivl_assert(*this, reg);
|
||||||
|
|
||||||
|
if (debug_elaborate) {
|
||||||
|
cerr << get_fileline() << ": PEIdent::elaborate_lval: "
|
||||||
|
<< "Lval reg = " << reg->name() << endl;
|
||||||
|
}
|
||||||
|
|
||||||
// We are processing the tail of a string of names. For
|
// We are processing the tail of a string of names. For
|
||||||
// example, the verilog may be "a.b.c", so we are processing
|
// example, the verilog may be "a.b.c", so we are processing
|
||||||
// "c" at this point. (Note that if method_name is not nil,
|
// "c" at this point. (Note that if method_name is not nil,
|
||||||
|
|
@ -389,7 +396,9 @@ NetAssign_* PEIdent::elaborate_lval_method_class_member_(Design*des,
|
||||||
if (class_type == 0)
|
if (class_type == 0)
|
||||||
return 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);
|
int pidx = class_type->property_idx_from_name(member_name);
|
||||||
if (pidx < 0)
|
if (pidx < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -402,6 +411,46 @@ NetAssign_* PEIdent::elaborate_lval_method_class_member_(Design*des,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (debug_elaborate) {
|
||||||
|
cerr << get_fileline() << ": PEIdent::elaborate_lval_method_class_member_: "
|
||||||
|
<< "Ident " << member_name
|
||||||
|
<< " is a property of class " << class_type->get_name() << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetExpr*canon_index = 0;
|
||||||
|
if (name_comp.index.size() > 0) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
cerr << get_fileline() << ": error: "
|
||||||
|
<< "Index expressions don't apply to this type of property." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Detect assignment to constant properties. Note that the
|
// Detect assignment to constant properties. Note that the
|
||||||
// initializer constructor MAY assign to constant properties,
|
// initializer constructor MAY assign to constant properties,
|
||||||
// as this is how the property gets its value.
|
// as this is how the property gets its value.
|
||||||
|
|
@ -438,6 +487,7 @@ NetAssign_* PEIdent::elaborate_lval_method_class_member_(Design*des,
|
||||||
|
|
||||||
NetAssign_*this_lval = new NetAssign_(this_net);
|
NetAssign_*this_lval = new NetAssign_(this_net);
|
||||||
this_lval->set_property(member_name);
|
this_lval->set_property(member_name);
|
||||||
|
if (canon_index) this_lval->set_word(canon_index);
|
||||||
|
|
||||||
return this_lval;
|
return this_lval;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
44
elab_sig.cc
44
elab_sig.cc
|
|
@ -836,48 +836,6 @@ void PWhile::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
statement_->elaborate_sig(des, scope);
|
statement_->elaborate_sig(des, scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool evaluate_ranges(Design*des, NetScope*scope,
|
|
||||||
vector<netrange_t>&llist,
|
|
||||||
const list<pform_range_t>&rlist)
|
|
||||||
{
|
|
||||||
bool bad_msb = false, bad_lsb = false;
|
|
||||||
|
|
||||||
for (list<pform_range_t>::const_iterator cur = rlist.begin()
|
|
||||||
; cur != rlist.end() ; ++cur) {
|
|
||||||
long use_msb, use_lsb;
|
|
||||||
|
|
||||||
NetExpr*texpr = elab_and_eval(des, scope, cur->first, -1, true);
|
|
||||||
if (! eval_as_long(use_msb, texpr)) {
|
|
||||||
cerr << cur->first->get_fileline() << ": error: "
|
|
||||||
"Range expressions must be constant." << endl;
|
|
||||||
cerr << cur->first->get_fileline() << " : "
|
|
||||||
"This MSB expression violates the rule: "
|
|
||||||
<< *cur->first << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
bad_msb = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete texpr;
|
|
||||||
|
|
||||||
texpr = elab_and_eval(des, scope, cur->second, -1, true);
|
|
||||||
if (! eval_as_long(use_lsb, texpr)) {
|
|
||||||
cerr << cur->second->get_fileline() << ": error: "
|
|
||||||
"Range expressions must be constant." << endl;
|
|
||||||
cerr << cur->second->get_fileline() << " : "
|
|
||||||
"This LSB expression violates the rule: "
|
|
||||||
<< *cur->second << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
bad_lsb = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete texpr;
|
|
||||||
|
|
||||||
llist.push_back(netrange_t(use_msb, use_lsb));
|
|
||||||
}
|
|
||||||
|
|
||||||
return bad_msb | bad_lsb;
|
|
||||||
}
|
|
||||||
|
|
||||||
static netclass_t* locate_class_type(Design*, NetScope*scope,
|
static netclass_t* locate_class_type(Design*, NetScope*scope,
|
||||||
class_type_t*class_type)
|
class_type_t*class_type)
|
||||||
{
|
{
|
||||||
|
|
@ -1288,7 +1246,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
|
|
||||||
if (debug_elaborate) {
|
if (debug_elaborate) {
|
||||||
cerr << get_fileline() << ": debug: Create signal " << wtype
|
cerr << get_fileline() << ": debug: Create signal " << wtype
|
||||||
<< " parray=" << use_type->packed_dimensions()
|
<< " parray=" << use_type->static_dimensions()
|
||||||
<< " " << name_ << unpacked_dimensions
|
<< " " << name_ << unpacked_dimensions
|
||||||
<< " in scope " << scope_path(scope) << endl;
|
<< " in scope " << scope_path(scope) << endl;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
19
elab_type.cc
19
elab_type.cc
|
|
@ -22,6 +22,7 @@
|
||||||
# include "netclass.h"
|
# include "netclass.h"
|
||||||
# include "netdarray.h"
|
# include "netdarray.h"
|
||||||
# include "netenum.h"
|
# include "netenum.h"
|
||||||
|
# include "netparray.h"
|
||||||
# include "netscalar.h"
|
# include "netscalar.h"
|
||||||
# include "netstruct.h"
|
# include "netstruct.h"
|
||||||
# include "netvector.h"
|
# include "netvector.h"
|
||||||
|
|
@ -203,9 +204,21 @@ ivl_type_s* uarray_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
|
||||||
|
|
||||||
ivl_type_t btype = base_type->elaborate_type(des, scope);
|
ivl_type_t btype = base_type->elaborate_type(des, scope);
|
||||||
|
|
||||||
assert(dims->size() == 1);
|
assert(dims->size() >= 1);
|
||||||
list<pform_range_t>::const_iterator cur = dims->begin();
|
list<pform_range_t>::const_iterator cur = dims->begin();
|
||||||
assert(cur->first == 0 && cur->second==0);
|
|
||||||
ivl_type_s*res = new netdarray_t(btype);
|
// Special case: if the dimension is nil:nil, this is a
|
||||||
|
// dynamic array. Note that we only know how to handle dynamic
|
||||||
|
// arrays with 1 dimension at a time.
|
||||||
|
if (cur->first==0 && cur->second==0) {
|
||||||
|
assert(dims->size()==1);
|
||||||
|
ivl_type_s*res = new netdarray_t(btype);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<netrange_t> dimensions;
|
||||||
|
bool bad_range = evaluate_ranges(des, scope, dimensions, *dims);
|
||||||
|
|
||||||
|
ivl_type_s*res = new netuarray_t(dimensions, btype);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
35
elaborate.cc
35
elaborate.cc
|
|
@ -40,6 +40,7 @@
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
# include "netvector.h"
|
# include "netvector.h"
|
||||||
# include "netdarray.h"
|
# include "netdarray.h"
|
||||||
|
# include "netparray.h"
|
||||||
# include "netclass.h"
|
# include "netclass.h"
|
||||||
# include "netmisc.h"
|
# include "netmisc.h"
|
||||||
# include "util.h"
|
# include "util.h"
|
||||||
|
|
@ -2290,6 +2291,14 @@ NetAssign_* PAssign_::elaborate_lval(Design*des, NetScope*scope) const
|
||||||
NetAssign_*lv = new NetAssign_(tmp);
|
NetAssign_*lv = new NetAssign_(tmp);
|
||||||
return lv;
|
return lv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (debug_elaborate) {
|
||||||
|
cerr << get_fileline() << ": PAssign_::elaborate_lval: "
|
||||||
|
<< "lval_ = " << *lval_ << endl;
|
||||||
|
cerr << get_fileline() << ": PAssign_::elaborate_lval: "
|
||||||
|
<< "lval_ expr type = " << typeid(*lval_).name() << endl;
|
||||||
|
}
|
||||||
|
|
||||||
return lval_->elaborate_lval(des, scope, false, false);
|
return lval_->elaborate_lval(des, scope, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2520,6 +2529,22 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
|
||||||
|
|
||||||
rv = elaborate_rval_(des, scope, use_lv_type);
|
rv = elaborate_rval_(des, scope, use_lv_type);
|
||||||
|
|
||||||
|
} else if (const netuarray_t*utype = dynamic_cast<const netuarray_t*>(lv_net_type)) {
|
||||||
|
ivl_assert(*this, lv->more==0);
|
||||||
|
if (debug_elaborate) {
|
||||||
|
if (lv->word())
|
||||||
|
cerr << get_fileline() << ": PAssign::elaborate: "
|
||||||
|
<< "lv->word() = " << *lv->word() << endl;
|
||||||
|
else
|
||||||
|
cerr << get_fileline() << ": PAssign::elaborate: "
|
||||||
|
<< "lv->word() = <nil>" << endl;
|
||||||
|
}
|
||||||
|
ivl_type_t use_lv_type = lv_net_type;
|
||||||
|
ivl_assert(*this, lv->word());
|
||||||
|
use_lv_type = utype->element_type();
|
||||||
|
|
||||||
|
rv = elaborate_rval_(des, scope, use_lv_type);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* Elaborate the r-value expression, then try to evaluate it. */
|
/* Elaborate the r-value expression, then try to evaluate it. */
|
||||||
rv = elaborate_rval_(des, scope, lv_net_type, lv->expr_type(), count_lval_width(lv));
|
rv = elaborate_rval_(des, scope, lv_net_type, lv->expr_type(), count_lval_width(lv));
|
||||||
|
|
@ -4595,6 +4620,16 @@ NetProc* PForeach::elaborate(Design*des, NetScope*scope) const
|
||||||
pform_name_t array_name;
|
pform_name_t array_name;
|
||||||
array_name.push_back(name_component_t(array_var_));
|
array_name.push_back(name_component_t(array_var_));
|
||||||
NetNet*array_sig = des->find_signal(scope, array_name);
|
NetNet*array_sig = des->find_signal(scope, array_name);
|
||||||
|
|
||||||
|
if (array_sig == 0) {
|
||||||
|
cerr << get_fileline() << ": error:"
|
||||||
|
<< " Unable to find " << array_name
|
||||||
|
<< " in scope " << scope_path(scope)
|
||||||
|
<< "." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
ivl_assert(*this, array_sig);
|
ivl_assert(*this, array_sig);
|
||||||
|
|
||||||
if (debug_elaborate) {
|
if (debug_elaborate) {
|
||||||
|
|
|
||||||
|
|
@ -139,7 +139,7 @@ void NetForLoop::wrap_up()
|
||||||
NetBlock*internal_block = new NetBlock(NetBlock::SEQU, 0);
|
NetBlock*internal_block = new NetBlock(NetBlock::SEQU, 0);
|
||||||
internal_block->set_line(*this);
|
internal_block->set_line(*this);
|
||||||
|
|
||||||
internal_block->append(statement_);
|
if (statement_) internal_block->append(statement_);
|
||||||
internal_block->append(step_statement_);
|
internal_block->append(step_statement_);
|
||||||
|
|
||||||
NetWhile*wloop = new NetWhile(condition_, internal_block);
|
NetWhile*wloop = new NetWhile(condition_, internal_block);
|
||||||
|
|
|
||||||
75
netmisc.cc
75
netmisc.cc
|
|
@ -22,6 +22,7 @@
|
||||||
# include <cstdlib>
|
# include <cstdlib>
|
||||||
# include <climits>
|
# include <climits>
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
|
# include "netparray.h"
|
||||||
# include "netvector.h"
|
# include "netvector.h"
|
||||||
# include "netmisc.h"
|
# include "netmisc.h"
|
||||||
# include "PExpr.h"
|
# include "PExpr.h"
|
||||||
|
|
@ -526,10 +527,8 @@ static void make_strides(const vector<netrange_t>&dims,
|
||||||
* word. If any of the indices are out of bounds, return nil instead
|
* word. If any of the indices are out of bounds, return nil instead
|
||||||
* of an expression.
|
* of an expression.
|
||||||
*/
|
*/
|
||||||
NetExpr* normalize_variable_unpacked(const NetNet*net, list<long>&indices)
|
static NetExpr* normalize_variable_unpacked(const vector<netrange_t>&dims, list<long>&indices)
|
||||||
{
|
{
|
||||||
const vector<netrange_t>&dims = net->unpacked_dims();
|
|
||||||
|
|
||||||
// Make strides for each index. The stride is the distance (in
|
// Make strides for each index. The stride is the distance (in
|
||||||
// words) to the next element in the canonical array.
|
// words) to the next element in the canonical array.
|
||||||
vector<long> stride (dims.size());
|
vector<long> stride (dims.size());
|
||||||
|
|
@ -559,10 +558,20 @@ NetExpr* normalize_variable_unpacked(const NetNet*net, list<long>&indices)
|
||||||
return canonical_expr;
|
return canonical_expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetExpr* normalize_variable_unpacked(const NetNet*net, list<NetExpr*>&indices)
|
NetExpr* normalize_variable_unpacked(const NetNet*net, list<long>&indices)
|
||||||
{
|
{
|
||||||
const vector<netrange_t>&dims = net->unpacked_dims();
|
const vector<netrange_t>&dims = net->unpacked_dims();
|
||||||
|
return normalize_variable_unpacked(dims, indices);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetExpr* normalize_variable_unpacked(const netsarray_t*stype, list<long>&indices)
|
||||||
|
{
|
||||||
|
const vector<netrange_t>&dims = stype->static_dimensions();
|
||||||
|
return normalize_variable_unpacked(dims, indices);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetExpr* normalize_variable_unpacked(const LineInfo&loc, const vector<netrange_t>&dims, list<NetExpr*>&indices)
|
||||||
|
{
|
||||||
// Make strides for each index. The stride is the distance (in
|
// Make strides for each index. The stride is the distance (in
|
||||||
// words) to the next element in the canonical array.
|
// words) to the next element in the canonical array.
|
||||||
vector<long> stride (dims.size());
|
vector<long> stride (dims.size());
|
||||||
|
|
@ -602,7 +611,7 @@ NetExpr* normalize_variable_unpacked(const NetNet*net, list<NetExpr*>&indices)
|
||||||
if (use_stride != 1)
|
if (use_stride != 1)
|
||||||
min_wid += num_bits(use_stride);
|
min_wid += num_bits(use_stride);
|
||||||
|
|
||||||
tmp = pad_to_width(tmp, min_wid, *net);
|
tmp = pad_to_width(tmp, min_wid, loc);
|
||||||
|
|
||||||
// Now generate the math to calculate the canonical address.
|
// Now generate the math to calculate the canonical address.
|
||||||
NetExpr*tmp_scaled = 0;
|
NetExpr*tmp_scaled = 0;
|
||||||
|
|
@ -641,11 +650,23 @@ NetExpr* normalize_variable_unpacked(const NetNet*net, list<NetExpr*>&indices)
|
||||||
// If we don't have an expression at this point, all the indices were
|
// If we don't have an expression at this point, all the indices were
|
||||||
// constant zero. But this variant of normalize_variable_unpacked()
|
// constant zero. But this variant of normalize_variable_unpacked()
|
||||||
// is only used when at least one index is not a constant.
|
// is only used when at least one index is not a constant.
|
||||||
ivl_assert(*net, canonical_expr);
|
ivl_assert(loc, canonical_expr);
|
||||||
|
|
||||||
return canonical_expr;
|
return canonical_expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NetExpr* normalize_variable_unpacked(const NetNet*net, list<NetExpr*>&indices)
|
||||||
|
{
|
||||||
|
const vector<netrange_t>&dims = net->unpacked_dims();
|
||||||
|
return normalize_variable_unpacked(*net, dims, indices);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetExpr* normalize_variable_unpacked(const LineInfo&loc, const netsarray_t*stype, list<NetExpr*>&indices)
|
||||||
|
{
|
||||||
|
const vector<netrange_t>&dims = stype->static_dimensions();
|
||||||
|
return normalize_variable_unpacked(loc, dims, indices);
|
||||||
|
}
|
||||||
|
|
||||||
NetEConst* make_const_x(unsigned long wid)
|
NetEConst* make_const_x(unsigned long wid)
|
||||||
{
|
{
|
||||||
verinum xxx (verinum::Vx, wid);
|
verinum xxx (verinum::Vx, wid);
|
||||||
|
|
@ -885,6 +906,48 @@ NetExpr* elab_sys_task_arg(Design*des, NetScope*scope, perm_string name,
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool evaluate_ranges(Design*des, NetScope*scope,
|
||||||
|
vector<netrange_t>&llist,
|
||||||
|
const list<pform_range_t>&rlist)
|
||||||
|
{
|
||||||
|
bool bad_msb = false, bad_lsb = false;
|
||||||
|
|
||||||
|
for (list<pform_range_t>::const_iterator cur = rlist.begin()
|
||||||
|
; cur != rlist.end() ; ++cur) {
|
||||||
|
long use_msb, use_lsb;
|
||||||
|
|
||||||
|
NetExpr*texpr = elab_and_eval(des, scope, cur->first, -1, true);
|
||||||
|
if (! eval_as_long(use_msb, texpr)) {
|
||||||
|
cerr << cur->first->get_fileline() << ": error: "
|
||||||
|
"Range expressions must be constant." << endl;
|
||||||
|
cerr << cur->first->get_fileline() << " : "
|
||||||
|
"This MSB expression violates the rule: "
|
||||||
|
<< *cur->first << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
bad_msb = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete texpr;
|
||||||
|
|
||||||
|
texpr = elab_and_eval(des, scope, cur->second, -1, true);
|
||||||
|
if (! eval_as_long(use_lsb, texpr)) {
|
||||||
|
cerr << cur->second->get_fileline() << ": error: "
|
||||||
|
"Range expressions must be constant." << endl;
|
||||||
|
cerr << cur->second->get_fileline() << " : "
|
||||||
|
"This LSB expression violates the rule: "
|
||||||
|
<< *cur->second << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
bad_lsb = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete texpr;
|
||||||
|
|
||||||
|
llist.push_back(netrange_t(use_msb, use_lsb));
|
||||||
|
}
|
||||||
|
|
||||||
|
return bad_msb | bad_lsb;
|
||||||
|
}
|
||||||
|
|
||||||
void eval_expr(NetExpr*&expr, int context_width)
|
void eval_expr(NetExpr*&expr, int context_width)
|
||||||
{
|
{
|
||||||
assert(expr);
|
assert(expr);
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@
|
||||||
|
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
|
|
||||||
|
class netsarray_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Search for a symbol using the "start" scope as the starting
|
* Search for a symbol using the "start" scope as the starting
|
||||||
* point. If the path includes a scope part, then locate the
|
* point. If the path includes a scope part, then locate the
|
||||||
|
|
@ -184,7 +186,10 @@ extern void indices_to_expressions(Design*des, NetScope*scope,
|
||||||
list<NetExpr*>&indices,list<long>&indices_const);
|
list<NetExpr*>&indices,list<long>&indices_const);
|
||||||
|
|
||||||
extern NetExpr*normalize_variable_unpacked(const NetNet*net, list<long>&indices);
|
extern NetExpr*normalize_variable_unpacked(const NetNet*net, list<long>&indices);
|
||||||
|
extern NetExpr*normalize_variable_unpacked(const netsarray_t*net, list<long>&indices);
|
||||||
|
|
||||||
extern NetExpr*normalize_variable_unpacked(const NetNet*net, list<NetExpr*>&indices);
|
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);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function takes as input a NetNet signal and adds a constant
|
* This function takes as input a NetNet signal and adds a constant
|
||||||
|
|
@ -278,6 +283,9 @@ extern NetExpr* elaborate_rval_expr(Design*des, NetScope*scope,
|
||||||
unsigned lv_width, PExpr*expr,
|
unsigned lv_width, PExpr*expr,
|
||||||
bool need_const =false);
|
bool need_const =false);
|
||||||
|
|
||||||
|
extern bool evaluate_ranges(Design*des, NetScope*scope,
|
||||||
|
std::vector<netrange_t>&llist,
|
||||||
|
const std::list<pform_range_t>&rlist);
|
||||||
/*
|
/*
|
||||||
* This procedure evaluates an expression and if the evaluation is
|
* This procedure evaluates an expression and if the evaluation is
|
||||||
* successful the original expression is replaced with the new one.
|
* successful the original expression is replaced with the new one.
|
||||||
|
|
|
||||||
22
netparray.cc
22
netparray.cc
|
|
@ -22,6 +22,10 @@
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
netsarray_t::~netsarray_t()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
netparray_t::~netparray_t()
|
netparray_t::~netparray_t()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -34,8 +38,8 @@ long netparray_t::packed_width(void) const
|
||||||
{
|
{
|
||||||
long cur_width = element_type()->packed_width();
|
long cur_width = element_type()->packed_width();
|
||||||
|
|
||||||
for (vector<netrange_t>::const_iterator cur = packed_dims_.begin()
|
for (vector<netrange_t>::const_iterator cur = static_dimensions().begin()
|
||||||
; cur != packed_dims_.end() ; ++cur) {
|
; cur != static_dimensions().end() ; ++cur) {
|
||||||
cur_width *= cur->width();
|
cur_width *= cur->width();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -44,14 +48,20 @@ long netparray_t::packed_width(void) const
|
||||||
|
|
||||||
vector<netrange_t> netparray_t::slice_dimensions() const
|
vector<netrange_t> netparray_t::slice_dimensions() const
|
||||||
{
|
{
|
||||||
|
const vector<netrange_t>&packed_dims = static_dimensions();
|
||||||
|
|
||||||
vector<netrange_t> elem_dims = element_type()->slice_dimensions();
|
vector<netrange_t> elem_dims = element_type()->slice_dimensions();
|
||||||
|
|
||||||
vector<netrange_t> res (packed_dims_.size() + elem_dims.size());
|
vector<netrange_t> res (packed_dims.size() + elem_dims.size());
|
||||||
|
|
||||||
for (size_t idx = 0 ; idx < packed_dims_.size() ; idx += 1)
|
for (size_t idx = 0 ; idx < packed_dims.size() ; idx += 1)
|
||||||
res[idx] = packed_dims_[idx];
|
res[idx] = packed_dims[idx];
|
||||||
for (size_t idx = 0 ; idx < elem_dims.size() ; idx += 1)
|
for (size_t idx = 0 ; idx < elem_dims.size() ; idx += 1)
|
||||||
res[idx+packed_dims_.size()] = elem_dims[idx];
|
res[idx+packed_dims.size()] = elem_dims[idx];
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
netuarray_t::~netuarray_t()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
|
||||||
57
netparray.h
57
netparray.h
|
|
@ -23,10 +23,39 @@
|
||||||
# include "nettypes.h"
|
# include "nettypes.h"
|
||||||
# include <vector>
|
# include <vector>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Arrays with static dimensions (packed and unpacked) share this
|
||||||
|
* common base type.
|
||||||
|
*/
|
||||||
|
class netsarray_t : public netarray_t {
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit netsarray_t(const std::vector<netrange_t>&packed,
|
||||||
|
ivl_type_t etype);
|
||||||
|
~netsarray_t();
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Virtual methods from the ivl_type_s type...
|
||||||
|
|
||||||
|
public:
|
||||||
|
inline const std::vector<netrange_t>& static_dimensions() const
|
||||||
|
{ return dims_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<netrange_t> dims_;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
inline netsarray_t::netsarray_t(const std::vector<netrange_t>&pd,
|
||||||
|
ivl_type_t etype)
|
||||||
|
: netarray_t(etype), dims_(pd)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Packed arrays.
|
* Packed arrays.
|
||||||
*/
|
*/
|
||||||
class netparray_t : public netarray_t {
|
class netparray_t : public netsarray_t {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit netparray_t(const std::vector<netrange_t>&packed,
|
explicit netparray_t(const std::vector<netrange_t>&packed,
|
||||||
|
|
@ -38,18 +67,28 @@ class netparray_t : public netarray_t {
|
||||||
long packed_width(void) const;
|
long packed_width(void) const;
|
||||||
std::vector<netrange_t> slice_dimensions() const;
|
std::vector<netrange_t> slice_dimensions() const;
|
||||||
|
|
||||||
public:
|
|
||||||
inline const std::vector<netrange_t>& packed_dimensions() const
|
|
||||||
{ return packed_dims_; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<netrange_t> packed_dims_;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline netparray_t::netparray_t(const std::vector<netrange_t>&pd,
|
inline netparray_t::netparray_t(const std::vector<netrange_t>&pd,
|
||||||
ivl_type_t etype)
|
ivl_type_t etype)
|
||||||
: netarray_t(etype), packed_dims_(pd)
|
: netsarray_t(pd, etype)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unpacked arrays are very similar, but lack packed slices.
|
||||||
|
*/
|
||||||
|
class netuarray_t : public netsarray_t {
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit netuarray_t(const std::vector<netrange_t>&packed,
|
||||||
|
ivl_type_t etype);
|
||||||
|
~netuarray_t();
|
||||||
|
};
|
||||||
|
|
||||||
|
inline netuarray_t::netuarray_t(const std::vector<netrange_t>&pd,
|
||||||
|
ivl_type_t etype)
|
||||||
|
: netsarray_t(pd, etype)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue