Commit Graph

16 Commits

Author SHA1 Message Date
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 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 e799a09605 data_type_t: Remove figure_packed_base_type() method
The figure_packed_base_type() method can be used to check whether a type is
2-state or 4-state at parse time. The parser no longer cares about the
specific type of a data type. The figure_packed_base_type() function is
no longer used, so remove it.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-09-15 10:07:10 +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 4bf0d62cd1 Support type identifier base type for enum
The base type for an enum type can be a type identifier for a typedef as
long as it resolves to a vector or integer type with at most one packed
dimension. This is described in section 6.19 ("Enumerations") of the LRM
(1800-2017). E.g.

```
typedef bit [3:0] T;
enum T {
 A
} e;
```

Add support for this by allowing to specify a type identifier as the base
type for an enum in the parser. During elaboration it is checked whether
the type identifier resolves to a valid enum base type.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-03-25 21:55:34 +01:00
Lars-Peter Clausen adf64f3cc8 Fix base type for nested types with enum or atom2 sub-types
To determine the base type structs and packed arrays call the
figure_packed_base_type() for their sub-types.

This method is not defined for enum or atom2 types and the default
implementation returns IVL_VT_NO_TYPE.

As a result packed arrays of enum or atom2 types and packed structs with
members of enum or atom2 types get elaborated with IVL_VT_NO_TYPE
as the base type.

For example

```
struct packed {
  bit signed [31:0] x;
} s1;
```

gets elaborated with a base type of IVL_VT_BOOL, while

```
struct packed {
  int x;
} s2;
```

gets elaborated with a base type of IVL_VT_NONE.

To fix this define the figure_packed_base_type() for enum_type_t and
atom2_type_t.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-01-08 15:41:49 +01:00
Martin Whitaker b88d91c617 Create new base class for all named items that can be added to a scope.
Provide a helper function to identify the derived classes when reporting
errors.
2019-09-27 22:19:30 +01:00
Stephen Williams f602ae84ab Elaborate foreach loops as synthetic for loops.
Create an implicit scope to hold the index variable, and
generate a for loop to perform the functionality of the
foreach.
2014-08-21 16:44:46 -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
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 3d9ed1f0f8 Clean up PWire handling of wire data type. / Reword packed type handling 2012-09-03 16:00:09 -07:00
Arun Persaud f5aafc32f9 updated FSF-address 2012-08-29 10:12:10 -07:00
Stephen Williams d48362b861 First pass at getting strings to work.
In vvp, create the .var/str variable for representing strings, and
handle strings in the $display system task.

Add to vvp threads the concept of a stack of strings. This is going to
be how complex objects are to me handled in the future: forth-like
operation stacks. Also add the first two instructions to minimally get
strings to work.

In the parser, handle the variable declaration and make it available
to the ivl_target.h code generator. The vvp code generator can use this
information to generate the code for new vvp support.
2012-07-22 10:52:06 -07:00
Stephen Williams e14628193a Parse simple typedefs
Parse typedefs with structs and enums, but give a sorry message,
because they are not yet supported. Rearrange some of the parse
rules for variables in order to increase comonality with the
typedef rules.
2012-02-02 16:18:50 -08:00
Stephen Williams 1ef7994ae2 Handle indexed defparams.
The l-value of a defparam assignment is a hierarchical name that may
include array selects to select scopes from module arrays. Therefore
it makes no sense to store parsed defparams in a map. Instead, they
should go into an ordered list. This also maked more sense because later
defparams *may* have the same name as a previous defparam, and will
override the previous defparam. So replace the map of parsed defparams
with a list of parsed defparams.

Also, as soon as the defparam expression is elaborated, the list entry
is no longer needed, so delete it. Save memory.
2008-06-28 09:30:09 -07:00
steve ddd36ecb6c Rework the heirarchical identifier parse syntax and pform
to handle more general combinations of heirarch and bit selects.
2007-05-24 04:07:11 +00:00