Semaphore Proposal
Semaphore Proposal
2. https://workspace.accellera.org/wg/pswg/document/11430
Motivation
In the procedural specification (within exec body or a target function), there is often a need to wait
until hardware completes the on-going operation - and indicates so by triggering an interrupt
condition.
Currently (with PSS2.0), this can be done in the following way (with semantics of yield() still not
part of the specification):
1
target function void do_xfer(/* ... */)
{
// Setup DMA channel registers
...
// Enable interrupt
grp.INT_ENABLE.write_val(1);
• The yield() construct used above is not standardized - hence not portable across PSS
implementations.
• The code uses busy-wait approach, by polling on the INT_STATUS - and not by waiting for an
interrupt event.
• Providing a semaphore construct that allows PSS test realization implementation to wait on an
event
Implementation proposal
For the purposes of this section, a "task" refers to one of:
The PSS semaphore models a counting semaphore. Conceptually, the semaphore has a certain
number of permits (zero or more) at any point in time. A task may attempt to acquire (one or more)
permits from the semaphores. The operation completes successfully if the semaphore has the
requested number of permits available (in which case, the number of available permits reduces by
the number the task acquires). If not, the operation shall wait for the requested number of permits
is available. A non-blocking version of the operation is also supported - which shall return
immediately, either with a "success" status if the acquisition was possible, or an "error" status if
otherwise.
2
Multiple tasks may attempt to acquire permits from the same semaphore concurrently. The order in
which the tasks will successfully acquire is not deterministic.
A task may release (one or more) permits of a semaphore. This causes the number of available
permits to increase by that number - and may (potentially) unblock other tasks waiting to acquire
the semaphore.
The task that releases permits may not necessarily be the task that previously acquired the permit.
enum status_e
{
SUCCESS,
FAIL
};
// Semaphore
pure component semaphore_c <int SZ = 32>
{
// Acquire `N` permits from this semaphore, block until such an acquisition is
successful.
// Decrement number of permits by `N` before returning.
target function void acquire(bit[SZ] N = 1);
// Acquire `N` permits from this semaphore, if all are available at the
// time of invocation and return SUCCESS; else return immediately with status as
FAIL
target function status_e try_acquire(bit[SZ] N = 1);