module vga_out ( input clk, input ypbpr_full, input ypbpr_en, input hsync, input vsync, input csync, input [23:0] din, output [23:0] dout, output reg hsync_o, output reg vsync_o, output reg csync_o ); 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 [5:0] red = din[23:18]; wire [5:0] green = din[15:10]; wire [5:0] blue = din[7:2]; // http://marsee101.blog19.fc2.com/blog-entry-2311.html // Y = 16 + 0.257*R + 0.504*G + 0.098*B (Y = 0.299*R + 0.587*G + 0.114*B) // Pb = 128 - 0.148*R - 0.291*G + 0.439*B (Pb = -0.169*R - 0.331*G + 0.500*B) // Pr = 128 + 0.439*R - 0.368*G - 0.071*B (Pr = 0.500*R - 0.419*G - 0.081*B) reg [18:0] y_2, pb_2, pr_2; wire [7:0] y = ( y_2[17:8] < 16) ? 8'd16 : ( y_2[17:8] > 235) ? 8'd235 : y_2[15:8]; wire [7:0] pb = (pb_2[17:8] < 16) ? 8'd16 : (pb_2[17:8] > 240) ? 8'd240 : pb_2[15:8]; wire [7:0] pr = (pr_2[17:8] < 16) ? 8'd16 : (pr_2[17:8] > 240) ? 8'd240 : pr_2[15:8]; reg [7:0] y_3, pb_3, pr_3; reg [23:0] din2, din3; reg hsync2, vsync2, csync2; always @(posedge clk) begin y_2 <= 19'd04096 + ({red, 8'd0} + {red, 3'd0}) + ({green, 9'd0} + {green, 2'd0}) + ({blue, 6'd0} + {blue, 5'd0} + {blue, 2'd0}); pb_2 <= 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}); pr_2 <= 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}); y_3 <= {(ypbpr_full ? yuv_full[y -8'd16] : y[7:2]), 2'b00}; pb_3 <= {(ypbpr_full ? yuv_full[pb-8'd16] : pb[7:2]), 2'b00}; pr_3 <= {(ypbpr_full ? yuv_full[pr-8'd16] : pr[7:2]), 2'b00}; hsync_o <= hsync2; hsync2 <= hsync; vsync_o <= vsync2; vsync2 <= vsync; csync_o <= csync2; csync2 <= csync; din2 <= din; din3 <= din2; end assign dout = ypbpr_en ? {pr_3, y_3, pb_3} : din3; endmodule