P
PCBman
Guest
I've written the following broken-code:
module v2001_practice;
reg signed [7:0] in_a, in_b;
wire signed [8:0] out_raw;
wire signed [7:0] out_c = out_raw; // truncate the upper bit!
wire signed [7:0] out_d; // <---- why does this guy truncate the result?!?
assign out_raw = (in_a + in_b)>>>1; // GOOD, correct 2's Complement result
assign out_d = (in_a + in_b)>>>1; // BAD, certain combos of in_a, in_b cause
truncated upper bit!
integer ectr, tctr;
initial begin
ectr = 0;
tctr = 0;
for ( in_a = -128; in_a < 127; in_a = in_a + 1 )
for ( in_b = -128; in_b < 127; in_b = in_b + 1 )
begin
#1;
if (out_c !== out_d)
begin
$display("ERROR, (%d+%d)>>>1 out_c(%d) !== out_d(%d)",
in_a, in_b, out_c, out_d );
ectr = ectr + 1; // increment error-counter
end // if
tctr = tctr + 1; // increment 'total' counter
end // for ( in _b
$display("tctr = %0d, ectr = %0d", tctr, ectr );
#100 $finish;
end
endmodule
///////////////////
Output from Modelsim 6.1c:
# tctr = 65025, ectr = 16131
# ** Note: $finish : sva_practice.v(28)
# Time: 65125 ps Iteration: 0 Instance: /v2001_practice
/////////////////
Oh the horror! Could someone explain to me why out_c[7:0] and out_d[7:0]
don't match?
Apparently, storing the intermediate result (in out_raw[8:0]) makes a
difference in the
final result of out_c[]!
Does it have something to do with how Verilog resolves the bit-width of
arithmetic expressions?
module v2001_practice;
reg signed [7:0] in_a, in_b;
wire signed [8:0] out_raw;
wire signed [7:0] out_c = out_raw; // truncate the upper bit!
wire signed [7:0] out_d; // <---- why does this guy truncate the result?!?
assign out_raw = (in_a + in_b)>>>1; // GOOD, correct 2's Complement result
assign out_d = (in_a + in_b)>>>1; // BAD, certain combos of in_a, in_b cause
truncated upper bit!
integer ectr, tctr;
initial begin
ectr = 0;
tctr = 0;
for ( in_a = -128; in_a < 127; in_a = in_a + 1 )
for ( in_b = -128; in_b < 127; in_b = in_b + 1 )
begin
#1;
if (out_c !== out_d)
begin
$display("ERROR, (%d+%d)>>>1 out_c(%d) !== out_d(%d)",
in_a, in_b, out_c, out_d );
ectr = ectr + 1; // increment error-counter
end // if
tctr = tctr + 1; // increment 'total' counter
end // for ( in _b
$display("tctr = %0d, ectr = %0d", tctr, ectr );
#100 $finish;
end
endmodule
///////////////////
Output from Modelsim 6.1c:
# tctr = 65025, ectr = 16131
# ** Note: $finish : sva_practice.v(28)
# Time: 65125 ps Iteration: 0 Instance: /v2001_practice
/////////////////
Oh the horror! Could someone explain to me why out_c[7:0] and out_d[7:0]
don't match?
Apparently, storing the intermediate result (in out_raw[8:0]) makes a
difference in the
final result of out_c[]!
Does it have something to do with how Verilog resolves the bit-width of
arithmetic expressions?