`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	DecimFilterWrapper
#(	
	parameter	AdcDataWidth		=	14,
	parameter	N	=	8,
	parameter	M	=	2,
	parameter	FilteredDataWidth	=	38,
	parameter	FirOutDataWidth		=	48,
	parameter	FirOutCutBit		=	42,
	parameter	LsbForR1	=	10'd16,
	parameter	LsbForR2	=	10'd16,
	parameter	LsbForR4	=	10'd16
)
(
	input	Clk_i,
	input	[2:0]	DecimFactor_i,
	input	Rst_i,
	
	input	DataVal_i,
	input	signed	[AdcDataWidth-1:0]	Data_i,
	
	output	signed	[16-1:0]	Data_o,
	output	DataVal_o
);
//================================================================================
//	REG/WIRE
//================================================================================
	wire	signed	[FilteredDataWidth-1:0]	filteredData;
	wire	signed	[FilteredDataWidth-1:0]	decimData;
	
	wire	filteredDataVal;
	wire	decimDataVal;
	
	reg		decimDataValR;

	
	reg		[15:0]	outDataI;
	
	localparam	extendBitNum	=	FilteredDataWidth-AdcDataWidth;
	
	wire	[39:0]	firData;
	wire	firDataVal;
	// wire	bypassFlag = (DecimFactor_i==3'd0 | DecimFactor_i==3'd1);
	reg		[2:0]	currDecimFactor;
	wire	bypassFlag = (currDecimFactor==3'd1);
	
	
	wire	[17:0]	adcExtData	=	{{extendBitNum{Data_i[AdcDataWidth-1]}},Data_i};
	
	wire [8:0] coefAddr;
	wire [17:0] coefData;
	wire coefDataVal;
	
	wire	oscWindVal;
	
//================================================================================
//	ASSIGNMENTS
//================================================================================
	assign oscWindVal = DataVal_i&(!coefDataVal);

	assign Data_o	=	(bypassFlag)? adcExtData[LsbForR1-1-:16]:decimData[17-:16];
	assign DataVal_o	=	(bypassFlag)? DataVal_i:decimDataVal;

//================================================================================
//	CODING
//================================================================================

	always @(posedge Clk_i) begin
		if (!Rst_i) begin
			case(DecimFactor_i)
				3'd0:	begin
							currDecimFactor <= 3'd1;
						end
				3'd1:	begin
							currDecimFactor <= 3'd1;
						end
				3'd2:	begin
							currDecimFactor <= 3'd2;
						end
				3'd3:	begin
							currDecimFactor <= 3'd4;
						end
				3'd4:	begin
							currDecimFactor <= 3'd4;
						end
				3'd5:	begin
							currDecimFactor <= 3'd6;
						end
				3'd6:	begin
							currDecimFactor <= 3'd6;
						end
				3'd7:	begin
							currDecimFactor <= 3'd7;
						end
			endcase
		end
	end
	
RomCtrl	RomCtrl
(
	.Clk_i		(Clk_i),
	.Rst_i		(Rst_i),
	.OscWind_i	(DataVal_i),
	.CoefDataVal_o	(coefDataVal),
	// .DecimFactor_i	(DecimFactor_i),
	.DecimFactor_i	(currDecimFactor),
	.CoefAddr_o	(coefAddr)
);

CoefROM CoefRom (
  .a(coefAddr),      // input wire [8 : 0] a
  .spo(coefData)  // output wire [17 : 0] spo
);

systolicFilter DataFitler (
	.Clk_i(Clk_i), 
	.Rst_i(Rst_i), 
	.CoefData_i(coefData),
	// .DecimFactor_i(DecimFactor_i),
	.DecimFactor_i(currDecimFactor),
	.CoefDataVal_i(coefDataVal),
	.Data_i(adcExtData), 
	.DataNd_i(oscWindVal), 
	.Data_o(filteredData), 
	.DataValid_o(filteredDataVal)
);

decimBlock
		#(	
			// .R	(R),
			.inOutDataWidth	(18),
			.decimCntWidth	(7)
		)
		decimBlockInst
		(
			.Clk_i			(Clk_i),
			.Rst_i			(Rst_i),
			// .DecimFactor_i	(DecimFactor_i),
			.DecimFactor_i	(currDecimFactor),
			.Data_i			(filteredData),
			.DataNd_i		(filteredDataVal),
			.Data_o			(decimData),
			.DataValid_o	(decimDataVal)
		);	
endmodule








