-
Notifications
You must be signed in to change notification settings - Fork 48
Error in implementation of SRAW and SRAIW instructions #95
Description
Hi,
I found inconsistent results when using the shift instructions sraw and sraiw. These 64-bit-specific instructions perform the shift on the right-hand 32-bit part of the word and propagate the sign of this 32-bit word to all bits, those added on the left-hand side of the 32-bit word as well as on the left-hand 32-bit part of the 64-bit word.
The current implementation doesn't seem to manage the propagation of this sign, which corresponds to the 32nd bit of the 64-bit word.
An example of the result for a 3-bit arithmetic right shift on 32-bit word in RV64I (the 32th bit is 0 and noted between parenthesis in unsigned binary representation) :
input : -11110001111000111101001001011001101010001100001111011011101
input length: 60
input unsigned binary : 11111000011100001110000101101101(0)0110010101110011110000100100011
input binary length : 64
output : 1110000000000000000000000000000000000110010101110011110000100100
output length : 64
As you could see "111" at the beginning should be "000" in the output.
A formal description of those instruction can be found here
https://github.com/SymbioticEDA/riscv-formal/blob/master/insns/insn_sraw.v
In the ShiftPlugin, the problem seems to be at line :
| val shifted = (S((SIGNED & ss.SRC1.msb) ## reversed) >> amplitude).resize(Global.XLEN bits) |
I think that a specific line when IS_W_RIGHT is true should be added :
shifted := (S((SIGNED & ss.SRC1(31)) ## reversed) >> amplitude).resize(width bits)
Vexiiriscv has the same issue.