Bird
Raised Fist0
Verilogprogramming~10 mins

UART receiver module in Verilog

Choose your learning style10 modes available
Introduction

A UART receiver module reads serial data sent one bit at a time and converts it into parallel data. It helps devices talk to each other using simple wires.

When you want to receive data from a serial device like a GPS or a sensor.
When building communication between a microcontroller and a computer.
When you need to read data sent over a simple wire without complex protocols.
When learning how serial communication works in hardware.
When designing embedded systems that use UART for debugging or control.
Syntax
Verilog
module uart_rx(
    input wire clk,
    input wire rst,
    input wire rx,
    output reg [7:0] data_out,
    output reg data_ready
);

// Internal signals and registers
// ...

endmodule

The module uses inputs for clock (clk), reset (rst), and the serial data line (rx).

Outputs include the received byte (data_out) and a flag (data_ready) to show when data is ready.

Examples
Basic module structure with inputs and outputs defined.
Verilog
module uart_rx(
    input wire clk,
    input wire rst,
    input wire rx,
    output reg [7:0] data_out,
    output reg data_ready
);

// Implementation here

endmodule
Using a clock and reset to control the receiving process.
Verilog
always @(posedge clk or posedge rst) begin
    if (rst) begin
        // reset logic
    end else begin
        // receive logic
    end
end
Sample Program

This UART receiver module listens on the rx line for serial data at 115200 baud with a 50MHz clock. It detects the start bit, samples each data bit in the middle, and outputs the received byte on data_out. When a full byte is received, data_ready goes high for one clock cycle.

Verilog
module uart_rx(
    input wire clk,
    input wire rst,
    input wire rx,
    output reg [7:0] data_out,
    output reg data_ready
);

    parameter CLKS_PER_BIT = 434; // For 115200 baud with 50MHz clock

    reg [8:0] clk_count = 0;
    reg [3:0] bit_index = 0;
    reg [7:0] rx_shift_reg = 0;
    reg rx_busy = 0;
    reg rx_d1 = 1, rx_d2 = 1;

    // Synchronize rx to clk domain
    always @(posedge clk) begin
        rx_d1 <= rx;
        rx_d2 <= rx_d1;
    end

    always @(posedge clk or posedge rst) begin
        if (rst) begin
            clk_count <= 0;
            bit_index <= 0;
            rx_busy <= 0;
            data_ready <= 0;
            data_out <= 0;
        end else begin
            data_ready <= 0; // Clear data ready each cycle
            if (!rx_busy) begin
                if (rx_d2 == 0) begin // Start bit detected
                    rx_busy <= 1;
                    clk_count <= CLKS_PER_BIT / 2; // To sample middle of bit
                    bit_index <= 0;
                end
            end else begin
                if (clk_count == CLKS_PER_BIT - 1) begin
                    clk_count <= 0;
                    bit_index <= bit_index + 1;

                    if (bit_index == 0) begin
                        // Start bit, ignore
                    end else if (bit_index >= 1 && bit_index <= 8) begin
                        rx_shift_reg <= {rx_d2, rx_shift_reg[7:1]};
                    end else if (bit_index == 9) begin
                        // Stop bit
                        rx_busy <= 0;
                        data_out <= rx_shift_reg;
                        data_ready <= 1;
                    end
                end else begin
                    clk_count <= clk_count + 1;
                end
            end
        end
    end

endmodule
OutputSuccess
Important Notes

Make sure the clock frequency and baud rate match for correct timing.

Sampling in the middle of each bit helps avoid errors from signal noise.

This example assumes 8 data bits, no parity, and 1 stop bit.

Summary

A UART receiver reads serial bits and converts them to bytes.

It uses a clock to time when to sample bits.

When a byte is ready, it signals with data_ready.

Practice

(1/5)
1. What is the primary role of a UART receiver module in digital communication?
easy
A. To read serial bits and convert them into bytes
B. To generate clock signals for data transmission
C. To encode parallel data into serial format
D. To amplify the input signal strength

Solution

  1. Step 1: Understand UART receiver function

    A UART receiver reads incoming serial bits one by one.
  2. Step 2: Conversion to bytes

    It collects these bits and converts them into a byte for further processing.
  3. Final Answer:

    To read serial bits and convert them into bytes -> Option A
  4. Quick Check:

    UART receiver = serial bits to bytes [OK]
Hint: Remember UART receiver converts serial bits to bytes [OK]
Common Mistakes:
  • Confusing receiver with transmitter
  • Thinking it generates clock signals
  • Assuming it amplifies signals
2. Which of the following is the correct Verilog syntax to declare a 8-bit output register named data_out in a UART receiver module?
easy
A. output reg [7:0] data_out;
B. reg output [7:0] data_out;
C. output [7:0] reg data_out;
D. reg [7:0] output data_out;

Solution

  1. Step 1: Identify correct order for output register declaration

    In Verilog, the correct order is 'output reg [width] name;'.
  2. Step 2: Check each option

    Only output reg [7:0] data_out; follows this syntax correctly.
  3. Final Answer:

    output reg [7:0] data_out; -> Option A
  4. Quick Check:

    output reg declaration syntax = output reg [7:0] data_out; [OK]
Hint: Use 'output reg [width] name;' for output registers [OK]
Common Mistakes:
  • Placing 'reg' after 'output'
  • Swapping 'output' and 'reg' keywords
  • Omitting bit width
3. Given the following Verilog snippet inside a UART receiver module:
always @(posedge clk) begin
  if (start_bit_detected) begin
    bit_count <= 0;
    data_reg <= 0;
  end else if (bit_sample_enable) begin
    data_reg <= {serial_in, data_reg[7:1]};
    bit_count <= bit_count + 1;
  end
end

What will be the value of data_reg after 3 samples if serial_in was 1, 0, then 1 in consecutive samples?
medium
A. 00000101 (binary)
B. 10100000 (binary)
C. 00000011 (binary)
D. 11100000 (binary)

Solution

  1. Step 1: Understand bit shifting in data_reg

    Each sample shifts data_reg right by 1 and inserts serial_in at MSB.
  2. Step 2: Calculate data_reg after each sample

    Initial data_reg=00000000
    Sample 1 (serial_in=1): data_reg=10000000
    Sample 2 (serial_in=0): data_reg=01000000
    Sample 3 (serial_in=1): data_reg=10100000
    Thus, after 3 samples, data_reg = 10100000 (binary)
  3. Final Answer:

    10100000 (binary) -> Option B
  4. Quick Check:

    Shift right + insert serial_in MSB = 10100000 [OK]
Hint: Track bit shifts and insertions stepwise [OK]
Common Mistakes:
  • Confusing MSB and LSB positions
  • Assuming left shift instead of right
  • Ignoring initial zero value
4. In a UART receiver module, the following code snippet causes the received data to be incorrect:
always @(posedge clk) begin
  if (start_bit_detected) begin
    bit_count <= 0;
    data_reg <= 0;
  end else if (bit_sample_enable) begin
    data_reg <= {data_reg[6:0], serial_in};
    bit_count <= bit_count + 1;
  end
end

What is the likely error in this code?
medium
A. bit_count is not incremented correctly
B. The start bit is not being detected properly
C. Bits are shifted left instead of right, causing wrong bit order
D. serial_in is not sampled at the correct clock edge

Solution

  1. Step 1: Analyze bit shifting direction

    The code shifts data_reg left by 1 bit and inserts serial_in at LSB.
  2. Step 2: Understand UART bit order

    UART typically receives LSB first, so bits should be shifted right with serial_in at MSB to maintain correct order.
  3. Final Answer:

    Bits are shifted left instead of right, causing wrong bit order -> Option C
  4. Quick Check:

    Incorrect shift direction = Bits are shifted left instead of right, causing wrong bit order [OK]
Hint: UART bits usually shift right; check shift direction [OK]
Common Mistakes:
  • Mixing up left and right shifts
  • Ignoring bit order in UART protocol
  • Assuming start bit detection error
5. You want to design a UART receiver module that sets a data_ready flag only after receiving all 8 data bits and the stop bit. Which approach correctly implements this behavior?
hard
A. Set data_ready when bit_count == 8 (only data bits)
B. Set data_ready immediately after detecting the start bit
C. Set data_ready after receiving 7 data bits only
D. Set data_ready when bit_count == 9 (8 data bits + 1 stop bit)

Solution

  1. Step 1: Understand UART frame structure

    A UART frame has 1 start bit, 8 data bits, and 1 stop bit.
  2. Step 2: Determine when data is fully received

    Data is ready only after all 8 data bits and the stop bit are received, so bit_count should reach 9.
  3. Final Answer:

    Set data_ready when bit_count == 9 (8 data bits + 1 stop bit) -> Option D
  4. Quick Check:

    Data ready after 9 bits = Set data_ready when bit_count == 9 (8 data bits + 1 stop bit) [OK]
Hint: Wait for all bits including stop bit before setting data_ready [OK]
Common Mistakes:
  • Setting data_ready too early
  • Ignoring stop bit in count
  • Confusing start bit with data bits
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard