35 using tlm_initiator_socket_t = tlm_utils::simple_initiator_socket_b<
MOD,
BUSWIDTH, tlm::tlm_base_protocol_types,
36 sc_core::SC_ZERO_OR_MORE_BOUND>;
37 using tlm_target_socket_t = tlm_utils::simple_target_socket_tagged_b<
MOD,
BUSWIDTH, tlm::tlm_base_protocol_types,
38 sc_core::SC_ZERO_OR_MORE_BOUND>;
40 sc_core::sc_vector<tlm_initiator_socket_t> initiator_sockets;
41 sc_core::sc_vector<tlm_target_socket_t> target_sockets;
42 cci::cci_param<uint32_t> p_tlm_ports_num;
46 : sc_core::sc_module(
nm)
47 , initiator_sockets(
"initiator_socket")
48 , target_sockets(
"target_socket")
49 , p_tlm_ports_num(
"dmic_tlm_ports_num", 1,
"number of tlm ports")
51 SCP_DEBUG(()) <<
"dmi_converter constructor";
52 initiator_sockets.init(p_tlm_ports_num.get_value(),
53 [
this](
const char*
n,
int i) { return new tlm_initiator_socket_t(n); });
54 target_sockets.init(p_tlm_ports_num.get_value(),
55 [
this](
const char*
n,
int i) { return new tlm_target_socket_t(n); });
56 for (
int i = 0;
i < p_tlm_ports_num.get_value();
i++) {
57 target_sockets[
i].register_b_transport(
this, &dmi_converter::b_transport,
i);
58 target_sockets[
i].register_transport_dbg(
this, &dmi_converter::transport_dbg,
i);
59 target_sockets[
i].register_get_direct_mem_ptr(
this, &dmi_converter::get_direct_mem_ptr,
i);
60 initiator_sockets[
i].register_invalidate_direct_mem_ptr(
this, &dmi_converter::invalidate_direct_mem_ptr);
67 void b_transport(
int id, tlm::tlm_generic_payload&
trans, sc_core::sc_time& delay)
71 tlm::tlm_command cmd =
trans.get_command();
74 unsigned int bel =
trans.get_byte_enable_length();
75 if (
ref_byt && (
bel <= 0))
SCP_FATAL(()) <<
"byte enable ptr is not NULL but byte enable length <= 0!";
76 std::unique_ptr<unsigned char[]>
byt;
78 byt = std::make_unique<unsigned char[]>(
bel);
86 tlm::tlm_dmi* dmi_data;
89 dmi_data = in_cache(
addr);
90 if (dmi_data && is_dmi_access_type_granted(*dmi_data, cmd)) {
91 sc_dt::uint64
start_addr = dmi_data->get_start_address();
92 sc_dt::uint64
end_addr = dmi_data->get_end_address();
93 unsigned char*
dmi_ptr = dmi_data->get_dmi_ptr();
97 case tlm::TLM_IGNORE_COMMAND:
99 case tlm::TLM_WRITE_COMMAND:
100 SCP_DEBUG(()) <<
"(write request) cache is used to write " << std::hex <<
iter_len
101 <<
" bytes starting from: 0x" << std::hex <<
addr
102 <<
", cache block used starts at: 0x" << std::hex <<
start_addr <<
" and ends at: 0x"
115 case tlm::TLM_READ_COMMAND:
117 <<
" bytes starting from: 0x" << std::hex <<
addr
118 <<
", cache block used starts at: 0x" << std::hex <<
start_addr <<
" and ends at: 0x"
132 SCP_FATAL(()) <<
"invalid tlm_command at address: 0x" << std::hex <<
addr;
142 trans.set_dmi_allowed(
true);
143 trans.set_response_status(tlm::TLM_OK_RESPONSE);
149 tlm::tlm_generic_payload
t_trans;
162 SCP_DEBUG(()) << get_access_type_str(cmd)
163 <<
" data is not in cache, DMI request is successful, granted start addr: "
165 << std::hex <<
t_dmi_data.get_start_address() <<
" granted end addr: 0x" << std::hex
170 SCP_DEBUG(()) << get_access_type_str(cmd)
171 <<
" data is not in cache, DMI request failed, b_transport used, len: " << std::hex
173 <<
" addr: 0x" << std::hex
175 trans.set_dmi_allowed(
false);
183 unsigned int transport_dbg(
int id, tlm::tlm_generic_payload&
trans)
185 SCP_DEBUG(()) <<
"calling dbg_transport: ";
186 return initiator_sockets[id]->transport_dbg(
trans);
189 bool get_direct_mem_ptr(
int id, tlm::tlm_generic_payload&
trans, tlm::tlm_dmi& dmi_data)
191 SCP_DEBUG(()) <<
"DMI to " <<
trans.get_address() <<
" range " << std::hex << dmi_data.get_start_address()
192 <<
" - " << std::hex << dmi_data.get_end_address();
196 return !(dmi_data.is_none_allowed());
199 if (
dmi_ptr_valid) m_dmi_cache[dmi_data.get_start_address()] = dmi_data;
204 void invalidate_direct_mem_ptr(sc_dt::uint64 start, sc_dt::uint64 end)
206 SCP_DEBUG(()) <<
" invalidate_direct_mem_ptr "
207 <<
" start address 0x" << std::hex << start <<
" end address 0x" << std::hex << end;
209 cache_clean(start, end);
210 for (
int i = 0;
i < target_sockets.size();
i++) {
211 target_sockets[
i]->invalidate_direct_mem_ptr(start, end);
234 bool is_dmi_access_type_granted(
const tlm::tlm_dmi& dmi_data,
const tlm::tlm_command& cmd)
237 case tlm::TLM_WRITE_COMMAND:
238 return dmi_data.is_write_allowed();
239 case tlm::TLM_READ_COMMAND:
240 return dmi_data.is_read_allowed();
246 std::string get_access_type_str(
const tlm::tlm_command& cmd)
250 case tlm::TLM_WRITE_COMMAND:
253 case tlm::TLM_READ_COMMAND:
256 case tlm::TLM_IGNORE_COMMAND:
260 ret_str =
"(invalid tlm_command)";
266 tlm::tlm_dmi* in_cache(
uint64_t address)
268 if (m_dmi_cache.size() > 0) {
269 auto it = m_dmi_cache.upper_bound(address);
270 if (
it != m_dmi_cache.begin()) {
273 return &(
it->second);
281 auto it = m_dmi_cache.upper_bound(start);
283 if (
it != m_dmi_cache.begin()) {
291 while (
it != m_dmi_cache.end()) {
292 tlm::tlm_dmi& r =
it->second;
294 if (r.get_start_address() > end) {
299 if (r.get_end_address() < start) {
304 it = m_dmi_cache.erase(
it);
309 std::map<uint64_t, tlm::tlm_dmi> m_dmi_cache;