2e38cd929fcddb38c9e30bcbe1864b4c127a3d9e
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
, pspec
, n_stages
):
29 FPState
.__init
__(self
, "divsetup")
31 self
.n_stages
= n_stages
# number of combinatorial stages
32 SimpleHandshake
.__init
__(self
, self
) # pipeline is its own stage
33 self
.m1o
= self
.ospec()
36 # REQUIRED. do NOT change.
37 return FPSCData(self
.pspec
, False) # from denorm
40 # XXX TODO: replace with "intermediary" (DivPipeInterstageData)
41 return FPDivStage0Data(self
.pspec
) # DIV ospec (loop)
43 def setup(self
, m
, i
):
44 """ links module to inputs and outputs.
46 note: this is a pure *combinatorial* module (StageChain).
47 therefore each sub-module must also be combinatorial
48 (and not do too much: in particular, n_stages must be
49 reduced slightly when either self.end=True or self.begin=True)
54 # Converts from FPSCData into DivPipeInputData
55 divstages
.append(FPDivStage0Mod(self
.pspec
))
57 # does 1 "convert" (actual processing) from DivPipeInputData
58 # into "intermediate" output (DivPipeInterstageData)
60 # FIXME divstages.append(DivPipeSetupStage(something))
63 # here is where the intermediary stages are added.
64 # n_stages is adjusted (in pipeline.py), reduced to take
65 # into account the extra processing that self.begin and self.end
67 for count
in range(self
.n_stages
): # number of combinatorial stages
68 # XXX: this can actually be entirely dropped...
69 divstages
.append(FPDivStage1Mod(self
.pspec
))
71 # ... and replaced with this.
73 #divstages.append(DivPipeCalculateStage(core_config, count))
76 chain
= StageChain(divstages
)
79 # output is from the last pipe stage
80 self
.o
= divstages
[-1].o
86 m
.d
.sync
+= self
.m1o
.eq(self
.process(None))
87 m
.next
= "normalise_1"
90 class FPDivStagesIntermediary(FPState
, SimpleHandshake
):
92 def __init__(self
, pspec
, n_stages
):
93 FPState
.__init
__(self
, "divintermediate")
95 self
.n_stages
= n_stages
# number of combinatorial stages
96 SimpleHandshake
.__init
__(self
, self
) # pipeline is its own stage
97 self
.m1o
= self
.ospec()
100 # TODO - this is for FPDivStage1Mod
101 return DivPipeInterstageData(self
.pspec
) # DIV ispec (loop)
104 # TODO - this is for FPDivStage1Mod
105 return DivPipeInterstageData(self
.pspec
) # DIV ospec (loop)
107 def setup(self
, m
, i
):
108 """ links module to inputs and outputs.
110 note: this is a pure *combinatorial* module (StageChain).
111 therefore each sub-module must also be combinatorial
112 (and not do too much)
117 # here is where the intermediary stages are added.
118 # n_stages is adjusted (in pipeline.py), reduced to take
119 # into account the extra processing that self.begin and self.end
121 for count
in range(self
.n_stages
): # number of combinatorial stages
122 # XXX: this can actually be entirely dropped...
123 divstages
.append(FPDivStage1Mod(self
.pspec
))
125 # ... and replaced with this.
127 #divstages.append(DivPipeCalculateStage(core_config, count))
130 chain
= StageChain(divstages
)
133 # output is from the last pipe stage
134 self
.o
= divstages
[-1].o
136 def process(self
, i
):
140 m
.d
.sync
+= self
.m1o
.eq(self
.process(None))
141 m
.next
= "normalise_1"
144 class FPDivStagesFinal(FPState
, SimpleHandshake
):
146 def __init__(self
, pspec
, n_stages
):
147 FPState
.__init
__(self
, "divfinal")
149 self
.n_stages
= n_stages
# number of combinatorial stages
150 SimpleHandshake
.__init
__(self
, self
) # pipeline is its own stage
151 self
.m1o
= self
.ospec()
154 # XXX TODO: replace with "intermediary" (DivPipeInterstageData?)
155 return FPDivStage0Data(self
.pspec
) # DIV ispec (loop)
158 # REQUIRED. do NOT change.
159 return FPAddStage1Data(self
.pspec
) # to post-norm
161 def setup(self
, m
, i
):
162 """ links module to inputs and outputs.
164 note: this is a pure *combinatorial* module (StageChain).
165 therefore each sub-module must also be combinatorial
166 (and not do too much)
169 # takes the DIV pipeline/chain data and munges it
170 # into the format that the normalisation can accept.
174 # here is where the intermediary stages are added.
175 # n_stages is adjusted (in pipeline.py), reduced to take
176 # into account the extra processing that self.begin and self.end
178 for count
in range(self
.n_stages
): # number of combinatorial stages
179 # XXX: this can actually be entirely dropped...
180 divstages
.append(FPDivStage1Mod(self
.pspec
))
182 # ... and replaced with this.
184 #divstages.append(DivPipeCalculateStage(core_config, count))
187 # does the final conversion from intermediary to output data
189 # FIXME divstages.append(DivPipeFinalStage(something))
192 # does conversion from DivPipeOutputData into
193 # FPAddStage1Data format (bad name, TODO, doesn't matter),
194 # so that post-normalisation and corrections can take over
195 divstages
.append(FPDivStage2Mod(self
.pspec
))
197 chain
= StageChain(divstages
)
200 # output is from the last pipe stage
201 self
.o
= divstages
[-1].o
203 def process(self
, i
):
207 m
.d
.sync
+= self
.m1o
.eq(self
.process(None))
208 m
.next
= "normalise_1"