A simple “Hello, World!” in UVM

Hello, World!

Thanks for joining me!

This is the first post in this blog and let’s start with a classic, the “Hello, World!“. Traditionally “Hello, World!” is the first step in learning a new language. It’s simple, prints output text and gives you a quick feel of what the language offers.

Let’s look at a few “Hello, World!” programs in different programming languages and make some comments.

#include <stdio.h>
void main() {
  printf("Hello World");
}

Easy enough, I had say.

Java

class HelloWorld {
  public static void main(String[] args) {
    System.out.println("Hello, world!");
  }
}

A Classification, I object.

Python

print("Hello, world!")

Really, this is it ?

Prologue

Universal Verification Methodology (UVM) is based on System-Verilog. I am not going to elaborate on what a methodology is, or how it came into being. That is a story for another day.

I have struggled to get started with UVM. There is no easy learning guide. Everything available online, barring a couple of web-pages, starts off in a complicated manner and doesn’t break down things for a beginner to understand. A lot of “Why’s” and “How’s” remain as questions long forgotten and conveniently ignored.

With this post, I intend to make things easy for beginners and novices. I will try to break down stuff that were hard for me to understand and digest. I will try to answer questions that I had. This post is also meant to serve me better understand these topics.

The first question that I have asked myself is :

How do I write a simple “Hello, World!” in UVM ? 

Let me add more context. All programming languages that I have learnt, I have indeed started with the quintessential “Hello, World!” It’s my first step, and a massive physiological barrier. If I can’t write a simple “Hello, World!”, is there any point in trying to do more?

The truth is, I have been doing more with UVM. Architecting and building massive UVM Test-benches using templates and available code. That’s pretty easy. However, every now and then, there comes a problem to solve for which I had to learn something I didn’t know. I soon realized that my foundations were shaky and I had to do something about it. 

After all, UVM is a methodology based on System-Verilog. I wanted to start with a “Hello, World!” program in System-Verilog and replace it part-by-part to make it a UVM “Hello, World!” The question I really wanted to answer was :

What’s the bare minimum code for UVM “Hello-World!” ?

System-Verilog

module my_sv_hw;
  initial
    $display("Hello, World!");
endmodule

I know this, alright!

UVM “Hello, World!”

One can argue, given that UVM is based on System-Verilog, the same program above is also the bare minimum “Hello, World!” in UVM. I tried the same argument in an interview, and I did not get the job for obvious reasons.

Let’s get started. I don’t really care about a Device-Under-Test (DUT). I am going to approach this as a programming language that can print a string. If System-Verilog can just print a string, UVM should also be able to achieve the same.

Step 1 : Use a ‘test’

UVM runs a “test“. I am going to replace the $display() with a “run_test()” in my UVM-Test-Bench. My code now looks like this:

module my_uvm_hw;
  initial
    run_test("my_uvm_hw_test");
endmodule

That’s it. UVM understands “run_test“, so I don’t really have to dig into what it does right now. “run_test“, true to what it sounds, is trying to run a test called “my_uvm_hw_test

Step 2a : Start Writing the test!

Using what little of object oriented programming I know, I am going to write my test. UVM says all tests need to extend from a base-class called “uvm_test”. Don’t ask why! Actually, it’s okay to ask “why”. I will address the “why” in another blog post. For now, I am going to assume that uvm_test base class is a basic class template that really does nothing by itself. This leads to the below skeleton.

class my_uvm_hw_test extends uvm_test;
endclass

Step 2b : The constructor

My class needs a constructor. It doesn’t really have to do anything. Nevertheless, you need a constructor to be present, and the constructor to reference the parent class’s constructor. This isn’t UVM, it’s just object-oriented-programming thing. The base class has a constructor, so extended class needs one too. This gives me the below code.

function new(string name, uvm_component parent);
  super.new(name, parent);
endfunction

Step 2c : Run it already!

UVM works in phases. Think of it as stages. Think of it as Lego. When you are putting all pieces together, it’s the “build” phase. When you playing with the completed Lego, it’s the “run” phase. I have just one block here. I don’t need a build-phase (because there is nothing else to put together). I just need a run-phase. And that’s where I am going to sneak in my little string.

task run_phase(uvm_phase phase);
  $display("Hello, World!");
endtask

Step 3 : Some UVM Stuff

UVM requires me to register classes with “factory“. I think of this as a passport or Social Security Number. It helps UVM factory know who I am, anytime. This is done by the below code.

`uvm_component_utils(my_uvm_hw_test)

For the compiler/simulator to understand that you are talking UVM, you need to import things-you-need from the uvm-package. For now, I will import everything (using *). For example, uvm_package includes the code for “uvm_test” base class.

Step 4 : Put everything together

import uvm_pkg::*; 
class my_uvm_hw_test extends uvm_test;
  `uvm_component_utils(my_uvm_hw_test)

  function new(string name, uvm_component parent);
    super.new(name, parent);
  endfunction

  task run_phase(uvm_phase phase);
    $display("Hello, World!");
  endtask
endclass

module my_uvm_hw;
  initial
    run_test("my_uvm_hw_test");
endmodule

Not too shabby, eh?

Final Thoughts

And I am done. I have a piece of code that I can understand. A piece of code that runs and displays “Hello, World!”. It’s simple and neat. I like it.

Of course, I can’t do much with just this. I had be surprised if this is useful in the real world at all. But that’s okay. Most “Hello, World!” programs aren’t immensely useful either. It’s a start. I can build on this!

There are still a few questions that remain unanswered. Can I skip the factory registration for my class ? Can I not have a constructor ? Do I really need a “run” phase ? I will try answering these questions in my upcoming posts.

Hopefully, this was helpful. If not, at least it was a decent read. Let me know your thoughts.

2 thoughts on “A simple “Hello, World!” in UVM

Leave a comment