module top_module(
    input clk,
    input reset,
    output reg shift_ena
);

    reg [2:0] count; // 3-bit counter to count clock cycles

    always @(posedge clk) begin
        if (reset) begin
            shift_ena <= 1'b1; // Enable shift for 4 cycles
            count <= 3'b000; // Reset counter
        end else if (count < 3'b100) begin
            shift_ena <= 1'b1; // Continue enabling shift
            count <= count + 1'b1; // Increment counter
        end else begin
            shift_ena <= 1'b0; // Disable shift
        end
    end

endmodule

module top_module(
    input clk,
    input reset,
    output reg shift_ena
);

    reg [2:0] state;
    parameter IDLE = 3'b000;
    parameter SHIFT1 = 3'b001;
    parameter SHIFT2 = 3'b010;
    parameter SHIFT3 = 3'b011;
    parameter SHIFT4 = 3'b100;

    always @(posedge clk) begin
        if (reset) begin
            state <= SHIFT1;
        end else begin
            case (state)
                IDLE: begin
                    shift_ena <= 0;
                    state <= IDLE;
                end
                SHIFT1: begin
                    shift_ena <= 1;
                    state <= SHIFT2;
                end
                SHIFT2: begin
                    shift_ena <= 1;
                    state <= SHIFT3;
                end
                SHIFT3: begin
                    shift_ena <= 1;
                    state <= SHIFT4;
                end
                SHIFT4: begin
                    shift_ena <= 1;
                    state <= IDLE;
                end
                default: begin
                    shift_ena <= 0;
                    state <= IDLE;
                end
            endcase
        end
    end
endmodule

module top_module(
    input clk,
    input reset,
    output shift_ena
);

    reg [2:0] count;
    reg ena;

    assign shift_ena = ena;

    always @(posedge clk) begin
        if (reset) begin
            count <= 3'b000;
            ena <= 1;
        end else if (ena) begin
            count <= count + 1;
            if (count == 3) begin
                ena <= 0;
            end
        end
    end

endmodule

module top_module(
    input clk,
    input reset,
    output reg shift_ena
);

    reg [2:0] count;

    always @(posedge clk) begin
        if (reset) begin
            shift_ena <= 1'b1;
            count <= 3'b100; // Initialize count to 4
        end else if (count > 0) begin
            shift_ena <= 1'b1;
            count <= count - 1;
        end else begin
            shift_ena <= 1'b0;
        end
    end

endmodule

module top_module(
    input clk,
    input reset,
    output reg shift_ena
);

    reg [2:0] count; // 3-bit counter to count up to 4 cycles

    always @(posedge clk) begin
        if (reset) begin
            count <= 3'b000;
            shift_ena <= 1;
        end
        else if (shift_ena) begin
            count <= count + 1;
            if (count == 3'b011) begin
                shift_ena <= 0;
            end
        end
    end

endmodule

module top_module(
    input clk,
    input reset,
    output shift_ena);

    reg [2:0] state;
    reg shift_ena_reg;

    always @(posedge clk) begin
        if (reset) begin
            state <= 3'd0;
            shift_ena_reg <= 1'b1;
        end else if (state < 3'd4) begin
            state <= state + 1;
            shift_ena_reg <= 1'b1;
        end else begin
            shift_ena_reg <= 1'b0;
        end
    end

    assign shift_ena = shift_ena_reg;

endmodule

module top_module(
    input clk,
    input reset,
    output reg shift_ena
);

    reg [2:0] count;

    always @(posedge clk) begin
        if (reset) begin
            count <= 3'b100;
            shift_ena <= 1'b1;
        end else if (count > 0) begin
            count <= count - 1;
            shift_ena <= 1'b1;
        end else begin
            shift_ena <= 1'b0;
        end
    end

endmodule

module top_module(
    input clk,
    input reset,
    output shift_ena
);

    reg [2:0] count;
    reg shift_ena_reg;

    assign shift_ena = shift_ena_reg;

    always @(posedge clk) begin
        if (reset) begin
            count <= 3'b100;
            shift_ena_reg <= 1'b1;
        end
        else if (count > 0) begin
            count <= count - 1;
            shift_ena_reg <= 1;
        end
        else begin
            shift_ena_reg <= 0;
        end
    end

endmodule

module top_module(
    input clk,
    input reset,
    output reg shift_ena
);

    reg [2:0] state, next_state;
    reg [2:0] count;

    // State encodings
    localparam IDLE = 3'b000;
    localparam ENABLE_1 = 3'b001;
    localparam ENABLE_2 = 3'b010;
    localparam ENABLE_3 = 3'b011;
    localparam ENABLE_4 = 3'b100;

    // State transition
    always @(posedge clk) begin
        if (reset) begin
            state <= ENABLE_1;
            count <= 3'b000;
        end else begin
            state <= next_state;
            if (shift_ena)
                count <= count + 1;
        end
    end

    // Next state logic
    always @(*) begin
        case (state)
            IDLE: begin
                shift_ena = 1'b0;
                if (reset)
                    next_state = ENABLE_1;
                else
                    next_state = IDLE;
            end
            ENABLE_1: begin
                shift_ena = 1'b1;
                next_state = ENABLE_2;
            end
            ENABLE_2: begin
                shift_ena = 1'b1;
                next_state = ENABLE_3;
            end
            ENABLE_3: begin
                shift_ena = 1'b1;
                next_state = ENABLE_4;
            end
            ENABLE_4: begin
                shift_ena = 1'b1;
                if (count == 3)
                    next_state = IDLE;
                else
                    next_state = ENABLE_4;
            end
            default: begin
                shift_ena = 1'b0;
                next_state = IDLE;
            end
        endcase
    end

endmodule

module top_module(
    input clk,
    input reset,
    output reg shift_ena
);

    reg [2:0] counter;

    always @(posedge clk) begin
        if (reset) begin
            counter <= 3'b100; // Initialize to 4
            shift_ena <= 1'b1;
        end else if (counter != 0) begin
            counter <= counter - 1;
            shift_ena <= 1'b1;
        end else begin
            shift_ena <= 1'b0;
        end
    end

endmodule

module top_module(
	input clk,
	input reset,
	output reg shift_ena);

	reg [2:0] state, next_state;

	// State encoding
	localparam IDLE     = 3'b000,
	           SHIFT_1  = 3'b001,
	           SHIFT_2  = 3'b010,
	           SHIFT_3  = 3'b011,
	           SHIFT_4  = 3'b100,
	           DONE     = 3'b101;

	// State transition
	always @(posedge clk) begin
		if (reset)
			state <= SHIFT_1;
		else
			state <= next_state;
	end

	// Next state logic
	always @(*) begin
		case (state)
			IDLE:
				next_state = IDLE;
			SHIFT_1:
				next_state = SHIFT_2;
			SHIFT_2:
				next_state = SHIFT_3;
			SHIFT_3:
				next_state = SHIFT_4;
			SHIFT_4:
				next_state = DONE;
			DONE:
				next_state = IDLE;
			default:
				next_state = IDLE;
		endcase
	end

	// Output logic
	always @(*) begin
		case (state)
			SHIFT_1, SHIFT_2, SHIFT_3, SHIFT_4:
				shift_ena = 1;
			default:
				shift_ena = 0;
		endcase
	end
endmodule

module top_module(
    input clk,
    input reset,
    output reg shift_ena
);

    reg [2:0] count;

    always @(posedge clk) begin
        if (reset) begin
            count <= 3'b100;
        end else if (count != 3'b000) begin
            count <= count - 1;
        end

        shift_ena <= (count != 3'b000);
    end

endmodule

module top_module(
    input clk,
    input reset,
    output reg shift_ena);

    reg [2:0] count;

    always @(posedge clk) begin
        if (reset) begin
            count <= 3'd4;
        end else if (count > 0) begin
            count <= count - 1;
        end
    end

    always @(posedge clk) begin
        if (reset) begin
            shift_ena <= 1;
        end else if (count > 0) begin
            shift_ena <= 1;
        end else begin
            shift_ena <= 0;
        end
    end

endmodule

module top_module(
    input clk,
    input reset,
    output reg shift_ena
);

    reg [2:0] count;

    always @(posedge clk) begin
        if (reset) begin
            shift_ena <= 1;
            count <= 3'b000;
        end
        else if (shift_ena) begin
            if (count == 3'b011) begin
                shift_ena <= 0;
            end
            count <= count + 1;
        end
    end

endmodule

module top_module(
    input clk,
    input reset,
    output reg shift_ena);

    reg [2:0] counter;

    always @(posedge clk) begin
        if (reset) begin
            shift_ena <= 1;
            counter <= 3'd3; // Load the counter with 3 to count 4 cycles (3 -> 2 -> 1 -> 0)
        end else if (counter != 3'd0) begin
            shift_ena <= 1;
            counter <= counter - 1;
        end else begin
            shift_ena <= 0;
        end
    end
endmodule

module top_module(
    input clk,
    input reset,
    output reg shift_ena
);

    reg [2:0] state, next_state;
    reg [2:0] count;

    // State enumeration
    localparam IDLE = 3'd0;
    localparam SHIFT = 3'd1;

    always @(posedge clk) begin
        if (reset) begin
            state <= SHIFT;
            count <= 3'd4;
        end else begin
            state <= next_state;
        end
    end

    always @(*) begin
        case (state)
            IDLE: begin
                shift_ena = 1'b0;
                next_state = IDLE;
            end
            SHIFT: begin
                if (count > 0) begin
                    shift_ena = 1'b1;
                    next_state = SHIFT;
                end else begin
                    shift_ena = 1'b0;
                    next_state = IDLE;
                end
            end
            default: begin
                shift_ena = 1'b0;
                next_state = IDLE;
            end
        endcase
    end

    always @(posedge clk) begin
        if (reset) begin
            count <= 3'd4;
        end else if (state == SHIFT && count > 0) begin
            count <= count - 1'b1;
        end
    end

endmodule

module top_module(
    input clk,
    input reset,
    output shift_ena
);

    reg [2:0] counter;
    reg shift_ena_reg;

    always @(posedge clk) begin
        if (reset) begin
            counter <= 3'd4;
            shift_ena_reg <= 1'b1;
        end else if (counter != 3'd0) begin
            counter <= counter - 1;
            shift_ena_reg <= 1'b1;
        end else begin
            shift_ena_reg <= 1'b0;
        end
    end

    assign shift_ena = shift_ena_reg;

endmodule

module top_module(
    input clk,
    input reset,
    output reg shift_ena
);

    reg [2:0] count;
    reg state;

    always @(posedge clk) begin
        if (reset) begin
            shift_ena <= 1;
            count <= 3'b000;
            state <= 1;
        end
        else if (state) begin
            count <= count + 1;
            if (count == 3'b011) begin
                shift_ena <= 0;
                state <= 0;
            end
        end
    end

endmodule

module top_module(
    input clk,
    input reset,
    output reg shift_ena
);

    reg [2:0] cycle_count;

    always @(posedge clk) begin
        if (reset) begin
            shift_ena <= 1'b1;
            cycle_count <= 3'b000;
        end else if (shift_ena) begin
            if (cycle_count == 3'b011) begin
                shift_ena <= 1'b0;
            end else begin
                cycle_count <= cycle_count + 1'b1;
            end
        end
    end

endmodule


module top_module (
    input a,
    input b,
    output out_and,
    output out_or,
    output out_xor,
    output out_nand,
    output out_nor,
    output out_xnor,
    output out_anotb
);
    assign out_and = a & b;
    assign out_or = a | b;
    assign out_xor = a ^ b;
    assign out_nand = ~(a & b);
    assign out_nor = ~(a | b);
    assign out_xnor = a ~^ b;
    assign out_anotb = a & ~b;
endmodule

module top_module (
    input a,
    input b,
    output out_and,
    output out_or,
    output out_xor,
    output out_nand,
    output out_nor,
    output out_xnor,
    output out_anotb
);
    // Implement logic for each output
    assign out_and = a & b;
    assign out_or = a | b;
    assign out_xor = a ^ b;
    assign out_nand = ~(a & b);
    assign out_nor = ~(a | b);
    assign out_xnor = ~(a ^ b);
    assign out_anotb = a & ~b;

endmodule

module top_module (
    input a,
    input b,
    output out_and,
    output out_or,
    output out_xor,
    output out_nand,
    output out_nor,
    output out_xnor,
    output out_anotb
);

    assign out_and = a & b;
    assign out_or = a | b;
    assign out_xor = a ^ b;
    assign out_nand = ~(a & b);
    assign out_nor = ~(a | b);
    assign out_xnor = ~(a ^ b);
    assign out_anotb = a & ~b;

endmodule


module top_module (
	input [3:0] in,
	output reg [1:0] pos
);

always @(*) begin
    casez (in)
        4'b1???: pos = 2'd3;
        4'b01??: pos = 2'd2;
        4'b001?: pos = 2'd1;
        4'b0001: pos = 2'd0;
        default: pos = 2'd0;
    endcase
end

endmodule

module top_module (
    input [3:0] in,
    output reg [1:0] pos
);

    always @(*) begin
        if (in[3])
            pos = 2'd3;
        else if (in[2])
            pos = 2'd2;
        else if (in[1])
            pos = 2'd1;
        else if (in[0])
            pos = 2'd0;
        else
            pos = 2'd0;  // If no bits are high
    end

endmodule

module top_module (
    input [3:0] in,
    output reg [1:0] pos
);

    always @(*) begin
        case (in)
            4'b0001: pos = 2'd0;
            4'b0010: pos = 2'd1;
            4'b0100: pos = 2'd2;
            4'b1000: pos = 2'd3;
            default: pos = 2'd0;
        endcase
    end

endmodule

module top_module (
    input [3:0] in,
    output reg [1:0] pos
);
    always @(*) begin
        case (in)
            4'b0000: pos = 2'd0;
            4'b0001: pos = 2'd0;
            4'b0010: pos = 2'd1;
            4'b0100: pos = 2'd2;
            4'b1000: pos = 2'd3;
            default: pos = 2'd0; // When none of the positions match, default to 0
        endcase
    end
endmodule

module top_module (
    input [3:0] in,
    output reg [1:0] pos
);

    always @(*) begin
        casez (in)
            4'b0001: pos = 2'd0;
            4'b001?: pos = 2'd1;
            4'b01??: pos = 2'd2;
            4'b1???: pos = 2'd3;
            default: pos = 2'd0; // output zero if no bits are high
        endcase
    end

endmodule

module top_module (
    input [3:0] in,
    output reg [1:0] pos
);

always @(*) begin
    if (in[3])
        pos = 2'd3;
    else if (in[2])
        pos = 2'd2;
    else if (in[1])
        pos = 2'd1;
    else if (in[0])
        pos = 2'd0;
    else
        pos = 2'd0;
end

endmodule

module top_module (
    input [3:0] in,
    output reg [1:0] pos
);
    always @(*) begin
        casez (in)
            4'b1???: pos = 2'd3;
            4'b01??: pos = 2'd2;
            4'b001?: pos = 2'd1;
            4'b0001: pos = 2'd0;
            default: pos = 2'd0; // When input is zero
        endcase
    end
endmodule


module top_module (
	input clk,
	input in,
	output logic out
);

	always @(posedge clk) begin
		out <= in ^ out;
	end

endmodule

module top_module (
    input clk,
    input in,
    output logic out
);

    logic d;

    always_ff @(posedge clk) begin
        out <= d;
    end

    assign d = in ^ out;

endmodule

module top_module (
	input clk,
	input in,
	output logic out
);

	logic xor_out;

	// XOR gate
	assign xor_out = in ^ out;

	// D flip-flop
	always_ff @(posedge clk) begin
		out <= xor_out;
	end

endmodule

module top_module (
	input clk,
	input in,
	output logic out
);

	always_ff @(posedge clk) begin
		out <= in ^ out;
	end

endmodule

module top_module (
	input clk,
	input in,
	output logic out
);

    logic xor_out;

    assign xor_out = in ^ out;

    always_ff @(posedge clk) begin
        out <= xor_out;
    end

endmodule

module top_module (
	input clk,
	input in,
	output logic out
);

    logic xor_out;

    always_ff @(posedge clk) begin
        xor_out <= in ^ out;
        out <= xor_out;
    end

endmodule

module top_module (
    input clk,
    input in,
    output logic out
);

    wire xor_out;

    // XOR gate
    assign xor_out = in ^ out;

    // D flip-flop
    always_ff @(posedge clk) begin
        out <= xor_out;
    end

endmodule

module top_module (
    input clk,
    input in,
    output logic out
);
    logic xor_out;

    always @(posedge clk) begin
        xor_out <= in ^ out;
        out <= xor_out;
    end
endmodule

module top_module (
	input clk,
	input in,
	output logic out
);

	logic d;

	// XOR gate
	assign d = in ^ out;

	// D Flip-Flop
	always_ff @(posedge clk) begin
		out <= d;
	end

endmodule


module top_module(
	input clk,
	input [7:0] d,
	input areset,
	output reg [7:0] q);

	always @(posedge clk or posedge areset) begin
		if (areset) begin
			q <= 8'b0;
		end else begin
			q <= d;
		end
	end

endmodule

module top_module(
    input clk,
    input [7:0] d,
    input areset,
    output reg [7:0] q
);
    always @(posedge clk or posedge areset) begin
        if (areset)
            q <= 8'b0;
        else
            q <= d;
    end
endmodule

module top_module(
    input clk,
    input [7:0] d,
    input areset,
    output reg [7:0] q);

    always @(posedge clk or posedge areset) begin
        if (areset)
            q <= 8'b0;
        else
            q <= d;
    end

endmodule

module top_module(
    input clk,
    input [7:0] d,
    input areset,
    output reg [7:0] q
);

    always @(posedge clk, posedge areset) begin
        if (areset) begin
            q <= 8'b0;
        end else begin
            q <= d;
        end
    end

endmodule


module top_module (
    input a,
    input b,
    input cin,
    output cout,
    output sum
);

    // Sum calculation using XOR gates
    assign sum = a ^ b ^ cin;

    // Carry-out calculation
    assign cout = (a & b) | (b & cin) | (cin & a);

endmodule

module top_module (
    input a,
    input b,
    input cin,
    output cout,
    output sum
);
    assign sum = a ^ b ^ cin;
    assign cout = (a & b) | (b & cin) | (cin & a);
endmodule

module top_module (
    input a,
    input b,
    input cin,
    output cout,
    output sum
);

    assign {cout, sum} = a + b + cin;

endmodule

module top_module (
	input a,
	input b,
	input cin,
	output cout,
	output sum
);

    assign sum = a ^ b ^ cin;       // Sum is the XOR of all three inputs
    assign cout = (a & b) | (b & cin) | (cin & a); // Carry-out is true if any two inputs are true

endmodule

module top_module (
    input a,
    input b,
    input cin,
    output cout,
    output sum
);

    assign sum = a ^ b ^ cin;
    assign cout = (a & b) | (b & cin) | (a & cin);

endmodule

module top_module (
    input a,
    input b,
    input cin,
    output cout,
    output sum
);
    // Internal signals
    wire ab_sum;
    wire ab_carry;
    wire sum_carry;

    // Sum of a and b
    assign ab_sum = a ^ b;
    assign ab_carry = a & b;

    // Final sum and carry out
    assign sum = ab_sum ^ cin;
    assign sum_carry = ab_sum & cin;
    assign cout = ab_carry | sum_carry;

endmodule

module top_module (
    input a,
    input b,
    input cin,
    output cout,
    output sum
);
    // Sum is calculated as XOR of the three inputs
    assign sum = a ^ b ^ cin;
    // Carry-out is calculated based on full adder carry logic
    assign cout = (a & b) | (b & cin) | (cin & a);
endmodule

module top_module (
    input a,
    input b,
    input cin,
    output cout,
    output sum
);

    // Sum calculation
    assign sum = a ^ b ^ cin;

    // Carry-out calculation
    assign cout = (a & b) | (b & cin) | (cin & a);

endmodule

module top_module (
    input a,
    input b,
    input cin,
    output cout,
    output sum
);

    assign sum = a ^ b ^ cin;       // Sum is the XOR of all three inputs
    assign cout = (a & b) | (b & cin) | (a & cin);  // Carry-out is true if at least two inputs are true

endmodule

module top_module (
    input a,
    input b,
    input cin,
    output cout,
    output sum
);

    assign sum = a ^ b ^ cin; // Sum bit
    assign cout = (a & b) | (b & cin) | (cin & a); // Carry-out bit

endmodule


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

    function [3:0] count_neighbors;
        input integer r, c;
        begin
            count_neighbors = q[((r+15)%16)*16 + ((c+15)%16)] +
                              q[((r+15)%16)*16 + c] +
                              q[((r+15)%16)*16 + ((c+1)%16)] +
                              q[r*16 + ((c+15)%16)] +
                              q[r*16 + ((c+1)%16)] +
                              q[((r+1)%16)*16 + ((c+15)%16)] +
                              q[((r+1)%16)*16 + c] +
                              q[((r+1)%16)*16 + ((c+1)%16)];
        end
    endfunction

    integer i, j;
    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
                    case (count_neighbors(i, j))
                        2: q[i*16 + j] <= q[i*16 + j]; // State does not change
                        3: q[i*16 + j] <= 1;           // Becomes alive
                        default: q[i*16 + j] <= 0;     // Becomes dead
                    endcase
                end
            end
        end
    end

endmodule

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

    reg [15:0] grid [15:0];
    reg [15:0] next_grid [15:0];

    integer i, j;
    integer ni, nj;
    reg [3:0] alive_neighbours;

    always @(posedge clk) begin
        if (load) begin
            // Load data into grid.
            for (i = 0; i < 16; i = i + 1) begin
                grid[i] <= data[(i+1)*16-1:i*16];
            end
        end else begin
            // Compute the next state of the grid.
            for (i = 0; i < 16; i = i + 1) begin
                for (j = 0; j < 16; j = j + 1) begin
                    // Count alive neighbours.
                    alive_neighbours = 0;
                    for (ni = -1; ni <= 1; ni = ni + 1) begin
                        for (nj = -1; nj <= 1; nj = nj + 1) begin
                            if (ni != 0 || nj != 0) begin
                                if (grid[(i+ni+16)%16][(j+nj+16)%16]) begin
                                    alive_neighbours = alive_neighbours + 1;
                                end
                            end
                        end
                    end

                    // Update cell based on the number of alive neighbours.
                    if (alive_neighbours < 2 || alive_neighbours > 3) begin
                        next_grid[i][j] <= 0;
                    end else if (alive_neighbours == 3) begin
                        next_grid[i][j] <= 1;
                    end else if (alive_neighbours == 2) begin
                        next_grid[i][j] <= grid[i][j];
                    end
                end
            end

            // Update the grid with the next state.
            for (i = 0; i < 16; i = i + 1) begin
                grid[i] <= next_grid[i];
            end
        end

        // Update output.
        for (i = 0; i < 16; i = i + 1) begin
            q[(i+1)*16-1:i*16] <= grid[i];
        end
    end

endmodule

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

    reg [15:0] grid[15:0];  // 16x16 grid
    integer i, j;

    // Function to count the number of neighbors
    function [3:0] count_neighbors;
        input [3:0] x, y;
        integer rel_x, rel_y;
        begin
            count_neighbors = 0;
            for (rel_x = -1; rel_x <= 1; rel_x = rel_x + 1) begin
                for (rel_y = -1; rel_y <= 1; rel_y = rel_y + 1) begin
                    if (rel_x != 0 || rel_y != 0) begin
                        count_neighbors = count_neighbors +
                            grid[(x + rel_x + 16) % 16][(y + rel_y + 16) % 16];
                    end
                end
            end
        end
    endfunction

    // Load initial state
    always @(posedge clk) begin
        if (load) begin
            for (i = 0; i < 16; i = i + 1) begin
                grid[i] <= data[i * 16 +: 16];
            end
        end else begin
            // Compute the next state of the grid
            reg [15:0] next_grid [15:0];
            integer x, y;
            for (x = 0; x < 16; x = x + 1) begin
                for (y = 0; y < 16; y = y + 1) begin
                    case (count_neighbors(x, y))
                        4'd2: next_grid[x][y] = grid[x][y];  // 2 neighbors: stay the same
                        4'd3: next_grid[x][y] = 1;          // 3 neighbors: become alive
                        default: next_grid[x][y] = 0;       // 0-1 or 4+ neighbors: become dead
                    endcase
                end
            end
            for (i = 0; i < 16; i = i + 1) begin
                grid[i] <= next_grid[i];
            end
        end
    end

    // Update the output
    always @(posedge clk) begin
        if (load) begin
            q <= data;
        end else begin
            for (i = 0; i < 16; i = i + 1) begin
                q[i*16 +: 16] <= grid[i];
            end
        end
    end
endmodule

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

    reg [15:0] grid [0:15];
    integer i, j, ni, nj, cnt;

    always @(posedge clk) begin
        if (load) begin
            for (i = 0; i < 16; i = i + 1) begin
                grid[i] <= data[i*16 +: 16];
            end
        end else begin
            reg [15:0] next_grid [0:15];

            for (i = 0; i < 16; i = i + 1) begin
                for (j = 0; j < 16; j = j + 1) begin
                    cnt = 0;
                    for (ni = -1; ni <= 1; ni = ni + 1) begin
                        for (nj = -1; nj <= 1; nj = nj + 1) begin
                            if (ni != 0 || nj != 0) begin
                                if (grid[(i+ni+16)%16][(j+nj+16)%16] == 1)
                                    cnt = cnt + 1;
                            end
                        end
                    end

                    case(cnt)
                        3: next_grid[i][j] = 1;
                        2: next_grid[i][j] = grid[i][j];
                        default: next_grid[i][j] = 0;
                    endcase
                end
            end

            for (i = 0; i < 16; i = i + 1) begin
                grid[i] <= next_grid[i];
            end
        end
    end

    always @(*) begin
        for (i = 0; i < 16; i = i + 1) begin
            q[i*16 +: 16] = grid[i];
        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 x, y, dx, dy;
    integer neighbors;

    always @(*) begin
        for (y = 0; y < 16; y = y + 1) begin
            for (x = 0; x < 16; x = x + 1) begin
                neighbors = 0;
                for (dy = -1; dy <= 1; dy = dy + 1) begin
                    for (dx = -1; dx <= 1; dx = dx + 1) begin
                        if (dx != 0 || dy != 0) begin
                            neighbors = neighbors + q[((y + dy + 16) % 16) * 16 + ((x + dx + 16) % 16)];
                        end
                    end
                end

                case (neighbors)
                    3: next_q[y * 16 + x] = 1;
                    2: next_q[y * 16 + x] = q[y * 16 + x];
                    default: next_q[y * 16 + x] = 0;
                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);

    integer i, j;
    reg [15:0] grid [15:0];
    reg [15:0] next_grid [15:0];

    // Initialize grid from 1D vector
    always @* begin
        for (i = 0; i < 16; i = i + 1) begin
            grid[i] = q[i*16 +: 16];
        end
    end

    // Compute next state of the grid
    always @* begin
        for (i = 0; i < 16; i = i + 1) begin
            for (j = 0; j < 16; j = j + 1) begin
                integer count;
                count = grid[(i-1+16)%16][(j-1+16)%16] +
                        grid[(i-1+16)%16][j] +
                        grid[(i-1+16)%16][(j+1)%16] +
                        grid[i][(j-1+16)%16] +
                        grid[i][(j+1)%16] +
                        grid[(i+1)%16][(j-1+16)%16] +
                        grid[(i+1)%16][j] +
                        grid[(i+1)%16][(j+1)%16];

                case (count)
                    2: next_grid[i][j] = grid[i][j]; // Remains the same
                    3: next_grid[i][j] = 1;         // Becomes alive
                    default: next_grid[i][j] = 0;   // Becomes dead
                endcase
            end
        end
    end

    // Synchronize on clock edge to update q
    always @(posedge clk) begin
        if (load) begin
            q <= data;
        end else begin
            for (i = 0; i < 16; i = i + 1) begin
                q[i*16 +: 16] <= next_grid[i];
            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;

    integer i, j;

    always @(*) begin
        for (i = 0; i < 16; i = i + 1) begin
            for (j = 0; j < 16; j = j + 1) begin
                integer up = (i == 0) ? 15 : i - 1;
                integer down = (i == 15) ? 0 : i + 1;
                integer left = (j == 0) ? 15 : j - 1;
                integer right = (j == 15) ? 0 : j + 1;

                integer neighbors = q[16*up + left] + q[16*up + j] + q[16*up + right] +
                                    q[16*i + left] + q[16*i + right] +
                                    q[16*down + left] + q[16*down + j] + q[16*down + right];

                case (neighbors)
                    3: next_q[16*i + j] = 1;
                    2: next_q[16*i + j] = q[16*i + j];
                    default: next_q[16*i + j] = 0;
                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 [15:0] grid [15:0]; // Declare a 16x16 grid of registers

    always @(posedge clk) begin
        if (load) begin
            // Load data into grid
            integer i;
            for (i = 0; i < 16; i = i + 1) begin
                grid[i] <= data[i*16 +: 16];
            end
        end else begin
            reg [15:0] new_grid [15:0]; // Temporary grid to store the updated state

            integer row, col;
            for (row = 0; row < 16; row = row + 1) begin
                for (col = 0; col < 16; col = col + 1) begin
                    // Determine indices of neighboring cells with wrapping
                    integer left = (col == 0) ? 15 : (col - 1);
                    integer right = (col == 15) ? 0 : (col + 1);
                    integer up = (row == 0) ? 15 : (row - 1);
                    integer down = (row == 15) ? 0 : (row + 1);

                    // Count live neighbors
                    integer live_neighbors = grid[up][left] + grid[up][col] + grid[up][right] +
                                             grid[row][left] + grid[row][right] +
                                             grid[down][left] + grid[down][col] + grid[down][right];

                    // Rule application
                    if (live_neighbors < 2 || live_neighbors > 3) begin
                        new_grid[row][col] = 0;
                    end else if (live_neighbors == 3) begin
                        new_grid[row][col] = 1;
                    end else begin
                        new_grid[row][col] = grid[row][col];
                    end
                end
            end

            // Update grid states
            for (row = 0; row < 16; row = row + 1) begin
                grid[row] <= new_grid[row];
            end
        end
    end

    // Concatenate 16x16 grid into a 256-bit vector for output
    always @(posedge clk) begin
        integer i;
        for (i = 0; i < 16; i = i + 1) begin
            q[i*16 +: 16] <= grid[i];
        end
    end

endmodule

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

    wire [3:0] neighbors_count[15:0][15:0];

    integer i, j, ni, nj;

    always @(*) begin
        for (i = 0; i < 16; i = i + 1) begin
            for (j = 0; j < 16; j = j + 1) begin
                neighbors_count[i][j] = 0;
                for (ni = i-1; ni <= i+1; ni = ni + 1) begin
                    for (nj = j-1; nj <= j+1; nj = nj + 1) begin
                        if (!(ni == i && nj == j)) begin
                            neighbors_count[i][j] = neighbors_count[i][j] + q[((ni+16)%16)*16 + ((nj+16)%16)];
                        end
                    end
                end
            end
        end
    end

    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
                    case (neighbors_count[i][j])
                        2: q[i*16 + j] <= q[i*16 + j]; // State does not change
                        3: q[i*16 + j] <= 1;            // Cell becomes alive
                        default: q[i*16 + j] <= 0;      // Cell becomes dead
                    endcase
                end
            end
        end
    end

endmodule

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

    // Helper function to count the number of 1s around the given cell
    function integer count_neighbors;
        input [255:0] cells;
        input [3:0] x, y;
        integer i, j;
        integer count;
    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)) begin
                    count = count + cells[((x + i + 16) % 16) * 16 + ((y + j + 16) % 16)];
                end
            end
        end
        count_neighbors = count;
    end
    endfunction

    reg [255:0] next_q;
    integer ix, iy, neighbors;

    always @(posedge clk) begin
        if (load) begin
            q <= data;
        end else begin
            for (ix = 0; ix < 16; ix = ix + 1) begin
                for (iy = 0; iy < 16; iy = iy + 1) begin
                    neighbors = count_neighbors(q, ix, iy);

                    // Apply the rules of the game
                    case (neighbors)
                        2: next_q[ix * 16 + iy] = q[ix * 16 + iy]; // stays the same
                        3: next_q[ix * 16 + iy] = 1; // becomes alive
                        default: next_q[ix * 16 + iy] = 0; // becomes dead
                    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);

    integer i, j;
    reg [15:0] grid [15:0];
    reg [15:0] next_grid [15:0];

    // Function to count the number of alive neighbours
    function [3:0] count_neighbours(input [15:0] local_grid [15:0], input integer row, column);
        integer m, n, r, c;
        begin
            count_neighbours = 0;
            for (m = -1; m <= 1; m = m + 1) begin
                for (n = -1; n <= 1; n = n + 1) begin
                    if (m != 0 || n != 0) begin
                        r = (row + m) & 4'hF;  // wrap around using modulo
                        c = (column + n) & 4'hF;
                        count_neighbours = count_neighbours + local_grid[r][c];
                    end
                end
            end
        end
    endfunction

    // Split flat data input vector into 16x16 grid
    always @* begin
        for (i = 0; i < 16; i = i + 1) begin
            grid[i] = data[i*16 +: 16];
        end
    end

    // Compute the next state
    always @* begin
        for (i = 0; i < 16; i = i + 1) begin
            for (j = 0; j < 16; j = j + 1) begin
                case (count_neighbours(grid, i, j))
                    4'd2: next_grid[i][j] = grid[i][j];    // Stay the same
                    4'd3: next_grid[i][j] = 1'b1;          // Become alive
                    default: next_grid[i][j] = 1'b0;       // Become dead
                endcase
            end
        end
    end

    // Load or update state on clock edge
    always @(posedge clk) begin
        if (load) begin
            q <= data;
        end else begin
            for (i = 0; i < 16; i = i + 1) begin
                q[i*16 +: 16] <= next_grid[i];
            end
        end
    end

endmodule

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

    integer i, j;
    reg [3:0] neighbors;

    // Function to calculate the number of neighbors for a given cell
    function [3:0] num_neighbors;
        input [3:0] x, y;
        integer x_minus, x_plus, y_minus, y_plus;
        x_minus = (x == 0) ? 15 : x - 1;
        x_plus = (x == 15) ? 0 : x + 1;
        y_minus = (y == 0) ? 15 : y - 1;
        y_plus = (y == 15) ? 0 : y + 1;
        num_neighbors = q[y_minus * 16 + x_minus] + q[y_minus * 16 + x] + q[y_minus * 16 + x_plus]
                      + q[y * 16 + x_minus] + q[y * 16 + x_plus]
                      + q[y_plus * 16 + x_minus] + q[y_plus * 16 + x] + q[y_plus * 16 + x_plus];
    endfunction

    // Always block for updating the state of the system
    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
                    neighbors = num_neighbors(j, i);
                    if (neighbors == 3) begin
                        q[i * 16 + j] <= 1;
                    end else if (neighbors == 2) begin
                        q[i * 16 + j] <= q[i * 16 + j];
                    end else begin
                        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 [15:0][15:0] grid;
    wire [15:0][15:0] next_grid;
    integer i, j, x, y;
    reg [3:0] neighbors;

    assign grid = q;

    always @(*) begin
        for (i = 0; i < 16; i = i + 1) begin
            for (j = 0; j < 16; j = j + 1) begin
                neighbors = 0;
                for (x = -1; x <= 1; x = x + 1) begin
                    for (y = -1; y <= 1; y = y + 1) begin
                        if (x != 0 || y != 0) begin
                            neighbors = neighbors + grid[(i + x + 16) % 16][(j + y + 16) % 16];
                        end
                    end
                end
                case (neighbors)
                    3: next_grid[i][j] = 1;
                    2: next_grid[i][j] = grid[i][j];
                    default: next_grid[i][j] = 0;
                endcase
            end
        end
    end

    always @(posedge clk) begin
        if (load)
            q <= data;
        else
            q <= {next_grid[0], next_grid[1], next_grid[2], next_grid[3], next_grid[4], next_grid[5], next_grid[6], next_grid[7], next_grid[8], next_grid[9], next_grid[10], next_grid[11], next_grid[12], next_grid[13], next_grid[14], next_grid[15]};
    end

endmodule

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

    reg [255:0] q_next;

    integer i, j;
    wire [3:0] sum [15:0][15:0];
    reg [3:0] neighbors;

    // Calculate the number of neighbors for each cell
    always @* begin
        for (i = 0; i < 16; i = i + 1) begin
            for (j = 0; j < 16; j = j + 1) begin
                neighbors = 4'd0;
                neighbors = neighbors + q[(i*16 + ((j+15) % 16))];
                neighbors = neighbors + q[(i*16 + ((j+1) % 16))];
                neighbors = neighbors + q[(((i+15) % 16)*16) + j];
                neighbors = neighbors + q[(((i+1) % 16)*16) + j];
                neighbors = neighbors + q[(((i+15) % 16)*16) + ((j+15) % 16)];
                neighbors = neighbors + q[(((i+15) % 16)*16) + ((j+1) % 16)];
                neighbors = neighbors + q[(((i+1) % 16)*16) + ((j+15) % 16)];
                neighbors = neighbors + q[(((i+1) % 16)*16) + ((j+1) % 16)];

                sum[i][j] = neighbors;
            end
        end
    end

    // Calculate next state
    always @* begin
        for (i = 0; i < 16; i = i + 1) begin
            for (j = 0; j < 16; j = j + 1) begin
                case (sum[i][j])
                    4'd0, 4'd1: q_next[i*16 + j] = 1'b0;
                    4'd2: q_next[i*16 + j] = q[i*16 + j];
                    4'd3: q_next[i*16 + j] = 1'b1;
                    default: q_next[i*16 + j] = 1'b0;
                endcase
            end
        end
    end

    // Update the state
    always @(posedge clk) begin
        if (load) begin
            q <= data;
        end else begin
            q <= q_next;
        end
    end

endmodule

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

    integer i, j, idx, ni, nj, neighbor_idx;
    reg [3:0] neighbors;

    always @(posedge clk) begin
        if (load) begin
            q <= data;
        end else begin
            reg [255:0] next_q = 256'b0;

            for (i = 0; i < 16; i = i + 1) begin
                for (j = 0; j < 16; j = j + 1) begin
                    idx = i*16 + j;
                    neighbors = 0;

                    for (ni = i-1; ni <= i+1; ni = ni + 1) begin
                        for (nj = j-1; nj <= j+1; nj = nj + 1) begin
                            if (!(ni == i && nj == j)) begin
                                neighbor_idx = ((ni + 16) % 16) * 16 + ((nj + 16) % 16);
                                neighbors = neighbors + q[neighbor_idx];
                            end
                        end
                    end

                    case (neighbors)
                        2: next_q[idx] = q[idx];
                        3: next_q[idx] = 1'b1;
                        default: next_q[idx] = 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
);

    // Calculate the number of neighbors for a cell at (i, j) considering wrap-around
    function integer count_neighbors;
        input [255:0] grid;
        input integer i, j;
        integer ni, nj;
        begin
            count_neighbors = 0;
            for(ni = i-1; ni <= i+1; ni = ni+1) begin
                for(nj = j-1; nj <= j+1; nj = nj+1) begin
                    if(!(ni == i && nj == j)) begin
                        count_neighbors = count_neighbors + grid[((ni + 16) % 16) * 16 + ((nj + 16) % 16)];
                    end
                end
            end
        end
    endfunction

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

    always @(posedge clk) begin
        if (load) begin
            q <= data;
        end else begin
            // Calculate the next state of each cell
            for (i = 0; i < 16; i = i + 1) begin
                for (j = 0; j < 16; j = j + 1) begin
                    neighbors = count_neighbors(q, i, j);
                    if ((neighbors == 3) || (q[i * 16 + j] && neighbors == 2))
                        next_q[i * 16 + j] = 1;
                    else
                        next_q[i * 16 + j] = 0;
                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 [15:0] grid [15:0]; // 16x16 grid

    integer i, j;

    // Function to count the number of alive neighbors
    function integer count_neighbors;
        input integer row, col;
        integer r, c;
        begin
            count_neighbors = 0;
            for(r = -1; r <= 1; r = r + 1) begin
                for(c = -1; c <= 1; c = c + 1) begin
                    if(r != 0 || c != 0) begin
                        // Use toroidal addressing
                        if(grid[(row + r + 16) % 16][(col + c + 16) % 16])
                            count_neighbors = count_neighbors + 1;
                    end
                end
            end
        end
    endfunction

    always @(posedge clk) begin
        if (load) begin
            // Load new data into grid
            for (i = 0; i < 16; i = i + 1) begin
                grid[i] <= data[i*16 +: 16];
            end
        end
        else begin
            // Calculate next state
            reg [15:0] new_grid [15:0];
            for (i = 0; i < 16; i = i + 1) begin
                for (j = 0; j < 16; j = j + 1) begin
                    integer neighbors = count_neighbors(i, j);
                    if (neighbors <= 1 || neighbors >= 4)
                        new_grid[i][j] = 0;
                    else if (neighbors == 3)
                        new_grid[i][j] = 1;
                    else
                        new_grid[i][j] = grid[i][j];
                end
            end
            // Update the grid state
            for (i = 0; i < 16; i = i + 1) begin
                grid[i] <= new_grid[i];
            end
        end

        // Update q output
        for (i = 0; i < 16; i = i + 1) begin
            q[i*16 +: 16] <= grid[i];
        end
    end

endmodule

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

    // Function to count live neighbors considering toroidal wrapping
    function [3:0] count_neighbors;
        input [15:0][15:0] cells;
        input [3:0] row;
        input [3:0] col;
        integer r, c;
        begin
            count_neighbors = 0;
            for (r = -1; r <= 1; r = r + 1) begin
                for (c = -1; c <= 1; c = c + 1) begin
                    if (!(r == 0 && c == 0)) begin
                        count_neighbors = count_neighbors + cells[(row + r) & 4'hF][(col + c) & 4'hF];
                    end
                end
            end
        end
    endfunction

    reg [15:0][15:0] grid, next_grid;
    integer i, j;
    always @(posedge clk) begin
        if (load) begin
            for (i = 0; i < 16; i = i + 1) begin
                grid[i] <= data[i*16 +: 16];
            end
        end else begin
            for (i = 0; i < 16; i = i + 1) begin
                for (j = 0; j < 16; j = j + 1) begin
                    case (count_neighbors(grid, i, j))
                        4'h2: next_grid[i][j] <= grid[i][j];
                        4'h3: next_grid[i][j] <= 1'b1;
                        default: next_grid[i][j] <= 1'b0;
                    endcase
                end
            end
            grid <= next_grid;
        end
        for (i = 0; i < 16; i = i + 1) begin
            q[i*16 +: 16] <= grid[i];
        end
    end

endmodule

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

    reg [15:0] grid [15:0]; // Array to hold current grid state
    reg [15:0] new_grid [15:0]; // Array to compute new grid state

    integer i, j, k, l;
    integer ni, nj;
    integer neighbours;

    always @(posedge clk) begin
        if (load) begin
            for (i = 0; i < 16; i = i + 1) begin
                grid[i] <= data[(i+1)*16-1 -: 16]; // Load initial state
            end
        end else begin
            for (i = 0; i < 16; i = i + 1) begin
                for (j = 0; j < 16; j = j + 1) begin
                    neighbours = 0;
                    // Check 8 neighboring cells with wrap-around
                    for (k = -1; k <= 1; k = k + 1) begin
                        for (l = -1; l <= 1; l = l + 1) begin
                            if (k != 0 || l != 0) begin
                                ni = (i + k + 16) % 16;
                                nj = (j + l + 16) % 16;
                                neighbours = neighbours + grid[ni][nj];
                            end
                        end
                    end
                    // Update cell based on the game rules
                    if (neighbours < 2 || neighbours > 3)
                        new_grid[i][j] = 0;
                    else if (neighbours == 3)
                        new_grid[i][j] = 1;
                    else
                        new_grid[i][j] = grid[i][j];
                end
            end
            for (i = 0; i < 16; i = i + 1) begin
                grid[i] <= new_grid[i]; // Update grid with new state
            end
        end
        // Convert 2D grid into 256-bit vector q
        for (i = 0; i < 16; i = i + 1) begin
            q[(i+1)*16-1 -: 16] <= grid[i];
        end
    end

endmodule

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

    reg [15:0] grid[15:0];
    reg [15:0] next_grid[15:0];
    integer i, j;

    // Update the next_grid based on the rules of the game
    always @(*) begin
        for (i = 0; i < 16; i = i + 1) begin
            for (j = 0; j < 16; j = j + 1) begin
                // Count the number of alive neighbors
                integer alive_neighbors = 0;
                integer row, col;
                for (row = -1; row <= 1; row = row + 1) begin
                    for (col = -1; col <= 1; col = col + 1) begin
                        if (!(row == 0 && col == 0)) begin
                            alive_neighbors = alive_neighbors +
                                grid[(i + row + 16) % 16][(j + col + 16) % 16];
                        end
                    end
                end

                // Apply the rules of the game
                if (alive_neighbors < 2 || alive_neighbors > 3) begin
                    next_grid[i][j] = 0;
                end else if (alive_neighbors == 3) begin
                    next_grid[i][j] = 1;
                end else if (alive_neighbors == 2) begin
                    next_grid[i][j] = grid[i][j];
                end
            end
        end
    end

    // Load data or update grid state at each clock cycle
    always @(posedge clk) begin
        if (load) begin
            for (i = 0; i < 16; i = i + 1) begin
                grid[i] <= data[i*16 +: 16];
            end
        end else begin
            for (i = 0; i < 16; i = i + 1) begin
                grid[i] <= next_grid[i];
            end
        end
    end

    // Flatten the grid to a 256-bit vector
    always @(*) begin
        for (i = 0; i < 16; i = i + 1) begin
            q[i*16 +: 16] = grid[i];
        end
    end

endmodule


module top_module(
    input clk,
    input reset,
    output [3:1] ena,
    output reg [15:0] q);

    wire[3:0] carry; // carry signals for incrementing the higher decades

    // Compute enable signals, indicating when each decade should increment
    assign ena[1] = (q[3:0] == 4'b1001); // enable tens when ones digit reaches 9
    assign ena[2] = (q[7:4] == 4'b1001) && ena[1]; // enable hundreds when tens digit reaches 9 and is enabled
    assign ena[3] = (q[11:8] == 4'b1001) && ena[2]; // enable thousands when hundreds digit reaches 9 and is enabled

    // Reset or count logic
    always @(posedge clk) begin
        if (reset) begin
            q <= 16'd0;
        end else begin
            // Count logic for each digit
            if (q[3:0] == 4'b1001) begin
                q[3:0] <= 4'b0000;
            end else begin
                q[3:0] <= q[3:0] + 1;
            end

            if (ena[1]) begin
                if (q[7:4] == 4'b1001) begin
                    q[7:4] <= 4'b0000;
                end else begin
                    q[7:4] <= q[7:4] + 1;
                end
            end

            if (ena[2]) begin
                if (q[11:8] == 4'b1001) begin
                    q[11:8] <= 4'b0000;
                end else begin
                    q[11:8] <= q[11:8] + 1;
                end
            end

            if (ena[3]) begin
                if (q[15:12] == 4'b1001) begin
                    q[15:12] <= 4'b0000;
                end else begin
                    q[15:12] <= q[15:12] + 1;
                end
            end
        end
    end

endmodule

module top_module(
    input clk,
    input reset,
    output [3:1] ena,
    output reg [15:0] q);

    // Internal signals for enable signals
    wire ena1, ena2, ena3;

    // Assign enable conditions for each BCD digit
    assign ena1 = (q[3:0] == 4'd9);        // When ones digit reaches 9, tens digit enable
    assign ena2 = (q[7:4] == 4'd9) & ena1; // When tens digit reaches 9 and ones digit is at 9, hundreds digit enable
    assign ena3 = (q[11:8] == 4'd9) & ena2;// When hundreds digit reaches 9 and previous digits are maxed, thousands digit enable

    // Assign calculated enable signals
    assign ena = {ena3, ena2, ena1};

    always @(posedge clk or posedge reset) begin
        if (reset) begin
            q <= 16'b0; // Reset all digits to 0
        end
        else begin
            if (ena1) begin
                q[3:0] <= 4'b0; // Reset ones digit
                if (ena2) begin
                    q[7:4] <= 4'b0; // Reset tens digit
                    if (ena3) begin
                        q[11:8] <= 4'b0; // Reset hundreds digit
                        q[15:12] <= q[15:12] + 4'b1; // Increment thousands digit
                    end
                    else begin
                        q[11:8] <= q[11:8] + 4'b1; // Increment hundreds digit
                    end
                end
                else begin
                    q[7:4] <= q[7:4] + 4'b1; // Increment tens digit
                end
            end
            else begin
                q[3:0] <= q[3:0] + 4'b1; // Increment ones digit
            end
        end
    end

endmodule

module top_module(
	input clk,
	input reset,
	output [3:1] ena,
	output reg [15:0] q);

    always @(posedge clk) begin
        if (reset) begin
            q <= 16'b0;
        end else begin
            if (q[3:0] == 4'd9) begin
                q[3:0] <= 4'd0;
                if (q[7:4] == 4'd9) begin
                    q[7:4] <= 4'd0;
                    if (q[11:8] == 4'd9) begin
                        q[11:8] <= 4'd0;
                        if (q[15:12] == 4'd9) begin
                            q[15:12] <= 4'd0;
                        end else begin
                            q[15:12] <= q[15:12] + 1'b1;
                        end
                    end else begin
                        q[11:8] <= q[11:8] + 1'b1;
                    end
                end else begin
                    q[7:4] <= q[7:4] + 1'b1;
                end
            end else begin
                q[3:0] <= q[3:0] + 1'b1;
            end
        end
    end

    assign ena[1] = (q[3:0] == 4'd9);
    assign ena[2] = (q[7:4] == 4'd9) && ena[1];
    assign ena[3] = (q[11:8] == 4'd9) && ena[2];

endmodule

module top_module(
    input clk,
    input reset,
    output [3:1] ena,
    output reg [15:0] q);

    // Intermediate signals for enables
    reg [3:0] digits [3:0];
    integer i;

    // Assign enable outputs based on the counter digits
    assign ena[1] = (digits[0] == 4'd9);
    assign ena[2] = ena[1] && (digits[1] == 4'd9);
    assign ena[3] = ena[2] && (digits[2] == 4'd9);

    always @(posedge clk) begin
        if (reset) begin
            // Synchronous reset
            digits[0] <= 4'd0;
            digits[1] <= 4'd0;
            digits[2] <= 4'd0;
            digits[3] <= 4'd0;
        end else begin
            // Ones digit increment and rollover
            if (digits[0] == 4'd9) begin
                digits[0] <= 4'd0;
                // Tens digit increment and rollover
                if (digits[1] == 4'd9) begin
                    digits[1] <= 4'd0;
                    // Hundreds digit increment and rollover
                    if (digits[2] == 4'd9) begin
                        digits[2] <= 4'd0;
                        // Thousands digit increment
                        if (digits[3] == 4'd9) begin
                            digits[3] <= 4'd0;
                        end else begin
                            digits[3] <= digits[3] + 1;
                        end
                    end else begin
                        digits[2] <= digits[2] + 1;
                    end
                end else begin
                    digits[1] <= digits[1] + 1;
                end
            end else begin
                digits[0] <= digits[0] + 1;
            end
        end

        // Concatenate digits into output q
        q <= {digits[3], digits[2], digits[1], digits[0]};
    end
endmodule

module top_module(
    input clk,
    input reset,
    output [3:1] ena,
    output reg [15:0] q);

    always @(posedge clk) begin
        if (reset) begin
            q <= 16'b0;
        end else begin
            // Increment the ones digit
            if (q[3:0] == 4'd9) begin
                q[3:0] <= 4'd0;
                // Increment the tens digit when the ones digit overflows
                if (q[7:4] == 4'd9) begin
                    q[7:4] <= 4'd0;
                    // Increment the hundreds digit when the tens digit overflows
                    if (q[11:8] == 4'd9) begin
                        q[11:8] <= 4'd0;
                        // Increment the thousands digit when the hundreds digit overflows
                        if (q[15:12] == 4'd9) begin
                            q[15:12] <= 4'd0;
                        end else begin
                            q[15:12] <= q[15:12] + 1;
                        end
                    end else begin
                        q[11:8] <= q[11:8] + 1;
                    end
                end else begin
                    q[7:4] <= q[7:4] + 1;
                end
            end else begin
                q[3:0] <= q[3:0] + 1;
            end
        end
    end

    assign ena[1] = (q[3:0] == 4'd9);
    assign ena[2] = (q[7:4] == 4'd9 && q[3:0] == 4'd9);
    assign ena[3] = (q[11:8] == 4'd9 && q[7:4] == 4'd9 && q[3:0] == 4'd9);

endmodule

module top_module(
    input clk,
    input reset,
    output [3:1] ena,
    output reg [15:0] q);

    always @(posedge clk or posedge reset) begin
        if (reset) begin
            q <= 16'd0;
        end else begin
            // Increment the ones digit
            if (q[3:0] == 4'd9) begin
                q[3:0] <= 4'd0;
                ena[1] = 1'b1; // Enable tens digit increment
            end else begin
                q[3:0] <= q[3:0] + 1'b1;
                ena[1] = 1'b0;
            end

            // Increment the tens digit
            if (ena[1] && q[7:4] == 4'd9) begin
                q[7:4] <= 4'd0;
                ena[2] = 1'b1; // Enable hundreds digit increment
            end else if (ena[1]) begin
                q[7:4] <= q[7:4] + 1'b1;
                ena[2] = 1'b0;
            end else begin
                ena[2] = 1'b0;
            end

            // Increment the hundreds digit
            if (ena[2] && q[11:8] == 4'd9) begin
                q[11:8] <= 4'd0;
                ena[3] = 1'b1; // Enable thousands digit increment
            end else if (ena[2]) begin
                q[11:8] <= q[11:8] + 1'b1;
                ena[3] = 1'b0;
            end else begin
                ena[3] = 1'b0;
            end

            // Increment the thousands digit
            if (ena[3] && q[15:12] == 4'd9) begin
                q[15:12] <= 4'd0;
            end else if (ena[3]) begin
                q[15:12] <= q[15:12] + 1'b1;
            end
        end
    end

endmodule

module top_module(
    input clk,
    input reset,
    output [3:1] ena,
    output reg [15:0] q
);

    always @(posedge clk or posedge reset) begin
        if (reset) begin
            q <= 16'b0; // Reset all digits to 0
        end else begin
            // Ones digit increment
            if (q[3:0] == 4'b1001) begin
                q[3:0] <= 4'b0000; // Reset ones digit to 0
                q[7:4] <= q[7:4] + 1'b1; // Enable tens increment
            end else begin
                q[3:0] <= q[3:0] + 1'b1;
            end

            // Tens digit increment
            if (q[7:4] == 4'b1010) begin
                q[7:4] <= 4'b0000; // Reset tens digit to 0
                q[11:8] <= q[11:8] + 1'b1; // Enable hundreds increment
            end

            // Hundreds digit increment
            if (q[11:8] == 4'b1010) begin
                q[11:8] <= 4'b0000; // Reset hundreds digit to 0
                q[15:12] <= q[15:12] + 1'b1; // Enable thousands increment
            end

            // Thousands digit increment
            if (q[15:12] == 4'b1010) begin
                q[15:12] <= 4'b0000; // Reset thousands digit to 0
            end
        end
    end

    // Enable signals for increment
    assign ena[3] = (q[11:8] == 4'b1001) && (q[7:4] == 4'b1001) && (q[3:0] == 4'b1001);
    assign ena[2] = (q[7:4] == 4'b1001) && (q[3:0] == 4'b1001);
    assign ena[1] = (q[3:0] == 4'b1001);

endmodule

module top_module(
    input clk,
    input reset,
    output [3:1] ena,
    output reg [15:0] q);

    always @(posedge clk or posedge reset) begin
        if (reset) begin
            q <= 16'b0;
        end
        else begin
            // Increment ones digit
            if (q[3:0] == 4'd9) begin
                q[3:0] <= 4'd0;
                ena[1] <= 1'b1;  // Enable tens digit increment
            end else begin
                q[3:0] <= q[3:0] + 4'd1;
                ena[1] <= 1'b0;
            end

            // Increment tens digit
            if (ena[1]) begin
                if (q[7:4] == 4'd9) begin
                    q[7:4] <= 4'd0;
                    ena[2] <= 1'b1;  // Enable hundreds digit increment
                end else begin
                    q[7:4] <= q[7:4] + 4'd1;
                    ena[2] <= 1'b0;
                end
            end

            // Increment hundreds digit
            if (ena[2]) begin
                if (q[11:8] == 4'd9) begin
                    q[11:8] <= 4'd0;
                    ena[3] <= 1'b1;  // Enable thousands digit increment
                end else begin
                    q[11:8] <= q[11:8] + 4'd1;
                    ena[3] <= 1'b0;
                end
            end

            // Increment thousands digit
            if (ena[3]) begin
                if (q[15:12] == 4'd9) begin
                    q[15:12] <= 4'd0;
                end else begin
                    q[15:12] <= q[15:12] + 4'd1;
                end
            end
        end
    end

endmodule

module top_module(
    input clk,
    input reset,
    output [3:1] ena,
    output reg [15:0] q);

    always @(posedge clk) begin
        if (reset) begin
            q <= 16'b0;
        end else begin
            // Ones digit
            if (q[3:0] == 4'd9) begin
                q[3:0] <= 4'd0;
                ena[1] <= 1;
            end else begin
                q[3:0] <= q[3:0] + 1;
                ena[1] <= 0;
            end

            // Tens digit
            if (ena[1]) begin
                if (q[7:4] == 4'd9) begin
                    q[7:4] <= 4'd0;
                    ena[2] <= 1;
                end else begin
                    q[7:4] <= q[7:4] + 1;
                    ena[2] <= 0;
                end
            end

            // Hundreds digit
            if (ena[2]) begin
                if (q[11:8] == 4'd9) begin
                    q[11:8] <= 4'd0;
                    ena[3] <= 1;
                end else begin
                    q[11:8] <= q[11:8] + 1;
                    ena[3] <= 0;
                end
            end

            // Thousands digit
            if (ena[3]) begin
                if (q[15:12] == 4'd9) begin
                    q[15:12] <= 4'd0;
                end else begin
                    q[15:12] <= q[15:12] + 1;
                end
            end
        end
    end

endmodule

module top_module(
    input clk,
    input reset,
    output [3:1] ena,
    output reg [15:0] q);

    always @(posedge clk) begin
        if (reset)
            q <= 16'b0;
        else begin
            // increment ones digit
            if (q[3:0] == 4'd9) begin
                q[3:0] <= 4'd0;
                // enable tens digit
                if (q[7:4] == 4'd9) begin
                    q[7:4] <= 4'd0;
                    // enable hundreds digit
                    if (q[11:8] == 4'd9) begin
                        q[11:8] <= 4'd0;
                        // enable thousands digit
                        if (q[15:12] == 4'd9) begin
                            q[15:12] <= 4'd0;
                        end else begin
                            q[15:12] <= q[15:12] + 4'd1;
                        end
                    end else begin
                        q[11:8] <= q[11:8] + 4'd1;
                    end
                end else begin
                    q[7:4] <= q[7:4] + 4'd1;
                end
            end else begin
                q[3:0] <= q[3:0] + 4'd1;
            end
        end
    end

    assign ena[1] = (q[3:0] == 4'd9);
    assign ena[2] = (ena[1] & (q[7:4] == 4'd9));
    assign ena[3] = (ena[2] & (q[11:8] == 4'd9));

endmodule

module top_module(
    input clk,
    input reset,
    output [3:1] ena,
    output reg [15:0] q
);

    // Enable signals for each of the upper three digits
    assign ena[1] = (q[3:0] == 4'd9);
    assign ena[2] = (q[7:4] == 4'd9) && ena[1];
    assign ena[3] = (q[11:8] == 4'd9) && ena[2];

    always @(posedge clk) begin
        if (reset) begin
            q <= 16'd0;
        end else begin
            // Increment ones digit
            if (q[3:0] == 4'd9) begin
                q[3:0] <= 4'd0;
            end else begin
                q[3:0] <= q[3:0] + 1;
            end

            // Increment tens digit
            if (ena[1]) begin
                if (q[7:4] == 4'd9) begin
                    q[7:4] <= 4'd0;
                end else begin
                    q[7:4] <= q[7:4] + 1;
                end
            end

            // Increment hundreds digit
            if (ena[2]) begin
                if (q[11:8] == 4'd9) begin
                    q[11:8] <= 4'd0;
                end else begin
                    q[11:8] <= q[11:8] + 1;
                end
            end

            // Increment thousands digit
            if (ena[3]) begin
                if (q[15:12] == 4'd9) begin
                    q[15:12] <= 4'd0;
                end else begin
                    q[15:12] <= q[15:12] + 1;
                end
            end
        end
    end
endmodule

module top_module(
    input clk,
    input reset,
    output [3:1] ena,
    output reg [15:0] q
);

    // Enable logic for the tens, hundreds, and thousands place
    assign ena[1] = (q[3:0] == 4'd9);          // Enable for tens digit
    assign ena[2] = ena[1] & (q[7:4] == 4'd9); // Enable for hundreds digit
    assign ena[3] = ena[2] & (q[11:8] == 4'd9); // Enable for thousands digit

    always @(posedge clk or posedge reset) begin
        if (reset) begin
            q <= 16'd0; // Reset all digits to zero
        end else begin
            if (q[3:0] == 4'd9) begin
                q[3:0] <= 4'd0; // Ones digit overflow
                if (q[7:4] == 4'd9) begin
                    q[7:4] <= 4'd0; // Tens digit overflow
                    if (q[11:8] == 4'd9) begin
                        q[11:8] <= 4'd0; // Hundreds digit overflow
                        if (q[15:12] == 4'd9) begin
                            q[15:12] <= 4'd0; // Thousands digit overflow
                        end else begin
                            q[15:12] <= q[15:12] + 4'd1;
                        end
                    end else begin
                        q[11:8] <= q[11:8] + 4'd1;
                    end
                end else begin
                    q[7:4] <= q[7:4] + 4'd1;
                end
            end else begin
                q[3:0] <= q[3:0] + 4'd1;
            end
        end
    end

endmodule

module top_module(
    input clk,
    input reset,
    output [3:1] ena,
    output reg [15:0] q);

    always @(posedge clk) begin
        if (reset) begin
            q <= 16'b0;
        end
        else begin
            // Increment ones digit
            if (q[3:0] == 4'd9) begin
                q[3:0] <= 4'd0;
                if (q[7:4] == 4'd9) begin
                    q[7:4] <= 4'd0;
                    if (q[11:8] == 4'd9) begin
                        q[11:8] <= 4'd0;
                        if (q[15:12] == 4'd9) begin
                            q[15:12] <= 4'd0;
                            // No carry to output since it's the highest digit
                        end
                        else begin
                            q[15:12] <= q[15:12] + 4'd1;
                        end
                    end
                    else begin
                        q[11:8] <= q[11:8] + 4'd1;
                    end
                end
                else begin
                    q[7:4] <= q[7:4] + 4'd1;
                end
            end
            else begin
                q[3:0] <= q[3:0] + 4'd1;
            end
        end
    end

    // Enable signals
    assign ena[1] = (q[3:0] == 4'd9);     // ones to tens
    assign ena[2] = (q[3:0] == 4'd9) && (q[7:4] == 4'd9);  // tens to hundreds
    assign ena[3] = (q[3:0] == 4'd9) && (q[7:4] == 4'd9) && (q[11:8] == 4'd9); // hundreds to thousands

endmodule

module top_module(
    input clk,
    input reset,
    output [3:1] ena,
    output reg [15:0] q);

    always @(posedge clk or posedge reset) begin
        if (reset) begin
            q <= 16'b0;
        end else begin
            // Increment the ones place
            if (q[3:0] == 4'd9) begin
                q[3:0] <= 4'd0;
                // Increment the tens place
                if (q[7:4] == 4'd9) begin
                    q[7:4] <= 4'd0;
                    // Increment the hundreds place
                    if (q[11:8] == 4'd9) begin
                        q[11:8] <= 4'd0;
                        // Increment the thousands place
                        if (q[15:12] == 4'd9) begin
                            q[15:12] <= 4'd0;
                        end else begin
                            q[15:12] <= q[15:12] + 1;
                        end
                    end else begin
                        q[11:8] <= q[11:8] + 1;
                    end
                end else begin
                    q[7:4] <= q[7:4] + 1;
                end
            end else begin
                q[3:0] <= q[3:0] + 1;
            end
        end
    end

    assign ena[1] = (q[3:0] == 4'd9);
    assign ena[2] = (q[7:4] == 4'd9) & ena[1];
    assign ena[3] = (q[11:8] == 4'd9) & ena[2];

endmodule

module top_module(
    input clk,
    input reset,
    output [3:1] ena,
    output reg [15:0] q);

    // Combinatorial logic to determine when to enable the increment of the next BCD digit
    assign ena[1] = (q[3:0] == 4'd9);
    assign ena[2] = ena[1] && (q[7:4] == 4'd9);
    assign ena[3] = ena[2] && (q[11:8] == 4'd9);

    always @(posedge clk) begin
        if (reset) begin
            q <= 16'b0; // On reset, set the counter to 0
        end else begin
            // Ones digit
            if (q[3:0] == 4'd9) begin
                q[3:0] <= 4'd0;
            end else begin
                q[3:0] <= q[3:0] + 4'd1;
            end

            // Tens digit
            if (ena[1]) begin
                if (q[7:4] == 4'd9) begin
                    q[7:4] <= 4'd0;
                end else begin
                    q[7:4] <= q[7:4] + 4'd1;
                end
            end

            // Hundreds digit
            if (ena[2]) begin
                if (q[11:8] == 4'd9) begin
                    q[11:8] <= 4'd0;
                end else begin
                    q[11:8] <= q[11:8] + 4'd1;
                end
            end

            // Thousands digit
            if (ena[3]) begin
                if (q[15:12] == 4'd9) begin
                    q[15:12] <= 4'd0;
                end else begin
                    q[15:12] <= q[15:12] + 4'd1;
                end
            end
        end
    end
endmodule

module top_module(
    input clk,
    input reset,
    output [3:1] ena,
    output reg [15:0] q
);

    assign ena[1] = (q[3:0] == 4'd9);
    assign ena[2] = ena[1] && (q[7:4] == 4'd9);
    assign ena[3] = ena[2] && (q[11:8] == 4'd9);

    always @(posedge clk) begin
        if (reset) begin
            q <= 16'd0;
        end else begin
            // Ones digit
            if (q[3:0] == 4'd9) begin
                q[3:0] <= 4'd0;
            end else begin
                q[3:0] <= q[3:0] + 4'd1;
            end

            // Tens digit
            if (ena[1]) begin
                if (q[7:4] == 4'd9) begin
                    q[7:4] <= 4'd0;
                end else begin
                    q[7:4] <= q[7:4] + 4'd1;
                end
            end

            // Hundreds digit
            if (ena[2]) begin
                if (q[11:8] == 4'd9) begin
                    q[11:8] <= 4'd0;
                end else begin
                    q[11:8] <= q[11:8] + 4'd1;
                end
            end

            // Thousands digit
            if (ena[3]) begin
                if (q[15:12] == 4'd9) begin
                    q[15:12] <= 4'd0;
                end else begin
                    q[15:12] <= q[15:12] + 4'd1;
                end
            end
        end
    end

endmodule

module top_module(
    input clk,
    input reset,
    output [3:1] ena,
    output reg [15:0] q
);

    always @(posedge clk) begin
        if (reset) begin
            q <= 16'b0;
        end else begin
            // Ones digit
            if (q[3:0] == 4'd9) begin
                q[3:0] <= 4'd0;
                ena[1] <= 1'b1;
            end else begin
                q[3:0] <= q[3:0] + 4'd1;
                ena[1] <= 1'b0;
            end

            // Tens digit
            if (ena[1]) begin
                if (q[7:4] == 4'd9) begin
                    q[7:4] <= 4'd0;
                    ena[2] <= 1'b1;
                end else begin
                    q[7:4] <= q[7:4] + 4'd1;
                    ena[2] <= 1'b0;
                end
            end else begin
                ena[2] <= 1'b0;
            end

            // Hundreds digit
            if (ena[2]) begin
                if (q[11:8] == 4'd9) begin
                    q[11:8] <= 4'd0;
                    ena[3] <= 1'b1;
                end else begin
                    q[11:8] <= q[11:8] + 4'd1;
                    ena[3] <= 1'b0;
                end
            end else begin
                ena[3] <= 1'b0;
            end

            // Thousands digit
            if (ena[3]) begin
                if (q[15:12] == 4'd9) begin
                    q[15:12] <= 4'd0;
                end else begin
                    q[15:12] <= q[15:12] + 4'd1;
                end
            end
        end
    end

endmodule

module top_module(
    input clk,
    input reset,
    output [3:1] ena,
    output reg [15:0] q);

    always @(posedge clk) begin
        if (reset) begin
            q <= 16'b0;
        end else begin
            // Ones digit
            if (q[3:0] == 4'd9) begin
                q[3:0] <= 4'd0;

                // Tens digit
                if (q[7:4] == 4'd9) begin
                    q[7:4] <= 4'd0;

                    // Hundreds digit
                    if (q[11:8] == 4'd9) begin
                        q[11:8] <= 4'd0;

                        // Thousands digit
                        if (q[15:12] == 4'd9) begin
                            q[15:12] <= 4'd0;
                        end else begin
                            q[15:12] <= q[15:12] + 4'd1;
                        end
                    end else begin
                        q[11:8] <= q[11:8] + 4'd1;
                    end
                end else begin
                    q[7:4] <= q[7:4] + 4'd1;
                end
            end else begin
                q[3:0] <= q[3:0] + 4'd1;
            end
        end
    end

    assign ena[1] = (q[3:0] == 4'd9);
    assign ena[2] = (q[3:0] == 4'd9) && (q[7:4] == 4'd9);
    assign ena[3] = (q[3:0] == 4'd9) && (q[7:4] == 4'd9) && (q[11:8] == 4'd9);

endmodule

module top_module(
    input clk,
    input reset,
    output [3:1] ena,
    output reg [15:0] q);

    always @(posedge clk) begin
        if (reset) begin
            q <= 16'b0;
        end else begin
            // Ones digit
            if (q[3:0] == 4'd9) begin
                q[3:0] <= 4'd0;
                ena[1] <= 1'b1;
            end else begin
                q[3:0] <= q[3:0] + 4'd1;
                ena[1] <= 1'b0;
            end

            // Tens digit
            if (ena[1]) begin
                if (q[7:4] == 4'd9) begin
                    q[7:4] <= 4'd0;
                    ena[2] <= 1'b1;
                end else begin
                    q[7:4] <= q[7:4] + 4'd1;
                    ena[2] <= 1'b0;
                end
            end else begin
                ena[2] <= 1'b0;
            end

            // Hundreds digit
            if (ena[2]) begin
                if (q[11:8] == 4'd9) begin
                    q[11:8] <= 4'd0;
                    ena[3] <= 1'b1;
                end else begin
                    q[11:8] <= q[11:8] + 4'd1;
                    ena[3] <= 1'b0;
                end
            end else begin
                ena[3] <= 1'b0;
            end

            // Thousands digit
            if (ena[3]) begin
                if (q[15:12] == 4'd9) begin
                    q[15:12] <= 4'd0;
                end else begin
                    q[15:12] <= q[15:12] + 4'd1;
                end
            end
        end
    end

endmodule

module top_module(
	input clk,
	input reset,
	output [3:1] ena,
	output reg [15:0] q);

    // Internal carry signals for enabling digit increments
    wire carry0, carry1, carry2;

    // Reset or increment ones digit
    always @(posedge clk) begin
        if (reset)
            q[3:0] <= 4'b0000;
        else if (q[3:0] == 4'b1001)
            q[3:0] <= 4'b0000;
        else
            q[3:0] <= q[3:0] + 1;
    end

    // Enable signal for tens digit, high when ones digit is about to overflow
    assign carry0 = (q[3:0] == 4'b1001);

    // Reset or increment tens digit
    always @(posedge clk) begin
        if (reset)
            q[7:4] <= 4'b0000;
        else if (carry0 && q[7:4] == 4'b1001)
            q[7:4] <= 4'b0000;
        else if (carry0)
            q[7:4] <= q[7:4] + 1;
    end

    // Enable signal for hundreds digit, high when tens digit is about to overflow
    assign carry1 = carry0 && (q[7:4] == 4'b1001);

    // Reset or increment hundreds digit
    always @(posedge clk) begin
        if (reset)
            q[11:8] <= 4'b0000;
        else if (carry1 && q[11:8] == 4'b1001)
            q[11:8] <= 4'b0000;
        else if (carry1)
            q[11:8] <= q[11:8] + 1;
    end

    // Enable signal for thousands digit, high when hundreds digit is about to overflow
    assign carry2 = carry1 && (q[11:8] == 4'b1001);

    // Reset or increment thousands digit
    always @(posedge clk) begin
        if (reset)
            q[15:12] <= 4'b0000;
        else if (carry2 && q[15:12] == 4'b1001)
            q[15:12] <= 4'b0000;
        else if (carry2)
            q[15:12] <= q[15:12] + 1;
    end

    // Enable signals for each of the upper three digits
    assign ena = {carry2, carry1, carry0};

endmodule