Тип данных enum в SystemVerilog
Если переменная имеет ограниченное число возможных значений, то иногда удобно присвоить этим значениям символьные имена. Распространенный пример – имена состояний автомата (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:
- first() – возвращает первое значение переменной типа enum
- last() – возвращает последнее значение переменной типа enum
- next() – возвращает i-e следующее по счету значение переменной, отсчитанное от текущего значения (по умолчанию возвращает просто следующее значение)
- prev() – возвращает i-e предыдущее по счету значение переменной, отсчитанное от текущего значения (по умолчанию возвращает просто предыдущее значение)
- 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;