From: Luke Kenneth Casson Leighton Date: Fri, 3 May 2019 02:13:33 +0000 (+0100) Subject: add mul0 based on add0 X-Git-Tag: ls180-24jan2020~1051 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e3c7c7bc005b155e46eb176c3aca970954dacd74;p=ieee754fpu.git add mul0 based on add0 --- diff --git a/src/ieee754/fpmul/mul0.py b/src/ieee754/fpmul/mul0.py new file mode 100644 index 00000000..bc264216 --- /dev/null +++ b/src/ieee754/fpmul/mul0.py @@ -0,0 +1,98 @@ +# IEEE Floating Point Muler (Single Precision) +# Copyright (C) Jonathan P Dawson 2013 +# 2013-12-12 + +from nmigen import Module, Signal, Cat, Elaboratable +from nmigen.cli import main, verilog + +from ieee754.fpcommon.fpbase import FPNumBase +from ieee754.fpcommon.fpbase import FPState +from ieee754.fpcommon.denorm import FPSCData + + +class FPMulStage0Data: + + def __init__(self, width, id_wid): + self.z = FPNumBase(width, False) + self.out_do_z = Signal(reset_less=True) + self.oz = Signal(width, reset_less=True) + mw = (self.z.m_width)*2 - 1 + 3 # sticky/round/guard bits + (2*mant) - 1 + self.product = Signal(mw, reset_less=True) + self.mid = Signal(id_wid, reset_less=True) + + def eq(self, i): + return [self.z.eq(i.z), self.out_do_z.eq(i.out_do_z), self.oz.eq(i.oz), + self.product.eq(i.product), self.mid.eq(i.mid)] + + +class FPMulStage0Mod(Elaboratable): + + def __init__(self, width, id_wid): + self.width = width + self.id_wid = id_wid + self.i = self.ispec() + self.o = self.ospec() + + def ispec(self): + return FPSCData(self.width, self.id_wid) + + def ospec(self): + return FPMulStage0Data(self.width, self.id_wid) + + def process(self, i): + return self.o + + def setup(self, m, i): + """ links module to inputs and outputs + """ + m.submodules.mul0 = self + m.d.comb += self.i.eq(i) + + def elaborate(self, platform): + m = Module() + m.submodules.mul0_in_a = self.i.a + m.submodules.mul0_in_b = self.i.b + m.submodules.mul0_out_z = self.o.z + + # store intermediate tests (and zero-extended mantissas) + seq = Signal(reset_less=True) + mge = Signal(reset_less=True) + am0 = Signal(len(self.i.a.m)+1, reset_less=True) + bm0 = Signal(len(self.i.b.m)+1, reset_less=True) + m.d.comb += [seq.eq(self.i.a.s == self.i.b.s), + mge.eq(self.i.a.m >= self.i.b.m), + am0.eq(Cat(self.i.a.m, 0)), + bm0.eq(Cat(self.i.b.m, 0)) + ] + # same-sign (both negative or both positive) mul mantissas + with m.If(~self.i.out_do_z): + m.d.comb += [self.o.z.e.eq(self.i.a.e + self.i.b.e + 1), + self.o.product.eq(am0 * bm0 * 4), + self.o.z.s.eq(self.i.a.s ^ self.i.b.s) + ] + + m.d.comb += self.o.oz.eq(self.i.oz) + m.d.comb += self.o.out_do_z.eq(self.i.out_do_z) + m.d.comb += self.o.mid.eq(self.i.mid) + return m + + +class FPMulStage0(FPState): + """ First stage of mul. + """ + + def __init__(self, width, id_wid): + FPState.__init__(self, "multiply_0") + self.mod = FPMulStage0Mod(width) + self.o = self.mod.ospec() + + def setup(self, m, i): + """ links module to inputs and outputs + """ + self.mod.setup(m, i) + + # NOTE: these could be done as combinatorial (merge mul0+mul1) + m.d.sync += self.o.eq(self.mod.o) + + def action(self, m): + m.next = "multiply_1"