From 45c5236700b8687fbb2c32c4b5a1586da01bcf15 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sat, 19 Sep 2020 19:01:49 +1000 Subject: [PATCH] FPU: Relax timing around multiplier output 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 --- fpu.vhdl | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/fpu.vhdl b/fpu.vhdl index 023dbf2..38495a9 100644 --- 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;