OpenCores

multiplication bug

Back to bugtracker overview.

Information:
Type :: BUG
Status :: CLOSED
Assigned to :: Steve, Rhoads

Description:
Hi,
I found a problem when multiplying 0x80000000 by 0x80000000.
The result should be 0x4000000000000000, but it is 0xC000000000000000.
I found it with the following test code:
li $t2, 0x80000000
mult $t2, $t2
mflo $t0
bne $t0, 0, fail
mfhi $t1
bne $t1, 0x40000000, fail
See you

Comments:

Rhoads, Steve Sep 3, 2010
Your solution is much better. I checked it in.

Thanks,
Steve
ilardo, santo Aug 31, 2010
What do you think about the following change? Maybe it requires less logic.

mode_reg <= MODE_MULT;
if b(31) = '0' then
aa_reg <= a;
bb_reg <= b;
-- sign_reg <= a(31);
else
aa_reg <= a_neg;
bb_reg <= b_neg;
-- sign_reg <= a_neg(31);
end if;
sign_reg <= a(31) xor b(31); -- added line
sign2_reg <= '0';
...
Rhoads, Steve Aug 31, 2010
Multiplying 0x80000000 times a negative number causes the bug. This is because -0x80000000 = ~0x80000000+1 = 0x80000000.

Here is a possible fix to mult.vhd:

when MULT_SIGNED_MULT =>
mode_reg <= MODE_MULT;
if b(31) = '0' then
aa_reg <= a;
bb_reg <= b;
sign_reg <= a(31);
--Special case of 0x80000000 * negative number
elsif a(31) = '1' and (a(30 downto 0) = ZERO(30 downto 0) or
b(30 downto 0) = ZERO(30 downto 0)) then
aa_reg <= a; --convert to unsigned mult
bb_reg <= b;
sign_reg <= '0';
else
aa_reg <= a_neg;
bb_reg <= b_neg;
sign_reg <= a_neg(31);
end if;

Post a comment:
Login to post comments!

Back to bugtracker overview.

© copyright 1999-2012 OpenCores.org, equivalent to ORSoC AB, all rights reserved. OpenCores®, registered trademark.