Saturday, September 5, 2020

`define Macro usage in System Verilog

 Hi Everyone !!!

In this blog we are going to see the usage of `define macro in System Verilog.

A text macro substitution facility has been provided so that meaningful names can be used to represent commonly used pieces of text. For example, in the situation where a constant number is repetitively used throughout a description, a text macro would be useful in that only one place in the source description would need to be altered if the value of the constant needed to be changed.

The directive `define creates a macro for text substitution. This directive can be used both inside and outside module. After a text macro is defined, it can be used in the source description by using the (`) character, followed by the macro name. The compiler shall substitute the text of the macro for the string `text_macro_name and any actual arguments that follow it. All compiler directives shall be considered predefined macro names; it shall be illegal

SYNTAX:

    `define  text_macro_name macro_text

Why Should we use ?

While coding our test-bench , we found ourself using any loops/substitution/assignment/displays at several places. At various places in our code We would have code like this,

Example 1:
In Below module for loop is used again and again.
module  TB;
  int addr[5]='{1,2,3,4,5};
  int data[5]='{5,6,7,8,9};
  initial begin
   for (int a=0; a<3; a++) begin                                   
          if ((a !=0) ) begin
           $display("\n"); 
           $display("0x%x ", addr[a]);
         end
       end 

   for (int a=2; a<5; a++) begin                                  
          if (a !=0) begin
           $display("\n"); 
           $display("0x%x ", data[a]);
         end
       end 
end
endmodule
Consider in ourTB the above two code snippets used in "n" times. Instead of writing redundant code again and again we can replace 6 line code into single line by using `define macro.

Solution:
`define for_loop(element, start_val, end_val) \
     for (int ii=start_val; ii<end_val; ii++) begin \
if ((ii != 0)) \
    $display("0x%x ", element[ii]); \
     end

    module TB;
      int data[5]='{1,2,3,4,5};
      int addr[5]='{6,7,8,9,10};
     initial begin
       `for_loop(data, 0, 3)   //here 5 line of code converted into single line
       `for_loop(addr, 2, 5)  //here 5 line of code converted into single line
     end   
    endmodule

This is the macro we defined globally or inside any TB.
 The first for loop can be replaced by `for_loop(addr,0,3) and second for loop can be replaced by `for_loop(data,2,5)

1. “``” (Double tick)

The “``” quotation can be used to form a signal/variable name by using given argument.

Example:
Macro definition:
    `define data(ARG)\
       addr=mas_''ARG;\
       addr1=slave_''ARG;
macro usage
     `data(100)
Actual code the macro replaces:                                                                                                                            addr=mas_100;                                                                                                                                            addr1=slave_100;


2. “`” “(Tick followed by a double quote)


The “`” “ quotation can be used to interpret the argument as a string. Example:

Macro Definition:
    `define assignment(ARG1) \
       data_''ARG1=addr_''ARG1; 
 Macro usage :
       `assignment(a)

Actual code the macro replaces:
      data_a=addr_a;

3. “`\`” “(Tick followed by backslash followed by a double quote)
The “ `\” “ quotation is used to replace the argument with an escape sequence.

Macro definition:

`define assignment(ARG1,ARG2) \ ARG1=ARG2; \ 
 $display('" Data name :'\'"ARG1'\',value : %0h'",ARG1);

Macro usage:

`assignment(reg_a,data_a)Actual code the macro replaces:
reg_a=data_a;
$display("Data name :\"reg_a\",value : %0h",reg_a);

We can see that the argument is replaced with “ ”reg_a” “ in the $display line which prints as “Reg name : “reg_a”, value : ‘hXYZ” when it is executed.

Example 2
`__FILE__ --> it will show the current file name
`__LINE__ --> it will show the line no

`" - If the macrotext is enclosed in plain quotation("), it essentially becomes a string

`define task1(A) $display(`"1 flower A`")
`define task2(A=rose, B, C=lotus) $display(`"3 flowers A, B, C`")
`define task3(A=str1, B, C=lotus) \
if (A == "RED")$display(" .. I received  ROSE!"); \
else $display(`"3 flowers %s, B, C`", A);
`define debug_msg1(module_name, MSG) \
$display(`" ``module_name`` >> %s, %0d: %s`", `__FILE__, `__LINE__, MSG)
`define debug_msg2(module_name, MSG) \
$display(`"%s >> %s, %0d: %s`", module_name, `__FILE__, `__LINE__, MSG)

module test;
initial begin
string
str1, str2;
str1 = "gray";
str2 = "RED";

// No args provided even without default value
`task1();
`task2(,,);

// Passing some args
`task1(jasmine);
`task2(,sun_flower,);


// Passing a var (str1, str2) as an arg
`task3(str1,daisy,tulips);
`task3(str2,daisy,tulips);


`debug_msg1(program-block, "this is a debug message");
`debug_msg2("program-block", "this is a debug message");


/* The following will result in an Error
* `task2(); // no args provided
* `task2(,); // insufficient args provided
*
* // arg1 is used as a var in an if statement,
* // This will compile fail because the macro
* // will expand to *if ( == "RED")*
* `task1(, rose, jasmine)
*/

end
endmodule

OUTPUT:

1 flower
3 flowers rose, , lotus
1 flower jasmine
3 flowers rose, sun_flower, lotus
3 flowers gray, daisy, tulips
.. I received ROSE!
program-block >> testbench.sv, 31: this is a debug message
program-block >> testbench.sv, 32: this is a debug message
V C S S i m u l a t i o n R e p o r t

Example 3:

`define arithmetic(var1,var2,result,expr) \
 result=var1 expr var2; \
$display(" Result is %0d",result);
module TB;
  int a,b,c;
  initial begin
    `arithmetic(10,5,a,+)  //a=10+5 and display will be executed
    `arithmetic(10,10,b,*)  //b=10*5 and display will be executed
    `arithmetic(10,2,c,/)   //c=10/2 and display will be executed
  end
endmodule

OUTPUT:
Result is 15
Result is 100
Result is 5
V C S S i m u l a t i o n R e p o r t

Macro usage in SV Assertion

As with coverage, many times in DV projects, we have some common assertions which can be used at multiple places and different components.

Macro usage for a covergroup

Many times in a verification project, there is a need to write the same coverage at different places.We can define common macro for covergroup, which can be used in all such components.

Hope this logic's will be useful to everyone !!!
Giving feedback is more precious than writing an article!!! 😊😊😊😊😊
Always welcome both positive and negative feedback's !!!
Feel free to post any queries related SV and UVM  

"With self-discipline most anything is possible"
-Theodore Roosevelt



Wednesday, September 2, 2020

Abstract Class in System Verilog

 Hi Everyone !!!,

In this Blog we are going to see the concepts about Abstract Class.

A virtual class is a class that cannot be directly constructed.A virtual class is often referred to as an abstract class that cannot be directly constructed.The virtual class is intended to create a template for classes that are extensions of the virtual class. 

  • An abstract class sets out the prototype for the sub-classes.
  • An abstract class cannot be instantiated, it can only be derived.
  • An abstract class can contain methods for which there are only a prototype and no implementation, just a method declaration.
SYNTAX:

virtual class example;
  //Class defintion
endclass

Virtual class is not useful until extended.

Example 1:
Abstract classes only be derived not allowed to create an object.

//abstract class
virtual class example1;
  bit [31:0] data;
endclass
module virtual_class;
  initial begin
    example1 p;
    = new(); //try to construct an object -> it leads to compilation error
  end
endmodule

OUTPUT:
virtual_class, "p = new();"
Instantiation of the object 'p' can not be done because its type 'example1' is
an abstract base class.
Perhaps there is a derived class that should be used.
There is a common misconception that all methods declared in a virtual class are automatically virtual methods. This is not true. For method to be virtual, it must be declared virtual, even in virtual classes.

Abstract method divided into two categories:
  • Virtual class methods
  • Pure virtual class methods
Virtual Methods: 
    Virtual methods are reference models in base class may optionally overridden in derived class. Virtual methods requires all the arguments and types to be same in the corresponding extended methods. Virtual method may or may not be abstract class.
 
Rules for extending virtual methods:
  Virtual methods numbers, types,name of the argument, return type must match with the same arguments and types of the base class method if overridden.

Rule 1:
Return type should match for overriding in extended class.
 
//abstract class
virtual class base;
   virtual function  display(int a ,int b);
    $display("Value of base is %0d %0d", a,b);
  endfunction
endclass
  
class ex_class extends base;
  virtual function void display( int a , int b) //Return type should match
    $display("Value of Extend is %0d %0d", a,b);
  endfunction
endclass
  
module virtual_class_TB;
  initial begin
    base b;
    ex_class ex;
    ex=new();
    ex.display(4,5);
  end
endmodule

OUTPUT:
Error-[SV-IRT] Incompatible return types
testbench.sv, 10
$unit, "display"
Definition of class function 'base::display' does not have the same return
type as mentioned in the declaration at: "testbench.sv", 4.

1 error
CPU time: .133 seconds to compile

Rule 2:
Number of argument should match.
 
//abstract class
virtual class base;
   virtual function void  display(int a ,int b);
    $display("Value of base is %0d %0d", a,b);
  endfunction
endclass
  
class ex_class extends base;
  virtual function void display( int a ) //Number of argument should match
    $display("Value of Extend is %0d", a);
  endfunction
endclass
  
module virtual_class_TB;
  initial begin
    base b;
    ex_class ex;
    ex=new();
    ex.display(4);
  end
endmodule

OUTPUT:
Error-[SV-INACF] Invalid number of args to class function
Too few arguments in class-method 'display' in derived class 'ex_class'.
Base class-method declared at "testbench.sv", 4
Derived class-method declared at "testbench.sv", 10
Please make sure that correct number of arguments are specified.

1 error

Rule 3:
Argument type should match for overriding in extended class.
 
//abstract class
virtual class base;
   virtual function void   display(int a ,int b);
    $display("Value of base is %0d %0d", a,b);
  endfunction
endclass
  
class ex_class extends base;
  virtual function void display( shortint a , int b) //Argument type should match
    $display("Value of Extend is %0d %0d", a,b);
  endfunction
endclass
  
module virtual_class_TB;
  initial begin
    base b;
    ex_class ex;
    ex=new();
    ex.display(4,5);
  end
endmodule


OUTPUT:

Error-[SV-ATDNMD] Argument types do not match
testbench.sv, 10
$unit, "a"
The argument type of 'a' for class method 'base::display' in the derived
class does not match the argument type of 'a' for class method in the base
class at: "testbench.sv", 4.
Please check and correct the argument types.

Rule 4:
Argument direction should match for overriding in extended class.
 
//abstract class
virtual class base;
   virtual function  display(int a ,int b);
    $display("Value of base is %0d %0d", a,b);
  endfunction
endclass
  
class ex_class extends base;
  virtual function display(output int a , int b) //Argument direction should match
    $display("Value of Extend is %0d %0d", a,b);
  endfunction
endclass
  
module virtual_class_TB;
  initial begin
    base b;
    ex_class ex;
    ex=new();
    ex.display(4,5);
  end
endmodule


OUTPUT:

Error-[SV-PDM2] Port direction mismatch
testbench.sv, 10
$unit
The port direction of port 'b' is defined 'output' in the derived class and
'input'in the base class (at testbench.sv, 4).


Rule 5:

Method name(task/function) should match for overriding in extended class. Refer in above example function names.

Rule 6:

If the base class declares a method to be virtual, the extended class method also be virtual.

Pure Virtual Method:

   The pure keyword can only be used in an abstract class (virtual class). It is illegal to use pure keyword in a class. The pure virtual method is either pure virtual task or pure virtual function prototype is not allowed to have implementation (no body code allowed) and is not even allowed to have an endtask or endfunction keyword to close the pure virtual method.

    The virtual class or method MUST be overridden in the first non-virtual extended class based on the abstract class

Rule 1:

 //abstract class
virtual class base;
   pure virtual function  display(int a ,int b) //pure keyword should be used in virtual class otherwise it lead to compilation error & and it should not contain implementation and end function/endtask
endclass
  
class ex_class extends base;
  virtual function display(int a , int b) 
    $display("Value of Extend is %0d %0d", a,b);
  endfunction
endclass
  
module virtual_class_TB;
  initial begin
    base b;
    ex_class ex;
    ex=new();
    ex.display(4,5);
  end
endmodule


The above virtual method Rules are also applicable to pure virtual method.


Difference between Virtual and Pure Virtual?

Virtual methods are reference models in base class may optionally overridden in derived class. Virtual method need not to an abstract class.

Pure Virtual methods are reference models in base class that are MUST be overridden in the derived class. Pure virtual method must be used in abstract class.


Hope this logic's will be useful to everyone !!!
Giving feedback is more precious than writing an article!!! 😊😊😊😊😊
Always welcome both positive and negative feedback's !!!
Feel free to post any queries related SV and UVM  


"It is impossible for a man to learn what he thinks he already knows"
                                                        -Epicteus




`define Macro usage in System Verilog

 Hi Everyone !!! In this blog we are going to see the usage of `define macro in System Verilog. A text macro substitution facility has been ...