+class FPADDBase(FPID):
+
+ def __init__(self, width, id_wid=None, single_cycle=False):
+ """ IEEE754 FP Add
+
+ * 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
+ self.mod = FPADDBaseMod(width, id_wid, single_cycle)
+
+ self.in_t = Trigger()
+ self.in_a = Signal(width)
+ self.in_b = Signal(width)
+ self.out_z = FPOp(width)
+
+ self.in_accept = Signal(reset_less=True)
+ self.stb = Signal(reset_less=True)
+ self.ack = Signal(reset=0, reset_less=True)
+
+ def setup(self, a, b, add_stb):
+ m.d.comb += [self.in_a.eq(a),
+ self.in_b.eq(b),
+ self.in_mid.eq(self.in_mod),
+
+ ]
+
+ m.d.comb += self.stb.eq(add_stb)
+ m.d.sync += self.ack.eq(0) # sets to zero when not in normalise_1 state
+
+ m.submodules.add = ab
+
+ def action(self, m):
+
+ m.d.comb += self.in_accept.eq((~self.ack) & (self.stb))
+
+ with m.If(self.out_norm):
+ with m.If(self.in_accept):
+ m.d.sync += [
+ self.ack.eq(1),
+ ]
+ with m.Else():
+ m.d.sync += self.ack.eq(0)
+ with m.Else():
+ # normalisation not required (or done).
+ m.next = "round"
+ m.d.sync += self.ack.eq(1)
+ m.d.sync += self.out_roundz.eq(self.mod.out_of.roundz)
+
+ if self.in_mid is not None:
+ m.d.sync += self.out_mid.eq(self.in_mid)
+
+ m.d.sync += [
+ self.out_z.v.eq(self.in_z.v)
+ ]
+ # move to output state on detecting z
+ with m.If(self.out_z.stb & self.out_z.ack):
+ m.d.sync += self.out_z.stb.eq(0)
+ m.next = "put_z"
+ with m.Else():
+ m.d.sync += self.out_z.stb.eq(1)
+