dvisampler: decode before channel sync
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Fri, 22 Mar 2013 22:49:25 +0000 (23:49 +0100)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Fri, 22 Mar 2013 22:49:25 +0000 (23:49 +0100)
milkymist/dvisampler/__init__.py
milkymist/dvisampler/chansync.py
milkymist/dvisampler/charsync.py
milkymist/dvisampler/common.py [new file with mode: 0644]
milkymist/dvisampler/decoding.py

index 2cab74254a3f5e1e82ca7d041839d2210fdf08dd..c752b1c28eea293129706a21cb67bbcb2a3e0dd1 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.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]
index bb515313d4b247a8538e08a4b67674547edc4507..08d3645abbb1009bd8363d888ee9db7b76398c9e 100644 (file)
@@ -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)
index 0545f7febbc80bdff8b77725b8a9035cc0a646cf..464a40b8f14aed6f9ed3d79f8d491e784cc64969 100644 (file)
@@ -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 (file)
index 0000000..7fb9a42
--- /dev/null
@@ -0,0 +1,2 @@
+control_tokens = [0b1101010100, 0b0010101011, 0b0101010100, 0b1010101011]
+channel_layout = [("d", 8), ("c", 2), ("de", 1)]
index 0e739b7789559a9b5401f61822b4b2b701157ea0..d051a86c5b0f85544123ef0f91303f988f5a1889 100644 (file)
@@ -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)