why wrap classes in package, if you want to use it in different file

879 views
Skip to first unread message

JoshforRefugee

unread,
Feb 6, 2007, 5:08:06 PM2/6/07
to Advanced Verification Methodology User Group
This is classic question, but didn't understand concept of this
(coming from C++ background). Can someone help me grasp this very
SystemVerilog concept
I am use to creating class in <class_name>.sv and including it in
<use_here>.sv
but that doesn't work for SV. you have to wrap <class_name>.sv in
package and import it to <use_here>.sv

why is that? My apology for not wording my question correctly.
Probably reason why I don't understand this concept.

Thank you,

Ray Salemi

unread,
Feb 6, 2007, 7:37:29 PM2/6/07
to avm-...@googlegroups.com
The package/import approach is a more general way of solving the problem of sharing definitions.  It's nice because you're no longer using your file system to manage your classes.  With C++ you sort of "trick" the compiler into sharing code by including things all over the place.  With SystemVerilog the language understands the concept of sharing class definitions.

This allows you to do some neat management tricks.  For example an IDE can read the package statements and show you the packages available.  You can expand the packages to see the classes in them.  Or, you can have two different packages that define the same classes different ways (say you want to try some new tricks out on working code).  Then you can control which classes you see with the import statement.

Granted.  You can make a filename-based system do almost all the same things as a language based system.  It's just more work and can get kludgey at times.
--
Author of Leading After a Layoff : http://tinyurl.com/ycv2xa

Ajeetha Kumari

unread,
Feb 6, 2007, 10:56:39 PM2/6/07
to avm-...@googlegroups.com
Hi,
I don't fully understand why you say you can't do without package -
you can. The way you have suggested, does work, use `include in your
<use_here.sv" file as:

====
`include "class.sv"
====

However it is a good idea to have them under package. In Sv, classes
can be declared in $root scope. There was a related discussion
sometime back in Orkut and I'm pasting my view I offered in that forum
over here.

HTH
Ajeetha, CVC
www.noveldv.com

------- $root vs. package -------

Hi,
Anything in $root is global - meaning a potential candidate for name
clash. For instance you are developing a USB VIP, you have a class
say:

class base_pkt;
//..
endclass

Say another VIP from your same company develops say an Ethernet VIP,
he/she may code same class name as say:

class base_pkt;

If these 2 VIPs were to be plugged into one single SoC, then user is
in trouble - hence will dislike your VIPs. If you instead put them
under say:

package usb_pkg;
package enet_pkg;

Then it would have been easier. Of-course the name of the package
itself may clash, but chances are rare and you prepend/append your
company name etc.

--------

--
Ajeetha Kumari
* A Pragmatic Approach to VMM Adoption
* SystemVerilog Assertions Handbook
* Using PSL/SUGAR
Design Verification Consultant,
Contemporary Verification Consultants Private Limited,
Bangalore, India, http://www.noveldv.com

JoshforRefugee

unread,
Feb 7, 2007, 9:17:01 AM2/7/07
to Advanced Verification Methodology User Group
thanks for great info Ray and Ajeetha.
here is my dilemma:

in my checker.sv:

interface checker_if (input bit clk)
.....
modport CHECKER_MP (clocking cb_block);
....

endinterface


class checker_c
virtual checker_if.CHECKER_MP my_interface;
..............
extern virutal function void reset();
endclass


function void checker_c::reset()
endfunction: reset

---------------------------------------------------------------------------------------
and in my tb.sv
I have a interface instantiation

module top;

wire clk;
checker_if my_checker_if(clk);
dut (...)
endmodule;

-------------------------------------------------------------------------------------------

and now in m test.sv

I am actually doing class instantiation here.

here I want to do:
checker_c my_checker_c = new (top.my_checker_if);
my_checker_c.reset();
.....

Can you guys suggest best way to do this. I can put interface in new
file, packed checker_c in package and new file. But that might create
problem (since class will not know where interface is, so not sure if -
> virtual checker_if.CHECKER_MP my_interface declaration will work in
class).

Ray Salemi

unread,
Feb 7, 2007, 12:17:43 PM2/7/07
to avm-...@googlegroups.com
I do this differently so I don't see the same issue you are seeing.
I've attached a sample design but basically I do things like this.

Given a DUT with an interface I have a top.sv that looks like this:

---- top.v ----
import multadd_tb_pkg::*;
import avm_pkg::*;


module top;

multadd_if ma_if();
clock_reset cr (ma_if);
multadd DUT (ma_if);
multadd_tb TB(ma_if);

endmodule // top
-----------

So the "checker" in this case is in the multadd_tb module. That
module looks like this.

---- multadd_tb.sv -----
import multadd_tb_pkg::*;

program multadd_tb (multadd_if ma_if);
ma_env env = new (ma_if);
initial begin
env.do_test();
end
endprogram
--------

So the multadd module is instantiating the environment, connecting it
to the interface, and starting it up.

So where does that leave test.sv? It looks like you are using the
checker class to create your checks. You could instantiate that
checker class where I have instantiated the env. Or you could put the
checker class in the env.

Does that help?

Ray

On 2/7/07, JoshforRefugee <ank...@yahoo.com> wrote:
>

--

avm_overview_class.tar.gz

Dave Rich

unread,
Feb 7, 2007, 8:35:49 PM2/7/07
to Advanced Verification Methodology User Group
Ajeetha,

$root vs. $unit vs. package vs. `include

$root is not the same as $unit. $root is the top of the elaborated
hierarchy for Verilog modules and programs. You can't explicitly put
anything into $root.

$unit is the top of the current compilation unit, and there can be
multiple $units in a design, each creating their private global space.
Each has their own namespace. You cannot `include a class definition
into multiple compilation units and get equivalent types. They will
each have independent set of static variables as well. The same is
true for `including definitions into different modules/programs/
interfaces. Each `include will create an independent type.

Only when your entire design is one compilation unit, do $unit and
$root appear to be the same. In that case, most people will want to
put their definitions local to their modules to prevent global
namespace pollution. But then you run into the problem I mentioned
above, unless you put your definitions into a package and import them.

Mike Mintz

unread,
Feb 8, 2007, 7:22:20 AM2/8/07
to Advanced Verification Methodology User Group
Hi,

Why not use the "extern" in all class methods ? Then you have the
equivalent of a c++ header file:

//in my_class.svh
`ifndef __my_class__
`define __my_class__

class my_class;
extern function new (string name);
extern task do_it ();
endclass
`endif

Then code can `include "my_class.svh" and use it as a declaration. You
have a separate my_class.sv for the implementation.

For an even weaker reference, use the forward declaration:
typedef class my_class; or
typedef my_class;

This is an even better way of minimizing the connections between
Modules. Of course, this is not appropriate on a class you are
extending.

I am not in favor of using packages (for class declarations). With
the current definition of SV, it is difficult to have a separate
implementation file for the classes/tasks declared in the package.
Also, package scopes cannot be added to, like C++ namespaces. This
warps the code. Using Ajeetha's uart example, I want to have separate
files to declare the driver, monitor, checker and generator. I cannot
do this (easily) in SV because once you start a "package uart", all
declarations and definitions have to be seen before the "end package".

The import package and import with a package rules are silly. If,
inside "package A; end package", you import other packages, they are
added to the scope of package A. This is fine for package A's
implementation, but inappropriate for users of package A. Please
correct me if I am mistaken.

I do use packages when I have a low level utility unit or for
encapsulating enums, consts, and parameters, since these cannot be in
a class.

Take Care,
Mike

Ray Salemi

unread,
Feb 8, 2007, 7:28:28 AM2/8/07
to avm-...@googlegroups.com
Hi Mike,

The imports don't chain in SV. So, if you do an import within a
package, users of that package don't get the references automatically.
They need to explicitly import the packages they want.

I do all my imports before the "package" keyword so as not to confuse
later readers. When they see the imports at the top of the file, they
know that these are not intended to be transported with the package.

Then, I use include files for each class between the
"package/endpackage" pair. That way I have a single file per class.

Best Regards,

Ray

Rose, Adam

unread,
Feb 8, 2007, 7:47:09 AM2/8/07
to avm-...@googlegroups.com

Mike,

I think you're imposing a C++ view of compilation onto SV.

In C++, the unit of compilation is basically a C++ file. We compile
these into object files which are then combined into libraries and
executables.

In SV, the basic unit of compilation is are modules, interface, program
blocks - and packages. It is packages that are compiled, not "sv" files.

As a result, the ifdefing that you would do in C++ is basically a waste
of effort in SV. You can simply go import my_pkg::* to gain access to
all the "foreign" symbols - there is no compile dependency in the C++
sense, since you do not have to include the headers from the imported
package at all.

I would slightly disagree with Ray about where to put the import
statement - I believe that the correct syntax is that you put the import
inside the package. But that's a minor detail - the point is that
packages are the best way to organise your dependencies in SV. Or more
precisely, there simply are no compile time dependencies if you use
packages, all there is is a compile ordering problem, since you have to
compile a package before you can import it. As Ray correctly points out,
it is quite easy to maintain one class per file by including a list of
files in your package file. I use .sv for package files, for the
included files I think it is important NOT to use .sv - I use .svh but
anything would be OK.

Adam.

Reply all
Reply to author
Forward
0 new messages