top of page

UART protocol Checker - Baud Rate

In the last tutorial, we wrote a basic program on UART protocol checker. 

Let's go ahead and enhance the checker but before that let's understand the term baud rate and how the protocol checker will be checking it. 

Let's again go to the story of two friends to understand this. 

Baud rate is like the speed at which two devices talk to each other. Imagine you have two friends and you want to send messages to each other using a flashlight. The speed at which you turn the flashlight on and off determines the baud rate.

If you turn the flashlight on and off very quickly, it means you are sending messages at a high baud rate. This means you can send messages faster, but it may be more difficult for your friend to understand the messages because they need to pay attention very quickly.

On the other hand, if you turn the flashlight on and off slowly, it means you are sending messages at a low baud rate. This means you can send messages more slowly, but it may be easier for your friend to understand the messages because they have more time to see each flash.

So, baud rate is simply the speed at which devices can send and receive messages. It determines how quickly or slowly they can communicate with each other.

Now as we understand baud rate, let's go ahead and enhance our checker. 

​​

Here are steps to do it: 

Step 1: Define the Baud Rate Checker Component

  • Create a new UVM component called "BaudRateChecker" that extends uvm_component.

  • Add a task or function to implement the baud rate check functionality.

Step 2: Configure the Baud Rate Checker in the Testbench

  • Instantiate the BaudRateChecker component in the testbench environment.

  • Set the desired baud rate value for the check using a configuration mechanism like UVM config objects or command-line arguments.

Step 3: Integrate the Baud Rate Checker in the Testbench

  • Connect the relevant signals from the DUT (Device Under Test) to the BaudRateChecker component.

  • Ensure the BaudRateChecker can access the necessary signals such as the clock and the RX (receive) signal.

Step 4: Implement the Baud Rate Check

  • In the BaudRateChecker, sample the RX signal on each rising edge of the clock.

  • Count the number of bit transitions (high-to-low or low-to-high) within a fixed time window.

  • Calculate the measured baud rate by dividing the number of bit transitions by the time window duration.

  • Compare the measured baud rate with the expected baud rate.

  • Raise an error or assertion if the measured baud rate deviates beyond an acceptable tolerance range.

​

UVM Code: 

`include "uvm_macros.svh"

class uart_checker extends uvm_component;
  // Input and output ports
  uvm_analysis_port #(bit) uart_rx;
 
  // Expected number of clock cycles for each bit
  parameter BAUD_RATE = 9600;
  parameter CLK_PERIOD = 1.0 / BAUD_RATE;
  parameter BIT_CYCLES = $floor(CLK_PERIOD / $timeunit);
 
  // Constructor
  function new(string name = "uart_checker", uvm_component parent = null);
    super.new(name, parent);
  endfunction

  // UVM component macro
  `uvm_component_utils(uart_checker)

  // Build phase
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    uart_rx = new("uart_rx", this);
  endfunction

  // Run phase
  task run_phase(uvm_phase phase);
    bit rx_bit;
    forever begin
      uart_rx.get(rx_bit);
      if (rx_bit == 1'b0) begin
        // Start bit detected, start monitoring data and stop bits
        bit [7:0] received_data = 0;
        bit expected_bit = 1;
        bit [BIT_CYCLES-1:0] bit_cycles = 0;
        bit baud_error = 0;
        bit framing_error = 0;
        
        repeat (BIT_CYCLES-1) begin
          uart_rx.get(rx_bit);
          received_data <<= 1;
          received_data[0] = rx_bit;
          bit_cycles++;
          
          if (rx_bit != expected_bit)
            framing_error = 1;
        end
        
        // Verify stop bit
        uart_rx.get(rx_bit);
        bit_cycles++;
        if (rx_bit != 1)
          framing_error = 1;
        
        // Verify baud rate
        if (bit_cycles != BIT_CYCLES)
          baud_error = 1;
        
        // Add your additional checks here
        
        if (baud_error)
          `uvm_error("BAUD_ERROR", $sformatf("Baud rate violation detected at cycle %0d", $time));
        if (framing_error)
          `uvm_error("FRAMING_ERROR", $sformatf("Framing error detected at cycle %0d", $time));
      end
    end
  endtask
endclass

module tb;
  initial begin
    // Create and configure the UART checker
    uart_checker checker;
    checker = new("uart_checker");
    checker.uart_rx.connect(tb.uart_rx); // Connect the checker's RX port to DUT's RX signal

    // Start the simulation
    run_test();
  end

  // Your DUT signals
  wire uart_rx;
 
  // Test task
  task run_test();
    // Add test scenarios to stimulate the DUT
    // ...
  endtask
endmodule

 

​
 

bottom of page