Support assignment of parray slices (issue #1256)
The existing elaboration code only allowed assignments from/to individual elements and either failed an assertion (when assigning the entire array) or failed to compile (when assigning an array slice).
This commit is contained in:
parent
f82c6c7b3a
commit
0ecb71625b
21
elab_expr.cc
21
elab_expr.cc
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999-2024 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1999-2025 Stephen Williams (steve@icarus.com)
|
||||||
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
|
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
|
|
@ -2585,14 +2585,21 @@ static NetExpr* check_for_struct_members(const LineInfo*li,
|
||||||
// variable, then stepping to the element type to
|
// variable, then stepping to the element type to
|
||||||
// possibly iterate through more of the member_path.
|
// possibly iterate through more of the member_path.
|
||||||
ivl_assert(*li, array->packed());
|
ivl_assert(*li, array->packed());
|
||||||
ivl_assert(*li, !member_comp.index.empty());
|
|
||||||
|
// We only need to process this if there are any
|
||||||
|
// index expressions. If not, then the packed
|
||||||
|
// array can be handled atomically.
|
||||||
|
if (member_comp.index.empty()) {
|
||||||
|
struct_type = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// These are the dimensions defined by the type
|
// These are the dimensions defined by the type
|
||||||
const netranges_t&mem_packed_dims = array->static_dimensions();
|
const netranges_t&mem_packed_dims = array->static_dimensions();
|
||||||
|
|
||||||
if (member_comp.index.size() != mem_packed_dims.size()) {
|
if (member_comp.index.size() > mem_packed_dims.size()) {
|
||||||
cerr << li->get_fileline() << ": error: "
|
cerr << li->get_fileline() << ": error: "
|
||||||
<< "Incorrect number of index expressions for member "
|
<< "Too many index expressions for member "
|
||||||
<< member_name << "." << endl;
|
<< member_name << "." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -2634,11 +2641,9 @@ static NetExpr* check_for_struct_members(const LineInfo*li,
|
||||||
|
|
||||||
// The width and offset calculated from the
|
// The width and offset calculated from the
|
||||||
// indices is actually in elements, and not
|
// indices is actually in elements, and not
|
||||||
// bits. In fact, in this context, the lwid should
|
// bits.
|
||||||
// come down to 1 (one element).
|
|
||||||
off += loff * element_width;
|
off += loff * element_width;
|
||||||
ivl_assert(*li, lwid==1);
|
use_width = lwid * element_width;
|
||||||
use_width = element_width;
|
|
||||||
|
|
||||||
// To move on to the next component in the member
|
// To move on to the next component in the member
|
||||||
// path, get the element type. For example, for
|
// path, get the element type. For example, for
|
||||||
|
|
|
||||||
18
elab_lval.cc
18
elab_lval.cc
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000-2024 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2000-2025 Stephen Williams (steve@icarus.com)
|
||||||
* Copyright CERN 2012-2013 / Stephen Williams (steve@icarus.com)
|
* Copyright CERN 2012-2013 / Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
|
|
@ -1445,14 +1445,18 @@ bool PEIdent::elaborate_lval_net_packed_member_(Design*des, NetScope*scope,
|
||||||
// possibly iterate through more of the member_path.
|
// possibly iterate through more of the member_path.
|
||||||
|
|
||||||
ivl_assert(*this, array->packed());
|
ivl_assert(*this, array->packed());
|
||||||
ivl_assert(*this, !member_comp.index.empty());
|
|
||||||
|
if (member_comp.index.empty()) {
|
||||||
|
struct_type = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// These are the dimensions defined by the type
|
// These are the dimensions defined by the type
|
||||||
const netranges_t&mem_packed_dims = array->static_dimensions();
|
const netranges_t&mem_packed_dims = array->static_dimensions();
|
||||||
|
|
||||||
if (member_comp.index.size() != mem_packed_dims.size()) {
|
if (member_comp.index.size() > mem_packed_dims.size()) {
|
||||||
cerr << get_fileline() << ": error: "
|
cerr << get_fileline() << ": error: "
|
||||||
<< "Incorrect number of index expressions for member "
|
<< "Too many index expressions for member "
|
||||||
<< member_name << "." << endl;
|
<< member_name << "." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -1502,11 +1506,9 @@ bool PEIdent::elaborate_lval_net_packed_member_(Design*des, NetScope*scope,
|
||||||
|
|
||||||
// The width and offset calculated from the
|
// The width and offset calculated from the
|
||||||
// indices is actually in elements, and not
|
// indices is actually in elements, and not
|
||||||
// bits. In fact, in this context, the lwid should
|
// bits.
|
||||||
// come down to 1 (one element).
|
|
||||||
off += loff * element_width;
|
off += loff * element_width;
|
||||||
ivl_assert(*this, lwid==1);
|
use_width = lwid * element_width;
|
||||||
use_width = element_width;
|
|
||||||
|
|
||||||
// To move on to the next component in the member
|
// To move on to the next component in the member
|
||||||
// path, get the element type. For example, for
|
// path, get the element type. For example, for
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue