radix: reading first page table entry
[soc.git] / src / soc / decoder / power_svp64_prefix.py
1 """SVP64 Prefix Decoder
2
3 """
4
5 from nmigen import Module, Elaboratable, Signal, Mux, Const, Cat
6 from nmigen.cli import rtlil
7 from nmutil.util import sel
8
9 from soc.consts import SVP64P
10
11 # SVP64 Prefix fields: see https://libre-soc.org/openpower/sv/svp64/
12 # identifies if an instruction is a SVP64-encoded prefix, and extracts
13 # the 24-bit SVP64 context (RM) if it is
14 class SVP64PrefixDecoder(Elaboratable):
15
16 def __init__(self):
17 self.opcode_in = Signal(32, reset_less=True)
18 self.raw_opcode_in = Signal.like(self.opcode_in, reset_less=True)
19 self.is_svp64_mode = Signal(1, reset_less=True)
20 self.svp64_rm = Signal(24, reset_less=True)
21 self.bigendian = Signal(reset_less=True)
22
23 def elaborate(self, platform):
24 m = Module()
25 opcode_in = self.opcode_in
26 comb = m.d.comb
27 # sigh copied this from TopPowerDecoder
28 # raw opcode in assumed to be in LE order: byte-reverse it to get BE
29 raw_le = self.raw_opcode_in
30 l = []
31 for i in range(0, 32, 8):
32 l.append(raw_le[i:i+8])
33 l.reverse()
34 raw_be = Cat(*l)
35 comb += opcode_in.eq(Mux(self.bigendian, raw_be, raw_le))
36
37 # start identifying if the incoming opcode is SVP64 prefix)
38 major = sel(m, opcode_in, SVP64P.OPC)
39 ident = sel(m, opcode_in, SVP64P.SVP64_7_9)
40
41 comb += self.is_svp64_mode.eq(
42 (major == Const(1, 6)) & # EXT01
43 (ident == Const(0b11, 2)) # identifier bits
44 )
45
46 with m.If(self.is_svp64_mode):
47 # now grab the 24-bit ReMap context bits,
48 rm = sel(m, opcode_in, SVP64P.RM)
49 comb += self.svp64_rm.eq(rm)
50
51 return m
52
53 def ports(self):
54 return [self.opcode_in, self.raw_opcode_in, self.is_svp64_mode,
55 self.svp64_rm, self.bigendian]
56
57
58 if __name__ == '__main__':
59 svp64 = SVP64PrefixDecoder()
60 vl = rtlil.convert(svp64, ports=svp64.ports())
61 with open("svp64_prefix_dec.il", "w") as f:
62 f.write(vl)