0% found this document useful (0 votes)
22 views

Semaphore Proposal

This proposal introduces a semaphore construct to PSS to allow tasks to wait for interrupt events rather than busy-waiting. It defines a semaphore component that models a counting semaphore with acquire, try_acquire, release, and get available permits methods. This avoids issues with the current approach that uses yield() and busy-waiting on interrupt status.

Uploaded by

Hbk Mohan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
22 views

Semaphore Proposal

This proposal introduces a semaphore construct to PSS to allow tasks to wait for interrupt events rather than busy-waiting. It defines a semaphore component that models a counting semaphore with acquire, try_acquire, release, and get available permits methods. This avoids issues with the current approach that uses yield() and busy-waiting on interrupt status.

Uploaded by

Hbk Mohan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 3

Proposal for interrupt handling at

test realization layer


References
1. https://accellera.jamacloud.com/perspective.req#/items/12715?projectId=47

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.

  target function void do_xfer(/* ... */)


  {
  // Setup DMA channel registers
  ...
  // Enable interrupt
  ...
  // Enable DMA - triggers the hardware operation
  ...
  // Wait for dma completion
  }

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);

  // Enable DMA - triggers the hardware operation


  grp.DMA_ENABLE.write_val(1);

  // Wait for dma completion


  while(grp.INT_STATUS.read_val() == 0) {
  yield();
  }
  // Clear the status and return
  grp.INT_CLEAR.write_val(1);
  }

However, the approach above has the following drawbacks:

• 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.

This proposal addresses this by:

• Incorporating, by reference, the proposal to export functions in PSS

• 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 statements in a native exec body.

• A PSS native function called (directly or indirectly) from an exec body.

• A PSS function that is exported to foreign environment

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);

  // Releases the given number of permits, returning them to the semaphore.


  // Return immediately. Threads that are waiting for the semaphore may
  // (potentially) get unblocked
  target function void release(bit[SZ] N = 1);

  // Get the number of permits for the semaphore. Returns immediately.


  target function bit[32] available_permits();

  // Non-blocking, solve time function


  // Set the initial value of number of permits of the semaphore
  solve function void set_permits(bit[SZ] value);
};

You might also like