data/full_repos/permissive/421380819/verilog/rtl/gpioModule/gpioCtrl.v
1: b'%Warning-WIDTH: data/full_repos/permissive/421380819/verilog/rtl/gpioModule/gpioCtrl.v:92: Operator ASSIGNW expects 8 bits on the Assign RHS, but Assign RHS\'s VARREF \'RAM_ADDR_i\' generates 32 bits.\n                                                                                         : ... In instance gpioCtrl\n    assign RAM_ADDR = RAM_ADDR_i;\n                    ^\n                ... Use "/* verilator lint_off WIDTH */" and lint_on around source to disable this message.\n%Warning-WIDTH: data/full_repos/permissive/421380819/verilog/rtl/gpioModule/gpioCtrl.v:116: Operator ASSIGNDLY expects 32 bits on the Assign RHS, but Assign RHS\'s CONST \'8\'h0\' generates 8 bits.\n                                                                                          : ... In instance gpioCtrl\n            default: CTRL_DATA_OUT_i <= 8\'b0000_0000;\n                                     ^~\n%Warning-WIDTH: data/full_repos/permissive/421380819/verilog/rtl/gpioModule/gpioCtrl.v:292: Operator ASSIGNDLY expects 32 bits on the Assign RHS, but Assign RHS\'s REPLICATE generates 7 bits.\n                                                                                          : ... In instance gpioCtrl\n            RAM_ADDR_i <= {BIT_IN_COUNT_Q[9:5], 2\'b00};\n                       ^~\n%Warning-WIDTH: data/full_repos/permissive/421380819/verilog/rtl/gpioModule/gpioCtrl.v:296: Operator ASSIGNDLY expects 32 bits on the Assign RHS, but Assign RHS\'s REPLICATE generates 7 bits.\n                                                                                          : ... In instance gpioCtrl\n            RAM_ADDR_i  <= {vBitOutCountSum, 2\'b00};\n                        ^~\n%Error: Exiting due to 4 warning(s)\n'
module gpioCtrl (

    input   wire            CLK,
    input   wire            RSTb,

    input   wire            CTRL_WE,
    input   wire    [3:0]   CTRL_ADDR,
    input   wire    [31:0]  CTRL_DATA_IN,
    output  wire    [31:0]  CTRL_DATA_OUT,

    input   wire    [37:0]  GPIO_IN,
    output  wire    [37:0]  GPIO_OUT,
    output  wire    [37:0]  GPIO_OEb,

    output  wire            RAM_CSb,
    output  wire            RAM_WEb,
    output  wire    [7:0]   RAM_ADDR,
    output  wire    [31:0]  RAM_DATA_IN,
    input   wire    [31:0]  RAM_DATA_OUT
);

    parameter sFSM_IN_STOP      	= 2'b00;
    parameter sFSM_IN_SHIFT     	= 2'b01;
    parameter sFSM_IN_STORE     	= 2'b10;

    parameter sFSM_OUT_STOP     	= 2'b00;
    parameter sFSM_OUT_LOAD     	= 2'b01;
    parameter sFSM_OUT_SHIFT    	= 2'b10;
    parameter sFSM_OUT_LOAD_NEXT 	= 2'b11;


    reg [31:0]  CTRL_DATA_OUT_i;
    reg         RAM_WEb_i;
    reg [31:0]  RAM_ADDR_i;
    reg [31:0]  RAM_DATA_IN_i;

    reg [31:0]  CTRL_REG_Q;
    reg [31:0]  CTRL_REG_D;

    wire        aSHIFT_IN_EN;
    wire [4:0]  aINPUT_SEL;
    wire        aSHIFT_OUT_EN;
    wire [4:0]  aOUTPUT_SEL;
    wire        aOUTPUT_LOOP;
    wire [9:0]  aOUTPUT_LEN;
    wire        aOUTPUT_LIMIT;

    reg [31:0]   DATA_IN_Q;
    reg [31:0]   DATA_IN_D;
    reg [31:0]   DATA_OUT_Q;
    reg [31:0]   DATA_OUT_D;
    reg [31:0]   DATA_OE_Q;
    reg [31:0]   DATA_OE_D;

    reg [31:0]   SHIFT_IN_Q;
    reg [31:0]   SHIFT_IN_D;
    reg [31:0]   SHIFT_OUT_Q;
    reg [31:0]   SHIFT_OUT_D;

    reg [1:0]   FSM_IN_Q;
    reg [1:0]   FSM_IN_D;
    reg [1:0]   FSM_OUT_Q;
    reg [1:0]   FSM_OUT_D;

    reg         SET_SHIFT_DATA;
    reg         SET_OUT_DATA;
    reg         RST_SHIFT_IN_EN;
    reg         RST_SHIFT_OUT_EN;
    reg         OVERRIDE_RAM_ADDR;
    reg         RAM_CSb_IN;
    reg         RAM_CSb_OUT;

    reg [9:0]   BIT_IN_COUNT_Q;
    reg [9:0]   BIT_IN_COUNT_D;
    reg [9:0]   BIT_OUT_COUNT_Q;
    reg [9:0]   BIT_OUT_COUNT_D;


    assign CTRL_DATA_OUT = CTRL_DATA_OUT_i;
    assign GPIO_OUT[31:0] = DATA_OUT_Q;
    assign GPIO_OUT[37:32] = 6'b000000;
    assign GPIO_OEb[31:0] = ~(DATA_OE_Q);
    assign GPIO_OEb[37:32] = 6'b111111;
    assign RAM_WEb = RAM_WEb_i;
    assign RAM_ADDR = RAM_ADDR_i;
    assign RAM_DATA_IN = RAM_DATA_IN_i;


    assign aSHIFT_OUT_EN    = CTRL_REG_Q[0];
    assign aOUTPUT_SEL      = CTRL_REG_Q[5:1];
    assign aSHIFT_IN_EN     = CTRL_REG_Q[6];
    assign aINPUT_SEL       = CTRL_REG_Q[11:7];
    assign aOUTPUT_LOOP     = CTRL_REG_Q[12];
    assign aOUTPUT_LEN      = CTRL_REG_Q[22:13];
    assign aOUTPUT_LIMIT    = CTRL_REG_Q[23];
    

    always @(*) begin : interface_read_access
        case (CTRL_ADDR[3:2])

            2'b00: CTRL_DATA_OUT_i <= CTRL_REG_Q;

            2'b01: CTRL_DATA_OUT_i <= DATA_IN_Q;

            2'b10: CTRL_DATA_OUT_i <= DATA_OUT_Q;

            2'b11: CTRL_DATA_OUT_i <= DATA_OE_Q;

            default: CTRL_DATA_OUT_i <= 8'b0000_0000;
        endcase
    end


    always @(*) begin : interface_write_access

        CTRL_REG_D   <= CTRL_REG_Q;
        SET_OUT_DATA <= 1'b0;
        DATA_OE_D   <= DATA_OE_Q;

        if (CTRL_WE == 1'b1) begin

            case (CTRL_ADDR[3:2])

                2'b00: begin
                    CTRL_REG_D  <= CTRL_DATA_IN;
                end

                2'b10: SET_OUT_DATA <= 1'b1;

                2'b11: DATA_OE_D  <= CTRL_DATA_IN;
            endcase
        end

        if (RST_SHIFT_IN_EN == 1'b1) CTRL_REG_D[6] <= 1'b0;
        if (RST_SHIFT_OUT_EN == 1'b1) CTRL_REG_D[0] <= 1'b0;

    end


    always @(*) begin : fsm_data_in

        FSM_IN_D        <= FSM_IN_Q;
        BIT_IN_COUNT_D  <= BIT_IN_COUNT_Q;
        RST_SHIFT_IN_EN <= 1'b0;

        RAM_WEb_i       <= 1'b1;

        case (FSM_IN_Q)

            sFSM_IN_STOP: begin
                BIT_IN_COUNT_D <= 10'b00_0000_0000;
                if (aSHIFT_IN_EN == 1'b1) begin
                    RST_SHIFT_IN_EN <= 1'b1;
                    FSM_IN_D <= sFSM_IN_SHIFT;
                end
            end

            sFSM_IN_SHIFT: begin
                BIT_IN_COUNT_D <= BIT_IN_COUNT_Q + 1;
                if (BIT_IN_COUNT_Q[4:0] == 5'b1_1110) FSM_IN_D <= sFSM_IN_STORE;
            end

            sFSM_IN_STORE: begin
                BIT_IN_COUNT_D  <= BIT_IN_COUNT_Q + 1;

                RAM_WEb_i       <= 1'b0;
                if (BIT_IN_COUNT_Q[9:5] == 5'b1_1111) FSM_IN_D <= sFSM_IN_STOP;
                else                                  FSM_IN_D <= sFSM_IN_SHIFT;
            end

            default: FSM_IN_D <= sFSM_IN_STOP;
        endcase
    end


    always @(*) begin : fsm_data_out

        FSM_OUT_D         <= FSM_OUT_Q;
        BIT_OUT_COUNT_D   <= BIT_OUT_COUNT_Q;
        RST_SHIFT_OUT_EN  <= 1'b0;
        SET_SHIFT_DATA    <= 1'b0;

        OVERRIDE_RAM_ADDR <= 1'b0;

        case (FSM_OUT_Q)

            sFSM_OUT_STOP: begin
                BIT_OUT_COUNT_D <= 10'b11_1111_1111;
                if (aSHIFT_OUT_EN == 1'b1) begin
                    RST_SHIFT_OUT_EN <= 1'b1;

                    FSM_OUT_D        <= sFSM_OUT_LOAD;
                end
            end

            sFSM_OUT_LOAD: begin
				BIT_OUT_COUNT_D <= 10'b00_0000_0000;
                SET_SHIFT_DATA  <= 1'b1;
                FSM_OUT_D       <= sFSM_OUT_SHIFT;
            end

            sFSM_OUT_SHIFT: begin
                BIT_OUT_COUNT_D <= BIT_OUT_COUNT_Q + 1;

                if (   aOUTPUT_LOOP == 1'b0
                    && (aOUTPUT_LIMIT == 1'b1 && BIT_OUT_COUNT_Q == aOUTPUT_LEN-1)) 
                    FSM_OUT_D <= sFSM_OUT_STOP;

                else if (   aOUTPUT_LOOP == 1'b1
                         && (aOUTPUT_LIMIT == 1'b1 && BIT_OUT_COUNT_Q == (aOUTPUT_LEN-2))) begin
                    OVERRIDE_RAM_ADDR <= 1'b1;

                    FSM_OUT_D <= sFSM_OUT_LOAD;

                end else if (BIT_OUT_COUNT_Q[4:0] == 5'b1_1110) begin

                    FSM_OUT_D <= sFSM_OUT_LOAD_NEXT;
                end
            end 

            sFSM_OUT_LOAD_NEXT: begin

                if (   aOUTPUT_LOOP == 1'b0
                    && (   BIT_OUT_COUNT_Q[9:5] == 5'b1_1111
                        || (aOUTPUT_LIMIT == 1'b1 && BIT_OUT_COUNT_Q == aOUTPUT_LEN-1))) 
                        FSM_OUT_D <= sFSM_OUT_STOP;

                else if (   aOUTPUT_LOOP == 1'b1
                    && (   BIT_OUT_COUNT_Q[9:5] == 5'b1_1111
                        || (aOUTPUT_LIMIT == 1'b1 && BIT_OUT_COUNT_Q == aOUTPUT_LEN-2))) begin
                        OVERRIDE_RAM_ADDR <= 1'b1;

                        FSM_OUT_D <= sFSM_OUT_LOAD;

                end else begin
                    SET_SHIFT_DATA  <= 1'b1;
                    BIT_OUT_COUNT_D <= BIT_OUT_COUNT_Q + 1;
                    FSM_OUT_D <= sFSM_OUT_SHIFT;
                end
            end

            default: FSM_OUT_D <= sFSM_OUT_STOP;
        endcase
    end


    always @(*) begin : input_data_path
        reg vDataInMux;

        DATA_IN_D <= GPIO_IN[31:0];

        vDataInMux = DATA_IN_Q[aINPUT_SEL];

        SHIFT_IN_D <= {SHIFT_IN_Q[30:0], vDataInMux};

        RAM_DATA_IN_i <= SHIFT_IN_Q;
    end


    always @(*) begin : output_data_path

        SHIFT_OUT_D <= {SHIFT_OUT_Q[30:0], 1'b0};

        if(SET_SHIFT_DATA == 1'b1) SHIFT_OUT_D <= RAM_DATA_OUT;

        DATA_OUT_D <= DATA_OUT_Q;

        if (SET_OUT_DATA == 1'b1) DATA_OUT_D <= CTRL_DATA_IN;

        if (FSM_OUT_Q != sFSM_OUT_STOP) DATA_OUT_D[aOUTPUT_SEL] <= SHIFT_OUT_Q[31];
    end


    always @(*) begin : ramAccessLogic
        reg [4:0] vBitOutCountSum;

        RAM_CSb_IN  <= 1'b1;
        RAM_CSb_OUT <= 1'b1;
        RAM_ADDR_i  <= 32'h00_00_00_00;
        if (OVERRIDE_RAM_ADDR == 1'b1) begin
            RAM_CSb_OUT <= 1'b0;
            RAM_ADDR_i  <= 32'h00_00_00_00;
        end else if (FSM_IN_Q != sFSM_IN_STOP) begin
            RAM_CSb_IN <= 1'b0; 
            RAM_ADDR_i <= {BIT_IN_COUNT_Q[9:5], 2'b00};
        end else if (FSM_OUT_Q != sFSM_OUT_STOP) begin
            RAM_CSb_OUT <= 1'b0;
            vBitOutCountSum = BIT_OUT_COUNT_Q[9:5] + 1;
            RAM_ADDR_i  <= {vBitOutCountSum, 2'b00};
        end
    end

    assign RAM_CSb = RAM_CSb_IN & RAM_CSb_OUT;


    always @(posedge CLK, negedge RSTb) begin : flip_flops
        if(RSTb == 1'b0) begin
            CTRL_REG_Q      <= 32'h00_00_00_00;
            DATA_IN_Q       <= 32'h00_00_00_00;
            DATA_OUT_Q      <= 32'h00_00_00_00;
            DATA_OE_Q       <= 32'h00_00_00_00;
            SHIFT_IN_Q      <= 32'h00_00_00_00;
            SHIFT_OUT_Q     <= 32'h00_00_00_00;
            FSM_IN_Q        <= sFSM_IN_STOP;
            FSM_OUT_Q       <= sFSM_OUT_STOP;
            BIT_IN_COUNT_Q  <= 10'b00_0000_0000;
            BIT_OUT_COUNT_Q <= 10'b00_0000_0000;
        end else begin
            CTRL_REG_Q  <= CTRL_REG_D;
            DATA_IN_Q   <= DATA_IN_D;
            DATA_OUT_Q  <= DATA_OUT_D; 
            DATA_OE_Q   <= DATA_OE_D; 
            SHIFT_IN_Q  <= SHIFT_IN_D;
            SHIFT_OUT_Q <= SHIFT_OUT_D;
            FSM_IN_Q    <= FSM_IN_D;
            FSM_OUT_Q   <= FSM_OUT_D;
            BIT_IN_COUNT_Q  <= BIT_IN_COUNT_D;
            BIT_OUT_COUNT_Q <= BIT_OUT_COUNT_D;
        end
    end

endmodule
module gpioCtrl (

    input   wire            CLK,
    input   wire            RSTb,

    input   wire            CTRL_WE,
    input   wire    [3:0]   CTRL_ADDR,
    input   wire    [31:0]  CTRL_DATA_IN,
    output  wire    [31:0]  CTRL_DATA_OUT,

    input   wire    [37:0]  GPIO_IN,
    output  wire    [37:0]  GPIO_OUT,
    output  wire    [37:0]  GPIO_OEb,

    output  wire            RAM_CSb,
    output  wire            RAM_WEb,
    output  wire    [7:0]   RAM_ADDR,
    output  wire    [31:0]  RAM_DATA_IN,
    input   wire    [31:0]  RAM_DATA_OUT
);


    parameter sFSM_IN_STOP      	= 2'b00;
    parameter sFSM_IN_SHIFT     	= 2'b01;
    parameter sFSM_IN_STORE     	= 2'b10;

    parameter sFSM_OUT_STOP     	= 2'b00;
    parameter sFSM_OUT_LOAD     	= 2'b01;
    parameter sFSM_OUT_SHIFT    	= 2'b10;
    parameter sFSM_OUT_LOAD_NEXT 	= 2'b11;


    reg [31:0]  CTRL_DATA_OUT_i;
    reg         RAM_WEb_i;
    reg [31:0]  RAM_ADDR_i;
    reg [31:0]  RAM_DATA_IN_i;

    reg [31:0]  CTRL_REG_Q;
    reg [31:0]  CTRL_REG_D;

    wire        aSHIFT_IN_EN;
    wire [4:0]  aINPUT_SEL;
    wire        aSHIFT_OUT_EN;
    wire [4:0]  aOUTPUT_SEL;
    wire        aOUTPUT_LOOP;
    wire [9:0]  aOUTPUT_LEN;
    wire        aOUTPUT_LIMIT;

    reg [31:0]   DATA_IN_Q;
    reg [31:0]   DATA_IN_D;
    reg [31:0]   DATA_OUT_Q;
    reg [31:0]   DATA_OUT_D;
    reg [31:0]   DATA_OE_Q;
    reg [31:0]   DATA_OE_D;

    reg [31:0]   SHIFT_IN_Q;
    reg [31:0]   SHIFT_IN_D;
    reg [31:0]   SHIFT_OUT_Q;
    reg [31:0]   SHIFT_OUT_D;

    reg [1:0]   FSM_IN_Q;
    reg [1:0]   FSM_IN_D;
    reg [1:0]   FSM_OUT_Q;
    reg [1:0]   FSM_OUT_D;

    reg         SET_SHIFT_DATA;
    reg         SET_OUT_DATA;
    reg         RST_SHIFT_IN_EN;
    reg         RST_SHIFT_OUT_EN;
    reg         OVERRIDE_RAM_ADDR;
    reg         RAM_CSb_IN;
    reg         RAM_CSb_OUT;

    reg [9:0]   BIT_IN_COUNT_Q;
    reg [9:0]   BIT_IN_COUNT_D;
    reg [9:0]   BIT_OUT_COUNT_Q;
    reg [9:0]   BIT_OUT_COUNT_D;


    assign CTRL_DATA_OUT = CTRL_DATA_OUT_i;
    assign GPIO_OUT[31:0] = DATA_OUT_Q;
    assign GPIO_OUT[37:32] = 6'b000000;
    assign GPIO_OEb[31:0] = ~(DATA_OE_Q);
    assign GPIO_OEb[37:32] = 6'b111111;
    assign RAM_WEb = RAM_WEb_i;
    assign RAM_ADDR = RAM_ADDR_i;
    assign RAM_DATA_IN = RAM_DATA_IN_i;


    assign aSHIFT_OUT_EN    = CTRL_REG_Q[0];
    assign aOUTPUT_SEL      = CTRL_REG_Q[5:1];
    assign aSHIFT_IN_EN     = CTRL_REG_Q[6];
    assign aINPUT_SEL       = CTRL_REG_Q[11:7];
    assign aOUTPUT_LOOP     = CTRL_REG_Q[12];
    assign aOUTPUT_LEN      = CTRL_REG_Q[22:13];
    assign aOUTPUT_LIMIT    = CTRL_REG_Q[23];
    

    always @(*) begin : interface_read_access
        case (CTRL_ADDR[3:2])

            2'b00: CTRL_DATA_OUT_i <= CTRL_REG_Q;

            2'b01: CTRL_DATA_OUT_i <= DATA_IN_Q;

            2'b10: CTRL_DATA_OUT_i <= DATA_OUT_Q;

            2'b11: CTRL_DATA_OUT_i <= DATA_OE_Q;

            default: CTRL_DATA_OUT_i <= 8'b0000_0000;
        endcase
    end


    always @(*) begin : interface_write_access

        CTRL_REG_D   <= CTRL_REG_Q;
        SET_OUT_DATA <= 1'b0;
        DATA_OE_D   <= DATA_OE_Q;

        if (CTRL_WE == 1'b1) begin

            case (CTRL_ADDR[3:2])

                2'b00: begin
                    CTRL_REG_D  <= CTRL_DATA_IN;
                end

                2'b10: SET_OUT_DATA <= 1'b1;

                2'b11: DATA_OE_D  <= CTRL_DATA_IN;
            endcase
        end

        if (RST_SHIFT_IN_EN == 1'b1) CTRL_REG_D[6] <= 1'b0;
        if (RST_SHIFT_OUT_EN == 1'b1) CTRL_REG_D[0] <= 1'b0;

    end


    always @(*) begin : fsm_data_in

        FSM_IN_D        <= FSM_IN_Q;
        BIT_IN_COUNT_D  <= BIT_IN_COUNT_Q;
        RST_SHIFT_IN_EN <= 1'b0;

        RAM_WEb_i       <= 1'b1;

        case (FSM_IN_Q)

            sFSM_IN_STOP: begin
                BIT_IN_COUNT_D <= 10'b00_0000_0000;
                if (aSHIFT_IN_EN == 1'b1) begin
                    RST_SHIFT_IN_EN <= 1'b1;
                    FSM_IN_D <= sFSM_IN_SHIFT;
                end
            end

            sFSM_IN_SHIFT: begin
                BIT_IN_COUNT_D <= BIT_IN_COUNT_Q + 1;
                if (BIT_IN_COUNT_Q[4:0] == 5'b1_1110) FSM_IN_D <= sFSM_IN_STORE;
            end

            sFSM_IN_STORE: begin
                BIT_IN_COUNT_D  <= BIT_IN_COUNT_Q + 1;

                RAM_WEb_i       <= 1'b0;
                if (BIT_IN_COUNT_Q[9:5] == 5'b1_1111) FSM_IN_D <= sFSM_IN_STOP;
                else                                  FSM_IN_D <= sFSM_IN_SHIFT;
            end

            default: FSM_IN_D <= sFSM_IN_STOP;
        endcase
    end


    always @(*) begin : fsm_data_out

        FSM_OUT_D         <= FSM_OUT_Q;
        BIT_OUT_COUNT_D   <= BIT_OUT_COUNT_Q;
        RST_SHIFT_OUT_EN  <= 1'b0;
        SET_SHIFT_DATA    <= 1'b0;

        OVERRIDE_RAM_ADDR <= 1'b0;

        case (FSM_OUT_Q)

            sFSM_OUT_STOP: begin
                BIT_OUT_COUNT_D <= 10'b11_1111_1111;
                if (aSHIFT_OUT_EN == 1'b1) begin
                    RST_SHIFT_OUT_EN <= 1'b1;

                    FSM_OUT_D        <= sFSM_OUT_LOAD;
                end
            end

            sFSM_OUT_LOAD: begin
				BIT_OUT_COUNT_D <= 10'b00_0000_0000;
                SET_SHIFT_DATA  <= 1'b1;
                FSM_OUT_D       <= sFSM_OUT_SHIFT;
            end

            sFSM_OUT_SHIFT: begin
                BIT_OUT_COUNT_D <= BIT_OUT_COUNT_Q + 1;

                if (   aOUTPUT_LOOP == 1'b0
                    && (aOUTPUT_LIMIT == 1'b1 && BIT_OUT_COUNT_Q == aOUTPUT_LEN-1)) 
                    FSM_OUT_D <= sFSM_OUT_STOP;

                else if (   aOUTPUT_LOOP == 1'b1
                         && (aOUTPUT_LIMIT == 1'b1 && BIT_OUT_COUNT_Q == (aOUTPUT_LEN-2))) begin
                    OVERRIDE_RAM_ADDR <= 1'b1;

                    FSM_OUT_D <= sFSM_OUT_LOAD;

                end else if (BIT_OUT_COUNT_Q[4:0] == 5'b1_1110) begin

                    FSM_OUT_D <= sFSM_OUT_LOAD_NEXT;
                end
            end 

            sFSM_OUT_LOAD_NEXT: begin

                if (   aOUTPUT_LOOP == 1'b0
                    && (   BIT_OUT_COUNT_Q[9:5] == 5'b1_1111
                        || (aOUTPUT_LIMIT == 1'b1 && BIT_OUT_COUNT_Q == aOUTPUT_LEN-1))) 
                        FSM_OUT_D <= sFSM_OUT_STOP;

                else if (   aOUTPUT_LOOP == 1'b1
                    && (   BIT_OUT_COUNT_Q[9:5] == 5'b1_1111
                        || (aOUTPUT_LIMIT == 1'b1 && BIT_OUT_COUNT_Q == aOUTPUT_LEN-2))) begin
                        OVERRIDE_RAM_ADDR <= 1'b1;

                        FSM_OUT_D <= sFSM_OUT_LOAD;

                end else begin
                    SET_SHIFT_DATA  <= 1'b1;
                    BIT_OUT_COUNT_D <= BIT_OUT_COUNT_Q + 1;
                    FSM_OUT_D <= sFSM_OUT_SHIFT;
                end
            end

            default: FSM_OUT_D <= sFSM_OUT_STOP;
        endcase
    end


    always @(*) begin : input_data_path
        reg vDataInMux;

        DATA_IN_D <= GPIO_IN[31:0];

        vDataInMux = DATA_IN_Q[aINPUT_SEL];

        SHIFT_IN_D <= {SHIFT_IN_Q[30:0], vDataInMux};

        RAM_DATA_IN_i <= SHIFT_IN_Q;
    end


    always @(*) begin : output_data_path

        SHIFT_OUT_D <= {SHIFT_OUT_Q[30:0], 1'b0};

        if(SET_SHIFT_DATA == 1'b1) SHIFT_OUT_D <= RAM_DATA_OUT;

        DATA_OUT_D <= DATA_OUT_Q;

        if (SET_OUT_DATA == 1'b1) DATA_OUT_D <= CTRL_DATA_IN;

        if (FSM_OUT_Q != sFSM_OUT_STOP) DATA_OUT_D[aOUTPUT_SEL] <= SHIFT_OUT_Q[31];
    end


    always @(*) begin : ramAccessLogic
        reg [4:0] vBitOutCountSum;

        RAM_CSb_IN  <= 1'b1;
        RAM_CSb_OUT <= 1'b1;
        RAM_ADDR_i  <= 32'h00_00_00_00;
        if (OVERRIDE_RAM_ADDR == 1'b1) begin
            RAM_CSb_OUT <= 1'b0;
            RAM_ADDR_i  <= 32'h00_00_00_00;
        end else if (FSM_IN_Q != sFSM_IN_STOP) begin
            RAM_CSb_IN <= 1'b0; 
            RAM_ADDR_i <= {BIT_IN_COUNT_Q[9:5], 2'b00};
        end else if (FSM_OUT_Q != sFSM_OUT_STOP) begin
            RAM_CSb_OUT <= 1'b0;
            vBitOutCountSum = BIT_OUT_COUNT_Q[9:5] + 1;
            RAM_ADDR_i  <= {vBitOutCountSum, 2'b00};
        end
    end

    assign RAM_CSb = RAM_CSb_IN & RAM_CSb_OUT;


    always @(posedge CLK, negedge RSTb) begin : flip_flops
        if(RSTb == 1'b0) begin
            CTRL_REG_Q      <= 32'h00_00_00_00;
            DATA_IN_Q       <= 32'h00_00_00_00;
            DATA_OUT_Q      <= 32'h00_00_00_00;
            DATA_OE_Q       <= 32'h00_00_00_00;
            SHIFT_IN_Q      <= 32'h00_00_00_00;
            SHIFT_OUT_Q     <= 32'h00_00_00_00;
            FSM_IN_Q        <= sFSM_IN_STOP;
            FSM_OUT_Q       <= sFSM_OUT_STOP;
            BIT_IN_COUNT_Q  <= 10'b00_0000_0000;
            BIT_OUT_COUNT_Q <= 10'b00_0000_0000;
        end else begin
            CTRL_REG_Q  <= CTRL_REG_D;
            DATA_IN_Q   <= DATA_IN_D;
            DATA_OUT_Q  <= DATA_OUT_D; 
            DATA_OE_Q   <= DATA_OE_D; 
            SHIFT_IN_Q  <= SHIFT_IN_D;
            SHIFT_OUT_Q <= SHIFT_OUT_D;
            FSM_IN_Q    <= FSM_IN_D;
            FSM_OUT_Q   <= FSM_OUT_D;
            BIT_IN_COUNT_Q  <= BIT_IN_COUNT_D;
            BIT_OUT_COUNT_Q <= BIT_OUT_COUNT_D;
        end
    end

endmodule