dvisampler: channel synchronization
This commit is contained in:
parent
515cdb2bd8
commit
d65941d6cc
|
@ -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.chansync import ChanSync
|
||||||
|
|
||||||
class DVISampler(Module, AutoReg):
|
class DVISampler(Module, AutoReg):
|
||||||
def __init__(self, inversions=""):
|
def __init__(self, inversions=""):
|
||||||
|
@ -34,3 +35,12 @@ class DVISampler(Module, AutoReg):
|
||||||
charsync = CharSync()
|
charsync = CharSync()
|
||||||
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)
|
||||||
|
|
||||||
|
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),
|
||||||
|
]
|
||||||
|
|
|
@ -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)
|
|
@ -9,7 +9,7 @@ _control_tokens = [0b1101010100, 0b0010101011, 0b0101010100, 0b1010101011]
|
||||||
class CharSync(Module, AutoReg):
|
class CharSync(Module, AutoReg):
|
||||||
def __init__(self, required_controls=8):
|
def __init__(self, required_controls=8):
|
||||||
self.raw_data = Signal(10)
|
self.raw_data = Signal(10)
|
||||||
self.char_synced = Signal()
|
self.synced = Signal()
|
||||||
self.data = Signal(10)
|
self.data = Signal(10)
|
||||||
|
|
||||||
self._r_char_synced = RegisterField(1, READ_ONLY, WRITE_ONLY)
|
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(found_control & (control_position == previous_control_position),
|
||||||
If(control_counter == (required_controls - 1),
|
If(control_counter == (required_controls - 1),
|
||||||
control_counter.eq(0),
|
control_counter.eq(0),
|
||||||
self.char_synced.eq(1),
|
self.synced.eq(1),
|
||||||
word_sel.eq(control_position)
|
word_sel.eq(control_position)
|
||||||
).Else(
|
).Else(
|
||||||
control_counter.eq(control_counter + 1)
|
control_counter.eq(control_counter + 1)
|
||||||
|
@ -46,6 +46,6 @@ class CharSync(Module, AutoReg):
|
||||||
),
|
),
|
||||||
previous_control_position.eq(control_position)
|
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)
|
self.sync.pix += self.data.eq(raw >> word_sel)
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
#define CSR_DVISAMPLER0_D2_PHASE_RESET DVISAMPLER0_CSR(0x3C)
|
#define CSR_DVISAMPLER0_D2_PHASE_RESET DVISAMPLER0_CSR(0x3C)
|
||||||
#define CSR_DVISAMPLER0_D2_CHAR_SYNCED DVISAMPLER0_CSR(0x40)
|
#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_CAL 0x01
|
||||||
#define DVISAMPLER_DELAY_RST 0x02
|
#define DVISAMPLER_DELAY_RST 0x02
|
||||||
#define DVISAMPLER_DELAY_INC 0x04
|
#define DVISAMPLER_DELAY_INC 0x04
|
||||||
|
|
|
@ -60,10 +60,11 @@ static void adjust_phase(void)
|
||||||
CSR_DVISAMPLER0_D2_PHASE_RESET = 1;
|
CSR_DVISAMPLER0_D2_PHASE_RESET = 1;
|
||||||
break;
|
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_D0_CHAR_SYNCED,
|
||||||
CSR_DVISAMPLER0_D1_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)
|
static void vmix(void)
|
||||||
|
|
Loading…
Reference in New Issue