Commit Graph

35 Commits

Author SHA1 Message Date
Wilson Snyder 716b404256 Optimize away empty ctor_var_reset.
Fixes #7154.
2026-03-23 18:10:34 -04:00
Veripool API Bot 1f67080a1f Tests: Verilog format 2026-03-09 21:39:16 -04:00
Wilson Snyder 7607f0e7fa
Support proper automatic/static initialization, and remove STATICVAR warning (#6405). (#7086) 2026-02-24 14:04:43 -05:00
Artur Bieniek da28c67e60
Fix #0 delays to control fork scheduling (#6730 repair) (#6891)
Signed-off-by: Artur Bieniek <abieniek@internships.antmicro.com>
2026-02-17 21:51:11 -05:00
Geza Lore 505d33b35a
Support #0 delays with IEEE-1800 compliant semantics (#7079)
This patch adds IEEE-1800 compliant scheduling support for the Inactive
scheduling region used for #0 delays.

Implementing this requires that **all** IEEE-1800 active region events
are placed in the internal 'act' section. This has simulation
performance implications. It prevents some optimizations (e.g.
V3LifePost), which reduces single threaded performance. It also reduces
the available work and parallelism in the internal 'nba' section, which
reduced the effectiveness of multi-threading severely.

Performance impact on RTLMeter when using scheduling adjusted to support
proper #0 delays is ~10-20% slowdown in single-threaded mode, and ~100%
(2x slower) with --threads 4.

To avoid paying this performance penalty unconditionally, the scheduling
is only adjusted if either:
1. The input contains a statically known #0 delay
2. The input contains a variable #x delay unknown at compile time

If no #0 is present, but #x variable delays are, a ZERODLY warning is
issued advising the use of '--no-sched-zero-delay' which is a promise
by the user that none of the variable delays will evaluate to a zero
delay at run-time. This warning is turned off if '--sched-zero-delay'
is explicitly given. This is similar to the '--timing' option.

If '--no-sched-zero-delay' was used at compile time, then executing
a zero delay will fail at runtime.

A ZERODLY warning is also issued if a static #0 if found, but the user
specified '--no-sched-zero-delay'. In this case the scheduling is not
adjusted to support #0, so executing it will fail at runtime. Presumably
the user knows it won't be executed.

The intended behaviour with all this is the following:

No #0, no #var in the design (#constant is OK)
-> Same as current behaviour, scheduling not adjusted,
   same code generated as before

Has static #0 and '--no-sched-zero-delay' is NOT given:
-> No warnings, scheduling adjusted so it just works, runs slow

Has static #0 and '--no-sched-zero-delay' is given:
-> ZERODLY on the #0, scheduling not adjusted, fails at runtime if hit

No static #0, but has #var and no option is given:
-> ZERODLY on the #var advising use of '--no-sched-zero-delay' or
   '--sched-zero-delay' (similar to '--timing'), scheduling adjusted
   assuming it can be a zero delay and it just works

No static #0, but has #var and '--no-sched-zero-delay' is given:
-> No warning, scheduling not adjusted, fails at runtime if zero delay

No static #0, but has #var and '--sched-zero-delay' is given:
-> No warning, scheduling adjusted so it just works
2026-02-16 03:55:55 +00:00
Igor Zaworski 446bec3d1a
Fix event triggering (#6932) 2026-02-11 10:35:59 -08:00
Geza Lore 7875552354
Internals: Add stats/dump of circular logic in scheduling (#6953) 2026-01-28 10:45:23 +00:00
Artur Bieniek 2c5ff3f63f
Fix fork scheduling semantics (#6730)
Signed-off-by: Artur Bieniek <abieniek@internships.antmicro.com>
2025-11-26 15:52:53 +03:00
Geza Lore d066504bb9
Optimize away calls to empty functions (#6626) 2025-11-02 16:11:02 -05:00
Geza Lore 2e502aead8
Internals: Make all scheduling region use a single trigger vector. (#6620)
The 'act' region used to have 2 trigger vectors ('act' and 'pre'), now
it uses a single "extended" trigger vector where the top bits are what
used to be the used bits in the 'pre' trigger vector. Please see the
description above `TriggerKit`. Also move the extra triggers from the
low end to the high end in the trigger vectors.
2025-11-01 15:43:20 +00:00
Geza Lore 922223a9c3
Internals: Replace VlTriggerVec with unpacked array (#6616)
Removed the VlTriggerVec type, and refactored to use an unpacked array
of 64-bit words instead. This means the trigger vector and its
operations are now the same as for any other unpacked array. The few
special functions required for operating on a trigger vector are now
generated in V3SchedTrigger as regular AstCFunc if needed.

No functional change intended, performance should be the same.
2025-10-31 18:29:11 +00:00
Wilson Snyder 001c098e5a Optimize empty function definition bodies (#5750). 2025-01-25 12:13:25 -05:00
Jinyan Xu 4650105d90
Fix conflicted namespace for coroutines (#4701) (#4707) 2023-11-20 21:02:10 -05:00
Wilson Snyder 9a0254a118
Optimize timing-delayed queue (#4584). (#4669) 2023-11-11 10:04:10 -05:00
Geza Lore 2cba167634 Make eval loop construction more unified and the output more readable 2023-10-28 08:48:04 +01:00
Geza Lore a09506a0ad Trivial simplification of V3EmitCModel
Still some remains of the --threads 0 mode. Remove unnecessary complexity
from V3EmitCModel. (Also don't pretend there is an MTask in single
threaded mode, when there really isn't.)
2023-10-21 20:41:46 +01:00
Krzysztof Bieganski 99ea16d7fd
Fix dynamic triggers for named events (#4571) 2023-10-16 11:06:41 -04:00
Wilson Snyder 6d5dde8645 Fix duplicate Vfork functions (#4418) 2023-08-30 17:59:25 -04:00
Aleksander Kiryk 7c7c92d2dd
Fix coroutine handle movement during queue manipulation (#4431) 2023-08-21 10:22:09 -04:00
Krzysztof Bieganski d5d1cc47e0
Fix multiple edge timing controls in class methods (#4318) (#4320) (#4344)
Multiple edge timing controls in class methods would cause compilation errors on
the generated C++ code. This is because the `SenExprBuilder` used for these
would get recreated per timing control, resulting in duplicate variable names.
The fix is to have a single `SenExprBuilder` per scope.
2023-07-07 08:19:49 -04:00
Wilson Snyder 294d78e0e2 Backout unstable dbb35ab8 (#4318) (#4320) 2023-07-05 14:26:28 -04:00
Krzysztof Bieganski 35d6da391b
Fix multiple edge timing controls in class methods (#4318) (#4320)
Multiple edge timing controls in class methods would cause compilation errors on the generated C++ code. This is because the `SenExprBuilder` used for these would get recreated per timing control, resulting in duplicate variable names. The fix is to have a single `SenExprBuilder` per scope.
2023-07-05 10:36:10 +00:00
Ryszard Rozak 4522834f7a
Fix duplicate fork names (#4295) 2023-06-22 06:51:53 -04:00
Krzysztof Bieganski 43fa6858f6
Fix `VlForkSync` redeclaration (#4277)
Given nested forks, if the inner fork had a `join` or `join_any` at the end,
`V3Sched::transformForks()` would decide that the fork's `VlForkSync` variable
should be passed in from the outside. This resulted in the `VlForkSync` getting
redeclared as a function argument. Ultimately, it led to C++ compilation errors
due to variable redeclaration.

Fixed by rearranging the `if`s that decide whether a variable should be passed
in or left as-is.
2023-06-15 07:49:50 -04:00
Krzysztof Bieganski 76c5875912
Fix marking overridden methods as coroutines (#4120) (#4169)
This patch fixes two cases where methods in base classes were not being marked
as coroutines, even though they were being overridden by coroutines.
- One case is the class member cache not getting refreshed for searched classes.
- The other is when the overriding methods are not declared as `virtual`. In
  that case, the `isVirtual()` getter on such a method returns false, which led
  to `V3Timing` skipping the step of searching for overridden methods.

Signed-off-by: Krzysztof Bieganski <kbieganski@antmicro.com>
2023-05-04 15:27:45 +02:00
Krzysztof Bieganski 5de8ccbf32
Fix task calls as fork statements (#4055)
Before this patch, calling tasks directly under forks would result in each
statement of these tasks being executed concurrently. This was due to Verilator
inlining tasks most of the time. Such inlined tasks' statements would simply
replace the original call, and there would be no indication that these used to
be grouped together. Ultimately resulting in `V3Timing` treating each statement
as a separate process.

The solution is simply to wrap each fork sub-statement in a begin in `V3Begin`
(except for the ones that are begins, as that would be pointless). `V3Begin` is
already aware of forks, and is supposed to avoid issues like this one, so it
seems like a natural fit. This also protects us from similar bugs, i.e. if some
statement gets replaced or expanded into multiple statements.

Signed-off-by: Krzysztof Bieganski <kbieganski@antmicro.com>
2023-03-21 13:50:53 +01:00
Kamil Rakoczy d6126c4b32
Remove --no-threads; require --threads 1 for single threaded (#3703). 2022-11-05 08:47:34 -04:00
Krzysztof Bieganski fcf0d03cd4
Dynamic triggers for non-static contexts (#3599)
In non-static contexts like class objects or stack frames, the use of
global trigger evaluation is not feasible. The concept of dynamic
triggers allows for trigger evaluation in such cases. These triggers are
simply local variables, and coroutines are themselves responsible for
evaluating them. They await the global dynamic trigger scheduler object,
which is responsible for resuming them during the trigger evaluation
step in the 'act' eval region. Once the trigger is set, they await the
dynamic trigger scheduler once again, and then get resumed during the
resumption step in the 'act' eval region.

Signed-off-by: Krzysztof Bieganski <kbieganski@antmicro.com>
2022-10-22 14:05:39 +00:00
Krzysztof Bieganski 785c51dd0b
Fix emitting timing debug info with `--protect-ids` (#3689) (#3701) 2022-10-21 16:56:44 -04:00
Krzysztof Bieganski 5688d1a935
Internals: Add `V3UniqueNames` consistency assertion (#3692) 2022-10-21 07:05:38 -04:00
Wilson Snyder 916a3d9066 Fix --main --trace missing initial timestep (#3678). 2022-10-15 13:24:38 -04:00
Krzysztof Bieganski 97add4d57a
Fix null access on optimized-out fork statements (#3658)
`V3SchedTiming` currently assumes that if a fork still exists, it must
have statements within it (otherwise it would have been deleted by
`V3Timing`). However, in a case like this:
```
module t;
    reg a;
    initial fork a = 1; join
endmodule
```
the assignment in the fork is optimized out by `V3Dead` after
`V3Timing`. This leads to `V3SchedTiming` accessing fork's `stmtsp`
pointer, which at this point is null. This patch addresses that issue.

Signed-off-by: Krzysztof Bieganski <kbieganski@antmicro.com>
2022-10-06 15:38:59 +02:00
Krzysztof Bieganski a2e1b32a1c
Fix inlining of forks (#3594)
Before this change, some forked processes were being inlined in
`V3Timing` because they contained no `CAwait`s. This only works under
the assumption that no `CAwait`s will be added there later, which is not
true, as a function called by a forked process could be turned into a
coroutine later. The call would be wrapped in a new `CAwait`, but the
process itself would have already been inlined at this point.

This commit moves the inlining to `transformForks` in `V3SchedTiming`,
which is called at a point when all `CAwait`s are already in place.

Signed-off-by: Krzysztof Bieganski <kbieganski@antmicro.com>
2022-09-05 15:19:19 +01:00
Krzysztof Bieganski da7ad35577
Fix fork debug output (#3593)
Signed-off-by: Krzysztof Bieganski <kbieganski@antmicro.com>
2022-09-05 11:27:24 +01:00
Krzysztof Bieganski 39af5d020e
Timing support (#3363)
Adds timing support to Verilator. It makes it possible to use delays,
event controls within processes (not just at the start), wait
statements, and forks.

Building a design with those constructs requires a compiler that
supports C++20 coroutines (GCC 10, Clang 5).

The basic idea is to have processes and tasks with delays/event controls
implemented as C++20 coroutines. This allows us to suspend and resume
them at any time.

There are five main runtime classes responsible for managing suspended
coroutines:
* `VlCoroutineHandle`, a wrapper over C++20's `std::coroutine_handle`
  with move semantics and automatic cleanup.
* `VlDelayScheduler`, for coroutines suspended by delays. It resumes
  them at a proper simulation time.
* `VlTriggerScheduler`, for coroutines suspended by event controls. It
  resumes them if its corresponding trigger was set.
* `VlForkSync`, used for syncing `fork..join` and `fork..join_any`
  blocks.
* `VlCoroutine`, the return type of all verilated coroutines. It allows
  for suspending a stack of coroutines (normally, C++ coroutines are
  stackless).

There is a new visitor in `V3Timing.cpp` which:
  * scales delays according to the timescale,
  * simplifies intra-assignment timing controls and net delays into
    regular timing controls and assignments,
  * simplifies wait statements into loops with event controls,
  * marks processes and tasks with timing controls in them as
    suspendable,
  * creates delay, trigger scheduler, and fork sync variables,
  * transforms timing controls and fork joins into C++ awaits

There are new functions in `V3SchedTiming.cpp` (used by `V3Sched.cpp`)
that integrate static scheduling with timing. This involves providing
external domains for variables, so that the necessary combinational
logic gets triggered after coroutine resumption, as well as statements
that need to be injected into the design eval function to perform this
resumption at the correct time.

There is also a function that transforms forked processes into separate
functions.

See the comments in `verilated_timing.h`, `verilated_timing.cpp`,
`V3Timing.cpp`, and `V3SchedTiming.cpp`, as well as the internals
documentation for more details.

Signed-off-by: Krzysztof Bieganski <kbieganski@antmicro.com>
2022-08-22 13:26:32 +01:00