//----------------------------------------------------------------------
// Copyright 2010 Mentor Graphics Corporation
// Copyright 2010 Synopsys, Inc.
// All Rights Reserved Worldwide
//
// Licensed under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in
// writing, software distributed under the License is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See
// the License for the specific language governing
// permissions and limitations under the License.
//----------------------------------------------------------------------
//----------------------------------------------------------------------
// Title: TLM Sockets
//
// Each uvm_tlm_*_socket class is derived from a corresponding
// uvm_tlm_*_socket_base class. The base class contains most of the
// implementation of the class, The derived classes (in this file)
// contain the connection semantics.
//
// Sockets come in several flavors: Each socket is either an initiator or a
// target, a pass-through or a terminator. Further, any particular socket
// implements either the blocking interfaces or the nonblocking interfaces.
// Terminator sockets are used on initiators and targets as well as
// interconnect components as shown in the figure above. Pass-through
// sockets are used to enable connections to cross hierarchical boundaries.
//
// There are eight socket types: the cross of blocking and nonblocking,
// pass-through and termination, target and initiator
//
// Sockets are specified based on what they are (IS-A)
// and what they contains (HAS-A).
// IS-A and HAS-A are types of object relationships.
// IS-A refers to the inheritance relationship and
// HAS-A refers to the ownership relationship.
// For example if you say D is a B that means that D is derived from base B.
// If you say object A HAS-A B that means that B is a member of A.
//----------------------------------------------------------------------
//----------------------------------------------------------------------
// Class: uvm_tlm_b_initiator_socket
//
// IS-A forward port; has no backward path except via the payload
// contents
//----------------------------------------------------------------------
class [docs]uvm_tlm_b_initiator_socket #(type T=uvm_tlm_generic_payload)
extends uvm_tlm_b_initiator_socket_base #(T);
// Function: new
// Construct a new instance of this socket
function [docs]new(string name, uvm_component parent);
super.new(name, parent);
endfunction
// Function: Connect
//
// Connect this socket to the specified <uvm_tlm_b_target_socket>
function void [docs]connect(this_type provider);
uvm_tlm_b_passthrough_initiator_socket_base #(T) initiator_pt_socket;
uvm_tlm_b_passthrough_target_socket_base #(T) target_pt_socket;
uvm_tlm_b_target_socket_base #(T) target_socket;
uvm_component c;
super.connect(provider);
if($cast(initiator_pt_socket, provider) ||
$cast(target_pt_socket, provider) ||
$cast(target_socket, provider))
return;
c = get_comp();
`uvm_error_context(get_type_name(),
"type mismatch in connect -- connection cannot be completed", c)
endfunction
endclass
//----------------------------------------------------------------------
// Class: uvm_tlm_b_target_socket
//
// IS-A forward imp; has no backward path except via the payload
// contents.
//
// The component instantiating this socket must implement
// a b_transport() method with the following signature
//
//| task b_transport(T t, uvm_tlm_time delay);
//
//----------------------------------------------------------------------
class [docs]uvm_tlm_b_target_socket #(type IMP=int,
type T=uvm_tlm_generic_payload)
extends uvm_tlm_b_target_socket_base #(T);
local IMP m_imp;
// Function: new
// Construct a new instance of this socket
// ~imp~ is a reference to the class implementing the
// b_transport() method.
// If not specified, it is assume to be the same as ~parent~.
function [docs]new (string name, uvm_component parent, IMP imp = null);
super.new (name, parent);
if (imp == null) $cast(m_imp, parent);
else m_imp = imp;
if (m_imp == null)
`uvm_error("UVM/TLM2/NOIMP", {"b_target socket ", name,
" has no implementation"});
endfunction
// Function: Connect
//
// Connect this socket to the specified <uvm_tlm_b_initiator_socket>
function void [docs]connect(this_type provider);
uvm_component c;
super.connect(provider);
c = get_comp();
`uvm_error_context(get_type_name(),
"You cannot call connect() on a target termination socket", c)
endfunction
`UVM_TLM_B_TRANSPORT_IMP(m_imp, T, t, delay)
endclass
//----------------------------------------------------------------------
// Class: uvm_tlm_nb_initiator_socket
//
// IS-A forward port; HAS-A backward imp
//
// The component instantiating this socket must implement
// a nb_transport_bw() method with the following signature
//
//| function uvm_tlm_sync_e nb_transport_bw(T t, ref P p, input uvm_tlm_time delay);
//
//----------------------------------------------------------------------
class [docs]uvm_tlm_nb_initiator_socket #(type IMP=int,
type T=uvm_tlm_generic_payload,
type P=uvm_tlm_phase_e)
extends uvm_tlm_nb_initiator_socket_base #(T,P);
uvm_tlm_nb_transport_bw_imp #(T,P,IMP) bw_imp;
// Function: new
// Construct a new instance of this socket
// ~imp~ is a reference to the class implementing the
// nb_transport_bw() method.
// If not specified, it is assume to be the same as ~parent~.
function [docs]new(string name, uvm_component parent, IMP imp = null);
super.new (name, parent);
if (imp == null) $cast(imp, parent);
if (imp == null)
`uvm_error("UVM/TLM2/NOIMP", {"nb_initiator socket ", name,
" has no implementation"});
bw_imp = new("bw_imp", imp);
endfunction
// Function: Connect
//
// Connect this socket to the specified <uvm_tlm_nb_target_socket>
function void [docs]connect(this_type provider);
uvm_tlm_nb_passthrough_initiator_socket_base #(T,P) initiator_pt_socket;
uvm_tlm_nb_passthrough_target_socket_base #(T,P) target_pt_socket;
uvm_tlm_nb_target_socket_base #(T,P) target_socket;
uvm_component c;
super.connect(provider);
if($cast(initiator_pt_socket, provider)) begin
initiator_pt_socket.bw_export.connect(bw_imp);
return;
end
if($cast(target_pt_socket, provider)) begin
target_pt_socket.bw_port.connect(bw_imp);
return;
end
if($cast(target_socket, provider)) begin
target_socket.bw_port.connect(bw_imp);
return;
end
c = get_comp();
`uvm_error_context(get_type_name(),
"type mismatch in connect -- connection cannot be completed", c)
endfunction
endclass
//----------------------------------------------------------------------
// Class: uvm_tlm_nb_target_socket
//
// IS-A forward imp; HAS-A backward port
//
// The component instantiating this socket must implement
// a nb_transport_fw() method with the following signature
//
//| function uvm_tlm_sync_e nb_transport_fw(T t, ref P p, input uvm_tlm_time delay);
//
//----------------------------------------------------------------------
class [docs]uvm_tlm_nb_target_socket #(type IMP=int,
type T=uvm_tlm_generic_payload,
type P=uvm_tlm_phase_e)
extends uvm_tlm_nb_target_socket_base #(T,P);
local IMP m_imp;
// Function: new
// Construct a new instance of this socket
// ~imp~ is a reference to the class implementing the
// nb_transport_fw() method.
// If not specified, it is assume to be the same as ~parent~.
function [docs]new (string name, uvm_component parent, IMP imp = null);
super.new (name, parent);
if (imp == null) $cast(m_imp, parent);
else m_imp = imp;
bw_port = new("bw_port", get_comp());
if (m_imp == null)
`uvm_error("UVM/TLM2/NOIMP", {"nb_target socket ", name,
" has no implementation"});
endfunction
// Function: connect
//
// Connect this socket to the specified <uvm_tlm_nb_initiator_socket>
function void [docs]connect(this_type provider);
uvm_component c;
super.connect(provider);
c = get_comp();
`uvm_error_context(get_type_name(),
"You cannot call connect() on a target termination socket", c)
endfunction
`UVM_TLM_NB_TRANSPORT_FW_IMP(m_imp, T, P, t, p, delay)
endclass
//----------------------------------------------------------------------
// Class: uvm_tlm_b_passthrough_initiator_socket
//
// IS-A forward port;
//----------------------------------------------------------------------
class [docs]uvm_tlm_b_passthrough_initiator_socket #(type T=uvm_tlm_generic_payload)
extends uvm_tlm_b_passthrough_initiator_socket_base #(T);
function [docs]new(string name, uvm_component parent);
super.new(name, parent);
endfunction
// Function : connect
//
// Connect this socket to the specified <uvm_tlm_b_target_socket>
function void [docs]connect(this_type provider);
uvm_tlm_b_passthrough_initiator_socket_base #(T) initiator_pt_socket;
uvm_tlm_b_passthrough_target_socket_base #(T) target_pt_socket;
uvm_tlm_b_target_socket_base #(T) target_socket;
uvm_component c;
super.connect(provider);
if($cast(initiator_pt_socket, provider) ||
$cast(target_pt_socket, provider) ||
$cast(target_socket, provider))
return;
c = get_comp();
`uvm_error_context(get_type_name(), "type mismatch in connect -- connection cannot be completed", c)
endfunction
endclass
//----------------------------------------------------------------------
// Class: uvm_tlm_b_passthrough_target_socket
//
// IS-A forward export;
//----------------------------------------------------------------------
class [docs]uvm_tlm_b_passthrough_target_socket #(type T=uvm_tlm_generic_payload)
extends uvm_tlm_b_passthrough_target_socket_base #(T);
function [docs]new(string name, uvm_component parent);
super.new(name, parent);
endfunction
// Function : connect
//
// Connect this socket to the specified <uvm_tlm_b_initiator_socket>
function void [docs]connect(this_type provider);
uvm_tlm_b_passthrough_target_socket_base #(T) target_pt_socket;
uvm_tlm_b_target_socket_base #(T) target_socket;
uvm_component c;
super.connect(provider);
if($cast(target_pt_socket, provider) ||
$cast(target_socket, provider))
return;
c = get_comp();
`uvm_error_context(get_type_name(),
"type mismatch in connect -- connection cannot be completed", c)
endfunction
endclass
//----------------------------------------------------------------------
// Class: uvm_tlm_nb_passthrough_initiator_socket
//
// IS-A forward port; HAS-A backward export
//----------------------------------------------------------------------
class [docs]uvm_tlm_nb_passthrough_initiator_socket #(type T=uvm_tlm_generic_payload,
type P=uvm_tlm_phase_e)
extends uvm_tlm_nb_passthrough_initiator_socket_base #(T,P);
function [docs]new(string name, uvm_component parent);
super.new(name, parent);
endfunction
// Function : connect
//
// Connect this socket to the specified <uvm_tlm_nb_target_socket>
function void [docs]connect(this_type provider);
uvm_tlm_nb_passthrough_initiator_socket_base #(T,P) initiator_pt_socket;
uvm_tlm_nb_passthrough_target_socket_base #(T,P) target_pt_socket;
uvm_tlm_nb_target_socket_base #(T,P) target_socket;
uvm_component c;
super.connect(provider);
if($cast(initiator_pt_socket, provider)) begin
bw_export.connect(initiator_pt_socket.bw_export);
return;
end
if($cast(target_pt_socket, provider)) begin
target_pt_socket.bw_port.connect(bw_export);
return;
end
if($cast(target_socket, provider)) begin
target_socket.bw_port.connect(bw_export);
return;
end
c = get_comp();
`uvm_error_context(get_type_name(),
"type mismatch in connect -- connection cannot be completed", c)
endfunction
endclass
//----------------------------------------------------------------------
// Class: uvm_tlm_nb_passthrough_target_socket
//
// IS-A forward export; HAS-A backward port
//----------------------------------------------------------------------
class [docs]uvm_tlm_nb_passthrough_target_socket #(type T=uvm_tlm_generic_payload,
type P=uvm_tlm_phase_e)
extends uvm_tlm_nb_passthrough_target_socket_base #(T,P);
function [docs]new(string name, uvm_component parent);
super.new(name, parent);
endfunction
// Function: connect
//
// Connect this socket to the specified <uvm_tlm_nb_initiator_socket>
function void [docs]connect(this_type provider);
uvm_tlm_nb_passthrough_target_socket_base #(T,P) target_pt_socket;
uvm_tlm_nb_target_socket_base #(T,P) target_socket;
uvm_component c;
super.connect(provider);
if($cast(target_pt_socket, provider)) begin
target_pt_socket.bw_port.connect(bw_port);
return;
end
if($cast(target_socket, provider)) begin
target_socket.bw_port.connect(bw_port);
return;
end
c = get_comp();
`uvm_error_context(get_type_name(),
"type mismatch in connect -- connection cannot be completed", c)
endfunction
endclass
//----------------------------------------------------------------------