Commit Graph

585 Commits

Author SHA1 Message Date
Stephen Williams 03f912dc55 Clean up warnings
Clean up warnings that show up on newer compilers. Many of these warnings
are related to obsolete c library features or language features. This does
not clear up warnings in code generated by bison or flex.
2022-12-18 10:18:10 -05:00
Stephen Williams 2d6243ea6c
Merge pull request #816 from larsclausen/task-in-expr-fail
Report errors for task and void function calls in expressions
2022-12-17 11:12:39 -08:00
Lars-Peter Clausen d426e80c73 Fix error reporting when calling task in an expression
Calling a task as part of an expression should report an error. The current
implementation uses `func_def()` and if that returns nullptr will report
the error. But `func_def()` will trigger an assert if the underlying scope
is not a function.

Make sure to first check that the scope is actually a function before
trying to call `func_def()`. If the scope is not a function report an
error.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-15 21:07:04 -08:00
Lars-Peter Clausen abc26eeaeb Report error when calling void function in an expression
Unlike normal functions void functions can not be called as part of an
expression. Trying so will currently hit an internal assert.

Make sure an error is reported instead.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-15 20:52:09 -08:00
Lars-Peter Clausen e0ec2ed386 Do not allow to create objects of virtual classes
It is not allowed to create objects of virtual classes. Currently the
virtual keyword is accepted by the parser, but otherwise ignored.

Keep track of whether a class is virtual and generate an error when the
class new operator is used for a virtual type.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-13 21:27:53 -08:00
Dag Lem 1e3994e1fa Support for range indexing of arrays with swapped ranges within structs
This patch corrects range indexing of members in structs such as:

struct packed {
   bit [0:7] [7:0] a;
   bit [0:15] b;
} bar;
2022-11-15 18:11:18 +01:00
Stephen Williams 10a39e59a1
Merge pull request #781 from larsclausen/darray-type-compat
Improve type compatibility checking for dynamic arrays and queues
2022-10-14 08:15:50 -07:00
Lars-Peter Clausen e897e3ab5f Avoid confusing type compatibility error messages
Icarus allows to pass a value of the element type as an argument to the
dynamic new operator. To allow this the type compatibility check for
dynamic arrays allows both the dynamic array type itself and also the
element type.

This currently leads to a confusing error message if neither type matches.
The error message will say that the passed value is not compatible with the
element type. E.g.

```
  real d1[];
  int d2[];
  d1 = d2;
```

results in

```
error: the type of the variable 'd2' doesn't match the context type.
     : variable type=dynamic array of netvector_t:bool signed[31:0]
     : context type=real
```

This is slightly confusing. Change the way the error message is reported so
that the context type is the type of the dynamic array and not the element.
With the change the above results in

```
error: the type of the variable 'd2' doesn't match the context type.
     : variable type=dynamic array of netvector_t:bool signed[31:0]
     : context type=dynamic array of real
```

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-10-08 14:01:41 +02:00
Lars-Peter Clausen 46951c778e Handle default argument values for class function method calls
For class function method calls currently only as many arguments as have
been supplied are elaborated. Any trailing arguments that might have default
values are skipped. This will trigger an assertion later on in the vvp code
generator backend.

Fix this by making sure that all arguments of the function are evaluated.

Note that this already works correctly for class task method calls.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-10-05 08:49:25 +02:00
Lars-Peter Clausen 1fd968773e Support class objects as function return values
There is nothing special to do for return class objects from a function.
They can be handled the same as other objects such as dynamic arrays and
queues.

But there currently is an assert in the code that handles function calls
assigned to objects that will trigger if the target type is not an queue or
dynamic array.

This is because Icarus allows dynamic arrays to be initialized with a
single value and for that the element with of the dynamic array needs to be
known, so the single value expression can be evaluated correctly.

Since classes can not be initialized from vector expressions the width does
not matter in that case.

Update the code to only query the element width if the target type is an
dynamic array or queue and pass a placeholder value of 1 for the width
otherwise.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-09-19 18:20:16 +02:00
Lars-Peter Clausen a73ee3e3e7 Add support for SystemVerilog sign cast
SystemVerilog supports sign cast where it is possible to change the
signedness of an expression. Syntactical it is similar to width or type
casting, except that the keywords 'signed' or 'unsigned' are used in front
of the cast operator. E.g.

```
  logic [3:0] a = 4'b1000;
  logic [7:0] b = signed'(a); // b is 8'b11111000;
  logic signed [3:0] c = 4'b1000;
  logic signed [7:0] d = unsigned'(c); // d is 8'b00001000;
```

As noted by the LRM section 6.24.1 ("Cast operator") applying a sign cast
to an expression is equivalent to calling the $signed() and $unsigned()
system functions on the expression.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-09-11 19:06:22 +02:00
Lars-Peter Clausen e15b125da8 Replace svector with std::vector
The custom `svector` class is essentially a subset of `std::vector`. There
is no inherent advantage to using `svector`. Both have the same memory
footprint.

`svector` was designed to be of static size, but there are a few places in
the parser where it has to grow at runtime. Handling this becomes a bit
easier by switching to `std::vector` since it is possible to use its
methods which take care of resizing the vector.

This also allows to remove the unused parameter of the `lgate` struct
constructor, which was only needed for compatibility with `svector`.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-05-15 21:56:48 +02:00
Lars-Peter Clausen eeed05d9cd Handle class new assignment to non-class variables
Using a class new operator on a non-class variable should result in an
error. At the moment when using a class new operator on a dynamic array or
queue will result in an segmentation fault. This is because the
implementation assumes that the left hand side is of a class type.

Add a check in the class new operator implementation that the type of the
left hand side is a class. Report an error if it is not.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-04-30 21:13:55 +02:00
Lars-Peter Clausen 227cf20684 PECastType: Use elaborated data type
PECastType currently uses the unelaborated data type to make the decision
how to implement the cast. The unelaborated data type is provided by the
parser and this works as long as the parser knows the data type.

But for example with type parameters the actual data type is not known
until elaboration. In preparation for supporting type parameters make sure
to only use the elaborated type in the PECastType implementation.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-04-22 09:06:08 +02:00
Lars-Peter Clausen 5b8fb089bf Elaborate array assignment pattern values in the right context
The expressions within an array assignment pattern should be evaluated in a
context that is equivalent to an assignment to a variable of the element
type of the l-value array.

This is defined in section 10.9.1 ("Array assignment patterns") of the LRM
(1800-2017).

At the moment the values in an assignment pattern are evaluated in a self
determined context, which can lead to incorrect behavior.

Use the existing `elaborate_rval_expr()` function, which is meant for
elaborating assignments, to elaborate the assignment pattern values.

This solves the following issues:
 * implicit width conversion (including sign extension)
 * implicit type conversion (e.g. real to vector)
 * math operators that depend on the target width (e.g. addition)
 * use of expressions that require `test_width()` to be called. (e.g.
   unary operator)
 * use of concatenations
 * use of named constants (e.g. parameters or enums)

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-04-17 09:58:19 +02:00
Lars-Peter Clausen ff8a44b025 Add variant of elaborate_rval_expr() that only takes a data_type_t
The `elaborate_rval_expr()` function takes a `data_type_t`, a
`ivl_variable_type_t` and a `width` parameter. In most places the
ivl_variable_type_t and width are directly derived from the data_type_t.
This slightly simplifies the code.

The only place where this is currently not possible is when assigning to a
compound expression like a concatenation, e.g. `{a,b} = c;`.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-04-17 09:58:03 +02:00
Lars-Peter Clausen 3a26bbb59a Handle context signedness and width expansion for class properties
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.

This is currently not considered when accessing class properties. This can
lead to incorrect behavior with regards to sign extension.

E.g. the following will print 4294967295 rather than 65535.

```
class C;
  shortint x = -1;
endclass
...
C c = new;
$display(c.x + 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.

```
class C;
  shortint x = -1;
endclass
...
C c = new;
int x;
bit a = 1'b1;
x = a ? c.x : 64'h0;
```

Solve both of this by using `pad_to_width()` on the property expression if
it is a vectorable type. Since any identifier, not just class properties,
need to have this done insert this on the common path and remove the
`pad_to_width()` call on individual paths.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-04-14 11:55:09 +02:00
Lars-Peter Clausen 22cba1073c Handle context signedness and width expansion for method return types
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>
2022-04-14 11:55:09 +02:00
Lars-Peter Clausen 2f38adaeff Report correct queue method return type when call without parenthesis
When calling a queue method without parenthesis it gets elaborated through
the PEIdent path. On this path the type, width and signdess are not
reported for the method call. This leads to incorrect behavior in contexts
where those are important.

Correctly report the type, the same as when the method is called with
parenthesis.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-04-14 10:45:32 +02:00
Lars-Peter Clausen 156f08a1c5 Set default signedness of return types for built-in methods of SV types
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>
2022-04-14 10:43:59 +02:00
Lars-Peter Clausen 427091d3d3 Support access to class constants on objects
It is allowed to access a constant declared in a class scope, such as a
enum value or parameter, on an object of that class type. This is described
in section 8.5 ("Object properties and object parameter data") of the LRM
(1800-2017).

E.g.

```
class C
  enum { A } e;
endclass

C c = new;
c.e = c.A;
```

Support this by in addition of searching for class properties on the object
also search for constants in the class scope.

A bit of refactoring is needed around the parameter elaboration functions
since they expect a non-const NetScope, but for classes we only have a
const scope available.

The non-const scope is needed to be able to mark specparams as
non-annotatable. Since classes can't have specparams this part is factored
out into a separate function the NetScope parameter for the shared
functions is made const.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-19 13:45:14 +01:00
Lars-Peter Clausen 892622bf64 Add helper function to get parameter line info
The NetScope class has a method called find_parameter() that looks up the
parameter and returns a iterator to it. This is only ever used to get the
line information of the parameter.

Refactor the function so that it only returns the line info. This will
allow to call this function on a const NetScope object.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-19 12:52:19 +01:00
Lars-Peter Clausen c4feb89957 Handle unpacked array types for $bits()
For unpacked statically sized array types $bits() is supposed to return the
total size of the array. Accumulated the number of unpacked dimensions and
multiply it by the packed with of the base type to get the right result.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-13 15:03:49 +01:00
Lars-Peter Clausen 053453c645 Add support for explicit cast to enum
Assigning a value to an enum signal that is not of the same type as the
enum requires an explicit cast.

To support this attach the type of a type cast to the resulting expression.
This allows the assignment elaboration to confirm that value has been
explicitly cast to the right type.

Also handle the case where the value is a constant. In this case create a
NetEConstEnum instead of a NetEConst as the resulting expression.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-01-17 20:21:28 +01:00
Lars-Peter Clausen 9b7c99b8a8 NetEConstEnum: Remove unused scope_ field
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>
2022-01-17 20:21:28 +01:00
Lars-Peter Clausen 25dae60bb6 Add support for explicit cast to packed struct and packed array
Currently explicit cast is supported to atom2 and vector types. packed
struct, packed array and enum are not supported.

An explicit cast to packed type works the same for all packed types though.

Add support for handling also packed structs, packed arrays and enums by
make the code more generic and querying the packed base type from the
ivl_type_t.

To correctly handle enums a bit more work is necessary, which will be done
in a follow up patch.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-01-17 20:21:28 +01:00
Martin Whitaker ecbbb60fb6 Remove "using namespace std" from compiler header files and fix the fallout. 2021-11-04 16:55:03 +00:00
Martin Whitaker 83d9b5deda Rework PEIdent::test_width() to use new-style symbol_search().
This fixes issue #527.
2021-07-31 14:18:52 +01:00
Martin Whitaker e547a8355d Rework PEIdent::elaborate_expr() to use new-style symbol_search(). 2021-07-31 13:19:12 +01:00
Martin Whitaker b9863b4fde Store user-supplied path to object in symbol_search results.
(wanted by next commit)
2021-07-31 12:42:53 +01:00
Martin Whitaker 7d7aa0604c Properly report errors for out-of-bounds constant indexed part selects.
(replacing assertions)

The IEEE standard either requires out-of-bounds bits to be ignored on
write, returned as 1'bx on read, or requires a compile-time error message.
The latter is easier to implement.
2021-04-20 22:58:40 +01:00
Martin Whitaker 4af830187e Support indexed part selects that index sub-arrays (issue #497) 2021-04-20 21:29:00 +01:00
Martin Whitaker 7c024d6cab Fix width calculation for bit/part selects of multi-dimensioned packed arrays.
If we have a bit/part select that is selecting one or more sub-arrays, e.g.

  wire [3:0][3:0] foo;
  assign foo[1] = 4'd1;

we need to take into account the bit width of the sub-array when calculating
the bit width of the select.
2021-04-20 21:02:04 +01:00
Cary R 753bf516d6 Update the symbol search to find class properties 2021-02-16 23:46:02 -08:00
Cary R 18392a464d Some clean up and add initial support for elaboration system tasks 2021-02-01 00:22:01 -08:00
Cary R a73357ec72 Fix space issues 2021-01-30 00:47:45 -08:00
Cary R a446c34d10 Fix down parameter out of bound message 2021-01-30 00:40:25 -08:00
Cary R 0c12344b27 Fix warning and little E full vector up/down selects 2021-01-30 00:40:16 -08:00
Cary R 9e3d6cc996 Elaborate alternate constant ternary expressions to check for errors 2021-01-29 18:10:03 -08:00
Cary R 21c5fbe759 Remove compile warnings 2021-01-18 13:15:12 -08:00
Stephen Williams 287ba56ab4
Merge pull request #473 from steveicarus/steveicarus/queue-element-expressions
Rework of elaboration of function calls.
Rework of symbol_lookup function and API.
2021-01-18 11:58:26 -08:00
Stephen Williams 38b3c8efb2 Rework symbol_search function.
There are too many ad hoc handlers of symbol_search partial results.
Rewrite symbol_search to clean up things like partial results and
member/method detections. Use this reworked symbol_search function
to rewrite expression elaborate for the PECallFunction expressions.
2021-01-17 19:33:52 -08:00
Cary R 308c744e98 Fix index down part selects to work with multiple dimensions 2021-01-11 21:39:38 -08:00
Cary R 5442f3fee7 Add sorry messages for missing array methods 2021-01-07 22:26:47 -08:00
Cary R da7484eea1 Update compiler with suggestions from cppcheck 2021-01-02 14:04:46 -08:00
Cary R 99cb22fce0 Add the file/line info to the enum type 2020-12-30 15:22:15 -08:00
Stephen Williams c335c68973 Fix compilation of enum.name method.
The implementation was mostly there, but elaboration failed
due to some obsolete assumtions.
2020-12-30 13:41:08 -08:00
Stephen Williams a286764c1d Add support for string parameters
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.
2020-12-27 21:17:57 -08:00
Stephen Williams 16646c547c Rework parsing of parameter types
Use the common data_type_or_implicit rules to support type
definitions for parameters. This eliminates a bunch of special
rules in parse.y, and opens the door for parameters having
more complex types.
2020-12-27 21:17:57 -08:00
Cary R 51025149a9 Report operators that cannot be used with null/class vars 2020-12-27 19:05:49 -08:00