SystemVerilog - Semaphore

2023-07-06
SystemVerilog

Semaphore就是類似有一個盒子裡面放了固定數量的key,想要往下執行的時候要先去get一把key,有成功拿到key之後才能往下執行,沒拿到key就繼續等待到有key之後再往下執行。

使用方式
new()的時候決定key的數量
get(keyCount)取得key,參數就是要取得key的數量
put(keyCount)取得key,參數就是要放回key的數量
也可以用try_get(keyCount)來嘗試取得key,取得key失敗就不會被block住

下面的例子是semaphore只有一把key,customerA和customerB在getRoom之前需要先去get() key,成功得到key之後一段時間就會把key用put()放回去,參數id其實只是個記號而已

Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
module tb();
semaphore key = new(1);

initial begin
fork
customerA();
customerB();
join
end

task customerA();
getRoom(1);
#5
rtnRoom(1);
endtask

task customerB();
getRoom(2);
#10
rtnRoom(2);
endtask

task getRoom(bit[0:1] id);
$display("t:%0d start get room id:%0d", $time, id);
key.get();
$display("t:%0d finish get room id:%0d", $time, id);
endtask

task rtnRoom(bit[0:1] id);
$display("t:%0d start return room id:%0d", $time, id);
key.put();
$display("t:%0d finish return room id:%0d", $time, id);
endtask
endmodule

Output

# run 10000
# t:0 start  get room id:1
# t:0 finish get room id:1
# t:0 start  get room id:2
# t:5 start  return room id:1
# t:5 finish return room id:1
# t:5 finish get room id:2
# t:15 start  return room id:2
# t:15 finish return room id:2
#  quit -f

這個例子因為只有一把Key,所以customerB必須等到customerA把key還回去之後,才能夠得到room並往下執行。


如果把上面的範例的key在new的時候改成兩把key的話,結果如下:

Example:

1
2
3
4
module tb();
semaphore key = new(2);
...
endmodule

Output

# run 10000
# t:0 start  get room id:1
# t:0 finish get room id:1
# t:0 start  get room id:2
# t:0 finish get room id:2
# t:5 start  return room id:1
# t:5 finish return room id:1
# t:10 start  return room id:2
# t:10 finish return room id:2
#  quit -f

因為key有兩把,所以A和B都會直接get到key然後往下執行。