`timescale 1ns / 1ps

module DecimFilterWrapperTb	();

reg		Clk50;
reg		Rst;

reg		[2:0]	decimFactor;

parameter	MaxWidth	=	32;

reg		[13:0]	adcData;
real	pi	=	3.14159265358;
real	phase	=	0;
real	phaseInc	=	0.001;
real	signal;

reg		[31:0]	tbCnt;
reg		[31:0]	pNumCnt;
wire	oscWind	=	(tbCnt>=4500&tbCnt<=4999)?	1'b1:1'b0;
// wire	oscWind	=	(tbCnt>=4500&tbCnt<=4999)||(tbCnt>=5500&tbCnt<=5999)||(tbCnt>=6500&tbCnt<=6999)||(tbCnt>=7500&tbCnt<=7999)||(tbCnt>=8500&tbCnt<=8999)||(tbCnt>=9500&tbCnt<=9999)?	1'b1:1'b0;
// wire	oscWind	=	(tbCnt>=1&)?	1'b1:1'b0;

wire	signed	[13:0]	ncoSin1;
wire	signed	[13:0]	ncoSin2;
wire	signed	[13:0]	ncoSin3;

wire	signed	[15:0]	filteredDataOut;
wire	signed	[MaxWidth-1:0]	impResponse;

wire	resultVal;
wire	respVal;


// wire	signed	[27:0]	adcDataMixed	=	oscWind?(ncoSin1*ncoSin2):28'd0;
wire	signed	[27:0]	adcDataMixed	=	(ncoSin1*ncoSin2);
wire	signed	[13:0]	adcDataMixedCut	=	adcDataMixed[26-:14];

// wire	signed	[13:0]	sinAdd	=	(ncoSin1>>>2)+(ncoSin2>>>2)+(ncoSin3>>>2);
wire	signed	[13:0]	sinAdd	=	(ncoSin1>>>1)+(ncoSin2>>>1);
// wire	signed	[13:0]	sinAdd	=	ncoSin1;
wire	signed	[15:0]	sinAddExt16	=	{{2{ncoSin2[14-1]}},ncoSin2};
wire	signed	[17:0]	sinAddExt18	=	{{4{sinAdd[14-1]}},sinAdd};

reg		signed	[13:0]	currTestData;

wire	signed	[17:0]	wind;

// wire	signed	[13:0]	singlePulse	=	(tbCnt>=4500&tbCnt<=4550)?	14'h1fff:14'h0;
wire	signed	[13:0]	singlePulse	=	(tbCnt==4551)?	14'h1fff:14'h0;
wire	signed	[17:0]	singlePulseExt	=	(tbCnt==4500)?	18'h1ffff:14'h0;
// wire	signed	[15:0]	singlePulseExt	=	(tbCnt>=4500&tbCnt<=4501)?	16'h7fff:14'h0;
wire	inglePulseExtVal	=	(tbCnt==4500)?	1:0;
//==========================================================================================
//clocks gen
always	#10 Clk50	=	~Clk50;

//==========================================================================================
parameter	N	=	8;
parameter	M	=	2;



parameter	LsbForR1	=	10'd16;
parameter	LsbForR2	=	10'd18;
parameter	LsbForR4	=	10'd18;
	
parameter	[31:0]	Nco1PhaseInc	=	32'h051eb852;	 //3mhz
parameter	[31:0]	Nco2PhaseInc	=	32'h40000000;	//15
parameter	[31:0]	Nco3PhaseInc	=	32'h428f5c28;	

initial begin
	Clk50		=	1'b1;
	Rst			=	1'b1;
#200;
	Rst			=	1'b0;
end	



always	@(posedge	Clk50)	begin
	if	(!Rst)	begin
		tbCnt	<=	tbCnt+32'd1;
	end	else	begin
		tbCnt	<=	32'd0;
	end
end

reg	[20:0]	oscWindDelay;

always	@(posedge	Clk50)	begin
	if	(!Rst)	begin
		oscWindDelay	<=	{oscWindDelay[20:0],oscWind};
	end	else	begin
		oscWindDelay	<= 22'd0;
	end
end

always	@(posedge	Clk50)	begin
	if	(!Rst)	begin
		if	(oscWind)	begin
			pNumCnt	<=	pNumCnt+32'd1;
		end	else	begin
			pNumCnt	<=	32'd0;
		end
	end	else	begin
		pNumCnt	<=	32'd0;
	end
end

always @ (posedge Clk50)	begin
	if (oscWind)	begin
			phase = phase + phaseInc;
			phaseInc <= phaseInc + 0.003;
			signal = $sin(2*pi*phase);
			adcData = 2**12 * signal;
	end	else	begin
		adcData = 0;
		phase	=	0;
		phaseInc	=	0.001;
	end
end
	
always	@(posedge	Clk50)	begin
	if	(!Rst)	begin
		if (tbCnt == 100) begin
			decimFactor	<= 2;
		end
		// end else if (tbCnt == 5400) begin
			// decimFactor	<= 1;
		// end else if (tbCnt == 6400) begin
			// decimFactor	<= 2;
		// end else if (tbCnt == 7400) begin
			// decimFactor	<= 3;
		// end else if (tbCnt == 8400) begin
			// decimFactor	<= 4;
		// end else if (tbCnt == 9400) begin
			// decimFactor	<= 5;
		// end else if (tbCnt == 10400) begin
			// decimFactor	<= 6;
		// end else if (tbCnt == 11400) begin
			// decimFactor	<= 7;
		// end
	end else begin
	 decimFactor <= 2;
	end 
end

CordicNco		
#(	
	.ODatWidth	(14),
	.PhIncWidth	(32),
	.IterNum	(10),
	.EnSinN		(1)
)
ncoInst1
(
	.Clk_i		(Clk50),
	.Rst_i		(Rst),
	.Val_i		(1'b1),
	.PhaseInc_i	(Nco1PhaseInc),
	.WindVal_i	(1'b1),
	.WinType_i	(),
	.Wind_o		(),
	.Sin_o		(ncoSin1),
	.Cos_o		(),
	.Val_o		()
);

CordicNco		
#(	
	.ODatWidth	(14),
	.PhIncWidth	(32),
	.IterNum	(10),
	.EnSinN		(1)
)
ncoInst2
(
	.Clk_i		(Clk50),
	.Rst_i		(Rst),
	.Val_i		(1'b1),
	.PhaseInc_i	(Nco2PhaseInc),
	.WindVal_i	(1'b1),
	.WinType_i	(),
	.Wind_o		(),
	.Sin_o		(ncoSin2),
	.Cos_o		(),
	.Val_o		()
);

CordicNco		
#(	
	.ODatWidth	(14),
	.PhIncWidth	(32),
	.IterNum	(10),
	.EnSinN		(1)
)
ncoInst3
(
	.Clk_i		(Clk50),
	.Rst_i		(Rst),
	.Val_i		(1'b1),
	.PhaseInc_i	(Nco3PhaseInc),
	.WindVal_i	(1'b1),
	.WinType_i	(),
	.Wind_o		(),
	.Sin_o		(ncoSin3),
	.Cos_o		(),
	.Val_o		()
);


DecimFilterWrapperTest	
#(	
	.AdcDataWidth	(14),
	.N	(N),
	.M	(M),
	.FilteredDataWidth	(MaxWidth),
	.FirOutDataWidth	(48),
	.FirOutCutBit		(42),
	.LsbForR1			(LsbForR1),
	.LsbForR2			(LsbForR2),
	.LsbForR4			(LsbForR4)
)
DecimFilter
(
	.Clk_i			(Clk50),
	.DecimFactor_i	(decimFactor),
	.Rst_i			(Rst),
	.DataVal_i		(oscWind),

	// .Data_i		(sinAdd),
	.Data_i		(adcDataMixedCut),
	// .Data_i		(adcData),
	// .Data_i		(ncoSin2),
	
	.Data_o	(filteredDataOut),
	.DataVal_o	(resultVal)
);

DecimFilterWrapperTest	
#(	
	.AdcDataWidth	(14),
	.N	(N),
	.M	(M),
	.FilteredDataWidth	(MaxWidth),
	.FirOutDataWidth	(48),
	.FirOutCutBit		(42),
	.LsbForR1			(LsbForR1),
	.LsbForR2			(LsbForR2),
	.LsbForR4			(LsbForR4)
)
ImpulseResponseFilter
(
	.Clk_i			(Clk50),
	.DecimFactor_i	(decimFactor),
	.Rst_i			(Rst),
	.DataVal_i		(oscWind),

	.Data_i		(singlePulse),
	
	.Data_o	(impResponse),
	.DataVal_o	()
);

// reg		[32-1:0]	windArg;
// wire	[31:0]	WindPhInc		=	32'h418937<<<decimFactor-2;

// always	@(posedge	Clk50)	begin
	// if	(!Rst)	begin
		// if	(resultVal)	begin
			// windArg	<=	windArg+WindPhInc;
		// end
	// end	else	begin
		// windArg	<=	WindPhInc>>1;
	// end
// end	

// reg	[1:0]	valReg;
// always	@(posedge	Clk50)	begin
	// if	(!Rst)	begin
		// valReg[0]	<=	resultVal;
		// valReg[1]	<=	valReg[0];
	// end	else	begin
		// valReg	<=	2'b0;
	// end
// end
	


integer inSignal,filteredData, impResp;
parameter	PNum	=	5000;

// wire	signed	[17:0]	firDataOut;
// wire	signed	[17:0]	firRespout;
// wire	firDataVal;
// wire	firRespVal;

// systolicFilter DataFitler (
	// .Clk_i(Clk50), 
	// .Rst_i(Rst), 
	// .Data_i(sinAddExt18), 
	// .DataNd_i(oscWind), 
	// .Data_o(firDataOut), 
	// .DataValid_o(firDataVal)
// );

// systolicFilter RespFilter (
	// .Clk_i(Clk50), 
	// .Rst_i(Rst), 
	// .Data_i(singlePulseExt), 
	// .DataNd_i(oscWind), 
	// .Data_o(firRespout), 
	// .DataValid_o(firRespVal)
// );



always	@(posedge	Clk50)	begin
	if	(tbCnt==32'd1)	begin
		inSignal = $fopen("C:/S5243_FFT_REPO/src/src/Sim/InputSignal.txt","w");
	end	else	begin
		if	(oscWind)	begin
			// $display("AdcData is %d", sinAdd);
			// $fwrite(inSignal,"%d\n",   sinAddExt18);
			$fwrite(inSignal,"%d\n",   adcDataMixedCut);
			// $fwrite(inSignal,"%d\n",   adcData);
		end	
	end	
end

reg	[31:0]	testCnt;
wire	[10:0]	test = N*2+N*2+decimFactor;
wire	[10:0]	test1 = N*2+N*2+decimFactor-1;
wire	writeEn	=	(oscWindDelay[N*2+N*2+decimFactor]);

always	@(posedge	Clk50)begin
	if	(!Rst)	begin
		if	(writeEn)	begin
			testCnt	<=	testCnt	+1;
		end
	end	else	begin
		testCnt	<=	0;
	end
end

always	@(posedge	Clk50)	begin
	if	(tbCnt==32'd1)	begin
		filteredData = $fopen("C:/S5243_FFT_REPO/src/src/Sim/FilteredData.txt","w");
	end	else	begin
		if	(resultVal)	begin
			$fwrite(filteredData,"%d\n",   filteredDataOut);
			// $fwrite(filteredData,"%d\n",   firDataOut);
		end	
	end	
end
 

always	@(posedge	Clk50)	begin
	if	(tbCnt==32'd1)	begin
		impResp = $fopen("C:/S5243_FFT_REPO/src/src/Sim/ImpResp.txt","w");
	end	else	begin
		if	(resultVal)	begin
			// $fwrite(impResp,"%d\n",   firRespout);
			$fwrite(impResp,"%d\n",   impResponse);
		end	
	end
end 

endmodule



















