Permalink
Browse files

framebuffer: prepare for DVI out

  • Loading branch information...
1 parent 20b758d commit e6e04a2e3a8fd08a150ce5a2302f1ffa8a728465 @sbourdeauducq sbourdeauducq committed Sep 17, 2013
View
@@ -21,11 +21,11 @@ def build(platform_name, build_bitstream, build_header, *soc_args, **soc_kwargs)
if hasattr(soc, "fb"):
platform.add_platform_command("""
-NET "vga_clk" TNM_NET = "GRPvga_clk";
+NET "{vga_clk}" TNM_NET = "GRPvga_clk";
NET "sys_clk" TNM_NET = "GRPsys_clk";
TIMESPEC "TSise_sucks1" = FROM "GRPvga_clk" TO "GRPsys_clk" TIG;
TIMESPEC "TSise_sucks2" = FROM "GRPsys_clk" TO "GRPvga_clk" TIG;
-""")
+""", vga_clk=soc.fb.driver.clocking.cd_pix.clk)
for d in ["mxcrg", "minimac3"]:
platform.add_source_dir(os.path.join("verilog", d))
@@ -4,52 +4,35 @@
from migen.bank.description import CSRStorage, AutoCSR
from migen.actorlib import dma_lasmi, structuring, sim, spi
-from milkymist.framebuffer.lib import bpp, pixel_layout, dac_layout, FrameInitiator, VTG, FIFO
+from milkymist.framebuffer.format import bpp, pixel_layout, FrameInitiator, VTG
+from milkymist.framebuffer.phy import Driver
-class Framebuffer(Module):
- def __init__(self, pads, lasmim, simulation=False):
+class Framebuffer(Module, AutoCSR):
+ def __init__(self, pads_vga, pads_dvi, lasmim, simulation=False):
pack_factor = lasmim.dw//(2*bpp)
packed_pixels = structuring.pack_layout(pixel_layout, pack_factor)
- fi = FrameInitiator()
- dma = spi.DMAReadController(dma_lasmi.Reader(lasmim), spi.MODE_EXTERNAL, length_reset=640*480*4)
+ self._enable = CSRStorage()
+ self.fi = FrameInitiator()
+ self.dma = spi.DMAReadController(dma_lasmi.Reader(lasmim), spi.MODE_EXTERNAL, length_reset=640*480*4)
+ self.driver = Driver(pads_vga, pads_dvi)
+
cast = structuring.Cast(lasmim.dw, packed_pixels, reverse_to=True)
unpack = structuring.Unpack(pack_factor, pixel_layout)
vtg = VTG()
- if simulation:
- fifo = sim.SimActor(sim_fifo_gen(), ("dac", Sink, dac_layout))
- else:
- fifo = FIFO()
g = DataFlowGraph()
- g.add_connection(fi, vtg, sink_ep="timing")
- g.add_connection(dma, cast)
+ g.add_connection(self.fi, vtg, sink_ep="timing")
+ g.add_connection(self.dma, cast)
g.add_connection(cast, unpack)
g.add_connection(unpack, vtg, sink_ep="pixels")
- g.add_connection(vtg, fifo)
+ g.add_connection(vtg, self.driver)
self.submodules += CompositeActor(g)
- self._enable = CSRStorage()
self.comb += [
- fi.trigger.eq(self._enable.storage),
- dma.generator.trigger.eq(self._enable.storage),
+ self.fi.trigger.eq(self._enable.storage),
+ self.dma.generator.trigger.eq(self._enable.storage),
]
- self._fi = fi
- self._dma = dma
-
- # Drive pads
- if not simulation:
- self.comb += [
- pads.hsync_n.eq(fifo.vga_hsync_n),
- pads.vsync_n.eq(fifo.vga_vsync_n),
- pads.r.eq(fifo.vga_r),
- pads.g.eq(fifo.vga_g),
- pads.b.eq(fifo.vga_b)
- ]
- self.comb += pads.psave_n.eq(1)
-
- def get_csrs(self):
- return [self._enable] + self._fi.get_csrs() + self._dma.get_csrs()
class Blender(PipelinedActor, AutoCSR):
def __init__(self, nimages, latency):
@@ -97,13 +80,14 @@ def __init__(self, nimages, latency):
self.comb += self.source.payload.eq(outval)
class MixFramebuffer(Module, AutoCSR):
- def __init__(self, pads, *lasmims, blender_latency=5):
+ def __init__(self, pads_vga, pads_dvi, *lasmims, blender_latency=5):
pack_factor = lasmims[0].dw//(2*bpp)
packed_pixels = structuring.pack_layout(pixel_layout, pack_factor)
self._enable = CSRStorage()
self.fi = FrameInitiator()
self.blender = Blender(len(lasmims), blender_latency)
+ self.driver = Driver(pads_vga, pads_dvi)
self.comb += self.fi.trigger.eq(self._enable.storage)
g = DataFlowGraph()
@@ -120,17 +104,7 @@ def __init__(self, pads, *lasmims, blender_latency=5):
setattr(self, "dma"+str(n), dma)
vtg = VTG()
- fifo = FIFO()
g.add_connection(self.fi, vtg, sink_ep="timing")
g.add_connection(self.blender, vtg, sink_ep="pixels")
- g.add_connection(vtg, fifo)
+ g.add_connection(vtg, self.driver)
self.submodules += CompositeActor(g)
-
- self.comb += [
- pads.hsync_n.eq(fifo.vga_hsync_n),
- pads.vsync_n.eq(fifo.vga_vsync_n),
- pads.r.eq(fifo.vga_r),
- pads.g.eq(fifo.vga_g),
- pads.b.eq(fifo.vga_b),
- pads.psave_n.eq(1)
- ]
@@ -0,0 +1,111 @@
+from migen.fhdl.std import *
+from migen.flow.actor import *
+from migen.bank.description import CSRStorage
+from migen.actorlib import spi
+
+_hbits = 11
+_vbits = 12
+
+bpp = 32
+bpc = 10
+pixel_layout_s = [
+ ("pad", bpp-3*bpc),
+ ("r", bpc),
+ ("g", bpc),
+ ("b", bpc)
+]
+pixel_layout = [
+ ("p0", pixel_layout_s),
+ ("p1", pixel_layout_s)
+]
+
+bpc_phy = 8
+phy_layout_s = [
+ ("r", bpc_phy),
+ ("g", bpc_phy),
+ ("b", bpc_phy)
+]
+phy_layout = [
+ ("hsync", 1),
+ ("vsync", 1),
+ ("p0", phy_layout_s),
+ ("p1", phy_layout_s)
+]
+
+class FrameInitiator(spi.SingleGenerator):
+ def __init__(self):
+ layout = [
+ ("hres", _hbits, 640, 1),
+ ("hsync_start", _hbits, 656, 1),
+ ("hsync_end", _hbits, 752, 1),
+ ("hscan", _hbits, 800, 1),
+
+ ("vres", _vbits, 480),
+ ("vsync_start", _vbits, 492),
+ ("vsync_end", _vbits, 494),
+ ("vscan", _vbits, 525)
+ ]
+ spi.SingleGenerator.__init__(self, layout, spi.MODE_EXTERNAL)
+
+class VTG(Module):
+ def __init__(self):
+ self.timing = Sink([
+ ("hres", _hbits),
+ ("hsync_start", _hbits),
+ ("hsync_end", _hbits),
+ ("hscan", _hbits),
+ ("vres", _vbits),
+ ("vsync_start", _vbits),
+ ("vsync_end", _vbits),
+ ("vscan", _vbits)])
+ self.pixels = Sink(pixel_layout)
+ self.phy = Source(phy_layout)
+ self.busy = Signal()
+
+ hactive = Signal()
+ vactive = Signal()
+ active = Signal()
+
+ generate_en = Signal()
+ hcounter = Signal(_hbits)
+ vcounter = Signal(_vbits)
+
+ skip = bpc - bpc_phy
+ self.comb += [
+ 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"]]
+ ),
+
+ generate_en.eq(self.timing.stb & (~active | self.pixels.stb)),
+ self.pixels.ack.eq(self.phy.ack & active),
+ self.phy.stb.eq(generate_en),
+ self.busy.eq(generate_en)
+ ]
+ tp = self.timing.payload
+ self.sync += [
+ self.timing.ack.eq(0),
+ If(generate_en & self.phy.ack,
+ hcounter.eq(hcounter + 1),
+
+ If(hcounter == 0, hactive.eq(1)),
+ If(hcounter == tp.hres, hactive.eq(0)),
+ If(hcounter == tp.hsync_start, self.phy.payload.hsync.eq(1)),
+ If(hcounter == tp.hsync_end, self.phy.payload.hsync.eq(0)),
+ If(hcounter == tp.hscan,
+ hcounter.eq(0),
+ If(vcounter == tp.vscan,
+ vcounter.eq(0),
+ self.timing.ack.eq(1)
+ ).Else(
+ vcounter.eq(vcounter + 1)
+ )
+ ),
+
+ If(vcounter == 0, vactive.eq(1)),
+ If(vcounter == tp.vres, vactive.eq(0)),
+ If(vcounter == tp.vsync_start, self.phy.payload.vsync.eq(1)),
+ If(vcounter == tp.vsync_end, self.phy.payload.vsync.eq(0))
+ )
+ ]
@@ -1,166 +0,0 @@
-from migen.fhdl.std import *
-from migen.genlib.record import Record
-from migen.genlib.fifo import AsyncFIFO
-from migen.flow.actor import *
-from migen.flow.network import *
-from migen.flow.transactions import *
-from migen.bank.description import CSRStorage
-from migen.actorlib import spi
-
-_hbits = 11
-_vbits = 12
-
-bpp = 32
-bpc = 10
-pixel_layout_s = [
- ("pad", bpp-3*bpc),
- ("r", bpc),
- ("g", bpc),
- ("b", bpc)
-]
-pixel_layout = [
- ("p0", pixel_layout_s),
- ("p1", pixel_layout_s)
-]
-
-bpc_dac = 8
-dac_layout_s = [
- ("r", bpc_dac),
- ("g", bpc_dac),
- ("b", bpc_dac)
-]
-dac_layout = [
- ("hsync", 1),
- ("vsync", 1),
- ("p0", dac_layout_s),
- ("p1", dac_layout_s)
-]
-
-class FrameInitiator(spi.SingleGenerator):
- def __init__(self):
- layout = [
- ("hres", _hbits, 640, 1),
- ("hsync_start", _hbits, 656, 1),
- ("hsync_end", _hbits, 752, 1),
- ("hscan", _hbits, 800, 1),
-
- ("vres", _vbits, 480),
- ("vsync_start", _vbits, 492),
- ("vsync_end", _vbits, 494),
- ("vscan", _vbits, 525)
- ]
- spi.SingleGenerator.__init__(self, layout, spi.MODE_EXTERNAL)
-
-class VTG(Module):
- def __init__(self):
- self.timing = Sink([
- ("hres", _hbits),
- ("hsync_start", _hbits),
- ("hsync_end", _hbits),
- ("hscan", _hbits),
- ("vres", _vbits),
- ("vsync_start", _vbits),
- ("vsync_end", _vbits),
- ("vscan", _vbits)])
- self.pixels = Sink(pixel_layout)
- self.dac = Source(dac_layout)
- self.busy = Signal()
-
- hactive = Signal()
- vactive = Signal()
- active = Signal()
-
- generate_en = Signal()
- hcounter = Signal(_hbits)
- vcounter = Signal(_vbits)
-
- skip = bpc - bpc_dac
- self.comb += [
- active.eq(hactive & vactive),
- If(active,
- [getattr(getattr(self.dac.payload, p), c).eq(getattr(getattr(self.pixels.payload, p), c)[skip:])
- for p in ["p0", "p1"] for c in ["r", "g", "b"]]
- ),
-
- generate_en.eq(self.timing.stb & (~active | self.pixels.stb)),
- self.pixels.ack.eq(self.dac.ack & active),
- self.dac.stb.eq(generate_en),
- self.busy.eq(generate_en)
- ]
- tp = self.timing.payload
- self.sync += [
- self.timing.ack.eq(0),
- If(generate_en & self.dac.ack,
- hcounter.eq(hcounter + 1),
-
- If(hcounter == 0, hactive.eq(1)),
- If(hcounter == tp.hres, hactive.eq(0)),
- If(hcounter == tp.hsync_start, self.dac.payload.hsync.eq(1)),
- If(hcounter == tp.hsync_end, self.dac.payload.hsync.eq(0)),
- If(hcounter == tp.hscan,
- hcounter.eq(0),
- If(vcounter == tp.vscan,
- vcounter.eq(0),
- self.timing.ack.eq(1)
- ).Else(
- vcounter.eq(vcounter + 1)
- )
- ),
-
- If(vcounter == 0, vactive.eq(1)),
- If(vcounter == tp.vres, vactive.eq(0)),
- If(vcounter == tp.vsync_start, self.dac.payload.vsync.eq(1)),
- If(vcounter == tp.vsync_end, self.dac.payload.vsync.eq(0))
- )
- ]
-
-class FIFO(Module):
- def __init__(self):
- self.dac = Sink(dac_layout)
- self.busy = Signal()
-
- self.vga_hsync_n = Signal()
- self.vga_vsync_n = Signal()
- self.vga_r = Signal(bpc_dac)
- self.vga_g = Signal(bpc_dac)
- self.vga_b = Signal(bpc_dac)
-
- ###
-
- data_width = 2+2*3*bpc_dac
- fifo = RenameClockDomains(AsyncFIFO(data_width, 512),
- {"write": "sys", "read": "vga"})
- self.submodules += fifo
- fifo_in = self.dac.payload
- fifo_out = Record(dac_layout)
- self.comb += [
- self.dac.ack.eq(fifo.writable),
- fifo.we.eq(self.dac.stb),
- fifo.din.eq(fifo_in.raw_bits()),
- fifo_out.raw_bits().eq(fifo.dout),
- self.busy.eq(0)
- ]
-
- pix_parity = Signal()
- self.sync.vga += [
- pix_parity.eq(~pix_parity),
- self.vga_hsync_n.eq(~fifo_out.hsync),
- self.vga_vsync_n.eq(~fifo_out.vsync),
- If(pix_parity,
- self.vga_r.eq(fifo_out.p1.r),
- self.vga_g.eq(fifo_out.p1.g),
- self.vga_b.eq(fifo_out.p1.b)
- ).Else(
- self.vga_r.eq(fifo_out.p0.r),
- self.vga_g.eq(fifo_out.p0.g),
- self.vga_b.eq(fifo_out.p0.b)
- )
- ]
- self.comb += fifo.re.eq(pix_parity)
-
-def sim_fifo_gen():
- while True:
- t = Token("dac")
- yield t
- print("H/V:" + str(t.value["hsync"]) + str(t.value["vsync"])
- + " " + str(t.value["r"]) + " " + str(t.value["g"]) + " " + str(t.value["b"]))
Oops, something went wrong.

0 comments on commit e6e04a2

Please sign in to comment.