`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// company: 
// engineer: 
// 
// create date:    16:37:06 07/11/2019 
// design name: 
// module name:    dsp_linkport_interface 
// project name: 
// target devices: 
// tool versions: 
// description: 					
//
// dependencies: 
//
// revision: 
// revision 0.01 - file created
// additional comments: 
//
//////////////////////////////////////////////////////////////////////////////////
module	DspInterface
#(	
	parameter	AdcDataWidth	=	14,	
	parameter	ExtAdcDataWidth	=	16,	
	parameter	ODataWidth		=	16,	
	parameter	ResultWidth		=	40,
	parameter	ChNum			=	16,
	parameter	CmdRegWidth		=	32,
	parameter	CmdDataRegWith	=	24,
	parameter	HeaderWidth		=	7,
	parameter	DataCntWidth	=	5,
	parameter	CmdWidth		=	3
)
(
	input	Clk_i,
	input	Rst_i,
	input	OscWind_i,
	input	StartMeasDsp_i,
	input	DspReadyForRx_i,
	input	[31:0]	MeasNum_i,
	
	input	Mosi_i,
	input	Sck_i,
	input	Ss_i,
	
	input	Mode_i,
	input	[CmdWidth-2:0]		PortSel_i,
	input	[CmdWidth-1:0]		DecimFactor_i,
	
	input	[CmdRegWidth-9:0]	IfFtwL_i,
	input	[CmdRegWidth-9:0]   IfFtwH_i,
	
	output	OscDataRdFlag_o,
	input	[AdcDataWidth-1:0]	Adc1ChT1Data_i,	
	input	[AdcDataWidth-1:0]	Adc1ChR1Data_i,	
	input	[AdcDataWidth-1:0]	Adc2ChR2Data_i,	
	input	[AdcDataWidth-1:0]	Adc2ChT2Data_i,	
	
	output	Mosi_o,
	output	Sck_o,
	output	Ss0_o,
	output	Ss1_o,
	input	Miso_i,
	output	Miso_o,

	
	output	[CmdRegWidth-1:0]	CmdDataReg_o,
	output	CmdDataVal_o,
	
	input	[CmdDataRegWith-1:0]	AnsReg_i,
	output	[HeaderWidth-1:0]		AnsAddr_o,	

	output	LpOutFs_o,
	output	LpOutClk_o,
	output	[ODataWidth-1:0]	LpOutData_o,
	
	input	[ResultWidth-1:0]	Adc1T1ImResult_i,	//T1_FIRST_IM->T2_I_F
	input	[ResultWidth-1:0]	Adc1T1ReResult_i,	//T1_FIRST_RE->T2_Q_F
	input	[ResultWidth-1:0]	Adc1R1ImResult_i,	
	input	[ResultWidth-1:0]	Adc1R1ReResult_i,	
	
	input	[ResultWidth-1:0]	Adc2R2ImResult_i,	
	input	[ResultWidth-1:0]	Adc2R2ReResult_i,	
	input	[ResultWidth-1:0]	Adc2T2ImResult_i,	//T1_SECOND_IM->T2_I_S
	input	[ResultWidth-1:0]	Adc2T2ReResult_i,	//T1_SECOND_RE->T2_Q_S
	input	[ChNum-1:0]			ServiseRegData_i,

	input	LpOutStart_i
);
//================================================================================
//	REG/WIRE
//================================================================================
	wire	[ResultWidth*(ChNum*2)-1:0]	measDataBus;
	wire	[ResultWidth*(ChNum*2)-1:0]	fftDataBus;
	wire	[ResultWidth*(ChNum*2)-1:0]	bypassDataBus;
	
	reg		[ResultWidth*(ChNum*2)-1:0]	dataForFifo;
	reg		dataForFifoVal;
	
	wire	fftDataBusVal;
	wire	bypassDataBusVal;
	
	wire	[ResultWidth*(ChNum*2)-1:0]	measDataBusTx;
	wire	measDataValTx;
	
	wire	ppiBusy;
	
	reg	signed	[15:0]	adc1ChT1DataExt;	
	reg	signed	[15:0]	adc1ChR1DataExt;	
	reg	signed	[15:0]	adc2ChR2DataExt;	
	reg	signed	[15:0]	adc2ChT2DataExt;
	
	reg		signed	[AdcDataWidth-1:0]	currDataChannel;
	wire	signed	[AdcDataWidth-1:0]	testData;
	
	wire	signed	[15:0]	filteredDecimDataI;
	wire	signed	[15:0]	filteredDecimDataQ;
	wire	filteredDecimDataVal;
//================================================================================
//	ASSIGNMENTS
//================================================================================

	assign	measDataBus	[(ResultWidth*(ChNum*2-7))-1-:ResultWidth]	=	Adc1T1ImResult_i;
	assign	measDataBus	[(ResultWidth*(ChNum*2-6))-1-:ResultWidth]	=	Adc1T1ReResult_i;
	assign	measDataBus	[(ResultWidth*(ChNum*2-5))-1-:ResultWidth]	=	Adc1R1ImResult_i;
	assign	measDataBus	[(ResultWidth*(ChNum*2-4))-1-:ResultWidth]	=	Adc1R1ReResult_i;
	assign	measDataBus	[(ResultWidth*(ChNum*2-3))-1-:ResultWidth]	=	Adc2T2ImResult_i;
	assign	measDataBus	[(ResultWidth*(ChNum*2-2))-1-:ResultWidth]	=	Adc2T2ReResult_i;
	assign	measDataBus	[(ResultWidth*(ChNum*2-1))-1-:ResultWidth]	=	Adc2R2ImResult_i;
	assign	measDataBus	[(ResultWidth*(ChNum*2-0))-1-:ResultWidth]	=	Adc2R2ReResult_i;
	
	// assign	measDataBus	[(ResultWidth*(ChNum*2-7))-1-:ResultWidth]	=	32'h4000_0000;	//2 in float
	// assign	measDataBus	[(ResultWidth*(ChNum*2-6))-1-:ResultWidth]	=	32'h4040_0000;	//3 in float
	// assign	measDataBus	[(ResultWidth*(ChNum*2-5))-1-:ResultWidth]	=	32'h4080_0000;	//4 in float
	// assign	measDataBus	[(ResultWidth*(ChNum*2-4))-1-:ResultWidth]	=	32'h4110_0000;	//9 in float
	// assign	measDataBus	[(ResultWidth*(ChNum*2-3))-1-:ResultWidth]	=	32'h3f80_0000;	//1 in float
	// assign	measDataBus	[(ResultWidth*(ChNum*2-2))-1-:ResultWidth]	=	32'h40c0_0000;	//6 in float
	// assign	measDataBus	[(ResultWidth*(ChNum*2-1))-1-:ResultWidth]	=	32'h40a0_0000;	//5 in float
	// assign	measDataBus	[(ResultWidth*(ChNum*2-0))-1-:ResultWidth]	=	32'h4000_0000;	//2 in float
	
	// assign	measDataBus	[(ResultWidth*(ChNum*2-7))-1-:ResultWidth]	=	32'h4000_0000;	//2 in float
	// assign	measDataBus	[(ResultWidth*(ChNum*2-6))-1-:ResultWidth]	=	32'h4040_0000;	//3 in float
	// assign	measDataBus	[(ResultWidth*(ChNum*2-5))-1-:ResultWidth]	=	32'h0;	//4 in float
	// assign	measDataBus	[(ResultWidth*(ChNum*2-4))-1-:ResultWidth]	=	32'h0;	//9 in float
	// assign	measDataBus	[(ResultWidth*(ChNum*2-3))-1-:ResultWidth]	=	32'h4000_0000;	//2 in float
	// assign	measDataBus	[(ResultWidth*(ChNum*2-2))-1-:ResultWidth]	=	32'h4040_0000;	//3 in float
	// assign	measDataBus	[(ResultWidth*(ChNum*2-1))-1-:ResultWidth]	=	32'h0;	//5 in float
	// assign	measDataBus	[(ResultWidth*(ChNum*2-0))-1-:ResultWidth]	=	32'h0;	//2 in float
	
	assign	OscDataRdFlag_o	=	measDataValTx;
	
//================================================================================
//	CODING
//================================================================================

reg	oscWindR;
reg	[15:0]	testPatternData;

wire	oscWindNeg	=	(!OscWind_i&oscWindR);

always	@(posedge	Clk_i)	begin
	if	(!Rst_i)	begin
		oscWindR	<=	OscWind_i;
	end	else	begin
		oscWindR	<=	0;
	end
end

always	@(posedge	Clk_i)	begin
	if	(!Rst_i)	begin
		if	(oscWindNeg)	begin
			testPatternData	<=	~testPatternData;
		end
	end	else	begin
		testPatternData	<=	16'h1fff;
	end
end

always	@(posedge	Clk_i)	begin
	if	(!Rst_i)	begin
		case(PortSel_i)
			0:	begin
					// currDataChannel	<=	testPatternData;
					currDataChannel	<=	Adc1ChT1Data_i;
				end
			1:	begin
					currDataChannel	<=	Adc1ChR1Data_i;
				end
			2:	begin
					currDataChannel	<=	Adc2ChT2Data_i;
				end
			3:	begin
					currDataChannel	<=	Adc2ChR2Data_i;
				end
		endcase
	end	else	begin
		currDataChannel	<=	0;
	end
end


SlaveSpi
#(	
	.CmdRegWidth	(CmdRegWidth),
	.DataCntWidth	(DataCntWidth),
	.HeaderWidth	(HeaderWidth)
)
DspSlaveSpi
(
	.Clk_i		(Clk_i),
	.Rst_i		(Rst_i),

	.Data_o		(CmdDataReg_o),
	.Val_o		(CmdDataVal_o),
	
	.Mosi_i		(Mosi_i),
	.Sck_i		(Sck_i),
	.Ss_i		(Ss_i),
	
	.Mosi_o		(Mosi_o),
	.Sck_o		(Sck_o),
	.Ss0_o		(Ss0_o),
	.Ss1_o		(Ss1_o),
	
	.AnsAddr_o	(AnsAddr_o),
	.AnsReg_i	(AnsReg_i),
	
	.Miso_i		(Miso_i),
	.Miso_o		(Miso_o)
);

// DecimFilterWrapper	DecimFilter
// (
	// .Clk_i			(Clk_i),
	// .Rst_i			(Rst_i),
	// .OscWind_i		(OscWind_i),
	// .DecimFactor_i	(DecimFactor_i),
	
	// .IfFtwL_i		(IfFtwL_i),
	// .IfFtwH_i		(IfFtwH_i),
	
	// .AdcData_i		(currDataChannel),
	// .TestData_o		(testData),
	
	// .FilteredAdcDataI_o	(filteredDecimDataI),
	// .FilteredAdcDataQ_o	(filteredDecimDataQ),
	// .FilteredDataVal_o	(filteredDecimDataVal)
// );

// FftDataFormer	FftDataFormerInst
// (
	// .Clk_i				(Clk_i), 
	// .Rst_i				(Rst_i),	
	// .OscWind_i			(OscWind_i),
	// .MeasNum_i			(MeasNum_i),
	
	// .AdcData_i			({filteredDecimDataI,filteredDecimDataQ}),
	// .AdcData_i			({testPatternData,testPatternData}),
	// .AdcDataVal_i		(filteredDecimDataVal),
	
	// .OscDataBus_o		(fftDataBus),
	// .OscDataBusVal_o	(fftDataBusVal)
// );

// OscDataFormer	BypassDataFormer
// (
	// .Clk_i				(Clk_i), 
	// .Rst_i				(Rst_i),	
	// .OscWind_i			(OscWind_i),
	// .MeasNum_i			(MeasNum_i),
	
	// .AdcData_i			(currDataChannel),	
	
	// .OscDataBus_o		(bypassDataBus),
	// .OscDataBusVal_o	(bypassDataBusVal)
// );

// always	@(posedge	Clk_i)	begin
	// if	(!Rst_i)	begin
		// if	(Mode_i)	begin
			// if	(DecimFactor_i	==	0)	begin
				// dataForFifo		<=	bypassDataBus;
				// dataForFifoVal	<=	bypassDataBusVal;
			// end	else	begin
				// dataForFifo		<=	fftDataBus;
				// dataForFifoVal	<=	fftDataBusVal;
			// end
		// end	else	begin
			// dataForFifo		<=	measDataBus;
			// dataForFifoVal	<=	LpOutStart_i;
		// end
	// end	else	begin
		// dataForFifo		<=	0;
		// dataForFifoVal	<=	0;
	// end
// end

MeasDataFifoWrapper		
#(	
	.DataWidth	(ResultWidth),
	.ChNum		(ChNum)
)
MeasDataFifoInst
(
	.Clk_i			(Clk_i), 
	.Rst_i			(Rst_i),	
	.PpiBusy_i		(ppiBusy),	
	.MeasNum_i		(MeasNum_i),	
	.StartMeasDsp_i	(StartMeasDsp_i),	
	.DspReadyForRx_i(DspReadyForRx_i),	
	.MeasDataBus_i	(measDataBus),
	// .MeasDataBus_i	(dataForFifo),
	.MeasDataVal_i	(LpOutStart_i),	
	// .MeasDataVal_i	(dataForFifoVal),	
	
	.MeasDataBus_o	(measDataBusTx),
	.MeasDataVal_o	(measDataValTx)
);

DspPpiOut	
#(	
	.ODataWidth		(ODataWidth),	
	.ResultWidth	(ResultWidth), 
	.ChNum			(ChNum)
)
MeasDataPpiOut
(
	.Rst_i				(Rst_i),	
	.Clk_i				(Clk_i),		
	
	.MeasDataBus_i		(measDataBusTx),
	.ServiseRegData_i	(ServiseRegData_i),
	
	.PpiBusy_o			(ppiBusy),
	.LpOutStart_i		(measDataValTx),
	
	.LpOutClk_o			(LpOutClk_o),
	.LpOutFs_o			(LpOutFs_o),
	.LpOutData_o		(LpOutData_o)
);

endmodule







