This does a better job of setting the intermediate expression types
and widths when calculating the canonical index into a packed array.
It still doesn't properly handle out-of-bound indices (br953).
A compressed assignment statement should give exactly the same
result as the equivalent uncompressed statement. This means
that the type (signed/unsigned) of the LHS affects the type of
the RHS expression (unlike in normal assignments). We need to
take care that bit/part selects and concatenations are correctly
identified as unsigned values, even in the cases where they
reduce to a single whole signal.
If an error is found whilst elaborating a range expression in a signal
declaration, create a dummy range and continue elaboration. This stops
the compiler reporting an error every time that signal is referenced.
If an expression contains a division, remainder, or right shift operation,
set the expression min_width to UINT_MAX to flag that the expression width
cannot be pruned. Using UINT_MAX ensures that the min_width won't change
as we continue to elaborate the expression.
When a mux (NetCondit) is only writing to a part of the output
vector (and using only a part of the inputs) then blend the mux
output with the previous statement output.
If both conditions of a NetCondit device assign to the same subset
of l-value bits, then generate a smaller NetMux device that only
switches the affected bits.
Unsized expressions can expand to extremely large widths. Usually this
is actually a mistake in the source code, but it can lead to the compiler
temporarily using extremely large amounts of memory, or in the worst
case, crashing. This adds a cap on the width of unsized expressions (by
default 65536 bits, but overridable by the user), and causes a warning
message to be output when the cap is reached.
When creating a constant zero for implementing a unary minus operation
using a binary subtraction operator, the constant needs to be to exactly
the expression width.
For constant word indices, issue a warning if the index is out of
range or an undefined value. In any case, the RHS value should be
discarded, and the actual assignment should be skipped.
The compiler was treating case and case item expressions as
self-determined. They should be context-sensitive, just like
the operands of a comparison operation.
IVL_VT_NO_TYPE is now used to signal an untyped LHS in a parameter
declaration. The parser function that handles specparam declarations
needs to do this too. Also, although it should never happen, make
sure we don't set the expression width in a NetECast object to a
negative number. Make constant evaluation of NetECast objects
observe the expression width.
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.
For a LPM constant we need to pass the sign information so that the vlog95
code generator can create the correct constant. Also when using the
sub_net_from() routine the numeric constant should have the same sign as
the signal so that it can also be displayed correctly.
Since the vlog95 code generator needs the strength information we do
not want to hide it behind a concat-Z optimization. For now we abort
the optimization, but in the future we could add parts of this back
in (e.g. all the drivers have matching strength then replace with a
normal concat and a buf-Z if the strength are not both strong. The
original buf-Z should be removed to reduce the number of LPM devices).
If a signal s driven by multiple non-overlapping NetPartSelect(PV)
objects, then combine them into a single NetConcat object. This
eliminates the need for resolvers in the target.