rewrite test_clz.py to actually test both CLZ and clz.
[nmutil.git] / src / nmutil / test / test_clz.py
1 from nmigen.sim import Delay
2 from nmutil.clz import CLZ, clz
3 from nmutil.sim_util import do_sim
4 import unittest
5
6
7 def reference_clz(v, width):
8 assert isinstance(width, int) and 0 <= width
9 assert isinstance(v, int) and 0 <= v < 1 << width
10 msb = 1 << (width - 1)
11 retval = 0
12 while retval < width:
13 if v & msb:
14 break
15 v <<= 1
16 retval += 1
17 return retval
18
19
20 class TestCLZ(unittest.TestCase):
21 def tst(self, width):
22 assert isinstance(width, int) and 0 <= width
23 dut = CLZ(width)
24
25 def process():
26 for inp in range(1 << width):
27 expected = reference_clz(inp, width)
28 with self.subTest(inp=hex(inp), expected=expected):
29 yield dut.sig_in.eq(inp)
30 yield Delay(1e-6)
31 sim_lz = yield dut.lz
32 py_lz = clz(inp, width)
33 with self.subTest(sim_lz=sim_lz, py_lz=py_lz):
34 self.assertEqual(sim_lz, expected)
35 self.assertEqual(py_lz, expected)
36 with do_sim(self, dut, [dut.sig_in, dut.lz]) as sim:
37 sim.add_process(process)
38 sim.run()
39
40 def test_1(self):
41 self.tst(1)
42
43 def test_2(self):
44 self.tst(2)
45
46 def test_3(self):
47 self.tst(3)
48
49 def test_4(self):
50 self.tst(4)
51
52 def test_5(self):
53 self.tst(5)
54
55 def test_6(self):
56 self.tst(6)
57
58 def test_7(self):
59 self.tst(7)
60
61 def test_8(self):
62 self.tst(8)
63
64 def test_9(self):
65 self.tst(9)
66
67 def test_10(self):
68 self.tst(10)
69
70 def test_11(self):
71 self.tst(11)
72
73 def test_12(self):
74 self.tst(12)
75
76
77 if __name__ == "__main__":
78 unittest.main()