The Ultimate Hitchhiker's Guide to Verification

Dumping ground of useful links/articles/tips/tricks on System Verilog/VMM/OVM as and when I stumble upon them and some of my views on it :)

What is this "System Verilog Callback"

Callback is one of the major confusing point for a System Verilog learner. Many people have asked the same question in many forums, but the answer doesn't seems to satisfy fully the quest of the person who has raised the querry. I too had the same issue, but I learned it slowly in a hard way. I am presenting here a way in which if I had an answer, I would have learned faster.

We can pass data member to any function. Now consider a case where you are passing a function (say func1) as a data member to another function (say func2) and you get what is called callback. The reason why it is called callback is that the function func2 now can call anywhere in its code function func1.

From wikipedia

In computer programming, a callback is executable code that is passed as an argument to other code. It allows a lower-level software layer to call a subroutine (or function) defined in a higher-level layer.

Note that SV doesn't give a straight-forward way of passing a function as argument for another function. But we can get the same result (almost we can say!) by using OOP. The idea is to describe all the functions (both func1 type and func2 type) in a base class (don't implement the funct2 kind of function and make them virtual for polymorphism), and then extend the class to a derived class where you implement the func2 type of function.

class abc_transactor;
virtual task pre_send(); endtask
virtual task post_send(); endtask

task xyz();
// Some code here
// Some more code here
// And some more code here
endtask : xyz
endclass : abc_transactor

class my_abc_transactor extend abc_transactor;
virtual task pre_send();
... // This function is implemented here

virtual task post_send();
... // This function is implemented here

endclass : my_abc_transactor

Now let me explain how it is going to work. The base class abc_transactor has 3 tasks, 2 of which are declared virtual and are not implemented. But they are being called from another task xyz() which is fully implemented. The unimplemented virtual task are called callback class.

The child class, which extends from the base class, implements the previous unimplemented tasks. It inherits the xyz() task from the base class and hence doesn't need to change it. By this we can inject executable code to a function without modifying it.

Now the next question is why is done. There are many reasons for it.
  1. The biggest advantage is that you can modify the behavior of task xyz() without modifying it in the base or child class. It is a big advantage as no one wants to fiddle with known good functioning code.
  2. Consider a case where you are writing a base class which is going to be used by multiple test environment, and for each test environment a known part of the code, or a known function/task is going to change. The natural choice is to implement those change-in-every-case functions/tasks as callback method and let the user extend your base class with specifying only that part of the code which need to be changed in his case.
Simple callback using the above approach does have some known limitations, which can be solved using design patterns (from OOP land), the details of which can be found at Janik's article of vmm_callback.



Post a Comment

About Me

My photo
I am from Sambalpur, Orissa, India. Have done Btech and Mtech in ECE from IIT Kharagpur. Currently working as Lead Member Technical Staff at Mentor Graphics Noida

My Feedburner


Search This Blog

My Shelfari Bookshelf

Shelfari: Book reviews on your book blog


Traffic Summary