From d65941d6cc4429ed7640173712698cb0b3111e3e Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Fri, 22 Mar 2013 18:37:10 +0100 Subject: [PATCH] dvisampler: channel synchronization --- milkymist/dvisampler/__init__.py | 10 +++++++ milkymist/dvisampler/chansync.py | 51 ++++++++++++++++++++++++++++++++ milkymist/dvisampler/charsync.py | 6 ++-- software/include/hw/dvisampler.h | 2 ++ software/videomixer/main.c | 5 ++-- 5 files changed, 69 insertions(+), 5 deletions(-) create mode 100644 milkymist/dvisampler/chansync.py diff --git a/milkymist/dvisampler/__init__.py b/milkymist/dvisampler/__init__.py index 0f338fcec..2cab74254 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.chansync import ChanSync class DVISampler(Module, AutoReg): def __init__(self, inversions=""): @@ -34,3 +35,12 @@ class DVISampler(Module, AutoReg): charsync = CharSync() setattr(self.submodules, name + "_charsync", charsync) self.comb += charsync.raw_data.eq(cap.d) + + 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), + ] diff --git a/milkymist/dvisampler/chansync.py b/milkymist/dvisampler/chansync.py new file mode 100644 index 000000000..bb515313d --- /dev/null +++ b/milkymist/dvisampler/chansync.py @@ -0,0 +1,51 @@ +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.misc import optree +from migen.bank.description import * + +_control_tokens = [0b1101010100, 0b0010101011, 0b0101010100, 0b1010101011] + +class ChanSync(Module, AutoReg): + def __init__(self, nchan=3, depth=8): + self.char_synced = Signal() + self.chan_synced = Signal() + + self._r_channels_synced = RegisterField(1, READ_ONLY, WRITE_ONLY) + + lst_control_starts = [] + all_control_starts = Signal() + for i in range(nchan): + name = "data_in" + str(i) + data_in = Signal(10, name=name) + setattr(self, name, data_in) + name = "data_out" + str(i) + data_out = Signal(10, name=name) + setattr(self, name, data_out) + + ### + + 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) + ] + is_control = Signal() + is_control_r = Signal() + self.sync.pix += If(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])), + 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.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 40a7b1674..0545f7feb 100644 --- a/milkymist/dvisampler/charsync.py +++ b/milkymist/dvisampler/charsync.py @@ -9,7 +9,7 @@ _control_tokens = [0b1101010100, 0b0010101011, 0b0101010100, 0b1010101011] class CharSync(Module, AutoReg): def __init__(self, required_controls=8): self.raw_data = Signal(10) - self.char_synced = Signal() + self.synced = Signal() self.data = Signal(10) self._r_char_synced = RegisterField(1, READ_ONLY, WRITE_ONLY) @@ -36,7 +36,7 @@ class CharSync(Module, AutoReg): If(found_control & (control_position == previous_control_position), If(control_counter == (required_controls - 1), control_counter.eq(0), - self.char_synced.eq(1), + self.synced.eq(1), word_sel.eq(control_position) ).Else( control_counter.eq(control_counter + 1) @@ -46,6 +46,6 @@ class CharSync(Module, AutoReg): ), previous_control_position.eq(control_position) ] - self.specials += MultiReg(self.char_synced, self._r_char_synced.field.w) + self.specials += MultiReg(self.synced, self._r_char_synced.field.w) self.sync.pix += self.data.eq(raw >> word_sel) diff --git a/software/include/hw/dvisampler.h b/software/include/hw/dvisampler.h index 626e96403..2e9223933 100644 --- a/software/include/hw/dvisampler.h +++ b/software/include/hw/dvisampler.h @@ -27,6 +27,8 @@ #define CSR_DVISAMPLER0_D2_PHASE_RESET DVISAMPLER0_CSR(0x3C) #define CSR_DVISAMPLER0_D2_CHAR_SYNCED DVISAMPLER0_CSR(0x40) +#define CSR_DVISAMPLER0_CHAN_SYNCED DVISAMPLER0_CSR(0x44) + #define DVISAMPLER_DELAY_CAL 0x01 #define DVISAMPLER_DELAY_RST 0x02 #define DVISAMPLER_DELAY_INC 0x04 diff --git a/software/videomixer/main.c b/software/videomixer/main.c index 70691e074..8040876a7 100644 --- a/software/videomixer/main.c +++ b/software/videomixer/main.c @@ -60,10 +60,11 @@ static void adjust_phase(void) CSR_DVISAMPLER0_D2_PHASE_RESET = 1; break; } - printf("Ph: %4d %4d %4d // %d%d%d\n", d0, d1, d2, + printf("Ph: %4d %4d %4d // %d%d%d // %d\n", d0, d1, d2, CSR_DVISAMPLER0_D0_CHAR_SYNCED, CSR_DVISAMPLER0_D1_CHAR_SYNCED, - CSR_DVISAMPLER0_D2_CHAR_SYNCED); + CSR_DVISAMPLER0_D2_CHAR_SYNCED, + CSR_DVISAMPLER0_CHAN_SYNCED); } static void vmix(void)