枚举(Enumeration)类型定义了一组命名值。 在下面的示例中,light_ *是一个枚举变量,可以存储三个可能值(0、1、2)之一。 默认情况下,枚举列表中的名字获得值0,随后的名字获得增量值,例如1和2。
enum {RED, YELLOW, GREEN} light_1; // int type; RED = 0, YELLOW = 1, GREEN = 2
enum bit[1:0] {RED, YELLOW, GREEN} light_2; // bit type; RED = 0, YELLOW = 1, GREEN = 2
用户可以为任何枚举名称分配任何整数值。 如果任何名称都没有分配的值,那么它将自动采用前一个名称的递增值。
enum {RED=3, YELLOW, GREEN} light_3; // RED = 3, YELLOW = 4, GREEN = 5
enum {RED = 4, YELLOW = 9, GREEN} light_4; // RED = 4, YELLOW = 9, GREEN = 10 (自动分配)
enum {RED = 2, YELLOW, GREEN = 3} light_5; // Error : YELLOW and GREEN are both assigned 3
enum bit[0:0] {RED, YELLOW, GREEN} light_6; // Error: minimum 2 bits are required(至少需要2位)
注意:枚举变量不能以数字开始
enum {1WAY, 2TIMES, SIXPACK=6} e_formula; // Compilation error on 1WAY, 2TIMES
enum {ONEWAY, TIMES2, SIXPACK=6} e_formula; // Correct way -> change 1 to ONE, 2 to TWO, etc
如何定义一个新的枚举数据类型?
可以创建自定义数据类型,以便可以使用相同的数据类型声明其他变量。
module tb;
// 新创建"e_true_false" 是具有两个有效值的新数据类型: TRUE and FALSE
typedef enum {TRUE, FALSE} e_true_false;
initial begin
// 声明类型为“ e_true_false”的变量,该变量可以存储TRUE或FALSE
e_true_false answer;
// 将TRUE / FALSE分配给枚举变量
answer = TRUE;
// 显示变量的字符串值
$display ("answer = %s", answer.name);
end
endmodule
Simulation Log
ncsim> run
answer = TRUE
ncsim: *W,RNQUIE: Simulation is complete.
为什么我们需要枚举?
使代码更简单易读。 考虑下面的示例,但不进行枚举。
bit [1:0] light;
light = 2'b00; // 假设00代表红色
// 在多行代码之后,我们必须关联00代表什么-是红色,黄色还是绿色?
if (light == 2'b00)
// Do something
由于枚举名称RED,YELLOW和GREEN,以下代码更易读。
typedef enum {RED, YELLOW, GREEN} e_light;
e_light light;
light = RED; //将light初始化为red
if (light == RED)
// Do something
枚举类型范围
name | 下一个数字将与姓名相关联 |
---|---|
name = C | 将常量C与名称关联 |
name[N] | 生成N个命名常量:name0,name1,…,nameN-1 |
– | – |
name[N] = C | 第一个命名常量获取值C,随后的常量与后续值关联 |
name[N:M] | 第一个命名常量为nameN,最后一个命名常量nameM,其中N和M为整数 |
– | – |
name[N:M] = C | 第一个命名常量,nameN将获得C,随后的常量将与连续值关联,直到nameM |
例
在下面的示例中,我们将尝试上表中显示的每种不同样式。
module tb;
// name : The next number will be associated with name starting from 0
// GREEN = 0, YELLOW = 1, RED = 2, BLUE = 3
typedef enum {GREEN, YELLOW, RED, BLUE} color_set_1;
// name = C : Associates the constant C to name
// MAGENTA = 2, VIOLET = 7, PURPLE = 8, PINK = 9
typedef enum {MAGENTA=2, VIOLET=7, PURPLE, PINK} color_set_2;
// name[N] : Generates N named constants : name0, name1, ..., nameN-1
// BLACK0 = 0, BLACK1 = 1, BLACK2 = 2, BLACK3 = 3
typedef enum {BLACK[4]} color_set_3;
// name[N] = C : First named constant gets value C and subsequent ones
// are associated to consecutive values
// RED0 = 5, RED1 = 6, RED2 = 7
typedef enum {RED[3] = 5} color_set_4;
// name[N:M] : First named constant will be nameN and last named
// constant nameM, where N and M are integers
// YELLOW3 = 0, YELLOW4 = 1, YELLOW5 = 2
typedef enum {YELLOW[3:5]} color_set_5;
// name[N:M] = C : First named constant, nameN will get C and
// subsequent ones are associated to consecutive values until nameM
// WHITE3 = 4, WHITE4 = 5, WHITE5 = 6
typedef enum {WHITE[3:5] = 4} color_set_6;
initial begin
// Create new variables for each enumeration style
color_set_1 color1;
color_set_2 color2;
color_set_3 color3;
color_set_4 color4;
color_set_5 color5;
color_set_6 color6;
color1 = YELLOW; $display ("color1 = %0d, name = %s", color1, color1.name());
color2 = PURPLE; $display ("color2 = %0d, name = %s", color2, color2.name());
color3 = BLACK3; $display ("color3 = %0d, name = %s", color3, color3.name());
color4 = RED1; $display ("color4 = %0d, name = %s", color4, color4.name());
color5 = YELLOW3;$display ("color5 = %0d, name = %s", color5, color5.name());
color6 = WHITE4; $display ("color6 = %0d, name = %s", color6, color6.name());
end
endmodule
Simulation Log
ncsim> run
color1 = 1, name = YELLOW
color2 = 8, name = PURPLE
color3 = 3, name = BLACK3
color4 = 6, name = RED1
color5 = 0, name = YELLOW3
color6 = 5, name = WHITE4
ncsim: *W,RNQUIE: Simulation is complete.
枚举类型方法
SystemVerilog包括一组专用方法,可用于遍历枚举类型的值。
first() | 返回枚举的第一个成员的值 |
---|---|
last() | 返回枚举的最后一个成员的值 |
next() | 从给定变量的当前值开始返回下一个枚举值 |
– | – |
prev() | 从给定变量的当前值开始返回第N个先前的枚举值 |
num() | 返回给定枚举中的元素数 |
– | – |
name() | 返回给定枚举值的字符串表示形式 |
枚举方法示例
// GREEN = 0, YELLOW = 1, RED = 2, BLUE = 3
typedef enum {GREEN, YELLOW, RED, BLUE} colors;
module tb;
initial begind
colors color;
// 将当前变量color值分配为YELLOW
color = YELLOW;
$display ("color.first() = %0d", color.first()); // First value is GREEN = 0
$display ("color.last() = %0d", color.last()); // Last value is BLUE = 3
$display ("color.next() = %0d", color.next()); // Next value is RED = 2
$display ("color.prev() = %0d", color.prev()); // Previous value is GREEN = 0
$display ("color.num() = %0d", color.num()); // Total number of enum = 4
$display ("color.name() = %s" , color.name()); // Name of the current enum
end
endmodule
Simulation Log
ncsim> run
color.first() = 0
color.last() = 3
color.next() = 2
color.prev() = 0
color.num() = 4
color.name() = YELLOW
ncsim: *W,RNQUIE: Simulation is complete.
参考文献:
【1】https://www.chipverify.com/systemverilog/systemverilog-enumeration#how-to-define-a-new-enumerated-data-type