1
0
mirror of https://github.com/Gehstock/Mist_FPGA.git synced 2026-02-16 12:42:49 +00:00

MiST: replace rgb2ypbpr

This commit is contained in:
Gyorgy Szombathelyi
2021-06-15 14:21:13 +02:00
parent 1ca029e184
commit d008721da6
4 changed files with 120 additions and 71 deletions

View File

@@ -5,6 +5,6 @@ set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) mist_vi
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) scandoubler.v]
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) osd.v]
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) arcade_inputs.v]
set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) rgb2ypbpr.sv]
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) rgb2ypbpr.v]
set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) cofi.sv]
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) dac.vhd]

View File

@@ -166,25 +166,26 @@ cofi cofi (
.blue_out( cofi_b )
);
wire [5:0] y, pb, pr;
wire hs, vs;
rgb2ypbpr rgb2ypbpr
RGBtoYPbPr #(6) rgb2ypbpr
(
.red ( cofi_r ),
.green ( cofi_g ),
.blue ( cofi_b ),
.y ( y ),
.pb ( pb ),
.pr ( pr )
.clk ( clk_sys ),
.ena ( ypbpr ),
.red_in ( cofi_r ),
.green_in ( cofi_g ),
.blue_in ( cofi_b ),
.hs_in ( cofi_hs ),
.vs_in ( cofi_vs ),
.red_out ( VGA_R ),
.green_out ( VGA_G ),
.blue_out ( VGA_B ),
.hs_out ( hs ),
.vs_out ( vs )
);
assign VGA_R = ypbpr?pr:cofi_r;
assign VGA_G = ypbpr? y:cofi_g;
assign VGA_B = ypbpr?pb:cofi_b;
wire cs = SYNC_AND ? (cofi_hs & cofi_vs) : ~(cofi_hs ^ cofi_vs);
wire hs = cofi_hs;
wire vs = cofi_vs;
wire cs = SYNC_AND ? (hs & vs) : ~(hs ^ vs);
// 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)

View File

@@ -1,55 +0,0 @@
module rgb2ypbpr (
input [5:0] red,
input [5:0] green,
input [5:0] blue,
output [5:0] y,
output [5:0] pb,
output [5:0] pr
);
wire [5:0] yuv_full[225] = '{
6'd0, 6'd0, 6'd0, 6'd0, 6'd1, 6'd1, 6'd1, 6'd1,
6'd2, 6'd2, 6'd2, 6'd3, 6'd3, 6'd3, 6'd3, 6'd4,
6'd4, 6'd4, 6'd5, 6'd5, 6'd5, 6'd5, 6'd6, 6'd6,
6'd6, 6'd7, 6'd7, 6'd7, 6'd7, 6'd8, 6'd8, 6'd8,
6'd9, 6'd9, 6'd9, 6'd9, 6'd10, 6'd10, 6'd10, 6'd11,
6'd11, 6'd11, 6'd11, 6'd12, 6'd12, 6'd12, 6'd13, 6'd13,
6'd13, 6'd13, 6'd14, 6'd14, 6'd14, 6'd15, 6'd15, 6'd15,
6'd15, 6'd16, 6'd16, 6'd16, 6'd17, 6'd17, 6'd17, 6'd17,
6'd18, 6'd18, 6'd18, 6'd19, 6'd19, 6'd19, 6'd19, 6'd20,
6'd20, 6'd20, 6'd21, 6'd21, 6'd21, 6'd21, 6'd22, 6'd22,
6'd22, 6'd23, 6'd23, 6'd23, 6'd23, 6'd24, 6'd24, 6'd24,
6'd25, 6'd25, 6'd25, 6'd25, 6'd26, 6'd26, 6'd26, 6'd27,
6'd27, 6'd27, 6'd27, 6'd28, 6'd28, 6'd28, 6'd29, 6'd29,
6'd29, 6'd29, 6'd30, 6'd30, 6'd30, 6'd31, 6'd31, 6'd31,
6'd31, 6'd32, 6'd32, 6'd32, 6'd33, 6'd33, 6'd33, 6'd33,
6'd34, 6'd34, 6'd34, 6'd35, 6'd35, 6'd35, 6'd35, 6'd36,
6'd36, 6'd36, 6'd36, 6'd37, 6'd37, 6'd37, 6'd38, 6'd38,
6'd38, 6'd38, 6'd39, 6'd39, 6'd39, 6'd40, 6'd40, 6'd40,
6'd40, 6'd41, 6'd41, 6'd41, 6'd42, 6'd42, 6'd42, 6'd42,
6'd43, 6'd43, 6'd43, 6'd44, 6'd44, 6'd44, 6'd44, 6'd45,
6'd45, 6'd45, 6'd46, 6'd46, 6'd46, 6'd46, 6'd47, 6'd47,
6'd47, 6'd48, 6'd48, 6'd48, 6'd48, 6'd49, 6'd49, 6'd49,
6'd50, 6'd50, 6'd50, 6'd50, 6'd51, 6'd51, 6'd51, 6'd52,
6'd52, 6'd52, 6'd52, 6'd53, 6'd53, 6'd53, 6'd54, 6'd54,
6'd54, 6'd54, 6'd55, 6'd55, 6'd55, 6'd56, 6'd56, 6'd56,
6'd56, 6'd57, 6'd57, 6'd57, 6'd58, 6'd58, 6'd58, 6'd58,
6'd59, 6'd59, 6'd59, 6'd60, 6'd60, 6'd60, 6'd60, 6'd61,
6'd61, 6'd61, 6'd62, 6'd62, 6'd62, 6'd62, 6'd63, 6'd63,
6'd63
};
wire [18:0] y_8 = 19'd04096 + ({red, 8'd0} + {red, 3'd0}) + ({green, 9'd0} + {green, 2'd0}) + ({blue, 6'd0} + {blue, 5'd0} + {blue, 2'd0});
wire [18:0] pb_8 = 19'd32768 - ({red, 7'd0} + {red, 4'd0} + {red, 3'd0}) - ({green, 8'd0} + {green, 5'd0} + {green, 3'd0}) + ({blue, 8'd0} + {blue, 7'd0} + {blue, 6'd0});
wire [18:0] pr_8 = 19'd32768 + ({red, 8'd0} + {red, 7'd0} + {red, 6'd0}) - ({green, 8'd0} + {green, 6'd0} + {green, 5'd0} + {green, 4'd0} + {green, 3'd0}) - ({blue, 6'd0} + {blue , 3'd0});
wire [7:0] y_i = ( y_8[17:8] < 16) ? 8'd16 : ( y_8[17:8] > 235) ? 8'd235 : y_8[15:8];
wire [7:0] pb_i = (pb_8[17:8] < 16) ? 8'd16 : (pb_8[17:8] > 240) ? 8'd240 : pb_8[15:8];
wire [7:0] pr_i = (pr_8[17:8] < 16) ? 8'd16 : (pr_8[17:8] > 240) ? 8'd240 : pr_8[15:8];
assign pr = yuv_full[pr_i - 8'd16];
assign y = yuv_full[y_i - 8'd16];
assign pb = yuv_full[pb_i - 8'd16];
endmodule

103
common/mist/rgb2ypbpr.v Normal file
View File

@@ -0,0 +1,103 @@
// Multiplier-based RGB -> YPbPr conversion
// Copyright 2020/2021 by Alastair M. Robinson
module RGBtoYPbPr
(
input clk,
input ena,
input [WIDTH-1:0] red_in,
input [WIDTH-1:0] green_in,
input [WIDTH-1:0] blue_in,
input hs_in,
input vs_in,
input cs_in,
input pixel_in,
output [WIDTH-1:0] red_out,
output [WIDTH-1:0] green_out,
output [WIDTH-1:0] blue_out,
output reg hs_out,
output reg vs_out,
output reg cs_out,
output reg pixel_out
);
parameter WIDTH = 8;
reg [8+WIDTH-1:0] r_y;
reg [8+WIDTH-1:0] g_y;
reg [8+WIDTH-1:0] b_y;
reg [8+WIDTH-1:0] r_b;
reg [8+WIDTH-1:0] g_b;
reg [8+WIDTH-1:0] b_b;
reg [8+WIDTH-1:0] r_r;
reg [8+WIDTH-1:0] g_r;
reg [8+WIDTH-1:0] b_r;
reg [8+WIDTH-1:0] y;
reg [8+WIDTH-1:0] b;
reg [8+WIDTH-1:0] r;
reg hs_d;
reg vs_d;
reg cs_d;
reg pixel_d;
assign red_out = r[8+WIDTH-1:8];
assign green_out = y[8+WIDTH-1:8];
assign blue_out = b[8+WIDTH-1:8];
// Multiply in the first stage...
always @(posedge clk) begin
hs_d <= hs_in; // Register sync, pixel clock, etc
vs_d <= vs_in; // so they're delayed the same amount as the incoming video
cs_d <= cs_in;
pixel_d <= pixel_in;
if(ena) begin
// (Y = 0.299*R + 0.587*G + 0.114*B)
r_y <= red_in * 8'd76;
g_y <= green_in * 8'd150;
b_y <= blue_in * 8'd29;
// (Pb = -0.169*R - 0.331*G + 0.500*B)
r_b <= red_in * 8'd43;
g_b <= green_in * 8'd84;
b_b <= blue_in * 8'd128;
// (Pr = 0.500*R - 0.419*G - 0.081*B)
r_r <= red_in * 8'd128;
g_r <= green_in * 8'd107;
b_r <= blue_in * 8'd20;
end else begin
r_r[8+WIDTH-1:8] <= red_in; // Passthrough
g_y[8+WIDTH-1:8] <= green_in;
b_b[8+WIDTH-1:8] <= blue_in;
end
end
// Second stage - adding
always @(posedge clk) begin
hs_out <= hs_d;
vs_out <= vs_d;
cs_out <= cs_d;
pixel_out <= pixel_d;
if(ena) begin
y <= r_y + g_y + b_y;
b <= 2'd2**(8+WIDTH-1) + b_b - r_b - g_b;
r <= 2'd2**(8+WIDTH-1) + r_r - g_r - b_r;
end else begin
y <= g_y; // Passthrough
b <= b_b;
r <= r_r;
end
end
endmodule