scc  2022.4.0
SystemC components library
apb_target.cpp
1 /*******************************************************************************
2  * Copyright 2019-2022 MINRES Technologies GmbH
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *******************************************************************************/
16 
17 #include "apb_target.h"
18 #include <scc/report.h>
19 #include <systemc>
20 #include <tuple>
21 
22 using namespace sc_core;
23 using namespace tlm;
24 using namespace apb::pe;
25 
26 /******************************************************************************
27  * target
28  ******************************************************************************/
29 
30 apb_target_b::apb_target_b(const sc_core::sc_module_name& nm, sc_core::sc_port_b<tlm::tlm_bw_transport_if<tlm_base_protocol_types>>& port,
31  size_t transfer_width)
32 : sc_module(nm)
33 , socket_bw(port) {
34  SC_METHOD(response);
35  dont_initialize();
36  sensitive << clk_i.pos();
37 }
38 
39 void apb_target_b::end_of_elaboration() { clk_if = dynamic_cast<sc_core::sc_clock*>(clk_i.get_interface()); }
40 
41 void apb_target_b::b_transport(payload_type& trans, sc_time& t) {
42  if(operation_cb)
43  operation_cb(trans);
44  trans.set_dmi_allowed(false);
45  trans.set_response_status(tlm::TLM_OK_RESPONSE);
46  clk_if = dynamic_cast<sc_core::sc_clock*>(clk_i.get_interface());
47  if(clk_if) {
48  t += 1 * clk_if->period();
49  }
50 }
51 
52 tlm_sync_enum apb_target_b::nb_transport_fw(payload_type& trans, phase_type& phase, sc_time& t) {
53  if(phase == tlm::BEGIN_REQ) {
54  sc_assert(active_tx == nullptr);
55  if(operation_cb)
56  operation_cb(trans);
57  active_tx = &trans;
58  if(trans.has_mm())
59  trans.acquire();
60  if(mhndl.valid())
61  mhndl.enable();
62  phase = tlm::END_REQ;
63  t += sc_time(clk_if ? clk_if->period() - 1_ps : SC_ZERO_TIME);
64  return tlm::TLM_UPDATED;
65  } else if(phase == tlm::END_REQ) {
66  sc_assert(active_tx == &trans);
67  if(active_tx->has_mm())
68  active_tx->release();
69  active_tx = nullptr;
70  return tlm::TLM_COMPLETED;
71  }
72  return tlm::TLM_ACCEPTED;
73 }
74 
75 bool apb_target_b::get_direct_mem_ptr(payload_type& trans, tlm_dmi& dmi_data) {
76  trans.set_dmi_allowed(false);
77  return false;
78 }
79 
80 unsigned int apb_target_b::transport_dbg(payload_type& trans) { return 0; }
81 
82 void apb_target_b::response() {
83  if(!mhndl.valid())
84  mhndl = sc_get_current_process_handle();
85  if(active_tx) {
86  tlm_phase phase{tlm::BEGIN_RESP};
87  sc_time delay;
88  auto ret = socket_bw->nb_transport_bw(*active_tx, phase, delay);
89  if((ret == tlm::TLM_UPDATED && phase == tlm::END_RESP) || ret == tlm::TLM_COMPLETED) {
90  if(active_tx->has_mm())
91  active_tx->release();
92  active_tx = nullptr;
93  }
94  if(mhndl.valid())
95  mhndl.disable();
96  }
97 }
protocol engine implementations
Definition: apb_initiator.h:27
SystemC TLM.