cleanup raduxmmu._walk_tree
[soc.git] / src / soc / decoder / power_svp64_rm.py
1 # SPDX-License-Identifier: LGPLv3+
2 # Copyright (C) 2021 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
3 # Funded by NLnet http://nlnet.nl
4 """SVP64 RM (Remap) Record.
5
6 https://libre-soc.org/openpower/sv/svp64/
7
8 | Field Name | Field bits | Description |
9 |-------------|------------|----------------------------------------|
10 | MASKMODE | `0` | Execution (predication) Mask Kind |
11 | MASK | `1:3` | Execution Mask |
12 | ELWIDTH | `4:5` | Element Width |
13 | ELWIDTH_SRC | `6:7` | Element Width for Source |
14 | SUBVL | `8:9` | Sub-vector length |
15 | EXTRA | `10:18` | context-dependent extra |
16 | MODE | `19:23` | changes Vector behaviour |
17 """
18
19 from nmigen import Elaboratable, Module, Signal
20 from soc.decoder.power_enums import (SVP64RMMode, Function, SVPtype,
21 SVP64PredMode, SVP64sat)
22 from soc.consts import EXTRA3, SVP64MODE
23 from soc.sv.svp64 import SVP64Rec
24 from nmutil.util import sel
25
26
27 """RM Mode
28
29 LD/ST immed:
30 00 str sz dz normal mode
31 01 inv CR-bit Rc=1: ffirst CR sel
32 01 inv els RC1 Rc=0: ffirst z/nonz
33 10 N sz els sat mode: N=0/1 u/s
34 11 inv CR-bit Rc=1: pred-result CR sel
35 11 inv els RC1 Rc=0: pred-result z/nonz
36
37 LD/ST indexed:
38 00 0 sz dz normal mode
39 00 rsv rsvd reserved
40 01 inv CR-bit Rc=1: ffirst CR sel
41 01 inv sz RC1 Rc=0: ffirst z/nonz
42 10 N sz dz sat mode: N=0/1 u/s
43 11 inv CR-bit Rc=1: pred-result CR sel
44 11 inv sz RC1 Rc=0: pred-result z/nonz
45
46 Arithmetic:
47 00 0 sz dz normal mode
48 00 1 sz CRM reduce mode (mapreduce), SUBVL=1
49 00 1 SVM CRM subvector reduce mode, SUBVL>1
50 01 inv CR-bit Rc=1: ffirst CR sel
51 01 inv sz RC1 Rc=0: ffirst z/nonz
52 10 N sz dz sat mode: N=0/1 u/s
53 11 inv CR-bit Rc=1: pred-result CR sel
54 11 inv sz RC1 Rc=0: pred-result z/nonz
55 """
56
57 class SVP64RMModeDecode(Elaboratable):
58 def __init__(self, name=None):
59 self.rm_in = SVP64Rec(name=name)
60 self.fn_in = Signal(Function) # LD/ST is different
61 self.ptype_in = Signal(SVPtype)
62 self.rc_in = Signal()
63
64 # main mode (normal, reduce, saturate, ffirst, pred-result)
65 self.mode = Signal(SVP64RMMode)
66
67 # predication
68 self.predmode = Signal(SVP64PredMode)
69 self.srcpred = Signal(3) # source predicate
70 self.dstpred = Signal(3) # destination predicate
71 self.pred_sz = Signal(1) # predicate source zeroing
72 self.pred_dz = Signal(1) # predicate dest zeroing
73
74 self.saturate = Signal(SVP64sat)
75 self.RC1 = Signal()
76 self.cr_sel = Signal(2)
77 self.inv = Signal(1)
78 self.map_evm = Signal(1)
79 self.map_crm = Signal(1)
80
81 def elaborate(self, platform):
82 m = Module()
83 comb = m.d.comb
84 mode = self.rm_in.mode
85
86 # decode pieces of mode
87 is_ldst = Signal()
88 comb += is_ldst.eq(self.fn_in == Function.LDST)
89 mode2 = sel(m, mode, SVP64MODE.MOD2)
90 with m.Switch(mode2):
91 with m.Case(0): # needs further decoding (LDST no mapreduce)
92 with m.If(is_ldst):
93 comb += self.mode.eq(SVP64RMMode.NORMAL)
94 with m.Elif(mode[SVP64MODE.REDUCE]):
95 comb += self.mode.eq(SVP64RMMode.MAPREDUCE)
96 with m.Else():
97 comb += self.mode.eq(SVP64RMMode.NORMAL)
98 with m.Case(1):
99 comb += self.mode.eq(SVP64RMMode.FFIRST) # fail-first
100 with m.Case(2):
101 comb += self.mode.eq(SVP64RMMode.SATURATE) # saturate
102 with m.Case(3):
103 comb += self.mode.eq(SVP64RMMode.PREDRES) # predicate result
104
105 # extract src/dest predicate. use EXTRA3.MASK because EXTRA2.MASK
106 # is in exactly the same bits
107 srcmask = sel(m, self.rm_in.extra, EXTRA3.MASK)
108 dstmask = self.rm_in.mask
109 with m.If(self.ptype_in == SVPtype.P2):
110 comb += self.srcpred.eq(srcmask)
111 with m.Else():
112 comb += self.srcpred.eq(dstmask)
113 comb += self.dstpred.eq(dstmask)
114
115 # identify predicate mode
116 with m.If(self.rm_in.mmode == 1):
117 comb += self.predmode.eq(SVP64PredMode.CR) # CR Predicate
118 with m.Elif(self.srcpred == 0):
119 comb += self.predmode.eq(SVP64PredMode.ALWAYS) # No predicate
120 with m.Else():
121 comb += self.predmode.eq(SVP64PredMode.INT) # non-zero src: INT
122
123 # TODO: detect zeroing mode, saturation mode, a few more.
124
125 return m
126