`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// company: 
// engineer: 
// 
// create date:    16:37:06 07/11/2019 
// design name: 
// module name:    dsp_linkport_interface 
// project name: 
// target devices: 
// tool versions: 
// description: 					
//
// dependencies: 
//
// revision: 
// revision 0.01 - file created
// additional comments: 
//
//////////////////////////////////////////////////////////////////////////////////
module	DecimFilterWrapper
#(	
	parameter	AdcDataWidth		=	14,
	parameter	N	=	4,
	parameter	M	=	1,
	parameter	FilteredDataWidth	=	29,
	parameter	FirOutDataWidth		=	48,
	parameter	FirOutCutBit		=	42
)
(
	input	Clk_i,
	input	[2:0]	DecimFactor_i,
	input	Rst_i,
	input	OscWind_i,
	
	input	[24-1:0]	IfFtwL_i,
	input	[24-1:0]	IfFtwH_i,
	
	input	signed	[AdcDataWidth-1:0]	AdcData_i,
	
	output	signed	[16-1:0]	FilteredAdcDataI_o,
	output	signed	[16-1:0]	FilteredAdcDataQ_o,
	output	FilteredDataVal_o
);
//================================================================================
//	REG/WIRE
//================================================================================
	wire	signed	[FilteredDataWidth-1:0]	decimDataI;
	wire	signed	[FilteredDataWidth-1:0]	decimDataQ;
	wire	decimDataValI;
	reg		decimDataValIR;
	wire	decimDataValQ;
	reg		decimDataValQR;
	
	wire	signed	[FirOutDataWidth-1:0]	firDataOut;
	wire	firDataOutVal;
	
	wire	[AdcDataWidth-1:0]	ncoCos;
	wire	[AdcDataWidth-1:0]	ncoSin;
	
	wire	[AdcDataWidth-1:0]	adcSinResult;
	wire	adcSinVal;
	wire	[AdcDataWidth-1:0]	adcCosResult;
	wire	adcCosVal;
	
	reg		[24-1:0]	ifFtwLReg;
	reg		[24-1:0]	ifFtwHReg;
	
	reg		[15:0]	outDataI;
	reg		[15:0]	outDataQ;
	
	localparam	maxWidthForR2	=	5'd18;	//msb for R = 2;
	localparam	maxWidthForR3	=	5'd21;	//msb for R = 3;
	localparam	maxWidthForR4	=	5'd22;	//msb for R = 4;
	localparam	maxWidthForR5	=	5'd24;	//msb for R = 5;
	localparam	maxWidthForR6	=	5'd25;	//msb for R = 6;
	localparam	maxWidthForR7	=	5'd26;	//msb for R = 7;
	// localparam	maxWidthForR8	=	5'd26;	//msb for R = 8;
	// localparam	maxWidthForR9	=	5'd27;	//msb for R = 9;
	// localparam	maxWidthForR10	=	5'd28;	//msb for R = 10;
	
//================================================================================
//	ASSIGNMENTS
//================================================================================

	assign	FilteredAdcDataI_o	=	outDataI;
	// assign	FilteredAdcDataI_o	=	decimDataI;
	assign	FilteredAdcDataQ_o	=	outDataQ;
	// assign	FilteredAdcDataQ_o	=	decimDataQ;
	// assign	FilteredDataVal_o	=	decimDataValIR&decimDataValQR;
	assign	FilteredDataVal_o	=	decimDataValI&decimDataValQ;


// {{14{AdcData_i[AdcDataWidth-1]}},AdcData_i}

//================================================================================
//	CODING
//================================================================================

always	@(posedge	Clk_i)	begin
	if	(!Rst_i)	begin
		case(DecimFactor_i)
			3'd2:	begin
						outDataI	<=	decimDataI[maxWidthForR2-:16];
						outDataQ	<=	decimDataQ[maxWidthForR2-:16];
						decimDataValIR	<=	decimDataValI;
						decimDataValQR	<=	decimDataValQ;
					end
			3'd3:	begin
						outDataI	<=	decimDataI[maxWidthForR3-:16];
						outDataQ	<=	decimDataQ[maxWidthForR3-:16];
						decimDataValIR	<=	decimDataValI;
						decimDataValQR	<=	decimDataValQ;
					end
			3'd4:	begin
						outDataI	<=	decimDataI[maxWidthForR4-:16];
						outDataQ	<=	decimDataQ[maxWidthForR4-:16];
						decimDataValIR	<=	decimDataValI;
						decimDataValQR	<=	decimDataValQ;
					end
			3'd5:	begin
						outDataI	<=	decimDataI[maxWidthForR5-:16];
						outDataQ	<=	decimDataQ[maxWidthForR5-:16];
						decimDataValIR	<=	decimDataValI;
						decimDataValQR	<=	decimDataValQ;
					end
			3'd6:	begin
						outDataI	<=	decimDataI[maxWidthForR6-:16];
						outDataQ	<=	decimDataQ[maxWidthForR6-:16];
						decimDataValIR	<=	decimDataValI;
						decimDataValQR	<=	decimDataValQ;
					end
			3'd7:	begin
						outDataI	<=	decimDataI[maxWidthForR7-:16];
						outDataQ	<=	decimDataQ[maxWidthForR7-:16];
						decimDataValIR	<=	decimDataValI;
						decimDataValQR	<=	decimDataValQ;
					end
		endcase
	end	else	begin
		outDataI	<=	16'd0;
		outDataQ	<=	16'd0;
		decimDataValIR	<=	1'b0;
		decimDataValQR	<=	1'b0;
	end
end

always	@(posedge	Clk_i)	begin
	if	(!Rst_i)	begin
		ifFtwLReg	<=	IfFtwL_i;
		ifFtwHReg	<=	IfFtwH_i;
	end	else	begin
		ifFtwLReg	<=	0;
		ifFtwHReg	<=	0;
	end
end

CordicNco		
#(	
	.ODatWidth	(14),
	.PhIncWidth	(32),
	.IterNum	(10),
	.EnSinN		(1)
)
ncoInst
(
	.Clk_i		(Clk_i),
	.Rst_i		(Rst_i),
	.Val_i		(1'b1),
	.PhaseInc_i	({ifFtwHReg[0+:32-24],ifFtwLReg}),
	// .PhaseInc_i	(32'h3eb851eb),
	.WindVal_i	(1'b1),
	.WinType_i	(),
	.Wind_o		(),
	.Sin_o		(ncoSin),
	.Cos_o		(ncoCos),
	.Val_o		()
);

SimpleMult	
#(	
	.FactorAWidth	(AdcDataWidth),
	.FactorBWidth	(AdcDataWidth),
	.OutputWidth	(AdcDataWidth)
)
AdcNcoSinMult	
(
	.Rst_i		(Rst_i),
	.Clk_i		(Clk_i),
	.Val_i		(1'b1),
	.FactorA_i	(ncoSin),
	.FactorB_i	(AdcData_i),	
	// .FactorB_i	(ncoSin),	
	.Result_o	(adcSinResult),
	.ResultVal_o(adcSinVal)
);

SimpleMult	
#(	
	.FactorAWidth	(AdcDataWidth),
	.FactorBWidth	(AdcDataWidth),
	.OutputWidth	(AdcDataWidth)
)
AdcNcoCosMult	
(
	.Rst_i		(Rst_i),
	.Clk_i		(Clk_i),
	.Val_i		(1'b1),
	.FactorA_i	(ncoCos),
	.FactorB_i	(AdcData_i),
	// .FactorB_i	(ncoSin),
	.Result_o	(adcCosResult),
	.ResultVal_o(adcCosVal)
);

cicFilter 
#(
	.N (N),	//filter order
	.M (M),	//comb delay
	.filteredDataWidth	(FilteredDataWidth),
	.inOutDataWidth		(FilteredDataWidth),
	.decimCntWidth		(7)
)
cicFilterInstI
(
	.Clk_i			(Clk_i),
	.Rst_i			(Rst_i),
	.DecimFactor_i	(DecimFactor_i),
	.Data_i			({{15{adcCosResult[AdcDataWidth-1]}},adcCosResult}),
	// .Data_i			({{15{AdcData_i[AdcDataWidth-1]}},AdcData_i}),
	.DataNd_i		(OscWind_i),
	.Data_o			(decimDataI),
	.DataValid_o	(decimDataValI)
);

cicFilter 
#(
	.N (N),	//filter order
	.M (M),	//comb delay
	.filteredDataWidth	(FilteredDataWidth),
	.inOutDataWidth		(FilteredDataWidth),
	.decimCntWidth		(7)
)
cicFilterInstQ
(
	.Clk_i			(Clk_i),
	.Rst_i			(Rst_i),
	.DecimFactor_i	(DecimFactor_i),
	.Data_i			({{15{adcSinResult[AdcDataWidth-1]}},adcSinResult}),
	// .Data_i			({{15{AdcData_i[AdcDataWidth-1]}},AdcData_i}),
	.DataNd_i		(OscWind_i),
	.Data_o			(decimDataQ),
	.DataValid_o	(decimDataValQ)
);
  
// fir_compiler_0 firCompensator 
// (
	// .aclk	(Clk_i),
	// .s_axis_data_tvalid	(decimDataVal),
	// .s_axis_data_tready	(),
	// .s_axis_data_tdata	({{3{decimData[FilteredDataWidth-1]}},decimData}),
	// .m_axis_data_tvalid	(firDataOutVal),
	// .m_axis_data_tdata	(firDataOut)
// );

endmodule








