Skip to content

Commit

Permalink
Merge pull request #930 from larsclausen/fix-fn-partial-oob-write
Browse files Browse the repository at this point in the history
Fix incorrect assert for partial oob write to function return value
  • Loading branch information
caryr authored Jun 11, 2023
2 parents bfba4bf + 4ab59dd commit bff9156
Show file tree
Hide file tree
Showing 6 changed files with 217 additions and 1 deletion.
99 changes: 99 additions & 0 deletions ivtest/ivltests/pv_wr_fn_vec2.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// Check that blocking partial writes to a 2-state vector function return value
// are correctly handled.

module test;

reg failed = 1'b0;

`define check(val, exp) \
if (exp !== val) begin \
$display("FAILED. Got %b, expected %b.", val, exp); \
failed = 1'b1; \
end

function bit [3:0] f;
integer i;

// Immediate index

// Within bounds
f = 'h0;
f[2:1] = 2'b10;
`check(f, 4'b0100)

// Partially oob at high and low side
f = 'h0;
f[4:-1] = 6'b101010;
`check(f, 4'b0101)
// Partially oob at low side
f = 'h0;
f[0:-1] = 2'b10;
`check(f, 4'b0001)
// Partially oob at high side
f = 'h0;
f[4:3] = 2'b01;
`check(f, 4'b1000)
// Fully oob at low side
f = 'h0;
f[-1:-2] = 2'b11;
`check(f, 4'b0000)
// Fully oob at high side
f = 'h0;
f[6:5] = 2'b11;
`check(f, 4'b0000)

// Variable index

// Within bounds
i = 1;
f = 'h0;
f[i+:2] = 2'b10;
`check(f, 4'b0100)

// Partially oob at high and low side
i = -1;
f = 'h0;
f[i+:6] = 6'b101010;
`check(f, 4'b0101)

// Partially oob at low side
i = -1;
f = 'h0;
f[i+:2] = 2'b10;
`check(f, 4'b0001)

// Partially oob at high side
i = 3;
f = 'h0;
f[i+:2] = 2'b01;
`check(f, 4'b1000)

// Fully oob at low side
i = -2;
f = 'h0;
f[i+:2] = 2'b11;
`check(f, 4'b0000)

// Fully oob at high side
i = 5;
f = 'h0;
f[i+:2] = 2'b11;
`check(f, 4'b0000)

// Undefined index
i = 'hx;
f = 'h0;
f[i+:2] = 2'b11;
`check(f, 4'b0000)
endfunction

initial begin
bit [3:0] x;
x = f();

if (!failed) begin
$display("PASSED");
end
end

endmodule
106 changes: 106 additions & 0 deletions ivtest/ivltests/pv_wr_fn_vec4.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// Check that blocking partial writes to a 4-state vector function return value
// are correctly handled.

module test;

reg failed = 1'b0;

`define check(val, exp) \
if (exp !== val) begin \
$display("FAILED. Got %b, expected %b.", val, exp); \
failed = 1'b1; \
end

integer i;

function reg [3:0] f(input reg unused);
begin
// Immediate index

// Within bounds
f = 'hx;
f[2:1] = 2'b10;
`check(f, 4'bx10x)

// Partially oob at high and low side
f = 'hx;
f[4:-1] = 6'b101010;
`check(f, 4'b0101)

// Partially oob at low side
f = 'hx;
f[0:-1] = 2'b10;
`check(f, 4'bxxx1)

// Partially oob at high side
f = 'hx;
f[4:3] = 2'b01;
`check(f, 4'b1xxx)

// Fully oob at low side
f = 'hx;
f[-1:-2] = 2'b11;
`check(f, 4'bxxxx)

// Fully oob at high side
f = 'hx;
f[6:5] = 2'b11;
`check(f, 4'bxxxx)

// Variable index

// Within bounds
i = 1;
f = 'hx;
f[i+:2] = 2'b10;
`check(f, 4'bx10x)

// Partially oob at high and low side
i = -1;
f = 'hx;
f[i+:6] = 6'b101010;
`check(f, 4'b0101)

// Partially oob at low side
i = -1;
f = 'hx;
f[i+:2] = 2'b10;
`check(f, 4'bxxx1)

// Partially oob at high side
i = 3;
f = 'hx;
f[i+:2] = 2'b01;
`check(f, 4'b1xxx)

// Fully oob at low side
i = -2;
f = 'hx;
f[i+:2] = 2'b11;
`check(f, 4'bxxxx)

// Fully oob at high side
i = 5;
f = 'hx;
f[i+:2] = 2'b11;
`check(f, 4'bxxxx)

// Undefined index
i = 'hx;
f = 'hx;
f[i+:2] = 2'b11;
`check(f, 4'bxxxx)
end
endfunction

reg [3:0] x;

initial begin
x = f(1'b0);

if (!failed) begin
$display("PASSED");
end
end

endmodule
2 changes: 2 additions & 0 deletions ivtest/regress-vvp.list
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ pr1388974 vvp_tests/pr1388974.json
pr1388974-vlog95 vvp_tests/pr1388974-vlog95.json
pr903 vvp_tests/pr903.json
pr903-vlog95 vvp_tests/pr903-vlog95.json
pv_wr_fn_vec2 vvp_tests/pv_wr_fn_vec2.json
pv_wr_fn_vec4 vvp_tests/pv_wr_fn_vec4.json
struct_packed_write_read vvp_tests/struct_packed_write_read.json
struct_packed_write_read2 vvp_tests/struct_packed_write_read2.json
sv_array_cassign6 vvp_tests/sv_array_cassign6.json
Expand Down
5 changes: 5 additions & 0 deletions ivtest/vvp_tests/pv_wr_fn_vec2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"type" : "normal",
"source" : "pv_wr_fn_vec2.v",
"iverilog-args" : [ "-g2009" ]
}
4 changes: 4 additions & 0 deletions ivtest/vvp_tests/pv_wr_fn_vec4.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"type" : "normal",
"source" : "pv_wr_fn_vec4.v"
}
2 changes: 1 addition & 1 deletion vvp/vthread.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5466,6 +5466,7 @@ bool of_RET_VEC4(vthread_t thr, vvp_code_t cp)

vthread_t fun_thr = get_func(thr);
assert(index < get_max(fun_thr, val));
assert(val.size() == wid);
unsigned depth = get_depth(fun_thr, index, val);

int64_t off = off_index ? thr->words[off_index].w_int : 0;
Expand All @@ -5485,7 +5486,6 @@ bool of_RET_VEC4(vthread_t thr, vvp_code_t cp)
fun_thr->parent->poke_vec4(depth, val);
} else {
vvp_vector4_t tmp_dst = fun_thr->parent->peek_vec4(depth);
assert(val.size() == wid);
tmp_dst.set_vec(off, val);
fun_thr->parent->poke_vec4(depth, tmp_dst);
}
Expand Down

0 comments on commit bff9156

Please sign in to comment.