Package export does not work like I expect

I would like to export the contents of an imported package, particularly class definitions, but this doesn’t seem to work like I expect:


package a_pkg;
  class a_class;
  endclass
endpackage

package b_pkg;
  import a_pkg::*;
//export a_pkg::a_class; // (1)
  export a_pkg::*;       // (2)
endpackage

package c_pkg;
  import b_pkg::*;
  a_class a;        // Compiles for (1), why doesn't it compile for (2)?
//a_pkg::a_class a; // Compiles for (1) and (2)
endpackage;

In reply to laarens:
Because a wildcard import statement does not import everything in package a_pkg; it only makes symbols candidates for importing.

The LRM says

Symbols that are candidates for import but not actually imported are not made available.

The symbol a_class must have a reference in b_pkg to be exported.

package b_pkg;
  import a_pkg::*;
  import a_pkg::a_class; // (1)
  export a_pkg::a_class; // (2)
  a_class a;             // (3)  
  export a_pkg::*;       
endpackage

Any of the statements (1), (2), or (3) will cause a_class to be exported.

In reply to dave_59:

Okay. Thanks for clarifying that for me.

In reply to dave_59:

Dave,
We had a similar requirement when trying to wrap UVM pkg into our own, custom package. Do you think it is reasonable to ask for an extension in the language for it? Consider:

package our_uvm_pkg;
import uvm_pkg::all; // Just a notion, for now it won’t work
export uvm_pkg::all; // Just a notion, for now it won’t work
// More code, uses some of the uvm base classes, but not all
endpackage : our_uvm_pkg

The benefit is user then has to import only “our_uvm_pkg” and gets all what’s provided by UVM.

Thanks
Srini
http://www.verifworks.com

In reply to dave_59:
Hi dave_59, could you please elaborate on what you mean by “candidate for importing” and “actually imported” objects?

In reply to kiranag:
You have to look at the flow of source code to determine which symbols are candidate versus actually being imported. It can change over the span of a scope.

package p1;
  int a,b,c,d;  
endpackage
package p2;
  int a;
  import p1::*; // the identifiers b,c, and d all become candidates for importing
                // 'a' is already declared in this local scope
  function f1;
     $display(b); // 'b' moves from being a candidate to actually imported. 
  endfunction 
  int c; // 'c' is no longer a candidate for importing
//int b; // this would be an error because 'b' was already imported. 
endpackage

So the
import p1::*;
wildcard import statement actually imports only one symbol; ‘b’. This distinction becomes more important when you have the same symbol being a candidate for import coming from multiple packages. That’s OK until someone tries to actually import the symbol - which package do you import it from? It means you eithe rneed to make the symbol name unique in each package, or the intent was not to import the symbol by declaring locally beforehand.

I follow this coding style putting all the files in a pkg.sv file but there is this compilation error. Not sure what caused this.

Error-[SE] Syntax error
Following verilog source has syntax error :
“project/verif/vkits/glbk/lbk_pkg.sv”, 66: token is ‘endpackage’
endpackage:lbk_pkg
^
System verilog keyword ‘endpackage’ is not expected to be used in this
context.

1 error

The file content is below.
package lbk_pkg;

//---------------------------------------------------------------------
// Group: Imports
import uvm_pkg::*;

// Forward class declarations to work around compile errors

typedef class config_vseq_c;
typedef class reg_comp_rst_vseq_c;
typedef class lbk_sec_reg_walk_seq_c;
typedef class lbk_non_sec_reg_walk_seq_c;
typedef class lbk_reg_walk_seq_c;
typedef class no_op_seq_c;
typedef class csr_background_read_vseq_c;
typedef class env_c;
typedef class lbk_p2x_cfg_c;
typedef class lbk_x2p_cfg_c;

//---------------------------------------------------------------------
// Group: Includes
// (include package member files here, alphabetically.) include “cvm_pcc_defs.vh”

include "lbk_ecam_cfg_function.sv" include “lbk_types.sv”
include "lbk_cfg.sv" include “lbk_pkt_cfg.sv”
include "lbk_pkt.sv" include “lbk_trans_sb.sv”
include "lbk_chan_cred_sb.sv" include “lbk_perf_sb.sv”
include "lbk_ebp_sb.sv" include “lbk_exer_seq_cfg.sv”
include "lbk_test_vseq_lib.sv" include “lbk_vsqr.sv”
include "lbk_config_vseq_lib.sv" include “lbk_env.sv”
include "lbk_p2x_cfg.sv" include “lbk_x2p_cfg.sv”

endpackage : lbk_pkg

In reply to dnguyen82us:
Usually when you get a syntax error from what seems like perfectly good code, it is because of the code just before it.

In reply to dave_59:

In reply to kiranag:
You have to look at the flow of source code to determine which symbols are candidate versus actually being imported. It can change over the span of a scope.

package p1;
int a,b,c,d;  
endpackage
package p2;
int a;
import p1::*; // the identifiers b,c, and d all become candidates for importing
// 'a' is already declared in this local scope
function f1;
$display(b); // 'b' moves from being a candidate to actually imported. 
endfunction 
int c; // 'c' is no longer a candidate for importing
//int b; // this would be an error because 'b' was already imported. 
endpackage

So the
import p1::*;
wildcard import statement actually imports only one symbol; ‘b’. This distinction becomes more important when you have the same symbol being a candidate for import coming from multiple packages. That’s OK until someone tries to actually import the symbol - which package do you import it from? It means you eithe rneed to make the symbol name unique in each package, or the intent was not to import the symbol by declaring locally beforehand.

Dave, just to be 100% sure: In your example, if the last line of the package was
export p1::;
, then another module with
import p2::
; would get
p1::b
. Correct? Therefore, export statements should be at the end of packages? This still is a big pain and not what’s expected. I agree with the suggestion of
export XX::all;
or similar. Do you know of any work on this in the 1800 committee?

Thanks,

David

In reply to dhrogoff:

It doesn’t matter where the wildcard export statement is located in the package. Whatever was actually imported by the point of the endpackage gets exported.

The 1800 SystemVerilog committee has been dormant for the last 3 years. Vendors needed a chance to catch up after too many years of change, and users want stability.

In reply to dave_59:

In reply to dhrogoff:
It doesn’t matter where the wildcard export statement is located in the package. Whatever was actually imported by the point of the endpackage gets exported.

Makes sense. Thanks.

The 1800 SystemVerilog committee has been dormant for the last 3 years. Vendors needed a chance to catch up after too many years of change, and users want stability.

Understandable

In reply to dave_59:
Hello Dave,
Hope you doing good
I have a dummy uvm environment with all components like for environment(seqr,driver,monitor,scoreboard) and a package file (env_pkg.sv) ,

for sequences( seq_pkg.sv) and for tests(test_pkg.sv)

when i try to include these in top file

module top;

 import uvm_pkg::*;
`include "uvm_macros.svh"             //UVM Library Package
 import seq_pkg::*;
 import env_pkg::*;
logic reset;
logic clk;
axi_intf intf(.clk(clk),.reset(reset));
 
initial
begin
  clk =0;
  reset =0;
  #10ns clk =1;
  reset =1;
end    

always #10 clk = ~clk;

//DUT dut_inst(.clk(intf.clk),.reset(intf.reset));

initial begin
uvm_config_db#(virtual axi_intf)::set(null, "uvm_test_top", "intf", intf);
factory.print();
run_test();

end

Iget error as "Error-[SV-LCM-PND] Package not defined
top.sv, 6
top, “seq_pkg::”
Package scope resolution failed. Token ‘seq_pkg’ is not a package.
Originating module ‘top’.
Move package definition before the use of the package.

Error-[SV-LCM-PND] Package not definedtop.sv, 7
top, “env_pkg::”
Package scope resolution failed. Token ‘env_pkg’ is not a package.
Originating module ‘top’.
Move package definition before the use of the package.
Please guide ,thnks

In reply to ramankaur09:

This error message is stating that the tool can’t find seq_pkg or env_pkg. Did you compile them before compiling top.sv?

In reply to cgales:
Hello cgales,
yes, thats correct reason,thnks for response

In reply to cgales:

I tried same think but doesnt work. Do you have any other idea? Thanks for answer