17 #ifndef _BUS_AXI_PIN_ACE_INITIATOR_H_
18 #define _BUS_AXI_PIN_ACE_INITIATOR_H_
20 #include <axi/axi_tlm.h>
21 #include <axi/fsm/base.h>
22 #include <axi/fsm/protocol_fsm.h>
23 #include <axi/signal_if.h>
25 #include <tlm/scc/tlm_mm.h>
26 #include <tlm_utils/peq_with_cb_and_phase.h>
33 using namespace axi::fsm;
35 template <
typename CFG>
37 public aw_ace<CFG, typename CFG::master_types>,
38 public wdata_ace<CFG, typename CFG::master_types>,
39 public b_ace<CFG, typename CFG::master_types>,
40 public ar_ace<CFG, typename CFG::master_types>,
41 public rresp_ace<CFG, typename CFG::master_types>,
43 public ac_ace<CFG, typename CFG::master_types>,
44 public cr_ace<CFG, typename CFG::master_types>,
45 public cd_ace<CFG, typename CFG::master_types>,
51 enum { CACHELINE_SZ = 64 };
53 using payload_type = axi::axi_protocol_types::tlm_payload_type;
54 using phase_type = axi::axi_protocol_types::tlm_phase_type;
56 sc_core::sc_in<bool> clk_i{
"clk_i"};
61 : sc_core::sc_module(nm)
63 ,
base(CFG::BUSWIDTH,
true) {
64 instance_name = name();
67 sensitive << clk_i.pos();
81 void b_transport(payload_type& trans, sc_core::sc_time& t)
override {
82 trans.set_dmi_allowed(
false);
83 trans.set_response_status(tlm::TLM_OK_RESPONSE);
86 tlm::tlm_sync_enum nb_transport_fw(payload_type& trans, phase_type& phase, sc_core::sc_time& t)
override {
88 sc_core::sc_time delay;
89 fw_peq.notify(trans, phase, delay);
90 return tlm::TLM_ACCEPTED;
93 bool get_direct_mem_ptr(payload_type& trans, tlm::tlm_dmi& dmi_data)
override {
94 trans.set_dmi_allowed(
false);
98 unsigned int transport_dbg(payload_type& trans)
override {
return 0; }
100 void end_of_elaboration()
override { clk_if =
dynamic_cast<sc_core::sc_clock*
>(clk_i.get_interface()); }
106 void clk_delay() { clk_delayed.notify(axi::CLK_DELAY); }
131 static typename CFG::data_t get_cache_data_for_beat(
fsm::fsm_handle* fsm_hndl);
132 unsigned int SNOOP = 3;
135 std::array<unsigned, 3> outstanding_cnt{0, 0, 0};
136 std::array<fsm_handle*, 3> active_req{
nullptr,
nullptr,
nullptr};
137 std::array<fsm_handle*, 3> active_resp{
nullptr,
nullptr,
nullptr};
138 std::array<fsm_handle*, 4> active_resp_beat{
nullptr,
nullptr,
nullptr};
139 sc_core::sc_clock* clk_if{
nullptr};
140 sc_core::sc_event clk_delayed, clk_self, r_end_resp_evt, w_end_resp_evt, aw_evt, ar_evt, ac_end_req_evt;
141 void nb_fw(payload_type& trans,
const phase_type& phase) {
142 auto t = sc_core::SC_ZERO_TIME;
145 tlm_utils::peq_with_cb_and_phase<ace_initiator> fw_peq{
this, &ace_initiator::nb_fw};
146 std::unordered_map<unsigned, std::deque<fsm_handle*>> rd_resp_by_id, wr_resp_by_id;
147 sc_core::sc_buffer<uint8_t> wdata_vl;
148 sc_core::sc_event rack_vl;
149 sc_core::sc_event wack_vl;
150 void write_ar(tlm::tlm_generic_payload& trans);
151 void write_aw(tlm::tlm_generic_payload& trans);
152 void write_wdata(tlm::tlm_generic_payload& trans,
unsigned beat,
bool last =
false);
159 sc_dt::sc_uint<CFG::ADDRWIDTH> addr = trans.get_address();
160 this->ar_addr.write(addr);
162 this->ar_prot.write(ext->get_prot());
164 this->ar_id->write(sc_dt::sc_uint<CFG::IDWIDTH>(ext->get_id()));
165 this->ar_len->write(sc_dt::sc_uint<8>(ext->get_length()));
166 this->ar_size->write(sc_dt::sc_uint<3>(ext->get_size()));
167 this->ar_burst->write(sc_dt::sc_uint<2>(
axi::to_int(ext->get_burst())));
168 if(ext->is_exclusive())
169 this->ar_lock->write(
true);
170 this->ar_cache->write(sc_dt::sc_uint<4>(ext->get_cache()));
171 this->ar_prot.write(ext->get_prot());
172 this->ar_qos->write(ext->get_qos());
173 this->ar_region->write(ext->get_region());
174 this->ar_domain->write(sc_dt::sc_uint<2>((uint8_t)ext->get_domain()));
175 this->ar_snoop->write(sc_dt::sc_uint<4>((uint8_t)ext->get_snoop()));
176 this->ar_bar->write(sc_dt::sc_uint<2>((uint8_t)ext->get_barrier()));
177 this->ar_user->write(ext->get_user(axi::common::id_type::CTRL));
182 sc_dt::sc_uint<CFG::ADDRWIDTH> addr = trans.get_address();
183 this->aw_addr.write(addr);
185 this->aw_prot.write(ext->get_prot());
186 if(ext->is_exclusive())
187 this->aw_lock->write(
true);
188 if(this->aw_id.get_interface())
189 this->aw_id->write(sc_dt::sc_uint<CFG::IDWIDTH>(ext->get_id()));
190 this->aw_len->write(sc_dt::sc_uint<8>(ext->get_length()));
191 this->aw_size->write(sc_dt::sc_uint<3>(ext->get_size()));
192 this->aw_burst->write(sc_dt::sc_uint<2>(
axi::to_int(ext->get_burst())));
193 this->aw_cache->write(sc_dt::sc_uint<4>(ext->get_cache()));
194 this->aw_qos->write(sc_dt::sc_uint<4>(ext->get_qos()));
195 this->aw_region->write(sc_dt::sc_uint<4>(ext->get_region()));
196 this->aw_user->write(ext->get_user(axi::common::id_type::CTRL));
197 this->aw_domain->write(sc_dt::sc_uint<2>((uint8_t)ext->get_domain()));
198 this->aw_snoop->write(sc_dt::sc_uint<CFG::AWSNOOPWIDTH>((uint8_t)ext->get_snoop()));
199 this->aw_bar->write(sc_dt::sc_uint<2>((uint8_t)ext->get_barrier()));
200 this->aw_unique->write(ext->get_unique());
206 typename CFG::data_t data{0};
207 sc_dt::sc_uint<CFG::BUSWIDTH / 8> strb{0};
210 auto byte_offset = beat * size;
211 auto offset = (trans.get_address() + byte_offset) & (CFG::BUSWIDTH / 8 - 1);
212 auto beptr = trans.get_byte_enable_length() ? trans.get_byte_enable_ptr() + byte_offset :
nullptr;
213 if(offset && (size + offset) > (CFG::BUSWIDTH / 8)) {
215 auto dptr = trans.get_data_ptr();
217 for(
size_t i = offset; i < size; ++i, ++dptr) {
218 auto bit_offs = i * 8;
219 data(bit_offs + 7, bit_offs) = *dptr;
221 strb[i] = *beptr == 0xff;
227 auto beat_start_idx = byte_offset - offset;
228 auto data_len = trans.get_data_length();
229 auto dptr = trans.get_data_ptr() + beat_start_idx;
231 for(
size_t i = 0; i < size && (beat_start_idx + i) < data_len; ++i, ++dptr) {
232 auto bit_offs = i * 8;
233 data(bit_offs + 7, bit_offs) = *dptr;
235 strb[i] = *beptr == 0xff;
242 auto dptr = trans.get_data_ptr() + byte_offset;
244 for(
size_t i = 0; i < size; ++i, ++dptr) {
245 auto bit_offs = (offset + i) * 8;
246 data(bit_offs + 7, bit_offs) = *dptr;
248 strb[offset + i] = *beptr == 0xff;
251 strb[offset + i] =
true;
254 this->w_data.write(data);
255 this->w_strb.write(strb);
257 this->w_id->write(ext->get_id());
258 if(this->w_user.get_interface())
259 this->w_user->write(ext->get_user(axi::common::id_type::DATA));
267 auto byte_offset = beat_count * size;
268 auto offset = (fsm_hndl->
trans->get_address() + byte_offset) & (CFG::BUSWIDTH / 8 - 1);
269 typename CFG::data_t data{0};
270 if(offset && (size + offset) > (CFG::BUSWIDTH / 8)) {
271 if(beat_count == 0) {
272 auto dptr = fsm_hndl->
trans->get_data_ptr();
273 for(
size_t i = offset; i < size; ++i, ++dptr) {
274 auto bit_offs = i * 8;
275 data(bit_offs + 7, bit_offs) = *dptr;
278 auto beat_start_idx = byte_offset - offset;
279 auto data_len = fsm_hndl->
trans->get_data_length();
280 auto dptr = fsm_hndl->
trans->get_data_ptr() + beat_start_idx;
281 for(
size_t i = offset; i < size && (beat_start_idx + i) < data_len; ++i, ++dptr) {
282 auto bit_offs = i * 8;
283 data(bit_offs + 7, bit_offs) = *dptr;
287 auto dptr = fsm_hndl->
trans->get_data_ptr() + byte_offset;
288 for(
size_t i = 0; i < size; ++i, ++dptr) {
289 auto bit_offs = (offset + i) * 8;
290 data(bit_offs + 7, bit_offs) = *dptr;
297 fsm_hndl->
fsm->cb[RequestPhaseBeg] = [
this, fsm_hndl]() ->
void {
299 SCCTRACE(SCMOD) <<
" for snoop in RequestPhaseBeg ";
302 outstanding_cnt[fsm_hndl->
trans->get_command()]++;
304 auto offset = fsm_hndl->
trans->get_address() % (CFG::BUSWIDTH / 8);
305 if(offset + fsm_hndl->
trans->get_data_length() > CFG::BUSWIDTH / 8) {
306 SCCFATAL(SCMOD) <<
" transaction " << *fsm_hndl->
trans <<
" is not AXI4Lite compliant";
311 fsm_hndl->
fsm->cb[BegPartReqE] = [
this, fsm_hndl]() ->
void {
312 sc_assert(fsm_hndl->
trans->is_write());
314 write_aw(*fsm_hndl->
trans);
315 aw_evt.notify(sc_core::SC_ZERO_TIME);
318 active_req[tlm::TLM_WRITE_COMMAND] = fsm_hndl;
321 fsm_hndl->
fsm->cb[EndPartReqE] = [
this, fsm_hndl]() ->
void {
322 active_req[tlm::TLM_WRITE_COMMAND] =
nullptr;
323 tlm::tlm_phase phase = axi::END_PARTIAL_REQ;
324 sc_core::sc_time t = (clk_if ? clk_if->period() - axi::CLK_DELAY - 1_ps : sc_core::SC_ZERO_TIME);
325 auto ret = tsckt->nb_transport_bw(*fsm_hndl->
trans, phase, t);
328 fsm_hndl->
fsm->cb[BegReqE] = [
this, fsm_hndl]() ->
void {
330 SCCTRACE(SCMOD) <<
" BegReq of setup_cb";
331 sc_core::sc_time t(sc_core::SC_ZERO_TIME);
332 tlm::tlm_phase phase = tlm::BEGIN_REQ;
333 auto ret = tsckt->nb_transport_bw(*fsm_hndl->
trans, phase, t);
335 switch(fsm_hndl->
trans->get_command()) {
336 case tlm::TLM_READ_COMMAND:
337 active_req[tlm::TLM_READ_COMMAND] = fsm_hndl;
338 write_ar(*fsm_hndl->
trans);
339 ar_evt.notify(sc_core::SC_ZERO_TIME);
341 case tlm::TLM_WRITE_COMMAND:
342 SCCTRACE(SCMOD) <<
"in BegReqE for trans " << *fsm_hndl->
trans;
343 active_req[tlm::TLM_WRITE_COMMAND] = fsm_hndl;
345 write_aw(*fsm_hndl->
trans);
346 aw_evt.notify(sc_core::SC_ZERO_TIME);
349 auto ext = fsm_hndl->
trans->get_extension<ace_extension>();
350 if(!axi::is_dataless(ext)) {
357 fsm_hndl->
fsm->cb[EndReqE] = [
this, fsm_hndl]() ->
void {
359 active_req[SNOOP] =
nullptr;
360 ac_end_req_evt.notify();
362 switch(fsm_hndl->
trans->get_command()) {
363 case tlm::TLM_READ_COMMAND:
364 rd_resp_by_id[axi::get_axi_id(*fsm_hndl->
trans)].push_back(fsm_hndl);
365 active_req[tlm::TLM_READ_COMMAND] =
nullptr;
367 case tlm::TLM_WRITE_COMMAND:
368 SCCTRACE(SCMOD) <<
"in EndReq for trans " << *fsm_hndl->
trans;
369 wr_resp_by_id[axi::get_axi_id(*fsm_hndl->
trans)].push_back(fsm_hndl);
370 active_req[tlm::TLM_WRITE_COMMAND] =
nullptr;
373 tlm::tlm_phase phase = tlm::END_REQ;
374 sc_core::sc_time t = (sc_core::SC_ZERO_TIME);
375 SCCTRACE(SCMOD) <<
" in EndReq before set_resp";
376 auto ret = tsckt->nb_transport_bw(*fsm_hndl->
trans, phase, t);
377 fsm_hndl->
trans->set_response_status(tlm::TLM_OK_RESPONSE);
380 fsm_hndl->
fsm->cb[BegPartRespE] = [
this, fsm_hndl]() ->
void {
382 active_resp_beat[SNOOP] = fsm_hndl;
383 cd_vl.notify({1, fsm_hndl});
387 assert(fsm_hndl->
trans->is_read());
388 tlm::tlm_phase phase = axi::BEGIN_PARTIAL_RESP;
389 sc_core::sc_time t(sc_core::SC_ZERO_TIME);
390 auto ret = tsckt->nb_transport_bw(*fsm_hndl->
trans, phase, t);
393 fsm_hndl->
fsm->cb[EndPartRespE] = [
this, fsm_hndl]() ->
void {
394 SCCTRACE(SCMOD) <<
"in EndPartRespE of setup_cb ";
396 tlm::tlm_phase phase = axi::END_PARTIAL_RESP;
397 sc_core::sc_time t(sc_core::SC_ZERO_TIME);
398 auto ret = tsckt->nb_transport_bw(*fsm_hndl->
trans, phase, t);
400 active_resp_beat[SNOOP] =
nullptr;
404 r_end_resp_evt.notify();
407 fsm_hndl->
fsm->cb[BegRespE] = [
this, fsm_hndl]() ->
void {
408 SCCTRACE(SCMOD) <<
"in setup_cb, processing event BegRespE for trans " << *fsm_hndl->
trans;
410 active_resp_beat[SNOOP] = fsm_hndl;
411 cd_vl.notify({3, fsm_hndl});
412 cr_resp_vl.notify({3, fsm_hndl});
416 tlm::tlm_phase phase = tlm::BEGIN_RESP;
417 sc_core::sc_time t(sc_core::SC_ZERO_TIME);
418 auto ret = tsckt->nb_transport_bw(*fsm_hndl->
trans, phase, t);
421 fsm_hndl->
fsm->cb[EndRespE] = [
this, fsm_hndl]() ->
void {
422 SCCTRACE(SCMOD) <<
"in EndResp of setup_cb for trans" << *fsm_hndl->
trans;
424 sc_core::sc_time t(sc_core::SC_ZERO_TIME);
425 tlm::tlm_phase phase = tlm::END_RESP;
426 auto ret = tsckt->nb_transport_bw(*fsm_hndl->
trans, phase, t);
427 active_resp_beat[SNOOP] =
nullptr;
429 fsm_hndl->
finish.notify();
431 if(fsm_hndl->
trans->is_read()) {
432 rd_resp_by_id[axi::get_axi_id(*fsm_hndl->
trans)].pop_front();
433 r_end_resp_evt.notify();
434 }
else if(fsm_hndl->
trans->is_write()) {
435 wr_resp_by_id[axi::get_axi_id(*fsm_hndl->
trans)].pop_front();
436 w_end_resp_evt.notify();
440 fsm_hndl->
fsm->cb[Ack] = [
this, fsm_hndl]() ->
void {
441 SCCTRACE(SCMOD) <<
"in ACK of setup_cb for " << *fsm_hndl->
trans;
442 if(fsm_hndl->
trans->is_read()) {
443 rack_vl.notify(sc_core::SC_ZERO_TIME);
445 if(fsm_hndl->
trans->is_write()) {
446 wack_vl.notify(sc_core::SC_ZERO_TIME);
452 this->r_ack.write(
false);
453 wait(sc_core::SC_ZERO_TIME);
456 this->r_ack.write(
true);
457 wait(clk_i.posedge_event());
458 this->r_ack.write(
false);
463 this->w_ack.write(
false);
464 wait(sc_core::SC_ZERO_TIME);
467 this->w_ack.write(
true);
468 wait(clk_i.posedge_event());
469 this->w_ack.write(
false);
474 this->ar_valid.write(
false);
475 wait(sc_core::SC_ZERO_TIME);
478 this->ar_valid.write(
true);
480 wait(this->ar_ready.posedge_event() | clk_delayed);
481 if(this->ar_ready.read())
482 react(axi::fsm::protocol_time_point_e::EndReqE, active_req[tlm::TLM_READ_COMMAND]);
483 }
while(!this->ar_ready.read());
484 wait(clk_i.posedge_event());
485 this->ar_valid.write(
false);
490 this->r_ready.write(
false);
491 wait(sc_core::SC_ZERO_TIME);
493 wait(this->r_valid.posedge_event() | clk_delayed);
494 if(this->r_valid.event() || (!active_resp[tlm::TLM_READ_COMMAND] && this->r_valid.read())) {
495 wait(sc_core::SC_ZERO_TIME);
496 auto id = CFG::IS_LITE ? 0U : this->r_id->read().to_uint();
497 auto data = this->r_data.read();
498 auto resp = this->r_resp.read();
499 SCCTRACE(SCMOD) <<
" r_t() get r_resp = " << resp;
500 auto& q = rd_resp_by_id[id];
502 auto* fsm_hndl = q.front();
505 auto byte_offset = beat_count * size;
506 auto offset = (fsm_hndl->
trans->get_address() + byte_offset) & (CFG::BUSWIDTH / 8 - 1);
507 if(offset && (size + offset) > (CFG::BUSWIDTH / 8)) {
508 if(beat_count == 0) {
509 auto dptr = fsm_hndl->
trans->get_data_ptr();
511 for(
size_t i = offset; i < size; ++i, ++dptr) {
512 auto bit_offs = i * 8;
513 *dptr = data(bit_offs + 7, bit_offs).to_uint();
516 auto beat_start_idx = beat_count * size - offset;
517 auto data_len = fsm_hndl->
trans->get_data_length();
518 auto dptr = fsm_hndl->
trans->get_data_ptr() + beat_start_idx;
520 for(
size_t i = offset; i < size && (beat_start_idx + i) < data_len; ++i, ++dptr) {
521 auto bit_offs = i * 8;
522 *dptr = data(bit_offs + 7, bit_offs).to_uint();
526 auto dptr = fsm_hndl->
trans->get_data_ptr() + beat_count * size;
528 for(
size_t i = 0; i < size; ++i, ++dptr) {
529 auto bit_offs = (offset + i) * 8;
530 *dptr = data(bit_offs + 7, bit_offs).to_uint();
534 fsm_hndl->
trans->get_extension(e);
539 if(axi::is_dataless(e)) {
540 SCCTRACE(SCMOD) <<
" r_t() for Make/Clean/Barrier Trans" << *fsm_hndl->
trans;
541 react(axi::fsm::protocol_time_point_e::BegRespE, fsm_hndl);
543 auto tp = CFG::IS_LITE || this->r_last->read() ? axi::fsm::protocol_time_point_e::BegRespE
544 : axi::fsm::protocol_time_point_e::BegPartRespE;
547 wait(r_end_resp_evt);
548 this->r_ready->write(
true);
549 wait(clk_i.posedge_event());
550 this->r_ready.write(
false);
556 this->aw_valid.write(
false);
557 wait(sc_core::SC_ZERO_TIME);
560 this->aw_valid.write(
true);
561 SCCTRACE(SCMOD) <<
" aw_t() write aw_valid ";
563 wait(this->aw_ready.posedge_event() | clk_delayed);
564 }
while(!this->aw_ready.read());
565 auto* fsm_hndl = active_req[tlm::TLM_WRITE_COMMAND];
567 react(axi::fsm::protocol_time_point_e::EndReqE, fsm_hndl);
568 wait(clk_i.posedge_event());
569 this->aw_valid.write(
false);
574 this->w_valid.write(
false);
575 wait(sc_core::SC_ZERO_TIME);
578 this->w_last->write(
false);
579 wait(wdata_vl.default_event());
580 auto val = wdata_vl.read();
581 SCCTRACE(SCMOD) <<
"wdata_t() with wdata_vl = " << (uint16_t)val;
582 this->w_valid.write(val & 0x1);
584 this->w_last->write(val & 0x2);
586 wait(this->w_ready.posedge_event() | clk_delayed);
588 if(this->w_ready.read()) {
590 CFG::IS_LITE || (val & 0x2) ? axi::fsm::protocol_time_point_e::EndReqE : axi::fsm::protocol_time_point_e::EndPartReqE;
591 react(evt, active_req[tlm::TLM_WRITE_COMMAND]);
593 }
while(!this->w_ready.read());
594 wait(clk_i.posedge_event());
595 this->w_valid.write(
false);
600 this->b_ready.write(
false);
601 wait(sc_core::SC_ZERO_TIME);
603 wait(this->b_valid.posedge_event() | clk_delayed);
604 if(this->b_valid.event() || (!active_resp[tlm::TLM_WRITE_COMMAND] && this->b_valid.read())) {
605 auto id = !CFG::IS_LITE ? this->b_id->read().to_uint() : 0U;
606 auto resp = this->b_resp.read();
607 auto& q = wr_resp_by_id[id];
609 auto* fsm_hndl = q.front();
611 fsm_hndl->
trans->get_extension(e);
612 e->
set_resp(axi::into<axi::resp_e>(resp));
613 react(axi::fsm::protocol_time_point_e::BegRespE, fsm_hndl);
615 wait(w_end_resp_evt);
616 this->b_ready.write(
true);
617 wait(clk_i.posedge_event());
618 this->b_ready.write(
false);
623 this->ac_ready.write(
false);
624 wait(sc_core::SC_ZERO_TIME);
628 auto arlen = ((CACHELINE_SZ - 1) / CFG::BUSWIDTH / 8);
631 auto data_len = (1 << arsize) * (arlen + 1);
633 wait(this->ac_valid.posedge_event() | clk_delayed);
634 if(this->ac_valid.read()) {
635 SCCTRACE(SCMOD) <<
"ACVALID detected, for address 0x" << std::hex << this->ac_addr.read();
636 SCCTRACE(SCMOD) <<
"in ac_t(), create snoop trans with data_len= " << data_len;
638 gp->set_address(this->ac_addr.read());
639 gp->set_command(tlm::TLM_READ_COMMAND);
640 gp->set_streaming_width(data_len);
642 gp->get_extension(ext);
644 if(data_len == (CFG::BUSWIDTH / 8))
648 ext->
set_snoop(axi::into<axi::snoop_e>(this->ac_snoop->read()));
649 ext->
set_prot(this->ac_prot->read());
654 active_req[SNOOP] = find_or_create(gp,
true);
655 active_req[SNOOP]->is_snoop =
true;
656 react(axi::fsm::protocol_time_point_e::RequestPhaseBeg, active_req[SNOOP]);
658 wait(ac_end_req_evt);
659 this->ac_ready.write(
true);
660 wait(clk_i.posedge_event());
661 this->ac_ready.write(
false);
666 this->cd_valid.write(
false);
667 wait(sc_core::SC_ZERO_TIME);
672 std::tie(val, fsm_hndl) = cd_vl.get();
673 SCCTRACE(SCMOD) << __FUNCTION__ <<
" val = " << (uint16_t)val <<
" beat_count = " << fsm_hndl->
beat_count;
674 SCCTRACE(SCMOD) << __FUNCTION__ <<
" got snoop beat of trans " << *fsm_hndl->
trans;
677 this->cd_data.write(get_cache_data_for_beat(fsm_hndl));
678 this->cd_valid.write(val & 0x1);
679 SCCTRACE(SCMOD) << __FUNCTION__ <<
"() write cd_valid high ";
680 this->cd_last->write(val & 0x2);
682 wait(this->cd_ready.posedge_event() | clk_delayed);
683 if(this->cd_ready.read()) {
685 CFG::IS_LITE || (val & 0x2) ? axi::fsm::protocol_time_point_e::EndRespE : axi::fsm::protocol_time_point_e::EndPartRespE;
689 SCCTRACE(SCMOD) << __FUNCTION__ <<
"() receives cd_ready high, schedule evt " << evt2str(evt);
690 react(evt, active_resp_beat[SNOOP]);
693 }
while(!this->cd_ready.read());
694 SCCTRACE(SCMOD) << __FUNCTION__ <<
" finished snoop beat of trans [" << fsm_hndl->
trans <<
"]";
695 wait(clk_i.posedge_event());
696 this->cd_valid.write(
false);
698 this->cd_last->write(
false);
702 this->cr_valid.write(
false);
703 wait(sc_core::SC_ZERO_TIME);
708 std::tie(val, fsm_hndl) = cr_resp_vl.get();
709 SCCTRACE(SCMOD) << __FUNCTION__ <<
" (), generate snoop response in cr channel, val = " << (uint16_t)val
710 <<
" total beat_num = " << fsm_hndl->
beat_count;
714 this->cr_valid.write(
true);
716 wait(this->cr_ready.posedge_event() | clk_delayed);
717 if(this->cr_ready.read()) {
718 auto evt = axi::fsm::protocol_time_point_e::EndRespE;
719 SCCTRACE(SCMOD) << __FUNCTION__ <<
"(), schedule EndRespE ";
720 react(evt, active_resp_beat[SNOOP]);
722 }
while(!this->cr_ready.read());
723 SCCTRACE(SCMOD) <<
"finished snoop response ";
724 wait(clk_i.posedge_event());
725 this->cr_valid.write(
false);
payload_type * allocate()
get a plain tlm_payload_type without extensions
static tlm_mm & get()
accessor function of the singleton
TLM2.0 components modeling AHB.
constexpr ULT to_int(E t)
unsigned get_burst_size(const request &r)
tlm::tlm_fw_transport_if< TYPES > ace_fw_transport_if
alias declaration for the ACE forward interface
CONSTEXPR unsigned ilog2(uint32_t val)
snoop address(AC) channel signals
void set_cresp(uint8_t)
set the coherent response status
uint8_t get_cresp() const
get the coherent response status
void set_snoop(snoop_e)
set the AxSNOOP value
void add_to_response_array(response &)
add a read response to the response array
snoop data(cd) channel signals
snoop response(cr) channel signals
base class of all AXITLM based adapters and interfaces.
tlm::tlm_sync_enum nb_fw(payload_type &trans, phase_type const &phase, sc_core::sc_time &t)
triggers the FSM based on TLM phases in the forward path. Should be called from np_transport_fw of th...
tlm::scc::tlm_gp_shared_ptr trans
pointer to the associated AXITLM payload
sc_core::sc_event finish
event indicating the end of the transaction
size_t beat_count
beat count of this transaction
AxiProtocolFsm *const fsm
pointer to the FSM
bool is_snoop
indicator if this is a snoop access
void set_length(uint8_t)
set the AxLEN value of the transaction, the value denotes the burst length - 1
void set_burst(burst_e)
set the AxBURST value,
void set_size(uint8_t)
get the AxSIZE value of the transaction, the length is 2^size. It needs to be less than 10 (512 bit w...
void set_prot(uint8_t)
set the AxPROT value as POD, only values from 0...7 are allowed
uint8_t get_size() const
set the AxSIZE value of the transaction
void set_resp(resp_e)
set the response status as POD