Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

framebuffer/dvi: TMDS encoder test bench

  • Loading branch information...
commit 20b758d52fd39db4d5bca33570ccfdd8f840f9e2 1 parent 78587d1
@sbourdeauducq sbourdeauducq authored
Showing with 74 additions and 16 deletions.
  1. +74 −16 milkymist/framebuffer/dvi.py
View
90 milkymist/framebuffer/dvi.py
@@ -9,7 +9,7 @@ def __init__(self):
self.c = Signal(2)
self.de = Signal()
- self.output = Signal(10)
+ self.out = Signal(10)
###
@@ -44,7 +44,7 @@ def __init__(self):
]
# stage 4 - final encoding
- cnt = Signal((5, True))
+ cnt = Signal((6, True))
s_c = self.c
s_de = self.de
@@ -56,33 +56,91 @@ def __init__(self):
self.sync += If(s_de,
If((cnt == 0) | (n1q_m == n0q_m),
- self.output[9].eq(~q_m_r[8]),
- self.output[8].eq(q_m_r[8]),
+ self.out[9].eq(~q_m_r[8]),
+ self.out[8].eq(q_m_r[8]),
If(q_m_r[8],
- self.output[:8].eq(q_m_r[:8]),
+ self.out[:8].eq(q_m_r[:8]),
cnt.eq(cnt + n1q_m - n0q_m)
).Else(
- self.output[:8].eq(~q_m_r[:8]),
+ self.out[:8].eq(~q_m_r[:8]),
cnt.eq(cnt + n0q_m - n1q_m)
)
).Else(
- If((~cnt[4] & (n1q_m > n0q_m)) | (cnt[4] & (n0q_m > n1q_m)),
- self.output[9].eq(1),
- self.output[8].eq(q_m_r[8]),
- self.output[:8].eq(~q_m_r[:8]),
+ If((~cnt[5] & (n1q_m > n0q_m)) | (cnt[5] & (n0q_m > n1q_m)),
+ self.out[9].eq(1),
+ self.out[8].eq(q_m_r[8]),
+ self.out[:8].eq(~q_m_r[:8]),
cnt.eq(cnt + Cat(0, q_m_r[8]) + n0q_m - n1q_m)
).Else(
- self.output[9].eq(0),
- self.output[8].eq(q_m_r[8]),
- self.output[:8].eq(q_m_r[:8]),
+ self.out[9].eq(0),
+ self.out[8].eq(q_m_r[8]),
+ self.out[:8].eq(q_m_r[:8]),
cnt.eq(cnt - Cat(0, ~q_m_r[8]) + n1q_m - n0q_m)
)
)
).Else(
- self.output.eq(Array(control_tokens)[s_c]),
+ self.out.eq(Array(control_tokens)[s_c]),
cnt.eq(0)
)
+class _EncoderTB(Module):
+ def __init__(self, inputs):
+ self.outs = []
+ self._iter_inputs = iter(inputs)
+ self._end_cycle = None
+ self.submodules.dut = Encoder()
+ self.comb += self.dut.de.eq(1)
+
+ def do_simulation(self, s):
+ if self._end_cycle is None:
+ try:
+ nv = next(self._iter_inputs)
+ except StopIteration:
+ self._end_cycle = s.cycle_counter + 4
+ else:
+ s.wr(self.dut.d, nv)
+ if s.cycle_counter == self._end_cycle:
+ s.interrupt = True
+ if s.cycle_counter > 4:
+ self.outs.append(s.rd(self.dut.out))
+
+def _bit(i, n):
+ return (i >> n) & 1
+
+def _decode_tmds(b):
+ try:
+ c = control_tokens.index(b)
+ de = False
+ except ValueError:
+ c = 0
+ de = True
+ vsync = bool(c & 2)
+ hsync = bool(c & 1)
+
+ value = _bit(b, 0) ^ _bit(b, 9)
+ for i in range(1, 8):
+ value |= (_bit(b, i) ^ _bit(b, i-1) ^ (~_bit(b, 8) & 1)) << i
+
+ return de, hsync, vsync, value
+
if __name__ == "__main__":
- from migen.fhdl import verilog
- print(verilog.convert(Encoder()))
+ from migen.sim.generic import Simulator
+ from random import Random
+
+ rng = Random(788)
+ test_list = [rng.randrange(256) for i in range(500)]
+ tb = _EncoderTB(test_list)
+ Simulator(tb).run()
+
+ check = [_decode_tmds(out)[3] for out in tb.outs]
+ assert(check == test_list)
+
+ nb0 = 0
+ nb1 = 0
+ for out in tb.outs:
+ for i in range(10):
+ if _bit(out, i):
+ nb1 += 1
+ else:
+ nb0 += 1
+ print("0/1: {}/{} ({:.2f})".format(nb0, nb1, nb0/nb1))
Please sign in to comment.
Something went wrong with that request. Please try again.