dvisampler: decode before channel sync
This commit is contained in:
parent
037625886d
commit
34b8388b45
|
@ -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]
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
)
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
control_tokens = [0b1101010100, 0b0010101011, 0b0101010100, 0b1010101011]
|
||||
channel_layout = [("d", 8), ("c", 2), ("de", 1)]
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue