String literals may have escaped special characters in them. Make sure
we are processing all the special characters that the standard supports,
and also fix the handling of the assignment to strings. Note that the
vvp input has string literals sanitized so that the parser can handle
the various binary values. desanitize the strings when pushing string
literals into the string stack. This fixes string assignments, and other
string operations.
When performing a signed division or modulus operation using native
arithmetic, trap the special case that the numerator is the minimum
integer value and the denominator is -1, as this gives an undefined
result in C++.
When unsized literals are used in case item expressions, it is likely
that the calculated expression width will be larger than necessary to
unambiguously select the correct case item (particularly when using
"strict" expression elaboration). This patch adds an optimisation
step that prunes the expressions to the minimum necessary width.
For shift operations evaluated at compile time, the compiler was converting
the right operand to a native unsigned long value. If the operand exceeded
the size of an unsigned long, excess bits were discarded, which could lead
to an incorrect result.
The fix I've chosen is to add an as_unsigned() function to the verinum class
which returns the maximum unsigned value if the internal verinum value is
wider than the native unsigned type. This then naturally gives the correct
result for shifts, as the verinum bit width is also an unsigned value.
I've changed the as_ulong() and as_ulong64() functions to do likewise, as
this is more likely to either give the correct behaviour or to give some
indication that an overflow has occurred where these functions are used.
The verinum arithmetic operators now observe the standard Verilog
rules for calculating the result width if all operands are sized.
If any operand is unsized, the result is lossless, as before.
They also now all observe the standard rules for handling partially
undefined operands (if any operand bit is 'x', the entire result is
'x').
I've also added the unary '-' operator, and renamed v_not() to be
the unary '~' operator. This has allowed some simplification in
other parts of the compiler.
This changes the verinum pow() function to use the more efficient algorithm
used in the vvp runtime. It will still be slow if the left operand is unsized
and the right operand is large, as it will expand the result vector to avoid
overflow.
This patch fixes a few issues/bugs that showed up when testing the
fixes for implicit casts:
1. Make the compile-time implementation of $abs, $min, and $max match
the run-time behaviour (system functions can't be polymorphic).
2. Correctly set the type (signed/unsigned) of the result of an
assignment inside a constant user function (the LHS should not
inherit the type of the RHS).
3. Fix a bug in the verinum(double) constructor (insufficient bits
were allocated in the case where the double value rounded up to
the next power of two).
This patch adds support for implicit casts to the elaborate_rval_expr()
function. This will handle the majority of cases where an implicit cast
can occur.
The power operator defines 2**-1 and -2**-1 to be zero. This patch fixes
both the procedural and continuous assignments to work correctly. It also
fixes a problem in the compiler power code so that the one constant value
always has at least two bits.
For diagnostics and to know what is really going on in the compiler
we need to keep any NULL that is in a verinum string or when
displayed as/converted to a string.
When padding a verinum string if the padding is in multiples of eight
then keep the string property.
When a verinum is displayed as a string we need to make sure that any
character that will be displayed as an octal constant must be converted
correctly. Also change to isprint() instead of isgraph() since it is the
same as isgraph() plus a space.
This patch covers more than it should. It removes many of the -Wextra
warnings in the main ivl directory. It also makes some minor code
improvements, adds support for constant logicals in eval_tree (&&/||),
adds support for correctly sign extending === and !==, it starts to
standardize the eval_tree debug messages and fixes a strength bug
in the target interface (found with -Wextra). The rest of the warnings
and eval_tree() rework will need to come as a second patch.
The functions (malloc, free, etc.) that used to be provided in
malloc.h are now provided in cstdlib for C++ files and stdlib.h for
C files. Since we require a C99 compliant compiler it makes sense
that malloc.h is no longer needed.
This patch also modifies all the C++ files to use the <c...>
version of the standard C header files (e.g. <cstdlib> vs
<stdlib.h>). Some of the files used the C++ version and others did
not. There are still a few other header changes that could be done,
but this takes care of much of it.
This is generating an octal constant but there is no reason to have
three '\' characters. You need two to get the leading '\', but the
last one is not needed.
The functionality of the integer power operator is specified in
1364-2005 on page 45-46 and specifically Table 5-6. This patch
fixes the verinum pow operator to work as specified in this
table. It also fixes an error in the == operator when both
operators are signed and only the left argument is negative.
This patch fixes fully out of range constant indexed part selects
to just return 'bx. It also adds support for constant undefined
base values which also just return 'bx.
A bug in the bit width calculation when building an unsized, signed
negative integer value was also fixed (-3 needs 3 bits not 2, etc.)
This test was way to picky about the widths of the arguments. In real
tests, the arguments may have different widths. This especially matter
when comparing unsized values.
Continue cleaning up shadowed variables, flagged by turning on -Wshadow.
No intended change in functionality. Patch looks right, and is tested
to compile and run on my machine. No regressions in test suite.
This patch adds the $clog2 system function. It also makes this
function work as a constant function. The runtime version still
needs to be updated to use an integer based version instead of
the current double based method. The double method suffers from
rounding errors.
This patch adds the time and realtime types to parameters
and local parameters. It also makes the width (range) of
an integer parameter match the variable "integer_width"
(normally 32 bits). It also converts a real value to
an integer when a range is implicitly or explicitly
given. This all matches what the standard specifies.
Fixed an error in converting -1 to a unsized verinum.
When calculating 0^z with constant arguments, make sure the result is
x. This problem only happens when the arguments are constants and the
expression is calculated at compile time.
When constant values are added to get another constant value, and the
expression is not otherwise a fixed size, then trim the result to
prevent unbounded expansion of unsized expression with.
In the process, find and fix a bug in the vtrim function that caused
an assert if trimming were not possible for an unsigned value.
Problems with signed expressions that are set to parameters and
that include multipliciation exposed a few bugs in the calculation
of signed multiply. Fix this and add some improved diagnostics.
This patch fixes some bugs in the implementation of signed integer
division with wide operands in constant expressions and adds support
for signed integer modulus with wide operands in constant expressions.
It also removes a few redundant lines of code.
Incorrect trimming of unsigned verinum values was causing the
compilers unsigned constant verinum pow function to give
incorrect results. This patch restores the pow compile time
optimization and fixes the trimming to always leave a single
zero in the MSB.
There was much redundant code in the compile-tile handling of the
less-then and greater-then of constant expressions, and much of it
was buggy. Unify much of the code and squeeze out the bugs so that
compile-time evaluations come out correctly.
The compiler attempts to precalculate the results of <= comparisons.
Fix a few corner cases where the arguments are signed. Also fix the
important test of constant against non-constant where we try to test
if the non-constant value can possibly make the test fail.
Signed divide of 32bit values can overflow if done in a 32bit long
due to the truncation of sign bits. So use the large value algorithm
if the values are >= 31 bits (63 bits on 64bit machines).
Signed-off-by: Stephen Williams <steve@icarus.com>