210ec5ce19bd91225fd6a0985b40ab1dea709c01
2 from migen
.flow
.actor
import *
3 from migen
.bank
.description
import CSRStorage
4 from migen
.genlib
.record
import Record
5 from migen
.genlib
.fsm
import FSM
, NextState
6 from migen
.actorlib
import spi
21 def pixel_layout(pack_factor
):
22 return [("p"+str(i
), pixel_layout_s
) for i
in range(pack_factor
)]
32 def phy_layout(pack_factor
):
33 r
= [("hsync", 1), ("vsync", 1), ("de", 1)]
34 for i
in range(pack_factor
):
35 r
.append(("p"+str(i
), phy_layout_s
))
39 class FrameInitiator(spi
.SingleGenerator
):
40 def __init__(self
, bus_aw
, pack_factor
, ndmas
=1):
41 h_alignment_bits
= log2_int(pack_factor
)
42 hbits_dyn
= _hbits
- h_alignment_bits
43 bus_alignment_bits
= h_alignment_bits
+ log2_int(bpp
//8)
45 ("hres", hbits_dyn
, 640, h_alignment_bits
),
46 ("hsync_start", hbits_dyn
, 656, h_alignment_bits
),
47 ("hsync_end", hbits_dyn
, 752, h_alignment_bits
),
48 ("hscan", hbits_dyn
, 800, h_alignment_bits
),
50 ("vres", _vbits
, 480),
51 ("vsync_start", _vbits
, 492),
52 ("vsync_end", _vbits
, 494),
53 ("vscan", _vbits
, 525),
55 ("length", bus_aw
+ bus_alignment_bits
, 640*480*bpp
//8, bus_alignment_bits
)
57 layout
+= [("base"+str(i
), bus_aw
+ bus_alignment_bits
, 0, bus_alignment_bits
)
58 for i
in range(ndmas
)]
59 spi
.SingleGenerator
.__init
__(self
, layout
, spi
.MODE_CONTINUOUS
)
61 timing_subr
= ["hres", "hsync_start", "hsync_end", "hscan",
62 "vres", "vsync_start", "vsync_end", "vscan"]
64 def dma_subr(self
, i
=0):
65 return ["length", "base"+str(i
)]
69 def __init__(self
, pack_factor
):
70 hbits_dyn
= _hbits
- log2_int(pack_factor
)
73 ("hsync_start", hbits_dyn
),
74 ("hsync_end", hbits_dyn
),
77 ("vsync_start", _vbits
),
78 ("vsync_end", _vbits
),
80 self
.timing
= Sink(timing_layout
)
81 self
.pixels
= Sink(pixel_layout(pack_factor
))
82 self
.phy
= Source(phy_layout(pack_factor
))
91 hcounter
= Signal(hbits_dyn
)
92 vcounter
= Signal(_vbits
)
96 active
.eq(hactive
& vactive
),
98 [getattr(getattr(self
.phy
.payload
, p
), c
).eq(getattr(getattr(self
.pixels
.payload
, p
), c
)[skip
:])
99 for p
in ["p"+str(i
) for i
in range(pack_factor
)] for c
in ["r", "g", "b"]],
102 self
.pixels
.ack
.eq(self
.phy
.ack
& active
)
105 load_timing
= Signal()
106 tr
= Record(timing_layout
)
107 self
.sync
+= If(load_timing
, tr
.eq(self
.timing
.payload
))
109 generate_en
= Signal()
110 generate_frame_done
= Signal()
112 generate_frame_done
.eq(0),
114 hcounter
.eq(hcounter
+ 1),
116 If(hcounter
== 0, hactive
.eq(1)),
117 If(hcounter
== tr
.hres
, hactive
.eq(0)),
118 If(hcounter
== tr
.hsync_start
, self
.phy
.hsync
.eq(1)),
119 If(hcounter
== tr
.hsync_end
, self
.phy
.hsync
.eq(0)),
120 If(hcounter
== tr
.hscan
,
122 If(vcounter
== tr
.vscan
,
124 generate_frame_done
.eq(1)
126 vcounter
.eq(vcounter
+ 1)
130 If(vcounter
== 0, vactive
.eq(1)),
131 If(vcounter
== tr
.vres
, vactive
.eq(0)),
132 If(vcounter
== tr
.vsync_start
, self
.phy
.vsync
.eq(1)),
133 If(vcounter
== tr
.vsync_end
, self
.phy
.vsync
.eq(0))
137 self
.submodules
.fsm
= FSM()
138 self
.fsm
.act("GET_TIMING",
139 self
.timing
.ack
.eq(1),
141 If(self
.timing
.stb
, NextState("GENERATE"))
143 self
.fsm
.act("GENERATE",
145 If(~active | self
.pixels
.stb
,
147 If(self
.phy
.ack
, generate_en
.eq(1))
149 If(generate_frame_done
, NextState("GET_TIMING"))