typedef enum logic [1:0] {S0, S1, S2} statetype;
这个语句是否意味着任何声明为 '
statetype
' 的变量只能取三个值:2'b00、2'b01 和 2'b10?如果是这样,如果我为所述变量分配值 2'b11 会发生什么?
IEEE Std 1800-2017,第 6.19.3 节类型检查,规定:
枚举类型是强类型的;因此,枚举类型的变量 不能直接分配枚举之外的值 设置除非使用显式强制转换或者除非枚举变量是 工会成员。这是一个强大的类型检查辅助工具, 防止用户意外分配不存在的值 枚举类型的变量。枚举值仍然可以是 用作表达式中的常量,结果可以赋值给 任何兼容整型的变量。
枚举变量在赋值、参数和 关系运算符。
我在实践中观察到,一些模拟器会发出编译警告,而另一些模拟器则会发出编译错误。您可以在 edaplayground 上查看多个模拟器上发生的情况(如果您在那里注册了免费帐户)。
例如,使用VCS,如下代码:
module tb;
typedef enum logic [1:0] {S0, S1, S2} statetype;
statetype s;
initial begin
s = S0;
$display("n=%s,s=%0d,", s.name(), s);
s = 3;
$display("n=%s,s=%0d,", s.name(), s);
end
endmodule
发出此警告:
Warning-[ENUMASSIGN] Illegal assignment to enum variable
tb.v, 16
tb, "s = 3;"
Only expressions of the enum type can be assigned to an enum variable.
The type int is incompatible with the enum 'statetype'
Expression: 3
Use the static cast operator to convert the expression to enum type.
但是,它仍然运行模拟并打印:
n=S0,s=0
n=,s=3
我认为这个问题应该改写为我们的测试平台中发生了什么以及如何避免它。这将为我们提供更干净、无错误的代码。
高效的代码以避免混乱:
typedef enum logic [1:0] {S0, S1, S2} statetype;
module top();
statetype st_e;
initial begin
for(int val=0;val<4; val++) begin
// casting for avoid confusion and gotchas
if (!$cast(st_e,val)) begin
$error("Casting not possible -> statetype:%0s and val:%0d",st_e,val);
end else begin
$display("statetype:%0s and val:%0d",st_e,val);
end
end
end
endmodule: top
此代码已在 edaplayground 中,请随意尝试并更新它。这可以替换为 sv 宏以提高效率。请告诉我,我将提供宏的示例。
输出将是:
# run -all
# statetype:S0 and val:0
# statetype:S1 and val:1
# statetype:S2 and val:2
# ** Error: Casting not possible -> statetype:S2 and val:3
# Time: 0 ns Scope: top File: testbench.sv Line: 14
# exit