from milkymist.dvisampler.edid import EDID
from milkymist.dvisampler.clocking import Clocking
from milkymist.dvisampler.datacapture import DataCapture
+from milkymist.dvisampler.charsync import CharSync
class DVISampler(Module, AutoReg):
def __init__(self, inversions=""):
for datan in "012":
name = "data" + str(datan)
invert = datan in inversions
+
+ signame = name + "_n" if invert else name
+ s = Signal(name=signame)
+ setattr(self, signame, s)
+
cap = DataCapture(8, invert)
setattr(self.submodules, name + "_cap", cap)
- if invert:
- name += "_n"
- s = Signal(name=name)
- setattr(self, name, s)
self.comb += [
cap.pad.eq(s),
cap.serdesstrobe.eq(self.clocking.serdesstrobe)
]
+
+ charsync = CharSync()
+ setattr(self.submodules, name + "_charsync", charsync)
+ self.comb += charsync.raw_data.eq(cap.d)
--- /dev/null
+from migen.fhdl.structure import *
+from migen.fhdl.module import Module
+from migen.genlib.cdc import MultiReg
+from migen.genlib.misc import optree
+from migen.bank.description import *
+
+_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.data = Signal(10)
+
+ self._r_char_synced = RegisterField(1, READ_ONLY, WRITE_ONLY)
+
+ ###
+
+ raw_data1 = Signal(10)
+ self.sync.pix += raw_data1.eq(self.raw_data)
+ raw = Signal(20)
+ self.comb += raw.eq(Cat(raw_data1, self.raw_data))
+
+ 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]),
+ found_control.eq(1),
+ control_position.eq(i)
+ )
+
+ control_counter = Signal(max=required_controls)
+ previous_control_position = Signal(max=10)
+ word_sel = Signal(max=10)
+ self.sync.pix += [
+ If(found_control & (control_position == previous_control_position),
+ If(control_counter == (required_controls - 1),
+ control_counter.eq(0),
+ self.char_synced.eq(1),
+ word_sel.eq(control_position)
+ ).Else(
+ control_counter.eq(control_counter + 1)
+ )
+ ).Else(
+ control_counter.eq(0)
+ ),
+ previous_control_position.eq(control_position)
+ ]
+ self.specials += MultiReg(self.char_synced, self._r_char_synced.field.w)
+
+ self.sync.pix += self.data.eq(raw >> word_sel)
#define CSR_DVISAMPLER0_D0_DELAY_BUSY DVISAMPLER0_CSR(0x0C)
#define CSR_DVISAMPLER0_D0_PHASE DVISAMPLER0_CSR(0x10)
#define CSR_DVISAMPLER0_D0_PHASE_RESET DVISAMPLER0_CSR(0x14)
-
-#define CSR_DVISAMPLER0_D1_DELAY_CTL DVISAMPLER0_CSR(0x18)
-#define CSR_DVISAMPLER0_D1_DELAY_BUSY DVISAMPLER0_CSR(0x1C)
-#define CSR_DVISAMPLER0_D1_PHASE DVISAMPLER0_CSR(0x20)
-#define CSR_DVISAMPLER0_D1_PHASE_RESET DVISAMPLER0_CSR(0x24)
-
-#define CSR_DVISAMPLER0_D2_DELAY_CTL DVISAMPLER0_CSR(0x28)
-#define CSR_DVISAMPLER0_D2_DELAY_BUSY DVISAMPLER0_CSR(0x2C)
-#define CSR_DVISAMPLER0_D2_PHASE DVISAMPLER0_CSR(0x30)
-#define CSR_DVISAMPLER0_D2_PHASE_RESET DVISAMPLER0_CSR(0x34)
+#define CSR_DVISAMPLER0_D0_CHAR_SYNCED DVISAMPLER0_CSR(0x18)
+
+#define CSR_DVISAMPLER0_D1_DELAY_CTL DVISAMPLER0_CSR(0x1C)
+#define CSR_DVISAMPLER0_D1_DELAY_BUSY DVISAMPLER0_CSR(0x20)
+#define CSR_DVISAMPLER0_D1_PHASE DVISAMPLER0_CSR(0x24)
+#define CSR_DVISAMPLER0_D1_PHASE_RESET DVISAMPLER0_CSR(0x28)
+#define CSR_DVISAMPLER0_D1_CHAR_SYNCED DVISAMPLER0_CSR(0x2C)
+
+#define CSR_DVISAMPLER0_D2_DELAY_CTL DVISAMPLER0_CSR(0x30)
+#define CSR_DVISAMPLER0_D2_DELAY_BUSY DVISAMPLER0_CSR(0x34)
+#define CSR_DVISAMPLER0_D2_PHASE DVISAMPLER0_CSR(0x38)
+#define CSR_DVISAMPLER0_D2_PHASE_RESET DVISAMPLER0_CSR(0x3C)
+#define CSR_DVISAMPLER0_D2_CHAR_SYNCED DVISAMPLER0_CSR(0x40)
#define DVISAMPLER_DELAY_CAL 0x01
#define DVISAMPLER_DELAY_RST 0x02
CSR_DVISAMPLER0_D2_PHASE_RESET = 1;
break;
}
- //printf("Ph: %4d %4d %4d\n", d0, d1, d2);
+ printf("Ph: %4d %4d %4d // %d%d%d\n", d0, d1, d2,
+ CSR_DVISAMPLER0_D0_CHAR_SYNCED,
+ CSR_DVISAMPLER0_D1_CHAR_SYNCED,
+ CSR_DVISAMPLER0_D2_CHAR_SYNCED);
}
static void vmix(void)