Commit Graph

9541 Commits

Author SHA1 Message Date
Stephen Williams 2f091c8f45 Start Icarus Verilog Documentation using Sphinx
Embed the Icarus Verilog documentation, and format it so that the
Sphinx tools can process it into html or other formats. This will
make the documentation easier to keep up to date with the actual
software.
2022-04-10 19:24:08 -07:00
Stephen Williams 7c5694e516
Merge pull request #673 from larsclausen/package-no-implicit-var
Require explicit data type for package variable declarations
2022-04-10 15:06:26 -07:00
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
Stephen Williams 070b8af63c
Merge pull request #663 from larsclausen/class-constructor
Small class syntax improvements
2022-04-10 14:56:51 -07:00
Stephen Williams 99eaf007a1
Merge pull request #662 from larsclausen/array-base-type-scope
Elaborate base type of array types in the right scope
2022-04-10 14:56:07 -07:00
Martin Whitaker 50ae8cf552 Add regression test for br_gh674. 2022-04-10 21:58:39 +01:00
Martin Whitaker 82caccd4eb Handle negative OOB access to local array in constant function (issue #674)
The word select expression is a zero-based canonical index, but the
expression evaluation may return a negative value.
2022-04-10 21:34:30 +01:00
Lars-Peter Clausen 35c69366a5 Add regression tests for implicit variable declarations in packages
Check that it is not possible to declare a variable in a package without an
explicit data type for the variable.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-04-09 09:15:23 +02: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
Martin Whitaker 42de9e646a Add regression test for br_gh661 and test for correct $random behaviour. 2022-04-03 19:56:56 +01:00
Martin Whitaker 94e09ec473 Use explicit 32-bit integers in random number system functions (issue #661).
This simplifies the code by making it independent of the size of 'long', and
fixes the behaviour of urandom_range when the upper limit is > 0x7fffffff.
2022-04-03 19:45:44 +01:00
Lars-Peter Clausen 4c9af1c47a Add regression tests for non-ANSI integer module ports
Check that it is possible to declare the type separately from the direction
for non-ANSI integer, time and atom2 ports. Check that it is possible to
both declare the type before and after the direction.

For integer, time and atom2 types the range specification on the port
direction declaration should be empty, rather than the implicit packed
dimension of the integer type.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-03-28 10:40:25 +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 de9e3b791b Correctly handle separate port type declaration for atom2 types
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 to vector types, i.e. the packed dimension is
explicitly declared. It does not apply to the atom2 types which have an
implicit packed dimension.

The current implementation requires that even for atom2 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;
  byte x;
endmodule
```

Currently atom2_type_t's are deconstructed into base type, range and
signdness in the parser. That data is then passed to the signal
elaboration, which will then construct a netvector_t from it. This makes it
impossible to e.g. differentiate between `bit signed [31:0]` and `int`
during elaboration.

Instead of breaking the data type apart pass it as the data_type_t of the
signal and use the elaborate_type() method in the signal elaboration to
generate the netvector_t.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-03-28 10:23:00 +02:00
Lars-Peter Clausen 571f222a73 Add additional regression tests for class syntax
Check that it is possible to both declare and call class constructors
without using parenthesis after the `new` keyword.

Check that a non-ANSI port for a class constructor results in an error.

Check that it is possible to invoke a class task through a implicit class
handle (`this` or `super`) without using parenthesis after the task name.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-03-28 10:14:56 +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
Lars-Peter Clausen 1a95dafc8d Add regression tests array base type elaboration scope
Check that for typedefs of array, dynamic array and queue types the base
type is elaborated in the right scope. There are separate tests for vector
base type and other base types since these take different paths internally.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-03-28 09:17:24 +02:00
Lars-Peter Clausen c96a6bfa09 Elaborate base type of array types in the right scope
The base type of an array type needs to be elaborated in the scope where
the array type is declared. At the moment it is elaborated in the scope
where the signal is declared, which can cause incorrect results.

E.g. in the example below the width of the array base type would be 4
instead of 8.

```
localparam A = 8;
typedef reg [A-1:0] T[1:0];

module test;
  localparam A = 4;
  T x;
endmodule
```

If an unpacked array type is specified use the scope of the array type as
the default scope for the base type. Note that the base type can still be a
typedef in a different scope than the array scope, but we need to start
searching for it in the array scope.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-03-28 09:14:28 +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
Stephen Williams 658d4f5eee
Merge pull request #658 from larsclausen/class-in-module
Handle multiple instances of modules with class definitions
2022-03-27 15:48:56 -07:00
Stephen Williams 4f971ea4f9
Merge pull request #657 from larsclausen/enum-base-type
Support type identifier base type for enum
2022-03-27 15:47:34 -07:00
Martin Whitaker 7dcde37475 Fix iverilog-vpi on Windows to handle more than one source file (issue #602)
Use the string containing the current source file path to derive the
object file name, not the string containing the space-separated list
of source files.

(thanks to DavidC-75 for pointing out the error)
2022-03-26 18:13:18 +00:00
Martin Whitaker 8a19380a5d Add multi-file VPI test. 2022-03-26 16:44:57 +00:00
Martin Whitaker 673b0d3066 vvp: Only support one path separator in IVERILOG_VPI_MODULE_PATH (issue #608)
Previously both ':' and ';' were recognised as path separators on all
platforms, but ':' can't be used in Windows. So now we only recognise
';' when running in Windows and ':' when running in any other OS.
2022-03-25 22:04:43 +00:00
Lars-Peter Clausen 315bc1908a Add regression tests for enum base type
Check that the behavior for all sorts of base types for enums is correctly
implemented. Both for valid as well as invalid base types.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-03-25 21:55:34 +01: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
Martin Whitaker 4c36b2a8a7 vvp: Fix implementation of strndup for Windows (issue #608).
The maximum length to copy, n, does not include the terminating null
character.
2022-03-25 20:34:11 +00:00
Martin Whitaker 3c58ca908d vvp: Fix error message output when a VPI module can't be found. 2022-03-25 20:23:47 +00:00
Martin Whitaker 2bf753fd8f vvp: Accept either \ or / as path separators in the -m option (issue #606).
Windows system calls will accept either of these. This is already done in
the iverilog driver.
2022-03-25 20:14:20 +00:00
Lars-Peter Clausen 252174d15a Add additional regression tests for typedef overwrites
Check that it is possible to create a typedef of an array type that shadows
an existing typedef in a higher level scope.

Also check that it is possible to create a typedef in a class scope that
shadows an exiting typedef in a higher level scope.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-03-23 10:53:56 +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
Cary R 86a7707482 Update vlog95 regress for some recent test changes 2022-03-23 00:07:30 -07:00
Cary R af7c3043d8 Update to the latest from GTKWave 2022-03-22 23:32:25 -07:00
Lars-Peter Clausen abe5e692ce Add regression test for classes defined in modules
Check that it is possible to have multiple instances of a module
that declares a class and that the class in each module instance
is a unique type that can have dependencies on module parameters.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-03-22 11:53:47 +01: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 583a7ddc35 netclass: Make pointer to base class const
The base class type is not owned by a class and is shared. For this reason
it must not be modified. To ensure this mark the base class pointer as
const.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-03-22 11:42:54 +01:00
Martin Whitaker b3f7ce6020 vvp: ensure array ports are added to the correct context (issue #621)
Array ports are created via a resolve list. We need to detect and
record whether they need to be created in an automatic context at
the point they are declared, not at the time they are created.
2022-03-21 19:57:05 +00:00
Martin Whitaker 2c505f0040 Add regression test for issue #621. 2022-03-21 19:55:15 +00:00
Stephen Williams fc80465b87
Merge pull request #656 from larsclausen/enum-compatibility
Restrict enum compatibility to the same scope
2022-03-20 19:13:56 -07:00
Stephen Williams f73af99ce7
Merge pull request #655 from larsclausen/fix-udp-output-reg
parser: Fix UDP registered output syntax
2022-03-20 19:12:34 -07:00
Stephen Williams 1de38dde12
Merge pull request #651 from larsclausen/consolidate-pform-set-datatype
Consolidate most pform_set_<type>_data_type() functions
2022-03-20 19:11:49 -07:00
Stephen Williams af09d86113
Merge pull request #647 from larsclausen/non-ansi-ports
Allow to declare direction after data type for non-ANSI ports
2022-03-20 19:10:49 -07:00
Lars-Peter Clausen 83da384df3 Add regression test for enum compatibility across module boundaries
Check that the compatibility of signals of enum data type across module
boundaries.

If the enum data type is declared at a higher level scope or imported from
a package the signals are compatible between different module instances. If
the enum data type is declared within the module itself though the signals
are not compatible.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-03-19 17:17:21 +01:00
Lars-Peter Clausen fabff5ef5f Restrict enum compatibility to the same scope
An enum data type declared in a module is not compatible between different
instances of the module. The type is unique in each hierarchical instance
scope. The type can for example depend on module parameters which would
result in conflicting definitions. This is defined in section 6.22 ("Type
compatibility") of the LRM (1800-2017).

At the moment enum compatibility is checked by comparing the enum_type_t.
But the enum_type_t is shared among the netenum_t that are created for each
module instance and gives the wrong result.

Since there is exactly one netenum_t created for each enum and each
instantiated scope use this to check if the data type of two enum type
signals is compatible.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-03-19 17:17:21 +01:00