module pipeline#(parameter DATA_WIDTH = 8)(
clk, rst_n,
in_valid, in_ready, in_data1, in_data2, in_data3,
out_valid, out_ready, out_data1, out_data2, out_data3
);
input clk;
input rst_n;
input in_valid;
output out_ready;
input[DATA_WIDTH-1:0] in_data1;
input[DATA_WIDTH-1:0] in_data2;
input[DATA_WIDTH-1:0] in_data3;
output out_valid;
input in_ready;
output[DATA_WIDTH-1:0] out_data1;
output[DATA_WIDTH-1:0] out_data2;
output[DATA_WIDTH-1:0] out_data3;
reg out_valid;
reg[DATA_WIDTH-1:0] out_data1;
reg[DATA_WIDTH-1:0] out_data2;
reg[DATA_WIDTH-1:0] out_data3;
wire handshake;
//------------------------------------------
//handshake logic
//-----------------------------------------
assign in_ready = out_ready || ~out_valid;
assign handshake = in_valid && in_ready;
//------------------------------------------
//valid
//------------------------------------------
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
out_valid <= 1'b0;
else if(handshake)
out_valid <= in_valid;
end
//--------------------------------------
//data
//------------------------------------
always@(posedge clk)begin
if(handshake)begin
out_data1 <= in_data1;
out_data2 <= in_data2;
out_data2 <= in_data3;
end
end
endmodule
module csc#(parameter DATA_WIDTH = 10)(
clk, rst_n,
i_valid, i_ready, i_r, i_g, i_b,
o_valid, o_ready, o_y, o_u, o_v
);
input clk;
input rst_n;
input i_valid;
output i_ready;
input[DATA_WIDTH-1:0] i_r, i_g, i_b;
output o_valid;
input o_ready;
output[DATA_WIDTH-1:0] o_y, o_u, o_v;
parameter PARA_R_FOR_Y = 8'd54;
parameter PARA_R_FOR_U = 8'd26;
parameter PARA_R_FOR_V = 8'd157;
parameter PARA_G_FOR_Y = 8'd183;
parameter PARA_G_FOR_U = 8'd86;
parameter PARA_G_FOR_V = 8'd143;
parameter PARA_B_FOR_Y = 8'd18;
parameter PARA_B_FOR_U = 8'd112;
parameter PARA_B_FOR_V = 8'd14;
wire[DATA_WIDTH+7:0] i_r_shift7, i_r_shift5, i_r_shift4, i_r_shift3, i_r_shift2, i_r_shift1;
wire[DATA_WIDTH+7:0] i_g_shift6, i_g_shift5, i_g_shift4, i_g_shift3, i_g_shift2, i_g_shift1;
wire[DATA_WIDTH+7:0] i_b_shift7, i_b_shift6, i_b_shift5, i_b_shift4, i_b_shift3, i_b_shift2, i_b_shift1;
wire[DATA_WIDTH+7:0] mult_r_for_y, mult_r_for_u, mult_r_for_v;
wire[DATA_WIDTH+7:0] mult_g_for_y, mult_g_for_u, mult_g_for_v;
wire[DATA_WIDTH+7:0] mult_b_for_y, mult_b_for_u, mult_b_for_v;
wire[DATA_WIDTH+7:0] r_for_y, r_for_u, r_for_v;
wire[DATA_WIDTH+7:0] g_for_y, g_for_u, g_for_v;
wire[DATA_WIDTH+7:0] b_for_y, b_for_u, b_for_v;
wire valid_p1_to_p2;
wire ready_p2_to_p1;
wire[DATA_WIDTH+9:0] add_y, add_u, add_v;
wire[DATA_WIDTH+9:0] temp_y, temp_u, temp_v;
wire[DATA_WIDTH+9:0] result_y, result_u, result_v;
//-------------------------------------------------
//first pipeline for mult
//-------------------------------------------------
assign i_r_shift7 = i_r << 7;
assign i_r_shift5 = i_r << 5;
assign i_r_shift4 = i_r << 4;
assign i_r_shift3 = i_r << 3;
assign i_r_shift2 = i_r << 2;
assign i_r_shift1 = i_r << 1; //red
assign i_g_shift7 = i_g << 7;
assign i_g_shift6 = i_g << 6;
assign i_g_shift5 = i_g << 5;
assign i_g_shift4 = i_g << 4;
assign i_g_shift3 = i_g << 3;
assign i_g_shift2 = i_g << 2;
assign i_g_shift1 = i_g << 1; //green
assign i_b_shift6 = i_b << 6;
assign i_b_shift5 = i_b << 5;
assign i_b_shift4 = i_b << 4;
assign i_b_shift3 = i_b << 3;
assign i_b_shift2 = i_b << 2;
assign i_b_shift1 = i_b << 1; //blue
assign mult_r_for_y = i_r_shift5 + i_r_shift4 + i_r_shift2 + i_r_shift1; //i_r*54
assign mult_r_for_u = i_r_shift4 + i_r_shift3 + i_r_shift1; //i_r*26
assign mult_r_for_v = i_r_shift7 + i_r_shift4 + i_r_shift3 + i_r_shift2 + i_r; //i_r*157
assign mult_g_for_y = i_g_shift7 + i_g_shift5 + i_g_shift4 + i_g_shift2 + i_g_shift1 + i_g; //i_g*183
assign mult_g_for_u = i_g_shift6 + i_g_shift4 + i_g_shift2 + i_g_shift1; //i_g*86
assign mult_g_for_v = i_g_shift7 + i_g_shift3 + i_g_shift2 + i_g_shift1 + i_g; //i_g*143
assign mult_b_for_y = i_b_shift4 + i_b_shift1; //i_b*18
assign mult_b_for_u = i_b_shift6 + i_b_shift5 + i_b_shift4; //i_b*112
assign mult_b_for_v = i_b_shift3 + i_b_shift2 + i_b_shift1; //i_b*14
pipeline #(.DATA_WIDTH(18)) u_ypipe1(.clk(clk), .rst_n(rst_n), .in_valid(i_valid), .in_ready(i_ready), .in_data1(mult_r_for_y), .in_data2(mult_g_for_y), .in_data3(mult_b_for_y), .out_valid(valid_p1_to_p2), .out_ready(ready_p2_to_p1), .out_data1(r_for_y), .out_data2(g_for_y), .out_data3(b_for_y));
pipeline #(.DATA_WIDTH(18)) u_upipe1(.clk(clk), .rst_n(rst_n), .in_valid(i_valid), .in_ready(i_ready), .in_data1(mult_r_for_u), .in_data2(mult_g_for_u), .in_data3(mult_b_for_u), .out_valid(valid_p1_to_p2), .out_ready(ready_p2_to_p1), .out_data1(r_for_u), .out_data2(g_for_u), .out_data3(b_for_u));
pipeline #(.DATA_WIDTH(18)) u_vpipe1(.clk(clk), .rst_n(rst_n), .in_valid(i_valid), .in_ready(i_ready), .in_data1(mult_r_for_v), .in_data2(mult_g_for_v), .in_data3(mult_b_for_v), .out_valid(valid_p1_to_p2), .out_ready(ready_p2_to_p1), .out_data1(r_for_v), .out_data2(g_for_v), .out_data3(b_for_v));
//-----------------------------------------------------------
//second pipeline section for add
//----------------------------------------------------------
assign add_y = r_for_y + g_for_y + b_for_y;
assign add_u = b_for_u - r_for_u - g_for_u;
assign add_v = r_for_v - g_for_v - b_for_v; // according to HT709
assign temp_y = add_y[19:8] + add_y[7];
assign temp_u = add_u[19:8] + add_u[7];
assign temp_v = add_v[19:8] + add_v[7]; // right_shift_8bit and round
assign result_y = (temp_y[11:10] == 2'b00) ? temp_y[9:0] : 10'h3ff;
assign result_u = (temp_u[11:10] == 2'b00) ? temp_u[9:0] : 10'h3ff;
assign result_v = (temp_v[11:10] == 2'b00) ? temp_v[9:0] : 10'h3ff; // select 10bit
pipeline #(.DATA_WIDTH(10)) u_yuvpipe2(.clk(clk), .rst_n(rst_n), .in_valid(valid_p1_to_p2), .in_ready(ready_p2_to_p1), .in_data1(result_y), .in_data2(result_u), .in_data3(result_v), .out_valid(o_valid), .out_ready(o_ready), .out_data1(o_y), .out_data2(o_u), .out_data3(o_v));
endmodule