data/full_repos/permissive/205739496/rtl/ctrl.v
1: b'%Warning-WIDTH: data/full_repos/permissive/205739496/rtl/ctrl.v:654: Operator ASSIGNDLY expects 1 bits on the Assign RHS, but Assign RHS\'s CONST \'2\'h1\' generates 2 bits.\n                                                                   : ... In instance ctrl\n                            FIFO_WDATA[32:32] <= 2\'h1;\n                                              ^~\n                ... Use "/* verilator lint_off WIDTH */" and lint_on around source to disable this message.\n%Warning-WIDTH: data/full_repos/permissive/205739496/rtl/ctrl.v:741: Operator ADD expects 8 bits on the RHS, but RHS\'s CONST \'4\'h1\' generates 4 bits.\n                                                                   : ... In instance ctrl\n                            REGS_ADDR <= REGS_ADDR + 4\'h1;\n                                                   ^\n%Error: Exiting due to 2 warning(s)\n'
module ctrl #(
    parameter           PROTOCOL = 8'hFF,
    parameter           REVISION = 8'hFF
) (
    input  wire         CLK,
    input  wire         RST_N,


    output wire         WB_CYC_O,
    output wire         WB_STB_O,
    output reg          WB_WE_O,
    output reg  [7:0]   WB_ADR_O,
    output reg  [7:0]   WB_DAT_O,
    input  wire [7:0]   WB_DAT_I,
    input  wire         WB_ACK_I,


    input  wire [7:0]   STATUS_REGISTER,


    output reg          REGS_WE,
    output reg  [7:0]   REGS_ADDR,
    output reg  [7:0]   REGS_WDATA,
    input  wire [7:0]   REGS_RDATA,


    input  wire         FIFO_FULL,
    output reg          FIFO_WE,
    output reg  [33:0]  FIFO_WDATA,


    output reg          FIFO_OVERFLOW,


    output reg          EOF
);






    `define REQ_READ                 1'b0
    `define REQ_WRITE                1'b1


    `define SPICR0                   8'h54
    `define SPICR1                   8'h55
    `define SPICR2                   8'h56
    `define SPIBR                    8'h57
    `define SPICSR                   8'h58
    `define SPITXDR                  8'h59
    `define SPISR                    8'h5A
    `define SPIRXDR                  8'h5B
    `define SPIIRQ                   8'h5C
    `define SPIIRQEN                 8'h5D


    `define SPICR1_CFG               8'h80
    `define SPICR2_CFG               8'h00
    `define SPITXDR_CFG              8'h00
    `define SPIIRQEN_CFG             8'h00


    `define SPI_CMD_PROTOCOL         8'hF0
    `define SPI_CMD_REVISION         8'hF1
    `define SPI_CMD_REG_READ         8'h00
    `define SPI_CMD_REG_WRITE        8'h01
    `define SPI_CMD_LOAD_RGB         8'h04
    `define SPI_CMD_LOAD_WRGB        8'h05
    `define SPI_CMD_LOAD_RESET_CYCLE 8'h06
    `define SPI_CMD_LOAD_RESET_CODE  8'h07


    `define S_INIT                   5'h00
    `define S_SPICR1                 5'h01
    `define S_SPICR2                 5'h02
    `define S_WAIT_FOR_TIPN          5'h03
    `define S_RXDR_DISCARD1          5'h04
    `define S_RXDR_DISCARD2          5'h05
    `define S_T1_TXDR                5'h06
    `define S_WAIT_FOR_TIP           5'h07
    `define S_T2_TRDY                5'h08
    `define S_T2_TXDR                5'h09
    `define S_R1_RRDY                5'h0A
    `define S_R1_RXDR                5'h0B
    `define S_T3_TRDY                5'h0C
    `define S_T3_TXDR                5'h0D
    `define S_RN_RRDY                5'h0E
    `define S_RN_RXDR                5'h0F
    `define S_RN_PROCESS             5'h10
    `define S_TN_TRDY                5'h11
    `define S_TN_TXDR                5'h12


    reg       wb_cyc;


    reg [4:0] sm_state;


    reg [7:0] sm_spi_cmd;
    reg [7:0] sm_spi_byte;
    reg [3:0] sm_byte_count;
    reg [1:0] sm_pixel_index;





    assign #1.000 WB_STB_O = wb_cyc;
    assign #1.000 WB_CYC_O = wb_cyc;





    always @(posedge CLK or negedge RST_N) begin
        if (RST_N == 1'b0) begin
            sm_state        <= `S_INIT;


            wb_cyc          <= 1'b0;
            WB_WE_O         <= 1'b0;
            WB_ADR_O        <= 8'h00;
            WB_DAT_O        <= 8'h00;


            REGS_ADDR       <= 8'h00;
            REGS_WDATA      <= 8'h00;
            REGS_WE         <= 1'b0;


            FIFO_WE         <= 1'b0;
            FIFO_WDATA      <= 34'h0_0000_0000;
            FIFO_OVERFLOW   <= 1'b0;


            sm_spi_cmd      <= 8'h00;
            sm_spi_byte     <= 8'h00;


            sm_byte_count   <= 4'h0;
            sm_pixel_index  <= 2'b00;


            EOF             <= 1'b0;
        end
        else begin

            wb_cyc          <= 1'b0;
            WB_WE_O         <= `REQ_READ;
            REGS_WE         <= 1'b0;
            FIFO_WE         <= 1'b0;
            FIFO_OVERFLOW   <= 1'b0;
            EOF             <= 1'b0;

            case (sm_state)




                `S_INIT: begin
                    sm_state <= `S_SPICR1;
                end





                `S_SPICR1: begin
                    wb_cyc   <= 1'b1;
                    WB_ADR_O <= `SPICR1;
                    WB_DAT_O <= `SPICR1_CFG;
                    WB_WE_O  <= `REQ_WRITE;
                    sm_state <= `S_SPICR1;

                    if (WB_ACK_I == 1'b1) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_SPICR2;
                    end
                end





                `S_SPICR2: begin
                    wb_cyc   <= 1'b1;
                    WB_ADR_O <= `SPICR2;
                    WB_DAT_O <= `SPICR2_CFG;
                    WB_WE_O  <= `REQ_WRITE;

                    if (WB_ACK_I == 1'b1) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_WAIT_FOR_TIPN;
                    end
                end





                `S_WAIT_FOR_TIPN: begin
                    wb_cyc   <= 1'b1;
                    WB_ADR_O <= `SPISR;
                    WB_WE_O  <= `REQ_READ;


                    if ( (WB_ACK_I    == 1'b1) &&
                         (WB_DAT_I[7] == 1'b0) ) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_RXDR_DISCARD1;
                    end

                    else if (WB_ACK_I == 1'b1)  begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_WAIT_FOR_TIPN;
                    end
                end







                `S_RXDR_DISCARD1: begin
                    wb_cyc   <= 1'b1;
                    WB_ADR_O <= `SPIRXDR;
                    WB_WE_O  <= `REQ_READ;

                    if (WB_ACK_I == 1'b1) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_RXDR_DISCARD2;
                    end
                end







                `S_RXDR_DISCARD2: begin
                    wb_cyc   <= 1'b1;
                    WB_ADR_O <= `SPIRXDR;
                    WB_WE_O  <= `REQ_READ;

                    if (WB_ACK_I == 1'b1) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_T1_TXDR;
                    end
                end







                `S_T1_TXDR: begin
                    wb_cyc   <= 1'b1;
                    WB_ADR_O <= `SPITXDR;
                    WB_DAT_O <= 8'h00;
                    WB_WE_O  <= `REQ_WRITE;

                    if (WB_ACK_I == 1'b1) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_WAIT_FOR_TIP;
                    end
                end





                `S_WAIT_FOR_TIP: begin
                    sm_byte_count  <= 4'h0;
                    sm_pixel_index <= 2'b00;

                    wb_cyc         <= 1'b1;
                    WB_ADR_O       <= `SPISR;
                    WB_WE_O        <= `REQ_READ;


                    if ( (WB_ACK_I    == 1'b1) &&
                         (WB_DAT_I[7] == 1'b1) &&
                         (WB_DAT_I[4] == 1'b1) ) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_T2_TXDR;
                    end

                    else if ( (WB_ACK_I    == 1'b1) &&
                              (WB_DAT_I[7] == 1'b1) ) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_T2_TRDY;
                    end

                    else if (WB_ACK_I == 1'b1) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_WAIT_FOR_TIP;
                    end
                end





                `S_T2_TRDY: begin
                    wb_cyc   <= 1'b1;
                    WB_ADR_O <= `SPISR;
                    WB_WE_O  <= `REQ_READ;


                    if ( (WB_ACK_I    == 1'b1) &&
                         (WB_DAT_I[4] == 1'b1) ) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_T2_TXDR;
                    end

                    else if (WB_ACK_I == 1'b1) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_T2_TRDY;
                    end
                end







                `S_T2_TXDR: begin
                    wb_cyc   <= 1'b1;
                    WB_ADR_O <= `SPITXDR;
                    WB_DAT_O <= 8'h00;
                    WB_WE_O  <= `REQ_WRITE;

                    if (WB_ACK_I == 1'b1) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_R1_RRDY;
                    end
                end





                `S_R1_RRDY: begin
                    wb_cyc   <= 1'b1;
                    WB_ADR_O <= `SPISR;
                    WB_WE_O  <= `REQ_READ;


                    if ( (WB_ACK_I    == 1'b1) &&
                         (WB_DAT_I[7] == 1'b0) &&
                         (WB_DAT_I[3] == 1'b0) ) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_SPICR2;
                    end

                    else if ( (WB_ACK_I    == 1'b1) &&
                              (WB_DAT_I[3] == 1'b1) ) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_R1_RXDR;
                    end

                    else if (WB_ACK_I == 1'b1) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_R1_RRDY;
                    end
                end







                `S_R1_RXDR: begin
                    wb_cyc   <= 1'b1;
                    WB_ADR_O <= `SPIRXDR;
                    WB_WE_O  <= `REQ_READ;

                    if (WB_ACK_I == 1'b1) begin
                        sm_byte_count <= 4'h1;
                        sm_spi_cmd    <= WB_DAT_I;

                        wb_cyc        <= 1'b0;
                        WB_WE_O       <= `REQ_READ;
                        sm_state      <= `S_T3_TRDY;
                    end
                end





                `S_T3_TRDY: begin
                    wb_cyc   <= 1'b1;
                    WB_ADR_O <= `SPISR;
                    WB_WE_O  <= `REQ_READ;


                    if ( (WB_ACK_I    == 1'b1) &&
                         (WB_DAT_I[7] == 1'b0) ) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_SPICR2;
                    end

                    else if ( (WB_ACK_I    == 1'b1) &&
                              (WB_DAT_I[4] == 1'b1) ) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_T3_TXDR;
                    end

                    else if (WB_ACK_I == 1'b1) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_T3_TRDY;
                    end
                end







                `S_T3_TXDR: begin
                    wb_cyc   <= 1'b1;
                    WB_ADR_O <= `SPITXDR;
                    WB_WE_O  <= `REQ_WRITE;


                    case (sm_spi_cmd)
                        `SPI_CMD_PROTOCOL: WB_DAT_O <= PROTOCOL;
                        `SPI_CMD_REVISION: WB_DAT_O <= REVISION;
                        default:           WB_DAT_O <= 8'h00;
                    endcase

                    if (WB_ACK_I == 1'b1) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_RN_RRDY;
                    end
                end





                `S_RN_RRDY: begin
                    wb_cyc   <= 1'b1;
                    WB_ADR_O <= `SPISR;
                    WB_WE_O  <= `REQ_READ;


                    if ( (WB_ACK_I    == 1'b1) &&
                         (WB_DAT_I[7] == 1'b0) &&
                         (WB_DAT_I[3] == 1'b0) ) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_SPICR2;
                    end

                    else if ( (WB_ACK_I    == 1'b1) &&
                              (WB_DAT_I[3] == 1'b1) ) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_RN_RXDR;
                    end

                    else if (WB_ACK_I == 1'b1) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_RN_RRDY;
                    end
                end







                `S_RN_RXDR: begin
                    wb_cyc   <= 1'b1;
                    WB_ADR_O <= `SPIRXDR;
                    WB_WE_O  <= `REQ_READ;

                    if (WB_ACK_I == 1'b1) begin
                        wb_cyc        <= 1'b0;
                        WB_WE_O       <= `REQ_READ;
                        sm_spi_byte   <= WB_DAT_I;


                        if ( (sm_byte_count == 4'h1)              &&
                            ((sm_spi_cmd    == `SPI_CMD_REG_READ) ||
                             (sm_spi_cmd    == `SPI_CMD_REG_WRITE)) ) begin
                            REGS_ADDR <= WB_DAT_I;
                        end

                        sm_state <= `S_RN_PROCESS;
                    end
                end





                `S_RN_PROCESS: begin
                    wb_cyc   <= 1'b1;
                    WB_ADR_O <= `SPISR;
                    WB_WE_O  <= `REQ_READ;
                    sm_state <= `S_TN_TRDY;





                    if (sm_byte_count != 4'hF) begin
                        sm_byte_count <= sm_byte_count + 4'h1;
                    end


                    case (sm_spi_cmd)


                        `SPI_CMD_LOAD_RGB: begin
                            FIFO_WDATA[33:32] <= 2'h0;

                            case (sm_pixel_index)
                                2'b00: FIFO_WDATA[23:16] <= sm_spi_byte;
                                2'b01: FIFO_WDATA[15: 8] <= sm_spi_byte;
                                2'b10: begin
                                    FIFO_WDATA[ 7: 0] <= sm_spi_byte;
                                    if (FIFO_FULL == 1'b0)
                                        FIFO_WE <= 1'b1;
                                    else
                                        FIFO_OVERFLOW <= 1'b1;
                                end
                            endcase

                            if (sm_pixel_index < 2'b10)
                                sm_pixel_index <= sm_pixel_index + 2'b01;
                            else
                                sm_pixel_index <= 2'b00;
                        end



                        `SPI_CMD_LOAD_WRGB: begin
                            FIFO_WDATA[33:32] <= 2'h0;

                            case (sm_pixel_index)
                                2'b00: FIFO_WDATA[31:24] <= sm_spi_byte;
                                2'b01: FIFO_WDATA[23:16] <= sm_spi_byte;
                                2'b10: FIFO_WDATA[15: 8] <= sm_spi_byte;
                                2'b11: begin
                                    FIFO_WDATA[ 7: 0] <= sm_spi_byte;
                                    if (FIFO_FULL == 1'b0)
                                        FIFO_WE <= 1'b1;
                                    else
                                        FIFO_OVERFLOW <= 1'b1;
                                end
                            endcase

                            if (sm_pixel_index < 2'b11)
                                sm_pixel_index <= sm_pixel_index + 2'b01;
                            else
                                sm_pixel_index <= 2'b00;
                        end



                        `SPI_CMD_LOAD_RESET_CYCLE: begin
                            FIFO_WDATA[33:32] <= 2'h2;

                            if (FIFO_FULL == 1'b0) begin
                                FIFO_WE <= 1'b1;
                                EOF     <= 1'b1;
                            end
                            else begin
                                FIFO_OVERFLOW <= 1'b1;
                            end
                        end



                        `SPI_CMD_LOAD_RESET_CODE: begin
                            FIFO_WDATA[32:32] <= 2'h1;

                            if (FIFO_FULL == 1'b0) begin
                                FIFO_WE <= 1'b1;
                                EOF     <= 1'b1;
                            end
                            else begin
                                FIFO_OVERFLOW <= 1'b1;
                            end
                        end


                        `SPI_CMD_REG_WRITE: begin
                            if (sm_byte_count > 4'h1) begin
                                REGS_WDATA <= sm_spi_byte;
                                REGS_WE    <= 1'b1;
                            end
                        end
                    endcase
                end





                `S_TN_TRDY: begin
                    wb_cyc   <= 1'b1;
                    WB_ADR_O <= `SPISR;
                    WB_WE_O  <= `REQ_READ;


                    if ( (WB_ACK_I    == 1'b1) &&
                         (WB_DAT_I[7] == 1'b0) ) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_SPICR2;
                    end

                    else if ( (WB_ACK_I    == 1'b1) &&
                              (WB_DAT_I[4] == 1'b1) ) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_TN_TXDR;
                    end

                    else if (WB_ACK_I == 1'b1) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_TN_TRDY;
                    end
                end





                `S_TN_TXDR: begin
                    wb_cyc   <= 1'b1;
                    WB_ADR_O <= `SPITXDR;
                    WB_WE_O  <= `REQ_WRITE;


                    if ( (sm_spi_cmd    == `SPI_CMD_REG_READ) &&
                         (sm_byte_count >= 4'h2) ) begin
                        WB_DAT_O <= REGS_RDATA;
                    end

                    else if ( (sm_spi_cmd == `SPI_CMD_LOAD_RGB)         ||
                              (sm_spi_cmd == `SPI_CMD_LOAD_WRGB)        ||
                              (sm_spi_cmd == `SPI_CMD_LOAD_RESET_CYCLE) ||
                              (sm_spi_cmd == `SPI_CMD_LOAD_RESET_CODE) ) begin
                        WB_DAT_O <= STATUS_REGISTER;
                    end

                    else begin
                        WB_DAT_O <= 8'h00;
                    end

                    if (WB_ACK_I == 1'b1) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;


                        if ( ((sm_byte_count >= 4'h3)                &&
                              (sm_spi_cmd    == `SPI_CMD_REG_WRITE)) ||
                             ((sm_byte_count >= 4'h2)                &&
                              (sm_spi_cmd    == `SPI_CMD_REG_READ)) ) begin
                            REGS_ADDR <= REGS_ADDR + 4'h1;
                        end

                        sm_state <= `S_RN_RRDY;
                    end
                end





                default: begin
                    sm_state <= `S_INIT;
                end
            endcase
        end
    end

endmodule
module ctrl #(
    parameter           PROTOCOL = 8'hFF,
    parameter           REVISION = 8'hFF
) (
    input  wire         CLK,
    input  wire         RST_N,


    output wire         WB_CYC_O,
    output wire         WB_STB_O,
    output reg          WB_WE_O,
    output reg  [7:0]   WB_ADR_O,
    output reg  [7:0]   WB_DAT_O,
    input  wire [7:0]   WB_DAT_I,
    input  wire         WB_ACK_I,


    input  wire [7:0]   STATUS_REGISTER,


    output reg          REGS_WE,
    output reg  [7:0]   REGS_ADDR,
    output reg  [7:0]   REGS_WDATA,
    input  wire [7:0]   REGS_RDATA,


    input  wire         FIFO_FULL,
    output reg          FIFO_WE,
    output reg  [33:0]  FIFO_WDATA,


    output reg          FIFO_OVERFLOW,


    output reg          EOF
);







    `define REQ_READ                 1'b0
    `define REQ_WRITE                1'b1


    `define SPICR0                   8'h54
    `define SPICR1                   8'h55
    `define SPICR2                   8'h56
    `define SPIBR                    8'h57
    `define SPICSR                   8'h58
    `define SPITXDR                  8'h59
    `define SPISR                    8'h5A
    `define SPIRXDR                  8'h5B
    `define SPIIRQ                   8'h5C
    `define SPIIRQEN                 8'h5D


    `define SPICR1_CFG               8'h80
    `define SPICR2_CFG               8'h00
    `define SPITXDR_CFG              8'h00
    `define SPIIRQEN_CFG             8'h00


    `define SPI_CMD_PROTOCOL         8'hF0
    `define SPI_CMD_REVISION         8'hF1
    `define SPI_CMD_REG_READ         8'h00
    `define SPI_CMD_REG_WRITE        8'h01
    `define SPI_CMD_LOAD_RGB         8'h04
    `define SPI_CMD_LOAD_WRGB        8'h05
    `define SPI_CMD_LOAD_RESET_CYCLE 8'h06
    `define SPI_CMD_LOAD_RESET_CODE  8'h07


    `define S_INIT                   5'h00
    `define S_SPICR1                 5'h01
    `define S_SPICR2                 5'h02
    `define S_WAIT_FOR_TIPN          5'h03
    `define S_RXDR_DISCARD1          5'h04
    `define S_RXDR_DISCARD2          5'h05
    `define S_T1_TXDR                5'h06
    `define S_WAIT_FOR_TIP           5'h07
    `define S_T2_TRDY                5'h08
    `define S_T2_TXDR                5'h09
    `define S_R1_RRDY                5'h0A
    `define S_R1_RXDR                5'h0B
    `define S_T3_TRDY                5'h0C
    `define S_T3_TXDR                5'h0D
    `define S_RN_RRDY                5'h0E
    `define S_RN_RXDR                5'h0F
    `define S_RN_PROCESS             5'h10
    `define S_TN_TRDY                5'h11
    `define S_TN_TXDR                5'h12


    reg       wb_cyc;


    reg [4:0] sm_state;


    reg [7:0] sm_spi_cmd;
    reg [7:0] sm_spi_byte;
    reg [3:0] sm_byte_count;
    reg [1:0] sm_pixel_index;





    assign #1.000 WB_STB_O = wb_cyc;
    assign #1.000 WB_CYC_O = wb_cyc;





    always @(posedge CLK or negedge RST_N) begin
        if (RST_N == 1'b0) begin
            sm_state        <= `S_INIT;


            wb_cyc          <= 1'b0;
            WB_WE_O         <= 1'b0;
            WB_ADR_O        <= 8'h00;
            WB_DAT_O        <= 8'h00;


            REGS_ADDR       <= 8'h00;
            REGS_WDATA      <= 8'h00;
            REGS_WE         <= 1'b0;


            FIFO_WE         <= 1'b0;
            FIFO_WDATA      <= 34'h0_0000_0000;
            FIFO_OVERFLOW   <= 1'b0;


            sm_spi_cmd      <= 8'h00;
            sm_spi_byte     <= 8'h00;


            sm_byte_count   <= 4'h0;
            sm_pixel_index  <= 2'b00;


            EOF             <= 1'b0;
        end
        else begin

            wb_cyc          <= 1'b0;
            WB_WE_O         <= `REQ_READ;
            REGS_WE         <= 1'b0;
            FIFO_WE         <= 1'b0;
            FIFO_OVERFLOW   <= 1'b0;
            EOF             <= 1'b0;

            case (sm_state)




                `S_INIT: begin
                    sm_state <= `S_SPICR1;
                end





                `S_SPICR1: begin
                    wb_cyc   <= 1'b1;
                    WB_ADR_O <= `SPICR1;
                    WB_DAT_O <= `SPICR1_CFG;
                    WB_WE_O  <= `REQ_WRITE;
                    sm_state <= `S_SPICR1;

                    if (WB_ACK_I == 1'b1) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_SPICR2;
                    end
                end





                `S_SPICR2: begin
                    wb_cyc   <= 1'b1;
                    WB_ADR_O <= `SPICR2;
                    WB_DAT_O <= `SPICR2_CFG;
                    WB_WE_O  <= `REQ_WRITE;

                    if (WB_ACK_I == 1'b1) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_WAIT_FOR_TIPN;
                    end
                end





                `S_WAIT_FOR_TIPN: begin
                    wb_cyc   <= 1'b1;
                    WB_ADR_O <= `SPISR;
                    WB_WE_O  <= `REQ_READ;


                    if ( (WB_ACK_I    == 1'b1) &&
                         (WB_DAT_I[7] == 1'b0) ) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_RXDR_DISCARD1;
                    end

                    else if (WB_ACK_I == 1'b1)  begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_WAIT_FOR_TIPN;
                    end
                end







                `S_RXDR_DISCARD1: begin
                    wb_cyc   <= 1'b1;
                    WB_ADR_O <= `SPIRXDR;
                    WB_WE_O  <= `REQ_READ;

                    if (WB_ACK_I == 1'b1) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_RXDR_DISCARD2;
                    end
                end







                `S_RXDR_DISCARD2: begin
                    wb_cyc   <= 1'b1;
                    WB_ADR_O <= `SPIRXDR;
                    WB_WE_O  <= `REQ_READ;

                    if (WB_ACK_I == 1'b1) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_T1_TXDR;
                    end
                end







                `S_T1_TXDR: begin
                    wb_cyc   <= 1'b1;
                    WB_ADR_O <= `SPITXDR;
                    WB_DAT_O <= 8'h00;
                    WB_WE_O  <= `REQ_WRITE;

                    if (WB_ACK_I == 1'b1) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_WAIT_FOR_TIP;
                    end
                end





                `S_WAIT_FOR_TIP: begin
                    sm_byte_count  <= 4'h0;
                    sm_pixel_index <= 2'b00;

                    wb_cyc         <= 1'b1;
                    WB_ADR_O       <= `SPISR;
                    WB_WE_O        <= `REQ_READ;


                    if ( (WB_ACK_I    == 1'b1) &&
                         (WB_DAT_I[7] == 1'b1) &&
                         (WB_DAT_I[4] == 1'b1) ) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_T2_TXDR;
                    end

                    else if ( (WB_ACK_I    == 1'b1) &&
                              (WB_DAT_I[7] == 1'b1) ) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_T2_TRDY;
                    end

                    else if (WB_ACK_I == 1'b1) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_WAIT_FOR_TIP;
                    end
                end





                `S_T2_TRDY: begin
                    wb_cyc   <= 1'b1;
                    WB_ADR_O <= `SPISR;
                    WB_WE_O  <= `REQ_READ;


                    if ( (WB_ACK_I    == 1'b1) &&
                         (WB_DAT_I[4] == 1'b1) ) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_T2_TXDR;
                    end

                    else if (WB_ACK_I == 1'b1) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_T2_TRDY;
                    end
                end







                `S_T2_TXDR: begin
                    wb_cyc   <= 1'b1;
                    WB_ADR_O <= `SPITXDR;
                    WB_DAT_O <= 8'h00;
                    WB_WE_O  <= `REQ_WRITE;

                    if (WB_ACK_I == 1'b1) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_R1_RRDY;
                    end
                end





                `S_R1_RRDY: begin
                    wb_cyc   <= 1'b1;
                    WB_ADR_O <= `SPISR;
                    WB_WE_O  <= `REQ_READ;


                    if ( (WB_ACK_I    == 1'b1) &&
                         (WB_DAT_I[7] == 1'b0) &&
                         (WB_DAT_I[3] == 1'b0) ) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_SPICR2;
                    end

                    else if ( (WB_ACK_I    == 1'b1) &&
                              (WB_DAT_I[3] == 1'b1) ) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_R1_RXDR;
                    end

                    else if (WB_ACK_I == 1'b1) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_R1_RRDY;
                    end
                end







                `S_R1_RXDR: begin
                    wb_cyc   <= 1'b1;
                    WB_ADR_O <= `SPIRXDR;
                    WB_WE_O  <= `REQ_READ;

                    if (WB_ACK_I == 1'b1) begin
                        sm_byte_count <= 4'h1;
                        sm_spi_cmd    <= WB_DAT_I;

                        wb_cyc        <= 1'b0;
                        WB_WE_O       <= `REQ_READ;
                        sm_state      <= `S_T3_TRDY;
                    end
                end





                `S_T3_TRDY: begin
                    wb_cyc   <= 1'b1;
                    WB_ADR_O <= `SPISR;
                    WB_WE_O  <= `REQ_READ;


                    if ( (WB_ACK_I    == 1'b1) &&
                         (WB_DAT_I[7] == 1'b0) ) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_SPICR2;
                    end

                    else if ( (WB_ACK_I    == 1'b1) &&
                              (WB_DAT_I[4] == 1'b1) ) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_T3_TXDR;
                    end

                    else if (WB_ACK_I == 1'b1) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_T3_TRDY;
                    end
                end







                `S_T3_TXDR: begin
                    wb_cyc   <= 1'b1;
                    WB_ADR_O <= `SPITXDR;
                    WB_WE_O  <= `REQ_WRITE;


                    case (sm_spi_cmd)
                        `SPI_CMD_PROTOCOL: WB_DAT_O <= PROTOCOL;
                        `SPI_CMD_REVISION: WB_DAT_O <= REVISION;
                        default:           WB_DAT_O <= 8'h00;
                    endcase

                    if (WB_ACK_I == 1'b1) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_RN_RRDY;
                    end
                end





                `S_RN_RRDY: begin
                    wb_cyc   <= 1'b1;
                    WB_ADR_O <= `SPISR;
                    WB_WE_O  <= `REQ_READ;


                    if ( (WB_ACK_I    == 1'b1) &&
                         (WB_DAT_I[7] == 1'b0) &&
                         (WB_DAT_I[3] == 1'b0) ) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_SPICR2;
                    end

                    else if ( (WB_ACK_I    == 1'b1) &&
                              (WB_DAT_I[3] == 1'b1) ) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_RN_RXDR;
                    end

                    else if (WB_ACK_I == 1'b1) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_RN_RRDY;
                    end
                end







                `S_RN_RXDR: begin
                    wb_cyc   <= 1'b1;
                    WB_ADR_O <= `SPIRXDR;
                    WB_WE_O  <= `REQ_READ;

                    if (WB_ACK_I == 1'b1) begin
                        wb_cyc        <= 1'b0;
                        WB_WE_O       <= `REQ_READ;
                        sm_spi_byte   <= WB_DAT_I;


                        if ( (sm_byte_count == 4'h1)              &&
                            ((sm_spi_cmd    == `SPI_CMD_REG_READ) ||
                             (sm_spi_cmd    == `SPI_CMD_REG_WRITE)) ) begin
                            REGS_ADDR <= WB_DAT_I;
                        end

                        sm_state <= `S_RN_PROCESS;
                    end
                end





                `S_RN_PROCESS: begin
                    wb_cyc   <= 1'b1;
                    WB_ADR_O <= `SPISR;
                    WB_WE_O  <= `REQ_READ;
                    sm_state <= `S_TN_TRDY;





                    if (sm_byte_count != 4'hF) begin
                        sm_byte_count <= sm_byte_count + 4'h1;
                    end


                    case (sm_spi_cmd)


                        `SPI_CMD_LOAD_RGB: begin
                            FIFO_WDATA[33:32] <= 2'h0;

                            case (sm_pixel_index)
                                2'b00: FIFO_WDATA[23:16] <= sm_spi_byte;
                                2'b01: FIFO_WDATA[15: 8] <= sm_spi_byte;
                                2'b10: begin
                                    FIFO_WDATA[ 7: 0] <= sm_spi_byte;
                                    if (FIFO_FULL == 1'b0)
                                        FIFO_WE <= 1'b1;
                                    else
                                        FIFO_OVERFLOW <= 1'b1;
                                end
                            endcase

                            if (sm_pixel_index < 2'b10)
                                sm_pixel_index <= sm_pixel_index + 2'b01;
                            else
                                sm_pixel_index <= 2'b00;
                        end



                        `SPI_CMD_LOAD_WRGB: begin
                            FIFO_WDATA[33:32] <= 2'h0;

                            case (sm_pixel_index)
                                2'b00: FIFO_WDATA[31:24] <= sm_spi_byte;
                                2'b01: FIFO_WDATA[23:16] <= sm_spi_byte;
                                2'b10: FIFO_WDATA[15: 8] <= sm_spi_byte;
                                2'b11: begin
                                    FIFO_WDATA[ 7: 0] <= sm_spi_byte;
                                    if (FIFO_FULL == 1'b0)
                                        FIFO_WE <= 1'b1;
                                    else
                                        FIFO_OVERFLOW <= 1'b1;
                                end
                            endcase

                            if (sm_pixel_index < 2'b11)
                                sm_pixel_index <= sm_pixel_index + 2'b01;
                            else
                                sm_pixel_index <= 2'b00;
                        end



                        `SPI_CMD_LOAD_RESET_CYCLE: begin
                            FIFO_WDATA[33:32] <= 2'h2;

                            if (FIFO_FULL == 1'b0) begin
                                FIFO_WE <= 1'b1;
                                EOF     <= 1'b1;
                            end
                            else begin
                                FIFO_OVERFLOW <= 1'b1;
                            end
                        end



                        `SPI_CMD_LOAD_RESET_CODE: begin
                            FIFO_WDATA[32:32] <= 2'h1;

                            if (FIFO_FULL == 1'b0) begin
                                FIFO_WE <= 1'b1;
                                EOF     <= 1'b1;
                            end
                            else begin
                                FIFO_OVERFLOW <= 1'b1;
                            end
                        end


                        `SPI_CMD_REG_WRITE: begin
                            if (sm_byte_count > 4'h1) begin
                                REGS_WDATA <= sm_spi_byte;
                                REGS_WE    <= 1'b1;
                            end
                        end
                    endcase
                end





                `S_TN_TRDY: begin
                    wb_cyc   <= 1'b1;
                    WB_ADR_O <= `SPISR;
                    WB_WE_O  <= `REQ_READ;


                    if ( (WB_ACK_I    == 1'b1) &&
                         (WB_DAT_I[7] == 1'b0) ) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_SPICR2;
                    end

                    else if ( (WB_ACK_I    == 1'b1) &&
                              (WB_DAT_I[4] == 1'b1) ) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_TN_TXDR;
                    end

                    else if (WB_ACK_I == 1'b1) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;
                        sm_state <= `S_TN_TRDY;
                    end
                end





                `S_TN_TXDR: begin
                    wb_cyc   <= 1'b1;
                    WB_ADR_O <= `SPITXDR;
                    WB_WE_O  <= `REQ_WRITE;


                    if ( (sm_spi_cmd    == `SPI_CMD_REG_READ) &&
                         (sm_byte_count >= 4'h2) ) begin
                        WB_DAT_O <= REGS_RDATA;
                    end

                    else if ( (sm_spi_cmd == `SPI_CMD_LOAD_RGB)         ||
                              (sm_spi_cmd == `SPI_CMD_LOAD_WRGB)        ||
                              (sm_spi_cmd == `SPI_CMD_LOAD_RESET_CYCLE) ||
                              (sm_spi_cmd == `SPI_CMD_LOAD_RESET_CODE) ) begin
                        WB_DAT_O <= STATUS_REGISTER;
                    end

                    else begin
                        WB_DAT_O <= 8'h00;
                    end

                    if (WB_ACK_I == 1'b1) begin
                        wb_cyc   <= 1'b0;
                        WB_WE_O  <= `REQ_READ;


                        if ( ((sm_byte_count >= 4'h3)                &&
                              (sm_spi_cmd    == `SPI_CMD_REG_WRITE)) ||
                             ((sm_byte_count >= 4'h2)                &&
                              (sm_spi_cmd    == `SPI_CMD_REG_READ)) ) begin
                            REGS_ADDR <= REGS_ADDR + 4'h1;
                        end

                        sm_state <= `S_RN_RRDY;
                    end
                end





                default: begin
                    sm_state <= `S_INIT;
                end
            endcase
        end
    end

endmodule