Re: FW: [sv-bc] parameterized structures

From: Greg Jaxon <Greg.Jaxon_at_.....>
Date: Mon Jun 19 2006 - 16:07:34 PDT
Gordon Vreugdenhil wrote:
> Greg,
> 
> I'm not sure I understand the issue here.
> 
> Let's stick with the process/scope case for a moment.
> 
>   module top;
>     class C #(int p = 1);
>        static int x;
>     endclass
> 
>     always @(clk) begin
>         C#(2) c_obj = new;
>         c_obj.x++;
>     end
> 
>     always @(clk) begin
>         C#(2) c_obj = new;
>         c_obj.x++;
>     end
>   endmodule
> 
> 
> Are we in agreement that there is only one "x" here and that
> it is the one that is the member of the specialized type C#(2)?

That is also what I'd like to see the LRM specify.  However, I will
note that the generic class has been declared in two different scopes,
neither of which is in a package context, so according the quote (see below)
I might expect them to be different types.

 >>> The set of matching specializations of a generic class is defined by
 >>> the context of the class declaration.  Because generic classes
 >>> in a package are visible throughout the system, all matching
 >>> specializations of a package generic class are
 >>> the same type. In other contexts, such as modules or programs, each
 >>> instance of the scope containing the
 >>> generic class declaration creates a unique generic class, thus,
 >>> defining a new set of matching specializations.

You see the thrust here?  Package / Not Package.  This is an insufficient
specification.  In fact all Gaul is divided in THREE parts.  Packages / Instances /
Scopes inside a package or instance (i.e. scopes of the Third Kind, if you will).

The LRM never really defines "instance", and here is where we need it to be
accurate.  Reword this paragraph to talk about the (few) scopes which
cause generic specializations to be cranked out once-per-invocation - let's
call these the "instance scopes" - I think this is the complete list, check my work:
     - Module declaration
     - Interface declaration
     - Generate block
     - Program declaration

Now consider all the other kinds of scopes we have: function bodies, loop
iterations, always blocks, nested blocks, etc...  Generic class specializations
declared there don't "create[] a unique generic class, thus, defining a new set
of matching specializations".  No!, they all hook up with a single type.  If one
of these Type 3 scopes is nested inside a package, then its class specializations
unify with each other globally across the package or $unit.  If the declaration
is in a scope local one of the four kinds of "instance scope", then it hooks up
with its identical twins across the current instance, but not across instances.

It does this regardless of whether the instance scope even made such a declaration!

So, yes, there are just two behaviors: global and per-instance.  But not all that
is a non-package creates a new instance.

As written, the LRM lumps always block scopes in with module scopes - they are
both non-packages, hence they make a new specialization every time you invoke
that scope.   Yes, yes, now that the coffee is working I realize that only
synthesis guys see things this way, but one should not have to read the LRM
with the right biases to get its meaning.

Greg


> If we are,  then I am not sure what modification of this you have
> in mind.  Can you give a specific example and what you think
> should happen?  If we aren't in agreement on my "single x"
> contention, then we need to have a different discussion as
> I think that is pretty clear from the LRM.

We are in agreement about what we want to have happen, but I'm just trying
to comprehend the LRM as a definitive document.  When I


>>
>>
>> Indeed there are two kinds of contexts - some "uniquify" the type 
>> one-per-instance
>> and others do not.  but the breakdown is not non-package vs package.  
>> Instead it
>> is:   { module, interface, program, or generate block } vs anything else.
>>
>> I looked for a definition of "instance" in the LRM, but haven't yet found
>> one to match the usage we're giving the word here.
>>
>> Greg
>>
>>
>>
>> Gordon Vreugdenhil wrote:
>>
>>>
>>>
>>> Greg Jaxon wrote:
>>>
>>>> I agree that the type universe is statically computable at
>>>> elaboration time.  
>>>
>>>
>>> Good.
>>>
>>>  > I guess the "lifetime" I'm referring to
>>>
>>>> is the sequential lifetime of scopes during elaboration.
>>>>
>>>> function automatic string foo();
>>>>   typedef struct { int wont_get; } food_again;
>>>>
>>>>   static food_again new_boss;
>>>>
>>>>   new_boss.wont_get = 32'shdeadbeef;
>>>>
>>>>   return $typename( new_boss );
>>>> endfunction
>>>>
>>>> Each time this function is called, we get a new "instance" of its 
>>>> scope, right?
>>>
>>>
>>> I don't think so.  You really need to think of "typedef" as being
>>> "static typedef".  There are no "automatic" types -- this is implied by
>>> the earlier statement that all types are computable at elaboration time.
>>> This also allows "static food_again new_boss;" to have a sensible
>>> and unsurprising meaning.
>>>
>>> Gord.
>>>
>>>> So each new_boss has a different type than the old new_boss, right?
>>>>
>>>> Greg
>>>>
>>>> Gordon Vreugdenhil wrote:
>>>>
>>>>> Greg,
>>>>>
>>>>> I think that you are assuming something stronger than what the
>>>>> LRM requires.  Class specialization requires *constant* values;
>>>>> as a result, the *type* universe is computable at elaboration
>>>>> time and doesn't grow during simulation.  "static" is useful
>>>>> since a type doesn't really come and go -- the local visibility
>>>>> does but not the type itself.
>>>>>
>>>>> Example:
>>>>>
>>>>>   module top;
>>>>>     class C #(int p = 1);
>>>>>        static int x;
>>>>>     endclass
>>>>>
>>>>>     function void foo;
>>>>>        C #(2) local_obj;
>>>>>     endfunction
>>>>>
>>>>>     C #(2) c_obj;
>>>>>   endmodule
>>>>>
>>>>> The type of "local_obj" in foo is *the same type* as the type
>>>>> for c_obj.  Any reference to "x" via either local_obj or
>>>>> c_obj always refers to the same "x" that is tied to the specialization
>>>>> of the type within the universe of class C.
>>>>>
>>>>> This means that any recursive call could still only create
>>>>> an elaboration time determinable universe of types.  It is an
>>>>> implementation issue about when the specializations actually
>>>>> occur but the static members never "go away".  The lifetime
>>>>> of a static class member conceptually extends from the first
>>>>> time the type is specialized until the end of simulation;
>>>>> any future specialization has the same static member.
>>>>>
>>>>> Gord.
>>>>
>>>>
>>>>
>>>>
>>>
>>
> 
Received on Mon Jun 19 16:07:39 2006

This archive was generated by hypermail 2.1.8 : Mon Jun 19 2006 - 16:07:50 PDT