data/full_repos/permissive/500717851/verilog/rtl/wfg/wfg_drive_spi/rtl/wfg_drive_spi.sv
1: b'%Warning-WIDTH: data/full_repos/permissive/500717851/verilog/rtl/wfg/wfg_drive_spi/rtl/wfg_drive_spi.sv:188: Operator ASSIGNDLY expects 32 bits on the Assign RHS, but Assign RHS\'s CONST \'1\'h0\' generates 1 bits.\n                                                                                                           : ... In instance wfg_drive_spi\n                    spi_data <= 1\'b0;\n                             ^~\n                ... Use "/* verilator lint_off WIDTH */" and lint_on around source to disable this message.\n%Error: Exiting due to 1 warning(s)\n'
module wfg_drive_spi #(
    parameter int AXIS_DATA_WIDTH = 32
) (
    input logic clk,
    input logic rst_n,


    input logic wfg_core_sync_i,
    input logic wfg_core_subcycle_i,


    input logic wfg_subcore_sync_i,
    input logic wfg_subcore_subcycle_i,


    output logic                       wfg_axis_tready_o,
    input  logic                       wfg_axis_tvalid_i,
    input  logic                       wfg_axis_tlast_i,
    input  logic [AXIS_DATA_WIDTH-1:0] wfg_axis_tdata_i,


    input logic ctrl_en_q_i,


    input logic [7:0] clkcfg_div_q_i,
    input logic       cfg_cpol_q_i,
    input logic       cfg_lsbfirst_q_i,
    input logic [1:0] cfg_dff_q_i,
    input logic       cfg_sspol_q_i,
    input logic       cfg_core_sel_q_i,


    output logic wfg_drive_spi_sclk_o,
    output logic wfg_drive_spi_cs_no,
    output logic wfg_drive_spi_sdo_o
);

    typedef enum logic [1:0] {
        ST_IDLE,
        ST_SEND_DATA,
        ST_LAST_BIT
    } my_uart_states_t;

    my_uart_states_t cur_state, next_state;

    logic transitioning;
    assign transitioning = cur_state != next_state;

    logic [7:0] counter;
    logic [7:0] clk_div;
    logic [4:0] current_bit;
    logic [31:0] spi_data;
    logic spi_cs;
    logic spi_clk;
    logic ready;
    logic lsbfirst;
    logic cpol;
    logic cspol;
    logic [1:0] byte_cnt;
    logic [4:0] bytes_to_bits [0:3];

    logic wfg_sync_i;
    logic wfg_subcycle_i;

    always_comb begin
        wfg_sync_i = 'x;
        wfg_subcycle_i = 'x;

        case (cfg_core_sel_q_i)
            1'b0: begin
                wfg_sync_i     = wfg_core_sync_i;
                wfg_subcycle_i = wfg_core_subcycle_i;
            end
            1'b1: begin
                wfg_sync_i     = wfg_subcore_sync_i;
                wfg_subcycle_i = wfg_subcore_subcycle_i;
            end
        endcase
    end


    always_ff @(posedge clk, negedge rst_n)
        if (!rst_n) cur_state <= ST_IDLE;
        else cur_state <= next_state;


    always_comb begin
        next_state = cur_state;
        case (cur_state)
            ST_IDLE: begin
                if (wfg_sync_i && wfg_axis_tvalid_i && ctrl_en_q_i) next_state = ST_SEND_DATA;
            end
            ST_SEND_DATA: begin
                if (counter == 0 && current_bit == 0 && spi_clk) begin
                    next_state = ST_LAST_BIT;
                end
            end
            ST_LAST_BIT: begin
                if (counter == 0) next_state = ST_IDLE;
            end
            default: begin
                next_state = ST_IDLE;
            end
        endcase
    end


    always_ff @(posedge clk, negedge rst_n)
        if (!rst_n) begin
            wfg_drive_spi_sclk_o <= '0;
            wfg_drive_spi_cs_no  <= '0;
            wfg_drive_spi_sdo_o  <= '0;

            counter              <= '0;
            current_bit          <= '0;
            spi_cs               <= '0;
            spi_data             <= '0;
            spi_clk              <= '0;
            ready                <= '0;
            clk_div              <= '0;
            lsbfirst             <= '0;
            cpol                 <= '0;
            cspol                <= '0;
            byte_cnt             <= '0;
            bytes_to_bits[0]     <= 5'd7;
            bytes_to_bits[1]     <= 5'd15;
            bytes_to_bits[2]     <= 5'd23;
            bytes_to_bits[3]     <= 5'd31;

        end else begin
            wfg_drive_spi_sclk_o <= cpol ? !spi_clk : spi_clk;
            wfg_drive_spi_cs_no  <= cspol ? spi_cs : !spi_cs;
            wfg_drive_spi_sdo_o  <= lsbfirst ? spi_data[0] : spi_data[bytes_to_bits[byte_cnt]];

            case (next_state)
                ST_IDLE: begin
                    counter  <= '0;
                    spi_clk  <= '0;
                    spi_cs   <= '0;
                    spi_data <= '0;

                    clk_div  <= clkcfg_div_q_i;
                    lsbfirst <= cfg_lsbfirst_q_i;
                    byte_cnt <= cfg_dff_q_i;
                    cpol     <= cfg_cpol_q_i;
                    cspol    <= cfg_sspol_q_i;
                end
                ST_SEND_DATA: begin
                    spi_cs <= 1'b1;

                    if (transitioning) begin
                        spi_data <= wfg_axis_tdata_i;
                        ready <= 1'b1;
                        counter <= clk_div;
                        current_bit <= bytes_to_bits[byte_cnt];
                    end else begin
                        counter <= counter - 1;
                        ready   <= 1'b0;

                        if (counter == 0) begin
                            spi_clk <= !spi_clk;
                            counter <= clk_div;

                            if (spi_clk == 1'b1) begin
                                current_bit <= current_bit - 1;
                                if (lsbfirst) begin
                                    spi_data <= {1'b0, spi_data[31:1]};
                                end else begin
                                    spi_data <= {spi_data[30:0], 1'b0};
                                end
                            end
                        end
                    end
                end
                ST_LAST_BIT: begin
                    if (transitioning) begin
                        counter <= clk_div;
                    end else begin
                        counter <= counter - 1;
                    end
                    spi_cs <= 1'b1;
                    spi_clk <= 1'b0;
                    ready <= 1'b0;
                    spi_data <= 1'b0;
                end
                default: begin
                    spi_cs   <= 'x;
                    spi_clk  <= 'x;
                    spi_data <= 'x;
                end
            endcase
        end

    assign wfg_axis_tready_o = ready;

endmodule
module wfg_drive_spi #(
    parameter int AXIS_DATA_WIDTH = 32
) (
    input logic clk,
    input logic rst_n,


    input logic wfg_core_sync_i,
    input logic wfg_core_subcycle_i,


    input logic wfg_subcore_sync_i,
    input logic wfg_subcore_subcycle_i,


    output logic                       wfg_axis_tready_o,
    input  logic                       wfg_axis_tvalid_i,
    input  logic                       wfg_axis_tlast_i,
    input  logic [AXIS_DATA_WIDTH-1:0] wfg_axis_tdata_i,


    input logic ctrl_en_q_i,


    input logic [7:0] clkcfg_div_q_i,
    input logic       cfg_cpol_q_i,
    input logic       cfg_lsbfirst_q_i,
    input logic [1:0] cfg_dff_q_i,
    input logic       cfg_sspol_q_i,
    input logic       cfg_core_sel_q_i,


    output logic wfg_drive_spi_sclk_o,
    output logic wfg_drive_spi_cs_no,
    output logic wfg_drive_spi_sdo_o
);


    typedef enum logic [1:0] {
        ST_IDLE,
        ST_SEND_DATA,
        ST_LAST_BIT
    } my_uart_states_t;

    my_uart_states_t cur_state, next_state;

    logic transitioning;
    assign transitioning = cur_state != next_state;

    logic [7:0] counter;
    logic [7:0] clk_div;
    logic [4:0] current_bit;
    logic [31:0] spi_data;
    logic spi_cs;
    logic spi_clk;
    logic ready;
    logic lsbfirst;
    logic cpol;
    logic cspol;
    logic [1:0] byte_cnt;
    logic [4:0] bytes_to_bits [0:3];

    logic wfg_sync_i;
    logic wfg_subcycle_i;

    always_comb begin
        wfg_sync_i = 'x;
        wfg_subcycle_i = 'x;

        case (cfg_core_sel_q_i)
            1'b0: begin
                wfg_sync_i     = wfg_core_sync_i;
                wfg_subcycle_i = wfg_core_subcycle_i;
            end
            1'b1: begin
                wfg_sync_i     = wfg_subcore_sync_i;
                wfg_subcycle_i = wfg_subcore_subcycle_i;
            end
        endcase
    end


    always_ff @(posedge clk, negedge rst_n)
        if (!rst_n) cur_state <= ST_IDLE;
        else cur_state <= next_state;


    always_comb begin
        next_state = cur_state;
        case (cur_state)
            ST_IDLE: begin
                if (wfg_sync_i && wfg_axis_tvalid_i && ctrl_en_q_i) next_state = ST_SEND_DATA;
            end
            ST_SEND_DATA: begin
                if (counter == 0 && current_bit == 0 && spi_clk) begin
                    next_state = ST_LAST_BIT;
                end
            end
            ST_LAST_BIT: begin
                if (counter == 0) next_state = ST_IDLE;
            end
            default: begin
                next_state = ST_IDLE;
            end
        endcase
    end


    always_ff @(posedge clk, negedge rst_n)
        if (!rst_n) begin
            wfg_drive_spi_sclk_o <= '0;
            wfg_drive_spi_cs_no  <= '0;
            wfg_drive_spi_sdo_o  <= '0;

            counter              <= '0;
            current_bit          <= '0;
            spi_cs               <= '0;
            spi_data             <= '0;
            spi_clk              <= '0;
            ready                <= '0;
            clk_div              <= '0;
            lsbfirst             <= '0;
            cpol                 <= '0;
            cspol                <= '0;
            byte_cnt             <= '0;
            bytes_to_bits[0]     <= 5'd7;
            bytes_to_bits[1]     <= 5'd15;
            bytes_to_bits[2]     <= 5'd23;
            bytes_to_bits[3]     <= 5'd31;

        end else begin
            wfg_drive_spi_sclk_o <= cpol ? !spi_clk : spi_clk;
            wfg_drive_spi_cs_no  <= cspol ? spi_cs : !spi_cs;
            wfg_drive_spi_sdo_o  <= lsbfirst ? spi_data[0] : spi_data[bytes_to_bits[byte_cnt]];

            case (next_state)
                ST_IDLE: begin
                    counter  <= '0;
                    spi_clk  <= '0;
                    spi_cs   <= '0;
                    spi_data <= '0;

                    clk_div  <= clkcfg_div_q_i;
                    lsbfirst <= cfg_lsbfirst_q_i;
                    byte_cnt <= cfg_dff_q_i;
                    cpol     <= cfg_cpol_q_i;
                    cspol    <= cfg_sspol_q_i;
                end
                ST_SEND_DATA: begin
                    spi_cs <= 1'b1;

                    if (transitioning) begin
                        spi_data <= wfg_axis_tdata_i;
                        ready <= 1'b1;
                        counter <= clk_div;
                        current_bit <= bytes_to_bits[byte_cnt];
                    end else begin
                        counter <= counter - 1;
                        ready   <= 1'b0;

                        if (counter == 0) begin
                            spi_clk <= !spi_clk;
                            counter <= clk_div;

                            if (spi_clk == 1'b1) begin
                                current_bit <= current_bit - 1;
                                if (lsbfirst) begin
                                    spi_data <= {1'b0, spi_data[31:1]};
                                end else begin
                                    spi_data <= {spi_data[30:0], 1'b0};
                                end
                            end
                        end
                    end
                end
                ST_LAST_BIT: begin
                    if (transitioning) begin
                        counter <= clk_div;
                    end else begin
                        counter <= counter - 1;
                    end
                    spi_cs <= 1'b1;
                    spi_clk <= 1'b0;
                    ready <= 1'b0;
                    spi_data <= 1'b0;
                end
                default: begin
                    spi_cs   <= 'x;
                    spi_clk  <= 'x;
                    spi_data <= 'x;
                end
            endcase
        end

    assign wfg_axis_tready_o = ready;

endmodule