Expression bit-length and Associativity

Hi Forum,

( A) I was trying the following code to calculate the bit length of an expression

The 1st initial block i1 has 6 $display statements where the intended output is observed in the last 4 $display statements.

(1) When we write 32’( i << j ) is the 32’ size cast applied to both operands or is it only i or j ?

(B) Return value of $bits.

As per LRM ::

$bits returns the number of bits required to hold an expression as a bit stream

Using the 2nd initial block i2 I am trying to understand the meaning of above quote

(2) When we write $bits(i << j), how is the return value calculated ?

(3) Why does $bits(32'(i << j)) give same output as $bits(32'(i) << j) or $bits(i << 32'(j)) ?

(4) When written in a conditional operation I observe different results with last 2 $display statements of i2, why is it so ?

(C) As per LRM binary operators + - have the same precedence.

Associativity for these operators is left to right.

What does the left to right mean here ?

For the following constraint expression A + B - C + D - E + F == Z

Does the quote imply that the calculation starts from leftmost variable i.e A ?

How would Z be calculated be in this case ?

Thanks

The answers to your questions are found in Table 11-2—Operator precedence and associativity and Table 11-21—Bit lengths resulting from self-determined expressions of the IEEE 1800-2023 SystemVerilog LRM. These tables are described in the sections they are enclosed in.

When writing the expression i << j, the width of the result is solely determined by the width of operandi. The operand ”j” is used in a self-determined or isolated context. The cast 32’( i << j ) is used to cast the result of the expression. The value that i or j holds is irrelevant to determining the width of that expression.

Associativity rules apply to operators that have the same precedence level. == has lower precedence than +/- so the result of A + B - C + D - E + F would be constrained to equal Z. Expressions with operators of the same precedence are ordered from left to right when left associativity is used as in
(((((A + B) - C) + D) - E) + F).

Hi Dave,

I get this part.Due to this reason we observe output as ‘d0 for the first two $displays in i1

Unfortunately I am still confused regarding this quote.

Does the 32’ cast take effect ( i.e variable i is size extended to 32-bits ) before the left shift operation ?

I am trying to correlate the above 32’ cast to size casting within with clause of array reduction

rand bit [3:0] a1[10];

constraint summ { a1.sum() with (32'(item)) == 25; }

Here each element is size casted to 32-bits in the equivalent expression i. e each element is padded with 0’s prior to addition operation.This ensures that sum doesn’t overflow

constraint summ2 { 32'( a1.sum() ) == 25; }

Here the 32’ size cast has no effect in the addition operation as the elements would use their default width of 4-bits

(B) Could you please share your thoughts on (2) , (3) and (4) above

How do I calculate the value returned by $bits in these three scenarios

Thanks

It would be helpful to clearly label all the questions and points when asking multiple questions around multiple points.

Variables don’t get extended; the operands of an expression can be extended before the expression is evaluated. In your example, the operand of the left shift operator is an expression consisting of a single variable. If you had written 32'( {1'b0, i} << j), the operand {1'b0, i} is what get extended because of the cast (assuming i is less than 31 bits). A cast creates an assignment-like context, similar to assigning a temporary variable of the same size as the casting width. That context gets applied to the LHS operand of the shift operator.

The array reduction methods are functions, and the context of the expression used with a function does not flow into the function itself. The with () clause of the array reduction methods is actually part of the definition of the inside of that function.