//////////////////////////////////////////////////////////////////////////////////
// Company:			TAIR
// Engineer:		
// 
// Create Date:		10/30/2023 11:24:31 AM
// Design Name:
// Module Name:		SmcAnsMux
// Project Name:	S5443_V3_FPGA3
// Target Devices:	BOARD: BY5443v3. FPGA: xc7s25csga225-2
// Tool Versions:
// Description: 	This module multiplexing the data either from FIFO or a RegMap 
//					based on an address
// 
// Dependencies: 
// 
// Revision:
// Revision 1.0 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////
module SmcAnsMux
#(
	parameter	CMD_REG_WIDTH	=	32,
	parameter	ADDR_REG_WIDTH	=	12
)
(
	input Clk_i,
	input [ADDR_REG_WIDTH-1:0] Addr_i,
	input [ADDR_REG_WIDTH-1:0] ToRegMapAddr_i,
	input RequestToFifo_i,
	input FifoRxRst_i,
	input SmcAre_i,

	input [CMD_REG_WIDTH/2-1:0] DataFromRegMap_i,

	input [CMD_REG_WIDTH-1:0] DataFromRxFifo1_i,
	input [CMD_REG_WIDTH-1:0] DataFromRxFifo2_i,
	input [CMD_REG_WIDTH-1:0] DataFromRxFifo3_i,
	input [CMD_REG_WIDTH-1:0] DataFromRxFifo4_i,
	input [CMD_REG_WIDTH-1:0] DataFromRxFifo5_i,
	input [CMD_REG_WIDTH-1:0] DataFromRxFifo6_i,
	input [CMD_REG_WIDTH-1:0] DataFromRxFifo7_i,

	output [CMD_REG_WIDTH/2-1:0] AnsData_o
);

//================================================================================
//	REG/WIRE
//================================================================================
	wire [0:31] dataFromRxFifo [6:0];
	wire [15:0] dataFromRegMap;
	
	reg [15:0] dataFromRxFifoR;
	reg [1:0] readEnCnt;
	
	(* dont_touch = "true" *)reg [CMD_REG_WIDTH/2-1:0] dataFromRxFifoR1;
	reg [CMD_REG_WIDTH-1:0] dataFromRxFifoR2;
	reg [CMD_REG_WIDTH-1:0] dataFromRxFifoR3;
	reg [CMD_REG_WIDTH-1:0] dataFromRxFifoR4;
	reg [CMD_REG_WIDTH-1:0] dataFromRxFifoR5;
	reg [CMD_REG_WIDTH-1:0] dataFromRxFifoR6;
	reg [CMD_REG_WIDTH-1:0] dataFromRxFifoR7;
	
//================================================================================
//	ASSIGNMENTS
//================================================================================
	assign dataFromRxFifo[0] = DataFromRxFifo1_i;
	assign dataFromRxFifo[1] = DataFromRxFifo2_i;
	assign dataFromRxFifo[2] = DataFromRxFifo3_i;
	assign dataFromRxFifo[3] = DataFromRxFifo4_i;
	assign dataFromRxFifo[4] = DataFromRxFifo5_i;
	assign dataFromRxFifo[5] = DataFromRxFifo6_i;
	assign dataFromRxFifo[6] = DataFromRxFifo7_i;
	
	assign dataFromRegMap = DataFromRegMap_i;
	assign AnsData_o = (!RequestToFifo_i) ? dataFromRegMap : dataFromRxFifoR;

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

//================================================================================
//	CODING
//================================================================================	
	always @(posedge Clk_i) begin 
		if (FifoRxRst_i) begin 
			readEnCnt <= 1'b0;
		end
		else begin 
			if (!SmcAre_i) begin 
				readEnCnt <= readEnCnt + 1'b1;
			end
			else begin 
				readEnCnt <= 1'b0;
			end
		end
	end
	
	always @(*) begin
		if (!SmcAre_i && readEnCnt < 1) begin  
			case(Addr_i)
				12'h1c: begin
					dataFromRxFifoR1 = DataFromRxFifo1_i[31:16];
				end
				12'h6c: begin
					dataFromRxFifoR2 = DataFromRxFifo2_i;
				end
				12'h10c: begin
					dataFromRxFifoR3 = DataFromRxFifo3_i;
				end
				12'h15c: begin
					dataFromRxFifoR4 = DataFromRxFifo4_i;
				end
				12'h1ac: begin
					dataFromRxFifoR5 = DataFromRxFifo5_i;
				end
				12'h1fc: begin
					dataFromRxFifoR6 = DataFromRxFifo6_i;
				end
				12'h24c: begin
					dataFromRxFifoR7 = DataFromRxFifo7_i;
				end
			endcase
		end
	end
	
	always @(*) begin 
			case (Addr_i)  
				12'h1c: begin 
					dataFromRxFifoR = DataFromRxFifo1_i[15:0];
				end
				12'h1e: begin
					dataFromRxFifoR = dataFromRxFifoR1;
				end 
				12'h6c: begin 
					dataFromRxFifoR = DataFromRxFifo2_i[15:0];
				end
				12'h6e: begin 
					dataFromRxFifoR = dataFromRxFifoR2[31:16];
				end
				12'h10c: begin 
					dataFromRxFifoR = DataFromRxFifo3_i[15:0];
				end
				12'h10e: begin 
					dataFromRxFifoR = dataFromRxFifoR3[31:16];
				end
				12'h15c: begin 
					dataFromRxFifoR = DataFromRxFifo4_i[15:0];
				end
				12'h15e: begin 
					dataFromRxFifoR = dataFromRxFifoR4[31:16];
				end
				12'h1ac: begin 
					dataFromRxFifoR = DataFromRxFifo5_i[15:0];
				end
				12'h1ae: begin 
					dataFromRxFifoR = dataFromRxFifoR5[31:16];
				end
				12'h1fc: begin 
					dataFromRxFifoR = DataFromRxFifo6_i[15:0];
				end
				12'h1fe: begin 
					dataFromRxFifoR = dataFromRxFifoR6[31:16];
				end
				12'h24c: begin 
					dataFromRxFifoR = DataFromRxFifo7_i[15:0];
				end
				12'h24e: begin 
					dataFromRxFifoR = dataFromRxFifoR7[31:16];
				end
				default: begin
					dataFromRxFifoR = 16'h0;
				end
			endcase
		end
endmodule