module top_module(
	input clk,
	input reset,
	input data,
    output reg shift_ena,
    output reg counting,
    input done_counting,
    output reg done,
    input ack );

    typedef enum reg [2:0] {
        IDLE,
        PATTERN,
        SHIFT,
        COUNT,
        DONE
    } state_t;

    state_t state, next_state;
    reg [3:0] shift_counter;

    always @(posedge clk or posedge reset) begin
        if (reset) begin
            state <= IDLE;
            shift_ena <= 0;
            counting <= 0;
            done <= 0;
            shift_counter <= 0;
        end else begin
            state <= next_state;
            if (state == SHIFT) begin
                if (shift_counter < 4) begin
                    shift_counter <= shift_counter + 1;
                end else begin
                    shift_counter <= 0;
                end
            end else begin
                shift_counter <= 0;
            end
        end
    end

    always @(*) begin
        next_state = state;
        shift_ena = 0;
        counting = 0;
        done = 0;

        case(state)
            IDLE: begin
                if (data == 1'b1) begin
                    next_state = PATTERN;
                end
            end
            PATTERN: begin
                if (data == 1'b1) begin
                    next_state = PATTERN;
                end else if (data == 1'b0) begin
                    next_state = SHIFT;
                    shift_ena = 1;
                end
            end
            SHIFT: begin
                if (shift_counter < 4) begin
                    next_state = SHIFT;
                    shift_ena = 1;
                end else begin
                    next_state = COUNT;
                    counting = 1;
                end
            end
            COUNT: begin
                if (done_counting) begin
                    next_state = DONE;
                    done = 1;
                end else begin
                    next_state = COUNT;
                end
            end
            DONE: begin
                if (ack) begin
                    next_state = IDLE;
                end else begin
                    next_state = DONE;
                end
            end
        endcase
    end

endmodule

module top_module(
    input clk,
    input reset,
    input data,
    output reg shift_ena,
    output reg counting,
    input done_counting,
    output reg done,
    input ack
);

    typedef enum reg [2:0] {
        IDLE,
        WAIT_PATTERN,
        SHIFT,
        COUNT,
        DONE
    } state_t;

    state_t current_state, next_state;
    reg [3:0] bit_count;

    always @(posedge clk or posedge reset) begin
        if (reset) begin
            current_state <= IDLE;
            shift_ena <= 0;
            counting <= 0;
            done <= 0;
            bit_count <= 0;
        end else begin
            current_state <= next_state;
        end
    end

    always @(*) begin
        next_state = current_state;
        shift_ena = 0;
        counting = 0;
        done = 0;

        case (current_state)
            IDLE: begin
                if (data == 1'b1) begin
                    next_state = WAIT_PATTERN;
                end
            end

            WAIT_PATTERN: begin
                if (data == 3'b110) begin
                    if (bit_count == 3) begin
                        next_state = SHIFT;
                        bit_count = 0;
                    end else begin
                        bit_count = bit_count + 1;
                    end
                end else begin
                    next_state = IDLE;
                end
            end

            SHIFT: begin
                shift_ena = 1;
                if (bit_count < 4) begin
                    bit_count = bit_count + 1;
                end else begin
                    next_state = COUNT;
                    bit_count = 0;
                end
            end

            COUNT: begin
                counting = 1;
                if (done_counting) begin
                    next_state = DONE;
                end
            end

            DONE: begin
                done = 1;
                if (ack) begin
                    next_state = IDLE;
                end
            end
        endcase
    end

endmodule

module top_module(
    input clk,
    input reset,
    input data,
    output reg shift_ena,
    output reg counting,
    input done_counting,
    output reg done,
    input ack );

    typedef enum reg [2:0] {
        IDLE,
        PATTERN_DETECTED,
        SHIFT,
        COUNTING,
        DONE
    } state_t;

    state_t current_state, next_state;

    // Pattern to detect: 1101
    reg [3:0] pattern;
    reg [3:0] counter;

    always @(posedge clk or posedge reset) begin
        if (reset) begin
            current_state <= IDLE;
            shift_ena <= 0;
            counting <= 0;
            done <= 0;
            pattern <= 0;
        end else begin
            current_state <= next_state;
        end
    end

    always @(posedge clk) begin
        case (current_state)
            IDLE: begin
                if (data) begin
                    pattern <= {pattern[2:0], data};
                    if (pattern == 4'b1101) begin
                        next_state <= PATTERN_DETECTED;
                    end
                end
            end

            PATTERN_DETECTED: begin
                shift_ena <= 1;
                next_state <= SHIFT;
                pattern <= 0; // Reset pattern
            end

            SHIFT: begin
                if (counter < 4) begin
                    counter <= counter + 1;
                end else begin
                    shift_ena <= 0;
                    counting <= 1;
                    next_state <= COUNTING;
                    counter <= 0; // Reset counter
                end
            end

            COUNTING: begin
                if (done_counting) begin
                    done <= 1;
                    counting <= 0;
                    next_state <= DONE;
                end
            end

            DONE: begin
                if (ack) begin
                    done <= 0;
                    next_state <= IDLE;
                end
            end

            default: next_state <= IDLE; // Fallback state
        endcase
    end

endmodule

module top_module(
    input clk,
    input reset,
    input data,
    output reg shift_ena,
    output reg counting,
    input done_counting,
    output reg done,
    input ack );

    typedef enum reg [2:0] {
        IDLE,
        DETECT_1,
        DETECT_11,
        DETECT_110,
        DETECT_1101,
        SHIFT,
        COUNT,
        DONE
    } state_t;

    state_t state, next_state;

    always @(posedge clk or posedge reset) begin
        if (reset)
            state <= IDLE;
        else
            state <= next_state;
    end

    always @(*) begin
        next_state = state;
        shift_ena = 0;
        counting = 0;
        done = 0;

        case (state)
            IDLE: begin
                if (data)
                    next_state = DETECT_1;
            end

            DETECT_1: begin
                if (data)
                    next_state = DETECT_11;
                else
                    next_state = IDLE;
            end

            DETECT_11: begin
                if (data)
                    next_state = DETECT_110;
                else
                    next_state = IDLE;
            end

            DETECT_110: begin
                if (data)
                    next_state = DETECT_1101;
                else
                    next_state = IDLE;
            end

            DETECT_1101: begin
                shift_ena = 1;
                next_state = SHIFT;
            end

            SHIFT: begin
                if (shift_ena) begin
                    // Shift 4 bits (assume this is handled externally)
                    // After 4 cycles, move to COUNT
                    next_state = COUNT; // (Implement shift count logic externally)
                end
            end

            COUNT: begin
                counting = 1;
                if (done_counting)
                    next_state = DONE;
            end

            DONE: begin
                done = 1;
                if (ack)
                    next_state = IDLE;
            end

        endcase
    end
endmodule

module top_module(
    input clk,
    input reset,
    input data,
    output reg shift_ena,
    output reg counting,
    input done_counting,
    output reg done,
    input ack );

    // State encoding
    typedef enum reg [2:0] {
        SEARCHING = 3'b000,
        SHIFTING = 3'b001,
        COUNTING = 3'b010,
        DONE = 3'b011
    } state_t;

    state_t current_state, next_state;
    reg [3:0] shift_count;

    always @(posedge clk or posedge reset) begin
        if (reset) begin
            current_state <= SEARCHING;
            shift_ena <= 0;
            counting <= 0;
            done <= 0;
            shift_count <= 0;
        end else begin
            current_state <= next_state;
        end
    end

    always @(current_state or data or done_counting or ack) begin
        case (current_state)
            SEARCHING: begin
                shift_ena <= 0;
                counting <= 0;
                done <= 0;
                if (data == 1) begin
                    // Check for pattern "1101"
                    if (/* Detecting pattern logic here */) begin
                        next_state = SHIFTING;
                        shift_count = 0;
                    end else begin
                        next_state = SEARCHING;
                    end
                end else begin
                    next_state = SEARCHING;
                end
            end

            SHIFTING: begin
                shift_ena <= 1;
                if (shift_count < 4) begin
                    shift_count <= shift_count + 1;
                    next_state = SHIFTING;
                end else begin
                    shift_ena <= 0;
                    next_state = COUNTING;
                end
            end

            COUNTING: begin
                counting <= 1;
                if (done_counting) begin
                    counting <= 0;
                    done <= 1;
                    next_state = DONE;
                end else begin
                    next_state = COUNTING;
                end
            end

            DONE: begin
                if (ack) begin
                    done <= 0;
                    next_state = SEARCHING;
                end else begin
                    next_state = DONE;
                end
            end

            default: next_state = SEARCHING;
        endcase
    end
endmodule

module top_module(
    input clk,
    input reset,
    input data,
    output reg shift_ena,
    output reg counting,
    input done_counting,
    output reg done,
    input ack );

    typedef enum reg [2:0] {
        S_IDLE,
        S_PATTERN,
        S_SHIFT,
        S_COUNT,
        S_DONE
    } state_t;

    state_t current_state, next_state;
    reg [3:0] shift_count;

    always @(posedge clk) begin
        if (reset) begin
            current_state <= S_IDLE;
            shift_ena <= 0;
            counting <= 0;
            done <= 0;
            shift_count <= 0;
        end else begin
            current_state <= next_state;
        end
    end

    always @(current_state or data or done_counting or ack) begin
        case (current_state)
            S_IDLE: begin
                shift_ena = 0;
                counting = 0;
                done = 0;
                if (data == 1'b1) begin
                    next_state = S_PATTERN;
                end else begin
                    next_state = S_IDLE;
                end
            end

            S_PATTERN: begin
                if (data == 1'b1) begin
                    next_state = S_PATTERN;
                end else if (data == 1'b0) begin
                    next_state = S_COUNT; // Assume receiving pattern is valid
                end
            end

            S_SHIFT: begin
                if (shift_count < 4) begin
                    shift_ena = 1;
                    shift_count = shift_count + 1;
                    next_state = S_SHIFT;
                end else begin
                    shift_ena = 0;
                    next_state = S_COUNT;
                    shift_count = 0;
                end
            end

            S_COUNT: begin
                counting = 1;
                if (done_counting) begin
                    counting = 0;
                    done = 1;
                    next_state = S_DONE;
                end else begin
                    next_state = S_COUNT;
                end
            end

            S_DONE: begin
                if (ack) begin
                    done = 0;
                    next_state = S_IDLE;
                end else begin
                    next_state = S_DONE;
                end
            end

            default: next_state = S_IDLE;
        endcase
    end
endmodule

module top_module(
    input clk,
    input reset,
    input data,
    output reg shift_ena,
    output reg counting,
    input done_counting,
    output reg done,
    input ack
);

    typedef enum reg [2:0] {
        IDLE,
        WAIT_FOR_PATTERN,
        SHIFT_ENABLE,
        COUNTING,
        NOTIFY,
        WAIT_FOR_ACK
    } state_t;

    state_t state, next_state;

    always @(posedge clk or posedge reset) begin
        if (reset)
            state <= IDLE;
        else
            state <= next_state;
    end

    always @(*) begin
        case (state)
            IDLE: begin
                shift_ena = 1'b0;
                counting = 1'b0;
                done = 1'b0;
                if (data == 1'b1)
                    next_state = WAIT_FOR_PATTERN;
                else
                    next_state = IDLE;
            end

            WAIT_FOR_PATTERN: begin
                shift_ena = 1'b0;
                counting = 1'b0;
                done = 1'b0;
                if (data == 1'b0)
                    next_state = IDLE;
                else
                    next_state = WAIT_FOR_PATTERN;
            end

            SHIFT_ENABLE: begin
                shift_ena = 1'b1;
                counting = 1'b0;
                done = 1'b0;
                next_state = COUNTING;
            end

            COUNTING: begin
                shift_ena = 1'b0;
                counting = 1'b1;
                done = 1'b0;
                if (done_counting)
                    next_state = NOTIFY;
                else
                    next_state = COUNTING;
            end

            NOTIFY: begin
                shift_ena = 1'b0;
                counting = 1'b0;
                done = 1'b1;
                if (ack)
                    next_state = IDLE;
                else
                    next_state = NOTIFY;
            end

            default: begin
                shift_ena = 1'b0;
                counting = 1'b0;
                done = 1'b0;
                next_state = IDLE;
            end
        endcase
    end
endmodule

module top_module(
	input clk,
	input reset,
	input data,
    output reg shift_ena,
    output reg counting,
    input done_counting,
    output reg done,
    input ack );

    typedef enum reg [2:0] {SEARCH, SHIFT, COUNT, NOTIFY} state_t;
    state_t current_state, next_state;

    always @(posedge clk or posedge reset) begin
        if (reset)
            current_state <= SEARCH;
        else
            current_state <= next_state;
    end

    always @(*) begin
        next_state = current_state; // default to current state
        shift_ena = 0;
        counting = 0;
        done = 0;

        case (current_state)
            SEARCH: begin
                if (data) begin // Assuming data is sampled continuously
                    next_state = (current_state == SEARCH) ? SHIFT : SEARCH;
                end
            end

            SHIFT: begin
                shift_ena = 1;
                if (shift_ena) // after 4 cycles of shift_ena
                    next_state = COUNT;
            end

            COUNT: begin
                counting = 1;
                if (done_counting)
                    next_state = NOTIFY;
            end

            NOTIFY: begin
                done = 1;
                if (ack)
                    next_state = SEARCH;
            end
        endcase
    end

endmodule

module top_module(
    input clk,
    input reset,
    input data,
    output reg shift_ena,
    output reg counting,
    input done_counting,
    output reg done,
    input ack
);

    typedef enum reg [2:0] {
        IDLE,
        WAIT_PATTERN,
        SHIFT_ENABLE,
        COUNTING,
        DONE
    } state_t;

    state_t current_state, next_state;
    reg [3:0] shift_count;

    always @(posedge clk or posedge reset) begin
        if (reset) begin
            current_state <= IDLE;
            shift_ena <= 0;
            counting <= 0;
            done <= 0;
            shift_count <= 0;
        end else begin
            current_state <= next_state;
        end
    end

    always @(*) begin
        next_state = current_state;
        shift_ena = 0;
        counting = 0;
        done = 0;

        case (current_state)
            IDLE: begin
                if (data == 1) begin
                    next_state = WAIT_PATTERN;
                end
            end

            WAIT_PATTERN: begin
                if (data == 1) begin
                    if (shift_count == 3) begin
                        next_state = SHIFT_ENABLE;
                        shift_count = 0;
                    end else begin
                        shift_count = shift_count + 1;
                    end
                end else begin
                    next_state = IDLE;
                    shift_count = 0;
                end
            end

            SHIFT_ENABLE: begin
                shift_ena = 1;
                if (shift_count < 3) begin
                    shift_count = shift_count + 1;
                    next_state = SHIFT_ENABLE;
                end else begin
                    next_state = COUNTING;
                    shift_count = 0;
                end
            end

            COUNTING: begin
                counting = 1;
                if (done_counting) begin
                    next_state = DONE;
                end
            end

            DONE: begin
                done = 1;
                if (ack) begin
                    next_state = IDLE;
                end
            end
        endcase
    end
endmodule

module top_module(
    input clk,
    input reset,
    input data,
    output reg shift_ena,
    output reg counting,
    input done_counting,
    output reg done,
    input ack );

    reg [2:0] state, next_state;
    parameter IDLE = 3'b000,
              DETECT = 3'b001,
              SHIFT = 3'b010,
              COUNT = 3'b011,
              DONE = 3'b100;

    always @(posedge clk or posedge reset) begin
        if (reset) begin
            state <= IDLE;
        end else begin
            state <= next_state;
        end
    end

    always @(*) begin
        next_state = state;
        shift_ena = 0;
        counting = 0;
        done = 0;

        case (state)
            IDLE: begin
                if ({data, 1'b0} == 3'b101) // Shifted data for pattern detection
                    next_state = DETECT;
            end
            DETECT: begin
                if ({data, 1'b0} == 3'b011) // Complete pattern detected (1101)
                    next_state = SHIFT;
            end
            SHIFT: begin
                shift_ena = 1;
                if (shift_ena) begin
                    next_state = COUNT; // Move to counting after 4 cycles
                end
            end
            COUNT: begin
                counting = 1;
                if (done_counting)
                    next_state = DONE;
            end
            DONE: begin
                done = 1;
                if (ack)
                    next_state = IDLE;
            end
        endcase
    end
endmodule

module top_module(
    input clk,
    input reset,
    input data,
    output reg shift_ena,
    output reg counting,
    input done_counting,
    output reg done,
    input ack
);

    // State encoding
    typedef enum reg [2:0] {
        IDLE,
        DETECT,
        SHIFT,
        COUNT,
        DONE
    } state_t;

    state_t current_state, next_state;

    // Counter for shift enabling
    reg [1:0] shift_count;

    // State transition
    always @(posedge clk or posedge reset) begin
        if (reset) begin
            current_state <= IDLE;
            shift_ena <= 0;
            counting <= 0;
            done <= 0;
            shift_count <= 0;
        end else begin
            current_state <= next_state;
        end
    end

    // Next state logic
    always @(*) begin
        next_state = current_state;
        shift_ena = 0;
        counting = 0;
        done = 0;

        case (current_state)
            IDLE: begin
                if (data == 1'b1) begin
                    // Check for the sequence 1101
                    next_state = DETECT;
                end
            end

            DETECT: begin
                if (data == 1'b1) begin
                    next_state = SHIFT;
                    shift_count = 0;
                    shift_ena = 1;
                end else begin
                    next_state = IDLE;
                end
            end

            SHIFT: begin
                if (shift_count < 3) begin
                    shift_count = shift_count + 1;
                    shift_ena = 1;
                end else begin
                    next_state = COUNT;
                    counting = 1;
                end
            end

            COUNT: begin
                if (done_counting) begin
                    next_state = DONE;
                    done = 1;
                end
            end

            DONE: begin
                if (ack) begin
                    next_state = IDLE;
                end
            end
        endcase
    end
endmodule

module top_module(
    input clk,
    input reset,
    input data,
    output reg shift_ena,
    output reg counting,
    input done_counting,
    output reg done,
    input ack
);

    typedef enum reg [2:0] {
        S_IDLE,
        S_PATTERN_DETECT,
        S_SHIFT,
        S_COUNT,
        S_NOTIFY
    } state_t;

    state_t current_state, next_state;

    reg [3:0] bit_count;

    // Sequential block for state transition
    always @(posedge clk or posedge reset) begin
        if (reset)
            current_state <= S_IDLE;
        else
            current_state <= next_state;
    end

    // Combinational block for next state logic and output signals
    always @(*) begin
        next_state = current_state;
        shift_ena = 0;
        counting = 0;
        done = 0;

        case (current_state)
            S_IDLE: begin
                if (data == 1) begin
                    next_state = S_PATTERN_DETECT;
                end
            end

            S_PATTERN_DETECT: begin
                if (data == 1) begin // first bit of pattern
                    next_state = S_PATTERN_DETECT;
                end else if (data == 0) begin
                    next_state = S_PATTERN_DETECT;
                end else if (data == 1) begin // second bit of pattern
                    next_state = S_SHIFT;
                end
            end

            S_SHIFT: begin
                shift_ena = 1;
                if (bit_count < 4) begin
                    bit_count = bit_count + 1;
                    next_state = S_SHIFT;
                end else begin
                    next_state = S_COUNT;
                    bit_count = 0;
                end
            end

            S_COUNT: begin
                counting = 1;
                if (done_counting) begin
                    next_state = S_NOTIFY;
                end
            end

            S_NOTIFY: begin
                done = 1;
                if (ack) begin
                    next_state = S_IDLE;
                end
            end
        endcase
    end

endmodule

module top_module(
    input clk,
    input reset,
    input data,
    output reg shift_ena,
    output reg counting,
    input done_counting,
    output reg done,
    input ack );

    typedef enum reg [2:0] {
        IDLE,
        WAIT_PATTERN,
        SHIFT_ENABLE,
        COUNTING,
        DONE
    } state_t;

    state_t state, next_state;

    always @(*) begin
        next_state = state;
        shift_ena = 0;
        counting = 0;
        done = 0;

        case (state)
            IDLE: begin
                if (data)
                    next_state = WAIT_PATTERN;
            end
            WAIT_PATTERN: begin
                if (data) begin
                    // Check for the pattern 1101
                    if (pattern_detected)
                        next_state = SHIFT_ENABLE;
                end
            end
            SHIFT_ENABLE: begin
                shift_ena = 1;
                if (shift_counter == 4) // Assumes a counter tracks 4 cycles
                    next_state = COUNTING;
            end
            COUNTING: begin
                counting = 1;
                if (done_counting)
                    next_state = DONE;
            end
            DONE: begin
                done = 1;
                if (ack)
                    next_state = IDLE;
            end
            default: next_state = IDLE;
        endcase
    end

    always @(posedge clk or posedge reset) begin
        if (reset)
            state <= IDLE;
        else
            state <= next_state;
    end

    // Assume a method to detect the given pattern
    function pattern_detected;
        // Implementation to detect the pattern
    endfunction

endmodule

module top_module(
    input clk,
    input reset,
    input data,
    output reg shift_ena,
    output reg counting,
    input done_counting,
    output reg done,
    input ack );

    typedef enum reg [2:0] {
        IDLE,
        SEARCH,
        SHIFT,
        COUNT,
        DONE
    } state_t;

    state_t current_state, next_state;
    reg [3:0] shift_counter;

    always @(posedge clk or posedge reset) begin
        if (reset) begin
            current_state <= IDLE;
            shift_ena <= 0;
            counting <= 0;
            done <= 0;
            shift_counter <= 0;
        end else begin
            current_state <= next_state;
        end
    end

    always @(*) begin
        next_state = current_state;
        shift_ena = 0;
        counting = 0;
        done = 0;

        case (current_state)
            IDLE: begin
                if (data) begin
                    if (data && shift_counter == 0) begin
                        shift_counter <= 1;
                    end else if (shift_counter == 1) begin
                        shift_counter <= 2;
                    end else if (shift_counter == 2) begin
                        shift_counter <= 3;
                    end else if (shift_counter == 3 && data) begin
                        next_state = SHIFT;
                        shift_counter <= 0;
                    end
                end
            end

            SHIFT: begin
                shift_ena = 1;
                if (shift_counter < 4) begin
                    shift_counter <= shift_counter + 1;
                end else begin
                    next_state = COUNT;
                end
            end

            COUNT: begin
                counting = 1;
                if (done_counting) begin
                    next_state = DONE;
                end
            end

            DONE: begin
                done = 1;
                if (ack) begin
                    next_state = IDLE;
                end
            end

            default: next_state = IDLE;
        endcase
    end
endmodule

module top_module(
    input clk,
    input reset,
    input data,
    output reg shift_ena,
    output reg counting,
    input done_counting,
    output reg done,
    input ack );

    typedef enum reg [2:0] {
        IDLE,
        DETECT,
        SHIFT,
        COUNT,
        NOTIFY
    } state_t;

    state_t current_state, next_state;
    reg [3:0] shift_count;

    always @(posedge clk or posedge reset) begin
        if (reset) begin
            current_state <= IDLE;
            shift_ena <= 0;
            counting <= 0;
            done <= 0;
            shift_count <= 0;
        end else begin
            current_state <= next_state;
        end
    end

    always @(*) begin
        next_state = current_state;
        shift_ena = 0;
        counting = 0;
        done = 0;
        case (current_state)
            IDLE: begin
                if (data == 1) begin
                    next_state = DETECT;
                end
            end
            DETECT: begin
                if (data == 1) begin
                    next_state = SHIFT;
                    shift_count = 0;
                end else begin
                    next_state = IDLE;
                end
            end
            SHIFT: begin
                shift_ena = 1;
                if (shift_count < 3) begin
                    shift_count = shift_count + 1;
                end else begin
                    next_state = COUNT;
                end
            end
            COUNT: begin
                counting = 1;
                if (done_counting) begin
                    next_state = NOTIFY;
                end
            end
            NOTIFY: begin
                done = 1;
                if (ack) begin
                    next_state = IDLE;
                end
            end
        endcase
    end
endmodule

module top_module(
    input clk,
    input reset,
    input data,
    output reg shift_ena,
    output reg counting,
    input done_counting,
    output reg done,
    input ack
);

    typedef enum reg [2:0] {
        S_SEARCH    = 3'b000,
        S_SHIFT     = 3'b001,
        S_COUNTING  = 3'b010,
        S_NOTIFY    = 3'b011,
        S_WAIT_ACK  = 3'b100
    } state_t;

    state_t state, next_state;
    reg [2:0] shift_count;

    always @(posedge clk or posedge reset) begin
        if (reset) begin
            state <= S_SEARCH;
            shift_ena <= 0;
            counting <= 0;
            done <= 0;
            shift_count <= 3'b000;
        end else begin
            state <= next_state;
        end
    end

    always @(*) begin
        next_state = state;
        shift_ena = 0;
        counting = 0;
        done = 0;

        case (state)
            S_SEARCH: begin
                if (data) begin
                    if (shift_count == 3'b110) begin // pattern detected
                        next_state = S_SHIFT;
                        shift_count = 3'b000;
                    end else begin
                        shift_count = shift_count + 1;
                    end
                end
            end

            S_SHIFT: begin
                shift_ena = 1;
                if (shift_count < 4) begin
                    shift_count = shift_count + 1;
                end else begin
                    next_state = S_COUNTING;
                    shift_count = 0;
                end
            end

            S_COUNTING: begin
                counting = 1;
                if (done_counting) begin
                    next_state = S_NOTIFY;
                end
            end

            S_NOTIFY: begin
                done = 1;
                next_state = S_WAIT_ACK;
            end

            S_WAIT_ACK: begin
                if (ack) begin
                    next_state = S_SEARCH;
                end
            end
        endcase
    end
endmodule

module top_module(
	input clk,
	input reset,
	input data,
    output reg shift_ena,
    output reg counting,
    input done_counting,
    output reg done,
    input ack );

    typedef enum reg [2:0] {IDLE, DETECT, SHIFT, COUNT, NOTIFY} state_t;
    state_t state, next_state;

    always @(posedge clk or posedge reset) begin
        if (reset)
            state <= IDLE;
        else
            state <= next_state;
    end

    always @* begin
        next_state = state;
        shift_ena = 0;
        counting = 0;
        done = 0;

        case (state)
            IDLE: begin
                if (data == 1'b1)
                    next_state = DETECT;
            end

            DETECT: begin
                if (data == 1'b1)
                    next_state = SHIFT;
                else
                    next_state = IDLE;
            end

            SHIFT: begin
                shift_ena = 1;
                next_state = (data == 1'b0) ? COUNT : SHIFT; // Assuming we are shifting in 4 bits
            end

            COUNT: begin
                counting = 1;
                if (done_counting)
                    next_state = NOTIFY;
            end

            NOTIFY: begin
                done = 1;
                if (ack)
                    next_state = IDLE;
            end
        endcase
    end

endmodule

module top_module(
    input clk,
    input reset,
    input data,
    output reg shift_ena,
    output reg counting,
    input done_counting,
    output reg done,
    input ack );

    typedef enum reg [2:0] {
        IDLE,
        DETECT,
        SHIFT,
        COUNT,
        DONE
    } state_t;

    state_t current_state, next_state;
    reg [3:0] shift_counter;

    always @(posedge clk or posedge reset) begin
        if (reset) begin
            current_state <= IDLE;
            shift_ena <= 0;
            counting <= 0;
            done <= 0;
            shift_counter <= 0;
        end else begin
            current_state <= next_state;
        end
    end

    always @(*) begin
        case (current_state)
            IDLE: begin
                shift_ena = 0;
                counting = 0;
                done = 0;
                if (data) begin
                    if (shift_counter == 3) begin
                        next_state = SHIFT;
                        shift_counter = 0;
                    end else begin
                        shift_counter = shift_counter + 1;
                        next_state = DETECT;
                    end
                end else begin
                    next_state = IDLE;
                end
            end
            DETECT: begin
                if (data) begin
                    if (shift_counter == 3) begin
                        next_state = SHIFT;
                        shift_counter = 0;
                    end else begin
                        shift_counter = shift_counter + 1;
                        next_state = DETECT;
                    end
                end else begin
                    shift_counter = 0;
                    next_state = IDLE;
                end
            end
            SHIFT: begin
                shift_ena = 1;
                if (shift_counter < 4) begin
                    shift_counter = shift_counter + 1;
                    next_state = SHIFT;
                end else begin
                    shift_ena = 0;
                    counting = 1;
                    next_state = COUNT;
                end
            end
            COUNT: begin
                counting = 1;
                if (done_counting) begin
                    done = 1;
                    next_state = DONE;
                end else begin
                    next_state = COUNT;
                end
            end
            DONE: begin
                if (ack) begin
                    done = 0;
                    next_state = IDLE;
                end else begin
                    next_state = DONE;
                end
            end
            default: next_state = IDLE;
        endcase
    end
endmodule

module top_module(
    input clk,
    input reset,
    input data,
    output reg shift_ena,
    output reg counting,
    input done_counting,
    output reg done,
    input ack );

    typedef enum logic [2:0] {
        IDLE,
        WAIT_PATTERN,
        SHIFT_ENABLE,
        COUNTING,
        DONE
    } state_t;

    state_t current_state, next_state;

    always_ff @(posedge clk or posedge reset) begin
        if (reset)
            current_state <= IDLE;
        else
            current_state <= next_state;
    end

    always_ff @(posedge clk) begin
        case (current_state)
            IDLE: begin
                shift_ena <= 0;
                counting <= 0;
                done <= 0;
            end
            WAIT_PATTERN: begin
                shift_ena <= 0;
                counting <= 0;
                done <= 0;
            end
            SHIFT_ENABLE: begin
                if (shift_ena) shift_ena <= 0;
                counting <= 0;
                done <= 0;
            end
            COUNTING: begin
                shift_ena <= 0;
                counting <= 1;
                done <= 0;
            end
            DONE: begin
                shift_ena <= 0;
                counting <= 0;
                done <= 1;
            end
        endcase
    end

    always_comb begin
        case (current_state)
            IDLE: begin
                if (data == 1)
                    next_state = WAIT_PATTERN;
                else
                    next_state = IDLE;
            end
            WAIT_PATTERN: begin
                if (data == 0)
                    next_state = SHIFT_ENABLE;
                else
                    next_state = WAIT_PATTERN;
            end
            SHIFT_ENABLE: begin
                shift_ena = 1;
                if ($counting_cycles == 4) // need to implement a cycle counter logic
                    next_state = COUNTING;
                else
                    next_state = SHIFT_ENABLE;
            end
            COUNTING: begin
                if (done_counting)
                    next_state = DONE;
                else
                    next_state = COUNTING;
            end
            DONE: begin
                if (ack)
                    next_state = IDLE;
                else
                    next_state = DONE;
            end
        endcase
    end

endmodule

module top_module(
	input clk,
	input reset,
	input data,
	output reg shift_ena,
	output reg counting,
	input done_counting,
	output reg done,
	input ack );

	typedef enum reg [2:0] {
		SEARCHING,
		DETECT_PATTERN,
		SHIFTS_ENABLE,
		WAIT_COUNTING,
		NOTIFY_DONE
	} state_t;

	state_t state, next_state;
	reg [3:0] shift_counter;

	always @(posedge clk or posedge reset) begin
		if (reset) begin
			state <= SEARCHING;
			shift_ena <= 0;
			counting <= 0;
			done <= 0;
			shift_counter <= 0;
		end else begin
			state <= next_state;
		end
	end

	always @(posedge clk) begin
		if (state == SHIFTS_ENABLE) begin
			if (shift_counter < 4) begin
				shift_counter <= shift_counter + 1;
			end else begin
				shift_counter <= 0;
			end
		end else begin
			shift_counter <= 0;
		end
	end

	always @(*) begin
		next_state = state;
		shift_ena = 0;
		counting = 0;
		done = 0;

		case (state)
			SEARCHING: begin
				if (data == 1) begin
					next_state = DETECT_PATTERN;
				end
			end

			DETECT_PATTERN: begin
				if (data == 1) begin
					next_state = WAIT_COUNTING;
				end else if (data == 0) begin
					next_state = SEARCHING;
				end
			end

			SHIFTS_ENABLE: begin
				shift_ena = 1;
				if (shift_counter == 3) begin
					next_state = WAIT_COUNTING;
				end
			end

			WAIT_COUNTING: begin
				counting = 1;
				if (done_counting) begin
					next_state = NOTIFY_DONE;
				end
			end

			NOTIFY_DONE: begin
				done = 1;
				if (ack) begin
					next_state = SEARCHING;
				end
			end

			default: next_state = SEARCHING;
		endcase
	end
endmodule


module top_module(
    input clk,
    input load,
    input [255:0] data,
    output reg [255:0] q
);
    reg [7:0] count;
    wire [255:0] next_q;

    // Calculate next state based on current state q
    function [2:0] count_neighbors(input [255:0] state, input [3:0] row, input [3:0] col);
        integer i, j;
        begin
            count_neighbors = 0;
            for (i = -1; i <= 1; i = i + 1) begin
                for (j = -1; j <= 1; j = j + 1) begin
                    if ((i != 0 || j != 0)) begin
                        count_neighbors = count_neighbors + state[((row + i + 16) % 16) * 16 + ((col + j + 16) % 16)];
                    end
                end
            end
        end
    endfunction

    // Generate next state of the grid
    generate
        genvar r, c;
        for (r = 0; r < 16; r = r + 1) begin : row
            for (c = 0; c < 16; c = c + 1) begin : col
                always @(*) begin
                    case (count_neighbors(q, r, c))
                        1: next_q[r * 16 + c] = 0; // 0-1 neighbors
                        2: next_q[r * 16 + c] = q[r * 16 + c]; // 2 neighbors
                        3: next_q[r * 16 + c] = 1; // 3 neighbors
                        default: next_q[r * 16 + c] = 0; // 4+ neighbors
                    endcase
                end
            end
        end
    endgenerate

    // Synchronous load and state update
    always @(posedge clk) begin
        if (load) begin
            q <= data;
        end else begin
            q <= next_q;
        end
    end
endmodule

module top_module(
    input clk,
    input load,
    input [255:0] data,
    output reg [255:0] q
);

    reg [255:0] next_q;

    always @(posedge clk) begin
        if (load)
            q <= data;
        else
            q <= next_q;
    end

    always @* begin
        integer i, j, count;
        next_q = q; // Default to the current state

        for (i = 0; i < 16; i = i + 1) begin
            for (j = 0; j < 16; j = j + 1) begin
                count = 0;

                // Check all 8 neighbours
                for (integer di = -1; di <= 1; di = di + 1) begin
                    for (integer dj = -1; dj <= 1; dj = dj + 1) begin
                        if (di == 0 && dj == 0) continue; // Skip the cell itself
                        count = count + q[((i + di + 16) % 16) * 16 + ((j + dj + 16) % 16)];
                    end
                end

                // Apply the rules
                case (count)
                    0, 1, 4: next_q[i * 16 + j] = 0;
                    2: next_q[i * 16 + j] = q[i * 16 + j]; // No change
                    3: next_q[i * 16 + j] = 1;
                    default: next_q[i * 16 + j] = 0;
                endcase
            end
        end
    end
endmodule

module top_module(
    input clk,
    input load,
    input [255:0] data,
    output reg [255:0] q
);
    reg [255:0] next_q;

    always @(posedge clk) begin
        if (load) begin
            q <= data;
        end else begin
            q <= next_q;
        end
    end

    integer i, j, alive_neighbors;

    always @(*) begin
        next_q = q;
        for (i = 0; i < 16; i = i + 1) begin
            for (j = 0; j < 16; j = j + 1) begin
                alive_neighbors = 0;
                // Count alive neighbors
                for (integer di = -1; di <= 1; di = di + 1) begin
                    for (integer dj = -1; dj <= 1; dj = dj + 1) begin
                        if (di == 0 && dj == 0) continue; // Skip the cell itself
                        alive_neighbors = alive_neighbors + q[(i + di + 16) % 16 * 16 + (j + dj + 16) % 16];
                    end
                end

                // Update next state based on rules
                case (q[i * 16 + j])
                    1'b0: begin
                        if (alive_neighbors == 3) next_q[i * 16 + j] = 1'b1;
                    end
                    1'b1: begin
                        if (alive_neighbors < 2 || alive_neighbors > 3) next_q[i * 16 + j] = 1'b0;
                    end
                endcase
            end
        end
    end
endmodule

module top_module(
    input clk,
    input load,
    input [255:0] data,
    output reg [255:0] q
);
    reg [255:0] temp_q;
    integer i, j, count;

    always @(posedge clk) begin
        if (load) begin
            q <= data;
        end else begin
            for (i = 0; i < 16; i = i + 1) begin
                for (j = 0; j < 16; j = j + 1) begin
                    count = 0;
                    // Count neighbors
                    for (integer di = -1; di <= 1; di = di + 1) begin
                        for (integer dj = -1; dj <= 1; dj = dj + 1) begin
                            if (di == 0 && dj == 0) continue; // Skip the cell itself
                            count = count + q[((i + di + 16) % 16) * 16 + ((j + dj + 16) % 16)];
                        end
                    end
                    // Update state based on the count of neighbors
                    if (q[i * 16 + j] == 1) begin
                        if (count < 2 || count > 3)
                            temp_q[i * 16 + j] = 0;
                        else
                            temp_q[i * 16 + j] = 1;
                    end else begin
                        if (count == 3)
                            temp_q[i * 16 + j] = 1;
                        else
                            temp_q[i * 16 + j] = 0;
                    end
                end
            end
            q <= temp_q;
        end
    end
endmodule

module top_module(
    input clk,
    input load,
    input [255:0] data,
    output reg [255:0] q
);
    reg [255:0] next_q;

    always @(posedge clk) begin
        if (load) begin
            q <= data;
        end else begin
            q <= next_q;
        end
    end

    always @* begin
        integer i, j, count;
        next_q = q; // default next state is current state

        for (i = 0; i < 16; i = i + 1) begin
            for (j = 0; j < 16; j = j + 1) begin
                count = 0;
                // Count the alive neighbors
                for (integer x = -1; x <= 1; x = x + 1) begin
                    for (integer y = -1; y <= 1; y = y + 1) begin
                        if ((x != 0 || y != 0)) begin
                            count = count + q[((i + x + 16) % 16) * 16 + ((j + y + 16) % 16)];
                        end
                    end
                end

                // Update the cell state based on neighbor count
                case (count)
                    0, 1, 4: next_q[i * 16 + j] = 0;
                    2: next_q[i * 16 + j] = q[i * 16 + j]; // state remains the same
                    3: next_q[i * 16 + j] = 1;
                endcase
            end
        end
    end
endmodule

module top_module(
    input clk,
    input load,
    input [255:0] data,
    output reg [255:0] q
);

    reg [255:0] temp_q;

    always @(posedge clk) begin
        if (load) begin
            q <= data;
        end else begin
            integer i, j, count;
            reg [1:0] current;
            temp_q = q;
            for (i = 0; i < 16; i = i + 1) begin
                for (j = 0; j < 16; j = j + 1) begin
                    count = 0;
                    // Count neighbours
                    for (integer x = -1; x <= 1; x = x + 1) begin
                        for (integer y = -1; y <= 1; y = y + 1) begin
                            if (x == 0 && y == 0) continue; // Skip self
                            if (temp_q[((i + x + 16) % 16) * 16 + ((j + y + 16) % 16)]) begin
                                count = count + 1;
                            end
                        end
                    end
                    current = temp_q[i * 16 + j];
                    // Update the cell state based on the count of neighbours
                    if (current == 1'b1) begin
                        if (count < 2 || count > 3)
                            q[i * 16 + j] <= 1'b0; // Cell dies
                        else
                            q[i * 16 + j] <= 1'b1; // Cell remains alive
                    end else begin
                        if (count == 3)
                            q[i * 16 + j] <= 1'b1; // Cell becomes alive
                        else
                            q[i * 16 + j] <= 1'b0; // Cell remains dead
                    end
                end
            end
        end
    end
endmodule

module top_module(
    input clk,
    input load,
    input [255:0] data,
    output reg [255:0] q);

    reg [4:0] x, y;
    reg [3:0] neighbor_count;
    reg [255:0] next_q;

    always @(posedge clk) begin
        if (load) begin
            q <= data;
        end else begin
            for (y = 0; y < 16; y = y + 1) begin
                for (x = 0; x < 16; x = x + 1) begin
                    neighbor_count = 0;
                    // Count neighbors
                    for (int dy = -1; dy <= 1; dy = dy + 1) begin
                        for (int dx = -1; dx <= 1; dx = dx + 1) begin
                            if (dx == 0 && dy == 0) continue;
                            neighbor_count = neighbor_count +
                                q[((y + dy + 16) % 16) * 16 + ((x + dx + 16) % 16)];
                        end
                    end

                    // Update the next state according to the rules
                    case (q[y * 16 + x])
                        1'b1: next_q[y * 16 + x] = (neighbor_count == 2) ? 1'b1 : 1'b0;
                        1'b0: next_q[y * 16 + x] = (neighbor_count == 3) ? 1'b1 : 1'b0;
                    endcase
                end
            end
            q <= next_q;
        end
    end
endmodule

module top_module(
	input clk,
	input load,
	input [255:0] data,
	output reg [255:0] q
);

	reg [255:0] next_q;

	// Function to count alive neighbors
	function [3:0] count_neighbors(input [255:0] grid, input [3:0] row, input [3:0] col);
		begin
			integer i, j;
			count_neighbors = 0;
			for (i = -1; i <= 1; i = i + 1) begin
				for (j = -1; j <= 1; j = j + 1) begin
					if (i == 0 && j == 0) continue; // Skip the cell itself
					// Calculate neighbor position with wrapping
					if (grid[(row + i + 16) % 16 * 16 + (col + j + 16) % 16]) begin
						count_neighbors = count_neighbors + 1;
					end
				end
			end
		end
	endfunction

	always @(*) begin
		next_q = q; // Default to current state
		for (int row = 0; row < 16; row = row + 1) begin
			for (int col = 0; col < 16; col = col + 1) begin
				case (count_neighbors(q, row, col))
					0, 1, 4: next_q[row * 16 + col] = 0; // Become dead
					2: next_q[row * 16 + col] = q[row * 16 + col]; // Stay the same
					3: next_q[row * 16 + col] = 1; // Become alive
				endcase
			end
		end
	end

	always @(posedge clk) begin
		if (load)
			q <= data; // Load data into q
		else
			q <= next_q; // Update state
	end

endmodule

module top_module(
	input clk,
	input load,
	input [255:0] data,
	output reg [255:0] q);

	reg [255:0] next_q;
	integer i, j, count;

	always @(posedge clk) begin
		if (load) begin
			q <= data;
		end else begin
			q <= next_q;
		end
	end

	// Compute the next state of the grid
	always @(*) begin
		next_q = q; // default to current state

		for (i = 0; i < 16; i = i + 1) begin
			for (j = 0; j < 16; j = j + 1) begin
				count = 0;

				// Calculate the number of alive neighbors
				for (integer dx = -1; dx <= 1; dx = dx + 1) begin
					for (integer dy = -1; dy <= 1; dy = dy + 1) begin
						if (dx == 0 && dy == 0) continue; // skip the cell itself
						count = count + q[((i + dx + 16) % 16) * 16 + ((j + dy + 16) % 16)];
					end
				end

				// Determine next state based on the neighbor count
				if (q[i * 16 + j] == 1) begin
					if (count < 2 || count > 3)
						next_q[i * 16 + j] = 0; // dies
				end else begin
					if (count == 3)
						next_q[i * 16 + j] = 1; // becomes alive
				end
			end
		end
	end
endmodule

module top_module(
	input clk,
	input load,
	input [255:0] data,
	output reg [255:0] q);

	reg [255:0] next_q;

	always @(posedge clk) begin
		if (load)
			q <= data;
		else
			q <= next_q;
	end

	integer i, j, count;

	always @* begin
		next_q = q; // Default to the current state

		for (i = 0; i < 16; i = i + 1) begin
			for (j = 0; j < 16; j = j + 1) begin
				count = 0;

				// Count alive neighbors
				for (integer di = -1; di <= 1; di = di + 1) begin
					for (integer dj = -1; dj <= 1; dj = dj + 1) begin
						if (di == 0 && dj == 0) continue;
						count = count + q[((i + di + 16) % 16) * 16 + ((j + dj + 16) % 16)];
					end
				end

				// Update the next state based on the current state and neighbor count
				if (q[i * 16 + j] == 1) begin
					if (count < 2 || count > 3)
						next_q[i * 16 + j] = 0;
				end else begin
					if (count == 3)
						next_q[i * 16 + j] = 1;
				end
			end
		end
	end
endmodule

module top_module(
    input clk,
    input load,
    input [255:0] data,
    output reg [255:0] q
);

    reg [255:0] next_q;

    always @(posedge clk) begin
        if (load) begin
            q <= data;
        end else begin
            q <= next_q;
        end
    end

    // Neighbour counting and state updating
    always @* begin
        next_q = q; // Default to current state
        integer i, j, count;
        for (i = 0; i < 16; i = i + 1) begin
            for (j = 0; j < 16; j = j + 1) begin
                count = 0;
                // Count neighbours
                for (integer di = -1; di <= 1; di = di + 1) begin
                    for (integer dj = -1; dj <= 1; dj = dj + 1) begin
                        if (di == 0 && dj == 0) continue;
                        count = count + q[((i + di + 16) % 16) * 16 + (j + dj + 16) % 16];
                    end
                end

                // Update cell state based on neighbour count
                case (count)
                    0, 1, 4: next_q[i * 16 + j] = 0; // 0-1 or 4+ neighbours -> dead
                    2: next_q[i * 16 + j] = q[i * 16 + j]; // 2 neighbours -> no change
                    3: next_q[i * 16 + j] = 1; // 3 neighbours -> alive
                    default: next_q[i * 16 + j] = 0; // Should not happen logically
                endcase
            end
        end
    end

endmodule

module top_module(
    input clk,
    input load,
    input [255:0] data,
    output reg [255:0] q
);

    reg [255:0] next_q;

    always @(posedge clk) begin
        if (load) begin
            q <= data;
        end else begin
            q <= next_q;
        end
    end

    always @* begin
        next_q = 256'b0;
        for (int i = 0; i < 16; i++) begin
            for (int j = 0; j < 16; j++) begin
                int alive_count = 0;
                for (int di = -1; di <= 1; di++) begin
                    for (int dj = -1; dj <= 1; dj++) begin
                        if (di == 0 && dj == 0) continue;
                        int ni = (i + di + 16) % 16;
                        int nj = (j + dj + 16) % 16;
                        alive_count += q[ni * 16 + nj];
                    end
                end

                int index = i * 16 + j;
                if (q[index] == 1) begin
                    if (alive_count < 2 || alive_count > 3) begin
                        next_q[index] = 0;
                    end else begin
                        next_q[index] = 1;
                    end
                end else begin
                    if (alive_count == 3) begin
                        next_q[index] = 1;
                    end
                end
            end
        end
    end

endmodule

module top_module(
    input clk,
    input load,
    input [255:0] data,
    output reg [255:0] q);

    reg [255:0] next_q;

    always @(*) begin
        integer i, j, count;
        next_q = q; // default to current state

        for (i = 0; i < 16; i = i + 1) begin
            for (j = 0; j < 16; j = j + 1) begin
                count = 0;

                // Count neighbours in the 16x16 toroidal grid
                for (integer x = -1; x <= 1; x = x + 1) begin
                    for (integer y = -1; y <= 1; y = y + 1) begin
                        if (x == 0 && y == 0) continue; // skip the cell itself
                        count = count + q[((i + x + 16) % 16) * 16 + ((j + y + 16) % 16)];
                    end
                end

                // Update next_q based on the rules
                case (q[i * 16 + j])
                    1'b0: begin
                        if (count == 3)
                            next_q[i * 16 + j] = 1'b1;
                    end
                    1'b1: begin
                        if (count < 2 || count > 3)
                            next_q[i * 16 + j] = 1'b0;
                    end
                endcase
            end
        end
    end

    always @(posedge clk) begin
        if (load)
            q <= data;
        else
            q <= next_q;
    end
endmodule

module top_module(
    input clk,
    input load,
    input [255:0] data,
    output reg [255:0] q
);

    reg [255:0] next_q;

    integer i, j;
    wire [7:0] neighbours;

    always @(posedge clk) begin
        if (load) begin
            q <= data;
        end else begin
            q <= next_q;
        end
    end

    always @(*) begin
        next_q = q; // Default to current state
        for (i = 0; i < 16; i = i + 1) begin
            for (j = 0; j < 16; j = j + 1) begin
                neighbours = 0;
                // Count neighbours
                for (int di = -1; di <= 1; di = di + 1) begin
                    for (int dj = -1; dj <= 1; dj = dj + 1) begin
                        if (di == 0 && dj == 0) continue;
                        neighbours = neighbours + q[((i + di + 16) % 16) * 16 + ((j + dj + 16) % 16)];
                    end
                end

                case (neighbours)
                    1, 0: next_q[i * 16 + j] = 0;      // 0-1 neighbour: Cell becomes 0
                    2: next_q[i * 16 + j] = q[i * 16 + j]; // 2 neighbours: Cell state does not change
                    3: next_q[i * 16 + j] = 1;         // 3 neighbours: Cell becomes 1
                    default: next_q[i * 16 + j] = 0;   // 4+ neighbours: Cell becomes 0
                endcase
            end
        end
    end

endmodule

module top_module(
	input clk,
	input load,
	input [255:0] data,
	output reg [255:0] q);

	// Internal signal to store the next state of the grid
	reg [255:0] next_q;

	// Function to count alive neighbors
	function [3:0] count_neighbors(
		input [255:0] state,
		input [3:0] row,
		input [3:0] col
	);
		reg [3:0] count;
		integer i, j;
		begin
			count = 0;
			for (i = -1; i <= 1; i = i + 1) begin
				for (j = -1; j <= 1; j = j + 1) begin
					if (i == 0 && j == 0) continue; // Skip the cell itself
					count = count + state[((row + i + 16) % 16) * 16 + ((col + j + 16) % 16)];
				end
			end
			count_neighbors = count;
		end
	endfunction

	// Always block to update state on clock edge
	always @(posedge clk) begin
		if (load) begin
			q <= data; // Load data into q
		end else begin
			for (int r = 0; r < 16; r = r + 1) begin
				for (int c = 0; c < 16; c = c + 1) begin
					case (count_neighbors(q, r, c))
						0, 1: next_q[r * 16 + c] = 0;      // 0-1 neighbors -> dead
						2: next_q[r * 16 + c] = q[r * 16 + c]; // 2 neighbors -> unchanged
						3: next_q[r * 16 + c] = 1;      // 3 neighbors -> alive
						default: next_q[r * 16 + c] = 0; // 4+ neighbors -> dead
					endcase
				end
			end
			q <= next_q; // Update the state with next_q
		end
	end
endmodule

module top_module(
    input clk,
    input load,
    input [255:0] data,
    output reg [255:0] q
);

    reg [255:0] next_q;

    always @(posedge clk) begin
        if (load) begin
            q <= data;
        end else begin
            q <= next_q;
        end
    end

    integer i, j, num_neighbors;
    wire [7:0] neighbors_count [0:15][0:15];

    always @* begin
        for (i = 0; i < 16; i = i + 1) begin
            for (j = 0; j < 16; j = j + 1) begin
                num_neighbors = 0;

                for (integer di = -1; di <= 1; di = di + 1) begin
                    for (integer dj = -1; dj <= 1; dj = dj + 1) begin
                        if (di == 0 && dj == 0) continue;
                        num_neighbors = num_neighbors +
                            q[((i + di + 16) % 16) * 16 + ((j + dj + 16) % 16)];
                    end
                end

                if (q[i * 16 + j] == 1) begin
                    if (num_neighbors < 2 || num_neighbors > 3) begin
                        next_q[i * 16 + j] = 0;
                    end else begin
                        next_q[i * 16 + j] = 1;
                    end
                end else begin
                    if (num_neighbors == 3) begin
                        next_q[i * 16 + j] = 1;
                    end else begin
                        next_q[i * 16 + j] = 0;
                    end
                end
            end
        end
    end

endmodule

module top_module(
	input clk,
	input load,
	input [255:0] data,
	output reg [255:0] q);

    wire [255:0] next_q;
    reg [3:0] i, j;
    reg [8:0] neighbor_count;

    always @(posedge clk) begin
        if (load) begin
            q <= data;
        end else begin
            for (i = 0; i < 16; i = i + 1) begin
                for (j = 0; j < 16; j = j + 1) begin
                    neighbor_count = 0;
                    // Count neighbors
                    for (int x = -1; x <= 1; x = x + 1) begin
                        for (int y = -1; y <= 1; y = y + 1) begin
                            if (!(x == 0 && y == 0)) begin
                                neighbor_count = neighbor_count +
                                    q[((i + x + 16) % 16) * 16 + ((j + y + 16) % 16)];
                            end
                        end
                    end

                    // Update the next state based on neighbor count
                    case (neighbor_count)
                        1, 0: next_q[i * 16 + j] = 0;
                        2: next_q[i * 16 + j] = q[i * 16 + j];
                        3: next_q[i * 16 + j] = 1;
                        default: next_q[i * 16 + j] = 0;
                    endcase
                end
            end
            q <= next_q;
        end
    end

endmodule

module top_module(
    input clk,
    input load,
    input [255:0] data,
    output reg [255:0] q
);
    reg [255:0] next_q;

    integer i, j, count;

    always @(posedge clk) begin
        if (load) begin
            q <= data;
        end else begin
            q <= next_q;
        end
    end

    always @* begin
        next_q = q;
        for (i = 0; i < 16; i = i + 1) begin
            for (j = 0; j < 16; j = j + 1) begin
                count = 0;
                // Count neighbours
                for (integer di = -1; di <= 1; di = di + 1) begin
                    for (integer dj = -1; dj <= 1; dj = dj + 1) begin
                        if (di == 0 && dj == 0) continue;
                        count = count + q[((i + di + 16) % 16) * 16 + ((j + dj + 16) % 16)];
                    end
                end

                // Update next_q based on the rules
                if (q[i * 16 + j] == 1) begin
                    if (count < 2 || count > 3)
                        next_q[i * 16 + j] = 0; // Become 0
                end else begin
                    if (count == 3)
                        next_q[i * 16 + j] = 1; // Become 1
                end
            end
        end
    end
endmodule

module top_module(
    input clk,
    input load,
    input [255:0] data,
    output reg [255:0] q
);

    reg [255:0] next_q;

    always @(*) begin
        integer i, j, count;
        next_q = q; // start with the current state

        for (i = 0; i < 16; i = i + 1) begin
            for (j = 0; j < 16; j = j + 1) begin
                count = 0;
                // Count the number of alive neighbors
                for (integer mi = -1; mi <= 1; mi = mi + 1) begin
                    for (integer mj = -1; mj <= 1; mj = mj + 1) begin
                        if (mi == 0 && mj == 0) continue; // skip the cell itself
                        count = count + q[((i + mi + 16) % 16) * 16 + ((j + mj + 16) % 16)];
                    end
                end

                // Determine the next state of the cell
                case (count)
                    0, 1: next_q[i * 16 + j] = 0;
                    2: next_q[i * 16 + j] = q[i * 16 + j];
                    3: next_q[i * 16 + j] = 1;
                    default: next_q[i * 16 + j] = 0;
                endcase
            end
        end
    end

    always @(posedge clk) begin
        if (load) begin
            q <= data; // Load initial state
        end else begin
            q <= next_q; // Update to the next state
        end
    end

endmodule

module top_module(
    input clk,
    input load,
    input [255:0] data,
    output reg [255:0] q
);

    reg [255:0] next_q;

    always @(posedge clk) begin
        if (load) begin
            q <= data;
        end else begin
            q <= next_q;
        end
    end

    always @* begin
        integer i, j, count;
        next_q = q; // start with the current state

        for (i = 0; i < 16; i = i + 1) begin
            for (j = 0; j < 16; j = j + 1) begin
                count = 0;

                // Check all 8 neighbors with toroidal wrapping
                for (integer di = -1; di <= 1; di = di + 1) begin
                    for (integer dj = -1; dj <= 1; dj = dj + 1) begin
                        if (di == 0 && dj == 0)
                            continue; // skip itself
                        count = count + q[(i + di + 16) % 16 * 16 + (j + dj + 16) % 16];
                    end
                end

                // Apply the game rules
                case (q[i * 16 + j])
                    1'b1: begin
                        if (count < 2 || count > 3)
                            next_q[i * 16 + j] = 1'b0; // Cell dies
                    end
                    1'b0: begin
                        if (count == 3)
                            next_q[i * 16 + j] = 1'b1; // Cell becomes alive
                    end
                endcase
            end
        end
    end

endmodule