gem5_to_tlm.cc (13821:f9252f27ded7) gem5_to_tlm.cc (13823:040971e0f728)
1/*
2 * Copyright 2019 Google, Inc.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met: redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer;
8 * redistributions in binary form must reproduce the above copyright

--- 49 unchanged lines hidden (view full) ---

58 * Authors: Gabe Black
59 * Matthias Jung
60 * Abdul Mutaal Ahmad
61 * Christian Menard
62 */
63
64#include "systemc/tlm_bridge/gem5_to_tlm.hh"
65
1/*
2 * Copyright 2019 Google, Inc.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met: redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer;
8 * redistributions in binary form must reproduce the above copyright

--- 49 unchanged lines hidden (view full) ---

58 * Authors: Gabe Black
59 * Matthias Jung
60 * Abdul Mutaal Ahmad
61 * Christian Menard
62 */
63
64#include "systemc/tlm_bridge/gem5_to_tlm.hh"
65
66#include "params/Gem5ToTlmBridge32.hh"
67#include "params/Gem5ToTlmBridge64.hh"
66#include "sim/system.hh"
67#include "systemc/tlm_bridge/sc_ext.hh"
68#include "systemc/tlm_bridge/sc_mm.hh"
69
70namespace sc_gem5
71{
72
73/**

--- 27 unchanged lines hidden (view full) ---

101 /* Do nothing */
102 } else if (packet->isWrite()) {
103 trans.set_command(tlm::TLM_WRITE_COMMAND);
104 } else {
105 SC_REPORT_FATAL("Gem5ToTlmBridge", "No R/W packet");
106 }
107}
108
68#include "sim/system.hh"
69#include "systemc/tlm_bridge/sc_ext.hh"
70#include "systemc/tlm_bridge/sc_mm.hh"
71
72namespace sc_gem5
73{
74
75/**

--- 27 unchanged lines hidden (view full) ---

103 /* Do nothing */
104 } else if (packet->isWrite()) {
105 trans.set_command(tlm::TLM_WRITE_COMMAND);
106 } else {
107 SC_REPORT_FATAL("Gem5ToTlmBridge", "No R/W packet");
108 }
109}
110
111template <unsigned int BITWIDTH>
109void
112void
110Gem5ToTlmBridge::pec(Gem5SystemC::PayloadEvent<Gem5ToTlmBridge> *pe,
113Gem5ToTlmBridge<BITWIDTH>::pec(
114 Gem5SystemC::PayloadEvent<Gem5ToTlmBridge<BITWIDTH>> *pe,
111 tlm::tlm_generic_payload &trans, const tlm::tlm_phase &phase)
112{
113 sc_core::sc_time delay;
114
115 if (phase == tlm::END_REQ ||
116 (&trans == blockingRequest && phase == tlm::BEGIN_RESP)) {
117 sc_assert(&trans == blockingRequest);
118 blockingRequest = nullptr;

--- 39 unchanged lines hidden (view full) ---

158 trans.release();
159 }
160 }
161 }
162 delete pe;
163}
164
165// Similar to TLM's blocking transport (LT)
115 tlm::tlm_generic_payload &trans, const tlm::tlm_phase &phase)
116{
117 sc_core::sc_time delay;
118
119 if (phase == tlm::END_REQ ||
120 (&trans == blockingRequest && phase == tlm::BEGIN_RESP)) {
121 sc_assert(&trans == blockingRequest);
122 blockingRequest = nullptr;

--- 39 unchanged lines hidden (view full) ---

162 trans.release();
163 }
164 }
165 }
166 delete pe;
167}
168
169// Similar to TLM's blocking transport (LT)
170template <unsigned int BITWIDTH>
166Tick
171Tick
167Gem5ToTlmBridge::recvAtomic(PacketPtr packet)
172Gem5ToTlmBridge<BITWIDTH>::recvAtomic(PacketPtr packet)
168{
169 panic_if(packet->cacheResponding(),
170 "Should not see packets where cache is responding");
171
172 panic_if(!(packet->isRead() || packet->isWrite()),
173 "Should only see read and writes at TLM memory\n");
174
175 sc_core::sc_time delay = sc_core::SC_ZERO_TIME;

--- 24 unchanged lines hidden (view full) ---

200 packet->makeResponse();
201 }
202
203 trans->release();
204
205 return delay.value();
206}
207
173{
174 panic_if(packet->cacheResponding(),
175 "Should not see packets where cache is responding");
176
177 panic_if(!(packet->isRead() || packet->isWrite()),
178 "Should only see read and writes at TLM memory\n");
179
180 sc_core::sc_time delay = sc_core::SC_ZERO_TIME;

--- 24 unchanged lines hidden (view full) ---

205 packet->makeResponse();
206 }
207
208 trans->release();
209
210 return delay.value();
211}
212
213template <unsigned int BITWIDTH>
208void
214void
209Gem5ToTlmBridge::recvFunctionalSnoop(PacketPtr packet)
215Gem5ToTlmBridge<BITWIDTH>::recvFunctionalSnoop(PacketPtr packet)
210{
211 // Snooping should be implemented with tlm_dbg_transport.
212 SC_REPORT_FATAL("Gem5ToTlmBridge",
213 "unimplemented func.: recvFunctionalSnoop");
214}
215
216// Similar to TLM's non-blocking transport (AT).
216{
217 // Snooping should be implemented with tlm_dbg_transport.
218 SC_REPORT_FATAL("Gem5ToTlmBridge",
219 "unimplemented func.: recvFunctionalSnoop");
220}
221
222// Similar to TLM's non-blocking transport (AT).
223template <unsigned int BITWIDTH>
217bool
224bool
218Gem5ToTlmBridge::recvTimingReq(PacketPtr packet)
225Gem5ToTlmBridge<BITWIDTH>::recvTimingReq(PacketPtr packet)
219{
220 panic_if(packet->cacheResponding(),
221 "Should not see packets where cache is responding");
222
223 panic_if(!(packet->isRead() || packet->isWrite()),
224 "Should only see read and writes at TLM memory\n");
225
226

--- 77 unchanged lines hidden (view full) ---

304 // Transaction is over nothing has do be done.
305 sc_assert(phase == tlm::END_RESP);
306 trans->release();
307 }
308
309 return true;
310}
311
226{
227 panic_if(packet->cacheResponding(),
228 "Should not see packets where cache is responding");
229
230 panic_if(!(packet->isRead() || packet->isWrite()),
231 "Should only see read and writes at TLM memory\n");
232
233

--- 77 unchanged lines hidden (view full) ---

311 // Transaction is over nothing has do be done.
312 sc_assert(phase == tlm::END_RESP);
313 trans->release();
314 }
315
316 return true;
317}
318
319template <unsigned int BITWIDTH>
312bool
320bool
313Gem5ToTlmBridge::recvTimingSnoopResp(PacketPtr packet)
321Gem5ToTlmBridge<BITWIDTH>::recvTimingSnoopResp(PacketPtr packet)
314{
315 // Snooping should be implemented with tlm_dbg_transport.
316 SC_REPORT_FATAL("Gem5ToTlmBridge",
317 "unimplemented func.: recvTimingSnoopResp");
318 return false;
319}
320
322{
323 // Snooping should be implemented with tlm_dbg_transport.
324 SC_REPORT_FATAL("Gem5ToTlmBridge",
325 "unimplemented func.: recvTimingSnoopResp");
326 return false;
327}
328
329template <unsigned int BITWIDTH>
321bool
330bool
322Gem5ToTlmBridge::tryTiming(PacketPtr packet)
331Gem5ToTlmBridge<BITWIDTH>::tryTiming(PacketPtr packet)
323{
324 panic("tryTiming(PacketPtr) isn't implemented.");
325}
326
332{
333 panic("tryTiming(PacketPtr) isn't implemented.");
334}
335
336template <unsigned int BITWIDTH>
327void
337void
328Gem5ToTlmBridge::recvRespRetry()
338Gem5ToTlmBridge<BITWIDTH>::recvRespRetry()
329{
330 /* Retry a response */
331 sc_assert(blockingResponse);
332
333 tlm::tlm_generic_payload *trans = blockingResponse;
334 blockingResponse = nullptr;
335 PacketPtr packet =
336 Gem5SystemC::Gem5Extension::getExtension(trans).getPacket();

--- 5 unchanged lines hidden (view full) ---

342 sc_core::sc_time delay = sc_core::SC_ZERO_TIME;
343 tlm::tlm_phase phase = tlm::END_RESP;
344 socket->nb_transport_fw(*trans, phase, delay);
345 // Release transaction with all the extensions
346 trans->release();
347}
348
349// Similar to TLM's debug transport.
339{
340 /* Retry a response */
341 sc_assert(blockingResponse);
342
343 tlm::tlm_generic_payload *trans = blockingResponse;
344 blockingResponse = nullptr;
345 PacketPtr packet =
346 Gem5SystemC::Gem5Extension::getExtension(trans).getPacket();

--- 5 unchanged lines hidden (view full) ---

352 sc_core::sc_time delay = sc_core::SC_ZERO_TIME;
353 tlm::tlm_phase phase = tlm::END_RESP;
354 socket->nb_transport_fw(*trans, phase, delay);
355 // Release transaction with all the extensions
356 trans->release();
357}
358
359// Similar to TLM's debug transport.
360template <unsigned int BITWIDTH>
350void
361void
351Gem5ToTlmBridge::recvFunctional(PacketPtr packet)
362Gem5ToTlmBridge<BITWIDTH>::recvFunctional(PacketPtr packet)
352{
353 // Prepare the transaction.
354 tlm::tlm_generic_payload *trans = mm.allocate();
355 trans->acquire();
356 packet2payload(packet, *trans);
357
358 // Attach the packet pointer to the TLM transaction to keep track.
359 auto *extension = new Gem5SystemC::Gem5Extension(packet);

--- 4 unchanged lines hidden (view full) ---

364 if (bytes != trans->get_data_length()) {
365 SC_REPORT_FATAL("Gem5ToTlmBridge",
366 "debug transport was not completed");
367 }
368
369 trans->release();
370}
371
363{
364 // Prepare the transaction.
365 tlm::tlm_generic_payload *trans = mm.allocate();
366 trans->acquire();
367 packet2payload(packet, *trans);
368
369 // Attach the packet pointer to the TLM transaction to keep track.
370 auto *extension = new Gem5SystemC::Gem5Extension(packet);

--- 4 unchanged lines hidden (view full) ---

375 if (bytes != trans->get_data_length()) {
376 SC_REPORT_FATAL("Gem5ToTlmBridge",
377 "debug transport was not completed");
378 }
379
380 trans->release();
381}
382
383template <unsigned int BITWIDTH>
372tlm::tlm_sync_enum
384tlm::tlm_sync_enum
373Gem5ToTlmBridge::nb_transport_bw(tlm::tlm_generic_payload &trans,
385Gem5ToTlmBridge<BITWIDTH>::nb_transport_bw(tlm::tlm_generic_payload &trans,
374 tlm::tlm_phase &phase, sc_core::sc_time &delay)
375{
376 auto *pe = new Gem5SystemC::PayloadEvent<Gem5ToTlmBridge>(
377 *this, &Gem5ToTlmBridge::pec, "PE");
378 Tick nextEventTick = curTick() + delay.value();
379 system->wakeupEventQueue(nextEventTick);
380 system->schedule(pe, nextEventTick);
381 return tlm::TLM_ACCEPTED;
382}
383
386 tlm::tlm_phase &phase, sc_core::sc_time &delay)
387{
388 auto *pe = new Gem5SystemC::PayloadEvent<Gem5ToTlmBridge>(
389 *this, &Gem5ToTlmBridge::pec, "PE");
390 Tick nextEventTick = curTick() + delay.value();
391 system->wakeupEventQueue(nextEventTick);
392 system->schedule(pe, nextEventTick);
393 return tlm::TLM_ACCEPTED;
394}
395
384Gem5ToTlmBridge::Gem5ToTlmBridge(
396template <unsigned int BITWIDTH>
397Gem5ToTlmBridge<BITWIDTH>::Gem5ToTlmBridge(
385 Params *params, const sc_core::sc_module_name &mn) :
398 Params *params, const sc_core::sc_module_name &mn) :
386 sc_core::sc_module(mn), bsp(std::string(name()) + ".gem5", *this),
399 Gem5ToTlmBridgeBase(mn), bsp(std::string(name()) + ".gem5", *this),
387 socket("tlm_socket"),
388 wrapper(socket, std::string(name()) + ".tlm", InvalidPortID),
389 system(params->system), blockingRequest(nullptr),
390 needToSendRequestRetry(false), blockingResponse(nullptr),
391 addrRanges(params->addr_ranges.begin(), params->addr_ranges.end())
392{
393}
394
400 socket("tlm_socket"),
401 wrapper(socket, std::string(name()) + ".tlm", InvalidPortID),
402 system(params->system), blockingRequest(nullptr),
403 needToSendRequestRetry(false), blockingResponse(nullptr),
404 addrRanges(params->addr_ranges.begin(), params->addr_ranges.end())
405{
406}
407
408template <unsigned int BITWIDTH>
395::Port &
409::Port &
396Gem5ToTlmBridge::gem5_getPort(const std::string &if_name, int idx)
410Gem5ToTlmBridge<BITWIDTH>::gem5_getPort(const std::string &if_name, int idx)
397{
398 if (if_name == "gem5")
399 return bsp;
400 else if (if_name == "tlm")
401 return wrapper;
402
403 return sc_core::sc_module::gem5_getPort(if_name, idx);
404}
405
411{
412 if (if_name == "gem5")
413 return bsp;
414 else if (if_name == "tlm")
415 return wrapper;
416
417 return sc_core::sc_module::gem5_getPort(if_name, idx);
418}
419
420template <unsigned int BITWIDTH>
406void
421void
407Gem5ToTlmBridge::before_end_of_elaboration()
422Gem5ToTlmBridge<BITWIDTH>::before_end_of_elaboration()
408{
409 bsp.sendRangeChange();
410
411 socket.register_nb_transport_bw(this, &Gem5ToTlmBridge::nb_transport_bw);
412 sc_core::sc_module::before_end_of_elaboration();
413}
414
415} // namespace sc_gem5
416
423{
424 bsp.sendRangeChange();
425
426 socket.register_nb_transport_bw(this, &Gem5ToTlmBridge::nb_transport_bw);
427 sc_core::sc_module::before_end_of_elaboration();
428}
429
430} // namespace sc_gem5
431
417sc_gem5::Gem5ToTlmBridge *
418Gem5ToTlmBridgeParams::create()
432sc_gem5::Gem5ToTlmBridge<32> *
433Gem5ToTlmBridge32Params::create()
419{
434{
420 return new sc_gem5::Gem5ToTlmBridge(
435 return new sc_gem5::Gem5ToTlmBridge<32>(
421 this, sc_core::sc_module_name(name.c_str()));
422}
436 this, sc_core::sc_module_name(name.c_str()));
437}
438
439sc_gem5::Gem5ToTlmBridge<64> *
440Gem5ToTlmBridge64Params::create()
441{
442 return new sc_gem5::Gem5ToTlmBridge<64>(
443 this, sc_core::sc_module_name(name.c_str()));
444}