Files
DRAMSys/dram/src/simulation/TracePlayer.h
2015-03-25 14:21:37 +01:00

158 lines
4.5 KiB
C++

/*
* traceplayer.h
*
* Created on: Mar 16, 2014
* Author: robert
*/
#ifndef TRACEPLAYER_H_
#define TRACEPLAYER_H_
#include <deque>
#include <tlm.h>
#include <systemc.h>
#include <tlm_utils/simple_initiator_socket.h>
#include <tlm_utils/peq_with_cb_and_phase.h>
#include <iostream>
#include <string>
#include "MemoryManager.h"
#include "../controller/core/configuration/Configuration.h"
#include "../common/DebugManager.h"
#include "../common/xmlAddressdecoder.h"
#include "../common/TlmRecorder.h"
#include "../common/dramExtension.h"
#include "../controller/core/TimingCalculation.h"
#include "TracePlayerListener.h"
using namespace std;
using namespace tlm;
template<unsigned int BUSWIDTH = 128>
struct TracePlayer: public sc_module
{
public:
tlm_utils::simple_initiator_socket<TracePlayer, BUSWIDTH, tlm::tlm_base_protocol_types> iSocket;
TracePlayer(TracePlayerListener* listener);
virtual void nextPayload() = 0;
protected:
gp* allocatePayload();
tlm_utils::peq_with_cb_and_phase<TracePlayer> payloadEventQueue;
void terminate();
void setDataPointer(gp* p, unsigned char * data);
void printDebugMessage(std::string message);
private:
tlm_sync_enum nb_transport_bw(tlm_generic_payload& payload, tlm_phase& phase, sc_time& bwDelay);
void peqCallback(tlm_generic_payload& payload, const tlm_phase& phase);
void sendToTarget(tlm_generic_payload& payload, const tlm_phase& phase, const sc_time& delay);
MemoryManager memoryManager;
unsigned int transactionsSent;
TracePlayerListener* listener;
};
template<unsigned int BUSWIDTH>
TracePlayer<BUSWIDTH>::TracePlayer(TracePlayerListener* listener) :
payloadEventQueue(this, &TracePlayer<BUSWIDTH>::peqCallback), transactionsSent(0), listener(listener)
{
iSocket.register_nb_transport_bw(this, &TracePlayer<BUSWIDTH>::nb_transport_bw);
}
template<unsigned int BUSWIDTH>
gp *TracePlayer<BUSWIDTH>::allocatePayload()
{
return memoryManager.allocate();
}
template<unsigned int BUSWIDTH>
void TracePlayer<BUSWIDTH>::terminate()
{
cout << sc_time_stamp() << " " << this->name() << " terminated" << std::endl;
listener->tracePlayerTerminates();
}
template<unsigned int BUSWIDTH>
void TracePlayer<BUSWIDTH>::printDebugMessage(std::string message)
{
DebugManager::getInstance().printDebugMessage(this->name(), message);
}
template<unsigned int BUSWIDTH>
//TODO: this doesn't depend on the tracePlayer, move it somewhere
void TracePlayer<BUSWIDTH>::setDataPointer(gp* payload, unsigned char * dataElement)
{
//check if payload takes ownership
payload->set_data_length(16*2); // TODO: column / burst breite ..... buswidth * burst /8
payload->set_data_ptr(dataElement);
for(int i = 0; i < 16*2; i++) // TODO: column / burst breite
dataElement[i] = 0;
}
template<unsigned int BUSWIDTH>
tlm_sync_enum TracePlayer<BUSWIDTH>::nb_transport_bw(tlm_generic_payload &payload, tlm_phase &phase, sc_time &bwDelay)
{
payloadEventQueue.notify(payload, phase, bwDelay);
return TLM_ACCEPTED;
}
template<unsigned int BUSWIDTH>
void TracePlayer<BUSWIDTH>::peqCallback(tlm_generic_payload &payload, const tlm_phase &phase)
{
if (phase == BEGIN_REQ)
{
payload.acquire();
GenerationExtension* genExtension = new GenerationExtension(sc_time_stamp());
payload.set_auto_extension(genExtension);
sendToTarget(payload, phase, SC_ZERO_TIME);
transactionsSent++;
DebugManager::getInstance().printDebugMessage(name(),
"Sending transaction number: " + std::to_string(transactionsSent));
}
else if (phase == END_REQ)
{
nextPayload();
}
else if (phase == BEGIN_RESP)
{
//TODO: cleanup:
// unsigned char * dataElement = payload.get_data_ptr();
//
// if(payload.get_command() == TLM_READ_COMMAND)
// {
// cout << "0x";
// for(int i=0; i < 16*2; i++)
// {
// cout << hex << int(dataElement[i]);
// }
// cout << endl;
// }
sendToTarget(payload, END_RESP, SC_ZERO_TIME);
payload.release();
}
else if (phase == END_RESP)
{
}
else
{
SC_REPORT_FATAL(0, "TracePlayer PEQ was triggered with unknown phase");
}
}
template<unsigned int BUSWIDTH>
void TracePlayer<BUSWIDTH>::sendToTarget(tlm_generic_payload &payload, const tlm_phase &phase, const sc_time &delay)
{
tlm_phase TPhase = phase;
sc_time TDelay = delay;
iSocket->nb_transport_fw(payload, TPhase, TDelay);
}
#endif /* TRACEPLAYER_H_ */