+# 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 SVP64PrefixDecoder(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]
+