17 #include "../../../interfaces/apb/pe/apb_initiator.h"
19 #include <scc/report.h>
21 using namespace sc_core;
26 uint8_t log2n(uint8_t siz) {
return ((siz > 1) ? 1 + log2n(siz >> 1) : 0); }
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,
35 , transfer_width_in_bytes(transfer_width / 8) {}
37 apb_initiator_b::~apb_initiator_b() =
default;
39 tlm::tlm_sync_enum apb_initiator_b::nb_transport_bw(payload_type& trans, phase_type& phase, sc_core::sc_time& t) {
41 peq.
notify(std::make_tuple(&trans, phase), t);
42 return tlm::TLM_ACCEPTED;
45 void apb_initiator_b::invalidate_direct_mem_ptr(sc_dt::uint64 start_range, sc_dt::uint64 end_range) {}
48 SCCTRACE(SCMOD) <<
"got transport req for id=" << &trans;
51 socket_fw->b_transport(trans, t);
54 SCCTRACE(SCMOD) <<
"start transport req for id=" << &trans;
55 trans.free_all_extensions();
56 tlm::tlm_phase phase{tlm::BEGIN_REQ};
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();
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());
73 phase = tlm::END_RESP;
75 socket_fw->nb_transport_fw(trans, phase, t);
76 SCCTRACE(SCMOD) <<
"finished non-blocking protocol";
77 any_tx_finished.notify(SC_ZERO_TIME);
79 SCCTRACE(SCMOD) <<
"finished transport req for id=" << &trans;
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.
void notify(const TYPE &entry, const sc_core::sc_time &t)
non-blocking push.