elsa.stack
elsa.stack

Reputation: 21

32-bit vs. 4-bit in enum declaration

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

Answers (2)

dave_59
dave_59

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

toolic
toolic

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

Related Questions