|HOME |ABOUT |ARTICLES |ACK |FEEDBACK |TOC |LINKS |BLOG |JOBS |


Tutorials



VERILOG SEMAPHORE

Semaphore In Verilog

A semaphore is a type of Interposes communication resource used for synchronization and mutual exclusion between any two asynchronous processes. A semaphore object is a synchronization object that maintains a count between zero and a specified maximum value. The count is decremented each time a thread completes a wait for the semaphore object and incremented each time a thread releases the semaphore. When the count reaches zero, no more threads can successfully wait for the semaphore object state to become signaled. The state of a semaphore is set to signaled when its count is greater than zero, and non-signaled when its count is zero. The semaphore object is useful in controlling a shared resource that can support a limited number of users. It acts as a gate that limits the number of threads sharing the resource to a specified maximum number.

Take an example, Many components in the testbench wants to access the dut memory. But memory has only one interface. So only one can do write and read operation at a time. Using semaphore, we can make sure that only one operation is done at a time.

Imagine a home with six persons living. They have only one car. Everyone wants to drive the car. But others plan to make a trip, when some other has gone out with car. The eldest person in home made a rule. Key will be with  him. Whoever wants, come to me and get the key. After finishing the job, return the key to him. This way, only one can plan for the trip.


EXAMPLE:
module sema(); 

    integer keys; 
    
    initial 
       keys = 1; 
    
    task get_key(); 
    input integer i; 
    begin 
        if ( keys == 0) 
        begin 
        $display(" KEY IS NOT AVAILABLE : WAITING FOR KEYS : process %d",i); 
        wait(keys == 1); 
        end 
        $display(" GOT THE KEY : GET SET GO :process %d",i); 
        keys = 0; 
    end  
    endtask 
    
    task put_keys(); 
    input integer i; 
    begin 
        keys = 1 ; 
        $display(" PROCESS %d gave the key back ",i); 
    end 
    endtask 
    
    initial 
    begin 
       # 10 ; 
       get_key(1); 
       repeat(4) 
       # 10 $display(" PROCESS 1 GOT KEYS : OTHERS CANT WRITE MESSAGE TO LOG "); 
       put_keys(1); 
    end 
    
    initial 
    begin 
        # 10 ; 
        get_key(2); 
        repeat(4) 
        # 10 $display(" PROCESS 2 GOT KEYS : OTHERS CANT WRITE MESSAGE TO LOG "); 
        put_keys(2); 
    end 
    
endmodule 

RESULTS:

GOT THE KEY : GET SET GO :process 1
KEY IS NOT AVAILABLE : WAITING FOR KEYS : process 2
PROCESS 1 GOT KEYS : OTHERS CANT WRITE MESSAGE TO LOG  
PROCESS 1 GOT KEYS : OTHERS CANT WRITE MESSAGE TO LOG  
PROCESS 1 GOT KEYS : OTHERS CANT WRITE MESSAGE TO LOG  
PROCESS 1 GOT KEYS : OTHERS CANT WRITE MESSAGE TO LOG  
PROCESS 1 gave the key back  
GOT THE KEY : GET SET GO :process 2
PROCESS 2 GOT KEYS : OTHERS CANT WRITE MESSAGE TO LOG  
PROCESS 2 GOT KEYS : OTHERS CANT WRITE MESSAGE TO LOG  
PROCESS 2 GOT KEYS : OTHERS CANT WRITE MESSAGE TO LOG  
PROCESS 2 GOT KEYS : OTHERS CANT WRITE MESSAGE TO LOG  
PROCESS 2 gave the key back  



In this home, some of them are not interested to wait until they got the key. So they want tp progress to other works without waiting for keys.
The following example shows, if keys are not available, the process don't wait.


EXAMPLE:
module sema(); 

integer keys; 

initial 
keys = 1; 

task get_key(); 
input integer i; 
begin 
if ( keys == 0) 
begin 
$display(" KEY IS NOT AVAILABLE : WAITING FOR KEYS : process %d",i); 
wait(keys == 1); 
end 
$display(" GOT THE KEY : GET SET GO :process %d",i); 
keys = 0; 
end  
endtask 

function get_key_dont_wait(); 
input integer i; 
reg got; 
begin 
got =0; 
if ( keys == 0) 
$display(" KEY IS NOT AVAILABLE : LEAVING WITHOUT WAITING FOR KEYS : process %d",i); 
else 
begin 
$display(" GOT THE KEY : GET SET GO :process %d",i); 
keys = 0; 
got = 1; 
end 
get_key_dont_wait = got; 
end  
endfunction 

task put_keys(); 
input integer i; 
begin 
keys = 1 ; 
$display(" PROCESS %d gave the key back ",i); 
end 
endtask 

initial 
begin 
# 10 ; 
get_key(1); 
repeat(4) 
# 10 $display(" PROCESS 1 GOT KEYS : OTHERS CANT WRITE MESSAGE TO LOG "); 
put_keys(1); 
end 

initial 
begin 
# 10 ; 
if(get_key_dont_wait(2)) 
begin 
repeat(4) 
# 10 $display(" PROCESS 2 GOT KEYS : OTHERS CANT WRITE MESSAGE TO LOG "); 
put_keys(2); 
end 
else 
$display(" IM not interested to wait "); 
end 

endmodule 

RESULTS:

GOT THE KEY : GET SET GO :process 1
KEY IS NOT AVAILABLE : LEAVING WITHOUT WAITING FOR KEYS : process 2
IM not interested to wait  
PROCESS 1 GOT KEYS : OTHERS CANT WRITE MESSAGE TO LOG  
PROCESS 1 GOT KEYS : OTHERS CANT WRITE MESSAGE TO LOG  
PROCESS 1 GOT KEYS : OTHERS CANT WRITE MESSAGE TO LOG  
PROCESS 1 GOT KEYS : OTHERS CANT WRITE MESSAGE TO LOG  
PROCESS 1 gave the key back



After some days, they got new car to home. Now they have two cars, at once 2 members can go on drive. Looking at the following code. The keys are initialized to 2. Two processes are running at once.


EXAMPLE:
module sema(); 

integer keys; 

initial 
keys = 2; 

task get_key(); 
input integer i; 
begin 
if ( keys == 0) 
begin 
$display(" KEY IS NOT AVAILABLE : WAITING FOR KEYS : process %d",i); 
wait(keys > 0); 
end 
$display(" GOT THE KEY : GET SET GO :process %d",i); 
keys = keys - 1; 
end  
endtask 

function get_key_dont_wait(); 
input integer i; 
reg got; 
begin 
got =0; 
if ( keys == 0) 
$display(" KEY IS NOT AVAILABLE : LEAVING WITHOUT WAITING FOR KEYS : process %d",i); 
else 
begin 
$display(" GOT THE KEY : GET SET GO :process %d",i); 
keys = keys - 1; 
got = 1; 
end 
get_key_dont_wait = got; 
end  
endfunction 

task put_keys(); 
input integer i; 
begin 
keys = keys + 1 ; 
$display(" PROCESS %d gave the key back ",i); 
end 
endtask 

initial 
begin 
# 10 ; 
get_key(1); 
repeat(4) 
# 10 $display(" PROCESS 1 GOT KEYS : IM ALOS RUNNING "); 
put_keys(1); 
end 

initial 
begin 
# 10 ; 
if(get_key_dont_wait(2)) 
begin 
repeat(4) 
# 10 $display(" PROCESS 2 GOT KEYS : IM ALSO RUNNING "); 
put_keys(2); 
end 
else 
$display(" IM not interested to wait "); 
end 


endmodule 

RESULTS:

GOT THE KEY : GET SET GO :process 1
GOT THE KEY : GET SET GO :process 2
PROCESS 1 GOT KEYS : IM ALOS RUNNING  
PROCESS 2 GOT KEYS : IM ALSO RUNNING  
PROCESS 1 GOT KEYS : IM ALOS RUNNING  
PROCESS 2 GOT KEYS : IM ALSO RUNNING  
PROCESS 1 GOT KEYS : IM ALOS RUNNING  
PROCESS 2 GOT KEYS : IM ALSO RUNNING  
PROCESS 1 GOT KEYS : IM ALOS RUNNING  
PROCESS 1 gave the key back  
PROCESS 2 GOT KEYS : IM ALSO RUNNING  
PROCESS 2 gave the key back


Index
Introduction
Linear Tb
File Io Tb
State Machine Based Tb
Task Based Tb
Self Checking Testbench
Verification Flow
Clock Generator
Simulation
Incremental Compilation
Store And Restore
Event Cycle Simulation
Time Scale And Precision
Stimulus Generation
System Function Random A Myth
Race Condition
Checker
Task And Function
Process Control
Disableing The Block
Watchdog
Compilation N Simulation Switchs
Debugging
About Code Coverage
Testing Stratigies
File Handling
Verilog Semaphore
Finding Testsenarious
Handling Testcase Files
Terimination
Error Injuction
Register Verification
Parameterised Macros
White Gray Black Box
Regression
Tips

Report a Bug or Comment on This section - Your input is what keeps Testbench.in improving with time!





<< PREVIOUS PAGE

TOP

NEXT PAGE >>

copyright © 2007-2017 :: all rights reserved www.testbench.in::Disclaimer