SystemVerilog Enumerations Data Type: A Beginner's Guide

If you're new to SystemVerilog, you may have heard of an "enumeration" or "enum" data type. In this blog post, we'll cover the basics of SystemVerilog enumerations, including their syntax, uses, and methods.

What is an Enumeration Data Type?

An enumeration is a data type that allows you to define a set of named values. Each value in the set is assigned an integer value, starting from zero and increasing by one for each subsequent value. For example, here's how you could define an enumeration for the four cardinal directions:

typedef enum { North, East, South, West } Direction;

In this example, North is assigned a value of 0, East is assigned a value of 1, and so on.

Syntax for Enumerations

Here's the general syntax for defining an enumeration in SystemVerilog:

enum {
  Member1,
  Member2,
  Member3
} EnumName;

Each member in the enumeration is separated by a comma. You can also assign a specific value to a member by using the syntax Name = Value. For example:

typedef enum { Red = 1, Green = 2, Blue = 4 } Color;

In this example, Red is assigned a value of 1, Green is assigned a value of 2, and Blue is assigned a value of 4.

Enumerated Type Ranges

You can define a range of members in an enumeration using the following syntax:

enum {
  Name[N],       // N named constants: Name0, Name1, ..., NameN-1
  Name[N] = C,   // assign C to the first generated constant
  Name[N:M],     // NameN to NameM, increment or decrement
  Name[N:M] = C, // assign C to the first generated constant in range
} EnumName;
  • Name[N] creates N named constants of the form Name0, Name1, ..., NameN-1.
  • Name[N] = C assigns the constant C to the first generated constant (Name0).
  • Name[N:M] creates members NameN through NameM, incrementing or decrementing the value for each member in consecutive order.
  • Name[N:M] = C assigns the constant C to the first generated constant in the range (NameN).

Here's an example of how to use enumerated type ranges:

enum {
  One, Two, Three,
  Four[2],        // creates Four0 and Four1
  Five[2] = 5,    // creates Five0 = 5 and Five1 = 6
  Six[4:6],       // creates Six4, Six5, and Six6 in that order
  Seven[4:6] = 7, // creates Seven4 = 7, Seven5 = 8, and Seven6 = 9
} MyEnum;

In this example, One, Two, and Three are members with consecutive values of 0, 1, and 2, respectively. Four[2] creates two members, Four0 and Four1. Five[2] creates two members, Five0 with a value of 5 and Five1 with a value of 6. Six[4:6] creates three members, Six4, Six5, and Six6 in that order. Seven[4:6] creates three members, Seven4 with a value of 7, Seven5 with a value of 8, and Seven6 with a value of 9.

Assigning Values to Enumerations

When assigning a value to an enumeration, it's important to remember that SystemVerilog is strongly typed. This means that you cannot assign a value outside of the range of the enumeration without an explicit cast. For example:

Color myColor = 5;         // This will result in a compilation error
Color myColor = Color'(5); // This will cast the integer value 5 to the Color enumeration

Enumeration Methods

SystemVerilog provides several built-in methods for working with enumerations. Here are some of the most commonly used methods:

  • first(): This function returns the value of the first member in the enumeration.
  • last(): This function returns the value of the last member in the enumeration.
  • next(N): This function returns the N-th next member in the enumeration. If N is not specified, it defaults to 1.
  • prev(N): This function returns the N-th previous member in the enumeration. If N is not specified, it defaults to 1.
  • num(): This function returns the number of members in the enumeration.
  • name(): This function returns the name of the current member as a string.

Here's an example of how to use these methods:

typedef enum { Mon = 1, Tue, Wed, Thu, Fri } Day;

initial begin
  Day myDay = Mon;
  $display("First day of the week is %0s", myDay.first().name());
  $display("Last day of the week is %0s", myDay.last().name());
  $display("The next day after %0s is %0s", myDay.name(), myDay.next().name());
  $display("The day after that is %0s", myDay.next(2).name());
  $display("The previous day before %0s is %0s", myDay.name(), myDay.prev().name());
  $display("The day before that is %0s", myDay.prev(2).name());
  $display("There are %0d days in the week", myDay.num());
end

In this example, the output will be:

First day of the week is Mon
Last day of the week is Fri
The next day after Mon is Tue
The day after that is Wed
The previous day before Mon is Fri
The day before that is Thu
There are 5 days in the week

Conclusion

In conclusion, SystemVerilog enumerations are a powerful data type that allow you to define sets of named values. With the ability to assign specific values to members, define ranges, and use built-in methods, enumerations provide a flexible and convenient way to represent data in your SystemVerilog code. So next time you need to define a set of related values, consider using an enumeration!