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.
This patch implements the evaluate_function method for the NetDisable
and NetSTask classes. It also makes the checks for a function being
constant work when the function contains nested scopes (named blocks).
If a ternary expression with mixed logic and real operands is
short-circuited and the logic value is selected, that value
should be cast to a real value.
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.
Add properties to the classes, and elaborate expressions that
have class properties. Describe class object property references
all the way down to the stub target.
The compiler doesn't currently check that the width of an indexed
part select is non-zero. If code contains this erroneous case, the
compiler can crash (with an assertion failure). This patch causes
the compiler to output a suitable error message and recover. It
also fixes a potential crash if an illegal expresson is encountered.
Implement through the ivl core to the ivl_target.h API.
Also draft implementation of creating and storing arrays
in the vvp runtime and code generator.
This patch extends the compiler to support all specparam declarations
allowed by the 1364-2005 standard. For compatibility with other
simulators, it allows specparam values to be used in any constant
expression, but outputs a warning message and disables run-time
annotation of a specparam if it is used in an expression that must
be evaluated at compile time.
This handles a few cases where the non-constant bit selects are
in the final index. This doesn't handle all the cases of packed
arrays, but it handles some common cases.
Add an implementation for the enumeration name() method. This currently
only works if the context defines the return width (e.g. the result is
assigned to a variable). It does not work in a self-determined context
(e.g. as an argument to a system function or in a comparison). This is
a limitation in the compiler/code generator/run time not the method
implementation provided here. We may need full string support to make
this work 100%.
Rework the actual next() and prev() methods to correctly process the
numeric count argument. Also rework the compiletf routine to give better
error messages and combine the call routine for the two methods.
Add a compiletf routine that checks the arguments and then report that
the name() method is not currently implemented.
Add code to allow an enumeration method to be called as a function.
This is only the compiler support. The runtime support is still missing
so only an empty argument call will succeed (e.g. next(), etc.). For now
the rest get a warning message.
This patch fixes a few more bugs in the enumeration code.
It add support for saving the file and line information to make
diagnostic messages better.
It updates some of the compiler warning messages to use the file
and line information.
It passes if the enumeration type is signed all the way to the
code generators.
It fixes the parser to correctly have the range after the signed
designation for the vector types.
It adds a warning that vvp does not currently support a negative
two state enumeration value.
The patch adds necessary error checking to verify that the operands of
increment decrement operator is not number.
Signed-off-by: Prasad Joshi <prasad@canopusconsultancy.com>
This patch adds support for increment/decrement operators as an
expression. The operations on real and vector slices have been
disabled for now.
These operators can be used as in independent statements. However, the
corresponding support is not added in parser.
Changes since V2:
- Additional error checking in elaboration to deny operation on vector
slices and real (suggested by Martin)
Changes since V1:
- Use 'i' and 'I' for increment (suggested by Cary)
- Evaluate sub-expression once (suggested by Cary and Stev)
- Add necessary checks during elaboration to ensure that the
expression is valid (suggested Stev)
- Proper width handling with vectors (suggested by Martin)
Signed-off-by: Prasad Joshi <prasad@canopusconsultancy.com>
The -gno-specify flag should only control the delay and timing checks.
It should not also remove the specparams since they can be used outside
of a specify block.
This patch adds code to properly calculate the type and width of a
specparam when it is used in an expression.
This patch also fixes a compiler crash when an unknown identifier is
used in a delay expression.
If the right hand operand of a shift is a signed vector value, it
is coerced to an unsigned value. This needs to be allowed for when
estimating the width expansion caused by a shift in a lossless
expression.
This patch allows the compiler to perform early elaboration
of functions if they are encountered in expressions that are
elaborated before the function would normally be elaborated.
This makes the function available for constant evaluation.
Suitable error messages are generated if a function that is
used in a constant expression is not a valid constant function.
When a user or system function is called on the RHS of a continuous
assignment, and one of the function arguments is an undeclared
identifier, the compiler reports the error correctly but then
crashes. This patch fixes the crash.
This patch changes the method used to signal that a constant expression
is being elaborated from flags stored in global variables to flags
passed down the call chain. It also generates more informative error
messages when variable references are found in a constant expression.
This patch ensures that the result of a shift is an undefined value
if the right operand is an undefined value. It also improves the
code generated for right shifts where the right operand is constant
and optimises away shifts where the right operand is a constant 0.
It also fixes a few places where the expression type (signed/unsigned)
was not being set correctly.
This patch adds a check on the expression type before adjusting an
unsized expression width up to integer_width. This adjustment should
only be performed for vectorable expressions.
The patch also fixes a few compiler warnings that only show up on
32-bit builds.
This patch modifies the compiler and the ivl interface to pass the
type of indexed part select that is being represented (up/down) in
a procedural L-value or R-value. This is needed by any back end that
wants to correctly denormalize the (zero based) base expression.
Constant user functions aren't currently supported. A suitable
error message should be output when a user function call is
encountered in a parameter expression. This got lost in the
parameter expression rework.
The compiler currently performs parameter expression elaboration before
performing parameter overrides. This means that the information needed
to correctly determine the expression type and width may not be available
at the time elaboration is performed. This patch reworks the code to
delay elaboration until after all overrides have been performed. It
also provides a new -g option that controls how the width of parameter
expressions is calculated when the parameter itself is unsized.
This gets the enumeration type through to the ivl_target API so
that code generators can do something with it. Generate stub
output with tgt-stub, and generate the proper vvp run time to
make simple enumerations work from end to end.
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.
This patch changes all the iterator code to use a prefix ++ instead
of postfix since it is more efficient (no need for a temporary). It
is likely that the compiler could optimize this away, but lets make
it efficient from the start.
I'm adding more uses of the make_range_from_width function, so
it seems like time to get rid of its use of the svector template.
This thread led to a lot of other uses of svector that had to
also be removed.
An unsized signed constant that is smaller than integer_width needs
to be resized up to either the integer_width or the expression width
whichever is smaller.
This patch mimics what was done for vectors, but is simpler since
arrays don't use the endian information. It also needs to address
the fact that .array/port assumes the expression is unsigned so
any signed expression must be padded to make it larger than the
maximum array word when it is converted to unsigned.