mirror of
https://github.com/rdolbeau/NuBusFPGA.git
synced 2024-12-23 01:30:32 +00:00
'de' reaches the PHY, so add inframe to cover the whole screen and stabilize the windowboxed modes
This commit is contained in:
parent
f722c396c9
commit
d0d98f1390
@ -12,11 +12,26 @@ from litex.build.io import SDROutput, DDROutput
|
|||||||
|
|
||||||
from litex.soc.cores.video import *
|
from litex.soc.cores.video import *
|
||||||
|
|
||||||
|
|
||||||
|
video_timing_nohwcursor_layout = [
|
||||||
|
# Synchronization signals.
|
||||||
|
("hsync", 1),
|
||||||
|
("vsync", 1),
|
||||||
|
("de", 1),
|
||||||
|
("inframe", 1),
|
||||||
|
# Extended/Optional synchronization signals.
|
||||||
|
("hres", hbits),
|
||||||
|
("vres", vbits),
|
||||||
|
("hcount", hbits),
|
||||||
|
("vcount", vbits),
|
||||||
|
]
|
||||||
|
|
||||||
video_timing_hwcursor_layout = [
|
video_timing_hwcursor_layout = [
|
||||||
# Synchronization signals.
|
# Synchronization signals.
|
||||||
("hsync", 1),
|
("hsync", 1),
|
||||||
("vsync", 1),
|
("vsync", 1),
|
||||||
("de", 1),
|
("de", 1),
|
||||||
|
("inframe", 1),
|
||||||
("hwcursor", 1),
|
("hwcursor", 1),
|
||||||
("hwcursorx", 5),
|
("hwcursorx", 5),
|
||||||
("hwcursory", 5),
|
("hwcursory", 5),
|
||||||
@ -72,7 +87,7 @@ class FBVideoTimingGenerator(Module, AutoCSR):
|
|||||||
self.specials += MultiReg(self.hwcursor_x, _hwcursor_x)
|
self.specials += MultiReg(self.hwcursor_x, _hwcursor_x)
|
||||||
self.specials += MultiReg(self.hwcursor_y, _hwcursor_y)
|
self.specials += MultiReg(self.hwcursor_y, _hwcursor_y)
|
||||||
else:
|
else:
|
||||||
self.source = source = stream.Endpoint(video_timing_layout)
|
self.source = source = stream.Endpoint(video_timing_nohwcursor_layout)
|
||||||
|
|
||||||
# # #
|
# # #
|
||||||
|
|
||||||
@ -106,8 +121,12 @@ class FBVideoTimingGenerator(Module, AutoCSR):
|
|||||||
self.specials += MultiReg(self._vres_end, vres_end)
|
self.specials += MultiReg(self._vres_end, vres_end)
|
||||||
|
|
||||||
# Generate timings.
|
# Generate timings.
|
||||||
|
# whether we're in the visible frame
|
||||||
hactive = Signal()
|
hactive = Signal()
|
||||||
vactive = Signal()
|
vactive = Signal()
|
||||||
|
# whether we're in the picture (including non-visible part of frame for windowboxing)
|
||||||
|
hinframe = Signal()
|
||||||
|
vinframe = Signal()
|
||||||
fsm = FSM(reset_state="IDLE")
|
fsm = FSM(reset_state="IDLE")
|
||||||
fsm = ResetInserter()(fsm)
|
fsm = ResetInserter()(fsm)
|
||||||
self.submodules.fsm = fsm
|
self.submodules.fsm = fsm
|
||||||
@ -115,6 +134,8 @@ class FBVideoTimingGenerator(Module, AutoCSR):
|
|||||||
fsm.act("IDLE",
|
fsm.act("IDLE",
|
||||||
NextValue(hactive, 0),
|
NextValue(hactive, 0),
|
||||||
NextValue(vactive, 0),
|
NextValue(vactive, 0),
|
||||||
|
NextValue(hinframe, 0),
|
||||||
|
NextValue(vinframe, 0),
|
||||||
NextValue(source.hres, hres),
|
NextValue(source.hres, hres),
|
||||||
NextValue(source.vres, vres),
|
NextValue(source.vres, vres),
|
||||||
NextValue(source.hcount, 0),
|
NextValue(source.hcount, 0),
|
||||||
@ -122,6 +143,7 @@ class FBVideoTimingGenerator(Module, AutoCSR):
|
|||||||
NextState("RUN")
|
NextState("RUN")
|
||||||
)
|
)
|
||||||
self.comb += source.de.eq(hactive & vactive) # DE when both HActive and VActive.
|
self.comb += source.de.eq(hactive & vactive) # DE when both HActive and VActive.
|
||||||
|
self.comb += source.inframe.eq(hinframe & vinframe) # InFrame when both HInFrame and VInFrame.
|
||||||
self.sync += source.first.eq((source.hcount == 0) & (source.vcount == 0)),
|
self.sync += source.first.eq((source.hcount == 0) & (source.vcount == 0)),
|
||||||
self.sync += source.last.eq( (source.hcount == hscan) & (source.vcount == vscan)),
|
self.sync += source.last.eq( (source.hcount == hscan) & (source.vcount == vscan)),
|
||||||
fsm.act("RUN",
|
fsm.act("RUN",
|
||||||
@ -132,6 +154,8 @@ class FBVideoTimingGenerator(Module, AutoCSR):
|
|||||||
# Generate HActive / HSync.
|
# Generate HActive / HSync.
|
||||||
If(source.hcount == hres_start, NextValue(hactive, 1)), # Start of HActive.
|
If(source.hcount == hres_start, NextValue(hactive, 1)), # Start of HActive.
|
||||||
If(source.hcount == hres_end, NextValue(hactive, 0)), # End of HActive.
|
If(source.hcount == hres_end, NextValue(hactive, 0)), # End of HActive.
|
||||||
|
If(source.hcount == 0, NextValue(hinframe, 1)), # Start of HInFrame.
|
||||||
|
If(source.hcount == hres, NextValue(hinframe, 0)), # End of HInFrame.
|
||||||
If(source.hcount == hsync_start, NextValue(source.hsync, 1)), # Start of HSync.
|
If(source.hcount == hsync_start, NextValue(source.hsync, 1)), # Start of HSync.
|
||||||
If(source.hcount == hsync_end, NextValue(source.hsync, 0)), # End of HSync.
|
If(source.hcount == hsync_end, NextValue(source.hsync, 0)), # End of HSync.
|
||||||
# End of HScan.
|
# End of HScan.
|
||||||
@ -142,7 +166,9 @@ class FBVideoTimingGenerator(Module, AutoCSR):
|
|||||||
NextValue(source.vcount, source.vcount + 1),
|
NextValue(source.vcount, source.vcount + 1),
|
||||||
# Generate VActive / VSync.
|
# Generate VActive / VSync.
|
||||||
If(source.vcount == vres_start, NextValue(vactive, 1)), # Start of VActive.
|
If(source.vcount == vres_start, NextValue(vactive, 1)), # Start of VActive.
|
||||||
If(source.vcount == vres_end, NextValue(vactive, 0)), # End of HActive.
|
If(source.vcount == vres_end, NextValue(vactive, 0)), # End of VActive.
|
||||||
|
If(source.vcount == 0, NextValue(vinframe, 1)), # Start of VInFrame.
|
||||||
|
If(source.vcount == vres, NextValue(vinframe, 0)), # End of VInFrame.
|
||||||
If(source.vcount == vsync_start, NextValue(source.vsync, 1)), # Start of VSync.
|
If(source.vcount == vsync_start, NextValue(source.vsync, 1)), # Start of VSync.
|
||||||
If(source.vcount == vsync_end, NextValue(source.vsync, 0)), # End of VSync.
|
If(source.vcount == vsync_end, NextValue(source.vsync, 0)), # End of VSync.
|
||||||
# End of VScan.
|
# End of VScan.
|
||||||
|
@ -79,7 +79,7 @@ class VideoFrameBufferMultiDepth(Module, AutoCSR):
|
|||||||
)
|
)
|
||||||
]
|
]
|
||||||
else:
|
else:
|
||||||
self.vtg_sink = vtg_sink = stream.Endpoint(video_timing_layout)
|
self.vtg_sink = vtg_sink = stream.Endpoint(video_timing_nohwcursor_layout)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -89,6 +89,7 @@ class VideoFrameBufferMultiDepth(Module, AutoCSR):
|
|||||||
#source_buf_ready = Signal()
|
#source_buf_ready = Signal()
|
||||||
source_buf_valid = Signal()
|
source_buf_valid = Signal()
|
||||||
source_buf_de = Signal()
|
source_buf_de = Signal()
|
||||||
|
source_buf_inframe = Signal()
|
||||||
source_buf_hsync = Signal()
|
source_buf_hsync = Signal()
|
||||||
source_buf_vsync = Signal()
|
source_buf_vsync = Signal()
|
||||||
data_buf_index = Signal(8)
|
data_buf_index = Signal(8)
|
||||||
@ -100,6 +101,7 @@ class VideoFrameBufferMultiDepth(Module, AutoCSR):
|
|||||||
|
|
||||||
source_buf_b_valid = Signal()
|
source_buf_b_valid = Signal()
|
||||||
source_buf_b_de = Signal()
|
source_buf_b_de = Signal()
|
||||||
|
source_buf_b_inframe = Signal()
|
||||||
source_buf_b_hsync = Signal()
|
source_buf_b_hsync = Signal()
|
||||||
source_buf_b_vsync = Signal()
|
source_buf_b_vsync = Signal()
|
||||||
data_buf_b_index = Signal(8)
|
data_buf_b_index = Signal(8)
|
||||||
@ -111,6 +113,7 @@ class VideoFrameBufferMultiDepth(Module, AutoCSR):
|
|||||||
#source_out_ready = Signal()
|
#source_out_ready = Signal()
|
||||||
source_out_valid = Signal()
|
source_out_valid = Signal()
|
||||||
source_out_de = Signal()
|
source_out_de = Signal()
|
||||||
|
source_out_inframe = Signal()
|
||||||
source_out_hsync = Signal()
|
source_out_hsync = Signal()
|
||||||
source_out_vsync = Signal()
|
source_out_vsync = Signal()
|
||||||
source_out_r = Signal(8)
|
source_out_r = Signal(8)
|
||||||
@ -264,6 +267,7 @@ class VideoFrameBufferMultiDepth(Module, AutoCSR):
|
|||||||
vtg_sink.ready.eq(source_buf_valid & source.ready),
|
vtg_sink.ready.eq(source_buf_valid & source.ready),
|
||||||
),
|
),
|
||||||
source_buf_de.eq(vtg_sink.de),
|
source_buf_de.eq(vtg_sink.de),
|
||||||
|
source_buf_inframe.eq(vtg_sink.inframe),
|
||||||
source_buf_hsync.eq(vtg_sink.hsync),
|
source_buf_hsync.eq(vtg_sink.hsync),
|
||||||
source_buf_vsync.eq(vtg_sink.vsync),
|
source_buf_vsync.eq(vtg_sink.vsync),
|
||||||
Case(self.indexed_mode, {
|
Case(self.indexed_mode, {
|
||||||
@ -284,8 +288,10 @@ class VideoFrameBufferMultiDepth(Module, AutoCSR):
|
|||||||
hwcursorx_buf.eq(vtg_sink.hwcursorx),
|
hwcursorx_buf.eq(vtg_sink.hwcursorx),
|
||||||
hwcursory_buf.eq(vtg_sink.hwcursory),
|
hwcursory_buf.eq(vtg_sink.hwcursory),
|
||||||
]
|
]
|
||||||
|
|
||||||
vga_sync += [
|
vga_sync += [
|
||||||
source_buf_b_de.eq(source_buf_de),
|
source_buf_b_de.eq(source_buf_de),
|
||||||
|
source_buf_b_inframe.eq(source_buf_inframe),
|
||||||
source_buf_b_hsync.eq(source_buf_hsync),
|
source_buf_b_hsync.eq(source_buf_hsync),
|
||||||
source_buf_b_vsync.eq(source_buf_vsync),
|
source_buf_b_vsync.eq(source_buf_vsync),
|
||||||
source_buf_b_valid.eq(source_buf_valid),
|
source_buf_b_valid.eq(source_buf_valid),
|
||||||
@ -303,6 +309,7 @@ class VideoFrameBufferMultiDepth(Module, AutoCSR):
|
|||||||
|
|
||||||
vga_sync += [
|
vga_sync += [
|
||||||
source_out_de.eq(source_buf_b_de),
|
source_out_de.eq(source_buf_b_de),
|
||||||
|
source_out_inframe.eq(source_buf_b_inframe),
|
||||||
source_out_hsync.eq(source_buf_b_hsync),
|
source_out_hsync.eq(source_buf_b_hsync),
|
||||||
source_out_vsync.eq(source_buf_b_vsync),
|
source_out_vsync.eq(source_buf_b_vsync),
|
||||||
source_out_valid.eq(source_buf_b_valid),
|
source_out_valid.eq(source_buf_b_valid),
|
||||||
@ -344,7 +351,7 @@ class VideoFrameBufferMultiDepth(Module, AutoCSR):
|
|||||||
]
|
]
|
||||||
|
|
||||||
self.comb += [
|
self.comb += [
|
||||||
source.de.eq(source_out_de),
|
source.de.eq(source_out_inframe), # inframe, not de
|
||||||
source.hsync.eq(source_out_hsync),
|
source.hsync.eq(source_out_hsync),
|
||||||
source.vsync.eq(source_out_vsync),
|
source.vsync.eq(source_out_vsync),
|
||||||
source.valid.eq(source_out_valid),
|
source.valid.eq(source_out_valid),
|
||||||
|
Loading…
Reference in New Issue
Block a user