In my environment I have a transaction received in a particular clock domain which I put into a mailbox.
This transaction is popped from the mailbox on a different clock domain the transaction should then be processed before generating a response after a fixed delay.
So I have this task in one class it is forked in the run stage of this class:
task get_lookup_request();
forever begin
@(negedge lkup_slave_if.slave.clk);
if(lkup_slave_if.slave.ready === 1'b1 && lkup_slave_if.slave.valid === 1'b1) begin
this.lkup_req_trans.key = this.lkup_slave_if.slave.key;
$display("Time %t, Got Lookup Request %h", $realtime, lkup_req_trans.key);
this.lkup_mbx.put(this.lkup_req_trans);
end
end
endtask
The model receiving the transaction has the following task executed in a fork run stage:
task arbitrate;
forever begin
fork
wait(this.rx_lkup_mbx.num > 0 && this.cam_busy.try_get(1));
join
wait fork;
// Arbitrate for access to the CAM
if(this.rx_lkup_mbx.num > 0)
lookup_driver();
end
endtask
So basically the transaction is read from the mailbox passed to some model and a response is provided.
In the model I tried to add a fixed delay on providing the response:
When I include the delay I cannot see the transactions coming out of the mailbox as I expected. I guess it must be something to do with the fact that the delay is blocking?
I know there are probably better ways to do this in UVM but I’ve no experience in UVM.
Your code is hard to follow and you need to explain what you mean by “cannot see the transactions coming out of the mailbox as I expected” What exactly are you expecting versus what is actually happening?
Also fork/join with one statement inside is exactly the same as having that one statement without the fork/join. Thewait fork does nothing either - there is no process to wait for at that point.
Also, why do you haveif(this.rx_lkup_mbx.num > 0)? There is no way to get to that point without it being true already.
Sorry the code is incomplete, the arbitrate task will eventually have multiple mailboxes so I will have some chain of if else branches. I Understand the point about the fork join.
To give more context on what’s going wrong basically say I put into this lkup_mbx 3 messages a, 8, 0. Without the fixed 900ns delay in my lookup_driver task I get the messages from the mailbox as I expected:
Time 60000, Got Lookup Request a
Time 65000, Lookup Key a
Time 80000, Got Lookup Request 8
Time 85000, Lookup Key 8
Time 100000, Got Lookup Request 0
Time 105000, Lookup Key 0
When I have this 900ns delay in my lookup driver I don’t see the second message:
Time 60000, Got Lookup Request a
Time 65000, Lookup Key a
Time 80000, Got Lookup Request 8
Time 100000, Got Lookup Request 0
Time 975000, Lookup Key 0
Time 1885000, Lookup Key 0
So it looks like I put message 8 into the mailbox ok but when I do the get I don’t see that message. I thought having the delay blocking would not be an issue since the arbitrate task will only call the lookup_driver when the cam_busy (semaphore) is released. Seems like some issue around this 900ns delay but I cant really understand what that is. I am coming more from a design background so apologies if this is a little bit muddled.