scc 2025.09
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
19#include <scc/report.h>
20
21using namespace sc_core;
22using namespace apb;
23using namespace apb::pe;
24
25namespace {
26uint8_t log2n(uint8_t siz) { return ((siz > 1) ? 1 + log2n(siz >> 1) : 0); }
27
28} // anonymous namespace
29
30apb_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
37apb_initiator_b::~apb_initiator_b() = default;
38
39tlm::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
45void apb_initiator_b::invalidate_direct_mem_ptr(sc_dt::uint64 start_range, sc_dt::uint64 end_range) {}
46
47void 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
TLM2.0 components modeling APB.
Definition apb_tlm.cpp:21
a lock for the semaphore