
(* keep_hierarchy = "yes" *)	
module DspPipeline 
#(	
	parameter	AdcDataWidth		=	14,
	parameter	AccWidth			=	48,
	parameter	WindWidth			=	14,
	parameter	AdcCorrData			=	20,
	parameter	NcoWidth			=	14,
	parameter	ResultWidth			=	32,
	parameter	WindNormCoefWidth	=	32,
	parameter	WindCorrCoefWidth	=	32,
	parameter	IntermediateWidth	=	14,
	parameter	FracWidth			=	51
)
(
    input	Clk_i,
    input	Rst_i,
    input	Val_i,
    input	StartFpConv_i,
	
	input	[WindCorrCoefWidth-1:0]	FilterCorrCoef_i,
	input	[WindCorrCoefWidth-1:0]	AverageNoizeLvl_i,
	input	[AdcCorrData-1:0]	AdcData_i,
	input	[WindWidth-1:0]		Wind_i,
	input	[NcoWidth-1:0]		NcoSin_i,
	input	[NcoWidth-1:0]		NcoCos_i,
	input	[WindNormCoefWidth-1:0]	NormCoef_i,
	
	output	[ResultWidth-1:0]	CorrResultIm_o,
	output	[ResultWidth-1:0]	CorrResultRe_o,
    output	CorrResultVal_o
);

//================================================================================
//  LOCALPARAMS
	localparam	NormResultWidth	=	AccWidth+WindNormCoefWidth;
	localparam	AdcWindWidth	=	37;
//================================================================================
//  REG/WIRE 
	wire	[AdcWindWidth-1:0]	adcWindResult;
	wire	adcWindResultVal;
	
	wire	[54:0]	adcWindSinResult;
	wire	adcWindSinResultVal;
	wire	[54:0]	adcWindCosResult;
	wire	adcWindCosResultVal;
	
	wire	[AccWidth-1:0]	AccResultI;
	wire	[AccWidth-1:0]	AccResultQ;
	
	wire	[ResultWidth-1:0]	NormResultI;
	wire	NormResultIVal;
	wire	[ResultWidth-1:0]	NormResultQ;
	wire	NormResultQVal;
	
	wire	[ResultWidth-1:0]	iFp32Result;
	wire	iFp32ResultVal;
	wire	[ResultWidth-1:0]	qFp32Result;
	wire	qFp32ResultVal;
	
	wire	CorrResultReVal;
	wire	CorrResultImVal;
	
	reg		valReg;
	reg		valRegReg;
//================================================================================
//  ASSIGNMENTS
	assign	CorrResultVal_o	=	CorrResultReVal&CorrResultImVal;
	
//================================================================================
//  CODING

	always	@(posedge	Clk_i)	begin
		if	(!Rst_i)	begin
			valReg		<=	Val_i;
			valRegReg	<=	valReg;
		end	else	begin
			valReg		<=	0;
			valRegReg	<=	0;	
		end
	end
	
//===============================Adc*Wind=========================================
SimpleMult	
#(	
	.FactorAWidth	(AdcCorrData),
	.FactorBWidth	(WindWidth),
	.OutputWidth	(AdcWindWidth)
)
AdcWindMult	
(
	.Rst_i		(Rst_i),
	.Clk_i		(Clk_i),
	.Val_i		(valRegReg),
	.FactorA_i	(AdcData_i),
	.FactorB_i	(Wind_i),
	.Result_o	(adcWindResult),
	.ResultVal_o(adcWindResultVal)
);
//===============================AdcWind*NcoSinCos================================
SimpleMult	
#(	
	.FactorAWidth	(AdcWindWidth),
	.FactorBWidth	(NcoWidth),
	.OutputWidth	(NcoWidth+AdcWindWidth)
)
AdcNcoSinMult	
(
	.Rst_i		(Rst_i),
	.Clk_i		(Clk_i),
	.Val_i		(adcWindResultVal),
	.FactorA_i	(adcWindResult),
	.FactorB_i	(NcoSin_i),	
	.Result_o	(adcWindSinResult),
	.ResultVal_o(adcWindSinResultVal)
);

SimpleMult	
#(	
	.FactorAWidth	(AdcWindWidth),
	.FactorBWidth	(NcoWidth),
	.OutputWidth	(NcoWidth+AdcWindWidth)
)
AdcNcoCosMult	
(
	.Rst_i		(Rst_i),
	.Clk_i		(Clk_i),
	.Val_i		(adcWindResultVal),
	.FactorA_i	(adcWindResult),
	.FactorB_i	(NcoCos_i),
	.Result_o	(adcWindCosResult),
	.ResultVal_o(adcWindCosResultVal)
);

//===============================SumAcc===========================================
SumAcc
#(	
	.IDataWidth	(NcoWidth+AdcWindWidth-1),
	.ODataWidth	(AccWidth)
)
SummAccQ
(
    .Clk_i		(Clk_i),
    .Rst_i		(Rst_i),
    .Val_i		(adcWindSinResultVal),
	
	.Data_i		(adcWindSinResult[53:0]),
	.Result_o	(AccResultQ)
);

SumAcc
#(	
	.IDataWidth	(NcoWidth+AdcWindWidth-1),
	.ODataWidth	(AccWidth)
)
SummAccI
(
    .Clk_i		(Clk_i),
    .Rst_i		(Rst_i),
    .Val_i		(adcWindCosResultVal),
	
	.Data_i		(adcWindCosResult[53:0]),
	.Result_o	(AccResultI)
);

//===============================InToFpConv=======================================
MyIntToFp
#(	
	.InWidth	(AccWidth),
	.ExpWidth	(8),
	.ManWidth	(23),
	.FracWidth	(FracWidth)
)
QToFp32
(	
	.Clk_i				(Clk_i),
	.Rst_i				(Rst_i),
	.InData_i			(AccResultQ),
	.AverageNoizeLvl_i	(AverageNoizeLvl_i),
	.InDataVal_i		(StartFpConv_i),
	.OutData_o			(qFp32Result),
	.OutDataVal_o		(qFp32ResultVal)
);

MyIntToFp
#(	
	.InWidth	(AccWidth),
	.ExpWidth	(8),
	.ManWidth	(23),
	.FracWidth	(FracWidth)
)
IToFp32
(	
	.Clk_i				(Clk_i),
	.Rst_i				(Rst_i),
	.InData_i			(AccResultI),
	.AverageNoizeLvl_i	(AverageNoizeLvl_i),
	.InDataVal_i		(StartFpConv_i),
	.OutData_o			(iFp32Result),
	.OutDataVal_o		(iFp32ResultVal)
);

//===============================Result*NormCoeff=================================
FpCustomMultiplier 
# (
	.ManWidth	(23),
	.ExpWidth	(8)
)
ResultQNorm
(
	.Rst_i			(Rst_i),
	.Clk_i			(Clk_i),
	.A_i			(qFp32Result),
	.B_i			(NormCoef_i),
	.Nd_i			(qFp32ResultVal),
	.Result_o		(NormResultQ),
	.ResultValid_o	(NormResultQVal)
);

FpCustomMultiplier 
# (
	.ManWidth	(23),
	.ExpWidth	(8)
)
ResultINorm
(
	.Rst_i			(Rst_i),
	.Clk_i			(Clk_i),
	.A_i			(iFp32Result),
	.B_i			(NormCoef_i),
	.Nd_i			(iFp32ResultVal),
	.Result_o		(NormResultI),
	.ResultValid_o	(NormResultIVal)
);

//===============================NormResult*CorrCoeff========================
FpCustomMultiplier 
# (
	.ManWidth	(23),
	.ExpWidth	(8)
)
ResultReCorr
(
	.Rst_i			(Rst_i),
	.Clk_i			(Clk_i),
	.A_i			(NormResultQ),
	.B_i			(FilterCorrCoef_i),
	.Nd_i			(NormResultQVal),
	.Result_o		(CorrResultRe_o),
	.ResultValid_o	(CorrResultReVal)
);

FpCustomMultiplier 
# (
	.ManWidth	(23),
	.ExpWidth	(8)
)
ResultImCorr
(
	.Rst_i			(Rst_i),
	.Clk_i			(Clk_i),
	.A_i			(NormResultI),
	.B_i			(FilterCorrCoef_i),
	.Nd_i			(NormResultIVal),
	.Result_o		(CorrResultIm_o),
	.ResultValid_o	(CorrResultImVal)
);

endmodule


















