From c7a5c64c1c434638298ab2da7e51233773d5bbc4 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Sat, 20 Apr 2019 16:21:48 +0100 Subject: [PATCH] convert to use PrevControl and NextControl instead of Trigger class Trigger contained stb/ack where it is ok to call them ready/valid prev/next --- src/add/fpadd/statemachine.py | 18 ++++++------- src/add/fpbase.py | 46 ++++++++++++++++++++++---------- src/add/fpcommon/getop.py | 11 ++++---- src/add/fpcommon/putz.py | 14 +++++----- src/add/nmigen_div_experiment.py | 12 ++++----- src/add/singlepipe.py | 10 +++---- src/add/test_fsm_experiment.py | 18 ++++++------- src/add/unit_test_single.py | 36 ++++++++++++------------- 8 files changed, 92 insertions(+), 73 deletions(-) diff --git a/src/add/fpadd/statemachine.py b/src/add/fpadd/statemachine.py index 01847074..dab9dd79 100644 --- a/src/add/fpadd/statemachine.py +++ b/src/add/fpadd/statemachine.py @@ -6,7 +6,7 @@ from nmigen import Module, Signal, Cat, Mux, Array, Const from nmigen.cli import main, verilog from math import log -from fpbase import FPOp +from fpbase import FPOpIn, FPOpOut from fpbase import Trigger from singlepipe import (StageChain, SimpleHandshake) @@ -31,7 +31,7 @@ from fpadd.addstages import FPAddAlignSingleAdd class FPOpData: def __init__(self, width, id_wid): - self.z = FPOp(width) + self.z = FPOpOut(width) self.mid = Signal(id_wid, reset_less=True) def eq(self, i): @@ -202,13 +202,13 @@ class FPADDBase(FPState): self.in_t.ack.eq(self.mod.in_t.ack), self.o.mid.eq(self.mod.o.mid), self.o.z.v.eq(self.mod.o.z.v), - self.o.z.stb.eq(self.mod.o.z.stb), - self.mod.o.z.ack.eq(self.o.z.ack), + self.o.z.o_valid.eq(self.mod.o.z.o_valid), + self.mod.o.z.i_ready.eq(self.o.z.i_ready_test), ] m.d.sync += self.add_stb.eq(add_stb) m.d.sync += self.add_ack.eq(0) # sets to zero when not in active state - m.d.sync += self.o.z.ack.eq(0) # likewise + m.d.sync += self.o.z.i_ready.eq(0) # likewise #m.d.sync += self.in_t.stb.eq(0) m.submodules.fpadd = self.mod @@ -230,7 +230,7 @@ class FPADDBase(FPState): with m.Else(): m.d.sync += [self.add_ack.eq(0), self.in_t.stb.eq(0), - self.o.z.ack.eq(1), + self.o.z.i_ready.eq(1), ] with m.Else(): # done: acknowledge, and write out id and value @@ -288,8 +288,8 @@ class FPADD(FPID): rs = [] for i in range(rs_sz): - in_a = FPOp(width) - in_b = FPOp(width) + in_a = FPOpIn(width) + in_b = FPOpIn(width) in_a.name = "in_a_%d" % i in_b.name = "in_b_%d" % i rs.append((in_a, in_b)) @@ -297,7 +297,7 @@ class FPADD(FPID): res = [] for i in range(rs_sz): - out_z = FPOp(width) + out_z = FPOpOut(width) out_z.name = "out_z_%d" % i res.append(out_z) self.res = Array(res) diff --git a/src/add/fpbase.py b/src/add/fpbase.py index b31ab21c..c53cabbb 100644 --- a/src/add/fpbase.py +++ b/src/add/fpbase.py @@ -7,6 +7,7 @@ from math import log from operator import or_ from functools import reduce +from singlepipe import PrevControl, NextControl from pipeline import ObjectProxy @@ -479,12 +480,12 @@ class Trigger: return [self.stb, self.ack] -class FPOp(Trigger): +class FPOpIn(PrevControl): def __init__(self, width): - Trigger.__init__(self) + PrevControl.__init__(self) self.width = width - - self.v = Signal(width) + self.v = Signal(width) + self.i_data = self.v def chain_inv(self, in_op, extra=None): stb = in_op.stb @@ -504,14 +505,31 @@ class FPOp(Trigger): in_op.ack.eq(self.ack), # send ACK ] - def eq(self, inp): - return [self.v.eq(inp.v), - self.stb.eq(inp.stb), - self.ack.eq(inp.ack) + +class FPOpOut(NextControl): + def __init__(self, width): + NextControl.__init__(self) + self.width = width + self.v = Signal(width) + self.o_data = self.v + + def chain_inv(self, in_op, extra=None): + stb = in_op.stb + if extra is not None: + stb = stb & extra + return [self.v.eq(in_op.v), # receive value + self.stb.eq(stb), # receive STB + in_op.ack.eq(~self.ack), # send ACK ] - def ports(self): - return [self.v, self.stb, self.ack] + def chain_from(self, in_op, extra=None): + stb = in_op.stb + if extra is not None: + stb = stb & extra + return [self.v.eq(in_op.v), # receive value + self.stb.eq(stb), # receive STB + in_op.ack.eq(self.ack), # send ACK + ] class Overflow: @@ -551,7 +569,7 @@ class FPBase: """ res = v.decode2(m) ack = Signal() - with m.If((op.ack) & (op.stb)): + with m.If((op.o_ready) & (op.i_valid_test)): m.next = next_state # op is latched in from FPNumIn class on same ack/stb m.d.comb += ack.eq(0) @@ -661,11 +679,11 @@ class FPBase: m.d.sync += [ out_z.v.eq(z.v) ] - with m.If(out_z.stb & out_z.ack): - m.d.sync += out_z.stb.eq(0) + with m.If(out_z.o_valid & out_z.i_ready_test): + m.d.sync += out_z.o_valid.eq(0) m.next = next_state with m.Else(): - m.d.sync += out_z.stb.eq(1) + m.d.sync += out_z.o_valid.eq(1) class FPState(FPBase): diff --git a/src/add/fpcommon/getop.py b/src/add/fpcommon/getop.py index 8cf5e421..e7756302 100644 --- a/src/add/fpcommon/getop.py +++ b/src/add/fpcommon/getop.py @@ -7,7 +7,7 @@ from nmigen.lib.coding import PriorityEncoder from nmigen.cli import main, verilog from math import log -from fpbase import FPNumIn, FPNumOut, FPOp, Overflow, FPBase, FPNumBase +from fpbase import FPNumIn, FPNumOut, FPOpIn, Overflow, FPBase, FPNumBase from fpbase import MultiShiftRMerge, Trigger from singlepipe import (ControlBase, StageChain, SimpleHandshake, PassThroughStage) @@ -19,13 +19,14 @@ from fpbase import FPState class FPGetOpMod: def __init__(self, width): - self.in_op = FPOp(width) + self.in_op = FPOpIn(width) self.out_op = Signal(width) self.out_decode = Signal(reset_less=True) def elaborate(self, platform): m = Module() - m.d.comb += self.out_decode.eq((self.in_op.ack) & (self.in_op.stb)) + m.d.comb += self.out_decode.eq((self.in_op.o_ready) & \ + (self.in_op.i_valid_test)) m.submodules.get_op_in = self.in_op #m.submodules.get_op_out = self.out_op with m.If(self.out_decode): @@ -58,11 +59,11 @@ class FPGetOp(FPState): with m.If(self.out_decode): m.next = self.out_state m.d.sync += [ - self.in_op.ack.eq(0), + self.in_op.o_ready.eq(0), self.out_op.eq(self.mod.out_op) ] with m.Else(): - m.d.sync += self.in_op.ack.eq(1) + m.d.sync += self.in_op.o_ready.eq(1) class FPNumBase2Ops: diff --git a/src/add/fpcommon/putz.py b/src/add/fpcommon/putz.py index 106fad9d..6b619ccb 100644 --- a/src/add/fpcommon/putz.py +++ b/src/add/fpcommon/putz.py @@ -25,11 +25,11 @@ class FPPutZ(FPState): m.d.sync += [ self.out_z.z.v.eq(self.in_z) ] - with m.If(self.out_z.z.stb & self.out_z.z.ack): - m.d.sync += self.out_z.z.stb.eq(0) + with m.If(self.out_z.z.o_valid & self.out_z.z.i_ready_test): + m.d.sync += self.out_z.z.o_valid.eq(0) m.next = self.to_state with m.Else(): - m.d.sync += self.out_z.z.stb.eq(1) + m.d.sync += self.out_z.z.o_valid.eq(1) class FPPutZIdx(FPState): @@ -46,15 +46,15 @@ class FPPutZIdx(FPState): def action(self, m): outz_stb = Signal(reset_less=True) outz_ack = Signal(reset_less=True) - m.d.comb += [outz_stb.eq(self.out_zs[self.in_mid].stb), - outz_ack.eq(self.out_zs[self.in_mid].ack), + m.d.comb += [outz_stb.eq(self.out_zs[self.in_mid].o_valid), + outz_ack.eq(self.out_zs[self.in_mid].i_ready_test), ] m.d.sync += [ self.out_zs[self.in_mid].v.eq(self.in_z.v) ] with m.If(outz_stb & outz_ack): - m.d.sync += self.out_zs[self.in_mid].stb.eq(0) + m.d.sync += self.out_zs[self.in_mid].o_valid.eq(0) m.next = self.to_state with m.Else(): - m.d.sync += self.out_zs[self.in_mid].stb.eq(1) + m.d.sync += self.out_zs[self.in_mid].o_valid.eq(1) diff --git a/src/add/nmigen_div_experiment.py b/src/add/nmigen_div_experiment.py index ff0e54cb..5dccecb5 100644 --- a/src/add/nmigen_div_experiment.py +++ b/src/add/nmigen_div_experiment.py @@ -5,7 +5,7 @@ from nmigen import Module, Signal, Const, Cat from nmigen.cli import main, verilog -from fpbase import FPNumIn, FPNumOut, FPOp, Overflow, FPBase, FPState +from fpbase import FPNumIn, FPNumOut, FPOpIn, FPOpOut, Overflow, FPBase, FPState from singlepipe import eq class Div: @@ -33,9 +33,9 @@ class FPDIV(FPBase): FPBase.__init__(self) self.width = width - self.in_a = FPOp(width) - self.in_b = FPOp(width) - self.out_z = FPOp(width) + self.in_a = FPOpIn(width) + self.in_b = FPOpIn(width) + self.out_z = FPOpOut(width) self.states = [] @@ -71,14 +71,14 @@ class FPDIV(FPBase): with m.State("get_a"): res = self.get_op(m, self.in_a, a, "get_b") - m.d.sync += eq([a, self.in_a.ack], res) + m.d.sync += eq([a, self.in_a.o_ready], res) # ****** # gets operand b with m.State("get_b"): res = self.get_op(m, self.in_b, b, "special_cases") - m.d.sync += eq([b, self.in_b.ack], res) + m.d.sync += eq([b, self.in_b.o_ready], res) # ****** # special cases: NaNs, infs, zeros, denormalised diff --git a/src/add/singlepipe.py b/src/add/singlepipe.py index 6ee5afc6..a977dfab 100644 --- a/src/add/singlepipe.py +++ b/src/add/singlepipe.py @@ -214,6 +214,7 @@ class PrevControl: self.i_data = None # XXX MUST BE ADDED BY USER if stage_ctl: self.s_o_ready = Signal(name="p_s_o_rdy") # prev <