// 波特率可更换，理论上比9600 大的都行，目前只测试了9600 和 115200
// 模块监听RX 数据线，如果有数据则串行收集，最后并行发出
// done_rx 为一个持续一个时钟周期的高电平脉冲，高电平结束后，data_rx 会被置0
module rx(
    input wire clk,
    input wire rst_n,
    input wire rx_M2,
    
    output reg [7:0] data_rx,
    output reg done_rx
);

parameter [4:0] IDLE    = 5'b00001;
parameter [4:0] START   = 5'b00010;
parameter [4:0] DATA    = 5'b00100;
parameter [4:0] STOP    = 5'b01000;
parameter [4:0] WAIT    = 5'b10000;

parameter sys_clk = 50_000_000;
parameter bps = 115200;
parameter delay = sys_clk / bps;

(* preserve *)reg [4:0] cur_state;
(* preserve *)reg [4:0] next_state;
// 接受到的bit 数
reg [3:0] rx_num;
reg [15:0] cnt;

reg [1:0] rx_buffer;
// 缓存两位rx
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        rx_buffer <= 2'b11;
    else
        rx_buffer <= {rx_M2, rx_buffer[1]};
end

// 第一段
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        cur_state <= IDLE;
    else
        cur_state <= next_state;
end
// 第二段
always @(*) begin
    if(!rst_n)begin
        next_state = IDLE;
    end
    else begin
        case (cur_state)
            IDLE    :begin
                if(rx_buffer == 2'b01)
                    next_state = WAIT;
                else
                    next_state = cur_state;
            end
            WAIT    :begin
                if(cnt == delay - 1'b1)
                    next_state = START;
                else
                    next_state = cur_state; 
            end
            START   :begin
                if(rx_num == 4'd8)
                    next_state = STOP;
                else
                    next_state = DATA;
            end
            DATA    :begin
                if(cnt == delay - 1'b1)
                    next_state = START;
                else
                    next_state = DATA;
            end
            STOP    :begin
                next_state = IDLE;
            end   
            default: next_state = IDLE;        
        endcase
    end
end
// 第三段
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)begin
        data_rx <= 1'b0;
        done_rx <= 1'b0;
        rx_num  <= 1'b0;
        cnt     <= 1'b0;
    end
    else begin
        case (cur_state)
            IDLE    :begin
            //    data_rx <= 1'b0;
               done_rx <= 1'b0;
               rx_num  <= 1'b0; 
               cnt     <= 1'b0;
            end
            WAIT    :begin
                data_rx <= 1'b0;
                done_rx <= 1'b0;
                rx_num  <= 1'b0; 
                if(cnt == delay - 1'b1)
                    cnt     <= 1'b0;
                else     
                    cnt     <= cnt + 1'b1;           
            end
            START   :begin
                done_rx <= 1'b0;
                cnt     <= 1'b0;
                rx_num  <= rx_num + 1'b1; 
            end
            DATA    :begin
                done_rx <= 1'b0;
                // 计时
                if(cnt == delay - 1'b1)
                    cnt     <= 1'b0; 
                else
                    cnt     <= cnt + 1'b1;
                // 输出
                if(cnt == delay/2-1)
                    data_rx[rx_num-1] <= rx_buffer[1];
                    // data_rx <= data_rx + 1;
            end
            STOP    :begin
                rx_num  <= 1'b0; 
                cnt     <= 1'b0;
                done_rx <= 1'b1;
            end   
            default:begin
                data_rx <= 1'b0;
                done_rx <= 1'b0;
                rx_num  <= 1'b0;
                cnt     <= 1'b0;
            end        
        endcase
    end
end

endmodule