158 lines
4.5 KiB
C++
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_ */
|
|
|