From 34b8388b45a8d19d958be8f3b6ef2571edf7baa7 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Fri, 22 Mar 2013 23:49:25 +0100 Subject: [PATCH] dvisampler: decode before channel sync --- milkymist/dvisampler/__init__.py | 25 +++++++++++--- milkymist/dvisampler/chansync.py | 21 ++++++------ milkymist/dvisampler/charsync.py | 4 +-- milkymist/dvisampler/common.py | 2 ++ milkymist/dvisampler/decoding.py | 58 +++++++------------------------- 5 files changed, 48 insertions(+), 62 deletions(-) create mode 100644 milkymist/dvisampler/common.py diff --git a/milkymist/dvisampler/__init__.py b/milkymist/dvisampler/__init__.py index 2cab74254..c752b1c28 100644 --- a/milkymist/dvisampler/__init__.py +++ b/milkymist/dvisampler/__init__.py @@ -6,6 +6,7 @@ from milkymist.dvisampler.edid import EDID from milkymist.dvisampler.clocking import Clocking from milkymist.dvisampler.datacapture import DataCapture from milkymist.dvisampler.charsync import CharSync +from milkymist.dvisampler.decoding import Decoding from milkymist.dvisampler.chansync import ChanSync class DVISampler(Module, AutoReg): @@ -36,11 +37,25 @@ class DVISampler(Module, AutoReg): setattr(self.submodules, name + "_charsync", charsync) self.comb += charsync.raw_data.eq(cap.d) + decoding = Decoding() + setattr(self.submodules, name + "_decod", decoding) + self.comb += [ + decoding.valid_i.eq(charsync.synced), + decoding.input.eq(charsync.data) + ] + self.submodules.chansync = ChanSync() self.comb += [ - self.chansync.char_synced.eq(self.data0_charsync.synced & \ - self.data1_charsync.synced & self.data2_charsync.synced), - self.chansync.data_in0.eq(self.data0_charsync.data), - self.chansync.data_in1.eq(self.data1_charsync.data), - self.chansync.data_in2.eq(self.data2_charsync.data), + self.chansync.valid_i.eq(self.data0_decod.valid_o & \ + self.data1_decod.valid_o & self.data2_decod.valid_o), + self.chansync.data_in0.eq(self.data0_decod.output), + self.chansync.data_in1.eq(self.data1_decod.output), + self.chansync.data_in2.eq(self.data2_decod.output), ] + + de = self.chansync.data_out0.de + r = self.chansync.data_out2.d + g = self.chansync.data_out1.d + b = self.chansync.data_out0.d + hsync = self.chansync.data_out0.c[0] + vsync = self.chansync.data_out0.c[1] diff --git a/milkymist/dvisampler/chansync.py b/milkymist/dvisampler/chansync.py index bb515313d..08d3645ab 100644 --- a/milkymist/dvisampler/chansync.py +++ b/milkymist/dvisampler/chansync.py @@ -2,14 +2,15 @@ from migen.fhdl.structure import * from migen.fhdl.module import Module from migen.genlib.cdc import MultiReg from migen.genlib.fifo import SyncFIFO +from migen.genlib.record import Record from migen.genlib.misc import optree from migen.bank.description import * -_control_tokens = [0b1101010100, 0b0010101011, 0b0101010100, 0b1010101011] +from milkymist.dvisampler.common import channel_layout class ChanSync(Module, AutoReg): def __init__(self, nchan=3, depth=8): - self.char_synced = Signal() + self.valid_i = Signal() self.chan_synced = Signal() self._r_channels_synced = RegisterField(1, READ_ONLY, WRITE_ONLY) @@ -18,10 +19,10 @@ class ChanSync(Module, AutoReg): all_control_starts = Signal() for i in range(nchan): name = "data_in" + str(i) - data_in = Signal(10, name=name) + data_in = Record(channel_layout, name=name) setattr(self, name, data_in) name = "data_out" + str(i) - data_out = Signal(10, name=name) + data_out = Record(channel_layout, name=name) setattr(self, name, data_out) ### @@ -29,23 +30,23 @@ class ChanSync(Module, AutoReg): fifo = SyncFIFO(10, depth) self.add_submodule(fifo, "pix") self.comb += [ - fifo.we.eq(self.char_synced), - fifo.din.eq(data_in), - data_out.eq(fifo.dout) + fifo.we.eq(self.valid_i), + fifo.din.eq(Cat(*data_in.flatten())), + Cat(*data_out.flatten()).eq(fifo.dout) ] is_control = Signal() is_control_r = Signal() - self.sync.pix += If(fifo.re, is_control_r.eq(is_control)) + self.sync.pix += If(fifo.readable & fifo.re, is_control_r.eq(is_control)) control_starts = Signal() self.comb += [ - is_control.eq(optree("|", [data_out == t for t in _control_tokens])), + is_control.eq(~data_out.de), control_starts.eq(is_control & ~is_control_r), fifo.re.eq(~is_control | all_control_starts) ] lst_control_starts.append(control_starts) self.comb += all_control_starts.eq(optree("&", lst_control_starts)) - self.sync.pix += If(~self.char_synced, + self.sync.pix += If(~self.valid_i, self.chan_synced.eq(0) ).Elif(all_control_starts, self.chan_synced.eq(1)) self.specials += MultiReg(self.chan_synced, self._r_channels_synced.field.w) diff --git a/milkymist/dvisampler/charsync.py b/milkymist/dvisampler/charsync.py index 0545f7feb..464a40b8f 100644 --- a/milkymist/dvisampler/charsync.py +++ b/milkymist/dvisampler/charsync.py @@ -4,7 +4,7 @@ from migen.genlib.cdc import MultiReg from migen.genlib.misc import optree from migen.bank.description import * -_control_tokens = [0b1101010100, 0b0010101011, 0b0101010100, 0b1010101011] +from milkymist.dvisampler.common import control_tokens class CharSync(Module, AutoReg): def __init__(self, required_controls=8): @@ -24,7 +24,7 @@ class CharSync(Module, AutoReg): found_control = Signal() control_position = Signal(max=10) for i in range(10): - self.sync.pix += If(optree("|", [raw[i:i+10] == t for t in _control_tokens]), + self.sync.pix += If(optree("|", [raw[i:i+10] == t for t in control_tokens]), found_control.eq(1), control_position.eq(i) ) diff --git a/milkymist/dvisampler/common.py b/milkymist/dvisampler/common.py new file mode 100644 index 000000000..7fb9a420a --- /dev/null +++ b/milkymist/dvisampler/common.py @@ -0,0 +1,2 @@ +control_tokens = [0b1101010100, 0b0010101011, 0b0101010100, 0b1010101011] +channel_layout = [("d", 8), ("c", 2), ("de", 1)] diff --git a/milkymist/dvisampler/decoding.py b/milkymist/dvisampler/decoding.py index 0e739b778..d051a86c5 100644 --- a/milkymist/dvisampler/decoding.py +++ b/milkymist/dvisampler/decoding.py @@ -1,57 +1,25 @@ from migen.fhdl.structure import * from migen.fhdl.module import Module +from migen.genlib.record import Record -class _TMDSDecoding(Module): - def __init__(self): - self.input = Signal(10) - self.de = Signal() - self.data = Signal(8) - self.c = Signal(2) - - ### - - self.sync.pix += self.de.eq(1) - for i, t in enumerate([0b1101010100, 0b0010101011, 0b0101010100, 0b1010101011]): - self.sync.pix += If(self.input == t, - self.de.eq(0), - self.c.eq(i) - ) - self.sync.pix += self.data[0].eq(self.input[0] ^ self.input[9]) - for i in range(1, 8): - self.sync.pix += self.data[i].eq(self.input[i] ^ self.input[i-1] ^ ~self.input[8]) +from milkymist.dvisampler.common import control_tokens, channel_layout class Decoding(Module): def __init__(self): self.valid_i = Signal() - self.data0 = Signal(10) - self.data1 = Signal(10) - self.data2 = Signal(10) - + self.input = Signal(10) self.valid_o = Signal() - self.de = Signal() - self.r = Signal(8) - self.g = Signal(8) - self.b = Signal(8) - self.hsync = Signal() - self.vsync = Signal() + self.output = Record(channel_layout) ### - self.submodules.decode0 = _TMDSDecoding() - self.submodules.decode1 = _TMDSDecoding() - self.submodules.decode2 = _TMDSDecoding() - - self.comb += [ - self.decode0.input.eq(self.data0), - self.decode1.input.eq(self.data1), - self.decode2.input.eq(self.data2), - - self.de.eq(self.decode0.de), - self.r.eq(self.decode2.data), - self.g.eq(self.decode1.data), - self.b.eq(self.decode0.data), - self.hsync.eq(self.decode0.c[0]), - self.vsync.eq(self.decode0.c[1]) - ] - + self.sync.pix += self.output.de.eq(1) + for i, t in enumerate(control_tokens): + self.sync.pix += If(self.input == t, + self.output.de.eq(0), + self.output.c.eq(i) + ) + self.sync.pix += self.output.d[0].eq(self.input[0] ^ self.input[9]) + for i in range(1, 8): + self.sync.pix += self.output.d[i].eq(self.input[i] ^ self.input[i-1] ^ ~self.input[8]) self.sync.pix += self.valid_o.eq(self.valid_i)