From: Luke Kenneth Casson Leighton Date: Sat, 29 Jun 2019 08:47:38 +0000 (+0100) Subject: put in place infrastructure for dropping in INT div unit X-Git-Tag: ls180-24jan2020~961 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=1ca7b302ef5a030407fc07e6435f7ba08c2ec83c;p=ieee754fpu.git put in place infrastructure for dropping in INT div unit number of combinatorial stages specified as an argument to FPDivStages start mode does initial conversion from pre-normalised format not-start and not-end mode inputs Q/Rem data and outputs Q/Rem data end mode converts Q/Rem data to format needed for post-normalisation --- diff --git a/src/ieee754/fpdiv/div0.py b/src/ieee754/fpdiv/div0.py index 796e6c29..45a5f971 100644 --- a/src/ieee754/fpdiv/div0.py +++ b/src/ieee754/fpdiv/div0.py @@ -6,7 +6,7 @@ Relevant bugreport: http://bugs.libre-riscv.org/show_bug.cgi?id=99 from nmigen import Module, Signal, Cat, Elaboratable from nmigen.cli import main, verilog -from ieee754.fpcommon.fpbase import FPNumBaseRecord +from ieee754.fpcommon.fpbase import (FPNumBaseRecord, Overflow) from ieee754.fpcommon.fpbase import FPState from ieee754.fpcommon.denorm import FPSCData @@ -17,6 +17,7 @@ class FPDivStage0Data: self.z = FPNumBaseRecord(width, False) self.out_do_z = Signal(reset_less=True) self.oz = Signal(width, reset_less=True) + self.of = Overflow() # TODO: here is where Q and R would be put, and passed # down to Stage1 processing. @@ -28,6 +29,7 @@ class FPDivStage0Data: def eq(self, i): return [self.z.eq(i.z), self.out_do_z.eq(i.out_do_z), self.oz.eq(i.oz), + self.of.eq(i.of), self.product.eq(i.product), self.mid.eq(i.mid)] diff --git a/src/ieee754/fpdiv/divstages.py b/src/ieee754/fpdiv/divstages.py index e1f8b113..2d0cbe5d 100644 --- a/src/ieee754/fpdiv/divstages.py +++ b/src/ieee754/fpdiv/divstages.py @@ -21,35 +21,53 @@ from .div2 import FPDivStage2Mod class FPDivStages(FPState, SimpleHandshake): - def __init__(self, width, id_wid): + def __init__(self, width, id_wid, n_stages, begin, end): FPState.__init__(self, "align") self.width = width self.id_wid = id_wid + 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() def ispec(self): - return FPSCData(self.width, self.id_wid, False) + if self.begin: + return FPSCData(self.width, self.id_wid, False) + return FPAddStage1Data(self.width, self.id_wid) # AddStage1 ospec def ospec(self): + if self.end: # TODO + return FPAddStage1Data(self.width, self.id_wid) # AddStage1 ospec return FPAddStage1Data(self.width, self.id_wid) # AddStage1 ospec def setup(self, m, i): """ links module to inputs and outputs """ - # TODO. clearly, this would be a for-loop, here, creating - # a huge number of stages (if radix-2 is used). interestingly - # the number of stages will be data-dependent. - divstages = [FPDivStage0Mod(self.width, self.id_wid)] - for i in range(self.width): # XXX TODO: work out actual number needed + # 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, + + # end mode takes the DIV pipeline/chain data and munges it + # into the format that the normalisation can accept. + + divstages = [] + + if self.begin: # XXX check this + divstages.append(FPDivStage0Mod(self.width, self.id_wid)) + + for count in range(self.n_stages): # number of combinatorial stages divstages.append(FPDivStage1Mod(self.width, self.id_wid)) - divstages.append(FPDivStage2Mod(self.width, self.id_wid)) + + if self.end: # XXX check this + divstages.append(FPDivStage2Mod(self.width, self.id_wid)) chain = StageChain(divstages) chain.setup(m, i) - self.o = m1mod.o + # output is from the last pipe stage + self.o = divstages[-1].o def process(self, i): return self.o diff --git a/src/ieee754/fpdiv/pipeline.py b/src/ieee754/fpdiv/pipeline.py index 7c130fae..8bd16908 100644 --- a/src/ieee754/fpdiv/pipeline.py +++ b/src/ieee754/fpdiv/pipeline.py @@ -18,17 +18,27 @@ from .divstages import FPDivStages class FPDIVBasePipe(ControlBase): def __init__(self, width, id_wid): ControlBase.__init__(self) - self.pipe1 = FPDIVSpecialCasesDeNorm(width, id_wid) - self.pipe2 = FPDivStages(width, id_wid) - self.pipe3 = FPNormToPack(width, id_wid) + self.pipestart = FPDIVSpecialCasesDeNorm(width, id_wid) + pipechain = [] + n_stages = 6 # TODO + n_combinatorial_stages = 2 # TODO + for i in range(n_stages): + begin = i == 0 # needs to convert input from pipestart ospec + end = i == n_stages - 1 # needs to convert output to pipeend ispec + pipechain.append(FPDivStages(width, id_wid, + n_combinatorial_stages, + begin, end)) + self.pipechain = pipechain + self.pipeend = FPNormToPack(width, id_wid) - self._eqs = self.connect([self.pipe1, self.pipe2, self.pipe3]) + self._eqs = self.connect([self.pipestart] + pipechain + [self.pipeend]) def elaborate(self, platform): m = ControlBase.elaborate(self, platform) - m.submodules.scnorm = self.pipe1 - m.submodules.divstages = self.pipe2 - m.submodules.normpack = self.pipe3 + m.submodules.scnorm = self.pipestart + for i, p in enumerate(self.pipechain): + setattr(m.submodules, "pipediv%d" % i, p) + m.submodules.normpack = self.pipeend m.d.comb += self._eqs return m