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
12 from ieee754
.pipeline
import DynamicPipe
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(DynamicPipe
):
28 def __init__(self
, pspec
, n_stages
, stage_offs
):
30 self
.n_stages
= n_stages
# number of combinatorial stages
31 self
.stage_offs
= stage_offs
# each CalcStage needs *absolute* idx
32 super().__init
__(pspec
)
35 # REQUIRED. do NOT change.
36 return FPSCData(self
.pspec
, False) # from denorm
39 return DivPipeInterstageData(self
.pspec
) # DIV ospec (loop)
41 def setup(self
, m
, i
):
42 """ links module to inputs and outputs.
44 note: this is a pure *combinatorial* module (StageChain).
45 therefore each sub-module must also be combinatorial
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 class FPDivStagesIntermediate(DynamicPipe
):
77 def __init__(self
, pspec
, n_stages
, stage_offs
):
79 self
.n_stages
= n_stages
# number of combinatorial stages
80 self
.stage_offs
= stage_offs
# each CalcStage needs *absolute* idx
81 super().__init
__(pspec
)
84 # TODO - this is for FPDivStage1Mod
85 return DivPipeInterstageData(self
.pspec
) # DIV ispec (loop)
88 # TODO - this is for FPDivStage1Mod
89 return DivPipeInterstageData(self
.pspec
) # DIV ospec (loop)
91 def setup(self
, m
, i
):
92 """ links module to inputs and outputs.
94 note: this is a pure *combinatorial* module (StageChain).
95 therefore each sub-module must also be combinatorial
100 # here is where the intermediary stages are added.
101 # n_stages is adjusted (in pipeline.py), reduced to take
102 # into account the extra processing that self.begin and self.end
104 for count
in range(self
.n_stages
): # number of combinatorial stages
105 idx
= count
+ self
.stage_offs
106 divstages
.append(DivPipeCalculateStage(self
.pspec
, idx
))
108 chain
= StageChain(divstages
)
111 # output is from the last pipe stage
112 self
.o
= divstages
[-1].o
114 def process(self
, i
):
118 class FPDivStagesFinal(DynamicPipe
):
120 def __init__(self
, pspec
, n_stages
, stage_offs
):
122 self
.n_stages
= n_stages
# number of combinatorial stages
123 self
.stage_offs
= stage_offs
# each CalcStage needs *absolute* idx
124 super().__init
__(pspec
)
127 return DivPipeInterstageData(self
.pspec
) # DIV ispec (loop)
130 # REQUIRED. do NOT change.
131 return FPAddStage1Data(self
.pspec
) # to post-norm
133 def setup(self
, m
, i
):
134 """ links module to inputs and outputs.
136 note: this is a pure *combinatorial* module (StageChain).
137 therefore each sub-module must also be combinatorial
140 # takes the DIV pipeline/chain data and munges it
141 # into the format that the normalisation can accept.
145 # here is where the intermediary stages are added.
146 # n_stages is adjusted (in pipeline.py), reduced to take
147 # into account the extra processing that self.begin and self.end
149 for count
in range(self
.n_stages
): # number of combinatorial stages
150 idx
= count
+ self
.stage_offs
151 divstages
.append(DivPipeCalculateStage(self
.pspec
, idx
))
153 # does the final conversion from intermediary to output data
154 divstages
.append(DivPipeFinalStage(self
.pspec
))
156 # does conversion from DivPipeOutputData into
157 # FPAddStage1Data format (bad name, TODO, doesn't matter),
158 # so that post-normalisation and corrections can take over
159 divstages
.append(FPDivStage2Mod(self
.pspec
))
161 chain
= StageChain(divstages
)
164 # output is from the last pipe stage
165 self
.o
= divstages
[-1].o
167 def process(self
, i
):