7b8015f1719798804a84ed4d9f7ada6c4cc634b9
1 from migen
.fhdl
.std
import *
2 from migen
.flow
.actor
import *
3 from migen
.flow
.network
import *
4 from migen
.flow
import plumbing
5 from migen
.bank
.description
import CSRStorage
, AutoCSR
6 from migen
.actorlib
import dma_lasmi
, structuring
, sim
, misc
8 from misoclib
.framebuffer
.format
import bpp
, pixel_layout
, FrameInitiator
, VTG
9 from misoclib
.framebuffer
.phy
import Driver
11 class Framebuffer(Module
, AutoCSR
):
12 def __init__(self
, pads_vga
, pads_dvi
, lasmim
, simulation
=False):
13 pack_factor
= lasmim
.dw
//bpp
17 self
.fi
= FrameInitiator(lasmim
.aw
, pack_factor
)
19 intseq
= misc
.IntSequence(lasmim
.aw
, lasmim
.aw
)
20 dma_out
= AbstractActor(plumbing
.Buffer
)
21 g
.add_connection(self
.fi
, intseq
, source_subr
=self
.fi
.dma_subr())
22 g
.add_pipeline(intseq
, AbstractActor(plumbing
.Buffer
), dma_lasmi
.Reader(lasmim
), dma_out
)
24 cast
= structuring
.Cast(lasmim
.dw
, pixel_layout(pack_factor
), reverse_to
=True)
25 vtg
= VTG(pack_factor
)
26 self
.driver
= Driver(pack_factor
, pads_vga
, pads_dvi
)
28 g
.add_connection(self
.fi
, vtg
, source_subr
=self
.fi
.timing_subr
, sink_ep
="timing")
29 g
.add_connection(dma_out
, cast
)
30 g
.add_connection(cast
, vtg
, sink_ep
="pixels")
31 g
.add_connection(vtg
, self
.driver
)
32 self
.submodules
+= CompositeActor(g
)
34 class Blender(PipelinedActor
, AutoCSR
):
35 def __init__(self
, nimages
, pack_factor
, latency
):
36 epixel_layout
= pixel_layout(pack_factor
)
37 sink_layout
= [("i"+str(i
), epixel_layout
) for i
in range(nimages
)]
38 self
.sink
= Sink(sink_layout
)
39 self
.source
= Source(epixel_layout
)
41 for i
in range(nimages
):
43 csr
= CSRStorage(8, name
=name
)
44 setattr(self
, name
, csr
)
45 factors
.append(csr
.storage
)
46 PipelinedActor
.__init
__(self
, latency
)
50 sink_registered
= Record(sink_layout
)
51 self
.sync
+= If(self
.pipe_ce
, sink_registered
.eq(self
.sink
.payload
))
53 imgs
= [getattr(sink_registered
, "i"+str(i
)) for i
in range(nimages
)]
54 outval
= Record(epixel_layout
)
55 for e
in epixel_layout
:
57 inpixs
= [getattr(img
, name
) for img
in imgs
]
58 outpix
= getattr(outval
, name
)
59 for component
in ["r", "g", "b"]:
60 incomps
= [getattr(pix
, component
) for pix
in inpixs
]
61 outcomp
= getattr(outpix
, component
)
62 outcomp_full
= Signal(19)
64 outcomp_full
.eq(sum(incomp
*factor
for incomp
, factor
in zip(incomps
, factors
))),
66 outcomp
.eq(2**10 - 1) # saturate on overflow
68 outcomp
.eq(outcomp_full
[8:18])
73 for i
in range(latency
-1):
74 new_outval
= Record(epixel_layout
)
75 pipe_stmts
.append(new_outval
.eq(outval
))
77 self
.sync
+= If(self
.pipe_ce
, pipe_stmts
)
78 self
.comb
+= self
.source
.payload
.eq(outval
)
80 class MixFramebuffer(Module
, AutoCSR
):
81 def __init__(self
, pads_vga
, pads_dvi
, *lasmims
, blender_latency
=5):
82 assert(all(lasmim
.aw
== lasmims
[0].aw
and lasmim
.dw
== lasmims
[0].dw
83 for lasmim
in lasmims
))
84 pack_factor
= lasmims
[0].dw
//bpp
86 self
.fi
= FrameInitiator(lasmims
[0].aw
, pack_factor
, len(lasmims
))
87 self
.blender
= Blender(len(lasmims
), pack_factor
, blender_latency
)
88 self
.driver
= Driver(pack_factor
, pads_vga
, pads_dvi
)
91 epixel_layout
= pixel_layout(pack_factor
)
92 for n
, lasmim
in enumerate(lasmims
):
93 intseq
= misc
.IntSequence(lasmim
.aw
, lasmim
.aw
)
94 dma_out
= AbstractActor(plumbing
.Buffer
)
95 g
.add_connection(self
.fi
, intseq
, source_subr
=self
.fi
.dma_subr(n
))
96 g
.add_pipeline(intseq
, AbstractActor(plumbing
.Buffer
), dma_lasmi
.Reader(lasmim
), dma_out
)
98 cast
= structuring
.Cast(lasmim
.dw
, epixel_layout
, reverse_to
=True)
99 g
.add_connection(dma_out
, cast
)
100 g
.add_connection(cast
, self
.blender
, sink_subr
=["i"+str(n
)])
102 vtg
= VTG(pack_factor
)
103 g
.add_connection(self
.fi
, vtg
, source_subr
=self
.fi
.timing_subr
, sink_ep
="timing")
104 g
.add_connection(self
.blender
, vtg
, sink_ep
="pixels")
105 g
.add_connection(vtg
, self
.driver
)
106 self
.submodules
+= CompositeActor(g
)