// RGB - YCbCr変換
// Y = 0.257R + 0.504G + 0.098B + 16
// Cb = -0.148R - 0.291G + 0.439B + 128
// Cr = 0.439R - 0.368G - 0.071B + 128
// 但し、Yは255以上だったら飽和演算をして255に丸める。Cb, Crは16以下だったら16に、240以上だったら240に飽和演算を行う。
// 0捨1入バージョン
`default_nettype none
module conv_rgb2ycbcr (
input wire [7:0] red,
input wire [7:0] green,
input wire [7:0] blue,
output reg [7:0] y,
output reg [7:0] cb,
output reg [7:0] cr
);
wire [18:0] y_lshift8;
wire [18:0] cb_lshift8;
wire [18:0] cr_lshift8;
assign y_lshift8 = ({5'd0, red, 6'd0} + {10'd0, red, 1'd0}) + ({4'd0, green, 7'd0} + {11'd0, green}) + ({7'd0, blue, 4'd0} + {8'd0, blue, 3'd0} + {11'd0, blue}) + 19'd4096;
assign cb_lshift8 = 19'd0 - ({6'd0, red, 5'd0} + {9'd0, red, 2'd0} + {10'd0, red, 1'd0}) - ({5'd0, green, 6'd0} + {8'd0, green, 3'd0} + {10'd0, green, 1'd0}) + ({5'd0, blue, 6'd0} + {6'd0, blue, 5'd0} + {7'd0, blue, 4'd0}) + 19'd32768;
assign cr_lshift8 = ({5'd0, red, 6'd0} + {6'd0, red, 5'd0} + {7'd0, red, 4'd0}) - ({5'd0, green, 6'd0} + {7'd0, green, 4'd0} + {8'd0, green, 3'd0} + {9'd0, green, 2'd0} + {10'd0, green, 1'd0}) - ({7'd0, blue, 4'd0} + {10'd0, blue , 1'd0}) + 19'd32768;
always @* begin
if (y_lshift8[18]==1'b1 || y_lshift8[17:8]<16) // マイナスまたは16以下なので16に丸める
y <= 8'd16;
else if (y_lshift8[17:8] > 235) // 235より大きければ235に丸める
y <= 8'd235;
else begin
if (y_lshift8[7] == 1'b1) begin
if (y_lshift8[15:8] == 8'd235)
y <= 8'd235;
else
y <= y_lshift8[15:8] + 8'd1;
end else
y <= y_lshift8[15:8];
end
end
always @* begin
if (cb_lshift8[18]==1'b1 || cb_lshift8[17:8]<16) // マイナスまたは16以下なので16に丸める
cb <= 8'd16;
else if (cb_lshift8[17:8] > 240) // 240より大きければ240に丸める
cb <= 8'd240;
else begin
if (cb_lshift8[7] == 1'b1) begin
if (cb_lshift8[15:8] == 8'd240)
cb <= 8'd240;
else
cb <= cb_lshift8[15:8] + 8'd1;
end else
cb <= cb_lshift8[15:8];
end
end
always @* begin
if (cr_lshift8[18]==1'b1 || cr_lshift8[17:8]<16) // マイナスまたは16以下なので16に丸める
cr <= 8'd16;
else if (cr_lshift8[17:8] > 240) // 240より大きければ240に丸める
cr <= 8'd240;
else begin
if (cr_lshift8[7] == 1'b1) begin
if (cr_lshift8[15:8] == 8'd240)
cr <= 8'd240;
else
cr <= cr_lshift8[15:8] + 8'd1;
end else
cr <= cr_lshift8[15:8];
end
end
endmodule
`default_nettype wire
// conv_rgb2ycbcr_top.v
`default_nettype none
module conv_rgb2ycbcr_rd_top (
input wire clk,
input wire reset,
input wire [7:0] red,
input wire [7:0] green,
input wire [7:0] blue,
output reg [7:0] y,
output reg [7:0] cb,
output reg [7:0] cr
);
reg [7:0] red_ff, green_ff, blue_ff;
wire [7:0] y_node, cb_node, cr_node;
always @(posedge clk) begin
if (reset) begin
red_ff <= 0;
green_ff <= 0;
blue_ff <= 0;
end else begin
red_ff <= red;
green_ff <= green;
blue_ff <= blue;
end
end
conv_rgb2ycbcr_round_down conv_rgb2ycbcr_rd_inst (
.red(red_ff),
.green(green_ff),
.blue(blue_ff),
.y(y_node),
.cb(cb_node),
.cr(cr_node)
);
always @(posedge clk) begin
if (reset) begin
y <= 0;
cb <= 0;
cr <= 0;
end else begin
y <= y_node;
cb <= cb_node;
cr <= cr_node;
end
end
endmodule
`default_nettype wire
| 日 | 月 | 火 | 水 | 木 | 金 | 土 |
|---|---|---|---|---|---|---|
| - | - | - | - | - | - | 1 |
| 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| 9 | 10 | 11 | 12 | 13 | 14 | 15 |
| 16 | 17 | 18 | 19 | 20 | 21 | 22 |
| 23 | 24 | 25 | 26 | 27 | 28 | 29 |
| 30 | - | - | - | - | - | - |