merged everythin into one project
This commit is contained in:
50
dram/src/simulation/MemoryManager.cpp
Normal file
50
dram/src/simulation/MemoryManager.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* MemoryManager.cpp
|
||||
*
|
||||
* Created on: Mar 16, 2014
|
||||
* Author: robert
|
||||
*/
|
||||
|
||||
#include "MemoryManager.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
MemoryManager::MemoryManager(): numberOfAllocations(0), numberOfFrees(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
MemoryManager::~MemoryManager()
|
||||
{
|
||||
for(gp* payload: freePayloads)
|
||||
{
|
||||
delete payload;
|
||||
numberOfFrees++;
|
||||
}
|
||||
cout << "Memory Manager: Number of allocated payloads: " << numberOfAllocations << std::endl;
|
||||
cout << "Memory Manager: Number of freed payloads: " << numberOfFrees << std::endl;
|
||||
|
||||
}
|
||||
|
||||
gp* MemoryManager::allocate()
|
||||
{
|
||||
//if(freePayloads.empty())
|
||||
//{
|
||||
//numberOfAllocations++;
|
||||
return new gp(this);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// gp* result = freePayloads.back();
|
||||
// freePayloads.pop_back();
|
||||
// return result;
|
||||
// }
|
||||
}
|
||||
|
||||
void MemoryManager::free(gp* payload)
|
||||
{
|
||||
payload->reset(); //clears all extensions
|
||||
freePayloads.push_back(payload);
|
||||
}
|
||||
|
||||
29
dram/src/simulation/MemoryManager.h
Normal file
29
dram/src/simulation/MemoryManager.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* MemoryManager.h
|
||||
*
|
||||
* Created on: Mar 16, 2014
|
||||
* Author: robert
|
||||
*/
|
||||
|
||||
#ifndef MEMORYMANAGER_H_
|
||||
#define MEMORYMANAGER_H_
|
||||
|
||||
#include <tlm.h>
|
||||
#include <vector>
|
||||
typedef tlm::tlm_generic_payload gp;
|
||||
|
||||
class MemoryManager : public tlm::tlm_mm_interface
|
||||
{
|
||||
public:
|
||||
MemoryManager();
|
||||
virtual ~MemoryManager();
|
||||
virtual gp* allocate();
|
||||
virtual void free(gp* payload);
|
||||
|
||||
private:
|
||||
unsigned int numberOfAllocations;
|
||||
unsigned int numberOfFrees;
|
||||
std::vector<gp*> freePayloads;
|
||||
};
|
||||
|
||||
#endif /* MEMORYMANAGER_H_ */
|
||||
145
dram/src/simulation/arbiter.h
Normal file
145
dram/src/simulation/arbiter.h
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* arbiter.h
|
||||
*
|
||||
* Created on: Mar 16, 2014
|
||||
* Author: robert
|
||||
*/
|
||||
|
||||
#ifndef ARBITER_H_
|
||||
#define ARBITER_H_
|
||||
|
||||
|
||||
|
||||
#include <deque>
|
||||
#include <tlm.h>
|
||||
#include <systemc.h>
|
||||
#include <tlm_utils/simple_target_socket.h>
|
||||
#include <tlm_utils/simple_initiator_socket.h>
|
||||
#include <tlm_utils/peq_with_cb_and_phase.h>
|
||||
#include "../common/xmlAddressdecoder.h"
|
||||
#include "../common/dramExtension.h"
|
||||
#include <iostream>
|
||||
|
||||
|
||||
using namespace std;
|
||||
using namespace tlm;
|
||||
|
||||
template<unsigned int NUMBER_OF_THREADS = 1, unsigned int BUSWIDTH = 128>
|
||||
struct Arbiter: public sc_module
|
||||
{
|
||||
public:
|
||||
tlm_utils::simple_initiator_socket<Arbiter,BUSWIDTH, tlm::tlm_base_protocol_types> iSocket;
|
||||
tlm_utils::simple_target_socket_tagged<Arbiter, BUSWIDTH, tlm::tlm_base_protocol_types> tSockets[NUMBER_OF_THREADS];
|
||||
|
||||
SC_CTOR(Arbiter) :
|
||||
payloadEventQueue(this, &Arbiter::peqCallback), channelIsFree(true)
|
||||
{
|
||||
iSocket.register_nb_transport_bw(this, &Arbiter::nb_transport_bw);
|
||||
|
||||
for (unsigned int i = 0; i < NUMBER_OF_THREADS; ++i)
|
||||
{
|
||||
tSockets[i].register_nb_transport_fw(this, &Arbiter::nb_transport_fw, i);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
tlm_utils::peq_with_cb_and_phase<Arbiter> payloadEventQueue;
|
||||
bool channelIsFree;
|
||||
deque<tlm_generic_payload* > backpressure;
|
||||
|
||||
|
||||
// Initiated by schedulerWrapper
|
||||
tlm_sync_enum nb_transport_bw(tlm_generic_payload& payload, tlm_phase& phase, sc_time& bwDelay)
|
||||
{
|
||||
payloadEventQueue.notify(payload, phase, bwDelay);
|
||||
return TLM_ACCEPTED;
|
||||
}
|
||||
|
||||
// Initiated by .stl players
|
||||
tlm_sync_enum nb_transport_fw(int socketId, tlm_generic_payload& payload, tlm_phase& phase,
|
||||
sc_time& fwDelay)
|
||||
{
|
||||
if(phase == BEGIN_REQ)
|
||||
{
|
||||
appendDramExtension(socketId, payload);
|
||||
payload.acquire();
|
||||
}
|
||||
else if(phase == END_RESP)
|
||||
payload.release();
|
||||
|
||||
payloadEventQueue.notify(payload, phase, fwDelay);
|
||||
return TLM_ACCEPTED;
|
||||
}
|
||||
|
||||
void peqCallback(tlm_generic_payload& payload, const tlm_phase& phase)
|
||||
{
|
||||
//Phases initiated by .stl players
|
||||
if (phase == BEGIN_REQ)
|
||||
{
|
||||
if(channelIsFree)
|
||||
{
|
||||
channelIsFree = false;
|
||||
sendToChannel(payload, phase, SC_ZERO_TIME );
|
||||
}
|
||||
else
|
||||
{
|
||||
backpressure.push_back(&payload);
|
||||
}
|
||||
}
|
||||
|
||||
else if (phase == END_RESP)
|
||||
{
|
||||
sendToChannel(payload, phase, SC_ZERO_TIME );
|
||||
}
|
||||
|
||||
//Phases initiated by dram backend
|
||||
else if (phase == END_REQ)
|
||||
{
|
||||
channelIsFree = true;
|
||||
sendToTraceplayer(DramExtension::getExtension(payload).getThread().ID(), payload, phase, SC_ZERO_TIME);
|
||||
|
||||
if(!backpressure.empty())
|
||||
{
|
||||
tlm_generic_payload* payloadToSend = backpressure.front();
|
||||
backpressure.pop_front();
|
||||
sendToChannel(*payloadToSend, BEGIN_REQ, SC_ZERO_TIME );
|
||||
channelIsFree = false;
|
||||
}
|
||||
}
|
||||
else if (phase == BEGIN_RESP)
|
||||
{
|
||||
sendToTraceplayer(DramExtension::getExtension(payload).getThread().ID(), payload, phase, SC_ZERO_TIME);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL(0, "Payload event queue in arbiter was triggered with unknown phase");
|
||||
}
|
||||
}
|
||||
|
||||
void sendToChannel(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);
|
||||
}
|
||||
|
||||
void sendToTraceplayer(unsigned int id, tlm_generic_payload& payload, const tlm_phase& phase, const sc_time& delay)
|
||||
{
|
||||
tlm_phase TPhase = phase;
|
||||
sc_time TDelay = delay;
|
||||
tSockets[id]->nb_transport_bw(payload, TPhase, TDelay);
|
||||
}
|
||||
|
||||
void appendDramExtension(int socketId, tlm_generic_payload& payload)
|
||||
{
|
||||
node n;
|
||||
xmlAddressDecoder::getInstance().getNode(static_cast<unsigned int>(payload.get_address()), &n);
|
||||
DramExtension* extension = new DramExtension(Thread(socketId), Channel(n.channel), Bank(n.bank), Row(n.row), Column(n.colum));
|
||||
payload.set_auto_extension(extension);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* ARBITER_H_ */
|
||||
270
dram/src/simulation/controllerwrapper.h
Normal file
270
dram/src/simulation/controllerwrapper.h
Normal file
@@ -0,0 +1,270 @@
|
||||
/*
|
||||
* ControllerWrapper.h
|
||||
*
|
||||
* Created on: Mar 15, 2014
|
||||
* Author: gernhard
|
||||
*/
|
||||
|
||||
#ifndef CONTROLLERWRAPPER_H_
|
||||
#define CONTROLLERWRAPPER_H_
|
||||
|
||||
#include <tlm.h>
|
||||
#include <systemc.h>
|
||||
#include <tlm_utils/simple_target_socket.h>
|
||||
#include <tlm_utils/simple_initiator_socket.h>
|
||||
#include <tlm_utils/peq_with_cb_and_phase.h>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
||||
#include "../common/protocol.h"
|
||||
#include "../common/tlmDBPhaseRecorder.h"
|
||||
#include "../core/IWrapperConnector.h"
|
||||
#include "../core/Controller.h"
|
||||
#include "../scheduler/Scheduler.h"
|
||||
#include "../scheduler/Fifo.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace tlm;
|
||||
using namespace core;
|
||||
using namespace scheduler;
|
||||
|
||||
template<unsigned int BUSWIDTH = 128>
|
||||
struct ControllerWrapper: public sc_module, public IWrapperConnector
|
||||
{
|
||||
public:
|
||||
|
||||
tlm_utils::simple_initiator_socket<ControllerWrapper, BUSWIDTH, tlm::tlm_base_protocol_types> iSocket;
|
||||
tlm_utils::simple_target_socket<ControllerWrapper, BUSWIDTH, tlm::tlm_base_protocol_types> tSocket;
|
||||
|
||||
ControllerWrapper(sc_module_name name, tlmDBPhaseRecorder& tpr):
|
||||
frontendPEQ(this, &ControllerWrapper::frontendPEQCallback), dramPEQ(
|
||||
this, &ControllerWrapper::dramPEQCallback), controllerPEQ(this,
|
||||
&ControllerWrapper::controllerPEQCallback), tpr(tpr)
|
||||
{
|
||||
controller = new DramController(*this);
|
||||
scheduler = new Fifo(controller->getBankStates());
|
||||
inputBufferDelay = controller->config.Timings.clk;
|
||||
iSocket.register_nb_transport_bw(this, &ControllerWrapper::nb_transport_bw);
|
||||
tSocket.register_nb_transport_fw(this, &ControllerWrapper::nb_transport_fw);
|
||||
|
||||
for(Bank bank:controller->getBankStates().getBanks())
|
||||
bankIsFreeForRequest[bank] = true;
|
||||
}
|
||||
|
||||
~ControllerWrapper()
|
||||
{
|
||||
delete controller;
|
||||
delete scheduler;
|
||||
}
|
||||
|
||||
virtual void send(const ScheduledCommand& command) override
|
||||
{
|
||||
assert(command.getStart() >= sc_time_stamp());
|
||||
sc_time delay = command.getStart() - sc_time_stamp();
|
||||
tlm::tlm_phase phase;
|
||||
|
||||
switch (command.getCommand())
|
||||
{
|
||||
case Read:
|
||||
phase = BEGIN_RD;
|
||||
break;
|
||||
case Write:
|
||||
phase = BEGIN_WR;
|
||||
break;
|
||||
case Refresh:
|
||||
phase = BEGIN_REFA;
|
||||
break;
|
||||
case Activate:
|
||||
phase = BEGIN_ACT;
|
||||
break;
|
||||
case Precharge:
|
||||
phase = BEGIN_PRE;
|
||||
break;
|
||||
default:
|
||||
SC_REPORT_FATAL(0, "unsupported command in controller wrapper");
|
||||
break;
|
||||
}
|
||||
|
||||
dramPEQ.notify(command.getTransaction(), phase, delay);
|
||||
}
|
||||
|
||||
virtual void send(Trigger trigger, sc_time time) override
|
||||
{
|
||||
assert(time >= sc_time_stamp());
|
||||
sc_time delay = time - sc_time_stamp();
|
||||
controllerPEQ.notify(triggerDummy, REFRESH_TRIGGER, delay);
|
||||
}
|
||||
|
||||
private:
|
||||
DramController* controller;
|
||||
Scheduler* scheduler;
|
||||
map<Bank, bool> bankIsFreeForRequest;
|
||||
|
||||
tlm_utils::peq_with_cb_and_phase<ControllerWrapper> frontendPEQ;
|
||||
tlm_utils::peq_with_cb_and_phase<ControllerWrapper> dramPEQ;
|
||||
tlm_utils::peq_with_cb_and_phase<ControllerWrapper> controllerPEQ;
|
||||
|
||||
sc_time inputBufferDelay;
|
||||
tlm::tlm_generic_payload triggerDummy;
|
||||
tlmDBPhaseRecorder& tpr;
|
||||
|
||||
|
||||
void payloadEntersSystem(tlm_generic_payload& payload)
|
||||
{
|
||||
//std::cout << "----------------------------------------------------------------------- " << std::endl;
|
||||
//std::cout << "Transaction enters system at " << sc_time_stamp() << std::endl;
|
||||
|
||||
Bank bank = DramExtension::getExtension(payload).getBank();
|
||||
scheduler->schedule(&payload);
|
||||
scheduleNextPayload(bank);
|
||||
}
|
||||
|
||||
void scheduleNextPayload(Bank bank)
|
||||
{
|
||||
//std::cout << "----------------------------------------------------------------------- " << std::endl;
|
||||
//std::cout << "In trigger for bank " << bank.ID() << std::endl;
|
||||
|
||||
if(controller->isBusy(sc_time_stamp(), bank))
|
||||
return;
|
||||
else if(scheduler->hasTransactionForBank(bank))
|
||||
{
|
||||
tlm_generic_payload* nextTransaction = scheduler->getTransactionForBank(bank);
|
||||
if(controller->schedule(sc_time_stamp(), *nextTransaction))
|
||||
{
|
||||
//std::cout << "Next payload was scheduled by core " << std::endl;
|
||||
scheduler->popTransactionForBank(bank);
|
||||
}
|
||||
else
|
||||
{
|
||||
//std::cout << "Next payload was not scheduled because of refresh " << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void payloadLeavesSystem(tlm_generic_payload& payload)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Initiated by dram
|
||||
tlm_sync_enum nb_transport_bw(tlm_generic_payload& payload, tlm_phase& phase, sc_time& bwDelay)
|
||||
{
|
||||
dramPEQ.notify(payload, phase, bwDelay);
|
||||
return TLM_ACCEPTED;
|
||||
}
|
||||
|
||||
// Initiated by dram frontend
|
||||
tlm_sync_enum nb_transport_fw(tlm_generic_payload& payload, tlm_phase& phase, sc_time& fwDelay)
|
||||
{
|
||||
DramExtension::getExtension(payload);
|
||||
tpr.recordPhase(payload,phase,sc_time_stamp());
|
||||
|
||||
if (phase == BEGIN_REQ)
|
||||
{
|
||||
payload.acquire();
|
||||
frontendPEQ.notify(payload, phase, inputBufferDelay);
|
||||
}
|
||||
else if (phase == END_RESP)
|
||||
{
|
||||
payloadLeavesSystem(payload);
|
||||
payload.release();
|
||||
}
|
||||
|
||||
return TLM_ACCEPTED;
|
||||
}
|
||||
|
||||
void frontendPEQCallback(tlm_generic_payload& payload, const tlm_phase& phase)
|
||||
{
|
||||
|
||||
if (phase == BEGIN_REQ)
|
||||
{
|
||||
payloadEntersSystem(payload);
|
||||
payload.set_response_status(tlm::TLM_OK_RESPONSE);
|
||||
tpr.recordPhase(payload, END_REQ, sc_time_stamp());
|
||||
sendToFrontend(payload, END_REQ, SC_ZERO_TIME);
|
||||
}
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL(0,
|
||||
"Frontend PEQ event queue in controller wrapper was triggered with unknown phase");
|
||||
}
|
||||
}
|
||||
|
||||
void dramPEQCallback(tlm_generic_payload& payload, const tlm_phase& phase)
|
||||
{
|
||||
tpr.recordPhase(payload,phase,sc_time_stamp());
|
||||
DramExtension *result = NULL;
|
||||
payload.get_extension(result);
|
||||
if(result==NULL)
|
||||
{
|
||||
cout << "ERROR AT TIME " << sc_time_stamp() << std::endl;
|
||||
cout << "Payload " << payload.get_address() << " " << phase;
|
||||
|
||||
assert(result != NULL);
|
||||
}
|
||||
if (phase == BEGIN_RD || phase == BEGIN_WR)
|
||||
{
|
||||
//std::cout << "BEGIN_RD at " <<sc_time_stamp() << " on Bank " << DramExtension::getExtension(payload).getBank().ID() << std::endl;
|
||||
scheduleNextPayload(DramExtension::getExtension(payload).getBank());
|
||||
sendToDram(payload, phase, SC_ZERO_TIME);
|
||||
}
|
||||
else if(phase == BEGIN_REFA || phase == BEGIN_ACT
|
||||
|| phase == BEGIN_PRE)
|
||||
{
|
||||
sendToDram(payload, phase, SC_ZERO_TIME);
|
||||
}
|
||||
else if(phase == END_REFA)
|
||||
{
|
||||
//std::cout << " --- END_REFA --- @:" <<sc_time_stamp() << std::endl;
|
||||
|
||||
for(Bank bank:controller->getBankStates().getBanks())
|
||||
scheduleNextPayload(bank);
|
||||
}
|
||||
else if (phase == END_RD || phase == END_WR)
|
||||
{
|
||||
tpr.recordPhase(payload, BEGIN_RESP, sc_time_stamp());
|
||||
sendToFrontend(payload, BEGIN_RESP, SC_ZERO_TIME);
|
||||
}
|
||||
else if (phase == END_PRE || phase == END_ACT)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL(0,
|
||||
"dramPEQCallback queue in controller wrapper was triggered with unknown phase");
|
||||
}
|
||||
}
|
||||
|
||||
void controllerPEQCallback(tlm_generic_payload& payload, const tlm_phase& phase)
|
||||
{
|
||||
if (phase == REFRESH_TRIGGER)
|
||||
{
|
||||
controller->scheduleRefresh(sc_time_stamp());
|
||||
}
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL(0,
|
||||
"controllerPEQCallback queue in controller wrapper was triggered with unknown phase");
|
||||
}
|
||||
}
|
||||
|
||||
void sendToDram(tlm_generic_payload& payload, const tlm_phase& phase, const sc_time& delay)
|
||||
{
|
||||
DramExtension::getExtension(payload);
|
||||
tlm_phase TPhase = phase;
|
||||
sc_time TDelay = delay;
|
||||
iSocket->nb_transport_fw(payload, TPhase, TDelay);
|
||||
}
|
||||
|
||||
void sendToFrontend(tlm_generic_payload& payload, const tlm_phase& phase, const sc_time& delay)
|
||||
{
|
||||
tlm_phase TPhase = phase;
|
||||
sc_time TDelay = delay;
|
||||
tSocket->nb_transport_bw(payload, TPhase, TDelay);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif /* CONTROLLERWRAPPER_H_ */
|
||||
219
dram/src/simulation/dram.h
Normal file
219
dram/src/simulation/dram.h
Normal file
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
* dram.h
|
||||
*
|
||||
* Created on: Mar 16, 2014
|
||||
* Author: robert
|
||||
*/
|
||||
|
||||
#ifndef DRAM_H_
|
||||
#define DRAM_H_
|
||||
|
||||
|
||||
#include <iomanip>
|
||||
#include <fstream>
|
||||
#include <tlm.h>
|
||||
#include <systemc.h>
|
||||
#include <tlm_utils/peq_with_cb_and_phase.h>
|
||||
#include <tlm_utils/simple_initiator_socket.h>
|
||||
#include <tlm_utils/simple_target_socket.h>
|
||||
|
||||
#include "../common/protocol.h"
|
||||
#include "../common/xmlConfig.h"
|
||||
|
||||
using namespace sc_core;
|
||||
using namespace sc_dt;
|
||||
using namespace std;
|
||||
using namespace tlm;
|
||||
|
||||
xmlConfig xc;
|
||||
|
||||
template <unsigned int BUSWIDTH = 128, unsigned int WORDS = 4096, bool STORE = true, bool FIXED_BL = false, unsigned int FIXED_BL_VALUE = 0>
|
||||
struct Dram: sc_module
|
||||
{
|
||||
tlm_utils::simple_target_socket<Dram, BUSWIDTH, tlm::tlm_base_protocol_types> tSocket;
|
||||
sc_event target_done_event;
|
||||
tlm_utils::peq_with_cb_and_phase<Dram> m_peq;
|
||||
|
||||
SC_CTOR(Dram) : tSocket("socket") ,m_peq(this, &Dram::peq_cb)
|
||||
{
|
||||
tSocket.register_nb_transport_fw(this, &Dram::nb_transport_fw);
|
||||
}
|
||||
|
||||
~Dram()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// TLM-2 non-blocking transport method
|
||||
virtual tlm::tlm_sync_enum nb_transport_fw( tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_time& delay )
|
||||
{
|
||||
// Queue the transaction until the annotated time has elapsed
|
||||
m_peq.notify( trans, phase, delay);
|
||||
return tlm::TLM_ACCEPTED;
|
||||
}
|
||||
|
||||
void peq_cb(tlm::tlm_generic_payload& trans, const tlm::tlm_phase& phase)
|
||||
{
|
||||
if(phase == BEGIN_PRE || phase == AUTO_PRECHARGE)
|
||||
{
|
||||
|
||||
if(phase == BEGIN_PRE)
|
||||
{
|
||||
send_end_pre(trans);
|
||||
}
|
||||
}
|
||||
else if(phase == BEGIN_ACT)
|
||||
{
|
||||
send_end_act(trans);
|
||||
}
|
||||
else if(phase == BEGIN_WR)
|
||||
{
|
||||
send_end_wr(trans,true);
|
||||
}
|
||||
else if(phase == BEGIN_RD)
|
||||
{
|
||||
send_end_rd(trans,true);
|
||||
}
|
||||
else if(phase == BEGIN_WRA)
|
||||
{
|
||||
send_end_wr(trans,false);
|
||||
}
|
||||
else if(phase == BEGIN_RDA)
|
||||
{
|
||||
send_end_rd(trans,false);
|
||||
}
|
||||
else if(phase == BEGIN_REFA)
|
||||
{
|
||||
send_end_refa(trans);
|
||||
}
|
||||
else if(phase == BEGIN_REFB)
|
||||
{
|
||||
send_end_refb(trans);
|
||||
}
|
||||
else if(phase == BEGIN_PDNP)
|
||||
{
|
||||
|
||||
}
|
||||
else if(phase == END_PDNP)
|
||||
{
|
||||
|
||||
}
|
||||
else if(phase == BEGIN_PDNA)
|
||||
{
|
||||
|
||||
}
|
||||
else if(phase == END_PDNA)
|
||||
{
|
||||
|
||||
}
|
||||
else if(phase == BEGIN_SREF)
|
||||
{
|
||||
|
||||
}
|
||||
else if(phase == END_SREF)
|
||||
{
|
||||
|
||||
}
|
||||
else // case tlm::BEGIN_REQ,END_REQ...
|
||||
{
|
||||
SC_REPORT_FATAL("TLM-2", "Illegal transaction phase received by target (2)");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void send_end_refa(tlm::tlm_generic_payload& trans)
|
||||
{
|
||||
tlm::tlm_phase bw_phase;
|
||||
sc_time delay;
|
||||
|
||||
bw_phase = END_REFA;
|
||||
delay = xc.tREFA;
|
||||
|
||||
tSocket->nb_transport_bw( trans, bw_phase, delay );
|
||||
|
||||
}
|
||||
|
||||
void send_end_refb(tlm::tlm_generic_payload& trans)
|
||||
{
|
||||
tlm::tlm_phase bw_phase;
|
||||
sc_time delay;
|
||||
|
||||
bw_phase = END_REFB;
|
||||
delay = xc.tREFB;
|
||||
|
||||
tSocket->nb_transport_bw( trans, bw_phase, delay );
|
||||
|
||||
}
|
||||
|
||||
void send_end_rd(tlm::tlm_generic_payload& trans, bool open_page_policy_f)
|
||||
{
|
||||
tlm::tlm_phase bw_phase;
|
||||
sc_time delay = SC_ZERO_TIME;
|
||||
|
||||
|
||||
unsigned int BL = 2;
|
||||
|
||||
if(open_page_policy_f == true)
|
||||
{
|
||||
bw_phase = END_RD;
|
||||
delay = xc.tRL + xc.clk * BL;
|
||||
}
|
||||
else
|
||||
{
|
||||
bw_phase = END_RDA;
|
||||
delay = xc.tRL + xc.clk * BL;
|
||||
}
|
||||
|
||||
tSocket->nb_transport_bw( trans, bw_phase, delay );
|
||||
}
|
||||
|
||||
void send_end_wr(tlm::tlm_generic_payload& trans, bool open_page_policy_f)
|
||||
{
|
||||
|
||||
tlm::tlm_phase bw_phase;
|
||||
sc_time delay = SC_ZERO_TIME;
|
||||
|
||||
unsigned int BL = 2;
|
||||
|
||||
if(open_page_policy_f == true)
|
||||
{
|
||||
bw_phase = END_WR;
|
||||
delay = xc.tWL + xc.clk * (BL -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
bw_phase = END_WRA;
|
||||
delay = xc.tWL + xc.clk * (BL -1) + xc.tWR;
|
||||
}
|
||||
|
||||
// Send end of WR
|
||||
tSocket->nb_transport_bw( trans, bw_phase, delay );
|
||||
}
|
||||
|
||||
void send_end_pre(tlm::tlm_generic_payload& trans)
|
||||
{
|
||||
tlm::tlm_phase bw_phase;
|
||||
sc_time delay;
|
||||
|
||||
bw_phase = END_PRE;
|
||||
delay = xc.tRP;
|
||||
|
||||
tSocket->nb_transport_bw( trans, bw_phase, delay );
|
||||
}
|
||||
void send_end_act(tlm::tlm_generic_payload& trans)
|
||||
{
|
||||
tlm::tlm_phase bw_phase;
|
||||
sc_time delay;
|
||||
|
||||
bw_phase = END_ACT;
|
||||
delay = xc.tRCD;
|
||||
|
||||
tSocket->nb_transport_bw( trans, bw_phase, delay );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* DRAM_H_ */
|
||||
77
dram/src/simulation/main.cpp
Normal file
77
dram/src/simulation/main.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* main.cpp
|
||||
*
|
||||
* Created on: Mar 16, 2014
|
||||
* Author: robert
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <systemc.h>
|
||||
#include <fstream>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include "../common/tlmDBPhaseRecorder.h"
|
||||
#include "../common/DebugManager.h"
|
||||
#include "../common/xmlAddressdecoder.h"
|
||||
#include "controllerwrapper.h"
|
||||
#include "dram.h"
|
||||
#include "arbiter.h"
|
||||
#include "traceplayer.h"
|
||||
#include <string>
|
||||
#include <ctime>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int sc_main(int argc, char **argv) {
|
||||
|
||||
DebugManager::getInstance().printDebug(Importance::Warning, DebugManager::Sender::Core, SC_ZERO_TIME, "hhh");
|
||||
|
||||
string executableName(argv[0]);
|
||||
string pathOfExecutable = executableName.substr(0,executableName.find_last_of('/'));
|
||||
//string pathToStaticFolder = pathOfExecutable + string("../static");
|
||||
string pathToStaticFolder = string("/home/jonny/git/dram/dram/static");
|
||||
xmlAddressDecoder::URI = pathToStaticFolder + string("/addressConfig.xml");
|
||||
|
||||
tlmDBPhaseRecorder *recorder = new tlmDBPhaseRecorder("tpr.tdb", pathToStaticFolder);
|
||||
|
||||
//TracePlayer<> player("player","/home/robert/traces/trace.stl");
|
||||
//TracePlayer<> player("player",string("/home/robert/common/common/static/test2.stl"));
|
||||
//TracePlayer<> player("player",string("/home/jonny/traces/mediabench-h263encode_32.stl"));
|
||||
TracePlayer<> player("player",string("/home/jonny/traces/mediabench-h263decode_32.stl"));
|
||||
|
||||
cout << "Toplevel: build player" << std::endl;
|
||||
Dram<> dram("dram");
|
||||
cout << "Toplevel: build dram" << std::endl;
|
||||
Arbiter<> arbiter("arbiter");
|
||||
cout << "Toplevel: build arbiter" << std::endl;
|
||||
ControllerWrapper<> controller("controller",*recorder);
|
||||
cout << "Toplevel: build controller" << std::endl;
|
||||
|
||||
cout << "Toplevel: binding sockets" << std::endl;
|
||||
player.iSocket.bind(arbiter.tSockets[0]);
|
||||
arbiter.iSocket.bind(controller.tSocket);
|
||||
controller.iSocket.bind(dram.tSocket);
|
||||
|
||||
cout << "Toplevel: simulation start" << std::endl;
|
||||
|
||||
clock_t begin = clock();
|
||||
sc_start();
|
||||
|
||||
clock_t end = clock();
|
||||
|
||||
double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
|
||||
|
||||
cout << "Simulation took " << elapsed_secs << " seconds. You better optimize your model ! " << endl;
|
||||
|
||||
delete recorder;
|
||||
|
||||
string testingScript = pathToStaticFolder + string("/tests.py");
|
||||
string runTestCommand = string("python ") + testingScript + string(" tpr.tdb");
|
||||
//system(runTestCommand.c_str());
|
||||
|
||||
string run_tpr = "/home/jonny/git/analyzer/build-traceAnalyzer-Desktop-Debug/traceAnalyzer tpr.tdb";
|
||||
system(run_tpr.c_str());
|
||||
return 0;
|
||||
}
|
||||
160
dram/src/simulation/traceplayer.h
Normal file
160
dram/src/simulation/traceplayer.h
Normal file
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* 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"
|
||||
|
||||
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;
|
||||
unsigned int transactionsSend;
|
||||
|
||||
TracePlayer(sc_module_name name, string pathToTrace) :
|
||||
payloadEventQueue(this, &TracePlayer::peqCallback), file(pathToTrace), numberOfPendingTransactions(0), transactionsSend(0)
|
||||
{
|
||||
if (!file.is_open())
|
||||
SC_REPORT_FATAL(0, (string("Could not open trace ") + pathToTrace).c_str());
|
||||
|
||||
if(!file)
|
||||
{
|
||||
SC_REPORT_FATAL(0, "trace is empty! Simulation stops");
|
||||
sc_stop();
|
||||
}
|
||||
|
||||
iSocket.register_nb_transport_bw(this, &TracePlayer::nb_transport_bw);
|
||||
scheduleNextPayload();
|
||||
}
|
||||
|
||||
private:
|
||||
tlm_utils::peq_with_cb_and_phase<TracePlayer> payloadEventQueue;
|
||||
MemoryManager memoryManager;
|
||||
ifstream file;
|
||||
unsigned int numberOfPendingTransactions;
|
||||
|
||||
void scheduleNextPayload()
|
||||
{
|
||||
if(file)
|
||||
{
|
||||
string time,command,address;
|
||||
file >> time >> command >>address;
|
||||
|
||||
//if there is a newline at the end of the .stl
|
||||
if(time.empty() || command.empty() || address.empty())
|
||||
return;
|
||||
|
||||
gp* payload = memoryManager.allocate();
|
||||
long parsedAdress = std::stoi(address.c_str(),0,16);
|
||||
payload->set_address(parsedAdress);
|
||||
|
||||
if(command == "read")
|
||||
{
|
||||
payload->set_command(TLM_READ_COMMAND);
|
||||
}
|
||||
else if(command == "write")
|
||||
{
|
||||
payload->set_command(TLM_WRITE_COMMAND);
|
||||
}
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL(0, (string("Corrupted tracefile, command ") + command + string(" unknown")).c_str());
|
||||
}
|
||||
|
||||
|
||||
payload->set_data_length(BUSWIDTH/8);
|
||||
payload->set_response_status(TLM_INCOMPLETE_RESPONSE);
|
||||
payload->set_dmi_allowed(false);
|
||||
payload->set_byte_enable_length(0);
|
||||
payload->set_streaming_width(0);
|
||||
|
||||
sc_time sendingTime = sc_time(std::stoi(time.c_str()), SC_NS);
|
||||
if(sendingTime <= sc_time_stamp())
|
||||
{
|
||||
payloadEventQueue.notify(*payload,BEGIN_REQ,SC_ZERO_TIME);
|
||||
}
|
||||
else
|
||||
{
|
||||
payloadEventQueue.notify(*payload,BEGIN_REQ,sendingTime - sc_time_stamp());
|
||||
}
|
||||
numberOfPendingTransactions++;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
tlm_sync_enum nb_transport_bw(tlm_generic_payload& payload, tlm_phase& phase, sc_time& bwDelay)
|
||||
{
|
||||
payloadEventQueue.notify(payload, phase, bwDelay);
|
||||
return TLM_ACCEPTED;
|
||||
}
|
||||
|
||||
|
||||
void peqCallback(tlm_generic_payload& payload, const tlm_phase& phase)
|
||||
{
|
||||
if (phase == BEGIN_REQ)
|
||||
{
|
||||
payload.acquire();
|
||||
sendToTarget(payload,phase,SC_ZERO_TIME);
|
||||
//cout << "Sending transaction number: " << transactionsSend << std::endl;
|
||||
transactionsSend++;
|
||||
//cout << "Traceplayer: sending transaction at " << sc_time_stamp() << std::endl;
|
||||
}
|
||||
|
||||
else if (phase == END_REQ)
|
||||
{
|
||||
scheduleNextPayload();
|
||||
}
|
||||
else if (phase == BEGIN_RESP)
|
||||
{
|
||||
payload.release();
|
||||
sendToTarget(payload,END_RESP,SC_ZERO_TIME);
|
||||
numberOfPendingTransactions--;
|
||||
//cout << numberOfPendingTransactions << std::endl;
|
||||
|
||||
if(numberOfPendingTransactions == 0)
|
||||
payloadEventQueue.notify(payload, END_RESP, SC_ZERO_TIME);
|
||||
}
|
||||
|
||||
//kleiner hack
|
||||
else if (phase == END_RESP)
|
||||
{
|
||||
cout << "simulation stop at " << sc_time_stamp() << std::endl;
|
||||
sc_stop();
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL(0, "TracePlayer PEQ was triggered with unknown phase");
|
||||
}
|
||||
}
|
||||
|
||||
void 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_ */
|
||||
Reference in New Issue
Block a user