385743f846fe37cd6d74167d8876ad2fd6d98e84
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
26 class FPDivStagesSetup(FPState
, SimpleHandshake
):
28 def __init__(self
, pspec
, n_stages
, stage_offs
):
29 FPState
.__init
__(self
, "divsetup")
31 self
.n_stages
= n_stages
# number of combinatorial stages
32 self
.stage_offs
= stage_offs
# each CalcStage needs *absolute* idx
33 SimpleHandshake
.__init
__(self
, self
) # pipeline is its own stage
34 self
.m1o
= self
.ospec()
37 # REQUIRED. do NOT change.
38 return FPSCData(self
.pspec
, False) # from denorm
41 return DivPipeInterstageData(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
52 # Converts from FPSCData into DivPipeInputData
53 divstages
.append(FPDivStage0Mod(self
.pspec
))
55 # does 1 "convert" (actual processing) from DivPipeInputData
56 # into "intermediate" output (DivPipeInterstageData)
57 divstages
.append(DivPipeSetupStage(self
.pspec
))
59 # here is where the intermediary stages are added.
60 # n_stages is adjusted (by pipeline.py), reduced to take
61 # into account extra processing that FPDivStage0Mod and DivPipeSetup
63 for count
in range(self
.n_stages
): # number of combinatorial stages
64 idx
= count
+ self
.stage_offs
65 divstages
.append(DivPipeCalculateStage(self
.pspec
, idx
))
67 chain
= StageChain(divstages
)
70 # output is from the last pipe stage
71 self
.o
= divstages
[-1].o
77 m
.d
.sync
+= self
.m1o
.eq(self
.process(None))
78 m
.next
= "normalise_1"
81 class FPDivStagesIntermediate(FPState
, SimpleHandshake
):
83 def __init__(self
, pspec
, n_stages
, stage_offs
):
84 FPState
.__init
__(self
, "divintermediate")
86 self
.n_stages
= n_stages
# number of combinatorial stages
87 self
.stage_offs
= stage_offs
# each CalcStage needs *absolute* idx
88 SimpleHandshake
.__init
__(self
, self
) # pipeline is its own stage
89 self
.m1o
= self
.ospec()
92 # TODO - this is for FPDivStage1Mod
93 return DivPipeInterstageData(self
.pspec
) # DIV ispec (loop)
96 # TODO - this is for FPDivStage1Mod
97 return DivPipeInterstageData(self
.pspec
) # DIV ospec (loop)
99 def setup(self
, m
, i
):
100 """ links module to inputs and outputs.
102 note: this is a pure *combinatorial* module (StageChain).
103 therefore each sub-module must also be combinatorial
108 # here is where the intermediary stages are added.
109 # n_stages is adjusted (in pipeline.py), reduced to take
110 # into account the extra processing that self.begin and self.end
112 for count
in range(self
.n_stages
): # number of combinatorial stages
113 idx
= count
+ self
.stage_offs
114 divstages
.append(DivPipeCalculateStage(self
.pspec
, idx
))
116 chain
= StageChain(divstages
)
119 # output is from the last pipe stage
120 self
.o
= divstages
[-1].o
122 def process(self
, i
):
126 m
.d
.sync
+= self
.m1o
.eq(self
.process(None))
127 m
.next
= "normalise_1"
130 class FPDivStagesFinal(FPState
, SimpleHandshake
):
132 def __init__(self
, pspec
, n_stages
, stage_offs
):
133 FPState
.__init
__(self
, "divfinal")
135 self
.n_stages
= n_stages
# number of combinatorial stages
136 self
.stage_offs
= stage_offs
# each CalcStage needs *absolute* idx
137 SimpleHandshake
.__init
__(self
, self
) # pipeline is its own stage
138 self
.m1o
= self
.ospec()
141 return DivPipeInterstageData(self
.pspec
) # DIV ispec (loop)
144 # REQUIRED. do NOT change.
145 return FPAddStage1Data(self
.pspec
) # to post-norm
147 def setup(self
, m
, i
):
148 """ links module to inputs and outputs.
150 note: this is a pure *combinatorial* module (StageChain).
151 therefore each sub-module must also be combinatorial
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"