From c8b65df880664006abef59a7ecf36cc9a06a0c9c Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Mon, 1 Mar 2021 15:40:31 +0000 Subject: [PATCH] move SVP64 RM decoder to separate module --- src/soc/decoder/power_svp64_rm.py | 124 ++++++++++++++++++++++++++++++ src/soc/sv/svp64.py | 103 +------------------------ 2 files changed, 125 insertions(+), 102 deletions(-) create mode 100644 src/soc/decoder/power_svp64_rm.py diff --git a/src/soc/decoder/power_svp64_rm.py b/src/soc/decoder/power_svp64_rm.py new file mode 100644 index 00000000..d98c16ef --- /dev/null +++ b/src/soc/decoder/power_svp64_rm.py @@ -0,0 +1,124 @@ +# SPDX-License-Identifier: LGPLv3+ +# Copyright (C) 2021 Luke Kenneth Casson Leighton +# Funded by NLnet http://nlnet.nl +"""SVP64 RM (Remap) Record. + +https://libre-soc.org/openpower/sv/svp64/ + +| Field Name | Field bits | Description | +|-------------|------------|----------------------------------------| +| MASKMODE | `0` | Execution (predication) Mask Kind | +| MASK | `1:3` | Execution Mask | +| ELWIDTH | `4:5` | Element Width | +| ELWIDTH_SRC | `6:7` | Element Width for Source | +| SUBVL | `8:9` | Sub-vector length | +| EXTRA | `10:18` | context-dependent extra | +| MODE | `19:23` | changes Vector behaviour | +""" + +from nmigen import Elaboratable, Module, Signal +from soc.decoder.power_enums import (SVP64RMMode, Function, SVPtype, + SVP64PredMode, SVP64sat) +from soc.consts import EXTRA3 +from soc.svp64 import SVP64Rec +from nmutil.util import sel + + +"""RM Mode + +LD/ST immed: +00 str sz dz normal mode +01 inv CR-bit Rc=1: ffirst CR sel +01 inv els RC1 Rc=0: ffirst z/nonz +10 N sz els sat mode: N=0/1 u/s +11 inv CR-bit Rc=1: pred-result CR sel +11 inv els RC1 Rc=0: pred-result z/nonz + +LD/ST indexed: +00 0 sz dz normal mode +00 rsv rsvd reserved +01 inv CR-bit Rc=1: ffirst CR sel +01 inv sz RC1 Rc=0: ffirst z/nonz +10 N sz dz sat mode: N=0/1 u/s +11 inv CR-bit Rc=1: pred-result CR sel +11 inv sz RC1 Rc=0: pred-result z/nonz + +Arithmetic: +00 0 sz dz normal mode +00 1 sz CRM reduce mode (mapreduce), SUBVL=1 +00 1 SVM CRM subvector reduce mode, SUBVL>1 +01 inv CR-bit Rc=1: ffirst CR sel +01 inv sz RC1 Rc=0: ffirst z/nonz +10 N sz dz sat mode: N=0/1 u/s +11 inv CR-bit Rc=1: pred-result CR sel +11 inv sz RC1 Rc=0: pred-result z/nonz +""" + +class SVP64RMMode(Elaboratable): + def __init__(self, name=None): + self.rm_in = SVP64Rec(name=name) + self.fn_in = Signal(Function) # LD/ST is different + self.ptype_in = Signal(SVPtype) + self.rc_in = Signal() + + # main mode (normal, reduce, saturate, ffirst, pred-result) + self.mode = Signal(SVP64RMMode) + + # predication + self.predmode = Signal(SVP64PredMode) + self.srcpred = Signal(3) # source predicate + self.dstpred = Signal(3) # destination predicate + self.pred_sz = Signal(1) # predicate source zeroing + self.pred_dz = Signal(1) # predicate dest zeroing + + self.saturate = Signal(SVP64sat) + self.RC1 = Signal() + self.cr_sel = Signal(2) + self.inv = Signal(1) + self.map_evm = Signal(1) + self.map_crm = Signal(1) + + def elaborate(self, platform): + m = Module() + comb = m.d.comb + + # decode pieces of mode + is_ldst = Signal() + mode2 = Signal(2) + comb += is_ldst.eq(self.fn_in == Function.LDST) + comb += mode2.eq(mode[0:2]) + with m.Switch(mode2): + with m.Case(0): # needs further decoding (LDST no mapreduce) + with m.If(is_ldst): + comb += self.mode.eq(SVP64RMMode.NORMAL) + with m.Elif(mode[3] == 1): + comb += self.mode.eq(SVP64RMMode.MAPREDUCE) + with m.Else(): + comb += self.mode.eq(SVP64RMMode.NORMAL) + with m.Case(1): + comb += self.mode.eq(SVP64RMMode.FFIRST) # fail-first + with m.Case(2): + comb += self.mode.eq(SVP64RMMode.SATURATE) # saturate + with m.Case(3): + comb += self.mode.eq(SVP64RMMode.PREDRES) # predicate result + + # identify predicate mode + with m.If(self.rm_in.mmode == 1): + comb += self.predmode.eq(SVP64PredMode.CR) # CR Predicate + with m.Elif(self.srcpred == 0): + comb += self.predmode.eq(SVP64PredMode.ALWAYS) # No predicate + with m.Else(): + comb += self.predmode.eq(SVP64PredMode.INT) # non-zero src: INT + + # extract src/dest predicate. use EXTRA3.MASK because EXTRA2.MASK + # is in exactly the same bits + srcmask = sel(m, self.rm_in.extra, EXTRA3.MASK) + dstmask = self.rm_in.mask + with m.If(self.ptype_in == SVPtype.P2): + comb += self.srcpred.eq(srcmask) + comb += self.dstpred.eq(dstmask) + + # TODO: detect zeroing mode, saturation mode, a few more. + + return m + diff --git a/src/soc/sv/svp64.py b/src/soc/sv/svp64.py index bbe03a60..b57ce780 100644 --- a/src/soc/sv/svp64.py +++ b/src/soc/sv/svp64.py @@ -16,10 +16,7 @@ https://libre-soc.org/openpower/sv/svp64/ | MODE | `19:23` | changes Vector behaviour | """ -from nmigen import Record, Elaboratable, Module, Signal -from soc.decoder.power_enums import (SVP64RMMode, Function, SVPtype, - SVP64PredMode, SVP64sat) -from soc.consts import EXTRA3 +from nmigen import Record # in nMigen, Record begins at the LSB and fills upwards class SVP64Rec(Record): @@ -36,101 +33,3 @@ class SVP64Rec(Record): return [self.mmode, self.mask, self.elwidth, self.ewsrc, self.extra, self.mode] -"""RM Mode - -LD/ST immed: -00 str sz dz normal mode -01 inv CR-bit Rc=1: ffirst CR sel -01 inv els RC1 Rc=0: ffirst z/nonz -10 N sz els sat mode: N=0/1 u/s -11 inv CR-bit Rc=1: pred-result CR sel -11 inv els RC1 Rc=0: pred-result z/nonz - -LD/ST indexed: -00 0 sz dz normal mode -00 rsv rsvd reserved -01 inv CR-bit Rc=1: ffirst CR sel -01 inv sz RC1 Rc=0: ffirst z/nonz -10 N sz dz sat mode: N=0/1 u/s -11 inv CR-bit Rc=1: pred-result CR sel -11 inv sz RC1 Rc=0: pred-result z/nonz - -Arithmetic: -00 0 sz dz normal mode -00 1 sz CRM reduce mode (mapreduce), SUBVL=1 -00 1 SVM CRM subvector reduce mode, SUBVL>1 -01 inv CR-bit Rc=1: ffirst CR sel -01 inv sz RC1 Rc=0: ffirst z/nonz -10 N sz dz sat mode: N=0/1 u/s -11 inv CR-bit Rc=1: pred-result CR sel -11 inv sz RC1 Rc=0: pred-result z/nonz -""" - -class SVP64RMMode(Elaboratable): - def __init__(self, name=None): - self.rm_in = SVP64Rec(name=name) - self.fn_in = Signal(Function) # LD/ST is different - self.ptype_in = Signal(SVPtype) - self.rc_in = Signal() - - # main mode (normal, reduce, saturate, ffirst, pred-result) - self.mode = Signal(SVP64RMMode) - - # predication - self.predmode = Signal(SVP64PredMode) - self.srcpred = Signal(3) # source predicate - self.dstpred = Signal(3) # destination predicate - self.pred_sz = Signal(1) # predicate source zeroing - self.pred_dz = Signal(1) # predicate dest zeroing - - self.saturate = Signal(SVP64sat) - self.RC1 = Signal() - self.cr_sel = Signal(2) - self.inv = Signal(1) - self.map_evm = Signal(1) - self.map_crm = Signal(1) - - def elaborate(self, platform): - m = Module() - comb = m.d.comb - - # decode pieces of mode - is_ldst = Signal() - mode2 = Signal(2) - comb += is_ldst.eq(self.fn_in == Function.LDST) - comb += mode2.eq(mode[0:2]) - with m.Switch(mode2): - with m.Case(0): # needs further decoding (LDST no mapreduce) - with m.If(is_ldst): - comb += self.mode.eq(SVP64RMMode.NORMAL) - with m.Elif(mode[3] == 1): - comb += self.mode.eq(SVP64RMMode.MAPREDUCE) - with m.Else(): - comb += self.mode.eq(SVP64RMMode.NORMAL) - with m.Case(1): - comb += self.mode.eq(SVP64RMMode.FFIRST) # fail-first - with m.Case(2): - comb += self.mode.eq(SVP64RMMode.SATURATE) # saturate - with m.Case(3): - comb += self.mode.eq(SVP64RMMode.PREDRES) # predicate result - - # identify predicate mode - with m.If(self.rm_in.mmode == 1): - comb += self.predmode.eq(SVP64PredMode.CR) # CR Predicate - with m.Elif(self.srcpred == 0): - comb += self.predmode.eq(SVP64PredMode.ALWAYS) # No predicate - with m.Else(): - comb += self.predmode.eq(SVP64PredMode.INT) # non-zero src: INT - - # extract src/dest predicate. use EXTRA3.MASK because EXTRA2.MASK - # is in exactly the same bits - srcmask = sel(m, self.rm_in.extra, EXTRA3.MASK) - dstmask = self.rm_in.mask - with m.If(self.ptype_in == SVPtype.P2): - comb += self.srcpred.eq(srcmask) - comb += self.dstpred.eq(dstmask) - - # TODO: detect zeroing mode, saturation mode, a few more. - - return m - -- 2.30.2