diff --git a/milkymist/framebuffer/__init__.py b/milkymist/framebuffer/__init__.py index 7a7dbc97f..add483139 100644 --- a/milkymist/framebuffer/__init__.py +++ b/milkymist/framebuffer/__init__.py @@ -2,7 +2,7 @@ from migen.fhdl.structure import * from migen.flow.actor import * from migen.flow.network import * from migen.flow import plumbing -from migen.actorlib import misc, dma_asmi, structuring, sim +from migen.actorlib import misc, dma_asmi, structuring, sim, spi from migen.bank.description import * from migen.bank import csrgen @@ -27,69 +27,23 @@ _dac_layout = [ ("r", BV(_bpc_dac)) ] -class _FrameInitiator(Actor): +class _FrameInitiator(spi.SingleGenerator): def __init__(self, asmi_bits, length_bits, alignment_bits): - self._alignment_bits = alignment_bits - - self._enable = RegisterField("enable") - - self._hres = RegisterField("hres", _hbits, reset=640) - self._hsync_start = RegisterField("hsync_start", _hbits, reset=656) - self._hsync_end = RegisterField("hsync_end", _hbits, reset=752) - self._hscan = RegisterField("hscan", _hbits, reset=799) - - self._vres = RegisterField("vres", _vbits, reset=480) - self._vsync_start = RegisterField("vsync_start", _vbits, reset=492) - self._vsync_end = RegisterField("vsync_end", _vbits, reset=494) - self._vscan = RegisterField("vscan", _vbits, reset=524) - - self._base = RegisterField("base", asmi_bits + self._alignment_bits) - self._length = RegisterField("length", length_bits + self._alignment_bits, reset=640*480*4) - layout = [ - ("hres", BV(_hbits)), - ("hsync_start", BV(_hbits)), - ("hsync_end", BV(_hbits)), - ("hscan", BV(_hbits)), - ("vres", BV(_vbits)), - ("vsync_start", BV(_vbits)), - ("vsync_end", BV(_vbits)), - ("vscan", BV(_vbits)), - ("base", BV(asmi_bits)), - ("length", BV(length_bits)) + ("hres", BV(_hbits), 640), + ("hsync_start", BV(_hbits), 656), + ("hsync_end", BV(_hbits), 752), + ("hscan", BV(_hbits), 799), + + ("vres", BV(_vbits), 480), + ("vsync_start", BV(_vbits), 492), + ("vsync_end", BV(_vbits), 494), + ("vscan", BV(_vbits), 524), + + ("base", BV(asmi_bits), 0, alignment_bits), + ("length", BV(length_bits), 640*480*4, alignment_bits) ] - super().__init__(("frame", Source, layout)) - - def get_registers(self): - return [self._enable, - self._hres, self._hsync_start, self._hsync_end, self._hscan, - self._vres, self._vsync_start, self._vsync_end, self._vscan, - self._base, self._length] - - def get_fragment(self): - # TODO: make address updates atomic - token = self.token("frame") - stb = self.endpoints["frame"].stb - ack = self.endpoints["frame"].ack - comb = [ - self.busy.eq(stb), - token.hres.eq(self._hres.field.r), - token.hsync_start.eq(self._hsync_start.field.r), - token.hsync_end.eq(self._hsync_end.field.r), - token.hscan.eq(self._hscan.field.r), - token.vres.eq(self._vres.field.r), - token.vsync_start.eq(self._vsync_start.field.r), - token.vsync_end.eq(self._vsync_end.field.r), - token.vscan.eq(self._vscan.field.r), - token.length.eq(self._length.field.r[self._alignment_bits:]) - ] - sync = [ - If(ack | ~stb, - stb.eq(self._enable.field.r), - token.base.eq(self._base.field.r[self._alignment_bits:]) - ) - ] - return Fragment(comb, sync) + super().__init__(layout, spi.MODE_CONTINUOUS) class VTG(Actor): def __init__(self):