Signed comparison in Verilog

时间:2023-03-09 15:41:01
Signed comparison in Verilog

Signed comparison in Verilog¶

When you write this in Verilog:

wire [7:0] a;
wire [7:0] b;
wire less;
assign less = (a < b);

the comparison between a and b is unsigned, that is a and b are numbers in the range 0-255. Writing this instead:

wire [7:0] a;
wire [7:0] b;
wire less;
assign less = ($signed(a) < $signed(b));

means that the comparison treats a and b as signed 8-bit numbers, which have a range of -128 to +127. Another way of writing the same thing is:

wire signed [7:0] a;
wire signed [7:0] b;
wire less;
assign less = (a < b);

A common operation on signed numbers is sign-extension.  Here’s an easy way of doing it:

wire [7:0] a;
wire [15:0] ax; // a sign-extended to 16-bit
assign ax = {{8{a[7]}}, a};

This works by concatenating 8 copies of a’s sign bit with a itself.

While it’s legal to write comparisons between values with different sizes and signednesses, the rules are so confusing that you’re better off converting the arguments explicitly beforehand.