📖 Scenario: You are designing a UART receiver module for a simple communication system. UART (Universal Asynchronous Receiver/Transmitter) is used to receive serial data bits and convert them into parallel data bytes.This project will guide you step-by-step to build a UART receiver module in Verilog that can receive 8-bit data with 1 start bit and 1 stop bit.
🎯 Goal: Build a UART receiver module in Verilog that reads serial data input, detects the start bit, samples the data bits, and outputs the received byte.
📋 What You'll Learn
Create a register to hold the received data bits
Create a counter to track bit positions
Detect the start bit on the serial input
Sample the data bits at the correct baud rate
Output the received 8-bit data byte
💡 Why This Matters
🌍 Real World
UART receivers are used in embedded systems to receive serial data from sensors, computers, or other devices.
💼 Career
Understanding UART communication and Verilog coding is essential for hardware engineers working on digital communication interfaces and FPGA design.
Progress0 / 4 steps
1
DATA SETUP: Define input and output ports and internal registers
Write a Verilog module named uart_rx with inputs clk, reset, and rx (serial data input). Define an 8-bit output register data_out to hold the received byte. Also, declare an internal 4-bit register bit_index to track the bit position during reception.
Verilog
Hint
Define the module and declare the inputs and outputs exactly as specified. Use reg for data_out and bit_index.
2
CONFIGURATION: Add a baud rate counter for timing
Inside the uart_rx module, declare a 16-bit register baud_counter to count clock cycles for baud rate timing. Also, define a parameter BAUD_MAX set to 5208 to represent the number of clock cycles per baud interval.
Verilog
Hint
Declare baud_counter as a 16-bit register and BAUD_MAX as a parameter with the exact value.
3
CORE LOGIC: Implement start bit detection and data bit sampling
Add an always @(posedge clk or posedge reset) block inside uart_rx. On reset, clear bit_index, baud_counter, and data_out. Otherwise, implement logic to detect the start bit (when rx is low and bit_index is zero), increment baud_counter each clock cycle, and when baud_counter reaches BAUD_MAX, sample the rx line into data_out at the current bit_index position, then increment bit_index. Reset baud_counter after sampling.
Verilog
Hint
Use an always block triggered on clock and reset. Detect start bit when bit_index is zero and rx is low. Use baud_counter to time sampling. Sample bits into data_out and increment bit_index. Reset counters appropriately.
4
OUTPUT: Display the received data byte
Add a testbench module named uart_rx_tb that instantiates uart_rx. In the testbench, simulate a clock and reset, then apply a serial data stream representing the byte 8'b10101010 with start and stop bits on the rx input. Use $display to print the received data_out value after reception.
Verilog
Hint
Create a testbench that toggles clk and applies the serial bits for the byte 8'b10101010 with start and stop bits on rx. Use $display to print data_out after reception.
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
Step 1: Understand UART receiver function
A UART receiver reads incoming serial bits one by one.
Step 2: Conversion to bytes
It collects these bits and converts them into a byte for further processing.
Final Answer:
To read serial bits and convert them into bytes -> Option A
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
Step 1: Identify correct order for output register declaration
In Verilog, the correct order is 'output reg [width] name;'.
Step 2: Check each option
Only output reg [7:0] data_out; follows this syntax correctly.
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
Step 1: Understand bit shifting in data_reg
Each sample shifts data_reg right by 1 and inserts serial_in at MSB.
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
Step 1: Analyze bit shifting direction
The code shifts data_reg left by 1 bit and inserts serial_in at LSB.
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.
Final Answer:
Bits are shifted left instead of right, causing wrong bit order -> Option C
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
Step 1: Understand UART frame structure
A UART frame has 1 start bit, 8 data bits, and 1 stop bit.
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.
Final Answer:
Set data_ready when bit_count == 9 (8 data bits + 1 stop bit) -> Option D
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 unknownstrongwhile earning +1 Grip toward your certificate.