dvisampler: channel synchronization
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Fri, 22 Mar 2013 17:37:10 +0000 (18:37 +0100)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Fri, 22 Mar 2013 17:37:10 +0000 (18:37 +0100)
milkymist/dvisampler/__init__.py
milkymist/dvisampler/chansync.py [new file with mode: 0644]
milkymist/dvisampler/charsync.py
software/include/hw/dvisampler.h
software/videomixer/main.c

index 0f338fcecaa952843dc56980f50d255dc9dfe8cc..2cab74254a3f5e1e82ca7d041839d2210fdf08dd 100644 (file)
@@ -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 (file)
index 0000000..bb51531
--- /dev/null
@@ -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)
index 40a7b167460cbac1936f424d1d3d00f173e2fba6..0545f7febbc80bdff8b77725b8a9035cc0a646cf 100644 (file)
@@ -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)
index 626e9640352ed33622907640602e9bfc5b32a897..2e9223933f47c918255eb81e507a36a901cc6fb8 100644 (file)
@@ -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
index 70691e0741004c187fdc7c26e54c64fd6c686304..8040876a74ba41bd0776d929a60f948385bcae36 100644 (file)
@@ -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)