[Edit of Image1]
Introduction
Hey it's a me again @drifter1!
Today we continue with the Logic Design series on SystemVerilog in order to cover Semaphores and Mailboxes, which are the two other interprocess communication mechanisms of SystemVerilog. Events were covered last time!
So, without further ado, let's get straight into it!
Semaphores
Semaphores are used for the purpose of mutual exclusion, letting only processes with a key to continue execution. This allows us to control the access of shared resources.
Semaphore Creation
Semaphores objects are created from the built-in semaphore
class and allocated / initialized using the new(key_count)
function, which takes the number of keys as an argument.
For example, a simple mutex is defined using the following code:
semaphore mutex;
initial begin
mutex = new(1);
end
Semaphore Methods
The following methods can be called on a semaphore object:
get(key_count)
: block execution until the specified amount of keys is obtained from the semaphore (lock).put(key_count)
: return the specified amount of keys to the semaphore (unlock).try_get(key_count)
: try obtaining the specified amount of keys from the semaphore but don't block execution.
If no number of keys is specified in those functions, then a default value of 1 is used.
The critical sections (sections where synchronization is needed) are thus enclosed within a get()
and put()
like shown below.
mutex.get();
/* critical section */
mutex.put();
The last method, try_get()
, can be used in conditional statements in order to execute different testing code if the semaphore is available or not:
if mutex.try_get()
// mutex available
else
// mutex unavailable
Mailboxes
Mailboxes are dedicated channels that connect two processes / components directly, allowing data to be exchanged between them. They behave like queues, but are different from the queue
data structure. A mailbox
uses semaphores for controlled atomic access, and operates in FIFO order only.
Mailbox Definition
Mailboxes are objects of the mailbox
class. A generic mailbox is thus defined by using the class name mailbox
as is:
mailbox mbx;
These generic mailboxes are typeless and any data can be send and received. In order to constrain them to a fixed data type, they can be parameterized to that data type, leading to so called parameterized mailboxes. Compiler errors would then be triggered whenever data type mismatches occur!
For example a string
-only mailbox
is defined as follows:
mailbox #(string) s_mbx;
Mailbox Methods
The following methods can be called on mailbox objects:
new(size)
: allocate mailbox with the specified queue size.num()
: returns the number of messages in the mailbox.put(msg)
: blocking method that stores the given message in FIFO order. Blocks if the mailbox is full.try_put(msg)
: same asput(msg)
but non-blocking. Returns 0 if the mailbox is full.get(msg_ref)
: blocking method that retrieves one message from the mailbox (by deleting it) and blocks execution if the mailbox is empty.try_get(msg_ref)
: same asget(msg_ref)
but non-blocking. Returns 0 if mailbox is empty.peek(msg_ref)
: blocking method that copies one message from the mailbox without deleting it, and blocks execution if the mailbox is empty.try_peek(msg_ref)
: same aspeek(msg_ref)
but non-blocking. Returns 0 if the mailbox is empty.
For example:
// create mailbox that can hold
// up to 2 string messages
mailbox #(string) s_mbx = new(2);
// store messages
s_mbx.put ("Komi");
s_mbx.put ("Tadano");
// retrieve message (deleting it)
string x;
s_mbx.get(x);
// x now contains "Komi"
// try peeking message (copy don't delete)
string y;
if s_mbx.try_peek(y)
// the mailbox contained an item
// so this code would be executed
// y now contains "Tadano"
// store message
s_mbx.put ("Yamai");
// try storing message
if s_mbx.try_put("Najimi")
// the mailbox is full
// so this code would not be executed!
RESOURCES:
References
- https://www.chipverify.com/systemverilog/systemverilog-tutorial
- https://www.asic-world.com/systemverilog/tutorial.html
Images
Block diagrams and other visualizations were made using draw.io
Previous articles of the series
Verilog
- Introduction → Basic Syntax, Data Types, Operators, Modules
- Combinational Logic → Assign Statement, Always Block, Control Blocks, Gate-Level Modeling and Primitives, User-Defined Primitives
- Combinational Logic Examples → One Circuit - Four Implementations, Encoder, Decoder, Multiplexer
- Sequential Logic → Procedural Blocks (Initial, Always), Blocking and Non-Blocking Assignments, Statement Groups
- Sequential Logic Examples → Flip Flops (DFF, TFF, JKFF, SRFF), N-bit Counter, Single-Port RAM
- Finite-State Machines → Finite-State Machine (FSM), FSM Types, State Encoding, Modeling FSMs in Verilog
- Finite-State Machine Examples → Moore FSM Example (1 and 2 always blocks), Mealy FSM Example (1, 2 and 3 always blocks)
- Testbenches and Simulation → Testbenches (DUT / UUT, Syntax, Test Cases), System Tasks, Simulation Tools
- Combinational Logic Testbench Example → Half Adder Implementation, Testbench and Simulation
- Sequential Logic Testbench Example → Sequence Detector FSM Implementation, Testbench and Simulation
- Functions and Tasks → Function and Task Syntax, Calling, Rules, Examples
- Module Parameters and Generate Block → Parameterized Module (Parameters, Instantiation and Overriding Parameters), Generate Blocks (For, If, Case)
- Compiler Directives → Summary of Verilog's Compiler Directives (Include, Macros, Timescale, Conditional Compilation, etc.)
- Switch Level Modeling → Transistors, Switch Primitives (NMOS, PMOS, CMOS, Bidirectional, Resistive), Signal Strengths
SystemVerilog
- From Verilog To SystemVerilog → Data Types, Arrays, Structures, Operators and Expressions
- Control Flow → Additional Procedural Blocks, Loops, Conditional Statements, Functions and Task Features
- Processes → Fork - Join in Verilog and SystemVerilog, Process Control (wait fork, disable fork)
- Events → Interprocess Communication, Events (Definition, Triggering, Waiting, Sequencing, Merging, as Arguments)
Final words | Next up
And this is actually it for today's post!
Next time we will cover interfaces and maybe even program blocks...
See Ya!
Keep on drifting!