module uart_receiver (
    input wire clk,
    input wire rst,
    input wire rx,
    output reg [7:0] data_out,
    output reg data_valid,
    output reg framing_error
);
    localparam [1:0] STATE_IDLE  = 2'd0;
    localparam [1:0] STATE_START = 2'd1;
    localparam [1:0] STATE_DATA  = 2'd2;
    localparam [1:0] STATE_STOP  = 2'd3;

    reg [1:0] state;
    reg [3:0] sample_count;
    reg [2:0] bit_index;
    reg [7:0] shift_reg;

    always @(posedge clk) begin
        data_valid <= 1'b0;
        framing_error <= 1'b0;

        if (rst) begin
            state <= STATE_IDLE;
            sample_count <= 4'd0;
            bit_index <= 3'd0;
            shift_reg <= 8'd0;
            data_out <= 8'd0;
        end else begin
            case (state)
                STATE_IDLE: begin
                    sample_count <= 4'd0;
                    bit_index <= 3'd0;
                    if (rx == 1'b0) begin
                        state <= STATE_START;
                        sample_count <= 4'd7;
                    end
                end

                STATE_START: begin
                    if (sample_count == 4'd0) begin
                        if (rx == 1'b0) begin
                            state <= STATE_DATA;
                            sample_count <= 4'd15;
                            bit_index <= 3'd0;
                        end else begin
                            state <= STATE_IDLE;
                        end
                    end else begin
                        sample_count <= sample_count - 4'd1;
                    end
                end

                STATE_DATA: begin
                    if (sample_count == 4'd0) begin
                        shift_reg[bit_index] <= rx;
                        if (bit_index == 3'd7) begin
                            state <= STATE_STOP;
                        end else begin
                            bit_index <= bit_index + 3'd1;
                        end
                        sample_count <= 4'd15;
                    end else begin
                        sample_count <= sample_count - 4'd1;
                    end
                end

                STATE_STOP: begin
                    if (sample_count == 4'd0) begin
                        state <= STATE_IDLE;
                        if (rx == 1'b1) begin
                            data_out <= shift_reg;
                            data_valid <= 1'b1;
                        end else begin
                            framing_error <= 1'b1;
                        end
                    end else begin
                        sample_count <= sample_count - 4'd1;
                    end
                end

                default: begin
                    state <= STATE_IDLE;
                    sample_count <= 4'd0;
                    bit_index <= 3'd0;
                end
            endcase
        end
    end
endmodule
