Reputation: 375
I have a requirement where I need to have two uvm_tlm_b_target_socket
in class as it going to receive a transaction from two different agents. I need to process the data received from the two sockets differently so I cannot have a single implementation of b_transport
task. Is there anything equivalent for target socket to terminator of analysis ports were we can use uvm_analysis_imp_decl
macro which allows us to have a different implementation of write
function? In the class reference manual I could find this macro uvm_blocking_transport_imp_decl
but couldn't find an example of how to use this. In summary I am trying to do this
uvm_tlm_b_target_socket A;
umv_tlm_b_target_socket B;
// b_transport task implementation for socket "A"
task b_transport;
// b_transport task implementation for socket "B"
task b_transport;
Upvotes: 0
Views: 418
Reputation: 7573
Aside from the classical TLM2 sockets, there are also *_transport_imps
. As far as I could tell, these do the same thing as sockets. You use the *_decl
macro just like you use uvm_analysis_imp_decl
:
class some_class;
`uvm_blocking_transport_imp_decl(_a)
`uvm_blocking_transport_imp_decl(_b)
uvm_transport_imp_a A;
umv_transport_imp_b B;
task b_transport_a(...);
task b_transport_b(...);
endclass
Upvotes: 1
Reputation: 792
uvm_tlm_b_target_socket when instantiated needs to be provided two parameters.
1) base class where the implementation - b_transport resides
2) the other is the data item itself.
uvm_tlm_b_target_socket #(receiver, data_item) A;
You can only have 1 transport_b function in your receiver class . But you can use a wrapper class to connect the other functions in your receiver class to other target sockets.
typedef class receiver; // name of the parent class processing the transport call.
class connect_transport ; // does not need to be a component but if you need it can - extends uvm_component;
receiver m_parent; // parent class
function new(string name = "receiver", receiver parent = null);
m_parent = parent; // connect the parent class
endfunction
task b_transport(data_item data, uvm_tlm_time delay);
// transport_b for B.
m_parent.b_transport_b(data,delay); // call the function in the parent class.
endtask
endclass
in the receiver class
class receiver extends umm_component ;
`uvm_component_utils(receiver)
connect_transport c1;
.....
uvm_tlm_b_target_socket #(receiver, data_item) A; // connects to the local b_transport function
uvm_tlm_b_target_socket #(connect_transport, data_item) B; // connect to the wrapper class
function new(string name = "receiver", uvm_component parent = null);
super.new(name, parent);
A = new("A", this);
c1 = new ("c1",this); // create the connecting class
B = new("B", this,c1); // connect the target socket to the connecting class
endfunction
//for socket B
task b_transport_b(data_item data, uvm_tlm_time delay);
......
end task
// will be connected to A socket.
task b_transport(data_item data, uvm_tlm_time delay);
......
end task
endclass
You can wrap this into a macro , and have an _imp_decl kind of implementation. You could also implement the check directly in the connect_transport.
Upvotes: 1