from nmigen import Module
from nmigen.cli import main, verilog
-from nmutil.singlepipe import (StageChain, SimpleHandshake)
+from nmutil.singlepipe import StageChain
-from ieee754.fpcommon.fpbase import FPState
+from ieee754.pipeline import DynamicPipe
from ieee754.fpcommon.denorm import FPSCData
from ieee754.fpcommon.postcalc import FPAddStage1Data
+from ieee754.div_rem_sqrt_rsqrt.div_pipe import (DivPipeInterstageData,
+ DivPipeSetupStage,
+ DivPipeCalculateStage,
+ DivPipeFinalStage,
+ )
# TODO: write these
from .div0 import FPDivStage0Mod
-from .div1 import FPDivStage1Mod
from .div2 import FPDivStage2Mod
-from .div0 import FPDivStage0Data
-class FPDivStages(FPState, SimpleHandshake):
+class FPDivStagesSetup(DynamicPipe):
- def __init__(self, width, pspec, n_stages, begin, end):
- FPState.__init__(self, "align")
- self.width = width
+ def __init__(self, pspec, n_stages, stage_offs):
self.pspec = pspec
self.n_stages = n_stages # number of combinatorial stages
- self.begin = begin # "begin" mode
- self.end = end # "end" mode
- SimpleHandshake.__init__(self, self) # pipeline is its own stage
- self.m1o = self.ospec()
+ self.stage_offs = stage_offs # each CalcStage needs *absolute* idx
+ super().__init__(pspec)
def ispec(self):
- if self.begin: # TODO - this is for FPDivStage0Mod
- # REQUIRED. do NOT change.
- return FPSCData(self.width, self.pspec, False) # from denorm
+ # REQUIRED. do NOT change.
+ return FPSCData(self.pspec, False) # from denorm
- if self.end: # TODO - this is for FPDivStage2Mod
- # XXX TODO: replace with "intermediary" (DivPipeCoreInterstageData?)
- return FPDivStage0Data(self.width, self.pspec) # DIV ispec (loop)
+ def ospec(self):
+ return DivPipeInterstageData(self.pspec) # DIV ospec (loop)
- # TODO - this is for FPDivStage1Mod
- # XXX TODO: replace with "intermediary" (DivPipeCoreInterstageData)
- return FPDivStage0Data(self.width, self.pspec) # DIV ispec (loop)
+ def setup(self, m, i):
+ """ links module to inputs and outputs.
+
+ note: this is a pure *combinatorial* module (StageChain).
+ therefore each sub-module must also be combinatorial
+ """
+
+ divstages = []
+
+ # Converts from FPSCData into DivPipeInputData
+ divstages.append(FPDivStage0Mod(self.pspec))
+
+ # does 1 "convert" (actual processing) from DivPipeInputData
+ # into "intermediate" output (DivPipeInterstageData)
+ divstages.append(DivPipeSetupStage(self.pspec))
+
+ # here is where the intermediary stages are added.
+ # n_stages is adjusted (by pipeline.py), reduced to take
+ # into account extra processing that FPDivStage0Mod and DivPipeSetup
+ # might add.
+ for count in range(self.n_stages): # number of combinatorial stages
+ idx = count + self.stage_offs
+ divstages.append(DivPipeCalculateStage(self.pspec, idx))
+
+ chain = StageChain(divstages)
+ chain.setup(m, i)
+
+ # output is from the last pipe stage
+ self.o = divstages[-1].o
+
+ def process(self, i):
+ return self.o
- def ospec(self):
- if self.begin: # TODO - this is for FPDivStage0Mod
- # XXX TODO: replace with "intermediary" (DivPipeCoreInterstageData)
- return FPDivStage0Data(self.width, self.pspec) # DIV ospec (loop)
- if self.end: # TODO - this is for FPDivStage2Mod
- # REQUIRED. do NOT change.
- return FPAddStage1Data(self.width, self.pspec) # to post-norm
+class FPDivStagesIntermediate(DynamicPipe):
+ def __init__(self, pspec, n_stages, stage_offs):
+ self.pspec = pspec
+ self.n_stages = n_stages # number of combinatorial stages
+ self.stage_offs = stage_offs # each CalcStage needs *absolute* idx
+ super().__init__(pspec)
+
+ def ispec(self):
# TODO - this is for FPDivStage1Mod
- # XXX TODO: replace with "intermediary" (DivPipeCoreInterstageData)
- return FPDivStage0Data(self.width, self.pspec) # DIV ospec (loop)
+ return DivPipeInterstageData(self.pspec) # DIV ispec (loop)
+
+ def ospec(self):
+ # TODO - this is for FPDivStage1Mod
+ return DivPipeInterstageData(self.pspec) # DIV ospec (loop)
def setup(self, m, i):
- """ links module to inputs and outputs
+ """ links module to inputs and outputs.
+
+ note: this is a pure *combinatorial* module (StageChain).
+ therefore each sub-module must also be combinatorial
"""
- # start mode accepts data from the FP normalisation stage
- # and does a bit of munging of the data. it will be chained
- # into the first DIV combinatorial block,
+ divstages = []
+
+ # here is where the intermediary stages are added.
+ # n_stages is adjusted (in pipeline.py), reduced to take
+ # into account the extra processing that self.begin and self.end
+ # will add.
+ for count in range(self.n_stages): # number of combinatorial stages
+ idx = count + self.stage_offs
+ divstages.append(DivPipeCalculateStage(self.pspec, idx))
- # end mode takes the DIV pipeline/chain data and munges it
- # into the format that the normalisation can accept.
+ chain = StageChain(divstages)
+ chain.setup(m, i)
- # neither start nor end mode simply takes the exact same
- # data in as out, this is where the Q/Rem comes in and Q/Rem goes out
+ # output is from the last pipe stage
+ self.o = divstages[-1].o
- divstages = []
+ def process(self, i):
+ return self.o
+
+
+class FPDivStagesFinal(DynamicPipe):
+
+ def __init__(self, pspec, n_stages, stage_offs):
+ self.pspec = pspec
+ self.n_stages = n_stages # number of combinatorial stages
+ self.stage_offs = stage_offs # each CalcStage needs *absolute* idx
+ super().__init__(pspec)
- if self.begin: # XXX check this
- divstages.append(FPDivStage0Mod(self.width, self.pspec))
+ def ispec(self):
+ return DivPipeInterstageData(self.pspec) # DIV ispec (loop)
+
+ def ospec(self):
+ # REQUIRED. do NOT change.
+ return FPAddStage1Data(self.pspec) # to post-norm
+
+ def setup(self, m, i):
+ """ links module to inputs and outputs.
+
+ note: this is a pure *combinatorial* module (StageChain).
+ therefore each sub-module must also be combinatorial
+ """
+ # takes the DIV pipeline/chain data and munges it
+ # into the format that the normalisation can accept.
+
+ divstages = []
+
+ # here is where the intermediary stages are added.
+ # n_stages is adjusted (in pipeline.py), reduced to take
+ # into account the extra processing that self.begin and self.end
+ # will add.
for count in range(self.n_stages): # number of combinatorial stages
- divstages.append(FPDivStage1Mod(self.width, self.pspec))
+ idx = count + self.stage_offs
+ divstages.append(DivPipeCalculateStage(self.pspec, idx))
+
+ # does the final conversion from intermediary to output data
+ divstages.append(DivPipeFinalStage(self.pspec))
- if self.end: # XXX check this
- divstages.append(FPDivStage2Mod(self.width, self.pspec))
+ # does conversion from DivPipeOutputData into
+ # FPAddStage1Data format (bad name, TODO, doesn't matter),
+ # so that post-normalisation and corrections can take over
+ divstages.append(FPDivStage2Mod(self.pspec))
chain = StageChain(divstages)
chain.setup(m, i)
def process(self, i):
return self.o
-
- def action(self, m):
- m.d.sync += self.m1o.eq(self.process(None))
- m.next = "normalise_1"
-
-