Commit Graph

743 Commits

Author SHA1 Message Date
Stephen Williams 3da5b4cf65
Merge pull request #664 from larsclausen/integer-port
Correctly handle separate port type declaration for integer types
2022-04-10 15:05:48 -07:00
Lars-Peter Clausen 8f6a9c5d3c Require explicit data type for package variable declarations
Variable declarations in packages need an explicit data type. Omitting the
data type or using just packed dimensions is not valid syntax. E.g. the
following should not work.

```
package P;
  x;
  [1:0] y;
endpackage
```

The current implementation does accept this tough. To fix this update the
parser to only allow explicit data types for package variable declarations.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-04-09 09:15:19 +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 51eae02e78 Support class method calls without parenthesis
It is possible to call a class method without parenthesis if no arguments
are specified.

At the moment this works when calling a class method by name. But when
using the implicit class handle `this` or `super` it does not work.

Add support for this.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-03-28 10:13:58 +02:00
Lars-Peter Clausen da5b9a4e5f Support class constructor without parenthesis
Class constructors can be declared without parenthesis after the `new` when
no arguments are required. Just like for normal function.

In a similar way the base class constructor can also be invoked without
parenthesis after the `new`.

```
class C extends D;
  function new;
    super.new;
  endfunction
endclass
```

Add support for this by making the parenthesis optional in the parser.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-03-28 10:13:58 +02:00
Lars-Peter Clausen e3bc99dbf3 Don't allow non-ANSI ports for class constructors
Class constructors don't allow for non-ANSI ports. E.g. the following is
not valid.

```
class C;
  function new();
    input int i;
  endfunction
endclass
```

The parser will currently accept this, but otherwise ignore the non-ANSI
port. Modify the parser rules so that this is a syntax error.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-03-28 10:13:58 +02:00
Lars-Peter Clausen 967e3455fe Add parser helper rule for class identifiers
There are a few places in the grammar that follow the pattern of
`implicit_class_handle '.' hierarchy_identifier` and then splice the two
identifier paths into a single one. Factor this into a common helper rule
to avoid duplicated code.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-03-28 10:13:58 +02:00
Lars-Peter Clausen 9810ce6e60 Add parser helper rules for optional argument list
There are a few places in the grammar where it is possible to specify a
argument list in parenthesis or nothing. E.g. a task invocation.

```
task t(int a = 10);
endtask

initial begin
  // All 3 are valid syntax
  t(1);
  t();
  t;
end
```

Factor this out into a common rule to be able to remove some duplicated
code.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-03-28 10:12:24 +02:00
Lars-Peter Clausen ad9f5a3aa6 Add parser helper rule for optional task port list
There are a few places in the grammar where it is possible to specify a
task/function port list in parenthesis or nothing. E.g. task and function
prototypes. Factor this out into a common rule to be able to remove some
duplicated code.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-03-28 10:11:37 +02:00
Stephen Williams d480c4d7d0
Merge pull request #659 from larsclausen/typedef-overwrite
Support typedef overwrites with unpacked dimensions and in classes
2022-03-27 15:49:55 -07: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 b30d3fc8d7 Support typedef overwrites in class scopes
It is possible to declare a new typedef that shadows an existing typedef in
a higher level scope. E.g.

```
typedef int T;
class C;
  typedef real T;
endclass
```

In the current implementation this works for scopes that are not class
scopes.

Update the parser to also support this in class scopes by re-using the
existing parser rule that is used for the other scopes.

Reusing the existing rule also adds support for class forward typedes
inside classes.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-03-23 10:53:56 +01:00
Lars-Peter Clausen 23e1143ad6 Support unpacked dimensions on typedef overwrites
It is possible to declare a new typedef that shadows an existing typedef in
a higher level scope. E.g.

```
typedef int T;
module M;
  typedef real T;
endmodule
```

In the current implementation this only works as long as the new type is
a not an array type.

Update the parser to allow to specify unpacked dimension when overwriting
a typedef from a different scope.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-03-23 10:53:56 +01:00
Lars-Peter Clausen aaffceff42 parser: Fix UDP registered output syntax
The parser currently expects `reg output` for UDP registered output. But
the correct syntax is `output reg`. Fix this to accept the correct syntax.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-03-19 12:59:20 +01:00
Stephen Williams 5bc1c08c67
Merge pull request #641 from larsclausen/lineinfo
parser: Consistently pass line information as `vlltype`
2022-03-13 14:35:09 -07:00
Lars-Peter Clausen 56f36a96d3 parser: Consistently pass line information as `vlltype`
Currently there is a mix of passing line information either as `struct
vlltype` or as a separate `const char *file` and `unsigned lineno`.

For consistency always use the struct vlltype variant.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-03-12 16:18:31 +01:00
Lars-Peter Clausen 3939126625 Handle empty class item declarations in parser
The SystemVerilog grammar explicitly allows an empty class item
declaration. The empty class item declaration is just a semicolon and has
no effect.

E.g. the following is legal
```
class C
  int x;;;
endclass
```

Add support to the parser to accept empty class item declarations.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-03-11 21:33:57 +01:00
Lars-Peter Clausen f67cdddecf Don't make input `integer` ports variables
In Verilog module input ports can only have a packed dimensions and a
signed flag, but no explicit data type.

In SystemVerilog an explicit data type can be specified for module input
ports. Such a port is a net, regardless of the data type, unless
explicitly made a variable using the `var` keyword.

This works for the most part in the current implementation, but for some
data types such as `reg` and `integer` the input port is turned into a
variable. And since input port's can't be variables in the current
implementation this results in an error.

Fix this by completely removing the `reg_flag` that is used to indicate
that a certain data type is always a variable. There is no such restriction
on data types for SystemVerilog and for Verilog there are already checks in
place that a input port can only have an implicit (or real) data type.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-03-03 10:30:28 +01:00
Lars-Peter Clausen 472598dd74 Report errors for nets with invalid data type
While a variable can have any data type the data type for nets is quite
restricted.

The SystemVerilog LRM section 6.7.1 ("Net declarations with built-in net
types") requires that the data type of a wire is either a 4-state packed or
a unpacked struct or unpacked array of 4-state packed types.

As an extension to this iverilog allows real data type for wires as well as
2-state packed types.

Add a check that reports an error if a net with any other type is declared.

In addition in Verilog a net can not have an explicit data type at all. It
can only have a packed dimension and a signed flag. As an extension to this
Icarus also allows wires to be of `real` data type.

Note that in Verilog mode the data type is checked in the parser since only
the parser knows whether the data type is an implicit type (`input reg
[7:0]` and `input [7:0] x` elaborate the same). But for SystemVerilog the
type is checked during elaboration since due to forward typedefs and type
parameters the type is not necessarily known in the parser.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-03-03 10:30:12 +01:00
Stephen Williams 5b65a583a1
Merge pull request #628 from larsclausen/module-output-var-types
Make output ports with data type variables
2022-02-27 15:08:46 -08:00
Lars-Peter Clausen 046893d97f Make output ports with data type variables
In SystemVerilog output ports are a variable if either:
 * They are explicitly declared a variable (with the `var` keyword)
 * There is no explicit net type, but a explicit data type

This is in detail described in section 23.2.2.3 ("Rules for determining port
kind, data type, and direction") of the LRM (1800-2017).

E.g.
```
output x // Net
output [1:0] x // Net
output signed x // Net
output wire x // Net
output wire logic x // Net
output var x // Variable
output logic x // Variable
output var logic x // Variable
output int x // Variable
output real x // Variable
output string x // Variable
output some_typedef x // Variable
```

At the moment the code checks for certain data types and only makes the
output port a variable for those. And it is even different data types
depending on whether the port is declared ANSI or non-ANSI style.

Change this so that if a data type is specified and it is not a implicit
data type (i.e. only ranges or `signed`) then the output is of type
variable.

This ensures consistent and correct behavior.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-27 13:28:26 +01:00
Lars-Peter Clausen 28bbebf98c Consolidate task and function item parser rules
Task and function item rules are identical. Consolidate them into a single
set of rules to remove some duplicated code.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-27 11:35:59 +01:00
Stephen Williams 978717f914
Merge pull request #623 from larsclausen/task-ports-sv
Support SystemVerilog non-ansi task/function port declarations
2022-02-26 09:16:33 -08:00
Lars-Peter Clausen b0c386182a Support unpacked array dimensions on non-ansi style task ports
SystemVerilog allows unpacked array dimensions on non-ANSI style task and
function ports.

To support this refactor pform_make_task_ports() to accept a of
pform_port_t, which in addition to the identifier name also allows to
specify per port unpacked dimensions.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-25 10:43:28 +01:00
Lars-Peter Clausen c631ff2483 Support SystemVerilog types for non-ansi task port declarations
Tasks and functions support two types of port declarations. Either ANSI
style, in parenthesis after the task name, or non-ANSI style, as
declaration statements in the task body.

In the current implementation SystemVerilog types are only accept for ANSI
style port declarations, while non-ANSI style only accept Verilog types
(reg, integer, time, real).

Add support for SystemVerilog data types for non-ansi style ports.

This also makes the parsing rules simpler since we can use `data_type` to
match all data types and don't need a explicit rule for each supported data
type.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-25 10:42:56 +01:00
Lars-Peter Clausen d104e28dbf Support non-overridable parameters in classes
SystemVerilog allows `parameter` and `localparam` to declare constants
within a class scope.  E.g.

```SystemVerilog
class C;
localparam A = 10;
endclass
```

In this context both declare a local parameter that can not be overwritten.

Supporting this can be achieved for the most part by adding a parser
sub-rule in class declaration rule. In addition some extra support code is
needed to mark the parameter as non-overridable.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-19 13:45:22 +01:00
Stephen Williams cc0a8c8dd2
Merge pull request #618 from larsclausen/signal-decl-consolidation
Consolidate signal declaration
2022-02-18 08:27:52 -08:00
Lars-Peter Clausen f6394c5fe6 Consolidate variable declaration parsing rules
There are currently two rules for parsing variable declarations.
One that is used when declaring variables in as a block declaration item
and another that is use everywhere else.

Consolidate those into a single set of rules. This removes a fair bit of
duplicated code in the parser.

A side effect of this refactoring is that class new statements can be used
as variable initializers as allowed by the standard. E.g.

```
module test;
  class C;
  endlcass
  C c = new C;
endmodule
```

This previously was not supported for block item variable declarations.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-18 11:59:09 +01:00
Lars-Peter Clausen 9da057ceb1 Add helper function for creating variable declarations
Variables don't have a delay or strength and the NetNet::Type is known. Add
a small wrapper around pform_makewire() that can be used to create
variables. This will allow to reduce the boilerplate code for variable
declarations.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-18 11:59:09 +01:00
Lars-Peter Clausen 6708c0f6df pform_makewire(): Allow to specify attributes
There are a few places where pform_makewire() is used and attributes can be
attached to the created net or variable. At the moment pform_makewire()
doesn't allow to specify the attributes, and they either get dropped
silently or with a warning.

Add support for passing the attributes to pform_makewire() which will then
pass it on to pform_set_data_type() to attach it to the declared net or
variable.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-18 11:59:09 +01:00
Lars-Peter Clausen a5e9358d42 Consolidate pform_makewire() variants
There are currently two very similar implementations of pform_makewire().
One that takes a `net_decl_assign_t`, the other a `std::list<decl_assignment_t*>`.

The one that takes a `std::list<decl_assignment_t*>` is a superset of the
other. It can handle both wires and variables, while the other can only
handle wires.

Update the parser to generate a `std::list<decl_assignment_t*>` for wire
declarations. This allows to remove one of the two functions.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-18 11:58:31 +01:00
Lars-Peter Clausen 6730ead119 Generate error for invalid declarations within generate block
Most things that can be declared in a module can also be declared in a
generate block.

But there are a few exceptions that can not be declared in generate block
 * module, program or interface declaration
 * specify block or specparam
 * timeunit

Some of these currently work while some of them trigger an assertion and
cause and application crash.

Add checks to make sure that all of them these are reported as an error and
do not cause a crash.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-16 11:23:39 +01:00
Zachary Snow a4d7c3f94e Restrict edge event to SV 2022-02-14 17:54:28 +01:00
Stephen Williams 27d81bc610 Add support for logical implication
The "->" operator is rarely used, but exists. Unfortunately, the syntax
is tied up in a horrible mess with the System Verilog constraint list
syntax. Do some flex magic to make it all work.
2022-02-13 18:48:16 -08:00
Lars-Peter Clausen 4a87bee3c0 Support parameters without default value
SystemVerilog allows to omit the default value of a parameter declared in a
parameter port list. In this case the parameter must be overridden for
every module instance. This is defined in section 6.20.1 ("Parameter
declaration syntax") of the LRM (1800-2017).

In addition a module that has a parameter without a default value does not
qualify for automatic toplevel module selection.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-13 18:21:56 +01:00
Stephen Williams b1fb4a6117
Merge pull request #611 from larsclausen/bits-types
Support calling $bits() with built-in data types
2022-02-13 08:15:46 -08:00
Lars-Peter Clausen c76db2867c Allow any data type in primary expression
There are a few system functions that take either an expression or a data
type. This is implemented in the parser by allowing a type identifier as a
primary expression.

But those functions allow any data type, not just typedefs. E.g.

```
$bits(int);
$bits(reg [1:0]);
$bits(struct packed { int x; });
```

Support this by changing the parser rule from TYPE_IDENTIFIER to data_type.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-13 14:49:29 +01:00
Lars-Peter Clausen 89e935c210 Allow omitting `parameter` in module parameter port list
SystemVerilog allows to completely omit the `parameter` keyword in a
module parameter port list. This is described in section 6.20.1 ("Parameter
declaration syntax") of the LRM (1800-2017).

E.g.

```
module a #(X = 10) ...
module b #(int Y = 20) ...
```

It also allows to redefine the parameter type without having to have a
parameter or localparam before the type.

E.g.

```
module a #(parameter int A = 1, real B = 2.0) ...
module b #(int X = 3, real Y = 4.0) ...
```

Extend the parser to support this.

Note that it is not possible to declare a parameter with an implicit data
type this way.

E.g. the following is not legal SystemVerilog
```
module a #([3:0] A = 1) ...
module b #(int X = 2, signed Y = 3.0) ...
```

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-11 10:57:46 +01:00
Lars-Peter Clausen 618959d147 Add helper function to emit error when SystemVerilog is requried
When encountering a construct that requires SystemVerilog in most cases an
error message is generated when SystemVerilog is not enabled and parsing
simply continues.

Factor the checking and generating of the error message into a helper
function. This slightly reduces boiler plate code and gives consistent
error messages.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-11 10:46:02 +01:00
Stephen Williams bb36a16704
Merge pull request #604 from larsclausen/parser-end-label-unnamed
Let the parser recover from end label on unnamed block
2022-02-10 17:14:42 -08:00
Lars-Peter Clausen 6a61144937 Support scoped base class type
A base class can be referenced by scope. E.g. if the base class is in a
package.

```
package P;
  class B;
  endclass
endpackage

module test;
  class C extends P::B;
  endlcass
endmodule
```

To support this let the parser accept a scope identifier for the base
class.

A small change is also necessary to how the base class lockup is done
during elaboration. At the moment the code will search for the base class
by name in the current scope. This doesn't work with scoped identifiers.

But we already have a reference to the base class data type, so we don't
have to search for it by name.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-06 21:37:46 +01:00
Lars-Peter Clausen 4bebcad6fd Add common parser rule for (scoped) type identifier
There are multiple places in the grammar where either a type identifier or
scoped type identifier is accepted.

Factor this into a common parser rule. This removes some duplicated code.
But it will also be required to avoid reduce-reduce conflicts for future
grammar extensions, e.g. to support type parameters.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-06 21:37:46 +01:00
Lars-Peter Clausen e950e2d0d3 Let the parser recover from end label on unnamed block
Currently when encountering an end label on a unnamed block
a 'syntax error' will be generated and the parser will give up.

Slightly refactor the parser so that this case is detected, a more specific
error message is generated and the parser can recover and continue.

This also slightly reduces the parser since it allows to merge the almost
identical rules for handling named and unnamed blocks.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-06 21:33:36 +01:00
Lars-Peter Clausen 7e18eba848 Add helper function to check end label
Most named constructs support a end label in SystemVerilog. The handling of
this end label is always the same.

 * Generate an error if the end label does not match the name of the block
 * Generate an error if not in SystemVerilog mode
 * Delete the end label

Factor this into a common helper function. This reduces code size a bit and
results in consistent error messages.

The latter requires refreshing of some gold files to match the slightly
different error messages.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-06 21:33:36 +01:00
Lars-Peter Clausen f2c1e21ad3 Allow unnamed parallel block with only variable declarations
While it is not a particular useful construct it is legal to have a
parallel block with just variable declarations and no statements. E.g.

```
fork
  int x;
join
```

At the moment there is a special rule for completely empty parallel
blocks. Remove that rule and change the statement_or_null_list in the
fork/join parser section to a statement_or_null_list_opt. This way it
covers both completely empty parallel blocks as well as parallel blocks
with only variable declarations.

Note that this already works as expected for named parallel blocks.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-06 14:13:02 +01:00
Lars-Peter Clausen 1549fd4332 Handle implicit `localparam`
When declaring module parameters in the ANSI style parameter list it is
possible to omit the `parameter` or `localparam` keyword. In this case
whether the parameter is local or non-local is inherited from the previous
parameter.

In the current implementation when the type of the parameter is not
specified it will always use parameter. E.g. the following will create a
localparam A and a parameter B, while it should be localparam A and B.

```
module #(localparam A = 1, B = 2);
```

Fix this by remembering whether the previous entry was a parameter or
localparam. This is similar to how the parameter data type is already
remembered.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-01-31 09:36:38 +01:00
Lars-Peter Clausen 0b30894f81 Support parameter value ranges on localparams
Verilog-AMS defines parameter value ranges which can restrict the value
that can be assigned to a parameter. It defines this for both `parameter`
and `localparam`. Currently it is only implemented for `parameter`. Support
it for `localparam` as well for consistency.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-01-27 18:51:13 +01:00
Lars-Peter Clausen ac040dae42 Consolidate parameter and localparam declaration handling
The code for handling parameter and localparameter declarations is very
similar. Consolidate this into a single helper function.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-01-27 18:51:13 +01:00
Lars-Peter Clausen ad6131b1c4 Allow unnamed begin/end block with only variable declarations
While it is not a particular useful construct it is legal to have a
begin/end block with just variable declarations and no statements. E.g.

```
begin
  int x;
end
```

At the moment there is a special rule for completely empty begin/end
blocks. Remove that rule and change the statement_or_null_list in the
begin/end block parser section to a statement_or_null_list_opt. This way it
covers both completely empty blocks as well as blocks with only variable
declarations.

Note that this already works as expected for named begin/end blocks.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-01-22 13:28:27 +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 3ca1c129ce Allow packed arrays of scoped types identifiers
Allow scoped identifiers to be used as the base type for packed array
types. Scoped type identifiers can be used the same way as unscoped type
identifiers.

E.g.
```
package p;
  typedef logic [1:0] vector;
endpackage

module test;
  p::vector [1:0] pa;
endmodule
```

is a valid construct.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-01-15 22:26:29 +01:00
Lars-Peter Clausen ae954e5df7 Support direct packed arrays of structs and enums
It is possible to directly declare a packed array of a struct or enum,
without having to typedef the struct or enum first. E.g.

```
struct packed {
  int x;
} [1:0] pa;
```

Add support to the parser for handling this.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-01-15 22:26:29 +01:00
Lars-Peter Clausen 9e6f651e09 Put enum type into scope when declaring it
When creating an enum type it must be added to the scope where it is
declared so it can later be elaborated and the enum and its names can be
referenced in expressions.

In addition the names of the enum must be added to the lexor scope so that
name collisions are detected and can be reported as errors.

This is done with pform_put_enum_type_in_scope() function.

At the moment the function is called from two different places
 * When adding a typedef of a enum type
 * When creating a signal of a enum type

In addition the enum_type_t is added to a class scope `enum_sets` when
declaring a enum property in a class. But this only makes sure that the
enum gets elaborated, its names are not added to the lexor scope.

This works fine for the most part, but breaks for a few corner cases.

E.g. it is possible to declare a enum type as part of the subtype of
another packed type such as structs or packed arrays. E.g.

```
struct packed {
  enum {
    A
  } e;
} s;
```

This is not covered by either of the cases above and neither do the names
of the enum get added to the lexor scope, nor is the enum type elaborated.

Another corner case that is currently not working is declaring a class
property where the type is a typedef of a enum that is declared outside of
the class. In this case the enum is elaborated again inside the class
scope. E.g. the below is supposed to work, but fails with an already
declared symbol error.

```
typedef enum {
  A
} e_t;

class C;
  typedef enum {
    A
  } e1;
  e_t e2;
endclass
```

In addition since for enums declared in classes they are only added to
`enum_sets`, but names are not added to the lexor scope, it is possible to
declare a different symbol in the class scope with the same name.

E.g. the following elaborates fine

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

To fix this call pform_put_enum_type_in_scope() when the enum_type_t is
created in the parser. This makes sure that it is handled the same
regardless where the type is declared or used.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-01-15 21:24:23 +01:00
Lars-Peter Clausen 74b433c083 parse.y: Refector enum rule
Refactor the enum rule by adding a enum_base_type rule which handles the
type specific initialization. This allows to keep the non-type specific
parts in a common rule, which makes it easier to modify in future changes.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-01-15 20:53:55 +01:00
Lars-Peter Clausen 5bfc8a42eb Handle invalid struct members
When something goes wrong when parsing a struct member, e.g. the type does
not exist, a nullptr is added to the struct member list. This will cause a
crash when iterating over the list.

E.g.

```
struct packed {
  logc x;
} s;
```

Add a check so that nullptr members are not added to the list.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-01-15 19:46:26 +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 dbf55da0f5 Clean up indentation. 2021-11-05 21:49:51 +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 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 7bb8a4463f Time literals need to be rounded using the time precision 2021-02-13 01:11:43 -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 d1eb4befcc Add initial parsing for let construct 2021-01-18 13:06:44 -08:00
Cary R 501586431b Darrays are SV only and fix queue error message 2021-01-07 23:55:07 -08:00
Cary R 5442f3fee7 Add sorry messages for missing array methods 2021-01-07 22:26:47 -08:00
Cary R 89eabdfa35 Skip scalared and vectored keywords for packed arrays 2021-01-07 20:45:49 -08:00
Cary R 32787bb973 Add support for SV edge 2021-01-07 01:22:49 -08:00
Stephen Williams 752401b88c output ports of real type are variables, not wires. 2020-12-29 22:00:04 -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 5ca947ea8a Allow signed/unsigned for fixed width integer data type parameters 2020-12-27 01:04:01 -08:00
Stephen Williams 156644d91e Detect and complain about some constructor chain errors
This.new is not allowed.

super.new beyond the first statement is not allowed.

And while I'm at it, clean up the use of "@" and "#" in
the code as tokens for this and super.
2020-11-22 15:31:40 -08:00
Cary R 292d174cad Add support for an empty ';' in the description text 2020-11-20 21:42:39 -08:00
Cary R b14a623eef Update module items to include just a ';' 2020-11-20 20:48:55 -08:00
Martin Whitaker 6880b39770 Refactor task declaration parsing and fix warning for empty port list.
1364-2005 and later allow a task declaration with an empty port list.
2020-10-03 09:30:51 +01:00
Lars-Peter Clausen 1064543d27 parse.y: Mark enum output ports always as IMPLICT_REG
Unless explicitly declared a wire an enum output port is of variable type
and should be marked as IMPLICT_REG.

Currently this is only done when the base type of the enum is `logic`. But
it should be done for all enums regardless of their base type.

Without this change for example the following snippet

```
  typedef enum {
      A,
      B
  } E;

  module M (
      input E ei,
      output E eo
  );

      always_comb eo = ei;

  endmodule
```

fails with the following error message

  test_enum.sv:11: error: eo is not a valid l-value in M.
  test_enum.sv:8:       : eo is declared here as wire.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2020-09-20 19:14:28 +02:00
Cary R 6ff07c1074 Enable support for providing a queue maximum index 2020-07-17 01:32:53 -07:00
martinwhitaker 07256646a5
Merge pull request #334 from purdeaandrei/f_fix_portless_declarationless_functions
Fix port-list-less declaration-less functions for SystemVerilog
2020-07-10 22:47:53 +01:00
Cary R c003bcc59a Add support for <-> in constant and procedural contexts 2020-07-07 23:29:19 -07:00
Cary R 018a649f59 A time variable defaults to unsigned, but can be declared as signed 2020-07-07 20:33:03 -07:00
Purdea Andrei a4d91c9023 Fix port-list-less declaration-less functions for SystemVerilog
For functions without a port list in parantheses, declarations are optional in SystemVerilog.
This is true even in IEEE1800-2005, but not in IEEE1364-2005
2020-06-22 23:51:10 +03:00
Martin Whitaker 8b85064341 Fix GitHub issue 310 - improve port declaration error message. 2020-02-15 12:02:15 +00:00
Martin Whitaker b1114760fc Fix for compatibility with old C++ standard. 2020-02-02 09:25:05 +00:00
Martin Whitaker 33b822d997 Add support for local genvar declaration in generate loops.
As requested in GitHub issue #304.
2020-01-31 20:29:22 +00:00
Martin Whitaker 0023804777 Add support for increment/decrement operators in generate loop iteration.
As requested in GitHub issue #303.
2020-01-30 21:45:04 +00:00
Martin Whitaker 9f712429c8 Fix elaboration of void functions with no arguments (GitHub issue #281)
N.B. commit 82c8a495 incorrectly referenced issue #281. It should have
referenced issue #280.
2019-11-09 20:16:25 +00:00
Martin Whitaker 06a60cac01 For SystemVerilog, support localparam in module parameter port lists. 2019-10-06 08:44:51 +01:00
Stephen Williams befc91340c Parse and elaborate unique and priority case statements
The unique, unique0, and priority keywords can decorate case statements
to tell the run time (or synthesis) to do extra tests (or make extra
assumptions). These tests are not implemented in the vvp run time, but
now the decorations make it to the code generators.
2019-10-05 16:23:04 -07:00
Martin Whitaker c86dc285cc Fix for br1004 - fully support class construction in variable initialisation. 2019-10-05 20:10:11 +01:00
Martin Whitaker 05641f386f Add -g option to only enable supported assertion statements. 2019-10-05 13:37:03 +01:00
Martin Whitaker 455702810e Add support for parsing (and ignoring) the other unsupported SV assertions. 2019-10-05 08:55:11 +01:00
Martin Whitaker 9167a236d8 Support import statements in packages and in the unit scope. 2019-10-03 19:44:44 +01:00
Martin Whitaker 17f0dd7e6e Enable package imports in blocks. 2019-10-01 09:07:59 +01:00
Martin Whitaker c5c264400e Add support for package scope resolution for named events. 2019-10-01 09:07:54 +01:00
Martin Whitaker 12fe4f2bf3 Fix handling of wildcard-imported types.
Don't add them to the explicit imports until they are referenced legally.
Stop searching when a matching name is found, even if it isn't a type name.
2019-10-01 09:07:48 +01:00
Martin Whitaker b0142a6406 Add support for named events in packages. 2019-10-01 09:07:39 +01:00
Martin Whitaker f69eccf903 Merge remote-tracking branch 'origin/master' into package-imports-rework 2019-10-01 09:06:15 +01:00
Stephen Williams 80478db6cc Support typedefs in class definitions. 2019-09-30 08:07:56 -07:00
Stephen Williams 50d71c8512 Support for enumerations in classes. 2019-09-29 18:27:27 -07:00
Martin Whitaker 03c4c63df1 Fix file/line reported for duplicate named blocks. 2019-09-27 22:19:30 +01:00