1 # SPDX-License-Identifier: LGPL-3-or-later
2 # See Notices.txt for copyright information
4 from nmigen
.hdl
.ast
import AnyConst
, Assert
, Assume
, Signal
5 from nmigen
.hdl
.dsl
import Module
6 from ieee754
.partitioned_signal_tester
import (
7 SimdSignalTester
, Layout
, Lane
, formal
)
11 class TestFormal(unittest
.TestCase
):
12 def test_formal(self
):
16 m
.d
.comb
+= a
.eq(AnyConst(10))
17 m
.d
.comb
+= b
.eq(AnyConst(10))
18 m
.d
.comb
+= Assume(a
* b
== 1021 * 1019)
19 m
.d
.comb
+= Assert((a
== 1021) |
(a
== 1019))
22 @unittest.expectedFailure
23 def test_formal_fail(self
):
27 m
.d
.comb
+= a
.eq(AnyConst(10))
28 m
.d
.comb
+= b
.eq(AnyConst(10))
29 m
.d
.comb
+= Assume(a
* b
== 1021 * 1019)
30 m
.d
.comb
+= Assert(a
== 1021)
34 class TestLayout(unittest
.TestCase
):
38 self
.assertEqual(repr(Layout({3: False, 7: True}, 16)),
39 "Layout((0, 3, 7, 16), width=16)")
40 self
.assertEqual(repr(Layout({7: False, 3: True}, 16)),
41 "Layout((0, 3, 7, 16), width=16)")
42 self
.assertEqual(repr(Layout(range(0, 10, 2), 10)),
43 "Layout((0, 2, 4, 6, 8, 10), width=10)")
44 self
.assertEqual(repr(Layout(range(0, 10, 2))),
45 "Layout((0, 2, 4, 6, 8), width=8)")
46 self
.assertEqual(repr(Layout(())),
47 "Layout((0,), width=0)")
48 self
.assertEqual(repr(Layout((1,))),
49 "Layout((0, 1), width=1)")
52 a
= Layout
.cast((1, 2, 3))
53 self
.assertEqual(repr(a
),
54 "Layout((0, 1, 2, 3), width=3)")
58 def test_part_signal_count(self
):
61 c
= Layout
.cast((1, 3))
62 d
= Layout
.cast((0, 1, 3))
63 e
= Layout
.cast((1, 2, 3))
64 self
.assertEqual(a
.part_signal_count
, 0)
65 self
.assertEqual(b
.part_signal_count
, 0)
66 self
.assertEqual(c
.part_signal_count
, 1)
67 self
.assertEqual(d
.part_signal_count
, 1)
68 self
.assertEqual(e
.part_signal_count
, 2)
72 self
.assertEqual(list(a
.lanes()), [])
74 self
.assertEqual(list(b
.lanes()), [Lane(0, 1, b
)])
75 c
= Layout
.cast((1, 3))
76 self
.assertEqual(list(c
.lanes()),
80 d
= Layout
.cast((1, 4, 5))
81 self
.assertEqual(list(d
.lanes()),
88 e
= Layout(range(0, 32, 8), 32)
89 self
.assertEqual(list(e
.lanes()),
101 def test_is_compatible(self
):
103 b
= Layout
.cast((1,))
104 c
= Layout
.cast((1, 2))
105 d
= Layout
.cast((4, 5))
106 e
= Layout
.cast((1, 2, 3, 4))
107 f
= Layout
.cast((8, 16, 24, 32))
108 compatibility_classes
= {
116 for lhs
in compatibility_classes
:
117 for rhs
in compatibility_classes
:
118 with self
.subTest(lhs
=lhs
, rhs
=rhs
):
119 self
.assertEqual(compatibility_classes
[lhs
]
120 == compatibility_classes
[rhs
],
121 lhs
.is_compatible(rhs
))
123 def test_translate_lanes_to(self
):
124 src
= Layout((0, 3, 7, 12, 13))
125 dest
= Layout((0, 8, 16, 24, 32))
126 src_lanes
= list(src
.lanes())
127 src_lanes
.sort(key
=lambda lane
: lane
.start
)
128 dest_lanes
= list(dest
.lanes())
129 dest_lanes
.sort(key
=lambda lane
: lane
.start
)
130 self
.assertEqual(len(src_lanes
), len(dest_lanes
))
131 for src_lane
, dest_lane
in zip(src_lanes
, dest_lanes
):
132 with self
.subTest(src_lane
=src_lane
, dest_lane
=dest_lane
):
133 self
.assertEqual(src_lane
.translate_to(dest
), dest_lane
)
134 self
.assertEqual(dest_lane
.translate_to(src
), src_lane
)
137 class TestLane(unittest
.TestCase
):
138 def test_is_active(self
):
139 layout
= Layout((0, 8, 16, 24, 32))
140 def do_test(part_starts
, expected_lanes
):
141 with self
.subTest(part_starts
=part_starts
,
142 expected_lanes
=expected_lanes
):
143 for lane
in layout
.lanes():
144 expected
= (lane
.start
, lane
.size
) in expected_lanes
145 with self
.subTest(lane
=lane
):
146 self
.assertEqual(lane
.is_active(part_starts
),
151 do_test((_1
, _0
, _0
, _0
, _1
),
153 do_test((_1
, _0
, _0
, _1
, _1
),
155 do_test((_1
, _0
, _1
, _0
, _1
),
157 do_test((_1
, _0
, _1
, _1
, _1
),
158 {(0, 16), (16, 8), (24, 8)})
159 do_test((_1
, _1
, _0
, _0
, _1
),
161 do_test((_1
, _1
, _0
, _1
, _1
),
162 {(0, 8), (8, 16), (24, 8)})
163 do_test((_1
, _1
, _1
, _0
, _1
),
164 {(0, 8), (8, 8), (16, 16)})
165 do_test((_1
, _1
, _1
, _1
, _1
),
166 {(0, 8), (8, 8), (16, 8), (24, 8)})
168 def test_as_slice(self
):
169 slice_target
= tuple(range(8))
170 layout
= Layout((0, 2, 4, 6, 8))
171 slices
= list(slice_target
[lane
.as_slice()]
172 for lane
in layout
.lanes())
173 self
.assertEqual(slices
,
183 (0, 1, 2, 3, 4, 5, 6, 7)])
186 class TestSimdSignalTester(unittest
.TestCase
):
187 def test_sim_identity(self
):
190 lambda inputs
: inputs
[0],
191 lambda lane
, inputs
: inputs
[0],
192 (0, 8, 16, 24, 32)).run_sim(self
)
194 def test_formal_identity(self
):
197 lambda inputs
: inputs
[0],
198 lambda lane
, inputs
: inputs
[0],
199 (0, 8, 16, 24, 32)).run_formal(self
)
201 def test_sim_pass_through_input(self
):
202 for which_input
in range(0, 2):
205 lambda inputs
: inputs
[which_input
],
206 lambda lane
, inputs
: inputs
[which_input
],
208 (0, 1, 2, 3, 4)).run_sim(self
)
210 def test_formal_pass_through_input(self
):
211 for which_input
in range(0, 2):
214 lambda inputs
: inputs
[which_input
],
215 lambda lane
, inputs
: inputs
[which_input
],
217 (0, 1, 2, 3, 4)).run_formal(self
)
220 if __name__
== '__main__':