m.d.sync += self.in_op.ack.eq(1)
-class FPGetOpB(FPState):
- """ gets operand b
- """
-
- def __init__(self, in_b, width):
- FPState.__init__(self, "get_b")
- self.in_b = in_b
- self.b = FPNumIn(self.in_b, width)
-
- def action(self, m):
- self.get_op(m, self.in_b, self.b, "special_cases")
-
-
class FPAddSpecialCasesMod:
""" special cases: NaNs, infs, zeros, denormalised
NOTE: some of these are unique to add. see "Special Operations"
self.out_z = FPNumOut(width, False)
self.out_do_z = Signal(reset_less=True)
- def setup(self, m, in_a, in_b, out_z, out_do_z):
- """ links module to inputs and outputs
- """
- m.d.comb += self.in_a.copy(in_a)
- m.d.comb += self.in_b.copy(in_b)
- #m.d.comb += out_z.v.eq(self.out_z.v)
- m.d.comb += out_do_z.eq(self.out_do_z)
-
def elaborate(self, platform):
m = Module()
return m
-class FPAddSpecialCases(FPState):
+class FPID:
+ def __init__(self, id_wid):
+ self.id_wid = id_wid
+ if self.id_wid:
+ self.in_mid = Signal(width, reset_less)
+ self.out_mid = Signal(width, reset_less)
+ else:
+ self.in_mid = None
+ self.out_mid = None
+
+ def idsync(self, m):
+ if self.id_wid:
+ m.d.sync += self.out_mid.eq(self.in_mid)
+
+
+class FPAddSpecialCases(FPState, FPID):
""" special cases: NaNs, infs, zeros, denormalised
NOTE: some of these are unique to add. see "Special Operations"
https://steve.hollasch.net/cgindex/coding/ieeefloat.html
"""
- def __init__(self, width):
+ def __init__(self, width, id_wid):
FPState.__init__(self, "special_cases")
+ FPID.__init__(self, id_wid)
self.mod = FPAddSpecialCasesMod(width)
self.out_z = FPNumOut(width, False)
self.out_do_z = Signal(reset_less=True)
+ def setup(self, m, in_a, in_b, in_mid):
+ """ links module to inputs and outputs
+ """
+ m.submodules.specialcases = self.mod
+ m.d.comb += self.mod.in_a.copy(in_a)
+ m.d.comb += self.mod.in_b.copy(in_b)
+ #m.d.comb += self.out_z.v.eq(self.mod.out_z.v)
+ m.d.comb += self.out_do_z.eq(self.mod.out_do_z)
+ if self.in_mid:
+ m.d.comb += self.in_mid.eq(in_mid)
+
def action(self, m):
+ self.idsync(m)
with m.If(self.out_do_z):
m.d.sync += self.out_z.v.eq(self.mod.out_z.v) # only take the output
m.next = "put_z"
return m
-class FPAddDeNorm(FPState):
+class FPAddDeNorm(FPState, FPID):
- def __init__(self, width):
+ def __init__(self, width, id_wid):
FPState.__init__(self, "denormalise")
+ FPID.__init__(self, id_wid)
self.mod = FPAddDeNormMod(width)
self.out_a = FPNumBase(width)
self.out_b = FPNumBase(width)
- def setup(self, m, in_a, in_b):
+ def setup(self, m, in_a, in_b, in_mid):
""" links module to inputs and outputs
"""
m.submodules.denormalise = self.mod
m.d.comb += self.mod.in_a.copy(in_a)
m.d.comb += self.mod.in_b.copy(in_b)
+ if self.in_mid:
+ m.d.comb += self.in_mid.eq(in_mid)
def action(self, m):
+ self.idsync(m)
# Denormalised Number checks
m.next = "align"
m.d.sync += self.out_a.copy(self.mod.out_a)
return m
-class FPAddAlignMulti(FPState):
+class FPAddAlignMulti(FPState, FPID):
- def __init__(self, width):
+ def __init__(self, width, id_wid):
+ FPID.__init__(self, id_wid)
FPState.__init__(self, "align")
self.mod = FPAddAlignMultiMod(width)
self.out_a = FPNumIn(None, width)
self.out_b = FPNumIn(None, width)
self.exp_eq = Signal(reset_less=True)
- def setup(self, m, in_a, in_b):
+ def setup(self, m, in_a, in_b, in_mid):
""" links module to inputs and outputs
"""
m.submodules.align = self.mod
#m.d.comb += self.out_a.copy(self.mod.out_a)
#m.d.comb += self.out_b.copy(self.mod.out_b)
m.d.comb += self.exp_eq.eq(self.mod.exp_eq)
+ if self.in_mid:
+ m.d.comb += self.in_mid.eq(in_mid)
def action(self, m):
+ self.idsync(m)
m.d.sync += self.out_a.copy(self.mod.out_a)
m.d.sync += self.out_b.copy(self.mod.out_b)
with m.If(self.exp_eq):
return m
-class FPAddAlignSingle(FPState):
+class FPAddAlignSingle(FPState, FPID):
- def __init__(self, width):
+ def __init__(self, width, id_wid):
FPState.__init__(self, "align")
+ FPID.__init__(self, id_wid)
self.mod = FPAddAlignSingleMod(width)
self.out_a = FPNumIn(None, width)
self.out_b = FPNumIn(None, width)
- def setup(self, m, in_a, in_b):
+ def setup(self, m, in_a, in_b, in_mid):
""" links module to inputs and outputs
"""
m.submodules.align = self.mod
m.d.comb += self.mod.in_a.copy(in_a)
m.d.comb += self.mod.in_b.copy(in_b)
+ if self.in_mid:
+ m.d.comb += self.in_mid.eq(in_mid)
def action(self, m):
+ self.idsync(m)
# NOTE: could be done as comb
m.d.sync += self.out_a.copy(self.mod.out_a)
m.d.sync += self.out_b.copy(self.mod.out_b)
m.d.comb += self.out_z.copy(self.in_z)
with m.If(self.in_z.is_denormalised):
m.d.comb += self.out_z.e.eq(self.in_z.N127)
-
- # with m.If(self.in_z.is_overflowed):
- # m.d.comb += self.out_z.inf(self.in_z.s)
- # with m.Else():
- # m.d.comb += self.out_z.create(self.in_z.s, self.in_z.e, self.in_z.m)
return m
m.d.sync += self.out_z.stb.eq(1)
-class FPADD:
+class FPADD(FPID):
+
+ def __init__(self, width, id_wid=None, single_cycle=False):
+ """ IEEE754 FP Add
- def __init__(self, width, single_cycle=False):
+ * width: bit-width of IEEE754. supported: 16, 32, 64
+ * id_wid: an identifier that is sync-connected to the input
+ * single_cycle: True indicates each stage to complete in 1 clock
+ """
+ FPID.__init__(self, id_wid)
self.width = width
self.single_cycle = single_cycle
getb.setup(m, self.in_b)
b = getb.out_op
- sc = self.add_state(FPAddSpecialCases(self.width))
- sc.mod.setup(m, a, b, sc.out_z, sc.out_do_z)
- m.submodules.specialcases = sc.mod
+ sc = self.add_state(FPAddSpecialCases(self.width, self.id_wid))
+ sc.setup(m, a, b, self.in_mid)
- dn = self.add_state(FPAddDeNorm(self.width))
- dn.setup(m, a, b)
+ dn = self.add_state(FPAddDeNorm(self.width, self.id_wid))
+ dn.setup(m, a, b, sc.in_mid)
if self.single_cycle:
- alm = self.add_state(FPAddAlignSingle(self.width))
- alm.setup(m, dn.out_a, dn.out_b)
+ alm = self.add_state(FPAddAlignSingle(self.width, self.id_wid))
+ alm.setup(m, dn.out_a, dn.out_b, dn.in_mid)
else:
- alm = self.add_state(FPAddAlignMulti(self.width))
- #alm.set_inputs({"a": a, "b": b})
- alm.setup(m, dn.out_a, dn.out_b)
+ alm = self.add_state(FPAddAlignMulti(self.width, self.id_wid))
+ alm.setup(m, dn.out_a, dn.out_b, dn.in_mid)
add0 = self.add_state(FPAddStage0(self.width))
add0.setup(m, alm.out_a, alm.out_b)