1 # SPDX-License-Identifier: LGPL-2.1-or-later
2 # See Notices.txt for copyright information
3 """ div/rem/sqrt/rsqrt pipeline. """
5 from nmigen
import Signal
6 from ieee754
.div_rem_sqrt_rsqrt
.core
import (DivPipeCoreConfig
,
8 DivPipeCoreInterstageData
,
10 DivPipeCoreSetupStage
,
11 DivPipeCoreCalculateStage
,
12 DivPipeCoreFinalStage
,
14 from ieee754
.fpcommon
.getop
import FPPipeContext
15 from ieee754
.fpcommon
.fpbase
import FPFormat
, FPNumBaseRecord
18 class DivPipeBaseData
:
19 """ input data base type for ``DivPipe``.
21 :attribute z: a convenient way to carry the sign and exponent through
22 the pipeline from when they were computed right at the
24 :attribute out_do_z: FIXME: document
25 :attribute oz: FIXME: document
26 :attribute ctx: FIXME: document
29 Alias of ``ctx.muxid``.
30 :attribute config: the ``DivPipeConfig`` instance.
33 def __init__(self
, pspec
):
34 """ Create a ``DivPipeBaseData`` instance. """
37 self
.z
= FPNumBaseRecord(width
, False) # s and e carried: m ignored
38 self
.out_do_z
= Signal(reset_less
=True)
39 self
.oz
= Signal(width
, reset_less
=True)
41 self
.ctx
= FPPipeContext(pspec
) # context: muxid, operator etc.
42 # FIXME: add proper muxid explanation somewhere and refer to it here
43 self
.muxid
= self
.ctx
.muxid
# annoying. complicated.
46 """ Get member signals. """
53 """ Assign member signals. """
54 return [self
.z
.eq(rhs
.z
), self
.out_do_z
.eq(rhs
.out_do_z
),
55 self
.oz
.eq(rhs
.oz
), self
.ctx
.eq(rhs
.ctx
)]
58 class DivPipeInputData(DivPipeCoreInputData
, DivPipeBaseData
):
59 """ input data type for ``DivPipe``. """
61 def __init__(self
, pspec
):
62 """ Create a ``DivPipeInputData`` instance. """
63 DivPipeCoreInputData
.__init
__(self
, pspec
.core_config
)
64 DivPipeBaseData
.__init
__(self
, pspec
)
67 """ Get member signals. """
68 yield from DivPipeCoreInputData
.__iter
__(self
)
69 yield from DivPipeBaseData
.__iter
__(self
)
72 """ Assign member signals. """
73 return DivPipeCoreInputData
.eq(self
, rhs
) + \
74 DivPipeBaseData
.eq(self
, rhs
)
77 class DivPipeInterstageData(DivPipeCoreInterstageData
, DivPipeBaseData
):
78 """ interstage data type for ``DivPipe``. """
80 def __init__(self
, pspec
):
81 """ Create a ``DivPipeInterstageData`` instance. """
82 DivPipeCoreInterstageData
.__init
__(self
, pspec
.core_config
)
83 DivPipeBaseData
.__init
__(self
, pspec
)
86 """ Get member signals. """
87 yield from DivPipeCoreInterstageData
.__iter
__(self
)
88 yield from DivPipeBaseData
.__iter
__(self
)
91 """ Assign member signals. """
92 return DivPipeCoreInterstageData
.eq(self
, rhs
) + \
93 DivPipeBaseData
.eq(self
, rhs
)
96 class DivPipeOutputData(DivPipeCoreOutputData
, DivPipeBaseData
):
97 """ output data type for ``DivPipe``. """
99 def __init__(self
, pspec
):
100 """ Create a ``DivPipeOutputData`` instance. """
101 DivPipeCoreOutputData
.__init
__(self
, pspec
.core_config
)
102 DivPipeBaseData
.__init
__(self
, pspec
)
105 """ Get member signals. """
106 yield from DivPipeCoreOutputData
.__iter
__(self
)
107 yield from DivPipeBaseData
.__iter
__(self
)
110 """ Assign member signals. """
111 return DivPipeCoreOutputData
.eq(self
, rhs
) + \
112 DivPipeBaseData
.eq(self
, rhs
)
115 class DivPipeBaseStage
:
116 """ Base Mix-in for DivPipe*Stage. """
118 def _elaborate(self
, m
, platform
):
119 m
.d
.comb
+= self
.o
.z
.eq(self
.i
.z
)
120 m
.d
.comb
+= self
.o
.oz
.eq(self
.i
.oz
)
121 m
.d
.comb
+= self
.o
.out_do_z
.eq(self
.i
.out_do_z
)
122 m
.d
.comb
+= self
.o
.ctx
.eq(self
.i
.ctx
)
124 def get_core_config(self
):
125 m_width
= self
.pspec
.m_width
# mantissa width
126 # 4 extra bits on the mantissa: MSB is zero, MSB-1 is 1
127 # then there is guard and round at the LSB end
128 return DivPipeCoreConfig(m_width
+4, 0, log_radix
=2)
131 class DivPipeSetupStage(DivPipeBaseStage
, DivPipeCoreSetupStage
):
133 def __init__(self
, pspec
):
134 DivPipeCoreSetupStage
.__init
__(self
.get_core_config())
137 def elaborate(self
, platform
):
138 m
= DivPipeCoreSetupStage(platform
) # XXX TODO: out_do_z logic!
139 self
._elaborate
(m
, platform
)
143 class DivPipeCalculateStage(DivPipeBaseStage
, DivPipeCoreCalculateStage
):
145 def __init__(self
, pspec
, stage_index
):
146 DivPipeCoreCalculateStage
.__init
__(self
.get_core_config(), stage_index
)
149 def elaborate(self
, platform
):
150 m
= DivPipeCoreCalculateStage(platform
) # XXX TODO: out_do_z logic!
151 self
._elaborate
(m
, platform
)
155 class DivPipeFinalStage(DivPipeBaseStage
, DivPipeCoreFinalStage
):
157 def __init__(self
, pspec
, stage_index
):
158 DivPipeCoreFinalStage
.__init
__(self
.get_core_config(), stage_index
)
161 def elaborate(self
, platform
):
162 m
= DivPipeCoreCalculateStage(platform
) # XXX TODO: out_do_z logic!
163 self
._elaborate
(m
, platform
)