scc  2022.4.0
SystemC components library
ace_lite_target.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_ACE_LITE_TARGET_H_
18 #define _BUS_AXI_PIN_ACE_LITE_TARGET_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 <systemc>
25 #include <tlm/scc/tlm_mm.h>
26 #include <util/ities.h>
27 
29 namespace axi {
31 namespace pin {
32 
33 using namespace axi::fsm;
34 
35 template <typename CFG>
36 struct ace_lite_target : public sc_core::sc_module,
37  public aw_ace_lite<CFG, typename CFG::slave_types>,
38  public wdata_ace_lite<CFG, typename CFG::slave_types>,
39  public b_ace_lite<CFG, typename CFG::slave_types>,
40  public ar_ace_lite<CFG, typename CFG::slave_types>,
41  public rresp_ace_lite<CFG, typename CFG::slave_types>,
42  protected axi::fsm::base,
43  public axi::axi_bw_transport_if<axi::axi_protocol_types> {
44  SC_HAS_PROCESS(ace_lite_target);
45 
46  using payload_type = axi::axi_protocol_types::tlm_payload_type;
47  using phase_type = axi::axi_protocol_types::tlm_phase_type;
48 
49  sc_core::sc_in<bool> clk_i{"clk_i"};
50 
52 
53  ace_lite_target(sc_core::sc_module_name const& nm)
54  : sc_core::sc_module(nm)
55  // ace_lite has no ack, therefore coherent= false
56  , base(CFG::BUSWIDTH, false) {
57  instance_name = name();
58  isckt.bind(*this);
59  SC_METHOD(clk_delay);
60  sensitive << clk_i.pos();
61  dont_initialize();
62  SC_THREAD(ar_t);
63  SC_THREAD(rresp_t);
64  SC_THREAD(aw_t);
65  SC_THREAD(wdata_t);
66  SC_THREAD(bresp_t);
67  }
68 
69 private:
70  tlm::tlm_sync_enum nb_transport_bw(payload_type& trans, phase_type& phase, sc_core::sc_time& t) override;
71 
72  void invalidate_direct_mem_ptr(sc_dt::uint64 start_range, sc_dt::uint64 end_range) override;
73 
74  void end_of_elaboration() override { clk_if = dynamic_cast<sc_core::sc_clock*>(clk_i.get_interface()); }
75 
76  axi::fsm::fsm_handle* create_fsm_handle() override { return new fsm_handle(); }
77 
78  void setup_callbacks(axi::fsm::fsm_handle*) override;
79 
80  void clk_delay() {
81 #ifdef DELTA_SYNC
82  if(sc_core::sc_delta_count_at_current_time() < 5) {
83  clk_self.notify(sc_core::SC_ZERO_TIME);
84  next_trigger(clk_self);
85  } else
86  clk_delayed.notify(sc_core::SC_ZERO_TIME /*clk_if ? clk_if->period() - 1_ps : 1_ps*/);
87 #else
88  clk_delayed.notify(axi::CLK_DELAY);
89 #endif
90  }
91  void ar_t();
92  void rresp_t();
93  void aw_t();
94  void wdata_t();
95  void bresp_t();
96  static typename CFG::data_t get_read_data_for_beat(fsm::fsm_handle* fsm_hndl);
97  struct aw_data {
98  unsigned id;
99  uint64_t addr;
100  unsigned prot;
101  unsigned size;
102  unsigned cache;
103  unsigned burst;
104  unsigned qos;
105  unsigned region;
106  unsigned len;
107  unsigned domain;
108  unsigned snoop;
109  unsigned bar;
110  unsigned unique;
111  unsigned stashnid;
112  unsigned stashlpid;
113  bool lock;
114  uint64_t user;
115  };
116 
117  std::deque<axi::fsm::fsm_handle*> snp_resp_queue;
118 
119  sc_core::sc_clock* clk_if{nullptr};
120  sc_core::sc_event clk_delayed, clk_self, ar_end_req_evt, wdata_end_req_evt;
121  std::array<fsm_handle*, 3> active_req_beat{nullptr, nullptr, nullptr};
122  std::array<fsm_handle*, 3> active_req{nullptr, nullptr, nullptr};
123  std::array<fsm_handle*, 3> active_resp_beat{nullptr, nullptr, nullptr};
124  scc::peq<aw_data> aw_que;
127 };
128 } // namespace pin
129 } // namespace axi
130 
131 template <typename CFG>
132 inline tlm::tlm_sync_enum axi::pin::ace_lite_target<CFG>::nb_transport_bw(payload_type& trans, phase_type& phase, sc_core::sc_time& t) {
133  auto ret = tlm::TLM_ACCEPTED;
134  SCCTRACE(SCMOD) << "nb_transport_bw with " << phase << " with delay= " << t << " of trans " << trans;
135  if(phase == END_PARTIAL_REQ || phase == tlm::END_REQ) { // read/write
136  schedule(phase == tlm::END_REQ ? EndReqE : EndPartReqE, &trans, t, false);
137  } else if(phase == axi::BEGIN_PARTIAL_RESP || phase == tlm::BEGIN_RESP) { // read/write response
138  schedule(phase == tlm::BEGIN_RESP ? BegRespE : BegPartRespE, &trans, t, false);
139  } else
140  SCCFATAL(SCMOD) << "Illegal phase received: " << phase;
141  return ret;
142 }
143 
144 template <typename CFG>
145 inline void axi::pin::ace_lite_target<CFG>::invalidate_direct_mem_ptr(sc_dt::uint64 start_range, sc_dt::uint64 end_range) {}
146 
147 template <typename CFG> typename CFG::data_t axi::pin::ace_lite_target<CFG>::get_read_data_for_beat(fsm_handle* fsm_hndl) {
148  auto beat_count = fsm_hndl->beat_count;
149  // SCCTRACE(SCMOD) << " " ;
150  auto size = axi::get_burst_size(*fsm_hndl->trans);
151  auto byte_offset = beat_count * size;
152  auto offset = (fsm_hndl->trans->get_address() + byte_offset) & (CFG::BUSWIDTH / 8 - 1);
153  typename CFG::data_t data{0};
154  if(offset && (size + offset) > (CFG::BUSWIDTH / 8)) { // un-aligned multi-beat access
155  if(beat_count == 0) {
156  auto dptr = fsm_hndl->trans->get_data_ptr();
157  for(size_t i = offset; i < size; ++i, ++dptr) {
158  auto bit_offs = i * 8;
159  data(bit_offs + 7, bit_offs) = *dptr;
160  }
161  } else {
162  auto beat_start_idx = byte_offset - offset;
163  auto data_len = fsm_hndl->trans->get_data_length();
164  auto dptr = fsm_hndl->trans->get_data_ptr() + beat_start_idx;
165  for(size_t i = offset; i < size && (beat_start_idx + i) < data_len; ++i, ++dptr) {
166  auto bit_offs = i * 8;
167  data(bit_offs + 7, bit_offs) = *dptr;
168  }
169  }
170  } else { // aligned or single beat access
171  auto dptr = fsm_hndl->trans->get_data_ptr() + byte_offset;
172  for(size_t i = 0; i < size; ++i, ++dptr) {
173  auto bit_offs = (offset + i) * 8;
174  data(bit_offs + 7, bit_offs) = *dptr;
175  }
176  }
177  return data;
178 }
179 
180 template <typename CFG> inline void axi::pin::ace_lite_target<CFG>::setup_callbacks(fsm_handle* fsm_hndl) {
181  fsm_hndl->fsm->cb[RequestPhaseBeg] = [this, fsm_hndl]() -> void { fsm_hndl->beat_count = 0; };
182  fsm_hndl->fsm->cb[BegPartReqE] = [this, fsm_hndl]() -> void {
183  sc_assert(fsm_hndl->trans->get_command() == tlm::TLM_WRITE_COMMAND);
184  tlm::tlm_phase phase = axi::BEGIN_PARTIAL_REQ;
185  sc_core::sc_time t(sc_core::SC_ZERO_TIME);
186  auto ret = isckt->nb_transport_fw(*fsm_hndl->trans, phase, t);
187  if(ret == tlm::TLM_UPDATED) {
188  schedule(EndPartReqE, fsm_hndl->trans, t, true);
189  }
190  };
191  fsm_hndl->fsm->cb[EndPartReqE] = [this, fsm_hndl]() -> void {
192  wdata_end_req_evt.notify();
193  active_req_beat[tlm::TLM_WRITE_COMMAND] = nullptr;
194  fsm_hndl->beat_count++;
195  };
196  fsm_hndl->fsm->cb[BegReqE] = [this, fsm_hndl]() -> void {
197  tlm::tlm_phase phase = tlm::BEGIN_REQ;
198  sc_core::sc_time t(sc_core::SC_ZERO_TIME);
199  auto ret = isckt->nb_transport_fw(*fsm_hndl->trans, phase, t);
200  if(ret == tlm::TLM_UPDATED) {
201  schedule(EndReqE, fsm_hndl->trans, t, true);
202  }
203  };
204  fsm_hndl->fsm->cb[EndReqE] = [this, fsm_hndl]() -> void {
205  switch(fsm_hndl->trans->get_command()) {
206  case tlm::TLM_READ_COMMAND:
207  ar_end_req_evt.notify();
208  active_req_beat[tlm::TLM_READ_COMMAND] = nullptr;
209  break;
210  case tlm::TLM_WRITE_COMMAND:
211  wdata_end_req_evt.notify();
212  active_req_beat[tlm::TLM_WRITE_COMMAND] = nullptr;
213  fsm_hndl->beat_count++;
214  break;
215  default:
216  break;
217  }
218  };
219  fsm_hndl->fsm->cb[BegPartRespE] = [this, fsm_hndl]() -> void {
220  assert(fsm_hndl->trans->is_read());
221  active_resp_beat[tlm::TLM_READ_COMMAND] = fsm_hndl;
222  rresp_vl.notify({1, fsm_hndl});
223  };
224  fsm_hndl->fsm->cb[EndPartRespE] = [this, fsm_hndl]() -> void {
225  // scheduling the response
226  assert(fsm_hndl->trans->is_read());
227  tlm::tlm_phase phase = axi::END_PARTIAL_RESP;
228  sc_core::sc_time t(sc_core::SC_ZERO_TIME);
229  auto ret = isckt->nb_transport_fw(*fsm_hndl->trans, phase, t);
230  active_resp_beat[tlm::TLM_READ_COMMAND] = nullptr;
231  fsm_hndl->beat_count++;
232  };
233  fsm_hndl->fsm->cb[BegRespE] = [this, fsm_hndl]() -> void {
234  SCCTRACE(SCMOD) << "processing event BegRespE for trans " << *fsm_hndl->trans;
235  auto size = axi::get_burst_size(*fsm_hndl->trans);
236  active_resp_beat[fsm_hndl->trans->get_command()] = fsm_hndl;
237  switch(fsm_hndl->trans->get_command()) {
238  case tlm::TLM_READ_COMMAND:
239  rresp_vl.notify({3, fsm_hndl});
240  break;
241  case tlm::TLM_WRITE_COMMAND:
242  wresp_vl.notify({3, fsm_hndl});
243  break;
244  default:
245  break;
246  }
247  };
248  fsm_hndl->fsm->cb[EndRespE] = [this, fsm_hndl]() -> void {
249  // scheduling the response
250  tlm::tlm_phase phase = tlm::END_RESP;
251  sc_core::sc_time t(sc_core::SC_ZERO_TIME);
252  auto ret = isckt->nb_transport_fw(*fsm_hndl->trans, phase, t);
253  SCCTRACE(SCMOD) << "EndResp of setup_cb with coherent = " << coherent;
254  fsm_hndl->finish.notify();
255  active_resp_beat[fsm_hndl->trans->get_command()] = nullptr;
256  };
257 }
258 
259 template <typename CFG> inline void axi::pin::ace_lite_target<CFG>::ar_t() {
260  this->ar_ready.write(false);
261  wait(sc_core::SC_ZERO_TIME);
262  auto arid = 0U;
263  auto arlen = 0U;
264  auto arsize = util::ilog2(CFG::BUSWIDTH / 8);
265  auto data_len = (1 << arsize) * (arlen + 1);
266  while(true) {
267  wait(this->ar_valid.posedge_event() | clk_delayed);
268  if(this->ar_valid.read()) {
269  SCCTRACE(SCMOD) << "ARVALID detected for 0x" << std::hex << this->ar_addr.read();
270  arid = this->ar_id->read().to_uint();
271  arlen = this->ar_len->read().to_uint();
272  arsize = this->ar_size->read().to_uint();
273  data_len = (1 << arsize) * (arlen + 1);
274  auto gp = tlm::scc::tlm_mm<>::get().allocate<axi::ace_extension>(data_len);
275  gp->set_address(this->ar_addr.read());
276  gp->set_command(tlm::TLM_READ_COMMAND);
277  gp->set_streaming_width(data_len);
278  axi::ace_extension* ext;
279  gp->get_extension(ext);
280  ext->set_id(arid);
281  ext->set_length(arlen);
282  if(this->ar_lock->read())
283  ext->set_exclusive(true);
284  ext->set_size(arsize);
285  ext->set_burst(axi::into<axi::burst_e>(this->ar_burst->read()));
286  ext->set_cache(this->ar_cache->read());
287  ext->set_prot(this->ar_prot->read());
288  ext->set_qos(this->ar_qos->read());
289  ext->set_region(this->ar_region->read());
290  ext->set_domain(axi::into<axi::domain_e>(this->ar_domain->read())); // ace extension
291  ext->set_snoop(axi::into<axi::snoop_e>(this->ar_snoop->read()));
292  ext->set_barrier(axi::into<axi::bar_e>(this->ar_bar->read()));
293 
294  active_req_beat[tlm::TLM_READ_COMMAND] = find_or_create(gp);
295  react(axi::fsm::protocol_time_point_e::BegReqE, active_req_beat[tlm::TLM_READ_COMMAND]);
296  wait(ar_end_req_evt);
297  this->ar_ready.write(true);
298  wait(clk_i.posedge_event());
299  this->ar_ready.write(false);
300  }
301  }
302 }
303 
304 template <typename CFG> inline void axi::pin::ace_lite_target<CFG>::rresp_t() {
305  this->r_valid.write(false);
306  wait(sc_core::SC_ZERO_TIME);
307  fsm_handle* fsm_hndl;
308  uint8_t val;
309  while(true) {
310  // rresp_vl notified in BEGIN_PARTIAL_REQ ( val=1 ??)or in BEG_RESP(val=3??)
311  std::tie(val, fsm_hndl) = rresp_vl.get();
312  SCCTRACE(SCMOD) << __FUNCTION__ << " val = " << (uint16_t)val << " beat count = " << fsm_hndl->beat_count;
313  SCCTRACE(SCMOD) << __FUNCTION__ << " got read response beat of trans " << *fsm_hndl->trans;
314  auto ext = fsm_hndl->trans->get_extension<axi::ace_extension>();
315  this->r_data.write(get_read_data_for_beat(fsm_hndl));
316  this->r_resp.write(ext->get_cresp());
317  this->r_valid.write(val & 0x1);
318  if(!CFG::IS_LITE) {
319  this->r_id->write(ext->get_id());
320  this->r_last->write(val & 0x2);
321  }
322  do {
323  wait(this->r_ready.posedge_event() | clk_delayed);
324  if(this->r_ready.read()) {
325  auto evt =
326  CFG::IS_LITE || (val & 0x2) ? axi::fsm::protocol_time_point_e::EndRespE : axi::fsm::protocol_time_point_e::EndPartRespE;
327  react(evt, active_resp_beat[tlm::TLM_READ_COMMAND]);
328  }
329  } while(!this->r_ready.read());
330  SCCTRACE(SCMOD) << "finished read response beat of trans [" << fsm_hndl->trans << "]";
331  wait(clk_i.posedge_event());
332  this->r_valid.write(false);
333  if(!CFG::IS_LITE)
334  this->r_last->write(false);
335  }
336 }
337 
338 template <typename CFG> inline void axi::pin::ace_lite_target<CFG>::aw_t() {
339  this->aw_ready.write(false);
340  wait(sc_core::SC_ZERO_TIME);
341  const auto awsize = util::ilog2(CFG::BUSWIDTH / 8);
342  while(true) {
343  wait(this->aw_valid.posedge_event() | clk_delayed);
344  if(this->aw_valid.event() || (!active_req_beat[tlm::TLM_IGNORE_COMMAND] && this->aw_valid.read())) {
345  SCCTRACE(SCMOD) << "AWVALID detected for 0x" << std::hex << this->aw_addr.read();
346  // clang-format off
347  aw_data awd = {CFG::IS_LITE ? 0U : this->aw_id->read().to_uint(),
348  this->aw_addr.read().to_uint64(),
349  this->aw_prot.read().to_uint(),
350  this->aw_size->read().to_uint(),
351  this->aw_cache->read().to_uint(),
352  this->aw_burst->read().to_uint(),
353  this->aw_qos->read().to_uint(),
354  this->aw_region->read().to_uint(),
355  this->aw_len->read().to_uint(),
356  this->aw_domain->read().to_uint(),
357  this->aw_snoop->read().to_uint(),
358  this->aw_bar->read().to_uint(),
359  this->aw_unique->read(),
360  this->aw_stashniden->read() ? 0U : this->aw_stashnid->read().to_uint(),
361  this->aw_stashlpiden->read()? 0U : this->aw_stashlpid->read().to_uint(),
362  this->aw_lock->read() ? true : false,
363  0};
364  // clang-format on
365  aw_que.notify(awd);
366  this->aw_ready.write(true);
367  wait(clk_i.posedge_event());
368  this->aw_ready.write(false);
369  }
370  }
371 }
372 
373 template <typename CFG> inline void axi::pin::ace_lite_target<CFG>::wdata_t() {
374  this->w_ready.write(false);
375  wait(sc_core::SC_ZERO_TIME);
376  while(true) {
377  wait(this->w_valid.posedge_event() | clk_delayed);
378  this->w_ready.write(false);
379  if(this->w_valid.event() || (!active_req_beat[tlm::TLM_WRITE_COMMAND] && this->w_valid.read())) {
380  if(!active_req[tlm::TLM_WRITE_COMMAND]) {
381  if(!aw_que.has_next())
382  wait(aw_que.event());
383  auto awd = aw_que.get();
384  auto data_len = (1 << awd.size) * (awd.len + 1);
385  auto gp = tlm::scc::tlm_mm<>::get().allocate<axi::ace_extension>(data_len, true);
386  gp->set_address(awd.addr);
387  gp->set_command(tlm::TLM_WRITE_COMMAND);
388  axi::ace_extension* ext;
389  gp->get_extension(ext);
390  ext->set_id(awd.id);
391  ext->set_length(awd.len);
392  ext->set_size(awd.size);
393  ext->set_burst(axi::into<axi::burst_e>(awd.burst));
394  ext->set_prot(awd.prot);
395  ext->set_qos(awd.qos);
396  ext->set_cache(awd.cache);
397  ext->set_region(awd.region);
398  ext->set_snoop(axi::into<axi::snoop_e>(awd.snoop));
399  ext->set_barrier(axi::into<axi::bar_e>(awd.bar));
400  // ace_lite does not have aw_unique ext->set_unique(awd.unique);
401  ext->set_stash_nid(awd.stashnid);
402  ext->set_stash_lpid(awd.stashlpid);
403  ext->set_exclusive(awd.lock);
404  if(CFG::USERWIDTH)
405  ext->set_user(axi::common::id_type::CTRL, awd.user);
406  active_req_beat[tlm::TLM_WRITE_COMMAND] = find_or_create(gp);
407  active_req[tlm::TLM_WRITE_COMMAND] = active_req_beat[tlm::TLM_WRITE_COMMAND];
408  }
409  auto* fsm_hndl = active_req[tlm::TLM_WRITE_COMMAND];
410  SCCTRACE(SCMOD) << "WDATA detected for 0x" << std::hex << this->ar_addr.read();
411  auto& gp = fsm_hndl->trans;
412  auto data = this->w_data.read();
413  auto strb = this->w_strb.read();
414  auto last = this->w_last->read();
415  auto beat_count = fsm_hndl->beat_count;
416  auto size = axi::get_burst_size(*fsm_hndl->trans);
417  auto byte_offset = beat_count * size;
418  auto offset = (fsm_hndl->trans->get_address() + byte_offset) & (CFG::BUSWIDTH / 8 - 1);
419  if(offset && (size + offset) > (CFG::BUSWIDTH / 8)) { // un-aligned multi-beat access
420  if(beat_count == 0) {
421  auto dptr = fsm_hndl->trans->get_data_ptr();
422  auto beptr = fsm_hndl->trans->get_byte_enable_ptr();
423  for(size_t i = offset; i < size; ++i, ++dptr, ++beptr) {
424  auto bit_offs = i * 8;
425  *dptr = data(bit_offs + 7, bit_offs).to_uint();
426  *beptr = strb[i] ? 0xff : 0;
427  }
428  } else {
429  auto beat_start_idx = byte_offset - offset;
430  auto data_len = fsm_hndl->trans->get_data_length();
431  auto dptr = fsm_hndl->trans->get_data_ptr() + beat_start_idx;
432  auto beptr = fsm_hndl->trans->get_byte_enable_ptr() + beat_start_idx;
433  for(size_t i = 0; i < size && (beat_start_idx + i) < data_len; ++i, ++dptr, ++beptr) {
434  auto bit_offs = i * 8;
435  *dptr = data(bit_offs + 7, bit_offs).to_uint();
436  *beptr = strb[i] ? 0xff : 0;
437  }
438  }
439  } else { // aligned or single beat access
440  auto dptr = fsm_hndl->trans->get_data_ptr() + byte_offset;
441  auto beptr = fsm_hndl->trans->get_byte_enable_ptr() + byte_offset;
442  for(size_t i = 0; i < size; ++i, ++dptr, ++beptr) {
443  auto bit_offs = (offset + i) * 8;
444  *dptr = data(bit_offs + 7, bit_offs).to_uint();
445  *beptr = strb[offset + i] ? 0xff : 0;
446  }
447  }
448  // TODO: assuming consecutive write (not scattered)
449  auto strobe = strb.to_uint();
450  if(last) {
451  auto act_data_len = CFG::IS_LITE ? util::bit_count(strobe) : (beat_count + 1) * size;
452  // if(CFG::IS_LITE && act_data_len<CFG::BUSWIDTH/8) {
453  // std::fill(gp->get_byte_enable_ptr(), gp->get_byte_enable_ptr() + act_data_len, 0xff);
454  // std::fill(gp->get_byte_enable_ptr() + act_data_len, gp->get_byte_enable_ptr() +
455  // gp->get_byte_enable_length(), 0x0);
456  // }
457  gp->set_data_length(act_data_len);
458  gp->set_byte_enable_length(act_data_len);
459  gp->set_streaming_width(act_data_len);
460  }
461  auto tp = this->w_last->read() ? axi::fsm::protocol_time_point_e::BegReqE : axi::fsm::protocol_time_point_e::BegPartReqE;
462  react(tp, fsm_hndl);
463  // notified in EndPartReqE/EndReq
464  wait(wdata_end_req_evt);
465  this->w_ready.write(true);
466  wait(clk_i.posedge_event());
467  this->w_ready.write(false);
468  if(last)
469  active_req[tlm::TLM_WRITE_COMMAND] = nullptr;
470  }
471  }
472 }
473 
474 template <typename CFG> inline void axi::pin::ace_lite_target<CFG>::bresp_t() {
475  this->b_valid.write(false);
476  wait(sc_core::SC_ZERO_TIME);
477  fsm_handle* fsm_hndl;
478  uint8_t val;
479  while(true) {
480  std::tie(val, fsm_hndl) = wresp_vl.get();
481  SCCTRACE(SCMOD) << "got write response of trans " << *fsm_hndl->trans;
482  auto ext = fsm_hndl->trans->get_extension<axi::ace_extension>();
483  this->b_resp.write(axi::to_int(ext->get_resp()));
484  this->b_valid.write(true);
485  if(!CFG::IS_LITE)
486  this->b_id->write(ext->get_id());
487  SCCTRACE(SCMOD) << "got write response";
488  do {
489  wait(this->b_ready.posedge_event() | clk_delayed);
490  if(this->b_ready.read()) {
491  react(axi::fsm::protocol_time_point_e::EndRespE, active_resp_beat[tlm::TLM_WRITE_COMMAND]);
492  }
493  } while(!this->b_ready.read());
494  SCCTRACE(SCMOD) << "finished write response of trans [" << fsm_hndl->trans << "]";
495  wait(clk_i.posedge_event());
496  this->b_valid.write(false);
497  }
498 }
499 
500 #endif /* _BUS_AXI_PIN_ace_lite_TARGET_H_ */
payload_type * allocate()
get a plain tlm_payload_type without extensions
Definition: tlm_mm.h:228
static tlm_mm & get()
accessor function of the singleton
Definition: tlm_mm.h:222
TLM2.0 components modeling AHB.
Definition: axi_initiator.h:30
tlm::tlm_bw_transport_if< TYPES > axi_bw_transport_if
alias declaration for the backward interface:
Definition: axi_tlm.h:918
constexpr ULT to_int(E t)
Definition: axi_tlm.h:47
unsigned get_burst_size(const request &r)
Definition: axi_tlm.h:1157
CONSTEXPR unsigned ilog2(uint32_t val)
Definition: ities.h:163
uint8_t get_cresp() const
get the coherent response status
Definition: axi_tlm.h:1533
void set_barrier(bar_e)
set the AxBAR value
Definition: axi_tlm.h:1449
void set_domain(domain_e)
set the AxDOMAIN value
Definition: axi_tlm.h:1441
void set_snoop(snoop_e)
set the AxSNOOP value
Definition: axi_tlm.h:1445
void set_exclusive(bool=true)
get the exclusive bit of AxLOCK (AxLOCK[0])
Definition: axi_tlm.h:1324
void set_id(unsigned int value)
Definition: axi_tlm.h:1252
void set_user(id_type chnl, unsigned int value)
Definition: axi_tlm.h:1256
unsigned int get_id() const
Definition: axi_tlm.h:1254
base class of all AXITLM based adapters and interfaces.
Definition: base.h:43
tlm::scc::tlm_gp_shared_ptr trans
pointer to the associated AXITLM payload
Definition: types.h:62
sc_core::sc_event finish
event indicating the end of the transaction
Definition: types.h:68
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_length(uint8_t)
set the AxLEN value of the transaction, the value denotes the burst length - 1
Definition: axi_tlm.h:1380
void set_qos(uint8_t)
set the AxQOS (quality of service) value
Definition: axi_tlm.h:1426
void set_cache(uint8_t)
set the AxCACHE value as POD, only value from 0..15 are allowed
Definition: axi_tlm.h:1434
void set_region(uint8_t)
set the AxREGION value
Definition: axi_tlm.h:1430
void set_stash_lpid(uint8_t)
set the raw AWSTASHLPID value
Definition: axi_tlm.h:1467
void set_burst(burst_e)
set the AxBURST value,
Definition: axi_tlm.h:1391
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...
Definition: axi_tlm.h:1384
void set_prot(uint8_t)
set the AxPROT value as POD, only values from 0...7 are allowed
Definition: axi_tlm.h:1395
void set_stash_nid(uint8_t)
set the raw AWSTASHNID value
Definition: axi_tlm.h:1461
resp_e get_resp() const
get the response status as POD
Definition: axi_tlm.h:1502