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" |
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> |
112void |
113Gem5ToTlmBridge<BITWIDTH>::pec( 114 Gem5SystemC::PayloadEvent<Gem5ToTlmBridge<BITWIDTH>> *pe, |
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> |
171Tick |
172Gem5ToTlmBridge<BITWIDTH>::recvAtomic(PacketPtr packet) |
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> |
214void |
215Gem5ToTlmBridge<BITWIDTH>::recvFunctionalSnoop(PacketPtr packet) |
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> |
224bool |
225Gem5ToTlmBridge<BITWIDTH>::recvTimingReq(PacketPtr packet) |
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> |
320bool |
321Gem5ToTlmBridge<BITWIDTH>::recvTimingSnoopResp(PacketPtr packet) |
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> |
330bool |
331Gem5ToTlmBridge<BITWIDTH>::tryTiming(PacketPtr packet) |
332{ 333 panic("tryTiming(PacketPtr) isn't implemented."); 334} 335 |
336template <unsigned int BITWIDTH> |
337void |
338Gem5ToTlmBridge<BITWIDTH>::recvRespRetry() |
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> |
361void |
362Gem5ToTlmBridge<BITWIDTH>::recvFunctional(PacketPtr packet) |
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> |
384tlm::tlm_sync_enum |
385Gem5ToTlmBridge<BITWIDTH>::nb_transport_bw(tlm::tlm_generic_payload &trans, |
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 |
396template <unsigned int BITWIDTH> 397Gem5ToTlmBridge<BITWIDTH>::Gem5ToTlmBridge( |
398 Params *params, const sc_core::sc_module_name &mn) : |
399 Gem5ToTlmBridgeBase(mn), bsp(std::string(name()) + ".gem5", *this), |
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> |
409::Port & |
410Gem5ToTlmBridge<BITWIDTH>::gem5_getPort(const std::string &if_name, int idx) |
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> |
421void |
422Gem5ToTlmBridge<BITWIDTH>::before_end_of_elaboration() |
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 |
432sc_gem5::Gem5ToTlmBridge<32> * 433Gem5ToTlmBridge32Params::create() |
434{ |
435 return new sc_gem5::Gem5ToTlmBridge<32>( |
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} |