module CicFilterNewWrapper #(
    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
//================================================================================
/* Integrator Block */
logic signed					[OutDataWidth-1:0] 	integratedDataIn 	[N-1:0];
logic 										        integratedDataValIn [N-1:0];
logic signed					[OutDataWidth-1:0] 	integratedDataOut 	[N-1:0];
logic 											    integratedValOut 	[N-1:0];
/* Decim Block */
logic signed 				    [OutDataWidth-1:0] 	decimDataOut;
logic 											    decimDataValOut;
/* Comb Filter Block */
logic signed					[OutDataWidth-1:0] 	combDataIn			[N-1:0];
logic 											    combDataValIn		[N-1:0];
logic signed					[OutDataWidth-1:0] 	combDataOut			[N-1:0];
logic 											    combDataValOut		[N-1:0];

/* ShTest */
logic signed					[InDataWidth-1:0] 	shTest;

//================================================================================
//								ASSIGNMENTS
//================================================================================
assign Data_o 		= decimDataOut;
assign DataVal_o 	= decimDataValOut;

assign shTest 		= decimDataOut>>> 14;
//================================================================================
//								CODING
//================================================================================
genvar i;
/* Integrators */
generate
    for (i = 0; i < N; i++) begin : gen_integrators
    
        assign integratedDataIn[i] = (i == 0) ? Data_i : combDataOut[i-1];
        assign integratedDataValIn[i] = (i == 0) ? DataVal_i : combDataValOut[i-1];

		CicIntDiffBlock #(
			.M              (M),
			.InDataWidth	(OutDataWidth),
			.OutDataWidth   (OutDataWidth)
		) CicIntDiff (
			.Clk_i          (Clk_i),
			.Rst_i          (Rst_i),
			.Data_i         (integratedDataIn[i]),
			.DataVal_i      (integratedDataValIn[i]),
			.Data_o         (combDataOut[i]),
			.DataVal_o      (combDataValOut[i])
		);
        
    end
endgenerate

/* Decimation */
CicDecimator #(
    .InDataWidth			(OutDataWidth)
) decimator_inst (
    .Clk_i          		(Clk_i),
    .Rst_i          		(Rst_i),
    .DecimFactor_i  		(DecimFactor_i),
    .DataVal_i      		(combDataValOut[N-1]),
    .Data_i         		(combDataOut[N-1]),
    .DataVal_o      		(decimDataValOut),
    .Data_o         		(decimDataOut)
);



endmodule