94 lines
2.2 KiB
Python
94 lines
2.2 KiB
Python
from migen.fhdl.std import *
|
|
|
|
"""
|
|
Encoders and decoders between binary and one-hot representation
|
|
"""
|
|
|
|
class Encoder(Module):
|
|
"""Encode one-hot to binary
|
|
|
|
If `n` is low, the `o` th bit in `i` is asserted, else none or
|
|
multiple bits are asserted.
|
|
|
|
Parameters
|
|
----------
|
|
width : int
|
|
Bit width of the input
|
|
|
|
Attributes
|
|
----------
|
|
i : Signal(width), in
|
|
One-hot input
|
|
o : Signal(max=width), out
|
|
Encoded binary
|
|
n : Signal(1), out
|
|
Invalid, either none or multiple input bits are asserted
|
|
"""
|
|
def __init__(self, width):
|
|
self.i = Signal(width) # one-hot
|
|
self.o = Signal(max=max(2, width)) # binary
|
|
self.n = Signal() # invalid: none or multiple
|
|
act = dict((1<<j, self.o.eq(j)) for j in range(width))
|
|
act["default"] = self.n.eq(1)
|
|
self.comb += Case(self.i, act)
|
|
|
|
class PriorityEncoder(Module):
|
|
"""Priority encode requests to binary
|
|
|
|
If `n` is low, the `o` th bit in `i` is asserted and the bits below
|
|
`o` are unasserted, else `o == 0`. The LSB has priority.
|
|
|
|
Parameters
|
|
----------
|
|
width : int
|
|
Bit width of the input
|
|
|
|
Attributes
|
|
----------
|
|
i : Signal(width), in
|
|
Input requests
|
|
o : Signal(max=width), out
|
|
Encoded binary
|
|
n : Signal(1), out
|
|
Invalid, no input bits are asserted
|
|
"""
|
|
def __init__(self, width):
|
|
self.i = Signal(width) # one-hot, lsb has priority
|
|
self.o = Signal(max=max(2, width)) # binary
|
|
self.n = Signal() # none
|
|
for j in range(width)[::-1]: # last has priority
|
|
self.comb += If(self.i[j], self.o.eq(j))
|
|
self.comb += self.n.eq(self.i == 0)
|
|
|
|
class Decoder(Module):
|
|
"""Decode binary to one-hot
|
|
|
|
If `n` is low, the `i` th bit in `o` is asserted, the others are
|
|
not, else `o == 0`.
|
|
|
|
Parameters
|
|
----------
|
|
width : int
|
|
Bit width of the output
|
|
|
|
Attributes
|
|
----------
|
|
i : Signal(max=width), in
|
|
Input binary
|
|
o : Signal(width), out
|
|
Decoded one-hot
|
|
n : Signal(1), in
|
|
Invalid, no output bits are to be asserted
|
|
"""
|
|
|
|
def __init__(self, width):
|
|
self.i = Signal(max=max(2, width)) # binary
|
|
self.n = Signal() # none/invalid
|
|
self.o = Signal(width) # one-hot
|
|
act = dict((j, self.o.eq(1<<j)) for j in range(width))
|
|
self.comb += Case(self.i, act)
|
|
self.comb += If(self.n, self.o.eq(0))
|
|
|
|
class PriorityDecoder(Decoder):
|
|
pass # same
|