14

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?

peterh
  • 638
  • 8
  • 25
daut
  • 151
  • 1
  • 1
  • 8

2 Answers2

16

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.

PeterJ
  • 17,131
  • 37
  • 56
  • 91
pre_randomize
  • 1,180
  • 6
  • 11
  • 2
    Wow, that is exactly the opposite of the meanings of the Java `>>` and `>>>` operators... wicked. – Colin D Bennett Oct 11 '14 at 07:23
  • 2
    Verilog was 10 years before Java. :P – dave_59 Oct 11 '14 at 15:49
  • 1
    @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. – The Photon Jan 19 '19 at 22:15
  • 1
    Verilog already had `>>` to mean logical shift in 1985 (taken from Pascal, which is from 1970). So it had to use `>>>` for arithmetic shift. – dave_59 Jan 20 '19 at 02:11
10

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
Qiu
  • 342
  • 1
  • 4
  • 13
  • 1
    The results of this example depend on the declaration of `c`: if you use `reg [4:0] c`, you'll get `5'b00101`, not `5'b11101`. Updating the example to clarify the types would be useful, I think. – Clément Feb 21 '20 at 14:06