56 lines
1.5 KiB
Verilog
56 lines
1.5 KiB
Verilog
/**
|
|
* UartRX receives bytes over UART
|
|
*
|
|
* When clear = 1 the chip clears the receive buffer and is ready to receive
|
|
* next byte. out[15] is set to 1 to show, that chip is ready to receive next
|
|
* byte. When RX goes low the chip starts sampling the RX line. After reading
|
|
* of byte completes, chip ouputs the received byte to out[7:0]] with out[15]=0.
|
|
*/
|
|
`default_nettype none
|
|
module UartRX (
|
|
input wire clk,
|
|
input wire clear,
|
|
input wire RX,
|
|
output reg [15:0] out
|
|
);
|
|
|
|
reg [7:0] baud_count;
|
|
reg [3:0] bit_index;
|
|
reg [7:0] rx_shift;
|
|
reg rx_active;
|
|
|
|
initial begin
|
|
out <= 16'b0;
|
|
rx_active <= 1'b0;
|
|
end
|
|
|
|
|
|
always @(posedge clk) begin
|
|
|
|
out <= (clear | out[15]) ? 16'h8000 : out;
|
|
|
|
if (!rx_active && !RX) begin
|
|
|
|
// RX Falling edge: Start bit detected
|
|
rx_active <= 1;
|
|
rx_shift <= 0;
|
|
baud_count <= 1;
|
|
bit_index <= 0;
|
|
end else if (rx_active) begin
|
|
|
|
baud_count <= (baud_count == 216) ? 0 : baud_count + 1;
|
|
bit_index <= (baud_count == 108) ? bit_index + 1 : bit_index;
|
|
|
|
if (bit_index >= 1 && bit_index <= 8 && baud_count == 108) begin
|
|
rx_shift <= {RX, rx_shift[7:1]};
|
|
end
|
|
|
|
if (bit_index == 10 && baud_count == 216) begin
|
|
rx_active <= 0; // Done receiving 8 bits + stop
|
|
out <= {8'b0, rx_shift};
|
|
end
|
|
end
|
|
end
|
|
|
|
endmodule
|