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