aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDag Lem <dag@nimrod.no>2022-11-23 16:31:08 +0100
committerDag Lem <dag@nimrod.no>2022-11-23 16:31:08 +0100
commitddb12148e74ba898dcb3bc729db691090e1524a2 (patch)
tree2fb0db7359437dabfb9a5d2040f3458f04d613aa
parentbab88630c28b43851162772c2ce35666357d8933 (diff)
downloadyosys-ddb12148e74ba898dcb3bc729db691090e1524a2.tar.gz
yosys-ddb12148e74ba898dcb3bc729db691090e1524a2.tar.bz2
yosys-ddb12148e74ba898dcb3bc729db691090e1524a2.zip
Support for swapped ranges in second array dimension
-rw-r--r--frontends/ast/simplify.cc13
-rw-r--r--tests/svtypes/struct_array.sv42
2 files changed, 52 insertions, 3 deletions
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc
index 923aaa156..c8958c646 100644
--- a/frontends/ast/simplify.cc
+++ b/frontends/ast/simplify.cc
@@ -465,10 +465,17 @@ static AstNode *make_struct_index_range(AstNode *node, AstNode *rnode, int strid
}
}
-static AstNode *slice_range(AstNode *rnode, AstNode *snode)
+static AstNode *slice_range(AstNode *rnode, AstNode *snode, AstNode *member_node)
{
+ if (member_node->multirange_swapped[1]) {
+ // The second dimension has swapped range; swap index into the struct accordingly.
+ int msb = member_node->multirange_dimensions[1] - 1;
+ for (auto &expr : snode->children) {
+ expr = new AstNode(AST_SUB, node_int(msb), expr);
+ }
+ }
+
// apply the bit slice indicated by snode to the range rnode
- // TODO: Check for swapped indexes - see make_struct_index_range
log_assert(rnode->type==AST_RANGE);
auto left = rnode->children[0];
auto right = rnode->children[1];
@@ -504,7 +511,7 @@ AstNode *AST::make_struct_member_range(AstNode *node, AstNode *member_node)
auto mrnode = node->children[0];
auto element_range = make_struct_index_range(node, mrnode->children[0], stride, range_right, member_node);
// then apply bit slice range
- auto range = slice_range(element_range, mrnode->children[1]);
+ auto range = slice_range(element_range, mrnode->children[1], member_node);
delete element_range;
return range;
}
diff --git a/tests/svtypes/struct_array.sv b/tests/svtypes/struct_array.sv
index d33d18da2..e7d09b7c3 100644
--- a/tests/svtypes/struct_array.sv
+++ b/tests/svtypes/struct_array.sv
@@ -59,6 +59,27 @@ module top;
always_comb assert(s3==80'hFC00_4200_0012_3400_FFFC);
+ // Same as s3, but with little endian bit addressing
+ struct packed {
+ bit [0:7] [0:7] a; // 8 element packed array of bytes
+ bit [0:15] b; // filler for non-zero offset
+ } s3_b;
+
+ initial begin
+ s3_b = '0;
+
+ s3_b.a[5:6] = 16'h1234;
+ s3_b.a[2] = 8'h42;
+
+ s3_b.a[0] = '1;
+ s3_b.a[0][6:7] = '0;
+
+ s3_b.b = '1;
+ s3_b.b[14:15] = '0;
+ end
+
+ always_comb assert(s3_b==80'hFC00_4200_0012_3400_FFFC);
+
// Note that the tests below for unpacked arrays in structs rely on the
// fact that they are actually packed in Yosys.
@@ -104,6 +125,27 @@ module top;
always_comb assert(s5==80'hFC00_4200_0012_3400_FFFC);
+ // Same as s5, but with little endian bit addressing
+ struct packed {
+ bit [0:7] a [0:7]; // 8 element unpacked array of bytes
+ bit [0:15] b; // filler for non-zero offset
+ } s5_b;
+
+ initial begin
+ s5_b = '0;
+
+ s5_b.a[5:6] = 16'h1234;
+ s5_b.a[2] = 8'h42;
+
+ s5_b.a[0] = '1;
+ s5_b.a[0][6:7] = '0;
+
+ s5_b.b = '1;
+ s5_b.b[14:15] = '0;
+ end
+
+ always_comb assert(s5_b==80'hFC00_4200_0012_3400_FFFC);
+
// Same as s5, but using C-type unpacked array syntax
struct packed {
bit [7:0] a [8]; // 8 element unpacked array of bytes