Why `ifndef and `define are used together?

May I know what is the purpose of ifndef followed by define as shown in below:

ifndef OVM_OBJECT_DEFINES_SVH define OVM_OBJECT_DEFINES_SVH

this is a snippet code taken from ovm_object_defines file. This pattern (ifndef define) is commonly used in OVM. But I wonder the purpose to do this.

It is used to include the part in ifndef only once in SV compilation. If the the variable is define then it will not include the part in ifndef into the compilation part.

For a more detailed explanation, refer to:

include guard - Wikipedia

Thanks for you guys, the information provided really helpful~ :D

In reply to xierian:

These defines are very helpful are in numerous scenario’s. Example : When you have two models with slightly different features than you could use these include directives for compiling different code. Think of them as if statement in C or C++.

Thanks,
Vikram Dadwal

sorry, I didn’t get it. Can you please elaborate it.

In reply to Sanjeeva Dinesh:

sorry, I didn’t get it. Can you please elaborate it.

In file c_file.sv:


#ifndef __C_FILE_SV__
#define __C_FILE_SV__

class C;
function new();
endfunction : new
endclass : C
#endif

We include c_file.sv in a_file.sv for using:


#ifndef __A_FILE_SV__
#define __A_FILE_SV__

#include "c_file.sv"
class A;
C _c;
function new();
endfunction : new
endclass : A
#endif

We also include it in b_file.sv:


#ifndef __B_FILE_SV__
#define __B_FILE_SV__

#include "c_file.sv"
class B;
C _c;
function new();
endfunction : new
endclass : B
#endif

Now, both a_file.sv and b_file.sv include c_file.sv, if we dont specify #ifndef/define in c_file.sv, then class C will be compiled twice and we will get error “multiple declaration” of class C. If we have these macros, c_file.sv only be compiled once, the second time will be ignore because C_FILE_SV is defined.

In reply to cuonghl:

A properly thought out compilation methodology using packages should not need compile guards in SystemVerilog. If you order your `include files in a package correctly, all of your classes and macros defines get compiled once.

In reply to cuonghl:

In reply to Sanjeeva Dinesh:
In file c_file.sv:


#ifndef __C_FILE_SV__
#define __C_FILE_SV__
class C;
function new();
endfunction : new
endclass : C
#endif

We include c_file.sv in a_file.sv for using:


#ifndef __A_FILE_SV__
#define __A_FILE_SV__
#include "c_file.sv"
class A;
C _c;
function new();
endfunction : new
endclass : A
#endif

We also include it in b_file.sv:


#ifndef __B_FILE_SV__
#define __B_FILE_SV__
#include "c_file.sv"
class B;
C _c;
function new();
endfunction : new
endclass : B
#endif

Now, both a_file.sv and b_file.sv include c_file.sv, if we dont specify #ifndef/define in c_file.sv, then class C will be compiled twice and we will get error “multiple declaration” of class C. If we have these macros, c_file.sv only be compiled once, the second time will be ignore because C_FILE_SV is defined.

thank you.

Hi,

I want to redefine some alias with the same name according to condition
let’s say,
//code from here
bit drop;

if (drop == 1)
define drop_by_ip uvm_info
else
define drop_by_ip uvm_error

//and that alias I am using in the display statement
`drop_by_ip(“DROP”,“PACKET DROPPED BY IP”)

So in simulation, it will always take as `uvm_error so how can I do to replace the string and I know that demoter class can do that but don’t want to use demoter class of UVM

In reply to J_M:

Your method won’t work. You need to remember that define is a pre-processor macro which is used during compilation. The 'if (drop == 1)' is run-time, and won't conditionally change the define.

Thanks for the reply. But is there any method to do that without redefining or without using demoter class.

In reply to J_M:

Please explain why you do not want to use set_report_severity_id_override

I am using this in my scoreboard for SoC project in which I have multiple packets and which can be dropped by IP’s and VIP’s so in the scoreboard from Expected side I will receive the packet but want be coming out in the actual side so for that case I want my scoreboard to throw warning not error and as I have mentioned that there are more than 30 types of packet so I don’t want to use set_report_severity_id_override for each packet and if I use that then my scoreboard want be able to throw error when packet is actually dropped by scoreboard or scoreboard doesn’t receive packet.