add comments on where DivPipeCoreSetupStage would be used
[ieee754fpu.git] / src / ieee754 / fpdiv / divstages.py
1 """IEEE754 Floating Point pipelined Divider
2
3 Relevant bugreport: http://bugs.libre-riscv.org/show_bug.cgi?id=99
4
5 """
6
7 from nmigen import Module
8 from nmigen.cli import main, verilog
9
10 from nmutil.singlepipe import (StageChain, SimpleHandshake)
11
12 from ieee754.fpcommon.fpbase import FPState
13 from ieee754.fpcommon.denorm import FPSCData
14 from ieee754.fpcommon.postcalc import FPAddStage1Data
15
16 # TODO: write these
17 from .div0 import FPDivStage0Mod
18 from .div1 import FPDivStage1Mod
19 from .div2 import FPDivStage2Mod
20 from .div0 import FPDivStage0Data
21
22
23 class FPDivStages(FPState, SimpleHandshake):
24
25 def __init__(self, width, pspec, n_stages, begin, end):
26 FPState.__init__(self, "align")
27 self.width = width
28 self.pspec = pspec
29 self.n_stages = n_stages # number of combinatorial stages
30 self.begin = begin # "begin" mode
31 self.end = end # "end" mode
32 SimpleHandshake.__init__(self, self) # pipeline is its own stage
33 self.m1o = self.ospec()
34
35 def ispec(self):
36 if self.begin: # TODO - this is for FPDivStage0Mod
37 # REQUIRED. do NOT change.
38 return FPSCData(self.width, self.pspec, False) # from denorm
39
40 if self.end: # TODO - this is for FPDivStage2Mod
41 # XXX TODO: replace with "intermediary" (DivPipeCoreInterstageData?)
42 return FPDivStage0Data(self.width, self.pspec) # DIV ispec (loop)
43
44 # TODO - this is for FPDivStage1Mod
45 # XXX TODO: replace with "intermediary" (DivPipeCoreInterstageData)
46 return FPDivStage0Data(self.width, self.pspec) # DIV ispec (loop)
47
48 def ospec(self):
49 if self.begin: # TODO - this is for FPDivStage0Mod
50 # XXX TODO: replace with "intermediary" (DivPipeCoreInterstageData)
51 return FPDivStage0Data(self.width, self.pspec) # DIV ospec (loop)
52
53 if self.end: # TODO - this is for FPDivStage2Mod
54 # REQUIRED. do NOT change.
55 return FPAddStage1Data(self.width, self.pspec) # to post-norm
56
57 # TODO - this is for FPDivStage1Mod
58 # XXX TODO: replace with "intermediary" (DivPipeCoreInterstageData)
59 return FPDivStage0Data(self.width, self.pspec) # DIV ospec (loop)
60
61 def setup(self, m, i):
62 """ links module to inputs and outputs
63 """
64
65 # start mode accepts data from the FP normalisation stage
66 # and does a bit of munging of the data. it will be chained
67 # into the first DIV combinatorial block,
68
69 # end mode takes the DIV pipeline/chain data and munges it
70 # into the format that the normalisation can accept.
71
72 # neither start nor end mode simply takes the exact same
73 # data in as out, this is where the Q/Rem comes in and Q/Rem goes out
74
75 divstages = []
76
77 if self.begin: # XXX check this
78 divstages.append(FPDivStage0Mod(self.width, self.pspec))
79 # XXX if FPDivStage0Mod is to be used to convert from
80 # FPSCData into DivPipeCoreInputData, rather than
81 # DivPipeCoreSetupStage conforming *to* FPSCData format,
82 # then DivPipeCoreSetupStage needs to be added here:
83 # vvvvvvv
84 # FIXME divstages.append(DivPipeCoreSetupStage(something))
85 # ^^^^^^^
86
87 for count in range(self.n_stages): # number of combinatorial stages
88 divstages.append(FPDivStage1Mod(self.width, self.pspec))
89
90 if self.end: # XXX check this
91 divstages.append(FPDivStage2Mod(self.width, self.pspec))
92
93 chain = StageChain(divstages)
94 chain.setup(m, i)
95
96 # output is from the last pipe stage
97 self.o = divstages[-1].o
98
99 def process(self, i):
100 return self.o
101
102 def action(self, m):
103 m.d.sync += self.m1o.eq(self.process(None))
104 m.next = "normalise_1"
105
106