Saturday, March 03, 2012

Interprocess Synchronization & Communication

Interprocess Synchronization & Communication

High-level and easy-to-use synchronization and communication mechanism are essential to control the kinds of interactions that occur between dynamic processes used to model a complex system or a highly reactive testbench. Verilog provides basic synchronization mechanisms (i.e., -> and @), but they are all limited to static objects and are adequate for synchronization at the hardware level, but fall short of the needs of a highly dynamic, reactive testbench. At the system level, an essential limitation of Verilog is its inability to create dynamic events and communication channels, which match the capability to create dynamic processes.

SystemVerilog adds a powerful and easy-to-use set of synchronization and communication mechanisms, all of which can be created and reclaimed dynamically. SystemVerilog adds a semaphore built-in class, which can be used for synchronization and mutual exclusion to shared resources, and a mailbox built-in class that can be used as a communication channel between processes. SystemVerilog also enhances Verilog’s named event data type to satisfy many of the system-level synchronization requirements.

Semaphores

Conceptually, a semaphore is a bucket. When a semaphore is allocated, a bucket that contains a fixed number of keys is created. Processes using semaphores must first procure a key from the bucket before they can continue to execute. If a specific process requires a key, only a fixed number of occurrences of that process can be in progress simultaneously. All others must wait until a sufficient number of keys is returned to the bucket. Semaphores are typically used for mutual exclusion, access control to shared resources, and for basic synchronization.

Semaphore is a built-in class that provides the following methods:

» Create a semaphore with a specified number of keys: new()

» Obtain one or more keys from the bucket: get()

» Return one or more keys into the bucket: put()

» Try to obtain one or more keys without blocking: try_get()

Mailboxes

A mailbox is a communication mechanism that allows messages to be exchanged between processes. Data can be sent to a mailbox by one process and retrieved by another. Conceptually, mailboxes behave like real mailboxes. When a letter is delivered and put into the mailbox, one can retrieve the letter (and any data stored within). However, if the letter has not been delivered when one checks the mailbox, one must choose whether to wait for the letter or retrieve the letter on subsequent trips to the mailbox.

Similarly, SystemVerilog's mailboxes provide processes to transfer and retrieve data in a controlled manner. Mailboxes are created as having either a bounded or unbounded queue size. A bounded mailbox becomes full when it contains the bounded number of messages. A process that attempts to place a message into a full mailbox shall be suspended until enough room becomes available in the mailbox queue.

Unbounded mailboxes never suspend a thread in a send operation

Mailbox is a built-in class that provides the following methods:

» Create a mailbox: new()
» Place a message in a mailbox: put()
» Try to place a message in a mailbox without blocking: try_put()
» Retrieve a message from a mailbox: get() or peek()
» Try to retrieve a message from a mailbox without blocking: try_get() or try_peek()
» Retrieve the number of messages in the mailbox: num()

Event

In Verilog, named events are static objects that can be triggered via the -> operator, and processes can wait for an event to be triggered via the @ operator. SystemVerilog events support the same basic operations, but enhance Verilog events in several ways. The most salient enhancement is that the triggered state of Verilog named events has no duration, whereas in SystemVerilog this state persists throughout the time-step in which the event triggered. Also, SystemVerilog events act as handles to synchronization queues, thus, they can be passed as arguments to tasks, and they can be assigned to one another or compared.

Existing Verilog event operations (@ and ->) are backward compatible and continue to work the same way when used in the static Verilog context. The additional functionality described below works with all events in either the static or dynamic context. A SystemVerilog event provides a handle to an underlying synchronization object. When a process waits for an event to be triggered, the process is put on a queue maintained within the synchronization object. Processes can wait for a SystemVerilog event to be triggered either via the @ operator, or by using the wait() construct to examine their triggered state. Events are triggered using the -> or the ->> operator.

Triggering an event:

Named events are triggered via the -> operator.

Triggering an event unblocks all processes currently waiting on that event. When triggered,

Nonblocking event trigger:

Nonblocking events are triggered using the ->> operator.

The effect of the ->> operator is that the statement executes without blocking and it creates a nonblocking assign update event in the time in which the delay control expires, or the event-control occurs.

Waiting for an event:

The basic mechanism to wait for an event to be triggered is via the event control operator, @.

@ hierarchical_event_identifier;

The @ operator blocks the calling process until the given event is triggered. For a trigger to unblock a process waiting on an event, the waiting process must execute the @ statement before the triggering process executes the trigger operator, ->. If the trigger executes first, then the waiting process remains blocked.

No comments:

Post a Comment

Popular Posts