Commit Graph

10116 Commits

Author SHA1 Message Date
Stephen Williams 1e84e78cd6
Merge pull request #799 from larsclausen/foreach-omit
Allow to omit dimensions in foreach loop
2022-12-11 15:31:49 -08:00
Lars-Peter Clausen fbfb6016c1 Add regression test for using packed scoped type identifier in class
Check that it is possible to use a packed scope type identifier for the
type of a class property when the class is defined in the unit scope. This
makes sure that the elaboration is done in an order so that the type is
available when the class property is elaborated.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-11 14:10:40 -08:00
Lars-Peter Clausen 68d89bbe05 Add regression test for referencing forward declared classes
Check that it is possible to use a forward declared class type as the type
of a property in another class.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-11 14:10:40 -08:00
Lars-Peter Clausen b4b591adba Elaborate class properties during signal phase instead of scope phase
Elaborating uses a multi stage approach. Currently non-static class
properties are elaborated during the scope elaboration phase. This can
cause problems if the type of a property is declared in a different scope.
In that case it is possible that the scope in which the type is defined has
not been elaborated yet and the type is not available. E.g.

```
package P;
  typedef int T;
endpackage

class C;
  P::T x;
endclass
```

Another area where this is problematic is when a class has a property of a
another class that has a forward declaration. In this case the type of the
forward declared class, which is created when the scope is elaborated, is
not available when the scope of the class that is using it is elaborated.
E.g.

```
typedef class B;

class A;
  B b;
endclass

class B;
endclass
```

To avoid this elaborate the properties during the signal elaboration phase.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-11 14:07:53 -08:00
Lars-Peter Clausen 0e86e99358 Add regression tests for omitted foreach dimensions
Check that it is possible to omit one or more dimensions in a foreach loop.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-11 14:06:30 -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 f8401095aa Add regression test for too many foreach loop indices
Check that an error is reported if too many indices are specified
in a foreach loop.

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 aec1ee5a42 Add regression tests for type parameters
Check that all sorts of variations of type parameters are supported.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-11 13:50:27 -08:00
Lars-Peter Clausen 5ef847ea87 Support type parameters
SystemVerilog supports type parameters. These are similar to value
parameters, but they allow to pass a type to a module or similar when
instantiating it.

E.g.

```
module A #(parameter type T = int);
endmodule

module B;
  A #(.T(real)) i_a;
endmodule
```

Add support for handling type parameters.

For the vlog95 and vhdl backends type parameters, similar to typedefs, get
replaced with their actual value. For modules with non-local type
parameters for each module instance a unique module or architecture is
generated with the actual type.

Querying type parameters through VPI is not yet supported.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-11 13:50:14 -08:00
Stephen Williams 3509cc86f8
Merge pull request #804 from larsclausen/swap-elaboration_work_list
Use std::swap() to exchange elaboration_work_list
2022-12-11 13:17:09 -08:00
Stephen Williams 1434936aaa
Merge pull request #802 from larsclausen/forward-typedef
Add support for forward type declarations
2022-12-11 13:16:17 -08:00
Stephen Williams e97b7c4c56
Merge pull request #803 from steveicarus/steveicarus/document-vvp-debugmode
vvp: Document the vvp interactive debug mode
2022-12-11 13:07:39 -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
Stephen Williams 06c819849f vvp: Document the vvp interactive debug mode
Vvp has an interactive debug mode that few seem to be aware of. Document
that mode.
2022-12-11 12:12:24 -08:00
Lars-Peter Clausen 10e35d1573 Add regression tests for circular type definitions
Check that circular type definitions are detected and an error is
reported.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-11 10:38:08 -08:00
Lars-Peter Clausen 3787eca248 Add regression tests for forward typedefs
Check that all sorts of forward typedefs are supported.
Also check that any recursive use of a type results in an error.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-11 10:37:46 -08:00
Lars-Peter Clausen cdc9629ce7 Add support for forward type declarations
SystemVerilog supports forward type declarations. This allows to declare a
type identifier and use it, e.g. in a signal declaration, before declaring
what the actual type is. The type still needs to be fully defined
eventually in the same scope as its forward type declaration. E.g.

```
typedef T;
T x;
typedef int T;
```

The forward type definition can also contain the kind of the type it is
going to be. E.g struct, union, class, etc. The LRM calls this the basic
type. If the actual type is not of the basic type specified in the forward
type declaration this is an error. E.g.

```
typedef struct T;
typedef int T; // Error, int is not a struct
```

It is legal to have more than one forward type declaration for the same
type name, as long as the basic type is the compatible. It is even legal to
have a forward type declaration after the actual type has already been
declared. E.g.

```
typedef T;
typedef int T;
typedef T;
```

Implement support for forward type definitions as part of the new
typedef_t. The basic type will be attached to the typedef_t.

The compatibility of the basic type for multiple forward type declarations
will be checked in the parser. The compatibility of the basic type to the
actual type will be checked during elaboration, once the actual type is
known.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-11 10:19:59 -08:00
Lars-Peter Clausen 699ceb15a5 Elaborate enum type on demand
Enum types are currently elaborated in lexical declaration order. With forward
typedefs it is possible that a type is referenced before it is declared.

To support this elaborate the enum type on demand when it is used. This is
similar to what is being done for other types.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-11 10:18:23 -08:00
Lars-Peter Clausen 8ee9d6b5ea Detect circular type definitions
With forward type declarations it is possible to create a circular type
definition where a type resolves to itself. E.g.

```
typedef T1;
typedef T1 T2;
typedef T2 T1;
```

Flag a type as elaborating when elaboration of the type is started and
clear it when elaboration finishes. If the elaboration function is entered
again while the flag is still set a circular type has been detected and an
error is reported.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-11 10:18:23 -08:00
Lars-Peter Clausen 2e0d6d5af1 Allow to attach additional information to typedefs
Currently typedefs are just a pointer to a data_type_t.

Currently typedefs are implemented by setting the name field of a
data_type_t when a typedef of the type is declared. This works mostly, but
there are some corner cases that can't be supported.

E.g. a typedef of a typedef does not work as it overwrites the name field
of the same data_type_t multiple times.

Forward typedefs can also not be supported since forward typedefs allow to
reference a type before it has been declared.

There are also some problems with type identifier references from a
higher-level scope if there is a type identifier in the current scope with
the same name, but it is declared after the type identifier has been
referenced. E.g. in the following x should be a vector fo width 8, but it
will be a vector of width 4, because while the right type is used it is
elaborated in the wrong scope.

```
localparam A = 8;
typedef logic [A-1:0] T;
module M;
  localparam A = 4;
  T x;
  typedef int T;
endmodule
```

Furthermore typedefs used for the type of ports are elaborated in the wrong
scope.

To handle these corner case issues introduce a data_type_t for typedefs.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-11 10:18:22 -08:00
Stephen Williams 3bea115c51
Merge pull request #798 from larsclausen/genvar-compressed
Support compressed assignment statements for genvar loops
2022-12-04 19:45:50 -08:00
Stephen Williams fdc7b0e1bd
Merge pull request #796 from jrrk2/isnan_patch
Explicitly refer to std::isnan to avoid clash with system standard library
2022-12-04 19:43:32 -08:00
Lars-Peter Clausen 9553a872da Add regression test for compressed assignment statement in genvar loops
Check that compressed assignment statements are supported for genvar loops.
This is supported in SystemVerilog, but not in Verilog.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-04 14:37:21 -08:00
Lars-Peter Clausen 410c8207ef Support compressed assignment statements for genvar loops
SystemVerilog supports using compressed assignment operators for the genvar
for loop variable update.

Add support for this in a similar way as increment/decrement operators by
transforming the statement to its uncompressed equivalent. E.g. `x += y`
gets transformed to `x = x + y`.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-04 14:37:21 -08:00
Stephen Williams 3438078c90
Merge pull request #795 from larsclausen/gh793-add-driver
Insert drivers for undriven nets
2022-12-02 18:03:32 -08:00
Stephen Williams a5a078ae08
Merge pull request #789 from daglem/struct-array-swapped-range
Support for range indexing of arrays with swapped ranges within structs
2022-12-02 18:02:17 -08:00
Jonathan Kimmitt fc2d9372ef Explicitly refer to std::isnan to avoid clash with system standard library 2022-12-02 16:10:36 +00:00
Lars-Peter Clausen 9e37f4382e Add regression test for issue #793
Check that $signed/$unsigned works when being combinatorially assigned with a
delay and the target of the function is a net without any drivers.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-11-29 20:28:03 -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
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 74c52d6fa1
Merge pull request #786 from Forty-Bot/ivlpp_segfault_fix
ivlpp: Fix segfault in macro_start_args
2022-10-30 16:00:49 -07:00
Sean Anderson b18d90a2d9 ivlpp: Fix segfault in macro_start_args
macro_start_args truncates def_buf, but does not check to ensure that
someone has allocated def_buf first. This will cause a null pointer
dereference if the first access to def_buf while parsing a file is a
macro invocation. Fix this by avoiding truncating def_buf if it is NULL,
as it is effectively already truncated.

Fixes: 680196953 ("Add support for text macros with arguments.")
Signed-off-by: Sean Anderson <seanga2@gmail.com>
2022-10-30 18:02:40 -04:00
Stephen Williams c2dbf4e483
Merge pull request #785 from larsclausen/type-ref
Improve handling of type identifier references
2022-10-16 20:52:52 -07:00
Stephen Williams 0c8c642022
Merge pull request #784 from larsclausen/class-call-void
Handle calling void function from class method
2022-10-16 20:52:13 -07:00
Stephen Williams 5a98e50db7
Merge pull request #783 from lparkes/master
Add #include <cstdarg> to all source files that use va_list
2022-10-16 20:51:38 -07:00
Martin Whitaker 01a11cce56 Handle C-style comments following a `include directive (issue #782) 2022-10-16 22:03:37 +01:00
Lars-Peter Clausen b9bc06951a Add regression tests for scoped type identifier references
Check that it is possible to have scoped reference to a type identifier in
a package.

 * As part of variable declarations
 * As an argument to a system function
 * As the type in a type cast

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-10-15 12:32:32 +02:00
Lars-Peter Clausen 998d0c655d Add regression test for chained type definitions
Check that chained type definitions declared in different scopes are
handled correctly.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-10-15 12:32:32 +02:00
Lars-Peter Clausen 54afdc1e6b Add regression test for module port with vector typedef
Check that for a module port with a vector type identifier the type is
elaborated in the scope where it is declared rather than the scope of the
module port.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-10-15 12:32:32 +02:00
Lars-Peter Clausen b7fce4a66e Improve handling of type identifier references
Currently when referencing a typedef this gets replaced with the
`data_type_t` that the typedef points to. This works for most cases, but
there are some corner cases where it breaks down.

E.g. it is possible to have a scoped type identifier which references a
type defined in a package. For such type identifiers, only the data_type_t
itself is remembered, but not the package scope. This will cause the type
identifier to be elaborated in the wrong scope.

Furthermore type identifiers of vector types used for module or task port
might not be elaborated in the correct scope.

Introduce a new `typeref_t` which has `data_type_t` as a base type and can
be used as the data type for a signal. A new instance of a `typeref_t` is
created when referencing a type identifier. The `typeref_t` remembers both
the data type and the scope of the type identifier.

When elaborating the `typeref_t` the elaboration is passed through to the
referenced `data_type_t`. But special care is taken to lookup the right
scope first.

With the new approach also typedefs of typedefs are supported. This
previously did not work because chained typedefs all reference the same
`data_type_t`, but each typedef sets the `name` field of the `data_type_t`.
So the second typedef overwrites the first typedef and a lookup of the
scope of the first typedef by name will fail as it will return the scope of
the second typedef.

This refactoring also allows to define clear ownership of a data_type_t
instance. This e.g. means that an array type owns its base type and the
base type can be freed when the array type itself is freed. The same is
true for signals and class properties, they now own their data type and the
data type can be freed when the signal or property is freed.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-10-15 12:32:22 +02:00
Lars-Peter Clausen 20d82bbdcb Simplify class end label parser rule
The current class end label parser rule gets the data type from the
TYPE_IDENTIFIER, casts that to a class_type_t and gets the name from that.
This code was written when the TYPE_IDENTIFIER only provided the data type.

But these days it provides both the data type and the name. Simplify the
code to get the name directly from the TYPE_IDENTIIFER.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-10-15 12:32:02 +02:00
Lars-Peter Clausen 0a2cbcb4b7 Remove pre C++11 compatibility code for unique_ptr
There is compatibility code that defines unique_ptr  as auto_ptr if the C++
version is before C++11.

But there are already other parts of the codebase that do require C++11 and
the minimum required version to build the project is C++11. So remove the
compat code as it is no longer needed.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-10-15 12:32:02 +02:00
Lars-Peter Clausen 4522709c06 Use C++11 for building the project
There are C++11 constructs in Icarus at the moment and the plan is to
retain C++11 compatibility until more modern versions are widely available
in the default installation of systems.

Pass `-std=c++11` to the compile to enforce building with C++11, this will
make sure that neither an older nor a newer version is used. E.g. compilers
on some platforms still default to an earlier version of C++11.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-10-15 12:32:02 +02:00
Lars-Peter Clausen 9107e298a3 Add regression test for calling void functions from class method
Check that it is possible to call a void function from a class method.
Check this for both functions defined in the global scope as well as
functions that are methods of the class or a base class.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-10-15 00:15:36 +02: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
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
Stephen Williams b0c262de80
Merge pull request #780 from larsclausen/nb-auto-struct-fail
Prevent non-blocking writes to fields of automatic structs
2022-10-14 08:13:53 -07:00
Stephen Williams 8bbddfb69f
Merge pull request #779 from larsclausen/method-call-default
Handle default argument values for class function method calls
2022-10-14 08:11:45 -07:00
Stephen Williams 90538e4193
Merge pull request #778 from larsclausen/ps-identifier
Improve parsing of package scoped identifiers
2022-10-14 08:10:24 -07:00