|  | // Oversampling UART receiver. | 
|  | module UART_RX( | 
|  | input rst, clk, baud_edge, rx, | 
|  | output [7:0] data, | 
|  | output data_ready, framing_error | 
|  | ); | 
|  | parameter OVERSAMPLE = 8; | 
|  | localparam FIND_EDGE = 3'd1, START = 3'd2, DATA = 3'd3, END = 3'd4; | 
|  |  | 
|  | reg prev_rx; | 
|  | reg [7:0] data_reg; | 
|  | reg [2:0] data_counter; | 
|  | reg [2:0] state = 0; | 
|  | reg [$clog2(OVERSAMPLE+OVERSAMPLE/2)-1:0] over_sample_counter = 0; | 
|  |  | 
|  | reg data_ready_reg = 0; | 
|  | reg framing_error_reg = 0; | 
|  |  | 
|  | assign data = data_reg; | 
|  | assign data_ready = data_ready_reg; | 
|  | assign framing_error = framing_error_reg; | 
|  |  | 
|  | always @(posedge clk) begin | 
|  | if(rst) begin | 
|  | data_reg <= 0; | 
|  | prev_rx <= 0; | 
|  | data_ready_reg <= 0; | 
|  | state <= FIND_EDGE; | 
|  | data_counter <= 0; | 
|  | over_sample_counter <= 0; | 
|  | end else if(baud_edge) begin | 
|  | case(state) | 
|  | FIND_EDGE: begin | 
|  | prev_rx <= rx; | 
|  |  | 
|  | if(prev_rx & !rx) begin | 
|  | state <= START; | 
|  | prev_rx <= 0; | 
|  | over_sample_counter <= 0; | 
|  | end | 
|  | end | 
|  | START: begin | 
|  | // Align sample edge in the middle of the pulses. | 
|  | if(over_sample_counter == OVERSAMPLE/2-1) begin | 
|  | over_sample_counter <= 0; | 
|  | data_counter <= 0; | 
|  | state <= DATA; | 
|  | end else begin | 
|  | over_sample_counter <= over_sample_counter + 1; | 
|  | end | 
|  | end | 
|  | DATA: begin | 
|  | if(over_sample_counter == OVERSAMPLE-1) begin | 
|  | over_sample_counter <= 0; | 
|  | data_reg[data_counter] <= rx; | 
|  | if(data_counter == 7) begin | 
|  | state <= END; | 
|  | data_counter <= 0; | 
|  | end else begin | 
|  | data_counter <= data_counter + 1; | 
|  | end | 
|  | end else begin | 
|  | over_sample_counter <= over_sample_counter + 1; | 
|  | end | 
|  | end | 
|  | END: begin | 
|  | if(over_sample_counter == OVERSAMPLE-1) begin | 
|  | if(rx) begin | 
|  | data_ready_reg <= 1; | 
|  | end else begin | 
|  | framing_error_reg <= 1; | 
|  | end | 
|  | state <= FIND_EDGE; | 
|  | end else begin | 
|  | over_sample_counter <= over_sample_counter + 1; | 
|  | end | 
|  |  | 
|  | end | 
|  | default: begin | 
|  | data_ready_reg <= 0; | 
|  | state <= FIND_EDGE; | 
|  | end | 
|  | endcase | 
|  | end else begin | 
|  | data_ready_reg <= 0; | 
|  | framing_error_reg <= 0; | 
|  | end | 
|  | end | 
|  | endmodule |