1 # SPDX-License-Identifier: LGPL-3-or-later
2 # Copyright 2022 Jacob Lifshay
4 # Funded by NLnet Assure Programme 2021-02-052, https://nlnet.nl/assure part
5 # of Horizon 2020 EU Programme 957073.
8 from nmigen
.hdl
.ast
import (AnyConst
, Assert
, Signal
, Const
, unsigned
, Cat
)
9 from nmigen
.hdl
.dsl
import Module
10 from nmutil
.formaltest
import FHDLTestCase
11 from nmigen_gf
.hdl
.cldivrem
import (equal_leading_zero_count_reference
,
12 EqualLeadingZeroCount
)
13 from nmigen
.sim
import Delay
14 from nmutil
.sim_util
import do_sim
, hash_256
17 class TestEqualLeadingZeroCount(FHDLTestCase
):
18 def tst(self
, width
, full
):
19 dut
= EqualLeadingZeroCount(width
)
20 self
.assertEqual(dut
.a
.shape(), unsigned(width
))
21 self
.assertEqual(dut
.b
.shape(), unsigned(width
))
22 self
.assertEqual(dut
.out
.shape(), unsigned(1))
25 assert isinstance(a
, int)
26 assert isinstance(b
, int)
27 expected
= a
.bit_length() == b
.bit_length()
28 with self
.subTest(a
=hex(a
), b
=hex(b
),
30 reference
= equal_leading_zero_count_reference(a
, b
, width
)
31 with self
.subTest(reference
=reference
):
32 self
.assertEqual(expected
, reference
)
34 with self
.subTest(a
=hex(a
), b
=hex(b
),
40 with self
.subTest(out
=out
):
41 self
.assertEqual(expected
, out
)
45 for a
in range(1 << width
):
46 for b
in range(1 << width
):
50 a
= hash_256(f
"eqlzc input a {i}")
51 a
= Const
.normalize(a
, dut
.a
.shape())
52 b
= hash_256(f
"eqlzc input b {i}")
53 b
= Const
.normalize(b
, dut
.b
.shape())
56 with
do_sim(self
, dut
, [dut
.a
, dut
.b
, dut
.out
]) as sim
:
57 sim
.add_process(process
)
60 def tst_formal(self
, width
):
61 dut
= EqualLeadingZeroCount(width
)
63 m
.submodules
.dut
= dut
64 m
.d
.comb
+= dut
.a
.eq(AnyConst(width
))
65 m
.d
.comb
+= dut
.b
.eq(AnyConst(width
))
67 with m
.Switch(Cat(dut
.a
, dut
.b
)):
68 with m
.Case('0' * (2 * width
)):
69 # `width` leading zeros
70 m
.d
.comb
+= expected
.eq(1)
71 for i
in range(width
):
73 pattern
= '0' * i
+ '1' + '-' * (width
- i
- 1)
74 with m
.Case(pattern
* 2):
75 m
.d
.comb
+= expected
.eq(1)
77 m
.d
.comb
+= expected
.eq(0)
78 m
.d
.comb
+= Assert(dut
.out
== expected
)
82 self
.tst(64, full
=False)
85 self
.tst(8, full
=False)
88 self
.tst(3, full
=True)
90 def test_formal_16(self
):
91 # yosys crashes with 32 or 64
92 # https://github.com/YosysHQ/yosys/issues/3268
95 def test_formal_8(self
):
98 def test_formal_3(self
):
101 # TODO: add TestCLDivRem
104 if __name__
== "__main__":