Commit Graph

9793 Commits

Author SHA1 Message Date
Lars-Peter Clausen 4036c77416 parser: Consolidate named expression parsing
There are a few different places in the parser that all parse named
expressions in the same way. Consolidate them into a single rule.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-08-19 10:12:00 -07:00
Lars-Peter Clausen e7f66fe7ac Use standard constructor to copy std::list to std::vector
There are a few places in the code where a std::list is copied to a
std::vector by iterating through the list and copying each element over to
the vector. The std::vector type has a iterator based constructor that can
do the same.

Update the code to use it instead. This removes a bit of boilerplate code
and also makes it easier to update the code.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-08-19 10:12:00 -07:00
Lars-Peter Clausen ce243268d0 Use `named_pexpr_t` type instead of open-coding it
`named_pexpr_t` is a typedef for `named<PExpr*>`. There are a few places
where `named<PExpr*>` is used directly. Replace those with `named_pexpr_t`
for consistency.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-08-19 10:12:00 -07:00
Lars-Peter Clausen 2cef85f8a1 Add helper function for printing expression list
There are a few places where some sort of expression list is printed. Add
helper functions to consolidate this in a single place and reduce the
amount of code.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-08-19 10:12:00 -07:00
Lars-Peter Clausen 520b00095c Remove unused `named_number_t` type
The last user of the named_number_t type was removed in commit 2f474358d9
("2f474358d99929ec625a46690d1be6939ed67064"). Remove the type as well.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-08-19 10:12:00 -07:00
Cary R 8bcdb5d862
Merge pull request #990 from masloyet/vvp-scope-search-typo
Fix Typo in vvp's scope search in interactive mode.
2023-08-18 07:07:58 -07:00
Mason Loyet dc1038c877 Fix Typo in vvp's scope search in interactive mode.
When vvp parses a command which it thinks is a system call it tries to
match the symbols to values in the scope. The typo uses the wrong index
variable to access the vpi table. This results in a failed dynamic cast
which goes unchecked until the value is dereferenced, resulting in a
segfault.
2023-08-17 05:44:31 +00:00
Cary R 09f3ebfc88
Merge pull request #984 from larsclausen/class-constructor-chain
Fix class constructor chaining corner cases
2023-08-06 04:25:40 -07:00
Lars-Peter Clausen 8ca8ad3c81 Add regression tests for chained constructors
Check that constructor chaining for various corner cases of mixing implicit
and explicit constructors are handled correctly.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-08-06 02:10:28 -07:00
Lars-Peter Clausen c512faa967 Make sure chained constructor is called when using `extends`
Currently when neither an explicit constructor is specified nor any
properties are present in the class that will create an implicit
constructor there will be no constructor for the class.

As a result a class that specifies the arguments for the base class
constructor as part of the `extends` clause will not have the base
constructor called with the right arguments.

E.g.
```
class C;
  function new(int a);
  endfunction
endclass

class D extends C(10);
endclass
```

To avoid this make sure that an implicit constructor is created when
passing arguments through the `extends` clause.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-08-06 02:10:28 -07:00
Lars-Peter Clausen 6ea01cbf7f Fix class constructor chaining corner cases
There are some corner cases around class constructor chaining that can
result in chained constructors not being called, or being called multiple
times.

This is primarily related to that a class can have either an explicit
constructor called `new` and an implicit constructor called `new@` and how
the lookup of them is done.

Lookup is currently done independently for the implicit and explicit
constructor using the `method_from_name()` method. `method_from_name()`
will search the whole class hierarchy for a class method. If a class
doesn't have a method by that name it will look in the parent class and so
on.

As a result the lookup for the explicit constructor can return the explicit
constructor of a parent class if the class itself only has an implicit
constructor and vice versa.

E.g. in the following example the constructor of D will not be called
because the implicit constructor for C is found when looking for a implicit
constructor in D.

```
class C;
  int x = 10;
endclass

class D extends C;
  function new;
    $display("D");
  endfunction
endclass

class E extends D;
  int y;
  function new;
    y = 20;
  endfunction
endclass

E e = new;
```

There is a similar case where the constructor of a base class can be called
multiple times if the base class has an explicit constructor and the
derived class has an implicit constructor. In that case the derived class
constructor will call the base class constructor, but the code that is
emitted for the `new` statement will call both of them.

To mitigate this introduce a new method to lookup the constructor that will
search for either the explicit or implicit constructor in the current class
and only continue to search in the base class if neither is found.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-08-06 02:10:28 -07:00
Cary R 0651e0be17
Merge pull request #982 from larsclausen/const-var-fix
Make sure `const var` variables are constant
2023-08-05 18:27:34 -07:00
Cary R d660ca7179
Merge pull request #981 from larsclausen/automatic-2state
vvp: Initialize automatic 2-state vectors to 0
2023-08-05 17:44:30 -07:00
Lars-Peter Clausen bdfd873dc4 Add regression test for `const var`
Check that variables declared with `const var` can not be modified.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-07-29 12:26:35 -07:00
Lars-Peter Clausen 06428f3d11 Make sure `const var` variables are constant
Commit 3daa2982ac ("Add support for `const` variables") added support for
constant variables, but had a small mistake and did propagate the constant
flag from the parser if the variable is declared with the `var` keyword.
Still allowing to modify those variables. Fix this.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-07-29 12:26:35 -07:00
Lars-Peter Clausen 6928b38720 Add regression tests for automatic 2-state variable default value
Check that automatic 2-state variables get initialized to 0.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-07-29 06:33:46 -07:00
Lars-Peter Clausen 0dfbcbdf47 vvp: Initialize automatic 2-state vectors to 0
Automatic 2-state vectors currently get initialized to 'hx, while their
default value should be 0.

Make sure the vector is initialized to 0 at the beginning of the automatic
context.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-07-29 06:17:47 -07:00
Stephen Williams 999bcb6935
Merge pull request #975 from larsclausen/sv_const_var
Add support for `const` variables
2023-07-25 19:15:10 -07:00
Lars-Peter Clausen f092820599 Add regression tests for const variables
Check that const variables are supported and they can not be overridden by
type of assignment.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-07-23 15:14:04 -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 9e4c4d5460 `line directive line number must be > 0 and can have arbitrary space 2023-07-19 01:51:36 -07:00
Cary R 3aafa1333b Update $ferror() and $fgets() to support SV strings 2023-07-19 00:30:50 -07:00
Cary R ceb07dc9db
Merge pull request #966 from mole99/delayed-signals
Handle delayed signals in timing checks as assignments
2023-07-14 06:33:37 -07:00
mole99 13fcf2d844 Remove checks for non-NULL before deleting 2023-07-14 08:06:06 +02:00
Stephen Williams f2621d88c1
Merge pull request #971 from larsclausen/arith-expr-type-fix-runtime
Avoid exponential execution time behavior in arith_expr_type()
2023-07-13 19:38:21 -07:00
mole99 e0d0dff8d6 Change timing check condition to expression for better compatibility 2023-07-13 10:15:52 +02:00
mole99 6b2990cfec Use more C++11 features 2023-07-12 15:10:23 +02:00
Lars-Peter Clausen 26d1c72e77 Avoid exponential execution time behavior in arith_expr_type()
arith_expr_type() queries the expression type of its two child nodes up to two
times. Since the child nodes might also need to query their child nodes
expression type to determine their own this can lead to an exponential runtime.

For complex expressions this can easily result in very long elaboration time.

Avoid this by querying the expression type only once for each child node.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-07-12 04:43:03 -07:00
mole99 7f5b8d49eb Fix timing_check_syntax 2023-07-10 16:12:27 +02:00
mole99 d46628b2f2 Improve parsing of timing checks 2023-07-10 15:59:14 +02:00
Cary R fdb9465329 Indexed part selects cannot use real values 2023-07-09 12:25:34 -07:00
Cary R 095e6daa0a Cannot use posedge, negedge or edge with a real expression 2023-07-09 05:02:01 -07:00
Cary R 2249d224de Bit/part selects cannot have real index expressions 2023-07-09 03:47:41 -07:00
mole99 e54ff22fce Fix wrong output 2023-07-05 16:50:10 +02:00
mole99 7aabcc113e Add test for delayed signals in timing checks 2023-07-05 16:24:04 +02:00
mole99 21b73eb187 Add test for parsing timing checks 2023-07-05 16:23:15 +02:00
mole99 87885dbd9b Handle delayed signals in timing checks as assignments 2023-07-05 16:22:08 +02:00
Cary R 272771d183
Merge pull request #965 from larsclausen/sv-partial-module-ports
Support SystemVerilog style partial ANSI port declarations
2023-06-30 07:25:16 -07:00
Lars-Peter Clausen c5f98fb671 Add regression tests for partial ANSI port declarations
Check that it is possible to declare module ports with only partial
attributes. Other attributes should be inherited from the previous port in
the list or use the default.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-30 06:09:45 -07:00
Lars-Peter Clausen 664a611e16 Support SystemVerilog style partial ANSI port declarations
In Verilog it is possible to declare multiple ports as part of the same
port declaration. Ports declared this way all have same direction, signal
kind and data type. E.g.

```
module M (input [3:0] a, b, c) ...
```

SystemVerilog extends this and allows to override on a per port basis
certain port attributes. E.g. redefine just the data type

```
module test (input [3:0] a, [1:0] b, int c) ...
```

Or to just redefine the port kind

```
module test(input [3:0] a, var b, wire c) ...
```

It is even possible to leave out the direction for the very first port. As
long as at least one other property of the port is specified. In that case
the direction will default to `inout`. E.g.

```
module test(integer a, b, c) ...
```

Furthermore it is possible to specify unpacked dimensions for each of the
ports. E.g.

```
module test(input integer a, b[1:0], c[3:0][1:0]) ...
```

If all port properties are omitted for the first port this indicates the
start of a non-ANSI port list.

Extend the parser to handle this.

If all three direction, port kind and data type are omitted they are
inherited from the previous port. Otherwise

 * If the direction is omitted it is inherited from the previous port.
 * If the data type is omitted it defaults to logic.
 * If the port kind is omitted the behavior depends on the direction.
   For output ports with an explicit data type it is a variable, for
   all others it is a net.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-30 05:58:19 -07:00
Lars-Peter Clausen 82a974a801 Add parser helper function for module port declaration
Add a helper function to the parser that handles module port declaration.
This allows to reduce a bit of duplicated code.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-28 07:58:33 -07:00
Cary R 17461e02de
Merge pull request #964 from larsclausen/bits-array
Support $bits() for arrays and array slices
2023-06-28 07:50:43 -07:00
Lars-Peter Clausen 708f7bc651 Add regression test for $bits() on array identifiers
Check that for array identifiers $bits() includes the total size of the
signal.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-27 05:29:47 -07:00
Lars-Peter Clausen 7908e15093 Support $bits() for arrays and array slices
`$bits()` for array types is supposed to return the full size of the array
in bits. This currently works for data types that are passed to `$bits()`,
but not for array typed identifiers.

E.g.
```
typedef int T[1:0];
T x;
$display($bits(T)); // -> 64
$display(x); // -> 32
```

Since the `$bits()` implementation uses the expr_width of an expression
include the size of the unpacked dimensions in that for array identifiers
and array slices. Strictly speaking an array identifier does not have an
expression width, but this would be its expression with if it were for
example bitstream cast to a vector.

Special care needs to be take to not trying to pad array identifier
expressions.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-27 05:26:58 -07:00
Cary R a3f1aded7c
Merge pull request #961 from larsclausen/fix-bitsel-sign
Fix bit select on signed multi-dimensional packed array
2023-06-26 07:57:03 -07:00
Lars-Peter Clausen 2a17b06fc4 Add regression test for bit select on multi-dimensional signed packed array
Check that element and bit select on multi-dimensional signed packed arrays
are unsigned.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-26 06:27:52 -07:00
Lars-Peter Clausen 61381fd9cd Fix bit select on signed multi-dimensional packed array
Bit selects on packed arrays are always unsigned and have a width of 1.
Element selects on a multi-dimensional packed array are always unsigned and
have the width of the element.

At the moment a element or bit select on the last level element of a
multi-dimensional signed array will incorrectly yield a signed expression.

Commit 40b36337e2 ("Fix some bugs with packed array dimensions") added
some special checks to fix the width on multi-dimensional array element
selects. But this removed the unsigned attribute from bit selects.

Commit 81947edaa5 ("A bit select is not the same as selecting part of a
packed array") fixed this for single dimensional packed array, but left it
broken for multi-dimensional arrays.

Commit 7c024d6cab ("Fix width calculation for bit/part selects of
multi-dimensioned packed arrays.") added some additional fixes for the
width calculation, which make the special checks in the first commit
unnecessary.

We can now remove those checks which will give us the correct behavior in
terms of the signedness of bit and element selects on both single- and
multi-dimensional packed arrays.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-26 06:27:30 -07:00
Cary R a21be045a1 Translate a Verilog for loop correctly in tgt-vhdl 2023-06-25 23:33:46 -07:00
Cary R a1c8b33945 Cleanup some clang compile warnings 2023-06-25 21:53:10 -07:00
Cary R 017a68c193 Update SDF warnings to include SDF file/line information 2023-06-25 20:12:43 -07:00