What is the difference between >>
and >>>
in verilog/system verilog? I know that ==
tests for only 1 and 0, while ===
tests for 1, 0, X, Z. So how is that similar to the shift operator?
It is not similar to ==
/===
, if the left hand operand is signed then >>>
performs sign extension.
reg signed [9:0] b = 10'sb11_0101_0101;
reg signed [9:0] a_signed;
reg [9:0] a_unsigned;
always_comb begin
a_signed = b >>> 2;
a_unsigned = b >> 2;
end
Result:
#a_signed 1111010101
#a_unsigned 0011010101
Example on EDA Playground.
-
2\$\begingroup\$ Wow, that is exactly the opposite of the meanings of the Java
>>
and>>>
operators... wicked. \$\endgroup\$ – Colin D Bennett Oct 11 '14 at 7:23 -
2
-
1\$\begingroup\$ @dave_59, but signed values (aside from the 32-bit
integer
type) and the arithmetic shift operators were only introduced to Verilog in Verilog-2001. \$\endgroup\$ – The Photon Jan 19 '19 at 22:15 -
1\$\begingroup\$ Verilog already had
>>
to mean logical shift in 1985 (taken from Pascal, which is from 1970). So it had to use>>>
for arithmetic shift. \$\endgroup\$ – dave_59 Jan 20 '19 at 2:11
According to IEEE1800-2012 >>
is a binary logical shift, while >>>
is a binary arithmetic shift.
Basically, arithmetic shift uses context to determine the fill bits, so:
- arithmetic right shift (
>>>
) - shift right specified number of bits, fill with value of sign bit if expression is signed, otherwise fill with zero, - arithmetic left shift (
<<<
) - shift left specified number of bits, fill with zero.
On the other hand, logical shift (<<
, >>
) always fill the vacated bit positions with zeroes.
For example:
a = 5'b10100;
b = a <<< 2; //b == 5'b10000
c = a >>> 2; //c == 5'b11101, 'cause sign bit was `1`
d = a << 2; //d == 5'b10000
e = a >> 2; //e == 5'b00101
-
\$\begingroup\$ The results of this example depend on the declaration of
c
: if you usereg [4:0] c
, you'll get5'b00101
, not5'b11101
. Updating the example to clarify the types would be useful, I think. \$\endgroup\$ – Clément Feb 21 '20 at 14:06