scnorm - FPDIVSpecialCasesDeNorm ispec FPADDBaseData
------ ospec FPSCData
- StageChain: FPDIVSpecialCasesMod,
- FPAddDeNormMod
+ StageChain: FPDIVSpecialCasesMod,
+ FPAddDeNormMod
pipediv0 - FPDivStagesSetup ispec FPSCData
-------- ospec DivPipeCoreInterstageData
- StageChain: FPDivStage0Mod,
- DivPipeCalculateStage,
- ...
- DivPipeCalculateStage
+ StageChain: FPDivStage0Mod,
+ DivPipeSetupStage,
+ DivPipeCalculateStage,
+ ...
+ DivPipeCalculateStage
pipediv1 - FPDivStagesIntermediate ispec DivPipeCoreInterstageData
-------- ospec DivPipeCoreInterstageData
- StageChain: DivPipeCalculateStage,
- ...
- DivPipeCalculateStage
+ StageChain: DivPipeCalculateStage,
+ ...
+ DivPipeCalculateStage
...
...
pipediv5 - FPDivStageFinal ispec FPDivStage0Data
-------- ospec FPAddStage1Data
- StageChain: DivPipeCalculateStage,
- ...
- DivPipeCalculateStage,
- DivPipeFinalStage,
- FPDivStage2Mod
+ StageChain: DivPipeCalculateStage,
+ ...
+ DivPipeCalculateStage,
+ DivPipeFinalStage,
+ FPDivStage2Mod
normpack - FPNormToPack ispec FPAddStage1Data
-------- ospec FPPackData
- StageChain: Norm1ModSingle,
- RoundMod,
- CorrectionsMod,
- PackMod
+ StageChain: Norm1ModSingle,
+ RoundMod,
+ CorrectionsMod,
+ PackMod
the number of combinatorial StageChains (n_comb_stages) in
FPDivStages is an argument arranged to get the length of the whole
from ieee754.fpcommon.getop import FPADDBaseData
from ieee754.fpcommon.denorm import FPSCData
+from ieee754.fpcommon.fpbase import FPFormat
from ieee754.fpcommon.pack import FPPackData
from ieee754.fpcommon.normtopack import FPNormToPack
-from .specialcases import FPDIVSpecialCasesDeNorm
-from .divstages import (FPDivStagesSetup,
- FPDivStagesIntermediate,
- FPDivStagesFinal)
-
+from ieee754.fpdiv.specialcases import FPDIVSpecialCasesDeNorm
+from ieee754.fpdiv.divstages import (FPDivStagesSetup,
+ FPDivStagesIntermediate,
+ FPDivStagesFinal)
+from ieee754.pipeline import PipelineSpec
+from ieee754.div_rem_sqrt_rsqrt.core import DivPipeCoreConfig
class FPDIVBasePipe(ControlBase):
- def __init__(self, width, pspec):
- ControlBase.__init__(self)
- self.width = width
+ def __init__(self, pspec):
self.pspec = pspec
+ ControlBase.__init__(self)
- def elaborate(self, platform):
- m = ControlBase.elaborate(self, platform)
-
- pipestart = FPDIVSpecialCasesDeNorm(self.width, self.pspec)
pipechain = []
n_stages = 6 # TODO (depends on width)
- n_comb_stages = 3 # TODO (depends on how many RS's we want)
- # to which the answer: "as few as possible"
- # is required. too many ReservationStations
- # means "big problems".
+ n_comb_stages = 3 # TODO (depends on how many RS's we want)
+ stage_idx = 0
+ # to which the answer: "as few as possible"
+ # is required. too many ReservationStations
+ # means "big problems".
+
for i in range(n_stages):
- if i == 0: # needs to convert input from pipestart ospec
+
+ # needs to convert input from pipestart ospec
+ if i == 0:
kls = FPDivStagesSetup
- n_comb_stages -= 1 # reduce due to work done at start
- elif i == n_stages - 1: # needs to convert output to pipeend ispec
+ n_comb_stages -= 1 # reduce due to work done at start
+
+ # needs to convert output to pipeend ispec
+ elif i == n_stages - 1:
kls = FPDivStagesFinal
- n_comb_stages -= 1 # reduce due to work done at end?
+ n_comb_stages -= 1 # FIXME - reduce due to work done at end?
+
+ # intermediary stage
else:
kls = FPDivStagesIntermediate
- pipechain.append(kls(self.width, self.pspec, n_comb_stages))
- pipeend = FPNormToPack(self.width, self.pspec)
+ pipechain.append(kls(self.pspec, n_comb_stages, stage_idx))
+ stage_idx += n_comb_stages # increment so that each CalcStage
+ # gets a (correct) unique index
+
+ self.pipechain = pipechain
+
+ # start and end: unpack/specialcases then normalisation/packing
+ self.pipestart = pipestart = FPDIVSpecialCasesDeNorm(self.pspec)
+ self.pipeend = pipeend = FPNormToPack(self.pspec)
+
+ self._eqs = self.connect([pipestart] + pipechain + [pipeend])
+
+ def elaborate(self, platform):
+ m = ControlBase.elaborate(self, platform)
# add submodules
- m.submodules.scnorm = pipestart
- for i, p in enumerate(pipechain):
+ m.submodules.scnorm = self.pipestart
+ for i, p in enumerate(self.pipechain):
setattr(m.submodules, "pipediv%d" % i, p)
- m.submodules.normpack = pipeend
+ m.submodules.normpack = self.pipeend
- # ControlBase.connect creates (returns) the "eqs" needed
- m.d.comb += self.connect([pipestart] + pipechain + [pipeend])
+ # ControlBase.connect creates the "eqs" needed to connect each pipe
+ m.d.comb += self._eqs
return m
:op_wid: - set this to the width of an operator which can
then be used to change the behaviour of the pipeline.
"""
+
def __init__(self, width, num_rows, op_wid=0):
- self.width = width
self.id_wid = num_bits(width)
- self.pspec = {'id_wid': self.id_wid, 'op_wid': op_wid}
- self.alu = FPDIVBasePipe(width, self.pspec)
+ self.pspec = PipelineSpec(width, self.id_wid, op_wid)
+ # get the standard mantissa width, store in the pspec
+ # (used in DivPipeBaseStage.get_core_config)
+ fpformat = FPFormat.standard(width)
+ log2_radix = 2
+ cfg = DivPipeCoreConfig(width, fpformat.fraction_width, log2_radix)
+ self.pspec.fpformat = fpformat
+ self.pspec.log2_radix = log2_radix
+ self.pspec.core_config = cfg
+
+ # XXX TODO - a class (or function?) that takes the pspec (right here)
+ # and creates... "something". that "something" MUST have an eq function
+ # new_pspec = deepcopy(self.pspec)
+ # new_pspec.opkls = DivPipeCoreOperation
+ # self.alu = FPDIVBasePipe(new_pspec)
+ self.alu = FPDIVBasePipe(self.pspec)
ReservationStations.__init__(self, num_rows)
def i_specfn(self):
- return FPADDBaseData(self.width, self.pspec)
+ return FPADDBaseData(self.pspec)
def o_specfn(self):
- return FPPackData(self.width, self.pspec)
+ return FPPackData(self.pspec)