module video_raw_to_rgb
		#(
			parameter	WB_ADR_WIDTH  = 8,
			parameter	WB_DAT_WIDTH  = 32,
			parameter	WB_SEL_WIDTH  = (WB_DAT_WIDTH / 8),
			
			parameter	DATA_WIDTH    = 10,
			
			parameter	IMG_Y_NUM     = 480,
			parameter	IMG_Y_WIDTH   = 12,
			
			parameter	TUSER_WIDTH   = 1,
			parameter	S_TDATA_WIDTH = DATA_WIDTH,
			parameter	M_TDATA_WIDTH = 4*DATA_WIDTH
		)
		(
			input	wire						aresetn,
			input	wire						aclk,
			
			input	wire						s_wb_rst_i,
			input	wire						s_wb_clk_i,
			input	wire	[WB_ADR_WIDTH-1:0]	s_wb_adr_i,
			input	wire	[WB_DAT_WIDTH-1:0]	s_wb_dat_i,
			output	wire	[WB_DAT_WIDTH-1:0]	s_wb_dat_o,
			input	wire						s_wb_we_i,
			input	wire	[WB_SEL_WIDTH-1:0]	s_wb_sel_i,
			input	wire						s_wb_stb_i,
			output	wire						s_wb_ack_o,
			
			input	wire	[TUSER_WIDTH-1:0]	s_axi4s_tuser,
			input	wire						s_axi4s_tlast,
			input	wire	[S_TDATA_WIDTH-1:0]	s_axi4s_tdata,
			input	wire						s_axi4s_tvalid,
			output	wire						s_axi4s_tready,
			
			output	wire	[TUSER_WIDTH-1:0]	m_axi4s_tuser,
			output	wire						m_axi4s_tlast,
			output	wire	[M_TDATA_WIDTH-1:0]	m_axi4s_tdata,
			output	wire						m_axi4s_tvalid,
			input	wire						m_axi4s_tready
		);
	
	localparam	USE_VALID  = 0;
	localparam	USER_WIDTH = TUSER_WIDTH > 1 ? TUSER_WIDTH - 1: 1;
	
	wire								reset = ~aresetn;
	wire								clk   = aclk;
	wire								cke;
	
	wire								src_img_line_first;
	wire								src_img_line_last;
	wire								src_img_pixel_first;
	wire								src_img_pixel_last;
	wire								src_img_de;
	wire	[USER_WIDTH-1:0]			src_img_user;
	wire	[S_TDATA_WIDTH-1:0]			src_img_data;
	wire								src_img_valid;
	
	wire								sink_img_line_first;
	wire								sink_img_line_last;
	wire								sink_img_pixel_first;
	wire								sink_img_pixel_last;
	wire								sink_img_de;
	wire	[USER_WIDTH-1:0]			sink_img_user;
	wire	[M_TDATA_WIDTH-1:0]			sink_img_data;
	wire								sink_img_valid;
	
	// img
	jelly_axi4s_img
			#(
				.TUSER_WIDTH			(TUSER_WIDTH),
				.S_TDATA_WIDTH			(DATA_WIDTH),
				.M_TDATA_WIDTH			(4*DATA_WIDTH),
				.IMG_Y_NUM				(IMG_Y_NUM),
				.IMG_Y_WIDTH			(IMG_Y_WIDTH),
				.BLANK_Y_WIDTH			(8),
				.IMG_CKE_BUFG			(0)
			)
		jelly_axi4s_img
			(
				.reset					(reset),
				.clk					(clk),
				
				.param_blank_num		(8'h00),
				
				.s_axi4s_tdata			(s_axi4s_tdata),
				.s_axi4s_tlast			(s_axi4s_tlast),
				.s_axi4s_tuser			(s_axi4s_tuser),
				.s_axi4s_tvalid			(s_axi4s_tvalid),
				.s_axi4s_tready			(s_axi4s_tready),
				
				.m_axi4s_tdata			(m_axi4s_tdata),
				.m_axi4s_tlast			(m_axi4s_tlast),
				.m_axi4s_tuser			(m_axi4s_tuser),
				.m_axi4s_tvalid			(m_axi4s_tvalid),
				.m_axi4s_tready			(m_axi4s_tready),
				
				
				.img_cke				(cke),
				
				.src_img_line_first		(src_img_line_first),
				.src_img_line_last		(src_img_line_last),
				.src_img_pixel_first	(src_img_pixel_first),
				.src_img_pixel_last		(src_img_pixel_last),
				.src_img_de				(src_img_de),
				.src_img_user			(src_img_user),
				.src_img_data			(src_img_data),
				.src_img_valid			(src_img_valid),
				
				.sink_img_line_first	(sink_img_line_first),
				.sink_img_line_last		(sink_img_line_last),
				.sink_img_pixel_first	(sink_img_pixel_first),
				.sink_img_pixel_last	(sink_img_pixel_last),
				.sink_img_user			(sink_img_user),
				.sink_img_de			(sink_img_de),
				.sink_img_data			(sink_img_data),
				.sink_img_valid			(sink_img_valid)
			);
	
	
	
	// demosaic
	wire								demosaic_img_line_first;
	wire								demosaic_img_line_last;
	wire								demosaic_img_pixel_first;
	wire								demosaic_img_pixel_last;
	wire								demosaic_img_de;
	wire	[USER_WIDTH-1:0]			demosaic_img_user;
	wire	[DATA_WIDTH-1:0]			demosaic_img_raw;
	wire	[DATA_WIDTH-1:0]			demosaic_img_r;
	wire	[DATA_WIDTH-1:0]			demosaic_img_g;
	wire	[DATA_WIDTH-1:0]			demosaic_img_b;
	wire								demosaic_img_valid;
	
	wire	[WB_DAT_WIDTH-1:0]			wb_demosaic_dat_o;
	wire								wb_demosaic_stb_i;
	wire								wb_demosaic_ack_o;
	
	jelly_img_demosaic_acpi
			#(
				.USER_WIDTH				(TUSER_WIDTH),
				.DATA_WIDTH				(DATA_WIDTH),
				.MAX_X_NUM				(4096),
				.RAM_TYPE				("block"),
				.USE_VALID				(USE_VALID),
				
				.WB_ADR_WIDTH			(6),
				.WB_DAT_WIDTH			(WB_DAT_WIDTH),
				
				.INIT_PARAM_PHASE		(2'b11)
			)
		i_img_demosaic_acpi
			(
				.reset					(reset),
				.clk					(clk),
				.cke					(cke),
				
				.s_wb_rst_i				(s_wb_rst_i),
				.s_wb_clk_i				(s_wb_clk_i),
				.s_wb_adr_i				(s_wb_adr_i[5:0]),
				.s_wb_dat_i				(s_wb_dat_i),
				.s_wb_dat_o				(wb_demosaic_dat_o),
				.s_wb_we_i				(s_wb_we_i),
				.s_wb_sel_i				(s_wb_sel_i),
				.s_wb_stb_i				(wb_demosaic_stb_i),
				.s_wb_ack_o				(wb_demosaic_ack_o),
				
				.s_img_line_first		(src_img_line_first),
				.s_img_line_last		(src_img_line_last),
				.s_img_pixel_first		(src_img_pixel_first),
				.s_img_pixel_last		(src_img_pixel_last),
				.s_img_de				(src_img_de),
				.s_img_user				(src_img_user),
				.s_img_raw				(src_img_data),
				.s_img_valid			(src_img_valid),
				
				.m_img_line_first		(demosaic_img_line_first),
				.m_img_line_last		(demosaic_img_line_last),
				.m_img_pixel_first		(demosaic_img_pixel_first),
				.m_img_pixel_last		(demosaic_img_pixel_last),
				.m_img_de				(demosaic_img_de),
				.m_img_user				(demosaic_img_user),
				.m_img_raw				(demosaic_img_raw),
				.m_img_r				(demosaic_img_r),
				.m_img_g				(demosaic_img_g),
				.m_img_b				(demosaic_img_b),
				.m_img_valid			(demosaic_img_valid)
			);
	
	
	wire	[WB_DAT_WIDTH-1:0]			wb_matrix_dat_o;
	wire								wb_matrix_stb_i;
	wire								wb_matrix_ack_o;
	
	jelly_img_color_matrix
			#(
				.USER_WIDTH           	(USER_WIDTH+DATA_WIDTH),
				.DATA_WIDTH           	(DATA_WIDTH),
				.INTERNAL_WIDTH       	(DATA_WIDTH+2),
				
				.COEFF_INT_WIDTH      	(9),
				.COEFF_FRAC_WIDTH     	(16),
				.COEFF3_INT_WIDTH     	(9),
				.COEFF3_FRAC_WIDTH    	(16),
				.STATIC_COEFF         	(1),
				.DEVICE               	("7SERIES"),
				
				.WB_ADR_WIDTH			(6),
				.WB_DAT_WIDTH			(WB_DAT_WIDTH),
				
				.INIT_PARAM_MATRIX00  	(2 << 16),
				.INIT_PARAM_MATRIX01  	(0),
				.INIT_PARAM_MATRIX02  	(0),
				.INIT_PARAM_MATRIX03  	(0),
				.INIT_PARAM_MATRIX10  	(0),
				.INIT_PARAM_MATRIX11  	(1 << 16),
				.INIT_PARAM_MATRIX12  	(0),
				.INIT_PARAM_MATRIX13  	(0),
				.INIT_PARAM_MATRIX20  	(0),
				.INIT_PARAM_MATRIX21  	(0),
				.INIT_PARAM_MATRIX22  	(2 << 16),
				.INIT_PARAM_MATRIX23  	(0),
				.INIT_PARAM_CLIP_MIN0 	({DATA_WIDTH{1'b0}}),
				.INIT_PARAM_CLIP_MAX0 	({DATA_WIDTH{1'b1}}),
				.INIT_PARAM_CLIP_MIN1 	({DATA_WIDTH{1'b0}}),
				.INIT_PARAM_CLIP_MAX1 	({DATA_WIDTH{1'b1}}),
				.INIT_PARAM_CLIP_MIN2 	({DATA_WIDTH{1'b0}}),
				.INIT_PARAM_CLIP_MAX2 	({DATA_WIDTH{1'b1}})
			)
		i_img_color_matrix
			(
				.reset					(reset),
				.clk					(clk),
				.cke					(cke),
				
				.s_wb_rst_i				(s_wb_rst_i),
				.s_wb_clk_i				(s_wb_clk_i),
				.s_wb_adr_i				(s_wb_adr_i[5:0]),
				.s_wb_dat_i				(s_wb_dat_i),
				.s_wb_dat_o				(wb_matrix_dat_o),
				.s_wb_we_i				(s_wb_we_i),
				.s_wb_sel_i				(s_wb_sel_i),
				.s_wb_stb_i				(wb_matrix_stb_i),
				.s_wb_ack_o				(wb_matrix_ack_o),
				
				.s_img_line_first		(demosaic_img_line_first),
				.s_img_line_last		(demosaic_img_line_last),
				.s_img_pixel_first		(demosaic_img_pixel_first),
				.s_img_pixel_last		(demosaic_img_pixel_last),
				.s_img_de				(demosaic_img_de),
				.s_img_user				({demosaic_img_user, demosaic_img_raw}),
				.s_img_color0			(demosaic_img_r),
				.s_img_color1			(demosaic_img_g),
				.s_img_color2			(demosaic_img_b),
				.s_img_valid			(demosaic_img_valid),
				
				.m_img_line_first		(sink_img_line_first),
				.m_img_line_last		(sink_img_line_last),
				.m_img_pixel_first		(sink_img_pixel_first),
				.m_img_pixel_last		(sink_img_pixel_last),
				.m_img_de				(sink_img_de),
				.m_img_user				({sink_img_user, sink_img_data[DATA_WIDTH*3 +: DATA_WIDTH]}),
				.m_img_color0			(sink_img_data[DATA_WIDTH*2 +: DATA_WIDTH]),
				.m_img_color1			(sink_img_data[DATA_WIDTH*1 +: DATA_WIDTH]),
				.m_img_color2			(sink_img_data[DATA_WIDTH*0 +: DATA_WIDTH]),
				.m_img_valid			(sink_img_valid)
			);
	
	assign wb_demosaic_stb_i = s_wb_stb_i & (s_wb_adr_i[WB_ADR_WIDTH-1:6] == 0);
	assign wb_matrix_stb_i   = s_wb_stb_i & (s_wb_adr_i[WB_ADR_WIDTH-1:6] == 1);
	
	assign s_wb_dat_o        = wb_demosaic_stb_i ? wb_demosaic_dat_o :
	                           wb_matrix_stb_i   ? wb_matrix_dat_o   :
	                           32'h0000_0000;
	
	assign s_wb_ack_o        = wb_demosaic_stb_i ? wb_demosaic_ack_o :
	                           wb_matrix_stb_i   ? wb_matrix_ack_o   :
	                           s_wb_stb_i;
	
	
	
endmodule