scc  2024.06
SystemC components library
apb_initiator.cpp
1 /*******************************************************************************
2  * Copyright 2020-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 "../../../interfaces/apb/pe/apb_initiator.h"
18 
19 #include <scc/report.h>
20 
21 using namespace sc_core;
22 using namespace apb;
23 using namespace apb::pe;
24 
25 namespace {
26 uint8_t log2n(uint8_t siz) { return ((siz > 1) ? 1 + log2n(siz >> 1) : 0); }
27 
28 } // anonymous namespace
29 
30 apb_initiator_b::apb_initiator_b(sc_core::sc_module_name nm,
31  sc_core::sc_port_b<tlm::tlm_fw_transport_if<tlm::tlm_base_protocol_types>>& port, size_t transfer_width,
32  bool coherent)
33 : sc_module(nm)
34 , socket_fw(port)
35 , transfer_width_in_bytes(transfer_width / 8) {}
36 
37 apb_initiator_b::~apb_initiator_b() = default;
38 
39 tlm::tlm_sync_enum apb_initiator_b::nb_transport_bw(payload_type& trans, phase_type& phase, sc_core::sc_time& t) {
40 
41  peq.notify(std::make_tuple(&trans, phase), t);
42  return tlm::TLM_ACCEPTED;
43 }
44 
45 void apb_initiator_b::invalidate_direct_mem_ptr(sc_dt::uint64 start_range, sc_dt::uint64 end_range) {}
46 
47 void apb_initiator_b::transport(payload_type& trans, bool blocking) {
48  SCCTRACE(SCMOD) << "got transport req for id=" << &trans;
49  if(blocking) {
50  sc_time t;
51  socket_fw->b_transport(trans, t);
52  } else {
54  SCCTRACE(SCMOD) << "start transport req for id=" << &trans;
55  trans.free_all_extensions();
56  tlm::tlm_phase phase{tlm::BEGIN_REQ};
57  sc_time t;
58  auto res = socket_fw->nb_transport_fw(trans, phase, t);
59  if(res == tlm::TLM_COMPLETED || (res == tlm::TLM_UPDATED && phase != tlm::END_REQ && phase != tlm::BEGIN_RESP))
60  SCCFATAL(SCMOD) << "target did not respsond with END_REQ or BEGIN_RESP to a BEGIN_REQ";
61  if(res != tlm::TLM_UPDATED || phase != tlm::BEGIN_RESP) {
62  payload_type* gp{nullptr};
63  while(phase != tlm::BEGIN_RESP) {
64  std::tie(gp, phase) = peq.get();
65  if(gp != &trans)
66  SCCFATAL(SCMOD) << "target did send the wrong transaction";
67  if(phase != tlm::END_REQ && phase != tlm::BEGIN_RESP)
68  SCCFATAL(SCMOD) << "target did not respsond with END_REQ or BEGIN_RESP to a BEGIN_REQ";
69  if(phase == tlm::END_REQ)
70  wait(clk_i.posedge_event());
71  }
72  }
73  phase = tlm::END_RESP;
74  t = SC_ZERO_TIME;
75  socket_fw->nb_transport_fw(trans, phase, t);
76  SCCTRACE(SCMOD) << "finished non-blocking protocol";
77  any_tx_finished.notify(SC_ZERO_TIME);
78  }
79  SCCTRACE(SCMOD) << "finished transport req for id=" << &trans;
80 }
void transport(payload_type &trans, bool blocking)
The forward transport function. It behaves blocking and is re-entrant.
protocol engine implementations
Definition: apb_initiator.h:27
TLM2.0 components modeling APB.
Definition: apb_tlm.cpp:21
a lock for the semaphore
void notify(const TYPE &entry, const sc_core::sc_time &t)
non-blocking push.
Definition: peq.h:77
TYPE get()
blocking get
Definition: peq.h:128