0

I have an issue when converting a SystemVerilog file to Verilog-2001 file coming from a GitHub project. It seems that in Verilog-2001, it not possible to place an unrolled loop of a table within a function:

  function [31:0] gen_val;
    input [31:0] old_val;
    input [31:0] new_val;
    input [3:0] be;

    integer n;

    for (n = 0 ; n < 4 ; n = n + 1) 
        gen_val[n*8+8:n*8] = be[n] ? new_val[n*8+8:n*8] : old_val[n*8+8:n*8];

  endfunction

When compiling with Icarus Verilog (iverilog) I get multiple error messages:

./tb_tiny.v:39: error: A reference to a wire or reg (`n') is not allowed in a constant expression.
./tb_tiny.v:39: error: Part select expressions must be constant.
./tb_tiny.v:39:      : This lsb expression violates the rule: (n)*('sd8)
./tb_tiny.v:39: error: A reference to a wire or reg (`n') is not allowed in a constant expression.
./tb_tiny.v:39: error: Part select expressions must be constant.
./tb_tiny.v:39:      : This msb expression violates the rule: ((n)*('sd8))+('sd8)
.....

Would anyone have an idea about the way to fix this in Verilog-2001 ?

Regards

0

1 Answer 1

0

IEEE standard for Verilog HDL (IEEE Std 1364-2001) clause 4.2.1 defines two types of part-selects: a constant part-select and an indexed part-select.

... A constant part-select of a vector reg or net is given with the following syntax:

vect[msb_expr:lsb_expr]

Both expressions shall be constant expressions. ...

An indexed part select of a vector net, vector reg, integer variable, or time variable is given with the following syntax:

reg [15:0] big_vect;
reg [0:15] little_vect;

   big_vect[lsb_base_expr +: width_expr]
little_vect[msb_base_expr +: width_expr]

   big_vect[msb_base_expr -: width_expr]
little_vect[lsb_base_expr -: width_expr] 

The width_expr shall be a constant expression. It also shall not be affected by run-time parameter assignments. The lsb_base_expr and msb_base_expr can vary at run-time. ...

Your function can be rewritten using an indexed part-select:

function [31:0] gen_val;
    input [31:0] old_val;
    input [31:0] new_val;
    input [3:0] be;

    integer n;

    for (n = 0 ; n < 4 ; n = n + 1) 
        gen_val[n*8 +: 8] = be[n] ? new_val[n*8 +: 8] : old_val[n*8 +: 8];

endfunction
Sign up to request clarification or add additional context in comments.

1 Comment

Dear Dmitry, Thanks for your feedback and that definitely fixed the problem. On my side, I don"t understand why the initial statement did not work and was fixed by the introduction of the indexed part select. I expected them to be equivalent but apparently this is not the case. Thanks again.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.