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
15 from ieee754
.div_rem_sqrt_rsqrt
.div_pipe
import (DivPipeInterstageData
,
17 DivPipeCalculateStage
,
22 from .div0
import FPDivStage0Mod
23 from .div2
import FPDivStage2Mod
24 from .div0
import FPDivStage0Data
27 class FPDivStagesSetup(FPState
, SimpleHandshake
):
29 def __init__(self
, pspec
, n_stages
, stage_offs
):
30 FPState
.__init
__(self
, "divsetup")
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()
38 # REQUIRED. do NOT change.
39 return FPSCData(self
.pspec
, False) # from denorm
42 return DivPipeInterstageData(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
53 # Converts from FPSCData into DivPipeInputData
54 divstages
.append(FPDivStage0Mod(self
.pspec
))
56 # does 1 "convert" (actual processing) from DivPipeInputData
57 # into "intermediate" output (DivPipeInterstageData)
58 divstages
.append(DivPipeSetupStage(self
.pspec
))
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
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
))
68 chain
= StageChain(divstages
)
71 # output is from the last pipe stage
72 self
.o
= divstages
[-1].o
78 m
.d
.sync
+= self
.m1o
.eq(self
.process(None))
79 m
.next
= "normalise_1"
82 class FPDivStagesIntermediate(FPState
, SimpleHandshake
):
84 def __init__(self
, pspec
, n_stages
, stage_offs
):
85 FPState
.__init
__(self
, "divintermediate")
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()
93 # TODO - this is for FPDivStage1Mod
94 return DivPipeInterstageData(self
.pspec
) # DIV ispec (loop)
97 # TODO - this is for FPDivStage1Mod
98 return DivPipeInterstageData(self
.pspec
) # DIV ospec (loop)
100 def setup(self
, m
, i
):
101 """ links module to inputs and outputs.
103 note: this is a pure *combinatorial* module (StageChain).
104 therefore each sub-module must also be combinatorial
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
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
))
117 chain
= StageChain(divstages
)
120 # output is from the last pipe stage
121 self
.o
= divstages
[-1].o
123 def process(self
, i
):
127 m
.d
.sync
+= self
.m1o
.eq(self
.process(None))
128 m
.next
= "normalise_1"
131 class FPDivStagesFinal(FPState
, SimpleHandshake
):
133 def __init__(self
, pspec
, n_stages
, stage_offs
):
134 FPState
.__init
__(self
, "divfinal")
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()
142 return DivPipeInterstageData(self
.pspec
) # DIV ispec (loop)
145 # REQUIRED. do NOT change.
146 return FPAddStage1Data(self
.pspec
) # to post-norm
148 def setup(self
, m
, i
):
149 """ links module to inputs and outputs.
151 note: this is a pure *combinatorial* module (StageChain).
152 therefore each sub-module must also be combinatorial
155 # takes the DIV pipeline/chain data and munges it
156 # into the format that the normalisation can accept.
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
164 for count
in range(self
.n_stages
): # number of combinatorial stages
165 idx
= count
+ self
.stage_offs
166 divstages
.append(DivPipeCalculateStage(pspec
, idx
))
168 # does the final conversion from intermediary to output data
169 divstages
.append(DivPipeFinalStage(pspec
))
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
))
176 chain
= StageChain(divstages
)
179 # output is from the last pipe stage
180 self
.o
= divstages
[-1].o
182 def process(self
, i
):
186 m
.d
.sync
+= self
.m1o
.eq(self
.process(None))
187 m
.next
= "normalise_1"