////////////////////////////////////////////////////////////////////////////////////////////
// Company:			TAIR
// Engineer:		Zaytsev Mikhail
// 
// Create Date:		19/04/2024 
// Design Name: 
// Module Name:		PacketAnalyzer1Mosi 
// Project Name:	SB_TMSG44V1_FPGA
// Target Devices:	Board: SB_TMSG44v1. FPGA: GW1N-LV9PG256C6/I5
// Tool versions:
// Description:		The module analyzes the data on the DataFromSpi_i[23:0] bus using the 
// 					ValDataFromSpi_i validity signal.  When a configuration packet is received, 
// 					data is captured into the two internal registers devId and cntData. 
// 					Next, the cntData register is decremented with each incoming data parcel 
// 					until it becomes zero. If the value in the register is equal to zero means 
// 					that the module is ready to receive the next configuration packet. 
// 					As long as the value of cntData is not equal to zero at the output of the 
// 					module is active signal FlagDirect..._o for the device specified in the 
// 					register devId. The module also has an output signal Busy_o, which signals 
// 					that the module is in the state of processing data received in 1MOSI mode.
// Dependencies:	
// Revision: 
// Revision 1.0 - File Created
// Additional Comments: 
//
////////////////////////////////////////////////////////////////////////////////////////////
module PacketAnalyzer1Mosi (
	input Clk_i,
	input Rst_i,

	input [23:0] DataFromSpi_i,
	input ValDataFromSpi_i,

	input BusyMosi4_i,

	output reg FlagDirectLmx_o,
	output reg FlagDirectDds_o,
	output reg FlagDirectPot_o,
	output reg FlagDirectDac_o,
	output reg FlagDirectAtt_o,
	output reg FlagDirectShReg_o,
	output reg FlagDirectMax_o,
	output reg FlagDirectGpio_o,
	output reg FlagDirectTemp_o,

	output reg Busy_o
);

//==========================================
// Registers
//==========================================
reg [4:0] devId;
reg [16:0] cntData;

//==========================================
// Wires
//==========================================

//==========================================
// Parameters
//==========================================
localparam DEV_ID_LMX 		= 5'd0;
localparam DEV_ID_DDS 		= 5'd1;
localparam DEV_ID_POT 		= 5'd2;
localparam DEV_ID_DAC 		= 5'd3;
localparam DEV_ID_ATT 		= 5'd4;
localparam DEV_ID_SH_REG 	= 5'd5;
localparam DEV_ID_MAX 		= 5'd6;
localparam DEV_ID_GPIO 		= 5'd7;
localparam DEV_ID_TEMP 		= 5'd8;

//==========================================
// Assignments
//==========================================

//==========================================================================//
//									CODING									//
//==========================================================================//
always @(posedge Clk_i) begin
	if(Rst_i || BusyMosi4_i) begin
		devId 	<= 5'b0;
		cntData <= 17'b0;
	end 
	else if (ValDataFromSpi_i) begin
		if (cntData == 0) begin 
			if (DataFromSpi_i[23] == 0) begin
				cntData <= DataFromSpi_i[17:1];
				devId 	<= DataFromSpi_i[22:18];
			end
			else begin
				cntData <= 5'b0;
				devId 	<= 17'b0;
			end
		end	
		else begin
			cntData <= cntData - 1'b1;	
		end
	end
	else if (cntData == 0) begin
		devId <= 5'b0;
	end
end

always @(posedge Clk_i) begin
	if (Rst_i) begin
		FlagDirectLmx_o 	<= 1'b0;
		FlagDirectDds_o 	<= 1'b0;
		FlagDirectPot_o 	<= 1'b0;
		FlagDirectDac_o 	<= 1'b0;
		FlagDirectAtt_o 	<= 1'b0;
		FlagDirectShReg_o 	<= 1'b0;
		FlagDirectMax_o 	<= 1'b0;
		FlagDirectGpio_o 	<= 1'b0;
		FlagDirectTemp_o 	<= 1'b0;
	end
	else if (cntData != 0) begin
		case (devId)
			DEV_ID_LMX : begin
				FlagDirectLmx_o <= 1'b1;
			end
			DEV_ID_DDS : begin
				FlagDirectDds_o <= 1'b1;
			end
			DEV_ID_POT : begin
				FlagDirectPot_o <= 1'b1;
			end
			DEV_ID_DAC : begin
				FlagDirectDac_o <= 1'b1;
			end
			DEV_ID_ATT : begin
				FlagDirectAtt_o <= 1'b1;
			end
			DEV_ID_SH_REG : begin
				FlagDirectShReg_o <= 1'b1;
			end
			DEV_ID_MAX : begin
				FlagDirectMax_o <= 1'b1;
			end
			DEV_ID_GPIO : begin
				FlagDirectGpio_o <= 1'b1;
			end
			DEV_ID_TEMP : begin
				FlagDirectTemp_o <= 1'b1;
			end
			default : begin
				FlagDirectLmx_o 	<= 1'b0;
				FlagDirectDds_o 	<= 1'b0;
				FlagDirectPot_o 	<= 1'b0;
				FlagDirectDac_o 	<= 1'b0;
				FlagDirectAtt_o 	<= 1'b0;
				FlagDirectShReg_o 	<= 1'b0;
				FlagDirectMax_o 	<= 1'b0;
				FlagDirectGpio_o 	<= 1'b0;
				FlagDirectTemp_o 	<= 1'b0;
			end
		endcase
	end
	else begin
		FlagDirectLmx_o 	<= 1'b0;
		FlagDirectDds_o 	<= 1'b0;
		FlagDirectPot_o 	<= 1'b0;
		FlagDirectDac_o 	<= 1'b0;
		FlagDirectAtt_o 	<= 1'b0;
		FlagDirectShReg_o 	<= 1'b0;
		FlagDirectMax_o 	<= 1'b0;
		FlagDirectGpio_o 	<= 1'b0;
		FlagDirectTemp_o 	<= 1'b0;
	end
end

always @(posedge Clk_i) begin
	if (Rst_i) begin
		Busy_o <= 1'b0;
	end
	else if (cntData != 0) begin
		Busy_o <= 1'b1;
	end
	else begin
		Busy_o <= 1'b0;
	end
end

endmodule