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