Jump to content

multiple threads calling sequencer lock results in deadlock

Recommended Posts

In my testbench I have two background sequences (call them S1 and S2) perform register access and a test that has multiple threads ( call them T1 to T7) also performing register access on the same shared bus.  T1 through T7 need to lock the sequencer in order to perform multi-cycle transactions on the CPU bus. The scenario is

  1. S1 issues a write, resulting in arb_sequence_q.size == 1 and arb_sequence_q[0].request == SEQ_TYPE_REQ
  2. in the same simulation tick, T1 through T7 issue lock requests. arb_sequence_q.size() == 8 and arb_sequence_q[0] is still the S1 request
  3. S2 issues a read, resulting in arb_sequence_q.size() == 9, arb_sequence_q[8].request == SEQ_TYPE_REQ
  4. The CPU driver calls get() and the request at the head of arb_sequence_q (the write from S1) gets popped, resulting in arb_sequence_q.size() == 8 and arb_sequence_q[0:6].request = SEQ_TYPE_LOCK and arb_sequence_q[7].request == SEQ_TYPE_REQ (this is the request from S2). 
  5. finish_item is called for the S1 request, resulting in grant_queued_locks getting called, pushing all LOCK requests onto the lock_list and leaving only S2 on the arb_sequence_q. 
    1. arb_sequence_q.size() == 1, arb_sequence_q[0].request = SEQ_TYPE_REQ (this is the S2 request)
    2. lock_list.size() == 7
    3. arb_completed.num() == 0
  6. T1 calls write, enqueuing a SEQ_TYPE_REQ on the arb_sequence_q. The arb_sequence_q.size() == 2, arb_sequence_q[0] is S2's request and arb_sequence_q[1] is T1's request.
  7. [edit] Here's where the problem hits. Because the lock_list size() > 1, when the consumer (driver) calls get(), the sequencer will cycle through all its requests in its arb_sequence_q until it finds one that is ~is_blocked(). Unfortunately, that function cycles through all sequences in the lock_list regardless of whether the first item in the lock list corresponds to the request being processed. So since we have 7 locks in there, one for each thread, when the driver tries to get a new sequence, T1 will always be blocked by T2:T7. Similarly any request from T1:T7 will get locked out by the others. 

We've now deadlocked. 

I believe there is an issue here with the is_blocked() function which should have some form of priority encoding.

Link to comment
Share on other sites

  • 3 years later...
  • 2 months later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Create New...