硅芯思见:关于SystemVerilog中枚举类型中枚举值列表的一些事儿

发布于:2023-01-18 ⋅ 阅读:(577) ⋅ 点赞:(0)

在编写代码时如果一个变量只有几种可能的值,并且使用时需要用一种数据类型进行表示时,在SystemVerilog中可以使用枚举类型(enumeration,简写enum)实现这样的功能,而所谓的“枚举”是指将变量的值一一列举出来,且变量的值来自于列举出来的值的范围内,并且枚举变量一次只能获取该值范围内的一个值(标签)。在SystemVerilog中枚举类型声明时的格式如下:

enum [enum_base_type] {标签名1, 标签名2, ...} 变量名;

其中的enum_base_type指定了枚举类中各标签及枚举变量的数据类型,一般在使用枚举类型时,我们都会缺省enum_base_type,缺省状态(implicit mode)下的数据类型默认为int型(32位,2-state),当然如果需要指定其他数据类型就需要显式(explicit mode)的指明数据类型。

【示例】隐式枚举类型

enum {READY,GO,FINISH} run_e;

其中枚举变量run_e为int型数据变量,列表中第一个标签READY的默认值为0,GO的默认值为1,FINISH为2。

【示例】显式枚举类型

enum bit [1:0] {READY,GO,FINISH} run_e;

其中枚举变量run_e为2位宽的bit类型变量,列表中第一个标签READY的默认值为2’b00,GO的默认值为2’b01,FINISH为2’b10。一般情况下,枚举值列表标签的数值是从0开始递增的,当然也可以根据需要指定特殊的值,下面将针对枚举类型中标签指定不同值进行示例说明。

1 标签值默认从0开始,逐个加1递增

【示例】

【仿真结果】

示例中,枚举类型run_e的类型为int,将枚举值列表中各标签的值分别赋值给枚举变量run_e,显示出来的结果可以看出每一个标签对应一个数值,并且这些数值按照从0开始按1递增的顺序排列,实际上枚举值列表中各标签的值可以根据需要进行指定,并不一定非要按照从0开始按1递增的顺序排列。

2 指定枚举值列表中标签值

【示例】

【仿真结果】

示例中,将枚举值列表中GO标签的值修改为了3,FINISH的值修改为了9,READY的值没有进行修改,通过仿真结果可以看到,READY的值仍然为0,但是GO和FINISH的值已经被分别修改为了3和9。可见通过直接对枚举值列表中的标签赋值可以修改该标签默认对应的数值,那么这些标签的数值可以肆无忌惮的随心所欲的设置吗?我们一起看看下面的示例。

【示例】

【仿真结果】

示例中,将枚举值列表中的标签GO的值修改为了2’bxx,仿真编译报错,这是因为该枚举变量指定的数据类型为2值逻辑,那么在给其中枚举值列表中标签指定值时,不能使用4值逻辑的x或者z进行赋值。那么是不是将枚举变量的数据类型指定为4值逻辑数据类型就可以了呢?请看下例。

【示例】

【仿真结果】

示例中,我们将上一个示例中枚举类型指定的数据类型从bit(2值逻辑)改为了logic(4值逻辑),但是结果依然不对。这是因为枚举值列表中的标签对应的数值都是唯一的,那么如果GO的值给为了2’bxx,那么该标签后的两个标签的值将也是2’bxx(2’bxx+1还是2’bxx),所以编译不通过,为了避免这种情况的出现,可以给紧邻GO后的标签赋一个确定的值,从而就可以确保枚举值列表中的所有标签都有一个唯一数值与之对应,如下例。

【示例】

【仿真结果】

上边的示例我们可以看到,所有枚举值列表中的标签的第一个标签的初始值都是0,那么这个初始值可以进行修改吗?

【示例】

【仿真结果】

示例中,将枚举值列表中的第一个标签的值(枚举值列表递增初始值)修改为了3,其后所有标签的值按照递增1的顺序都自动进行了变更。那么是不是可以将这个初始值也按照需要任意修改呢?

【示例】

【仿真结果】

示例中,将枚举值列表的第一个标签的值该为了7,因为第一个标签之后的标签都没有赋值那么其后所有标签的值将以第一个标签的初始值开始按照1递增赋值,那么示例中的GO此时的值应该为8,FINISH值应该为9,NOP值应该为10,但是需要注意该枚举类型是3位bit类型,所以该枚举变量所能取得最大值也就是3’b111,即7,所以此时的GO、FINISH和NOP的值都超过了该枚举变量所能“承载”的最大范围,所以此处编译报错,为了对此进行修改,可以将其中所有的标签值都明确给定为数据类型可表示的范围内的数值。

还需要注意,在给定枚举数值列表中部分标签值时,要保证各个标签的数值间隔,否则也可能不对,如下例。

【示例】

【仿真结果】

示例中,将READY设置为了5,FINISH设置为6,GO并没有设置任何值,此时GO的值将会按照枚举值列表中数值递增的关系获取到值为6,但是此时在值列表中已经设置了FINISH为6,所以此时出现矛盾,导致值列表标签存在重复数值的情况,编译错误。

枚举值列表在赋值时,还需要考虑给标签赋的值位宽是否与该枚举类型本身指定的数据类型匹配,如果不匹配也会产生问题,如下示例。

【示例】

【仿真结果】

示例中,枚举类型指定的数据类型为3位宽bit类型,但是在给枚举值列表中标签赋值时,第一个标签赋值为2’b00,最后一个标签赋值为4’b0011,虽然两个标签赋的值都在该枚举类型指定的数值范围之内,并且也不存在标签值递增关系不满足要求的情况,但是在SystemVerilog中,对于给标签赋的值位宽小于指定数据类型位宽的情况,会产生warning,对于给标签赋的值位宽大于指定数据类型位宽的情况,会产生error,提示用户是否设置了合适的标签值,是否存在标签值位宽设置不匹配的情况?除了示例中可能会出现将标签值位宽设置不合理出现问题之外,还有可能会出现对于枚举类型指定的数据类型位宽不合理产生问题的情况,如下例。

【示例】

【仿真结果】

示例中,给枚举类型指定的数据类型为单bit,但是此时枚举列表中的标签有四个,单bit的枚举变量run_e不能获取到四种不同数值的标签,只能获取到两种,但是示例中的枚举值列表存在四种不同的标签,所以给该枚举类型指定的数据类型位宽不能容纳下四个标签,所以此时编译就会报错。

通过上述几个示例,可以得到枚举类型指定的数据类型和枚举值列表中标签值之间的关系如下:

  • 如果没有指定枚举类型对应的数据类型,那么该类型默认为int型,其中枚举值列表的标签值从默认初始值0开始,顺序按1递增;

  • 如果没有指定枚举类型对应的数据类型,枚举值列表标签值的初始默认值以及其他标签对应的数值可以根据需要指定;

  • 如果没有指定枚举类型对应的数据类型或者指定的枚举类型对应的数据类型为2值逻辑数据类型,那么在给枚举值列表中的标签赋值为x或者z,将会报错,因为数据类型不匹配;

  • 如果指定的枚举类型对应的数据类型为4值逻辑数据类型,在给枚举值列表中的某个标签赋值为x或者z,那么紧跟其后的标签必须要有明确对应的数值;

  • 如果给枚举值列表部分标签赋值,那么需要确保连续标签的数值间隔大于等于1;

  • 如果指定了枚举类型对应的数据类型,需要保证指定的数据类型的位宽与赋给枚举值列表中标签的数值位宽匹配;

  • 如果指定了枚举类型对应的数据类型,需要保证指定的数据类型的位宽与枚举值列表标签个数匹配;

更多内容请关注下面公众号!图片

本文纯属学习之用,欢迎指正文中不足,封面图片若有侵权,请及时沟通!

 

本文含有隐藏内容,请 开通VIP 后查看