Re: [sv-ec] Class static memember initialization

From: Gordon Vreugdenhil <gordonv_at_.....>
Date: Thu Oct 30 2008 - 14:20:19 PDT
Mark -- see "GORD" comments below.  Sorry about the length, there
is a lot of detail at work here.

Mark Hartoog wrote:
> The LRM does say “A generic class is not a type; only a concrete 
> specialization represents a type,” but it is very unclear what the rules 
> are about initialization of static members .
> 
>  
> 
> Consider this simple example:
> 
> 
> module test;
> 
> class C #(p = 1);
>    static function int f();
>       $display("Init value = ", p);
>       return p;
>    endfunction
>    static int value = f();
> endclass
> 
> C #(2) c = new();
> 
> endmodule
> 
> Should this print:
> 
> Init value =           1
> Init value =           2
> 
> Or should it just print:
> 
> Init value =           2
> 
>  
> 
> Do the static members of class ‘C’ get initialized for the default 
> parameter values of the class, even though the default parameter values 
> are never used in the design?

GORD:

I view static members as part of the *type*, not the parameterized
class.  The LRM is pretty clear that the *types* instantiated for
"C" are just C#(2) so that is the only static member that exists.

I would expect just the output:
     Init value =           2


It is not the case that the default type exists; the default type
may not even be legal as you raised as well.

For example:
    class C #(type T);
      static T x;
    endclass

Since "T" is not required to have a default now, you can't even *have*
a default type for "C".

In code that is common (for us), we see things like:

    class C #(type T = int);
      T x;
      function new;
         x = new;
      endfunction
    endclass

or similar where the implied invariant is that "T" must be overridden
with some type that admits "new". This gives a way of effectively requiring
an override without the new mechanism of type parameters without defaults.



> If you think the static members should always be initialized for default 
> values, even though they are not used, then what about the case where 
> the parameter has no default value? 

GORD:
   Right -- I don't think default types always exist due to this
   reason (see above).

> What about the case where the parameterized class is never used in the 
> design at all?


GORD:

Then there are no "types" that are built from the parameterized
class and thus no static members exist.


> What about a non-parameterized class that is never used in the design?

GORD:

Ah, but that is different.  A non-parameterized class is itself a
type, it isn't a "type generator".  So its static members *do* exist
independent of use.

This is similar to doing something like the following:

    typedef C#(2) my_type;

That creates the *type* C#(2).  Whether that type (conveniently
named "my_type") is used or not is immaterial.  The type existence
is what counts.  One way to think about this is as though a
normal class was really just a typedef to a specialization
of a parameterless type generator -- ie.
    class D;
    endclass
has exactly the same behavior as
    class D_generator #();
    endclass
    typedef D_generator #() D;



> If parameterized classes are like C++ templates, 

GORD:

I don't think they are quite the same.

The rules in C++ are more "structurally" determinable and rely
on compile/link semantics.  The SV rules are in fact more dynamic
since the elaboration of the design (including configurations,
etc) are all part of the decision.

The SV LRM intentionally blurs some of the difference between
compile and elaborate to allow for vendor differences,
however, it is clear that whenever parameter type and value
binding, configurations, etc. are applied to the design (which
is usually called "elaboration" in the LRM), that information is
required to determine the set of types.

For a parameterized class this determination can be quite complex.
For packages the entire universe of elaborated design use has to map
into the same set of specialized types due to the type matching rules.
For modules there is the further complication of the existence of
the module parameters and the fact that those parameters can interact
with the parameterized class specializations.  This makes things
interesting when considering things like configurations, "bind",
and defparam which can impact the type universe in interesting ways.


> then the static members 
> should only be initialized for classes that are used in the design, but 
> the LRM does not seem clear about this.

GORD:

C++ has tighter definitions on this.  Part of this also relates
to when (in SV) static declarations in a task/function are
initialized.  These initializations also happen prior to
the first call (traditionally) and this is observable based
on hierarchical references to the statics.

Consider, for example:

    module top;
      function int f();
         static int cnt = 1;
         return cnt++;
      endfunction
      task t;
         int x = f();
         int y = f();
      endtask
      initial #1 $display(f.cnt);
    endmodule


I think it would be very surprising to see anything other
than a "3" from this code.  Such code is not expressible
in C/C++ and as such the question really doesn't come
into play as much but in Verilog hierarchical access to
tf statics makes this more obvious.

The similar class code is of course:
    module top;
      function int f();
         static int cnt = 1;
         return cnt++;
      endfunction         i
      class c;
         static int x = f();
         static int y = f();
      endclass
      initial #1 $display(f.cnt);
    endmodule

I think it would be equally surprising to not get a "3"
from this code in SV.



I don't think that these examples are completely esoteric
in terms of legacy code (at least the non-class one of
course).  I'd be very uncomfortable with having different
semantics in terms of how this would interact in the
class domain; I think  that what I've described here is
consistent with legacy expectations and use as well as
explicit rules regarding specializations and typing in
the LRM.

Gord.

-- 
--------------------------------------------------------------------
Gordon Vreugdenhil                                503-685-0808
Model Technology (Mentor Graphics)                gordonv@model.com


-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.
Received on Thu Oct 30 14:25:12 2008

This archive was generated by hypermail 2.1.8 : Thu Oct 30 2008 - 14:25:40 PDT