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.Received on Tue Sep 4 20:57:13 2007
This archive was generated by hypermail 2.1.8 : Tue Sep 04 2007 - 20:57:35 PDT