`timescale 1ns / 1ps
(* keep_hierarchy = "yes" *)	
module OscDataFormer
#(	
	parameter	AdcDataWidth		=	32,	
	parameter	ExtAdcDataWidth		=	AdcDataWidth+2,	
	parameter	ChNum				=	1,
	parameter	DataValCycles		=	8,
	parameter	OutDataWidth		=	(AdcDataWidth*ChNum)*DataValCycles
)	
(
	input	Clk_i, 
	input	Rst_i,	
	input	OscWind_i,
	input	[31:0]	MeasNum_i,
	
	input	AdcDataVal_i,
	input	[AdcDataWidth-1:0]	AdcData_i,	
	
	output	[OutDataWidth-1:0]	OscDataBus_o,
	output	OscDataBusVal_o
);
//================================================================================
//  REG/WIRE
//================================================================================
	
	wire	signed	[15:0]	adcDataExt	=	{{2{AdcData_i[AdcDataWidth-1]}},AdcData_i};
	
	reg	[OutDataWidth-1:0]	oscDataBusReg;
	reg	[OutDataWidth-1:0]	oscDataBusRegReg;
	
	reg	oscDataBusValReg;
	reg	oscDataBusValRegReg;
	
	reg	[4-1:0]	cycleCnt;
	
	reg	[31:0]	wrDataCnt;
	wire	wrDone	=	OscWind_i?	(wrDataCnt	==	MeasNum_i):1'b0;
	
//================================================================================
//  ASSIGNMENTS
//================================================================================
	assign	OscDataBus_o	=	oscDataBusRegReg;
	assign	OscDataBusVal_o	=	oscDataBusValRegReg;
	
//================================================================================
//  CODING
//================================================================================	

	always	@(posedge	Clk_i)	begin
		if	(!Rst_i)	begin
			if	(OscWind_i)	begin
				if	(!wrDone)	begin
					oscDataBusValRegReg	<=	oscDataBusValReg;
				end	else	begin
					oscDataBusValRegReg	<=	0;
				end
			end	else	begin
				oscDataBusValRegReg	<=	0;
			end
		end	else	begin
			oscDataBusValRegReg	<=	0;
		end
	end
	
	always	@(posedge	Clk_i)	begin
		if	(!Rst_i)	begin
			if	(OscWind_i)	begin
				if	(oscDataBusValReg)	begin
					oscDataBusRegReg	<=	{oscDataBusReg[32*6-1-:64],oscDataBusReg[32*2-1-:64],oscDataBusReg[32*8-1-:64],oscDataBusReg[32*4-1-:64]};
					// oscDataBusRegReg	<=	{oscDataBusReg[127:0], oscDataBusReg[OutDataWidth-1:128]};
					// oscDataBusRegReg	<=	oscDataBusReg;
					// oscDataBusRegReg	<=	{16'h7,16'h6,16'h5,16'h4,16'h3,16'h2,16'h1,16'h0,16'hF,16'hE,16'hD,16'hC,16'hB,16'hA,16'h9,16'h8};
					// oscDataBusRegReg	<=	{32'hB,32'hA,32'h9,32'h8,      32'h3,32'h2,32'h1,32'h0,         32'hF,32'hE,32'hD,32'hC,       32'h7,32'h6,32'h5,32'h4};
					// oscDataBusRegReg	<=	{32'h6,32'h5,	32'h2,32'h1,	32'h8,32'h7,	32'h4,32'h3};
				end	
			end	else	begin
				oscDataBusRegReg	<=	0;
			end
		end	else	begin
			oscDataBusRegReg	<=	0;
		end
	end
	
	always	@(posedge	Clk_i)	begin
		if	(!Rst_i)	begin
			if	(OscWind_i)	begin
				if	(AdcDataVal_i)	begin
					if (cycleCnt	!=	DataValCycles-1) begin
						cycleCnt	<=	cycleCnt+4'd1;
					end else begin
						cycleCnt	<= 0;
					end 
				end
			end	else	begin
				cycleCnt	<=	0;
			end
		end	else	begin
			cycleCnt	<=	4'd0;
		end
	end
	
	always	@(posedge	Clk_i)	begin
		if	(!Rst_i)	begin
			if	(OscWind_i)	begin
				if	(oscDataBusValRegReg)	begin
					if	(wrDataCnt	!=	MeasNum_i)	begin
						wrDataCnt	<=	wrDataCnt+1;
					end
				end
			end	else	begin
				wrDataCnt	<=	0;
			end
		end	else	begin
			wrDataCnt	<=	0;
		end
	end

	always	@(posedge	Clk_i)	begin
		if	(!Rst_i)	begin
			if	(OscWind_i)	begin
				if	(AdcDataVal_i)	begin
					oscDataBusReg	<=	{AdcData_i,oscDataBusReg[OutDataWidth-1:AdcDataWidth]};	//first points
				end
			end	else	begin
				oscDataBusReg		<=	0;
			end
		end	else	begin
			oscDataBusReg		<=	0;
		end
	end
	
	always	@(posedge	Clk_i)	begin
		if	(!Rst_i)	begin
			if	(cycleCnt	==	DataValCycles-1	&	AdcDataVal_i)	begin
				oscDataBusValReg	<=	1'b1;
			end	else	begin
				oscDataBusValReg	<=	1'b0;
			end
		end	else	begin
			oscDataBusValReg	<=	1'b0;
		end
	end
	
endmodule
