Skip to content

Instantly share code, notes, and snippets.

@vvuk
Created December 11, 2022 06:25
Show Gist options
  • Save vvuk/31c50be9d3050db83e4bdd492cfb0487 to your computer and use it in GitHub Desktop.
Save vvuk/31c50be9d3050db83e4bdd492cfb0487 to your computer and use it in GitHub Desktop.
uart.v
reg [3:0] rxState = 0;
reg [12:0] rxDelay = 0;
reg [2:0] rxBitIndex = 0;
reg [7:0] dataIn = 0;
reg byteReady = 0;
localparam RX_STATE_IDLE = 0;
localparam RX_STATE_START_BIT = 1;
localparam RX_STATE_READ = 2;
localparam RX_STATE_STOP_BIT = 3;
always @(posedge clk) begin
if (rxDelay != 0)
rxDelay <= rxDelay - 1;
else begin
case (rxState)
// we're idle; if uart_rx goes low, then we're about to get a start bit.
// delay by the half the frame length to synchronize
RX_STATE_IDLE: begin
if (uart_rx == 0) begin
rxState <= RX_STATE_START_BIT;
rxDelay <= FRAME_LENGTH / 2;
rxBitIndex <= 0;
byteReady <= 0;
end
end
RX_STATE_START_BIT: begin
// we're at the middle of the start bit, delay for a full frame, then read a data bit
rxDelay <= FRAME_LENGTH;
rxState <= RX_STATE_READ;
end
RX_STATE_READ: begin
// read the bit into dataIn
dataIn <= {uart_rx, dataIn[7:1]};
rxBitIndex <= rxBitIndex + 1;
// wait a full frame before the next state...
rxDelay <= FRAME_LENGTH;
// ... which is going to be STATE_READ again, until we read all the bits, and then STOP_BIT
if (rxBitIndex == 3'b111)
rxState <= RX_STATE_STOP_BIT;
end
RX_STATE_STOP_BIT: begin
byteReady <= 1;
// delay the second half of the frame length, and then we're idle again
rxDelay = FRAME_LENGTH / 2 + 1;
rxState <= RX_STATE_IDLE;
end
endcase
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment