scc  2022.4.0
SystemC components library
ace_lite_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_ACE_LITE_INITIATOR_H_
18 #define _BUS_AXI_PIN_ACE_LITE_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 <systemc>
25 #include <tlm/scc/tlm_mm.h>
26 #include <tlm_utils/peq_with_cb_and_phase.h>
27 
29 namespace axi {
31 namespace pin {
32 
33 template <typename CFG>
34 struct ace_lite_initiator : public sc_core::sc_module,
35  public aw_ace_lite<CFG, typename CFG::master_types>,
36  public wdata_ace_lite<CFG, typename CFG::master_types>,
37  public b_ace_lite<CFG, typename CFG::master_types>,
38  public ar_ace_lite<CFG, typename CFG::master_types>,
39  public rresp_ace_lite<CFG, typename CFG::master_types>,
40  protected axi::fsm::base,
41  public axi::ace_fw_transport_if<axi::axi_protocol_types> {
42  SC_HAS_PROCESS(ace_lite_initiator);
43 
44  using payload_type = axi::axi_protocol_types::tlm_payload_type;
45  using phase_type = axi::axi_protocol_types::tlm_phase_type;
46 
47  sc_core::sc_in<bool> clk_i{"clk_i"};
48 
50 
51  ace_lite_initiator(sc_core::sc_module_name const& nm)
52  : sc_core::sc_module(nm)
53  // ace_lite has no ack, therefore coherent= false
54  , base(CFG::BUSWIDTH, false) {
55  instance_name = name();
56  tsckt(*this);
57  SC_METHOD(clk_delay);
58  sensitive << clk_i.pos();
59  SC_THREAD(ar_t);
60  SC_THREAD(r_t);
61  SC_THREAD(aw_t);
62  SC_THREAD(wdata_t);
63  SC_THREAD(b_t);
64  }
65 
66 private:
67  void b_transport(payload_type& trans, sc_core::sc_time& t) override {
68  trans.set_dmi_allowed(false);
69  trans.set_response_status(tlm::TLM_OK_RESPONSE);
70  }
71 
72  tlm::tlm_sync_enum nb_transport_fw(payload_type& trans, phase_type& phase, sc_core::sc_time& t) override {
73  assert(trans.get_extension<axi::ace_extension>() && "missing ACE extension");
74  sc_core::sc_time delay; // FIXME: calculate delay correctly
75  fw_peq.notify(trans, phase, delay);
76  return tlm::TLM_ACCEPTED;
77  }
78 
79  bool get_direct_mem_ptr(payload_type& trans, tlm::tlm_dmi& dmi_data) override {
80  trans.set_dmi_allowed(false);
81  return false;
82  }
83 
84  unsigned int transport_dbg(payload_type& trans) override { return 0; }
85 
86  void end_of_elaboration() override { clk_if = dynamic_cast<sc_core::sc_clock*>(clk_i.get_interface()); }
87 
88  fsm_handle* create_fsm_handle() { return new fsm_handle(); }
89 
90  void setup_callbacks(fsm_handle* fsm_hndl);
91 
92  void clk_delay() { clk_delayed.notify(axi::CLK_DELAY); }
93 
94  void ar_t();
95  void r_t();
96  void aw_t();
97  void wdata_t();
98  void b_t();
106  static typename CFG::data_t get_cache_data_for_beat(fsm::fsm_handle* fsm_hndl);
107  std::array<unsigned, 3> outstanding_cnt{0, 0, 0};
108  std::array<fsm_handle*, 3> active_req{nullptr, nullptr, nullptr};
109  std::array<fsm_handle*, 3> active_resp{nullptr, nullptr, nullptr};
110  sc_core::sc_clock* clk_if{nullptr};
111  sc_core::sc_event clk_delayed, clk_self, r_end_resp_evt, w_end_resp_evt, aw_evt, ar_evt;
112  void nb_fw(payload_type& trans, const phase_type& phase) {
113  auto t = sc_core::SC_ZERO_TIME;
114  base::nb_fw(trans, phase, t);
115  }
116  tlm_utils::peq_with_cb_and_phase<ace_lite_initiator> fw_peq{this, &ace_lite_initiator::nb_fw};
117  std::unordered_map<unsigned, std::deque<fsm_handle*>> rd_resp_by_id, wr_resp_by_id;
118  sc_core::sc_buffer<uint8_t> wdata_vl;
119  void write_ar(tlm::tlm_generic_payload& trans);
120  void write_aw(tlm::tlm_generic_payload& trans);
121  void write_wdata(tlm::tlm_generic_payload& trans, unsigned beat, bool last = false);
122 };
123 
124 } // namespace pin
125 } // namespace axi
126 
127 template <typename CFG> inline void axi::pin::ace_lite_initiator<CFG>::write_ar(tlm::tlm_generic_payload& trans) {
128  sc_dt::sc_uint<CFG::ADDRWIDTH> addr = trans.get_address();
129  this->ar_addr.write(addr);
130  if(auto ext = trans.get_extension<axi::ace_extension>()) {
131  this->ar_id->write(sc_dt::sc_uint<CFG::IDWIDTH>(ext->get_id()));
132  this->ar_len->write(sc_dt::sc_uint<8>(ext->get_length()));
133  this->ar_size->write(sc_dt::sc_uint<3>(ext->get_size()));
134  this->ar_burst->write(sc_dt::sc_uint<2>(axi::to_int(ext->get_burst())));
135  if(ext->is_exclusive())
136  this->ar_lock->write(true);
137  this->ar_cache->write(sc_dt::sc_uint<4>(ext->get_cache()));
138  this->ar_prot.write(ext->get_prot());
139  this->ar_qos->write(ext->get_qos());
140  this->ar_region->write(ext->get_region());
141  this->ar_domain->write(sc_dt::sc_uint<2>((uint8_t)ext->get_domain()));
142  this->ar_snoop->write(sc_dt::sc_uint<4>((uint8_t)ext->get_snoop()));
143  this->ar_bar->write(sc_dt::sc_uint<2>((uint8_t)ext->get_barrier()));
144  this->ar_user->write(ext->get_user(axi::common::id_type::CTRL));
145  }
146 }
147 
148 template <typename CFG> inline void axi::pin::ace_lite_initiator<CFG>::write_aw(tlm::tlm_generic_payload& trans) {
149  sc_dt::sc_uint<CFG::ADDRWIDTH> addr = trans.get_address();
150  this->aw_addr.write(addr);
151  if(auto ext = trans.get_extension<axi::ace_extension>()) {
152  this->aw_prot.write(ext->get_prot());
153  // TBD?? this->aw_lock.write();
154  if(this->aw_id.get_interface())
155  this->aw_id->write(sc_dt::sc_uint<CFG::IDWIDTH>(ext->get_id()));
156  if(ext->is_exclusive())
157  this->aw_lock->write(true);
158  this->aw_len->write(sc_dt::sc_uint<8>(ext->get_length()));
159  this->aw_size->write(sc_dt::sc_uint<3>(ext->get_size()));
160  this->aw_burst->write(sc_dt::sc_uint<2>(axi::to_int(ext->get_burst())));
161  this->aw_cache->write(sc_dt::sc_uint<4>(ext->get_cache()));
162  this->aw_qos->write(sc_dt::sc_uint<4>(ext->get_qos()));
163  this->aw_region->write(sc_dt::sc_uint<4>(ext->get_region()));
164  this->aw_user->write(ext->get_user(axi::common::id_type::CTRL));
165  this->aw_domain->write(sc_dt::sc_uint<2>((uint8_t)ext->get_domain()));
166  this->aw_snoop->write(sc_dt::sc_uint<CFG::AWSNOOPWIDTH>((uint8_t)ext->get_snoop()));
167  this->aw_bar->write(sc_dt::sc_uint<2>((uint8_t)ext->get_barrier()));
168  /* ace_lite doe not have unique* */
169  // this->aw_unique->write(ext->get_unique());
170  if(ext->is_stash_nid_en()) {
171  this->aw_stashniden->write(true);
172  this->aw_stashnid->write(sc_dt::sc_uint<11>(ext->get_stash_nid()));
173  }
174  if(ext->is_stash_lpid_en()) {
175  this->aw_stashlpiden->write(true);
176  this->aw_stashlpid->write(sc_dt::sc_uint<5>(ext->get_stash_lpid()));
177  }
178  }
179 }
180 
181 // FIXME: strb not yet correct
182 template <typename CFG>
183 inline void axi::pin::ace_lite_initiator<CFG>::write_wdata(tlm::tlm_generic_payload& trans, unsigned beat, bool last) {
184  typename CFG::data_t data{0};
185  sc_dt::sc_uint<CFG::BUSWIDTH / 8> strb{0};
186  auto ext = trans.get_extension<axi::ace_extension>();
187  auto size = 1u << ext->get_size();
188  auto byte_offset = beat * size;
189  auto offset = (trans.get_address() + byte_offset) & (CFG::BUSWIDTH / 8 - 1);
190  auto beptr = trans.get_byte_enable_length() ? trans.get_byte_enable_ptr() + byte_offset : nullptr;
191  if(offset && (size + offset) > (CFG::BUSWIDTH / 8)) { // un-aligned multi-beat access
192  if(beat == 0) {
193  auto dptr = trans.get_data_ptr();
194  if(dptr)
195  for(size_t i = offset; i < size; ++i, ++dptr) {
196  auto bit_offs = i * 8;
197  data(bit_offs + 7, bit_offs) = *dptr;
198  if(beptr) {
199  strb[i] = *beptr == 0xff;
200  ++beptr;
201  } else
202  strb[i] = true;
203  }
204  } else {
205  auto beat_start_idx = byte_offset - offset;
206  auto data_len = trans.get_data_length();
207  auto dptr = trans.get_data_ptr() + beat_start_idx;
208  if(dptr)
209  for(size_t i = 0; i < size && (beat_start_idx + i) < data_len; ++i, ++dptr) {
210  auto bit_offs = i * 8;
211  data(bit_offs + 7, bit_offs) = *dptr;
212  if(beptr) {
213  strb[i] = *beptr == 0xff;
214  ++beptr;
215  } else
216  strb[i] = true;
217  }
218  }
219  } else { // aligned or single beat access
220  auto dptr = trans.get_data_ptr() + byte_offset;
221  if(dptr)
222  for(size_t i = 0; i < size; ++i, ++dptr) {
223  auto bit_offs = (offset + i) * 8;
224  data(bit_offs + 7, bit_offs) = *dptr;
225  if(beptr) {
226  strb[offset + i] = *beptr == 0xff;
227  ++beptr;
228  } else
229  strb[offset + i] = true;
230  }
231  }
232  this->w_data.write(data);
233  this->w_strb.write(strb);
234  if(!CFG::IS_LITE) {
235  this->w_id->write(ext->get_id());
236  if(this->w_user.get_interface())
237  this->w_user->write(ext->get_user(axi::common::id_type::DATA));
238  }
239 }
240 
241 template <typename CFG> typename CFG::data_t axi::pin::ace_lite_initiator<CFG>::get_cache_data_for_beat(fsm_handle* fsm_hndl) {
242  auto beat_count = fsm_hndl->beat_count;
243  // SCCTRACE(SCMOD) << " " ;
244  auto size = axi::get_burst_size(*fsm_hndl->trans);
245  auto byte_offset = beat_count * size;
246  auto offset = (fsm_hndl->trans->get_address() + byte_offset) & (CFG::BUSWIDTH / 8 - 1);
247  typename CFG::data_t data{0};
248  if(offset && (size + offset) > (CFG::BUSWIDTH / 8)) { // un-aligned multi-beat access
249  if(beat_count == 0) {
250  auto dptr = fsm_hndl->trans->get_data_ptr();
251  for(size_t i = offset; i < size; ++i, ++dptr) {
252  auto bit_offs = i * 8;
253  data(bit_offs + 7, bit_offs) = *dptr;
254  }
255  } else {
256  auto beat_start_idx = byte_offset - offset;
257  auto data_len = fsm_hndl->trans->get_data_length();
258  auto dptr = fsm_hndl->trans->get_data_ptr() + beat_start_idx;
259  for(size_t i = offset; i < size && (beat_start_idx + i) < data_len; ++i, ++dptr) {
260  auto bit_offs = i * 8;
261  data(bit_offs + 7, bit_offs) = *dptr;
262  }
263  }
264  } else { // aligned or single beat access
265  auto dptr = fsm_hndl->trans->get_data_ptr() + byte_offset;
266  for(size_t i = 0; i < size; ++i, ++dptr) {
267  auto bit_offs = (offset + i) * 8;
268  data(bit_offs + 7, bit_offs) = *dptr;
269  }
270  }
271  return data;
272 }
273 
274 template <typename CFG> inline void axi::pin::ace_lite_initiator<CFG>::setup_callbacks(fsm_handle* fsm_hndl) {
275  fsm_hndl->fsm->cb[RequestPhaseBeg] = [this, fsm_hndl]() -> void {
276  if(fsm_hndl->is_snoop) {
277  SCCTRACE(SCMOD) << " for snoop in RequestPhaseBeg ";
278  } else {
279  fsm_hndl->beat_count = 0;
280  outstanding_cnt[fsm_hndl->trans->get_command()]++;
281  if(CFG::IS_LITE) {
282  auto offset = fsm_hndl->trans->get_address() % (CFG::BUSWIDTH / 8);
283  if(offset + fsm_hndl->trans->get_data_length() > CFG::BUSWIDTH / 8) {
284  SCCFATAL(SCMOD) << " transaction " << *fsm_hndl->trans << " is not AXI4Lite compliant";
285  }
286  }
287  }
288  };
289  fsm_hndl->fsm->cb[BegPartReqE] = [this, fsm_hndl]() -> void {
290  sc_assert(fsm_hndl->trans->is_write());
291  if(fsm_hndl->beat_count == 0) {
292  write_aw(*fsm_hndl->trans);
293  aw_evt.notify(sc_core::SC_ZERO_TIME);
294  }
295  write_wdata(*fsm_hndl->trans, fsm_hndl->beat_count);
296  active_req[tlm::TLM_WRITE_COMMAND] = fsm_hndl;
297  wdata_vl.write(0x1);
298  };
299  fsm_hndl->fsm->cb[EndPartReqE] = [this, fsm_hndl]() -> void {
300  active_req[tlm::TLM_WRITE_COMMAND] = nullptr;
301  tlm::tlm_phase phase = axi::END_PARTIAL_REQ;
302  sc_core::sc_time t = (clk_if ? clk_if->period() - axi::CLK_DELAY - 1_ps : sc_core::SC_ZERO_TIME);
303  auto ret = tsckt->nb_transport_bw(*fsm_hndl->trans, phase, t);
304  fsm_hndl->beat_count++;
305  };
306  fsm_hndl->fsm->cb[BegReqE] = [this, fsm_hndl]() -> void {
307  SCCTRACEALL(SCMOD) << "In BegReqE of setup_cb";
308  switch(fsm_hndl->trans->get_command()) {
309  case tlm::TLM_READ_COMMAND:
310  active_req[tlm::TLM_READ_COMMAND] = fsm_hndl;
311  write_ar(*fsm_hndl->trans);
312  ar_evt.notify(sc_core::SC_ZERO_TIME);
313  break;
314  case tlm::TLM_WRITE_COMMAND:
315  active_req[tlm::TLM_WRITE_COMMAND] = fsm_hndl;
316  if(fsm_hndl->beat_count == 0) {
317  write_aw(*fsm_hndl->trans);
318  aw_evt.notify(sc_core::SC_ZERO_TIME);
319  }
320  /* for dataless trans, no data on wdata_t*/
321  auto ext = fsm_hndl->trans->get_extension<ace_extension>();
322  if(!axi::is_dataless(ext)) {
323  write_wdata(*fsm_hndl->trans, fsm_hndl->beat_count, true);
324  wdata_vl.write(0x3);
325  }
326  }
327  };
328  fsm_hndl->fsm->cb[EndReqE] = [this, fsm_hndl]() -> void {
329  SCCTRACEALL(SCMOD) << "In EndReqE of setup_cb";
330  switch(fsm_hndl->trans->get_command()) {
331  case tlm::TLM_READ_COMMAND:
332  rd_resp_by_id[axi::get_axi_id(*fsm_hndl->trans)].push_back(fsm_hndl);
333  active_req[tlm::TLM_READ_COMMAND] = nullptr;
334  break;
335  case tlm::TLM_WRITE_COMMAND:
336  wr_resp_by_id[axi::get_axi_id(*fsm_hndl->trans)].push_back(fsm_hndl);
337  active_req[tlm::TLM_WRITE_COMMAND] = nullptr;
338  fsm_hndl->beat_count++;
339  }
340  tlm::tlm_phase phase = tlm::END_REQ;
341  sc_core::sc_time t = (clk_if ? clk_if->period() - axi::CLK_DELAY - 1_ps : sc_core::SC_ZERO_TIME);
342  SCCTRACE(SCMOD) << " in EndReq before set_resp";
343  auto ret = tsckt->nb_transport_bw(*fsm_hndl->trans, phase, t);
344  fsm_hndl->trans->set_response_status(tlm::TLM_OK_RESPONSE);
345  };
346 
347  fsm_hndl->fsm->cb[BegPartRespE] = [this, fsm_hndl]() -> void {
348  // scheduling the response
349  assert(fsm_hndl->trans->is_read());
350  tlm::tlm_phase phase = axi::BEGIN_PARTIAL_RESP;
351  sc_core::sc_time t(sc_core::SC_ZERO_TIME);
352  auto ret = tsckt->nb_transport_bw(*fsm_hndl->trans, phase, t);
353  };
354  fsm_hndl->fsm->cb[EndPartRespE] = [this, fsm_hndl]() -> void {
355  SCCTRACE(SCMOD) << "in EndPartRespE of setup_cb ";
356  fsm_hndl->beat_count++;
357  r_end_resp_evt.notify();
358  };
359  fsm_hndl->fsm->cb[BegRespE] = [this, fsm_hndl]() -> void {
360  // scheduling the response
361  tlm::tlm_phase phase = tlm::BEGIN_RESP;
362  sc_core::sc_time t(sc_core::SC_ZERO_TIME);
363  auto ret = tsckt->nb_transport_bw(*fsm_hndl->trans, phase, t);
364  };
365  fsm_hndl->fsm->cb[EndRespE] = [this, fsm_hndl]() -> void {
366  SCCTRACE(SCMOD) << "in EndResp of setup_cb ";
367  if(fsm_hndl->trans->is_read()) {
368  rd_resp_by_id[axi::get_axi_id(*fsm_hndl->trans)].pop_front();
369  r_end_resp_evt.notify();
370  }
371  if(fsm_hndl->trans->is_write()) {
372  wr_resp_by_id[axi::get_axi_id(*fsm_hndl->trans)].pop_front();
373  w_end_resp_evt.notify();
374  }
375  };
376 }
377 template <typename CFG> inline void axi::pin::ace_lite_initiator<CFG>::ar_t() {
378  this->ar_valid.write(false);
379  wait(sc_core::SC_ZERO_TIME);
380  while(true) {
381  wait(ar_evt);
382  this->ar_valid.write(true);
383  do {
384  wait(this->ar_ready.posedge_event() | clk_delayed);
385  if(this->ar_ready.read())
386  react(axi::fsm::protocol_time_point_e::EndReqE, active_req[tlm::TLM_READ_COMMAND]);
387  } while(!this->ar_ready.read());
388  wait(clk_i.posedge_event());
389  this->ar_valid.write(false);
390  }
391 }
392 
393 template <typename CFG> inline void axi::pin::ace_lite_initiator<CFG>::r_t() {
394  this->r_ready.write(false);
395  wait(sc_core::SC_ZERO_TIME);
396  while(true) {
397  wait(this->r_valid.posedge_event() | clk_delayed);
398  if(this->r_valid.event() || (!active_resp[tlm::TLM_READ_COMMAND] && this->r_valid.read())) {
399  wait(sc_core::SC_ZERO_TIME);
400  auto id = CFG::IS_LITE ? 0U : this->r_id->read().to_uint();
401  auto data = this->r_data.read();
402  auto resp = this->r_resp.read();
403  auto& q = rd_resp_by_id[id];
404  sc_assert(q.size());
405  auto* fsm_hndl = q.front();
406  auto beat_count = fsm_hndl->beat_count;
407  auto size = axi::get_burst_size(*fsm_hndl->trans);
408  auto byte_offset = beat_count * size;
409  auto offset = (fsm_hndl->trans->get_address() + byte_offset) & (CFG::BUSWIDTH / 8 - 1);
410  if(offset && (size + offset) > (CFG::BUSWIDTH / 8)) { // un-aligned multi-beat access
411  if(beat_count == 0) {
412  auto dptr = fsm_hndl->trans->get_data_ptr();
413  if(dptr)
414  for(size_t i = offset; i < size; ++i, ++dptr) {
415  auto bit_offs = i * 8;
416  *dptr = data(bit_offs + 7, bit_offs).to_uint();
417  }
418  } else {
419  auto beat_start_idx = beat_count * size - offset;
420  auto data_len = fsm_hndl->trans->get_data_length();
421  auto dptr = fsm_hndl->trans->get_data_ptr() + beat_start_idx;
422  if(dptr)
423  for(size_t i = offset; i < size && (beat_start_idx + i) < data_len; ++i, ++dptr) {
424  auto bit_offs = i * 8;
425  *dptr = data(bit_offs + 7, bit_offs).to_uint();
426  }
427  }
428  } else { // aligned or single beat access
429  auto dptr = fsm_hndl->trans->get_data_ptr() + beat_count * size;
430  if(dptr)
431  for(size_t i = 0; i < size; ++i, ++dptr) {
432  auto bit_offs = (offset + i) * 8;
433  *dptr = data(bit_offs + 7, bit_offs).to_uint();
434  }
435  }
437  fsm_hndl->trans->get_extension(e);
438  e->set_cresp(resp);
439  e->add_to_response_array(*e);
440  /* dataless trans * */
441  if(axi::is_dataless(e)) {
442  SCCTRACE(SCMOD) << " r_t() for Make/Clean/Barrier Trans" << *fsm_hndl->trans;
443  react(axi::fsm::protocol_time_point_e::BegRespE, fsm_hndl);
444  } else {
445  auto tp = CFG::IS_LITE || this->r_last->read() ? axi::fsm::protocol_time_point_e::BegRespE
446  : axi::fsm::protocol_time_point_e::BegPartRespE;
447  react(tp, fsm_hndl);
448  }
449 
450  // r_end_resp_evt notified in EndPartialResp or Endresp
451  wait(r_end_resp_evt);
452  this->r_ready->write(true);
453  wait(clk_i.posedge_event());
454  this->r_ready.write(false);
455  }
456  }
457 }
458 
459 template <typename CFG> inline void axi::pin::ace_lite_initiator<CFG>::aw_t() {
460  this->aw_valid.write(false);
461  wait(sc_core::SC_ZERO_TIME);
462  while(true) {
463  wait(aw_evt);
464  this->aw_valid.write(true);
465  do {
466  wait(this->aw_ready.posedge_event() | clk_delayed);
467  } while(!this->aw_ready.read());
468  auto* fsm_hndl = active_req[tlm::TLM_WRITE_COMMAND];
469  if(axi::is_dataless(fsm_hndl->trans->get_extension<axi::ace_extension>()))
470  react(axi::fsm::protocol_time_point_e::EndReqE, fsm_hndl);
471  wait(clk_i.posedge_event());
472  this->aw_valid.write(false);
473  }
474 }
475 
476 template <typename CFG> inline void axi::pin::ace_lite_initiator<CFG>::wdata_t() {
477  this->w_valid.write(false);
478  wait(sc_core::SC_ZERO_TIME);
479  while(true) {
480  if(!CFG::IS_LITE)
481  this->w_last->write(false);
482  wait(wdata_vl.default_event());
483  auto val = wdata_vl.read();
484  this->w_valid.write(val & 0x1);
485  if(!CFG::IS_LITE)
486  this->w_last->write(val & 0x2);
487  do {
488  wait(this->w_ready.posedge_event() | clk_delayed);
489  if(this->w_ready.read()) {
490  auto evt =
491  CFG::IS_LITE || (val & 0x2) ? axi::fsm::protocol_time_point_e::EndReqE : axi::fsm::protocol_time_point_e::EndPartReqE;
492  react(evt, active_req[tlm::TLM_WRITE_COMMAND]);
493  }
494  } while(!this->w_ready.read());
495  wait(clk_i.posedge_event());
496  this->w_valid.write(false);
497  }
498 }
499 
500 template <typename CFG> inline void axi::pin::ace_lite_initiator<CFG>::b_t() {
501  this->b_ready.write(false);
502  wait(sc_core::SC_ZERO_TIME);
503  while(true) {
504  wait(this->b_valid.posedge_event() | clk_delayed);
505  if(this->b_valid.event() || (!active_resp[tlm::TLM_WRITE_COMMAND] && this->b_valid.read())) {
506  SCCTRACEALL(SCMOD) << " b_t() received b_valid ";
507  auto id = !CFG::IS_LITE ? this->b_id->read().to_uint() : 0U;
508  auto resp = this->b_resp.read();
509  auto& q = wr_resp_by_id[id];
510  sc_assert(q.size());
511  auto* fsm_hndl = q.front();
513  fsm_hndl->trans->get_extension(e);
514  e->set_resp(axi::into<axi::resp_e>(resp));
515  react(axi::fsm::protocol_time_point_e::BegRespE, fsm_hndl);
516  // w_end_resp_evt notified in Endresp
517  wait(w_end_resp_evt);
518  this->b_ready.write(true);
519  wait(clk_i.posedge_event());
520  this->b_ready.write(false);
521  }
522  }
523 }
524 #endif /* _BUS_AXI_PIN_ace_lite_INITIATOR_H_ */
TLM2.0 components modeling AHB.
Definition: axi_initiator.h:30
constexpr ULT to_int(E t)
Definition: axi_tlm.h:47
unsigned get_burst_size(const request &r)
Definition: axi_tlm.h:1157
tlm::tlm_fw_transport_if< TYPES > ace_fw_transport_if
alias declaration for the ACE forward interface
Definition: axi_tlm.h:920
void set_cresp(uint8_t)
set the coherent response status
Definition: axi_tlm.h:1531
void add_to_response_array(response &)
add a read response to the response array
Definition: axi_tlm.h:1598
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
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
uint8_t get_size() const
set the AxSIZE value of the transaction
Definition: axi_tlm.h:1389
void set_resp(resp_e)
set the response status as POD
Definition: axi_tlm.h:1500