1 from nmigen
import Module
, Signal
, Elaboratable
, Cat
, Repl
4 class CLZ(Elaboratable
):
5 def __init__(self
, width
):
7 self
.sig_in
= Signal(width
, reset_less
=True)
8 out_width
= math
.ceil(math
.log2(width
+1))
9 self
.lz
= Signal(out_width
)
11 def generate_pairs(self
, m
):
13 assert self
.width
% 2 == 0 # TODO handle odd widths
15 for i
in range(0, self
.width
, 2):
16 pair
= Signal(2, name
="pair%d" % i
)
17 comb
+= pair
.eq(self
.sig_in
[i
:i
+2])
19 pair_cnt
= Signal(2, name
="cnt_1_%d" % (i
/2))
22 comb
+= pair_cnt
.eq(2)
24 comb
+= pair_cnt
.eq(1)
26 comb
+= pair_cnt
.eq(0)
27 pairs
.append(pair_cnt
)
30 def combine_pairs(self
, m
, iteration
, pairs
):
33 assert length
% 2 == 0 # TODO handle non powers of 2
35 for i
in range(0, length
, 2):
38 width
= left
.width
+ 1
40 print(f
"pair({i}, {i+1}) - cnt_{iteration}_{i}")
41 new_pair
= Signal(left
.width
+ 1, name
="cnt_%d_%d" %
43 with m
.If(left
[-1] == 1):
44 with m
.If(right
[-1] == 1):
45 comb
+= new_pair
.eq(Cat(Repl(0, width
-1), 1))
47 comb
+= new_pair
.eq(Cat(right
[0:-1], 0b01))
49 comb
+= new_pair
.eq(Cat(left
, 0))
54 def elaborate(self
, platform
):
58 pairs
= self
.generate_pairs(m
)
61 pairs
= self
.combine_pairs(m
, i
, pairs
)
64 comb
+= self
.lz
.eq(pairs
[0])