gem5  v22.1.0.0
SimpleATInitiator2.h
Go to the documentation of this file.
1 /*****************************************************************************
2 
3  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
4  more contributor license agreements. See the NOTICE file distributed
5  with this work for additional information regarding copyright ownership.
6  Accellera licenses this file to you under the Apache License, Version 2.0
7  (the "License"); you may not use this file except in compliance with the
8  License. You may obtain a copy of the License at
9 
10  http://www.apache.org/licenses/LICENSE-2.0
11 
12  Unless required by applicable law or agreed to in writing, software
13  distributed under the License is distributed on an "AS IS" BASIS,
14  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15  implied. See the License for the specific language governing
16  permissions and limitations under the License.
17 
18  *****************************************************************************/
19 
20 //====================================================================
21 // Nov 06, 2008
22 //
23 // Updated by:
24 // Xiaopeng Qiu, JEDA Technologies, Inc
25 // Email: qiuxp@jedatechnologies.net
26 //
27 // To fix violations of TLM2.0 rules, which are detected by JEDA
28 // TLM2.0 checker.
29 //
30 //====================================================================
31 
32 #ifndef __SIMPLE_AT_INITIATOR2_H__
33 #define __SIMPLE_AT_INITIATOR2_H__
34 
35 #include "tlm.h"
36 #include "tlm_utils/simple_initiator_socket.h"
37 //#include <systemc>
38 #include <cassert>
39 #include <queue>
40 //#include <iostream>
41 
43 {
44 public:
49 
50 public:
51  // extended transaction, holds tlm_generic_payload + data storage
52  template <typename DT>
54  {
55  public:
57  {
58  this->set_data_ptr(reinterpret_cast<unsigned char*>(&mData));
59  }
61  {
62  this->set_data_ptr(reinterpret_cast<unsigned char*>(&mData));
63  }
64 
65  void setData(DT& data) { mData = data; }
66  DT getData() const { return mData; }
67 
68  private:
69  DT mData;
70  };
72 
73  // Dummy Transaction Pool
75  {
76  public:
79  {
81  t->acquire();
82  return t;
83  }
85  {
86  t->release();
87  }
89  {
90  t->reset();
91  delete t;
92  }
93  };
94 
95 public:
97 
98 public:
101  unsigned int nrOfTransactions = 0x5,
102  unsigned int baseAddress = 0) :
104  socket("socket"),
105  ACCEPT_DELAY(10, sc_core::SC_NS),
106  mNrOfTransactions(nrOfTransactions),
107  mBaseAddress(baseAddress),
110  {
111  // register nb_transport method
113 
114  // Initiator thread
115  SC_THREAD(run);
116  }
117 
119  {
121  trans = transPool.claim();
123  trans->setData(mTransactionCount);
125 
126  } else if (mTransactionCount < 2 * mNrOfTransactions) {
127  trans = transPool.claim();
130 
131  } else {
132  return false;
133  }
134 
135  trans->set_data_length(4);
136  trans->set_streaming_width(4);
137 
139  return true;
140  }
141 
143  {
144  if (trans.get_command() == tlm::TLM_WRITE_COMMAND) {
145  std::cout << name() << ": Send write request: A = 0x"
146  << std::hex << (unsigned int)trans.get_address()
147  << ", D = 0x" << trans.getData() << std::dec
148  << " @ " << sc_core::sc_time_stamp() << std::endl;
149 
150  } else {
151  std::cout << name() << ": Send read request: A = 0x"
152  << std::hex << (unsigned int)trans.get_address() << std::dec
153  << " @ " << sc_core::sc_time_stamp() << std::endl;
154  }
155  }
156 
158  {
159  if (trans.get_response_status() != tlm::TLM_OK_RESPONSE) {
160  std::cout << name() << ": Received error response @ "
161  << sc_core::sc_time_stamp() << std::endl;
162 
163  } else {
164  std::cout << name() << ": Received ok response";
165  if (trans.get_command() == tlm::TLM_READ_COMMAND) {
166  std::cout << ": D = 0x" << std::hex << trans.getData() << std::dec;
167  }
168  std::cout << " @ " << sc_core::sc_time_stamp() << std::endl;
169  }
170  }
171 
172  //
173  // Simple AT Initiator
174  // - Request must be accepted by the target before the next request can be
175  // send
176  // - Responses can come out of order
177  // - Responses will be accepted after fixed delay
178  //
179  void run()
180  {
181  phase_type phase;
183 
184  mytransaction_type* ptrans;
185  while (initTransaction(ptrans)) {
186  // Create transaction and initialise phase and t
187  mytransaction_type& trans = *ptrans;
188  phase = tlm::BEGIN_REQ;
190 
191  logStartTransation(trans);
192 
193  switch (socket->nb_transport_fw(trans, phase, t)) {
194  case tlm::TLM_COMPLETED:
195  // Transaction Finished, wait for the returned delay
196  wait(t);
197  logEndTransaction(trans);
198  transPool.release(&trans);
199  break;
200 
201  case tlm::TLM_ACCEPTED:
202  case tlm::TLM_UPDATED:
203  switch (phase) {
204  case tlm::BEGIN_REQ:
205  // Request phase not yet finished
206  // Wait until end of request phase before sending new request
207 
208  // FIXME
209  mCurrentTransaction = &trans;
212  break;
213 
214  case tlm::END_REQ:
215  // Request phase ended
216  if (t != sc_core::SC_ZERO_TIME) {
217  // Wait until end of request time before sending new request
218  wait(t);
219  }
220  break;
221 
222  case tlm::BEGIN_RESP:
223  // Request phase ended and response phase already started
224  if (t != sc_core::SC_ZERO_TIME) {
225  // Wait until end of request time before sending new request
226  wait(t);
227  }
228  // Notify end of response phase after ACCEPT delay
229  t += ACCEPT_DELAY;
230  phase = tlm::END_RESP;
231  socket->nb_transport_fw(trans, phase, t);
232  logEndTransaction(trans);
233  transPool.release(&trans);
234  break;
235 
236  case tlm::END_RESP: // fall-through
237  default:
238  // A target should never return with these phases
239  // If phase == END_RESP, nb_transport should have returned true
240  assert(0); exit(1);
241  break;
242  }
243  break;
244 
245  default:
246  assert(0); exit(1);
247  };
248  }
249  wait();
250 
251  }
252 
254  {
255  switch (phase) {
256  case tlm::END_REQ:
257  assert(t == sc_core::SC_ZERO_TIME); // FIXME: can t != 0?
258  // Request phase ended
260  return tlm::TLM_ACCEPTED;
261 
262  case tlm::BEGIN_RESP:
263  {
264  assert(t == sc_core::SC_ZERO_TIME); // FIXME: can t != 0?
265 
266  // Notify end of request phase if run thread is waiting for it
267  // FIXME
268  if (&trans == mCurrentTransaction) {
270  }
271 
272  assert(dynamic_cast<mytransaction_type*>(&trans));
273  mytransaction_type* myTrans = static_cast<mytransaction_type*>(&trans);
274  assert(myTrans);
275 
276  // Notify end of response phase after ACCEPT delay
277  t += ACCEPT_DELAY;
278  phase = tlm::END_RESP;
279  logEndTransaction(*myTrans);
280  transPool.release(myTrans);
281 
282  return tlm::TLM_COMPLETED;
283  }
284 
285  case tlm::BEGIN_REQ: // fall-through
286  case tlm::END_RESP: // fall-through
287  default:
288  // A target should never call nb_transport with these phases
289  assert(0); exit(1);
290 // return tlm::TLM_COMPLETED; //unreachable code
291  };
292  }
293 
294 private:
296 
297 private:
298  unsigned int mNrOfTransactions;
299  unsigned int mBaseAddress;
301  unsigned int mTransactionCount;
304 };
305 
306 #endif
const char data[]
MyTransaction(tlm::tlm_mm_interface *mm)
void release(mytransaction_type *t)
mytransaction_type * claim()
void free(tlm::tlm_generic_payload *t)
sc_core::sc_event mEndRequestPhase
bool initTransaction(mytransaction_type *&trans)
tlm::tlm_sync_enum sync_enum_type
initiator_socket_type socket
sync_enum_type myNBTransport(transaction_type &trans, phase_type &phase, sc_core::sc_time &t)
void logEndTransaction(mytransaction_type &trans)
MyTransaction< unsigned int > mytransaction_type
tlm::tlm_generic_payload transaction_type
tlm_utils::simple_initiator_socket< SimpleATInitiator2 > initiator_socket_type
unsigned int mTransactionCount
tlm::tlm_phase phase_type
SimpleATInitiator2(sc_core::sc_module_name name, unsigned int nrOfTransactions=0x5, unsigned int baseAddress=0)
SC_HAS_PROCESS(SimpleATInitiator2)
transaction_type * mCurrentTransaction
void logStartTransation(mytransaction_type &trans)
const sc_core::sc_time ACCEPT_DELAY
unsigned int mNrOfTransactions
Definition: mm.h:9
const char * name() const
Definition: sc_object.cc:44
void set_data_ptr(unsigned char *data)
Definition: gp.hh:189
void set_address(const sc_dt::uint64 address)
Definition: gp.hh:185
void set_command(const tlm_command command)
Definition: gp.hh:181
sc_dt::uint64 get_address() const
Definition: gp.hh:184
tlm_response_status get_response_status() const
Definition: gp.hh:199
void set_data_length(const unsigned int length)
Definition: gp.hh:193
tlm_command get_command() const
Definition: gp.hh:180
void set_streaming_width(const unsigned int streaming_width)
Definition: gp.hh:213
void register_nb_transport_bw(MODULE *mod, sync_enum_type(MODULE::*cb)(transaction_type &, phase_type &, sc_core::sc_time &))
Bitfield< 51 > t
Definition: pagetable.hh:56
Bitfield< 3 > exit
Definition: misc.hh:855
const sc_time SC_ZERO_TIME
Definition: sc_time.cc:290
@ SC_NS
Definition: sc_time.hh:43
const sc_time & sc_time_stamp()
Definition: sc_main.cc:127
@ BEGIN_RESP
Definition: phase.hh:43
@ END_RESP
Definition: phase.hh:44
@ BEGIN_REQ
Definition: phase.hh:41
@ END_REQ
Definition: phase.hh:42
@ TLM_READ_COMMAND
Definition: gp.hh:84
@ TLM_WRITE_COMMAND
Definition: gp.hh:85
@ TLM_OK_RESPONSE
Definition: gp.hh:91
tlm_sync_enum
Definition: fw_bw_ifs.hh:31
@ TLM_COMPLETED
Definition: fw_bw_ifs.hh:31
@ TLM_ACCEPTED
Definition: fw_bw_ifs.hh:31
@ TLM_UPDATED
Definition: fw_bw_ifs.hh:31
#define SC_THREAD(name)
Definition: sc_module.hh:313

Generated on Wed Dec 21 2022 10:22:42 for gem5 by doxygen 1.9.1