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 :)

Answers to SystemVerilog Interview Questions - 4

(25)What is the difference between rand and randc?

 Ans:-
rand - Random Variable, same value might come before all the the possible value have been returned. Analogous to throwing a dice.

randc - Random Cyclic Variable, same value doesn't get returned until all possible value have been returned. Analogous to picking of card from a deck of card without replacing. Resource intensive, use sparingly/judiciously
 
(24)How to call the task which is defined in parent object into derived class ?
Ans:-
super.task_name();

(21)What is the difference between always_combo and always@(*)?
 Ans:-
 From SystemVerilog LRM 3.1a:-

  1. always_comb get executed once at time 0, always @* waits till a change occurs on a signal in the inferred sensitivity list
  2. Statement within always_comb can't have blocking timing, event control, or fork-join statement. No such restriction of always @*
  3. Optionally EDA tool might perform additional checks to warn if the behavior within always_comb procedure doesn't represent combinatorial logic
  4. Variables on the left-hand side of assignments within an always_comb procedure, including variables
    from the contents of a called function, shall not be written to by any other processes, whereas always @* permits multiple processes to write to the same variable.
  5. always_comb is sensitive to changes within content of a function, whereas always @* is only sensitive to changes to the arguments to the function.
A small SystemVerilog code snippet to illustrate #5


module dummy;
    logic a, b, c, x, y;

    // Example void function
    function void my_xor;
        input a;           // b and c are hidden input here
        x = a ^ b ^ c;
    endfunction : my_xor

    function void my_or;
        input a;           // b and c are hidden input here
        y = a | b | c;
    endfunction : my_xor
    
    always_comb            // equivalent to always(a,b,c)
        my_xor(a);         // Hidden inputs are also added to sensitivity list

    always @*              // equivalent to always(a)
        my_or(a);          // b and c are not added to sensitivity list
endmodule

(20)List the predefined randomization methods.
  Ans:-
  1. randomize
  2. pre_randomize
  3. post_randomize
(19)What is scope randomization ?
  Ans:-
  Scope randomization ins SystemVerilog allows assignment of unconstrained or constrained random value to the variable within current scope

module MyModule;      
integer var, MIN;      

initial begin          
    MIN = 50;          
    for ( int i = 0;i<10 ;i++) begin              
        if( randomize(var) with { var < 100 ; var > MIN ;})  
            $display(" Randomization sucsessfull : var = %0d Min = %0d",var,MIN);   
        else                  
            $display("Randomization failed");
    end
          
    $finish;     
end
endmodule

Answers to SystemVerilog Interview Questions - 3

(88)How to check weather a handles is holding object or not ?
Ans:-
It is basically checking if the object is initialized or not. In SystemVerilog all uninitialized object handles have a special value of null, and therefore whether it is holding an object or not can be found out by comparing the object handle to null. So the code will look like:-


usb_packet My_usb_packet; 
...
if(My_usb_packet == null) begin
    // This loop will get exited if the handle is not holding any object
    ....
end else begin
    // Hurray ... the handle is holding an object
    ...
end

(87)What is the difference between initial block and final block?
Ans:-
There are many difference between initial and final block. I am listing the few differences that is coming to mind now.
  1. The most obvious one : Initial blocks get executed at the beginning of the simulation, final block at the end of simulation
  2. Final block has to be executed in zero time, which implies it can't have any delay, wait, or non-blocking assignments. Initial block doesn't have any such restrictions of execution in zero time (and can have delay, wait and non-blocking statements)
Final block can be used to display statistical/genaral information regarding the status of the execution like this:-

final begin
    $display("Simulation Passed");
    $display("Final value of xyz = %h",xyz);
    $display("Bye :: So long, and Thanks for all the fishes");
end

(69)What is the difference between bits and logic?
Ans:-
bits is 2-valued (1/0) and logic is 4-valued (0/1/x/z)

(65)What is tagged union ?
Ans:-
An union is used to stored multiple different kind/size of data in the same storage location.

typedef union{
    bit [31:0]  a;
    int         b;
} data_u;

Now here XYZ union can contain either bit [31:0] data or an int data. It can be written with a bit [31:0] data and read-back with a int data. There is no type-checking done.

In the case where we want to enforce that the read-back data-type is same as the written data-type we can use tagged union which is declared using the qualifier tagged. Whenever an union is defined as tagged, it stores the tag information along with the value (in expense of few extra bits). The tag and values can only be updated together using a statically type-checked tagged union expression. The data member value can be read with a type that is consistent with current tag value, making it impossible to write one type and read another type of value in tagged union. (the details of which can be found in section 3.10 and 7.15 of SV LRM 3.1a).

typedef union tagged{
    bit [31:0]  a;
    int         b;
} data_tagged_u;

// Tagged union expression
data_tagged_u data1 = tagged a 32'h0;
data_tagged_u data2 = tagged b 5;

// Reading back the value
int xyz = data2.b;

(56)What is the need of alias in SV?
Ans:-
The Verilog has one-way assign statement is a unidirectional assignment and can contain delay and strength change. To have bidirectional short-circuit connection SystemVerilog has added alias statement. An excellent usage example of alias can be found out at http://www.systemverilog.org/pdf/SV_Symposium_2003.pdf(Slide # 59)

Few minor updates

Two small updates from my blog.

  1. My blog has started getting attentions from Verification community. Recently my blog got added to blogroll of VMM martial art blog (http://www.vmmcentral.org/vmartialarts/). Seems people are finding my blog worth reading/visiting. My blog is feeling blessed :)
  2. With almost 4-5 hrs of effort I could make syntaxhighlighter work (with small minor hiccups). It took way too much time as compared to what I hoped for, but the end result of it is worth it. A sample o/p from syntax highlighter.

// Byte Pack
function int unsigned atm_cell::byte_pack(ref logic [7:0] bytes[],
                                          input int unsigned offset,
                                          input int kind);
   // Make sure there is enough room in the array
   if(bytes.size() < this.byte_size())
        bytes = new [this.byte_size()] (bytes);
   // Pack the bytes
   bytes[0] = {gfc, vpi[7:4]};
   bytes[1] = {vpi[3:0], vci[15:12]};
   bytes[2] = {vci[11:4]};
   bytes[3] = {vci[3:0], pt, clp};
   bytes[4] = {hec};
   for (int i=0; i < 48; i++)
     bytes[i+5]=payload[i];
   byte_pack = 53;
endfunction

// Byte Unpack
function int unsigned atm_cell::byte_unpack(const ref logic[7:0] bytes[],
                                            input int unsigned offset,
                                            input int len,
                                            input int kind);
   {gfc, vpi, vci, pt, clp, hec} = {bytes[0], bytes[1], bytes[2],
                                     bytes[3], bytes[4]};
   for (int i = 0; i != 48; ++i)
     payload[i] = bytes[i+5];

   return 53;
endfunction

All about fork-join of System Verilog

I have added histstat hit counter for my blog to have an idea about traffic/visitor/search engine trends. One interesting I am observing is that quite a few hit to my site is coming for fork/join interview questions in Google. Hence I thought, why not have a real useful post on fork/join{x} of SystemVerilog and its associated disable/wait command.

Fork-join statement has come from Verilog. It is used for forking out parallel processes in test bench. SV substantially improved fork/join construct to have much more controllability in process creation, destruction, and waiting for end of the process.

The basic syntax of fork join block looks like this:

fork
   begin : First_thread
       // Code for 1st thread
   end
   begin : Second_thread
       // Code for 2nd thread
   end
   begin : Third thread
       // Code for 3rd branch
   end
   ...
join    // Can be join_any, join_none in SV

There are 3 different kind of join keyword in SV, each specifying a different way of waiting for completion of the threads/process created by the fork.
  • join : waits for completion of all of the threads
  • join_any : waits for the completion of the 1st thread, then comes out of fork loop, but lets the other process/thread execute as usual
  • join_none : doesn't wait for completion of any thread, just starts then and immediately exits fork loop.
Now, suppose you have exited the fork loop by join_none or join_any and after some steps, you want to wait till completion of all the threads spanned by the previous fork loop. SV has "wait fork" for the same.

Now, suppose you have exited the fork loop by join_none or join_any and after some steps, you want to kill all the threads spanned by the previous fork loop. SV has "disable fork" for the same.

Next interesting scenario: you have exited fork loop by join_none or join_any and after some steps, you want to kill just one thread (out of many). The solution, have named begin end block and call "disable ". (For example, in the last example if you want to kill only the 2nd thread after exiting the loop via join_any/join_none, then add "disable Second_thread;" at the point where you want to disable the second thread.

I have created a image to pictorially depict fork/join in SV. Hope that will help understand this in a much better way.

VMM shorthand macros

Those who have worked with VMM based verification environment must have encountered situation where you need to code the different essential functions of vmm_data class like copy, psdisplay, compare and so on. This task become very tedious/boring when the number of classes you need to code is substantial, each having lengthy list of data member. Not long back, to get rid of the monotonicity of the above task, I sat for a day and wrote a perl script to generate the complete vmm_data class with essential functions from a class template.

Well, my one day effort is fixing the same is not worth the effort, as VMM has in-built short-hand-macros to solve it. It's especially useful when you don't have much non-standard data type (which are not supported by VMM shorthand macro)


class sample_class extends vmm_data;

// Simple scalar types
rand bit [7:0] da;
rand bit [8:0] db [10];
rand bit dc [];
rand bit dd [int];
rand bit de [string];

...
‘vmm_data_member_begin(sample_class)
‘vmm_data_member_scalar(da, DO_ALL)
‘vmm_data_member_scalar_array(db, DO_ALL)
‘vmm_data_member_scalar_da(dc, DO_ALL)
‘vmm_data_member_scalar_aa_scalar(dd, DO_ALL)
‘vmm_data_member_scalar_aa_string(de, DO_ALL)
‘vmm_data_member_end(sample_class)
...
endclass : sample_class


Some salient features of VMM shorthand macros are :
  1. They can be used for {scalar, string, enums, vmm_data, handles} x {normal, array, dynamic array, associative array (scalar, and string type)} combination (Total 25 types)
  2. These shorthands are valid for classes derived from vmm_data, vmm_env, vmm_subenv, vmm_xactor, and vmm_scenario
  3. The function which will get implemented depends upon what class your class is being instantiated from.
  4. For unlucky data member which doesn't fall into these 25 category, you can specify the same using `vmm_data_member_user_defined macro
What I have presented here is a very high level overview of the feature and in no way complete. For interested user please refer these links for complete details:-

Explain the difference between data types logic and reg and wire

Ans:-
To answer this I am not assuming the reader knows the answer for the difference between wire and reg.

Wire:-

  1. Wires are used for connecting different elements
  2. They can be treated as a physical wire
  3. They can be read or assigned
  4. No values get stored in them
  5. They need to be driven by either continuous assign statement or from a port of a module
Reg:-
  1. Contrary to their name, regs doesn't necessarily corresponds to physical registers
  2. They represents data storage elements in Verilog/SystemVerilog
  3. They retain their value till next value is assigned to them (not through assign statement)
  4. They can be synthesized to FF, latch or combinational circuit (They might not be synthesizable !!!)
Wires and Regs are present from Verilog timeframe. SystemVerilog added a new data type called logic to them. So the next question is what is this logic data type and how it is different from our good old wire/reg.

Logic:-
  1. As we have seen, reg data type is bit mis-leading in Verilog. SystemVerilog's logic data type addition is to remove the above confusion. The idea behind having a new data type called logic which at least doesn't give an impression that it is hardware synthesizable
  2. Logic data type doesn't permit multiple driver. It has a last assignment wins behavior in case of multiple assignment (which implies it has no hardware equivalence). Reg/Wire data type give X if multiple driver try to drive them with different value. Logic data type simply assign the last assignment value.
  3. The next difference between reg/wire and logic is that logic can be both driven by assign block, output of a port and inside a procedural block like this
    logic a;
    assign a = b ^ c; // wire style
    always (c or d) a = c + d; // reg style
    MyModule module(.out(a), .in(xyz)); // wire style


Reference:-
  1. Cliff's article on the same
  2. Discussion on the same at Verification Guild

SystemVerilog OOP links

Here are some nice OOP links on SystemVerilog OOP which can be used as a good starting point/reference.

  1. Object Oriented Programming for Hardware Verification







  2. Improve Your SystemVerilog OOP Skills by Learning Principles and Patterns
  3. SystemVerilog OOP OVM Feature Summary


  4. Enhancing SystemVerilog with AOP Concepts (On how to mimic AOP features in OOP, good for guyz coming from e background)
  5. Testbench.in OOP Tutorial

Answers to SystemVerilog Interview Questions - 2

(86) What is the use of "extern"?
(66)What is "scope resolution operator"?

Ans:-
extern keyword allows out-of-body method declaration in classes. Scope resolution operator ( :: ) links method declaration to class declaration.

class XYZ;
// SayHello() will be declared outside the body
// of the class
extern void task SayHello();
endclass : XYZ

void task XYZ :: SayHello();
$Message("Hello !!!\n");
endtask : SayHello




(76) What is layered architecture ?

Ans:-
In SystemVerilog based constrained random verification environment, the test environment is divided into multiple layered as shown in the figure. It allows verification component re-use across verification projects.

(71)What is the difference between $rose and posedge?

Ans:-
posedge return an event, whereas $rose returns a Boolean value. Therefore they are not interchangeable.

(64)What is "this"?

Ans:-
"this" pointer refers to current instance.

(38)Write a clock generator without using always block.

Ans:-
initial begin
clk <= '0;
forever #(CYCLE/2) clk = ~clk
end


(35)How to implement always block logic in program block ?

Ans:-

Use of forever begin end. If it is a complex always block statement like always (@ posedge clk or negedge reset_)

always @(posedge clk or negedge reset_) begin
if(!reset_) begin
data <= '0;
end else begin
data <= data_next;
end
end

// Using forever : slightly complex but doable
forever begin
fork
begin : reset_logic
@ (negedge reset_);
data <= '0;
end : reset_logic
begin : clk_logic
@ (posedge clk);
if(!reset_) data <= '0;
else data <= data_next;
end : clk_logic
join_any
disable fork
end

Answers to SystemVerilog Interview Questions - I

Posting answers to few System Verilog Questions (Please refer System Verilog Interview Questions for questions)

10> What is the need of virtual interface ?
Ans:-
An interface encapsulate a group of inter-related wires, along with their directions (via modports) and synchronization details (via clocking block). The major usage of interface is to simplify the connection between modules.

But Interface can't be instantiated inside program block, class (or similar non-module entity in SystemVerilog). But they needed to be driven from verification environment like class. To solve this issue virtual interface concept was introduced in SV.

Virtual interface is a data type (that implies it can be instantiated in a class) which hold reference to an interface (that implies the class can drive the interface using the virtual interface). It provides a mechanism for separating abstract models and test programs from the actual signals that make up the design. Another big advantage of virtual interface is that class can dynamically connect to different physical interfaces in run time.

For more details please refer the following links


18> What is difference between $random() and $urandom()
Ans:-
  1. $random system function returns a 32-bit signed random number each time it is called
  2. $urandom system function returns a 32-bit unsigned random number each time it is called. (newly added in SV, not present in verilog)

47> How to randomize dynamic arrays of an object
Ans:-

class ABC;
// Dynamic array
rand bit [7:0] data [];

// Constraints
constraint cc {
// Constraining size
data.size inside {[1:10]};

// Constraining individual entry
data[0] > 5;

// All elements
foreach(data[i])
if(i > 0)
data[i] > data[i-1];
}
endclass : ABC


Event Region, Scheduling Semantics in System Verilog

Let me start the post by asking one commonly asked interview question in verilog/system-verilog, that is what is the output of the following block


always @(posedge clk) begin
a = 0;
a <= 1;
$display(s);
end


To begin with let me be clear that this is not the correct way to code in verilog/SV. One shouldn't mix blocking and non-blocking assignment in the same begin-end block. But this question is asked to check the knowledge of scheduling semantics of verilog/SV.

Verilog scheduling semantics basically imply a four-level deep queue for the current simulation time:-
  1. Active Events (blocking assignment, RHS of NBA, continuous assignment, $display, ...)
  2. Inactive Events (#0 blocking assignment)
  3. Non-Blocking Assign Updates (LHS of NBA)
  4. Monitor Events ($monitor, $strobe).
Which implies, a=0 will be get printed in this example.

System Verilog has added few more level queue for simulation, the details of which can be found in these 2 excellent link on scheduling semantics of SV.

The Hitchhiker series on Verification - From Mentor Graphics

It seems I am not the 1st one to have the Hichhiker series on SV-VMM. Back from 2007 time frame Mentor has a series of talk on System Verilog/AVM which is named as "The Hitchhiker Guide to XYZ". The good thing about these talks is that you don't need to register for watching these videos (almost all of the rest multimedia needs a registration for watching them). These are the links for your viewing and Learning:-

What is Factory Pattern

If you are working in System Verilog/VMM environment, it is high likely that you will be bombarded with word/expression from OOP world like "Factory Pattern", "Facade Pattern", "Observer Pattern" and so on. There is a finite possibility that you will seat down and start thinking what does those word mean and why they were used too frequently. Let me try to explain the idea/concept behind such word in the simplest way possible.

In SW engineering, a design pattern (or simply pattern) means a general repeatable solution to a commonly occurring problem. Most of these patterns have similarity to something or other in human society and hence they are known by that name.

Factory pattern as the name suggest, is aimed at solving the issue of creation of object. (Factory pattern is not the only pattern to deal with creation of objects, there are a bunch of more patterns for handling different kind of cases, and collectively they are known a creational patterns)

Let me give an example of case where we might need to use creational pattern and how to do so it in SV. Suppose you want to create a "Toy Factory" class which needs to create multiple types of toys (say toy aeroplane, toy tank, toy bus) depending upon the string input to it.

To create these different types of toys we need to have class defined for them. And there will be common method and data interface for these classes, hence it make sense to put all the common data member/task/functions in a class called toy class and then extend it.

class TOY;
// Common data memeber
string type;

// Common methods
virtual function string get_type();
endclass : TOY

class TOY_Tank extends TOY;
function new();
this.string = "Toy Tank";
endfunction : new

string function string get_type();
return this.string;
endfunction : get_type
endclass : TOY_Tank
class TOY_Bus extends TOY;
function new();
this.string = "Toy Bus";
endfunction : new

string function string get_type();
return this.string;
endfunction : get_type
endclass : TOY_Bus

Now we are done with the bothering about the objects to be created. The next problem that we need to solve is to write the toy factory class itself. For simplicity, let's consider the case where we will want to pass 1 to get an instance of tank class and 2 for getting an instance of bus class from the factory. Now the factory class will look like this.
class TOY_factory;
Toy my_toy

// Common methods
function toy get_toy(int type);
if(type == 1) this.my_toy = new TOY_Tank();
if(type == 2) this.my_toy = new TOY_Bus();
return this.my_toy;
endfunction : get_toy
endclass : TOY_factory

Note that we are using virtual function for bringing polymorphism in action and save us from having an individual instance of the toy type in the factory class.

Reference

System Verilog Interview Questions

System Verilog Interview questions from http://www.edaboard.com/ftopic315416.html. I don't know answers to all of the questions, but will try to find out their answer from internet (thanks to the all powerful Google) and post the answers in this blog (one by one most likely). If you know answers to any of these then you are well come to share the same by commenting to this post.

  1. What is callback ?
  2. What is factory pattern ?
  3. Explain the difference between data types logic and reg and wire 
  4. What is the need of clocking blocks ?
  5. What are the ways to avoid race condition between testbench and RTL using SystemVerilog?
  6. Explain Event regions in SV.
  7. What are the types of coverages available in SV ? 
  8. What is OOPS?
  9. What is inheritance and polymorphism?
  10. What is the need of virtual interfaces ?
  11. Explain about the virtual task and methods .
  12. What is the use of the abstract class?
  13. What is the difference between mailbox and queue?
  14. What data structure you used to build scoreboard
  15. What are the advantages of linkedlist over the queue ?
  16. How parallel case and full cases problems are avoided in SV 
  17. What is the difference between pure function and cordinary function ?
  18. What is the difference between $random and $urandom?
  19. What is scope randomization 
  20. List the predefined randomization methods.
  21. What is the dfference between always_combo and always@(*)?
  22. What is the use of packagess?
  23. What is the use of $cast?
  24. How to call the task which is defined in parent object into derived class ?
  25. What is the difference between rand and randc?
  26. What is $root?
  27. What is $unit?
  28. What are bi-directional constraints?
  29. What is solve...before constraint ?
  30. Without using randomize method or rand,generate an array of unique values?
  31. Explain about pass by ref and pass by value?
  32. What is the difference between bit[7:0] sig_1; and byte sig_2;
  33. What is the difference between program block and module ?
  34. What is final block ?
  35. How to implement always block logic in program block ?
  36. What is the difference between fork/joins, fork/join_none fork/join_any ?
  37. What is the use of modports ? 
  38. Write a clock generator without using always block.
  39. What is forward referencing and how to avoid this problem?
  40. What is circular dependency and how to avoid this problem ?
  41. What is cross coverage ?
  42.  Describe the difference between Code Coverage and Functional Coverage Which is more important and Why we need them
  43. How to kill a process in fork/join?
  44. Difference between Associative array and Dynamic array ?
  45. Difference b/w Procedural and Concurrent Assertions?
  46. What are the advantages of SystemVerilog DPI?
  47. How to randomize dynamic arrays of objects?
  48. What is randsequence and what is its use?
  49. What is bin?
  50. Why always block is not allowed in program block?
  51. Which is best to use to model transaction? Struct or class ?
  52. How SV is more random stable then Verilog?
  53. Difference between assert and expect statements?
  54. How to add a new processs with out disturbing the random number generator state ?
  55. What is the need of alias in SV?
  56. What is the need to implement explicitly a copy() method inside a transaction , when we can simple assign one object to other ?
  57. How different is the implementation of a struct and union in SV.
  58. What is "this"?
  59. What is tagged union ?
  60. What is "scope resolution operator"?
  61. What is the difference between Verilog Parameterized Macros and SystemVerilog Parameterized Macros?
  62. What is the difference between



    logic data_1;
    var logic data_2;
    wire logic data_3j;
    bit data_4;
    var bit data_5;
    
  63. What is the difference between bits and logic?
  64. Write a Statemechine in SV styles.
  65. What is the difference between $rose and posedge?
  66. What is advantage of program block over clockcblock w.r.t race condition?
  67. How to avoid the race condition between programblock ?
  68. What is the difference between assumes and assert?
  69. What is coverage driven verification?
  70. What is layered architecture ?
  71. What are the simulation phases in your verification environment?
  72. How to pick a element which is in queue from random index?
  73. What data structure is used to store data in your environment and why ?
  74. What is casting? Explain about the various types of casting available in SV.
  75. How to import all the items declared inside a package ?
  76. Explain how the timescale unit and precision are taken when a module does not have any timescalerdeclaration in RTL?
  77. What is streaming operator and what is its use?
  78. What are void functions ?
  79. How to make sure that a function argument passed has ref is not changed by the function?
  80. What is the use of "extern"?
  81. What is the difference between initial block and final block?
  82. How to check weather a handles is holding object or not ?
  83. How to disable multiple threads which are spawned by fork...join

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.

Example:-
class abc_transactor;
virtual task pre_send(); endtask
virtual task post_send(); endtask

task xyz();
// Some code here
this.pre_send();
// Some more code here
this.post_send();
// 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
endtask

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

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.

Reference:-

System Verilog Gotchas - by Stuart Sutherland

In one of my last post I have added one of the System Verilog Gotcha paper. There are 2 more System Verilog Gotcha presentations (this time by Stuart Sutherland).


The compete presentation/papers of Stuart on System Verilog, Verification, Verilog can be viewed at http://www.sutherland-hdl.com/papers-by-sutherland.php

System Verilog LRM

System Verilog LRM, as the name suggest, is the definite reference manual for SV. Unlike other standard reference manual, which are too academic or boring to read, this one is a easy to use, easy to read and has large number of examples. The link of which can be easily got by a simple google search.

http://www.vhdl.org/sv/SystemVerilog_3.1a.pdf

There is another reference manual or standard for SV (IEEE 1800) which is pretty much same as the LRM, and you have to pay for downloading it (assuming your organization don't pay $$$ to IEEE for free access to its huge papers and standards)

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

Followers

Search This Blog

My Shelfari Bookshelf

Shelfari: Book reviews on your book blog

 

Traffic Summary