Commit Graph

9421 Commits

Author SHA1 Message Date
Lars-Peter Clausen 2e845821a8 Add regression test for localparams in classes
Check that localparams and non-overridable parameters can be declared in a
class.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-19 13:45:22 +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
Lars-Peter Clausen 427091d3d3 Support access to class constants on objects
It is allowed to access a constant declared in a class scope, such as a
enum value or parameter, on an object of that class type. This is described
in section 8.5 ("Object properties and object parameter data") of the LRM
(1800-2017).

E.g.

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

C c = new;
c.e = c.A;
```

Support this by in addition of searching for class properties on the object
also search for constants in the class scope.

A bit of refactoring is needed around the parameter elaboration functions
since they expect a non-const NetScope, but for classes we only have a
const scope available.

The non-const scope is needed to be able to mark specparams as
non-annotatable. Since classes can't have specparams this part is factored
out into a separate function the NetScope parameter for the shared
functions is made const.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-19 13:45:14 +01:00
Lars-Peter Clausen ad23b08a10 Constify scope reference in NetEConstParam and NetECRealParam
Parameter expressions need to remember the scope they have been declared in
so that the code generator backends can insert the right parameter
reference, rather than a constant value.

Currently the scope is stored as a non-const reference. But that is not
needed. Mark the scope reference as const so NetEConstParam and
NetECRealParam can be created when only a const scope reference is
available.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-19 13:00:12 +01:00
Lars-Peter Clausen 892622bf64 Add helper function to get parameter line info
The NetScope class has a method called find_parameter() that looks up the
parameter and returns a iterator to it. This is only ever used to get the
line information of the parameter.

Refactor the function so that it only returns the line info. This will
allow to call this function on a const NetScope object.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-19 12:52:19 +01:00
Lars-Peter Clausen aa905a27cf Initialize LexicalScope::has_parameter_port_list
The has_parameter_port_list member of the LexicalScope class is not
initialized, which means its default value is undefined. This leads to
random failures where a parameter is marked as non-overridable when it
shouldn't.

Make sure has_parameter_port_list is properly initialized to false.

Fixes: 673b40b78c ("Elaborate `parameter` as non-overridable where required")
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-19 08:50:23 +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
Stephen Williams afaaaed0a4
Merge pull request #617 from larsclausen/generate-invalid
Generate error for invalid declarations within generate block
2022-02-18 08:26:08 -08:00
Stephen Williams 21c769e1e1
Merge pull request #616 from larsclausen/parameter-non-overridable
Elaborate `parameter` as non-overridable where required
2022-02-18 08:25:30 -08:00
Lars-Peter Clausen ce8ee42619 Add regression test for class new initializer
Check that it is possible to use a class new as
an initializer for a variable or property declaration.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-18 11:59:09 +01: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 47b6ee714d Remove unused pform_makewire() variants
There are two versions of pform_makewire() that are not used anywhere,
remove them.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-18 10:40:53 +01:00
Lars-Peter Clausen b37636e4fc Add regression test for invalid declarations in generate blocks
Check that the following declarations inside a generate block generate an
error:
 * module, program or interface
 * specparam
 * specify block
 * timeunit

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-16 11:23:39 +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
Lars-Peter Clausen bb74c6412d Refactor test for invalid parameter overrides
Split the test into multiple tests that each check one type of invalid
override rather than having one big tests that checks for everything.

This allow to check whether the test passes or fails by seeing if it
compiles or not. The one big test on the other hand relies on seeing the
exact error messages as recorded in the gold file.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-15 11:31:35 +01:00
Lars-Peter Clausen 673b40b78c Elaborate `parameter` as non-overridable where required
For modules, programs and interfaces that have a parameter port list, a
parameter declared inside the scope's body is supposed to be elaborated as
a local parameter.

TThis is described in the Verilog LRM (1364-2005) section 4.10.1 ("Module
parameters") and the SystemVerilog LRM (1800-2017) section 6.20.1
("Parameter declaration syntax").

Implement this by marking a parameter declared in such a way as
non-overridable.

Note that a parameter declared within a named block, function or task can
still be overridden, even if the module has a parameter port list.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-15 11:31:09 +01:00
Stephen Williams 96a1cbf7b2
Merge pull request #615 from zachjs/sv-edge
Restrict edge event to SV
2022-02-14 21:05:05 -08:00
Zachary Snow a4d7c3f94e Restrict edge event to SV 2022-02-14 17:54:28 +01:00
Stephen Williams 560129f0c6
Merge pull request #614 from steveicarus/logical-implication
Logical implication
2022-02-14 08:01:14 -08:00
Stephen Williams 6c04749a68 Add the l_impl test for the logical implication operator. 2022-02-13 18:48:40 -08: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
Stephen Williams 3f048f266a
Merge pull request #613 from larsclausen/param-no-default
Support parameters without default value
2022-02-13 15:40:00 -08:00
Lars-Peter Clausen 91579c7c79 Add regression tests for parameters without default
SystemVerilog supports parameters without default values in parameter port
list. Add regression tests to check this feature.

Also add a regression test to check that modules without a default
parameter are not automatically picked as a toplevel module.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-13 18:21:56 +01: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
Stephen Williams 13aa782be2
Merge pull request #609 from larsclausen/sv-omit-param-keyword
Allow omitting `parameter` in module parameter port list
2022-02-13 08:13:11 -08:00
Stephen Williams 310fe6c4de
Merge pull request #610 from larsclausen/attrib-expr
Support full set of constant expressions in attributes
2022-02-13 08:08:25 -08:00
Lars-Peter Clausen ef42df6fef Add a regression test for calling $bits() with a data type
Check that $bits() can be called with packed data types.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-13 15:03:49 +01:00
Lars-Peter Clausen c4feb89957 Handle unpacked array types for $bits()
For unpacked statically sized array types $bits() is supposed to return the
total size of the array. Accumulated the number of unpacked dimensions and
multiply it by the packed with of the base type to get the right result.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-13 15:03:49 +01: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 481f461e59 Add regression test for expressions in attributes
Check that all types of constant expressions are supported in attributes.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-12 17:56:30 +01:00
Lars-Peter Clausen 497c98bf9b Remove eval_const()
There are no more users of the eval_const() system. Lets remove it.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-12 17:41:41 +01:00
Lars-Peter Clausen 30ff2aa5d1 Support full set of constant expressions in attributes
There are currently two different systems to evaluate constant expressions
in iverilog.

The PExpr based system using the eval_const() method and the NetExpr based
system using the eval_tree() method. The latter is more complete while the
former only implements the bare minimum and also has some minor bugs.

The PExpr based system is only used to evaluate expressions within
attributes.

Switch attribute expression evaluation over to elab_and_eval(). This
enables to use the full  set of constant expressions for attributes, maybe
most importantly constant functions and system math functions.

It also allows to remove the PExpr based system since there are no more
users.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-12 17:40:45 +01:00
Lars-Peter Clausen 7f40e120c8 Add regression tests for omitting `parameter` in parameter port list
SystemVerilog allows to completely omit the `parameter` or `localparam`
keyword in the parameter list. Both at the beginning and before redefining
the parameter data type. This is not support in Verilog.

Add regression tests that check that this is supported when in
SystemVerilog mode.

It is not valid to use an implicit data type e.g. just `signed` when
`parameter` was omitted, add regression tests to check for this as well.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-11 11:09:59 +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 771d02bee1
Merge pull request #607 from larsclausen/sv-parameter-in-generate
Allow parameter in generate blocks for SystemVerilog
2022-02-10 17:16:22 -08: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
Stephen Williams a7a154047a
Merge pull request #605 from larsclausen/class-scoped-base
Support scoped base class type
2022-02-10 17:12:27 -08:00
Lars-Peter Clausen 47e6c71113 Add regression tests for parameters in generate blocks
In Verilog a parameter in a generate block is invalid and should
result in a compile error.

In SystemVerilog on the other hand it is valid, but it is equivalent
to a localparam and can't be overridden.

Add regression tests that check for this.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-10 11:37:38 +01:00
Lars-Peter Clausen 9a94e6b43b Allow `parameter` in generate blocks for SystemVerilog
SystemVerilog allows to use the `parameter` keyword in a generate
block. If used in a generate block it behaves like a `localparam` and
cannot be overridden.

This is described in section 27.2 ("Generate constructs - Overview") of the
LRM (1800-2017).

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-10 11:37:38 +01:00
Lars-Peter Clausen 9f5ad34e35 Track whether a parameter is overridable
Parameters declared in certain scopes behave like local parameters and can
not be overridden. Rather than making those parameters a localparam track
whether a parameter can be overridden.

This allows to generate better error messages when trying to override the
parameter.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-10 11:37:34 +01: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
Lars-Peter Clausen 42dd8a0703 Add regression test for class with scoped base class type
Check that classes with a scoped base class type get elaborated correctly.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-06 21:50:51 +01: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 305a1a9262 Add regression test for end labels on unnamed blocks
An end label on an unnamed block should generate an error. Add a regression
test to check this.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-06 21:33:36 +01:00