OpenCores
Issue List
multiplication bug #19
Closed ulixxe opened this issue over 13 years ago
ulixxe commented over 13 years ago

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

rhoads commented over 13 years ago

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;
rhoads was assigned over 13 years ago
ulixxe commented over 13 years ago

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 commented over 13 years ago

Your solution is much better. I checked it in.

Thanks, Steve

rhoads closed this over 13 years ago

Assignee
rhoads
Labels
Bug