rename DIV->Div to be consistent
[soc.git] / src / soc / fu / div / pipe_data.py
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)
8
9
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
15 def __init__(self, pspec):
16 super().__init__(pspec, False)
17 # convenience
18 self.a, self.b = self.ra, self.rb
19
20
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')]
27
28 def __init__(self, pspec):
29 super().__init__(pspec, True)
30 # convenience
31 self.cr0 = self.cr_a
32
33
34 class DivPipeSpec(CommonPipeSpec):
35 regspec = (DivInputData.regspec, DivMulOutputData.regspec)
36 opsubsetkls = CompLogicalOpSubset
37 core_config = DivPipeCoreConfig(
38 bit_width=64,
39 fract_width=64,
40 log2_radix=1,
41 supported=[DP.UDivRem]
42 )
43
44
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)
52
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)
58
59 def __iter__(self):
60 yield from super().__iter__()
61 yield from self.core.__iter__(self)
62 yield self.divisor_neg
63 yield self.dividend_neg
64
65 def eq(self, rhs):
66 return self.eq_without_core(rhs) + self.core.eq(rhs.core)
67
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)]
75
76
77 class CoreInputData(CoreBaseData):
78 def __init__(self, pspec):
79 super().__init__(pspec, DivPipeCoreInputData)
80
81
82 class CoreInterstageData(CoreBaseData):
83 def __init__(self, pspec):
84 super().__init__(pspec, DivPipeCoreInterstageData)
85
86
87 class CoreOutputData(CoreBaseData):
88 def __init__(self, pspec):
89 super().__init__(pspec, DivPipeCoreOutputData)