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.
This patch adds a number of compile and run-time checks for illegal
uses of variables declared in automatic tasks and functions. It
also adds a check for event expressions in automatic tasks that use
features not yet supported in VVP.
The natures of disciplines were already available, this just brings
the information forward to the ivl_target.h API and exposes them via
access functions.
The arguments of logical and/or are self determined, and the width is
fixed as 1 bit. Account for this special behavior by creating the
PEBLogic class.
The comparison operator operands are self determined, but are forced
to be the width of the wider operand. This means that the operands must
be evaluated with their widths truncated. In spite of all this, note
that comparisons expression results are 1 bit wide.
The condition expression needs its width tested, even if the width
is not used. Also clean up some handling of widths/types for other
expression types.
If either of the operands of a ternary expression are unsigned, then
both are treated as unsigned. It works just like a binary expression
in that regard.
Later passes need the intermediate results for width and size so that
some special cases, were self-determined arguments occur, can be
processed properly during elaboration. This can be especially tricky
and interesting for ternary expressions.
This patch removes all the checks for constant expressions performed
during the parsing phase, as these checks are (mostly) repeated during
elaboration. It adds the missing check in the elaboration phase (the
RHS of a register initialisation), and improves the error reporting
and error recovery in other checks.
This patch fixes pr2132552, which was caused by a fault in the parser
constant expression checking.
The arguments to user defined functions are self-determined. And if
the result is real valued, we can call them lossless self-determined.
Treat these arguments like r-value elaboration for assignments.
Also clean up the binary divide elaboration a little bit.
Also, floating point literals are unsized with width==1.
the PGAssign elaborate method used the test_width to get the width
of the r-value expression. This should be completely sufficient to
get the width of the expression, so always use a defined width to
elaborate the expression.
When the condition expression of a ternary is constant 1 or 0, we can
short-circuit the elaboration by only processing the clause (true or
false) that we need. This saves compile time and execution time.
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.
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.
Detect function call expressions that turn out to be calls to the
access function of a nature. Elaborate the access function and stub
the emit code. This gets the access function just short of the code
generator.
Contribution statements have an l-value and r-value. Parse those
expressions into pform so that elaboration has something to work with.
In this process, this patch also changes the PECallFunction class to
use the vector template instead of the svector template. The latter
doesn't add anything over the STL vector template, so this is a start
of working the svector out.
It is legal (though worthy of a warning, I think) for the part select
of an l-value to me out of bounds, so replace the error message with
a warning, and generate the appropriate code. In the process, clean
up some of the code for signal l-values to divide out the various kinds
of processing that can be done. This cleans things up a bit.
Part select of parameter names is fixed up to be structurally similar
to part select of signals, and also to behave similarly. (Though not
identically, for reason.)
The Verilog LRM specifies that it is legal to give constant part
selects that are beyond the bounds of the identifier being selected.
But elaboration was flagging that as an error. This patch changes it
to a warning, and handles the cases by generating 'bx bits as needed.
When left-shifting unsized constants in self-determined contexts, the
constant value is normally pared down to its minimum required width.
But this practically guarantees loss of bits. Instead, detect this
special case and give the unsized constant a width of an integer.
Still allow for the super-special case that the shifted value and the
shift amount are constants. In that case, the result width (and value)
can be calculated precisely and there is no need to resort to default
widths.
It is questionable, but probably legal, for expressions passed as
arguments to input ports of various kinds of gates to implicitly
declare nets. This patch allows the scan through different types
of expressions for implicit nets.
The elaborate_sig handling here does not test for the legality of
having a non-trivial expression as argument to a port. For example,
it is definitely NOT legal to have r-value expressions passed to
output or inout ports. But that will be checked for later when the
instance is elaborated for real.
If implicit nets are declared during elaboration, then the success
of binding during elaboration will depend on the order of the code
in the source file.
Comparison operands are signed only of both operands are signed.
If one is unsigned, then they both are unsigned. This does not
affect the signedness of the comparison itself, which is unsigned.
Signed-off-by: Stephen Williams <steve@icarus.com>
Here are some more array fixes. They are mostly better error messages
instead of just asserting and some code cleanup. The one new thing
that probably should have been a separate submission is that down
indexed part select [base -: width] can now be a lvalue.
The argument to $unsigned is self-determined no matter what the
context the $unsigned itself is in. This is important only where
the result can be negative but the result width is context-determined.
Do ocntext fitting manually to prevent the context fitting it and
affecting the expression argument.
Signed-off-by: Stephen Williams <steve@icarus.com>
In expressions, user defined functions have a clearly defined
width and the test_width expression needs to express that. Note
that the $signed/$unsigned functions are special and magical.
Signed-off-by: Stephen Williams <steve@icarus.com>
Non-constant indexed part select in continuous assignment generates
a select node with the correct width. In the process factor out and
share some of the part select calculations with expr part select
handling methods.
Signed-off-by: Stephen Williams <steve@icarus.com>