openfpga
openfpga copied to clipboard
Detect bitwidth mismatches in linting
Assignments with mismatched widths.
Assignments of numbers without specified width (defaults to 32 bits) when the destination is wider than 32 bits. Been bit by this...
wire [63:0] = 12345
The 12345 is assumed to be 32 bits wide.
Cool idea, BTW. Good luck with the project.
(defaults to 32 bits) [..] The 12345 is assumed to be 32 bits wide.
This is not correct. The Verilog standard says that unsized constants must be at least 32 bits wide. Yosys creates a larger constant if the number does not fit into 32 bits. After the constant is created it is extended to expression width, which is in this case 64 bits, because in Verilog the LHS size of an assignment contributes to the expression size. So there really ios nothing to warn about here.
The only case that is problematic is in self-sized expressions. But by definition, they don't have a destination size to compare with. (E.g. {123456789*123456789}
will perform the multiplication with 32 bits width, because all values are 32 bits wide and the expression inside {...}
is self-sized.)
Yosys may do the smart thing, but the standard is obviously ambiguous. Other compilers don't necessarily do the smart thing and relying on it is asking for unportability and trouble.
On Wed, Oct 19, 2016 at 11:28 PM, Clifford Wolf [email protected] wrote:
(defaults to 32 bits) [..] The 12345 is assumed to be 32 bits wide.
This is not correct. The Verilog standard says that unsized constants must be at least 32 bits wide. Yosys creates a larger constant if the number does not fit into 32 bits. After the constant is created it is extended to expression width, which is in this case 64 bits, because in Verilog the LHS size of an assignment contributes to the expression size. So there really ios nothing to warn about here.
The only case that is problematic is in self-sized expressions. But by definition, they don't have a destination size to compare with. (E.g. {123456789*123456789} will perform the multiplication with 32 bits width, because all values are 32 bits wide and the expression inside {...} is self-sized.)
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/azonenberg/openfpga/issues/47#issuecomment-255020158, or mute the thread https://github.com/notifications/unsubscribe-auth/ADvoIYV94s7IPhJaTbR1iLKvBYsNiadTks5q1woAgaJpZM4Kbvbj .
Yosys may do the smart thing, but the standard is obviously ambiguous.
Yes, the standard is ambiguous, but only for constants that do not fit in 32 bits! There is nothing ambiguous about the code you posted.
To further elaborate, I thing the following two conditions should trigger a warning in a Verilog linter:
- Use of unsized constants in certain self-sized contexts, such as
{...}
or{N{...}}
, or the argument of a reduce operation. - Use of unsized constants with a value that does not fit in 32 bits. (Or maybe even something smaller, like 24 bits, to make sure that there is no overflow that might change the outcome of a calculation, e.g. when adding a few of those constants.)
Verilog rules for expression sizes are complicated and hard to get right.