1 # SPDX-License-Identifier: LGPL-2.1-or-later
2 # See Notices.txt for copyright information
3 """ div/rem/sqrt/rsqrt pipeline. """
5 from .core
import (DivPipeCoreConfig
, DivPipeCoreInputData
,
6 DivPipeCoreInterstageData
, DivPipeCoreOutputData
)
7 from ieee754
.fpcommon
.getop
import FPPipeContext
8 from ieee754
.fpcommon
.fpbase
import FPFormat
, FPNumBaseRecord
12 """ Configuration for the div/rem/sqrt/rsqrt pipeline.
14 :attribute pspec: ``PipelineSpec`` instance
15 :attribute core_config: the ``DivPipeCoreConfig`` instance.
18 def __init__(self
, pspec
, log2_radix
=3):
19 """ Create a ``DivPipeConfig`` instance. """
21 bit_width
= pspec
.width
22 fract_width
= FPFormat
.standard(bit_width
).fraction_width
23 self
.core_config
= DivPipeCoreConfig(bit_width
,
28 class DivPipeBaseData
:
29 """ input data base type for ``DivPipe``.
31 :attribute z: a convenient way to carry the sign and exponent through
32 the pipeline from when they were computed right at the
34 :attribute out_do_z: FIXME: document
35 :attribute oz: FIXME: document
36 :attribute ctx: FIXME: document
39 Alias of ``ctx.muxid``.
40 :attribute config: the ``DivPipeConfig`` instance.
43 def __init__(self
, config
):
44 """ Create a ``DivPipeBaseData`` instance. """
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)
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.
56 """ Get member signals. """
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
),
68 class DivPipeInputData(DivPipeCoreInputData
, DivPipeBaseData
):
69 """ input data type for ``DivPipe``. """
71 def __init__(self
, config
):
72 """ Create a ``DivPipeInputData`` instance. """
73 DivPipeCoreInputData
.__init
__(self
, config
.core_config
)
74 DivPipeBaseData
.__init
__(self
, config
)
77 """ Get member signals. """
78 yield from DivPipeCoreInputData
.__iter
__(self
)
79 yield from DivPipeBaseData
.__iter
__(self
)
82 """ Assign member signals. """
83 return DivPipeCoreInputData
.eq(self
, rhs
) + \
84 DivPipeBaseData
.eq(self
, rhs
)
87 class DivPipeInterstageData(DivPipeCoreInterstageData
, DivPipeBaseData
):
88 """ interstage data type for ``DivPipe``. """
90 def __init__(self
, config
):
91 """ Create a ``DivPipeInterstageData`` instance. """
92 DivPipeCoreInterstageData
.__init
__(self
, config
.core_config
)
93 DivPipeBaseData
.__init
__(self
, config
)
96 """ Get member signals. """
97 yield from DivPipeCoreInterstageData
.__iter
__(self
)
98 yield from DivPipeBaseData
.__iter
__(self
)
101 """ Assign member signals. """
102 return DivPipeCoreInterstageData
.eq(self
, rhs
) + \
103 DivPipeBaseData
.eq(self
, rhs
)
106 class DivPipeOutputData(DivPipeCoreOutputData
, DivPipeBaseData
):
107 """ output data type for ``DivPipe``. """
109 def __init__(self
, config
):
110 """ Create a ``DivPipeOutputData`` instance. """
111 DivPipeCoreOutputData
.__init
__(self
, config
.core_config
)
112 DivPipeBaseData
.__init
__(self
, config
)
115 """ Get member signals. """
116 yield from DivPipeCoreOutputData
.__iter
__(self
)
117 yield from DivPipeBaseData
.__iter
__(self
)
120 """ Assign member signals. """
121 return DivPipeCoreOutputData
.eq(self
, rhs
) + \
122 DivPipeBaseData
.eq(self
, rhs
)
125 class DivPipeBaseStage
:
126 """ Base Mix-in for DivPipe*Stage. """
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
)
134 def get_core_config(self
):
135 width
= self
.pspec
.width
136 return DivPipeCoreConfig(width
+2, 0, 1)
139 class DivPipeSetupStage(DivPipeBaseStage
, DivPipeCoreSetupStage
):
141 def __init__(self
, pspec
):
142 DivPipeCoreSetupStage
.__init
__(self
.get_core_config())
145 def elaborate(self
, platform
):
146 m
= DivPipeCoreSetupStage(platform
) # XXX TODO: out_do_z logic!
147 self
._elaborate
(m
, platform
)
151 class DivPipeCalculateStage(DivPipeBaseStage
, DivPipeCoreCalculateStage
):
153 def __init__(self
, pspec
, stage_index
):
154 DivPipeCoreCalculateStage
.__init
__(self
.get_core_config(), stage_index
)
157 def elaborate(self
, platform
):
158 m
= DivPipeCoreCalculateStage(platform
) # XXX TODO: out_do_z logic!
159 self
._elaborate
(m
, platform
)
163 class DivPipeFinalStage(DivPipeBaseStage
, DivPipeCoreFinalStage
):
165 def __init__(self
, pspec
, stage_index
):
166 DivPipeCoreFinalStage
.__init
__(self
.get_core_config(), stage_index
)
169 def elaborate(self
, platform
):
170 m
= DivPipeCoreCalculateStage(platform
) # XXX TODO: out_do_z logic!
171 self
._elaborate
(m
, platform
)