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.
6 https://libre-soc.org/openpower/sv/svp64/
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 |
19 from nmigen
import Record
, Elaboratable
, Module
, Signal
20 from soc
.decoder
.power_enums
import (SVP64RMMode
, Function
, SVPtype
,
21 SVP64PredMode
, SVP64sat
)
22 from soc
.consts
import EXTRA3
24 # in nMigen, Record begins at the LSB and fills upwards
25 class SVP64Rec(Record
):
26 def __init__(self
, name
=None):
27 Record
.__init
__(self
, layout
=[("mode" , 5),
33 ("mmode" , 1)], name
=name
)
36 return [self
.mmode
, self
.mask
, self
.elwidth
, self
.ewsrc
,
37 self
.extra
, self
.mode
]
42 00 str sz dz normal mode
43 01 inv CR-bit Rc=1: ffirst CR sel
44 01 inv els RC1 Rc=0: ffirst z/nonz
45 10 N sz els sat mode: N=0/1 u/s
46 11 inv CR-bit Rc=1: pred-result CR sel
47 11 inv els RC1 Rc=0: pred-result z/nonz
50 00 0 sz dz normal mode
52 01 inv CR-bit Rc=1: ffirst CR sel
53 01 inv sz RC1 Rc=0: ffirst z/nonz
54 10 N sz dz sat mode: N=0/1 u/s
55 11 inv CR-bit Rc=1: pred-result CR sel
56 11 inv sz RC1 Rc=0: pred-result z/nonz
59 00 0 sz dz normal mode
60 00 1 sz CRM reduce mode (mapreduce), SUBVL=1
61 00 1 SVM CRM subvector reduce mode, SUBVL>1
62 01 inv CR-bit Rc=1: ffirst CR sel
63 01 inv sz RC1 Rc=0: ffirst z/nonz
64 10 N sz dz sat mode: N=0/1 u/s
65 11 inv CR-bit Rc=1: pred-result CR sel
66 11 inv sz RC1 Rc=0: pred-result z/nonz
69 class SVP64RMMode(Elaboratable
):
70 def __init__(self
, name
=None):
71 self
.rm_in
= SVP64Rec(name
=name
)
72 self
.fn_in
= Signal(Function
) # LD/ST is different
73 self
.ptype_in
= Signal(SVPtype
)
76 # main mode (normal, reduce, saturate, ffirst, pred-result)
77 self
.mode
= Signal(SVP64RMMode
)
80 self
.predmode
= Signal(SVP64PredMode
)
81 self
.srcpred
= Signal(3) # source predicate
82 self
.dstpred
= Signal(3) # destination predicate
83 self
.pred_sz
= Signal(1) # predicate source zeroing
84 self
.pred_dz
= Signal(1) # predicate dest zeroing
86 self
.saturate
= Signal(SVP64sat
)
88 self
.cr_sel
= Signal(2)
90 self
.map_evm
= Signal(1)
91 self
.map_crm
= Signal(1)
93 def elaborate(self
, platform
):
97 # decode pieces of mode
100 comb
+= is_ldst
.eq(self
.fn_in
== Function
.LDST
)
101 comb
+= mode2
.eq(mode
[0:2])
102 with m
.Switch(mode2
):
103 with m
.Case(0): # needs further decoding (LDST no mapreduce)
105 comb
+= self
.mode
.eq(SVP64RMMode
.NORMAL
)
106 with m
.Elif(mode
[3] == 1):
107 comb
+= self
.mode
.eq(SVP64RMMode
.MAPREDUCE
)
109 comb
+= self
.mode
.eq(SVP64RMMode
.NORMAL
)
111 comb
+= self
.mode
.eq(SVP64RMMode
.FFIRST
) # fail-first
113 comb
+= self
.mode
.eq(SVP64RMMode
.SATURATE
) # saturate
115 comb
+= self
.mode
.eq(SVP64RMMode
.PREDRES
) # predicate result
117 # identify predicate mode
118 with m
.If(self
.rm_in
.mmode
== 1):
119 comb
+= self
.predmode
.eq(SVP64PredMode
.CR
) # CR Predicate
120 with m
.Elif(self
.srcpred
== 0):
121 comb
+= self
.predmode
.eq(SVP64PredMode
.ALWAYS
) # No predicate
123 comb
+= self
.predmode
.eq(SVP64PredMode
.INT
) # non-zero src: INT
125 # extract src/dest predicate. use EXTRA3.MASK because EXTRA2.MASK
126 # is in exactly the same bits
127 srcmask
= sel(m
, self
.rm_in
.extra
, EXTRA3
.MASK
)
128 dstmask
= self
.rm_in
.mask
129 with m
.If(self
.ptype_in
== SVPtype
.P2
):
130 comb
+= self
.srcpred
.eq(srcmask
)
131 comb
+= self
.dstpred
.eq(dstmask
)
133 # TODO: detect zeroing mode, saturation mode, a few more.