Sunday, 18 March 2018

Cleaner way to kill a fork/join thread

A cleaner way to kill any fork/join, fork/join_any, fork/join_none process would be to use SystemVerilog process construct as given below,



process threadA;
// Start a Process
fork
begin: A
 // Get process and store it to a process handle to clean up later
 threadA = process::self();
 taskA();
 taskB();
end
join_none
#0; // Let the process start

wait();
threadA.kill(); // Kill processes started by above fork cleanly

- Store process information in a process variable using process::self().
- Start parallel tasks to be run under this process.
- Use #0 delay for fork/join_none thread to get started.
- Wait for required status flag.
- End the process (here processes started by fork/join_none) with kill() method in process.


There are other ways to kill threads with "disable fork" and disable <PROC_LABEL>. Given approach is frequently used by UVM users and this is the way it has been done in UVM base class library to cleanly end processes.

Thursday, 25 May 2017

Friday, 3 February 2017

Abstract class in SystemVerilog/ Virtual Class

Abstract class is used to define template class. This class defines non-virtual/virtual/pure virtual methods prototype which are implemented by extended class. By use of abstract class, extended classes are required to implement methods as per definitions given in abstract class. 

Objects of abstract class can not be created. Class uvm_object in UVM base class library is an example of abstract class.


Thursday, 29 December 2016

Polymorphism in SystemVerilog


Here Class C is extended from class B, class B is extended from class A. To achieve polymorphism for class B, method must be declared virtual in class A. Again to achieve polymorphism in class C, the method is not required to be declared virtual in class B, as class A method prototype has virtual qualifier.

Code on GitHub


class A;

    // For polymorphism to work, method prototype 
    // (method name, return type, arguments) must  
    // be the same. 
    virtual function void display(); 
      $display("Display: Class A"); 
    endfunction 

    function void message();
      $display("Message: Class A"); 
    endfunction

endclass
Class A implements display() as virtual method and message() as non-virtual. Now, extended class from class A does not need to declare display() method as virtual once again. Virtual is implicit in all extended classes.


 class B extends A; 

    // As display() function is virtual in  
    // class A, no need to explicitly diclare 
    // it virtual here 
    function void display(); 
      $display("Display: Class B"); 
    endfunction 

    function void message(); 
      $display("Message: Class B");
    endfunction 

  endclass


  class C extends B; 

    // As display() function is virtual in  
    // class A, hece class B as well, no  
    // need to explicitly diclare it virtual here 
    function void display(); 
      $display("Display: Class C"); 
    endfunction 

    function void message(); 
      $display("Message: Class C"); 
    endfunction 

  endclass

  A a_h;
B b_h;
  C c_h; 

  initial 
  begin 
    a_h = new(); 
    b_h = new(); 
    c_h = new(); 

    a_h = b_h; 

    $display("\n\n----------------"); 
    $display("Accessing object B using class A handle.\n"); 

    a_h.display(); 
    a_h.message(); 

    $display("----------------"); 

    b_h = c_h; 

    $display("\n\n----------------"); 
    $display("Accessing object C using class B handle.\n"); 

    b_h.display(); 
    b_h.message(); 

    $display("----------------\n\n"); 
  end


Output of above setup looks like this,

# ----------------
# Accessing object B using class A handle.
#
# Display: Class B
# Message: Class A
# ----------------
#
# ----------------
# Accessing object C using class B handle.
#
# Display: Class C
# Message: Class B
# ----------------

Next arguments could be, what if class A does not declare methods as virtual but class B does. Can we achieve polymorphism from class A to class C? Try this out.