signed wired bits calculation

Status
Not open for further replies.

kissmoh

Junior Member level 1
Joined
Jan 17, 2013
Messages
16
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Visit site
Activity points
1,443
im trying to make a simple code

Code:
// case 1
// w_buf_x : registered value


              localparam 
              threshold = 3'd2;

              reg [7:0] w_buf_0 [2:0];
              reg [7:0] w_buf_1 [2:0];
              reg [7:0] w_buf_2 [2:0];

	wire signed [8:0] s_0, s_1, s_2, s_3;

	assign s_0 = (w_buf_1[0] - w_buf_1[2] - threshold);			
	assign s_1 = (w_buf_2[0] - w_buf_0[2] - threshold);			
	assign s_2 = (w_buf_2[1] - w_buf_0[1] - threshold);
	assign s_3 = (w_buf_2[2] - w_buf_0[0] - threshold);

	assign r_0 = (s_0 > 0) ? 1'b1 : 0;
	assign r_1 = (s_1 > 0) ? 2'd2 : 0;
	assign r_2 = (s_2 > 0) ? 3'd4 : 0;
	assign r_3 = (s_3 > 0) ? 4'd8 : 0;

//case 2

	assign s_0 = (w_buf_1[0] - w_buf_1[2]);			
	assign s_1 = (w_buf_2[0] - w_buf_0[2]);			
	assign s_2 = (w_buf_2[1] - w_buf_0[1]);
	assign s_3 = (w_buf_2[2] - w_buf_0[0]);

	assign r_0 = (s_0 > threshold) ? 1'b1 : 0;
	assign r_1 = (s_1 > threshold) ? 2'd2 : 0;
	assign r_2 = (s_2 > threshold) ? 3'd4 : 0;
	assign r_3 = (s_3 > threshold) ? 4'd8 : 0;





assign result = r_0 + r_1 + r_2 + r_3;

i think the two cases work samely
but after implementing it, the results were different(this code is part of image processing module and the final result after passed other modules was checked through monitor)

is there any difference in that two case?
( other values execpt the s_x signal were unsigned value and the simulation using modelsim showed valid result) in that code
 

What kind of values did you supply from modelsim (i.e. was your test comprehensive enough)?

Did you examine the post synthesis schematic (Altera, Xilinx, and Synplify can all do this) for differences between the two implementations?

Regards
 



this is the simulation result, all values were represented as binary form

the s_3 is 111111000(thus negative), but the result r_3 is 1000, not 0000, what is the problem?
it seems that the value declared as signed, is treated as unsigned,
 
Last edited:

You have to be very careful when using signed arithmetic in Verilog and System Verilog. Unless you really understand the way the language treats signed values, and especially the way it treats combinations of signed and unsigned values, you can find many ways to hang yourself.

In your case, I would refer to section 11.4.4 of the Verilog/SystemVerilog Language Reference Manual. This section talks about relational operators(i.e. > and <).

Specifically:


So your comparison between s_3 (signed) and threshold (unsigned) is treated as an comparison between unsigned 111111000 and unsigned 00000010, which is true in your example , giving a result of 1000, as you saw.

Your comparison of s_3 to 0 in the first example might have been treated differently if 0 is treated as signed automatically (given 0 is a special case), but in general, integer constants like 2'h2 are considered unsigned.

If you are using System Verilog, you can cast threshold to be a signed value (i.e. signed'(threshold)) or you can use a signed constant like 3'sd2. I don't recall if vanilla Verilog can accept this syntax.

It would be a good idea to read the LRM or to search for Stuart Sutherlands excellent papers on verilog gotchas presented at the 2006 SNUG in Boston.

r.b.
 

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…