invert bits of field in decoder (not instruction bits)
[soc.git] / src / soc / decoder / power_fieldsn.py
1 from collections import OrderedDict
2 from soc.decoder.power_fields import DecodeFields, BitRange
3 from nmigen import Module, Elaboratable, Signal, Cat
4 from nmigen.cli import rtlil
5
6
7 class SignalBitRange(BitRange):
8 def __init__(self, signal):
9 BitRange.__init__(self)
10 self.signal = signal
11
12 def _rev(self, k):
13 width = self.signal.shape()[0]
14 return width-1-k
15
16 def __getitem__(self, subs):
17 # *sigh* field numberings are bit-inverted. PowerISA 3.0B section 1.3.2
18 print (dir(self))
19 print (self.items())
20 if isinstance(subs, slice):
21 res = []
22 print (subs)
23 start, stop, step = subs.start, subs.stop, subs.step
24 if step is None:
25 step = 1
26 if start is None:
27 start = 0
28 if stop is None:
29 stop = -1
30 if start < 0:
31 start = len(self) + start
32 if stop < 0:
33 stop = len(self) + stop
34 print ("range", start, stop, step)
35 for t in range(start, stop, step):
36 t = len(self) - 1 - t # invert field back
37 k = OrderedDict.__getitem__(self, t)
38 print ("t", t, k)
39 res.append(self.signal[self._rev(k)]) # reverse-order here
40 return Cat(*res)
41 else:
42 if subs < 0:
43 subs = len(self) + sub
44 subs = len(self) - 1 - subs # invert field back
45 k = OrderedDict.__getitem__(self, subs)
46 return self.signal[self._rev(k)] # reverse-order here
47
48 print ("translated", subs, translated)
49
50
51 class SigDecode(Elaboratable):
52
53 def __init__(self, width):
54 self.opcode_in = Signal(width, reset_less=False)
55 self.df = DecodeFields(SignalBitRange, [self.opcode_in])
56 self.df.create_specs()
57 self.x_s = Signal(len(self.df.FormX.S), reset_less=True)
58 self.x_sh = Signal(len(self.df.FormX.SH), reset_less=True)
59 self.dq_xs_s = Signal(len(self.df.FormDQ.SX_S), reset_less=True)
60
61 def elaborate(self, platform):
62 m = Module()
63 comb = m.d.comb
64 comb += self.x_s.eq(self.df.FormX.S[0])
65 comb += self.x_sh.eq(self.df.FormX.SH[0:-1])
66 comb += self.dq_xs_s.eq(self.df.FormDQ.SX_S[0:-1])
67 return m
68
69 def ports(self):
70 return [self.opcode_in, self.x_s, self.x_sh]
71
72 def create_sigdecode():
73 s = SigDecode(32)
74 return s
75
76 if __name__ == '__main__':
77 sigdecode = create_sigdecode()
78 vl = rtlil.convert(sigdecode, ports=sigdecode.ports())
79 with open("decoder.il", "w") as f:
80 f.write(vl)
81