1 from nmigen
import Signal
, Const
2 from soc
.fu
.pipe_data
import IntegerData
3 from soc
.fu
.alu
.pipe_data
import CommonPipeSpec
4 from soc
.fu
.logical
.logical_input_record
import CompLogicalOpSubset
5 from ieee754
.div_rem_sqrt_rsqrt
.core
import (
6 DivPipeCoreConfig
, DivPipeCoreInputData
, DP
,
7 DivPipeCoreInterstageData
, DivPipeCoreOutputData
)
10 class DivInputData(IntegerData
):
11 regspec
= [('INT', 'ra', '0:63'), # RA
12 ('INT', 'rb', '0:63'), # RB/immediate
13 ('XER', 'xer_so', '32'), ] # XER bit 32: SO
15 def __init__(self
, pspec
):
16 super().__init
__(pspec
, False)
18 self
.a
, self
.b
= self
.ra
, self
.rb
21 # output stage shared between div and mul: like ALUOutputData but no CA/32
22 class DivMulOutputData(IntegerData
):
23 regspec
= [('INT', 'o', '0:63'),
24 ('CR', 'cr_a', '0:3'),
25 ('XER', 'xer_ov', '33,44'), # bit0: ov, bit1: ov32
26 ('XER', 'xer_so', '32')]
28 def __init__(self
, pspec
):
29 super().__init
__(pspec
, True)
34 class DivPipeSpec(CommonPipeSpec
):
35 regspec
= (DivInputData
.regspec
, DivMulOutputData
.regspec
)
36 opsubsetkls
= CompLogicalOpSubset
37 core_config
= DivPipeCoreConfig(
41 supported
=[DP
.UDivRem
]
45 class CoreBaseData(DivInputData
):
46 def __init__(self
, pspec
, core_data_class
):
47 super().__init
__(pspec
)
48 self
.core
= core_data_class(pspec
.core_config
)
49 self
.divisor_neg
= Signal(reset_less
=True)
50 self
.dividend_neg
= Signal(reset_less
=True)
51 self
.div_by_zero
= Signal(reset_less
=True)
53 # set if an overflow for divide extended instructions is detected
54 # because `abs_dividend >= abs_divisor` for the appropriate bit width;
55 # 0 if the instruction is not a divide extended instruction
56 self
.dive_abs_ov32
= Signal(reset_less
=True)
57 self
.dive_abs_ov64
= Signal(reset_less
=True)
60 yield from super().__iter
__()
61 yield from self
.core
.__iter
__(self
)
62 yield self
.divisor_neg
63 yield self
.dividend_neg
66 return self
.eq_without_core(rhs
) + self
.core
.eq(rhs
.core
)
68 def eq_without_core(self
, rhs
):
69 return super().eq(rhs
) + \
70 [self
.divisor_neg
.eq(rhs
.divisor_neg
),
71 self
.dividend_neg
.eq(rhs
.dividend_neg
),
72 self
.dive_abs_ov32
.eq(rhs
.dive_abs_ov32
),
73 self
.dive_abs_ov64
.eq(rhs
.dive_abs_ov64
),
74 self
.div_by_zero
.eq(rhs
.div_by_zero
)]
77 class CoreInputData(CoreBaseData
):
78 def __init__(self
, pspec
):
79 super().__init
__(pspec
, DivPipeCoreInputData
)
82 class CoreInterstageData(CoreBaseData
):
83 def __init__(self
, pspec
):
84 super().__init
__(pspec
, DivPipeCoreInterstageData
)
87 class CoreOutputData(CoreBaseData
):
88 def __init__(self
, pspec
):
89 super().__init
__(pspec
, DivPipeCoreOutputData
)