//////////////////////////////////////////////////////////////////////////////////
// Company:			TAIR
// Engineer:		
// 
// Create Date:		10/30/2023 11:24:31 AM
// Design Name:
// Module Name:		SmcInDataMux
// Project Name:	S5443_V3_FPGA3
// Target Devices:	BOARD: BY5443v3. FPGA: xc7s25csga225-2
// Tool Versions:
// Description: 	This module determines which entity is referred(FIFO or a RegMap)
//					based on an adrress and sets a validity signal	
// 
// Dependencies: 
// 
// Revision:
// Revision 1.0 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////
module SmcInDataMux 
#(
	parameter	CMD_REG_WIDTH	=	16,
	parameter	ADDR_REG_WIDTH	=	12,
	
	parameter	FIFO_NUM	=	7,
	
	parameter	FIFO_0_WRITE_LSB_ADDR	=	12'h0+12'd24,
	parameter	FIFO_0_WRITE_MSB_ADDR	=	12'h0+12'd26,
	parameter	FIFO_1_WRITE_LSB_ADDR	=	12'h50+12'd24,
	parameter	FIFO_1_WRITE_MSB_ADDR	=	12'h50+12'd26,
	parameter	FIFO_2_WRITE_LSB_ADDR	=	12'hf0+12'd24,
	parameter	FIFO_2_WRITE_MSB_ADDR	=	12'hf0+12'd26,
	parameter	FIFO_3_WRITE_LSB_ADDR	=	12'h140+12'd24,
	parameter	FIFO_3_WRITE_MSB_ADDR	=	12'h140+12'd26,
	parameter	FIFO_4_WRITE_LSB_ADDR	=	12'h190+12'd24,
	parameter	FIFO_4_WRITE_MSB_ADDR	=	12'h190+12'd26,
	parameter	FIFO_5_WRITE_LSB_ADDR	=	12'h1e0+12'd24,
	parameter	FIFO_5_WRITE_MSB_ADDR	=	12'h1e0+12'd26,
	parameter	FIFO_6_WRITE_LSB_ADDR	=	12'h230+12'd24,
	parameter	FIFO_6_WRITE_MSB_ADDR	=	12'h230+12'd26,

	parameter	FIFO_0_READ_LSB_ADDR	=	12'h0+12'd28,
	parameter	FIFO_0_READ_MSB_ADDR	=	12'h0+12'd30,
	parameter	FIFO_1_READ_LSB_ADDR	=	12'h50+12'd28,
	parameter	FIFO_1_READ_MSB_ADDR	=	12'h50+12'd30,
	parameter	FIFO_2_READ_LSB_ADDR	=	12'hf0+12'd28,
	parameter	FIFO_2_READ_MSB_ADDR	=	12'hf0+12'd30,
	parameter	FIFO_3_READ_LSB_ADDR	=	12'h140+12'd28,
	parameter	FIFO_3_READ_MSB_ADDR	=	12'h140+12'd30,
	parameter	FIFO_4_READ_LSB_ADDR	=	12'h190+12'd28,
	parameter	FIFO_4_READ_MSB_ADDR	=	12'h190+12'd30,
	parameter	FIFO_5_READ_LSB_ADDR	=	12'h1e0+12'd28,
	parameter	FIFO_5_READ_MSB_ADDR	=	12'h1e0+12'd30,
	parameter	FIFO_6_READ_LSB_ADDR	=	12'h230+12'd28,
	parameter	FIFO_6_READ_MSB_ADDR	=	12'h230+12'd30
)
(
	input	Clk_i,
	input	Rst_i,

	input	SmcVal_i,
	input	[CMD_REG_WIDTH-1:0]		SmcData_i,
	input	[ADDR_REG_WIDTH-1:0]	SmcAddr_i,

	output	RequestToFifo_o,

	output	reg	ToRegMapVal_o,
	output	reg	[CMD_REG_WIDTH-1:0]		ToRegMapData_o,
	output	reg	[ADDR_REG_WIDTH-1:0]	ToRegMapAddr_o,
	
	output	reg	[FIFO_NUM-1:0]	ToFifoVal_o,
	output	reg	[CMD_REG_WIDTH*2*FIFO_NUM-1:0]	ToFifoData_o
);

//================================================================================
//	REG/WIRE
//================================================================================
	wire	requestToFifo0	=((SmcAddr_i==FIFO_0_WRITE_LSB_ADDR||SmcAddr_i==FIFO_0_WRITE_MSB_ADDR)|| (SmcAddr_i==FIFO_0_READ_LSB_ADDR||SmcAddr_i==FIFO_0_READ_MSB_ADDR));
	wire	requestToFifo1	=((SmcAddr_i==FIFO_1_WRITE_LSB_ADDR||SmcAddr_i==FIFO_1_WRITE_MSB_ADDR)|| (SmcAddr_i==FIFO_1_READ_LSB_ADDR||SmcAddr_i==FIFO_1_READ_MSB_ADDR));
	wire	requestToFifo2	=((SmcAddr_i==FIFO_2_WRITE_LSB_ADDR||SmcAddr_i==FIFO_2_WRITE_MSB_ADDR)|| (SmcAddr_i==FIFO_2_READ_LSB_ADDR||SmcAddr_i==FIFO_2_READ_MSB_ADDR));
	wire	requestToFifo3	=((SmcAddr_i==FIFO_3_WRITE_LSB_ADDR||SmcAddr_i==FIFO_3_WRITE_MSB_ADDR)|| (SmcAddr_i==FIFO_3_READ_LSB_ADDR||SmcAddr_i==FIFO_3_READ_MSB_ADDR));
	wire	requestToFifo4	=((SmcAddr_i==FIFO_4_WRITE_LSB_ADDR||SmcAddr_i==FIFO_4_WRITE_MSB_ADDR)|| (SmcAddr_i==FIFO_4_READ_LSB_ADDR||SmcAddr_i==FIFO_4_READ_MSB_ADDR));
	wire	requestToFifo5	=((SmcAddr_i==FIFO_5_WRITE_LSB_ADDR||SmcAddr_i==FIFO_5_WRITE_MSB_ADDR)|| (SmcAddr_i==FIFO_5_READ_LSB_ADDR||SmcAddr_i==FIFO_5_READ_MSB_ADDR));
	wire	requestToFifo6	=((SmcAddr_i==FIFO_6_WRITE_LSB_ADDR||SmcAddr_i==FIFO_6_WRITE_MSB_ADDR)|| (SmcAddr_i==FIFO_6_READ_LSB_ADDR||SmcAddr_i==FIFO_6_READ_MSB_ADDR));
	
	wire	requestToFifo	=	(requestToFifo0|requestToFifo1|requestToFifo2|requestToFifo3|requestToFifo4|requestToFifo5|requestToFifo6);

//================================================================================
//	ASSIGNMENTS
//================================================================================
	assign	RequestToFifo_o	=	requestToFifo;

//================================================================================
//	LOCALPARAMS
//================================================================================

//================================================================================
//	CODING
//================================================================================
	always	@(posedge	Clk_i	or	posedge	Rst_i)	begin
		if	(Rst_i)	begin
			ToRegMapVal_o	<=	1'b0;
			ToRegMapData_o	<=	16'h0;
			ToRegMapAddr_o	<=	12'h0;
			
			ToFifoVal_o		<=	7'h0;
			ToFifoData_o	<=	0;
		end	else	begin
			if	(requestToFifo)	begin	
				case(SmcAddr_i)	
					FIFO_0_WRITE_LSB_ADDR:	begin
										ToFifoVal_o[0]	<=	1'b0;
										ToFifoData_o[CMD_REG_WIDTH*0+:CMD_REG_WIDTH]	<=	SmcData_i;
									end
					FIFO_0_WRITE_MSB_ADDR:	begin
										ToFifoVal_o[0]	<=	SmcVal_i;
										ToFifoData_o[CMD_REG_WIDTH*1+:CMD_REG_WIDTH]	<=	SmcData_i;
									end
									
					FIFO_1_WRITE_LSB_ADDR:	begin
										ToFifoVal_o[1]	<=	1'b0;
										ToFifoData_o[CMD_REG_WIDTH*2+:CMD_REG_WIDTH]	<=	SmcData_i;
									end
					FIFO_1_WRITE_MSB_ADDR:	begin
										ToFifoVal_o[1]	<=	SmcVal_i;
										ToFifoData_o[CMD_REG_WIDTH*3+:CMD_REG_WIDTH]	<=	SmcData_i;
									end
									
					FIFO_2_WRITE_LSB_ADDR:	begin
										ToFifoVal_o[2]	<=	1'b0;
										ToFifoData_o[CMD_REG_WIDTH*4+:CMD_REG_WIDTH]	<=	SmcData_i;
									end
					FIFO_2_WRITE_MSB_ADDR:	begin
										ToFifoVal_o[2]	<=	SmcVal_i;
										ToFifoData_o[CMD_REG_WIDTH*5+:CMD_REG_WIDTH]	<=	SmcData_i;
									end
									
					FIFO_3_WRITE_LSB_ADDR:	begin
										ToFifoVal_o[3]	<=	1'b0;
										ToFifoData_o[CMD_REG_WIDTH*6+:CMD_REG_WIDTH]	<=	SmcData_i;
									end
					FIFO_3_WRITE_MSB_ADDR:	begin
										ToFifoVal_o[3]	<=	SmcVal_i;
										ToFifoData_o[CMD_REG_WIDTH*7+:CMD_REG_WIDTH]	<=	SmcData_i;
									end
									
					FIFO_4_WRITE_LSB_ADDR:	begin
										ToFifoVal_o[4]	<=	1'b0;
										ToFifoData_o[CMD_REG_WIDTH*8+:CMD_REG_WIDTH]	<=	SmcData_i;
									end
					FIFO_4_WRITE_MSB_ADDR:	begin
										ToFifoVal_o[4]	<=	SmcVal_i;
										ToFifoData_o[CMD_REG_WIDTH*9+:CMD_REG_WIDTH]	<=	SmcData_i;
									end
									
					FIFO_5_WRITE_LSB_ADDR:	begin
										ToFifoVal_o[5]	<=	1'b0;
										ToFifoData_o[CMD_REG_WIDTH*10+:CMD_REG_WIDTH]	<=	SmcData_i;
									end
					FIFO_5_WRITE_MSB_ADDR:	begin
										ToFifoVal_o[5]	<=	SmcVal_i;
										ToFifoData_o[CMD_REG_WIDTH*11+:CMD_REG_WIDTH]	<=	SmcData_i;
									end
									
					FIFO_6_WRITE_LSB_ADDR:	begin
										ToFifoVal_o[6]	<=	1'b0;
										ToFifoData_o[CMD_REG_WIDTH*12+:CMD_REG_WIDTH]	<=	SmcData_i;
									end
					FIFO_6_WRITE_MSB_ADDR:	begin
										ToFifoVal_o[6]	<=	SmcVal_i;
										ToFifoData_o[CMD_REG_WIDTH*13+:CMD_REG_WIDTH]	<=	SmcData_i;
									end
				endcase
				ToRegMapAddr_o	<=	0;
				ToRegMapVal_o	<=	0;
			end	else	begin
				ToRegMapVal_o	<=	SmcVal_i;
				ToFifoVal_o		<=	7'h0;
				ToRegMapData_o	<=	SmcData_i;
				ToRegMapAddr_o	<=	SmcAddr_i;
				ToFifoData_o	<=	0;
			end
		end
	end
endmodule