`timescale 1ns / 1ps
(* keep_hierarchy = "yes" *)	
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 		Churbanov S.
// 
// Create Date:		15:22:20 12/08/2019 
// Design Name: 
// Module Name:		Win_parameters
// Project Name:	Compact_main
// Target Devices: 
// Tool versions: 
// Description: 	
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
module Win_calc	(
	input			clk_i,
	input			wind_clk,
	input	[7:0]	filterCmd_i,
	input			reset_i,
	input			WinCtrl_i,
	input			MeasWind_i,
	input	[1:0]	TukeyCtrl_i,
	input	[31:0]	win_value_i,
	input	[2:0]	win_type_i,	
	output	signed [17:0]	win_o,
	output	reg	signed [17:0]	sinWin_o
);

//================================================================================
//  PARAMETERS
//================================================================================
	localparam	signed	A3_1	=	18'h15584;
// ????????? ??? ?????????? SIN
	localparam signed	[17:0]	A1	=	18'h12400;			// a-1
	localparam signed	[17:0]	A2	=	18'h002C0;			// b
	localparam signed	[17:0]	A3	=	~A3_1	+	1'b1;	// c
	localparam signed	[17:0]	A4	=	18'h0126C;			// d
	localparam signed	[17:0]	A5	=	18'h01C5C;			// e
	
	localparam	CalcWidth			=	10;
	localparam	CalcWidthR			=	18;
	localparam	b2Width				=	CalcWidth*2;
	localparam	b3Width				=	CalcWidth*3;
	localparam	b4Width				=	CalcWidth*4;
	localparam	b5Width				=	CalcWidth*5;
	
	localparam [31:0]	testArg	=	32'h12492492;
//================================================================================
//  REG/WIRE
//================================================================================
	reg			signed	[17:0]	sinWind;
	reg			signed	[17:0]	tukeyWind;	
		
	reg	[1:0]	tukeyCtrlR;
	reg	[1:0]	tukeyCtrlRR;
	
	reg	[35:0]	sinWindPow2;
	
	wire	sinFilterFlag	=	(filterCmd_i>=8'h54	&	filterCmd_i<=8'h62);
	wire	rectFilterFlag	=	(filterCmd_i>=8'h63	&	filterCmd_i!=8'h70);
	
	wire	[CalcWidth-1:0]	bCurr	=	win_value_i[31]	?	10'h3FF	-	win_value_i[31-:CalcWidth]	:	win_value_i	[31-:CalcWidth];
	
	wire	[CalcWidthR-1:0]	bNew	=	win_value_i[31]	?	18'h3FFFF	-	win_value_i[31:14]	:	win_value_i	[31:14];
	
	wire	signed	[17:0]	constOne	=	18'b011111111111111111;
	
	reg		signed	[18:0]	tukeyCorr;
	
	reg		[17:0]	tukeyWindOut;
	
	wire	signed [17:0]	windMux1;
	wire	signed [17:0]	windMux2;
	
	wire	signed	[b2Width-1:0]	b2	=	bCurr**2;
	wire	signed	[b3Width-1:0]	b3	=	bCurr**3;
	wire	signed	[b4Width-1:0]	b4	=	bCurr**4;
	wire	signed	[b5Width-1:0]	b5	=	bCurr**5;
	
	wire	signed	[CalcWidthR-1:0]	b2Cut	=	b2[b2Width-2-:CalcWidthR];
	wire	signed	[CalcWidthR-1:0]	b3Cut	=	b3[b3Width-3-:CalcWidthR];
	wire	signed	[CalcWidthR-1:0]	b4Cut	=	b4[b4Width-4-:CalcWidthR];
	wire	signed	[CalcWidthR-1:0]	b5Cut	=	b5[b5Width-5-:CalcWidthR];
	
	reg		signed	[CalcWidthR*2-1:0]	a1b;
	reg		signed	[CalcWidthR*2-1:0]	a2b2;
	reg		signed	[CalcWidthR*2-1:0]	a3b3;
	reg		signed	[CalcWidthR*2-1:0]	a4b4;
	reg		signed	[CalcWidthR*2-1:0]	a5b5;
	
	wire	signed	[CalcWidthR-1:0]	a1bCut	=	a1b	[CalcWidthR*2-2-:CalcWidthR];
	wire	signed	[CalcWidthR-1:0]	a2b2Cut	=	a2b2[CalcWidthR*2-2-:CalcWidthR];
	wire	signed	[CalcWidthR-1:0]	a3b3Cut	=	a3b3[CalcWidthR*2-2-:CalcWidthR];
	wire	signed	[CalcWidthR-1:0]	a4b4Cut	=	a4b4[CalcWidthR*2-2-:CalcWidthR];
	wire	signed	[CalcWidthR-1:0]	a5b5Cut	=	a5b5[CalcWidthR*2-2-:CalcWidthR];
	
	reg		signed	[CalcWidthR-1:0]	bPrevSh;
		
	wire	signed	[CalcWidthR-1:0]	approxSin	=	a5b5Cut+a4b4Cut+a3b3Cut+a2b2Cut+a1bCut+bPrevSh;	
	
	wire	signed	[CalcWidthR-1:0]	resultSin	=	approxSin[17]?	18'h1ffff:approxSin;
//================================================================================
//  ASSIGNMENTS
// ================================================================================	
	
	assign	windMux1	=	(sinFilterFlag)	?	sinWindPow2[34-:18]:tukeyWindOut;
	assign	windMux2	=	(rectFilterFlag)?	18'h1ffff:windMux1;

	assign	win_o		=	windMux2;
// ================================================================================
//  CODING
//================================================================================	

always	@(posedge	clk_i)	begin
	if	(!reset_i)	begin
		a5b5	<=	A5*b5Cut;
		a4b4	<=	A4*b4Cut;
		a3b3	<=	A3*b3Cut;
		a2b2	<=	A2*b2Cut;
		a1b		<=	A1*bNew;
		bPrevSh	<=	bNew;
	end	else	begin
		a5b5	<=	0;
		a4b4	<=	0;
		a3b3	<=	0;
		a2b2	<=	0;
		a1b		<=	0;
		bPrevSh	<=	0;
	end
end

always	@(posedge	clk_i)	begin
	if	(!reset_i)	begin
		tukeyCtrlR	<=	TukeyCtrl_i;
		tukeyCtrlRR	<=	tukeyCtrlR;
	end	else	begin
		tukeyCtrlR	<=	0;
		tukeyCtrlRR	<=	0;
	end
end

always	@(*)	begin
	if	(!reset_i)	begin
		tukeyCorr	=	(tukeyWind+constOne);
		sinWindPow2	=	resultSin**2;
	end	else	begin
		tukeyCorr	=	18'h0;
		sinWindPow2	=	18'h0;
	end
end

always	@(*)	begin
	if	(!reset_i)	begin
		case(tukeyCtrlR)
			2'h0:		begin
							tukeyWindOut	=	0;
						end
			2'h1:		begin
							tukeyWindOut	=	18'h1ffff;
						end
			2'h2:		begin
							tukeyWindOut	=	tukeyCorr[18-:18];
						end
			default:	begin
							tukeyWindOut	=	0;
						end
		endcase
	end	else	begin
		tukeyWindOut	=	18'h0;
	end
end


always	@(*)	begin
	if	(!reset_i)	begin
		if	(!win_type_i)	begin 
			if	(!WinCtrl_i)	begin
				tukeyWind	=	resultSin;
			end	else	begin
				tukeyWind	=	0-resultSin;
			end
		end	else	begin
			tukeyWind	=	18'h0;
		end
	end	else	begin
		tukeyWind	=	18'h0;
	end
end
endmodule
