When your front door interface is pipelined and targeting multiple slaves where read transaction responses from different slaves may not be in the same order of request transactions, the read response could be all mixed up if multiple treads are issuing read transactions. The issue is that in reg/uvm_reg_map.svh (UVM 1.2, see bellow) call to rw.parent.get_base_response(bus_rsp); used default transaction_id = -1 as opposed to the read request transaction id, which results in popping next response item from the response queue in the get_base_response task which could be wrong response as it is not matching the transaction id !!
Example:
- tread#1 issued read to slave#1
- then thread#2 issued read to slave#2
---> now both threads are waiting for response and trying to pop net element available in the response_queue.
- slave#2 responded first and its response get put into the response_queue.
- thread#1 could be served first and get the response from slave#2 which is meant for thread#2 !!!
The solution is at line# 2085 bellow, the call to get_base_response should be: rw.parent.get_base_response(bus_rsp, rw.get_transaction_id());
In file reg/uvm_reg_map.svh:
=======================
1976 task uvm_reg_map::do_bus_read (
.......
2081 if (adapter.provides_responses) begin
2082 uvm_sequence_item bus_rsp;
2083 uvm_access_e op;
2084 // TODO: need to test for right trans type, if not put back in q
2085 rw.parent.get_base_response(bus_rsp);
2086 adapter.bus2reg(bus_rsp,rw_access);
2087 end
2088 else begin
2089 adapter.bus2reg(bus_req,rw_access);
2090 end
.....
1976 task uvm_reg_map::do_bus_read (
In file: seq/uvm_sequence_base.svh:
=============================
1157 virtual task get_base_response(output uvm_sequence_item response, input int transaction_id = -1);
1158
1159 int queue_size, i;
1160
1161 if (response_queue.size() == 0)
1162 wait (response_queue.size() != 0);
1163
1164 if (transaction_id == -1) begin
1165 response = response_queue.pop_front();
1166 return;
1167 end
1168
1169 forever begin
1170 queue_size = response_queue.size();
1171 for (i = 0; i < queue_size; i++) begin
1172 if (response_queue[i].get_transaction_id() == transaction_id)
1173 begin
1174 $cast(response,response_queue[i]);
1175 response_queue.delete(i);
1176 return;
1177 end
1178 end
1179 wait (response_queue.size() != queue_size);
1180 end
1181 endtask