# Copyright (C) Jonathan P Dawson 2013
# 2013-12-12
-from nmigen import Module, Signal
+from nmigen import Module, Signal, Elaboratable
from nmigen.cli import main, verilog
from math import log
class FPSCData:
- def __init__(self, width, id_wid):
- self.a = FPNumBase(width, True)
- self.b = FPNumBase(width, True)
+ def __init__(self, width, id_wid, m_extra=True):
+ self.a = FPNumBase(width, m_extra)
+ self.b = FPNumBase(width, m_extra)
self.z = FPNumOut(width, False)
self.oz = Signal(width, reset_less=True)
self.out_do_z = Signal(reset_less=True)
self.a.eq(i.a), self.b.eq(i.b), self.mid.eq(i.mid)]
-class FPAddDeNormMod(FPState):
+class FPAddDeNormMod(FPState, Elaboratable):
- def __init__(self, width, id_wid):
+ def __init__(self, width, id_wid, m_extra=True):
self.width = width
self.id_wid = id_wid
+ self.m_extra = m_extra
self.i = self.ispec()
self.o = self.ospec()
def ispec(self):
- return FPSCData(self.width, self.id_wid)
+ return FPSCData(self.width, self.id_wid, self.m_extra)
def ospec(self):
- return FPSCData(self.width, self.id_wid)
+ return FPSCData(self.width, self.id_wid, self.m_extra)
def process(self, i):
return self.o
espec = (len(i.z.e), True)
ediff_n126 = Signal(espec, reset_less=True)
- msr = MultiShiftRMerge(mwid, espec)
+ msr = MultiShiftRMerge(mwid+2, espec)
m.submodules.multishift_r = msr
m.d.comb += i.eq(self.i)
self.o = self.ospec()
def ispec(self):
- return FPSCData(self.width, self.id_wid)
+ return FPSCData(self.width, self.id_wid, False)
def ospec(self):
return FPMulStage0Data(self.width, self.id_wid)
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),
+ m.d.comb += [
am0.eq(Cat(self.i.a.m, 0)),
bm0.eq(Cat(self.i.b.m, 0))
]
self.m1o = self.ospec()
def ispec(self):
- return FPSCData(self.width, self.id_wid)
+ return FPSCData(self.width, self.id_wid, False)
def ospec(self):
return FPAddStage1Data(self.width, self.id_wid) # AddStage1 ospec
# IEEE Floating Point Multiplier
-from nmigen import Module, Signal, Cat, Const
+from nmigen import Module, Signal, Cat, Const, Elaboratable
from nmigen.cli import main, verilog
from math import log
from ieee754.fpcommon.denorm import (FPSCData, FPAddDeNormMod)
-class FPMulSpecialCasesMod:
+class FPMulSpecialCasesMod(Elaboratable):
""" special cases: NaNs, infs, zeros, denormalised
see "Special Operations"
https://steve.hollasch.net/cgindex/coding/ieeefloat.html
return FPADDBaseData(self.width, self.id_wid)
def ospec(self):
- return FPSCData(self.width, self.id_wid)
+ return FPSCData(self.width, self.id_wid, False)
def setup(self, m, i):
""" links module to inputs and outputs
m.submodules.sc_out_z = self.o.z
# decode: XXX really should move to separate stage
- a1 = FPNumDecode(None, self.width)
- b1 = FPNumDecode(None, self.width)
+ a1 = FPNumDecode(None, self.width, False)
+ b1 = FPNumDecode(None, self.width, False)
m.submodules.sc_decode_a = a1
m.submodules.sc_decode_b = b1
m.d.comb += [a1.v.eq(self.i.a),
self.o.b.eq(b1)
]
- s_nomatch = Signal(reset_less=True)
- m.d.comb += s_nomatch.eq(a1.s != b1.s)
-
- m_match = Signal(reset_less=True)
- m.d.comb += m_match.eq(a1.m == b1.m)
-
- e_match = Signal(reset_less=True)
- m.d.comb += e_match.eq(a1.e == b1.e)
-
- aeqmb = Signal(reset_less=True)
- m.d.comb += aeqmb.eq(s_nomatch & m_match & e_match)
-
obz = Signal(reset_less=True)
m.d.comb += obz.eq(a1.is_zero & b1.is_zero)
def __init__(self, width, id_wid):
FPState.__init__(self, "special_cases")
- self.mod = FPAddSpecialCasesMod(width)
+ self.mod = FPMulSpecialCasesMod(width)
self.out_z = self.mod.ospec()
self.out_do_z = Signal(reset_less=True)
return FPADDBaseData(self.width, self.id_wid) # SpecialCases ispec
def ospec(self):
- return FPSCData(self.width, self.id_wid) # DeNorm ospec
+ return FPSCData(self.width, self.id_wid, False) # DeNorm ospec
def setup(self, m, i):
""" links module to inputs and outputs
"""
smod = FPMulSpecialCasesMod(self.width, self.id_wid)
- dmod = FPAddDeNormMod(self.width, self.id_wid)
+ dmod = FPAddDeNormMod(self.width, self.id_wid, False)
chain = StageChain([smod, dmod])
chain.setup(m, i)
count = 0
#regression tests
- stimulus_a = [0xba57711a, 0xbf9b1e94, 0x34082401, 0x5e8ef81,
+
+ stimulus_a = [0xa4504d7, 0xba57711a, 0xbf9b1e94, 0x34082401, 0x5e8ef81,
0x5c75da81, 0x2b017]
- stimulus_b = [0xee1818c5, 0xc038ed3a, 0xb328cd45, 0x114f3db,
+ stimulus_b = [0xb4658540, 0xee1818c5, 0xc038ed3a, 0xb328cd45, 0x114f3db,
0x2f642a39, 0xff3807ab]
yield from run_fpunit(dut, stimulus_a, stimulus_b, mul, get_case)
count += len(stimulus_a)