Commit Graph

172 Commits

Author SHA1 Message Date
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
Martin Whitaker dc5429e5e7 Fix assertion failure on assignment to part of variable member (GitHub issue #226)
For now, output a "sorry" message, as the compiler doesn't support this.
2019-01-26 17:36:19 +00:00
Cary R 5853e32f82 Fix some cppcheck warning issues 2016-09-13 23:45:25 -07:00
Martin Whitaker b51e58fa9d Fix for br1007 - out-of-range constant bit select should be a warning.
An out-of-range constant bit select on the LHS of an assignment was being
treated as an error, whereas an out-of range constant part select would
only result in a warning. In any other context, either case would result
in a warning, so convert the error to a warning.

In addition, all warnings for out-of-range or undefined constant bit/part
selects should be controlled by -Wselect-range.
2016-08-08 22:10:16 +01:00
Larry Doolittle 89edf62206 Capitalize Verilog in a few places 2016-04-01 11:02:24 -07:00
Martin Whitaker 0199ad129d Fix expression type for compressed assignment statements.
A compressed assignment statement should give exactly the same
result as the equivalent uncompressed statement. This means
that the type (signed/unsigned) of the LHS affects the type of
the RHS expression (unlike in normal assignments). We need to
take care that bit/part selects and concatenations are correctly
identified as unsigned values, even in the cases where they
reduce to a single whole signal.
2016-02-23 16:53:01 +00:00
Larry Doolittle 3e2196651a Remove unused parameter to indices_to_expressions
need_addr has been hanging around, unused, since commit 078a3fd4 on Jan 17, 2014.
2015-07-31 09:48:33 -07:00
Larry Doolittle b23faff27c Just a few more spelling fixes
Includes some user-visible messages
2015-06-17 08:09:34 -07:00
Stephen Williams 386774ac19 Work towards handing packed arrayed members. 2015-02-19 20:02:15 -08:00
Stephen Williams 86562e60ba Work towards nested packed struct member vectors. 2014-12-23 13:52:38 -08:00
Stephen Williams a98f21aa65 Merge branch 'master' into vec4-stack
Conflicts:
	elab_lval.cc
	netmisc.cc
	tgt-vvp/eval_object.c
	tgt-vvp/vvp_process.c
	vvp/codes.h
	vvp/compile.cc
	vvp/opcodes.txt
	vvp/vpi_tasks.cc
	vvp/vpi_vthr_vector.cc
	vvp/vthread.cc
2014-10-21 09:12:02 -07:00
Stephen Williams ea4b000be6 Get arrayed property expressions down to the ivl_target API. 2014-09-15 17:37:30 -07:00
Cary R 1cfbd2db63 Fix some cppcheck warnings. 2014-09-10 18:54:01 -07:00
Stephen Williams 697701a26e Sorry messages for property arrays. 2014-09-07 17:48:19 -07:00
Stephen Williams 88e951418b Handle elaboration of class properties referenced within sub-scopes. 2014-09-06 16:26:08 -07:00
Stephen Williams 3b0dfaadba Some support for unpacked arrays in class properties. 2014-09-02 09:23:54 -07:00
Stephen Williams 1d63875e5d Merge branch 'master' into vec4-stack
Conflicts:
	elab_lval.cc
2014-02-10 16:26:22 -08:00
Stephen Williams 52a9fdde8a Handle packed structs as module outputs. 2014-02-03 19:22:59 -08:00
Stephen Williams 4f1c43b690 Account for force l-values that are uwires. 2014-02-02 17:05:42 -08:00
Stephen Williams 0be577cc44 Allow some behavioral assignments to unresolved wires.
If the l-value is an unresolved wire, then elaboration can allow
the assignment as long as it is to bits that are not otherwise
driven. Handle this in some simple cases.
2014-02-02 11:08:43 -08:00