module video_dnn_count
		#(
			parameter	NUM_CALSS     = 10,
			parameter	COUNT_WIDTH   = 3,
			parameter	CHANNEL_WIDTH = (1 << COUNT_WIDTH) - 1,
			
			parameter	TUSER_WIDTH   = 1,
			
			parameter	M_SLAVE_REGS  = 1,
			parameter	M_MASTER_REGS = 1,
			
			// local
			parameter	TDATA_WIDTH   = NUM_CALSS * CHANNEL_WIDTH,
			parameter	TCOUNT_WIDTH  = NUM_CALSS * COUNT_WIDTH
		)
		(
			input	wire							aresetn,
			input	wire							aclk,
			input	wire							aclken,
			
			input	wire	[TUSER_WIDTH-1:0]		s_axi4s_tuser,
			input	wire							s_axi4s_tlast,
			input	wire	[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	[TCOUNT_WIDTH-1:0]		m_axi4s_tcount,
			output	wire	[TDATA_WIDTH-1:0]		m_axi4s_tdata,
			output	wire							m_axi4s_tvalid,
			input	wire							m_axi4s_tready
		);
	
	
	wire						cke;
	
	// counting
	integer						i, j;
	integer						sum;
	
	reg							reg_tlast;
	reg		[TUSER_WIDTH-1:0]	reg_tuser;
	reg		[TDATA_WIDTH-1:0]	reg_tdata;
	reg		[TCOUNT_WIDTH-1:0]	reg_tcount;
	reg							reg_tvalid;
	
	always @(posedge aclk) begin
		if( ~aresetn ) begin
			reg_tlast  <= 1'bx;
			reg_tuser  <= {TUSER_WIDTH{1'bx}};
			reg_tcount <= {TCOUNT_WIDTH{1'bx}};
			reg_tvalid <= 1'b0;
		end
		else if ( cke ) begin
			reg_tlast <= s_axi4s_tlast;
			reg_tuser <= s_axi4s_tuser;
			reg_tdata <= s_axi4s_tdata;
			for ( i = 0; i < NUM_CALSS; i = i+1 ) begin
				sum = 0;
				for ( j = 0; j < CHANNEL_WIDTH; j = j+1 ) begin
					sum = sum + s_axi4s_tdata[j*NUM_CALSS + i];
				end
				reg_tcount[COUNT_WIDTH*i +: COUNT_WIDTH] <= sum;
			end
			reg_tvalid  <= s_axi4s_tvalid;
		end
	end
	
	
	// output
	jelly_pipeline_insert_ff
			#(
				.DATA_WIDTH			(TUSER_WIDTH+1+TCOUNT_WIDTH+TDATA_WIDTH),
				.SLAVE_REGS			(M_SLAVE_REGS),
				.MASTER_REGS		(M_MASTER_REGS)
			)
		i_pipeline_insert_ff
			(
				.reset				(~aresetn),
				.clk				(aclk),
				.cke				(aclken),
				
				.s_data				({reg_tuser, reg_tlast, reg_tcount, reg_tdata}),
				.s_valid			(reg_tvalid),
				.s_ready			(s_axi4s_tready),
				
				.m_data				({m_axi4s_tuser, m_axi4s_tlast, m_axi4s_tcount, m_axi4s_tdata}),
				.m_valid			(m_axi4s_tvalid),
				.m_ready			(m_axi4s_tready),
				
				.buffered			(),
				.s_ready_next		()
			);
	
	assign cke = s_axi4s_tready && aclken;
	
	
endmodule