module top_module (
	input clk,
	input in,
	input reset,
	output reg done
);

	localparam IDLE = 3'b000;
	localparam START = 3'b001;
	localparam DATA = 3'b010;
	localparam STOP = 3'b011;
	localparam ERROR = 3'b100;

	reg [2:0] state, next_state;
	reg [3:0] bit_count;

	always @(posedge clk) begin
		if (reset) begin
			state <= IDLE;
			bit_count <= 0;
			done <= 0;
		end else begin
			state <= next_state;
			if (state == DATA)
				bit_count <= bit_count + 1;
			else
				bit_count <= 0;
		end
	end

	always @(*) begin
		next_state = state;
		done = 0;
		case (state)
			IDLE: begin
				if (!in)
					next_state = START;
			end
			START: begin
				next_state = DATA;
			end
			DATA: begin
				if (bit_count == 4'b0111)
					next_state = STOP;
			end
			STOP: begin
				if (in) begin
					done = 1;
					next_state = IDLE;
				end else
					next_state = ERROR;
			end
			ERROR: begin
				if (in)
					next_state = IDLE;
			end
		endcase
	end

endmodule

module top_module (
	input clk,
	input in,
	input reset,
	output reg done
);

	localparam IDLE = 3'd0;
	localparam START = 3'd1;
	localparam DATA = 3'd2;
	localparam STOP = 3'd3;
	localparam ERROR = 3'd4;

	reg [2:0] state, next_state;
	reg [3:0] bit_count;

	always @(posedge clk) begin
		if (reset) begin
			state <= IDLE;
			bit_count <= 0;
		end else begin
			state <= next_state;
			if (state == DATA)
				bit_count <= bit_count + 1;
			else
				bit_count <= 0;
		end
	end

	always @(*) begin
		next_state = state;
		done = 1'b0;

		case (state)
			IDLE: begin
				if (~in) next_state = START;
			end
			START: begin
				next_state = DATA;
			end
			DATA: begin
				if (bit_count == 4'd7) begin
					if (in) next_state = STOP;
					else next_state = ERROR;
				end
			end
			STOP: begin
				done = 1'b1;
				next_state = IDLE;
			end
			ERROR: begin
				if (in) next_state = IDLE;
			end
		endcase
	end

endmodule

module top_module (
	input clk,
	input in,
	input reset,
	output reg done
);

    localparam IDLE = 3'd0;
    localparam START = 3'd1;
    localparam DATA = 3'd2;
    localparam STOP = 3'd3;
    localparam ERROR = 3'd4;

    reg [2:0] state, next_state;
    reg [3:0] bit_count;

    always @(posedge clk) begin
        if (reset) begin
            state <= IDLE;
            bit_count <= 0;
            done <= 0;
        end else begin
            state <= next_state;
            if (state == DATA)
                bit_count <= bit_count + 1;
            else
                bit_count <= 0;
        end
    end

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

        case (state)
            IDLE: begin
                if (!in)
                    next_state = START;
            end
            START: begin
                next_state = DATA;
            end
            DATA: begin
                if (bit_count == 4'd7)
                    next_state = STOP;
            end
            STOP: begin
                if (in) begin
                    next_state = IDLE;
                    done = 1;
                end else
                    next_state = ERROR;
            end
            ERROR: begin
                if (in)
                    next_state = IDLE;
            end
        endcase
    end

endmodule

module top_module (
    input clk,
    input in,
    input reset,
    output done
);

    parameter IDLE = 3'd0, START = 3'd1, DATA = 3'd2, STOP = 3'd3, ERROR = 3'd4;

    reg [2:0] state, next_state;
    reg [3:0] bit_count;

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

    always @(posedge clk) begin
        if (reset)
            bit_count <= 0;
        else if (state == DATA)
            bit_count <= bit_count + 1;
        else
            bit_count <= 0;
    end

    always @(*) begin
        case (state)
            IDLE: next_state = (in == 0) ? START : IDLE;
            START: next_state = DATA;
            DATA: next_state = (bit_count == 4'd7) ? STOP : DATA;
            STOP: next_state = (in == 1) ? IDLE : ERROR;
            ERROR: next_state = (in == 1) ? IDLE : ERROR;
            default: next_state = IDLE;
        endcase
    end

    assign done = (state == STOP) && (in == 1);

endmodule

module top_module (
	input clk,
	input in,
	input reset,
	output reg done
);

    parameter IDLE = 3'd0, START = 3'd1, DATA = 3'd2, STOP = 3'd3, ERROR = 3'd4;
    reg [2:0] state, next_state;
    reg [3:0] bit_count;

    always @(posedge clk) begin
        if (reset) begin
            state <= IDLE;
            bit_count <= 0;
            done <= 0;
        end else begin
            state <= next_state;
            if (state == DATA)
                bit_count <= bit_count + 1;
            else
                bit_count <= 0;
        end
    end

    always @(*) begin
        next_state = state;
        done = 0;
        case (state)
            IDLE: if (~in) next_state = START;
            START: next_state = DATA;
            DATA: begin
                if (bit_count == 7) begin
                    if (in) next_state = STOP;
                    else next_state = ERROR;
                end
            end
            STOP: begin
                done = 1;
                next_state = IDLE;
            end
            ERROR: if (in) next_state = IDLE;
        endcase
    end

endmodule

module top_module (
	input clk,
	input in,
	input reset,
	output reg done
);

    localparam IDLE = 3'd0;
    localparam START = 3'd1;
    localparam DATA = 3'd2;
    localparam STOP = 3'd3;
    localparam ERROR = 3'd4;

    reg [2:0] state, next_state;
    reg [3:0] bit_count;

    always @(posedge clk) begin
        if (reset) begin
            state <= IDLE;
            bit_count <= 4'd0;
        end else begin
            state <= next_state;
            if (state == DATA)
                bit_count <= bit_count + 1;
            else
                bit_count <= 4'd0;
        end
    end

    always @(*) begin
        next_state = state;
        done = 1'b0;

        case (state)
            IDLE: begin
                if (!in) next_state = START;
            end
            START: begin
                next_state = DATA;
            end
            DATA: begin
                if (bit_count == 4'd7) begin
                    if (in) next_state = STOP;
                    else next_state = ERROR;
                end
            end
            STOP: begin
                done = 1'b1;
                next_state = IDLE;
            end
            ERROR: begin
                if (in) next_state = IDLE;
            end
        endcase
    end

endmodule

module top_module (
	input clk,
	input in,
	input reset,
	output reg done
);

    localparam IDLE = 3'd0;
    localparam START = 3'd1;
    localparam DATA = 3'd2;
    localparam STOP = 3'd3;
    localparam ERROR = 3'd4;

    reg [2:0] state, next_state;
    reg [3:0] bit_count;

    always @(posedge clk) begin
        if (reset) begin
            state <= IDLE;
            bit_count <= 4'd0;
        end else begin
            state <= next_state;
            if (state == DATA)
                bit_count <= bit_count + 1;
            else
                bit_count <= 4'd0;
        end
    end

    always @(*) begin
        next_state = state;
        done = 1'b0;

        case (state)
            IDLE: begin
                if (!in) next_state = START;
            end
            START: begin
                next_state = DATA;
            end
            DATA: begin
                if (bit_count == 4'd7) begin
                    next_state = STOP;
                end
            end
            STOP: begin
                if (in) begin
                    next_state = IDLE;
                    done = 1'b1;
                end else begin
                    next_state = ERROR;
                end
            end
            ERROR: begin
                if (in) next_state = IDLE;
            end
        endcase
    end

endmodule

module top_module (
	input clk,
	input in,
	input reset,
	output done
);

    parameter IDLE = 3'd0, START = 3'd1, DATA = 3'd2, STOP = 3'd3, ERROR = 3'd4;

    reg [2:0] state, next_state;
    reg [3:0] bit_count;

    always @(posedge clk or posedge reset) begin
        if (reset) begin
            state <= IDLE;
            bit_count <= 4'd0;
        end else begin
            state <= next_state;
            if (state == DATA)
                bit_count <= bit_count + 1;
            else
                bit_count <= 4'd0;
        end
    end

    always @(*) begin
        next_state = state;
        case (state)
            IDLE: if (!in) next_state = START;
            START: next_state = DATA;
            DATA: if (bit_count == 4'd7) next_state = STOP;
            STOP: next_state = in ? IDLE : ERROR;
            ERROR: if (in) next_state = IDLE;
        endcase
    end

    assign done = (state == STOP) && in;

endmodule

module top_module (
	input clk,
	input in,
	input reset,
	output reg done
);

	parameter IDLE = 3'd0;
	parameter START = 3'd1;
	parameter DATA = 3'd2;
	parameter STOP = 3'd3;
	parameter ERROR = 3'd4;

	reg [2:0] state, next_state;
	reg [3:0] bit_count;

	always @(posedge clk or posedge reset) begin
		if (reset) begin
			state <= IDLE;
			bit_count <= 4'd0;
			done <= 1'b0;
		end else begin
			state <= next_state;
			if (state == DATA)
				bit_count <= bit_count + 1;
			else
				bit_count <= 4'd0;
		end
	end

	always @(*) begin
		next_state = state;
		done = 1'b0;
		case (state)
			IDLE: begin
				if (in == 1'b0)
					next_state = START;
			end
			START: begin
				next_state = DATA;
			end
			DATA: begin
				if (bit_count == 4'd7)
					next_state = STOP;
			end
			STOP: begin
				if (in == 1'b1) begin
					next_state = IDLE;
					done = 1'b1;
				end else
					next_state = ERROR;
			end
			ERROR: begin
				if (in == 1'b1)
					next_state = IDLE;
			end
		endcase
	end

endmodule

module top_module (
	input clk,
	input in,
	input reset,
	output reg done
);

    reg [3:0] state, next_state;
    reg [3:0] bit_count;

    localparam IDLE = 4'd0,
               START = 4'd1,
               DATA = 4'd2,
               STOP = 4'd3,
               ERROR = 4'd4;

    always @(posedge clk) begin
        if (reset) begin
            state <= IDLE;
            bit_count <= 0;
        end else begin
            state <= next_state;
            if (state == DATA)
                bit_count <= bit_count + 1;
            else
                bit_count <= 0;
        end
    end

    always @(*) begin
        next_state = state;
        done = 1'b0;

        case (state)
            IDLE: begin
                if (~in) next_state = START;
            end
            START: begin
                next_state = DATA;
            end
            DATA: begin
                if (bit_count == 4'd7) next_state = STOP;
            end
            STOP: begin
                if (in) begin
                    next_state = IDLE;
                    done = 1'b1;
                end else begin
                    next_state = ERROR;
                end
            end
            ERROR: begin
                if (in) next_state = IDLE;
            end
        endcase
    end

endmodule

module top_module (
	input clk,
	input in,
	input reset,
	output reg done
);

	localparam IDLE = 3'd0;
	localparam START = 3'd1;
	localparam DATA = 3'd2;
	localparam STOP = 3'd3;
	localparam ERROR = 3'd4;

	reg [2:0] state, next_state;
	reg [3:0] bit_count;

	always @(posedge clk) begin
		if (reset) begin
			state <= IDLE;
			bit_count <= 0;
		end else begin
			state <= next_state;
			if (state == DATA)
				bit_count <= bit_count + 1;
			else
				bit_count <= 0;
		end
	end

	always @(*) begin
		next_state = state;
		done = 1'b0;

		case (state)
			IDLE: begin
				if (!in) next_state = START;
			end
			START: begin
				next_state = DATA;
			end
			DATA: begin
				if (bit_count == 4'd7) begin
					if (in) next_state = STOP;
					else next_state = ERROR;
				end
			end
			STOP: begin
				done = 1'b1;
				next_state = IDLE;
			end
			ERROR: begin
				if (in) next_state = IDLE;
			end
		endcase
	end

endmodule

module top_module (
	input clk,
	input in,
	input reset,
	output reg done
);

	localparam IDLE = 3'd0,
			   START = 3'd1,
			   DATA = 3'd2,
			   STOP = 3'd3,
			   ERROR = 3'd4;

	reg [2:0] state, next_state;
	reg [3:0] bit_count;

	always @(posedge clk) begin
		if (reset) begin
			state <= IDLE;
			bit_count <= 0;
		end else begin
			state <= next_state;
			if (state == DATA)
				bit_count <= bit_count + 1;
			else
				bit_count <= 0;
		end
	end

	always @(*) begin
		next_state = state;
		done = 1'b0;

		case (state)
			IDLE: begin
				if (~in) next_state = START;
			end
			START: begin
				next_state = DATA;
			end
			DATA: begin
				if (bit_count == 4'd7) begin
					next_state = STOP;
				end
			end
			STOP: begin
				if (in) begin
					done = 1'b1;
					next_state = IDLE;
				end else begin
					next_state = ERROR;
				end
			end
			ERROR: begin
				if (in) next_state = IDLE;
			end
		endcase
	end

endmodule

module top_module (
	input clk,
	input in,
	input reset,
	output reg done
);

    parameter IDLE = 3'd0, START = 3'd1, DATA = 3'd2, STOP = 3'd3, ERROR = 3'd4;
    reg [2:0] state, next_state;
    reg [3:0] bit_count;

    always @(posedge clk) begin
        if (reset) begin
            state <= IDLE;
            bit_count <= 0;
            done <= 0;
        end else begin
            state <= next_state;
            if (state == DATA)
                bit_count <= bit_count + 1;
            else
                bit_count <= 0;
        end
    end

    always @(*) begin
        next_state = state;
        done = 0;
        case (state)
            IDLE: if (~in) next_state = START;
            START: next_state = DATA;
            DATA: begin
                if (bit_count == 4'd7) begin
                    if (in) next_state = STOP;
                    else next_state = ERROR;
                end
            end
            STOP: begin
                if (in) begin
                    next_state = IDLE;
                    done = 1;
                end else begin
                    next_state = ERROR;
                end
            end
            ERROR: if (in) next_state = IDLE;
        endcase
    end

endmodule

module top_module (
	input clk,
	input in,
	input reset,
	output reg done
);

    localparam IDLE = 3'd0, START = 3'd1, DATA = 3'd2, STOP = 3'd3, ERROR = 3'd4;
    reg [2:0] state, next_state;
    reg [3:0] bit_count;

    always @(posedge clk or posedge reset) begin
        if (reset) begin
            state <= IDLE;
            bit_count <= 0;
            done <= 0;
        end else begin
            state <= next_state;
            if (state == DATA)
                bit_count <= bit_count + 1;
            else
                bit_count <= 0;
        end
    end

    always @(*) begin
        next_state = state;
        done = 0;
        case (state)
            IDLE: begin
                if (~in) next_state = START;
            end
            START: begin
                next_state = DATA;
            end
            DATA: begin
                if (bit_count == 7)
                    next_state = STOP;
            end
            STOP: begin
                if (in) begin
                    next_state = IDLE;
                    done = 1;
                end else begin
                    next_state = ERROR;
                end
            end
            ERROR: begin
                if (in) next_state = IDLE;
            end
        endcase
    end

endmodule

module top_module (
	input clk,
	input in,
	input reset,
	output done
);

    localparam IDLE = 3'd0;
    localparam START = 3'd1;
    localparam DATA = 3'd2;
    localparam STOP = 3'd3;
    localparam ERROR = 3'd4;

    reg [2:0] state, next_state;
    reg [3:0] bit_count;
    reg done_reg;

    always @(posedge clk) begin
        if (reset) begin
            state <= IDLE;
            bit_count <= 4'd0;
        end else begin
            state <= next_state;
            if (state == DATA)
                bit_count <= bit_count + 1;
            else
                bit_count <= 4'd0;
        end
    end

    always @(*) begin
        next_state = state;
        done_reg = 1'b0;
        case (state)
            IDLE: if (!in) next_state = START;
            START: next_state = DATA;
            DATA: begin
                if (bit_count == 4'd7) begin
                    if (in) next_state = STOP;
                    else next_state = ERROR;
                end
            end
            STOP: begin
                done_reg = 1'b1;
                if (in) next_state = IDLE;
                else next_state = START;
            end
            ERROR: if (in) next_state = IDLE;
        endcase
    end

    assign done = done_reg;

endmodule

module top_module (
	input clk,
	input in,
	input reset,
	output reg done
);

    reg [3:0] state;
    reg [3:0] bit_count;

    localparam IDLE = 4'd0,
               START = 4'd1,
               DATA = 4'd2,
               STOP = 4'd3,
               ERROR = 4'd4;

    always @(posedge clk) begin
        if (reset) begin
            state <= IDLE;
            bit_count <= 0;
            done <= 0;
        end else begin
            case (state)
                IDLE: begin
                    done <= 0;
                    if (!in) state <= START;
                end
                START: begin
                    state <= DATA;
                    bit_count <= 0;
                end
                DATA: begin
                    if (bit_count == 7) begin
                        state <= STOP;
                    end else begin
                        bit_count <= bit_count + 1;
                    end
                end
                STOP: begin
                    if (in) begin
                        state <= IDLE;
                        done <= 1;
                    end else begin
                        state <= ERROR;
                    end
                end
                ERROR: begin
                    if (in) state <= IDLE;
                end
            endcase
        end
    end

endmodule

module top_module (
	input clk,
	input in,
	input reset,
	output reg done
);

    parameter IDLE = 3'd0, START = 3'd1, DATA = 3'd2, STOP = 3'd3, ERROR = 3'd4;
    reg [2:0] state, next_state;
    reg [3:0] bit_count;

    always @(posedge clk) begin
        if (reset) begin
            state <= IDLE;
            bit_count <= 0;
            done <= 0;
        end else begin
            state <= next_state;
            if (state == DATA)
                bit_count <= bit_count + 1;
            else
                bit_count <= 0;
        end
    end

    always @(*) begin
        next_state = state;
        done = 0;
        case (state)
            IDLE: begin
                if (~in) next_state = START;
            end
            START: begin
                next_state = DATA;
            end
            DATA: begin
                if (bit_count == 4'd7) begin
                    if (in) next_state = STOP;
                    else next_state = ERROR;
                end
            end
            STOP: begin
                done = 1;
                if (in) next_state = IDLE;
                else next_state = START;
            end
            ERROR: begin
                if (in) next_state = IDLE;
            end
        endcase
    end

endmodule

module top_module (
	input clk,
	input in,
	input reset,
	output reg done
);

    localparam IDLE = 3'd0,
               START = 3'd1,
               DATA = 3'd2,
               STOP = 3'd3,
               ERROR = 3'd4;

    reg [2:0] state, next_state;
    reg [3:0] bit_count;

    always @(posedge clk or posedge reset) begin
        if (reset) begin
            state <= IDLE;
            bit_count <= 0;
            done <= 0;
        end else begin
            state <= next_state;
            if (state == DATA)
                bit_count <= bit_count + 1;
            else
                bit_count <= 0;
        end
    end

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

        case (state)
            IDLE: begin
                if (!in) next_state = START;
            end
            START: begin
                next_state = DATA;
            end
            DATA: begin
                if (bit_count == 4'd7) begin
                    if (in) next_state = STOP;
                    else next_state = ERROR;
                end
            end
            STOP: begin
                done = 1;
                next_state = IDLE;
            end
            ERROR: begin
                if (in) next_state = IDLE;
            end
        endcase
    end

endmodule


module top_module (
	input clk,
	input in,
	input reset,
	output reg [7:0] out_byte,
	output reg done
);

reg [3:0] state;
reg [3:0] bit_count;
reg [7:0] shift_reg;

parameter IDLE = 4'd0, START = 4'd1, DATA = 4'd2, STOP = 4'd3, ERROR = 4'd4;

always @(posedge clk) begin
    if (reset) begin
        state <= IDLE;
        bit_count <= 0;
        shift_reg <= 8'b0;
        out_byte <= 8'b0;
        done <= 0;
    end else begin
        case (state)
            IDLE: begin
                done <= 0;
                if (in == 0) begin
                    state <= START;
                    bit_count <= 0;
                end
            end
            START: begin
                state <= DATA;
                bit_count <= 0;
                shift_reg <= 8'b0;
            end
            DATA: begin
                shift_reg <= {in, shift_reg[7:1]};
                bit_count <= bit_count + 1;
                if (bit_count == 7) begin
                    state <= STOP;
                end
            end
            STOP: begin
                if (in == 1) begin
                    state <= IDLE;
                    out_byte <= shift_reg;
                    done <= 1;
                end else begin
                    state <= ERROR;
                end
            end
            ERROR: begin
                if (in == 1) begin
                    state <= IDLE;
                end
            end
        endcase
    end
end

endmodule

module top_module (
	input clk,
	input in,
	input reset,
	output reg [7:0] out_byte,
	output reg done
);

	localparam IDLE = 3'd0,
			   START = 3'd1,
			   DATA = 3'd2,
			   STOP = 3'd3,
			   ERROR = 3'd4;

	reg [2:0] state, next_state;
	reg [3:0] bit_count;
	reg [7:0] shift_reg;

	always @(posedge clk) begin
		if (reset) begin
			state <= IDLE;
			bit_count <= 0;
			shift_reg <= 8'b0;
			out_byte <= 8'b0;
			done <= 1'b0;
		end else begin
			state <= next_state;
			if (state == DATA) begin
				shift_reg <= {in, shift_reg[7:1]};
				bit_count <= bit_count + 1;
			end else begin
				bit_count <= 0;
			end
		end
	end

	always @(*) begin
		next_state = state;
		done = 1'b0;
		case (state)
			IDLE: begin
				if (!in) next_state = START;
			end
			START: begin
				next_state = DATA;
			end
			DATA: begin
				if (bit_count == 4'd7) next_state = STOP;
			end
			STOP: begin
				if (in) begin
					next_state = IDLE;
					done = 1'b1;
					out_byte = shift_reg;
				end else begin
					next_state = ERROR;
				end
			end
			ERROR: begin
				if (in) next_state = IDLE;
			end
		endcase
	end

endmodule

module top_module (
	input clk,
	input in,
	input reset,
	output reg [7:0] out_byte,
	output reg done
);

	localparam IDLE = 3'd0, START = 3'd1, DATA = 3'd2, STOP = 3'd3, ERROR = 3'd4;
	reg [2:0] state, next_state;
	reg [3:0] bit_count;
	reg [7:0] shift_reg;

	always @(posedge clk) begin
		if (reset) begin
			state <= IDLE;
			bit_count <= 0;
			shift_reg <= 8'b0;
			done <= 0;
			out_byte <= 8'b0;
		end else begin
			state <= next_state;
			case (state)
				DATA: begin
					if (bit_count < 8) begin
						shift_reg <= {in, shift_reg[7:1]};
						bit_count <= bit_count + 1;
					end
				end
				STOP: begin
					if (in) begin
						out_byte <= shift_reg;
						done <= 1;
					end
				end
				default: begin
					bit_count <= 0;
					done <= 0;
				end
			endcase
		end
	end

	always @(*) begin
		next_state = state;
		case (state)
			IDLE: if (!in) next_state = START;
			START: next_state = DATA;
			DATA: if (bit_count == 8) next_state = STOP;
			STOP: next_state = in ? IDLE : ERROR;
			ERROR: if (in) next_state = IDLE;
		endcase
	end

endmodule

module top_module (
	input clk,
	input in,
	input reset,
	output reg [7:0] out_byte,
	output reg done
);

	localparam IDLE = 3'd0, START = 3'd1, DATA = 3'd2, STOP = 3'd3, ERROR = 3'd4;
	reg [2:0] state, next_state;
	reg [3:0] bit_count;
	reg [7:0] shift_reg;

	always @(posedge clk) begin
		if (reset) begin
			state <= IDLE;
			bit_count <= 0;
			shift_reg <= 8'b0;
			out_byte <= 8'b0;
			done <= 1'b0;
		end else begin
			state <= next_state;
			case (state)
				DATA: begin
					if (bit_count < 8) begin
						shift_reg <= {in, shift_reg[7:1]};
						bit_count <= bit_count + 1;
					end
				end
				STOP: begin
					if (in) begin
						out_byte <= shift_reg;
						done <= 1'b1;
					end
				end
				default: begin
					bit_count <= 0;
					done <= 1'b0;
				end
			endcase
		end
	end

	always @(*) begin
		next_state = state;
		case (state)
			IDLE: if (!in) next_state = START;
			START: next_state = DATA;
			DATA: if (bit_count == 8) next_state = STOP;
			STOP: next_state = in ? IDLE : ERROR;
			ERROR: if (in) next_state = IDLE;
		endcase
	end

endmodule

module top_module (
	input clk,
	input in,
	input reset,
	output reg [7:0] out_byte,
	output reg done
);

	localparam IDLE = 3'd0, START = 3'd1, DATA = 3'd2, STOP = 3'd3, ERROR = 3'd4;
	reg [2:0] state, next_state;
	reg [3:0] bit_count;
	reg [7:0] shift_reg;

	always @(posedge clk or posedge reset) begin
		if (reset) begin
			state <= IDLE;
			bit_count <= 0;
			shift_reg <= 8'b0;
			out_byte <= 8'b0;
			done <= 0;
		end else begin
			state <= next_state;
			if (state == DATA) begin
				shift_reg <= {in, shift_reg[7:1]};
				bit_count <= bit_count + 1;
			end
			if (next_state == STOP && in == 1) begin
				out_byte <= shift_reg;
				done <= 1;
			end else begin
				done <= 0;
			end
		end
	end

	always @(*) begin
		case (state)
			IDLE: next_state = (in == 0) ? START : IDLE;
			START: next_state = DATA;
			DATA: next_state = (bit_count == 7) ? STOP : DATA;
			STOP: next_state = (in == 1) ? IDLE : ERROR;
			ERROR: next_state = (in == 1) ? IDLE : ERROR;
			default: next_state = IDLE;
		endcase
	end

endmodule

module top_module (
	input clk,
	input in,
	input reset,
	output reg [7:0] out_byte,
	output reg done
);

	localparam IDLE = 3'd0, START = 3'd1, DATA = 3'd2, STOP = 3'd3, ERROR = 3'd4;
	reg [2:0] state, next_state;
	reg [3:0] bit_count;
	reg [7:0] shift_reg;

	always @(posedge clk or posedge reset) begin
		if (reset) begin
			state <= IDLE;
			bit_count <= 0;
			shift_reg <= 0;
			out_byte <= 0;
			done <= 0;
		end else begin
			state <= next_state;
			case (state)
				DATA: begin
					if (bit_count < 8) begin
						shift_reg <= {in, shift_reg[7:1]};
						bit_count <= bit_count + 1;
					end
				end
				STOP: begin
					if (in) begin
						out_byte <= shift_reg;
						done <= 1;
					end
				end
				default: begin
					bit_count <= 0;
					done <= 0;
				end
			endcase
		end
	end

	always @(*) begin
		next_state = state;
		case (state)
			IDLE: if (!in) next_state = START;
			START: next_state = DATA;
			DATA: if (bit_count == 8) next_state = STOP;
			STOP: next_state = in ? IDLE : ERROR;
			ERROR: if (in) next_state = IDLE;
		endcase
	end

endmodule

module top_module (
	input clk,
	input in,
	input reset,
	output reg [7:0] out_byte,
	output reg done
);

    localparam IDLE = 3'd0, START = 3'd1, DATA = 3'd2, STOP = 3'd3, ERROR = 3'd4;
    reg [2:0] state, next_state;
    reg [3:0] bit_count;
    reg [7:0] shift_reg;

    always @(posedge clk) begin
        if (reset) begin
            state <= IDLE;
            out_byte <= 8'd0;
            done <= 1'b0;
            bit_count <= 4'd0;
            shift_reg <= 8'd0;
        end else begin
            state <= next_state;
            if (state == DATA) begin
                shift_reg <= {in, shift_reg[7:1]};
                bit_count <= bit_count + 1;
            end
            if (state == STOP && in == 1'b1) begin
                out_byte <= shift_reg;
                done <= 1'b1;
            end else begin
                done <= 1'b0;
            end
        end
    end

    always @(*) begin
        case (state)
            IDLE: next_state = (in == 1'b0) ? START : IDLE;
            START: next_state = DATA;
            DATA: next_state = (bit_count == 4'd7) ? STOP : DATA;
            STOP: next_state = (in == 1'b1) ? IDLE : ERROR;
            ERROR: next_state = (in == 1'b1) ? IDLE : ERROR;
            default: next_state = IDLE;
        endcase
    end

endmodule

module top_module (
	input clk,
	input in,
	input reset,
	output reg [7:0] out_byte,
	output reg done
);

    parameter IDLE = 3'd0, START = 3'd1, DATA = 3'd2, STOP = 3'd3, ERROR = 3'd4;
    reg [2:0] state, next_state;
    reg [2:0] bit_count;
    reg [7:0] shift_reg;

    always @(posedge clk or posedge reset) begin
        if (reset) begin
            state <= IDLE;
            out_byte <= 8'd0;
            done <= 1'b0;
            bit_count <= 3'd0;
            shift_reg <= 8'd0;
        end else begin
            state <= next_state;
            if (state == DATA) begin
                shift_reg <= {in, shift_reg[7:1]};
                bit_count <= bit_count + 1;
            end
            if (next_state == STOP && in == 1'b1) begin
                out_byte <= shift_reg;
                done <= 1'b1;
            end else begin
                done <= 1'b0;
            end
        end
    end

    always @(*) begin
        case (state)
            IDLE: next_state = (in == 1'b0) ? START : IDLE;
            START: next_state = DATA;
            DATA: next_state = (bit_count == 3'd7) ? STOP : DATA;
            STOP: next_state = (in == 1'b1) ? IDLE : ERROR;
            ERROR: next_state = (in == 1'b1) ? IDLE : ERROR;
            default: next_state = IDLE;
        endcase
    end

endmodule

module top_module (
	input clk,
	input in,
	input reset,
	output reg [7:0] out_byte,
	output reg done
);

    reg [3:0] state;
    reg [3:0] bit_count;
    reg [7:0] shift_reg;

    localparam IDLE = 4'd0,
               START = 4'd1,
               DATA = 4'd2,
               STOP = 4'd3,
               ERROR = 4'd4;

    always @(posedge clk) begin
        if (reset) begin
            state <= IDLE;
            bit_count <= 0;
            shift_reg <= 8'b0;
            out_byte <= 8'b0;
            done <= 0;
        end else begin
            case (state)
                IDLE: begin
                    done <= 0;
                    if (in == 0) state <= START;
                end
                START: begin
                    bit_count <= 0;
                    shift_reg <= 8'b0;
                    state <= DATA;
                end
                DATA: begin
                    shift_reg <= {in, shift_reg[7:1]};
                    bit_count <= bit_count + 1;
                    if (bit_count == 4'd7) state <= STOP;
                end
                STOP: begin
                    if (in == 1) begin
                        out_byte <= shift_reg;
                        done <= 1;
                        state <= IDLE;
                    end else begin
                        state <= ERROR;
                    end
                end
                ERROR: begin
                    if (in == 1) state <= IDLE;
                end
            endcase
        end
    end

endmodule

module top_module (
	input clk,
	input in,
	input reset,
	output reg [7:0] out_byte,
	output reg done
);

    reg [3:0] state;
    reg [3:0] bit_count;
    reg [7:0] shift_reg;

    localparam IDLE = 4'd0,
               START = 4'd1,
               DATA = 4'd2,
               STOP = 4'd3,
               ERROR = 4'd4;

    always @(posedge clk) begin
        if (reset) begin
            state <= IDLE;
            bit_count <= 0;
            shift_reg <= 8'b0;
            out_byte <= 8'b0;
            done <= 0;
        end else begin
            case (state)
                IDLE: begin
                    done <= 0;
                    if (!in) state <= START;
                end
                START: begin
                    bit_count <= 0;
                    shift_reg <= 8'b0;
                    state <= DATA;
                end
                DATA: begin
                    shift_reg <= {in, shift_reg[7:1]};
                    bit_count <= bit_count + 1;
                    if (bit_count == 4'd7) state <= STOP;
                end
                STOP: begin
                    if (in) begin
                        state <= IDLE;
                        out_byte <= shift_reg;
                        done <= 1;
                    end else begin
                        state <= ERROR;
                    end
                end
                ERROR: begin
                    if (in) state <= IDLE;
                end
            endcase
        end
    end

endmodule

module top_module (
	input clk,
	input in,
	input reset,
	output reg [7:0] out_byte,
	output reg done
);

	localparam IDLE = 3'd0, START = 3'd1, DATA = 3'd2, STOP = 3'd3, ERROR = 3'd4;
	reg [2:0] state, next_state;
	reg [3:0] bit_count;
	reg [7:0] shift_reg;

	always @(posedge clk or posedge reset) begin
		if (reset) begin
			state <= IDLE;
			bit_count <= 0;
			shift_reg <= 8'b0;
			out_byte <= 8'b0;
			done <= 0;
		end else begin
			state <= next_state;
			case (state)
				DATA: begin
					shift_reg <= {in, shift_reg[7:1]};
					bit_count <= bit_count + 1;
				end
				STOP: begin
					if (in) begin
						out_byte <= shift_reg;
						done <= 1;
					end
				end
				default: begin
					bit_count <= 0;
					done <= 0;
				end
			endcase
		end
	end

	always @(*) begin
		case (state)
			IDLE: next_state = (in == 0) ? START : IDLE;
			START: next_state = DATA;
			DATA: next_state = (bit_count == 7) ? STOP : DATA;
			STOP: next_state = (in == 1) ? IDLE : ERROR;
			ERROR: next_state = (in == 1) ? IDLE : ERROR;
			default: next_state = IDLE;
		endcase
	end

endmodule

module top_module (
	input clk,
	input in,
	input reset,
	output reg [7:0] out_byte,
	output reg done
);

    reg [3:0] state;
    reg [3:0] bit_count;
    reg [7:0] shift_reg;

    localparam IDLE = 4'd0, START = 4'd1, DATA = 4'd2, STOP = 4'd3, ERROR = 4'd4;

    always @(posedge clk) begin
        if (reset) begin
            state <= IDLE;
            bit_count <= 0;
            shift_reg <= 0;
            out_byte <= 0;
            done <= 0;
        end else begin
            case (state)
                IDLE: begin
                    done <= 0;
                    if (!in) state <= START;
                end
                START: begin
                    bit_count <= 0;
                    shift_reg <= 0;
                    state <= DATA;
                end
                DATA: begin
                    shift_reg <= {in, shift_reg[7:1]};
                    bit_count <= bit_count + 1;
                    if (bit_count == 7) state <= STOP;
                end
                STOP: begin
                    if (in) begin
                        state <= IDLE;
                        out_byte <= shift_reg;
                        done <= 1;
                    end else begin
                        state <= ERROR;
                    end
                end
                ERROR: begin
                    if (in) state <= IDLE;
                end
            endcase
        end
    end

endmodule

module top_module (
	input clk,
	input in,
	input reset,
	output reg [7:0] out_byte,
	output reg done
);

reg [3:0] state;
reg [3:0] bit_count;
reg [7:0] shift_reg;

parameter IDLE = 4'd0, START = 4'd1, DATA = 4'd2, STOP = 4'd3, ERROR = 4'd4;

always @(posedge clk) begin
    if (reset) begin
        state <= IDLE;
        bit_count <= 0;
        shift_reg <= 8'b0;
        out_byte <= 8'b0;
        done <= 0;
    end else begin
        case (state)
            IDLE: begin
                done <= 0;
                if (in == 0) begin
                    state <= START;
                end
            end
            START: begin
                state <= DATA;
                bit_count <= 0;
                shift_reg <= 8'b0;
            end
            DATA: begin
                shift_reg <= {in, shift_reg[7:1]};
                bit_count <= bit_count + 1;
                if (bit_count == 7) begin
                    state <= STOP;
                end
            end
            STOP: begin
                if (in == 1) begin
                    state <= IDLE;
                    out_byte <= shift_reg;
                    done <= 1;
                end else begin
                    state <= ERROR;
                end
            end
            ERROR: begin
                if (in == 1) begin
                    state <= IDLE;
                    done <= 1;
                end
            end
            default: state <= IDLE;
        endcase
    end
end

endmodule

module top_module (
	input clk,
	input in,
	input reset,
	output reg [7:0] out_byte,
	output reg done
);

    parameter IDLE = 3'd0, START = 3'd1, DATA = 3'd2, STOP = 3'd3, ERROR = 3'd4;
    reg [2:0] state, next_state;
    reg [3:0] bit_count;
    reg [7:0] shift_reg;

    always @(posedge clk) begin
        if (reset) begin
            state <= IDLE;
            done <= 0;
            out_byte <= 8'b0;
            bit_count <= 0;
            shift_reg <= 8'b0;
        end else begin
            state <= next_state;
            if (state == DATA) begin
                shift_reg <= {in, shift_reg[7:1]};
                bit_count <= bit_count + 1;
            end
            if (next_state == STOP && in == 1) begin
                done <= 1;
                out_byte <= shift_reg;
            end else begin
                done <= 0;
            end
        end
    end

    always @(*) begin
        case (state)
            IDLE: next_state = (in == 0) ? START : IDLE;
            START: next_state = DATA;
            DATA: next_state = (bit_count == 4'd7) ? STOP : DATA;
            STOP: next_state = (in == 1) ? IDLE : ERROR;
            ERROR: next_state = (in == 1) ? IDLE : ERROR;
            default: next_state = IDLE;
        endcase
    end

endmodule

module top_module (
	input clk,
	input in,
	input reset,
	output reg [7:0] out_byte,
	output reg done
);

	localparam IDLE = 3'd0, START = 3'd1, DATA = 3'd2, STOP = 3'd3, ERROR = 3'd4;
	reg [2:0] state, next_state;
	reg [3:0] bit_count;
	reg [7:0] shift_reg;

	always @(posedge clk) begin
		if (reset) begin
			state <= IDLE;
			bit_count <= 0;
			shift_reg <= 0;
			out_byte <= 0;
			done <= 0;
		end else begin
			state <= next_state;
			case (state)
				DATA: begin
					if (bit_count < 8) begin
						shift_reg <= {in, shift_reg[7:1]};
						bit_count <= bit_count + 1;
					end
				end
				STOP: begin
					if (in) begin
						out_byte <= shift_reg;
						done <= 1;
					end
				end
				default: begin
					bit_count <= 0;
					done <= 0;
				end
			endcase
		end
	end

	always @(*) begin
		next_state = state;
		case (state)
			IDLE: if (~in) next_state = START;
			START: next_state = DATA;
			DATA: if (bit_count == 8) next_state = STOP;
			STOP: next_state = in ? IDLE : ERROR;
			ERROR: if (in) next_state = IDLE;
		endcase
	end

endmodule

module top_module (
	input clk,
	input in,
	input reset,
	output reg [7:0] out_byte,
	output reg done
);

    reg [3:0] state;
    reg [3:0] bit_count;
    reg [7:0] shift_reg;

    localparam IDLE = 4'd0, START = 4'd1, DATA = 4'd2, STOP = 4'd3, ERROR = 4'd4;

    always @(posedge clk) begin
        if (reset) begin
            state <= IDLE;
            bit_count <= 0;
            shift_reg <= 8'b0;
            done <= 0;
            out_byte <= 8'b0;
        end else begin
            case (state)
                IDLE: begin
                    done <= 0;
                    if (in == 0) begin
                        state <= START;
                    end
                end
                START: begin
                    state <= DATA;
                    bit_count <= 0;
                    shift_reg <= 8'b0;
                end
                DATA: begin
                    shift_reg <= {in, shift_reg[7:1]};
                    bit_count <= bit_count + 1;
                    if (bit_count == 7) begin
                        state <= STOP;
                    end
                end
                STOP: begin
                    if (in == 1) begin
                        state <= IDLE;
                        done <= 1;
                        out_byte <= shift_reg;
                    end else begin
                        state <= ERROR;
                    end
                end
                ERROR: begin
                    if (in == 1) begin
                        state <= IDLE;
                    end
                end
            endcase
        end
    end

endmodule

module top_module (
	input clk,
	input in,
	input reset,
	output reg [7:0] out_byte,
	output reg done
);

    localparam IDLE = 3'd0, START = 3'd1, DATA = 3'd2, STOP = 3'd3, ERROR = 3'd4;
    reg [2:0] state, next_state;
    reg [2:0] bit_count;
    reg [7:0] shift_reg;

    always @(posedge clk) begin
        if (reset) begin
            state <= IDLE;
            out_byte <= 8'd0;
            done <= 1'b0;
            bit_count <= 3'd0;
            shift_reg <= 8'd0;
        end else begin
            state <= next_state;
            if (state == DATA) begin
                shift_reg <= {in, shift_reg[7:1]};
                bit_count <= bit_count + 1'b1;
            end
            if (state == STOP && in == 1'b1) begin
                out_byte <= shift_reg;
                done <= 1'b1;
            end else begin
                done <= 1'b0;
            end
        end
    end

    always @(*) begin
        case (state)
            IDLE: next_state = (in == 1'b0) ? START : IDLE;
            START: next_state = DATA;
            DATA: next_state = (bit_count == 3'd7) ? STOP : DATA;
            STOP: next_state = (in == 1'b1) ? IDLE : ERROR;
            ERROR: next_state = (in == 1'b1) ? IDLE : ERROR;
            default: next_state = IDLE;
        endcase
    end

endmodule


module top_module(
	input clk,
	input areset,

	input predict_valid,
	input [6:0] predict_pc,
	output predict_taken,
	output [6:0] predict_history,

	input train_valid,
	input train_taken,
	input train_mispredicted,
	input [6:0] train_history,
	input [6:0] train_pc
);

    reg [1:0] pht [127:0];
    reg [6:0] global_history;
    wire [6:0] predict_index, train_index;

    assign predict_index = predict_pc ^ global_history;
    assign train_index = train_pc ^ train_history;

    assign predict_taken = pht[predict_index][1];
    assign predict_history = global_history;

    integer i;
    always @(posedge clk or posedge areset) begin
        if (areset) begin
            global_history <= 7'b0;
            for (i = 0; i < 128; i = i + 1)
                pht[i] <= 2'b01;
        end else begin
            if (train_valid && train_mispredicted)
                global_history <= {train_history[5:0], train_taken};
            else if (predict_valid)
                global_history <= {global_history[5:0], predict_taken};

            if (train_valid) begin
                case (pht[train_index])
                    2'b00: pht[train_index] <= train_taken ? 2'b01 : 2'b00;
                    2'b01: pht[train_index] <= train_taken ? 2'b10 : 2'b00;
                    2'b10: pht[train_index] <= train_taken ? 2'b11 : 2'b01;
                    2'b11: pht[train_index] <= train_taken ? 2'b11 : 2'b10;
                endcase
            end
        end
    end

endmodule

module top_module(
	input clk,
	input areset,

	input predict_valid,
	input [6:0] predict_pc,
	output predict_taken,
	output [6:0] predict_history,

	input train_valid,
	input train_taken,
	input train_mispredicted,
	input [6:0] train_history,
	input [6:0] train_pc
);

    reg [1:0] pht [127:0];
    reg [6:0] global_history;
    wire [6:0] predict_index, train_index;

    assign predict_index = predict_pc ^ global_history;
    assign train_index = train_pc ^ train_history;

    assign predict_taken = pht[predict_index][1];
    assign predict_history = global_history;

    integer i;
    always @(posedge clk or posedge areset) begin
        if (areset) begin
            global_history <= 7'b0;
            for (i = 0; i < 128; i = i + 1) begin
                pht[i] <= 2'b01;
            end
        end else begin
            if (train_valid) begin
                if (train_taken) begin
                    pht[train_index] <= (pht[train_index] == 2'b11) ? 2'b11 : pht[train_index] + 1;
                end else begin
                    pht[train_index] <= (pht[train_index] == 2'b00) ? 2'b00 : pht[train_index] - 1;
                end

                if (train_mispredicted) begin
                    global_history <= {train_history[5:0], train_taken};
                end else if (predict_valid) begin
                    global_history <= {global_history[5:0], predict_taken};
                end
            end else if (predict_valid) begin
                global_history <= {global_history[5:0], predict_taken};
            end
        end
    end

endmodule

module top_module(
	input clk,
	input areset,

	input predict_valid,
	input [6:0] predict_pc,
	output predict_taken,
	output [6:0] predict_history,

	input train_valid,
	input train_taken,
	input train_mispredicted,
	input [6:0] train_history,
	input [6:0] train_pc
);

    reg [1:0] pht [127:0];
    reg [6:0] global_history;

    wire [6:0] predict_index = predict_pc ^ global_history;
    wire [6:0] train_index = train_pc ^ train_history;

    assign predict_taken = pht[predict_index][1];
    assign predict_history = global_history;

    integer i;
    always @(posedge clk or posedge areset) begin
        if (areset) begin
            global_history <= 7'b0;
            for (i = 0; i < 128; i = i + 1) begin
                pht[i] <= 2'b01;
            end
        end else begin
            if (train_valid) begin
                if (train_taken && pht[train_index] != 2'b11)
                    pht[train_index] <= pht[train_index] + 1;
                else if (!train_taken && pht[train_index] != 2'b00)
                    pht[train_index] <= pht[train_index] - 1;

                if (train_mispredicted)
                    global_history <= {train_history[5:0], train_taken};
            end else if (predict_valid) begin
                global_history <= {global_history[5:0], predict_taken};
            end
        end
    end

endmodule

module top_module(
	input clk,
	input areset,

	input predict_valid,
	input [6:0] predict_pc,
	output predict_taken,
	output [6:0] predict_history,

	input train_valid,
	input train_taken,
	input train_mispredicted,
	input [6:0] train_history,
	input [6:0] train_pc
);

    reg [1:0] pht [127:0];
    reg [6:0] global_history;

    wire [6:0] predict_index = predict_pc ^ predict_history;
    wire [6:0] train_index = train_pc ^ train_history;

    assign predict_taken = pht[predict_index][1];
    assign predict_history = global_history;

    integer i;

    always @(posedge clk or posedge areset) begin
        if (areset) begin
            global_history <= 7'b0;
            for (i = 0; i < 128; i = i + 1) begin
                pht[i] <= 2'b01;
            end
        end else begin
            if (train_valid) begin
                if (train_taken) begin
                    pht[train_index] <= (pht[train_index] == 2'b11) ? 2'b11 : pht[train_index] + 1;
                end else begin
                    pht[train_index] <= (pht[train_index] == 2'b00) ? 2'b00 : pht[train_index] - 1;
                end

                if (train_mispredicted) begin
                    global_history <= {train_history[5:0], train_taken};
                end
            end

            if (predict_valid && !train_mispredicted) begin
                global_history <= {global_history[5:0], predict_taken};
            end
        end
    end

endmodule

module top_module(
	input clk,
	input areset,

	input predict_valid,
	input [6:0] predict_pc,
	output predict_taken,
	output [6:0] predict_history,

	input train_valid,
	input train_taken,
	input train_mispredicted,
	input [6:0] train_history,
	input [6:0] train_pc
);

    reg [1:0] pht [127:0];
    reg [6:0] global_history;

    wire [6:0] predict_index = predict_pc ^ predict_history;
    wire [6:0] train_index = train_pc ^ train_history;

    assign predict_history = global_history;
    assign predict_taken = pht[predict_index][1];

    integer i;
    always @(posedge clk or posedge areset) begin
        if (areset) begin
            global_history <= 7'b0;
            for (i = 0; i < 128; i = i + 1) begin
                pht[i] <= 2'b01;
            end
        end else begin
            if (train_valid) begin
                if (train_taken && pht[train_index] != 2'b11)
                    pht[train_index] <= pht[train_index] + 1;
                else if (!train_taken && pht[train_index] != 2'b00)
                    pht[train_index] <= pht[train_index] - 1;

                if (train_mispredicted)
                    global_history <= {train_history[5:0], train_taken};
            end else if (predict_valid) begin
                global_history <= {global_history[5:0], predict_taken};
            end
        end
    end

endmodule

module top_module(
	input clk,
	input areset,

	input predict_valid,
	input [6:0] predict_pc,
	output predict_taken,
	output [6:0] predict_history,

	input train_valid,
	input train_taken,
	input train_mispredicted,
	input [6:0] train_history,
	input [6:0] train_pc
);

    reg [1:0] pht [127:0];
    reg [6:0] global_history;
    wire [6:0] predict_index, train_index;

    assign predict_index = predict_pc ^ global_history;
    assign train_index = train_pc ^ train_history;

    assign predict_taken = pht[predict_index][1];
    assign predict_history = global_history;

    integer i;
    always @(posedge clk or posedge areset) begin
        if (areset) begin
            global_history <= 7'b0;
            for (i = 0; i < 128; i = i + 1) begin
                pht[i] <= 2'b01;
            end
        end else begin
            if (train_valid) begin
                if (train_taken && pht[train_index] != 2'b11)
                    pht[train_index] <= pht[train_index] + 1;
                else if (!train_taken && pht[train_index] != 2'b00)
                    pht[train_index] <= pht[train_index] - 1;

                if (train_mispredicted)
                    global_history <= {train_history[5:0], train_taken};
            end else if (predict_valid) begin
                global_history <= {global_history[5:0], predict_taken};
            end
        end
    end

endmodule

module top_module(
	input clk,
	input areset,

	input predict_valid,
	input [6:0] predict_pc,
	output predict_taken,
	output [6:0] predict_history,

	input train_valid,
	input train_taken,
	input train_mispredicted,
	input [6:0] train_history,
	input [6:0] train_pc
);

    reg [1:0] pht [127:0];
    reg [6:0] global_history;
    wire [6:0] predict_index, train_index;

    assign predict_index = predict_pc ^ global_history;
    assign train_index = train_pc ^ train_history;
    assign predict_history = global_history;
    assign predict_taken = pht[predict_index][1];

    integer i;

    always @(posedge clk or posedge areset) begin
        if (areset) begin
            global_history <= 7'b0;
            for (i = 0; i < 128; i = i + 1) begin
                pht[i] <= 2'b01;
            end
        end else begin
            if (train_valid && train_mispredicted) begin
                global_history <= {train_history[5:0], train_taken};
            end else if (predict_valid) begin
                global_history <= {global_history[5:0], predict_taken};
            end

            if (train_valid) begin
                if (train_taken && pht[train_index] != 2'b11)
                    pht[train_index] <= pht[train_index] + 1;
                else if (!train_taken && pht[train_index] != 2'b00)
                    pht[train_index] <= pht[train_index] - 1;
            end
        end
    end

endmodule

module top_module(
    input clk,
    input areset,

    input predict_valid,
    input [6:0] predict_pc,
    output predict_taken,
    output [6:0] predict_history,

    input train_valid,
    input train_taken,
    input train_mispredicted,
    input [6:0] train_history,
    input [6:0] train_pc
);

    reg [1:0] pht [127:0];
    reg [6:0] global_history;

    wire [6:0] predict_index = predict_pc ^ predict_history;
    wire [6:0] train_index = train_pc ^ train_history;

    assign predict_taken = pht[predict_index][1];
    assign predict_history = global_history;

    always @(posedge clk or posedge areset) begin
        if (areset) begin
            global_history <= 7'b0;
            for (integer i = 0; i < 128; i = i + 1) begin
                pht[i] <= 2'b01;
            end
        end else begin
            if (train_valid && train_mispredicted) begin
                global_history <= {train_history[5:0], train_taken};
            end else if (predict_valid) begin
                global_history <= {global_history[5:0], predict_taken};
            end

            if (train_valid) begin
                case (pht[train_index])
                    2'b00: pht[train_index] <= train_taken ? 2'b01 : 2'b00;
                    2'b01: pht[train_index] <= train_taken ? 2'b10 : 2'b00;
                    2'b10: pht[train_index] <= train_taken ? 2'b11 : 2'b01;
                    2'b11: pht[train_index] <= train_taken ? 2'b11 : 2'b10;
                endcase
            end
        end
    end

endmodule

module top_module(
	input clk,
	input areset,

	input predict_valid,
	input [6:0] predict_pc,
	output predict_taken,
	output [6:0] predict_history,

	input train_valid,
	input train_taken,
	input train_mispredicted,
	input [6:0] train_history,
	input [6:0] train_pc
);

    reg [1:0] pht [127:0];
    reg [6:0] global_history;
    wire [6:0] predict_index, train_index;
    reg [1:0] predict_counter, train_counter;

    assign predict_index = predict_pc ^ global_history;
    assign train_index = train_pc ^ train_history;
    assign predict_taken = predict_counter[1];
    assign predict_history = global_history;

    always @(posedge clk or posedge areset) begin
        if (areset) begin
            global_history <= 7'b0;
            for (int i = 0; i < 128; i = i + 1) begin
                pht[i] <= 2'b01;
            end
        end else begin
            if (train_valid && train_mispredicted) begin
                global_history <= {train_history[5:0], train_taken};
            end else if (predict_valid) begin
                global_history <= {global_history[5:0], predict_taken};
            end

            if (train_valid) begin
                if (train_taken && train_counter != 2'b11)
                    pht[train_index] <= train_counter + 1;
                else if (!train_taken && train_counter != 2'b00)
                    pht[train_index] <= train_counter - 1;
            end
        end
    end

    always @(*) begin
        predict_counter = pht[predict_index];
        train_counter = pht[train_index];
    end

endmodule

module top_module(
	input clk,
	input areset,

	input predict_valid,
	input [6:0] predict_pc,
	output predict_taken,
	output [6:0] predict_history,

	input train_valid,
	input train_taken,
	input train_mispredicted,
	input [6:0] train_history,
	input [6:0] train_pc
);

    reg [6:0] global_history;
    reg [1:0] pht [127:0];
    wire [6:0] predict_index, train_index;
    reg [1:0] predict_counter, train_counter;

    assign predict_index = predict_pc ^ global_history;
    assign train_index = train_pc ^ train_history;

    assign predict_taken = predict_counter[1];
    assign predict_history = global_history;

    integer i;

    always @(posedge clk or posedge areset) begin
        if (areset) begin
            global_history <= 7'b0;
            for (i = 0; i < 128; i = i + 1) begin
                pht[i] <= 2'b01;
            end
        end else begin
            if (train_valid && train_mispredicted) begin
                global_history <= {train_history[5:0], train_taken};
            end else if (predict_valid) begin
                global_history <= {global_history[5:0], predict_taken};
            end

            if (train_valid) begin
                if (train_taken && train_counter != 2'b11)
                    pht[train_index] <= train_counter + 1;
                else if (!train_taken && train_counter != 2'b00)
                    pht[train_index] <= train_counter - 1;
            end
        end
    end

    always @(*) begin
        predict_counter = pht[predict_index];
        train_counter = pht[train_index];
    end

endmodule

module top_module(
	input clk,
	input areset,

	input predict_valid,
	input [6:0] predict_pc,
	output predict_taken,
	output [6:0] predict_history,

	input train_valid,
	input train_taken,
	input train_mispredicted,
	input [6:0] train_history,
	input [6:0] train_pc
);

    reg [1:0] pht [127:0];
    reg [6:0] global_history;
    wire [6:0] predict_index, train_index;

    assign predict_index = predict_pc ^ global_history;
    assign train_index = train_pc ^ train_history;

    assign predict_taken = pht[predict_index][1];
    assign predict_history = global_history;

    integer i;
    always @(posedge clk or posedge areset) begin
        if (areset) begin
            global_history <= 7'b0;
            for (i = 0; i < 128; i = i + 1) begin
                pht[i] <= 2'b01;
            end
        end else begin
            if (train_valid) begin
                if (train_taken) begin
                    pht[train_index] <= (pht[train_index] == 2'b11) ? 2'b11 : pht[train_index] + 1;
                end else begin
                    pht[train_index] <= (pht[train_index] == 2'b00) ? 2'b00 : pht[train_index] - 1;
                end

                if (train_mispredicted) begin
                    global_history <= {train_history[5:0], train_taken};
                end
            end

            if (predict_valid && !train_mispredicted) begin
                global_history <= {global_history[5:0], predict_taken};
            end
        end
    end

endmodule

module top_module(
	input clk,
	input areset,

	input predict_valid,
	input [6:0] predict_pc,
	output predict_taken,
	output [6:0] predict_history,

	input train_valid,
	input train_taken,
	input train_mispredicted,
	input [6:0] train_history,
	input [6:0] train_pc
);

    reg [1:0] pht [127:0];
    reg [6:0] global_history;
    wire [6:0] predict_index, train_index;

    assign predict_index = predict_pc ^ global_history;
    assign train_index = train_pc ^ train_history;

    assign predict_taken = pht[predict_index][1];
    assign predict_history = global_history;

    integer i;
    always @(posedge clk or posedge areset) begin
        if (areset) begin
            global_history <= 7'b0;
            for (i = 0; i < 128; i = i + 1) begin
                pht[i] <= 2'b01;
            end
        end else begin
            if (train_valid && train_mispredicted) begin
                global_history <= {train_history[5:0], train_taken};
            end else if (predict_valid && !train_valid) begin
                global_history <= {global_history[5:0], predict_taken};
            end

            if (train_valid) begin
                if (train_taken && pht[train_index] != 2'b11)
                    pht[train_index] <= pht[train_index] + 1;
                else if (!train_taken && pht[train_index] != 2'b00)
                    pht[train_index] <= pht[train_index] - 1;
            end
        end
    end

endmodule

module top_module(
	input clk,
	input areset,

	input predict_valid,
	input [6:0] predict_pc,
	output predict_taken,
	output [6:0] predict_history,

	input train_valid,
	input train_taken,
	input train_mispredicted,
	input [6:0] train_history,
	input [6:0] train_pc
);

    reg [1:0] pht [127:0];
    reg [6:0] global_history;

    wire [6:0] predict_index = predict_pc ^ predict_history;
    wire [6:0] train_index = train_pc ^ train_history;

    assign predict_taken = pht[predict_index][1];
    assign predict_history = global_history;

    integer i;

    always @(posedge clk or posedge areset) begin
        if (areset) begin
            global_history <= 7'b0;
            for (i = 0; i < 128; i = i + 1) begin
                pht[i] <= 2'b01;
            end
        end else begin
            if (train_valid) begin
                if (train_taken && pht[train_index] != 2'b11)
                    pht[train_index] <= pht[train_index] + 1;
                else if (!train_taken && pht[train_index] != 2'b00)
                    pht[train_index] <= pht[train_index] - 1;

                if (train_mispredicted)
                    global_history <= {train_history[5:0], train_taken};
            end
            else if (predict_valid) begin
                global_history <= {global_history[5:0], predict_taken};
            end
        end
    end

endmodule

module top_module(
	input clk,
	input areset,

	input predict_valid,
	input [6:0] predict_pc,
	output predict_taken,
	output [6:0] predict_history,

	input train_valid,
	input train_taken,
	input train_mispredicted,
	input [6:0] train_history,
	input [6:0] train_pc
);

    reg [1:0] pht [127:0];
    reg [6:0] global_history;
    wire [6:0] predict_index, train_index;

    assign predict_index = predict_pc ^ global_history;
    assign train_index = train_pc ^ train_history;
    assign predict_history = global_history;
    assign predict_taken = pht[predict_index][1];

    always @(posedge clk or posedge areset) begin
        if (areset) begin
            global_history <= 7'b0;
            for (integer i = 0; i < 128; i = i + 1)
                pht[i] <= 2'b01;
        end else begin
            if (train_valid) begin
                if (train_taken && pht[train_index] != 2'b11)
                    pht[train_index] <= pht[train_index] + 1;
                else if (!train_taken && pht[train_index] != 2'b00)
                    pht[train_index] <= pht[train_index] - 1;

                if (train_mispredicted)
                    global_history <= {train_history[5:0], train_taken};
            end else if (predict_valid) begin
                global_history <= {global_history[5:0], predict_taken};
            end
        end
    end

endmodule

module top_module(
	input clk,
	input areset,

	input predict_valid,
	input [6:0] predict_pc,
	output predict_taken,
	output [6:0] predict_history,

	input train_valid,
	input train_taken,
	input train_mispredicted,
	input [6:0] train_history,
	input [6:0] train_pc
);

    reg [1:0] pht [127:0];
    reg [6:0] global_history;
    wire [6:0] predict_index, train_index;

    assign predict_index = predict_pc ^ global_history;
    assign train_index = train_pc ^ train_history;

    assign predict_taken = pht[predict_index][1];
    assign predict_history = global_history;

    integer i;
    always @(posedge clk or posedge areset) begin
        if (areset) begin
            global_history <= 7'b0;
            for (i = 0; i < 128; i = i + 1) begin
                pht[i] <= 2'b01;
            end
        end else begin
            if (train_valid && train_mispredicted) begin
                global_history <= {train_history[5:0], train_taken};
            end else if (predict_valid) begin
                global_history <= {global_history[5:0], predict_taken};
            end

            if (train_valid) begin
                case (pht[train_index])
                    2'b00: pht[train_index] <= train_taken ? 2'b01 : 2'b00;
                    2'b01: pht[train_index] <= train_taken ? 2'b10 : 2'b00;
                    2'b10: pht[train_index] <= train_taken ? 2'b11 : 2'b01;
                    2'b11: pht[train_index] <= train_taken ? 2'b11 : 2'b10;
                endcase
            end
        end
    end

endmodule

module top_module(
    input clk,
    input areset,

    input predict_valid,
    input [6:0] predict_pc,
    output predict_taken,
    output [6:0] predict_history,

    input train_valid,
    input train_taken,
    input train_mispredicted,
    input [6:0] train_history,
    input [6:0] train_pc
);

    reg [1:0] pht [127:0];
    reg [6:0] global_history;
    wire [6:0] predict_index, train_index;

    assign predict_index = predict_pc ^ global_history;
    assign train_index = train_pc ^ train_history;

    assign predict_taken = pht[predict_index][1];
    assign predict_history = global_history;

    always @(posedge clk or posedge areset) begin
        if (areset) begin
            global_history <= 7'b0;
            for (integer i = 0; i < 128; i = i + 1)
                pht[i] <= 2'b01;
        end
        else begin
            if (train_valid && train_mispredicted)
                global_history <= {train_history[5:0], train_taken};
            else if (predict_valid)
                global_history <= {global_history[5:0], predict_taken};

            if (train_valid) begin
                case (pht[train_index])
                    2'b00: pht[train_index] <= train_taken ? 2'b01 : 2'b00;
                    2'b01: pht[train_index] <= train_taken ? 2'b10 : 2'b00;
                    2'b10: pht[train_index] <= train_taken ? 2'b11 : 2'b01;
                    2'b11: pht[train_index] <= train_taken ? 2'b11 : 2'b10;
                endcase
            end
        end
    end

endmodule

module top_module(
	input clk,
	input areset,

	input predict_valid,
	input [6:0] predict_pc,
	output predict_taken,
	output [6:0] predict_history,

	input train_valid,
	input train_taken,
	input train_mispredicted,
	input [6:0] train_history,
	input [6:0] train_pc
);

    reg [1:0] pht [127:0];
    reg [6:0] global_history;

    wire [6:0] predict_index = predict_pc ^ predict_history;
    wire [6:0] train_index = train_pc ^ train_history;

    assign predict_history = global_history;
    assign predict_taken = pht[predict_index][1];

    integer i;
    always @(posedge clk or posedge areset) begin
        if (areset) begin
            global_history <= 7'b0;
            for (i = 0; i < 128; i = i + 1) begin
                pht[i] <= 2'b01;
            end
        end else begin
            if (train_valid) begin
                if (train_taken) begin
                    pht[train_index] <= (pht[train_index] == 2'b11) ? 2'b11 : pht[train_index] + 1;
                end else begin
                    pht[train_index] <= (pht[train_index] == 2'b00) ? 2'b00 : pht[train_index] - 1;
                end

                if (train_mispredicted) begin
                    global_history <= {train_history[5:0], train_taken};
                end else if (predict_valid) begin
                    global_history <= {global_history[5:0], predict_taken};
                end
            end else if (predict_valid) begin
                global_history <= {global_history[5:0], predict_taken};
            end
        end
    end

endmodule