data/full_repos/permissive/19449788/rtl/i2c_slave.v
 line:181: before: ","
1: b'%Warning-IMPLICIT: data/full_repos/permissive/19449788/rtl/i2c_slave.v:232: Signal definition not found, creating implicitly: \'scl_posedge\'\nassign scl_posedge = scl_i_reg && !last_scl_i_reg;\n       ^~~~~~~~~~~\n                   ... Use "/* verilator lint_off IMPLICIT */" and lint_on around source to disable this message.\n%Warning-IMPLICIT: data/full_repos/permissive/19449788/rtl/i2c_slave.v:233: Signal definition not found, creating implicitly: \'scl_negedge\'\n                                                                          : ... Suggested alternative: \'scl_posedge\'\nassign scl_negedge = !scl_i_reg && last_scl_i_reg;\n       ^~~~~~~~~~~\n%Warning-IMPLICIT: data/full_repos/permissive/19449788/rtl/i2c_slave.v:234: Signal definition not found, creating implicitly: \'sda_posedge\'\n                                                                          : ... Suggested alternative: \'scl_posedge\'\nassign sda_posedge = sda_i_reg && !last_sda_i_reg;\n       ^~~~~~~~~~~\n%Warning-IMPLICIT: data/full_repos/permissive/19449788/rtl/i2c_slave.v:235: Signal definition not found, creating implicitly: \'sda_negedge\'\n                                                                          : ... Suggested alternative: \'scl_negedge\'\nassign sda_negedge = !sda_i_reg && last_sda_i_reg;\n       ^~~~~~~~~~~\n%Warning-IMPLICIT: data/full_repos/permissive/19449788/rtl/i2c_slave.v:237: Signal definition not found, creating implicitly: \'start_bit\'\nassign start_bit = sda_negedge && scl_i_reg;\n       ^~~~~~~~~\n%Warning-IMPLICIT: data/full_repos/permissive/19449788/rtl/i2c_slave.v:238: Signal definition not found, creating implicitly: \'stop_bit\'\n                                                                          : ... Suggested alternative: \'start_bit\'\nassign stop_bit = sda_posedge && scl_i_reg;\n       ^~~~~~~~\n%Warning-WIDTH: data/full_repos/permissive/19449788/rtl/i2c_slave.v:172: Operator VAR \'STATE_IDLE\' expects 5 bits on the Initial value, but Initial value\'s CONST \'4\'h0\' generates 4 bits.\n                                                                       : ... In instance i2c_slave\n    STATE_IDLE = 4\'d0,\n    ^~~~~~~~~~\n%Warning-WIDTH: data/full_repos/permissive/19449788/rtl/i2c_slave.v:173: Operator VAR \'STATE_ADDRESS\' expects 5 bits on the Initial value, but Initial value\'s CONST \'4\'h1\' generates 4 bits.\n                                                                       : ... In instance i2c_slave\n    STATE_ADDRESS = 4\'d1,\n    ^~~~~~~~~~~~~\n%Warning-WIDTH: data/full_repos/permissive/19449788/rtl/i2c_slave.v:174: Operator VAR \'STATE_ACK\' expects 5 bits on the Initial value, but Initial value\'s CONST \'4\'h2\' generates 4 bits.\n                                                                       : ... In instance i2c_slave\n    STATE_ACK = 4\'d2,\n    ^~~~~~~~~\n%Warning-WIDTH: data/full_repos/permissive/19449788/rtl/i2c_slave.v:175: Operator VAR \'STATE_WRITE_1\' expects 5 bits on the Initial value, but Initial value\'s CONST \'4\'h3\' generates 4 bits.\n                                                                       : ... In instance i2c_slave\n    STATE_WRITE_1 = 4\'d3,\n    ^~~~~~~~~~~~~\n%Warning-WIDTH: data/full_repos/permissive/19449788/rtl/i2c_slave.v:176: Operator VAR \'STATE_WRITE_2\' expects 5 bits on the Initial value, but Initial value\'s CONST \'4\'h4\' generates 4 bits.\n                                                                       : ... In instance i2c_slave\n    STATE_WRITE_2 = 4\'d4,\n    ^~~~~~~~~~~~~\n%Warning-WIDTH: data/full_repos/permissive/19449788/rtl/i2c_slave.v:177: Operator VAR \'STATE_READ_1\' expects 5 bits on the Initial value, but Initial value\'s CONST \'4\'h5\' generates 4 bits.\n                                                                       : ... In instance i2c_slave\n    STATE_READ_1 = 4\'d5,\n    ^~~~~~~~~~~~\n%Warning-WIDTH: data/full_repos/permissive/19449788/rtl/i2c_slave.v:178: Operator VAR \'STATE_READ_2\' expects 5 bits on the Initial value, but Initial value\'s CONST \'4\'h6\' generates 4 bits.\n                                                                       : ... In instance i2c_slave\n    STATE_READ_2 = 4\'d6,\n    ^~~~~~~~~~~~\n%Warning-WIDTH: data/full_repos/permissive/19449788/rtl/i2c_slave.v:179: Operator VAR \'STATE_READ_3\' expects 5 bits on the Initial value, but Initial value\'s CONST \'4\'h7\' generates 4 bits.\n                                                                       : ... In instance i2c_slave\n    STATE_READ_3 = 4\'d7;\n    ^~~~~~~~~~~~\n%Warning-WIDTH: data/full_repos/permissive/19449788/rtl/i2c_slave.v:458: Operator OR expects 4 bits on the RHS, but RHS\'s VARREF \'scl_i\' generates 1 bits.\n                                                                       : ... In instance i2c_slave\n    scl_i_filter <= (scl_i_filter << 1) | scl_i;\n                                        ^\n%Warning-WIDTH: data/full_repos/permissive/19449788/rtl/i2c_slave.v:459: Operator OR expects 4 bits on the RHS, but RHS\'s VARREF \'sda_i\' generates 1 bits.\n                                                                       : ... In instance i2c_slave\n    sda_i_filter <= (sda_i_filter << 1) | sda_i;\n                                        ^\n%Error: Exiting due to 16 warning(s)\n'
module i2c_slave #(
    parameter FILTER_LEN = 4
)
(
    input wire         clk,
    input wire         rst,


    input  wire        release_bus,

    input  wire [7:0]  s_axis_data_tdata,
    input  wire        s_axis_data_tvalid,
    output wire        s_axis_data_tready,
    input  wire        s_axis_data_tlast,

    output wire [7:0]  m_axis_data_tdata,
    output wire        m_axis_data_tvalid,
    input  wire        m_axis_data_tready,
    output wire        m_axis_data_tlast,


    input  wire        scl_i,
    output wire        scl_o,
    output wire        scl_t,
    input  wire        sda_i,
    output wire        sda_o,
    output wire        sda_t,


    output wire        busy,
    output wire [6:0]  bus_address,
    output wire        bus_addressed,
    output wire        bus_active,


    input  wire        enable,
    input  wire [6:0]  device_address,
    input  wire [6:0]  device_address_mask
);


localparam [4:0]
    STATE_IDLE = 4'd0,
    STATE_ADDRESS = 4'd1,
    STATE_ACK = 4'd2,
    STATE_WRITE_1 = 4'd3,
    STATE_WRITE_2 = 4'd4,
    STATE_READ_1 = 4'd5,
    STATE_READ_2 = 4'd6,
    STATE_READ_3 = 4'd7;

reg [4:0] state_reg = STATE_IDLE, state_next;

reg [6:0] addr_reg = 7'd0, addr_next;
reg [7:0] data_reg = 8'd0, data_next;
reg data_valid_reg = 1'b0, data_valid_next;
reg data_out_reg_valid_reg = 1'b0, data_out_reg_valid_next;
reg last_reg = 1'b0, last_next;

reg mode_read_reg = 1'b0, mode_read_next;

reg [3:0] bit_count_reg = 4'd0, bit_count_next;

reg s_axis_data_tready_reg = 1'b0, s_axis_data_tready_next;

reg [7:0] m_axis_data_tdata_reg = 8'd0, m_axis_data_tdata_next;
reg m_axis_data_tvalid_reg = 1'b0, m_axis_data_tvalid_next;
reg m_axis_data_tlast_reg = 1'b0, m_axis_data_tlast_next;

reg [FILTER_LEN-1:0] scl_i_filter = {FILTER_LEN{1'b1}};
reg [FILTER_LEN-1:0] sda_i_filter = {FILTER_LEN{1'b1}};

reg scl_i_reg = 1'b1;
reg sda_i_reg = 1'b1;

reg scl_o_reg = 1'b1, scl_o_next;
reg sda_o_reg = 1'b1, sda_o_next;

reg last_scl_i_reg = 1'b1;
reg last_sda_i_reg = 1'b1;

reg busy_reg = 1'b0;
reg bus_active_reg = 1'b0;
reg bus_addressed_reg = 1'b0, bus_addressed_next;

assign bus_address = addr_reg;

assign s_axis_data_tready = s_axis_data_tready_reg;

assign m_axis_data_tdata = m_axis_data_tdata_reg;
assign m_axis_data_tvalid = m_axis_data_tvalid_reg;
assign m_axis_data_tlast = m_axis_data_tlast_reg;

assign scl_o = scl_o_reg;
assign scl_t = scl_o_reg;
assign sda_o = sda_o_reg;
assign sda_t = sda_o_reg;

assign busy = busy_reg;
assign bus_active = bus_active_reg;
assign bus_addressed = bus_addressed_reg;

assign scl_posedge = scl_i_reg && !last_scl_i_reg;
assign scl_negedge = !scl_i_reg && last_scl_i_reg;
assign sda_posedge = sda_i_reg && !last_sda_i_reg;
assign sda_negedge = !sda_i_reg && last_sda_i_reg;

assign start_bit = sda_negedge && scl_i_reg;
assign stop_bit = sda_posedge && scl_i_reg;

always @* begin
    state_next = STATE_IDLE;

    addr_next = addr_reg;
    data_next = data_reg;
    data_valid_next = data_valid_reg;
    data_out_reg_valid_next = data_out_reg_valid_reg;
    last_next = last_reg;

    mode_read_next = mode_read_reg;

    bit_count_next = bit_count_reg;

    s_axis_data_tready_next = 1'b0;

    m_axis_data_tdata_next = m_axis_data_tdata_reg;
    m_axis_data_tvalid_next = m_axis_data_tvalid_reg && !m_axis_data_tready;
    m_axis_data_tlast_next = m_axis_data_tlast_reg;

    scl_o_next = scl_o_reg;
    sda_o_next = sda_o_reg;

    bus_addressed_next = bus_addressed_reg;

    if (start_bit) begin

        data_valid_next = 1'b0;
        data_out_reg_valid_next = 1'b0;
        bit_count_next = 4'd7;
        m_axis_data_tlast_next = 1'b1;
        m_axis_data_tvalid_next = data_out_reg_valid_reg;
        bus_addressed_next = 1'b0;
        state_next = STATE_ADDRESS;
    end else if (release_bus || stop_bit) begin

        data_valid_next = 1'b0;
        data_out_reg_valid_next = 1'b0;
        m_axis_data_tlast_next = 1'b1;
        m_axis_data_tvalid_next = data_out_reg_valid_reg;
        bus_addressed_next = 1'b0;
        state_next = STATE_IDLE;
    end else begin
        case (state_reg)
            STATE_IDLE: begin

                data_valid_next = 1'b0;
                data_out_reg_valid_next = 1'b0;
                bus_addressed_next = 1'b0;
                state_next = STATE_IDLE;
            end
            STATE_ADDRESS: begin

                if (scl_posedge) begin
                    if (bit_count_reg > 0) begin

                        bit_count_next = bit_count_reg-1;
                        data_next = {data_reg[6:0], sda_i_reg};
                        state_next = STATE_ADDRESS;
                    end else begin

                        if (enable && (device_address & device_address_mask) == (data_reg[6:0] & device_address_mask)) begin

                            addr_next = data_reg[6:0];
                            mode_read_next = sda_i_reg;
                            bus_addressed_next = 1'b1;
                            state_next = STATE_ACK;
                        end else begin

                            state_next = STATE_IDLE;
                        end
                    end
                end else begin
                    state_next = STATE_ADDRESS;
                end
            end
            STATE_ACK: begin

                if (scl_negedge) begin
                    sda_o_next = 1'b0;
                    bit_count_next = 4'd7;
                    if (mode_read_reg) begin

                        s_axis_data_tready_next = 1'b1;
                        data_valid_next = 1'b0;
                        state_next = STATE_READ_1;
                    end else begin

                        state_next = STATE_WRITE_1;
                    end
                end else begin
                    state_next = STATE_ACK;
                end
            end
            STATE_WRITE_1: begin

                if (scl_negedge || !scl_o_reg) begin
                    sda_o_next = 1'b1;
                    if (m_axis_data_tvalid && !m_axis_data_tready) begin

                        scl_o_next = 1'b0;
                        state_next = STATE_WRITE_1;
                    end else begin
                        scl_o_next = 1'b1;
                        if (data_valid_reg) begin

                            m_axis_data_tdata_next = data_reg;
                            m_axis_data_tlast_next = 1'b0;
                        end
                        data_valid_next = 1'b0;
                        data_out_reg_valid_next = data_valid_reg;
                        state_next = STATE_WRITE_2;
                    end
                end else begin
                    state_next = STATE_WRITE_1;
                end
            end
            STATE_WRITE_2: begin

                if (scl_posedge) begin

                    data_next = {data_reg[6:0], sda_i_reg};
                    if (bit_count_reg > 0) begin
                        bit_count_next = bit_count_reg-1;
                        state_next = STATE_WRITE_2;
                    end else begin

                        m_axis_data_tvalid_next = data_out_reg_valid_reg;
                        data_out_reg_valid_next = 1'b0;
                        data_valid_next = 1'b1;
                        state_next = STATE_ACK;
                    end
                end else begin
                    state_next = STATE_WRITE_2;
                end
            end
            STATE_READ_1: begin

                if (s_axis_data_tready && s_axis_data_tvalid) begin

                    s_axis_data_tready_next = 1'b0;
                    data_next = s_axis_data_tdata;
                    data_valid_next = 1'b1;
                end else begin

                    s_axis_data_tready_next = !data_valid_reg;
                end

                if (scl_negedge || !scl_o_reg) begin

                    if (!data_valid_reg) begin

                        scl_o_next = 1'b0;
                        state_next = STATE_READ_1;
                    end else begin
                        scl_o_next = 1'b1;
                        {sda_o_next, data_next} = {data_reg, 1'b0};
                        
                        if (bit_count_reg > 0) begin
                            bit_count_next = bit_count_reg-1;
                            state_next = STATE_READ_1;
                        end else begin
                            state_next = STATE_READ_2;
                        end
                    end
                end else begin
                    state_next = STATE_READ_1;
                end
            end
            STATE_READ_2: begin

                if (scl_negedge) begin

                    sda_o_next = 1'b1;
                    state_next = STATE_READ_3;
                end else begin
                    state_next = STATE_READ_2;
                end
            end
            STATE_READ_3: begin

                if (scl_posedge) begin
                    if (sda_i_reg) begin

                        state_next = STATE_IDLE;
                    end else begin

                        bit_count_next = 4'd7;
                        s_axis_data_tready_next = 1'b1;
                        data_valid_next = 1'b0;
                        state_next = STATE_READ_1;
                    end
                end else begin
                    state_next = STATE_READ_3;
                end
            end
        endcase
    end
end

always @(posedge clk) begin
    state_reg <= state_next;

    addr_reg <= addr_next;
    data_reg <= data_next;
    data_valid_reg <= data_valid_next;
    data_out_reg_valid_reg <= data_out_reg_valid_next;
    last_reg <= last_next;

    mode_read_reg <= mode_read_next;

    bit_count_reg <= bit_count_next;

    s_axis_data_tready_reg <= s_axis_data_tready_next;

    m_axis_data_tdata_reg <= m_axis_data_tdata_next;
    m_axis_data_tvalid_reg <= m_axis_data_tvalid_next;
    m_axis_data_tlast_reg <= m_axis_data_tlast_next;

    scl_i_filter <= (scl_i_filter << 1) | scl_i;
    sda_i_filter <= (sda_i_filter << 1) | sda_i;

    if (scl_i_filter == {FILTER_LEN{1'b1}}) begin
        scl_i_reg <= 1'b1;
    end else if (scl_i_filter == {FILTER_LEN{1'b0}}) begin
        scl_i_reg <= 1'b0;
    end

    if (sda_i_filter == {FILTER_LEN{1'b1}}) begin
        sda_i_reg <= 1'b1;
    end else if (sda_i_filter == {FILTER_LEN{1'b0}}) begin
        sda_i_reg <= 1'b0;
    end

    scl_o_reg <= scl_o_next;
    sda_o_reg <= sda_o_next;

    last_scl_i_reg <= scl_i_reg;
    last_sda_i_reg <= sda_i_reg;

    busy_reg <= !(state_reg == STATE_IDLE);

    if (start_bit) begin
        bus_active_reg <= 1'b1;
    end else if (stop_bit) begin
        bus_active_reg <= 1'b0;
    end else begin
        bus_active_reg <= bus_active_reg;
    end

    bus_addressed_reg <= bus_addressed_next;

    if (rst) begin
        state_reg <= STATE_IDLE;
        s_axis_data_tready_reg <= 1'b0;
        m_axis_data_tvalid_reg <= 1'b0;
        scl_o_reg <= 1'b1;
        sda_o_reg <= 1'b1;
        busy_reg <= 1'b0;
        bus_active_reg <= 1'b0;
        bus_addressed_reg <= 1'b0;
    end
end

endmodule
module i2c_slave #(
    parameter FILTER_LEN = 4
)
(
    input wire         clk,
    input wire         rst,


    input  wire        release_bus,

    input  wire [7:0]  s_axis_data_tdata,
    input  wire        s_axis_data_tvalid,
    output wire        s_axis_data_tready,
    input  wire        s_axis_data_tlast,

    output wire [7:0]  m_axis_data_tdata,
    output wire        m_axis_data_tvalid,
    input  wire        m_axis_data_tready,
    output wire        m_axis_data_tlast,


    input  wire        scl_i,
    output wire        scl_o,
    output wire        scl_t,
    input  wire        sda_i,
    output wire        sda_o,
    output wire        sda_t,


    output wire        busy,
    output wire [6:0]  bus_address,
    output wire        bus_addressed,
    output wire        bus_active,


    input  wire        enable,
    input  wire [6:0]  device_address,
    input  wire [6:0]  device_address_mask
);



localparam [4:0]
    STATE_IDLE = 4'd0,
    STATE_ADDRESS = 4'd1,
    STATE_ACK = 4'd2,
    STATE_WRITE_1 = 4'd3,
    STATE_WRITE_2 = 4'd4,
    STATE_READ_1 = 4'd5,
    STATE_READ_2 = 4'd6,
    STATE_READ_3 = 4'd7;

reg [4:0] state_reg = STATE_IDLE, state_next;

reg [6:0] addr_reg = 7'd0, addr_next;
reg [7:0] data_reg = 8'd0, data_next;
reg data_valid_reg = 1'b0, data_valid_next;
reg data_out_reg_valid_reg = 1'b0, data_out_reg_valid_next;
reg last_reg = 1'b0, last_next;

reg mode_read_reg = 1'b0, mode_read_next;

reg [3:0] bit_count_reg = 4'd0, bit_count_next;

reg s_axis_data_tready_reg = 1'b0, s_axis_data_tready_next;

reg [7:0] m_axis_data_tdata_reg = 8'd0, m_axis_data_tdata_next;
reg m_axis_data_tvalid_reg = 1'b0, m_axis_data_tvalid_next;
reg m_axis_data_tlast_reg = 1'b0, m_axis_data_tlast_next;

reg [FILTER_LEN-1:0] scl_i_filter = {FILTER_LEN{1'b1}};
reg [FILTER_LEN-1:0] sda_i_filter = {FILTER_LEN{1'b1}};

reg scl_i_reg = 1'b1;
reg sda_i_reg = 1'b1;

reg scl_o_reg = 1'b1, scl_o_next;
reg sda_o_reg = 1'b1, sda_o_next;

reg last_scl_i_reg = 1'b1;
reg last_sda_i_reg = 1'b1;

reg busy_reg = 1'b0;
reg bus_active_reg = 1'b0;
reg bus_addressed_reg = 1'b0, bus_addressed_next;

assign bus_address = addr_reg;

assign s_axis_data_tready = s_axis_data_tready_reg;

assign m_axis_data_tdata = m_axis_data_tdata_reg;
assign m_axis_data_tvalid = m_axis_data_tvalid_reg;
assign m_axis_data_tlast = m_axis_data_tlast_reg;

assign scl_o = scl_o_reg;
assign scl_t = scl_o_reg;
assign sda_o = sda_o_reg;
assign sda_t = sda_o_reg;

assign busy = busy_reg;
assign bus_active = bus_active_reg;
assign bus_addressed = bus_addressed_reg;

assign scl_posedge = scl_i_reg && !last_scl_i_reg;
assign scl_negedge = !scl_i_reg && last_scl_i_reg;
assign sda_posedge = sda_i_reg && !last_sda_i_reg;
assign sda_negedge = !sda_i_reg && last_sda_i_reg;

assign start_bit = sda_negedge && scl_i_reg;
assign stop_bit = sda_posedge && scl_i_reg;

always @* begin
    state_next = STATE_IDLE;

    addr_next = addr_reg;
    data_next = data_reg;
    data_valid_next = data_valid_reg;
    data_out_reg_valid_next = data_out_reg_valid_reg;
    last_next = last_reg;

    mode_read_next = mode_read_reg;

    bit_count_next = bit_count_reg;

    s_axis_data_tready_next = 1'b0;

    m_axis_data_tdata_next = m_axis_data_tdata_reg;
    m_axis_data_tvalid_next = m_axis_data_tvalid_reg && !m_axis_data_tready;
    m_axis_data_tlast_next = m_axis_data_tlast_reg;

    scl_o_next = scl_o_reg;
    sda_o_next = sda_o_reg;

    bus_addressed_next = bus_addressed_reg;

    if (start_bit) begin

        data_valid_next = 1'b0;
        data_out_reg_valid_next = 1'b0;
        bit_count_next = 4'd7;
        m_axis_data_tlast_next = 1'b1;
        m_axis_data_tvalid_next = data_out_reg_valid_reg;
        bus_addressed_next = 1'b0;
        state_next = STATE_ADDRESS;
    end else if (release_bus || stop_bit) begin

        data_valid_next = 1'b0;
        data_out_reg_valid_next = 1'b0;
        m_axis_data_tlast_next = 1'b1;
        m_axis_data_tvalid_next = data_out_reg_valid_reg;
        bus_addressed_next = 1'b0;
        state_next = STATE_IDLE;
    end else begin
        case (state_reg)
            STATE_IDLE: begin

                data_valid_next = 1'b0;
                data_out_reg_valid_next = 1'b0;
                bus_addressed_next = 1'b0;
                state_next = STATE_IDLE;
            end
            STATE_ADDRESS: begin

                if (scl_posedge) begin
                    if (bit_count_reg > 0) begin

                        bit_count_next = bit_count_reg-1;
                        data_next = {data_reg[6:0], sda_i_reg};
                        state_next = STATE_ADDRESS;
                    end else begin

                        if (enable && (device_address & device_address_mask) == (data_reg[6:0] & device_address_mask)) begin

                            addr_next = data_reg[6:0];
                            mode_read_next = sda_i_reg;
                            bus_addressed_next = 1'b1;
                            state_next = STATE_ACK;
                        end else begin

                            state_next = STATE_IDLE;
                        end
                    end
                end else begin
                    state_next = STATE_ADDRESS;
                end
            end
            STATE_ACK: begin

                if (scl_negedge) begin
                    sda_o_next = 1'b0;
                    bit_count_next = 4'd7;
                    if (mode_read_reg) begin

                        s_axis_data_tready_next = 1'b1;
                        data_valid_next = 1'b0;
                        state_next = STATE_READ_1;
                    end else begin

                        state_next = STATE_WRITE_1;
                    end
                end else begin
                    state_next = STATE_ACK;
                end
            end
            STATE_WRITE_1: begin

                if (scl_negedge || !scl_o_reg) begin
                    sda_o_next = 1'b1;
                    if (m_axis_data_tvalid && !m_axis_data_tready) begin

                        scl_o_next = 1'b0;
                        state_next = STATE_WRITE_1;
                    end else begin
                        scl_o_next = 1'b1;
                        if (data_valid_reg) begin

                            m_axis_data_tdata_next = data_reg;
                            m_axis_data_tlast_next = 1'b0;
                        end
                        data_valid_next = 1'b0;
                        data_out_reg_valid_next = data_valid_reg;
                        state_next = STATE_WRITE_2;
                    end
                end else begin
                    state_next = STATE_WRITE_1;
                end
            end
            STATE_WRITE_2: begin

                if (scl_posedge) begin

                    data_next = {data_reg[6:0], sda_i_reg};
                    if (bit_count_reg > 0) begin
                        bit_count_next = bit_count_reg-1;
                        state_next = STATE_WRITE_2;
                    end else begin

                        m_axis_data_tvalid_next = data_out_reg_valid_reg;
                        data_out_reg_valid_next = 1'b0;
                        data_valid_next = 1'b1;
                        state_next = STATE_ACK;
                    end
                end else begin
                    state_next = STATE_WRITE_2;
                end
            end
            STATE_READ_1: begin

                if (s_axis_data_tready && s_axis_data_tvalid) begin

                    s_axis_data_tready_next = 1'b0;
                    data_next = s_axis_data_tdata;
                    data_valid_next = 1'b1;
                end else begin

                    s_axis_data_tready_next = !data_valid_reg;
                end

                if (scl_negedge || !scl_o_reg) begin

                    if (!data_valid_reg) begin

                        scl_o_next = 1'b0;
                        state_next = STATE_READ_1;
                    end else begin
                        scl_o_next = 1'b1;
                        {sda_o_next, data_next} = {data_reg, 1'b0};
                        
                        if (bit_count_reg > 0) begin
                            bit_count_next = bit_count_reg-1;
                            state_next = STATE_READ_1;
                        end else begin
                            state_next = STATE_READ_2;
                        end
                    end
                end else begin
                    state_next = STATE_READ_1;
                end
            end
            STATE_READ_2: begin

                if (scl_negedge) begin

                    sda_o_next = 1'b1;
                    state_next = STATE_READ_3;
                end else begin
                    state_next = STATE_READ_2;
                end
            end
            STATE_READ_3: begin

                if (scl_posedge) begin
                    if (sda_i_reg) begin

                        state_next = STATE_IDLE;
                    end else begin

                        bit_count_next = 4'd7;
                        s_axis_data_tready_next = 1'b1;
                        data_valid_next = 1'b0;
                        state_next = STATE_READ_1;
                    end
                end else begin
                    state_next = STATE_READ_3;
                end
            end
        endcase
    end
end

always @(posedge clk) begin
    state_reg <= state_next;

    addr_reg <= addr_next;
    data_reg <= data_next;
    data_valid_reg <= data_valid_next;
    data_out_reg_valid_reg <= data_out_reg_valid_next;
    last_reg <= last_next;

    mode_read_reg <= mode_read_next;

    bit_count_reg <= bit_count_next;

    s_axis_data_tready_reg <= s_axis_data_tready_next;

    m_axis_data_tdata_reg <= m_axis_data_tdata_next;
    m_axis_data_tvalid_reg <= m_axis_data_tvalid_next;
    m_axis_data_tlast_reg <= m_axis_data_tlast_next;

    scl_i_filter <= (scl_i_filter << 1) | scl_i;
    sda_i_filter <= (sda_i_filter << 1) | sda_i;

    if (scl_i_filter == {FILTER_LEN{1'b1}}) begin
        scl_i_reg <= 1'b1;
    end else if (scl_i_filter == {FILTER_LEN{1'b0}}) begin
        scl_i_reg <= 1'b0;
    end

    if (sda_i_filter == {FILTER_LEN{1'b1}}) begin
        sda_i_reg <= 1'b1;
    end else if (sda_i_filter == {FILTER_LEN{1'b0}}) begin
        sda_i_reg <= 1'b0;
    end

    scl_o_reg <= scl_o_next;
    sda_o_reg <= sda_o_next;

    last_scl_i_reg <= scl_i_reg;
    last_sda_i_reg <= sda_i_reg;

    busy_reg <= !(state_reg == STATE_IDLE);

    if (start_bit) begin
        bus_active_reg <= 1'b1;
    end else if (stop_bit) begin
        bus_active_reg <= 1'b0;
    end else begin
        bus_active_reg <= bus_active_reg;
    end

    bus_addressed_reg <= bus_addressed_next;

    if (rst) begin
        state_reg <= STATE_IDLE;
        s_axis_data_tready_reg <= 1'b0;
        m_axis_data_tvalid_reg <= 1'b0;
        scl_o_reg <= 1'b1;
        sda_o_reg <= 1'b1;
        busy_reg <= 1'b0;
        bus_active_reg <= 1'b0;
        bus_addressed_reg <= 1'b0;
    end
end

endmodule