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