Commit Graph

51 Commits

Author SHA1 Message Date
Martin Whitaker e22831553d Improve identifier lexical position accuracy in declarations.
Enhance the lists of identifiers and declaration assignments generated
by the parser to associate each identifier with its lexical_pos. Also do
this for single items in complex parser rules where the location passed
to the pform is not the location of the identifier.
2024-02-19 18:16:35 +00:00
Lars-Peter Clausen 763907b0e5 Add a typedef for `std::vector<netrange_t>`
`std::vector<netrange_t>` is used for signal array dimensions. As such it is
used in quite a few places.

Add a typedef that can be used as a shorthand to refer to it. This helps to
keep lines where this is used from growing to overly long.

The new type is called `netranges_t`.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-09-09 05:50:40 -07:00
أحمد المحمودي (Ahmed El-Mahmoudy) 08aee81924 Fix typos 2023-05-17 07:08:00 +02:00
Lars-Peter Clausen 6713b343cc Report error for packed struct default member values
SystemVerilog allows struct members to have default values specified as
part of the struct declaration. But this is only allowed for unpacked
structs. For packed structs an error should be reported. This is defined in
section 7.2.2 ("Assigning to structures") of the LRM (1800-2017).

Currently default member values are just silently discarded if specified
for a packed struct. Make sure to report an error instead.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-27 08:46:53 -08:00
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
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
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
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
Stephen Williams 0d180ae465
Merge pull request #769 from larsclausen/struct-member-unpacked-array
Handle unpacked dimensions for struct and union members
2022-09-18 08:27:41 -07:00
Lars-Peter Clausen 832917008c Handle unpacked dimensions for struct and union members
Unpacked dimensions for struct or union members are currently silently
discarded. E.g.

```
struct packed { int x[2]; } s;
```

will elaborate successfully as a struct with a non-array int typed field.

This should instead elaborate to an unpacked array of ints typed field. And
subsequently, since unpacked arrays are not allowed in a packed struct or
union, result in an error instead.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-09-15 12:53:29 +02:00
Lars-Peter Clausen d6337a5bc5 parray_type_t: Check if base type is packed after elaboration
Packed arrays are only allowed of packed base types. Currently whether the
base type is packed is checked before elaborating the base type.

This works as long as the actual type is known before elaboration. But for
example with type parameters the actual type is only known after
elaboration. In order to be able to support type parameters move the check
for whether the type is packed after elaboration.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-09-15 10:06:43 +02:00
Lars-Peter Clausen 37f9cde49f Handle scalar typed parameters
Parameters without any type or range specification inherit the type from
the value that has been assigned to it. Similarly a parameter with just an
`signed` or `unsigned` keyword will inherit its range from the value
assigned to it.

In the current implementation any vector type parameter that does not have
a range specification inherits the type form the assigned value. That
includes parameters with an explicit scalar vector type. E.g.

```
parameter bit X = 10
```

Make sure that a parameter only uses the width from the assigned value if
the parameter does not have an explicit data type.

To support this we need to remember whether a `netvector_t` was declared as
an explicit or implicit data type. Currently this information is only
available on the unelaborated `vector_type_t`.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-05-02 14:33:31 +02:00
Lars-Peter Clausen 724d7d4282 Consolidate unpacked array type elaboration
There are currently two implementations for elaborating unpacked array
types. One that is used when elaborating a signal with an unpacked array
type and one that is used everywhere else using the elaborate_type()
infrastructure.

The elaborate_type() implementation is less complete and for example does
not support bounded queue types.

Consolidate both into a single implementation to reduce duplicated code and
get consistent behavior. This for example makes sure that the maximum queue
size is respected when used as a function return type.

Nested data structures of arrays, dynamic arrays or queues are not yet
supported. In the current implementation when encountering such a type an
assert will be triggered and the application crashes. In the new
implementation an error message will be printed without crashing the
application.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-04-18 09:58:02 +02:00
Lars-Peter Clausen 27f3fcc5f1 Allow queue types outside of classes
Currently the elaboration function for unpacked array types prints an error
for queues that they are not allowed inside classes. And while this error
gets triggered when declaring a property with a queue type, it also gets
triggered for other places that uses a queue type, e.g. a function return
type. The only exception is signals which uses a different internal code
path when elaborating queue types.

Move the error message, that is class property specific, to the class
property elaboration. This also makes sure that the error messages
references the line where the property is declared and not the line where
the type is declared.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-04-17 09:14:38 +02:00
Lars-Peter Clausen f6042033d0 Correctly handle separate port type declaration for `integer` and `time`
When using non-ANSI style port declarations it is possible to declare the
port direction and the data type for the port in separate statements. E.g.

```
input x;
reg x;
```

When using packed array dimensions they must match for both declarations.
E.g.

```
input [3:0] x;
reg [3:0] x;
```

But this only applies for vector types, i.e. the packed dimension is
explicitly declared. It does not apply to the `integer` and `time` types,
which have an implicit packed dimension.

The current implementation requires that even for `integer` and `time`
types the implicit dimension needs to be explicitly declared in the port
direction. E.g. the following will result in a elaboration error
complaining about a packed dimension mismatch.

```
module test;
  output x;
  integer x;
endmodule
```

Currently the parser creates a vector_type_t for `time` and `integer`. This
means that e.g. `time` and `reg [63:0]` are indistinguishable during
elaboration, even though they require different behavior.

To fix let the atom2_type_t handle `integer` and `time`. Since it no longer
exclusively handles 2-state types, rename it to atom_type_t.

This also fixes a problem with the vlog95 target unit tests. The vlog95
target translates

```
module test(output integer x);
endmodule
```

to

```
module test(x);
  output x;
  integer x;
endmodule
```

which then fails when being elaborated again. There were some regression
tests that were failing because of this that will now pass.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-03-28 10:40:06 +02:00
Lars-Peter Clausen eed38bd14a Handle multiple instances of modules with class definitions
For classes declared inside a module each module instance creates a new
unique class type. These types are not compatible to each other. This is
necessary since module parameters can change the class implementation.
This is defined in section 6.22 ("Type compatibility") of the LRM (1800-2017).

In the current implementation when a class is elaborated the elaborated
type is stored in the class_type_t so it is possible to look up the
elaborated class type. But this class_type_t is shared among elaborated
class types. As a result when creating multiple instances of a module with
a class definition an internal assert is triggered.

To support multiple module instances with class definitions instead of
storing the elaborated type in the type definition look up the type in the
scope in which the type definition is references.

This is similar to how the same problem is solved for enum types.

For packages we still need to remember the elaborated type otherwise scoped
class type references wont work. Since there is only one instance of a
package this doesn't have the same problem as classes in modules.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-03-22 11:53:47 +01:00
Lars-Peter Clausen 7f4013ac66 data_type_t::elaborate_type(): Make return type const
For some data types the value returned by the `elaborate_type()` method is
shared among different signals of that type. E.g. all string or real types
get elaborated to the same ivl_type_s. This means the returned value must
not be modified, otherwise the data type for unrelated signals might get
changed.

To enforce this and protect against accidental breakage make the return
type of the `elaborate_type()` and the related `elaborate_type_raw()`
methods const.

Note that `ivl_type_t` is used for the new return type which is a typedef
for `const ivl_type_s*`.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-03-14 22:06:12 +01:00
Lars-Peter Clausen ac815a6118 netstruct_t: Set line info
netstruct_t inherits from LineInfo. But the file and line information is
never set leading to messages like

  :0: error: Member r of packed struct/union must be packed.

When elaborating a netstruct_t set the line info from the struct_type_t it
is elaborated from. This makes sure that error messages for the struct type
have the proper file and line information when printed.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-01-23 19:47:46 +01:00
Lars-Peter Clausen 09ac7c207e Add support for signed packed structs/unions
packed structs and packed unions as a whole can either be signed or
unsigned. This information is used when it is used as a primary in an
expression, i.e. without accessing any of the members.

Add support for parsing and elaborating signed structs.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-01-16 16:16:24 +01:00
Lars-Peter Clausen 9ec42b1b8c Check that packed array base-type is packed
When creating a signal of a packed array it is checked that the base-type
of the packed array is a packed type.

But this check is only done if the packed array itself is the type of the
signal. Placing the packed array in a struct or class will elaborate fine,
but then crash during simulation.

E.g.

```
typedef real myreal;
struct packed {
  myreal [1:0] p;
} s;
```

Move the check from signal creation to type elaboration, so that it is not
possible to create a packed type with a non-packed base-type.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-01-09 20:31:21 +01:00
Lars-Peter Clausen 52925ce9ff Handle invalid packed dimensions
Trying to elaborate a type with invalid packed dimensions currently results
in a crash. E.g. `typedef logic [] T;`

The issue is in the `elaborate_array_ranges()` function which
does not verify that the range specification is valid.

Replace the `elaborate_array_ranges()` with `evaluate_ranges()`, which does
the same thing, but properly checks the range specification and
reports an error if it is invalid.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-01-08 15:41:49 +01:00
Stephen Williams 752401b88c output ports of real type are variables, not wires. 2020-12-29 22:00:04 -08:00
Cary R 6ff07c1074 Enable support for providing a queue maximum index 2020-07-17 01:32:53 -07:00
Martin Whitaker 8dc395940d Fix issue #298: elaborate types in the scope where they were declared.
The compiler elaborates types on the fly as they are used. For user-
defined types (typedefs) we must do the elaboration in the scope where
the type was declared, not in the scope where it is used.
2019-12-22 17:29:23 +00:00
Martin Whitaker 732a763188 Record typedef name in data_type_t struct.
This will be used to locate the scope where the type was declared.
2019-12-22 11:21:05 +00:00
Martin Whitaker 832adc5c74 Improve handling of invalid packed and unpacked dimensions.
As reported on iverilog-devel on 2018-10-12, a dimension size of zero
could case the compiler to go into an infinite loop. Further tests
showed that unsized or queue dimensions entered as packed dimensions
would cause the compiler to crash.
2019-09-14 09:10:52 +01:00
Martin Whitaker 988816c0b1 Support separate compilation units in SystemVerilog.
The compilation unit scope is now treated as a specialised form of
package (with an automatically generated name). All items declared
outside a design element are added to the current compilation unit
package. Apart from when searching for a symbol, once we get into
elaboration we can treat these just like any other package.
2017-10-31 20:38:59 +00:00
Martin Whitaker ad1101cc80 Fix for br1005 - segfault when SV queue is declared inside a class.
For now, output a "sorry" message to indicate this is not yet
supported.
2016-07-11 20:04:24 +01:00
Frederick C. Kurz 9bcafe39c6 Changes to elab_type.c
Changes for "Microsoft Visual Studio Express 2015 RC Web" to first check for a dereferencable iterator so pr1741212.v, and many others, will pass with a DEBUG build.
2015-07-22 09:09:47 -07:00
Stephen Williams 86562e60ba Work towards nested packed struct member vectors. 2014-12-23 13:52:38 -08:00
Cary R ac2e8dd6cd Report that packed arrays can not currently be elaborated in all cases 2014-11-24 19:11:08 -08:00
Martin Whitaker 7fad4779c5 Add error recovery when elaboration of a type range fails.
If elaboration of the msb or lsb expression in the range of a vector
type specification failed (due to an error in the Verilog code being
compiled), an assertion failure was being triggered when the compiler
attempted to evaluate the expressions. Bypassing the evaluation (and
using a default value) should allow us to recover from the error.
2014-10-30 20:42:12 +00:00
Stephen Williams 712f394224 Elaborate classes in packages. 2014-10-10 18:53:53 -07:00
Stephen Williams 480668fee6 Add support for classes defined in $root scope. 2014-09-15 17:37:30 -07:00
Stephen Williams 3b0dfaadba Some support for unpacked arrays in class properties. 2014-09-02 09:23:54 -07:00
Stephen Williams ec0c66ff25 Fix internal error elaborating types used in different scopes
Some types, i.e. vector types with parameterized dimensions,
may have different elaboration results in different scopes.
Handle those cases in the elaboration caches.
2014-05-08 15:05:08 -07:00
Larry Doolittle be17bfc0e9 Spelling fixes
Mostly comments.
One user-visible string ("Evalutated to ") changed in the debug_eval_tree case.
2014-01-30 15:34:20 -08:00
Stephen Williams fc42f40770 Fix problem with enum types in re-used modules
When a module is instantiated multiple times, the enum
types contained within would cause trouble. This fixes
that by elaborating in proper scope context.
2014-01-11 19:19:15 -08:00
Stephen Williams 6ec31517a9 Implement $bits(type) to get the size of a type
In the process, I implemented a means to get at
previously elaborated types from the pform type
pointer.
2014-01-11 19:19:15 -08:00
Stephen Williams 819770a6c4 Handle enumerations as packed struct/union members.
There were also some subtleties related to using enumerations
from typedefs and using them in multiple places. Fix various
bugs related to those issues.
2013-12-07 12:20:28 -08:00
Stephen Williams 0d6c15e45a Handle packed unions properly during elaboration.
This also gets r-value use of packed unions correct.
2013-12-07 12:20:28 -08:00
Stephen Williams 20ee350601 Generalize user defined function return type handling.
I'm gonna need functions to return class objects, so generalize
the output types of user defined functions.
2013-04-20 16:38:35 -07:00
Cary R 15379f1750 Remove some compile warnings 2013-04-17 17:13:22 -07:00
Stephen Williams d8592b1444 Allow for class objects an class properties. 2013-01-27 20:10:25 -08:00
Stephen Williams 4568766cff Add support for darrays as class properties. 2013-01-27 20:10:25 -08:00
Stephen Williams c49b21115a Handle strings as class object properties.
While we are at it, fix a handling of null strings in
string expressions.
2013-01-27 20:10:25 -08:00
Stephen Williams 106850ca7d Handle real value class properties.
As a side effect, this also adds support for 64bit integers.
2013-01-27 20:10:25 -08:00