Re: [sv-bc] Assignment compatibility after elaboration

From: Greg Jaxon <Greg.Jaxon_at_.....>
Date: Wed Sep 05 2007 - 10:14:12 PDT
Bresticker, Shalom wrote:
> Greg,
> 
> I actually read your entire mail 

... and I'm not an easy-reading author ;-)

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

I agree: it's been "minor" so far.  Partly because it is impossible to
detect instance-specificity without crossing a hierarchy boundary
somewhere.

> 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?

Yes.  Are they rare?  Once you adopt a coding style that relies on type
parameters or types declared in interfaces, this issue comes up immediately.

> 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.

I agree that structs in packages are immune from this concern.  There
are workarounds for this simulation->synthesis migration issue.  I'm
just wondering why it needs a workaround at all.

Is the module-specialization forest something that a testbench compiler
can reconstruct from all the trees of a fully instantiated design?  If
that is hopeless, then perhaps the LRM is serving testbench needs here.
I'd find that argument hard to believe, but I'm not a testbench expert.

Thanks for your thoughts,
Greg

>> -----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:07:56 2007

This archive was generated by hypermail 2.1.8 : Fri Sep 07 2007 - 15:11:59 PDT