A self-determined expression is the one whose bit length is solely determined by the expression itself.
SystemVerilog LRM defines the bit lengths resulting from self-determined expressions. In the table below, i, j, and k represent expressions of an operand, while L(i) represents the operand i’s bit width.

Designers should avoid using self-determined expressions in RTL, since self-determined expressions may lose carry bits.
SystemVerilog LRM has an example of how this can happen:
logic [15:0] a, b, answer;
assign answer = (a + b) >> 1;
The intention is to add “a” and “b” (resulting in an overflow), and then do a right shift by 1 to preserve the carry bit in the 16-bit “answer”. However, all operands in this self-determined expression are 16-bit in width, thus the expression (a + b) produces an intermediate result of 16 bits, and the carry bit is lost during the right shift operation.
The best practice is to make the widths of expression (a + b) explicit by using an intermediate variable to hold the results of this expression.
The following are some other examples where self-determine expressions can create unintended results:
// DO NOT do this!
z = (a + b) > c;
if ((a + b) > c) …
// DO this instead!
x = a + b;
z = x > c;
if (x > c) …
Reference:
- SystemVerilog LRM: https://fpga.mit.edu/6205/_static/F23/documentation/1800-2017.pdf

Leave a comment