From SystemVerilog_Wiki

Jump to: navigation, search


Declaring an enum

Much like C/C++, the enum construct in SystemVerilog, provides a way to declare a strongly typed integral type, which is a subtype of the base integral type (defaults to int). Enumerated variables that can take only one of values amongst those specified in the enum declaration.

enum {RED, GREEN, BLUE} color1, color2;

The above declaration does two things. It defines RED, GREEN, and BLUE as constants with values 0, 1, and 2 respectively. It also declares variables color1 and color2. These variables are strongly typed and can take only 0, 1, or 2 as their values.

Additionally, SystemVerilog allows the user to define the base type of the enum and the base type can be either a two-state or four-state integral type. Note that C/C++ does not let the user specify the base type and the base type is always fixed to int.

enum bit [1:0] {RED, GREEN, BLUE} color1, color2;
// four state enumeration
enum logic [1:0] {IDLE, UNKNOWN=`x, TRISTATE=`z, S1=2`b01, S2=2`b10} state, next;

In practice the enum keyword is almost always used in conjunction with typedef.

typedef enum {RED, GREEN, BLUE} BasicColors;

It is possible to automatically define an indexed range of enumeration elements using name[N] or name[N:M]. The following table lists the various forms in which enumeration elements can be specified:

Specifying Enumeration Elements
Syntax Implication
name Incrementally associates the name with the next consecutive integral value
name = C Associates the given constant value C with the name
name[N] Associates the sequence name0..nameN to consecutive integral values
name[N] = C Same as above, but starts the name0 association with the constant value C
name[N:M] Associate sequence nameN..nameM, N could be greater or smaller than M
name[N:M] = C Same as above, but starts the name0 association with the constant value C

Since enumerations are integral types, SystemVerilog allows enum variables to be declared as rand/randc. When declaring an enum variable as randc, it might be more efficient to limit the number of bits in the base type of the enum declaration<ref>Srinivas Venkataraman, VerificationOnWeb (VoW), 2009, "SystemVerilog tip: watch out enum and randc", accessed on 08-AUG-2010</ref>.

Down-Casting Integral types to Enumerations

Enumerations are strongly typed. Thereby, a variable of an enum type can not be assigned from another integral type without (static or dynamic) casting. Static casting operation does not check whether the assigned value is within the range of the enumerated type. Unless sure that the assigned value is within the range, one should use dynamic cast operation to stuff value into a variable of enumerated type.

typedef enum {MON, TUE, WED, THU, FRI, SAT, SUN} Weekday;

Weekday day1 = WED;  // no type conversion required
day1 = 2;            // illegal type conversion
day1 = Weekday`2;    // OK
day1 = Weekday'10;   // legal out of range assignment forced by static cast
if (! $cast(day1, 10))  // legal dynamic cast operation that would FAIL
   $display("Dynamic cast operation FAILED");

Up-Casting Enumerated variables to Integral Types

Inter-operations between Enumerations and generic integral types are allowed and no special syntax is usually involved. Variables of Enumerated types are automatically up-casted to other integral types whenever such an operation is required.

Methods associated with Enumerated Types

Enumeration Methods
Name Explanation Remarks
first() Returns the first value in the enumerated type
last() Returns the last value in the enumerated type
next(int N=1) Increment the value of the variable by N places within the enumerated type If the resulting type falls out of range, the first value would be returned
prev(int N=1) Decrement the value of the variable by N places within the enumerated type
num() Returns the number of elements in the enumerated type
name() Returns the value of the variable as string

The name() method is particularly useful when printing debug messages involving enumerated variables: