I was recently writing some tests for our VHDL expression evaluator and was amazed by the the result of evaluting -16 ** 2
.
I expected 256
, but it wasn’t.
Can you guess the output of running this process?
process is
begin
report "-5 mod (-3) : " & integer'image(-5 mod (-3));
report "(-5) mod (-3) : " & integer'image((-5) mod (-3));
report "-(5 mod (-3)) : " & integer'image(-(5 mod (-3)));
report "-16 ** 2 : " & integer'image(-16 ** 2);
report "(-16) ** 2 : " & integer'image((-16) ** 2);
report "-(16 ** 2) : " & integer'image(-(16 ** 2));
wait;
end process ;
The output is:
# ** Note: -5 mod (-3) : 1
# ** Note: (-5) mod (-3) : -2
# ** Note: -(5 mod (-3)) : 1
# ** Note: -16 ** 2 : -256
# ** Note: (-16) ** 2 : 256
# ** Note: -(16 ** 2) : -256
It turns out unary minus has a lower priority than the modulo and exponentiation operator. I had to consult the LRM again to find this list of operator priorities (from high to low):
- **, abs, not
- *, /, mod, rem
- +, - (unary versions)
- +, -, &
- sll, srl, sla, sra, rol, ror
- =, /=, <, <=, >, >=, ?=, ?/=, ?<, ?<=, ?>, ?>=
- and, or, nand, nor, xor, xnor
So be careful when you are typing expressions; make sure you use enough parentheses.
P.S: You may have noticed that I wrote -5 mod (-3)
and not -5 mod -3
. The latter, -5 mod -3
, is not valid VHDL. This again is because unary minus has lower priority than the modulo operator.
See also
- To "to" or to "downto"... Ranges in VHDL (blog post)
- VHDL 2019: Conditional Analysis (blog post)
- VHDL 2019 Conditional Analysis (screencast)
- Customizing documentation from Sigasi Visual HDL: easier than you think (knowledge)
- Sigasi's Software Development Kit Part 2 (legacy)