This article looks at the suitability of object-oriented programming (OOP) principles for the development of VHDL code. This article does not report on the current status of work within the IEEE DASC Study Group on OO Extensions to VHDL, but does provide a basis for understanding OOP principles as applied to VHDL coding. Indeed, we will not be discussing object-oriented analysis and design or object-oriented hardware design until later articles in this series; in this article we address the fundemental questions: what is OOP? How will it effect my coding? What are the advantages?
Why object-oriented programming?
OOP has recently became a fashionable software paradigm. Historically, structured programming (as exemplified by the Algol family of languages, e.g., Pascal) has been the principle used to develop most software. The software community has been moving towards adopting the principles of OOP in order to enable inherently re-usable software components. Design re-use is now of interest to us all as a means of (ultimately) achieving shortest time-to-market. If we, as VHDL coders, can take advantage of the promise of OOP, there exists the real possibility that our hardware designs will be more re-usable than if we had used structured programming principles.
History has shown us that large software projects embodying the use of structured programming have failed (p. 160, Code Complete). The LRM essentially defines VHDL as a structured programming language. History has not yet shown us that OOP is a panacea for this ill!
OOP definition
Object-oriented programming embodies the three principles of encapsulation, polymorphism and inheritance. Let's define these three principles in more detail.
Encapsulation is the mechanism used for information hiding. Encpasulation allows access to the contents of a data structure only through function calls which operate on that data.
In VHDL, we can group a data structure and its associated functions in a package. However, a VHDL package is an abstract data type (ADT) when used in this way. VHDL does not support encapsulation through a package because the data structure is accessible without recourse to the packages functions. For example,
package unencapsulated_ADT is subtype index is integer range 0 to 31; type colour is (RED, YELLOW, GREEN, BLUE); type access_mode is (READ, WRITE); type super_colour is record index_element : index; colour_element : colour; end record; procedure set_colour_element ( super_colour_parameter: inout super_colour; colour_parameter: colour ); function get_colour_element ( super_colour_parameter: super_colour ) return colour; end unencapsulated_ADT; package body unencapsulated_ADT is procedure set_colour_element ( super_colour_parameter: inout super_colour; colour_parameter: colour ) is begin super_colour_parameter.colour_element := colour_parameter; end set_colour_element; function get_colour_element ( super_colour_parameter: super_colour ) return colour is begin return super_colour_parameter.colour_element; end get_colour_element; end unencapsulated_ADT;
In use, one would expect to see a process statement something like,
a_label: process (a_super_colour) variable a_colour: colour; begin a_colour := get_colour_element(a_super_colour); end process;
However, this relies on programmer discipline. The package does allow direct access to the variables data structure - this is not encapsulation. The following code snippett is an example of direct access,
b_label: process (sensitivity_list) use a_library.unencapsulated_ADT.all; variable a_colour: super_colour; begin a_colour.colour_element := RED; end process;
To extend the abstract data type (ADT) principle to encapsulation, the data structure declaration and its associated access functions need to be defined in a new kind of programming element, typically referred to as a class. The term class will be used throughout this article to denote a progamming element that contains both a data structure declaration and its associated functions. In VHDL, a package serves as such a programming element, notwithstanding its information hiding limitation. In object-oriented programming, an object is an instance of a class. We can draw a parallel between OOP and VHDL already in that a variable (or signal) is an instance of a type. If the declaration of this type occurs in a package along with functions applicable to that type, then in order to use VHDL variables as objects in an OOP sense, we need only make the contents of the package visible at the same level of scope as the variable. An example follows,
a_label: process (a_super_colour) use a_library.all; variable a_colour: unencapsulated_ADT.colour; begin a_colour := unencapsulated_ADT.get_colour_element(a_super_colour); end process;
Note that in the above code snippett, we have made the constructs a little verbose in order to show that the functions and data are declared in the same package. In use, however, ideal encapsulation is usually rather unwieldy. Imagine having to call a function every time you wished to alter the value of an element in a record variable! As a result, encapsulating the declaration of a type and its associated functions in a package is sufficient for real coding use. The loss of robustness through non-adherence to the information hiding principle seems worthwhile when compared to the advantage of code legibility as shown in the following example,
a_label: process (a_super_colour) variable a_colour: unencapsulated_class.colour; begin a_colour := a_super_colour.colour_element; end process;
Polymorphism
In VHDL jargon, we use the term "overloading" to describe the use of the same function name (or operator symbol) for different type-dependent purposes. For example, we could define two functions for the addition operator, in one case the function could accept integers as parameters, the other could accept colours. (Note that the integer addition operator is pre-defined). However, the parameter profiles for each function must be defined before the function is subsequently called in VHDL code. This compile-time overloading is static, whereas for true OOP, polymorphism allows for the use of the same function or operator name with different parameter profiles to be invoked at run-time; true polymorphism is dynamic.
For example, the LRM defines multiplication ("*") between two operands of any integer type. The following declaration overloads the * operator to allow for std_logic_vector types.
function "*" (a, b: std_logic_vector) return std_logic_vector;
Inheritance
Inheritance allows for the definition of a new class based on the definition of an existing class. The new class is said to be a derived class of the existing base class. A class may inherit both data and functions from its base class. Thus inheritance allows us to build on code that is already written; inheritance inherently supports design re-use. In the following pseudo-code snippett, we see how inheritance may manifest itself:
-- pseudo code, not VHDL! class derived_class uses unencapsulated_ADT is record colour_plus uses super_colour with third_element_name : a_type; fourth_element_name : b_type; end record; function get_third_element (formal: colour_plus) return a_type; end;
Note that through class inheritance, the objects of the derived class can use base class (unencapsulated_ADT) functions and types without further definition. Let's look at how inheritence could be mimicked in VHDL. We will use our existing super_colour record and derive the colour_plus record and its associated functions,
type super_colour is record index_element : index; colour_element : colour; end record;
This allows for simple extension of the capabilities of an existing class to a new more powerful class. The simplest mechanism that VHDL could use to allow inheritance is the package:
package derived_class is type colour_plus is record colour_class : super_colour; third_element_name : a_type; fourth_element_name : b_type; end record; function get_third_element (formal: colour_plus) return a_type; function get_index_element (formal: super_colour) return index; end derived_class;
In this example, we see the limitation of using a VHDL package to mimic class capability; get_index_element is re-declared.
Thus the obvious difference between a class and a package masquerading as a class is that in the class the data definition and the function definition are bound together in the declaration of the class. The data-function binding is said to be tight. However, in a VHDL package, the data-function binding is loose, because the type definition can be made visible through a use clause without making the functions visible. For example,
c_label: process (a_super_colour) use a_library.all; variable a_colour: unencapsulated_ADT.colour; begin a_colour := RED; end process;
A more serious ramification of loose data-function binding is that functions are not inherited; they must be re-declared or referenced via the "base class" package. In VHDL, we can only really obtain an extension to the data structure rather than true inheritance.
OOP in use
Given the three key elements of OOP, we note that VHDL is found wanting in all three areas. Encapsulation as an ideal is not currently supported by VHDL, but then again, the definition of an ADT is likely to be sufficient for real coding usage (let's be pragmatic!). Polymorphism as a dynamic function invocation mechanism is not supported either, but here again, the use of the static overloading is sufficient for real coding usage. Also, we note that VHDL does not provide a simple inheritance mechanism. Inheritance is key to design re-use, so this is one area of the VHDL language definition that needs to be addressed if OOVHDL is to become a reality.
More OOP
In the next article in this series, I will look in more detail at the use of an object-oriented approach to VHDL as well as some of the necessary language extensions that would result in VHDL being a language able to offer true OOP.
References:
Code Complete, Steve McConnell, Microsoft Press, 1993.
The C++ Programming Language, Bjarne Stroustrup, Addison-Wesley,
1991.
VHDL FAQ
Doulos Training Courses
Copyright 1995-1996 Doulos
This page was last updated 10th February 1996.
We welcome your e-mail comments. Please contact us at: webmaster@doulos.co.uk