switch to exact version of cython
[ieee754fpu.git] / src / ieee754 / div_rem_sqrt_rsqrt / div_pipe.py
1 # SPDX-License-Identifier: LGPL-2.1-or-later
2 # See Notices.txt for copyright information
3 """ div/rem/sqrt/rsqrt pipeline. """
4
5 from nmigen import Signal
6 from ieee754.div_rem_sqrt_rsqrt.core import (DivPipeCoreConfig,
7 DivPipeCoreInputData,
8 DivPipeCoreInterstageData,
9 DivPipeCoreOutputData,
10 DivPipeCoreSetupStage,
11 DivPipeCoreCalculateStage,
12 DivPipeCoreFinalStage,
13 )
14 from ieee754.fpcommon.getop import FPPipeContext
15 from ieee754.fpcommon.fpbase import FPFormat, FPNumBaseRecord
16
17
18 class DivPipeBaseData:
19 """ input data base type for ``DivPipe``.
20
21 :attribute z: a convenient way to carry the sign and exponent through
22 the pipeline from when they were computed right at the
23 start.
24 :attribute out_do_z: FIXME: document
25 :attribute oz: FIXME: document
26 :attribute ctx: FIXME: document
27 :attribute muxid:
28 FIXME: document
29 Alias of ``ctx.muxid``.
30 :attribute config: the ``DivPipeConfig`` instance.
31 """
32
33 def __init__(self, pspec):
34 """ Create a ``DivPipeBaseData`` instance. """
35 self.pspec = pspec
36 width = pspec.width
37 # s and e carried: m ignored
38 self.z = FPNumBaseRecord(width, False, name="z")
39 self.out_do_z = Signal(reset_less=True)
40 self.oz = Signal(width, reset_less=True)
41
42 self.ctx = FPPipeContext(pspec) # context: muxid, operator etc.
43 # FIXME: add proper muxid explanation somewhere and refer to it here
44 self.muxid = self.ctx.muxid # annoying. complicated.
45
46 def __iter__(self):
47 """ Get member signals. """
48 yield from self.z
49 yield self.out_do_z
50 yield self.oz
51 yield from self.ctx
52
53 def eq(self, rhs):
54 """ Assign member signals. """
55 return [self.z.eq(rhs.z), self.out_do_z.eq(rhs.out_do_z),
56 self.oz.eq(rhs.oz), self.ctx.eq(rhs.ctx)]
57
58
59 class DivPipeInputData(DivPipeCoreInputData, DivPipeBaseData):
60 """ input data type for ``DivPipe``. """
61
62 def __init__(self, pspec):
63 """ Create a ``DivPipeInputData`` instance. """
64 DivPipeCoreInputData.__init__(self, pspec.core_config)
65 DivPipeBaseData.__init__(self, pspec)
66
67 def __iter__(self):
68 """ Get member signals. """
69 yield from DivPipeCoreInputData.__iter__(self)
70 yield from DivPipeBaseData.__iter__(self)
71
72 def eq(self, rhs):
73 """ Assign member signals. """
74 return DivPipeCoreInputData.eq(self, rhs) + \
75 DivPipeBaseData.eq(self, rhs)
76
77
78 class DivPipeInterstageData(DivPipeCoreInterstageData, DivPipeBaseData):
79 """ interstage data type for ``DivPipe``. """
80
81 def __init__(self, pspec):
82 """ Create a ``DivPipeInterstageData`` instance. """
83 DivPipeCoreInterstageData.__init__(self, pspec.core_config)
84 DivPipeBaseData.__init__(self, pspec)
85
86 def __iter__(self):
87 """ Get member signals. """
88 yield from DivPipeCoreInterstageData.__iter__(self)
89 yield from DivPipeBaseData.__iter__(self)
90
91 def eq(self, rhs):
92 """ Assign member signals. """
93 #print (self, rhs)
94 return DivPipeCoreInterstageData.eq(self, rhs) + \
95 DivPipeBaseData.eq(self, rhs)
96
97
98 class DivPipeOutputData(DivPipeCoreOutputData, DivPipeBaseData):
99 """ output data type for ``DivPipe``. """
100
101 def __init__(self, pspec):
102 """ Create a ``DivPipeOutputData`` instance. """
103 DivPipeCoreOutputData.__init__(self, pspec.core_config)
104 DivPipeBaseData.__init__(self, pspec)
105
106 def __iter__(self):
107 """ Get member signals. """
108 yield from DivPipeCoreOutputData.__iter__(self)
109 yield from DivPipeBaseData.__iter__(self)
110
111 def eq(self, rhs):
112 """ Assign member signals. """
113 return DivPipeCoreOutputData.eq(self, rhs) + \
114 DivPipeBaseData.eq(self, rhs)
115
116
117 class DivPipeBaseStage:
118 """ Base Mix-in for DivPipe*Stage. """
119
120 def _elaborate(self, m, platform):
121 m.d.comb += self.o.ctx.eq(self.i.ctx)
122 m.d.comb += self.o.z.eq(self.i.z)
123 m.d.comb += self.o.oz.eq(self.i.oz)
124 m.d.comb += self.o.out_do_z.eq(self.i.out_do_z)
125
126
127 class DivPipeSetupStage(DivPipeBaseStage, DivPipeCoreSetupStage):
128 """ FIXME: add docs. """
129
130 def __init__(self, pspec):
131 self.pspec = pspec
132 #print ("DivPipeSetupStage", pspec, pspec.core_config)
133 DivPipeCoreSetupStage.__init__(self, pspec.core_config)
134
135 def ispec(self):
136 """ Get the input spec for this pipeline stage."""
137 return DivPipeInputData(self.pspec)
138
139 def ospec(self):
140 """ Get the output spec for this pipeline stage."""
141 return DivPipeInterstageData(self.pspec)
142
143 def elaborate(self, platform):
144 # XXX TODO: out_do_z logic!
145 m = DivPipeCoreSetupStage.elaborate(self, platform)
146 self._elaborate(m, platform)
147 return m
148
149
150 class DivPipeCalculateStage(DivPipeBaseStage, DivPipeCoreCalculateStage):
151 """ FIXME: add docs. """
152
153 def __init__(self, pspec, stage_idx):
154 self.pspec = pspec
155 DivPipeCoreCalculateStage.__init__(self, pspec.core_config, stage_idx)
156
157 def ispec(self):
158 """ Get the input spec for this pipeline stage."""
159 return DivPipeInterstageData(self.pspec)
160
161 def ospec(self):
162 """ Get the output spec for this pipeline stage."""
163 return DivPipeInterstageData(self.pspec)
164
165 def elaborate(self, platform):
166 # XXX TODO: out_do_z logic!
167 m = DivPipeCoreCalculateStage.elaborate(self, platform)
168 self._elaborate(m, platform)
169 return m
170
171
172 class DivPipeFinalStage(DivPipeBaseStage, DivPipeCoreFinalStage):
173 """ FIXME: add docs. """
174
175 def __init__(self, pspec):
176 self.pspec = pspec
177 DivPipeCoreFinalStage.__init__(self, pspec.core_config)
178
179 def ispec(self):
180 """ Get the input spec for this pipeline stage."""
181 return DivPipeInterstageData(self.pspec)
182
183 def ospec(self):
184 """ Get the output spec for this pipeline stage."""
185 return DivPipeOutputData(self.pspec)
186
187 def elaborate(self, platform):
188 # XXX TODO: out_do_z logic!
189 m = DivPipeCoreFinalStage.elaborate(self, platform)
190 self._elaborate(m, platform)
191 return m