RE: [sv-bc] Assignment compatibility after elaboration

From: Bresticker, Shalom <shalom.bresticker_at_.....>
Date: Wed Sep 05 2007 - 09:14:58 PDT
Greg,

I actually read your entire mail (though I probably unconsiously skipped
a few words here and there).

I am not sure that the disconnect for a SYNTHESIS tool is so big.

For example, long before Verilog-2001 automatic functions, synthesis
tools were in practice implementing functions in synthesizal RTL as
though they were automatic. Did it matter? Nope, because the
synthesizable subset did not include those situations where it would
matter, with maybe some extremely rare exceptions. 

I am not sure that is not the case here. Surya's original case, for
example:

>> module top;
>>   bottom #(2) b1();
>>   bottom #(3) b2();
>>   initial begin
>>      b1.s = b2.s;
>>   end
>> endmodule

is not in today's synthesizable subset because you can't do hierarchical
references, except into generate scopes.

Do you have a case where it would matter to a synthesis tool?

On the other hand, to a testbench, which does hierarchical references
all the time, it seems it would certainly matter. That maybe means that
the RTL coding style has to be such as to be good for the testbench as
well. 

That is one reason for putting such common definitions in packages.

Regards,
Shalom


> -----Original Message-----
> From: owner-sv-bc@server.eda.org 
> [mailto:owner-sv-bc@server.eda.org] On Behalf Of Greg Jaxon
> Sent: Wednesday, September 05, 2007 6:57 AM
> To: Gordon Vreugdenhil
> Cc: sv-bc@eda-stds.org
> Subject: Re: [sv-bc] Assignment compatibility after elaboration
> 
> Gordon,
> 
>   Thanks for the encouraging reply.  I agree that the LRM 
> lacks some of these important concepts, but I see this as a 
> problem with the LRM, not with the concepts...  (more below)
> 
> Gordon Vreugdenhil wrote:
> > 
> > 
> 
> 
> >>> Surya Pratik Saha wrote:
> 
> >>>> module bottom;
> >>>>   parameter p = 1;
> >>>>   typedef struct {int x; int y;} st;
> >>>>   st s;
> >>>> endmodule
> >>>>
> >>>> module top;
> >>>>   bottom #(2) b1();
> >>>>   bottom #(3) b2();
> >>>>   initial begin
> >>>>      b1.s = b2.s;
> >>>>   end
> >>>> endmodule
> 
> >> Gordon Vreugdenhil wrote:
> >>>
> >>> This should be illegal.
> >>>
> >>> SV does NOT do structural compatibility -- for a struct, each 
> >>> elaborated struct declaration is a unique type.  Here 
> there are two 
> >>> "instance paths" to the types so the types are distinct and the 
> >>> assignment is illegal.
> 
> > Greg Jaxon wrote:
> >> I have a follow-up question...
> >>
> >> The two types "st" can be distinguished in two ways:
> >>
> >>   1) They are declared by different specializations of the module 
> >> template "bottom".
> >>
> >>   2) They are declared by different instances of the 
> "bottom" module.
> >>
> >> Gordon is faithful to the LRM when he appeals to reason #2 
> to answer Surya.
> >> I wonder, though, whether it would be more sensible to 
> rely solely on reason #1.
> >>
> >> Is there any functional dependence a type can have on its 
> "home instance"?
> >> I suppose classes whose methods have side-effects outside 
> the class members
> >> would be the canonical example - can this arise in SV?   
> 
> > Sure.
> > 
> >    module bottom;
> >       int x;
> >       class C;
> >           function void incr();
> >               x++;
> >           endfunction
> >       endclass
> >    endmodule
> > 
> > "x" here is like a static member.  In fact, a static member 
> would also 
> > be a determinable way of discovering whether an implementation was 
> > compliant to the specs requirements.
> > 
> > 
> >> If so, do all such dependences arise from "class" types?
> > 
> > I believe so.
> 
> Now let's consider the "depends upon" side of this arc...
> 
> A class type's identity can depend upon instances of what?
> Just modules (and interfaces), or can it also refer to static 
> data inside lexically more global class declarations?
> 
> Undoubtedly a class type's identity can be tied to physical 
> instances of certain design components by using static data 
> from such instances.
> Is this difference between the expressive power of classes 
> and the simpler "structural" types significant?
> 
> Structs and unions can have class fields.  In the recursive 
> definition of "matching type", such structs will only match 
> if all their fields also  have matching types, i.e. identical 
> classes dependent upon the identical component instances.  
> This allows two struct types to be instanced from the same 
> lexical source and yet not match, giving an appearance of 
> instance-specificity.  But instance-specificity is not a 
> necessary property of every struct/union type (unless we 
> define it so).
> 
> Why do that?
> 
> On behalf of the synthesis products, I want to object to 
> making this definition.  I'll note that currently (and 
> probably for some time to come), no synthesis product 
> implements SV classes (except for static classes, or those 
> which by definition are incapable of external data reference).
> SV class objects are dynamic pointers - a behavioral 
> abstraction generally considered too high level for RTL 
> synthesis.  This leaves the synthesis subset with no known 
> benefit from instance-specificity and a potentially onerous 
> cost.  This was why I said:
> 
> >> Working from existing synthesis technology, I see a minor 
> disconnect 
> >> in the type system based on instances.  In practice, designers may 
> >> specialize a module template a few times, but replicate them 
> >> sometimes hundreds or thousands of times.  To keep compile costs 
> >> down, perfect replicas aren't made unique until quite late 
> in the compiler flow - place and route, maybe even later.
> 
> > There is no concept of "specialization" for modules.  Modules are 
> > instantiated; parameterized classes are specialized.
> 
> The LRM doesn't articulate this concept, but I assure you it exists:
> "4 bit signed carry/save" is a specialization of "adder"; 
> folks often load such a design from elaborated RTL and then 
> proceed to instantiate lots of them with no further 
> involvement of the synthesis front-end.
> The universe of discourse within that front-end refers to 
> module template specializations; the synthesis-subset of 
> defparams are just a syntactically clumsier way of 
> controlling specialization.
> 
> Contrary to the LRM, in a design DB, the concept of a module 
> instantiation is usually nothing more than another edge in a 
> large DAG.  The meaty nodes of that graph start off being 
> labeled as module template specializations.  They are only 
> split into instantiations as needed to further specialize for 
> optimal timing, area, congestion, etc.
> 
> > Implementations may *choose* to optimize by determining how 
> to safely 
> > fold together the behavior from various instantiations of a 
> module but 
> > that is strictly an optimizations.  The LRM view of the 
> relationship 
> > is what matters.
> 
> I understand this viewpoint, but for the last few years I've 
> been bewildered about how it aligns with reality.  It 
> doesn't.  This isn't simply an optimization.  No CSE hash 
> tables are consulted to produce these DAGs; they are 
> synthesized by a process no different in principle from 
> wiring up the RTL for a sequential block.
> 
> >> To insist that we be able to distinguish the replicas during 
> >> elaboration (when type information can influence logic) seems 
> >> excessive.  Is it really necessary?
> > 
> > Again, what an optimization can decide to safely do is up to the 
> > implementation; the LRM conceptualization is based on 
> instantiations.
> 
> Gord is absolutely right that this is how the LRM is now.
> I just cannot yet see why it /must/ be this way.
> I think struct, union, and enum type identities can safely be 
> tied to unique module specializations.
> Indeed, this is all that I have been able so far to tie them 
> to in the synthesis implementation I work on; and the SV 
> designers seem to think it follows their mental model of 
> elaboration naturally enough.
> 
> What Gord calls an optimization, I think of as a simplification
>  - more than that: an architectural choice in favor of simplicity.
> Do not unnecessarily multiply neither module instances nor 
> type identities.
> 
> Here is what synthesis would require to implement the LRM's
> definition:  Any module or interface which declared a struct, 
> union, or enum type would need to take a new implicit 
> parameter "instance_identity"
> to build into these "strong" type identities and to pass on 
> to down designs via type parameters as needed.
> 
> Each design instance would then require individualized 
> elaboration (or at least some last-minute substitution of the 
> actual instance
> identity before types are compared).   Of course, $instance_id can be
> added to the specialization recipe - they're not /my/ CPU cycles!
> Before spending my customers' elaboration time spamming him 
> with personalized chain letter .db, I want to be sure this is 
> what the world really wants.  Of course, for classes, it IS 
> what you want.  But structs are not as complex as classes, is 
> it surprising that you might expect less from them?
> 
> You can look at the absence of such a hidden parameter as
>   - an LRM conformance bug, or as
>   - the discovery of a simpler model for the language semantics.
> Seeing it as a bug requires conceiving of 
> instance-specificity as being the designer's intent when 
> (s)he writes down an enumeration or a struct layout.  
> Instance-specific structs, unions, and enums might on rare 
> occasions be a nifty way to propagate hierarchical info, but 
> that is rarely needed information.  Instance-specificity 
> seems (to me) to be an optional and somewhat marginal property.
> In fact, it seems excessively finicky, because it picks up 
> dependences on hierarchical paths that are usually irrelevant 
> to the purely structural nature of data access to struct fields.
> 
> Why is this bundled into a straightforward idea like field 
> aggregation?
> Do I have to go back to using macros for field access to get 
> the original lightweight concept we lifted from Pascal, C, 
> Fortran90, et al?
> 
> I am NOT arguing for structural-equivalence here.  I still 
> hold to the notion that each source declaration produces a 
> unique type identity.
> That's the notion most important to a software engineer: 
> knowing that there is exactly one source location that 
> governs accesses to any given strong data type.  All the 
> functional variations are expressed by specializing the 
> enclosing design components around this source location.  
> Finally instantiating them doesn't alter function or source 
> ancestry - it only fills in object names for all the copies 
> of these functionally unique specializations.
> 
> Surely in the few cases where instance-specificity might be 
> desired, some further syntactic specification could be 
> applied whose effect would be to capture the module/interface 
> instance_identity into a type's matching criteria.  Maybe 
> "unique struct { ... }" ?
> 
> Greg Jaxon
> 
> BIG disclaimer:  This is really just personal opinion at this point.
> This belonged on the agenda several years back - and I'm sure 
> it was discussed then.  I regret having been unable then to 
> penetrate the LRM verbiage enough to make this point clearly. 
>  I don't think it's too late to make it now.
> 
> 
> --
> This message has been scanned for viruses and dangerous 
> content by MailScanner, and is believed to be clean.
> 

-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.
Received on Fri Sep 7 15:01:01 2007

This archive was generated by hypermail 2.1.8 : Fri Sep 07 2007 - 15:01:33 PDT