Commit Graph

10116 Commits

Author SHA1 Message Date
Stephen Williams 2693dd32b0
Merge pull request #728 from larsclausen/nb-ec-multi
tgt-vvp: Fix syntax when using multiple events for non-blocking event control
2022-06-07 21:39:22 -07:00
Lars-Peter Clausen 2bc1385a59 Add regression test for multiple events in non-blocking event control
Check that multiple events can be used in a non-blocking event control
assignment. The assignment should happen if either of the events trigger.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-06-06 17:01:23 +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
Stephen Williams e5abd4bf82
Merge pull request #727 from larsclausen/nb-ec-concat
Handle non-blocking event control to lvalue concatenation
2022-06-05 17:31:14 -07:00
Stephen Williams 68f75dce61
Merge pull request #726 from larsclausen/vvp-remove-unused-instructions
vvp: Remove unused index word instructions
2022-06-05 17:29:38 -07:00
Lars-Peter Clausen ebd574474c Add regression test for non-blocking event control to concatenation
Check that a non-blocking event control assignment works as expected to a
lvalue concatenation. All values that are part of the concatenation should
only be assigned after the event triggers.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-06-05 11:40:55 +02:00
Lars-Peter Clausen 34876c8854 Add additional regression test for non-blocking event control on array partsel
Check that non-blocking event control assignments works on an array part
select if the part select index is not an immediate value.

This is a copy of the nb_ec_array_pv test, but using variable indices
instead of immediate values.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-06-04 22:27:00 +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 5fb2d9158d
Merge pull request #725 from larsclausen/vvp-get-rval-helper
vvp: `%{concati,pushi}/vec4` use `get_immediate_rval()` helper
2022-06-02 18:30:32 -07:00
Lars-Peter Clausen 07378fd300 vvp: `%{concati,pushi}/vec4` use `get_immediate_rval()` helper
Both the `%concati/vec4` and `%pushi/vec4` instructions need to construct a
vector from the immediate value encoded in the instruction. Currently both
these instructions have a custom implementation for that.

Remove the custom implementations from those functions and use the
`get_immediate_rval()` helper function. This removes a bit of duplicated
code.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-06-02 22:11:46 +02:00
Lars-Peter Clausen 86cc6e6159 vvp: Remove unused `%cmp/ws` and `%cmp/wu` instructions
The `%cmp/ws` and `%cmp/wu` instructions compare two index registers. They
are currently unused. Since the index registers are not used for data there
is not really a need to compare them. Values can be compared before loading
them into an index register.

So remove these two instructions.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-06-02 21:53:27 +02:00
Lars-Peter Clausen 781089662c vvp: Remove unused `%mov/wu` instruction
The `%mov/wu` instruction moves data from one index register to another.
The instruction is not used. It also does the same as `%ix/mov`. So remove
it.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-06-02 21:53:27 +02:00
Stephen Williams e8cc9f3721
Merge pull request #724 from larsclausen/vvp-pv-remove-wid
vvp: Remove `wid` parameter from `recv_vec{4,8}_pv()`
2022-06-01 23:14:50 -07: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
Stephen Williams e4d2b05976
Merge pull request #721 from larsclausen/vvp-struct-sign
tgt-vvp: Handle signedness when passing struct member to system function
2022-06-01 23:11:58 -07:00
Lars-Peter Clausen 2032e14f5a vvp: Remove `wid` parameter from `recv_vec{4,8}_pv()`
The `recv_vec{4,8}_pv()` functions are used to implement a partial write to
a vector. As parameters they take both the value and the width of the
value.

All callers of of these functions pass `val.size()` or a variation thereof
as the width of the value. And all implementations that do anything with
the data have an assert that `val.size() == wid`.

Remove the `wid` parameter from these functions and just use `val.size()`
directly where needed. This allows to simplify the interface and also
to remove the asserts.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-05-28 15:34:02 +02:00
Lars-Peter Clausen 5ae7425fdb Add regression tests for assignment operator on real array entries
Check that assignment operators on real array entries are supported.

Also check that
  * out-of-bounds indices work as expected
  * it works after a comparison that set vvp flag 4 to 0

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-05-26 22:02:24 +02: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 61549165cf Add regression test for passing struct members to system functions
Check that the signedness of a struct member is properly handled when being
passed to a system function.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-05-24 11:32:31 +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
Stephen Williams 8fb38d7046
Merge pull request #720 from larsclausen/vvp-assign-op-oob
tgt-vvp: Fix out-of-bounds compressed assignment to arrays
2022-05-22 18:21:08 -07:00
Lars-Peter Clausen 12188f8d83 Add regression test for out-of-bounds array assignment operator
Check that an assignment operator on an out-of-bounds array element works
as expected. The out-of-bounds access should leave the array unmodified,
but the right-hand side must be evaluated regardless.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-05-22 10:55:58 +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
Stephen Williams e8bc3bf8dd
Merge pull request #719 from steveicarus/steveicarus/issue717-vcd-real-parameters
Fix vcd dump of real value parameters
2022-05-21 11:35:17 -07:00
Stephen Williams 6564f55219 Fix vcd dump of real value parameters
Parameters with real values are possible in Verilog, but not in the VCD
format, so lie a little and call them "real" objects. Otherwise, we can
treat them like constants and it works out, at least for gtkwave.
2022-05-21 10:13:27 -07:00
Stephen Williams 6176f8eec3
Merge pull request #715 from larsclausen/vvp-load-store-skip
tgt-vvp: Fix incorrect load or store operation skip
2022-05-21 09:17:38 -07:00
Stephen Williams 5d97405724
Merge pull request #714 from steveicarus/steveicarus/issue156-vcd-dump-parameter
Add parameters to vcd dumps
2022-05-17 08:37:21 -07:00
Stephen Williams 73f40f73b0 Add parameters to fst dumps
Add support for parameters (constants) in fst dumps. And while we are at
it, factor out some of the declarations shared with sys_vcd.
2022-05-16 20:47:32 -07:00
Lars-Peter Clausen c2c758369d Add regression tests for accidental store/load skip
Check that for the following operations the load or store is not skipped
after a operation that sets vvp flag 4.

 * Assignment to immediate indexed real array entry
 * Assignment operator on immediate indexed vector array entry
 * Assignment operator on dynamic vector part select

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-05-16 11:36: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 4c8903f117
Merge pull request #713 from larsclausen/remove-svector
Replace svector with std::vector
2022-05-15 18:59:09 -07:00
Stephen Williams e4372c8eda
Merge pull request #712 from larsclausen/fix-darray-oob
Return value of correct width for dynamic array out-of-bound access
2022-05-15 18:57:49 -07:00
Stephen Williams a1485906ca Add parameters to vcd dumps
Writing parameters into VCD files makes the values available to waveform
tools. This can be done easily enough by writing out a $dumpadd section
at the beginning of the file that sets the parameter values. We don't need
to track the values over change, because by definition they do not change.

This changes the typical vcd output as well, so a few of the regression tests
need to be adjusted to account for this.

Also, while tracking this down, found and fixed the vvp/README.txt documention
for the .param/x records.
2022-05-15 18:47:18 -07:00
Lars-Peter Clausen b83daa3ae3 Add regression tests for dynamic array and queue out-of-bounds access
Check that out-of-bounds access on a dynamic array or queue works and
returns the correct value.

  * 2-state vectors: '0 with the element width
  * 4-state vectors: 'x with the element width
  * reals: 0.0
  * strings: ""

Note that the 2-state test currently still fails as out-of-bounds access on
a 2-state vector incorrectly returns 'x.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-05-15 21:58:01 +02:00
Lars-Peter Clausen abc3ad95e6 Return value of correct width for dynamic array out-of-bound access
Commit e1870acfac ("Return the correct value when a queue or darray
references an undefined element") added support for specifying the width of
the vector elements stored in a queue or dynamic array, so that an
out-of-bounds access can create a word with the right width.

To get the element width of a queue or dynamic array it uses the
`packed_width()` method. But this method is only implemented for
`netqueue_t` and returns always 1 for dynamic arrays. As a result
out-of-bounds access on a dynamic array will push a vector of the wrong
width onto the stack if the vector element is wider than 1 bit. This will
usually trigger an assert in vvp.

Fix this by moving the `packed_width()` method implementation from
`netqueue_t` to its base class `netdarray_t` so that it works for all types
of dynamic arrays.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-05-15 21:57:51 +02:00
Lars-Peter Clausen e15b125da8 Replace svector with std::vector
The custom `svector` class is essentially a subset of `std::vector`. There
is no inherent advantage to using `svector`. Both have the same memory
footprint.

`svector` was designed to be of static size, but there are a few places in
the parser where it has to grow at runtime. Handling this becomes a bit
easier by switching to `std::vector` since it is possible to use its
methods which take care of resizing the vector.

This also allows to remove the unused parameter of the `lgate` struct
constructor, which was only needed for compatibility with `svector`.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-05-15 21:56:48 +02:00
Lars-Peter Clausen 278e071b35 netqueue_t: Remove redundant get_signed() method
The get_signed() method for the netqueue_t class is identical to that of
its base class netdarray_t.

Remove the redundant re-implementation of the method.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-05-14 13:42:59 +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
Stephen Williams e076400449
Merge pull request #708 from larsclausen/real-array-multi-dim
tgt-vvp: Allow multi-dimensional real arrays
2022-05-12 14:48:15 -07:00
Stephen Williams 508564b79f
Merge pull request #706 from larsclausen/parameter-scalar
Handle scalar typed parameters
2022-05-12 14:46:31 -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 37392383b5 Add regression test for scalar and 1-bit parameters
Check that scalar typed parameters are handled correctly. Make sure the
width of the parameter only depends on the type and not on the value
assigned to the parameter.

Same for parameters with a 1-bit range specification.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-05-02 14:33:31 +02:00
Lars-Peter Clausen 37f9cde49f Handle scalar typed parameters
Parameters without any type or range specification inherit the type from
the value that has been assigned to it. Similarly a parameter with just an
`signed` or `unsigned` keyword will inherit its range from the value
assigned to it.

In the current implementation any vector type parameter that does not have
a range specification inherits the type form the assigned value. That
includes parameters with an explicit scalar vector type. E.g.

```
parameter bit X = 10
```

Make sure that a parameter only uses the width from the assigned value if
the parameter does not have an explicit data type.

To support this we need to remember whether a `netvector_t` was declared as
an explicit or implicit data type. Currently this information is only
available on the unelaborated `vector_type_t`.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-05-02 14:33:31 +02:00
Lars-Peter Clausen ef009e7200 Add regression test for multi-dimensional real array
Check that multi-dimensional real arrays are supported and can be accessed.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-05-02 14:30:29 +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
Stephen Williams 0a86773c5e
Merge pull request #705 from larsclausen/class_new_fix
Handle class new assignment to non-class variables
2022-05-01 07:36:10 -07:00