From: Luke Kenneth Casson Leighton Date: Wed, 31 Jul 2019 12:06:53 +0000 (+0100) Subject: tidyup, use FPModBaseChain and FPModBase X-Git-Tag: ls180-24jan2020~635 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=98e97ab576da3b41a47fb0fe202b8da7d6080969;p=ieee754fpu.git tidyup, use FPModBaseChain and FPModBase --- diff --git a/src/ieee754/fpadd/addstages.py b/src/ieee754/fpadd/addstages.py index 48936583..170b37c6 100644 --- a/src/ieee754/fpadd/addstages.py +++ b/src/ieee754/fpadd/addstages.py @@ -4,45 +4,19 @@ Copyright (C) 2019 Luke Kenneth Casson Leighton """ -from nmigen import Module -from nmigen.cli import main, verilog +from ieee754.fpcommon.modbase import FPModBaseChain -from nmutil.singlepipe import StageChain -from ieee754.pipeline import DynamicPipe - -from ieee754.fpcommon.denorm import FPSCData -from ieee754.fpcommon.postcalc import FPAddStage1Data from ieee754.fpadd.align import FPAddAlignSingleMod from ieee754.fpadd.add0 import FPAddStage0Mod from ieee754.fpadd.add1 import FPAddStage1Mod -class FPAddAlignSingleAdd(DynamicPipe): - - def __init__(self, pspec): - self.pspec = pspec - super().__init__(pspec) - - def ispec(self): - return FPSCData(self.pspec, True) - - def ospec(self): - return FPAddStage1Data(self.pspec) # AddStage1 ospec - - def setup(self, m, i): - """ links module to inputs and outputs - """ +class FPAddAlignSingleAdd(FPModBaseChain): + def get_chain(self): # chain AddAlignSingle, AddStage0 and AddStage1 mod = FPAddAlignSingleMod(self.pspec) a0mod = FPAddStage0Mod(self.pspec) a1mod = FPAddStage1Mod(self.pspec) - chain = StageChain([mod, a0mod, a1mod]) - chain.setup(m, i) - - self.o = a1mod.o - - def process(self, i): - return self.o - + return [mod, a0mod, a1mod] diff --git a/src/ieee754/fpcommon/modbase.py b/src/ieee754/fpcommon/modbase.py index 0daa6f63..1b338747 100644 --- a/src/ieee754/fpcommon/modbase.py +++ b/src/ieee754/fpcommon/modbase.py @@ -1,4 +1,7 @@ from nmigen import Elaboratable +from ieee754.pipeline import DynamicPipe +from nmutil.singlepipe import StageChain + class FPModBase(Elaboratable): """FPModBase: common code between nearly every pipeline module @@ -18,3 +21,30 @@ class FPModBase(Elaboratable): setattr(m.submodules, self.modname, self) m.d.comb += self.i.eq(i) + +class FPModBaseChain(DynamicPipe): + """FPModBaseChain: common code between stage-chained pipes + """ + def __init__(self, pspec): + self.pspec = pspec + self.chain = self.get_chain() + super().__init__(pspec) + + def ispec(self): + """ returns the input spec of the first module in the chain + """ + return self.chain[0].ispec() + + def ospec(self): + """ returns the output spec of the last module in the chain + """ + return self.chain[-1].ospec() + + def process(self, i): + return self.o # ... returned here (see setup comment below) + + def setup(self, m, i): + """ links module to inputs and outputs + """ + StageChain(self.chain).setup(m, i) # input linked here, through chain + self.o = self.chain[-1].o # output is the last thing in the chain... diff --git a/src/ieee754/fpdiv/div0.py b/src/ieee754/fpdiv/div0.py index 4b9f25a9..af0097c3 100644 --- a/src/ieee754/fpdiv/div0.py +++ b/src/ieee754/fpdiv/div0.py @@ -13,15 +13,15 @@ Relevant bugreports: from nmigen import Module, Signal, Cat, Elaboratable, Const, Mux from nmigen.cli import main, verilog +from ieee754.fpcommon.modbase import FPModBase from ieee754.fpcommon.fpbase import FPNumBaseRecord -from ieee754.fpcommon.fpbase import FPState from ieee754.fpcommon.denorm import FPSCData from ieee754.fpcommon.getop import FPPipeContext from ieee754.div_rem_sqrt_rsqrt.div_pipe import DivPipeInputData from ieee754.div_rem_sqrt_rsqrt.core import DivPipeCoreOperation as DPCOp -class FPDivStage0Mod(Elaboratable): +class FPDivStage0Mod(FPModBase): """ DIV/SQRT/RSQRT "preparation" module. adjusts mantissa and exponent (sqrt/rsqrt exponent must be even), @@ -32,9 +32,7 @@ class FPDivStage0Mod(Elaboratable): """ def __init__(self, pspec): - self.pspec = pspec - self.i = self.ispec() - self.o = self.ospec() + super().__init__(pspec, "div0") def ispec(self): return FPSCData(self.pspec, False) @@ -42,15 +40,6 @@ class FPDivStage0Mod(Elaboratable): def ospec(self): return DivPipeInputData(self.pspec) - def process(self, i): - return self.o - - def setup(self, m, i): - """ links module to inputs and outputs - """ - m.submodules.div0 = self - m.d.comb += self.i.eq(i) - def elaborate(self, platform): m = Module() comb = m.d.comb @@ -118,22 +107,3 @@ class FPDivStage0Mod(Elaboratable): return m -class FPDivStage0(FPState): - """ First stage of div. - """ - - def __init__(self, pspec): - FPState.__init__(self, "divider_0") - self.mod = FPDivStage0Mod(pspec) - self.o = self.mod.ospec() - - def setup(self, m, i): - """ links module to inputs and outputs - """ - self.mod.setup(m, i) - - # NOTE: these could be done as combinatorial (merge div0+div1) - m.d.sync += self.o.eq(self.mod.o) - - def action(self, m): - m.next = "divider_1" diff --git a/src/ieee754/fpdiv/div2.py b/src/ieee754/fpdiv/div2.py index 5a26ace7..c8f26aa8 100644 --- a/src/ieee754/fpdiv/div2.py +++ b/src/ieee754/fpdiv/div2.py @@ -9,15 +9,15 @@ Relevant bugreports: * http://bugs.libre-riscv.org/show_bug.cgi?id=44 """ -from nmigen import Module, Signal, Elaboratable, Cat +from nmigen import Module, Signal, Cat from nmigen.cli import main, verilog -from ieee754.fpcommon.fpbase import FPState +from ieee754.fpcommon.modbase import FPModBase from ieee754.fpcommon.postcalc import FPAddStage1Data from ieee754.div_rem_sqrt_rsqrt.div_pipe import DivPipeOutputData -class FPDivStage2Mod(FPState, Elaboratable): +class FPDivStage2Mod(FPModBase): """ Last stage of div: preparation for normalisation. NOTE: this phase does NOT do ACTUAL DIV processing, it ONLY @@ -25,9 +25,7 @@ class FPDivStage2Mod(FPState, Elaboratable): """ def __init__(self, pspec): - self.pspec = pspec - self.i = self.ispec() - self.o = self.ospec() + super().__init__(pspec, "div1") def ispec(self): return DivPipeOutputData(self.pspec) # Q/Rem in... @@ -37,15 +35,6 @@ class FPDivStage2Mod(FPState, Elaboratable): # required for ongoing processing (normalisation, correction etc.) return FPAddStage1Data(self.pspec) # out to post-process - def process(self, i): - return self.o - - def setup(self, m, i): - """ links module to inputs and outputs - """ - m.submodules.div1 = self - m.d.comb += self.i.eq(i) - def elaborate(self, platform): m = Module() comb = m.d.comb @@ -117,25 +106,3 @@ class FPDivStage2Mod(FPState, Elaboratable): return m -class FPDivStage2(FPState): - - def __init__(self, pspec): - FPState.__init__(self, "divider_1") - self.mod = FPDivStage2Mod(pspec) - self.out_z = FPNumBaseRecord(pspec, False) - self.out_of = Overflow() - self.norm_stb = Signal() - - def setup(self, m, i): - """ links module to inputs and outputs - """ - self.mod.setup(m, i) - - m.d.sync += self.norm_stb.eq(0) # sets to zero when not in div1 state - - m.d.sync += self.out_of.eq(self.mod.out_of) - m.d.sync += self.out_z.eq(self.mod.out_z) - m.d.sync += self.norm_stb.eq(1) - - def action(self, m): - m.next = "normalise_1" diff --git a/src/ieee754/fpmul/mulstages.py b/src/ieee754/fpmul/mulstages.py index 5ce17c1f..fb809cbc 100644 --- a/src/ieee754/fpmul/mulstages.py +++ b/src/ieee754/fpmul/mulstages.py @@ -5,38 +5,19 @@ from nmigen.cli import main, verilog from nmutil.singlepipe import StageChain -from ieee754.pipeline import DynamicPipe +from ieee754.fpcommon.modbase import FPModBaseChain from ieee754.fpcommon.denorm import FPSCData from ieee754.fpcommon.postcalc import FPAddStage1Data from ieee754.fpmul.mul0 import FPMulStage0Mod from ieee754.fpmul.mul1 import FPMulStage1Mod -class FPMulStages(DynamicPipe): - - def __init__(self, pspec): - self.pspec = pspec - super().__init__(pspec) - - def ispec(self): - return FPSCData(self.pspec, False) - - def ospec(self): - return FPAddStage1Data(self.pspec) - - def setup(self, m, i): - """ links module to inputs and outputs - """ +class FPMulStages(FPModBaseChain): + def get_chain(self): # chain MulStage0 and MulStage1 m0mod = FPMulStage0Mod(self.pspec) m1mod = FPMulStage1Mod(self.pspec) - chain = StageChain([m0mod, m1mod]) - chain.setup(m, i) - - self.o = m1mod.o - - def process(self, i): - return self.o + return [m0mod, m1mod]