FPU: Relax timing around multiplier output
authorPaul Mackerras <paulus@ozlabs.org>
Sat, 19 Sep 2020 09:01:49 +0000 (19:01 +1000)
committerPaul Mackerras <paulus@ozlabs.org>
Fri, 15 Jan 2021 01:40:09 +0000 (12:40 +1100)
At present there is a state transition in the handling of the fmadd
instructions where the next state depends on the sign bit of the
multiplier result.  This creates a critical path which doesn't make
timing on the A7-100.  To fix this, we make the state transition
independent of the sign of the multiplier result, which improves
timing, but means we take one more cycle to do a fmadd-family
instruction in some cases.

Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
fpu.vhdl

index 023dbf270c946a9776482903e80490f74a8fae58..38495a9979c9312c7a87f9cdc1511bb9bf1d62ed 100644 (file)
--- a/fpu.vhdl
+++ b/fpu.vhdl
@@ -1704,22 +1704,19 @@ begin
                 opsel_r <= RES_MULT;
                 opsel_s <= S_MULT;
                 set_s := '1';
-                v.shift := to_signed(56, EXP_BITS);
                 if multiply_to_f.valid = '1' then
-                    if multiply_to_f.result(121) = '1' then
-                        v.state := FMADD_5;
-                    else
-                        v.state := FMADD_6;
-                    end if;
+                    v.state := FMADD_5;
                 end if;
 
             when FMADD_5 =>
-                -- negate R:S:X
-                v.result_sign := not r.result_sign;
-                opsel_ainv <= '1';
-                carry_in <= not (s_nz or r.x);
-                opsel_s <= S_NEG;
-                set_s := '1';
+                -- negate R:S:X if negative
+                if r.r(63) = '1' then
+                    v.result_sign := not r.result_sign;
+                    opsel_ainv <= '1';
+                    carry_in <= not (s_nz or r.x);
+                    opsel_s <= S_NEG;
+                    set_s := '1';
+                end if;
                 v.shift := to_signed(56, EXP_BITS);
                 v.state := FMADD_6;