gem5 v24.0.0.0
Loading...
Searching...
No Matches
SimpleLTInitiator1_DMI.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_LT_INITIATOR1_DMI_H__
33#define __SIMPLE_LT_INITIATOR1_DMI_H__
34
35#include "tlm.h"
36#include <systemc>
37#include <cassert>
38#include <iostream>
39#include <iomanip>
40
42 public sc_core::sc_module,
43 public virtual tlm::tlm_bw_transport_if<>
44{
45public:
53
54public:
56
57public:
60 unsigned int nrOfTransactions = 0x5,
61 unsigned int baseAddress = 0x0) :
62 sc_core::sc_module(name),
63 socket("socket"),
64 mNrOfTransactions(nrOfTransactions),
65 mBaseAddress(baseAddress),
67 {
69
70 // Bind this initiator's interface to the initiator socket
71 socket(*this);
72
73 // Initiator thread
75 }
76
78 {
79 // initialize DMI hint:
80 trans.set_dmi_allowed(false);
81
86
87 } else if (mTransactionCount < 2 * mNrOfTransactions) {
89 mData = 0;
91
92 } else {
93 return false;
94 }
95
96 trans.set_data_ptr(reinterpret_cast<unsigned char*>(&mData));
97 trans.set_data_length(4);
98 trans.set_streaming_width(4);
99
101 return true;
102 }
103
105 {
106 if (trans.get_command() == tlm::TLM_WRITE_COMMAND) {
107 std::cout << name() << ": Send write request: A = 0x"
108 << std::hex << (unsigned int)trans.get_address()
109 << ", D = 0x" << mData << std::dec
110 << " @ " << sc_core::sc_time_stamp() << std::endl;
111
112 } else {
113 std::cout << name() << ": Send read request: A = 0x"
114 << std::hex << (unsigned int)trans.get_address() << std::dec
115 << " @ " << sc_core::sc_time_stamp() << std::endl;
116 }
117 }
118
120 {
122 std::cout << name() << ": Received error response @ "
123 << sc_core::sc_time_stamp() << std::endl;
124
125 } else {
126 std::cout << name() << ": Received ok response";
127 if (trans.get_command() == tlm::TLM_READ_COMMAND) {
128 std::cout << ": D = 0x" << std::hex << mData << std::dec;
129 }
130 std::cout << " @ " << sc_core::sc_time_stamp() << std::endl;
131 }
132 }
133
134 void run()
135 {
136 transaction_type trans;
137 phase_type phase;
139
140 while (initTransaction(trans)) {
141 // Create transaction and initialise phase and t
142 phase = tlm::BEGIN_REQ;
144
145 logStartTransation(trans);
146
148 // DMI handling:
149 // We use the DMI hint to check if it makes sense to ask for
150 // DMI pointers. The pattern is:
151 // - if the address is covered by a DMI region do a DMI access
152 // - otherwise do a normal transaction
153 // -> check if we get a DMI hint and acquire the DMI pointers if it is
154 // set
156
157 // Check if the address is covered by our DMI region
158 if ( (trans.get_address() >= mDMIData.get_start_address()) &&
159 (trans.get_address() <= mDMIData.get_end_address()) ) {
160 // We can handle the data here. As the logEndTransaction is assuming
161 // something to happen in the data structure, we really need to
162 // do this:
165 if (trans.get_command() == tlm::TLM_WRITE_COMMAND) {
166 *(unsigned int*)&mDMIData.get_dmi_ptr()[tmp] = mData;
167
168 } else {
169 mData = *(unsigned int*)&mDMIData.get_dmi_ptr()[tmp];
170 }
171
172 // Do the wait immediately. Note that doing the wait here eats almost
173 // all the performance anyway, so we only gain something if we're
174 // using temporal decoupling.
175 if (trans.get_command() == tlm::TLM_WRITE_COMMAND) {
177
178 } else {
180 }
181
182 logEndTransaction(trans);
183
184 } else { // we need a full transaction
185 sc_dt::uint64 addr = trans.get_address(); //Save address before it is mutated
186 socket->b_transport(trans, t);
187 wait(t);
188 logEndTransaction(trans);
189
190 // Acquire DMI pointer on is available:
191 if (trans.is_dmi_allowed())
192 {
193 dmi_type tmp;
194 tmp.init();
195 trans.set_address(addr); //restore address, in case it was mutated.
196 trans.set_write();
197 if ( socket->get_direct_mem_ptr(trans, tmp)
198 && tmp.is_write_allowed() )
199 {
200 mDMIData = tmp;
201 }
202 }
203 }
204 }
205 wait();
206 }
207
209 {
210 // We should never be called
211 assert(0);
212 return tlm::TLM_COMPLETED;
213 }
214
215 void invalidate(dmi_type& dmiData)
216 {
217 dmiData.set_start_address(1);
218 dmiData.set_end_address(0);
219 }
220
221 // Invalidate DMI pointer(s)
223 sc_dt::uint64 end_range)
224 {
225 // do the invalidation if there is an address range overlap
226 if (start_range <= mDMIData.get_end_address ()&&
227 end_range >= mDMIData.get_start_address()) {
228 std::cout << name() << ": got DMI pointer invalidation"
229 << " @ " << sc_core::sc_time_stamp() << std::endl;
230
232 } else {
233 std::cout << name() << ": ignored DMI invalidation for addresses "
234 << std::hex << start_range << ", "
235 << end_range << std::dec
236 << " @ " << sc_core::sc_time_stamp() << std::endl;
237 }
238 }
239
240 // Test for transport_dbg:
241 // FIXME: use a configurable address
243 {
244 std::cout << name() << ", <<SimpleLTInitiator1>>:" << std::endl
245 << std::endl;
246 unsigned char data[32];
247
248 transaction_type trans;
250 trans.set_data_length(32);
251 trans.set_data_ptr(data);
252 trans.set_read();
253
254 unsigned int n = socket->transport_dbg(trans);
255
256 std::cout << "Mem @" << std::hex << mBaseAddress << std::endl;
257 unsigned int j = 0;
258
259 if (n > 0)
260 {
261 // always align endianness, so that we don't get a diff when
262 // printing the raw data
263 int e_start = 0;
264 int e_end = 4;
265 int e_increment = 1;
267 {
268 e_start = 3;
269 e_end = -1;
270 e_increment = -1;
271 }
272
273 for (unsigned int i=0; i<n; i+=4)
274 {
275 for (int k=e_start; k!=e_end; k+=e_increment)
276 {
277 std::cout << std::setw(2) << std::setfill('0')
278 << (int)data[i+k];
279 j++;
280 if (j==16) {
281 j=0;
282 std::cout << std::endl;
283 } else {
284 std::cout << " ";
285 }
286 }
287 }
288 }
289 else
290 {
291 std::cout << "ERROR: debug transaction didn't give data." << std::endl;
292 }
293 std::cout << std::dec << std::endl;
294 }
295private:
297
299 unsigned int mNrOfTransactions;
300 unsigned int mBaseAddress;
301 unsigned int mTransactionCount;
302 unsigned int mData;
303};
304
305#endif
const char data[]
void invalidate(dmi_type &dmiData)
tlm::tlm_fw_transport_if fw_interface_type
void invalidate_direct_mem_ptr(sc_dt::uint64 start_range, sc_dt::uint64 end_range)
tlm::tlm_generic_payload transaction_type
sync_enum_type nb_transport_bw(transaction_type &trans, phase_type &phase, sc_core::sc_time &t)
SC_HAS_PROCESS(SimpleLTInitiator1_dmi)
tlm::tlm_initiator_socket initiator_socket_type
bool initTransaction(transaction_type &trans)
void logEndTransaction(transaction_type &trans)
void logStartTransation(transaction_type &trans)
SimpleLTInitiator1_dmi(sc_core::sc_module_name name, unsigned int nrOfTransactions=0x5, unsigned int baseAddress=0x0)
tlm::tlm_bw_transport_if bw_interface_type
tlm::tlm_sync_enum sync_enum_type
initiator_socket_type socket
const char * name() const
Definition sc_object.cc:44
void init()
Definition dmi.hh:48
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_write_allowed() const
Definition dmi.hh:71
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
void set_streaming_width(const unsigned int streaming_width)
Definition gp.hh:213
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_REQ
Definition phase.hh:41
@ 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
bool host_has_little_endianness()
Definition helpers.hh:43
#define SC_THREAD(name)
Definition sc_module.hh:313

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