70fb69717d76462ad3414511cf3665d1c4b33349
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",
175 Instance
.Parameter("data_width", data_width
),
176 Instance
.Parameter("address_width", 8),
178 Instance
.Output("data_out", BV(data_width
)),
179 Instance
.Output("empty", BV(1)),
180 Instance
.Input("read_en", BV(1)),
181 Instance
.Input("clk_read", self
.vga_clk
),
183 Instance
.Input("data_in", BV(data_width
)),
184 Instance
.Output("full", BV(1)),
185 Instance
.Input("write_en", BV(1)),
186 Instance
.ClockPort("clk_write"),
188 Instance
.Input("rst", BV(1)))
189 t
= self
.token("dac")
192 asfifo
.get_io("read_en").eq(1),
193 Cat(self
.vga_hsync_n
, self
.vga_vsync_n
, self
.vga_r
, self
.vga_g
, self
.vga_b
).eq(asfifo
.get_io("data_out")),
195 self
.endpoints
["dac"].ack
.eq(~asfifo
.get_io("full")),
196 asfifo
.get_io("write_en").eq(self
.endpoints
["dac"].stb
),
197 asfifo
.get_io("data_in").eq(Cat(~t
.hsync
, ~t
.vsync
, t
.r
, t
.g
, t
.b
)),
200 asfifo
.get_io("rst").eq(0)
208 print("H/V:" + str(t
.value
["hsync"]) + str(t
.value
["vsync"])
209 + " " + str(t
.value
["r"]) + " " + str(t
.value
["g"]) + " " + str(t
.value
["b"]))
213 def __init__(self
, address
, asmiport
, simulation
=False):
214 asmi_bits
= asmiport
.hub
.aw
215 alignment_bits
= bits_for(asmiport
.hub
.dw
//8) - 1
216 length_bits
= _hbits
+ _vbits
+ 2 - alignment_bits
217 pack_factor
= asmiport
.hub
.dw
//_bpp
218 packed_pixels
= structuring
.pack_layout(_pixel_layout
, pack_factor
)
220 fi
= ActorNode(_FrameInitiator(asmi_bits
, length_bits
, alignment_bits
))
221 adrloop
= ActorNode(misc
.IntSequence(length_bits
, asmi_bits
))
222 adrbuffer
= ActorNode(plumbing
.Buffer
)
223 dma
= ActorNode(dma_asmi
.Reader(asmiport
))
224 datbuffer
= ActorNode(plumbing
.Buffer
)
225 cast
= ActorNode(structuring
.Cast(asmiport
.hub
.dw
, packed_pixels
))
226 unpack
= ActorNode(structuring
.Unpack(pack_factor
, _pixel_layout
))
227 vtg
= ActorNode(VTG())
229 fifo
= ActorNode(sim
.SimActor(sim_fifo_gen(), ("dac", Sink
, _dac_layout
)))
231 fifo
= ActorNode(FIFO())
234 g
.add_connection(fi
, adrloop
, source_subr
=["length", "base"])
235 g
.add_connection(adrloop
, adrbuffer
)
236 g
.add_connection(adrbuffer
, dma
)
237 g
.add_connection(dma
, datbuffer
)
238 g
.add_connection(datbuffer
, cast
)
239 g
.add_connection(cast
, unpack
)
240 g
.add_connection(unpack
, vtg
, sink_ep
="pixels")
241 g
.add_connection(fi
, vtg
, sink_ep
="timing", source_subr
=[
242 "hres", "hsync_start", "hsync_end", "hscan",
243 "vres", "vsync_start", "vsync_end", "vscan"])
244 g
.add_connection(vtg
, fifo
)
245 self
._comp
_actor
= CompositeActor(g
, debugger
=False)
247 self
.bank
= csrgen
.Bank(fi
.actor
.get_registers() + self
._comp
_actor
.get_registers(),
252 self
.vga_clk
= fifo
.actor
.vga_clk
255 self
.vga_psave_n
= Signal()
257 self
.vga_hsync_n
= fifo
.actor
.vga_hsync_n
258 self
.vga_vsync_n
= fifo
.actor
.vga_vsync_n
259 self
.vga_sync_n
= Signal()
260 self
.vga_blank_n
= Signal()
262 self
.vga_r
= fifo
.actor
.vga_r
263 self
.vga_g
= fifo
.actor
.vga_g
264 self
.vga_b
= fifo
.actor
.vga_b
266 def get_fragment(self
):
268 self
.vga_sync_n
.eq(0),
269 self
.vga_psave_n
.eq(1),
270 self
.vga_blank_n
.eq(1)
272 return self
.bank
.get_fragment() \
273 + self
._comp
_actor
.get_fragment() \