Introduction to Verilog's expression sizing/typing algorithm.
Sizing expressions in Verilog is a two-phase process.
Stop! Carefully read the above steps again. Understanding the two phases is a critical first step to making any sense of the rules.
Let us now begin making these steps more precise.
First, the claim that "final size of the expression is the maximum size of
any of its operands" is basically true for expressions like
The actual rules for computing the final width of an expression are given in Table 5-22 of the Verilog spec, which we now reproduce:
Expression Bit Length Notes ----------------------------------------------------------------------------- Unsized constants "Same as integer" (see ** below) Sized constants As given i [+ - * / % & | ^ ^~ ~^] j max{L(i),L(j)} [+ - ~] i L(i) i [=== !== == != > >= < <=] j 1 bit i,j sized to max(L(i),L(j)) i [&& ||] j 1 bit i,j self-determined [& ~& | ~| ^ ~^ ^~ !] i 1 bit i self-determined i [>> << ** >>> <<<] j L(i) j self-determined i ? j : k max(L(j),L(k)) i self-determined {i, ..., j} L(i)+...+L(j) all self-determined {i {j, ..., k}} i*(L(j)+...+L(k)) all self-determined -----------------------------------------------------------------------------
(**) What does "same as integer" mean? From Section 4.8: Verilog implementations may limit the size of integer variables. The limit must be at least 32 bits, but is not otherwise unconstrained. Hence, expressions involving unsized constants may have implementation-dependent sizes (and can in fact have implementation-dependent results).
VL acts like a 32-bit implementation, so effectively any unsized constant is
treated as if it has size 32. I historically tried to directly support
abstract "integer-sized" expressions so that we could warn about expressions
whose behavior might be implementation-dependent. But I eventually decided
that this approach overly complicated the sizing code. Today, the VL lexer automatically treats unsized constants as if they were 32 bits so the
whole matter of "how large is integer-size?" is effectively settle a priori.
But the lexer also marks any unsized constants with the
At any rate, the "bit length" column in the above table gives an almost
full story about how to determine the finalwidth of an expression. But as a
final twist, when assignment statements are sized, the bit-length of the
left-hand side of the assignment also plays a role in the finalwidth
computation. Essentially, the finalwidth of
Our main function for computing the desired finalwidth of an expression is vl-expr-selfsize.
The above claim that "the final signedness will be unsigned unless all
operands are signed" is basically true for expressions like
The Verilog rules for signedness are covered in Section 5.5.1 and 5.5.4. We summarize these rules here:
Another rule is found in 5.1.12, which says the right-hand side of a shift is always treated as unsigned.
Some additional technical questions and investigations may be found in expression-sizing-minutia.
In VL, our main function for computing the final signedness of an expression is vl-expr-typedecide.
BOZO document this.