打造IC人才
科技生态圈

关于SV中枚举类型的一些“不正经”用法

发布时间:2022-08-26

来源:IC修真院

SystemVerilog中枚举类型虽然属于一种“强类型”,但是枚举类型还是提供了一些“不正经”的用法可以实现一些很常见的功能,本文将示例一些在枚举类型使用过程中的一些“不正经”用法,并给出一些使用建议。

1、同一个作用域内定义多个枚举类型,并且这些枚举类型的枚举值列表中存在相同的标签名

 【示例】

SystemVerilog

【仿真结果】

仿真结果

示例中,定义了两个枚举变量fsm_s1和fsm_s2,并且其对应的枚举值列表中都包含了相同的标签“GO”,编译后报错。其实可以想象下,如果在SystemVerilog的同一个作用域中允许这种同名的标签存在,那么在具体对于某一个枚举变量使用标签进行赋值操作时,那么这个标签到底是来自于哪个枚举变量中对应的枚举列表呢?所以,在SystemVerilog中,同一个作用域内定义多个枚举类型时,这些枚举类型的枚举值列表中不能存在同名的标签。

2、枚举值列表中的标签用于运算

【示例】

枚举值列表中的标签用于运算

【仿真结果】

枚举值列表中的标签用于运算仿真结果

示例中,将枚举变量cal_e的枚举值列表中的标签被用于运算操作,并且可以获得对应的计算结果。这是因为枚举值列表中的每个标签都有对应的数值,默认情况下,枚举值列表中第一个标签对应的数值为0,其后标签对应数值按照加1递增。当枚举值列表中的标签用于具体运算表达式时,与这些标签关联的数值会自动“替换”掉表达式中的标签,从而实际完成运算的是标签对应的数值。但是限于枚举值列表可以表示的数据范围有限,建议不要将枚举列表中的标签用于具体运算过程中。

3、将数值直接赋给枚举变量

【示例】

将数值直接赋给枚举变量

【仿真结果】

将数值直接赋给枚举变量仿真结果1

示例中,第6行和第8行分别将数值直接赋予了枚举变量cal,此时编译会提示此处的赋值为illegal,但是SystemVerilog对于这个赋值操作还是会进行的。第10行采用$cast进行动态转换,将数值转换成枚举变量cal,间接实现了对cal的赋值操作,此时因为采用了显式的类型转换,并且转换成功,所以并不会产生任何提示信息。第12行使用了静态转换,将数值转换成枚举变量cal,此时因为采用了显式的类型转换,所以也并不会产生任何提示信息。但是在将具体数值赋值枚举类型变量时,最好采用显式的动态转换或者静态转换。

4、赋给枚举变量的数值位宽与枚举变量位宽不匹配时的结果

【示例】

4

【仿真结果】

41

示例中,第6行将数值“4”赋给枚举变量cal,该枚举变量可以选择的枚举值列表中的数值只可能为:0,1,2,3,显然数值“4”不在该范围之内,所以通过枚举变量调用name()函数得到的标签为“空”。但是“4”的位宽在该枚举变量所能表示的数值范围之内(不在枚举值列表之内),所以该值会被赋给该枚举变量,其数值可以被显示出来。

第9行将数值“9”赋给枚举变量cal,数值“9”为4位宽,枚举变量cal位宽为3,数值“9”不在该枚举变量所能表示的数值范围之内,所以“9”会被截位后赋给枚举变量,所以此时枚举变量对应的数值为“3’b001”而不是“4’b1001”,而与数值“3’b001”对应的枚举值列表中标签是“ONE”,所以通过枚举变量调用name()函数得到的标签为“ONE”,显示的数值为“1”。

为了在仿真过程中避免类似情况出现,在将具体数值赋给枚举变量时,建议采用动态转换$cast,不要寄希望于仿真器能够“揣测明白你的心意悄悄的”静态的完成类型的转换赋值,使用动态转换$cast当遇到类型不匹配时立刻可以报错提醒。


推荐阅读

换一换