`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	=	21,
	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	[AdcDataWidth+1:0]	FilteredAdcDataI_o,
	output	signed	[AdcDataWidth+1:0]	FilteredAdcDataQ_o,
	output	FilteredDataVal_o
);
//================================================================================
//	REG/WIRE
//================================================================================
	wire	signed	[FilteredDataWidth-1:0]	decimDataI;
	wire	signed	[FilteredDataWidth-1:0]	decimDataQ;
	wire	decimDataValI;
	wire	decimDataValQ;
	
	wire	signed	[FirOutDataWidth-1:0]	firDataOut;
	wire	firDataOutVal;
	
	wire	[AdcDataWidth-1:0]	ncoCos;
	wire	[AdcDataWidth-1:0]	ncoSin;
	
	wire	[FilteredDataWidth-1:0]	adcSinResult;
	wire	adcSinVal;
	wire	[FilteredDataWidth-1:0]	adcCosResult;
	wire	adcCosVal;
	
	reg		[24-1:0]	ifFtwLReg;
	reg		[24-1:0]	ifFtwHReg;
//================================================================================
//	ASSIGNMENTS
//================================================================================

	assign	FilteredAdcDataI_o		=	decimDataI[FilteredDataWidth-1-:AdcDataWidth+2];
	assign	FilteredAdcDataQ_o		=	decimDataQ[FilteredDataWidth-1-:AdcDataWidth+2];
	assign	FilteredDataVal_o		=	decimDataValI&decimDataValQ;
	
//================================================================================
//	CODING
//================================================================================

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}),
	.WindVal_i	(1'b1),
	.WinType_i	(),
	.Wind_o		(),
	.Sin_o		(ncoSin),
	.Cos_o		(ncoCos),
	.Val_o		()
);

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

SimpleMult	
#(	
	.FactorAWidth	(AdcDataWidth),
	.FactorBWidth	(AdcDataWidth),
	.OutputWidth	(FilteredDataWidth)
)
AdcNcoCosMult	
(
	.Rst_i		(Rst_i),
	.Clk_i		(Clk_i),
	.Val_i		(1'b1),
	.FactorA_i	(ncoCos),
	.FactorB_i	(AdcData_i),
	.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			({{7{AdcData_i[AdcDataWidth-1]}},AdcData_i}),
	.Data_i			(adcCosResult),
	.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			(AdcData_i),
	// .Data_i			({{7{AdcData_i[AdcDataWidth-1]}},AdcData_i}),
	.Data_i			(adcSinResult),
	.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








