From: Paul Mackerras Date: Sat, 19 Sep 2020 09:01:49 +0000 (+1000) Subject: FPU: Relax timing around multiplier output X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=45c5236700b8687fbb2c32c4b5a1586da01bcf15;p=microwatt.git 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 --- 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;