1 # SPDX-License-Identifier: LGPL-3-or-later
2 # Copyright 2022 Jacob Lifshay
4 from functools
import reduce
7 from nmigen
.hdl
.ast
import AnyConst
, Assert
, Signal
, Const
, Assume
8 from nmigen
.hdl
.dsl
import Module
9 from nmutil
.formaltest
import FHDLTestCase
10 from nmutil
.byterev
import byte_reverse
11 from nmutil
.grev
import grev
12 from nmutil
.sim_util
import write_il
15 VALID_BYTE_REVERSE_LENGTHS
= tuple(1 << i
for i
in range(4))
19 class TestByteReverse(FHDLTestCase
):
20 def tst(self
, log2_width
, rev_length
=None):
21 assert isinstance(log2_width
, int) and log2_width
>= LOG2_BYTE_SIZE
22 assert rev_length
is None or rev_length
in VALID_BYTE_REVERSE_LENGTHS
24 width
= 1 << log2_width
26 m
.d
.comb
+= inp
.eq(AnyConst(width
))
27 length_sig
= Signal(range(max(VALID_BYTE_REVERSE_LENGTHS
) + 1))
28 m
.d
.comb
+= length_sig
.eq(AnyConst(length_sig
.shape()))
30 if rev_length
is None:
31 rev_length
= length_sig
33 m
.d
.comb
+= Assume(length_sig
== rev_length
)
35 with m
.Switch(length_sig
):
36 for l
in VALID_BYTE_REVERSE_LENGTHS
:
38 m
.d
.comb
+= Assume(width
>= l
<< LOG2_BYTE_SIZE
)
40 m
.d
.comb
+= Assume(False)
42 out
= byte_reverse(m
, name
="out", data
=inp
, length
=rev_length
)
44 expected
= Signal(width
)
45 for log2_chunk_size
in range(LOG2_BYTE_SIZE
, log2_width
+ 1):
46 chunk_size
= 1 << log2_chunk_size
47 chunk_byte_size
= chunk_size
>> LOG2_BYTE_SIZE
48 chunk_sizes
= chunk_size
- 8
49 with m
.If(rev_length
== chunk_byte_size
):
50 m
.d
.comb
+= expected
.eq(grev(inp
, chunk_sizes
, log2_width
)
51 & ((1 << chunk_size
) - 1))
53 m
.d
.comb
+= Assert(expected
== out
)
57 def test_8_len_1(self
):
58 self
.tst(log2_width
=3, rev_length
=1)
61 self
.tst(log2_width
=3)
63 def test_16_len_1(self
):
64 self
.tst(log2_width
=4, rev_length
=1)
66 def test_16_len_2(self
):
67 self
.tst(log2_width
=4, rev_length
=2)
70 self
.tst(log2_width
=4)
72 def test_32_len_1(self
):
73 self
.tst(log2_width
=5, rev_length
=1)
75 def test_32_len_2(self
):
76 self
.tst(log2_width
=5, rev_length
=2)
78 def test_32_len_4(self
):
79 self
.tst(log2_width
=5, rev_length
=4)
82 self
.tst(log2_width
=5)
84 def test_64_len_1(self
):
85 self
.tst(log2_width
=6, rev_length
=1)
87 def test_64_len_2(self
):
88 self
.tst(log2_width
=6, rev_length
=2)
90 def test_64_len_4(self
):
91 self
.tst(log2_width
=6, rev_length
=4)
93 def test_64_len_8(self
):
94 self
.tst(log2_width
=6, rev_length
=8)
97 self
.tst(log2_width
=6)
99 def test_128_len_1(self
):
100 self
.tst(log2_width
=7, rev_length
=1)
102 def test_128_len_2(self
):
103 self
.tst(log2_width
=7, rev_length
=2)
105 def test_128_len_4(self
):
106 self
.tst(log2_width
=7, rev_length
=4)
108 def test_128_len_8(self
):
109 self
.tst(log2_width
=7, rev_length
=8)
112 self
.tst(log2_width
=7)
115 if __name__
== "__main__":