Last active
June 6, 2022 02:59
-
-
Save dvtalk/692f45bba567aaeae98f61f63d867058 to your computer and use it in GitHub Desktop.
uvm_semaphore, wrap around std::semaphore class of SystemVerilog
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://dvtalk.me/2021/10/03/uvm-pool-and-semaphore/ | |
class uvm_semaphore extends uvm_object; | |
protected semaphore m_semaphore; | |
protected string m_name; | |
protected int m_keyCount; | |
protected int m_remainKeyinBucket; | |
protected bit m_expandBucket_en; | |
function new (string name="", int keyCount=0); | |
super.new(name); | |
m_semaphore = new(keyCount); | |
m_name = name; | |
m_keyCount = keyCount; | |
m_remainKeyinBucket = keyCount; | |
m_expandBucket_en = 1; | |
uvm_report_info("SEMAPHORE", $psprintf("[%s] Create new semaphore, number of keys: %0d",name, keyCount)); | |
endfunction | |
virtual function void set_keyCount(int keyCount=0); | |
if (keyCount > m_keyCount) begin | |
// if new keyCount is greater than current m_keyCount, just put more keys in the bucket | |
this.put(keyCount-m_keyCount); | |
end | |
else if (keyCount < m_keyCount) begin | |
// if new keyCount is smaller than current m_keyCount, | |
// create new semaphore if all keys are in the bucket. | |
if (m_remainKeyinBucket == m_keyCount) begin | |
m_semaphore = new(keyCount); | |
m_keyCount = keyCount; | |
m_remainKeyinBucket = keyCount; | |
uvm_report_info("SEMAPHORE", $psprintf("[%s] Create new semaphore, number of keys: %0d",m_name, keyCount)); | |
end | |
else begin | |
uvm_report_error("SEMAPHORE",$psprintf("[%s] Semphore key is already used, cannot set the keyCount to smaller than %0d",m_name, m_keyCount)); | |
end | |
end | |
endfunction | |
virtual function void put(int keyCount=1); | |
m_semaphore.put(keyCount); | |
if ((m_remainKeyinBucket + keyCount)> m_keyCount) begin | |
if (is_expand_bucket_en()) begin | |
uvm_report_warning("SEMAPHORE", $psprintf("[%s] [PUT] ADDING %0d MORE keys to the orginal total keys (%0d)",m_name, (m_remainKeyinBucket+keyCount)-m_keyCount, m_keyCount )); | |
m_remainKeyinBucket += keyCount; | |
m_keyCount = m_remainKeyinBucket; | |
uvm_report_info("SEMAPHORE", $psprintf("[%s] [PUT] Remaining keys in bucket: %0d, total keys of semaphore: %0d", m_name, m_remainKeyinBucket, m_keyCount)); | |
end | |
else begin | |
uvm_report_warning("SEMAPHORE", $psprintf("[%s] [PUT] Used keys : %0d, total keys of semaphore: %0d", m_name, m_keyCount - m_remainKeyinBucket, m_keyCount)); | |
uvm_report_warning("SEMAPHORE", $psprintf("[%s] [PUT] Trying to put %0d keys to the bucket. Only put %0d keys in the bucket, to allow expanding the bucket keys, call <semaphore handle>.set_expand_bucket_en(1'b1); " ,m_name, keyCount, m_keyCount-m_remainKeyinBucket)); | |
m_remainKeyinBucket = m_keyCount; | |
uvm_report_info("SEMAPHORE", $psprintf("[%s] [PUT] Remaining keys in bucket: %0d, total keys of semaphore: %0d", m_name, m_remainKeyinBucket, m_keyCount)); | |
end | |
end | |
else begin | |
uvm_report_info("SEMAPHORE", $psprintf("[%s] [PUT] Put %0d keys in bucket, remaining keys in bucket: %0d, total keys of semaphore: %0d", m_name, keyCount, m_remainKeyinBucket, m_keyCount)); | |
end | |
endfunction | |
virtual task get(int keyCount=1); | |
m_semaphore.get(keyCount); | |
m_remainKeyinBucket -= keyCount; | |
uvm_report_info("SEMAPHORE", $psprintf("[%s] [GET] Get %0d keys from bucket, remaining keys in bucket: %0d, total keys of semaphore: %0d", m_name, keyCount, m_remainKeyinBucket, m_keyCount)); | |
endtask | |
virtual function int try_get(int keyCount=1); | |
int try_get = m_semaphore.try_get(keyCount); | |
if (try_get==0) begin | |
uvm_report_info("SEMAPHORE", $psprintf("[%s] [TRY_GET] Try Get %0d keys from bucket UNSUCCESSFUL, remaining keys in bucket: %0d, total keys of semaphore: %0d",m_name,keyCount, m_remainKeyinBucket, m_keyCount)); | |
end | |
else begin | |
m_remainKeyinBucket -= keyCount; | |
uvm_report_info("SEMAPHORE", $psprintf("[%s] [TRY_GET] Try Get %0d keys from bucket, remaining keys in bucket: %0d, total keys of semaphore: %0d", m_name, keyCount, m_remainKeyinBucket, m_keyCount)); | |
end | |
endfunction | |
virtual function int get_remaining_keys(); | |
return this.m_remainKeyinBucket; | |
endfunction | |
virtual function int get_total_keys(); | |
return this.m_keyCount; | |
endfunction | |
virtual function void set_expand_bucket_en(bit expand_bucket_en); | |
this.m_expandBucket_en = expand_bucket_en; | |
endfunction | |
virtual function bit is_expand_bucket_en(); | |
return this.m_expandBucket_en; | |
endfunction | |
endclass: uvm_semaphore | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment