3.12 Class
§ “An object can be declared as an argument of type input, output, inout, or, ref.“
§ input, outputs etc. are not types!
§
The comma after “or” is not needed. – Typo
Agreed. A correction in errata proposal is being prepared.
Change:
The object-oriented class extension allows objects to be
created and destroyed dynamically. Class instances, or objects, can be passed
around via object handles, which add a safe-pointer capability to the language.
An object can be declared as an argument of with direction type input, output, inout, or, ref. In each case, the argument copied is the object handle,
not the contents of the object.
4.2
Packed and unpacked array + 4.6 Dynamic array + 4.9 Associative arrays
§
Can an unpacked
array be declared with a basic type “dynamic array” etc.? Yes.
typedef int int_a
[8];
int_a k[];
int_a l[int];
typedef int
int_da [];
int_da m[8];
int_da n[];
int_da o[int];
typedef int int_aa
[int];
int_aa p[8];
int_aa q[];
int_aa r[int];
§
“SystemVerilog accepts
a single number (not a range) to specify the size of an unpacked array, like
C.”
§
Is this possible for unpacked arrays, only? Why
not for packed arrays?
The primary reason for providing the “short cut” of using a single number for the range was for convenience to those familiar with C (thereby the definition of the number represents the range from 0 to N). This was not extended to packed data types because for packed types the index direction is very important and a very common usage is to specify a range N:0, which is backwards from the C notation. Defining the order or the range with only the size specified differently for packed and unpacked would be confusing. Defining the order for packed arrays to be the same as for unpacked (and thereby 0:N) was considered confusing. To minimize the confusion (and possible unexpected behavior) the short cut was only defined for unpacked arrays.
No change.
5.3
Constants
· If a constant instance of a class references another object, can this object be changed?
Since the constant is the reference and not the class itself the
contents of the class can be changed (except for those members that are
declared const). In order to clarify
this in the LRM an errata proposal is being prepared.
Change:
This means that the object acts like a variable that cannot
be written. The arguments to the new method must be constant expressions. The members of the object can be written
(except for those members that are declared const).
10.5.2
·
If an instance
of a class (used as “const ref” parameter) references inside another object,
can this object be changed in the subroutine?
The const ref here
refers to the ability to pass a reference to an object handle which cannot be
changed. This is essentially the same as item 5.3 above.
No change.
11.3
Overview + 17.10 The property definition
·
The term
“property” is introduced twice into SystemVerilog for two different things!!
Agreed. The term is also used in a third way
within the LRM that does not refer to class properties or to the property keyword. An errata proposal is
being prepared.
Change:
Section
3.12
A class is a collection of data and a set of
subroutines that operate on that data. The data in a class is referred to as class properties, and its subroutines are called
methods. The class properties and methods, taken
together, define the contents and capabilities of a class instance or object.
Section
11.3
A class is a type that includes data and
subroutines (functions and tasks) that operate on that data. A class’s data is
referred to as class
properties, and its
subroutines are called methods, both are members of the class. The class properties and methods, taken together, define
the contents and capabilities of some kind of object.
Section 11.5
The data fields of an object can be used by qualifying class property names with an instance name. Using the
earlier example, the commands for the Packet object p can be used
as follows:
Section 11.6
An object’s methods can be accessed using the same syntax
used to access class properties:
Section 11.8
11.8 Static class
properties
The previous examples have only declared instance class properties. Each instance of the class (i.e.,
each object of type Packet), has its own
copy of each of its six variables. Sometimes only one version of a variable is
required to be shared by all instances. These class properties are created
using the keyword static. Thus, for
example, in a case where all instances of a class need access to a common file descriptor:
Section 11.9
Methods can be declared as static. A static method is subject
to all the class scoping and access rules, but behaves like a regular
subroutine that can be called outside the class, even with no class
instantiation. A static method has no access to non-static members (class properties or methods), but it can directly
access static class properties or call static methods of the same class. Access
to non-static members or to the special this handle within the body of a static
method is illegal and results in a compiler error. Static methods cannot be virtual.
Section 11.10
The this keyword is used to unambiguously
refer to class properties or methods of the
current instance. The this keyword denotes a predefined object handle
that refers to the object that was used to invoke the subroutine that this is used within. The
this keyword shall only be used within non-static class methods,
otherwise an error shall be issued. For example, the following declaration is a
common way to write an initialization task:
The x is now both
a property of the class and an argument to the function new. In the function new, an unqualified reference to x shall be resolved by looking at the
innermost scope, in this case the subroutine argument declaration. To access
the instance class property, it is qualified
with the this keyword, to refer to the current
instance.
Section 11.11
The last statement has new executing
a second time, thus creating a new object p2, whose class
properties are copied from p1. This is known as a shallow copy. All of
the variables are copied across: integers, strings, instance handles, etc.
Objects, however, are not copied, only their handles; as before, two names for
the same object have been created. This is true even if the class declaration
includes the instantiation operator new:
Several things are noteworthy. First, class properties and instantiated objects can be
initialized directly in a class declaration. Second, the shallow copy does not
copy objects. Third, instance qualifications can be chained as needed to reach
into objects or to reach through objects:
Section 11.12
To refer to a class property
of Packet, the
variable packet_c needs to be referenced.
Now, all of the methods and class
properties of Packet are part of LinkedPacket—as if they
were defined in LinkedPacket—and LinkedPacket
has
additional class properties and methods.
Section 11.13
In this case, references to p access
the methods and class properties of the Packet class. So, for example, if class properties and methods in LinkedPacket are overridden, these overridden members referred to through
p get the
original members in the Packet class. From p, new and all
overridden members in LinkedPacket
are
now hidden.
Section 11.17
So far, all class properties and methods have been made
available to the outside world without restriction. Often, it is desirable to
restrict access to class properties and methods
from outside the class by hiding their names. This keeps other programmers from
relying on a specific implementation, and it also protects against accidental
modifications to class properties that are
internal to the class. When all data becomes hidden—being accessed only by
public methods—testing and maintenance of the code becomes much easier.
In SystemVerilog, unqualified class
properties and methods are public, available to anyone who has access to the
object’s name.
A member identified as local is available only to methods
inside the class. Further, these local members are not visible within
subclasses. Of course, non-local methods that access local class properties or methods can be inherited, and work
properly as methods of the subclass.
A protected
class property or method has all of the characteristics of a local member, except that it can be
inherited; it is visible to subclasses.
Note that within the class, a local method or class property of the class can be referenced, even if
it is in a different instance. For example:
A strict interpretation of encapsulation might say that other.i should not be visible inside of this packet, since it is a
local class property being referenced from
outside its instance. Within the same class, however, these references are
allowed. In this case, this.i shall be
compared to other.i and the result of the logical comparison returned.
Class members can be identified as either local or protected; class
properties can be further defined as const, and methods
can be defined as virtual. There is
no predefined ordering for specifying these modifiers; however, they can only
appear once per member. It shall be an error to define members to be both local and protected, or to duplicate any of the
other modifiers.
Section 11.18
11.18 Constant Class Properties
Global constant class properties
are those that include an initial value as part of their declaration. They are
similar to other const
variables
in that they cannot be assigned a value anywhere other than in the declaration.
Section 11.21
Because classes and other scopes can have the same
identifiers, the scope resolution operator uniquely identifies a member of a
particular class. In addition, to disambiguating class scope identifiers, the :: operator also allows access to
static members (class properties and methods)
from outside the class, as well as access to public or protected elements of a
super-classes from within the derived classes.
The scope resolution operator enables:
— Access to static public members (methods and class properties) from outside the class hierarchy.
11.7
Constructors
·
Semantic of the
following example should be defined.
class
A ;
integer j = 5;
function new();
j = 3;
endfunction
endclass
Agreed. An errata proposal is being prepared.
Change:
Section 11.7
The new operation is defined as a function with no return
type, and like any other function, it must be nonblocking. Even though new does
not specify a return type, the left-hand side of the assignment determines the
return type.
Class properties that
include an initializer in their declaration are
initialized before the execution of the user-defined class constructor.
Thus, initializer values can be overriden
by the class constructor.
11.8
Class properties
·
It should be mentioned
that class properties can be used without any instance as in the example from
the LRM.
Packet p;
c = $fgetc(p.fileID );
Agreed. an errata
proposal is being prepared.
Change:
Section 11.8
Now, fileID shall be created
and initialized once. Thereafter, every Packet object can access the file
descriptor in the usual way:
Packet
p;
c = $fgetc( p.fileID );
Note that static
class properties can be used without creating an object of that type.
11.9
Static methods
·
Different
semantic of “static task” and “task static” is very confusing.
Yes, this can be confusing. In a future version it might be
considered to use another word (such as 'unique task' as an alias for 'static
task'). The other option might be to disallow 'task static' for class methods.
No errata proposal is being considered at this point.
No change.
11.19
Abstract classes
·
I suggest to
change the grammar that there is no “endfunction” in
the example:
virtual class BasePacket;
virtual protected function integer send(bit[31:0] data);
endfunction
endclass
Agreed. An errata proposal is being prepared.
Change:
Change BNF so that virtual
functions and tasks do not use endfunction/endtask.
Section 11.19
virtual class BasePacket;
virtual protected function integer send(bit[31:0] data);
endfunction
endclass
11.19
Abstract classes
·
According to the
LRM, non-abstract classes can have virtual methods (which must have a body).
What is the difference to a “normal,” non-virtual methods? If there is none,
they are not needed. As I know now:
Virtual methods are a basic polymorphic construct. A virtual
method overrides a method in all the base classes, whereas a normal method only
overrides a method in that class and its descendants. One way to view this is
that there is only one implementation of a virtual method per class hierarchy,
and it is always the one in the latest derived class.
This
is a very important info and should be inserted in the LRM in any case!
Agreed. An errata proposal is being prepared.
Change:
Section 11.19
Abstract classes can also have virtual methods. Virtual methods are a basic polymorphic
construct. A virtual method overrides a method in all the base classes, whereas
a normal method only overrides a method in that class and its descendants. One
way to view this is that there is only one implementation of a virtual method
per class hierarchy, and it is always the one in the latest derived class.
Virtual
methods provide prototypes for subroutines, all of the information generally
found on the first line of a method declaration: the encapsulation criteria,
the type and number of arguments, and the return type if it is needed. Later,
when subclasses override virtual methods, they must follow the prototype
exactly. Thus, all versions of the virtual method look identical in all
subclasses:
11.20
Polymorphism
·
The method call
“send” in the example can not be used if it is assumed a method from the
example in 11.18 is called because they are protected. If there is no
connection between the examples of the subsections, then the classes must be
defined.
·
Otherwise, the
names of the classes are identical with the classes in the previous subsection.
In addition they all have the method “send”, so every reader would assume that
the used classes “BasePacket”, “EtherPacket”
are the classes defined in the subsection before. But here “send” is defined as
“protected”. So the only change, which is needed, is the removing of the
keyword “protected” in the declaration of “send” in 11.19.
Agreed. An errata proposal is being prepared.
Change:
Section 11.19
virtual class BasePacket;
virtual protected function integer
send(bit[31:0] data);
endfunction
endclass
class EtherPacket
extends BasePacket;
protected function integer send(bit[31:0]
data);
// body
of the function
...
endfunction
endclass
11.22
Out-of-block declaration (please note the orthography)
·
The location,
where the out-of-block declarations have to be, must be declared.
Agreed. An errata proposal is being prepared.
Change:
Section 11.22
The out of block method declaration
must match the prototype declaration exactly; the only syntactical difference
is that the method name is preceded by the class name and scope operator (::).
Out of block declarations must be declared in the same scope as the
class declaration.
12.5.2
Random Constraints
·
Only here the
term “overload” is used (twice). Does this means the same as “override”?
Definition is needed!!
Agreed. An errata proposal is being prepared.
Change (to match V2K):
Section 12.2
Occasionally, it is desirable to perform operations
immediately before or after randomization. That is accomplished via two
built-in methods, pre_randomize() and
post_randomize(), which are automatically called
before and after randomization. These methods can be overridden
overloaded with the desired functionality:
By default, pre_randomize() and post_randomize() call their overridden
overloaded parent class methods. When pre_randomize() or post_randomize() are overridden
overloaded, care must be taken to invoke the parent class’
methods, unless the class is a base class (has no parent class), otherwise the
base class methods shall not be called.
Section 12.5.2
Users can override overload the pre_randomize() in any class to perform
initialization and set pre-conditions before the object is randomized.
Users can override overload the post_randomize() in any class to perform cleanup,
print diagnostics, and check post-conditions after the object is randomized.
If these methods are overridden overloaded,
they must call their associated parent class methods, otherwise their pre- and
post-randomization processing steps shall be skipped.
Section 12.5.3
— The randomize() method shall
not be overridden overloaded.
13.2.1
new() (Semaphores)
·
One sensible
enhancement would be to define a maximal number of keys in the semaphores to
avoid programming mistakes, which can happen very easily (e.g., a process puts
two keys back instead of one so that two processes can get a key).
A suggested way to handle this is to create a derived class that
implements the desired functionality. This is one of the advantages of defining
Semaphores as a class.
No Change.
13.2.3 get() (Semaphores)
· “If the specified number of key are not available, the process blocks until the keys become available.”
·
It should be
defined, when exactly get() will continue after
blocking. In the same time step ….
It unblocks as any other event control waiting on a signal. No errata
proposal is being prepared.
No Change.
14.2 Event simulation
·
Maybe, the
special handling of always_comb etc. should be
mentioned here.
Agreed. An errata proposal is being prepared.
Change:
Section 14.2
A SystemVerilog description consists of connected threads of
execution or processes. Processes are objects that can be evaluated, that can
have state, and that can respond to changes on their inputs to produce outputs.
Processes are concurrently scheduled elements, such as initial blocks. Example of processes
include, but are not limited to, primitives, initial, and always, always_comb, always_latch, and always_ff procedural blocks, continuous
assignments, asynchronous tasks, and procedural assignment statements.
14.3.1
The SystemVerilog simulation reference algorithm
·
Initialization
of consts are missing
·
What is the
initialization order in case of dependent initialization?
The missing item here is that consts are variables and are
handled the same. The ordering issue exists for variables that aren’t const as well. An errata proposal is
being prepared.
Change:
Section 5.3
Constants are named data variables items
which never change. There are three kinds of constants, declared with the
keywords localparam, specparam and const, respectively. All three can be
initialized with a literal.
19.5.3
An example of exporting tasks and functions
The tasks Read and Write
are used (declared, defined, called) four times each. Sometimes they have one
parameter, sometimes none. I assume that the slave defines the tasks and made
them available via “export”. It seems, the master want
to use exactly these tasks because the tasks with parameters are not defined in
the interface, and in the master module (cpuMod), the
comment describes explicitly the use of the slave method--but the call is made
with a parameter!!
The root of this confusion appears to stem
from the fact that exported tasks do not require complete prototype (as defined
in pg. 213 In a modport, the import and export constructs
can either use task or function prototypes or use just the identifiers. The
only exception is when a modport is used to import a
function or task from another module, in which case a full prototype shall be
used.). This can result in the same task being declared in different ways
depending on the context.
No Change.