`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    14:22:41 09/18/2019 
// Design Name: 
// Module Name:    MeasCtrlModule 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
module MeasCtrlModule
#(	
	parameter	WindPNumWidth	=	48,
	localparam	TukeyWinAlpha	=	4
)
(
	input	Clk_i,
	input	Rst_i,
	output	OscWind_o,
	
	input	StartMeas_i,
	input	StartMeasDsp_i,
	input	[7:0]	FilterCmd_i,
	input	Mode_i,
	input	OscDataRdFlag_i,
	
	input	[32-1:0]	MeasNum_i,

	input	[WindPNumWidth-1:0]	WindPointsNum_i,
	
	input	[32-1:0]	WindPhInc_i,
	input	[32-1:0]	WindPhIncStart_i,
	output	[32-1:0]	WindArg_o,
	
	output	StartFpConv_o,
	output	MeasWind_o,
	output	MeasWindEnd_o,
	output	StopMeas_o,
	output	MeasEnd_o,
	output	WinCtrl_o,
	output	SampleStrobeGenRst_o,
	output	[1:0]	TukeyCtrl_o
);


//================================================================================
//  REG/WIRE
	reg	startFpConv;

	reg	[1:0]	startFpConvPipe	[3:0];
	integer i;

	reg		measWind;
	reg		measWindR;
	
	reg		startMeasReg;										
	reg		startMeasDspReg;										
	wire	startMeasCmd	=	(StartMeas_i		&	!startMeasReg);	//esli prihodit bol'she chem 1 sigtal zapuska na 1 izmerenie, to ostal'nie ignoriruutsya
	wire	stopMeasCmd		=	(!StartMeasDsp_i	&	startMeasDspReg);
	wire	startMeasDspPos	=	(StartMeasDsp_i		&	!startMeasDspReg);
	
	reg		[31:0]	measCnt;
	
	reg		[WindPNumWidth-1:0]	pNumCnt;

	reg		measWindEnd;
	reg		pMeasEnd;
	wire	pNumCntRes		=	!measWind;
	wire	measCntRes		=	pMeasEnd|!StartMeasDsp_i;
	
	wire	stopCalc		=	(stopMeasCmd|measWindEnd);

	reg		[32-1:0]	windArg;
	
	wire	oscMode	=	(Mode_i	==	1'b1);
	
	reg		oscWind;
	
	wire	[31:0]	tukeyCosPNum = WindPointsNum_i/TukeyWinAlpha;
	
	wire	[31:0]	tukeyCosPNumDiv2			=	tukeyCosPNum/2;
	wire	[31:0]	tukeyFirstCosValues			=	tukeyCosPNum/2;
	wire	[31:0]	tukeyFirstCosValuesDiv2		=	tukeyFirstCosValues/2;
	wire	[31:0]	tukeySecondCosValuesDiv2	=	(WindPointsNum_i-tukeyFirstCosValuesDiv2);
	wire	[31:0]	tukeySecondCosValues		=	(WindPointsNum_i-tukeyCosPNum/2);

	reg		[1:0]	tukeyCtrl;
	reg		[1:0]	tukeyCtrlR;
	reg		[1:0]	tukeyCtrlRR;

	
	wire	incPhase	=	(pNumCnt	<=	tukeyFirstCosValues);
	wire	decrPhase	=	(pNumCnt	>=	tukeySecondCosValues-1	&	pNumCnt	<=	WindPointsNum_i-1);
	
	wire	wideFilterFlag	=	(FilterCmd_i>=8'h54	&	FilterCmd_i!=8'h70);
	
	reg		sampleStrobeGenRst;
	
	wire	measWindOr	=	(measWind|measWindR);
//================================================================================
//  ASSIGNMENTS
	assign	StartFpConv_o			=	startFpConvPipe	[2];
	// assign	MeasWind_o				=	measWind;
	assign	MeasWind_o				=	measWindOr;
	assign	MeasWindEnd_o			=	measWindEnd;
	assign	StopMeas_o				=	pMeasEnd;
	assign	MeasEnd_o				=	stopMeasCmd;
	assign	WindArg_o				=	windArg;
	assign	OscWind_o				=	oscWind;
	assign	TukeyCtrl_o				=	tukeyCtrl;
	assign	WinCtrl_o				=	(pNumCnt<=tukeyFirstCosValuesDiv2+1|pNumCnt>tukeySecondCosValuesDiv2);
	assign	SampleStrobeGenRst_o	=	sampleStrobeGenRst;
//================================================================================
//  CODING
	
	always	@(posedge	Clk_i)	begin
		if	(!Rst_i)	begin
			if	(measCnt	==	MeasNum_i-1	&	measWind)	begin
				sampleStrobeGenRst	<=	1'b1;
			end	else	begin
				sampleStrobeGenRst	<=	1'b0;
			end
		end	else	begin
			sampleStrobeGenRst	<=	1'b0;
		end
	end
	
	always	@(*)	begin
		if	(!Rst_i)	begin
			if	(measWind)	begin
				if	(pNumCnt	!=	0)	begin
					if	(pNumCnt	<=	tukeyFirstCosValues-1	|	pNumCnt	>	tukeySecondCosValues)	begin
						tukeyCtrl	=	2'd2;
					end	else	begin
						tukeyCtrl	=	2'd1;
					end
				end	else	begin
					tukeyCtrl	=	2'd0;
				end
			end	else	begin
				tukeyCtrl	=	2'd0;
			end
		end	else	begin
			tukeyCtrl	=	2'd0;
		end
	end
	
	always	@(posedge	Clk_i)	begin
		if	(!Rst_i)	begin
			measWindR	<=	measWind;
		end	else	begin
			measWindR	<=	1'b0;
		end
	end
	
	always	@(posedge	Clk_i)	begin
		if	(!Rst_i)	begin
			tukeyCtrlR	<=	tukeyCtrl;
			tukeyCtrlRR	<=	tukeyCtrlR;
		end	else	begin
			tukeyCtrlR	<=	1'b0;
			tukeyCtrlRR	<=	1'b0;
		end
	end
	
	always	@(posedge	Clk_i)	begin
		if	(!Rst_i)	begin
			if	(measWindR)	begin
				if	(pNumCnt	==	WindPointsNum_i-2)	begin
					measWindEnd	<=	1'b1;
				end	else	begin
					measWindEnd	<=	1'b0;
				end
			end	else	begin
				measWindEnd	<=	1'b0;
			end
		end	else	begin
			measWindEnd	<=	1'b0;
		end
	end
	
	always	@(posedge	Clk_i)	begin
		if	(!Rst_i)	begin
			if	(!oscMode)	begin
				if	(measCnt	==	MeasNum_i-1)	begin
					if	(measWindEnd)	begin
						pMeasEnd	<=	1'b1;
					end	else	begin
						pMeasEnd	<=	1'b0;
					end
				end	else	begin
					pMeasEnd	<=	1'b0;
				end
			end	else	begin
				if	(measCnt	==	MeasNum_i-1)	begin
					if	(OscDataRdFlag_i)	begin
						pMeasEnd	<=	1'b1;
					end	else	begin
						pMeasEnd	<=	1'b0;
					end
				end	else	begin
					pMeasEnd	<=	1'b0;
				end
			end
		end	else	begin
			pMeasEnd	<=	1'b0;
		end
	end
	
	always	@(posedge	Clk_i)	begin
		if	(!Rst_i)	begin
			if	(wideFilterFlag)	begin
				if	(measWind)	begin
					windArg	<=	windArg+WindPhInc_i;
				end	else	begin
					windArg	<=	WindPhInc_i>>1;
				end
			end	else	begin
				if	(measWind)	begin
					if	(incPhase)	begin
						windArg	<=	windArg+WindPhInc_i;
					end	
					if	(decrPhase)	begin
						windArg	<=	windArg-WindPhInc_i;
					end
				end	else	begin
					windArg	<=	WindPhIncStart_i;
				end
			end
		end	else	begin
			windArg	<=	0;
		end
	end
	
	always	@(posedge	Clk_i)	begin
		if	(!Rst_i)	begin
			if	(!measCntRes)	begin
				if	(!oscMode)	begin
					if	(measCnt	!=	MeasNum_i-1)	begin
						if	(measWindEnd)	begin
							measCnt	<=	measCnt+1;
						end
					end
				end	else	begin
					if	(measCnt	!=	MeasNum_i-1)	begin
						if	(OscDataRdFlag_i)	begin
							measCnt	<=	measCnt+1;
						end
					end
				end
			end	else	begin
				measCnt	<=	0;
			end
		end	else	begin
			measCnt	<=	0;
		end	
	end
	
	always	@(posedge	Clk_i)	begin
		if	(!Rst_i)	begin
			if	(oscMode)	begin
				if	(startMeasDspPos)	begin
					oscWind	<=	1'b1;
				end	
				if	(pMeasEnd)	begin
					oscWind	<=	1'b0;
				end
			end	else	begin
				oscWind	<=	1'b0;
			end
		end	else	begin
			oscWind	<=	1'b0;
		end
	end
	
	always	@(posedge	Clk_i) begin
		if	(!Rst_i)	begin
			if	(measWindEnd)	begin
				startFpConv	<=	1'b1;
			end	else	begin
				startFpConv	<=	1'b0;
			end
		end	else	begin
			startFpConv	<=	1'b0;
		end
	end

	always @(posedge Clk_i) begin
		startFpConvPipe[0]  <= startFpConv;
		for(i=1; i<4; i=i+1) begin
			startFpConvPipe	[i]<=startFpConvPipe[i-1];
		end
	end
	
	always 	@(posedge	Clk_i)	begin
		if	(!Rst_i)	begin
			if	(pNumCntRes)	begin
				pNumCnt	<=	{WindPNumWidth{1'b0}};
			end	else	begin
				pNumCnt	<=	pNumCnt	+	{{WindPNumWidth-1{1'b0}},1'b1};
			end
		end	else	begin
			pNumCnt	<=	{WindPNumWidth{1'b0}};
		end
	end

	always	@(posedge	Clk_i)	begin
		if	(!Rst_i)	begin
			startMeasReg	<=	StartMeas_i;
		end	else	begin
			startMeasReg	<=	1'b0;
		end
	end
	
	always	@(posedge	Clk_i)	begin
		if	(!Rst_i)	begin
			startMeasDspReg	<=	StartMeasDsp_i;
		end	else	begin
			startMeasDspReg	<=	1'b0;
		end
	end
	
	always	@(*)	begin	
		if	(!Rst_i)	begin
			if	(StartMeasDsp_i)	begin
				if	(!measWind)	begin
					if	(startMeasCmd)	begin
						measWind	=	1'b1;
					end	
				end	else	if	(stopCalc)	begin	
					measWind	=	1'b0;
				end
			end	else	begin
				measWind	=	1'b0;
			end
		end	else	begin
			measWind	=	1'b0;
		end
	end

endmodule
