From this paper: http://fpgacpu.ca/fpga/hdl/Tumbush%20DVCon%2005.pdf
- If any operand in an operation is unsigned the entire operation is unsigned.
- Investigate fully all "signed to unsigned conversion occurs" synthesis warnings. These point to incorrect functionality.
- All signed operands will be sign-extended to match the size of the largest signed operand.
- Type casting using $unsigned will make the operation unsigned. The operand will be extended with 0’s if necessary.
- Type casting using $signed makes the operand signed. The operand will be sign-extended with 1's if necessary. Pad the operand with a single 0 bit before the cast if this is not desired.
- Expression type depends only on the operands or operation; it does not depend on the LHS of the expression.
Additional points based on feedback from Owen Shepherd:
- In SystemVerilog, signed' and unsigned' are the preferred way of doing things.
- Do explicit widening with N'(x) rather than relying on implicit widening. (This is a SystemVerilog only feature.)
- Instead of 0 padding as in the paper's point 5, you can use explicit pre-widening, e.g. $signed(32'(x)).
However it was a good thing I made this example because I hadn't noticed that there were a way to turn off this BS!