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 # 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)
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.
47 """ Get member signals. """
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
)]
59 class DivPipeInputData(DivPipeCoreInputData
, DivPipeBaseData
):
60 """ input data type for ``DivPipe``. """
62 def __init__(self
, pspec
):
63 """ Create a ``DivPipeInputData`` instance. """
64 DivPipeCoreInputData
.__init
__(self
, pspec
.core_config
)
65 DivPipeBaseData
.__init
__(self
, pspec
)
68 """ Get member signals. """
69 yield from DivPipeCoreInputData
.__iter
__(self
)
70 yield from DivPipeBaseData
.__iter
__(self
)
73 """ Assign member signals. """
74 return DivPipeCoreInputData
.eq(self
, rhs
) + \
75 DivPipeBaseData
.eq(self
, rhs
)
78 class DivPipeInterstageData(DivPipeCoreInterstageData
, DivPipeBaseData
):
79 """ interstage data type for ``DivPipe``. """
81 def __init__(self
, pspec
):
82 """ Create a ``DivPipeInterstageData`` instance. """
83 DivPipeCoreInterstageData
.__init
__(self
, pspec
.core_config
)
84 DivPipeBaseData
.__init
__(self
, pspec
)
87 """ Get member signals. """
88 yield from DivPipeCoreInterstageData
.__iter
__(self
)
89 yield from DivPipeBaseData
.__iter
__(self
)
92 """ Assign member signals. """
94 return DivPipeCoreInterstageData
.eq(self
, rhs
) + \
95 DivPipeBaseData
.eq(self
, rhs
)
98 class DivPipeOutputData(DivPipeCoreOutputData
, DivPipeBaseData
):
99 """ output data type for ``DivPipe``. """
101 def __init__(self
, pspec
):
102 """ Create a ``DivPipeOutputData`` instance. """
103 DivPipeCoreOutputData
.__init
__(self
, pspec
.core_config
)
104 DivPipeBaseData
.__init
__(self
, pspec
)
107 """ Get member signals. """
108 yield from DivPipeCoreOutputData
.__iter
__(self
)
109 yield from DivPipeBaseData
.__iter
__(self
)
112 """ Assign member signals. """
113 return DivPipeCoreOutputData
.eq(self
, rhs
) + \
114 DivPipeBaseData
.eq(self
, rhs
)
117 class DivPipeBaseStage
:
118 """ Base Mix-in for DivPipe*Stage. """
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
)
127 class DivPipeSetupStage(DivPipeBaseStage
, DivPipeCoreSetupStage
):
128 """ FIXME: add docs. """
130 def __init__(self
, pspec
):
132 #print ("DivPipeSetupStage", pspec, pspec.core_config)
133 DivPipeCoreSetupStage
.__init
__(self
, pspec
.core_config
)
136 """ Get the input spec for this pipeline stage."""
137 return DivPipeInputData(self
.pspec
)
140 """ Get the output spec for this pipeline stage."""
141 return DivPipeInterstageData(self
.pspec
)
143 def elaborate(self
, platform
):
144 # XXX TODO: out_do_z logic!
145 m
= DivPipeCoreSetupStage
.elaborate(self
, platform
)
146 self
._elaborate
(m
, platform
)
150 class DivPipeCalculateStage(DivPipeBaseStage
, DivPipeCoreCalculateStage
):
151 """ FIXME: add docs. """
153 def __init__(self
, pspec
, stage_idx
):
155 DivPipeCoreCalculateStage
.__init
__(self
, pspec
.core_config
, stage_idx
)
158 """ Get the input spec for this pipeline stage."""
159 return DivPipeInterstageData(self
.pspec
)
162 """ Get the output spec for this pipeline stage."""
163 return DivPipeInterstageData(self
.pspec
)
165 def elaborate(self
, platform
):
166 # XXX TODO: out_do_z logic!
167 m
= DivPipeCoreCalculateStage
.elaborate(self
, platform
)
168 self
._elaborate
(m
, platform
)
172 class DivPipeFinalStage(DivPipeBaseStage
, DivPipeCoreFinalStage
):
173 """ FIXME: add docs. """
175 def __init__(self
, pspec
):
177 DivPipeCoreFinalStage
.__init
__(self
, pspec
.core_config
)
180 """ Get the input spec for this pipeline stage."""
181 return DivPipeInterstageData(self
.pspec
)
184 """ Get the output spec for this pipeline stage."""
185 return DivPipeOutputData(self
.pspec
)
187 def elaborate(self
, platform
):
188 # XXX TODO: out_do_z logic!
189 m
= DivPipeCoreFinalStage
.elaborate(self
, platform
)
190 self
._elaborate
(m
, platform
)