This.new is not allowed.
super.new beyond the first statement is not allowed.
And while I'm at it, clean up the use of "@" and "#" in
the code as tokens for this and super.
A NetESelect is used for accessing packed struct members and also for
accessing dynamic array elements. In these cases the expr_type() and
enumeration() methods should reflect the member/element type.
When -pfileline=1 is used the queue procedural warnings have file
and line information added to the messages. Also switch the trace
debugging to be off by default.
Also, Add some preliminary missing darray functionality.
When strings are arguments to functions/tasks, that doesn't suddenly
make them implicitly scalar. Strings are vectors and should be treated
that was, even if they are IMPLICIT_REG.
We don't support evaluating user-defined system functions at compile
time. If possible, defer evaluation until run time. If used in a
constant expression, output a "sorry" message.
Casting from signed to unsigned types and vice versa is legal in SV,
as is casting from a larger to a smaller size. Obey Verilog rules
for expression bit width and signedness.
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.
This goes all the way down to the vvp level, where we create support
for arrays of objects, generate the new code in the -tvvp code
generator, and elaborate the arrays in the first place.
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.
Internally, treat the "$" as a special expression type that takes
as an argument the signal that is being indexed. In the vvp target,
use the $last system function to implement this.
This works by translating it to a $size() system function call.
The $size function is already implemented for dynamic queues and
it is easy enough to expand it for queues.
The netparray_t::slice_dimensions bug was the most insidious and
caused all manner of confusion. Also fix some other packed array
and unpacked array (and mixed) indexing calculations.
When an expression is elaborated, the compiler converts multiplies with
one constamt zero operand into a constant zero value. This is only valid
if the other operand is not a 4-state variable.
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.
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.
The code should only look at the real argument that exist any missing
arguments default to not being defined and hence needs to use the
default expression. Found with valgrind.
It is better to leave the handling of PChainConstructor calls to
the elaboration, instead of stripping them out early. This allows
for handling the arguments of the chain constructor in the correct
scope.
It is more common to find an unsized number on the right hand side
of a binary operator than on the left hand side, particularly for
comparison operations (e.g. x < 10 rather than 10 > x), so testing
the width of the right operand first is less likely to result in
the width needing to be retested. Counting the number of times an
operand width is retested when running the test suite confirms this;
before this change an operand width was retested 4869 times, after
the change an operand width was retested 99 times.
To be strictly compliant with the standard and compatible with other
EDA tools, unsized numbers should be treated as having a fixed size
(the same size as an integer). The -gstrict-expr-width option is
extended to allow the user to enable this behaviour.
This includes adding support for returning strings from functions,
adding initializing new darray with array_pattern strings, and
assigning an array_pattern of strings to a preallocated darray.
Also fix up support for initializing array with simple string
expression.
Turns out that call to eval_expr is redundant, and in degenerate
situations can lead to so many wasteful calls to eval_expr that
elaboration performance suffers dramatically.
For variable parameter selects (indexed and bit) pass the value being
selected as a parameter reference instead of just a numeric constant
so it is easy to get the underlying parameter information.
Move the parameter bit select code into its own routine and cleanup
the remaining general code.
This should not effect the VVP code, but the ivl_expr_parameter(<expr>)
routine can be used to get at the actual parameter information in the
vlog95 target.
Static properties are like variables in a named scope.
Detect these variables during elaboration so that the
code generator just sees them as variables.
The VHDL to_unsigned function with to arguments is best handled
in the ivl elaborator, so have it generate an $ivlh_to_unsigned
function call in the vhdlpp code, and implement it in the ivl
core.
Also, implement the 'length attribute as a $bits() call for
similar reasons.
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.
Class constructors are the "new" method in a class description.
Elaborate the constructor as an ordinary method, but the only
way to access this method is to implicitly call it. The elaborator
will take the constructor call and generate a naked "new" expression
and implicit constructor method call with the object itself as the
return value.
Rework lexical support for PACKAGE_IDENTIFIER so that the lexor
can help with package scoped identifiers.
Pform package types and package functions up to elaboration.