From: Luke Kenneth Casson Leighton Date: Wed, 6 Mar 2019 12:14:47 +0000 (+0000) Subject: in the middle of rewiring FPADD to use FPADDBase X-Git-Tag: ls180-24jan2020~1722 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f39188c47f81343121785bad1366a831d115a924;p=ieee754fpu.git in the middle of rewiring FPADD to use FPADDBase --- diff --git a/src/add/nmigen_add_experiment.py b/src/add/nmigen_add_experiment.py index edcb17dd..2f5d9811 100644 --- a/src/add/nmigen_add_experiment.py +++ b/src/add/nmigen_add_experiment.py @@ -28,7 +28,7 @@ class FPState(FPBase): class FPGetOpMod: def __init__(self, width): self.in_op = FPOp(width) - self.out_op = FPNumIn(self.in_op, width) + self.out_op = Signal(width) self.out_decode = Signal(reset_less=True) def elaborate(self, platform): @@ -38,7 +38,7 @@ class FPGetOpMod: m.submodules.get_op_out = self.out_op with m.If(self.out_decode): m.d.comb += [ - self.out_op.decode(self.in_op.v), + self.out_op.eq(self.in_op.v), ] return m @@ -52,7 +52,7 @@ class FPGetOp(FPState): self.out_state = out_state self.mod = FPGetOpMod(width) self.in_op = in_op - self.out_op = FPNumIn(in_op, width) + self.out_op = Signal(width) self.out_decode = Signal(reset_less=True) def setup(self, m, in_op): @@ -60,7 +60,7 @@ class FPGetOp(FPState): """ setattr(m.submodules, self.state_from, self.mod) m.d.comb += self.mod.in_op.copy(in_op) - m.d.comb += self.out_op.v.eq(self.mod.out_op.v) + #m.d.comb += self.out_op.eq(self.mod.out_op) m.d.comb += self.out_decode.eq(self.mod.out_decode) def action(self, m): @@ -68,7 +68,7 @@ class FPGetOp(FPState): m.next = self.out_state m.d.sync += [ self.in_op.ack.eq(0), - self.out_op.copy(self.mod.out_op) + self.out_op.eq(self.mod.out_op) ] with m.Else(): m.d.sync += self.in_op.ack.eq(1) @@ -1026,7 +1026,7 @@ class FPPutZ(FPState): m.d.sync += self.out_z.stb.eq(1) -class FPADDBase(FPID): +class FPADDBaseMod(FPID): def __init__(self, width, id_wid=None, single_cycle=False): """ IEEE754 FP Add @@ -1109,8 +1109,85 @@ class FPADDBase(FPID): return m +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) + class FPADD(FPID): + """ FPADD: stages as follows: + + FPGetOp (a) + | + FPGetOp (b) + | + FPAddBase---> GetOps->Specials->Align->Add1/2->Norm->Round/Pack->PutZ + | + PutZ + + FPAddBase is tricky: it is both a stage and *has* stages. + """ def __init__(self, width, id_wid=None, single_cycle=False): """ IEEE754 FP Add @@ -1121,6 +1198,7 @@ class FPADD(FPID): """ FPID.__init__(self, id_wid) self.width = width + self.id_wid = id_wid self.single_cycle = single_cycle self.in_a = FPOp(width) @@ -1146,17 +1224,16 @@ class FPADD(FPID): geta.setup(m, self.in_a) a = geta.out_op - getb = self.add_state(FPGetOp("get_b", "special_cases", + getb = self.add_state(FPGetOp("get_b", "add", self.in_b, self.width)) getb.setup(m, self.in_b) b = getb.out_op - ab = FPADDBase() - #pa = self.add_state(FPPack(self.width, self.id_wid)) - #pa.setup(m, cor.out_z, rn.in_mid) + ab = FPADDBase(self.width, self.id_wid, self.single_cycle)) + ab = self.add_state("add", ab) - pz = self.add_state(FPPutZ("put_z", sc.out_z, self.out_z, - pa.in_mid, self.out_mid)) + pz = self.add_state(FPPutZ("put_z", ab.out_z, self.out_z, + ab.out_mid, self.out_mid)) with m.FSM() as fsm: diff --git a/src/add/test_add_base.py b/src/add/test_add_base.py index d1552c19..803124c1 100644 --- a/src/add/test_add_base.py +++ b/src/add/test_add_base.py @@ -89,6 +89,6 @@ def testbench(dut): yield from check_case(dut, 0x42500000, 0x4E5693A4, 0x4E5693A5) if __name__ == '__main__': - dut = FPADDBase(width=32, id_wid=5, single_cycle=True) + dut = FPADDBaseMod(width=32, id_wid=5, single_cycle=True) run_simulation(dut, testbench(dut), vcd_name="test_add.vcd")