Commit Graph

1073 Commits

Author SHA1 Message Date
Lars-Peter Clausen d4765e3354 Don't implement `packed_width()` for dynamic array types
The `netdarray_t` type implements the `packed_width()` method by returning
the packed width of the element type. It is the only non-packed type that
implements the method.

This triggers an assert in the vlog95 backend for tasks with dynamic array
typed parameters. And while the vlog95 backend does not support dynamic
array types it should not result in a crash, just an error message.

The only place that relies on the behavior that the packed width of the
element type is returned is in the vvp backend where variable declarations
are generated. Update that code to query the packed width of the element
type instead and then remove the `packed_width()` implementation for the
`netdarray_t` type.

This fixes the assert in the vlog95 backend. But it is also nicer from an
architectural perspective as this brings the type in line with the other
types in terms of behavior.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-10-08 13:42:45 +02:00
Lars-Peter Clausen f831d7d76f Add `ivl_type_packed_width()` API
The C++ API for `ivl_type_t` has a method to query the total width of a
packed type. This is currently not exported to the C API and the tgt-vvp
backend implements similar functionality by querying the individual
dimensions of a type.

Export the `packed_width()` method to the C API. This allows to remove the
custom implementation from the tgt-vvp backend.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-10-08 13:42:40 +02:00
Lars-Peter Clausen c3c7f6d9ee tgt-vvp: Fix syntax when using multiple events for non-blocking event control
When multiple events are used in a non-blocking event control they need to
be combined into a single event using `event/or`.

The generated `event/or` statement is missing the trailing semicolon and
newline, which results in parser error when vvp tries to run.

E.g.

```
event e, f;
integer x;
x <= @(e or f) 10;
```

Add the missing semicolon and newline to fix this.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-06-06 17:00:13 +02:00
Lars-Peter Clausen ec75c1aa74 Handle non-blocking event control to lvalue concatenation
A non-blocking event controlled assignment consists of 3 steps.

 * Setup event
 * Perform assignment
 * Clear event

This works fine if the lvalue is a singular value. If the lvalue is a
concatenation multiple assignments are generated and the event is cleared
after each assignment. As a result only the first assignment is event
controlled. All other assignments will be regular non-blocking assignments.

E.g.

```
reg x, y;
event e;
{x,y} <= @e 2'b11;
$display(x, y); // x will be 1'b1, y will be 1'bx
```

To resolve this the event needs to be cleared after all assignments have
been done. This requires changes to both tgt-vvp and the vvp runtime.

tgt-vvp is updated to only insert a single `%evctl/c` instruction for each
event controlled non-blocking assignment.

The vvp runtime is not updated to implicitly clear the event in the
`%assign/vec4/e` instruction and instead rely on the explicit `%evctl/c`.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-06-04 22:27:00 +02:00
Lars-Peter Clausen ab95d1d903 tgt-vvp: Handle dynamic part select on array element non-blocking event control
VVP array assignment operations expect the array element index to be in
index register 3.

For array element assignments with a dynamic part select the array index
gets moved into a temporary index register and has to be moved into
register 3 after evaluating the dynamic part select.  This is currently not
done non-blocking event control assignments. This causes the write to go to
the wrong array element. It will go to whatever value is in the register 3
from previous operations.

```
reg [3:0] a[1:0];
integer i = 0;
event e;
a[1][i+:2] <= @e 2'b10; // Will write to the wrong array element
->e;
```

Make sure to move the temporary register to register 3.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-06-04 22:26:53 +02:00
Stephen Williams bf4bee319d
Merge pull request #722 from larsclausen/real-array-assignment-op
tgt-vvp: Handle assignment operator on real array entries
2022-06-01 23:13:05 -07:00
Lars-Peter Clausen a4eeea75ce tgt-vvp: Handle assignment operator on real array entries
The basic structure for supporting assignment operators on real arrays
exists in the tgt-vvp backend. But there are a few problems, most
importantly it generates the wrong instruction for loading data from the
real array.

The instruction it uses is `%load/reala`, but that instruction does not
exist, the correct name is `%load/ar`.

In addition to this there are a few minor problems.
  * Out-of-bounds access on the array triggers an assert
  * Missing `%pop/real` instruction when skipping a write due to
    out-of-bounds access

Address these so assignment operators are supported on real array entries.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-05-26 21:30:04 +02:00
Lars-Peter Clausen d3573334d6 tgt-vvp: Handle signedness when passing struct member to system function
Access to members in packed struct fields is internally implemented using a
part select.

vvp has a special syntax for passing a part select of a vector to a system
function. This special syntax assumes that the part select is unsigned like
it is for normal Verilog part selects.

As a result passing a signed struct member to a system function will
interpret it as unsigned.

Add a check to make sure that the expression is actually unsigned. If it is
not fall back to evaluating the expression on the vector stack and pass the
value on the stack to the system function.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-05-24 11:32:19 +02:00
Lars-Peter Clausen d651aefd92 tgt-vvp: Allow out-of-bounds assignment operator on arrays wider than 32 bits
For an out-of-bounds assignment operator on an array element an assert is
hit if the element width is great than 32.

Remove the assert and make sure that this case is handled correctly by
using the `%pad/s` instruction to extended the X value to the correct
width.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-05-21 21:30:33 +02:00
Lars-Peter Clausen d746c592b2 tgt-vvp: Fix out-of-bounds compressed assignment to arrays
If the index of an array access is known to be out-of-bounds during
elaboration it is replaced with 'x. In the tgt-vvp backend that is handling
compressed array assignments there is an assert() that triggers if the
index is an undefined immediate.

There is already an existing code path that is capable of handling
out-of-bounds access. Remove the assert and set the index to ULONG_MAX to
trigger taking the out-of-bound access path.

On this out-of-bounds path the write to the array is skipped. But this
leaves the result on the vector stack. Insert the `%pop/vec4` instruction
to make sure it is removed.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-05-21 21:15:20 +02:00
Lars-Peter Clausen e263d5b268 tgt-vvp: Fix store skip for assignment operator on dynamic part select
The operator assignment on dynamic part selects uses the `%store/vec4`
instruction to store the value. This instruction will skip the assignment
if flag 4 is set. This is for handling the case where the index is
undefined.

Since the left hand side of the assignment is an arbitrary expression it
can change the flag. The implementation handles this by making a copy of
the flag and restoring it before executing the `%store/vec4` instruction.

The flag is set by the `%ix/vec4` instruction when loading the index
register. But the copy of the flag is made before that and just picks
up the flag that was stored by previous expressions. This can cause
the store to be skipped when it shouldn't.

E.g. in the following code the increment will be skipped. Flag 4 is used
from the `a == 0` comparison, rather than from computing the part select
index.

```
int a = 0;
if (a == 0) begin
  a[a+:2] += 1;
end
$display(a); // Will print 0, should print 1
```

Fix this by moving the copy of the flag after the `%ix/vec4` instruction.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-05-16 10:18:27 +02:00
Lars-Peter Clausen 2abfef68ff tgt-vvp: Fix load skip for assignment operator to array entry
The vvp `%load/vec4a` instruction will skip the load if vvp flag 4 is set
and return 'x. This is meant for handling the case where the index is
undefined.

For assignment operators on array entries, when the index is an immediate
value, vvp flag 4 is not cleared before the load instruction. If a previous
instruction set flag 4 it load yield 'x.

E.g. for the following sequence `x[0]` should be `11`, but will be `'x`.

```
integer x[10];
logic a = 1'b0;
x[0] = 10;
if (a == 0) begin
  x[0] += 1;
end
```

Properly clear the flag before the load instruction to handle this
correctly.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-05-16 10:18:27 +02:00
Lars-Peter Clausen b83ebf3c8e tgt-vvp: Fix store skip on real typed array entries
When assigning a value to a real typed array entry the vvp `%store/reala`
instruction. This instruction will skip the store if the vvp flag 4 is set.
This is to handle the case where the index is undefined.

When the index into the array is an immediate value the flag 4 is not
cleared. If a previous instruction set flag 4 the store will be skipped.

E.g. for the following r[0] will remain 0.0 since the assignment to it is
skipped.

```
integer a = 0;
real r[1:0];
if (a == 0) begin
  r[0] = 1.23;
end
```

Fix this by using the `draw_eval_expr_into_integer()` helper function to
evaluate the index into a word register. The function correctly handles all
the special cases.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-05-16 10:18:27 +02:00
Stephen Williams e67a796a77
Merge pull request #709 from larsclausen/remove-draw-bool
tgt-vvp: Remove unused draw_eval_bool64()
2022-05-12 14:49:42 -07:00
Lars-Peter Clausen 5a616bcaf4 tgt-vvp: Remove unused draw_eval_bool64()
Ever since the conversion to use a stack for vectors `draw_eval_bool64()`
has been unused. The last caller of `draw_eval_bool64()` was removed in
commit e4b862f3d1 ("Clean up vector handling dead code.").

Remove `draw_eval_bool64()` and related functions as well.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-05-04 11:45:46 +02:00
Lars-Peter Clausen 1eb22b7e14 tgt-vvp: Allow multi-dimensional real arrays
There is currently a restriction in the vvp code generator backend that
throws an assertion when generating wire access for a multi-dimensional
real array.

But there is nothing special about multi-dimensional arrays. In vvp arrays
are in canonical form. Meaning they only have a single dimension and the
conversion form multi to single dimension is done in the higher layers.

Remove the assert to allow multi-dimensional real arrays.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-05-02 14:29:15 +02:00
Lars-Peter Clausen b11da7e16f tgt-vvp: Don't accidentally skip assignment pattern initialization
The `%store/dar/...` and `%store/qdar/...` instructions are used to load a
value into an entry in dynamic array or queue. These instructions will skip
the load if VVP flag 4 is 1.

For assignment pattern initialization these instructions are used to load
the value of the individual assignment pattern expressions into the dynamic
array.

For queues flag 4 is never cleared when generating the code for the
assignment pattern. This means the initialization might be skipped
depending on what value the flag had before.

```
int a = 1;
int q[$];
a = a == 1;
q = {1, 2, 3, 4};
```

For dynamic arrays it is cleared once in the beginning. But each item in
the assignment pattern can be an arbitrary expression.  Evaluating the
expression can cause the flag to get overwritten. E.g. the following code
will skip the assignments.

```
int a = 1;
int d[];
d = {a ? 1 : 1, 2, 3, 4};
```

To fix these issues make sure that the flag is cleared after evaluating
each initialization expression and before executing the `%store/...`
instruction.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-04-17 09:09:38 +02:00
Lars-Peter Clausen 84c3c72563 Support recursive functions using `return` statement
A `return` statement in a function gets translated into a vvp `%disable`
instruction. This works fine as long as no recursion is involved. The
`%disable` instruction will stop execution of all active threads of a
particular scope. For recursive functions this means as soon as the inner
most function returns all containing outer function calls get disabled as
well. This results in incorrect behavior.

To make recursive functions using the `return` statement work use the new
vvp `%disable/parent` instruction. This instruction will only disable the
closest thread in the thread hierarchy that matches the target scope.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-04-11 22:03:02 +02:00
Martin Whitaker e53b2e774b Further fixes for vvp code generation for c. assign of an array word.
The draw_net_input() function can write additional statements to the output
file, so must not be called in the midst of writing a statement.
2022-03-19 10:22:49 +00:00
Martin Whitaker 831db5a0d7 Fix vvp code generation for c. assign shift of array word (issue #632) 2022-03-14 23:24:20 +00:00
Lars-Peter Clausen 32d1f385f8 tgt-vvp: Allow dynamic array new for vectors with multiple packed dimensions
In the vvp all vector signals are in canonical form. This means a single
dimension and the lsb starts at 0.

This means that there is no need to restrict new operations for dynamic
arrays of vectors to vectors with 0 or 1 packed dimensions. Multiple packed
dimensions will work just fine. All that is needed is the total packed
width for the signal.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-03-12 12:17:08 +01: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
Lars-Peter Clausen d4334139d3 tgt-vvp: Short circuit logical operators
Section 11.4.7 of the SystemVerilog LRM states

```
The && and || operators shall use short circuit evaluation as follows:
  - The first operand expression shall always be evaluated.
  - For &&, if the first operand value is logically false then the second operand shall not be evaluated.
  - For ||, if the first operand value is logically true then the second operand shall not be evaluated.
```

vvp currently evaluates both operands of a logical operator. This works
fine as long as the right-hand side does not have a side effect. But if it
has the result might be incorrect.

E.g. for `a && b++` `b` must not be incremented if `a` evaluates to false.

The Verilog LRM mentions that it is allowed to short circuit any expression
"if the final result of an expression can be determined early". But there
is no requirement to do so.

So the new and the old behavior are both correct implementations in
Verilog.

Use the new behavior in both Verilog and SystemVerilog mode to make sure
the behavior is consistent when an expression has side effects.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2021-12-30 18:56:39 +01:00
Lars-Peter Clausen 2fa7260a4c tgt-vvp: Consolidate vec4 logical `and` and `or` generation
The code for generating the logical `and` and `or` operators is identical
except for the final opcode to combine the two results.

Consolidate this into a single function to reduce the code a bit.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2021-12-29 16:20:22 +01:00
Martin Whitaker 9cc09b8513 Remove "using namespace std" from vvp header files and fix the fallout. 2021-11-04 17:02:07 +00:00
Cary R 60a77b08d2 Add compiler and the start of vvp support for ->> 2021-02-19 23:21:51 -08:00
Cary R c978d28c09 Update main component Copyright to 2021 2021-01-10 14:32:30 -08:00
Cary R 32787bb973 Add support for SV edge 2021-01-07 01:22:49 -08:00
Cary R fbe42f13e2 Update tgt- directories with cppcheck suggested fixes 2021-01-02 13:31:26 -08:00
Cary R 1d318c4393 Update cppcheck to not run posix and add some -U flags 2021-01-02 13:23:59 -08:00
Cary R 053777f16d Fix some cppcheck warnings in tgt-vvp 2020-12-31 23:19:34 -08:00
Cary R 540555fca3 Add fix for GH460 a darray can have no packed dimension 2020-12-31 00:36:44 -08:00
Cary R 51025149a9 Report operators that cannot be used with null/class vars 2020-12-27 19:05:49 -08:00
Cary R 05a4e72b1a Add support for passing a null object to $display 2020-12-13 23:02:11 -08:00
Stephen Williams 3c2fb6a601 Fix dynamic array assignment to make a copy of the rvalue.
IEEE Std 1800-2017 Section 7.6 Array assignments

Assignment of a dynamic array creates a duplicate of the source,
so that assignments to the copy don't impact the original. Handle
all sorts of dynamic array base types.
2020-11-26 12:52:06 -08:00
Cary R ad862020bb Move GNU lesser to tgt-vvp since that is the only place where LGPL code is located 2020-11-14 19:03:27 -08:00
Lars-Peter Clausen 1ec5a441f3 tgt-vvp: Remove (almost) empty file vector.c
Since commit 62fce50f8c ("Remove dead code for allocate_vec handling.")
vector.c only contains the license header and some include directives
but no actual code.

Remove the file.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2020-09-19 12:39:04 +02:00
Cary R 112ebb48d8 Add file/line information to procedural warnings and darray fixes
When -pfileline=1 is used the queue procedural warnings have file
and line information added to the messages. Also switch the trace
debugging to be off by default.

Also, Add some preliminary missing darray functionality.
2020-08-10 22:01:55 -07:00
Cary R 1a0c06566d Update vvp code generation to properly emit file/line for void functions 2020-08-09 20:11:46 -07:00
Cary R e77d22e135 Add file and line information to warning message 2020-08-07 01:02:00 -07:00
Cary R bff115b9f7 Add initial support for assigning between queues and darrays 2020-08-07 00:23:43 -07:00
Martin Whitaker 9d15b771b1 Fix GitHub issue #356 - use pull strength for tri0/tri1 tie-offs.
When connecting module inout ports, an island is created. If there
is no other driver on one of the island ports, a tie-off is added.
In the case of a tri0 or tri1 net, this must have the correct (pull)
drive strength.
2020-08-06 14:20:16 +01:00
Cary R eb8f457803 Fix a spacing issue in output 2020-08-05 23:19:39 -07:00
Cary R 199ed39abe Report when the array pattern is larger than the maximum queue size 2020-08-02 23:40:35 -07:00
Cary R 2530041a38 Add support for assign array patterns to a queue 2020-07-30 19:52:38 -07:00
Cary R a2ba8a16b1 Add support for inserting into a queue 2020-07-29 23:00:19 -07:00
Cary R bed4758b0f A value of all X or Z can be an immediate number 2020-07-29 23:00:09 -07:00
Martin Whitaker e69549034d Fix potential buffer overflows (GitHub issue #346). 2020-07-28 13:17:57 +01:00
Cary R 14ade1a9f4 Pass the max size when storing to a queue 2020-07-27 21:24:22 -07:00
Cary R c969c324ed Add initial support for using a queue element as an L-value 2020-07-26 14:02:29 -07:00