Critique of the Objective VHDL Language Definition

1 downloads 0 Views 161KB Size Report
tion, encapsulation, and inheritance with polymorphism. [4, page 181]. ... not addressed by the existing VHDL language are: inherit- ance-based ..... features in a future revision of Java. ... it now would be a significant language design exercise.
Submitted to Design Automation and Test in Europe 2000.

Critique of the Objective VHDL Language Definition Philip A. Wilsey and Dale E. Martin

Peter J. Ashenden Department of Computer Science University of Adelaide, SA 5005 Australia [email protected]

Dept. ECECS, PO Box 210030 University of Cincinnati Cincinnati, OH 45221-0030, USA [email protected] [email protected]

ommend which proposal best serves as the basis for standardised extensions to VHDL. The findings of the panel will be reported elsewhere. We introduce our critique of the Objective VHDL language definition by presenting some views on language design principles that lead to high-quality languages. While many of the principles presented here may appear to be common sense or general “motherhood and apple pie” statements, it is important to bear them in mind when designing language extensions, as they are all too often overlooked. As Brooks notes, “Conceptual integrity does require that a system reflect a single philosophy and that the specification as seen by the user flow from a few minds” [5, page 49]. The foremost principle is that language design should focus on semantics first and syntax second. The semantics of language features embody the meaning of the features, and determine what design intent can be expressed in the language. The benefits of a semantics-based language design methodology are illustrated by Tennent [9]. He comments that a methodological approach based on semantics is “intended to help a designer cope with the detailed problems of achieving consistency, completeness, and regularity in the design of specific language features,” and “has the effect of drawing [the designer’s] attention to deeper structural issues” in a language. Syntax, on the other hand, is the concrete expression of semantic features. While poor syntax may obfuscate the design intent, it does not prohibit expression of the intent. Good syntax design allows the designer to think about and communicate design intent clearly. In determining semantic features to be included in a language, sufficient simple semantic mechanisms should be preferred over more complicated general solutions; the simple mechanisms can then be used to build applicationspecific solutions. The semantic mechanisms should, as

Abstract This paper provides a critical analysis of Objective VHDL, an object-oriented extension to VHDL. It is demonstrated that several design decisions lead to unnecessary complexity in the language and consequent modelling difficulty for designers. The SUAVE object-oriented extensions to VHDL, on the other hand, avoid these problems by more careful selection of language features.

1. Introduction The design of a programming language or a hardware description language is a difficult task. Since the language is the vehicle for expression of design intent, a good language can greatly help the design process, whereas a poor language can significantly hinder it. A language should conform to a set of ideals or philosophies to make it coherent, easy to learn, and easy to read and understand. This is what Brooks refers to as “conceptual integrity” [5]. Recently, two language designs have been proposed to the IEEE Object-Oriented VHDL (OOVHDL) Study Group as candidates for standardisation: SUAVE [2, 3] and Objective VHDL [8]. Both extend the VHDL hardware description language to include features for object-orientation. SUAVE also adds features for type-genericity, abstract communication, and dynamic process creation. As part of a process of review of the two proposals within the study group, we, the authors of the SUAVE proposal, have prepared this critique of the Objective VHDL proposal. The Objective VHDL proposers have likewise prepared a critique of the SUAVE proposal. The language descriptions, critiques and other material are to be examined by a panel of distinguished experts, who will rec-

1

In the remainder of this paper, we demonstrate that several features of Objective VHDL violate the design principles introduced above. We contrast the features of Objective VHDL with those of SUAVE.

much as possible, be orthogonal to each other. As Hoare suggests [6], “concentrate on one feature at a time,” and “reject any that are mutually inconsistent.” By choosing simple orthogonal semantic mechanisms, interaction between mechanisms is reduced and easier to understand. Simplicity of mechanism and reduced interaction make it easier for tool builders to optimise their implementation of language features.

2. Class Types Objective VHDL uses class type definitions to provide data abstraction, encapsulation and inheritance in a single language construct. A class definition defines encapsulated data and operations for a type, and allows specification of a superclass from which data and operations are inherited.

When extending an existing language, the preceding principles should be applied to the extensions. Simple semantic mechanisms should be chosen to augment the existing mechanisms, not to replace them. The new features should conform to the same design philosophies that were followed in the original language design so as to maintain architectural coherence. Careful consideration must be given to interactions between new features and existing features. While the semantics of new features are of primary concern, integration of new syntax is also important. Extensions should aim for stylistic consistency with the existing language. New features that are just syntactic rewrites of existing features (“syntactic sugar”) should only be included if they significantly enhance the expressiveness of the language. As Wirth puts it [11], “distinguish ... between what is essential and what ephemeral.”

2.1

Class Types and Information Hiding

A class in an object-oriented language can be considered as an ADT with inheritance. VHDL already provides a partial facility for defining ADTs, based on the package construct. The user declares the concrete type in a package, and provides operations in the form of subprograms taking parameters of the concrete type. While the implementation details of the operations can be hidden (they are declared in the package body), VHDL provides no mechanism to hide the implementation details of the concrete type. Thus the security of ADTs in VHDL is weak.

Given the importance of integration of new features with existing features, we need to identify existing features that relate to object-oriented modelling. VHDL already includes many features that relate to the principles cited by Booch as necessary for object-orientation: data abstraction, encapsulation, and inheritance with polymorphism [4, page 181]. Subprograms, entities, and packages support abstraction and encapsulation (albeit weak encapsulation in the case of packages); and overloading provides a limited, ad-hoc form of polymorphism. In the terminology of Wegner [10], these features are sufficient for VHDL to be called “object-based.”

Objective VHDL addresses this weakness by adding a new language construct, class type definition, that provides secure forms of ADTs. A class type definition allows declaration of data elements and operations to be encapsulated by the ADT, and ensures that the implementation details are not visible outside the class type definition. Our first criticism is that the class type definition feature replicates much of the encapsulation facility provided by packages. This adds complexity to the language and its implementation. It forces a user to make a decision between two similar language mechanisms (packages or classes) when there ought not to be a need for such a choice. The choice is not always clear, and requires the designer to project the future evolution of the design. If the designer initially chooses to use a package for and ADT, and in subsequent development of the design discovers that features of a class type are required, the designer is forced to undertake significant re-engineering of the ADT and its use.

The main issues for object-oriented modelling that are not addressed by the existing VHDL language are: inheritance-based hierarchy (for data types and hardware structures); the form of dynamic polymorphism that goes with inheritance (namely, dynamic binding); a stronger form of abstraction and encapsulation for abstract data types (ADTs); and a more flexible form of static polymorphism, such as that represented by generics in Ada and templates in C++. We maintain that language extensions to support object-oriented modelling should address these issues without subverting or replacing existing language features. Rather, they should build upon the existing language features that make VHDL object-based. Furthermore, there should be a clear separation of concerns between language features, so that a given feature does not attempt to serve multiple underlying modelling requirements. The interactions between language features should be well defined and understandable to language users.

A further consequence of the Objective VHDL class mechanism is that will frequently lead to “double encapsulation.” Consider the common case of a class being declared so that it is visible in multiple design units. The class must be encapsulated in a package, as illustrated by the following example. package T_pkg is type T is class class attribute A : ... ;

2

procedure op_1 ( ... ); ... end class T;

The problem that arises in Objective VHDL is that, in a class definition, it is not known whether the class will be instantiated as a memory location (constant or variable) or as a signal. The object on which a method is invoked is passed implicitly to the method, rather than being explicitly part of the method’s interface. Hence, for each method in the class, it is not known whether to use memory location or signal semantics for assignment and reading of the encapsulated data. Objective VHDL solves this problem with the mechanism of object configurations within a class definition. Object configurations for constants, variables and signals group method definitions that are to be used should the class be instantiated as a constant, variable or signal object respectively. A method with a given name and signature can appear in one or more of the following places: the common part, a constant object configuration, a variable object configuration, or a signal configuration. The kind of storage object on which the method is invoked determines which version of the method is called. Each version of the method must only use semantics appropriate for the kind of storage object implicitly passed to it. While this approach seemingly solves the problem, it does not integrate with the existing VHDL models of declarative regions and scope and visibility of names. The closest analogs of class definitions in VHDL are record and protected type definitions, each of which define a single declarative region in which homographs are disallowed. In contrast, a class definition defines three declarative regions, one each for constant, variable and signal objects, each consisting of the union of the common part and the corresponding object configurations in the class definition. This is a significant complication and departure from the existing language. There is significant potential for confusion in a model where names might be homographs and cause hiding in some configurations of a class and not in others. A further complication arises in methods in the common part of a class definition. Such methods may only read the values of class data. While the syntax of reading a value is the same for constants, variables and signals, the semantics differ between storage locations and signals. Thus the kind of read to use must be dynamically determined, making analysis, simulation and synthesis more complex. Alternatively, separate versions of the common methods must be generated, corresponding to the separate object configurations. The problem of dealing with objects of different storage kinds naturally arises with SUAVE also. However, it is easily dealt with using existing language mechanisms. Since the object on which a method is invoked is passed as an explicit parameter to the method, the storage class of the parameter (constant, variable or signal) determines the applicable semantics for update and reading. Multiple dif-

end package T_pkg;

The package serves no purpose other than to contain the class type, in which the data types and operations are declared. This extra layer of encapsulation adds unnecessary complexity to the model. SUAVE avoids these difficulties by making use of the existing mechanism (packages) to provide encapsulation for classes. Information hiding for the encapsulated data is provided through private types, and inheritance is provided through type derivation. (These features in SUAVE are adopted from the Ada-95 programming language [7].) Thus the choices of language features needed for particular application problems are clear, and no unnecessary encapsulation is required.

2.2

Encapsulated Storage v. Encapsulated Type

A class in Objective VHDL encapsulates class attributes that denote the storage of a class instance. This leads to two problems, discussed in this section.

2.2.1

Variables and Signals

In conventional imperative object-oriented programming languages, there is only one kind of storage for objects, namely, abstract memory locations with simple storage semantics. A location is updated by assignment, and its value can be read by naming the location in an expression. In imperative programming languages where storage is encapsulated within a class definition, the semantics of assignment and reading of encapsulated data are clearly those of storage locations. In VHDL, however, there are two kinds of storage: memory locations (constants and variables) and signals. The semantics of memory locations are the same as those of iterative programming languages. However, the semantics of signal storage are significantly different and more complex. Signal assignment involves editing transaction lists on drivers (which itself involves comparison and assignment of values), resolution of driving values, evaluation of nets (including invocation of type conversions and conversion functions) to determine driving and effective values, comparison of old and new values to determine events, and evaluation of dependent implicit signals. Because of the significant difference in semantics, VHDL uses separate assignment operations for memory location update (”:=”) and signal transaction scheduling (”