d8807d10ddae2da497c3f5ffd9f4c2246aaebbb7
[ieee754fpu.git] / src / ieee754 / fpdiv / divstages.py
1 """IEEE754 Floating Point pipelined Divider
2
3 This module simply constructs register-based pipeline(s) out of
4 appropriate combinatorial blocks: setup, intermediary and final
5 single-clock pipelines.
6
7 "actual" processing is carried out by the DivPipeCalculateStage
8 combinatorial block: everything else is chaining and pre- and post-
9 data formatting.
10
11 there's no "actual" work done here: it's just a "joining-together" job.
12 see pipeline.py for an ASCII diagram showing how everything fits together
13
14 Relevant bugreport: http://bugs.libre-riscv.org/show_bug.cgi?id=99
15
16 """
17
18 from nmutil.pipemodbase import PipeModBaseChain
19 from ieee754.div_rem_sqrt_rsqrt.div_pipe import (DivPipeInterstageData,
20 DivPipeSetupStage,
21 DivPipeCalculateStage,
22 DivPipeFinalStage,
23 )
24 from ieee754.fpdiv.div0 import FPDivStage0Mod
25 from ieee754.fpdiv.div2 import FPDivStage2Mod
26
27
28 class FPDivStagesSetup(PipeModBaseChain):
29
30 def __init__(self, pspec, n_stages, stage_offs):
31 self.n_stages = n_stages # number of combinatorial stages
32 self.stage_offs = stage_offs # each CalcStage needs *absolute* idx
33 super().__init__(pspec)
34
35 def get_chain(self):
36 """ gets module chain
37
38 note: this is a pure *combinatorial* module (StageChain).
39 therefore each sub-module must also be combinatorial
40 """
41
42 # chain to be returned
43 divstages = []
44
45 # Converts from FPSCData into DivPipeInputData
46 divstages.append(FPDivStage0Mod(self.pspec))
47
48 # does 1 "convert" (actual processing) from DivPipeInputData
49 # into "intermediate" output (DivPipeInterstageData)
50 divstages.append(DivPipeSetupStage(self.pspec))
51
52 # here is where the intermediary stages are added.
53 for count in range(self.n_stages): # number of combinatorial stages
54 idx = count + self.stage_offs
55 divstages.append(DivPipeCalculateStage(self.pspec, idx))
56
57 return divstages
58
59
60 class FPDivStagesIntermediate(PipeModBaseChain):
61
62 def __init__(self, pspec, n_stages, stage_offs):
63 self.n_stages = n_stages # number of combinatorial stages
64 self.stage_offs = stage_offs # each CalcStage needs *absolute* idx
65 super().__init__(pspec)
66
67 def get_chain(self):
68 """ gets module chain
69
70 note: this is a pure *combinatorial* module (StageChain).
71 therefore each sub-module must also be combinatorial
72 """
73
74 # chain to be returned
75 divstages = []
76
77 # here is where the intermediary stages are added.
78 for count in range(self.n_stages): # number of combinatorial stages
79 idx = count + self.stage_offs
80 divstages.append(DivPipeCalculateStage(self.pspec, idx))
81
82 return divstages
83
84
85 class FPDivStagesFinal(PipeModBaseChain):
86
87 def __init__(self, pspec, n_stages, stage_offs):
88 self.n_stages = n_stages # number of combinatorial stages
89 self.stage_offs = stage_offs # each CalcStage needs *absolute* idx
90 super().__init__(pspec)
91
92 def get_chain(self):
93 """ gets module chain
94
95 note: this is a pure *combinatorial* module (StageChain).
96 therefore each sub-module must also be combinatorial
97 """
98
99 # chain to be returned
100 divstages = []
101
102 # here is where the last intermediary stages are added.
103 for count in range(self.n_stages): # number of combinatorial stages
104 idx = count + self.stage_offs
105 divstages.append(DivPipeCalculateStage(self.pspec, idx))
106
107 # does the final conversion from intermediary to output data
108 divstages.append(DivPipeFinalStage(self.pspec))
109
110 # does conversion from DivPipeOutputData into FPPostCalcData format
111 # so that post-normalisation and corrections can take over
112 divstages.append(FPDivStage2Mod(self.pspec))
113
114 return divstages