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 # XXX TODO: replace with "intermediary" (DivPipeInterstageData)
102 return FPDivStage0Data(self
.pspec
) # DIV ispec (loop)
105 # TODO - this is for FPDivStage1Mod
106 # XXX TODO: replace with "intermediary" (DivPipeInterstageData)
107 return FPDivStage0Data(self
.pspec
) # DIV ospec (loop)
109 def setup(self
, m
, i
):
110 """ links module to inputs and outputs.
112 note: this is a pure *combinatorial* module (StageChain).
113 therefore each sub-module must also be combinatorial
114 (and not do too much)
119 # here is where the intermediary stages are added.
120 # n_stages is adjusted (in pipeline.py), reduced to take
121 # into account the extra processing that self.begin and self.end
123 for count
in range(self
.n_stages
): # number of combinatorial stages
124 # XXX: this can actually be entirely dropped...
125 divstages
.append(FPDivStage1Mod(self
.pspec
))
127 # ... and replaced with this.
129 #divstages.append(DivPipeCalculateStage(core_config, count))
132 chain
= StageChain(divstages
)
135 # output is from the last pipe stage
136 self
.o
= divstages
[-1].o
138 def process(self
, i
):
142 m
.d
.sync
+= self
.m1o
.eq(self
.process(None))
143 m
.next
= "normalise_1"
146 class FPDivStagesFinal(FPState
, SimpleHandshake
):
148 def __init__(self
, pspec
, n_stages
):
149 FPState
.__init
__(self
, "divfinal")
151 self
.n_stages
= n_stages
# number of combinatorial stages
152 SimpleHandshake
.__init
__(self
, self
) # pipeline is its own stage
153 self
.m1o
= self
.ospec()
156 # XXX TODO: replace with "intermediary" (DivPipeInterstageData?)
157 return FPDivStage0Data(self
.pspec
) # DIV ispec (loop)
160 # REQUIRED. do NOT change.
161 return FPAddStage1Data(self
.pspec
) # to post-norm
163 def setup(self
, m
, i
):
164 """ links module to inputs and outputs.
166 note: this is a pure *combinatorial* module (StageChain).
167 therefore each sub-module must also be combinatorial
168 (and not do too much)
171 # takes the DIV pipeline/chain data and munges it
172 # into the format that the normalisation can accept.
176 # here is where the intermediary stages are added.
177 # n_stages is adjusted (in pipeline.py), reduced to take
178 # into account the extra processing that self.begin and self.end
180 for count
in range(self
.n_stages
): # number of combinatorial stages
181 # XXX: this can actually be entirely dropped...
182 divstages
.append(FPDivStage1Mod(self
.pspec
))
184 # ... and replaced with this.
186 #divstages.append(DivPipeCalculateStage(core_config, count))
189 # does the final conversion from intermediary to output data
191 # FIXME divstages.append(DivPipeFinalStage(something))
194 # does conversion from DivPipeOutputData into
195 # FPAddStage1Data format (bad name, TODO, doesn't matter),
196 # so that post-normalisation and corrections can take over
197 divstages
.append(FPDivStage2Mod(self
.pspec
))
199 chain
= StageChain(divstages
)
202 # output is from the last pipe stage
203 self
.o
= divstages
[-1].o
205 def process(self
, i
):
209 m
.d
.sync
+= self
.m1o
.eq(self
.process(None))
210 m
.next
= "normalise_1"