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 .div2
import FPDivStage2Mod
19 from .div0
import FPDivStage0Data
22 class FPDivStagesSetup(FPState
, SimpleHandshake
):
24 def __init__(self
, pspec
, n_stages
, stage_offs
):
25 FPState
.__init
__(self
, "divsetup")
27 self
.n_stages
= n_stages
# number of combinatorial stages
28 self
.stage_offs
= stage_offs
# each CalcStage needs *absolute* idx
29 SimpleHandshake
.__init
__(self
, self
) # pipeline is its own stage
30 self
.m1o
= self
.ospec()
33 # REQUIRED. do NOT change.
34 return FPSCData(self
.pspec
, False) # from denorm
37 return DivPipeInterstageData(self
.pspec
) # DIV ospec (loop)
39 def setup(self
, m
, i
):
40 """ links module to inputs and outputs.
42 note: this is a pure *combinatorial* module (StageChain).
43 therefore each sub-module must also be combinatorial
48 # Converts from FPSCData into DivPipeInputData
49 divstages
.append(FPDivStage0Mod(self
.pspec
))
51 # does 1 "convert" (actual processing) from DivPipeInputData
52 # into "intermediate" output (DivPipeInterstageData)
53 divstages
.append(DivPipeSetupStage(self
.pspec
))
55 # here is where the intermediary stages are added.
56 # n_stages is adjusted (by pipeline.py), reduced to take
57 # into account extra processing that FPDivStage0Mod and DivPipeSetup
59 for count
in range(self
.n_stages
): # number of combinatorial stages
60 idx
= count
+ self
.stage_offs
61 divstages
.append(DivPipeCalculateStage(self
.pspec
, idx
))
63 chain
= StageChain(divstages
)
66 # output is from the last pipe stage
67 self
.o
= divstages
[-1].o
73 m
.d
.sync
+= self
.m1o
.eq(self
.process(None))
74 m
.next
= "normalise_1"
77 class FPDivStagesIntermediary(FPState
, SimpleHandshake
):
79 def __init__(self
, pspec
, n_stages
, stage_offs
):
80 FPState
.__init
__(self
, "divintermediate")
82 self
.n_stages
= n_stages
# number of combinatorial stages
83 self
.stage_offs
= stage_offs
# each CalcStage needs *absolute* idx
84 SimpleHandshake
.__init
__(self
, self
) # pipeline is its own stage
85 self
.m1o
= self
.ospec()
88 # TODO - this is for FPDivStage1Mod
89 return DivPipeInterstageData(self
.pspec
) # DIV ispec (loop)
92 # TODO - this is for FPDivStage1Mod
93 return DivPipeInterstageData(self
.pspec
) # DIV ospec (loop)
95 def setup(self
, m
, i
):
96 """ links module to inputs and outputs.
98 note: this is a pure *combinatorial* module (StageChain).
99 therefore each sub-module must also be combinatorial
104 # here is where the intermediary stages are added.
105 # n_stages is adjusted (in pipeline.py), reduced to take
106 # into account the extra processing that self.begin and self.end
108 for count
in range(self
.n_stages
): # number of combinatorial stages
109 idx
= count
+ self
.stage_offs
110 divstages
.append(DivPipeCalculateStage(self
.pspec
, idx
))
112 chain
= StageChain(divstages
)
115 # output is from the last pipe stage
116 self
.o
= divstages
[-1].o
118 def process(self
, i
):
122 m
.d
.sync
+= self
.m1o
.eq(self
.process(None))
123 m
.next
= "normalise_1"
126 class FPDivStagesFinal(FPState
, SimpleHandshake
):
128 def __init__(self
, pspec
, n_stages
, stage_offs
):
129 FPState
.__init
__(self
, "divfinal")
131 self
.n_stages
= n_stages
# number of combinatorial stages
132 self
.stage_offs
= stage_offs
# each CalcStage needs *absolute* idx
133 SimpleHandshake
.__init
__(self
, self
) # pipeline is its own stage
134 self
.m1o
= self
.ospec()
137 return DivPipeInterstageData(self
.pspec
) # DIV ispec (loop)
140 # REQUIRED. do NOT change.
141 return FPAddStage1Data(self
.pspec
) # to post-norm
143 def setup(self
, m
, i
):
144 """ links module to inputs and outputs.
146 note: this is a pure *combinatorial* module (StageChain).
147 therefore each sub-module must also be combinatorial
150 # takes the DIV pipeline/chain data and munges it
151 # into the format that the normalisation can accept.
155 # here is where the intermediary stages are added.
156 # n_stages is adjusted (in pipeline.py), reduced to take
157 # into account the extra processing that self.begin and self.end
159 for count
in range(self
.n_stages
): # number of combinatorial stages
160 idx
= count
+ self
.stage_offs
161 divstages
.append(DivPipeCalculateStage(pspec
, idx
))
163 # does the final conversion from intermediary to output data
164 divstages
.append(DivPipeFinalStage(pspec
))
166 # does conversion from DivPipeOutputData into
167 # FPAddStage1Data format (bad name, TODO, doesn't matter),
168 # so that post-normalisation and corrections can take over
169 divstages
.append(FPDivStage2Mod(self
.pspec
))
171 chain
= StageChain(divstages
)
174 # output is from the last pipe stage
175 self
.o
= divstages
[-1].o
177 def process(self
, i
):
181 m
.d
.sync
+= self
.m1o
.eq(self
.process(None))
182 m
.next
= "normalise_1"