1
0
mirror of https://github.com/Gehstock/Mist_FPGA.git synced 2026-02-07 00:27:10 +00:00
Files
Gehstock.Mist_FPGA/common/mist/mist_video.v
2019-06-04 16:10:42 +02:00

140 lines
3.3 KiB
Verilog

// A video pipeline for MiST. Just insert between the core video output and the VGA pins
// Provides an optional scandoubler, a rotateable OSD and (optional) RGb->YPbPr conversion
module mist_video
(
// master clock
// it should be 4xpixel clock for the scandoubler
input clk_sys,
// OSD SPI interface
input SPI_SCK,
input SPI_SS3,
input SPI_DI,
// scanlines (00-none 01-25% 10-50% 11-75%)
input [1:0] scanlines,
// 0 = HVSync 31KHz, 1 = CSync 15KHz
input scandoubler_disable,
// YPbPr always uses composite sync
input ypbpr,
// Rotate OSD [0] - rotate [1] - left or right
input [1:0] rotate,
// video in
input [COLOR_DEPTH-1:0] R,
input [COLOR_DEPTH-1:0] G,
input [COLOR_DEPTH-1:0] B,
input HSync,
input VSync,
// MiST video output signals
output [5:0] VGA_R,
output [5:0] VGA_G,
output [5:0] VGA_B,
output VGA_VS,
output VGA_HS
);
parameter OSD_COLOR = 3'd4;
parameter OSD_X_OFFSET = 10'd0;
parameter OSD_Y_OFFSET = 10'd0;
parameter SD_HCNT_WIDTH = 9;
parameter COLOR_DEPTH = 6; // 1-6
wire [5:0] SD_R_O;
wire [5:0] SD_G_O;
wire [5:0] SD_B_O;
wire SD_HS_O;
wire SD_VS_O;
reg [5:0] R_full;
reg [5:0] G_full;
reg [5:0] B_full;
always @(*) begin
if (COLOR_DEPTH == 6) begin
R_full = R;
G_full = G;
B_full = B;
end else if (COLOR_DEPTH == 2) begin
R_full = {3{R}};
G_full = {3{G}};
B_full = {3{B}};
end else if (COLOR_DEPTH == 1) begin
R_full = {6{R}};
G_full = {6{G}};
B_full = {6{B}};
end else begin
R_full = { R, R[COLOR_DEPTH-1 -:(6-COLOR_DEPTH)] };
G_full = { G, G[COLOR_DEPTH-1 -:(6-COLOR_DEPTH)] };
B_full = { B, B[COLOR_DEPTH-1 -:(6-COLOR_DEPTH)] };
end
end
scandoubler #(SD_HCNT_WIDTH, COLOR_DEPTH) scandoubler
(
.clk_sys ( clk_sys ),
.scanlines ( scanlines ),
.hs_in ( HSync ),
.vs_in ( VSync ),
.r_in ( R ),
.g_in ( G ),
.b_in ( B ),
.hs_out ( SD_HS_O ),
.vs_out ( SD_VS_O ),
.r_out ( SD_R_O ),
.g_out ( SD_G_O ),
.b_out ( SD_B_O )
);
wire [5:0] osd_r_o;
wire [5:0] osd_g_o;
wire [5:0] osd_b_o;
osd #(OSD_X_OFFSET, OSD_Y_OFFSET, OSD_COLOR) osd
(
.clk_sys ( clk_sys ),
.rotate ( rotate ),
.SPI_DI ( SPI_DI ),
.SPI_SCK ( SPI_SCK ),
.SPI_SS3 ( SPI_SS3 ),
.R_in ( scandoubler_disable ? R_full : SD_R_O ),
.G_in ( scandoubler_disable ? G_full : SD_G_O ),
.B_in ( scandoubler_disable ? B_full : SD_B_O ),
.HSync ( scandoubler_disable ? HSync : SD_HS_O ),
.VSync ( scandoubler_disable ? VSync : SD_VS_O ),
.R_out ( osd_r_o ),
.G_out ( osd_g_o ),
.B_out ( osd_b_o )
);
wire [5:0] y, pb, pr;
rgb2ypbpr rgb2ypbpr
(
.red ( osd_r_o ),
.green ( osd_g_o ),
.blue ( osd_b_o ),
.y ( y ),
.pb ( pb ),
.pr ( pr )
);
assign VGA_R = ypbpr?pr:osd_r_o;
assign VGA_G = ypbpr? y:osd_g_o;
assign VGA_B = ypbpr?pb:osd_b_o;
wire cs = scandoubler_disable ? ~(HSync ^ VSync) : ~(SD_HS_O ^ SD_VS_O);
wire hs = scandoubler_disable ? HSync : SD_HS_O;
wire vs = scandoubler_disable ? VSync : SD_VS_O;
// a minimig vga->scart cable expects a composite sync signal on the VGA_HS output.
// and VCC on VGA_VS (to switch into rgb mode)
assign VGA_HS = (scandoubler_disable || ypbpr)? cs : hs;
assign VGA_VS = (scandoubler_disable || ypbpr)? 1'b1 : vs;
endmodule