Rounding issue for `vasub(u).(vv|vx)`
Hi @michael-platzer,
Issue
I think there is a problem with the computation of the averaging subtract (vasub(u).(vv|vx)) instructions.
For example, when executing the instruction vasub.vv v22, v14, v9 with SEW=8, LMUL=1/4, VL=8 and VXRM=0 (round-to-nearest-up) the following warning pops up in the UVM environment:
# UVM_WARNING cvxif_scoreboard.svh(412) @ 15740: uvm_test_top.env.scoreboard [CVXIF_SCOREBOARD] Instr "vasub.vv v22, v14, v9 mf4, tu, mu" with id = 5 in Prog "vxrm_problem" failed:
# at 15740 ns:
# State Difference
# ref.vproc_register[22]: 7638ad74df266c62c9f2dff8998e21bd22d914e457b59c602b4acff31eb7df20, dut.vproc_reg[22]: 7638ad74df266c62c9f2dff8998e21bd22d914e457b59c602b4acef31eb6df1f
from this warning one can see that for example element 0 of the result vector should be equal to 0x20 but Vicuna calculates 0x1f.
If we do the calculation by hand we see that the correct value should be 0x20:
0xDA (binary: 0b1101_1010, decimal: - 38) (element 0 in vector v14)
-0x9A (binary: 0b1001_1010, decimal: -102) (element 0 in vector v9)
=0x40 (binary: 0b0100_0000, decimal: 64)
Since we have averaging subtract (with rounding mode round-to-nearest-up) we need to shift the result to the right by one bit and add the LSB (LSB of the "unshifted" result) to the shifted value. (Here the LSB is 0).
0b0100_0000 >> 1
=0b0010_0000
=0x20
Sidenote
I think this issue is not specific to this particular rounding-mode. From what I have seen, Vicunas result is almost always one off the correct result for these instructions.
How to reproduce
You can reproduce this issue by running the cvxif_test_direct_issue_96 in the UVM environment.
Important note: I had to add some functionality to spike, so before running this test, you need to apply the newest patch to spike and install spike again.