1 from migen
.fhdl
.structure
import *
2 from migen
.flow
.actor
import *
3 from migen
.flow
.network
import *
4 from migen
.flow
import plumbing
5 from migen
.actorlib
import misc
, dma_asmi
, structuring
, sim
6 from migen
.bank
.description
import *
7 from migen
.bank
import csrgen
18 ("pad", BV(_bpp
-3*_bpc
))
30 class _FrameInitiator(Actor
):
31 def __init__(self
, asmi_bits
, length_bits
, alignment_bits
):
32 self
._alignment
_bits
= alignment_bits
34 self
._enable
= RegisterField("enable")
36 self
._hres
= RegisterField("hres", _hbits
, reset
=640)
37 self
._hsync
_start
= RegisterField("hsync_start", _hbits
, reset
=656)
38 self
._hsync
_end
= RegisterField("hsync_end", _hbits
, reset
=752)
39 self
._hscan
= RegisterField("hscan", _hbits
, reset
=799)
41 self
._vres
= RegisterField("vres", _vbits
, reset
=480)
42 self
._vsync
_start
= RegisterField("vsync_start", _vbits
, reset
=492)
43 self
._vsync
_end
= RegisterField("vsync_end", _vbits
, reset
=494)
44 self
._vscan
= RegisterField("vscan", _vbits
, reset
=524)
46 self
._base
= RegisterField("base", asmi_bits
+ self
._alignment
_bits
)
47 self
._length
= RegisterField("length", length_bits
+ self
._alignment
_bits
, reset
=640*480*4)
51 ("hsync_start", BV(_hbits
)),
52 ("hsync_end", BV(_hbits
)),
53 ("hscan", BV(_hbits
)),
55 ("vsync_start", BV(_vbits
)),
56 ("vsync_end", BV(_vbits
)),
57 ("vscan", BV(_vbits
)),
58 ("base", BV(asmi_bits
)),
59 ("length", BV(length_bits
))
61 super().__init
__(("frame", Source
, layout
))
63 def get_registers(self
):
65 self
._hres
, self
._hsync
_start
, self
._hsync
_end
, self
._hscan
,
66 self
._vres
, self
._vsync
_start
, self
._vsync
_end
, self
._vscan
,
67 self
._base
, self
._length
]
69 def get_fragment(self
):
70 # TODO: make address updates atomic
71 token
= self
.token("frame")
72 stb
= self
.endpoints
["frame"].stb
73 ack
= self
.endpoints
["frame"].ack
76 token
.hres
.eq(self
._hres
.field
.r
),
77 token
.hsync_start
.eq(self
._hsync
_start
.field
.r
),
78 token
.hsync_end
.eq(self
._hsync
_end
.field
.r
),
79 token
.hscan
.eq(self
._hscan
.field
.r
),
80 token
.vres
.eq(self
._vres
.field
.r
),
81 token
.vsync_start
.eq(self
._vsync
_start
.field
.r
),
82 token
.vsync_end
.eq(self
._vsync
_end
.field
.r
),
83 token
.vscan
.eq(self
._vscan
.field
.r
),
84 token
.length
.eq(self
._length
.field
.r
[self
._alignment
_bits
:])
88 stb
.eq(self
._enable
.field
.r
),
89 token
.base
.eq(self
._base
.field
.r
[self
._alignment
_bits
:])
92 return Fragment(comb
, sync
)
99 ("hsync_start", BV(_hbits
)),
100 ("hsync_end", BV(_hbits
)),
101 ("hscan", BV(_hbits
)),
102 ("vres", BV(_vbits
)),
103 ("vsync_start", BV(_vbits
)),
104 ("vsync_end", BV(_vbits
)),
105 ("vscan", BV(_vbits
))]),
106 ("pixels", Sink
, _pixel_layout
),
107 ("dac", Source
, _dac_layout
)
110 def get_fragment(self
):
115 generate_en
= Signal()
116 hcounter
= Signal(BV(_hbits
))
117 vcounter
= Signal(BV(_vbits
))
119 skip
= _bpc
- _bpc_dac
121 active
.eq(hactive
& vactive
),
123 self
.token("dac").r
.eq(self
.token("pixels").r
[skip
:]),
124 self
.token("dac").g
.eq(self
.token("pixels").g
[skip
:]),
125 self
.token("dac").b
.eq(self
.token("pixels").b
[skip
:])
128 generate_en
.eq(self
.endpoints
["timing"].stb
& (~active | self
.endpoints
["pixels"].stb
)),
129 self
.endpoints
["pixels"].ack
.eq(self
.endpoints
["dac"].ack
& active
),
130 self
.endpoints
["dac"].stb
.eq(generate_en
)
132 tp
= self
.token("timing")
134 self
.endpoints
["timing"].ack
.eq(0),
135 If(generate_en
& self
.endpoints
["dac"].ack
,
136 hcounter
.eq(hcounter
+ 1),
138 If(hcounter
== 0, hactive
.eq(1)),
139 If(hcounter
== tp
.hres
, hactive
.eq(0)),
140 If(hcounter
== tp
.hsync_start
, self
.token("dac").hsync
.eq(1)),
141 If(hcounter
== tp
.hsync_end
, self
.token("dac").hsync
.eq(0)),
142 If(hcounter
== tp
.hscan
,
144 If(vcounter
== tp
.vscan
,
146 self
.endpoints
["timing"].ack
.eq(1)
148 vcounter
.eq(vcounter
+ 1)
152 If(vcounter
== 0, vactive
.eq(1)),
153 If(vcounter
== tp
.vres
, vactive
.eq(0)),
154 If(vcounter
== tp
.vsync_start
, self
.token("dac").vsync
.eq(1)),
155 If(vcounter
== tp
.vsync_end
, self
.token("dac").vsync
.eq(0))
159 return Fragment(comb
, sync
)
163 super().__init
__(("dac", Sink
, _dac_layout
))
165 self
.vga_clk
= Signal()
166 self
.vga_hsync_n
= Signal()
167 self
.vga_vsync_n
= Signal()
168 self
.vga_r
= Signal(BV(_bpc_dac
))
169 self
.vga_g
= Signal(BV(_bpc_dac
))
170 self
.vga_b
= Signal(BV(_bpc_dac
))
172 def get_fragment(self
):
173 data_width
= 2+3*_bpc_dac
174 asfifo
= Instance("asfifo",
176 ("data_out", BV(data_width
)),
182 ("clk_read", self
.vga_clk
),
184 ("data_in", BV(data_width
)),
190 ("data_width", data_width
),
194 t
= self
.token("dac")
197 asfifo
.ins
["read_en"].eq(1),
198 Cat(self
.vga_hsync_n
, self
.vga_vsync_n
, self
.vga_r
, self
.vga_g
, self
.vga_b
).eq(asfifo
.outs
["data_out"]),
200 self
.endpoints
["dac"].ack
.eq(~asfifo
.outs
["full"]),
201 asfifo
.ins
["write_en"].eq(self
.endpoints
["dac"].stb
),
202 asfifo
.ins
["data_in"].eq(Cat(~t
.hsync
, ~t
.vsync
, t
.r
, t
.g
, t
.b
)),
205 asfifo
.ins
["rst"].eq(0)
213 print("H/V:" + str(t
.value
["hsync"]) + str(t
.value
["vsync"])
214 + " " + str(t
.value
["r"]) + " " + str(t
.value
["g"]) + " " + str(t
.value
["b"]))
218 def __init__(self
, address
, asmiport
, simulation
=False):
219 asmi_bits
= asmiport
.hub
.aw
220 alignment_bits
= bits_for(asmiport
.hub
.dw
//8) - 1
221 length_bits
= _hbits
+ _vbits
+ 2 - alignment_bits
222 pack_factor
= asmiport
.hub
.dw
//_bpp
223 packed_pixels
= structuring
.pack_layout(_pixel_layout
, pack_factor
)
225 fi
= ActorNode(_FrameInitiator(asmi_bits
, length_bits
, alignment_bits
))
226 adrloop
= ActorNode(misc
.IntSequence(length_bits
, asmi_bits
))
227 adrbuffer
= ActorNode(plumbing
.Buffer
)
228 dma
= ActorNode(dma_asmi
.Reader(asmiport
))
229 datbuffer
= ActorNode(plumbing
.Buffer
)
230 cast
= ActorNode(structuring
.Cast(asmiport
.hub
.dw
, packed_pixels
))
231 unpack
= ActorNode(structuring
.Unpack(pack_factor
, _pixel_layout
))
232 vtg
= ActorNode(VTG())
234 fifo
= ActorNode(sim
.SimActor(sim_fifo_gen(), ("dac", Sink
, _dac_layout
)))
236 fifo
= ActorNode(FIFO())
239 g
.add_connection(fi
, adrloop
, source_subr
=["length", "base"])
240 g
.add_connection(adrloop
, adrbuffer
)
241 g
.add_connection(adrbuffer
, dma
)
242 g
.add_connection(dma
, datbuffer
)
243 g
.add_connection(datbuffer
, cast
)
244 g
.add_connection(cast
, unpack
)
245 g
.add_connection(unpack
, vtg
, sink_ep
="pixels")
246 g
.add_connection(fi
, vtg
, sink_ep
="timing", source_subr
=[
247 "hres", "hsync_start", "hsync_end", "hscan",
248 "vres", "vsync_start", "vsync_end", "vscan"])
249 g
.add_connection(vtg
, fifo
)
250 self
._comp
_actor
= CompositeActor(g
, debugger
=True)
252 self
.bank
= csrgen
.Bank(fi
.actor
.get_registers() + self
._comp
_actor
.get_registers(),
254 self
._comp
_actor
.debugger
.print_map()
258 self
.vga_clk
= fifo
.actor
.vga_clk
261 self
.vga_psave_n
= Signal()
263 self
.vga_hsync_n
= fifo
.actor
.vga_hsync_n
264 self
.vga_vsync_n
= fifo
.actor
.vga_vsync_n
265 self
.vga_sync_n
= Signal()
266 self
.vga_blank_n
= Signal()
268 self
.vga_r
= fifo
.actor
.vga_r
269 self
.vga_g
= fifo
.actor
.vga_g
270 self
.vga_b
= fifo
.actor
.vga_b
272 def get_fragment(self
):
274 self
.vga_sync_n
.eq(0),
275 self
.vga_psave_n
.eq(1),
276 self
.vga_blank_n
.eq(1)
278 return self
.bank
.get_fragment() \
279 + self
._comp
_actor
.get_fragment() \