dvisampler: decode before channel sync

This commit is contained in:
Sebastien Bourdeauducq 2013-03-22 23:49:25 +01:00
parent 037625886d
commit 34b8388b45
5 changed files with 48 additions and 62 deletions

View File

@ -6,6 +6,7 @@ from milkymist.dvisampler.edid import EDID
from milkymist.dvisampler.clocking import Clocking from milkymist.dvisampler.clocking import Clocking
from milkymist.dvisampler.datacapture import DataCapture from milkymist.dvisampler.datacapture import DataCapture
from milkymist.dvisampler.charsync import CharSync from milkymist.dvisampler.charsync import CharSync
from milkymist.dvisampler.decoding import Decoding
from milkymist.dvisampler.chansync import ChanSync from milkymist.dvisampler.chansync import ChanSync
class DVISampler(Module, AutoReg): class DVISampler(Module, AutoReg):
@ -36,11 +37,25 @@ class DVISampler(Module, AutoReg):
setattr(self.submodules, name + "_charsync", charsync) setattr(self.submodules, name + "_charsync", charsync)
self.comb += charsync.raw_data.eq(cap.d) 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.submodules.chansync = ChanSync()
self.comb += [ self.comb += [
self.chansync.char_synced.eq(self.data0_charsync.synced & \ self.chansync.valid_i.eq(self.data0_decod.valid_o & \
self.data1_charsync.synced & self.data2_charsync.synced), self.data1_decod.valid_o & self.data2_decod.valid_o),
self.chansync.data_in0.eq(self.data0_charsync.data), self.chansync.data_in0.eq(self.data0_decod.output),
self.chansync.data_in1.eq(self.data1_charsync.data), self.chansync.data_in1.eq(self.data1_decod.output),
self.chansync.data_in2.eq(self.data2_charsync.data), 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]

View File

@ -2,14 +2,15 @@ from migen.fhdl.structure import *
from migen.fhdl.module import Module from migen.fhdl.module import Module
from migen.genlib.cdc import MultiReg from migen.genlib.cdc import MultiReg
from migen.genlib.fifo import SyncFIFO from migen.genlib.fifo import SyncFIFO
from migen.genlib.record import Record
from migen.genlib.misc import optree from migen.genlib.misc import optree
from migen.bank.description import * from migen.bank.description import *
_control_tokens = [0b1101010100, 0b0010101011, 0b0101010100, 0b1010101011] from milkymist.dvisampler.common import channel_layout
class ChanSync(Module, AutoReg): class ChanSync(Module, AutoReg):
def __init__(self, nchan=3, depth=8): def __init__(self, nchan=3, depth=8):
self.char_synced = Signal() self.valid_i = Signal()
self.chan_synced = Signal() self.chan_synced = Signal()
self._r_channels_synced = RegisterField(1, READ_ONLY, WRITE_ONLY) self._r_channels_synced = RegisterField(1, READ_ONLY, WRITE_ONLY)
@ -18,10 +19,10 @@ class ChanSync(Module, AutoReg):
all_control_starts = Signal() all_control_starts = Signal()
for i in range(nchan): for i in range(nchan):
name = "data_in" + str(i) name = "data_in" + str(i)
data_in = Signal(10, name=name) data_in = Record(channel_layout, name=name)
setattr(self, name, data_in) setattr(self, name, data_in)
name = "data_out" + str(i) name = "data_out" + str(i)
data_out = Signal(10, name=name) data_out = Record(channel_layout, name=name)
setattr(self, name, data_out) setattr(self, name, data_out)
### ###
@ -29,23 +30,23 @@ class ChanSync(Module, AutoReg):
fifo = SyncFIFO(10, depth) fifo = SyncFIFO(10, depth)
self.add_submodule(fifo, "pix") self.add_submodule(fifo, "pix")
self.comb += [ self.comb += [
fifo.we.eq(self.char_synced), fifo.we.eq(self.valid_i),
fifo.din.eq(data_in), fifo.din.eq(Cat(*data_in.flatten())),
data_out.eq(fifo.dout) Cat(*data_out.flatten()).eq(fifo.dout)
] ]
is_control = Signal() is_control = Signal()
is_control_r = 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() control_starts = Signal()
self.comb += [ 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), control_starts.eq(is_control & ~is_control_r),
fifo.re.eq(~is_control | all_control_starts) fifo.re.eq(~is_control | all_control_starts)
] ]
lst_control_starts.append(control_starts) lst_control_starts.append(control_starts)
self.comb += all_control_starts.eq(optree("&", lst_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) self.chan_synced.eq(0)
).Elif(all_control_starts, self.chan_synced.eq(1)) ).Elif(all_control_starts, self.chan_synced.eq(1))
self.specials += MultiReg(self.chan_synced, self._r_channels_synced.field.w) self.specials += MultiReg(self.chan_synced, self._r_channels_synced.field.w)

View File

@ -4,7 +4,7 @@ from migen.genlib.cdc import MultiReg
from migen.genlib.misc import optree from migen.genlib.misc import optree
from migen.bank.description import * from migen.bank.description import *
_control_tokens = [0b1101010100, 0b0010101011, 0b0101010100, 0b1010101011] from milkymist.dvisampler.common import control_tokens
class CharSync(Module, AutoReg): class CharSync(Module, AutoReg):
def __init__(self, required_controls=8): def __init__(self, required_controls=8):
@ -24,7 +24,7 @@ class CharSync(Module, AutoReg):
found_control = Signal() found_control = Signal()
control_position = Signal(max=10) control_position = Signal(max=10)
for i in range(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), found_control.eq(1),
control_position.eq(i) control_position.eq(i)
) )

View File

@ -0,0 +1,2 @@
control_tokens = [0b1101010100, 0b0010101011, 0b0101010100, 0b1010101011]
channel_layout = [("d", 8), ("c", 2), ("de", 1)]

View File

@ -1,57 +1,25 @@
from migen.fhdl.structure import * from migen.fhdl.structure import *
from migen.fhdl.module import Module from migen.fhdl.module import Module
from migen.genlib.record import Record
class _TMDSDecoding(Module): from milkymist.dvisampler.common import control_tokens, channel_layout
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])
class Decoding(Module): class Decoding(Module):
def __init__(self): def __init__(self):
self.valid_i = Signal() self.valid_i = Signal()
self.data0 = Signal(10) self.input = Signal(10)
self.data1 = Signal(10)
self.data2 = Signal(10)
self.valid_o = Signal() self.valid_o = Signal()
self.de = Signal() self.output = Record(channel_layout)
self.r = Signal(8)
self.g = Signal(8)
self.b = Signal(8)
self.hsync = Signal()
self.vsync = Signal()
### ###
self.submodules.decode0 = _TMDSDecoding() self.sync.pix += self.output.de.eq(1)
self.submodules.decode1 = _TMDSDecoding() for i, t in enumerate(control_tokens):
self.submodules.decode2 = _TMDSDecoding() self.sync.pix += If(self.input == t,
self.output.de.eq(0),
self.comb += [ self.output.c.eq(i)
self.decode0.input.eq(self.data0), )
self.decode1.input.eq(self.data1), self.sync.pix += self.output.d[0].eq(self.input[0] ^ self.input[9])
self.decode2.input.eq(self.data2), 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.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.valid_o.eq(self.valid_i) self.sync.pix += self.valid_o.eq(self.valid_i)