scc 2025.09
SystemC components library
axi4_initiator.h
1/*******************************************************************************
2 * Copyright 2021-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#ifndef _BUS_AXI_PIN_AXI4_INITIATOR_H_
18#define _BUS_AXI_PIN_AXI4_INITIATOR_H_
19
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>
24#include <cci_configuration>
25#include <scc/fifo_w_cb.h>
26#include <systemc>
27#include <tlm_utils/peq_with_cb_and_phase.h>
28
30namespace axi {
32namespace pin {
33
34using namespace axi::fsm;
35
36template <typename CFG>
37struct axi4_initiator : public sc_core::sc_module,
38 public aw_axi<CFG, typename CFG::master_types>,
39 public wdata_axi<CFG, typename CFG::master_types>,
40 public b_axi<CFG, typename CFG::master_types>,
41 public ar_axi<CFG, typename CFG::master_types>,
42 public rresp_axi<CFG, typename CFG::master_types>,
43 protected axi::fsm::base,
44 public axi::axi_fw_transport_if<axi::axi_protocol_types> {
45 SC_HAS_PROCESS(axi4_initiator);
46
47 using payload_type = axi::axi_protocol_types::tlm_payload_type;
48 using phase_type = axi::axi_protocol_types::tlm_phase_type;
49
50 sc_core::sc_in<bool> clk_i{"clk_i"};
51
53
54 cci::cci_param<bool> pipelined_wrreq{"pipelined_wrreq", false};
55
56 cci::cci_param<bool> mask_axi_id{"mask_axi_id", false};
57
58 axi4_initiator(sc_core::sc_module_name const& nm, bool pipelined_wrreq = false)
59 : sc_core::sc_module(nm)
60 , base(CFG::BUSWIDTH)
61 , pipelined_wrreq("pipelined_wrreq", pipelined_wrreq) {
62 instance_name = name();
63 tsckt(*this);
64 SC_METHOD(clk_delay);
65 sensitive << clk_i.pos();
66 SC_THREAD(ar_t);
67 SC_THREAD(r_t);
68 SC_THREAD(aw_t);
69 SC_THREAD(wdata_t);
70 SC_THREAD(b_t);
71 }
72
73private:
74 void b_transport(payload_type& trans, sc_core::sc_time& t) override {
75 trans.set_dmi_allowed(false);
76 trans.set_response_status(tlm::TLM_OK_RESPONSE);
77 }
78
79 tlm::tlm_sync_enum nb_transport_fw(payload_type& trans, phase_type& phase, sc_core::sc_time& t) override {
80 assert(trans.get_extension<axi::axi4_extension>() && "missing AXI4 extension");
81 sc_core::sc_time delay; // FIXME: calculate delay correctly
82 fw_peq.notify(trans, phase, delay);
83 return tlm::TLM_ACCEPTED;
84 }
85
86 bool get_direct_mem_ptr(payload_type& trans, tlm::tlm_dmi& dmi_data) override {
87 trans.set_dmi_allowed(false);
88 return false;
89 }
90
91 unsigned int transport_dbg(payload_type& trans) override { return 0; }
92
93 void end_of_elaboration() override { clk_if = dynamic_cast<sc_core::sc_clock*>(clk_i.get_interface()); }
94
95 fsm_handle* create_fsm_handle() { return new fsm_handle(); }
96
97 void setup_callbacks(fsm_handle* fsm_hndl);
98
99 void clk_delay() { clk_delayed.notify(axi::CLK_DELAY); }
100
101 void ar_t();
102 void r_t();
103 void aw_t();
104 void wdata_t();
105 void b_t();
106 std::array<unsigned, 3> outstanding_cnt{0, 0, 0};
107 sc_core::sc_clock* clk_if{nullptr};
108 sc_core::sc_event clk_delayed, clk_self, r_end_resp_evt, w_end_resp_evt;
109 void nb_fw(payload_type& trans, const phase_type& phase) {
110 auto t = sc_core::SC_ZERO_TIME;
111 base::nb_fw(trans, phase, t);
112 }
113 tlm_utils::peq_with_cb_and_phase<axi4_initiator> fw_peq{this, &axi4_initiator::nb_fw};
114 std::unordered_map<unsigned, std::deque<fsm_handle*>> rd_resp_by_id, wr_resp_by_id;
115 struct fifo_entry {
116 tlm::tlm_generic_payload* gp = nullptr;
117 bool last = false;
118 bool needs_end_req = false;
119 size_t beat_num = 0;
120 fifo_entry(tlm::tlm_generic_payload* gp, bool last, bool needs_end_req, size_t beat_num)
121 : gp(gp)
122 , last(last)
123 , needs_end_req(needs_end_req)
124 , beat_num(beat_num) {
125 if(gp->has_mm())
126 gp->acquire();
127 }
128 fifo_entry(tlm::tlm_generic_payload* gp, bool needs_end_req)
129 : gp(gp)
130 , needs_end_req(needs_end_req) {
131 if(gp->has_mm())
132 gp->acquire();
133 }
134 fifo_entry(fifo_entry const& o)
135 : gp(o.gp)
136 , last(o.last)
137 , needs_end_req(o.needs_end_req)
138 , beat_num(o.beat_num) {
139 if(gp && gp->has_mm())
140 gp->acquire();
141 }
142 fifo_entry& operator=(const fifo_entry& o) {
143 gp = o.gp;
144 last = o.last;
145 needs_end_req = o.needs_end_req;
146 beat_num = o.beat_num;
147 return *this;
148 }
149 ~fifo_entry() {
150 if(gp && gp->has_mm())
151 gp->release();
152 }
153 };
154 scc::fifo_w_cb<fifo_entry> ar_fifo{"ar_fifo"};
155 scc::fifo_w_cb<fifo_entry> aw_fifo{"aw_fifo"};
156 scc::fifo_w_cb<fifo_entry> wdata_fifo{"wdata_fifo"};
157 void write_ar(tlm::tlm_generic_payload& trans);
158 void write_aw(tlm::tlm_generic_payload& trans);
159 void write_wdata(tlm::tlm_generic_payload& trans, unsigned beat);
160};
161
162template <typename CFG> using axi5_initiator = axi4_initiator<CFG>;
163
164} // namespace pin
165} // namespace axi
166
167template <typename CFG> inline void axi::pin::axi4_initiator<CFG>::write_ar(tlm::tlm_generic_payload& trans) {
168 sc_dt::sc_uint<CFG::ADDRWIDTH> addr = trans.get_address();
169 this->ar_addr.write(addr);
170 if(auto ext = trans.get_extension<axi::axi4_extension>()) {
171 this->ar_prot.write(ext->get_prot());
172 if(!CFG::IS_LITE) {
173 auto id = ext->get_id();
174 if(!mask_axi_id.get_value() && id >= (1 << CFG::IDWIDTH))
175 SCCERR(SCMOD) << "ARID value larger that signal arid with width=" << CFG::IDWIDTH << " can carry";
176 this->ar_id->write(sc_dt::sc_uint<CFG::IDWIDTH>(id));
177 this->ar_len->write(sc_dt::sc_uint<8>(ext->get_length()));
178 this->ar_size->write(sc_dt::sc_uint<3>(ext->get_size()));
179 this->ar_burst->write(sc_dt::sc_uint<2>(axi::to_int(ext->get_burst())));
180 this->ar_lock->write(ext->is_exclusive());
181 this->ar_cache->write(sc_dt::sc_uint<4>(ext->get_cache()));
182 this->ar_qos->write(ext->get_qos());
183 if(this->ar_user.get_interface())
184 this->ar_user->write(ext->get_user(axi::common::id_type::CTRL));
185 }
186 }
187}
188
189template <typename CFG> inline void axi::pin::axi4_initiator<CFG>::write_aw(tlm::tlm_generic_payload& trans) {
190 sc_dt::sc_uint<CFG::ADDRWIDTH> addr = trans.get_address();
191 this->aw_addr.write(addr);
192 if(auto ext = trans.get_extension<axi::axi4_extension>()) {
193 this->aw_prot.write(ext->get_prot());
194 if(!CFG::IS_LITE) {
195 auto id = ext->get_id();
196 if(!mask_axi_id.get_value() && id >= (1 << CFG::IDWIDTH))
197 SCCERR(SCMOD) << "AWID value larger than signal awid with width=" << CFG::IDWIDTH << " can carry";
198 this->aw_id->write(sc_dt::sc_uint<CFG::IDWIDTH>(id));
199 this->aw_len->write(sc_dt::sc_uint<8>(ext->get_length()));
200 this->aw_size->write(sc_dt::sc_uint<3>(ext->get_size()));
201 this->aw_burst->write(sc_dt::sc_uint<2>(axi::to_int(ext->get_burst())));
202 this->aw_cache->write(sc_dt::sc_uint<4>(ext->get_cache()));
203 this->aw_qos->write(ext->get_qos());
204 this->aw_lock->write(ext->is_exclusive());
205 this->aw_atop->write(ext->get_atop());
206 if(this->aw_user.get_interface())
207 this->aw_user->write(ext->get_user(axi::common::id_type::CTRL));
208 }
209 }
210}
211
212// FIXME: strb not yet correct
213template <typename CFG> inline void axi::pin::axi4_initiator<CFG>::write_wdata(tlm::tlm_generic_payload& trans, unsigned beat) {
214 typename CFG::data_t data{0};
215 typename CFG::strb_t strb{0};
216 auto ext = trans.get_extension<axi::axi4_extension>();
217 auto size = 1u << ext->get_size();
218 auto byte_offset = beat * size;
219 auto offset = (trans.get_address() + byte_offset) & (CFG::BUSWIDTH / 8 - 1);
220 auto beptr = trans.get_byte_enable_length() ? trans.get_byte_enable_ptr() + byte_offset : nullptr;
221 if(offset && (size + offset) > (CFG::BUSWIDTH / 8)) { // un-aligned multi-beat access
222 if(beat == 0) {
223 auto dptr = trans.get_data_ptr();
224 if(dptr)
225 for(size_t i = offset; i < size; ++i, ++dptr) {
226 auto bit_offs = i * 8;
227 data(bit_offs + 7, bit_offs) = *dptr;
228 if(beptr) {
229 strb[i] = *beptr == 0xff;
230 ++beptr;
231 } else
232 strb[i] = true;
233 }
234 } else {
235 auto beat_start_idx = byte_offset - offset;
236 auto data_len = trans.get_data_length();
237 auto dptr = trans.get_data_ptr() + beat_start_idx;
238 if(dptr)
239 for(size_t i = 0; i < size && (beat_start_idx + i) < data_len; ++i, ++dptr) {
240 auto bit_offs = i * 8;
241 data(bit_offs + 7, bit_offs) = *dptr;
242 if(beptr) {
243 strb[i] = *beptr == 0xff;
244 ++beptr;
245 } else
246 strb[i] = true;
247 }
248 }
249 } else { // aligned or single beat access
250 auto dptr = trans.get_data_ptr() + byte_offset;
251 if(dptr)
252 for(size_t i = 0; i < size; ++i, ++dptr) {
253 auto bit_offs = (offset + i) * 8;
254 data(bit_offs + 7, bit_offs) = *dptr;
255 if(beptr) {
256 strb[offset + i] = *beptr == 0xff;
257 ++beptr;
258 } else
259 strb[offset + i] = true;
260 }
261 }
262 this->w_data.write(data);
263 this->w_strb.write(strb);
264 if(!CFG::IS_LITE) {
265 this->w_id->write(ext->get_id());
266 if(this->w_user.get_interface())
267 this->w_user->write(ext->get_user(axi::common::id_type::DATA));
268 }
269}
270
271template <typename CFG> inline void axi::pin::axi4_initiator<CFG>::setup_callbacks(fsm_handle* fsm_hndl) {
272 fsm_hndl->fsm->cb[RequestPhaseBeg] = [this, fsm_hndl]() -> void {
273 fsm_hndl->beat_count = 0;
274 outstanding_cnt[fsm_hndl->trans->get_command()]++;
275 if(CFG::IS_LITE) {
276 auto offset = fsm_hndl->trans->get_address() % (CFG::BUSWIDTH / 8);
277 if(offset + fsm_hndl->trans->get_data_length() > CFG::BUSWIDTH / 8) {
278 SCCFATAL(SCMOD) << " transaction " << *fsm_hndl->trans << " is not AXI4Lite compliant";
279 }
280 }
281 };
282 fsm_hndl->fsm->cb[BegPartReqE] = [this, fsm_hndl]() -> void {
283 sc_assert(fsm_hndl->trans->is_write());
284 if(fsm_hndl->beat_count == 0) {
285 aw_fifo.push_back({fsm_hndl->trans.get(), false});
286 }
287 wdata_fifo.push_back({fsm_hndl->trans.get(), false, wdata_fifo.num_avail() > 0, fsm_hndl->beat_count});
288 if(pipelined_wrreq && !wdata_fifo.num_avail())
289 schedule(EndPartReqE, fsm_hndl->trans, sc_core::SC_ZERO_TIME);
290 };
291 fsm_hndl->fsm->cb[EndPartReqE] = [this, fsm_hndl]() -> void {
292 tlm::tlm_phase phase = axi::END_PARTIAL_REQ;
293 sc_core::sc_time t(clk_if ? ::scc::time_to_next_posedge(clk_if) - 1_ps : sc_core::SC_ZERO_TIME);
294 auto ret = tsckt->nb_transport_bw(*fsm_hndl->trans, phase, t);
295 fsm_hndl->beat_count++;
296 };
297 fsm_hndl->fsm->cb[BegReqE] = [this, fsm_hndl]() -> void {
298 switch(fsm_hndl->trans->get_command()) {
299 case tlm::TLM_READ_COMMAND:
300 ar_fifo.push_back({fsm_hndl->trans.get(), false});
301 break;
302 case tlm::TLM_WRITE_COMMAND:
303 if(fsm_hndl->beat_count == 0) {
304 aw_fifo.push_back({fsm_hndl->trans.get(), false});
305 }
306 wdata_fifo.push_back({fsm_hndl->trans.get(), true, wdata_fifo.num_avail() > 0, fsm_hndl->beat_count});
307 if(pipelined_wrreq && !wdata_fifo.num_avail())
308 schedule(EndReqE, fsm_hndl->trans, sc_core::SC_ZERO_TIME);
309 }
310 };
311 fsm_hndl->fsm->cb[EndReqE] = [this, fsm_hndl]() -> void {
312 auto id = axi::get_axi_id(*fsm_hndl->trans);
313 if(mask_axi_id.get_value())
314 id &= (1UL << CFG::IDWIDTH) - 1;
315 switch(fsm_hndl->trans->get_command()) {
316 case tlm::TLM_READ_COMMAND:
317 rd_resp_by_id[id].push_back(fsm_hndl);
318 break;
319 case tlm::TLM_WRITE_COMMAND:
320 wr_resp_by_id[id].push_back(fsm_hndl);
321 fsm_hndl->beat_count++;
322 }
323 tlm::tlm_phase phase = tlm::END_REQ;
324 sc_core::sc_time t(clk_if ? ::scc::time_to_next_posedge(clk_if) - 1_ps : sc_core::SC_ZERO_TIME);
325 auto ret = tsckt->nb_transport_bw(*fsm_hndl->trans, phase, t);
326 fsm_hndl->trans->set_response_status(tlm::TLM_OK_RESPONSE);
327 };
328 fsm_hndl->fsm->cb[BegPartRespE] = [this, fsm_hndl]() -> void {
329 // scheduling the response
330 assert(fsm_hndl->trans->is_read());
331 tlm::tlm_phase phase = axi::BEGIN_PARTIAL_RESP;
332 sc_core::sc_time t(sc_core::SC_ZERO_TIME);
333 auto ret = tsckt->nb_transport_bw(*fsm_hndl->trans, phase, t);
334 };
335 fsm_hndl->fsm->cb[EndPartRespE] = [this, fsm_hndl]() -> void {
336 fsm_hndl->beat_count++;
337 r_end_resp_evt.notify();
338 };
339 fsm_hndl->fsm->cb[BegRespE] = [this, fsm_hndl]() -> void {
340 // scheduling the response
341 tlm::tlm_phase phase = tlm::BEGIN_RESP;
342 sc_core::sc_time t(sc_core::SC_ZERO_TIME);
343 auto ret = tsckt->nb_transport_bw(*fsm_hndl->trans, phase, t);
344 };
345 fsm_hndl->fsm->cb[EndRespE] = [this, fsm_hndl]() -> void {
346 if(fsm_hndl->trans->is_read()) {
347 rd_resp_by_id[axi::get_axi_id(*fsm_hndl->trans)].pop_front();
348 r_end_resp_evt.notify();
349 }
350 if(fsm_hndl->trans->is_write()) {
351 wr_resp_by_id[axi::get_axi_id(*fsm_hndl->trans)].pop_front();
352 w_end_resp_evt.notify();
353 }
354 };
355}
356
357template <typename CFG> inline void axi::pin::axi4_initiator<CFG>::ar_t() {
358 this->ar_valid.write(false);
359 wait(sc_core::SC_ZERO_TIME);
360 while(true) {
361 auto val = ar_fifo.read();
362 write_ar(*val.gp);
363 this->ar_valid.write(true);
364 do {
365 wait(this->ar_ready.posedge_event() | clk_delayed);
366 if(this->ar_ready.read())
367 react(axi::fsm::protocol_time_point_e::EndReqE, val.gp);
368 } while(!this->ar_ready.read());
369 wait(clk_i.posedge_event());
370 this->ar_valid.write(false);
371 }
372}
373
374template <typename CFG> inline void axi::pin::axi4_initiator<CFG>::r_t() {
375 this->r_ready.write(false);
376 wait(sc_core::SC_ZERO_TIME);
377 while(true) {
378 wait(clk_delayed);
379 while(!this->r_valid.read()) {
380 wait(this->r_valid.posedge_event());
381 wait(CLK_DELAY); // verilator might create spurious events
382 }
383 auto id = CFG::IS_LITE ? 0U : this->r_id->read().to_uint();
384 auto data = this->r_data.read();
385 auto resp = this->r_resp.read();
386 auto& q = rd_resp_by_id[id];
387 sc_assert(q.size() && "No transaction found for received id");
388 auto* fsm_hndl = q.front();
389 auto beat_count = fsm_hndl->beat_count;
390 auto size = axi::get_burst_size(*fsm_hndl->trans);
391 auto byte_offset = beat_count * size;
392 auto offset = (fsm_hndl->trans->get_address() + byte_offset) & (CFG::BUSWIDTH / 8 - 1);
393 if(offset && (size + offset) > (CFG::BUSWIDTH / 8)) { // un-aligned multi-beat access
394 if(beat_count == 0) {
395 auto dptr = fsm_hndl->trans->get_data_ptr();
396 if(dptr)
397 for(size_t i = offset; i < size; ++i, ++dptr) {
398 auto bit_offs = i * 8;
399 *dptr = data(bit_offs + 7, bit_offs).to_uint();
400 }
401 } else {
402 auto beat_start_idx = beat_count * size - offset;
403 auto data_len = fsm_hndl->trans->get_data_length();
404 auto dptr = fsm_hndl->trans->get_data_ptr() + beat_start_idx;
405 if(dptr)
406 for(size_t i = 0; i < size && (beat_start_idx + i) < data_len; ++i, ++dptr) {
407 auto bit_offs = i * 8;
408 *dptr = data(bit_offs + 7, bit_offs).to_uint();
409 }
410 }
411 } else { // aligned or single beat access
412 auto dptr = fsm_hndl->trans->get_data_ptr() + beat_count * size;
413 if(dptr)
414 for(size_t i = 0; i < size; ++i, ++dptr) {
415 auto bit_offs = (offset + i) * 8;
416 *dptr = data(bit_offs + 7, bit_offs).to_uint();
417 }
418 }
420 fsm_hndl->trans->get_extension(e);
423 auto tp = CFG::IS_LITE || this->r_last->read() ? axi::fsm::protocol_time_point_e::BegRespE
424 : axi::fsm::protocol_time_point_e::BegPartRespE;
425 react(tp, fsm_hndl);
426 wait(r_end_resp_evt);
427 this->r_ready.write(true);
428 wait(clk_i.posedge_event());
429 this->r_ready.write(false);
430 }
431}
432
433template <typename CFG> inline void axi::pin::axi4_initiator<CFG>::aw_t() {
434 this->aw_valid.write(false);
435 wait(sc_core::SC_ZERO_TIME);
436 while(true) {
437 auto val = aw_fifo.read();
438 write_aw(*val.gp);
439 this->aw_valid.write(true);
440 do {
441 wait(this->aw_ready.posedge_event() | clk_delayed);
442 } while(!this->aw_ready.read());
443 wait(clk_i.posedge_event());
444 this->aw_valid.write(false);
445 }
446}
447
448template <typename CFG> inline void axi::pin::axi4_initiator<CFG>::wdata_t() {
449 this->w_valid.write(false);
450 wait(sc_core::SC_ZERO_TIME);
451 while(true) {
452 if(!CFG::IS_LITE)
453 this->w_last->write(false);
454 if(pipelined_wrreq) {
455 while(!wdata_fifo.num_avail()) {
456 wait(clk_i.posedge_event());
457 }
458 } else {
459 wait(wdata_fifo.data_written_event());
460 }
461 auto val = wdata_fifo.front();
462 wdata_fifo.pop_front();
463 write_wdata(*val.gp, val.beat_num);
464 if(pipelined_wrreq && val.needs_end_req) {
465 auto evt = CFG::IS_LITE || (val.last) ? axi::fsm::protocol_time_point_e::EndReqE : axi::fsm::protocol_time_point_e::EndPartReqE;
466 schedule(evt, val.gp, sc_core::SC_ZERO_TIME);
467 }
468 this->w_valid.write(true);
469 if(!CFG::IS_LITE)
470 this->w_last->write(val.last);
471 do {
472 wait(this->w_ready.posedge_event() | clk_delayed);
473 if(!pipelined_wrreq && this->w_ready.read()) {
474 auto evt =
475 CFG::IS_LITE || (val.last) ? axi::fsm::protocol_time_point_e::EndReqE : axi::fsm::protocol_time_point_e::EndPartReqE;
476 schedule(evt, val.gp, sc_core::SC_ZERO_TIME);
477 }
478 } while(!this->w_ready.read());
479 wait(clk_i.posedge_event());
480 this->w_valid.write(false);
481 }
482}
483
484template <typename CFG> inline void axi::pin::axi4_initiator<CFG>::b_t() {
485 this->b_ready.write(false);
486 wait(sc_core::SC_ZERO_TIME);
487 while(true) {
488 wait(clk_delayed);
489 while(!this->b_valid.read()) {
490 wait(this->b_valid.posedge_event());
491 wait(CLK_DELAY); // verilator might create spurious events
492 }
493 auto id = !CFG::IS_LITE ? this->b_id->read().to_uint() : 0U;
494 auto resp = this->b_resp.read();
495 auto& q = wr_resp_by_id[id];
496 sc_assert(q.size());
497 auto* fsm_hndl = q.front();
499 fsm_hndl->trans->get_extension(e);
501 react(axi::fsm::protocol_time_point_e::BegRespE, fsm_hndl);
502 wait(w_end_resp_evt);
503 this->b_ready.write(true);
504 wait(clk_i.posedge_event());
505 this->b_ready.write(false);
506 }
507}
508
509#endif /* _BUS_AXI_PIN_AXI4_INITIATOR_H_ */
fifo with callbacks
Definition fifo_w_cb.h:38
T * get() const noexcept
Return the stored pointer.
pin level adapters
TLM2.0 components modeling AHB.
E into(typename std::underlying_type< E >::type t)
tlm::tlm_fw_transport_if< TYPES > axi_fw_transport_if
alias declaration for the forward interface
Definition axi_tlm.h:954
constexpr ULT to_int(E t)
Definition axi_tlm.h:47
unsigned get_burst_size(const request &r)
Definition axi_tlm.h:1202
void add_to_response_array(response &)
add a read response to the response array
Definition axi_tlm.h:1670
base class of all AXITLM based adapters and interfaces.
Definition base.h:43
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...
Definition base.cpp:190
virtual axi::fsm::fsm_handle * create_fsm_handle()=0
function to create a fsm_handle. Needs to be implemented by the derived class
base(size_t transfer_width, bool coherent=false, axi::fsm::protocol_time_point_e wr_start=axi::fsm::RequestPhaseBeg)
the constructor
Definition base.cpp:43
tlm::scc::tlm_gp_shared_ptr trans
pointer to the associated AXITLM payload
Definition types.h:62
size_t beat_count
beat count of this transaction
Definition types.h:64
AxiProtocolFsm *const fsm
pointer to the FSM
Definition types.h:60
void set_resp(resp_e)
set the response status as POD
Definition axi_tlm.h:1572