diff --git a/milkymist/dvisampler/__init__.py b/milkymist/dvisampler/__init__.py index d20880a02..0f338fcec 100644 --- a/milkymist/dvisampler/__init__.py +++ b/milkymist/dvisampler/__init__.py @@ -5,6 +5,7 @@ from migen.bank.description import * from milkymist.dvisampler.edid import EDID from milkymist.dvisampler.clocking import Clocking from milkymist.dvisampler.datacapture import DataCapture +from milkymist.dvisampler.charsync import CharSync class DVISampler(Module, AutoReg): def __init__(self, inversions=""): @@ -18,13 +19,18 @@ class DVISampler(Module, AutoReg): for datan in "012": name = "data" + str(datan) invert = datan in inversions + + signame = name + "_n" if invert else name + s = Signal(name=signame) + setattr(self, signame, s) + cap = DataCapture(8, invert) setattr(self.submodules, name + "_cap", cap) - if invert: - name += "_n" - s = Signal(name=name) - setattr(self, name, s) self.comb += [ cap.pad.eq(s), cap.serdesstrobe.eq(self.clocking.serdesstrobe) ] + + charsync = CharSync() + setattr(self.submodules, name + "_charsync", charsync) + self.comb += charsync.raw_data.eq(cap.d) diff --git a/milkymist/dvisampler/charsync.py b/milkymist/dvisampler/charsync.py new file mode 100644 index 000000000..40a7b1674 --- /dev/null +++ b/milkymist/dvisampler/charsync.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.misc import optree +from migen.bank.description import * + +_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.data = Signal(10) + + self._r_char_synced = RegisterField(1, READ_ONLY, WRITE_ONLY) + + ### + + raw_data1 = Signal(10) + self.sync.pix += raw_data1.eq(self.raw_data) + raw = Signal(20) + self.comb += raw.eq(Cat(raw_data1, self.raw_data)) + + 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]), + found_control.eq(1), + control_position.eq(i) + ) + + control_counter = Signal(max=required_controls) + previous_control_position = Signal(max=10) + word_sel = Signal(max=10) + self.sync.pix += [ + If(found_control & (control_position == previous_control_position), + If(control_counter == (required_controls - 1), + control_counter.eq(0), + self.char_synced.eq(1), + word_sel.eq(control_position) + ).Else( + control_counter.eq(control_counter + 1) + ) + ).Else( + control_counter.eq(0) + ), + previous_control_position.eq(control_position) + ] + self.specials += MultiReg(self.char_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 30b60fa60..626e96403 100644 --- a/software/include/hw/dvisampler.h +++ b/software/include/hw/dvisampler.h @@ -13,16 +13,19 @@ #define CSR_DVISAMPLER0_D0_DELAY_BUSY DVISAMPLER0_CSR(0x0C) #define CSR_DVISAMPLER0_D0_PHASE DVISAMPLER0_CSR(0x10) #define CSR_DVISAMPLER0_D0_PHASE_RESET DVISAMPLER0_CSR(0x14) +#define CSR_DVISAMPLER0_D0_CHAR_SYNCED DVISAMPLER0_CSR(0x18) -#define CSR_DVISAMPLER0_D1_DELAY_CTL DVISAMPLER0_CSR(0x18) -#define CSR_DVISAMPLER0_D1_DELAY_BUSY DVISAMPLER0_CSR(0x1C) -#define CSR_DVISAMPLER0_D1_PHASE DVISAMPLER0_CSR(0x20) -#define CSR_DVISAMPLER0_D1_PHASE_RESET DVISAMPLER0_CSR(0x24) +#define CSR_DVISAMPLER0_D1_DELAY_CTL DVISAMPLER0_CSR(0x1C) +#define CSR_DVISAMPLER0_D1_DELAY_BUSY DVISAMPLER0_CSR(0x20) +#define CSR_DVISAMPLER0_D1_PHASE DVISAMPLER0_CSR(0x24) +#define CSR_DVISAMPLER0_D1_PHASE_RESET DVISAMPLER0_CSR(0x28) +#define CSR_DVISAMPLER0_D1_CHAR_SYNCED DVISAMPLER0_CSR(0x2C) -#define CSR_DVISAMPLER0_D2_DELAY_CTL DVISAMPLER0_CSR(0x28) -#define CSR_DVISAMPLER0_D2_DELAY_BUSY DVISAMPLER0_CSR(0x2C) -#define CSR_DVISAMPLER0_D2_PHASE DVISAMPLER0_CSR(0x30) -#define CSR_DVISAMPLER0_D2_PHASE_RESET DVISAMPLER0_CSR(0x34) +#define CSR_DVISAMPLER0_D2_DELAY_CTL DVISAMPLER0_CSR(0x30) +#define CSR_DVISAMPLER0_D2_DELAY_BUSY DVISAMPLER0_CSR(0x34) +#define CSR_DVISAMPLER0_D2_PHASE DVISAMPLER0_CSR(0x38) +#define CSR_DVISAMPLER0_D2_PHASE_RESET DVISAMPLER0_CSR(0x3C) +#define CSR_DVISAMPLER0_D2_CHAR_SYNCED DVISAMPLER0_CSR(0x40) #define DVISAMPLER_DELAY_CAL 0x01 #define DVISAMPLER_DELAY_RST 0x02 diff --git a/software/videomixer/main.c b/software/videomixer/main.c index e549ae7d1..70691e074 100644 --- a/software/videomixer/main.c +++ b/software/videomixer/main.c @@ -60,7 +60,10 @@ static void adjust_phase(void) CSR_DVISAMPLER0_D2_PHASE_RESET = 1; break; } - //printf("Ph: %4d %4d %4d\n", d0, d1, d2); + printf("Ph: %4d %4d %4d // %d%d%d\n", d0, d1, d2, + CSR_DVISAMPLER0_D0_CHAR_SYNCED, + CSR_DVISAMPLER0_D1_CHAR_SYNCED, + CSR_DVISAMPLER0_D2_CHAR_SYNCED); } static void vmix(void)