from migen.fhdl.structure import *
from migen.fhdl.module import Module
-from migen.bank.description import *
-from migen.genlib.fifo import AsyncFIFO
-from migen.actorlib import structuring, dma_asmi, spi
+from migen.bank.description import AutoCSR
from milkymist.dvisampler.edid import EDID
from milkymist.dvisampler.clocking import Clocking
from milkymist.dvisampler.charsync import CharSync
from milkymist.dvisampler.decoding import Decoding
from milkymist.dvisampler.chansync import ChanSync
-from milkymist.dvisampler.syncpol import SyncPolarity
-from milkymist.dvisampler.resdetection import ResolutionDetection
+from milkymist.dvisampler.analysis import SyncPolarity, ResolutionDetection, FrameExtraction
+from milkymist.dvisampler.dma import DMA
class DVISampler(Module, AutoCSR):
- def __init__(self, pads):
+ def __init__(self, pads, asmiport):
self.submodules.edid = EDID(pads)
self.submodules.clocking = Clocking(pads)
self.chansync.data_in2.eq(self.data2_decod.output),
]
+ ###
+
self.submodules.syncpol = SyncPolarity()
self.comb += [
self.syncpol.valid_i.eq(self.chansync.chan_synced),
self.submodules.resdetection = ResolutionDetection()
self.comb += [
+ self.resdetection.valid_i.eq(self.syncpol.valid_o),
self.resdetection.de.eq(self.syncpol.de),
self.resdetection.vsync.eq(self.syncpol.vsync)
]
-class RawDVISampler(Module, AutoCSR):
- def __init__(self, pads, asmiport):
- self.submodules.edid = EDID(pads)
- self.submodules.clocking = Clocking(pads)
-
- invert = False
- try:
- s = getattr(pads, "data0")
- except AttributeError:
- s = getattr(pads, "data0_n")
- invert = True
- self.submodules.data0_cap = DataCapture(8, invert)
+ self.submodules.frame = FrameExtraction()
self.comb += [
- self.data0_cap.pad.eq(s),
- self.data0_cap.serdesstrobe.eq(self.clocking.serdesstrobe)
+ self.frame.valid_i.eq(self.syncpol.valid_o),
+ self.frame.de.eq(self.syncpol.de),
+ self.frame.vsync.eq(self.syncpol.vsync),
+ self.frame.r.eq(self.syncpol.r),
+ self.frame.g.eq(self.syncpol.g),
+ self.frame.b.eq(self.syncpol.b)
]
- fifo = AsyncFIFO(10, 1024)
- self.add_submodule(fifo, {"write": "pix", "read": "sys"})
- self.comb += [
- fifo.din.eq(self.data0_cap.d),
- fifo.we.eq(1)
- ]
-
- pack_factor = asmiport.hub.dw//16
- self.submodules.packer = structuring.Pack([("word", 10), ("pad", 6)], pack_factor)
- self.submodules.cast = structuring.Cast(self.packer.source.payload.layout, asmiport.hub.dw)
- self.submodules.dma = spi.DMAWriteController(dma_asmi.Writer(asmiport), spi.MODE_SINGLE_SHOT)
- self.comb += [
- self.packer.sink.stb.eq(fifo.readable),
- fifo.re.eq(self.packer.sink.ack),
- self.packer.sink.payload.word.eq(fifo.dout),
- self.packer.source.connect(self.cast.sink, match_by_position=True),
- self.cast.source.connect(self.dma.data, match_by_position=True)
- ]
+ self.submodules.dma = DMA(asmiport)
+ self.comb += self.frame.frame.connect(self.dma.frame)
--- /dev/null
+from migen.fhdl.structure import *
+from migen.fhdl.module import Module
+from migen.genlib.cdc import MultiReg
+from migen.genlib.fifo import AsyncFIFO
+from migen.genlib.record import Record
+from migen.bank.description import *
+from migen.flow.actor import *
+
+from milkymist.dvisampler.common import channel_layout, frame_layout
+
+class SyncPolarity(Module):
+ def __init__(self):
+ self.valid_i = Signal()
+ self.data_in0 = Record(channel_layout)
+ self.data_in1 = Record(channel_layout)
+ self.data_in2 = Record(channel_layout)
+
+ self.valid_o = Signal()
+ self.de = Signal()
+ self.hsync = Signal()
+ self.vsync = Signal()
+ self.r = Signal(8)
+ self.g = Signal(8)
+ self.b = Signal(8)
+
+ ###
+
+ de = self.data_in0.de
+ de_r = Signal()
+ c = self.data_in0.c
+ c_polarity = Signal(2)
+ c_out = Signal(2)
+
+ self.comb += [
+ self.de.eq(de_r),
+ self.hsync.eq(c_out[0]),
+ self.vsync.eq(c_out[1])
+ ]
+
+ self.sync.pix += [
+ self.valid_o.eq(self.valid_i),
+ self.r.eq(self.data_in2.d),
+ self.g.eq(self.data_in1.d),
+ self.b.eq(self.data_in0.d),
+
+ de_r.eq(de),
+ If(de_r & ~de,
+ c_polarity.eq(c),
+ c_out.eq(0)
+ ).Else(
+ c_out.eq(c ^ c_polarity)
+ )
+ ]
+
+class ResolutionDetection(Module, AutoCSR):
+ def __init__(self, nbits=11):
+ self.valid_i = Signal()
+ self.vsync = Signal()
+ self.de = Signal()
+
+ self._hres = CSRStatus(nbits)
+ self._vres = CSRStatus(nbits)
+
+ ###
+
+ # Detect DE transitions
+ de_r = Signal()
+ pn_de = Signal()
+ self.sync.pix += de_r.eq(self.de)
+ self.comb += pn_de.eq(~self.de & de_r)
+
+ # HRES
+ hcounter = Signal(nbits)
+ self.sync.pix += If(self.valid_i & self.de,
+ hcounter.eq(hcounter + 1)
+ ).Else(
+ hcounter.eq(0)
+ )
+
+ hcounter_st = Signal(nbits)
+ self.sync.pix += If(self.valid_i,
+ If(pn_de, hcounter_st.eq(hcounter))
+ ).Else(
+ hcounter_st.eq(0)
+ )
+ self.specials += MultiReg(hcounter_st, self._hres.status)
+
+ # VRES
+ vsync_r = Signal()
+ p_vsync = Signal()
+ self.sync.pix += vsync_r.eq(self.vsync),
+ self.comb += p_vsync.eq(self.vsync & ~vsync_r)
+
+ vcounter = Signal(nbits)
+ self.sync.pix += If(self.valid_i & p_vsync,
+ vcounter.eq(0)
+ ).Elif(pn_de,
+ vcounter.eq(vcounter + 1)
+ )
+
+ vcounter_st = Signal(nbits)
+ self.sync.pix += If(self.valid_i,
+ If(p_vsync, vcounter_st.eq(vcounter))
+ ).Else(
+ vcounter_st.eq(0)
+ )
+ self.specials += MultiReg(vcounter_st, self._vres.status)
+
+class FrameExtraction(Module):
+ def __init__(self):
+ # in pix clock domain
+ self.valid_i = Signal()
+ self.vsync = Signal()
+ self.de = Signal()
+ self.r = Signal(8)
+ self.g = Signal(8)
+ self.b = Signal(8)
+
+ # in sys clock domain
+ self.frame = Source(frame_layout)
+ self.busy = Signal()
+
+ ###
+
+ fifo_stb = Signal()
+ fifo_in = Record(frame_layout)
+ self.comb += [
+ fifo_stb.eq(self.valid_i & self.de),
+ fifo_in.r.eq(self.r),
+ fifo_in.g.eq(self.g),
+ fifo_in.b.eq(self.b),
+ ]
+ vsync_r = Signal()
+ self.sync.pix += [
+ If(self.vsync & ~vsync_r, fifo_in.parity.eq(~fifo_in.parity)),
+ vsync_r.eq(self.vsync)
+ ]
+
+ fifo = AsyncFIFO(layout_len(frame_layout), 256)
+ self.add_submodule(fifo, {"write": "pix", "read": "sys"})
+ self.comb += [
+ fifo.we.eq(fifo_stb),
+ fifo.din.eq(fifo_in.raw_bits()),
+ self.frame.stb.eq(fifo.readable),
+ self.frame.payload.raw_bits().eq(fifo.dout),
+ fifo.re.eq(self.frame.ack),
+ self.busy.eq(0)
+ ]
control_tokens = [0b1101010100, 0b0010101011, 0b0101010100, 0b1010101011]
channel_layout = [("d", 8), ("c", 2), ("de", 1)]
+frame_layout = [("parity", 1), ("r", 8), ("g", 8), ("b", 8)]
--- /dev/null
+from migen.fhdl.structure import *
+from migen.fhdl.module import Module
+from migen.genlib.fifo import AsyncFIFO
+from migen.genlib.record import layout_len
+from migen.bank.description import AutoCSR
+from migen.actorlib import structuring, dma_asmi, spi
+
+from milkymist.dvisampler.edid import EDID
+from milkymist.dvisampler.clocking import Clocking
+from milkymist.dvisampler.datacapture import DataCapture
+
+class RawDVISampler(Module, AutoCSR):
+ def __init__(self, pads, asmiport):
+ self.submodules.edid = EDID(pads)
+ self.submodules.clocking = Clocking(pads)
+
+ invert = False
+ try:
+ s = getattr(pads, "data0")
+ except AttributeError:
+ s = getattr(pads, "data0_n")
+ invert = True
+ self.submodules.data0_cap = DataCapture(8, invert)
+ self.comb += [
+ self.data0_cap.pad.eq(s),
+ self.data0_cap.serdesstrobe.eq(self.clocking.serdesstrobe)
+ ]
+
+ fifo = AsyncFIFO(10, 256)
+ self.add_submodule(fifo, {"write": "pix", "read": "sys"})
+ self.comb += [
+ fifo.din.eq(self.data0_cap.d),
+ fifo.we.eq(1)
+ ]
+
+ pack_factor = asmiport.hub.dw//16
+ self.submodules.packer = structuring.Pack([("word", 10), ("pad", 6)], pack_factor)
+ self.submodules.cast = structuring.Cast(self.packer.source.payload.layout, asmiport.hub.dw)
+ self.submodules.dma = spi.DMAWriteController(dma_asmi.Writer(asmiport), spi.MODE_SINGLE_SHOT, free_flow=True)
+ self.comb += [
+ self.packer.sink.stb.eq(fifo.readable),
+ fifo.re.eq(self.packer.sink.ack),
+ self.packer.sink.payload.word.eq(fifo.dout),
+ self.packer.source.connect(self.cast.sink, match_by_position=True),
+ self.cast.source.connect(self.dma.data, match_by_position=True)
+ ]
--- /dev/null
+from migen.fhdl.structure import *
+from migen.fhdl.module import Module
+from migen.bank.description import *
+from migen.flow.actor import *
+from migen.actorlib import structuring, dma_asmi, spi
+
+from milkymist.dvisampler.common import frame_layout
+
+class DMA(Module):
+ def __init__(self, asmiport):
+ self.frame = Sink(frame_layout)
+ self.shoot = CSR()
+
+ ###
+
+ sof = Signal()
+ parity_r = Signal()
+ self.comb += sof.eq(self.frame.stb & (parity_r ^ self.frame.payload.parity))
+ self.sync += If(self.frame.stb & self.frame.ack, parity_r.eq(self.frame.payload.parity))
+
+ pending = Signal()
+ frame_en = Signal()
+ self.sync += [
+ If(sof,
+ frame_en.eq(0),
+ If(pending, frame_en.eq(1)),
+ pending.eq(0)
+ ),
+ If(self.shoot.re, pending.eq(1))
+ ]
+
+ pack_factor = asmiport.hub.dw//32
+ self.submodules.packer = structuring.Pack(list(reversed([("pad", 2), ("r", 10), ("g", 10), ("b", 10)])), pack_factor)
+ self.submodules.cast = structuring.Cast(self.packer.source.payload.layout, asmiport.hub.dw, reverse_from=False)
+ self.submodules.dma = spi.DMAWriteController(dma_asmi.Writer(asmiport), spi.MODE_EXTERNAL)
+ self.comb += [
+ self.dma.generator.trigger.eq(self.shoot.re),
+ self.packer.sink.stb.eq(self.frame.stb & frame_en),
+ self.frame.ack.eq(self.packer.sink.ack | (~frame_en & ~(pending & sof))),
+ self.packer.sink.payload.r.eq(self.frame.payload.r << 2),
+ self.packer.sink.payload.g.eq(self.frame.payload.g << 2),
+ self.packer.sink.payload.b.eq(self.frame.payload.b << 2),
+ self.packer.source.connect(self.cast.sink, match_by_position=True),
+ self.cast.source.connect(self.dma.data, match_by_position=True)
+ ]
+
+ def get_csrs(self):
+ return [self.shoot] + self.dma.get_csrs()
+++ /dev/null
-from migen.fhdl.structure import *
-from migen.fhdl.module import Module
-from migen.genlib.cdc import MultiReg
-from migen.bank.description import *
-
-class ResolutionDetection(Module, AutoCSR):
- def __init__(self, nbits=11):
- self.vsync = Signal()
- self.de = Signal()
-
- self._hres = CSRStatus(nbits)
- self._vres = CSRStatus(nbits)
-
- ###
-
- # Detect DE transitions
- de_r = Signal()
- pn_de = Signal()
- self.sync.pix += de_r.eq(self.de)
- self.comb += pn_de.eq(~self.de & de_r)
-
- # HRES
- hcounter = Signal(nbits)
- self.sync.pix += If(self.de,
- hcounter.eq(hcounter + 1)
- ).Else(
- hcounter.eq(0)
- )
-
- hcounter_st = Signal(nbits)
- self.sync.pix += If(pn_de, hcounter_st.eq(hcounter))
- self.specials += MultiReg(hcounter_st, self._hres.status)
-
- # VRES
- vsync_r = Signal()
- p_vsync = Signal()
- self.sync.pix += vsync_r.eq(self.vsync),
- self.comb += p_vsync.eq(self.vsync & ~vsync_r)
-
- vcounter = Signal(nbits)
- self.sync.pix += If(p_vsync,
- vcounter.eq(0)
- ).Elif(pn_de,
- vcounter.eq(vcounter + 1)
- )
-
- vcounter_st = Signal(nbits)
- self.sync.pix += If(p_vsync, vcounter_st.eq(vcounter))
- self.specials += MultiReg(vcounter_st, self._vres.status)
+++ /dev/null
-from migen.fhdl.structure import *
-from migen.fhdl.module import Module
-from migen.genlib.record import Record
-
-from milkymist.dvisampler.common import channel_layout
-
-class SyncPolarity(Module):
- def __init__(self):
- self.valid_i = Signal()
- self.data_in0 = Record(channel_layout)
- self.data_in1 = Record(channel_layout)
- self.data_in2 = Record(channel_layout)
-
- self.valid_o = Signal()
- self.de = Signal()
- self.hsync = Signal()
- self.vsync = Signal()
- self.r = Signal(8)
- self.g = Signal(8)
- self.b = Signal(8)
-
- ###
-
- de = self.data_in0.de
- de_r = Signal()
- c = self.data_in0.c
- c_polarity = Signal(2)
- c_out = Signal(2)
-
- self.comb += [
- self.de.eq(de_r),
- self.hsync.eq(c_out[0]),
- self.vsync.eq(c_out[1])
- ]
-
- self.sync.pix += [
- self.valid_o.eq(self.valid_i),
- self.r.eq(self.data_in2.d),
- self.g.eq(self.data_in1.d),
- self.b.eq(self.data_in0.d),
-
- de_r.eq(de),
- If(de_r & ~de,
- c_polarity.eq(c),
- c_out.eq(0)
- ).Else(
- c_out.eq(c ^ c_polarity)
- )
- ]
self.submodules.asmicon = asmicon.ASMIcon(sdram_phy, sdram_geom, sdram_timing)
asmiport_wb = self.asmicon.hub.get_port()
asmiport_fb = self.asmicon.hub.get_port(3)
+ asmiport_dvi0 = self.asmicon.hub.get_port(2)
self.asmicon.finalize()
#
self.submodules.timer0 = timer.Timer()
self.submodules.fb = framebuffer.Framebuffer(platform.request("vga"), asmiport_fb)
self.submodules.asmiprobe = asmiprobe.ASMIprobe(self.asmicon.hub)
- self.submodules.dvisampler0 = dvisampler.DVISampler(platform.request("dvi_in", 0))
- self.submodules.dvisampler1 = dvisampler.DVISampler(platform.request("dvi_in", 1))
+ self.submodules.dvisampler0 = dvisampler.DVISampler(platform.request("dvi_in", 0), asmiport_dvi0)
+ #self.submodules.dvisampler1 = dvisampler.DVISampler(platform.request("dvi_in", 1))
self.submodules.csrbankarray = csrgen.BankArray(self,
lambda name, memory: self.csr_map[name if memory is None else name + "_" + memory.name_override])