`include "UartStates.vh" /* * 8-bit UART Receiver. * Able to receive 8 bits of serial data, one start bit, one stop bit. * When receive is complete {done} is driven high for one clock cycle. * Output data should be taken away by a few clocks or can be lost. * When receive is in progress {busy} is driven high. * Clock should be decreased to baud rate. */ module Uart8Receiver ( input wire clk, // baud rate input wire en, input wire in, // rx output reg [7:0] out, // received data output reg done, // end on transaction output reg busy, // transaction is in process output reg err // error while receiving data ); // states of state machine reg [1:0] state; reg [2:0] bitIdx = 3'b0; // for 8-bit data reg [7:0] receivedData = 8'b0; // temporary storage for input data initial begin out <= 8'b0; err <= 1'b0; done <= 1'b0; busy <= 1'b0; state <= 2'b00; // RESET state end always @(posedge clk) begin if (!en) begin state <= 2'b00; // RESET state end case (state) 2'b00: begin // RESET state out <= 8'b0; err <= 1'b0; done <= 1'b0; busy <= 1'b0; bitIdx <= 3'b0; receivedData <= 8'b0; if (en) begin state <= 2'b01; // Transition to IDLE state end end 2'b01: begin // IDLE state done <= 1'b0; if (!in) begin // Detecting start bit (line goes low) state <= 2'b10; // Transition to DATA_BITS state bitIdx <= 3'b0; receivedData <= 8'b0; busy <= 1'b1; err <= 1'b0; end end 2'b10: begin // DATA_BITS state receivedData[bitIdx] <= in; // Collecting data bits if (bitIdx == 3'b111) begin bitIdx <= 3'b0; out <= receivedData; // Store received byte state <= 2'b11; // Transition to STOP_BIT state end else begin bitIdx <= bitIdx + 3'b1; end end 2'b11: begin // STOP_BIT state if (in) begin // Stop bit should be high (line goes high) state <= 2'b01; // Transition back to IDLE state done <= 1'b1; busy <= 1'b0; end else begin err <= 1'b1; // Error if stop bit is not high state <= 2'b00; // Transition to RESET state end end default: state <= 2'b01; // Default to IDLE state endcase end endmodule