I've got a register declared as so:
logic signed [15:0][2:0][15:0] registers;
When I place a 2's compliment number into the array and arithmetically shift the number, it logical shifts instead:
registers[0][0] = 16'b1000000000000000;
registers[0][0] = registers[0][0]>>>2;
Apparently, the system will logical shift instead of arithmetically shift if the number is not signed. However as you can clearly see, 'registers' is definitely signed.
Does anybody know what I might be missing here?
Thanks!
An arithmetic right shift means that the sign bit is extended to fill the upper bits, whereas a logical right shift uses zeroes to fill the upper bits. The register 's value, modulus the register size (32 or 64), is used as the shift amount. The operation rotates n bits to the right. Those bits “wrap around” and are shifted into the upper bits.
For example :Arithmetic Shift. an micro operations that specify a 1-bit shift to left of content of register R1 and 1-bit shift to right of content of register R2. The left most bit is a register that holds sign bit and remaining bits and remaining bits hold the number.
Logical shift. 1. An arithmetic shift via micro operation that shifts a signed binary number to the left and right. A logical shift is one that transforms through the serial input. 2. An arithmetic shift left multiplies assigned binary number by. An arithmetic shift right divides number by 2.
However, care must be taken to ensure that an arithmetic shift is used if the dividend is a signed two's complement number, and a logical shift is used if the dividend is unsigned. The algorithm for dividing binary numbers is somewhat more complicated than the algorithm for multiplication.
With Verilog, once you take a part-select, the result is unsigned
. Use the $signed
system task on the part select to make it signed.
res = $signed(registers[0][0]) >>> 2;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With