Commit Graph

772 Commits

Author SHA1 Message Date
Lars-Peter Clausen c0adbd0deb Add support for handling `super` keyword
SystemVerilog allows to use the `super` keyword to access properties and
methods of a base class. This is useful if there is for example an
identifier with the same name in the current class as in the base class and
the code wants to access the base class identifier.

To support this a bit of refactoring is required. Currently properties are
internally referenced by name, this does not work if there are multiple
properties of the same. Instead reference properties always by index.

In addition when looking up an identifier that resolves to an object return
both the type and the object itself. This is necessary since both `this`
and `super` resolve to the same object, but each with a different type.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-25 09:19:21 -08:00
Stephen Williams 580d79eae3
Merge pull request #820 from larsclausen/array-compatibility
Add error checking for continuous unpacked array assignments
2022-12-21 11:38:15 -08:00
Lars-Peter Clausen 5ec72f4cc8 Add error checking for continuous unpacked array assignments
Currently there is no error checking for continuous assignments to unpacked
arrays. If the lvalue and rvalue net are not compatible undefined behavior
occurs. For some types of incompatibility it will crash during elaboration,
for others it will crash during simulation, and for some it will just work,
even though the assignment is not allowed by the standard.

Implement checking to ensure the two nets are compatible as required by the
standard and report an error otherwise.

Two arrays are considered to be compatible if their element types are
equivalent, they have the same number of ranges and each range has the same
number of elements.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-17 15:29:38 -08:00
Lars-Peter Clausen 0e62ff153d Add support for void cast function call
SystemVerilog has explicit support for calling a function
as a statement. This is allowed when the function call is encapsulated in
`void'(...)`. E.g. `void'(f(1, 2, 3));`

We already support calling function calls as statements without the void
cast and emit a warning when doing so.

Adding support for void casts only requires to update the parser to handle
the void cast and then do not emit the warning if a function is called as
a statement as part of a void cast.

Void casting a task or void function call is not allowed and will generate
an elaboration error.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-17 11:19:30 -08:00
Lars-Peter Clausen 54956f0f29 Be consistent on allowing calling non-void function as task
When calling non-void functions or non-void methods of built-in types  as a
task a warning is issued. But when calling a non-void method of a user
defined class as a task an error is generated.

Be consistent here and generate a warning in both cases.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-17 11:19:30 -08:00
Stephen Williams 5b9ceee062 Make the for_step of for loops optional
In IEEE Std 1800-2017 A.6.8: the for_step part of the for loop
is optional. If missing, it is assumed that the programmer known
what they are doing.
2022-12-11 16:39:53 -08:00
Stephen Williams bb779112c7
Merge pull request #807 from steveicarus/steveicarus/issue801-empty-for-init
Handle empty for-loop init statement
2022-12-11 16:07:24 -08:00
Stephen Williams 78f37f7156 Handle for loops with empty initialization statement
For loops may have empty initialization statements. In that case some things
can't be done, such as loop unrolling or synthesis, but otherwise it is a
valid thing to do. So generate the correct code in this case.
2022-12-11 15:46:16 -08:00
Lars-Peter Clausen e141aef828 Allow to omit dimensions in foreach loop
SystemVerilog allows to skip dimensions in a foreach loop by not specifying
an identifier name for the dimensions. E.g. the following will iterate over
the first and last dimensions, but skip the middle dimension.

```
int x[1][2][3];
foreach(x[a,,b]) ...
```

Add support for this to the parser as well as elaboration.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-11 13:56:48 -08:00
Lars-Peter Clausen eaea5e7939 Print error if foreach loops variables exceed number of array dimensions
Currently when the number of loop variables in a foreach loop is larger
than the number of array dimensions an assertion is triggered.

Turn this into a error message instead for graceful error reporting.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-11 13:56:48 -08:00
Lars-Peter Clausen bdafdb1e65 Use std::swap() to exchange elaboration_work_list
Rather than moving one item at a time form the elaboration_work_list to the
temporary queue use std::swap to exchange them all at once. This is a bit
more efficient.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-11 12:38:47 -08:00
Lars-Peter Clausen d97c1bc6db Insert drivers for undriven nets
Trying to add a drive strength or delay to a undriven net will result in an
assertion. Make sure that a driver is added to undriven nets.

A driver is already added for all NetESignals, which covers most expression that
can produce a raw net rvalue. But there are other ways we can end up with just a
net as the rvalue, e.g.  when applying a sign cast to a net. The following
example triggers the issue

```
wire [7:0] a;
wire [7:0] b = $signed(a);
```

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-11-29 20:28:03 -08:00
Lars-Peter Clausen 85edd8bb18 Handle calling void function from class method
Calling a void function (or a regular function and ignoring the result)
from within a class method will currently result in an error unless the
void function itself is a method of the same class.

This is because we add the implicit `this` as an object on which to search
for the function and if we do not find it print an error. Change this to
only print an error if the implicit this was not added and it was a method
call on an object identifier.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-10-15 00:15:20 +02:00
Lars-Peter Clausen 246a0d3ce8 Allow inputs to be variables in SystemVerilog
SystemVerilog allows input ports to be variables. If something is connected
to the input port it will be converted to an unresolved wire.

This is handled the same as having a continuous assignment on a
SystemVerilog varibale.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-09-10 21:39:10 +02:00
Martin Whitaker 310e239637 Fix expansion of unbased unsized literal in port assignment (issue #756) 2022-08-27 16:16:49 +01:00
Henner Zeller 05a0622154 Add missing <algorithm> header, needed to use std::transform().
Signed-off-by: Henner Zeller <h.zeller@acm.org>
2022-08-04 09:40:17 -07: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 f19ba64614 trash 2022-04-17 09:58:11 +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 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 84c3c72563 Support recursive functions using `return` statement
A `return` statement in a function gets translated into a vvp `%disable`
instruction. This works fine as long as no recursion is involved. The
`%disable` instruction will stop execution of all active threads of a
particular scope. For recursive functions this means as soon as the inner
most function returns all containing outer function calls get disabled as
well. This results in incorrect behavior.

To make recursive functions using the `return` statement work use the new
vvp `%disable/parent` instruction. This instruction will only disable the
closest thread in the thread hierarchy that matches the target scope.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-04-11 22:03:02 +02:00
Stephen Williams e6bab92274 Implement the string val-to-a methods
These methods are tasks that write into the "this" object the value
passed as an argument, converted using the appropriate base.
2022-02-27 20:28:30 -08:00
Lars-Peter Clausen 1207e908b1 PScope: Keep parameter and localparams in the same list
During parsing parameters and localparams are kept in a separate list only
to be collected into the same list during elaboration.

Store them in the same list during parsing as well, this allows to remove
some duplicated code.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-10 11:07:03 +01:00
Martin Whitaker dcc9b59f6d Support SV [size] dimension for module and gate instances (issue #553).
Also output a proper error message if multiple dimensions are supplied
instead of failing an assertion.
2021-11-06 00:02:38 +00: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 c34167b2c0 Fix detection of directly nested generate constructs.
If a generate construct is enclosed in a begin-end pair, it can't
be directly nested (1364-2005 section 12.4.2).
2021-08-04 10:37:26 +01:00
Martin Whitaker 061121203b Fix segfault in wildcard port connection with unnamed port (issue #530).
A module port list may contain unnamed entries, e.g.

  module dut(a,);

When performing a wildcard connection, these entries should be skipped,
as there is no name to match.
2021-07-30 17:42:16 +01:00
Cary R eb5b04626d Handle elaboration tasks with a single string argument 2021-06-20 22:03:55 -07:00
Martin Whitaker 45db0db8b3 Check that port default values are constant expressions. 2021-03-12 23:27:19 +00:00
Martin Whitaker c7eaa06a2b Add support for module input port default values (issue #489). 2021-03-10 08:21:42 +00:00
Cary R 60a77b08d2 Add compiler and the start of vvp support for ->> 2021-02-19 23:21:51 -08: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 8484ff71ac Program supports NBA and BA to module variables 2021-01-30 14:28:48 -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 1bffc649cb Fix some cleanup code in the compiler 2021-01-07 23:53:53 -08:00
Cary R 5442f3fee7 Add sorry messages for missing array methods 2021-01-07 22:26:47 -08:00
Cary R 32787bb973 Add support for SV edge 2021-01-07 01:22:49 -08:00
Martin Whitaker ba25b55f53 Elaborate package scopes in textual order (fix for issue #461)
When elaborating a subclass, the base class scope needs to be elaborated
before the subclass scope. If the base class and subclass are defined in
different packages, this requires the package scopes to be elaborated in
the correct order. SystemVerilog reqires packages to be defined before
they are used, so that is the order we should elaborate them in.
2021-01-03 18:45:08 +00:00
Cary R da7484eea1 Update compiler with suggestions from cppcheck 2021-01-02 14:04:46 -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 cf53584733 Check if no argument task calls are allowed in the current context 2020-12-27 12:05:54 -08:00
Martin Whitaker a019994513 Fix search for class imported from another package (issue #437). 2020-12-23 19:16:14 +00:00
Cary R 71843a66f8 Add support for calling queue/darray functions as tasks 2020-12-20 16:50:11 -08:00
Martin Whitaker f8c49469fa Report a call to an unknown task as an error, not an internal error.
This error can certainly be triggered by invalid user code - see
issue #419.
2020-12-13 22:12:02 +00:00
Martin Whitaker fbd87b4fee Add extra debug output. 2020-12-13 21:49:42 +00:00
Martin Whitaker 393236a9a8 Fix assertion failure when elaborating a void function call (issue #318)
Depending on the order of elaboration, a function may not have been
elaborated before a call to it is elaborated, so don't assert that it
has been. As an optimisation, try to elaborate it on the fly, so we can
elide the call if the function body is empty.
2020-12-13 21:42:13 +00:00
Martin Whitaker 94b503fc64 Fix assertion failure for function body with single null statement (GH issue #411) 2020-12-10 17:40:30 +00:00
Cary R c37f1c9309 An input port driven by a variable is not collapsible 2020-11-30 22:48:39 -08:00
Martin Whitaker 55e06db693 Support calls to inherited methods without "this." prefix (GitHub issue #388). 2020-11-23 22:03:59 +00:00