Commit Graph

191 Commits

Author SHA1 Message Date
Cary R cc496c3cf3 More ivl cppcheck cleanup 2025-10-23 10:01:06 -07:00
Cary R 860761f9c6 More cppcheck fixes - part 2 2025-10-20 23:54:15 -07:00
Martin Whitaker 0ecb71625b Support assignment of parray slices (issue #1256)
The existing elaboration code only allowed assignments from/to individual
elements and either failed an assertion (when assigning the entire array)
or failed to compile (when assigning an array slice).
2025-07-05 18:02:40 +01:00
Dag Lem ba7da9d5a5 Guard against overflow / wrap around of internal part-select bit address
Internally, the maximum address space of a vector is 31 bits + a sign bit
to signal invalid addresses (out of bounds or has one or more x or z bits).

This commit ensures that unsigned part-select bit addresses which would
otherwise overflow and wrap around within this address space are correctly
handled as out of bounds.
2024-09-16 23:50:24 +02:00
Martin Whitaker f08ff895af Add informational messages that point to declaration after use. 2024-02-25 16:12:31 +00:00
Martin Whitaker 649fbb9a59 Modify symbol_search() to only return declared nets and named events.
This only applies to simple identifiers. Only return a match if the
lexical position of the identifier being searched is later in the
source text than the lexical position of a matching symbol.
2024-02-19 18:19:55 +00:00
Martin Whitaker dd082b849b Improve error message for non-constant bit select in mixed assignment.
Report the conflict with the continuous assignment as the reason this
is not allowed.
2024-02-03 21:58:25 +00:00
Martin Whitaker 3a2a1fb93d Check for mixed assignment conflicts in procedural indexed part selects. 2024-02-03 21:16:57 +00:00
Martin Whitaker d4759e02aa Allow multiple procedural assignents to same part of mixed-mode variables.
If we have a variable which is part driven by a continuous assignment,
the parts that are not driven by that assignment can be the target of
more than one procedural assignment. So we need to only test the cassign
mask, not test and set it, when elaborating the procedural assignments.
2024-02-03 21:12:05 +00:00
Martin Whitaker abb9959339 Factor out code for reporting mixed assignment conflicts.
This makes the error reporting uniform.
2024-02-03 20:24:22 +00:00
Martin Whitaker 9faf8d6b09 Ignore force statements when checking for mixed assignment conflicts.
This was already done in some places. Do it everywhere.
2024-02-03 19:23:15 +00:00
Martin Whitaker 89bb86962f Allow mixed procedural/continuous assignment for array words.
This is legal if the procedural and continuous assignments target
different words.

NOTE: This is not fully compliant with the standard, because vvp
does not know that the nets were originally declared as variables,
so initialises to 'bz instead of 'bx and does not handle release
correctly.
2024-02-03 17:55:32 +00:00
Martin Whitaker 42c5174c8d Improve error messages for mixed procedural/continuous assignments.
We have already eliminated procedural assignments to uwires, so if
we find a l-value of type UNRESOLVED_WIRE, it must be a variable
that has a continuous assignment. Report it as such.
2024-02-03 17:08:44 +00:00
Martin Whitaker 11fc90faf7 Catch procedural assignments to uwires earlier in elaboration.
A uwire is never a valid l-value for a procedural assignment (other
than a force/release), so catch that error as soon as we can. We
then know that any remaining l-values with type UNRESOLVED_WIRE must
be variables which have been coerced by a continuous assignment.
2024-02-03 16:57:36 +00:00
Martin Whitaker a133ae5d9a Add check that entire array isn't both procedurally and continuously assigned.
This fixes issue #1090.
2024-02-03 16:19:22 +00:00
Martin Whitaker 73897b2af6 Refactor code to reduce indentation level.
In preparation for next commit. No functional change.
2024-02-02 22:30:17 +00:00
Martin Whitaker 56f457d65e Allow force assignments on unresolved wire array words.
A force doesn't require resolution. We already allow this for
individual unresolved wires.
2024-01-28 14:33:17 +00:00
Lars-Peter Clausen 131e64c53c Detect reversed part select on inner dimensions
The order of the indices of a part select need to match the order in which
the dimension of a packed array has been declared. E.g. if the msb is less
than the lsb in the declaration it also has to be for the part select.

If the order of the part select is the opposite of the declaration this is
an error. This works as expected for part selects on the most outer
dimensions.

But for inner dimensions the current implementation just swaps the msb and
lsb of the part select if they are in the wrong order.

Refactor this so that an error is reported for both the outer and inner
dimensions.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-12-29 16:34:46 -08: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
Lars-Peter Clausen 3daa2982ac Add support for `const` variables
SystemVerilog allows to declare const variables. These variables are
read-only and can not be assigned a value after their declaration. It is
only possible to assign an initial value as an initializer.

E.g.
```
const int x = 10;
x = 20; // Error
```

The LRM requires that for variable declarations with static storage the
initializer is a constant expression with the extension that other const
variables are also allowed. const variables with automatic storage can
be initialized by any expression.

Checking if an expression contains only const variables requires a bit more
work to implement. So for now be more lenient that what the standard
requires and allow arbitrary expressions to initialize const variables even
for those with static storage.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-07-23 15:08:39 -07:00
Cary R fdb9465329 Indexed part selects cannot use real values 2023-07-09 12:25:34 -07:00
Cary R 2249d224de Bit/part selects cannot have real index expressions 2023-07-09 03:47:41 -07:00
Lars-Peter Clausen 9549156226 Add initial support for array assignment patterns
SystemVerilog allows to use assignment patterns to assign values to an
array. E.g. `int a[4] = '{1, 2, 3, 4}`.

Each value is evaluated in the context of the element type of the array.

Nested assignment patterns are supported. E.g. `int a[2][2] = '{'{1, 2},
'{1, 2}};`

Add initial support for array assignment patterns for both continuous as
well as procedural assignments.

For continuous assignments the assignment pattern is synthesized into an
array of nets. Each pin is connected to one of the assignment pattern
values and then the whole net array is connected to target array.

For procedural assignments it is unrolled in the vvp backend. E.g
effectively turning `a = '{1, 2};` into `a[0] = 1; a[1] = 2;`.

Not yet supported are indexed initializers or `default`.
E.g. `int a[10] = '{1:10, default: 20};`

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-17 11:50:23 -07:00
Lars-Peter Clausen 3fc6ab5afc Replace assert() with ivl_assert() where line information is available
`ivl_assert()` is similar to `assert()` except that it will also include
source file and line information about the expression for which the assert
was triggered.

Use `ivl_assert()` instead of `assert()` where the line information is
available. This will generate better bug reports and make it easier to
diagnose why an assert is triggered.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-16 05:06:15 -07:00
Stephen Williams 18192fdba9
Merge pull request #862 from larsclausen/enum-compat-check
Improve enum compatbility checks
2023-01-16 19:34:05 -08:00
Lars-Peter Clausen d0613f24b8 Allow to attach data type to lvalue part select
In most cases the type of an lvalue part select is the base type of the
lvalue with the width of the part select. But there are some exceptions.

1) An index into a `string` type is of type `byte`.

2) Packed structs are implemented as packed arrays under the hood. A lvalue
struct member is elaborated as a normal part select on a packed array. The
type of that select should be the type of the member.

For the case 1 there is some special handling for strings that accounts for
this. But for case 2 the type information of the member is lost.

This works fine for most things but there are a few constructs where the
type information is required.
 * Enum type compatibility check
 * Assignment pattern behavior depends on the type of the lvalue

Allow to attach a specific type to a lvalue part select to allow correct
behavior for constructs where the type is required.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-01-16 12:38:10 -08:00
Lars-Peter Clausen e24aa18a80 Add common implementation for scoped symbol search
In SystemVerilog identifiers can usually have an additional package scope
in which they should be resolved. At the moment there are many places in
the code base that handle the resolution of the package scope.

Add a common data type for package scoped paths as well as a
symbol_search() variant that works on package scoped identifiers. This
allows to handle package scope resolution in a central place.

Having the code in a central place makes it easier to ensure consistent and
correct behavior. E.g. there are currently some corner case bugs that are
common to all implementations. With the common implementation it only has
to be fixed in one place.

It will also make it easier to eventually implement class scoped
identifiers.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-01-16 12:26:24 -08:00
Lars-Peter Clausen 07e20376d7 Consolidate class property handling
There are currently two mechanisms for handling class properties. One that
is used when a class property is accessed through an object and other when
a class property is used freestanding in a class method.

Both are very similar, but there are some small differences. E.g. one
supports arrays, the other supports nested properties.

```
class B;
  int x;
endclass

class C;
  B b;
  B ba[2];
  task t;
    ba[0] = new; // Does work
    this.ba[0] = new; // Does not work
    b.x = 10; // Does not work
    this.b.x = 10; // Does work
  endtask
```

There is another problem where free standing properties take precedence
over local variables. E.g.

```
class C;
  int x = 1;
  task t();
    int x = 2;
    $display(x); // Should print 2, will print 1
  endtask
endclass
```

The class property elaboration also ignores the package scope of the
identifier resulting in access to a class property being elaborated if
there is a property of the same name as the scoped identifier. E.g.

```
package P;
  int x = 2;
endpackage

class C;
  int x = 1;
  task t;
    $display(P::x); // Should print 2, will print 1
  endtask
endclass
```

Consolidate the two implementation to use the same code path. This is
mainly done by letting the symbol search return a result for free standing
properties as if the property had been specified on the `this` object. I.e.
`prop` and `this.prop` will return the same result from the symbol search.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-01-16 07:13:42 -08:00
Lars-Peter Clausen 8a807695e5 Allow access to static properties of base classes
Classes are allowed to access properties of the base class. This also
includes static properties. Currently when looking up a static property
only those of the class itself are considered. Extend this to also consider
properties of the base classes.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-29 11:17:43 -08:00
Lars-Peter Clausen 710267e9bb Elaborate member selects in the scope where they are used
There are a few cases where a member select on a package scoped identifier
is evaluated in the scope of the package rather than the scope where the
identifier is referenced.

This leads to incorrect behavior if a local symbol is used as an index in a
part select of the referenced member select. E.g.

```
package P;
  localparam N = 1;
  struct packed {
    logic [3:0] x;
  } s = 4'b0101;
endpackage

module test;
  localparam N = 2;
  initial $display(P::s.x[N]); // Will print 0, should print 1
endmodule
```

Use the scope where the member select is used, rather than the scope where
the identifier is defined, to fix this.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-28 17:54:48 -08:00
Cary R dc8b7d0184 Cleanup some cppcheck warnings 2022-12-28 00:00:31 -08:00
Lars-Peter Clausen c0adbd0deb Add support for handling `super` keyword
SystemVerilog allows to use the `super` keyword to access properties and
methods of a base class. This is useful if there is for example an
identifier with the same name in the current class as in the base class and
the code wants to access the base class identifier.

To support this a bit of refactoring is required. Currently properties are
internally referenced by name, this does not work if there are multiple
properties of the same. Instead reference properties always by index.

In addition when looking up an identifier that resolves to an object return
both the type and the object itself. This is necessary since both `this`
and `super` resolve to the same object, but each with a different type.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-25 09:19:21 -08:00
Lars-Peter Clausen 862b118098 PEIdent::elaborate_{expr,lval}(): Use new symbol_search()
The PEIdent elaborate_expr() and elaborate_lval() are sort of open-coding
the path traversal implemented by the new symbol_search() using the old
symbol_search().

Switch them over to use the new symbol search as it is better at handling
the corner cases and is also less code.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-25 09:19:12 -08:00
Lars-Peter Clausen f95f9955c8 Handle assignment to static class properties in class methods
Assigning a value to a static class property in a class task or function
will currently not write to the static signal, but instead to an otherwise
invisible per instance property. E.g. the example below will print 0 when
the task `t` is called.

```
class C;
  static int i;
  task t;
    i = 10;
    $display(i);
  end
endclass
```

Since static class properties are implemented as normal signals just
fallback to the default signal handling when an assignment to a static
class property is detected.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-04-12 11:45:25 +02:00
Martin Whitaker 71c36d1289 Improve error message on assignment to an array or array slice (issue #562).
This is valid SystemVerilog, but not something we support yet.
2021-11-12 21:43:24 +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 7d7aa0604c Properly report errors for out-of-bounds constant indexed part selects.
(replacing assertions)

The IEEE standard either requires out-of-bounds bits to be ignored on
write, returned as 1'bx on read, or requires a compile-time error message.
The latter is easier to implement.
2021-04-20 22:58:40 +01:00
Martin Whitaker 4af830187e Support indexed part selects that index sub-arrays (issue #497) 2021-04-20 21:29:00 +01: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 da7484eea1 Update compiler with suggestions from cppcheck 2021-01-02 14:04:46 -08:00
Stephen Williams c943484b39 Fix elaborations_sig of string types.
String variables are "string" and not "netvector_t:string".
Why did this ever work?
2020-12-30 10:39:51 -08:00
Stephen Williams 752401b88c output ports of real type are variables, not wires. 2020-12-29 22:00:04 -08:00
Stephen Williams a79b55ae28 Support nested struct in continuous assign l-values
When doing continuous assignment of packed structs, support the case
where the value being assigned is a member of a member, etc. Procedural
assignments already support this.

See issue#307
2020-11-29 18:18:55 -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
Martin Whitaker 465e0d2710 Allow classes to reference declarations in their enclosing scope(s).
The original implementation made each class a root scope. They should
be added to the scope hierarchy just like any other declaration.
2019-12-22 10:46:38 +00:00
Stephen Williams 7feb26ff6b Cleaner elaboration of void functions.
This fixed githun issue # 281.
2019-11-07 14:25:51 -08:00
Cary R e4ef928751 Fix some space issues 2019-09-29 17:11:19 -07:00
Stephen Williams d7ee6bb6bb Support struct member part selects in l-values. 2019-09-27 13:51:51 -07:00
Stephen Williams 2aa7700970 Add support for packed arrays in nested struct l-values. 2019-09-17 13:34:36 -07:00
Stephen Williams 1c281c2d77 Support nested struct l-values. 2019-09-16 13:50:17 -07:00