Logo

Enumeration in system verilog

20 May 2022
4 mins

Enumeration, commonly called Enum, is a special data type introduced in System Verilog. This data type is a user-defined data type which means that a new data type can be created using Enum. In this article, we will learn about Enums and see how these are beneficial in writing complex code.

What is Enumeration?

Enumeration/Enum is a data type which assigns names to the integer constants. These are used to simplify the code and make it easier to read and manage. Also, Enum is synthesizable in System Verilog and thus can be used for design as well as test bench code.

Syntax

enum <data-type> {<elements>} <name>; 

enum {IDLE, SETUP, ACCESS} state; // example 1
enum bit[1:0] {IDLE, SETUP, ACCESS} state; // example 2

In the above example, the Enum type state has 3 elements, IDLE, SETUP and ACCESS. By default, the first element is Enum gets the value of 0 and the value increments for other following elements. Values can be manually assigned to Enum elements as shown below. If the value is only defined for the first element, the following elements get incremented value unless otherwise stated.

enum {IDLE=6, SETUP, ACCESS} state; // example 3 - IDLE=6, SETUP=7, ACCESS=8
enum {IDLE=6, SETUP=9, ACCESS} state; // example 3 - IDLE=6, SETUP=9, ACCESS=10
enum {IDLE=6, SETUP=9, ACCESS=14} state; // example 4 - IDLE=6, SETUP=9, ACCESS=14

Some important points

Below are some important points which should be kept in mind while working with Enums.

  1. Enums can be used as a data type only when the typedef keyword is used to define the enum. Otherwise, it’s a simple variable.
  2. Elements defined inside Enum can be referenced directly. It will return the value that it holds.
  3. Elements having the same name cannot be defined inside 2 different enums. It is because the element of an enum has visibility in the entire block inside which the enum is defined.
enum bit[2:0] { RED , BLUE } color_1;
enum bit[2:0] { RED , GREEN } color_2; // Will show error
enum bit[2:0] { VOILET , GREEN } color_2; // Will work fine
  1. If the value for an element is not mentioned explicitly it will automatically take the incremented value of the previous element for which the value is mentioned.

Use case

Enum is synthesizable in System Verilog and thus can be used both in design and test bench. One of the most common uses of Enum is to define the different states for an FSM (finite state machine). In Verilog we can define the states using parameters. But the disadvantage of this method is that it does not improve readability and often makes the code more complex.

In test benches, Enums can be used to create knobs for configuring the test bench. The use of enums in test benches will be discussed in later parts where we will discuss test benches.

Example

In the example below, we are defining the states using Enum. This state data type is then used in the FSM logic. We see that using Enums makes the code easier to read and manage.

module enum_state(input clk, resetn, enable);
    typedef enum reg[1:0] { IDLE, SETUP, ACCESS } state;
    state cur_state, nxt_state;

    always @(posedge clk) begin
        if(!resetn) begin
            cur_state <= IDLE;
        end
        else begin
            $display("%0t Switching to %s...", $time(), nxt_state.name());
            cur_state <= nxt_state;
        end
    end

    always @(*) begin
        case (cur_state)
            IDLE:
            begin
                $display("IDLE state");
                if(enable)
                    nxt_state = SETUP;
            end
            SETUP:
            begin
                $display("SETUP state");
                if(enable)
                    nxt_state = ACCESS;
            end
            ACCESS:
            begin
                $display("ACCESS state");
                if(enable)
                    nxt_state = IDLE;
            end
        endcase
    end
endmodule

module tb();
    bit clk, resetn, enable;
    enum_state dut(clk, resetn, enable);

    initial begin
        forever #10 clk = ~clk;
    end

    initial begin
        resetn = 0;
        enable = 0;
        #40 resetn = 1;
        enable = 1;
    end
endmodule
Output
# IDLE state
# IDLE state
# 50 Switching to SETUP...
# SETUP state
# 70 Switching to ACCESS...
# ACCESS state
# 90 Switching to IDLE...
# IDLE state
# 110 Switching to SETUP...
# SETUP state
# 130 Switching to ACCESS...
# ACCESS state
# 150 Switching to IDLE...
# IDLE state
# 170 Switching to SETUP...
# SETUP state
Try this code in EDA Playground

Enumeration Methods

Enum provides various in-built system functions that can be used to iterate within elements of the Enum. Let’s see these in-built functions in detail.

  1. first() – return the value of the first element of the Enum
  2. last() – returns the value of the last element of the Enum
  3. prev(int N) – returns the value of the Nth element before the current element of Enum
  4. next(int N) – returns the value of the Nth element after the current element of Enum
  5. num() – returns the number of element in the Enum
  6. name() – returns the name of the element

Example

module enum1();
    typedef enum bit[4:0] { Violet, Indigo, Blue, Green, Yellow, Orange, Red } color_e;
    color_e color;
    int i, n;
    initial begin
        $display("First element is %0d and its name is %s", color.first(), color.first().name());
        $display("Last element is %0d and its name is %s", color.last(), color.last().name());

        n = color.num();
        for (i=1; i<n; ++i) begin
            color = color.next();
            $display("Element no %0d is %s", color, color.name());
        end
        color = color.prev(3);
        $display("Third Element from the last element is %s", color.name());
    end
endmodule
Output
# First element is 0 and its name is Violet
# Last element is 6 and its name is Red
# Element no 1 is Indigo
# Element no 2 is Blue
# Element no 3 is Green
# Element no 4 is Yellow
# Element no 5 is Orange
# Element no 6 is Red
# Third Element from the last element is Green

Enum named ranges

In SV Enum, there are various shorthand to define the elements inside an Enum. If we want to define multiple elements having same name and appended by different number, like, state1, state2, state3, … these name ranges come in handy. Different ways to use named ranges are shown below.

  1. name[n] – makes N elements with starting element as name[0] having value 0 and last element as name[n-1] and value as n-1.
  2. name[M:N] - makes N elements with starting element as name[M] having value 0 and last element as name[N-M-1] and value as N-M-1.
Please note that while using named ranges we cannot specify any explicit values. That is name[M:N] = A, won’t generate the correct output. Although this is correct in terms of syntax, but many simulators do not generate the intended output

Example

module enum2();
    enum bit[3:0] { state[8] } state_1;
    enum bit[3:0] { state[8:15] } state_2;

    int n1, n2, i;
    initial begin
        n1 = state_1.num();
        $display("Elements of state_1");
        for(i=0; i< n1; i++) begin
            $display("Element no %0d is %s and its value is %0d", i, state_1.name(), state_1);
            state_1 = state_1.next();
        end

        n2 = state_2.num();
        $display("\nElements of state_2");
        for(i=0; i< n2; i++) begin
            $display("Element no %0d is %s and its value is %0d", i, state_2.name(), state_2);
            state_2 = state_2.next();
        end
    end
endmodule
Output
# Elements of state_1
# Element no 0 is state0 and its value is 0
# Element no 1 is state1 and its value is 1
# Element no 2 is state2 and its value is 2
# Element no 3 is state3 and its value is 3
# Element no 4 is state4 and its value is 4
# Element no 5 is state5 and its value is 5
# Element no 6 is state6 and its value is 6
# Element no 7 is state7 and its value is 7
# 
# Elements of state_2
# Element no 0 is state8 and its value is 0
# Element no 1 is state9 and its value is 1
# Element no 2 is state10 and its value is 2
# Element no 3 is state11 and its value is 3
# Element no 4 is state12 and its value is 4
# Element no 5 is state13 and its value is 5
# Element no 6 is state14 and its value is 6
# Element no 7 is state15 and its value is 7
Try this code in EDA Playground