What is the best/recommended practice to implement a bi-direction bus in uvm framework

hi sir,
i’m trying to adopt uvm framework to next project, and will use sim/emu test bench (yes, my company has veloce server ^-^, and that’s why uvm framework attracts me)
but there is an implementation choice surfacing:
the protocol that dut uses is a bi-directional, req/response protocol, similar like pcie tlp (memory read/write, and write also needs response) but far simpler since it is an on chip bus and no switch connection)

the figure below is tx cmd examples. anyway, dut/agent could receive commands at any time as long as rx bus is idle, and relies status after cmd finished.
so here is my question:
where to implement this protocol, bus_driver or bus_driver_bfm? (NOTICE: i wish i could get benefit from veloce either)
in uvm framework, it defines an agent/driver either INITIATOR or RESPONDER but both, so i’m not sure what is best/recommend way to handle this protocol.
I could process all the commands in driver or driver_bfm. the implementation of this protocol is up to me. anyway, since i decided to adopt uvm framework, it’s better to obeying experts’ advices, and i believe this will gain especial veloce speed-up performance

thanks!

In reply to zxwbobo:

there is a typo in the figure.
rx_rsp should be rx_data, and cmd/rsp will be distinguished by data (with rx_start rising edge) itself
e.g., at rx_starting rising, msb of data set to 1’b1 indicates command, and 0 means response

thanks