gem5 v24.0.0.0
Loading...
Searching...
No Matches
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{
35public:
42
43public:
45
46public:
49 unsigned int nrOfTransactions = 0x5,
50 unsigned int baseAddress = 0x0) :
51 sc_core::sc_module(name),
52 socket("socket"),
53 mNrOfTransactions(nrOfTransactions),
54 mBaseAddress(baseAddress),
56 {
58
59 // register nb_transport method
62
63 // Initiator thread
65
66 }
67
69 {
70 // initialize DMI hint:
71 trans.set_dmi_allowed(false);
72
74 {
77 trans.set_data_ptr(reinterpret_cast<unsigned char*>(&mData));
79
80 }
82 {
84 mData = 0;
85 trans.set_data_ptr(reinterpret_cast<unsigned char*>(&mData));
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 {
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
150 logStartTransation(trans);
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)) {
192 // Transaction Finished, wait for the returned delay
193 wait(t);
194 break;
195
197 case tlm::TLM_UPDATED:
198 // Transaction not yet finished, wait for the end of it
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
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)
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
281 {
282 std::cout << name() << ", <<SimpleLTInitiator1>>:" << std::endl
283 << std::endl;
284 unsigned char data[32];
285
286 transaction_type trans;
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 }
333private:
335
337 unsigned int mNrOfTransactions;
338 unsigned int mBaseAddress;
339 unsigned int mTransactionCount;
340 unsigned int mData;
341};
342
343#endif
const char data[]
SC_HAS_PROCESS(SimpleLTInitiator_ext)
void logStartTransation(transaction_type &trans)
tlm::tlm_sync_enum sync_enum_type
SimpleLTInitiator_ext(sc_core::sc_module_name name, unsigned int nrOfTransactions=0x5, unsigned int baseAddress=0x0)
tlm::tlm_generic_payload transaction_type
void logEndTransaction(transaction_type &trans)
tlm_utils::simple_initiator_socket< SimpleLTInitiator_ext, 32, my_extended_payload_types > initiator_socket_type
initiator_socket_type socket
bool initTransaction(transaction_type &trans)
void invalidate(dmi_type &dmiData)
void invalidate_direct_mem_ptr(sc_dt::uint64 start_range, sc_dt::uint64 end_range)
sync_enum_type myNBTransport(transaction_type &trans, phase_type &phase, sc_core::sc_time &t)
const char * name() const
Definition sc_object.cc:44
unsigned char * get_dmi_ptr() const
Definition dmi.hh:58
sc_dt::uint64 get_start_address() const
Definition dmi.hh:59
sc_core::sc_time get_write_latency() const
Definition dmi.hh:62
sc_dt::uint64 get_end_address() const
Definition dmi.hh:60
bool is_read_write_allowed() const
Definition dmi.hh:76
sc_core::sc_time get_read_latency() const
Definition dmi.hh:61
void set_start_address(sc_dt::uint64 addr)
Definition dmi.hh:82
void set_end_address(sc_dt::uint64 addr)
Definition dmi.hh:83
void set_data_ptr(unsigned char *data)
Definition gp.hh:189
void set_dmi_allowed(bool dmi_allowed)
Definition gp.hh:239
void set_response_status(const tlm_response_status response_status)
Definition gp.hh:204
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
bool is_dmi_allowed() const
Definition gp.hh:244
tlm_command get_command() const
Definition gp.hh:180
T * set_extension(T *ext)
Definition gp.hh:340
void register_nb_transport_bw(MODULE *mod, sync_enum_type(MODULE::*cb)(transaction_type &, phase_type &, sc_core::sc_time &))
void register_invalidate_direct_mem_ptr(MODULE *mod, void(MODULE::*cb)(sc_dt::uint64, sc_dt::uint64))
const sc_time SC_ZERO_TIME
Definition sc_time.cc:290
const sc_time & sc_time_stamp()
Definition sc_main.cc:127
uint64_t uint64
Definition sc_nbdefs.hh:172
@ 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
bool host_has_little_endianness()
Definition helpers.hh:43
#define SC_THREAD(name)
Definition sc_module.hh:313
#define sc_assert(expr)

Generated on Tue Jun 18 2024 16:24:07 for gem5 by doxygen 1.11.0