move intermediates to separate module, use i/o data struct
[ieee754fpu.git] / src / nmutil / picker.py
1 """ Priority Picker: optimised back-to-back PriorityEncoder and Decoder
2
3 The input is N bits, the output is N bits wide and only one is
4 enabled.
5 """
6
7 from nmigen import Module, Signal, Cat, Elaboratable
8
9 class PriorityPicker(Elaboratable):
10 """ implements a priority-picker. input: N bits, output: N bits
11 """
12 def __init__(self, wid):
13 self.wid = wid
14 # inputs
15 self.i = Signal(wid, reset_less=True)
16 self.o = Signal(wid, reset_less=True)
17
18 def elaborate(self, platform):
19 m = Module()
20
21 res = []
22 ni = Signal(self.wid, reset_less = True)
23 m.d.comb += ni.eq(~self.i)
24 for i in range(0, self.wid):
25 t = Signal(reset_less = True)
26 res.append(t)
27 if i == 0:
28 m.d.comb += t.eq(self.i[i])
29 else:
30 m.d.comb += t.eq(~Cat(ni[i], *self.i[:i]).bool())
31
32 # we like Cat(*xxx). turn lists into concatenated bits
33 m.d.comb += self.o.eq(Cat(*res))
34
35 return m
36
37 def __iter__(self):
38 yield self.i
39 yield self.o
40
41 def ports(self):
42 return list(self)