def METHOD_NAME(self, platform):
    m = Module()
    rx    = Signal(5)
    gx    = Signal(5)
    bx    = Signal(5)
    dck   = Signal()
    m.submodules += [
        FFSynchronizer(self.pads.r_t.i, rx),
        FFSynchronizer(self.pads.g_t.i, gx),
        FFSynchronizer(self.pads.b_t.i, bx),
        FFSynchronizer(self.pads.dck_t.i, dck)
    ]
    dck_r = Signal()
    stb   = Signal()
    m.d.sync += [
        dck_r.eq(dck),
        stb.eq(~dck_r & dck)
    ]
    w_en    = Signal()
    w_data  = Signal.like(self.in_fifo.w_data)
    ovf   = Signal()
    ovf_c = Signal()
    m.d.comb += [
        self.in_fifo.w_en.eq(w_en & ~ovf),
        self.in_fifo.w_data.eq(w_data),
    ]
    with m.If(ovf_c):
        m.d.sync += ovf.eq(0)
    with m.Elif(w_en & ~self.in_fifo.w_rdy):
        m.d.sync += ovf.eq(1)
    pixel = Signal(15)
    with m.If(stb):
        m.d.sync += pixel.eq(Cat(rx, gx, bx))
    frame = Signal(5)
    ovf_r = Signal()
    row   = Signal(range(self.rows + 1))
    col   = Signal(range(self.columns))
    m.domains.fsm = ClockDomain()
    with m.FSM(domain="fsm"):
        with m.State("CAPTURE-ROW"):
            with m.If(stb):
                with m.If(row == 0):
                    m.d.sync += [
                        ovf_r.eq(ovf),
                        frame.eq(frame + 1)
                    ]
                    m.d.comb += [
                        ovf_c.eq(1),
                    ]
                    m.next = "SKIP-FIRST-PIXEL"
                with m.Elif(row == self.rows):
                    m.d.fsm += row.eq(0)
                    m.next = "REPORT-FRAME"
                with m.Else():
                    m.next = "REPORT-FRAME"
        with m.State("SKIP-FIRST-PIXEL"):
            with m.If(stb):
                m.next = "REPORT-FRAME"
        with m.State("REPORT-FRAME"):
            m.d.comb += [
                w_data.eq(0x80 | (ovf_r << 6) | (frame << 1) | (row >> 7)),
                w_en.eq(1),
            ]
            m.next = "REPORT-ROW"
        with m.State("REPORT-ROW"):
            m.d.comb += [
                w_data.eq(row & 0x7f),
                w_en.eq(1),
            ]
            m.next = "REPORT-1"
        for (state, offset, nextstate) in (
            ("REPORT-1",  0, "REPORT-2"),
            ("REPORT-2",  5, "REPORT-3"),
            ("REPORT-3", 10, "CAPTURE-PIXEL")
        ):
            with m.State(state):
                m.d.comb += [
                    w_data.eq((pixel >> offset) & 0x1f),
                    w_en.eq(1),
                ]
                m.next = nextstate
        with m.State("CAPTURE-PIXEL"):
            with m.If(stb):
                with m.If(col == self.columns - 1):
                    m.d.fsm += [
                        col.eq(0),
                        row.eq(row + 1),
                    ]
                    m.next = "CAPTURE-ROW"
                with m.Else():
                    m.d.fsm += col.eq(col + 1),
                    m.next = "REPORT-1"
    vblank_cyc = math.ceil(self.vblank * 0.9 * self.sys_clk_freq) # reset at 90% vblank
    timer      = Signal(range(vblank_cyc))
    with m.If(dck):
        with m.If(timer != vblank_cyc):
            m.d.sync += timer.eq(timer + 1)
    with m.Else():
        m.d.sync += timer.eq(0)
    m.d.comb += [
        ResetSignal("fsm").eq((timer == vblank_cyc) | ResetSignal("sync")),
        ClockSignal("fsm").eq(ResetSignal("sync")),
    ]
    return m