framebuffer: reorganize in preparation for mixer
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Thu, 9 May 2013 17:23:22 +0000 (19:23 +0200)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Thu, 9 May 2013 17:23:22 +0000 (19:23 +0200)
milkymist/framebuffer/__init__.py
milkymist/framebuffer/lib.py [new file with mode: 0644]

index 1a93cad12b7aa2a0fe9c9483700474d344f7eb2b..830e731d46c93a1555d554a7132f195d34b6155e 100644 (file)
 from migen.fhdl.structure import *
-from migen.fhdl.specials import Instance
 from migen.fhdl.module import Module
-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 dma_asmi, structuring, sim, 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 = AsyncFIFO(data_width, 256)
-               self.add_submodule(fifo, {"write": "sys", "read": "vga"})
-               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"]))
+from milkymist.framebuffer.lib import bpp, pixel_layout, dac_layout, FrameInitiator, VTG, FIFO
 
 class Framebuffer(Module):
        def __init__(self, pads, asmiport, simulation=False):
-               pack_factor = asmiport.hub.dw//(2*_bpp)
-               packed_pixels = structuring.pack_layout(_pixel_layout, pack_factor)
+               pack_factor = asmiport.hub.dw//(2*bpp)
+               packed_pixels = structuring.pack_layout(pixel_layout, pack_factor)
                
-               fi = _FrameInitiator()
+               fi = FrameInitiator()
                dma = spi.DMAReadController(dma_asmi.Reader(asmiport), spi.MODE_EXTERNAL, length_reset=640*480*4)
                cast = structuring.Cast(asmiport.hub.dw, packed_pixels, reverse_to=True)
-               unpack = structuring.Unpack(pack_factor, _pixel_layout)
+               unpack = structuring.Unpack(pack_factor, pixel_layout)
                vtg = VTG()
                if simulation:
-                       fifo = sim.SimActor(sim_fifo_gen(), ("dac", Sink, _dac_layout))
+                       fifo = sim.SimActor(sim_fifo_gen(), ("dac", Sink, dac_layout))
                else:
                        fifo = FIFO()
                
diff --git a/milkymist/framebuffer/lib.py b/milkymist/framebuffer/lib.py
new file mode 100644 (file)
index 0000000..e85ed9d
--- /dev/null
@@ -0,0 +1,167 @@
+from migen.fhdl.structure import *
+from migen.fhdl.module import Module
+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 = AsyncFIFO(data_width, 256)
+               self.add_submodule(fifo, {"write": "sys", "read": "vga"})
+               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,
+                               # FIXME: p0/p1 should be the other way around. Clarify this.
+                               self.vga_r.eq(fifo_out.p0.r),
+                               self.vga_g.eq(fifo_out.p0.g),
+                               self.vga_b.eq(fifo_out.p0.b)
+                       ).Else(
+                               self.vga_r.eq(fifo_out.p1.r),
+                               self.vga_g.eq(fifo_out.p1.g),
+                               self.vga_b.eq(fifo_out.p1.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"]))