
//////////////////////////////////////////////////////////////////////////////////
// Company:			TAIR
// Engineer:		
// 
// Create Date:		10/30/2023 11:24:31 AM
// Design Name:
// Module Name:		QuadSPIm
// Project Name:	S5443_V3_FPGA3
// Target Devices:	BOARD: BY5443v3. FPGA: xc7s25csga225-2
// Tool Versions:
// Description: 	This is module implements QuadSpi Master protocol. For more info refer 
//					to the techincal reference manual. 
// 
// Dependencies: 
// 
// Revision:
// Revision 1.0 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////
module QuadSPIm
(
    input Clk_i,
    input Rst_i,
    input Start_i,
    input EmptyFlag_i,
    input ClockPhase_i,
    input [31:0] SpiData_i,
    input SelSt_i,
    input [1:0] WidthSel_i,
    input  Lag_i,
    input  Lead_i,
    input EndianSel_i,
    input [5:0] Stop_i,
    input PulsePol_i,   
    output reg Mosi0_o,
    output reg Mosi1_o,
    output reg Mosi2_o,
    output reg Mosi3_o,
    output reg  Sck_o,
    output reg Val_o,
    output Ss_o 
);
//================================================================================
//  REG/WIRE
//================================================================================
    reg startFlag;
    reg startR;
    reg [31:0] trCnt;

    reg valReg;
    reg lineBusy;
    reg [5:0] ssCnt;
    reg ss;
    reg ssR;
    reg oldDataFlag;
    reg [7:0] mosiReg0;
    reg [7:0] mosiReg1;
    reg [7:0] mosiReg2;
    reg [7:0] mosiReg3;
    reg [3:0] ssNum;
    reg [2:0] delayCnt;
    reg stopFlag;
	
	wire [31:0] txLenght = ssNum+Lag_i+Lead_i;
//================================================================================
//  ASSIGNMENTS
//================================================================================

    assign Ss_o = ss; 
//================================================================================
//  CODING
//================================================================================	


    always @(*) begin 
        if (Start_i) begin 
            Val_o = valReg;
        end
        else begin 
            Val_o = 1'b0;
        end
    end

    always @(*) begin 
        if (SelSt_i) begin 
            if (!ss) begin 
                lineBusy = 1'b1;
            end
            else begin 
                lineBusy = 1'b0;
            end
        end
        else begin 
            if (ss) begin 
                lineBusy = 1'b1;
            end
            else begin 
                lineBusy = 1'b0;
            end
        end
    end
	
	always @(negedge Clk_i) begin 
        if (Rst_i) begin 
            delayCnt <= 1'b0;
        end else begin 
			if (stopFlag) begin 
				delayCnt <= delayCnt + 1'b1;
			end else begin
				delayCnt <= 0;
			end
		end
    end
	
    always @(*) begin 
        if (Rst_i) begin 
            stopFlag = 1'b0;
        end
        else begin
			if (Stop_i != 0) begin
				if (SelSt_i) begin 
					if (ss && !ssR) begin 
						stopFlag = 1'b1;
					end
					else if (delayCnt == Stop_i-1) begin 
						stopFlag = 1'b0;
					end
				end
				else begin 
					if (!ss && ssR) begin 
						stopFlag = 1'b1;
					end
					else if (delayCnt == Stop_i-1) begin 
						stopFlag = 1'b0;
					end
				end
			end else begin
				stopFlag = 1'b0;
			end
        end
    end
	
	reg [2:0] clkCtrlReg;
	always @(*) begin
		if (Rst_i) 	begin
			clkCtrlReg = 0;
		end else begin
			clkCtrlReg = {SelSt_i,PulsePol_i,ClockPhase_i};
		end
	end
	
	always @(*) begin
		if (Rst_i) begin
			Sck_o = 0;
		end else begin
			if (Stop_i!=0) begin
				case (clkCtrlReg) 
					0:	begin
							if (!Lag_i) begin
								if (!Lead_i) begin
									if (ss) begin
										Sck_o = Clk_i;
									end else begin
										Sck_o = 0;
									end
								end else begin
									if (ssCnt < txLenght-1) begin
										Sck_o = Clk_i;
									end else begin
										Sck_o = 0;
									end
								end
							end else begin
								if (!Lead_i) begin
									if (ssCnt > 0) begin
										Sck_o = Clk_i;
									end else begin
										Sck_o = 0;
									end
								end else begin
									if (ssCnt >0 && ssCnt < txLenght-1) begin
										Sck_o = Clk_i;
									end else begin
										Sck_o = 0;
									end
								end
							end
						end
					1:	begin
							if (!Lag_i) begin
								if (!Lead_i) begin
									if (ss) begin
										Sck_o = !Clk_i;
									end else begin
										Sck_o = 0;
									end
								end else begin
									if (ssCnt < txLenght-1) begin
										Sck_o = !Clk_i;
									end else begin
										Sck_o = 0;
									end
								end
							end else begin
								if (!Lead_i) begin
									if (ssCnt > 0) begin
										Sck_o = !Clk_i;
									end else begin
										Sck_o = 0;
									end
								end else begin
									if (ssCnt >0 && ssCnt < txLenght-1) begin
										Sck_o = !Clk_i;
									end else begin
										Sck_o = 0;
									end
								end
							end
						end
					2:	begin
							if (!Lag_i) begin
								if (!Lead_i) begin
									if (ss) begin
										Sck_o = !Clk_i;
									end else begin
										Sck_o = 0;
									end
								end else begin
									if (ssCnt < txLenght-1) begin
										Sck_o = !Clk_i;
									end else begin
										Sck_o = 0;
									end
								end
							end else begin
								if (!Lead_i) begin
									if (ssCnt > 0) begin
										Sck_o = !Clk_i;
									end else begin
										Sck_o = 0;
									end
								end else begin
									if (ssCnt >0 && ssCnt < txLenght-1) begin
										Sck_o = !Clk_i;
									end else begin
										Sck_o = 0;
									end
								end
							end
						end
					3:	begin
							if (!Lag_i) begin
								if (!Lead_i) begin
									if (ss) begin
										Sck_o = Clk_i;
									end else begin
										Sck_o = 0;
									end
								end else begin
									if (ssCnt < txLenght-1) begin
										Sck_o = Clk_i;
									end else begin
										Sck_o = 0;
									end
								end
							end else begin
								if (!Lead_i) begin
									if (ssCnt > 0) begin
										Sck_o = Clk_i;
									end else begin
										Sck_o = 0;
									end
								end else begin
									if (ssCnt >0 && ssCnt < txLenght-1) begin
										Sck_o = Clk_i;
									end else begin
										Sck_o = 0;
									end
								end
							end
						end
					4:	begin
							if (!Lag_i) begin
								if (!Lead_i) begin
									if (!ss) begin
										Sck_o = Clk_i;
									end else begin
										Sck_o = 0;
									end
								end else begin
									if (ssCnt < txLenght-1) begin
										Sck_o = Clk_i;
									end else begin
										Sck_o = 0;
									end
								end
							end else begin
								if (!Lead_i) begin
									if (ssCnt > 0) begin
										Sck_o = Clk_i;
									end else begin
										Sck_o = 0;
									end
								end else begin
									if (ssCnt >0 && ssCnt < txLenght-1) begin
										Sck_o = Clk_i;
									end else begin
										Sck_o = 0;
									end
								end
							end
						end
					5:	begin
							if (!Lag_i) begin
								if (!Lead_i) begin
									if (!ss) begin
										Sck_o = !Clk_i;
									end else begin
										Sck_o = 0;
									end
								end else begin
									if (ssCnt < txLenght-1) begin
										Sck_o = !Clk_i;
									end else begin
										Sck_o = 0;
									end
								end
							end else begin
								if (!Lead_i) begin
									if (ssCnt > 0) begin
										Sck_o = !Clk_i;
									end else begin
										Sck_o = 0;
									end
								end else begin
									if (ssCnt >0 && ssCnt < txLenght-1) begin
										Sck_o = !Clk_i;
									end else begin
										Sck_o = 0;
									end
								end
							end
						end
					6:	begin
							if (!Lag_i) begin
								if (!Lead_i) begin
									if (!ss) begin
										Sck_o = !Clk_i;
									end else begin
										Sck_o = 0;
									end
								end else begin
									if (ssCnt < txLenght-1) begin
										Sck_o = !Clk_i;
									end else begin
										Sck_o = 0;
									end
								end
							end else begin
								if (!Lead_i) begin
									if (ssCnt > 0) begin
										Sck_o = !Clk_i;
									end else begin
										Sck_o = 0;
									end
								end else begin
									if (ssCnt >0 && ssCnt < txLenght-1) begin
										Sck_o = !Clk_i;
									end else begin
										Sck_o = 0;
									end
								end
							end
						end
					7:	begin
							if (!Lag_i) begin
								if (!Lead_i) begin
									if (!ss) begin
										Sck_o = Clk_i;
									end else begin
										Sck_o = 0;
									end
								end else begin
									if (ssCnt < txLenght-1) begin
										Sck_o = Clk_i;
									end else begin
										Sck_o = 0;
									end
								end
							end else begin
								if (!Lead_i) begin
									if (ssCnt > 0) begin
										Sck_o = Clk_i;
									end else begin
										Sck_o = 0;
									end
								end else begin
									if (ssCnt >0 && ssCnt < txLenght-1) begin
										Sck_o = Clk_i;
									end else begin
										Sck_o = 0;
									end
								end
							end
						end
				endcase
			end else begin
				if (SelSt_i) begin
					if (!ss) begin
						if (PulsePol_i) begin 
							if (ClockPhase_i) begin
								Sck_o = Clk_i;
							end
							else begin 
								Sck_o = ~Clk_i;
							end
						end else begin
							if (ClockPhase_i) begin
								Sck_o = ~Clk_i;
							end
							else begin 
								Sck_o = Clk_i;
							end
						end
					end else begin
						Sck_o = 1'b0;
					end
				end else begin
					if (ss) begin
						if (PulsePol_i) begin 
							if (ClockPhase_i) begin
								Sck_o = Clk_i;
							end
							else begin 
								Sck_o = ~Clk_i;
							end
						end else begin
							if (ClockPhase_i) begin
								Sck_o = ~Clk_i;
							end
							else begin 
								Sck_o = Clk_i;
							end
						end
					end else begin
						Sck_o = 1'b0;
					end
				end
			end
		end
	end
    
    always @(*) begin
        if (SelSt_i) begin 
            if (EndianSel_i) begin 
                case (WidthSel_i) 
                    0 : begin 
                        Mosi0_o = (!ss) ? (mosiReg3[0]):1'b0;
                        Mosi1_o = (!ss) ? (mosiReg2[0]):1'b0;
                        Mosi2_o = (!ss) ? (mosiReg1[0]):1'b0;
                        Mosi3_o = (!ss) ? (mosiReg0[0]):1'b0;
                    end
                    1 : begin 
                        Mosi0_o = (!ss) ? (mosiReg3[0]):1'b0;
                        Mosi1_o = (!ss) ? (mosiReg2[0]):1'b0;
                        Mosi2_o = (!ss) ? (mosiReg1[0]):1'b0;
                        Mosi3_o = (!ss) ? (mosiReg0[0]):1'b0;
                    end
                    2 : begin 
                        Mosi0_o = (!ss) ? (mosiReg3[0]):1'b0;
                        Mosi1_o = (!ss) ? (mosiReg2[0]):1'b0;
                        Mosi2_o = (!ss) ? (mosiReg1[0]):1'b0;
                        Mosi3_o = (!ss) ? (mosiReg0[0]):1'b0;
                    end
                    3 : begin 
                        Mosi0_o = (!ss) ? (mosiReg3[0]):1'b0;
                        Mosi1_o = (!ss) ? (mosiReg2[0]):1'b0;
                        Mosi2_o = (!ss) ? (mosiReg1[0]):1'b0;
                        Mosi3_o = (!ss) ? (mosiReg0[0]):1'b0;
                    end
                endcase
            end
            else begin 
                case (WidthSel_i)
                    0 : begin
                        Mosi0_o = (!ss)? (mosiReg0[1]):1'b0;
                        Mosi1_o = (!ss)? (mosiReg1[1]):1'b0;
                        Mosi2_o = (!ss)? (mosiReg2[1]):1'b0;
                        Mosi3_o = (!ss)? (mosiReg3[1]):1'b0;
                    end
                    1 : begin
                        Mosi0_o = (!ss)? (mosiReg0[3]):1'b0;
                        Mosi1_o = (!ss)? (mosiReg1[3]):1'b0;
                        Mosi2_o = (!ss)? (mosiReg2[3]):1'b0;
                        Mosi3_o = (!ss)? (mosiReg3[3]):1'b0;
                    end
                    2 : begin
                        Mosi0_o = (!ss)? (mosiReg0[5]):1'b0;
                        Mosi1_o = (!ss)? (mosiReg1[5]):1'b0;
                        Mosi2_o = (!ss)? (mosiReg2[5]):1'b0;
                        Mosi3_o = (!ss)? (mosiReg3[5]):1'b0;
                    end
                    3 : begin
                        Mosi0_o = (!ss)? (mosiReg0[7]):1'b0;
                        Mosi1_o = (!ss)? (mosiReg1[7]):1'b0;
                        Mosi2_o = (!ss)? (mosiReg2[7]):1'b0;
                        Mosi3_o = (!ss)? (mosiReg3[7]):1'b0;
                    end
                endcase
            end
        end
        else begin 
            if (EndianSel_i) begin 
                case (WidthSel_i) 
                    0 : begin 
                        Mosi0_o = (ss) ? (mosiReg3[0]):1'b0;
                        Mosi1_o = (ss) ? (mosiReg2[0]):1'b0;
                        Mosi2_o = (ss) ? (mosiReg1[0]):1'b0;
                        Mosi3_o = (ss) ? (mosiReg0[0]):1'b0;
                    end
                    1 : begin 
                        Mosi0_o = (ss) ? (mosiReg3[0]):1'b0;
                        Mosi1_o = (ss) ? (mosiReg2[0]):1'b0;
                        Mosi2_o = (ss) ? (mosiReg1[0]):1'b0;
                        Mosi3_o = (ss) ? (mosiReg0[0]):1'b0;
                    end
                    2 : begin
                        Mosi0_o = (ss) ? (mosiReg3[0]):1'b0;
                        Mosi1_o = (ss) ? (mosiReg2[0]):1'b0;
                        Mosi2_o = (ss) ? (mosiReg1[0]):1'b0;
                        Mosi3_o = (ss) ? (mosiReg0[0]):1'b0;
                    end
                    3 : begin 
                        Mosi0_o = (ss) ? (mosiReg3[0]):1'b0;
                        Mosi1_o = (ss) ? (mosiReg2[0]):1'b0;
                        Mosi2_o = (ss) ? (mosiReg1[0]):1'b0;
                        Mosi3_o = (ss) ? (mosiReg0[0]):1'b0;
                    end
                endcase
            end
            else begin 
                case (WidthSel_i)
                    0 : begin
                        Mosi0_o = (ss)? (mosiReg0[1]):1'b0;
                        Mosi1_o = (ss)? (mosiReg1[1]):1'b0;
                        Mosi2_o = (ss)? (mosiReg2[1]):1'b0;
                        Mosi3_o = (ss)? (mosiReg3[1]):1'b0;
                    end
                    1 : begin
                        Mosi0_o = (ss)? (mosiReg0[3]):1'b0;
                        Mosi1_o = (ss)? (mosiReg1[3]):1'b0;
                        Mosi2_o = (ss)? (mosiReg2[3]):1'b0;
                        Mosi3_o = (ss)? (mosiReg3[3]):1'b0;
                    end
                    2 : begin
                        Mosi0_o = (ss)? (mosiReg0[5]):1'b0;
                        Mosi1_o = (ss)? (mosiReg1[5]):1'b0;
                        Mosi2_o = (ss)? (mosiReg2[5]):1'b0;
                        Mosi3_o = (ss)? (mosiReg3[5]):1'b0;
                    end
                    3 : begin
                        Mosi0_o = (ss)? (mosiReg0[7]):1'b0;
                        Mosi1_o = (ss)? (mosiReg1[7]):1'b0;
                        Mosi2_o = (ss)? (mosiReg2[7]):1'b0;
                        Mosi3_o = (ss)? (mosiReg3[7]):1'b0;
                    end
                endcase
            end
        end
    end
    
    always @(posedge Clk_i) begin
        ssR <= ss;
    end
    
	always @(posedge Clk_i) begin
        if (Rst_i) begin
			valReg <= 0;
		end else begin
			if (ssCnt == txLenght-3) begin
				if (!valReg) begin
					valReg <= 1;
				end else begin
					valReg <= 0;
				end
			end else begin
				valReg <= 0;
			end
		end
    end
    
    always @(*) begin 
        if (Rst_i) begin 
            startFlag = 1'b0;
        end
        else begin 
            if (Start_i && !stopFlag && !EmptyFlag_i ) begin 
                startFlag = 1'b1;
            end
            else begin 
                startFlag = 1'b0;
            end
        end
    end
    
    always @(*) begin 
        if (Rst_i) begin 
            ssNum = 1'b0;
        end
        else begin 
            case (WidthSel_i) 
                0 : begin 
                    ssNum = 2;
                end
                1 : begin 
                    ssNum = 4;
                end
                2 : begin 
                    ssNum = 6;
                end
                3 : begin 
                    ssNum = 8;
                end
            endcase
        end
    end
    
	always @(negedge Clk_i) begin 
        if (Rst_i) begin 
            ssCnt <= 0;
        end
        else begin
			if (SelSt_i) begin
				if (!ss) begin
					if (ssCnt != txLenght-1) begin 
						ssCnt <= ssCnt + 1;
					end else begin
						ssCnt <= 0;
					end
				end else begin
					ssCnt <= 0;
				end
			end else begin
				if (ss) begin
					if (ssCnt != txLenght-1) begin 
						ssCnt <= ssCnt + 1;
					end else begin
						ssCnt <= 0;
					end
				end else begin
					ssCnt <= 0;
				end
			end
		end
    end
	
    
    always @(negedge Clk_i) begin
		if (Rst_i) begin 
			ss <= 1'b1;
		end else begin
			if (Stop_i != 0) begin
				if (startFlag) begin
					if (SelSt_i) begin  
						if (ssCnt != txLenght-1) begin 
							ss <= 1'b0;
						end
						else begin 
							ss <= 1'b1;
						end
					end else begin
						if (ssCnt != txLenght-1) begin 
							ss <= 1'b1;
						end
						else begin 
							ss <= 1'b0;
						end
					end
				end else begin
					if (SelSt_i) begin  
						ss <= 1'b1;
					end else begin 
						ss <= 1'b0;
					end
				end
			end else begin
				if (startFlag) begin
					if (SelSt_i) begin
						ss <= 1'b0;
					end else begin
						ss <= 1'b1;
					end
				end else begin
					if (SelSt_i) begin
						ss <= 1'b1;
					end else begin
						ss <= 1'b0;
					end
				end
			end
        end
    end
    
    always @(negedge Clk_i) begin 
        if (Rst_i) begin 
            mosiReg3 <= SpiData_i[7:0];
			mosiReg2 <= SpiData_i[15:8];
			mosiReg1 <= SpiData_i[23:16];
			mosiReg0 <= SpiData_i[31:24];
        end
        else begin
            case (WidthSel_i)
            3: begin 
                if (!EndianSel_i) begin 
                    if (SelSt_i) begin 
						if (Lag_i != 0) begin
							if (!ss&& (ssCnt > 0 && ssCnt < txLenght-1)) begin
								mosiReg3 <= {mosiReg3[6:0],1'b0};
								mosiReg2 <= {mosiReg2[6:0],1'b0};
								mosiReg1 <= {mosiReg1[6:0],1'b0};
								mosiReg0 <= {mosiReg0[6:0],1'b0};
							end
							else begin 
								mosiReg3 <= SpiData_i[7:0];
								mosiReg2 <= SpiData_i[15:8];
								mosiReg1 <= SpiData_i[23:16];
								mosiReg0 <= SpiData_i[31:24];
							end
						end else begin
							if (!ss&& (ssCnt < txLenght-1)) begin
								mosiReg3 <= {mosiReg3[6:0],1'b0};
								mosiReg2 <= {mosiReg2[6:0],1'b0};
								mosiReg1 <= {mosiReg1[6:0],1'b0};
								mosiReg0 <= {mosiReg0[6:0],1'b0};
							end
							else begin 
								mosiReg3 <= SpiData_i[7:0];
								mosiReg2 <= SpiData_i[15:8];
								mosiReg1 <= SpiData_i[23:16];
								mosiReg0 <= SpiData_i[31:24];
							end
						end
                    end
                    else begin 
						if (Lag_i != 0) begin
							if (ss&& (ssCnt > 0 && ssCnt < txLenght-1)) begin
								mosiReg3 <= {mosiReg3[6:0],1'b0};
								mosiReg2 <= {mosiReg2[6:0],1'b0};
								mosiReg1 <= {mosiReg1[6:0],1'b0};
								mosiReg0 <= {mosiReg0[6:0],1'b0};
							end
							else begin 
								mosiReg3 <= SpiData_i[7:0];
								mosiReg2 <= SpiData_i[15:8];
								mosiReg1 <= SpiData_i[23:16];
								mosiReg0 <= SpiData_i[31:24];
							end
						end else begin
							if (!ss&& (ssCnt < txLenght-1)) begin
								mosiReg3 <= {mosiReg3[6:0],1'b0};
								mosiReg2 <= {mosiReg2[6:0],1'b0};
								mosiReg1 <= {mosiReg1[6:0],1'b0};
								mosiReg0 <= {mosiReg0[6:0],1'b0};
							end
							else begin 
								mosiReg3 <= SpiData_i[7:0];
								mosiReg2 <= SpiData_i[15:8];
								mosiReg1 <= SpiData_i[23:16];
								mosiReg0 <= SpiData_i[31:24];
							end
						end
                    end
                end
                else begin 
                    if (SelSt_i) begin 
						if (Lag_i != 0) begin
							if (!ss&& (ssCnt > 0 && ssCnt < txLenght-1)) begin
								mosiReg3 <= {1'b0, mosiReg3[7:1] };
								mosiReg2 <= {1'b0, mosiReg2[7:1] };
								mosiReg1 <= {1'b0, mosiReg1[7:1] };
								mosiReg0 <= {1'b0, mosiReg0[7:1] };
							end
							else begin 
								mosiReg3 <= SpiData_i[7:0];
								mosiReg2 <= SpiData_i[15:8];
								mosiReg1 <= SpiData_i[23:16];
								mosiReg0 <= SpiData_i[31:24];
							end
						end else begin
							if (!ss&& (ssCnt < txLenght-1)) begin
								mosiReg3 <= {1'b0, mosiReg3[7:1] };
								mosiReg2 <= {1'b0, mosiReg2[7:1] };
								mosiReg1 <= {1'b0, mosiReg1[7:1] };
								mosiReg0 <= {1'b0, mosiReg0[7:1] };
							end
							else begin 
								mosiReg3 <= SpiData_i[7:0];
								mosiReg2 <= SpiData_i[15:8];
								mosiReg1 <= SpiData_i[23:16];
								mosiReg0 <= SpiData_i[31:24];
							end
						end
                    end
                    else begin 
						if (Lag_i != 0) begin
							if (ss&& (ssCnt > 0 && ssCnt < txLenght-1)) begin
								mosiReg3 <= {1'b0, mosiReg3[7:1] };
								mosiReg2 <= {1'b0, mosiReg2[7:1] };
								mosiReg1 <= {1'b0, mosiReg1[7:1] };
								mosiReg0 <= {1'b0, mosiReg0[7:1] };
							end
							else begin 
								mosiReg3 <= SpiData_i[7:0];
								mosiReg2 <= SpiData_i[15:8];
								mosiReg1 <= SpiData_i[23:16];
								mosiReg0 <= SpiData_i[31:24];
							end
						end else begin
							if (!ss&& (ssCnt < txLenght-1)) begin
								mosiReg3 <= {1'b0, mosiReg3[7:1] };
								mosiReg2 <= {1'b0, mosiReg2[7:1] };
								mosiReg1 <= {1'b0, mosiReg1[7:1] };
								mosiReg0 <= {1'b0, mosiReg0[7:1] };
							end
							else begin 
								mosiReg3 <= SpiData_i[7:0];
								mosiReg2 <= SpiData_i[15:8];
								mosiReg1 <= SpiData_i[23:16];
								mosiReg0 <= SpiData_i[31:24];
							end
						end
                    end
                end
            end
            2: begin 
                if (!EndianSel_i) begin 
                    if (SelSt_i) begin  
						if (Lag_i != 0) begin
							if (!ss&& (ssCnt > 0 && ssCnt < txLenght-1)) begin
								mosiReg3 <= mosiReg3 << 1;
								mosiReg2 <= mosiReg2 << 1;
								mosiReg1 <= mosiReg1 << 1;
								mosiReg0 <= mosiReg0 << 1;
							end
							else begin 
								mosiReg3 <= SpiData_i[5:0];
								mosiReg2 <= SpiData_i[11:6];
								mosiReg1 <= SpiData_i[17:12];
								mosiReg0 <= SpiData_i[23:18];
							end
						end else begin
							if (!ss&& (ssCnt < txLenght-1)) begin
								mosiReg3 <= mosiReg3 << 1;
								mosiReg2 <= mosiReg2 << 1;
								mosiReg1 <= mosiReg1 << 1;
								mosiReg0 <= mosiReg0 << 1;
							end
							else begin 
								mosiReg3 <= SpiData_i[5:0];
								mosiReg2 <= SpiData_i[11:6];
								mosiReg1 <= SpiData_i[17:12];
								mosiReg0 <= SpiData_i[23:18];
							end
						end
                    end
                    else begin 
						if (Lag_i != 0) begin
							if (ss&& (ssCnt > 0 && ssCnt < txLenght-1)) begin 
								mosiReg3 <= mosiReg3 << 1;
								mosiReg2 <= mosiReg2 << 1;
								mosiReg1 <= mosiReg1 << 1;
								mosiReg0 <= mosiReg0 << 1;
							end
							else begin 
								mosiReg3 <= SpiData_i[5:0];
								mosiReg2 <= SpiData_i[11:6];
								mosiReg1 <= SpiData_i[17:12];
								mosiReg0 <= SpiData_i[23:18];
							end
						end else begin
							if (!ss&& (ssCnt < txLenght-1)) begin
								mosiReg3 <= mosiReg3 << 1;
								mosiReg2 <= mosiReg2 << 1;
								mosiReg1 <= mosiReg1 << 1;
								mosiReg0 <= mosiReg0 << 1;
							end
							else begin 
								mosiReg3 <= SpiData_i[5:0];
								mosiReg2 <= SpiData_i[11:6];
								mosiReg1 <= SpiData_i[17:12];
								mosiReg0 <= SpiData_i[23:18];
							end
						end
                    end
                end
                else begin 
                    if (SelSt_i) begin  
						if (Lag_i != 0) begin
							if (!ss&& (ssCnt > 0 && ssCnt < txLenght-1)) begin
								mosiReg3 <= mosiReg3 >> 1;
								mosiReg2 <= mosiReg2 >> 1;
								mosiReg1 <= mosiReg1 >> 1;
								mosiReg0 <= mosiReg0 >> 1;
							end
							else begin 
								mosiReg3 <= SpiData_i[5:0];
								mosiReg2 <= SpiData_i[11:6];
								mosiReg1 <= SpiData_i[17:12];
								mosiReg0 <= SpiData_i[23:18];
							end
						end else begin
							if (!ss&& (ssCnt < txLenght-1)) begin
								mosiReg3 <= mosiReg3 >> 1;
								mosiReg2 <= mosiReg2 >> 1;
								mosiReg1 <= mosiReg1 >> 1;
								mosiReg0 <= mosiReg0 >> 1;
							end
							else begin 
								mosiReg3 <= SpiData_i[5:0];
								mosiReg2 <= SpiData_i[11:6];
								mosiReg1 <= SpiData_i[17:12];
								mosiReg0 <= SpiData_i[23:18];
							end
						end
                    end
                    else begin 
						if (Lag_i != 0) begin
							if (ss&& (ssCnt > 0 && ssCnt < txLenght-1)) begin 
								mosiReg3 <= mosiReg3 >> 1;
								mosiReg2 <= mosiReg2 >> 1;
								mosiReg1 <= mosiReg1 >> 1;
								mosiReg0 <= mosiReg0 >> 1;
							end
							else begin 
								mosiReg3 <= SpiData_i[5:0];
								mosiReg2 <= SpiData_i[11:6];
								mosiReg1 <= SpiData_i[17:12];
								mosiReg0 <= SpiData_i[23:18];
							end
						end else begin
							if (!ss&& (ssCnt < txLenght-1)) begin
								mosiReg3 <= mosiReg3 >> 1;
								mosiReg2 <= mosiReg2 >> 1;
								mosiReg1 <= mosiReg1 >> 1;
								mosiReg0 <= mosiReg0 >> 1;
							end
							else begin 
								mosiReg3 <= SpiData_i[5:0];
								mosiReg2 <= SpiData_i[11:6];
								mosiReg1 <= SpiData_i[17:12];
								mosiReg0 <= SpiData_i[23:18];
							end
						end
                    end
                end
            end
            1: begin 
                if (!EndianSel_i) begin 
                    if (SelSt_i) begin  
						if (Lag_i != 0) begin
							if (!ss&& (ssCnt > 0 && ssCnt < txLenght-1)) begin
								mosiReg3 <= mosiReg3 << 1;
								mosiReg2 <= mosiReg2 << 1;
								mosiReg1 <= mosiReg1 << 1;
								mosiReg0 <= mosiReg0 << 1;
							end
							else begin 
								mosiReg3 <= SpiData_i[3:0];
								mosiReg2 <= SpiData_i[7:4];
								mosiReg1 <= SpiData_i[11:8];
								mosiReg0 <= SpiData_i[15:12];
							end
						end else begin
							if (!ss&& (ssCnt < txLenght-1)) begin
								mosiReg3 <= mosiReg3 << 1;
								mosiReg2 <= mosiReg2 << 1;
								mosiReg1 <= mosiReg1 << 1;
								mosiReg0 <= mosiReg0 << 1;
							end
							else begin 
								mosiReg3 <= SpiData_i[3:0];
								mosiReg2 <= SpiData_i[7:4];
								mosiReg1 <= SpiData_i[11:8];
								mosiReg0 <= SpiData_i[15:12];
							end
						end
                    end
                    else begin 
						if (Lag_i != 0) begin
							if (ss&& (ssCnt > 0 && ssCnt < txLenght-1)) begin 
								mosiReg3 <= mosiReg3 << 1;
								mosiReg2 <= mosiReg2 << 1;
								mosiReg1 <= mosiReg1 << 1;
								mosiReg0 <= mosiReg0 << 1;
							end
							else begin 
								mosiReg3 <= SpiData_i[3:0];
								mosiReg2 <= SpiData_i[7:4];
								mosiReg1 <= SpiData_i[11:8];
								mosiReg0 <= SpiData_i[15:12];
							end
						end else begin
							if (!ss&& (ssCnt < txLenght-1)) begin
								mosiReg3 <= mosiReg3 << 1;
								mosiReg2 <= mosiReg2 << 1;
								mosiReg1 <= mosiReg1 << 1;
								mosiReg0 <= mosiReg0 << 1;
							end
							else begin 
								mosiReg3 <= SpiData_i[3:0];
								mosiReg2 <= SpiData_i[7:4];
								mosiReg1 <= SpiData_i[11:8];
								mosiReg0 <= SpiData_i[15:12];
							end
						end
                    end
                end
                else begin 
                    if (SelSt_i) begin  
						if (Lag_i != 0) begin
							if (!ss&& (ssCnt > 0 && ssCnt < txLenght-1)) begin
								mosiReg3 <= mosiReg3 >> 1;
								mosiReg2 <= mosiReg2 >> 1;
								mosiReg1 <= mosiReg1 >> 1;
								mosiReg0 <= mosiReg0 >> 1;
							end
							else begin 
								mosiReg3 <= SpiData_i[3:0];
								mosiReg2 <= SpiData_i[7:4];
								mosiReg1 <= SpiData_i[11:8];
								mosiReg0 <= SpiData_i[15:12];
							end
						end else begin
							if (!ss&& (ssCnt < txLenght-1)) begin
								mosiReg3 <= mosiReg3 >> 1;
								mosiReg2 <= mosiReg2 >> 1;
								mosiReg1 <= mosiReg1 >> 1;
								mosiReg0 <= mosiReg0 >> 1;
							end
							else begin 
								mosiReg3 <= SpiData_i[3:0];
								mosiReg2 <= SpiData_i[7:4];
								mosiReg1 <= SpiData_i[11:8];
								mosiReg0 <= SpiData_i[15:12];
							end
						end
                    end
                    else begin 
						if (Lag_i != 0) begin
							if (ss&& (ssCnt > 0 && ssCnt < txLenght-1)) begin 
								mosiReg3 <= mosiReg3 >> 1;
								mosiReg2 <= mosiReg2 >> 1;
								mosiReg1 <= mosiReg1 >> 1;
								mosiReg0 <= mosiReg0 >> 1;
							end
							else begin 
								mosiReg3 <= SpiData_i[3:0];
								mosiReg2 <= SpiData_i[7:4];
								mosiReg1 <= SpiData_i[11:8];
								mosiReg0 <= SpiData_i[15:12];
							end
						end else begin
							if (!ss&& (ssCnt < txLenght-1)) begin
								mosiReg3 <= mosiReg3 >> 1;
								mosiReg2 <= mosiReg2 >> 1;
								mosiReg1 <= mosiReg1 >> 1;
								mosiReg0 <= mosiReg0 >> 1;
							end
							else begin 
								mosiReg3 <= SpiData_i[3:0];
								mosiReg2 <= SpiData_i[7:4];
								mosiReg1 <= SpiData_i[11:8];
								mosiReg0 <= SpiData_i[15:12];
							end
						end
                    end
                end
            end
            0: begin 
                if (!EndianSel_i) begin 
                    if (SelSt_i) begin  
						if (Lag_i != 0) begin
							if (!ss&& (ssCnt > 0 && ssCnt < txLenght-1)) begin
								mosiReg3 <= mosiReg3 << 1;
								mosiReg2 <= mosiReg2 << 1;
								mosiReg1 <= mosiReg1 << 1;
								mosiReg0 <= mosiReg0 << 1;
							end
							else begin 
								mosiReg3 <= SpiData_i[1:0];
								mosiReg2 <= SpiData_i[3:2];
								mosiReg1 <= SpiData_i[5:4];
								mosiReg0 <= SpiData_i[7:6];
							end
						end else begin
							if (!ss&& (ssCnt < txLenght-1)) begin
								mosiReg3 <= mosiReg3 << 1;
								mosiReg2 <= mosiReg2 << 1;
								mosiReg1 <= mosiReg1 << 1;
								mosiReg0 <= mosiReg0 << 1;
							end
							else begin 
								mosiReg3 <= SpiData_i[1:0];
								mosiReg2 <= SpiData_i[3:2];
								mosiReg1 <= SpiData_i[5:4];
								mosiReg0 <= SpiData_i[7:6];
							end
						end
                    end
                    else begin 
						if (Lag_i != 0) begin
							if (ss&& (ssCnt > 0 && ssCnt < txLenght-1)) begin 
								mosiReg3 <= mosiReg3 << 1;
								mosiReg2 <= mosiReg2 << 1;
								mosiReg1 <= mosiReg1 << 1;
								mosiReg0 <= mosiReg0 << 1;
							end
							else begin 
								mosiReg3 <= SpiData_i[1:0];
								mosiReg2 <= SpiData_i[3:2];
								mosiReg1 <= SpiData_i[5:4];
								mosiReg0 <= SpiData_i[7:6];
							end
						end else begin
							if (!ss&& (ssCnt < txLenght-1)) begin
								mosiReg3 <= mosiReg3 << 1;
								mosiReg2 <= mosiReg2 << 1;
								mosiReg1 <= mosiReg1 << 1;
								mosiReg0 <= mosiReg0 << 1;
							end
							else begin 
								mosiReg3 <= SpiData_i[1:0];
								mosiReg2 <= SpiData_i[3:2];
								mosiReg1 <= SpiData_i[5:4];
								mosiReg0 <= SpiData_i[7:6];
							end
						end
                    end
                end
                else begin 
                    if (SelSt_i) begin  
						if (Lag_i != 0) begin
							if (!ss&& (ssCnt > 0 && ssCnt < txLenght-1)) begin
								mosiReg3 <= mosiReg3 >> 1;
								mosiReg2 <= mosiReg2 >> 1;
								mosiReg1 <= mosiReg1 >> 1;
								mosiReg0 <= mosiReg0 >> 1;
							end
							else begin 
								mosiReg3 <= SpiData_i[1:0];
								mosiReg2 <= SpiData_i[3:2];
								mosiReg1 <= SpiData_i[5:4];
								mosiReg0 <= SpiData_i[7:6];
							end
						end else begin
							if (!ss&& (ssCnt < txLenght-1)) begin
								mosiReg3 <= mosiReg3 >> 1;
								mosiReg2 <= mosiReg2 >> 1;
								mosiReg1 <= mosiReg1 >> 1;
								mosiReg0 <= mosiReg0 >> 1;
							end
							else begin 
								mosiReg3 <= SpiData_i[1:0];
								mosiReg2 <= SpiData_i[3:2];
								mosiReg1 <= SpiData_i[5:4];
								mosiReg0 <= SpiData_i[7:6];
							end
						end
                    end
                    else begin 
						if (Lag_i != 0) begin
							if (ss&& (ssCnt > 0 && ssCnt < txLenght-1)) begin 
								mosiReg3 <= mosiReg3 >> 1;
								mosiReg2 <= mosiReg2 >> 1;
								mosiReg1 <= mosiReg1 >> 1;
								mosiReg0 <= mosiReg0 >> 1;
							end
							else begin 
								mosiReg3 <= SpiData_i[1:0];
								mosiReg2 <= SpiData_i[3:2];
								mosiReg1 <= SpiData_i[5:4];
								mosiReg0 <= SpiData_i[7:6];
							end
						end else begin
							if (!ss&& (ssCnt < txLenght-1)) begin
								mosiReg3 <= mosiReg3 >> 1;
								mosiReg2 <= mosiReg2 >> 1;
								mosiReg1 <= mosiReg1 >> 1;
								mosiReg0 <= mosiReg0 >> 1;
							end
							else begin 
								mosiReg3 <= SpiData_i[1:0];
								mosiReg2 <= SpiData_i[3:2];
								mosiReg1 <= SpiData_i[5:4];
								mosiReg0 <= SpiData_i[7:6];
							end
						end
                    end
                end
            end
            endcase
        end
    end

endmodule