SystemVerilog Enumeration(SystemVerilog枚举)

枚举(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

发布了91 篇原创文章 · 获赞 7 · 访问量 5267

猜你喜欢

转载自blog.csdn.net/qq_43042339/article/details/104454479