module systolicFilterBlockTest # (
	parameter CoeffCount = 64
)
(
	input Clk_i,
	input Rst_i,
	input [17:0] Data_i,
	input [2:0]  DecimFactor_i,
	input DataNd_i,
	output [47:0] Data_o,
	output DataValid_o
);

	`include "CoeffsForR2.vh"
	`include "CoeffsForR3.vh"
	// `include "CoeffsForR4.vh"
	// `include "CoeffsForR5.vh"
	// `include "CoeffsForR6.vh"
	// `include "CoeffsForR7.vh"

	// wire signed [17:0] coeff[0:CoeffCount-1];
	reg	 signed [17:0] coeff[0:CoeffCount-1];
	wire signed [17:0] dataIn = Data_i;
	// reg [3:0] ndShReg;
	reg [CoeffCount-1:0] ndShReg;
	
	reg [31:0]	testCnt;
	
	wire comRst = (Rst_i|!(DataNd_i|DataValid_o));
	
	always @ (posedge Clk_i)
		if (!Rst_i) begin
			ndShReg <= {ndShReg[CoeffCount-2:0], DataNd_i};
		end else begin
			ndShReg <= 0;
		end
	
	reg signed [17:0] inReg0[0:CoeffCount-1];
	reg signed [17:0] inReg1[0:CoeffCount-1];
	reg signed [34:0] multResult[0:CoeffCount-1];
	reg signed [47:0] sumResult[0:CoeffCount-1];
	
	always	@(posedge	Clk_i)	begin
		if	(!Rst_i)	begin
			if	(DataValid_o)	begin
				testCnt	<=	testCnt+1;
			end	else	begin
				testCnt	<=	0;
			end
		end	else	begin
			testCnt	<=	0;
		end
	end
	genvar i;
	generate
		for (i = 0; i < CoeffCount; i = i + 1)begin 
			always @ (posedge Clk_i) begin
				if (!comRst) begin
					if (DataNd_i) begin
						if (i == 0) begin
							inReg0[i] <= 0;
							inReg1[i] <= dataIn;
						end else begin
							inReg0[i] <= inReg1[i-1];
							inReg1[i] <= inReg0[i];
						end
					end
				
					if (ndShReg[0]|ndShReg[CoeffCount-2]) begin
						case (DecimFactor_i) 
							2:	begin
									multResult[i] <= inReg1[i] * coeffForR2[i];
								end
							3:	begin
									multResult[i] <= inReg1[i] * coeffForR3[i];
								end
							// 4:	begin
									// multResult[i] <= inReg1[i] * coeffForR4[i];
								// end
							// 5:	begin
									// multResult[i] <= inReg1[i] * coeffForR5[i];
								// end
							// 6:	begin
									// multResult[i] <= inReg1[i] * coeffForR6[i];
								// end
							// 7:	begin
									// multResult[i] <= inReg1[i] * coeffForR7[i];
								// end
						endcase
					end 
					
					if (ndShReg[1]|ndShReg[CoeffCount-1]) begin
						if (i == 0) begin
							sumResult[i] <= multResult[i];
						end else begin
							sumResult[i] <= multResult[i] + sumResult[i-1];
						end
					end
				end else begin
					sumResult[i] <= 0;
					multResult[i] <= 0;
					inReg0[i] <= 0;
					inReg1[i] <= 0;
				end
			end 
		end
	endgenerate

	assign Data_o = comRst?	48'd0:sumResult[CoeffCount-1];
	assign DataValid_o = ndShReg[CoeffCount-1];

endmodule