scc 2025.09
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
19#include <scc/report.h>
20#include <systemc>
21#include <tuple>
22
23using namespace sc_core;
24using namespace tlm;
25using namespace apb::pe;
26
27/******************************************************************************
28 * target
29 ******************************************************************************/
30
31apb_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,
32 size_t transfer_width)
33: sc_module(nm)
34, socket_bw(port) {
35 SC_METHOD(response);
36 dont_initialize();
37 sensitive << clk_i.pos();
38}
39
40void apb_target_b::end_of_elaboration() { clk_if = dynamic_cast<sc_core::sc_clock*>(clk_i.get_interface()); }
41
42void apb_target_b::b_transport(payload_type& trans, sc_time& t) {
43 if(operation_cb)
44 operation_cb(trans);
45 trans.set_dmi_allowed(false);
46 trans.set_response_status(tlm::TLM_OK_RESPONSE);
47 clk_if = dynamic_cast<sc_core::sc_clock*>(clk_i.get_interface());
48 if(clk_if) {
49 t += 1 * clk_if->period();
50 }
51}
52
53tlm_sync_enum apb_target_b::nb_transport_fw(payload_type& trans, phase_type& phase, sc_time& t) {
54 if(phase == tlm::BEGIN_REQ) {
55 sc_assert(active_tx == nullptr);
56 if(operation_cb)
57 operation_cb(trans);
58 active_tx = &trans;
59 if(trans.has_mm())
60 trans.acquire();
61 if(mhndl.valid())
62 mhndl.enable();
63 phase = tlm::END_REQ;
64 t += sc_time(clk_if ? clk_if->period() - 1_ps : SC_ZERO_TIME);
65 return tlm::TLM_UPDATED;
66 } else if(phase == tlm::END_REQ) {
67 sc_assert(active_tx == &trans);
68 if(active_tx->has_mm())
69 active_tx->release();
70 active_tx = nullptr;
71 return tlm::TLM_COMPLETED;
72 }
73 return tlm::TLM_ACCEPTED;
74}
75
76bool apb_target_b::get_direct_mem_ptr(payload_type& trans, tlm_dmi& dmi_data) {
77 trans.set_dmi_allowed(false);
78 return false;
79}
80
81unsigned int apb_target_b::transport_dbg(payload_type& trans) { return 0; }
82
83void apb_target_b::response() {
84 if(!mhndl.valid())
85 mhndl = sc_get_current_process_handle();
86 if(active_tx) {
87 tlm_phase phase{tlm::BEGIN_RESP};
88 sc_time delay;
89 auto ret = socket_bw->nb_transport_bw(*active_tx, phase, delay);
90 if((ret == tlm::TLM_UPDATED && phase == tlm::END_RESP) || ret == tlm::TLM_COMPLETED) {
91 if(active_tx->has_mm())
92 active_tx->release();
93 active_tx = nullptr;
94 }
95 if(mhndl.valid())
96 mhndl.disable();
97 }
98}
apb_target_b(const sc_core::sc_module_name &nm, sc_core::sc_port_b< tlm::tlm_bw_transport_if< tlm::tlm_base_protocol_types > > &port, size_t transfer_width)
protocol engine implementations
SystemC TLM.
Definition dmi_mgr.h:19