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
14 def __init__(self
, pspec
):
15 super().__init
__(pspec
, False)
17 self
.a
, self
.b
= self
.ra
, self
.rb
20 # output stage shared between div and mul: like ALUOutputData but no CA/32
21 class DivMulOutputData(IntegerData
):
22 regspec
= [('INT', 'o', '0:63'),
23 ('CR', 'cr_a', '0:3'),
24 ('XER', 'xer_ov', '33,44'), # bit0: ov, bit1: ov32
25 ('XER', 'xer_so', '32')]
26 def __init__(self
, pspec
):
27 super().__init
__(pspec
, True)
33 class DIVPipeSpec(CommonPipeSpec
):
34 regspec
= (DIVInputData
.regspec
, DivMulOutputData
.regspec
)
35 opsubsetkls
= CompLogicalOpSubset
36 core_config
= DivPipeCoreConfig(
40 supported
=[DP
.UDivRem
]
44 class CoreBaseData(DIVInputData
):
45 def __init__(self
, pspec
, core_data_class
):
46 super().__init
__(pspec
)
47 self
.core
= core_data_class(pspec
.core_config
)
48 self
.divisor_neg
= Signal(reset_less
=True)
49 self
.dividend_neg
= Signal(reset_less
=True)
50 self
.div_by_zero
= Signal(reset_less
=True)
52 # set if an overflow for divide extended instructions is detected
53 # because `abs_dividend >= abs_divisor` for the appropriate bit width;
54 # 0 if the instruction is not a divide extended instruction
55 self
.dive_abs_ov32
= Signal(reset_less
=True)
56 self
.dive_abs_ov64
= Signal(reset_less
=True)
59 yield from super().__iter
__()
60 yield from self
.core
.__iter
__(self
)
61 yield self
.divisor_neg
62 yield self
.dividend_neg
65 return self
.eq_without_core(rhs
) + self
.core
.eq(rhs
.core
)
67 def eq_without_core(self
, rhs
):
68 return super().eq(rhs
) + \
69 [self
.divisor_neg
.eq(rhs
.divisor_neg
),
70 self
.dividend_neg
.eq(rhs
.dividend_neg
),
71 self
.dive_abs_ov32
.eq(rhs
.dive_abs_ov32
),
72 self
.dive_abs_ov64
.eq(rhs
.dive_abs_ov64
),
73 self
.div_by_zero
.eq(rhs
.div_by_zero
)]
76 class CoreInputData(CoreBaseData
):
77 def __init__(self
, pspec
):
78 super().__init
__(pspec
, DivPipeCoreInputData
)
81 class CoreInterstageData(CoreBaseData
):
82 def __init__(self
, pspec
):
83 super().__init
__(pspec
, DivPipeCoreInterstageData
)
86 class CoreOutputData(CoreBaseData
):
87 def __init__(self
, pspec
):
88 super().__init
__(pspec
, DivPipeCoreOutputData
)