gem5  v20.1.0.0
SimpleLTInitiator_ext.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 #ifndef __SIMPLE_LT_INITIATOR_EXT_H__
21 #define __SIMPLE_LT_INITIATOR_EXT_H__
22 
23 #include "tlm.h"
24 #include "tlm_utils/simple_initiator_socket.h"
25 #include "my_extension.h"
26 
27 #include <systemc>
28 #include <cassert>
29 #include <iostream>
30 #include <iomanip>
31 #include <map>
32 
34 {
35 public:
37  typedef tlm::tlm_dmi dmi_type;
38  typedef tlm::tlm_phase phase_type;
42 
43 public:
45 
46 public:
49  unsigned int nrOfTransactions = 0x5,
50  unsigned int baseAddress = 0x0) :
52  socket("socket"),
53  mNrOfTransactions(nrOfTransactions),
54  mBaseAddress(baseAddress),
56  {
58 
59  // register nb_transport method
62 
63  // Initiator thread
64  SC_THREAD(run);
65 
66  }
67 
69  {
70  // initialize DMI hint:
71  trans.set_dmi_allowed(false);
72 
74  {
75  trans.set_address(mBaseAddress + 4*mTransactionCount);
77  trans.set_data_ptr(reinterpret_cast<unsigned char*>(&mData));
78  trans.set_command(tlm::TLM_WRITE_COMMAND);
79 
80  }
81  else if (mTransactionCount < 2 * mNrOfTransactions)
82  {
83  trans.set_address(mBaseAddress + 4*(mTransactionCount-mNrOfTransactions));
84  mData = 0;
85  trans.set_data_ptr(reinterpret_cast<unsigned char*>(&mData));
86  trans.set_command(tlm::TLM_READ_COMMAND);
87 
88  }
89  else
90  {
91  return false;
92  }
93 
95  return true;
96  }
97 
99  {
100  if (trans.get_command() == tlm::TLM_WRITE_COMMAND)
101  {
102  std::cout << name() << ": Send write request: A = 0x"
103  << std::hex << (unsigned int)trans.get_address()
104  << ", D = 0x" << mData << std::dec
105  << " @ " << sc_core::sc_time_stamp() << std::endl;
106 
107  }
108  else
109  {
110  std::cout << name() << ": Send read request: A = 0x"
111  << std::hex << (unsigned int)trans.get_address()
112  << std::dec
113  << " @ " << sc_core::sc_time_stamp() << std::endl;
114  }
115  }
116 
118  {
119  if (trans.get_response_status() != tlm::TLM_OK_RESPONSE) {
120  std::cout << name() << ": Received error response @ "
121  << sc_core::sc_time_stamp() << std::endl;
122  }
123  else
124  {
125  std::cout << name() << ": Received ok response";
126  if (trans.get_command() == tlm::TLM_READ_COMMAND) {
127  std::cout << ": D = 0x" << std::hex << mData << std::dec;
128  }
129  std::cout << " @ " << sc_core::sc_time_stamp() << std::endl;
130  }
131  }
132 
133  void run()
134  {
135  transaction_type trans;
136  phase_type phase;
138  // make sure that our transaction has the proper extension:
139  my_extension* tmp_ext = new my_extension();
140  tmp_ext->m_data = 11;
141 
142  trans.set_extension(tmp_ext);
143 
144  while (initTransaction(trans))
145  {
146  // Create transaction and initialise phase and t
147  phase = tlm::BEGIN_REQ;
149 
152  // DMI handling:
153  // We use the DMI hint to check if it makes sense to ask for
154  // DMI pointers. The pattern is:
155  // - if the address is covered by a DMI region do a DMI access
156  // - otherwise do a normal transaction
157  // -> check if we get a DMI hint and acquire the DMI pointers if it
158  // is set
160 
161  // Check if the address is covered by our DMI region
162  if ( (trans.get_address() >= mDMIData.get_start_address()) &&
163  (trans.get_address() <= mDMIData.get_end_address()) )
164  {
165  // We can handle the data here. As the logEndTransaction is
166  // assuming something to happen in the data structure, we really
167  // need to do this:
170  if (trans.get_command() == tlm::TLM_WRITE_COMMAND) {
171  *(unsigned int*)&mDMIData.get_dmi_ptr()[tmp] = mData;
172 
173  } else {
174  mData = *(unsigned int*)&mDMIData.get_dmi_ptr()[tmp];
175  }
176 
177  // Do the wait immediately. Note that doing the wait here eats
178  // almost all the performance anyway, so we only gain something
179  // if we're using temporal decoupling.
180  if (trans.get_command() == tlm::TLM_WRITE_COMMAND) {
182 
183  } else {
185  }
186 
187  logEndTransaction(trans);
188 
189  } else { // we need a full transaction
190  switch (socket->nb_transport_fw(trans, phase, t)) {
191  case tlm::TLM_COMPLETED:
192  // Transaction Finished, wait for the returned delay
193  wait(t);
194  break;
195 
196  case tlm::TLM_ACCEPTED:
197  case tlm::TLM_UPDATED:
198  // Transaction not yet finished, wait for the end of it
199  wait(mEndEvent);
200  break;
201 
202  default:
203  sc_assert(0); exit(1);
204  };
205 
206  logEndTransaction(trans);
207 
208  // Acquire DMI pointer if one is available:
209  if (trans.is_dmi_allowed())
210  {
211  trans.set_write();
212  dmi_type tmp;
213  if (socket->get_direct_mem_ptr(trans,
214  tmp))
215  {
216  // FIXME: No support for separate read/write ranges
217  sc_assert(tmp.is_read_write_allowed());
218  mDMIData = tmp;
219  }
220  }
221  }
222  }
223  delete tmp_ext;
224  wait();
225 
226  }
227 
229  phase_type& phase,
231  {
232  switch (phase) {
233  case tlm::END_REQ:
234  // Request phase ended
235  return tlm::TLM_ACCEPTED;
236 
237  case tlm::BEGIN_RESP:
238  sc_assert(t == sc_core::SC_ZERO_TIME); // FIXME: can t != 0?
239  mEndEvent.notify(t);
240  // Not needed to update the phase if true is returned
241  return tlm::TLM_COMPLETED;
242 
243  case tlm::BEGIN_REQ: // fall-through
244  case tlm::END_RESP: // fall-through
245  default:
246  // A target should never call nb_transport with these phases
247  sc_assert(0); exit(1);
248 // return tlm::TLM_COMPLETED; //unreachable code
249  };
250  }
251 
252  void invalidate(dmi_type& dmiData)
253  {
254  dmiData.set_start_address(1);
255  dmiData.set_end_address(0);
256  }
257 
258  // Invalidate DMI pointer(s)
259  void invalidate_direct_mem_ptr(sc_dt::uint64 start_range,
260  sc_dt::uint64 end_range)
261  {
262  // do the invalidation if there is an address range overlap
263  if (start_range <= mDMIData.get_end_address ()&&
264  end_range >= mDMIData.get_start_address()) {
265  std::cout << name() << ": got DMI pointer invalidation"
266  << " @ " << sc_core::sc_time_stamp() << std::endl;
267 
269  } else {
270  std::cout << name() << ": ignored DMI invalidation for addresses "
271  << std::hex << start_range << ", "
272  << end_range << std::dec
273  << " @ " << sc_core::sc_time_stamp() << std::endl;
274  }
275  }
276 
277  // Test for transport_dbg, this one should fail in bus_dmi as we address
278  // a target that doesn't support transport_dbg:
279  // FIXME: use a configurable address
280  void end_of_simulation()
281  {
282  std::cout << name() << ", <<SimpleLTInitiator1>>:" << std::endl
283  << std::endl;
284  unsigned char data[32];
285 
286  transaction_type trans;
287  trans.set_address(mBaseAddress);
288  trans.set_data_length(32);
289  trans.set_data_ptr(data);
290  trans.set_read();
291 
292  unsigned int n = socket->transport_dbg(trans);
293 
294  std::cout << "Mem @" << std::hex << mBaseAddress << std::endl;
295  unsigned int j = 0;
296 
297  if (n > 0)
298  {
299  // always align endianness, so that we don't get a diff when
300  // printing the raw data
301  int e_start = 0;
302  int e_end = 4;
303  int e_increment = 1;
305  {
306  e_start = 3;
307  e_end = -1;
308  e_increment = -1;
309  }
310 
311  for (unsigned int i=0; i<n; i+=4)
312  {
313  for (int k=e_start; k!=e_end; k+=e_increment)
314  {
315  std::cout << std::setw(2) << std::setfill('0')
316  << (int)data[i+k];
317  j++;
318  if (j==16) {
319  j=0;
320  std::cout << std::endl;
321  } else {
322  std::cout << " ";
323  }
324  }
325  }
326  }
327  else
328  {
329  std::cout << "OK: debug transaction didn't give data." << std::endl;
330  }
331  std::cout << std::dec << std::endl;
332  }
333 private:
335 
337  unsigned int mNrOfTransactions;
338  unsigned int mBaseAddress;
339  unsigned int mTransactionCount;
340  unsigned int mData;
341 };
342 
343 #endif
tlm::tlm_dmi::get_read_latency
sc_core::sc_time get_read_latency() const
Definition: dmi.hh:95
SimpleLTInitiator_ext::logEndTransaction
void logEndTransaction(transaction_type &trans)
Definition: SimpleLTInitiator_ext.h:134
tlm::tlm_generic_payload::set_data_length
void set_data_length(const unsigned int length)
Definition: gp.hh:210
SimpleLTInitiator_ext::SC_HAS_PROCESS
SC_HAS_PROCESS(SimpleLTInitiator_ext)
tlm::tlm_generic_payload::set_write
void set_write()
Definition: gp.hh:196
SC_THREAD
#define SC_THREAD(name)
Definition: sc_module.hh:309
data
const char data[]
Definition: circlebuf.test.cc:42
tlm_utils::simple_initiator_socket_b::register_nb_transport_bw
void register_nb_transport_bw(MODULE *mod, sync_enum_type(MODULE::*cb)(transaction_type &, phase_type &, sc_core::sc_time &))
Definition: simple_initiator_socket.h:97
sc_core::sc_module
Definition: sc_module.hh:97
SimpleLTInitiator_ext::mData
unsigned int mData
Definition: SimpleLTInitiator_ext.h:357
tlm::tlm_phase
Definition: phase.hh:47
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
X86ISA::exit
Bitfield< 3 > exit
Definition: misc.hh:848
tlm::TLM_COMPLETED
@ TLM_COMPLETED
Definition: fw_bw_ifs.hh:65
sc_core
Definition: messages.cc:31
tlm::TLM_WRITE_COMMAND
@ TLM_WRITE_COMMAND
Definition: gp.hh:102
tlm::tlm_dmi
Definition: dmi.hh:46
tlm::TLM_UPDATED
@ TLM_UPDATED
Definition: fw_bw_ifs.hh:65
tlm::TLM_OK_RESPONSE
@ TLM_OK_RESPONSE
Definition: gp.hh:108
tlm::END_REQ
@ END_REQ
Definition: phase.hh:42
sc_core::sc_module::sc_module
sc_module()
Definition: sc_module.cc:256
sc_core::SC_ZERO_TIME
const sc_time SC_ZERO_TIME
Definition: sc_time.cc:290
SimpleLTInitiator_ext::invalidate
void invalidate(dmi_type &dmiData)
Definition: SimpleLTInitiator_ext.h:269
SimpleLTInitiator_ext::mNrOfTransactions
unsigned int mNrOfTransactions
Definition: SimpleLTInitiator_ext.h:354
SimpleLTInitiator_ext::mDMIData
dmi_type mDMIData
Definition: SimpleLTInitiator_ext.h:351
tlm::tlm_generic_payload::is_dmi_allowed
bool is_dmi_allowed() const
Definition: gp.hh:261
SimpleLTInitiator_ext::mBaseAddress
unsigned int mBaseAddress
Definition: SimpleLTInitiator_ext.h:355
sc_assert
#define sc_assert(expr)
Definition: sc_report_handler.hh:135
tlm::tlm_dmi::get_write_latency
sc_core::sc_time get_write_latency() const
Definition: dmi.hh:96
SimpleLTInitiator_ext::invalidate_direct_mem_ptr
void invalidate_direct_mem_ptr(sc_dt::uint64 start_range, sc_dt::uint64 end_range)
Definition: SimpleLTInitiator_ext.h:276
SimpleLTInitiator_ext::initiator_socket_type
tlm_utils::simple_initiator_socket< SimpleLTInitiator_ext, 32, my_extended_payload_types > initiator_socket_type
Definition: SimpleLTInitiator_ext.h:58
ArmISA::n
Bitfield< 31 > n
Definition: miscregs_types.hh:450
tlm_utils::simple_initiator_socket_b::register_invalidate_direct_mem_ptr
void register_invalidate_direct_mem_ptr(MODULE *mod, void(MODULE::*cb)(sc_dt::uint64, sc_dt::uint64))
Definition: simple_initiator_socket.h:105
ArmISA::j
Bitfield< 24 > j
Definition: miscregs_types.hh:54
tlm::tlm_generic_payload::get_command
tlm_command get_command() const
Definition: gp.hh:197
MipsISA::k
Bitfield< 23 > k
Definition: dt_constants.hh:78
my_extension::m_data
int m_data
Definition: my_extension.h:64
sc_dt::uint64
uint64_t uint64
Definition: sc_nbdefs.hh:206
SimpleLTInitiator_ext::end_of_simulation
void end_of_simulation()
Definition: SimpleLTInitiator_ext.h:297
tlm::tlm_generic_payload::set_read
void set_read()
Definition: gp.hh:194
SimpleLTInitiator_ext
Definition: SimpleLTInitiator_ext.h:33
sc_core::sc_event
Definition: sc_event.hh:169
SimpleLTInitiator_ext::mTransactionCount
unsigned int mTransactionCount
Definition: SimpleLTInitiator_ext.h:356
sc_core::sc_time
Definition: sc_time.hh:49
tlm::tlm_dmi::get_end_address
sc_dt::uint64 get_end_address() const
Definition: dmi.hh:94
tlm::TLM_READ_COMMAND
@ TLM_READ_COMMAND
Definition: gp.hh:101
tlm_utils::simple_initiator_socket
Definition: simple_initiator_socket.h:173
tlm::tlm_dmi::get_start_address
sc_dt::uint64 get_start_address() const
Definition: dmi.hh:93
sc_core::sc_module_name
Definition: sc_module_name.hh:41
my_extension.h
SimpleLTInitiator_ext::socket
initiator_socket_type socket
Definition: SimpleLTInitiator_ext.h:61
tlm::END_RESP
@ END_RESP
Definition: phase.hh:44
SimpleLTInitiator_ext::initTransaction
bool initTransaction(transaction_type &trans)
Definition: SimpleLTInitiator_ext.h:85
SimpleLTInitiator_ext::transaction_type
tlm::tlm_generic_payload transaction_type
Definition: SimpleLTInitiator_ext.h:53
SimpleLTInitiator_ext::run
void run()
Definition: SimpleLTInitiator_ext.h:150
tlm::tlm_dmi::get_dmi_ptr
unsigned char * get_dmi_ptr() const
Definition: dmi.hh:92
sc_core::sc_event::notify
void notify()
Definition: sc_event.cc:337
tlm::BEGIN_REQ
@ BEGIN_REQ
Definition: phase.hh:41
tlm::tlm_generic_payload
Definition: gp.hh:133
my_extended_payload_types
Definition: my_extension.h:50
SimpleLTInitiator_ext::sync_enum_type
tlm::tlm_sync_enum sync_enum_type
Definition: SimpleLTInitiator_ext.h:56
ArmISA::t
Bitfield< 5 > t
Definition: miscregs_types.hh:67
tlm::host_has_little_endianness
bool host_has_little_endianness()
Definition: helpers.hh:60
sc_core::sc_object::name
const char * name() const
Definition: sc_object.cc:44
tlm::tlm_generic_payload::set_address
void set_address(const sc_dt::uint64 address)
Definition: gp.hh:202
tlm::tlm_generic_payload::set_extension
T * set_extension(T *ext)
Definition: gp.hh:357
tlm::tlm_sync_enum
tlm_sync_enum
Definition: fw_bw_ifs.hh:48
sc_core::sc_module::wait
void wait()
Definition: sc_module.cc:428
SimpleLTInitiator_ext::mEndEvent
sc_core::sc_event mEndEvent
Definition: SimpleLTInitiator_ext.h:353
SimpleLTInitiator_ext::phase_type
tlm::tlm_phase phase_type
Definition: SimpleLTInitiator_ext.h:55
my_extension
Definition: my_extension.h:26
SimpleLTInitiator_ext::dmi_type
tlm::tlm_dmi dmi_type
Definition: SimpleLTInitiator_ext.h:54
SimpleLTInitiator_ext::SimpleLTInitiator_ext
SimpleLTInitiator_ext(sc_core::sc_module_name name, unsigned int nrOfTransactions=0x5, unsigned int baseAddress=0x0)
Definition: SimpleLTInitiator_ext.h:65
SimpleLTInitiator_ext::myNBTransport
sync_enum_type myNBTransport(transaction_type &trans, phase_type &phase, sc_core::sc_time &t)
Definition: SimpleLTInitiator_ext.h:245
SimpleLTInitiator_ext::logStartTransation
void logStartTransation(transaction_type &trans)
Definition: SimpleLTInitiator_ext.h:115
tlm::tlm_generic_payload::get_address
sc_dt::uint64 get_address() const
Definition: gp.hh:201
sc_core::sc_time_stamp
const sc_time & sc_time_stamp()
Definition: sc_main.cc:128
tlm::BEGIN_RESP
@ BEGIN_RESP
Definition: phase.hh:43
tlm::tlm_generic_payload::set_data_ptr
void set_data_ptr(unsigned char *data)
Definition: gp.hh:206
tlm::tlm_generic_payload::set_response_status
void set_response_status(const tlm_response_status response_status)
Definition: gp.hh:221
tlm::TLM_ACCEPTED
@ TLM_ACCEPTED
Definition: fw_bw_ifs.hh:65

Generated on Wed Sep 30 2020 14:02:18 for gem5 by doxygen 1.8.17