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.
The code that calculated the canonical index for a multi-dimensional
array access did not correctly estimate the index expression width
in the case that the first index value was a constant zero. This
patch fixes the problem, and, in passing, also makes the expression
calculation more efficient if any of the indices are constant zeroes.
This involves working out the code to get the base type of a select
expression of a darray. Also added the runtime support for darrays
with real value elements.
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.
The final step of expression elaboration is to reduce the width of
lossless/unsized constant expressions to the minimum needed to hold
the resulting constant value. This leads to unexpected results if
the user supplies a literal number with redundant digits that gets
passed to a system task that is sensitive to the width (e.g. $display).
This patch prevents width reduction occurring in this case.
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.
If a constant is padded the original constant will be freed and replaced
with a new one. This results in the ce pointer pointing to freed memory.
In reality the second check only needs to be done if the first one is
false so avoid the whole issue by only performing the second check if
the first on is false.
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>
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.
During elaboration, it is sometimes efficient to collapse a
collections of PV drivers to a net to a single concatenation.
This removes a bunch of resolutions and other nodes, and also
is the only way that 2-value logic should work.
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 fixes a bunch of objects to have the correct file/line
information. It also adds support for getting file/line information
for events (named events have a definition line).
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.
BOOL values have a specific cast from LOGIC, this node takes care
of it. Also arrange for the elaboration to insert them in the right
planes and for the code generator to generate them.
A real delay must be scaled and rounded using the local precision
before it is finally scaled to the simulation time units. This
patch fixes the compiler to do this correctly or generate the
correct code for run time calculated delays. Delays in a CA
already worked correctly. The run time was also fixed to scale
modpath (SDF back annotation) delays correctly.
You need to probe the expression width before trying to elaborate and
evaluate an expression. The eval_path_component() routine was missing
this and was causing an assert.
The Cygwin compiler is a bit picky. This patch adds some casts
to remove compilation warnings. In the past I have had warnings
off because of problems with the STL, but for this directory we
mas as well remove the warnings we can. It also does not
recognize that an assert(0) or assert(false) ends a routine so
it complains about no return at end of function or variables
not being defined.
The standard allows an output declared as "output reg" to be
given an initialization assignment in the output declaration.
this patch adds that functionality. Specifically:
output reg out = 1'b0;
works as expected.
This patch adds messages in various places to warn that constant
user functions are not supported. It uses a global variable to
indicate when we are in a constant context. This is a bit of a
kludge, but works well without needing to change a bunch of code.
It is interesting to note that ports are elaborated late enough
that if we had the constant function evaluation code they would
evaluate correctly. This also applies to the function return
range, the concatenation repeat, specparams and initial values.
Signal definitions are early enough that elaboration is what is
failing because the function body is not available (has not been
elaborated). The same thing applies to both parameters and
localparms.
This patch adds logical support for real values (!, && and ||). It
also prints an appropriate error message when a real value is
incorrectly given to an operator that does not allow real arguments
(bit-wise, reduction, shift and repeat/concatenation).
This fixes up the elaboration of binary expressions found in
parameter expressions. Parameter expressions are special because
they elaborate early, before all the other parameters are necessarily
completed.
The power (**) and shift operators are different from other binary
operators because their expression width calculations rely only on
their left operand, with their right operand self-determined. Get
the handling of these operators out of the PEBinary base class to
prevent confusion.
unary expressions that have problems should not assert in the
test_width method. Instead, let the error propagate back and be
handled during expression elaboration. This found a few places
where expression widths/types weren't probed before elaboration.
In the transition to the new expression code we forgot how to
handle the logical not (!) of a real value. This patch adds a
more appropriate error message until we get this reimplemented.
the sub_net_from function is used by the ::synthesize method of the
NetEUnary class to make the expression 0-N. By making that function
handle a real-valued net, the NetEUnary suddenly supports real-valued
nets, and this probably helps in other places as well.
The expr:::synthesize methods need not deal with saturating left or
right shifts if they are dealt with early, in elaborate_expr methods.
So the elaborate_expr for shift takes on much more responsibility.
Since NetExpr::synthesize methods were rarely used, then had a lot
of bugs. Now that continuous assign uses these methods, these bugs
must be fixed.
Binary and Unary minus properly pad/extens its arguments,
Case compare generates correct code,
Divide properly takes on signed flag,
Signed right shift sign-extends its argument to prevent loss of sign bits
and uses the NetSignExtend instead of simple padding,
Use the correct target node for reduction NAND,
Properly handle constant arguments of NetESelect
Handle some exressions that were not handled before, include abs()
and POW.
This patch adds .cast/int and updates .cast/real to act as a local
(temporary) net and to support either a signed or unsigned input.
The vvp_vector4_t class not can convert an arbitrarily sized double
to a vector value. This removes the restriction of lround().
Also document the new statements.
This handles the general case of a non-real operand to a real-valued
division. This can turn up if only 1 operand of a divide is real. In
this case the division as a whole is real and the other operand must
be cast to real.
This method creates an extra node, but it should be a very compact
node and this node does no evaluation tricks so in the run time should
be no more expensive then folding the cast into the .arith/div.r itself.
Part selects to signals are allowed to be off the ends of the signal
itself. The bits that are beyond the vector return X. This may mean
creating constant X bits on one or both ends of the result.
Before this, the types of parameters were always logic, only the
width and signed-ness could be controlled. A parameter may take
on implicit real values if the expression were real.
With this patch, the type for the parameter can be explicitly set
to logic or real. This also means that the parameter real valued
expressions need to be more crefully treated, possibly with casting
integral expressions to real values, or real expressions to integral
values.
Logical and/or take as inputs condition expressions, which are scalar
expressions. Be sure to reduce vectors using proper logic to get the
right condition value.
This patch reworks much of the ternary code to short circuit when
possible and supports real values better. It adds a blend operator
for real values that returns 0.0 when the values differ and the value
when they match. This deviates slightly from the standard which
specifies that the value for reals is always 0.0 when the conditional
is 'bx. There are also a couple bug fixes.
These fixes have not been ported to continuous assignments yet.
Ternary operators used at compile time and in procedural assignments
should be complete (short circuit and support real values).
Rework the handling of file names to use a perm_string heap to hold
the file names, instead of the custom file name heap in the lexor.
Also rename the get_line to get_fileline to reflect its real duties.
This latter chage touched a lot of files.
Better handle cases where the scope part of a heirarchical name does
not match any existing scope, or where scope index expressions are
not correct.
Signed-off-by: Stephen Williams <steve@icarus.com>
Handle real valued expressions in vector declarations. Also clean
up the handling of vector declaration expressions.
Signed-off-by: Stephen Williams <steve@icarus.com>