import migen in litex/gen
[litex.git] / litex / gen / migen / genlib / coding.py
1 """
2 Encoders and decoders between binary and one-hot representation
3 """
4
5 from migen.fhdl.structure import *
6 from migen.fhdl.module import Module
7
8
9 class Encoder(Module):
10 """Encode one-hot to binary
11
12 If `n` is low, the `o` th bit in `i` is asserted, else none or
13 multiple bits are asserted.
14
15 Parameters
16 ----------
17 width : int
18 Bit width of the input
19
20 Attributes
21 ----------
22 i : Signal(width), in
23 One-hot input
24 o : Signal(max=width), out
25 Encoded binary
26 n : Signal(1), out
27 Invalid, either none or multiple input bits are asserted
28 """
29 def __init__(self, width):
30 self.i = Signal(width) # one-hot
31 self.o = Signal(max=max(2, width)) # binary
32 self.n = Signal() # invalid: none or multiple
33 act = dict((1<<j, self.o.eq(j)) for j in range(width))
34 act["default"] = self.n.eq(1)
35 self.comb += Case(self.i, act)
36
37
38 class PriorityEncoder(Module):
39 """Priority encode requests to binary
40
41 If `n` is low, the `o` th bit in `i` is asserted and the bits below
42 `o` are unasserted, else `o == 0`. The LSB has priority.
43
44 Parameters
45 ----------
46 width : int
47 Bit width of the input
48
49 Attributes
50 ----------
51 i : Signal(width), in
52 Input requests
53 o : Signal(max=width), out
54 Encoded binary
55 n : Signal(1), out
56 Invalid, no input bits are asserted
57 """
58 def __init__(self, width):
59 self.i = Signal(width) # one-hot, lsb has priority
60 self.o = Signal(max=max(2, width)) # binary
61 self.n = Signal() # none
62 for j in range(width)[::-1]: # last has priority
63 self.comb += If(self.i[j], self.o.eq(j))
64 self.comb += self.n.eq(self.i == 0)
65
66
67 class Decoder(Module):
68 """Decode binary to one-hot
69
70 If `n` is low, the `i` th bit in `o` is asserted, the others are
71 not, else `o == 0`.
72
73 Parameters
74 ----------
75 width : int
76 Bit width of the output
77
78 Attributes
79 ----------
80 i : Signal(max=width), in
81 Input binary
82 o : Signal(width), out
83 Decoded one-hot
84 n : Signal(1), in
85 Invalid, no output bits are to be asserted
86 """
87
88 def __init__(self, width):
89 self.i = Signal(max=max(2, width)) # binary
90 self.n = Signal() # none/invalid
91 self.o = Signal(width) # one-hot
92 act = dict((j, self.o.eq(1<<j)) for j in range(width))
93 self.comb += Case(self.i, act)
94 self.comb += If(self.n, self.o.eq(0))
95
96
97 class PriorityDecoder(Decoder):
98 pass # same