Khoa Trần
Khoa Trần

Reputation: 25

The generate if condition must be a constant expression

I am trying to create an Immediate Generator for RISC-V assembly, but I have encountered an error with if statement.

Here is my code in Verilog:

module signextend(in, out, sel);
    parameter nin = 32;
    parameter nout = 32;
    input [nin-1:nin-25] in;
    input [2:0] sel;
    output [nout-1:0] out;
    
    if (sel == 3'b000)
        begin
            assign out[19:0] = in[31:12];
            assign out[31:20] = {12{in[31]}};
        end
    else if (sel == 3'b001) 
        begin
            assign out[11:0] = in[31:20];
            assign out[31:12] = {20{in[31]}};
        end
    else if (sel == 3'b010)
        begin
            assign out[4:0] = in[24:20];
            assign out[31:5] = 0;
        end
    else if (sel == 3'b011)
        begin
            assign out[3:0] = in[11:8];
            assign out[4:9] = in[30:25];
            assign out[10] = in[7];
            assign out[11] = in[31];
            assign out[31:12] = {20{in[31]}};
        end
    else if (sel == 3'b100)
        begin
            assign out[4:0] = in[11:7];
            assign out[11:5] = in[31:25];
            assign out[31:12] = {20{in[31]}};
        end
    else if (sel == 3'b101)
        begin
            assign out[9:0] = in[21:30];
            assign out[10] = in[20];
            assign out[18:11] = in[19:12];
            assign out[19] = in[31];
            assign out[31:20] = {12{in[31]}};
        end 
    else 
        assign out = 32'hxxxx;  
endmodule

The problem exists in each if statement:

The generate if condition must be a constant expression.

Upvotes: 2

Views: 10138

Answers (1)

Matthew
Matthew

Reputation: 13987

You need to put all your code inside an always block and remove the assigns:

always @(*) begin
  if (sel == 3'b000)
      begin
          out[19:0] = in[31:12];
          out[31:20] = {12{in[31]}};
      end
  else if (sel == 3'b001) 
    // etc

An always block contains a little bit of software (your if statements) that models a little bit of hardware (the resulting combinational logic).

It is legal to have an if statement outside an always (or initial) block, but then it means something different. Then it means conditional including of hardware, ie if some condition is true, include this hardware. Such a condition has to be static, ie fixed at compile time. It cannot be an input, like your sel. If you think about it, that makes total sense: how could you create some hardware that magically appears and disappears depending on the value of some input? You can't. That is why you are getting your error.

You need to remove the assigns, because while it is legal to have an assign inside an always block, it means something weird. Never do it.

Upvotes: 2

Related Questions