genlib/coding.py: binary vs. one-hot, priority coding
authorRobert Jördens <jordens@gmail.com>
Thu, 27 Jun 2013 18:56:57 +0000 (12:56 -0600)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Fri, 28 Jun 2013 13:20:01 +0000 (15:20 +0200)
migen/genlib/coding.py [new file with mode: 0644]

diff --git a/migen/genlib/coding.py b/migen/genlib/coding.py
new file mode 100644 (file)
index 0000000..559dab0
--- /dev/null
@@ -0,0 +1,55 @@
+from migen.fhdl.std import *
+
+"""
+Encoders and decoders between binary and one-hot representation
+
+i: input (binary or one-hot)
+o: output (one-hot or binary)
+n: "none" signal (in/out), binary value is invalid
+"""
+
+class Encoder(Module):
+       def __init__(self, width):
+               self.i = Signal(width) # one-hot
+               self.o = Signal(max=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):
+       def __init__(self, width):
+               self.i = Signal(width) # one-hot, lsb has priority
+               self.o = Signal(max=width) # binary
+               self.n = Signal() # none
+               act = If(0)
+               for j in range(width):
+                       act = act.Elif(self.i[j], self.o.eq(j))
+               self.comb += act
+               self.comb += self.n.eq(self.i == 0)
+
+class Decoder(Module):
+       def __init__(self, width):
+               self.i = Signal(max=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
+
+def _main():
+       from migen.sim.generic import Simulator, TopLevel
+       from migen.fhdl import verilog
+
+       e = Encoder(8)
+       print(verilog.convert(e, ios={e.i, e.o, e.n}))
+       pe = PriorityEncoder(8)
+       print(verilog.convert(pe, ios={pe.i, pe.o, pe.n}))
+       d = Decoder(8)
+       print(verilog.convert(d, ios={d.i, d.n, d.o}))
+
+if __name__ == "__main__":
+       _main()