The signedness of an expression can change depending on its context. E.g.
for an arithmetic operation with one unsigned operand all operands are
treated as unsigned.
For methods, both on built-in SystemVerilog types as well as user defined
classes, this is currently not considered. This can lead to incorrect behavior
if the value is sign extended.
E.g. the following will print 4294967295 rather than 65535.
```
shortint q[$];
q.push_back(-1);
$display(q.pop_front() + 32'h0);
```
Furthermore the return value is not expanded to the width of its context.
This can cause vvp to crash with an exception when it expects a vector on
the stack to have a certain width.
E.g.
```
int d[];
longint x;
bit a = 1'b1;
x = a ? d.size() : 64'h0;
```
Solve both of this by using `pad_to_width()` on the method return value if
it is a vectorable type. Since any function call, not just methods, needs
to have this done to its return value insert this on the common path.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The result for the built-in methods for the SystemVerilog types is
currently always unsigned. This can lead to incorrect behavior if the value
is sign extended or passed as an argument to a system function (e.g.
$display).
For most built-in methods this does not matter, since even though they have
a signed return type, they will not return a negative value. E.g. the
string `len()` or queue `size()` functions.
It does make a difference though for the queue `pop_front()` and
`pop_back()` methods. Their return type is the element type of the queue.
If the element type is signed and the value in queue is negative is will be
handled incorrectly.
E.g. the following will print `4294967295` rather than `-1`.
```
int q[$];
q.push_back(-1);
$display(q.pop_front());
```
To correctly support this consistently assign the actual data type of the
built-in method's return value to the `NetESFunc`, rather than just the width
and base type. The width, base type and also the signedness can be derived
from the data type.
Note that this only fixes the default signedness, but not the case where
the signedness of the expression is changed by its context (e.g. in
arithmetic expression). Handling this will require some additional work.
Also note that assigning the actual data type is also required to support type
checking on the return value, e.g. as needed for enum types.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Parameter expressions need to remember the scope they have been declared in
so that the code generator backends can insert the right parameter
reference, rather than a constant value.
Currently the scope is stored as a non-const reference. But that is not
needed. Mark the scope reference as const so NetEConstParam and
NetECRealParam can be created when only a const scope reference is
available.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The scope_ field of the NetEConstEnum class is initialized in the
constructor, but never used anywhere again. Remove it.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Parameters can have string type and do the usual string stuff,
and also implement some of the string methods on string parameters
so that they evaluate down to constants.
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.
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.
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 provides the ivl_target.h interface for class definitions
and expressions, the vvp code generator support for class objects
and properties, and the vvp run time support. Trivial class objects
now seem to work.
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.
Strings, when put into dynamic arrays, are treated as first class
types much line reals. Add the code generator and vvp support for
this situation. Also fix a bug distinguishing between character
selects from strings and select form arrays of strings.
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 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.
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 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.
The pform propagates the parsed enum base type information
to the elaborator so that the base type can be fully elaborated.
This is necessary to get the types of the enumeration literals
correct.
When enum names are used as r-values in expressions, use their
values. Treat the enum names similar to (but not exactly as)
localparams so that they fit into the rest of the elaboration
flow naturally.
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.
In some cases, it was possible for the NetEConcat expression to
lose track of the repeat expression, causing the output result to
have a broken concatenation expression.
This also adds some internal checks that the concatenation widths
add up properly.
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.
Continue cleaning up shadowed variables, flagged by turning on -Wshadow.
No intended change in functionality. Patch looks right, and is tested
to compile and run on my machine. No regressions in test suite.
When doing lossless addition to an unsized constant, we make the size
be width of an integer, only to be consistent with other tools. In fact,
don't go overboard if we don't have to.