module DecimFilterWrapperTest2 #(
    parameter InDataWidth = 14,
    parameter N = 6, // Number of stages
    parameter M = 4, // Differential delay
    parameter OutDataWidth = 17
)
(
    input logic 								Clk_i,
    input logic 			[2:0]               DecimFactor_i, // Decimation factor (1, 2, 4, 8)
	input logic                     			Rst_i,

    input logic                     			DataVal_i,
    input logic 	signed	[InDataWidth-1:0]   Data_i,

    output logic 								DataVal_o,
    output logic 	signed	[OutDataWidth-1:0] 	Data_o
);
//================================================================================
//								REG/WIRE
//================================================================================
/* LocalParams */
localparam extendBitNum = OutDataWidth - InDataWidth;

/* Integrator Block */
wire signed					[OutDataWidth-1:0] 	integratedDataIn 	[N-1:0];
wire 											adcExtData				   ;
wire signed										integratedDataValIn [N-1:0];
wire signed					[OutDataWidth-1:0] 	integratedDataOut 	[N-1:0];
wire 											integratedValOut 	[N-1:0];

/* Decim Block */
wire signed 				[OutDataWidth-1:0] 	decimDataOut;
wire 											decimDataValOut;

/* Comb Filter Block */
wire signed					[OutDataWidth-1:0] 	combDataIn			[N-1:0];
wire 											combDataValIn		[N-1:0];
wire signed					[OutDataWidth-1:0] 	combDataOut			[N-1:0];
wire 											combDataValOut		[N-1:0];

wire signed					[InDataWidth-1:0] 	shTest;


//================================================================================
//								ASSIGNMENTS
//================================================================================
assign shTest = combDataOut[N-1] >>> 14;

assign Data_o 		= shTest;
assign DataVal_o 	= combDataValOut[N-1];


//================================================================================
//								CODING
//================================================================================
genvar i;

/* Integrators */
generate 
	for (i = 0; i < N; i++) begin : gen_integrators

		assign integratedDataIn[i] = (i == 0) ? Data_i : integratedDataOut[i-1];
		assign integratedDataValIn[i] = (i == 0) ? DataVal_i : integratedValOut[i-1];

		intFilterBlock
		#(
			.InDataWidth	(OutDataWidth),
			.OutDataWidth	(OutDataWidth)
		)
		inFilterBlockInst 
		(
			.Clk_i			(Clk_i),
			.Rst_i			(Rst_i),
			.Data_i			(integratedDataIn[i]),
			.DataNd_i		(integratedDataValIn[i]),
			.Data_o			(integratedDataOut[i]),
			.DataValid_o	(integratedValOut[i])
		);
	end

endgenerate

/* Decimator */
decimBlock 
#(
	.InDataWidth	(OutDataWidth)
)
decimBlock_inst (
	.Clk_i			(Clk_i),
	.Rst_i			(Rst_i),
	.DecimFactor_i	(DecimFactor_i),
	.Data_i			(integratedDataOut[N-1]),
	.DataNd_i		(integratedValOut[N-1]),
	.Data_o			(decimDataOut),
	.DataValid_o	(decimDataValOut)

);

/* Cascade of Combs */
genvar j;
generate 
	for (j = 0; j < N; j++) begin : gen_combs

	assign combDataIn[j] 	= (j == 0) ? decimDataOut 		: combDataOut[j-1];
	assign combDataValIn[j] = (j == 0) ? decimDataValOut 	: combDataValOut[j-1];

		combFilterBlock
		#(
			.InOutDataWidth	(OutDataWidth),
			.M(M)
		)
		combFilterBlockInst 
		(
			.Clk_i			(Clk_i),
			.Rst_i			(Rst_i),
			.Data_i			(combDataIn[j]),
			.DataNd_i		(combDataValIn[j]),
			.Data_o			(combDataOut[j]),
			.DataValid_o	(combDataValOut[j])
		);
	end

endgenerate




endmodule

  