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:
Martin Whitaker 2025-07-05 18:02:40 +01:00
parent f82c6c7b3a
commit 0ecb71625b
2 changed files with 23 additions and 16 deletions

View File

@ -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)
*
* 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
// possibly iterate through more of the member_path.
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
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: "
<< "Incorrect number of index expressions for member "
<< "Too many index expressions for member "
<< member_name << "." << endl;
des->errors += 1;
return 0;
@ -2634,11 +2641,9 @@ static NetExpr* check_for_struct_members(const LineInfo*li,
// The width and offset calculated from the
// indices is actually in elements, and not
// bits. In fact, in this context, the lwid should
// come down to 1 (one element).
// bits.
off += loff * element_width;
ivl_assert(*li, lwid==1);
use_width = element_width;
use_width = lwid * element_width;
// To move on to the next component in the member
// path, get the element type. For example, for

View File

@ -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)
*
* 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.
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
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: "
<< "Incorrect number of index expressions for member "
<< "Too many index expressions for member "
<< member_name << "." << endl;
des->errors += 1;
return false;
@ -1502,11 +1506,9 @@ bool PEIdent::elaborate_lval_net_packed_member_(Design*des, NetScope*scope,
// The width and offset calculated from the
// indices is actually in elements, and not
// bits. In fact, in this context, the lwid should
// come down to 1 (one element).
// bits.
off += loff * element_width;
ivl_assert(*this, lwid==1);
use_width = element_width;
use_width = lwid * element_width;
// To move on to the next component in the member
// path, get the element type. For example, for