However, when trying to implement the following code:
function bit[31:0] assign_value (
input bit [31:0] initial_value,
input bit [31:0] assigned_field,
const ref int lsb,
const ref int msb);
assign_value = initial_value;
assign_value[msb:lsb] = assigned_field;
endfunction : assign_value
I get following compilation error whether I try to compile under Synopsys or Cadence (do not have access to Mentor Questa)…
**assign_value[msb:lsb] = assigned_field;
|
xmvlog: *E,NOTPAR (slice_access.sv,86|21): Illegal operand for constant expression [4(IEEE)].
**
In SystemVerilog, a const is not the same thing as a constant. A const is still a variable that is written only once at the time of the variable’s initialization.
You will need to create a for loop that does the assignment bit for bit.
Thank you for your answer, I was actually looking for a solution that was more elegant and more “SystemVerilog” than using C style for assigning a slice…
The only solution I see now, if I want to avoid the loop for assigning every bit one by one is to use of preprocessor `define values or (local)parameters… Unfortunately I cannot pack those into associative arrays (unlike const int).
That’s exactly what I meant by C-style bit slice assignment, using an inverted mask and logical ‘or’. The thread was triggered from a discussion we had within our team about whether there was a better way of doing bit slice assignment in SystemVerilog - most of people use indeed C-Style assignment.
C-style assignment works perfectly but it’s far less readable than:
vector[msb:lsb]=new_slice_value;
Unfortunately this previous statement only works when msb and lsb are constant (not const int as documented by Dave previously).
In reply to sylvainb:
This seems very readable to me:
function bit[31:0] assign_value (
bit [31:0] initial_value,
bit [31:0] assigned_field,
int lsb,
int msb);
assign_value = initial_value;
for(int index=lsb; index <= msb; index++) assign_value[index] = assigned_field[index-lsb];
endfunction : assign_value
I agree with you that it is readable but it forces everyone in the project to use this ‘assign_value’ function in order to circumvent the requirement of SystemVerilog demanding constant for msb_expr and lsb_expr (or for width_expr in case of part-select addressing) cf. IEEE 1800-2017 section 11.5.1
It then becomes harder to convince people using C-style bit slice access to switch to a function locally defined in the project…
This assign_value function begs the question of, why does this restriction still exist in the language?
This is because SystemVerilog is a statically typed language and bit-width is a part of the type. You cannot have an operand dynamically changing its type. It may seem overly restrictive for a simple assignment, but the rules for evaluating bit-widths of expressions gets complex quickly as soon as you introduce boolean and arithmetic expression involving operands of different bit-widths with signed and unsigned types.