How to implement semaphore with priority request to bypass other pending request?

I want to implement a semaphore which allots a single key to drive single request per cycle. However, if there are multiple request waiting already for the key in the same cycle, I want a priority request to bypass all the pending request and the priority request to receive the request. I am unable to find a way to implement as I have tried approach but still not working in corner cases. Is there anyway this can be implemented?

In reply to rahulkumarbudhwani:

You are not going to be able to implement this with a single semaphore. This question is difficult to answer without knowing the architecture of your testbench. We don’t know what a “request” looks like, or how process communication works. If you were using the UVM, it sequuence/sequencer/driver mechanism is already set up to handle this very easily.

But if you are doing this on your own, we need to know a lot of things like how threads are putting in requests, and is there a different thread servicing the requests? Is there a thread per requestor, and can each have several pending requests. How many priority levels are there and how are requests with the same priority level handled?

In reply to dave_59:

Hi Dave,
I am fine with using different approach also. The request in our TB takes one clock cycle to drive the request, i.e., (get key → drive signal->-> @(cb)->put key). I know that the sequencer/driver has a mechanism of priority request. However, currently in TB, the priority request is sort of re-run of the request depending on certain condition, which means, that request was received as normal from the sequencer side, but after certain condition, we are driving as priority from driver side again. Let me know if this clarify the statement else I could go into more details.

In reply to rahulkumarbudhwani:

Hi Rahul,

I still can’t get your request clearly but whatever my understanding is there i will put in the pseudo code here. I understand that you need to drive certain threads based on certain condition and priority. You can use combination of if and case statement for getting the condition and then choosing/assigning the priority of thread and then driving the pins within those thread using semaphore.

// In driver code (Runs in forever block)


if(condition on which priority is defined)  
begin
  case(priority)
  1 : priority 1 thread ();
  2 : priority 2 thread (); 
  3 : priority 3 thread ();
  endcase
end

task priority 1 thread();
  sema.get(1)
   drive();
  sema.put(1);
endtask

In reply to rahulkumarbudhwani:

I have to assume a lot of things without more details. You probably have a number of threads all sharing the same semaphore. Each thread only has one request, activated by the call to get key and is doing the driving as well.

What you probably want to do is have a semaphore for each thread and have another thread doing the arbitration. Each thread does only the semaphore getting and the arbitrating thread does the putting.

Thread N:

Req[[N] = MyPriorty; 
while(!sema[N].try_get()) @CB; // loop each block cycle waiting for sema[N};
Req[[N] = NoRequest; // some value outside of priority range -1
drive signal;

Thread Arbitration:

forever @(CB)
  for(int priority = Highest to Lowest) begin
     indexes = Req.find_index() with (item == priority)
     if (indexes.size>0) begin // found at least one request
         sema[index[0]].put();
         break; // start over next clock cycle
     end