SV - Structures and Unions


Structures

A structure represents a collection of data types that can be referenced as a whole, or the individual data types that make up the structure can be referenced by name.

By default, structures are unpacked, meaning that there is an implementation-dependent packing of the data types. Unpacked structures can contain any data type.

Examples of declaring structures are as follows:

                          
Packed Structures

A packed structure is a mechanism for subdividing a vector into subfields, which can be conveniently accessed as members.

Consequently, a packed structure consists of bit fields, which are packed together in memory without gaps.

A packed structure differs from an unpacked structure in that, when a packed structure appears as a primary, it shall be treated as a single vector.

NOTE : Only packed data types and the integer data types are legal in packed structures.
Few things to note related to packed structures :
  • If all data types within a packed structure are 2-state, the structure as a whole is treated as a 2-state vector.
  • If any data type within a packed structure is 4-state, the structure as a whole is treated as a 4-state vector. If there are also 2-state members in the structure, there is an implicit conversion from 4-state to 2-state when reading those members and from 2-state to 4-state when writing them.
  • One or more bits of a packed structure can be selected as if it were a packed array with the range [n-1 : 0]:

Refer below example for declaring a packed structure :

                          
Nested Structures

System Verilog also allows for structures to be nested. Refer example below :

                          

Code Output :

                          
Signed and Unsigned Packed Structures

A packed structure can also be used as a whole with arithmetic and logical operators, and its behavior is determined by its signedness, with unsigned being the default. The first member specified is the most significant and subsequent members follow in decreasing significance.

Refer below example for declaring a signed packed structure :

                          
Assigning to Structures

A structure can be assigned as a whole and passed to or from a subroutine as a whole.

Members of a structure data type can be assigned individual default member values by using an initial assignment with the declaration of each member. The assigned expression shall be a constant expression.

An example of initializing members of a structure type is as follows :

                          

Code Output :

                          

Unions

System Verilog adds C-like unions to Verilog.

A union is a data type that represents a single piece of storage that can be accessed using one of the named member data types. Only one of the data types in the union can be used at a time. By default, a union is unpacked, meaning there is no required representation for how members of the union are stored. Dynamic types and chandle types can only be used in tagged unions (discussed later).

A union is a single storage element that can have multiple representations. Each representation of the storage can be a different type.

The declaration syntax for a union is similar to a structure :

                          

Refer below example of using unions :

                          

Code Output :

                          
NOTE : unions can also contain structures, and structures can also contain unions.
Tagged Unions

The qualifier 'tagged' in a union declares it as a tagged union, which is a type-checked union.

An ordinary (untagged) union can be updated using a value of one member type and read as a value of another member type, which is a potential type loophole.

A tagged union stores both the member value and a tag, i.e., additional bits representing the current member name. The tag and value can only be updated together consistently using a statically type-checked tagged union expression.

NOTE : The member value can only be read with a type that is consistent with the current tag value (i.e., member name). Thus, it is impossible to store a value of one type and (mis)interpret the bits as another type.

Refer below example of declaring a tagged union :

                          
Packed Unions

Packed Unions shall only contain members that are of integral data types.

NOTE : The members of a packed untagged union shall all be the same size (in contrast to an unpacked union or a packed tagged union, where the members can be different sizes).

Refer below example of packed union :

                          

Similar to packed structures, A packed union can also be used as a whole with arithmetic and logical operators, and its behavior is determined by its signedness, with unsigned being the default. One or more bits of a packed union can be selected as if it were a packed array with the range [ n-1 : 0 ].