17 #include "ahb_initiator.h"
18 #include <atp/timing_params.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 ahb_initiator_b::ahb_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)
36 , coherent(coherent) {
44 ahb_initiator_b::~ahb_initiator_b() {
45 for(
auto& e : tx_state_by_id)
49 tlm::tlm_sync_enum ahb_initiator_b::nb_transport_bw(payload_type& trans, phase_type& phase, sc_core::sc_time& t) {
51 auto it = tx_state_by_id.find(&trans);
52 sc_assert(it != tx_state_by_id.end());
53 it->second->peq.notify(std::make_tuple(&trans, phase), t);
54 return tlm::TLM_ACCEPTED;
57 void ahb_initiator_b::invalidate_direct_mem_ptr(sc_dt::uint64 start_range, sc_dt::uint64 end_range) {}
60 sc_core::sc_time delay;
61 SCCTRACE(SCMOD) <<
"Send REQ";
62 tlm::tlm_sync_enum ret = socket_fw->nb_transport_fw(trans, phase, delay);
63 if(ret == tlm::TLM_UPDATED) {
67 auto entry = txs->peq.
get();
68 sc_assert(std::get<0>(entry) == &trans);
69 return std::get<1>(entry);
74 SCCTRACE(SCMOD) <<
"got transport req for id=" << &trans;
77 socket_fw->b_transport(trans, t);
79 auto it = tx_state_by_id.find(&trans);
80 if(it == tx_state_by_id.end()) {
82 std::tie(it, success) = tx_state_by_id.insert(std::make_pair(&trans,
new tx_state()));
84 auto& txs = it->second;
85 auto timing_e = trans.set_extension<atp::timing_params>(
nullptr);
87 txs->active_tx = &trans;
88 SCCTRACE(SCMOD) <<
"start transport req for id=" << &trans;
92 auto delay_in_cycles = trans.is_read() ? (timing_e ? timing_e->artv :
artv.value) : (timing_e ? timing_e->awtv :
awtv.value);
95 for(
unsigned i = 0; i < delay_in_cycles; ++i)
96 wait(clk_i.posedge_event());
97 auto burst_length = 0U;
98 switch(ext->get_burst()) {
99 case ahb::burst_e::SINGLE:
102 case ahb::burst_e::INCR:
105 case ahb::burst_e::WRAP4:
106 case ahb::burst_e::INCR4:
109 case ahb::burst_e::WRAP8:
110 case ahb::burst_e::INCR8:
113 case ahb::burst_e::WRAP16:
114 case ahb::burst_e::INCR16:
118 tlm::tlm_phase next_phase{tlm::UNINITIALIZED_PHASE};
120 SCCTRACE(SCMOD) <<
"starting read address phase of tx with id=" << &trans;
121 auto res = send(trans, txs, tlm::BEGIN_REQ);
122 if(res == tlm::BEGIN_RESP)
124 else if(res != tlm::END_REQ)
125 SCCERR(SCMOD) <<
"target did not repsond with END_REQ to a BEGIN_REQ";
126 wait(clk_i.posedge_event());
127 auto finished =
false;
128 const auto exp_burst_length = burst_length;
133 auto entry = next_phase == tlm::UNINITIALIZED_PHASE ? txs->peq.
get() : std::make_tuple(&trans, next_phase);
134 next_phase = tlm::UNINITIALIZED_PHASE;
136 if(std::get<0>(entry) == &trans && std::get<1>(entry) == tlm::BEGIN_RESP) {
137 SCCTRACE(SCMOD) <<
"received last beat of tx with id=" << &trans;
138 auto delay_in_cycles = timing_e ? (trans.is_read() ? timing_e->rbr : timing_e->br) :
br.value;
139 for(
unsigned i = 0; i < delay_in_cycles; ++i)
140 wait(clk_i.posedge_event());
141 trans.set_response_status(tlm::TLM_OK_RESPONSE);
143 tlm::tlm_phase phase = tlm::END_RESP;
144 sc_time delay = clk_if ? clk_if->period() - 1_ps : SC_ZERO_TIME;
145 socket_fw->nb_transport_fw(trans, phase, delay);
147 SCCWARN(SCMOD) <<
"got wrong number of burst beats, expected " << exp_burst_length <<
", got "
148 << exp_burst_length - burst_length;
149 wait(clk_i.posedge_event());
154 SCCTRACE(SCMOD) <<
"finished non-blocking protocol";
155 txs->active_tx =
nullptr;
156 any_tx_finished.notify(SC_ZERO_TIME);
158 SCCTRACE(SCMOD) <<
"finished transport req for id=" << &trans;
sc_core::sc_attribute< unsigned > artv
Read address valid to next read address valid.
sc_core::sc_attribute< unsigned > br
Write response valid to ready.
sc_core::sc_attribute< unsigned > awtv
Write address valid to next write address valid.
void transport(payload_type &trans, bool blocking)
The forward transport function. It behaves blocking and is re-entrant.
int post() override
unlock (give) the semaphore
int wait() override
lock (take) the semaphore, block if not available
protocol engine implementations
TLM2.0 components modeling AHB.