Reputation: 21
When I change the enumerated type variables from 4 bit to 32 bit, my error is appeased. I am wondering why I cannot keep it at 4 bit in this code.
Here are some pertinent snippets; I have deleted code related to non-pertinent variables:
Testbench:
module ALUtestbench;
//Variable Declaration
typedef enum {ADD = 32'b00, SUB = 32'b01, INV = 32'b10, RED = 32'b11} opcode_t;
opcode_t opcode; //declare typed variable
//Module Instance
alu alu_inst(
.opcode(opcode));
initial begin
opcode = opcode.first();
#10;
do
begin
$display(opcode);
$display("For opcode %s the result is: %0h", opcode.name, result);
opcode = opcode.next;
#10;
end
while (opcode != opcode.first);
end
endmodule
Design:
module ALU;
input reg A [4:0];
inout reg B [4:0];
output reg C [4:0];
initial begin
always @ (*)
begin
case(opcode)
ADD : C = A + B;
SUB : C = A - B;
INV : C = ~A;
endcase
end
endmodule
At first, I had
typedef enum {ADD = 4'b00, SUB = 4'b01, INV = 4'b10, RED = 4'b11} opcode_t;
opcode_t opcode; //declare typed variable
and the compiler gave me the error:
SystemVerilog requires the width of a sized constant in this context to match the width of the enumeration type.
I then changed to 32-bit, and the code now does not have this error. I am wondering why I needed to do that. Does the case
statement reject anything less than 32-bit?
Upvotes: 2
Views: 1259
Reputation: 42623
If you do not explicitly declare a base type for an enumeration, the implicit datatype is int
, which has a 32-bit width. Earlier versions of the SystemVerilog LRM also allowed you to use the label assignments form sized literals (i.e. ADD = 32'b00
) to define the width explicitly instead of an explicit base type. But now the LRM only allows explicit base types. But it still has this rule in the IEEE 1800-2017 SystemVerilog LRM, section 6.19 Enumerations
If the integer value expression is a sized literal constant, it shall be an error if the size is different from the enum base type, even if the value is within the representable range.
So either drop the size for the literals
typedef enum {ADD = 'b00, SUB = 'b01, INV = 'b10, RED = 'b11} opcode_t;
or write it as
typedef enum bit [3:0] {ADD = 4'b00, SUB = 4'b01, INV = 4'b10, RED = 4'b11} opcode_t;
Upvotes: 3
Reputation: 62037
From IEEE Std 1800-2017, section 6.19 Enumerations:
In the absence of a data type declaration, the default data type shall be int. Any other data type used with enumerated types shall require an explicit data type declaration.
Since int
is 32-bit, you do not get an error when your constants are 32-bit.
If you want to use 4-bit constants, you need to explicitly declare your enum
as 4-bit. Change:
typedef enum {ADD = 4'b00, SUB = 4'b01, INV = 4'b10, RED = 4'b11} opcode_t;
to:
typedef enum bit [3:0] {ADD = 4'b00, SUB = 4'b01, INV = 4'b10, RED = 4'b11} opcode_t;
This has nothing to do with the case
statement.
Upvotes: 2