# IEEE Floating Point Multiplier
-from nmigen import Module, Signal, Cat, Mux, Elaboratable
+from nmigen import Module, Signal, Cat, Mux
from nmigen.cli import main, verilog
from math import log
-from nmutil.singlepipe import StageChain
-
-from ieee754.fpcommon.fpbase import (Overflow, OverflowMod,
- FPNumBase, FPNumBaseRecord)
+from ieee754.fpcommon.modbase import FPModBase
+from ieee754.fpcommon.fpbase import FPNumBase
from ieee754.fpcommon.getop import FPPipeContext
from ieee754.fpcommon.msbhigh import FPMSBHigh
from ieee754.fpcommon.denorm import FPSCData
from ieee754.fpcommon.postcalc import FPAddStage1Data
-class FPAlignModSingle(Elaboratable):
+class FPAlignModSingle(FPModBase):
def __init__(self, pspec, e_extra=False):
- self.pspec = pspec
self.e_extra = e_extra
- self.i = self.ispec()
- self.o = self.ospec()
+ super().__init__(pspec, "align")
def ispec(self):
return FPSCData(self.pspec, False)
def ospec(self):
return FPSCData(self.pspec, False)
- def setup(self, m, i):
- """ links module to inputs and outputs
- """
- m.submodules.align = self
- m.d.comb += self.i.eq(i)
-
- def process(self, i):
- return self.o
-
def elaborate(self, platform):
m = Module()
+ comb = m.d.comb
self.o.a.m.name = "o_a_m"
self.o.b.m.name = "o_b_m"
m.submodules.norm_pe_b = msb_b
# connect to msb_a/b module
- m.d.comb += msb_a.m_in.eq(insel_a.m)
- m.d.comb += msb_a.e_in.eq(insel_a.e)
- m.d.comb += msb_b.m_in.eq(insel_b.m)
- m.d.comb += msb_b.e_in.eq(insel_b.e)
+ comb += msb_a.m_in.eq(insel_a.m)
+ comb += msb_a.e_in.eq(insel_a.e)
+ comb += msb_b.m_in.eq(insel_b.m)
+ comb += msb_b.e_in.eq(insel_b.e)
# copy input to output (overridden below)
- m.d.comb += self.o.a.eq(insel_a)
- m.d.comb += self.o.b.eq(insel_b)
+ comb += self.o.a.eq(insel_a)
+ comb += self.o.b.eq(insel_b)
# normalisation increase/decrease conditions
decrease_a = Signal(reset_less=True)
decrease_b = Signal(reset_less=True)
- m.d.comb += decrease_a.eq(insel_a.m_msbzero)
- m.d.comb += decrease_b.eq(insel_b.m_msbzero)
+ comb += decrease_a.eq(insel_a.m_msbzero)
+ comb += decrease_b.eq(insel_b.m_msbzero)
- # ok this is near-identical to FPNorm. TODO: modularise
+ # ok this is near-identical to FPNorm: use same class (FPMSBHigh)
with m.If(~self.i.out_do_z):
with m.If(decrease_a):
- m.d.comb += [
+ comb += [
self.o.a.e.eq(msb_a.e_out),
self.o.a.m.eq(msb_a.m_out),
]
with m.If(decrease_b):
- m.d.comb += [
+ comb += [
self.o.b.e.eq(msb_b.e_out),
self.o.b.m.eq(msb_b.m_out),
]
- m.d.comb += self.o.ctx.eq(self.i.ctx)
- m.d.comb += self.o.out_do_z.eq(self.i.out_do_z)
- m.d.comb += self.o.oz.eq(self.i.oz)
+ comb += self.o.ctx.eq(self.i.ctx)
+ comb += self.o.out_do_z.eq(self.i.out_do_z)
+ comb += self.o.oz.eq(self.i.oz)
return m
-
-
from nmigen import Module, Signal, Cat, Elaboratable
from nmigen.cli import main, verilog
+from ieee754.fpcommon.modbase import FPModBase
from ieee754.fpcommon.fpbase import FPNumBaseRecord
from ieee754.fpcommon.denorm import FPSCData
from ieee754.fpcommon.getop import FPPipeContext
self.product.eq(i.product), self.ctx.eq(i.ctx)]
-class FPMulStage0Mod(Elaboratable):
+class FPMulStage0Mod(FPModBase):
def __init__(self, pspec):
- self.pspec = pspec
- self.i = self.ispec()
- self.o = self.ospec()
+ super().__init__(pspec, "mul0")
def ispec(self):
return FPSCData(self.pspec, False)
def ospec(self):
return FPMulStage0Data(self.pspec)
- 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()
+ comb = m.d.comb
# store intermediate tests (and zero-extended mantissas)
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 += [
+ comb += [
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),
+ 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.ctx.eq(self.i.ctx)
+ comb += self.o.oz.eq(self.i.oz)
+ comb += self.o.out_do_z.eq(self.i.out_do_z)
+ comb += self.o.ctx.eq(self.i.ctx)
+
return m
from nmigen import Module, Signal, Elaboratable
from nmigen.cli import main, verilog
+from ieee754.fpcommon.modbase import FPModBase
from ieee754.fpcommon.postcalc import FPAddStage1Data
from ieee754.fpmul.mul0 import FPMulStage0Data
-class FPMulStage1Mod(Elaboratable):
+class FPMulStage1Mod(FPModBase):
""" Second stage of mul: preparation for normalisation.
"""
def __init__(self, pspec):
- self.pspec = pspec
- self.i = self.ispec()
- self.o = self.ospec()
+ super().__init__(pspec, "mul1")
def ispec(self):
return FPMulStage0Data(self.pspec)
def ospec(self):
return FPAddStage1Data(self.pspec)
- def process(self, i):
- return self.o
-
- def setup(self, m, i):
- """ links module to inputs and outputs
- """
- m.submodules.mul1 = self
- m.d.comb += self.i.eq(i)
-
def elaborate(self, platform):
m = Module()
- m.d.comb += self.o.z.eq(self.i.z)
+ comb = m.d.comb
+
+ comb += self.o.z.eq(self.i.z)
with m.If(~self.i.out_do_z):
# results are in the range 0.25 to 0.999999999999
# sometimes the MSB will be zero, (0.5 * 0.5 = 0.25 which
# to shift the mantissa up (and reduce the exponent by 1)
p = Signal(len(self.i.product), reset_less=True)
with m.If(self.i.product[-1]):
- m.d.comb += p.eq(self.i.product)
+ comb += p.eq(self.i.product)
with m.Else():
# get 1 bit of extra accuracy if the mantissa top bit is zero
- m.d.comb += p.eq(self.i.product<<1)
- m.d.comb += self.o.z.e.eq(self.i.z.e-1)
+ comb += p.eq(self.i.product<<1)
+ comb += self.o.z.e.eq(self.i.z.e-1)
# top bits are mantissa, then guard and round, and the rest of
# the product is sticky
mw = self.o.z.m_width
- m.d.comb += [
+ comb += [
self.o.z.m.eq(p[mw+2:]), # mantissa
self.o.of.m0.eq(p[mw+2]), # copy of LSB
self.o.of.guard.eq(p[mw+1]), # guard
self.o.of.sticky.eq(p[0:mw].bool()) # sticky
]
- m.d.comb += self.o.out_do_z.eq(self.i.out_do_z)
- m.d.comb += self.o.oz.eq(self.i.oz)
- m.d.comb += self.o.ctx.eq(self.i.ctx)
+ comb += self.o.out_do_z.eq(self.i.out_do_z)
+ comb += self.o.oz.eq(self.i.oz)
+ comb += self.o.ctx.eq(self.i.ctx)
return m
def __init__(self, pspec):
self.pspec = pspec
super().__init__(pspec)
- self.m1o = self.ospec()
def ispec(self):
return FPSCData(self.pspec, False)