114 auto axi_id = get_axi_id(trans);
115 if(flavor == flavor_e::AXI) {
118 sc_assert(
ace &&
"No valid extension found in transaction");
122 trans.set_extension(
axi4);
126 sc_assert(trans.get_extension<
axi::ace_extension>() &&
"No ACE extension found in transaction");
128 SCCTRACE(SCMOD) <<
"got transport req for " << trans;
131 socket_fw->b_transport(trans, t);
133 auto it = tx_state_by_tx.find(&trans);
134 if(it == tx_state_by_tx.end()) {
136 std::tie(it, success) = tx_state_by_tx.insert(std::make_pair(&trans,
new tx_state()));
142 auto& txs = it->second;
143 auto timing_e = trans.set_auto_extension<atp::timing_params>(
nullptr);
146 if(!id_mtx[axi_id]) {
149 id_mtx[axi_id]->wait();
151 txs->active_tx = &trans;
152 auto burst_length = 0;
154 burst_length = is_dataless(e) ? 1 : e->get_length() + 1;
156 burst_length = e->get_length() + 1;
158 burst_length = e->get_length() + 1;
160 SCCTRACE(SCMOD) <<
"start transport " << trans;
161 tlm::tlm_phase next_phase{tlm::UNINITIALIZED_PHASE};
162 if(!trans.is_read()) {
163 if(!data_interleaving.get_value()) {
164 sem_lock lck(wr_chnl);
168 for(
unsigned i = 1; i < (timing_e ? timing_e->awtv :
awtv.get_value()); ++i) {
169 wait(clk_i.posedge_event());
171 SCCTRACE(SCMOD) <<
"starting " << burst_length <<
" write beats of " << trans;
172 for(
unsigned i = 0; i < burst_length - 1; ++i) {
173 if(protocol_cb[axi::fsm::BegPartReqE])
174 protocol_cb[axi::fsm::BegPartReqE](trans,
false);
175 auto res = send(trans, txs, axi::BEGIN_PARTIAL_REQ);
176 if(axi::END_PARTIAL_REQ != res)
177 SCCFATAL(SCMOD) <<
"target responded with " << res <<
" for the " << i <<
"th beat of " << burst_length
178 <<
" beats in transaction " << trans;
179 for(
unsigned i = 0; i < (timing_e ? timing_e->wbv :
wbv.get_value()); ++i)
180 wait(clk_i.posedge_event());
181 if(protocol_cb[axi::fsm::EndPartReqE])
182 protocol_cb[axi::fsm::EndPartReqE](trans,
false);
184 auto res = send(trans, txs, tlm::BEGIN_REQ);
185 if(res == axi::BEGIN_PARTIAL_RESP || res == tlm::BEGIN_RESP)
187 else if(res != tlm::END_REQ)
188 SCCERR(SCMOD) <<
"target did not repsond with END_REQ to a BEGIN_REQ";
189 wait(clk_i.posedge_event());
191 SCCTRACE(SCMOD) <<
"starting " << burst_length <<
" write beats of " << trans;
192 for(
unsigned i = 0; i < burst_length - 1; ++i) {
193 sem_lock lck(wr_chnl);
198 for(
unsigned i = 1; i < (timing_e ? timing_e->awtv :
awtv.get_value()); ++i)
199 wait(clk_i.posedge_event());
201 auto res = send(trans, txs, axi::BEGIN_PARTIAL_REQ);
202 sc_assert(axi::END_PARTIAL_REQ == res);
203 for(
unsigned i = 1; i < (timing_e ? timing_e->wbv :
wbv.get_value()); ++i)
204 wait(clk_i.posedge_event());
206 sem_lock lck(wr_chnl);
207 if(burst_length == 1) {
211 if(protocol_cb[axi::fsm::BegReqE])
212 protocol_cb[axi::fsm::BegReqE](trans,
false);
213 auto res = send(trans, txs, tlm::BEGIN_REQ);
214 if(res == axi::BEGIN_PARTIAL_RESP || res == tlm::BEGIN_RESP)
216 else if(res != tlm::END_REQ)
217 SCCERR(SCMOD) <<
"target did not repsond with END_REQ to a BEGIN_REQ";
218 wait(clk_i.posedge_event());
219 if(protocol_cb[axi::fsm::EndReqE])
220 protocol_cb[axi::fsm::EndReqE](trans,
false);
223 sem_lock lck(rd_chnl);
227 for(
unsigned i = 1; i < (timing_e ? timing_e->artv :
artv.get_value()); ++i)
228 wait(clk_i.posedge_event());
229 SCCTRACE(SCMOD) <<
"starting address phase of " << trans;
230 if(protocol_cb[axi::fsm::BegPartReqE])
231 protocol_cb[axi::fsm::BegPartReqE](trans,
false);
232 auto res = send(trans, txs, tlm::BEGIN_REQ);
233 if(res == axi::BEGIN_PARTIAL_RESP || res == tlm::BEGIN_RESP)
235 else if(res != tlm::END_REQ)
236 SCCERR(SCMOD) <<
"target did not repsond with END_REQ to a BEGIN_REQ";
237 wait(clk_i.posedge_event());
238 if(protocol_cb[axi::fsm::EndReqE])
239 protocol_cb[axi::fsm::EndReqE](trans,
false);
241 auto finished =
false;
242 if(!trans.is_read() || !trans.get_data_length())
244 const auto exp_burst_length = burst_length;
247 auto entry = next_phase == tlm::UNINITIALIZED_PHASE ? txs->peq.get() : std::make_tuple(&trans, next_phase);
248 next_phase = tlm::UNINITIALIZED_PHASE;
250 if(std::get<0>(entry) == &trans && std::get<1>(entry) == tlm::BEGIN_RESP) {
251 if(protocol_cb[axi::fsm::BegRespE])
252 protocol_cb[axi::fsm::BegRespE](trans,
false);
253 SCCTRACE(SCMOD) <<
"received last beat of " << trans;
254 auto delay_in_cycles = timing_e ? (trans.is_read() ? timing_e->rbr : timing_e->br) :
br.get_value();
255 for(
unsigned i = 0; i < delay_in_cycles; ++i)
256 wait(clk_i.posedge_event());
258 tlm::tlm_phase phase = tlm::END_RESP;
259 sc_time delay = clk_if ? ::scc::time_to_next_posedge(clk_if) - 1_ps : SC_ZERO_TIME;
260 socket_fw->nb_transport_fw(trans, phase, delay);
262 SCCWARN(SCMOD) <<
"got wrong number of burst beats, expected " << exp_burst_length <<
", got "
263 << exp_burst_length - burst_length;
264 wait(clk_i.posedge_event());
265 if(protocol_cb[axi::fsm::EndRespE])
266 protocol_cb[axi::fsm::EndRespE](trans,
false);
268 }
else if(std::get<0>(entry) == &trans && std::get<1>(entry) == axi::BEGIN_PARTIAL_RESP) {
269 SCCTRACE(SCMOD) <<
"received beat = " << burst_length <<
" with trans " << trans;
270 auto delay_in_cycles = timing_e ? timing_e->rbr :
rbr.get_value();
271 for(
unsigned i = 0; i < delay_in_cycles; ++i)
272 wait(clk_i.posedge_event());
274 if(protocol_cb[axi::fsm::BegPartRespE])
275 protocol_cb[axi::fsm::BegPartRespE](trans,
false);
276 tlm::tlm_phase phase = axi::END_PARTIAL_RESP;
277 sc_time delay = clk_if ? ::scc::time_to_next_posedge(clk_if) - 1_ps : SC_ZERO_TIME;
278 auto res = socket_fw->nb_transport_fw(trans, phase, delay);
279 if(res == tlm::TLM_UPDATED) {
283 if(protocol_cb[axi::fsm::EndPartRespE])
284 protocol_cb[axi::fsm::EndPartRespE](trans,
false);
287 if(flavor == flavor_e::ACE) {
288 if(trans.is_read() &&
rla.get_value() != std::numeric_limits<unsigned>::max()) {
289 for(
unsigned i = 0; i <
rla.get_value(); ++i)
290 wait(clk_i.posedge_event());
291 tlm::tlm_phase phase = axi::ACK;
292 sc_time delay = SC_ZERO_TIME;
293 socket_fw->nb_transport_fw(trans, phase, delay);
294 wait(clk_i.posedge_event());
296 }
else if(trans.is_write() &&
ba.get_value() != std::numeric_limits<unsigned>::max()) {
297 for(
unsigned i = 0; i <
ba.get_value(); ++i)
298 wait(clk_i.posedge_event());
299 tlm::tlm_phase phase = axi::ACK;
300 sc_time delay = SC_ZERO_TIME;
301 socket_fw->nb_transport_fw(trans, phase, delay);
302 wait(clk_i.posedge_event());
309 SCCTRACE(SCMOD) <<
"finished non-blocking protocol";
311 id_mtx[axi_id]->post();
313 txs->active_tx =
nullptr;
314 any_tx_finished.notify(SC_ZERO_TIME);
316 SCCTRACE(SCMOD) <<
"finished transport req for " << trans;
363 auto it = snp_state_by_id.find(&trans);
364 sc_assert(it != snp_state_by_id.end());
365 auto& txs = it->second;
366 auto data_len = trans.get_data_length();
367 auto burst_length = data_len / transfer_width_in_bytes;
370 tlm::tlm_phase next_phase{tlm::UNINITIALIZED_PHASE};
371 auto delay_in_cycles =
wbv.get_value();
372 sem_lock lck(sresp_chnl);
377 SCCTRACE(SCMOD) <<
"starting snoop resp with " << burst_length <<
" beats of " << trans;
378 for(
unsigned i = 0; i < burst_length - 1; ++i) {
379 if(protocol_cb[axi::fsm::BegPartRespE])
380 protocol_cb[axi::fsm::BegPartRespE](trans,
true);
381 auto res = send(trans, txs, axi::BEGIN_PARTIAL_RESP);
382 sc_assert(axi::END_PARTIAL_RESP == res);
383 wait(clk_i.posedge_event());
384 if(protocol_cb[axi::fsm::EndPartRespE])
385 protocol_cb[axi::fsm::EndPartRespE](trans,
true);
386 for(
unsigned i = 1; i < delay_in_cycles; ++i)
387 wait(clk_i.posedge_event());
389 if(protocol_cb[axi::fsm::BegRespE])
390 protocol_cb[axi::fsm::BegRespE](trans,
true);
391 auto res = send(trans, txs, tlm::BEGIN_RESP);
392 if(res != tlm::END_RESP)
393 SCCERR(SCMOD) <<
"target did not respond with END_RESP to a BEGIN_RESP";
394 wait(clk_i.posedge_event());
395 if(protocol_cb[axi::fsm::EndRespE])
396 protocol_cb[axi::fsm::EndRespE](trans,
true);