From d008721da61980a87a21fd01ab0e11bfa3e096a9 Mon Sep 17 00:00:00 2001 From: Gyorgy Szombathelyi Date: Tue, 15 Jun 2021 14:21:13 +0200 Subject: [PATCH] MiST: replace rgb2ypbpr --- common/mist/mist.qip | 2 +- common/mist/mist_video.v | 31 ++++++------ common/mist/rgb2ypbpr.sv | 55 --------------------- common/mist/rgb2ypbpr.v | 103 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 120 insertions(+), 71 deletions(-) delete mode 100644 common/mist/rgb2ypbpr.sv create mode 100644 common/mist/rgb2ypbpr.v diff --git a/common/mist/mist.qip b/common/mist/mist.qip index 46cde4bc..de360210 100644 --- a/common/mist/mist.qip +++ b/common/mist/mist.qip @@ -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] diff --git a/common/mist/mist_video.v b/common/mist/mist_video.v index a0142aba..39774525 100644 --- a/common/mist/mist_video.v +++ b/common/mist/mist_video.v @@ -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) diff --git a/common/mist/rgb2ypbpr.sv b/common/mist/rgb2ypbpr.sv deleted file mode 100644 index 1e1662e8..00000000 --- a/common/mist/rgb2ypbpr.sv +++ /dev/null @@ -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 diff --git a/common/mist/rgb2ypbpr.v b/common/mist/rgb2ypbpr.v new file mode 100644 index 00000000..ee3afc1a --- /dev/null +++ b/common/mist/rgb2ypbpr.v @@ -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