From 891ef06c970d97457b664a6e026768927dd09067 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Sun, 25 Aug 2019 16:10:11 +0100 Subject: [PATCH] remove m.If/Elif/Elif replace with Mux --- src/ieee754/fpmul/specialcases.py | 68 ++++++++++++++++--------------- 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/src/ieee754/fpmul/specialcases.py b/src/ieee754/fpmul/specialcases.py index 4fc3e3cf..066d2b9f 100644 --- a/src/ieee754/fpmul/specialcases.py +++ b/src/ieee754/fpmul/specialcases.py @@ -5,7 +5,7 @@ Copyright (C) 2019 Jake Lifshay """ -from nmigen import Module, Signal, Cat, Const +from nmigen import Module, Signal, Cat, Const, Mux from nmigen.cli import main, verilog from math import log @@ -36,7 +36,7 @@ class FPMulSpecialCasesMod(PipeModBase): m = Module() comb = m.d.comb - # decode: XXX really should move to separate stage + # decode a/b width = self.pspec.width a1 = FPNumBaseRecord(width, False) b1 = FPNumBaseRecord(width, False) @@ -48,45 +48,49 @@ class FPMulSpecialCasesMod(PipeModBase): self.o.b.eq(b1) ] - obz = Signal(reset_less=True) - comb += obz.eq(a1.is_zero | b1.is_zero) - + # intermediaries / tests + t_obz = Signal(reset_less=True) + t_a1inf = Signal(reset_less=True) + t_b1inf = Signal(reset_less=True) + t_abnan = Signal(reset_less=True) + t_special = Signal(reset_less=True) sabx = Signal(reset_less=True) # sign a xor b (sabx, get it?) - comb += sabx.eq(a1.s ^ b1.s) - abnan = Signal(reset_less=True) - comb += abnan.eq(a1.is_nan | b1.is_nan) - - # initialise and override if needed - comb += self.o.out_do_z.eq(1) + comb += sabx.eq(a1.s ^ b1.s) + comb += t_obz.eq(a1.is_zero | b1.is_zero) + comb += t_a1inf.eq(a1.is_inf) + comb += t_b1inf.eq(b1.is_inf) + comb += t_abnan.eq(a1.is_nan | b1.is_nan) + comb += t_special.eq(Cat(t_obz, t_abnan, t_b1inf, t_a1inf).bool()) + + # prepare inf/zero/nans + z_zero = FPNumBaseRecord(width, False, name="z_zero") + z_nan = FPNumBaseRecord(width, False, name="z_nan") + z_inf = FPNumBaseRecord(width, False, name="z_inf") + comb += z_zero.zero(sabx) + comb += z_nan.nan(0) + comb += z_inf.inf(sabx) + + # special case pipeline bypass enabled y/n + comb += self.o.out_do_z.eq(t_special) # if a is NaN or b is NaN return NaN - with m.If(abnan): - comb += self.o.z.nan(0) - # if a is inf return inf (or NaN) - with m.Elif(a1.is_inf): - comb += self.o.z.inf(sabx) - # b is zero return NaN - with m.If(b1.is_zero): - comb += self.o.z.nan(0) - + # if b is zero return NaN # if b is inf return inf (or NaN) - with m.Elif(b1.is_inf): - comb += self.o.z.inf(sabx) - # a is zero return NaN - with m.If(a1.is_zero): - comb += self.o.z.nan(0) - + # if a is zero return NaN # if a is zero or b zero return signed-a/b - with m.Elif(obz): - comb += self.o.z.zero(sabx) - # Denormalised Number checks next, so pass a/b data through - with m.Else(): - comb += self.o.out_do_z.eq(0) + # invert the sequence above to create the Mux tree + # XXX TODO: use PriorityPicker? + oz = 0 + oz = Mux(t_obz, z_zero.v, oz) + oz = Mux(t_b1inf, Mux(a1.is_zero, z_nan.v, z_inf.v), oz) + oz = Mux(t_a1inf, Mux(b1.is_zero, z_nan.v, z_inf.v), oz) + oz = Mux(t_abnan, z_nan.v, oz) + comb += self.o.oz.eq(oz) - comb += self.o.oz.eq(self.o.z.v) + # pass through context comb += self.o.ctx.eq(self.i.ctx) return m -- 2.30.2