From 9cc04f05fff07d38c685614190007e107ee8b891 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Wed, 3 Feb 2021 21:23:22 +0000 Subject: [PATCH] add SVP64PowerDecoder, extracts svp64 remap if correctly identified --- src/soc/decoder/power_decoder.py | 1 + src/soc/decoder/power_decoder2.py | 51 +++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/src/soc/decoder/power_decoder.py b/src/soc/decoder/power_decoder.py index bdad81ba..81a80b8b 100644 --- a/src/soc/decoder/power_decoder.py +++ b/src/soc/decoder/power_decoder.py @@ -493,6 +493,7 @@ class TopPowerDecoder(PowerDecoder): def elaborate(self, platform): m = PowerDecoder.elaborate(self, platform) comb = m.d.comb + # sigh duplicated in SVP64PowerDecoder # raw opcode in assumed to be in LE order: byte-reverse it to get BE raw_le = self.raw_opcode_in l = [] diff --git a/src/soc/decoder/power_decoder2.py b/src/soc/decoder/power_decoder2.py index 72b0e246..2f6c0bde 100644 --- a/src/soc/decoder/power_decoder2.py +++ b/src/soc/decoder/power_decoder2.py @@ -1269,6 +1269,53 @@ class PowerDecode2(PowerDecodeSubset): comb += self.do_copy("cia", self.state.pc, True) # copy of PC "state" +# SVP64 Prefix fields: see https://libre-soc.org/openpower/sv/svp64/ +# identifies if an instruction is a SVP64-encoded prefix, and extracts +# the 24-bit SVP64 context (RM) if it is +class SVP64PowerDecoder(Elaboratable): + + def __init__(self): + self.opcode_in = Signal(32, reset_less=True) + self.raw_opcode_in = Signal.like(self.opcode_in, reset_less=True) + self.is_svp64_mode = Signal(1, reset_less=True) + self.svp64_rm = Signal(24, reset_less=True) + self.bigendian = Signal(reset_less=True) + + def elaborate(self, platform): + m = Module() + comb = m.d.comb + # sigh copied this from TopPowerDecoder + # raw opcode in assumed to be in LE order: byte-reverse it to get BE + raw_le = self.raw_opcode_in + l = [] + for i in range(0, 32, 8): + l.append(raw_le[i:i+8]) + l.reverse() + raw_be = Cat(*l) + comb += self.opcode_in.eq(Mux(self.bigendian, raw_be, raw_le)) + + # start identifying if the incoming opcode is SVP64 prefix) + major = Signal(6, reset_less=True) + + comb += major.eq(self.opcode_in[26:32]) + comb += self.is_svp64_mode.eq((major == Const(1, 6)) & # EXT01 + self.opcode_in[31-7] & # identifier + self.opcode_in[31-9]) # bits + + # now grab the 24-bit ReMap context bits, + rmfields = [6, 8] + list(range(10,32)) # SVP64 24-bit RM + l = [] + for idx in rmfields: + l.append(self.opcode_in[32-idx]) + with m.If(self.is_svp64_mode): + comb += self.svp64_rm.eq(Cat(*l)) + + return m + + def ports(self): + return [self.opcode_in, self.raw_opcode_in, self.is_svp64_mode, + self.svp64_rm, self.bigendian] + def get_rdflags(e, cu): rdl = [] for idx in range(cu.n_src): @@ -1280,6 +1327,10 @@ def get_rdflags(e, cu): if __name__ == '__main__': + svp64 = SVP64PowerDecoder() + vl = rtlil.convert(svp64, ports=svp64.ports()) + with open("svp64_dec.il", "w") as f: + f.write(vl) pdecode = create_pdecode() dec2 = PowerDecode2(pdecode) vl = rtlil.convert(dec2, ports=dec2.ports() + pdecode.ports()) -- 2.30.2