b0c539f9805e94080c0713fd83f76fd6739101cc
1 """IEEE754 Floating Point pipelined Divider
3 Relevant bugreport: http://bugs.libre-riscv.org/show_bug.cgi?id=99
7 from nmigen
import Module
8 from nmigen
.cli
import main
, verilog
10 from nmutil
.singlepipe
import (StageChain
, SimpleHandshake
)
12 from ieee754
.fpcommon
.fpbase
import FPState
13 from ieee754
.fpcommon
.denorm
import FPSCData
14 from ieee754
.fpcommon
.postcalc
import FPAddStage1Data
17 from .div0
import FPDivStage0Mod
18 from .div1
import FPDivStage1Mod
# can be dropped entirely
19 # (replaced with DivPipeCalculateStage)
20 # note, yes, DivPipeCalculateStage *NOT*
21 # DivPipeCoreCalculateStage
22 from .div2
import FPDivStage2Mod
23 from .div0
import FPDivStage0Data
26 class FPDivStagesSetup(FPState
, SimpleHandshake
):
28 def __init__(self
, width
, pspec
, n_stages
):
29 FPState
.__init
__(self
, "divsetup")
32 self
.n_stages
= n_stages
# number of combinatorial stages
33 SimpleHandshake
.__init
__(self
, self
) # pipeline is its own stage
34 self
.m1o
= self
.ospec()
37 # REQUIRED. do NOT change.
38 return FPSCData(self
.width
, self
.pspec
, False) # from denorm
41 # XXX TODO: replace with "intermediary" (DivPipeInterstageData)
42 return FPDivStage0Data(self
.width
, self
.pspec
) # DIV ospec (loop)
44 def setup(self
, m
, i
):
45 """ links module to inputs and outputs.
47 note: this is a pure *combinatorial* module (StageChain).
48 therefore each sub-module must also be combinatorial
49 (and not do too much: in particular, n_stages must be
50 reduced slightly when either self.end=True or self.begin=True)
55 # Converts from FPSCData into DivPipeInputData
56 divstages
.append(FPDivStage0Mod(self
.width
, self
.pspec
))
58 # does 1 "convert" (actual processing) from DivPipeInputData
59 # into "intermediate" output (DivPipeInterstageData)
61 # FIXME divstages.append(DivPipeSetupStage(something))
64 # here is where the intermediary stages are added.
65 # n_stages is adjusted (in pipeline.py), reduced to take
66 # into account the extra processing that self.begin and self.end
68 for count
in range(self
.n_stages
): # number of combinatorial stages
69 # XXX: this can actually be entirely dropped...
70 divstages
.append(FPDivStage1Mod(self
.width
, self
.pspec
))
72 # ... and replaced with this.
74 #divstages.append(DivPipeCalculateStage(core_config, count))
77 chain
= StageChain(divstages
)
80 # output is from the last pipe stage
81 self
.o
= divstages
[-1].o
87 m
.d
.sync
+= self
.m1o
.eq(self
.process(None))
88 m
.next
= "normalise_1"
91 class FPDivStagesIntermediary(FPState
, SimpleHandshake
):
93 def __init__(self
, width
, pspec
, n_stages
):
94 FPState
.__init
__(self
, "divintermediate")
97 self
.n_stages
= n_stages
# number of combinatorial stages
98 self
.begin
= begin
# "begin" mode
99 self
.end
= end
# "end" mode
100 SimpleHandshake
.__init
__(self
, self
) # pipeline is its own stage
101 self
.m1o
= self
.ospec()
104 # TODO - this is for FPDivStage1Mod
105 # XXX TODO: replace with "intermediary" (DivPipeInterstageData)
106 return FPDivStage0Data(self
.width
, self
.pspec
) # DIV ispec (loop)
109 # TODO - this is for FPDivStage1Mod
110 # XXX TODO: replace with "intermediary" (DivPipeInterstageData)
111 return FPDivStage0Data(self
.width
, self
.pspec
) # DIV ospec (loop)
113 def setup(self
, m
, i
):
114 """ links module to inputs and outputs.
116 note: this is a pure *combinatorial* module (StageChain).
117 therefore each sub-module must also be combinatorial
118 (and not do too much)
123 # here is where the intermediary stages are added.
124 # n_stages is adjusted (in pipeline.py), reduced to take
125 # into account the extra processing that self.begin and self.end
127 for count
in range(self
.n_stages
): # number of combinatorial stages
128 # XXX: this can actually be entirely dropped...
129 divstages
.append(FPDivStage1Mod(self
.width
, self
.pspec
))
131 # ... and replaced with this.
133 #divstages.append(DivPipeCalculateStage(core_config, count))
136 chain
= StageChain(divstages
)
139 # output is from the last pipe stage
140 self
.o
= divstages
[-1].o
142 def process(self
, i
):
146 m
.d
.sync
+= self
.m1o
.eq(self
.process(None))
147 m
.next
= "normalise_1"
150 class FPDivStagesFinal(FPState
, SimpleHandshake
):
152 def __init__(self
, width
, pspec
, n_stages
):
153 FPState
.__init
__(self
, "divfinal")
156 self
.n_stages
= n_stages
# number of combinatorial stages
157 SimpleHandshake
.__init
__(self
, self
) # pipeline is its own stage
158 self
.m1o
= self
.ospec()
161 # XXX TODO: replace with "intermediary" (DivPipeInterstageData?)
162 return FPDivStage0Data(self
.width
, self
.pspec
) # DIV ispec (loop)
165 # REQUIRED. do NOT change.
166 return FPAddStage1Data(self
.width
, self
.pspec
) # to post-norm
168 def setup(self
, m
, i
):
169 """ links module to inputs and outputs.
171 note: this is a pure *combinatorial* module (StageChain).
172 therefore each sub-module must also be combinatorial
173 (and not do too much)
176 # takes the DIV pipeline/chain data and munges it
177 # into the format that the normalisation can accept.
181 # here is where the intermediary stages are added.
182 # n_stages is adjusted (in pipeline.py), reduced to take
183 # into account the extra processing that self.begin and self.end
185 for count
in range(self
.n_stages
): # number of combinatorial stages
186 # XXX: this can actually be entirely dropped...
187 divstages
.append(FPDivStage1Mod(self
.width
, self
.pspec
))
189 # ... and replaced with this.
191 #divstages.append(DivPipeCalculateStage(core_config, count))
194 # does the final conversion from intermediary to output data
196 # FIXME divstages.append(DivPipeFinalStage(something))
199 # does conversion from DivPipeOutputData into
200 # FPAddStage1Data format (bad name, TODO, doesn't matter),
201 # so that post-normalisation and corrections can take over
202 divstages
.append(FPDivStage2Mod(self
.width
, self
.pspec
))
204 chain
= StageChain(divstages
)
207 # output is from the last pipe stage
208 self
.o
= divstages
[-1].o
210 def process(self
, i
):
214 m
.d
.sync
+= self
.m1o
.eq(self
.process(None))
215 m
.next
= "normalise_1"