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



No comments:

Post a Comment

`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 ...