Если переменная имеет ограниченное число возможных значений, то иногда удобно присвоить этим значениям символьные имена. Распространенный пример - имена состояний автомата (IDLE, REQ, RESP и т.д.), которые в символьном виде делают код более читабельным. Если в Verilog присвоить символьные имена можно было с помощью параметров или дефайнов, то в SystemVerilog для этого был введен специальный тип данных enum. Состояния автомата с помощью этого типа можно описать следующим образом:

enum {IDLE,REQ,RESP} states;

В этом примере создается тип данных states. Переменные этого типа могут принимать только значения, указанные в фигурных скобках (IDLE, REQ и RESP). Если попытаться присвоить переменной типа states значение, которое не было указано в фигурных скобках, то возникнет ошибка. Тип данных enum является жестко типизированным.

По умолчанию значения в фигурных скобках будут типа int. В предыдущем примере IDLE=0, REQ=1, RESP=2. Эти значения можно выводить на печать как в числовом, так и в символьном формате.

Можно явно присваивать значения символьным именам. Если значение не задано явно, то будет присвоено увеличенное на 1 предыдущее значение. Значение первого символьного имени по умолчанию равно 0.

// символьному имени 'c' автоматически присвоится значение 6
enum {a=3, b=5, c} operands;
    
// Синтаксическая ошибка: 'c' и 'd' имеют значение 8
enum {a=0, b=7, c, d=8} operands;
    
// a=0, b=7, c=8
enum {a, b=7, c} operands;

Методы для работы с переменными типа enum

В SV есть несколько методов, которые упрощают обращение к значениям переменной типа enum:

  1. first() - возвращает первое значение переменной типа enum
  2. last() - возвращает последнее значение переменной типа enum
  3. next() - возвращает i-e следующее по счету значение переменной, отсчитанное от текущего значения (по умолчанию возвращает просто следующее значение)
  4. prev() - возвращает i-e предыдущее по счету значение переменной, отсчитанное от текущего значения (по умолчанию возвращает просто предыдущее значение)
  5. name() - возвращает символьное отображение значения переменной типа enum. Если значение не определено для данного типа, то метод name() вернет пустую строку

Примеры:

module enum_methods;
   typedef enum {red,blue,green} e_color;
   e_color color;
   initial
   begin
	  color = color.first();
	  $display(" %s ",color.name);
	  color = color.next();
	  $display(" %s ",color.name);
	  color = color.last();
	  $display(" %s ",color.name);
	  color = color.prev();
	  $display(" %s ",color.name);
   end
endmodule

Результаты:

 red
 blue
 green
 blue

Переменные типа enum в численных выражениях

Элементы переменных типа enum могут использоваться в численных выражениях. В выражениях действия выполняются над числовыми значениями соответствующих символьных отображений.

Используемая в выражении переменная типа enum или идентификатор автоматически приводятся к базовому типу (заданному или типу по умолчанию int). Если тип выражения отличается от типа участвующих в нем переменных, может потребоваться приведение типов.

Примеры:

module enum_methods;
typedef enum {red,blue,green} e_color;
e_color c,d;
int i;
	initial
	begin
		$display("%s",c.name());
		d = c;
		$display("%s",d.name());
		d = e_color'(c + 1); // приведение к типу e_color
		$display("%s",d.name());
		i = d; // автоматическое приведение
		$display("%0d",i);
		c = e_color'(i);
		$display("%s",c.name());
	end
endmodule

Результаты:

red
red
blue
1
blue
Если требуется определить в типе enum значения X и Z, то необходимо явно указать тип данных с 4-мя состояниями:
enum integer {IDLE, XX='x, S1='b01, S2='b10} state, next;