How text macro affect inside and outside pkg?

Hi folks,

I am trying to get better understanding on text macro(`ifdef) within and outside packages. Can someone share some insight on that?

Why compiling pkg_ac.sv, a.sv is not compiled? (The source codes append in the end)

According to LRM2012 P18, “The text macro name space is global within the compilation unit.”
Here my understanding are:

  • pkg_ab.sv is a compilation unit which contains a.sv & b.sv & pkg_ab.sv(itself)
  • pkg_ac.sv is another compilation unit which contains a.sv & c.sv & pkg_ac.sv(itself)
  • `define A_SV is global within pkg_ab.sv but not outside pkg_ab.sv

Now the compilation log shows Error when compiling pkg_ac.sv due to class identifier - a is not visible, so why is a.sv not compiled in pkg_ac.sv? I wonder why does define A_SV inside pkg_ab.sv go out of the scope then make pkg_ac.sv see define A_SV.

The source code are distributed in 6 files:
a.sv

`ifndef A_SV
`define A_SV

class a;
endclass // a

 `endif

b.sv

`ifndef B_SV
`define B_SV

class b extends a;
endclass // b

 `endif

c.sv

`ifndef C_SV
`define C_SV

class c extends a;
endclass // c

 `endif

pkg_ab.sv

`ifndef PKG_AB_SV
 `define PKG_AB_SV

package pkg_ab;
 `include "a.sv"
 `include "b.sv"
endpackage // pkg_ab

`endif

pkg_ac.sv

`ifndef PKG_AC_SV
 `define PKG_AC_SV

package pkg_ac;
 `include "a.sv"
 `include "c.sv"
endpackage // pkg_ac

`endif

tb.sv

`include "pkg_ab.sv"
`include "pkg_ac.sv"

module tb;
   a a0;
   b b0;
   c c0;
endmodule

The scope of `define macros, and most other compiler directives is a compilation unit. A compilation unit is a stream of source text that a compiler parses. A macro gets defined at the point it appears in the compilation unit and is visible from that point onward.

The scopes defined by modules, packages, and other namespaces are irrelevant because macros are pre-processed before any Verilog or SystemVerilog syntax gets recognized.

And you need to import your package into your module before referencing anything inside them.

You are exactly correct, I am pretty new to package than other definition namespace such as module, interface. And I forget to import pkg_ab::, import pkg_ac:: in tb.sv.

When import pkg, such as uvm_pkg, both inside module tb and outside module tb can compile without error. I want to know which way is more practical.