Gord, Sorry for the late response, Hopefully, we can still use as a basis for discussion in today's meeting. I believe that your proposal still exhibits type system problems. A serious drawback of the proposal is it breaks the "is-of" relationship between base classes and derived classes. Your proposal prohibits the creation of "schedulefree" classes, but that restriction is not enough to avoid the scheduling ambiguity surrounding schedulefree base classes. The ambiguity arises because once an object has been created, users will want to assign handles of the derived (program/design) type to a handle of the (schedulefree) base class type. And, then the base class handle exhibits the same scheduling ambiguity as before, that is, if the base class contains any tasks then what should the scheduling semantics of those tasks be? How does the compiler know whether it needs to add additional synchronization code or not? If a schedulefree class is allowed to be extended into both program and design classes and the context of the extension modifies the behavior of the base class then we are really creating two different base classes. Thus, the same base class results in two distinct types, and their corresponding handles should not be assignment compatible, which deprives users of the benefits of polymorphism! Restricting the language by disallowing even handles of schedulefree classes is too restrictive --- for example a task or method with an argument of type schedulefree class would be illegal --- and changing the semantics of tasks based on the inheritance scope breaks the semantics of classes and open the door to race conditions over the class properties. Another problem with your proposal is that it does not address is the issue that design and program classes are subject to different semantic checks in addition to the execution region: Design signals may only be driven via NBA's from program classes, and design classes have no visibility into program data, etc... It appears that what you want is to give users the ability to specify a parameterized class whose program/design personality can modified by the instantiation or the inheritance context. If that is the case then why not use a variant of the existing parameterization mechanism? For example, a schedulefree class could be written as: class scfree#(context = program); ... endclass An interesting variant of the above parameterized class is: class scfree#(context=.); ... endclass In this case, the "." would be treated as a parameter that is determined by the syntactical context in which a handle is declared or in which the class is extended. This mechanism appears to cover the same functionality as your proposal, but it is up-front about creating different types, it avoids the separate compilation issues (the class is parameterized), requires fewer keywords, and seems much less verbose. Note that the instantiation by users of the class requires no special treatment! Arturo ----- Original Message ----- From: "Gordon Vreugdenhil" <gordonv@Model.com> To: "SV_EC List" <sv-ec@eda.org> Sent: Wednesday, April 20, 2005 12:28 PM Subject: [sv-ec] Class extension and scheduling The following is the somewhat delayed document regarding class methods and scheduling semantics. The main issues that we are trying to resolve are: 1) the need to have a package class type be reusable in both program and module (design) contexts. 2) the need to have the semantics of task suspension be determined prior to simulation. 3) the need to have clearly defined semantics for class extension Requirement 2 is needed to satisfy implementation issues raised by Synopsys and Cadence. This necessitates coupling the scheduling semantics with the type which reduces orthogonality between types and scheduling but we are prepared to accept that in order to reach a compromise. Preliminaries ------------- When tasks block, they need to follow one of two scheduling paradigms -- program (testbench) semantics which cause wakeup to occur in the reactive region or design semantics which cause wakeup to occur in the active region. In the context of classes, this leads to three possibilities: 1) classes that don't contain (potentially) blocking task methods. Such classes, since there are no delays, are free of any scheduling semantics. 2) classes with tasks where the semantics need to follow the design scheduling semantics. 3) classes with tasks where the semantics need to follow the program scheduling semantics. We introduce the concept of "schedulefree class", "design class", and "program class" (defined below) to describe these fundamental compositions of class and scheduling paradigm. We disallow any form of classes which express mixed scheduling semantics since such forms are extremely difficult to reason about and have the high potential for design errors. Due to the need for reusable class types, the scheduling semantics for a class containing a task should be permitted to be undefined as long as no objects of that class type can be created. When an object that contains a task is created, it must have a known scheduling paradigm defined by the type. Note that we borrowed a few keywords rather than introduce new ones but that is easily replaceable. We do introduce the keyword "schedulefree" for the purposes of this discussion. New concepts: 1) a "schedulefree class" is a class with no predetermined scheduling semantics for its methods. 2) a "program class" is a class with "program" scheduling semantics for its methods. 3) a "design class" is a class with "module" scheduling semantics for its methods. The idea of a "schedulefree class" is that it is neutral in terms of scheduling semantics and can be extended in either of the two scheduling domains. Once the scheduling domain is pinned down the class can't cross over into the other domain nor can it be extended in a manner that causes it to have mixed semantics. Thus any object has a single consistent behavior defined by its class. A consequence of this is that a "schedulefree class" that contains a task cannot have objects created via "new". Such a class must be extended into one of the scheduling domains before objects of the class type can be created. Rules: 1) A "class" type defaults to "design class" in modules and interfaces. A "class" type defaults to "program class" in a program. A "class" type defaults to "schedulefree class" in a package. Note: could also introduce prescribed defaults, ie. 'default_class_kind <module|schedulefree|program|none> 2) a "schedulefree class" shall only extend a "schedulefree class". 3) a "program class" shall only extend a "program class" or a "schedulefree class". No data member of a "program class" shall be of "design class" type. 4) a "design class" shall only extend a "design class" or a "schedulefree class". No data member of a "design class" shall be of "program class" type. 5) it shall be illegal to create objects of type "schedulefree class" if the type contains task members. Syntax Note: We used "program class", "design class", and "schedulefree class" in the discussion for readability. For the syntax, we kept the qualifications immediately after the word "class". Before or after the word "class" is immaterial. ------------------------------------------ Example: -------- package pkg; // defaults to "schedulefree" class vector #(int size = 1); bit [size-1:0] a; task do_something(); ... endtask; endclass endpackage module M; import pkg::*; // the sole purpose of the following is to "convert" // the schedulefree class into a design class class my_vect extends vector; endclass my_vect m_v = new; initial m_v.do_something(); endmodule program P; import pkg::*; // the sole purpose of the following is to "convert" // the schedulefree class into a program class class my_vect extends vector; endclass my_vect m_v = new; initial m_v.do_something(); endmodule ------------------------------------------ Example (Explicit variant) -------------------------- package pkg; class schedulefree vector #(int size = 1); bit [size-1:0] a; task do_something(); ... endtask; endclass endpackage module M; import pkg::*; class design my_vect extends vector; endclass my_vect m_v = new; initial m_v.do_something(); endmodule program P; import pkg::*; class program my_vect extends vector; endclass my_vect m_v = new; initial m_v.do_something(); endmodule ------------------------------------------ Example (Explicit variant with all types in package) ---------------------------------------------------- package pkg; class schedulefree vector #(int size = 1); bit [size-1:0] a; task do_something(); ... endtask; endclass class design design_vect extends vector; endclass class program program_vect extends vector; endclass endpackage module M; import pkg::*; design_vect m_v = new; initial m_v.do_something(); endmodule program P; import pkg::*; program_vect m_v = new; initial m_v.do_something(); endmodule ------------------------------------------ A good facet of this example is that we get nice reuse of the methods defined in pkg without having to do anything special. The limitations on the types are easily described. This allows "schedulefree class" types to propogate freely through the system. Class extension doesn't need to be restricted within a "program class" hierarchy or "design class" hierarchy and the boundary cases are covered for both type parameters and interface access to "design class" types from a program. -- -------------------------------------------------------------------- Gordon Vreugdenhil, Staff Engineer 503-685-0808 Model Technology (Mentor Graphics) gordonv@model.comReceived on Mon Apr 25 08:53:57 2005
This archive was generated by hypermail 2.1.8 : Mon Apr 25 2005 - 08:56:02 PDT