beginner - question about comparing negative #'s in binary

The favorite HDL language in North America

beginner - question about comparing negative #'s in binary

Postby jwill » Tue Jun 08, 2010 12:29 am

I am making a range limiter with upper and lower boundaries. My code works for the most part. But when I am trying to compare negative numbers I don't get the correct output.

When I compare a negative number with the lower boundary I want to output -1 but that doesn't happen.

Can someone help me understand how this works ?

always @ (a)
begin

if (a >= 4'b0110) //4'b0110, 4 bit number = 6

y = 4'b1; //upper boundary

else if (a <= 4'b0011) //4'b0011 4 bit number = 3

y = 4'b1111; //4 bit number = -1; //bottom boundary

else

y = a; // if a is inbetween boundaries, output a
end


Thank you
jwill
 
Posts: 4
Joined: Sat Jun 05, 2010 5:31 pm

Postby Case23 » Tue Jun 08, 2010 8:51 am

hi,

i dont know much about verilog, but maybe you have to tell verilog that a and your literals are signed numbers. If verilog treats them as unsigned the behavior is correct.
Case23
 
Posts: 75
Joined: Wed May 19, 2004 9:41 am

Postby NickH » Tue Jun 08, 2010 10:52 am

Verilog has complicated rules about sign and size of numbers, which mostly "do the right thing" but occasionally do something unexpected. That's part of its charm :)

By default:
- reg and wire are unsigned
- sized constants (e.g. 4'b1111) are unsigned
- integer variables are signed
- sizeless constants (e.g. 123) are signed
- mixing signed and unsigned operands will silently cast to unsigned

Since Verilog 2001, you can get around these rules by making something explicitly signed, e.g.
- wire signed [3:0] foo = 4'sb1111;
or by using the $signed and $unsigned casting operators:
- if ($signed(a) >= 4'sb0110) y=4'b1;

But some people find that kind of thing awkward, and prefer to keep everything unsigned (like in Verilog-1995). If you choose that approach, then you'll need to construct your own explicit sign-extension and sign comparison where necessary, e.g.
- if (a[2:0] >= 3'b110 && !a[3]) y=4'b1.

Regards,

Nick
NickH
 
Posts: 88
Joined: Tue Sep 02, 2008 1:53 pm

Postby jwill » Tue Jun 08, 2010 3:19 pm

Case23 & NickH

I always thought that the values were unsigned by default but when I viewed my results using ModelSim the

- 4'b1111 read as a value of (-1), and thats what I wanted so I thought all of the values were signed. I remember defining values as (signed or unsigned) in VHDL but not in Verilog.

Thanks for the advice, I will give this a try.


JWill
jwill
 
Posts: 4
Joined: Sat Jun 05, 2010 5:31 pm

Postby jwill » Thu Jun 10, 2010 1:09 pm

I tried the sugestions that you gave me but I still recieved the same results.

To my understanding verilog operates using 2's compliment, and it is confirmed when look at the way the numbers are being represented. But when I compare Negative numbers I am still not getting the correct result.

For example

If I compare two positive numbers I get the correct result
A<B = ?
0100 (4) < 0110 (6) The result is true, correct
or
A<B =?
0110 (6) < 0100 (4) The result is false, correct

But when I compare a negave number I do not get the correct result

A<B = ?
1101(-3) < 0010 (2) The result is fales, Incorrect

Im not sure why this happens because as I mentioned, the numbers are being represented correctly, however they are not being evaluated correctly.

Can anyone help me understand why this is so?'

Thank you
JWill
jwill
 
Posts: 4
Joined: Sat Jun 05, 2010 5:31 pm

Postby NickH » Thu Jun 10, 2010 2:32 pm

Try this in your favourite simulator:

Code: Select all
module foo;

initial begin
   if (4'b1101  < 4'b0000)  $display("4'b1101  < 4'b0000");
   if (4'b1101  < 4'sb0000) $display("4'b1101  < 4'sb0000");
   if (4'sb1101 < 4'b0000)  $display("4'sb1101 < 4'b0000");
   if (4'sb1101 < 4'sb0000) $display("4'sb1101 < 4'sb0000");
end

endmodule


You should find that only the last one is true -- both operands have to be explicitly signed to make signed comparison work.

Nick
NickH
 
Posts: 88
Joined: Tue Sep 02, 2008 1:53 pm

Postby jwill » Fri Jun 18, 2010 11:32 am

Nick,

Thanks for the help, that works
jwill
 
Posts: 4
Joined: Sat Jun 05, 2010 5:31 pm


Return to Verilog HDL