more imports / syntax errors
[ieee754fpu.git] / src / ieee754 / fpdiv / divstages.py
1 """IEEE754 Floating Point pipelined Divider
2
3 Relevant bugreport: http://bugs.libre-riscv.org/show_bug.cgi?id=99
4
5 """
6
7 from nmigen import Module
8 from nmigen.cli import main, verilog
9
10 from nmutil.singlepipe import (StageChain, SimpleHandshake)
11
12 from ieee754.fpcommon.fpbase import FPState
13 from ieee754.fpcommon.denorm import FPSCData
14 from ieee754.fpcommon.postcalc import FPAddStage1Data
15 from ieee754.div_rem_sqrt_rsqrt.div_pipe import (DivPipeInterstageData,
16 DivPipeSetupStage,
17 DivPipeCalculateStage,
18 DivPipeFinalStage,
19 )
20
21 # TODO: write these
22 from .div0 import FPDivStage0Mod
23 from .div2 import FPDivStage2Mod
24 from .div0 import FPDivStage0Data
25
26
27 class FPDivStagesSetup(FPState, SimpleHandshake):
28
29 def __init__(self, pspec, n_stages, stage_offs):
30 FPState.__init__(self, "divsetup")
31 self.pspec = pspec
32 self.n_stages = n_stages # number of combinatorial stages
33 self.stage_offs = stage_offs # each CalcStage needs *absolute* idx
34 SimpleHandshake.__init__(self, self) # pipeline is its own stage
35 self.m1o = self.ospec()
36
37 def ispec(self):
38 # REQUIRED. do NOT change.
39 return FPSCData(self.pspec, False) # from denorm
40
41 def ospec(self):
42 return DivPipeInterstageData(self.pspec) # DIV ospec (loop)
43
44 def setup(self, m, i):
45 """ links module to inputs and outputs.
46
47 note: this is a pure *combinatorial* module (StageChain).
48 therefore each sub-module must also be combinatorial
49 """
50
51 divstages = []
52
53 # Converts from FPSCData into DivPipeInputData
54 divstages.append(FPDivStage0Mod(self.pspec))
55
56 # does 1 "convert" (actual processing) from DivPipeInputData
57 # into "intermediate" output (DivPipeInterstageData)
58 divstages.append(DivPipeSetupStage(self.pspec))
59
60 # here is where the intermediary stages are added.
61 # n_stages is adjusted (by pipeline.py), reduced to take
62 # into account extra processing that FPDivStage0Mod and DivPipeSetup
63 # might add.
64 for count in range(self.n_stages): # number of combinatorial stages
65 idx = count + self.stage_offs
66 divstages.append(DivPipeCalculateStage(self.pspec, idx))
67
68 chain = StageChain(divstages)
69 chain.setup(m, i)
70
71 # output is from the last pipe stage
72 self.o = divstages[-1].o
73
74 def process(self, i):
75 return self.o
76
77 def action(self, m):
78 m.d.sync += self.m1o.eq(self.process(None))
79 m.next = "normalise_1"
80
81
82 class FPDivStagesIntermediate(FPState, SimpleHandshake):
83
84 def __init__(self, pspec, n_stages, stage_offs):
85 FPState.__init__(self, "divintermediate")
86 self.pspec = pspec
87 self.n_stages = n_stages # number of combinatorial stages
88 self.stage_offs = stage_offs # each CalcStage needs *absolute* idx
89 SimpleHandshake.__init__(self, self) # pipeline is its own stage
90 self.m1o = self.ospec()
91
92 def ispec(self):
93 # TODO - this is for FPDivStage1Mod
94 return DivPipeInterstageData(self.pspec) # DIV ispec (loop)
95
96 def ospec(self):
97 # TODO - this is for FPDivStage1Mod
98 return DivPipeInterstageData(self.pspec) # DIV ospec (loop)
99
100 def setup(self, m, i):
101 """ links module to inputs and outputs.
102
103 note: this is a pure *combinatorial* module (StageChain).
104 therefore each sub-module must also be combinatorial
105 """
106
107 divstages = []
108
109 # here is where the intermediary stages are added.
110 # n_stages is adjusted (in pipeline.py), reduced to take
111 # into account the extra processing that self.begin and self.end
112 # will add.
113 for count in range(self.n_stages): # number of combinatorial stages
114 idx = count + self.stage_offs
115 divstages.append(DivPipeCalculateStage(self.pspec, idx))
116
117 chain = StageChain(divstages)
118 chain.setup(m, i)
119
120 # output is from the last pipe stage
121 self.o = divstages[-1].o
122
123 def process(self, i):
124 return self.o
125
126 def action(self, m):
127 m.d.sync += self.m1o.eq(self.process(None))
128 m.next = "normalise_1"
129
130
131 class FPDivStagesFinal(FPState, SimpleHandshake):
132
133 def __init__(self, pspec, n_stages, stage_offs):
134 FPState.__init__(self, "divfinal")
135 self.pspec = pspec
136 self.n_stages = n_stages # number of combinatorial stages
137 self.stage_offs = stage_offs # each CalcStage needs *absolute* idx
138 SimpleHandshake.__init__(self, self) # pipeline is its own stage
139 self.m1o = self.ospec()
140
141 def ispec(self):
142 return DivPipeInterstageData(self.pspec) # DIV ispec (loop)
143
144 def ospec(self):
145 # REQUIRED. do NOT change.
146 return FPAddStage1Data(self.pspec) # to post-norm
147
148 def setup(self, m, i):
149 """ links module to inputs and outputs.
150
151 note: this is a pure *combinatorial* module (StageChain).
152 therefore each sub-module must also be combinatorial
153 """
154
155 # takes the DIV pipeline/chain data and munges it
156 # into the format that the normalisation can accept.
157
158 divstages = []
159
160 # here is where the intermediary stages are added.
161 # n_stages is adjusted (in pipeline.py), reduced to take
162 # into account the extra processing that self.begin and self.end
163 # will add.
164 for count in range(self.n_stages): # number of combinatorial stages
165 idx = count + self.stage_offs
166 divstages.append(DivPipeCalculateStage(pspec, idx))
167
168 # does the final conversion from intermediary to output data
169 divstages.append(DivPipeFinalStage(pspec))
170
171 # does conversion from DivPipeOutputData into
172 # FPAddStage1Data format (bad name, TODO, doesn't matter),
173 # so that post-normalisation and corrections can take over
174 divstages.append(FPDivStage2Mod(self.pspec))
175
176 chain = StageChain(divstages)
177 chain.setup(m, i)
178
179 # output is from the last pipe stage
180 self.o = divstages[-1].o
181
182 def process(self, i):
183 return self.o
184
185 def action(self, m):
186 m.d.sync += self.m1o.eq(self.process(None))
187 m.next = "normalise_1"
188
189