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
44 (and not do too much: in particular, n_stages must be
45 reduced slightly when either self.end=True or self.begin=True)
50 # Converts from FPSCData into DivPipeInputData
51 divstages
.append(FPDivStage0Mod(self
.pspec
))
53 # does 1 "convert" (actual processing) from DivPipeInputData
54 # into "intermediate" output (DivPipeInterstageData)
55 divstages
.append(DivPipeSetupStage(self
.pspec
))
57 # here is where the intermediary stages are added.
58 # n_stages is adjusted (by pipeline.py), reduced to take
59 # into account extra processing that FPDivStage0Mod and DivPipeSetup
61 for count
in range(self
.n_stages
): # number of combinatorial stages
62 idx
= count
+ self
.stage_offs
63 divstages
.append(DivPipeCalculateStage(self
.pspec
, idx
))
65 chain
= StageChain(divstages
)
68 # output is from the last pipe stage
69 self
.o
= divstages
[-1].o
75 m
.d
.sync
+= self
.m1o
.eq(self
.process(None))
76 m
.next
= "normalise_1"
79 class FPDivStagesIntermediary(FPState
, SimpleHandshake
):
81 def __init__(self
, pspec
, n_stages
, stage_offs
):
82 FPState
.__init
__(self
, "divintermediate")
84 self
.n_stages
= n_stages
# number of combinatorial stages
85 self
.stage_offs
= stage_offs
# each CalcStage needs *absolute* idx
86 SimpleHandshake
.__init
__(self
, self
) # pipeline is its own stage
87 self
.m1o
= self
.ospec()
90 # TODO - this is for FPDivStage1Mod
91 return DivPipeInterstageData(self
.pspec
) # DIV ispec (loop)
94 # TODO - this is for FPDivStage1Mod
95 return DivPipeInterstageData(self
.pspec
) # DIV ospec (loop)
97 def setup(self
, m
, i
):
98 """ links module to inputs and outputs.
100 note: this is a pure *combinatorial* module (StageChain).
101 therefore each sub-module must also be combinatorial
102 (and not do too much)
107 # here is where the intermediary stages are added.
108 # n_stages is adjusted (in pipeline.py), reduced to take
109 # into account the extra processing that self.begin and self.end
111 for count
in range(self
.n_stages
): # number of combinatorial stages
112 idx
= count
+ self
.stage_offs
113 divstages
.append(DivPipeCalculateStage(self
.pspec
, idx
))
115 chain
= StageChain(divstages
)
118 # output is from the last pipe stage
119 self
.o
= divstages
[-1].o
121 def process(self
, i
):
125 m
.d
.sync
+= self
.m1o
.eq(self
.process(None))
126 m
.next
= "normalise_1"
129 class FPDivStagesFinal(FPState
, SimpleHandshake
):
131 def __init__(self
, pspec
, n_stages
, stage_offs
):
132 FPState
.__init
__(self
, "divfinal")
134 self
.n_stages
= n_stages
# number of combinatorial stages
135 self
.stage_offs
= stage_offs
# each CalcStage needs *absolute* idx
136 SimpleHandshake
.__init
__(self
, self
) # pipeline is its own stage
137 self
.m1o
= self
.ospec()
140 return DivPipeInterstageData(self
.pspec
) # DIV ispec (loop)
143 # REQUIRED. do NOT change.
144 return FPAddStage1Data(self
.pspec
) # to post-norm
146 def setup(self
, m
, i
):
147 """ links module to inputs and outputs.
149 note: this is a pure *combinatorial* module (StageChain).
150 therefore each sub-module must also be combinatorial
151 (and not do too much)
154 # takes the DIV pipeline/chain data and munges it
155 # into the format that the normalisation can accept.
159 # here is where the intermediary stages are added.
160 # n_stages is adjusted (in pipeline.py), reduced to take
161 # into account the extra processing that self.begin and self.end
163 for count
in range(self
.n_stages
): # number of combinatorial stages
164 idx
= count
+ self
.stage_offs
165 divstages
.append(DivPipeCalculateStage(pspec
, idx
))
167 # does the final conversion from intermediary to output data
168 divstages
.append(DivPipeFinalStage(pspec
))
170 # does conversion from DivPipeOutputData into
171 # FPAddStage1Data format (bad name, TODO, doesn't matter),
172 # so that post-normalisation and corrections can take over
173 divstages
.append(FPDivStage2Mod(self
.pspec
))
175 chain
= StageChain(divstages
)
178 # output is from the last pipe stage
179 self
.o
= divstages
[-1].o
181 def process(self
, i
):
185 m
.d
.sync
+= self
.m1o
.eq(self
.process(None))
186 m
.next
= "normalise_1"