84ba740a6a0b02888416b32e7ae13624609b72c1
[nmutil.git] / src / nmutil / byterev.py
1 """
2 This work is funded through NLnet under Grant 2019-02-012
3
4 License: LGPLv3+
5 """
6
7 from nmigen import Signal, Cat
8
9 # TODO: turn this into a module?
10
11
12 def byte_reverse(m, name, data, length):
13 """byte_reverse: unlike nmigen word_select this takes a dynamic length
14
15 nmigen Signal.word_select may only take a fixed length. we need
16 bigendian byte-reverse, half-word reverse, word and dword reverse.
17 """
18 comb = m.d.comb
19 data_r = Signal.like(data, name=name)
20
21 # if length is a static integer, we do not require a Case statement
22 if isinstance(length, int):
23 j = length
24 rev = []
25 for i in range(j):
26 dest = data_r.word_select(i, 8)
27 rev.append(data.word_select(j-1-i, 8))
28 comb += data_r.eq(Cat(*rev))
29 return data_r
30
31 # Switch statement needed: dynamic length had better be = 1,2,4 or 8
32 with m.Switch(length):
33 for j in [1, 2, 4, 8]:
34 with m.Case(j):
35 rev = []
36 for i in range(j):
37 rev.append(data.word_select(j-1-i, 8))
38 comb += data_r.eq(Cat(*rev))
39 return data_r