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