typedef enum logic [1:0] {S0, S1, S2} statetype; Does this statement mean that any variable declared as 'statetype' can only take three values, 2'b00, 2'b01, and 2'b10? If so, what happens if I assign the said variable with the value 2'b11?
2 Answers
The IEEE Std 1800-2017, section 6.19.3 Type checking, states:
Enumerated types are strongly typed; thus, a variable of type enum cannot be directly assigned a value that lies outside the enumeration set unless an explicit cast is used or unless the enum variable is a member of a union. This is a powerful type-checking aid, which prevents users from accidentally assigning nonexistent values to variables of an enumerated type. The enumeration values can still be used as constants in expressions, and the results can be assigned to any variable of a compatible integral type.
Enumerated variables are type-checked in assignments, arguments, and relational operators.
What I observe in practice is that some simulators issue a compile warning while others issue a compile error. You can see what happens on multiple simulators on edaplayground (if you sign up for a free account there).
For example, with VCS, the following code:
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 issues this warning:
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. but, it still runs the simulation and prints:
n=S0,s=0 n=,s=3 0I believe the question should be rephrased to say that what is this is happening in our test-bench and how to avoid it. This will gives us more cleaner and bug free code.
efficient code to avoid the confusion:
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 This code is already there in edaplayground feel free to try it and update it. This could be replace with the sv macro for more efficiency. Please let me know I will provide the example for macros.
Output will be:
# 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