from nmigen import Module, Signal, Cat, Elaboratable
from nmigen.cli import main, verilog
-from ieee754.fpcommon.fpbase import FPNumBase
+from ieee754.fpcommon.fpbase import FPNumBase, FPNumBaseRecord
from ieee754.fpcommon.fpbase import FPState
from ieee754.fpcommon.denorm import FPSCData
class FPAddStage0Data:
def __init__(self, width, id_wid):
- self.z = FPNumBase(width, False)
+ self.z = FPNumBaseRecord(width, False)
self.out_do_z = Signal(reset_less=True)
self.oz = Signal(width, reset_less=True)
self.tot = Signal(self.z.m_width + 4, reset_less=True)
def elaborate(self, platform):
m = Module()
- m.submodules.add0_in_a = self.i.a
- m.submodules.add0_in_b = self.i.b
- m.submodules.add0_out_z = self.o.z
+ #m.submodules.add0_in_a = self.i.a
+ #m.submodules.add0_in_b = self.i.b
+ #m.submodules.add0_out_z = self.o.z
# store intermediate tests (and zero-extended mantissas)
seq = Signal(reset_less=True)
from nmigen.cli import main, verilog
from ieee754.fpcommon.fpbase import FPNumOut, FPNumIn, FPNumBase
+from ieee754.fpcommon.fpbase import FPNumBaseRecord
from ieee754.fpcommon.fpbase import MultiShiftRMerge
from ieee754.fpcommon.fpbase import FPState
from ieee754.fpcommon.denorm import FPSCData
class FPNumIn2Ops:
def __init__(self, width, id_wid):
- self.a = FPNumIn(None, width)
- self.b = FPNumIn(None, width)
- self.z = FPNumOut(width, False)
+ self.a = FPNumBaseRecord(width)
+ self.b = FPNumBaseRecord(width)
+ self.z = FPNumBaseRecord(width, False)
self.out_do_z = Signal(reset_less=True)
self.oz = Signal(width, reset_less=True)
self.mid = Signal(id_wid, reset_less=True)
class FPAddAlignMultiMod(FPState):
def __init__(self, width):
- self.in_a = FPNumBase(width)
- self.in_b = FPNumBase(width)
- self.out_a = FPNumIn(None, width)
- self.out_b = FPNumIn(None, width)
+ self.in_a = FPNumBaseRecord(width)
+ self.in_b = FPNumBaseRecord(width)
+ self.out_a = FPNumBaseRecord(width)
+ self.out_b = FPNumBaseRecord(width)
self.exp_eq = Signal(reset_less=True)
def elaborate(self, platform):
m = Module()
- m.submodules.align_in_a = self.in_a
- m.submodules.align_in_b = self.in_b
- m.submodules.align_out_a = self.out_a
- m.submodules.align_out_b = self.out_b
+ #m.submodules.align_in_a = self.in_a
+ #m.submodules.align_in_b = self.in_b
+ #m.submodules.align_out_a = self.out_a
+ #m.submodules.align_out_b = self.out_b
# NOTE: this does *not* do single-cycle multi-shifting,
# it *STAYS* in the align state until exponents match
def __init__(self, width, id_wid):
FPState.__init__(self, "align")
self.mod = FPAddAlignMultiMod(width)
- self.out_a = FPNumIn(None, width)
- self.out_b = FPNumIn(None, width)
+ self.out_a = FPNumBaseRecord(width)
+ self.out_b = FPNumBaseRecord(width)
self.exp_eq = Signal(reset_less=True)
def setup(self, m, in_a, in_b):
"""
m = Module()
- m.submodules.align_in_a = self.i.a
- m.submodules.align_in_b = self.i.b
- m.submodules.align_out_a = self.o.a
- m.submodules.align_out_b = self.o.b
+ #m.submodules.align_in_a = self.i.a
+ #m.submodules.align_in_b = self.i.b
+ #m.submodules.align_out_a = self.o.a
+ #m.submodules.align_out_b = self.o.b
# temporary (muxed) input and output to be shifted
- t_inp = FPNumBase(self.width)
- t_out = FPNumIn(None, self.width)
+ t_inp = FPNumBaseRecord(self.width)
+ t_out = FPNumBaseRecord(self.width)
espec = (len(self.i.a.e), True)
msr = MultiShiftRMerge(self.i.a.m_width, espec)
- m.submodules.align_t_in = t_inp
- m.submodules.align_t_out = t_out
+ #m.submodules.align_t_in = t_inp
+ #m.submodules.align_t_out = t_out
m.submodules.multishift_r = msr
ediff = Signal(espec, reset_less=True)
from ieee754.fpcommon.fpbase import FPNumDecode
from nmutil.singlepipe import SimpleHandshake, StageChain
-from ieee754.fpcommon.fpbase import FPState, FPID
+from ieee754.fpcommon.fpbase import FPState, FPID, FPNumBaseRecord
from ieee754.fpcommon.getop import FPADDBaseData
from ieee754.fpcommon.denorm import (FPSCData, FPAddDeNormMod)
def elaborate(self, platform):
m = Module()
- m.submodules.sc_out_z = self.o.z
+ #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)
- m.submodules.sc_decode_a = a1
- m.submodules.sc_decode_b = b1
+ a1 = FPNumBaseRecord(self.width)
+ b1 = FPNumBaseRecord(self.width)
+ m.submodules.sc_decode_a = a1 = FPNumDecode(None, a1)
+ m.submodules.sc_decode_b = b1 = FPNumDecode(None, b1)
m.d.comb += [a1.v.eq(self.i.a),
b1.v.eq(self.i.b),
self.o.a.eq(a1),
from nmigen import Module, Elaboratable
from nmigen.cli import main, verilog
-from ieee754.fpcommon.fpbase import FPState
+from ieee754.fpcommon.fpbase import FPState, FPNumBase
from .roundz import FPRoundData
def elaborate(self, platform):
m = Module()
- m.submodules.corr_in_z = self.i.z
- m.submodules.corr_out_z = self.out_z.z
+ m.submodules.corr_in_z = in_z = FPNumBase(self.i.z)
+ #m.submodules.corr_out_z = self.out_z.z
m.d.comb += self.out_z.eq(self.i) # copies mid, z, out_do_z
with m.If(~self.i.out_do_z):
- with m.If(self.i.z.is_denormalised):
+ with m.If(in_z.is_denormalised):
m.d.comb += self.out_z.z.e.eq(self.i.z.N127)
return m
class FPSCData:
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.a = FPNumBaseRecord(width, m_extra)
+ self.b = FPNumBaseRecord(width, m_extra)
+ self.z = FPNumBaseRecord(width, False)
self.oz = Signal(width, reset_less=True)
self.out_do_z = Signal(reset_less=True)
self.mid = Signal(id_wid, reset_less=True)
def elaborate(self, platform):
m = Module()
- m.submodules.denorm_in_a = self.i.a
- m.submodules.denorm_in_b = self.i.b
- m.submodules.denorm_in_z = self.i.z
- m.submodules.denorm_out_a = self.o.a
- m.submodules.denorm_out_b = self.o.b
- m.submodules.denorm_out_z = self.o.z
+ m.submodules.denorm_in_a = in_a = FPNumBase(self.i.a)
+ m.submodules.denorm_in_b = in_b = FPNumBase(self.i.b)
+ #m.submodules.denorm_out_a = self.o.a
+ #m.submodules.denorm_out_b = self.o.b
+ #m.submodules.denorm_out_z = self.o.z
with m.If(~self.i.out_do_z):
# XXX hmmm, don't like repeating identical code
m.d.comb += self.o.a.eq(self.i.a)
- with m.If(self.i.a.exp_n127):
+ with m.If(in_a.exp_n127):
m.d.comb += self.o.a.e.eq(self.i.a.N126) # limit a exponent
with m.Else():
m.d.comb += self.o.a.m[-1].eq(1) # set top mantissa bit
m.d.comb += self.o.b.eq(self.i.b)
- with m.If(self.i.b.exp_n127):
+ with m.If(in_b.exp_n127):
m.d.comb += self.o.b.e.eq(self.i.b.N126) # limit a exponent
with m.Else():
m.d.comb += self.o.b.m[-1].eq(1) # set top mantissa bit
def __init__(self, width, id_wid):
FPState.__init__(self, "denormalise")
self.mod = FPAddDeNormMod(width)
- self.out_a = FPNumBase(width)
- self.out_b = FPNumBase(width)
+ self.out_a = FPNumBaseRecord(width)
+ self.out_b = FPNumBaseRecord(width)
def setup(self, m, i):
""" links module to inputs and outputs
self.N127 = Const(-(e_max-1), (e_width, True))
self.N126 = Const(-(e_max-2), (e_width, True))
+ def drop_in(self, fp):
+ fp.s = self.s
+ fp.e = self.e
+ fp.m = self.m
+ fp.v = self.v
+ fp.width = self.width
+ fp.e_width = self.e_width
+ fp.m_width = self.m_width
+ fp.e_start = self.e_start
+ fp.e_end = self.e_end
+ fp.m_extra = self.m_extra
+
+ def create(self, s, e, m):
+ """ creates a value from sign / exponent / mantissa
+
+ bias is added here, to the exponent
+ """
+ return [
+ self.v[-1].eq(s), # sign
+ self.v[self.e_start:self.e_end].eq(e + self.P127), # exp (add on bias)
+ self.v[0:self.e_start].eq(m) # mantissa
+ ]
+
+ def nan(self, s):
+ return self.create(s, self.P128, 1<<(self.e_start-1))
+
+ def inf(self, s):
+ return self.create(s, self.P128, 0)
+
+ def zero(self, s):
+ return self.create(s, self.N127, 0)
+
+ def create2(self, s, e, m):
+ """ creates a value from sign / exponent / mantissa
+
+ bias is added here, to the exponent
+ """
+ e = e + self.P127 # exp (add on bias)
+ return Cat(m[0:self.e_start],
+ e[0:self.e_end-self.e_start],
+ s)
+
+ def nan2(self, s):
+ return self.create2(s, self.P128, self.msb1)
+
+ def inf2(self, s):
+ return self.create2(s, self.P128, self.mzero)
+
+ def zero2(self, s):
+ return self.create2(s, self.N127, self.mzero)
+
def __iter__(self):
yield self.s
yield self.e
return [self.s.eq(inp.s), self.e.eq(inp.e), self.m.eq(inp.m)]
-class FPNumBase(FPNumBaseRecord): # Elaboratable
+class FPNumBase(FPNumBaseRecord, Elaboratable):
""" Floating-point Base Number Class
"""
- def __init__(self, width, m_extra=True):
- FPNumBaseRecord.__init__(self, width, m_extra)
- e_width = self.e_width
+ def __init__(self, fp):
+ fp.drop_in(self)
+ self.fp = fp
+ e_width = fp.e_width
self.is_nan = Signal(reset_less=True)
self.is_zero = Signal(reset_less=True)
m.d.comb += self.is_inf.eq(self._is_inf())
m.d.comb += self.is_overflowed.eq(self._is_overflowed())
m.d.comb += self.is_denormalised.eq(self._is_denormalised())
- m.d.comb += self.exp_128.eq(self.e == self.P128)
- m.d.comb += self.exp_sub_n126.eq(self.e - self.N126)
+ m.d.comb += self.exp_128.eq(self.e == self.fp.P128)
+ m.d.comb += self.exp_sub_n126.eq(self.e - self.fp.N126)
m.d.comb += self.exp_gt_n126.eq(self.exp_sub_n126 > 0)
m.d.comb += self.exp_lt_n126.eq(self.exp_sub_n126 < 0)
- m.d.comb += self.exp_gt127.eq(self.e > self.P127)
- m.d.comb += self.exp_n127.eq(self.e == self.N127)
- m.d.comb += self.exp_n126.eq(self.e == self.N126)
- m.d.comb += self.m_zero.eq(self.m == self.mzero)
- m.d.comb += self.m_msbzero.eq(self.m[self.e_start] == 0)
+ m.d.comb += self.exp_gt127.eq(self.e > self.fp.P127)
+ m.d.comb += self.exp_n127.eq(self.e == self.fp.N127)
+ m.d.comb += self.exp_n126.eq(self.e == self.fp.N126)
+ m.d.comb += self.m_zero.eq(self.m == self.fp.mzero)
+ m.d.comb += self.m_msbzero.eq(self.m[self.fp.e_start] == 0)
return m
(m[-1]) is effectively a carry-overflow. The other three are
guard (m[2]), round (m[1]), and sticky (m[0])
"""
- def __init__(self, width, m_extra=True):
- FPNumBase.__init__(self, width, m_extra)
+ def __init__(self, fp):
+ FPNumBase.__init__(self, fp)
def elaborate(self, platform):
m = FPNumBase.elaborate(self, platform)
return m
- def create(self, s, e, m):
- """ creates a value from sign / exponent / mantissa
-
- bias is added here, to the exponent
- """
- return [
- self.v[-1].eq(s), # sign
- self.v[self.e_start:self.e_end].eq(e + self.P127), # exp (add on bias)
- self.v[0:self.e_start].eq(m) # mantissa
- ]
-
- def nan(self, s):
- return self.create(s, self.P128, 1<<(self.e_start-1))
-
- def inf(self, s):
- return self.create(s, self.P128, 0)
-
- def zero(self, s):
- return self.create(s, self.N127, 0)
-
- def create2(self, s, e, m):
- """ creates a value from sign / exponent / mantissa
-
- bias is added here, to the exponent
- """
- e = e + self.P127 # exp (add on bias)
- return Cat(m[0:self.e_start],
- e[0:self.e_end-self.e_start],
- s)
-
- def nan2(self, s):
- return self.create2(s, self.P128, self.msb1)
-
- def inf2(self, s):
- return self.create2(s, self.P128, self.mzero)
-
- def zero2(self, s):
- return self.create2(s, self.N127, self.mzero)
-
class MultiShiftRMerge(Elaboratable):
""" shifts down (right) and merges lower bits into m[0].
(m[-1]) is effectively a carry-overflow. The other three are
guard (m[2]), round (m[1]), and sticky (m[0])
"""
- def __init__(self, op, width, m_extra=True):
- FPNumBase.__init__(self, width, m_extra)
+ def __init__(self, op, fp):
+ FPNumBase.__init__(self, fp)
self.op = op
def elaborate(self, platform):
args = [0] * self.m_extra + [v[0:self.e_start]] # pad with extra zeros
#print ("decode", self.e_end)
return [self.m.eq(Cat(*args)), # mantissa
- self.e.eq(v[self.e_start:self.e_end] - self.P127), # exp
+ self.e.eq(v[self.e_start:self.e_end] - self.fp.P127), # exp
self.s.eq(v[-1]), # sign
]
(m[-1]) is effectively a carry-overflow. The other three are
guard (m[2]), round (m[1]), and sticky (m[0])
"""
- def __init__(self, op, width, m_extra=True):
- FPNumBase.__init__(self, width, m_extra)
+ def __init__(self, op, fp):
+ FPNumBase.__init__(self, fp)
self.latch_in = Signal()
self.op = op
from nmigen import Module, Signal, Elaboratable
from nmigen.cli import main, verilog
-from ieee754.fpcommon.fpbase import FPNumOut
+from ieee754.fpcommon.fpbase import FPNumOut, FPNumBaseRecord, FPNumBase
from ieee754.fpcommon.fpbase import FPState
from .roundz import FPRoundData
from nmutil.singlepipe import Object
def elaborate(self, platform):
m = Module()
- z = FPNumOut(self.width, False)
- m.submodules.pack_in_z = self.i.z
- m.submodules.pack_out_z = z
+ z = FPNumBaseRecord(self.width, False)
+ m.submodules.pack_in_z = in_z = FPNumBase(self.i.z)
+ #m.submodules.pack_out_z = out_z = FPNumOut(z)
m.d.comb += self.o.mid.eq(self.i.mid)
with m.If(~self.i.out_do_z):
- with m.If(self.i.z.is_overflowed):
+ with m.If(in_z.is_overflowed):
m.d.comb += z.inf(self.i.z.s)
with m.Else():
m.d.comb += z.create(self.i.z.s, self.i.z.e, self.i.z.m)
# 2013-12-12
from nmigen import Signal
-from ieee754.fpcommon.fpbase import Overflow, FPNumBase
+from ieee754.fpcommon.fpbase import Overflow, FPNumBaseRecord
class FPAddStage1Data:
def __init__(self, width, id_wid):
- self.z = FPNumBase(width, False)
+ self.z = FPNumBaseRecord(width, False)
self.out_do_z = Signal(reset_less=True)
self.oz = Signal(width, reset_less=True)
self.of = Overflow()
from nmigen.cli import main, verilog
from math import log
-from ieee754.fpcommon.fpbase import Overflow, FPNumBase
+from ieee754.fpcommon.fpbase import Overflow, FPNumBase, FPNumBaseRecord
from ieee754.fpcommon.fpbase import MultiShiftRMerge
from ieee754.fpcommon.fpbase import FPState
from .postcalc import FPAddStage1Data
def __init__(self, width, id_wid):
self.roundz = Signal(reset_less=True, name="norm1_roundz")
- self.z = FPNumBase(width, False)
+ self.z = FPNumBaseRecord(width, False)
self.out_do_z = Signal(reset_less=True)
self.oz = Signal(width, reset_less=True)
self.mid = Signal(id_wid, reset_less=True)
of = Overflow()
m.d.comb += self.o.roundz.eq(of.roundz)
- m.submodules.norm1_out_z = self.o.z
+ #m.submodules.norm1_out_z = self.o.z
m.submodules.norm1_out_overflow = of
- m.submodules.norm1_in_z = self.i.z
+ #m.submodules.norm1_in_z = self.i.z
m.submodules.norm1_in_overflow = self.i.of
i = self.ispec()
- m.submodules.norm1_insel_z = i.z
+ m.submodules.norm1_insel_z = insel_z = FPNumBase(i.z)
m.submodules.norm1_insel_overflow = i.of
- espec = (len(i.z.e), True)
+ espec = (len(insel_z.e), True)
ediff_n126 = Signal(espec, reset_less=True)
msr = MultiShiftRMerge(mwid+2, espec)
m.submodules.multishift_r = msr
m.d.comb += i.eq(self.i)
# initialise out from in (overridden below)
- m.d.comb += self.o.z.eq(i.z)
+ m.d.comb += self.o.z.eq(insel_z)
m.d.comb += of.eq(i.of)
# normalisation increase/decrease conditions
decrease = Signal(reset_less=True)
increase = Signal(reset_less=True)
- m.d.comb += decrease.eq(i.z.m_msbzero & i.z.exp_gt_n126)
- m.d.comb += increase.eq(i.z.exp_lt_n126)
+ m.d.comb += decrease.eq(insel_z.m_msbzero & insel_z.exp_gt_n126)
+ m.d.comb += increase.eq(insel_z.exp_lt_n126)
# decrease exponent
with m.If(~self.i.out_do_z):
with m.If(decrease):
# we reverse the order of the bits.
temp_m = Signal(mwid, reset_less=True)
temp_s = Signal(mwid+1, reset_less=True)
- clz = Signal((len(i.z.e), True), reset_less=True)
+ clz = Signal((len(insel_z.e), True), reset_less=True)
# make sure that the amount to decrease by does NOT
# go below the minimum non-INF/NaN exponent
- limclz = Mux(i.z.exp_sub_n126 > pe.o, pe.o,
- i.z.exp_sub_n126)
+ limclz = Mux(insel_z.exp_sub_n126 > pe.o, pe.o,
+ insel_z.exp_sub_n126)
m.d.comb += [
# cat round and guard bits back into the mantissa
- temp_m.eq(Cat(i.of.round_bit, i.of.guard, i.z.m)),
+ temp_m.eq(Cat(i.of.round_bit, i.of.guard, insel_z.m)),
pe.i.eq(temp_m[::-1]), # inverted
clz.eq(limclz), # count zeros from MSB down
temp_s.eq(temp_m << clz), # shift mantissa UP
- self.o.z.e.eq(i.z.e - clz), # DECREASE exponent
+ self.o.z.e.eq(insel_z.e - clz), # DECREASE exponent
self.o.z.m.eq(temp_s[2:]), # exclude bits 0&1
of.m0.eq(temp_s[2]), # copy of mantissa[0]
# overflow in bits 0..1: got shifted too (leave sticky)
temp_m = Signal(mwid+1, reset_less=True)
m.d.comb += [
temp_m.eq(Cat(i.of.sticky, i.of.round_bit, i.of.guard,
- i.z.m)),
- ediff_n126.eq(i.z.N126 - i.z.e),
+ insel_z.m)),
+ ediff_n126.eq(insel_z.fp.N126 - insel_z.e),
# connect multi-shifter to inp/out mantissa (and ediff)
msr.inp.eq(temp_m),
msr.diff.eq(ediff_n126),
of.guard.eq(msr.m[2]), # guard
of.round_bit.eq(msr.m[1]), # round
of.sticky.eq(msr.m[0]), # sticky
- self.o.z.e.eq(i.z.e + ediff_n126),
+ self.o.z.e.eq(insel_z.e + ediff_n126),
]
m.d.comb += self.o.mid.eq(self.i.mid)
from nmigen import Module, Signal, Elaboratable
from nmigen.cli import main, verilog
-from ieee754.fpcommon.fpbase import FPNumBase
+from ieee754.fpcommon.fpbase import FPNumBase, FPNumBaseRecord
from ieee754.fpcommon.fpbase import FPState
from .postnormalise import FPNorm1Data
class FPRoundData:
def __init__(self, width, id_wid):
- self.z = FPNumBase(width, False)
+ self.z = FPNumBaseRecord(width, False)
self.out_do_z = Signal(reset_less=True)
self.oz = Signal(width, reset_less=True)
self.mid = Signal(id_wid, reset_less=True)
def setup(self, m, i):
m.submodules.roundz = self
- m.submodules.round_out_z = self.i.z
m.d.comb += self.i.eq(i)
def elaborate(self, platform):