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
):
25 FPState
.__init
__(self
, "divsetup")
27 self
.n_stages
= n_stages
# number of combinatorial stages
28 SimpleHandshake
.__init
__(self
, self
) # pipeline is its own stage
29 self
.m1o
= self
.ospec()
32 # REQUIRED. do NOT change.
33 return FPSCData(self
.pspec
, False) # from denorm
36 return DivPipeInterstageData(self
.pspec
) # DIV ospec (loop)
38 def setup(self
, m
, i
):
39 """ links module to inputs and outputs.
41 note: this is a pure *combinatorial* module (StageChain).
42 therefore each sub-module must also be combinatorial
43 (and not do too much: in particular, n_stages must be
44 reduced slightly when either self.end=True or self.begin=True)
49 # Converts from FPSCData into DivPipeInputData
50 divstages
.append(FPDivStage0Mod(self
.pspec
))
52 # does 1 "convert" (actual processing) from DivPipeInputData
53 # into "intermediate" output (DivPipeInterstageData)
54 divstages
.append(DivPipeSetupStage(self
.pspec
))
56 # here is where the intermediary stages are added.
57 # n_stages is adjusted (in pipeline.py), reduced to take
58 # into account the extra processing that self.begin and self.end
60 for count
in range(self
.n_stages
): # number of combinatorial stages
61 divstages
.append(DivPipeCalculateStage(self
.pspec
, count
))
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
):
80 FPState
.__init
__(self
, "divintermediate")
82 self
.n_stages
= n_stages
# number of combinatorial stages
83 SimpleHandshake
.__init
__(self
, self
) # pipeline is its own stage
84 self
.m1o
= self
.ospec()
87 # TODO - this is for FPDivStage1Mod
88 return DivPipeInterstageData(self
.pspec
) # DIV ispec (loop)
91 # TODO - this is for FPDivStage1Mod
92 return DivPipeInterstageData(self
.pspec
) # DIV ospec (loop)
94 def setup(self
, m
, i
):
95 """ links module to inputs and outputs.
97 note: this is a pure *combinatorial* module (StageChain).
98 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 divstages
.append(DivPipeCalculateStage(self
.pspec
, count
))
111 chain
= StageChain(divstages
)
114 # output is from the last pipe stage
115 self
.o
= divstages
[-1].o
117 def process(self
, i
):
121 m
.d
.sync
+= self
.m1o
.eq(self
.process(None))
122 m
.next
= "normalise_1"
125 class FPDivStagesFinal(FPState
, SimpleHandshake
):
127 def __init__(self
, pspec
, n_stages
):
128 FPState
.__init
__(self
, "divfinal")
130 self
.n_stages
= n_stages
# number of combinatorial stages
131 SimpleHandshake
.__init
__(self
, self
) # pipeline is its own stage
132 self
.m1o
= self
.ospec()
135 # XXX TODO: replace with "intermediary" (?)
136 return DivPipeInterstageData(self
.pspec
) # DIV ispec (loop)
139 # REQUIRED. do NOT change.
140 return FPAddStage1Data(self
.pspec
) # to post-norm
142 def setup(self
, m
, i
):
143 """ links module to inputs and outputs.
145 note: this is a pure *combinatorial* module (StageChain).
146 therefore each sub-module must also be combinatorial
147 (and not do too much)
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 divstages
.append(DivPipeCalculateStage(pspec
, count
))
162 # does the final conversion from intermediary to output data
163 divstages
.append(DivPipeFinalStage(pspec
))
165 # does conversion from DivPipeOutputData into
166 # FPAddStage1Data format (bad name, TODO, doesn't matter),
167 # so that post-normalisation and corrections can take over
168 divstages
.append(FPDivStage2Mod(self
.pspec
))
170 chain
= StageChain(divstages
)
173 # output is from the last pipe stage
174 self
.o
= divstages
[-1].o
176 def process(self
, i
):
180 m
.d
.sync
+= self
.m1o
.eq(self
.process(None))
181 m
.next
= "normalise_1"