add DVI output
This commit is contained in:
parent
189803416b
commit
ea0503173d
1
make.py
1
make.py
|
@ -17,6 +17,7 @@ INST "mxcrg/wr_bufpll" LOC = "BUFPLL_X0Y2";
|
|||
INST "mxcrg/rd_bufpll" LOC = "BUFPLL_X0Y3";
|
||||
|
||||
PIN "mxcrg/bufg_x1.O" CLOCK_DEDICATED_ROUTE = FALSE;
|
||||
PIN "pix2x_bufg.O" CLOCK_DEDICATED_ROUTE = FALSE;
|
||||
""")
|
||||
|
||||
if hasattr(soc, "fb"):
|
||||
|
|
|
@ -83,6 +83,76 @@ class Encoder(Module):
|
|||
cnt.eq(0)
|
||||
)
|
||||
|
||||
class _EncoderSerializer(Module):
|
||||
def __init__(self, serdesstrobe, pad_p, pad_n):
|
||||
self.submodules.encoder = RenameClockDomains(Encoder(), "pix")
|
||||
self.d, self.c, self.de = self.encoder.d, self.encoder.c, self.encoder.de
|
||||
|
||||
###
|
||||
|
||||
# 2X soft serialization
|
||||
ed_2x = Signal(5)
|
||||
self.sync.pix2x += ed_2x.eq(Mux(ClockSignal("pix"), self.encoder.out[:5], self.encoder.out[5:]))
|
||||
|
||||
# 5X hard serialization
|
||||
cascade_di = Signal()
|
||||
cascade_do = Signal()
|
||||
cascade_ti = Signal()
|
||||
cascade_to = Signal()
|
||||
pad_se = Signal()
|
||||
self.specials += [
|
||||
Instance("OSERDES2",
|
||||
p_DATA_WIDTH=5, p_DATA_RATE_OQ="SDR", p_DATA_RATE_OT="SDR",
|
||||
p_SERDES_MODE="MASTER", p_OUTPUT_MODE="DIFFERENTIAL",
|
||||
|
||||
o_OQ=pad_se,
|
||||
i_OCE=1, i_IOCE=serdesstrobe, i_RST=0,
|
||||
i_CLK0=ClockSignal("pix10x"), i_CLK1=0, i_CLKDIV=ClockSignal("pix2x"),
|
||||
i_D1=ed_2x[4], i_D2=0, i_D3=0, i_D4=0,
|
||||
i_T1=0, i_T2=0, i_T3=0, i_T4=0,
|
||||
i_TRAIN=0, i_TCE=1,
|
||||
i_SHIFTIN1=1, i_SHIFTIN2=1,
|
||||
i_SHIFTIN3=cascade_do, i_SHIFTIN4=cascade_to,
|
||||
o_SHIFTOUT1=cascade_di, o_SHIFTOUT2=cascade_ti),
|
||||
Instance("OSERDES2",
|
||||
p_DATA_WIDTH=5, p_DATA_RATE_OQ="SDR", p_DATA_RATE_OT="SDR",
|
||||
p_SERDES_MODE="SLAVE", p_OUTPUT_MODE="DIFFERENTIAL",
|
||||
|
||||
i_OCE=1, i_IOCE=serdesstrobe, i_RST=0,
|
||||
i_CLK0=ClockSignal("pix10x"), i_CLK1=0, i_CLKDIV=ClockSignal("pix2x"),
|
||||
i_D1=ed_2x[0], i_D2=ed_2x[1], i_D3=ed_2x[2], i_D4=ed_2x[3],
|
||||
i_T1=0, i_T2=0, i_T3=0, i_T4=0,
|
||||
i_TRAIN=0, i_TCE=1,
|
||||
i_SHIFTIN1=cascade_di, i_SHIFTIN2=cascade_ti,
|
||||
i_SHIFTIN3=1, i_SHIFTIN4=1,
|
||||
o_SHIFTOUT3=cascade_do, o_SHIFTOUT4=cascade_to),
|
||||
Instance("OBUFDS", i_I=pad_se, o_O=pad_p, o_OB=pad_n)
|
||||
]
|
||||
|
||||
|
||||
class PHY(Module):
|
||||
def __init__(self, serdesstrobe, pads):
|
||||
self.hsync = Signal()
|
||||
self.vsync = Signal()
|
||||
self.de = Signal()
|
||||
self.r = Signal(8)
|
||||
self.g = Signal(8)
|
||||
self.b = Signal(8)
|
||||
|
||||
###
|
||||
|
||||
self.submodules.es0 = _EncoderSerializer(serdesstrobe, pads.data0_p, pads.data0_n)
|
||||
self.submodules.es1 = _EncoderSerializer(serdesstrobe, pads.data1_p, pads.data1_n)
|
||||
self.submodules.es2 = _EncoderSerializer(serdesstrobe, pads.data2_p, pads.data2_n)
|
||||
self.comb += [
|
||||
self.es0.c.eq(Cat(self.hsync, self.vsync)),
|
||||
self.es1.c.eq(0),
|
||||
self.es2.c.eq(0),
|
||||
self.es0.de.eq(self.de),
|
||||
self.es1.de.eq(self.de),
|
||||
self.es2.de.eq(self.de),
|
||||
]
|
||||
|
||||
class _EncoderTB(Module):
|
||||
def __init__(self, inputs):
|
||||
self.outs = []
|
||||
|
|
|
@ -28,6 +28,7 @@ phy_layout_s = [
|
|||
phy_layout = [
|
||||
("hsync", 1),
|
||||
("vsync", 1),
|
||||
("de", 1),
|
||||
("p0", phy_layout_s),
|
||||
("p1", phy_layout_s)
|
||||
]
|
||||
|
@ -75,7 +76,8 @@ class VTG(Module):
|
|||
active.eq(hactive & vactive),
|
||||
If(active,
|
||||
[getattr(getattr(self.phy.payload, p), c).eq(getattr(getattr(self.pixels.payload, p), c)[skip:])
|
||||
for p in ["p0", "p1"] for c in ["r", "g", "b"]]
|
||||
for p in ["p0", "p1"] for c in ["r", "g", "b"]],
|
||||
self.phy.payload.de.eq(1)
|
||||
),
|
||||
|
||||
generate_en.eq(self.timing.stb & (~active | self.pixels.stb)),
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
from migen.fhdl.std import *
|
||||
from migen.genlib.record import Record
|
||||
from migen.genlib.fifo import AsyncFIFO
|
||||
from migen.genlib.cdc import MultiReg
|
||||
from migen.bank.description import *
|
||||
from migen.flow.actor import *
|
||||
|
||||
from milkymist.framebuffer.format import bpc_phy, phy_layout
|
||||
from milkymist.framebuffer import dvi
|
||||
|
||||
class _FIFO(Module):
|
||||
def __init__(self):
|
||||
|
@ -14,39 +14,37 @@ class _FIFO(Module):
|
|||
|
||||
self.pix_hsync = Signal()
|
||||
self.pix_vsync = Signal()
|
||||
self.pix_de = Signal()
|
||||
self.pix_r = Signal(bpc_phy)
|
||||
self.pix_g = Signal(bpc_phy)
|
||||
self.pix_b = Signal(bpc_phy)
|
||||
|
||||
###
|
||||
|
||||
data_width = 2+2*3*bpc_phy
|
||||
fifo = RenameClockDomains(AsyncFIFO(data_width, 512),
|
||||
fifo = RenameClockDomains(AsyncFIFO(phy_layout, 512),
|
||||
{"write": "sys", "read": "pix"})
|
||||
self.submodules += fifo
|
||||
fifo_in = self.phy.payload
|
||||
fifo_out = Record(phy_layout)
|
||||
self.comb += [
|
||||
self.phy.ack.eq(fifo.writable),
|
||||
fifo.we.eq(self.phy.stb),
|
||||
fifo.din.eq(fifo_in.raw_bits()),
|
||||
fifo_out.raw_bits().eq(fifo.dout),
|
||||
fifo.din.eq(self.phy.payload),
|
||||
self.busy.eq(0)
|
||||
]
|
||||
|
||||
pix_parity = Signal()
|
||||
self.sync.pix += [
|
||||
pix_parity.eq(~pix_parity),
|
||||
self.pix_hsync.eq(fifo_out.hsync),
|
||||
self.pix_vsync.eq(fifo_out.vsync),
|
||||
self.pix_hsync.eq(fifo.dout.hsync),
|
||||
self.pix_vsync.eq(fifo.dout.vsync),
|
||||
self.pix_de.eq(fifo.dout.de),
|
||||
If(pix_parity,
|
||||
self.pix_r.eq(fifo_out.p1.r),
|
||||
self.pix_g.eq(fifo_out.p1.g),
|
||||
self.pix_b.eq(fifo_out.p1.b)
|
||||
self.pix_r.eq(fifo.dout.p1.r),
|
||||
self.pix_g.eq(fifo.dout.p1.g),
|
||||
self.pix_b.eq(fifo.dout.p1.b)
|
||||
).Else(
|
||||
self.pix_r.eq(fifo_out.p0.r),
|
||||
self.pix_g.eq(fifo_out.p0.g),
|
||||
self.pix_b.eq(fifo_out.p0.b)
|
||||
self.pix_r.eq(fifo.dout.p0.r),
|
||||
self.pix_g.eq(fifo.dout.p0.g),
|
||||
self.pix_b.eq(fifo.dout.p0.b)
|
||||
)
|
||||
]
|
||||
self.comb += fifo.re.eq(pix_parity)
|
||||
|
@ -143,7 +141,7 @@ class _Clocking(Module, AutoCSR):
|
|||
Instance("BUFPLL", p_DIVIDE=5,
|
||||
i_PLLIN=pll_clk0, i_GCLK=ClockSignal("pix2x"), i_LOCKED=pll_locked,
|
||||
o_IOCLK=self.cd_pix10x.clk, o_LOCK=locked_async, o_SERDESSTROBE=self.serdesstrobe),
|
||||
Instance("BUFG", i_I=pll_clk1, o_O=self.cd_pix2x.clk),
|
||||
Instance("BUFG", name="pix2x_bufg", i_I=pll_clk1, o_O=self.cd_pix2x.clk),
|
||||
Instance("BUFG", i_I=pll_clk2, o_O=self.cd_pix.clk),
|
||||
MultiReg(locked_async, mult_locked, "sys")
|
||||
]
|
||||
|
@ -166,7 +164,7 @@ class _Clocking(Module, AutoCSR):
|
|||
i_C1=~ClockSignal("pix"),
|
||||
i_CE=1, i_D0=1, i_D1=0,
|
||||
i_R=0, i_S=0)
|
||||
self.specials += Instance("OBUFTDS", i_I=dvi_clk_se,
|
||||
self.specials += Instance("OBUFDS", i_I=dvi_clk_se,
|
||||
o_O=pads_dvi.clk_p, o_OB=pads_dvi.clk_n)
|
||||
|
||||
class Driver(Module, AutoCSR):
|
||||
|
@ -187,3 +185,13 @@ class Driver(Module, AutoCSR):
|
|||
pads_vga.b.eq(fifo.pix_b),
|
||||
pads_vga.psave_n.eq(1)
|
||||
]
|
||||
if pads_dvi is not None:
|
||||
self.submodules.dvi_phy = dvi.PHY(self.clocking.serdesstrobe, pads_dvi)
|
||||
self.comb += [
|
||||
self.dvi_phy.hsync.eq(fifo.pix_hsync),
|
||||
self.dvi_phy.vsync.eq(fifo.pix_vsync),
|
||||
self.dvi_phy.de.eq(fifo.pix_de),
|
||||
self.dvi_phy.r.eq(fifo.pix_r),
|
||||
self.dvi_phy.g.eq(fifo.pix_g),
|
||||
self.dvi_phy.b.eq(fifo.pix_b)
|
||||
]
|
||||
|
|
5
top.py
5
top.py
|
@ -161,13 +161,14 @@ class SoC(Module):
|
|||
self.submodules.timer0 = timer.Timer()
|
||||
if platform_name == "mixxeo":
|
||||
self.submodules.leds = gpio.GPIOOut(platform.request("user_led"))
|
||||
self.submodules.fb = framebuffer.MixFramebuffer(platform.request("vga_out"), None, lasmim_fb0, lasmim_fb1)
|
||||
self.submodules.fb = framebuffer.MixFramebuffer(platform.request("vga_out"), platform.request("dvi_out"),
|
||||
lasmim_fb0, lasmim_fb1)
|
||||
self.submodules.dvisampler0 = dvisampler.DVISampler(platform.request("dvi_in", 0), lasmim_dvi0)
|
||||
self.submodules.dvisampler1 = dvisampler.DVISampler(platform.request("dvi_in", 1), lasmim_dvi1)
|
||||
if platform_name == "m1":
|
||||
self.submodules.buttons = gpio.GPIOIn(Cat(platform.request("user_btn", 0), platform.request("user_btn", 2)))
|
||||
self.submodules.leds = gpio.GPIOOut(Cat(*[platform.request("user_led", i) for i in range(2)]))
|
||||
self.submodules.fb = framebuffer.Framebuffer(platform.request("vga"), lasmim_fb)
|
||||
self.submodules.fb = framebuffer.Framebuffer(platform.request("vga"), None, lasmim_fb)
|
||||
if with_memtest:
|
||||
self.submodules.memtest_w = memtest.MemtestWriter(lasmim_mtw)
|
||||
self.submodules.memtest_r = memtest.MemtestReader(lasmim_mtr)
|
||||
|
|
Loading…
Reference in New Issue