Merge pull request #893 from larsclausen/array-assign-order

Connect continuous array assignments in the right order
This commit is contained in:
Cary R 2023-06-02 13:57:18 -07:00 committed by GitHub
commit 2e84766e79
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 239 additions and 8 deletions

View File

@ -0,0 +1,106 @@
0 6 0 1
0 6 1 2
0 6 2 3
0 6 3 4
0 6 4 5
0 5 0 6
0 5 1 7
0 5 2 8
0 5 3 9
0 5 4 10
0 4 0 11
0 4 1 12
0 4 2 13
0 4 3 14
0 4 4 15
0 3 0 16
0 3 1 17
0 3 2 18
0 3 3 19
0 3 4 20
0 2 0 21
0 2 1 22
0 2 2 23
0 2 3 24
0 2 4 25
0 1 0 26
0 1 1 27
0 1 2 28
0 1 3 29
0 1 4 30
0 0 0 31
0 0 1 32
0 0 2 33
0 0 3 34
0 0 4 35
1 6 0 36
1 6 1 37
1 6 2 38
1 6 3 39
1 6 4 40
1 5 0 41
1 5 1 42
1 5 2 43
1 5 3 44
1 5 4 45
1 4 0 46
1 4 1 47
1 4 2 48
1 4 3 49
1 4 4 50
1 3 0 51
1 3 1 52
1 3 2 53
1 3 3 54
1 3 4 55
1 2 0 56
1 2 1 57
1 2 2 58
1 2 3 59
1 2 4 60
1 1 0 61
1 1 1 62
1 1 2 63
1 1 3 64
1 1 4 65
1 0 0 66
1 0 1 67
1 0 2 68
1 0 3 69
1 0 4 70
2 6 0 71
2 6 1 72
2 6 2 73
2 6 3 74
2 6 4 75
2 5 0 76
2 5 1 77
2 5 2 78
2 5 3 79
2 5 4 80
2 4 0 81
2 4 1 82
2 4 2 83
2 4 3 84
2 4 4 85
2 3 0 86
2 3 1 87
2 3 2 88
2 3 3 89
2 3 4 90
2 2 0 91
2 2 1 92
2 2 2 93
2 2 3 94
2 2 4 95
2 1 0 96
2 1 1 97
2 1 2 98
2 1 3 99
2 1 4 100
2 0 0 101
2 0 1 102
2 0 2 103
2 0 3 104
2 0 4 105
PASSED

View File

@ -0,0 +1,21 @@
// Check that continuous array assignment behaves correctly when left-to-right
// order is reversed.
module test;
wire [31:0] x[1:0];
wire [31:0] y[0:1];
assign x[0] = 1;
assign x[1] = 2;
assign y = x;
final begin
if (y[0] === 2 || y[1] === 1) begin
$display("PASSED");
end else begin
$display("FAILED");
end
end
endmodule

View File

@ -0,0 +1,37 @@
// Check that continuous array assignment for multi-dimensional arrays behaves
// correctly when left-to-right order is reversed.
module test;
logic [31:0] x[2:0][6:0][4:0];
wire [31:0] y[0:2][6:0][0:4];
assign y = x;
initial begin
static integer idx = 1;
static bit failed = 1'b0;
foreach (x[i,j,k]) begin
x[i][j][k] = idx;
idx++;
end
#1
idx = 1;
foreach (y[i,j,k]) begin
$display(i, j, k, y[i][j][k]);
if (y[i][j][k] !== idx) begin
$display("FAILED");
failed = 1'b1;
end
idx++;
end
if (!failed) begin
$display("PASSED");
end
end
endmodule

View File

@ -33,6 +33,8 @@ pr903 vvp_tests/pr903.json
pr903-vlog95 vvp_tests/pr903-vlog95.json pr903-vlog95 vvp_tests/pr903-vlog95.json
struct_packed_write_read vvp_tests/struct_packed_write_read.json struct_packed_write_read vvp_tests/struct_packed_write_read.json
struct_packed_write_read2 vvp_tests/struct_packed_write_read2.json struct_packed_write_read2 vvp_tests/struct_packed_write_read2.json
sv_array_cassign6 vvp_tests/sv_array_cassign6.json
sv_array_cassign7 vvp_tests/sv_array_cassign7.json
sv_foreach9 vvp_tests/sv_foreach9.json sv_foreach9 vvp_tests/sv_foreach9.json
sv_foreach10 vvp_tests/sv_foreach10.json sv_foreach10 vvp_tests/sv_foreach10.json
sdf_header vvp_tests/sdf_header.json sdf_header vvp_tests/sdf_header.json

View File

@ -0,0 +1,5 @@
{
"type" : "normal",
"source" : "sv_array_cassign6.v",
"iverilog-args" : [ "-g2009" ]
}

View File

@ -0,0 +1,6 @@
{
"type" : "normal",
"source" : "sv_array_cassign7.v",
"iverilog-args" : [ "-g2009" ],
"gold" : "sv_array_cassign7"
}

View File

@ -1628,21 +1628,75 @@ NetExpr*collapse_array_indices(Design*des, NetScope*scope, NetNet*net,
return res; return res;
} }
static void assign_unpacked_with_bufz_dim(Design *des, NetScope *scope,
const LineInfo *loc,
NetNet *lval, NetNet *rval,
const std::vector<long> &stride,
unsigned int dim = 0,
unsigned int idx_l = 0,
unsigned int idx_r = 0)
{
int inc_l, inc_r;
bool up_l, up_r;
const auto &l_dims = lval->unpacked_dims();
const auto &r_dims = rval->unpacked_dims();
up_l = l_dims[dim].get_msb() < l_dims[dim].get_lsb();
up_r = r_dims[dim].get_msb() < r_dims[dim].get_lsb();
inc_l = inc_r = stride[dim];
/*
* Arrays dimensions get connected left-to-right. This means if the
* left-to-right order differs for a particular dimension between the two
* arrays the elements for that dimension will get connected in reverse
* order.
*/
if (!up_l) {
/* Go to the last element and count down */
idx_l += inc_l * (l_dims[dim].width() - 1);
inc_l = -inc_l;
}
if (!up_r) {
/* Go to the last element and count down */
idx_r += inc_r * (r_dims[dim].width() - 1);
inc_r = -inc_r;
}
for (unsigned int idx = 0; idx < l_dims[dim].width(); idx++) {
if (dim == l_dims.size() - 1) {
NetBUFZ *driver = new NetBUFZ(scope, scope->local_symbol(),
lval->vector_width(), false);
driver->set_line(*loc);
des->add_node(driver);
connect(lval->pin(idx_l), driver->pin(0));
connect(driver->pin(1), rval->pin(idx_r));
} else {
assign_unpacked_with_bufz_dim(des, scope, loc, lval, rval,
stride, dim + 1, idx_l, idx_r);
}
idx_l += inc_l;
idx_r += inc_r;
}
}
void assign_unpacked_with_bufz(Design*des, NetScope*scope, void assign_unpacked_with_bufz(Design*des, NetScope*scope,
const LineInfo*loc, const LineInfo*loc,
NetNet*lval, NetNet*rval) NetNet*lval, NetNet*rval)
{ {
ivl_assert(*loc, lval->pin_count()==rval->pin_count()); ivl_assert(*loc, lval->pin_count()==rval->pin_count());
for (unsigned idx = 0 ; idx < lval->pin_count() ; idx += 1) { const auto &dims = lval->unpacked_dims();
NetBUFZ*driver = new NetBUFZ(scope, scope->local_symbol(), vector<long> stride(dims.size());
lval->vector_width(), false);
driver->set_line(*loc);
des->add_node(driver);
connect(lval->pin(idx), driver->pin(0)); make_strides(dims, stride);
connect(driver->pin(1), rval->pin(idx)); assign_unpacked_with_bufz_dim(des, scope, loc, lval, rval, stride);
}
} }
/* /*