1 from nmigen
import Signal
, Elaboratable
, Module
2 from ieee754
.div_rem_sqrt_rsqrt
.core
import DivPipeCoreOperation
5 class SimOnlyCoreConfig
:
11 class SimOnlyCoreInputData
:
12 def __init__(self
, core_config
, reset_less
=True):
13 self
.core_config
= core_config
14 self
.dividend
= Signal(128, reset_less
=reset_less
)
15 self
.divisor_radicand
= Signal(64, reset_less
=reset_less
)
16 self
.operation
= DivPipeCoreOperation
.create_signal(
17 reset_less
=reset_less
)
20 """ Get member signals. """
22 yield self
.divisor_radicand
26 """ Assign member signals. """
27 return [self
.dividend
.eq(rhs
.dividend
),
28 self
.divisor_radicand
.eq(rhs
.divisor_radicand
),
29 self
.operation
.eq(rhs
.operation
),
33 class SimOnlyCoreInterstageData
:
34 def __init__(self
, core_config
, reset_less
=True):
35 self
.core_config
= core_config
36 self
.dividend
= Signal(128, reset_less
=reset_less
)
37 self
.divisor
= Signal(64, reset_less
=reset_less
)
40 """ Get member signals. """
45 """ Assign member signals. """
46 return [self
.dividend
.eq(rhs
.dividend
),
47 self
.divisor
.eq(rhs
.divisor
)]
50 class SimOnlyCoreOutputData
:
51 def __init__(self
, core_config
, reset_less
=True):
52 self
.core_config
= core_config
53 self
.quotient_root
= Signal(64, reset_less
=reset_less
)
54 self
.remainder
= Signal(3 * 64, reset_less
=reset_less
)
57 """ Get member signals. """
58 yield self
.quotient_root
63 """ Assign member signals. """
64 return [self
.quotient_root
.eq(rhs
.quotient_root
),
65 self
.remainder
.eq(rhs
.remainder
)]
68 class SimOnlyCoreSetupStage(Elaboratable
):
69 def __init__(self
, core_config
):
70 self
.core_config
= core_config
75 """ Get the input spec for this pipeline stage."""
76 return SimOnlyCoreInputData(self
.core_config
)
79 """ Get the output spec for this pipeline stage."""
80 return SimOnlyCoreInterstageData(self
.core_config
)
82 def setup(self
, m
, i
):
83 """ Pipeline stage setup. """
84 m
.submodules
.sim_only_core_setup
= self
85 m
.d
.comb
+= self
.i
.eq(i
)
88 """ Pipeline stage process. """
89 return self
.o
# return processed data (ignore i)
91 def elaborate(self
, platform
):
92 """ Elaborate into ``Module``. """
96 comb
+= self
.o
.divisor
.eq(self
.i
.divisor_radicand
)
97 comb
+= self
.o
.dividend
.eq(self
.i
.dividend
)
102 class SimOnlyCoreCalculateStage(Elaboratable
):
103 def __init__(self
, core_config
, stage_index
):
104 assert stage_index
== 0
105 self
.core_config
= core_config
106 self
.stage_index
= stage_index
107 self
.i
= self
.ispec()
108 self
.o
= self
.ospec()
111 """ Get the input spec for this pipeline stage. """
112 return SimOnlyCoreInterstageData(self
.core_config
)
115 """ Get the output spec for this pipeline stage. """
116 return SimOnlyCoreInterstageData(self
.core_config
)
118 def setup(self
, m
, i
):
119 """ Pipeline stage setup. """
120 setattr(m
.submodules
,
121 f
"sim_only_core_calculate_{self.stage_index}",
123 m
.d
.comb
+= self
.i
.eq(i
)
125 def process(self
, i
):
126 """ Pipeline stage process. """
129 def elaborate(self
, platform
):
130 """ Elaborate into ``Module``. """
132 m
.d
.comb
+= self
.o
.eq(self
.i
)
136 class SimOnlyCoreFinalStage(Elaboratable
):
137 """ Final Stage of the core of the div/rem/sqrt/rsqrt pipeline. """
139 def __init__(self
, core_config
):
140 """ Create a ``SimOnlyCoreFinalStage`` instance."""
141 self
.core_config
= core_config
142 self
.i
= self
.ispec()
143 self
.o
= self
.ospec()
146 """ Get the input spec for this pipeline stage."""
147 return SimOnlyCoreInterstageData(self
.core_config
)
150 """ Get the output spec for this pipeline stage."""
151 return SimOnlyCoreOutputData(self
.core_config
)
153 def setup(self
, m
, i
):
154 """ Pipeline stage setup. """
155 m
.submodules
.sim_only_core_final
= self
156 m
.d
.comb
+= self
.i
.eq(i
)
158 def process(self
, i
):
159 """ Pipeline stage process. """
160 return self
.o
# return processed data (ignore i)
162 def elaborate(self
, platform
):
163 """ Elaborate into ``Module``. """
165 remainder_shift
= self
.core_config
.fract_width
166 with m
.If(self
.i
.divisor
!= 0):
167 quotient
= self
.i
.dividend
// self
.i
.divisor
168 remainder
= self
.i
.dividend
% self
.i
.divisor
169 m
.d
.comb
+= self
.o
.quotient_root
.eq(quotient
)
170 m
.d
.comb
+= self
.o
.remainder
.eq(remainder
<< remainder_shift
)
172 m
.d
.comb
+= self
.o
.quotient_root
.eq(-1)
173 m
.d
.comb
+= self
.o
.remainder
.eq(self
.i
.dividend
<< remainder_shift
)