gem5  v20.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
SimpleATInitiator1.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_INITIATOR1_H__
33 #define __SIMPLE_AT_INITIATOR1_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>
53  class MyTransaction : public transaction_type
54  {
55  public:
57  {
58  this->set_data_ptr(reinterpret_cast<unsigned char*>(&mData));
59  }
60  MyTransaction(tlm::tlm_mm_interface* mm) : transaction_type(mm)
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:
78  mytransaction_type* claim()
79  {
80  mytransaction_type* t = new mytransaction_type(this);
81  t->acquire();
82  return t;
83  }
84  void release(mytransaction_type* t)
85  {
86  t->release();
87  }
89  {
90  t->reset();
91  delete t;
92  }
93  };
94 
95 public:
96  initiator_socket_type socket;
97 
98 public:
101  unsigned int nrOfTransactions = 0x5,
102  unsigned int baseAddress = 0x0) :
103  sc_core::sc_module(name),
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 
119  dont_initialize();
120  }
121 
122  bool initTransaction(mytransaction_type*& trans)
123  {
125  trans = transPool.claim();
127  trans->setData(mTransactionCount);
129 
130  } else if (mTransactionCount < 2 * mNrOfTransactions) {
131  trans = transPool.claim();
134 
135  } else {
136  return false;
137  }
138 
139  trans->set_data_length(4);
140  trans->set_streaming_width(4);
141 
143  return true;
144  }
145 
146  void logStartTransation(mytransaction_type& trans)
147  {
148  if (trans.get_command() == tlm::TLM_WRITE_COMMAND) {
149  std::cout << name() << ": Send write request: A = 0x"
150  << std::hex << (unsigned int)trans.get_address()
151  << ", D = 0x" << trans.getData() << std::dec
152  << " @ " << sc_core::sc_time_stamp() << std::endl;
153 
154  } else {
155  std::cout << name() << ": Send read request: A = 0x"
156  << std::hex << (int)trans.get_address() << std::dec
157  << " @ " << sc_core::sc_time_stamp() << std::endl;
158  }
159  }
160 
161  void logEndTransaction(mytransaction_type& trans)
162  {
163  if (trans.get_response_status() != tlm::TLM_OK_RESPONSE) {
164  std::cout << name() << ": Received error response @ "
165  << sc_core::sc_time_stamp() << std::endl;
166 
167  } else {
168  std::cout << name() << ": Received ok response";
169  if (trans.get_command() == tlm::TLM_READ_COMMAND) {
170  std::cout << ": D = 0x" << trans.getData() << std::dec;
171  }
172  std::cout << " @ " << sc_core::sc_time_stamp() << std::endl;
173  }
174  }
175 
176  //
177  // Simple AT Initiator
178  // - Request must be accepted by the target before the next request can be
179  // send
180  // - Responses can come out of order
181  // - Responses will be accepted after fixed delay
182  //
183  void run()
184  {
185  phase_type phase;
187 
188  mytransaction_type* ptrans;
189  while (initTransaction(ptrans)) {
190  // Create transaction and initialise phase and t
191  mytransaction_type& trans = *ptrans;
192  phase = tlm::BEGIN_REQ;
194 
195  logStartTransation(trans);
196 
197  switch (socket->nb_transport_fw(trans, phase, t)) {
198  case tlm::TLM_COMPLETED:
199  // Transaction Finished, wait for the returned delay
200  wait(t);
201  logEndTransaction(trans);
202  transPool.release(&trans);
203  break;
204 
205  case tlm::TLM_ACCEPTED:
206  case tlm::TLM_UPDATED:
207  switch (phase) {
208  case tlm::BEGIN_REQ:
209  // Request phase not yet finished
210  // Wait until end of request phase before sending new request
211 
212  // FIXME
213  mCurrentTransaction = &trans;
216  break;
217 
218  case tlm::END_REQ:
219  // Request phase ended
220  if (t != sc_core::SC_ZERO_TIME) {
221  // Wait until end of request time before sending new request
222  wait(t);
223  }
224  break;
225 
226  case tlm::BEGIN_RESP:
227  // Request phase ended and response phase already started
228  if (t != sc_core::SC_ZERO_TIME) {
229  // Wait until end of request time before sending new request
230  wait(t);
231  }
232  if (mEndResponseQueue.empty()) {
233  // Notify end of response phase after ACCEPT delay
235  }
236  mEndResponseQueue.push(&trans);
237  break;
238 
239  case tlm::END_RESP: // fall-through
240  default:
241  // A target should never return with these phases
242  // If phase == END_RESP, nb_transport should have returned true
243  assert(0); exit(1);
244  break;
245  }
246  break;
247 
248  default:
249  assert(0); exit(1);
250  };
251  }
252  wait();
253  }
254 
255  sync_enum_type myNBTransport(transaction_type& trans, phase_type& phase, sc_core::sc_time& t)
256  {
257  switch (phase) {
258  case tlm::END_REQ:
259  assert(t == sc_core::SC_ZERO_TIME); // FIXME: can t != 0?
260  // Request phase ended
262  return tlm::TLM_ACCEPTED;
263 
264  case tlm::BEGIN_RESP:
265  {
266  assert(t == sc_core::SC_ZERO_TIME); // FIXME: can t != 0?
267 
268  // Notify end of request phase if run thread is waiting for it
269  // FIXME
270  if (&trans == mCurrentTransaction) {
272  }
273 
274  assert(dynamic_cast<mytransaction_type*>(&trans));
275  mytransaction_type* myTrans = static_cast<mytransaction_type*>(&trans);
276  assert(myTrans);
277 
278  if (mEndResponseQueue.empty()) {
279  // Notify end of response phase after ACCEPT delay
281  }
282  mEndResponseQueue.push(myTrans);
283  return tlm::TLM_ACCEPTED;
284  }
285 
286  case tlm::BEGIN_REQ: // fall-through
287  case tlm::END_RESP: // fall-through
288  default:
289  // A target should never call nb_transport with these phases
290  assert(0); exit(1);
291 // return tlm::TLM_COMPLETED; //unreachable code
292  };
293  }
294 
295  void endResponse()
296  {
297  assert(!mEndResponseQueue.empty());
298  // end response phase
299  phase_type phase = tlm::END_RESP;
301  mytransaction_type* trans = mEndResponseQueue.front();
302  assert(trans);
303  mEndResponseQueue.pop();
304  #if ( ! NDEBUG )
305  sync_enum_type r = socket->nb_transport_fw(*trans, phase, t);
306  #endif /* ! NDEBUG */
307  assert(r == tlm::TLM_COMPLETED); // FIXME: target should return TLM_COMPLETED?
308  assert(t == sc_core::SC_ZERO_TIME); // t must be SC_ZERO_TIME
309 
310  logEndTransaction(*trans);
311  transPool.release(trans);
312 
313  if (!mEndResponseQueue.empty()) {
314  // Notify end of response phase after ACCEPT delay
316  }
317  }
318 
319 private:
321 
322 private:
323  unsigned int mNrOfTransactions;
324  unsigned int mBaseAddress;
326  unsigned int mTransactionCount;
328  std::queue<mytransaction_type*> mEndResponseQueue;
330  transaction_type* mCurrentTransaction;
331 };
332 
333 #endif
SimpleATInitiator1(sc_core::sc_module_name name, unsigned int nrOfTransactions=0x5, unsigned int baseAddress=0x0)
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 &))
mytransaction_type * claim()
bool initTransaction(mytransaction_type *&trans)
Definition: mm.h:8
initiator_socket_type socket
tlm::tlm_generic_payload transaction_type
#define SC_METHOD(name)
Definition: sc_module.hh:299
sc_core::sc_event mEndResponseEvent
Bitfield< 3 > exit
Definition: misc.hh:848
unsigned int mTransactionCount
SC_HAS_PROCESS(SimpleATInitiator1)
const char * name() const
Definition: sc_object.cc:44
sc_sensitive sensitive
Definition: sc_module.hh:206
void dont_initialize()
Definition: sc_module.cc:336
sc_dt::uint64 get_address() const
Definition: gp.hh:184
std::queue< mytransaction_type * > mEndResponseQueue
MyTransaction< unsigned int > mytransaction_type
void set_address(const sc_dt::uint64 address)
Definition: gp.hh:185
#define SC_THREAD(name)
Definition: sc_module.hh:309
MyTransaction(tlm::tlm_mm_interface *mm)
transaction_type * mCurrentTransaction
void release(mytransaction_type *t)
void set_data_ptr(unsigned char *data)
Definition: gp.hh:189
tlm::tlm_sync_enum sync_enum_type
sc_core::sc_event mEndRequestPhase
unsigned int mNrOfTransactions
tlm::tlm_phase phase_type
const sc_time & sc_time_stamp()
Definition: sc_main.cc:128
tlm_response_status get_response_status() const
Definition: gp.hh:199
const sc_time SC_ZERO_TIME
Definition: sc_time.cc:290
void logEndTransaction(mytransaction_type &trans)
sync_enum_type myNBTransport(transaction_type &trans, phase_type &phase, sc_core::sc_time &t)
tlm_command get_command() const
Definition: gp.hh:180
void set_command(const tlm_command command)
Definition: gp.hh:181
void logStartTransation(mytransaction_type &trans)
tlm_sync_enum
Definition: fw_bw_ifs.hh:31
Bitfield< 5 > t
void set_data_length(const unsigned int length)
Definition: gp.hh:193
const char data[]
void free(tlm::tlm_generic_payload *t)
tlm_utils::simple_initiator_socket< SimpleATInitiator1 > initiator_socket_type
const sc_core::sc_time ACCEPT_DELAY

Generated on Thu May 28 2020 16:21:37 for gem5 by doxygen 1.8.13