1 # SPDX-License-Identifier: LGPL-2.1-or-later
2 # See Notices.txt for copyright information
3 """ div/rem/sqrt/rsqrt pipeline. """
5 from ieee754
.div_rem_sqrt_rsqrt
.core
import (DivPipeCoreConfig
,
7 DivPipeCoreInterstageData
,
10 DivPipeCoreCalculateStage
,
11 DivPipeCoreFinalStage
,
13 from ieee754
.fpcommon
.getop
import FPPipeContext
14 from ieee754
.fpcommon
.fpbase
import FPFormat
, FPNumBaseRecord
18 """ Configuration for the div/rem/sqrt/rsqrt pipeline.
20 :attribute pspec: ``PipelineSpec`` instance
21 :attribute core_config: the ``DivPipeCoreConfig`` instance.
24 def __init__(self
, pspec
, log2_radix
=3):
25 """ Create a ``DivPipeConfig`` instance. """
27 bit_width
= pspec
.width
28 fract_width
= FPFormat
.standard(bit_width
).fraction_width
29 self
.core_config
= DivPipeCoreConfig(bit_width
,
34 class DivPipeBaseData
:
35 """ input data base type for ``DivPipe``.
37 :attribute z: a convenient way to carry the sign and exponent through
38 the pipeline from when they were computed right at the
40 :attribute out_do_z: FIXME: document
41 :attribute oz: FIXME: document
42 :attribute ctx: FIXME: document
45 Alias of ``ctx.muxid``.
46 :attribute config: the ``DivPipeConfig`` instance.
49 def __init__(self
, config
):
50 """ Create a ``DivPipeBaseData`` instance. """
52 width
= config
.pspec
.width
53 self
.z
= FPNumBaseRecord(width
, False) # s and e carried: m ignored
54 self
.out_do_z
= Signal(reset_less
=True)
55 self
.oz
= Signal(width
, reset_less
=True)
57 self
.ctx
= FPPipeContext(config
.pspec
) # context: muxid, operator etc.
58 # FIXME: add proper muxid explanation somewhere and refer to it here
59 self
.muxid
= self
.ctx
.muxid
# annoying. complicated.
62 """ Get member signals. """
69 """ Assign member signals. """
70 return [self
.z
.eq(rhs
.z
), self
.out_do_z
.eq(i
.out_do_z
), self
.oz
.eq(i
.oz
),
74 class DivPipeInputData(DivPipeCoreInputData
, DivPipeBaseData
):
75 """ input data type for ``DivPipe``. """
77 def __init__(self
, config
):
78 """ Create a ``DivPipeInputData`` instance. """
79 DivPipeCoreInputData
.__init
__(self
, config
.core_config
)
80 DivPipeBaseData
.__init
__(self
, config
)
83 """ Get member signals. """
84 yield from DivPipeCoreInputData
.__iter
__(self
)
85 yield from DivPipeBaseData
.__iter
__(self
)
88 """ Assign member signals. """
89 return DivPipeCoreInputData
.eq(self
, rhs
) + \
90 DivPipeBaseData
.eq(self
, rhs
)
93 class DivPipeInterstageData(DivPipeCoreInterstageData
, DivPipeBaseData
):
94 """ interstage data type for ``DivPipe``. """
96 def __init__(self
, config
):
97 """ Create a ``DivPipeInterstageData`` instance. """
98 DivPipeCoreInterstageData
.__init
__(self
, config
.core_config
)
99 DivPipeBaseData
.__init
__(self
, config
)
102 """ Get member signals. """
103 yield from DivPipeCoreInterstageData
.__iter
__(self
)
104 yield from DivPipeBaseData
.__iter
__(self
)
107 """ Assign member signals. """
108 return DivPipeCoreInterstageData
.eq(self
, rhs
) + \
109 DivPipeBaseData
.eq(self
, rhs
)
112 class DivPipeOutputData(DivPipeCoreOutputData
, DivPipeBaseData
):
113 """ output data type for ``DivPipe``. """
115 def __init__(self
, config
):
116 """ Create a ``DivPipeOutputData`` instance. """
117 DivPipeCoreOutputData
.__init
__(self
, config
.core_config
)
118 DivPipeBaseData
.__init
__(self
, config
)
121 """ Get member signals. """
122 yield from DivPipeCoreOutputData
.__iter
__(self
)
123 yield from DivPipeBaseData
.__iter
__(self
)
126 """ Assign member signals. """
127 return DivPipeCoreOutputData
.eq(self
, rhs
) + \
128 DivPipeBaseData
.eq(self
, rhs
)
131 class DivPipeBaseStage
:
132 """ Base Mix-in for DivPipe*Stage. """
134 def _elaborate(self
, m
, platform
):
135 m
.d
.comb
+= self
.o
.z
.eq(self
.i
.z
)
136 m
.d
.comb
+= self
.o
.oz
.eq(self
.i
.oz
)
137 m
.d
.comb
+= self
.o
.out_do_z
.eq(self
.i
.out_do_z
)
138 m
.d
.comb
+= self
.o
.ctx
.eq(self
.i
.ctx
)
140 def get_core_config(self
):
141 m_width
= self
.pspec
.m_width
# mantissa width
142 # 4 extra bits on the mantissa: MSB is zero, MSB-1 is 1
143 # then there is guard and round at the LSB end
144 return DivPipeCoreConfig(m_width
+4, 0, log_radix
=2)
147 class DivPipeSetupStage(DivPipeBaseStage
, DivPipeCoreSetupStage
):
149 def __init__(self
, pspec
):
150 DivPipeCoreSetupStage
.__init
__(self
.get_core_config())
153 def elaborate(self
, platform
):
154 m
= DivPipeCoreSetupStage(platform
) # XXX TODO: out_do_z logic!
155 self
._elaborate
(m
, platform
)
159 class DivPipeCalculateStage(DivPipeBaseStage
, DivPipeCoreCalculateStage
):
161 def __init__(self
, pspec
, stage_index
):
162 DivPipeCoreCalculateStage
.__init
__(self
.get_core_config(), stage_index
)
165 def elaborate(self
, platform
):
166 m
= DivPipeCoreCalculateStage(platform
) # XXX TODO: out_do_z logic!
167 self
._elaborate
(m
, platform
)
171 class DivPipeFinalStage(DivPipeBaseStage
, DivPipeCoreFinalStage
):
173 def __init__(self
, pspec
, stage_index
):
174 DivPipeCoreFinalStage
.__init
__(self
.get_core_config(), stage_index
)
177 def elaborate(self
, platform
):
178 m
= DivPipeCoreCalculateStage(platform
) # XXX TODO: out_do_z logic!
179 self
._elaborate
(m
, platform
)