2 from nmigen
import Elaboratable
, Module
, Signal
, Shape
, unsigned
, Cat
, Mux
3 from soc
.fu
.div
.pipe_data
import CoreInputData
, CoreOutputData
, DivPipeSpec
4 from nmutil
.iocontrol
import PrevControl
, NextControl
5 from ieee754
.div_rem_sqrt_rsqrt
.core
import DivPipeCoreOperation
8 class FSMDivCoreConfig
:
14 class FSMDivCoreInputData
:
15 def __init__(self
, core_config
, reset_less
=True):
16 self
.core_config
= core_config
17 self
.dividend
= Signal(128, reset_less
=reset_less
)
18 self
.divisor_radicand
= Signal(64, reset_less
=reset_less
)
19 self
.operation
= DivPipeCoreOperation
.create_signal(
20 reset_less
=reset_less
)
23 """ Get member signals. """
25 yield self
.divisor_radicand
29 """ Assign member signals. """
30 return [self
.dividend
.eq(rhs
.dividend
),
31 self
.divisor_radicand
.eq(rhs
.divisor_radicand
),
32 self
.operation
.eq(rhs
.operation
),
36 class FSMDivCoreOutputData
:
37 def __init__(self
, core_config
, reset_less
=True):
38 self
.core_config
= core_config
39 self
.quotient_root
= Signal(64, reset_less
=reset_less
)
40 self
.remainder
= Signal(3 * 64, reset_less
=reset_less
)
43 """ Get member signals. """
44 yield self
.quotient_root
49 """ Assign member signals. """
50 return [self
.quotient_root
.eq(rhs
.quotient_root
),
51 self
.remainder
.eq(rhs
.remainder
)]
54 class FSMDivCorePrevControl(PrevControl
):
57 def __init__(self
, pspec
):
58 super().__init
__(stage_ctl
=True, maskwid
=pspec
.id_wid
)
60 self
.data_i
= CoreInputData(pspec
)
63 class FSMDivCoreNextControl(NextControl
):
64 data_o
: CoreOutputData
66 def __init__(self
, pspec
):
67 super().__init
__(stage_ctl
=True, maskwid
=pspec
.id_wid
)
69 self
.data_o
= CoreOutputData(pspec
)
72 class DivStateNext(Elaboratable
):
73 def __init__(self
, quotient_width
):
74 self
.quotient_width
= quotient_width
75 self
.i
= DivState(quotient_width
=quotient_width
, name
="i")
76 self
.divisor
= Signal(quotient_width
)
77 self
.o
= DivState(quotient_width
=quotient_width
, name
="o")
79 def elaborate(self
, platform
):
81 difference
= Signal(self
.i
.quotient_width
* 2)
82 m
.d
.comb
+= difference
.eq(self
.i
.dividend_quotient
84 << (self
.quotient_width
- 1)))
85 next_quotient_bit
= Signal()
86 m
.d
.comb
+= next_quotient_bit
.eq(
87 ~difference
[self
.quotient_width
* 2 - 1])
88 value
= Signal(self
.i
.quotient_width
* 2)
89 with m
.If(next_quotient_bit
):
90 m
.d
.comb
+= value
.eq(difference
)
92 m
.d
.comb
+= value
.eq(self
.i
.dividend_quotient
)
94 with m
.If(self
.i
.done
):
95 m
.d
.comb
+= self
.o
.eq(self
.i
)
98 self
.o
.q_bits_known
.eq(self
.i
.q_bits_known
+ 1),
99 self
.o
.dividend_quotient
.eq(Cat(next_quotient_bit
, value
))]
103 class DivStateInit(Elaboratable
):
104 def __init__(self
, quotient_width
):
105 self
.quotient_width
= quotient_width
106 self
.dividend
= Signal(quotient_width
* 2)
107 self
.o
= DivState(quotient_width
=quotient_width
, name
="o")
109 def elaborate(self
, platform
):
111 m
.d
.comb
+= self
.o
.q_bits_known
.eq(0)
112 m
.d
.comb
+= self
.o
.dividend_quotient
.eq(self
.dividend
)
117 def __init__(self
, quotient_width
, name
):
118 self
.quotient_width
= quotient_width
119 self
.q_bits_known
= Signal(range(1 + quotient_width
),
120 name
=name
+ "_q_bits_known")
121 self
.dividend_quotient
= Signal(unsigned(2 * quotient_width
),
122 name
=name
+ "_dividend_quotient")
126 return self
.q_bits_known
== self
.quotient_width
130 """ get the quotient -- requires self.done is True """
131 return self
.dividend_quotient
[0:self
.quotient_width
]
135 """ get the remainder -- requires self.done is True """
136 return self
.dividend_quotient
[self
.quotient_width
:self
.quotient_width
*2]
139 return [self
.q_bits_known
.eq(rhs
.q_bits_known
),
140 self
.dividend_quotient
.eq(rhs
.dividend_quotient
)]
143 class FSMDivCoreStage(Elaboratable
):
144 def __init__(self
, pspec
: DivPipeSpec
):
146 self
.p
= FSMDivCorePrevControl(pspec
)
147 self
.n
= FSMDivCoreNextControl(pspec
)
148 self
.saved_input_data
= CoreInputData(pspec
)
149 self
.canceled
= Signal()
150 self
.empty
= Signal(reset
=1)
151 self
.saved_state
= DivState(64)
153 def elaborate(self
, platform
):
155 m
.submodules
.p
= self
.p
156 m
.submodules
.n
= self
.n
157 data_i
= self
.p
.data_i
158 data_o
= self
.p
.data_o
160 # TODO: calculate self.canceled from self.p.data_i.ctx
161 m
.d
.comb
+= self
.canceled
.eq(False)
163 # TODO: adapt to refactored DivState interface
164 fsm_state_in
= DivState(64)
165 divisor
= Signal(unsigned(64))
166 fsm_state_out
= fsm_state_in
.make_next_state(m
, divisor
)
168 with m
.If(self
.canceled
):
169 with m
.If(self
.p
.valid_i
):
174 with m
.If(self
.p
.valid_i
):