length on data strobe different for double data rate and single data rate

This commit is contained in:
Janik Schlemminger
2014-04-09 20:15:03 +02:00
24 changed files with 229 additions and 127 deletions

View File

@@ -49,7 +49,10 @@ CREATE TABLE Transactions(
TBank INTEGER,
TRow INTEGER,
TColumn INTEGER,
Command TEXT);
Command TEXT,
DataStrobeBegin INTEGER,
DataStrobeEnd INTEGER
);
CREATE INDEX ranges_index ON Transactions(Range);
CREATE INDEX "phasesTransactions" ON "Phases" ("Transact" ASC);

View File

@@ -35,7 +35,7 @@ def getTraceLength(connection):
@metric
def average_response_latency_in_ns(connection):
cursor = connection.cursor()
cursor.execute("""SELECT avg(ranges.end-ranges.begin) FROM transactions INNER JOIN ranges
cursor.execute("""SELECT avg(ranges.end-ranges.begin)/1000 FROM transactions INNER JOIN ranges
ON transactions.range = ranges.ID where TThread != 0""")
result = cursor.fetchone()
@@ -44,7 +44,7 @@ def average_response_latency_in_ns(connection):
@threadMetric
def average_response_latency_in_ns(connection, thread):
cursor = connection.cursor()
query = """SELECT avg(ranges.end-ranges.begin) FROM transactions INNER JOIN ranges
query = """SELECT avg(ranges.end-ranges.begin)/1000 FROM transactions INNER JOIN ranges
ON transactions.range = ranges.ID where TThread = :Thread """
cursor.execute(query, {"Thread": thread})

View File

@@ -89,9 +89,11 @@ void TlmRecorder::setUpTransactionTerminatingPhases()
void TlmRecorder::prepareSqlStatements()
{
insertTransactionString =
"INSERT INTO Transactions VALUES (:id,:rangeID,:address,:burstlength,:thread,:channel,:bank,:row,:column,:command)";
"INSERT INTO Transactions VALUES (:id,:rangeID,:address,:burstlength,:thread,:channel,:bank,:row,:column,:command,:dataStrobeBegin,:dataStrobeEnd)";
insertRangeString = "INSERT INTO Ranges VALUES (:id,:begin,:end)";
updateRangeString = "UPDATE Ranges SET End = :end WHERE ID = :id";
updateDataStrobeString = "UPDATE Transactions SET DataStrobeBegin = :begin, DataStrobeEnd = :end WHERE ID = :id";
insertPhaseString =
"INSERT INTO Phases (PhaseName,PhaseBegin,PhaseEnd,Transact) VALUES (:name,:begin,:end,:transaction)";
updatePhaseString =
@@ -99,11 +101,13 @@ void TlmRecorder::prepareSqlStatements()
insertGeneralInfoString =
"INSERT INTO GeneralInfo (NumberOfTransactions,TraceEnd,NumberOfBanks,description,clk,UnitOfTime) Values (:numberOfTransactions,:end,:numberOfBanks,:description,:clk,:unitOfTime)";
insertDebugMessageString = "INSERT INTO DebugMessages (Time,Message) Values (:time,:message)";
sqlite3_prepare(db, insertTransactionString.c_str(), -1, &insertTransactionStatement, 0);
sqlite3_prepare(db, insertRangeString.c_str(), -1, &insertRangeStatement, 0);
sqlite3_prepare(db, updateRangeString.c_str(), -1, &updateRangeStatement, 0);
sqlite3_prepare(db, insertPhaseString.c_str(), -1, &insertPhaseStatement, 0);
sqlite3_prepare(db, updatePhaseString.c_str(), -1, &updatePhaseStatement, 0);
sqlite3_prepare(db, updateDataStrobeString.c_str(), -1, &updateDataStrobeStatement, 0);
sqlite3_prepare(db, insertGeneralInfoString.c_str(), -1, &insertGeneralInfoStatement, 0);
sqlite3_prepare(db, insertDebugMessageString.c_str(), -1, &insertDebugMessageStatement, 0);
}
@@ -150,6 +154,8 @@ void TlmRecorder::insertTransactionInDB(unsigned int id, tlm::tlm_generic_payloa
sqlite3_bind_int(insertTransactionStatement, 7, extension.getBank().ID());
sqlite3_bind_int(insertTransactionStatement, 8, extension.getRow().ID());
sqlite3_bind_int(insertTransactionStatement, 9, extension.getColumn().ID());
sqlite3_bind_int(insertTransactionStatement, 10, 0);
sqlite3_bind_int(insertTransactionStatement, 11, 0);
executeSqlStatement(insertTransactionStatement);
}
@@ -181,6 +187,15 @@ void TlmRecorder::updatePhaseEndInDB(string phaseName, const sc_time& time,
executeSqlStatement(updatePhaseStatement);
}
void TlmRecorder::updateDataStrobe(const sc_time& begin,const sc_time& end, tlm::tlm_generic_payload& trans)
{
unsigned int id = getElementFromMap(currentTransactionsInSystem, &trans);
sqlite3_bind_int64(updateDataStrobeStatement, 1, begin.value());
sqlite3_bind_int64(updateDataStrobeStatement, 2, end.value());
sqlite3_bind_int(updateDataStrobeStatement, 3, id);
executeSqlStatement(updateDataStrobeStatement);
}
void TlmRecorder::introduceNewTransactionToSystem(const sc_time& time,
tlm::tlm_generic_payload& trans)
{
@@ -242,8 +257,12 @@ string TlmRecorder::getFileContents(string filename)
in.close();
return (contents);
}
throw(errno);
}
else
{
reportFatal("Error in TraceRecorder", "Could not load sql script from " + filename);
return "";
}
}
void TlmRecorder::printDebugMessage(std::string message)
{

View File

@@ -28,6 +28,7 @@ public:
void recordPhase(tlm::tlm_generic_payload &trans, tlm::tlm_phase phase, sc_time time);
void recordPhase(tlm::tlm_generic_payload &trans, std::string name, sc_time begin, sc_time end);
void recordDebugMessage(std::string message, sc_time time);
void updateDataStrobe(const sc_time& begin, const sc_time& end, tlm::tlm_generic_payload& trans);
void closeConnection();
private:
@@ -61,8 +62,8 @@ private:
std::vector<tlm::tlm_phase> transactionTerminatingPhases;
sqlite3 *db;
sqlite3_stmt *insertTransactionStatement, *insertRangeStatement, *updateRangeStatement,
*insertPhaseStatement, *updatePhaseStatement, *insertGeneralInfoStatement, *insertDebugMessageStatement;
*insertPhaseStatement, *updatePhaseStatement, *insertGeneralInfoStatement, *insertDebugMessageStatement, *updateDataStrobeStatement;
std::string insertTransactionString, insertRangeString, updateRangeString, insertPhaseString, updatePhaseString, insertGeneralInfoString,
insertDebugMessageString;
insertDebugMessageString, updateDataStrobeString;
};
#endif

View File

@@ -24,9 +24,11 @@ namespace core {
std::string ControllerCore::senderName = "Controller Core";
ControllerCore::ControllerCore(IWrapperConnector& wrapperConnector, std::map<Bank, int>& numberOfPayloads) :
config(Configuration::getInstance()), state(&config), wrapper(wrapperConnector), commandChecker(), numberOfPayloads(numberOfPayloads), savedState(
&config), commandSequenceGenerator(state), commandSequenceScheduler(*this)
ControllerCore::ControllerCore(IWrapperConnector& wrapperConnector,
std::map<Bank, int>& numberOfPayloads) :
config(Configuration::getInstance()), state(&config), wrapper(wrapperConnector), commandChecker(), numberOfPayloads(
numberOfPayloads), savedState(&config), commandSequenceGenerator(state), commandSequenceScheduler(
*this)
{
commandChecker[Command::Activate] = new ActivateChecker(config, state);
@@ -106,7 +108,7 @@ void ControllerCore::triggerWakeUp(tlm::tlm_generic_payload& payload, sc_time ti
bool ControllerCore::scheduleRequest(sc_time start, tlm::tlm_generic_payload& payload)
{
start = clkAlign(start, config.Timings.clk);
start = clkAlign(start);
state.cleanUp(start);
saveState();
@@ -136,7 +138,7 @@ bool ControllerCore::isBusy(sc_time time, Bank bank)
{
return (time < lastScheduledCommand.getStart());
}
else if(lastScheduledCommand.commandIsIn({Command::WriteA, Command::ReadA}))
else if (lastScheduledCommand.commandIsIn( { Command::WriteA, Command::ReadA }))
{
return (time < lastScheduledCommand.getEnd());
}

View File

@@ -22,8 +22,8 @@ struct Configuration
static Configuration& getInstance();
string MemoryId;
string MemoryType;
std::string MemoryId;
std::string MemoryType;
//MemSpecification
unsigned int NumberOfBanks;
@@ -42,7 +42,7 @@ struct Configuration
bool AdaptiveOpenPagePolicy;
bool RefreshAwareScheduling;
unsigned int MaxNrOfTransactions;
string Scheduler;
std::string Scheduler;
unsigned int Capsize;
private:

View File

@@ -72,10 +72,11 @@ void MemSpecLoader::loadDDR4(Configuration& config, XMLElement* memspec)
double clkMhz = queryDoubleParameter(timings, "clkMhz");
sc_time clk = sc_time(1 / clkMhz, SC_US);
config.Timings.clk = clk;
//TODO
config.Timings.tRP = clk * queryUIntParameter(timings, "RP");
config.Timings.tRAS = clk * queryUIntParameter(timings, "RAS");
config.Timings.tRC = clk * queryUIntParameter(timings, "RC");
config.Timings.tRTP = clk * queryUIntParameter(timings, "RTP");
config.Timings.tRRD_S = clk * queryUIntParameter(timings, "RRD_S");
config.Timings.tRRD_L = clk * queryUIntParameter(timings, "RRD_L");
config.Timings.tCCD_S = clk * queryUIntParameter(timings, "CCD_S");
@@ -135,6 +136,7 @@ void MemSpecLoader::loadWideIO(Configuration& config, XMLElement* memspec)
config.Timings.tWR = clk * queryUIntParameter(timings, "WR");
config.Timings.tWTR_S = clk * queryUIntParameter(timings, "WTR");
config.Timings.tWTR_L = config.Timings.tWTR_S;
config.Timings.tRTP = SC_ZERO_TIME; //TODO .. not defined in jedec. bl on datastrobe used
config.Timings.tCKESR = clk * queryUIntParameter(timings, "CKESR");
config.Timings.tCKE = clk * queryUIntParameter(timings, "CKE");
config.Timings.tXP = clk * queryUIntParameter(timings, "XP");

View File

@@ -32,6 +32,7 @@ struct TimingConfiguration
sc_time tRC; //RAS-cycle-time (min time bw 2 succesive ACT to same bank)
sc_time tCCD_S; //TODO: relevant? max(bl, tCCD)
sc_time tCCD_L;
sc_time tRTP; //Read to precharge
sc_time tRRD_S; //min time bw 2 succesive ACT to different banks (different bank group)
sc_time tRRD_L; //.. (same bank group)
sc_time tRCD; //act -> read/write

View File

@@ -207,7 +207,7 @@ Command PowerDownManager::getWakeUpCommand(PowerDownState state)
void PowerDownManager::sendPowerDownPayload(sc_time time, Bank bank, Command cmd)
{
time = clkAlign(time, controller.config.Timings.clk); //TODO is clkaligned already?
time = clkAlign(time); //TODO is clkaligned already?
tlm_generic_payload& payload = getPayload(bank);
ScheduledCommand pdn(cmd, time, controller.config.Timings.clk, DramExtension::getExtension(payload));

View File

@@ -112,7 +112,7 @@ void PowerDownManagerGrouped::wakeUpAllForRefresh(sc_time time)
void PowerDownManagerGrouped::sendPowerDownPayload(sc_time time, Command cmd)
{
time = clkAlign(time, controller.config.Timings.clk);
time = clkAlign(time);
//just to find slot
tlm_generic_payload& payload = getPayload(Bank(0));

View File

@@ -79,7 +79,7 @@ void RefreshManager::planNextRefresh()
void RefreshManager::reInitialize(tlm::tlm_generic_payload& payload, sc_time time)
{
nextPlannedRefresh = clkAlign(time, controller.config.Timings.clk, Alignment::DOWN);
nextPlannedRefresh = clkAlign(time, Alignment::DOWN);
planNextRefresh();
}

View File

@@ -104,7 +104,7 @@ void RefreshManagerBankwise::RefreshManagerForBank::planNextRefresh()
void RefreshManagerBankwise::RefreshManagerForBank::reInitialize(tlm::tlm_generic_payload& payload,
sc_time time)
{
nextPlannedRefresh = clkAlign(time, controller.config.Timings.clk, Alignment::DOWN);
nextPlannedRefresh = clkAlign(time, Alignment::DOWN);
planNextRefresh();
}

View File

@@ -7,6 +7,7 @@
#include "ScheduledCommand.h"
#include "../utils/Utils.h"
#include "../../common/Utils.h"
#include "../configuration/Configuration.h"
namespace core {
@@ -82,5 +83,33 @@ bool ScheduledCommand::commandIsIn(const std::vector<Command>& commandSet) const
return isIn(command, commandSet);
}
TimeInterval ScheduledCommand::getIntervalOnDataStrobe() const
{
sc_assert(
getCommand() == Command::Read || getCommand() == Command::ReadA
|| getCommand() == Command::Write
|| getCommand() == Command::WriteA);
TimingConfiguration& timings = Configuration::getInstance().Timings;
sc_time burstLengthOnDataStrobe = getBurstLengthOnDataStrobe(getBurstLength());
if (getCommand() == Command::Read || getCommand() == Command::ReadA)
{
return TimeInterval(getStart() + timings.tRL,
getStart() + timings.tRL + burstLengthOnDataStrobe);
}
else
{
return TimeInterval(getStart() + timings.tWL - timings.clk / 2,
getStart() + timings.tWL + burstLengthOnDataStrobe - timings.clk / 2);
}
}
bool ScheduledCommand::collidesOnDataStrobe(const ScheduledCommand& cmd) const
{
return cmd.getIntervalOnDataStrobe().intersects(getIntervalOnDataStrobe());
}
}

View File

@@ -13,6 +13,7 @@
#include "../Command.h"
#include "../../common/dramExtension.h"
#include "../../common/TlmRecorder.h"
#include "../utils/Utils.h"
namespace core {
@@ -52,6 +53,9 @@ public:
bool commandIsIn(const std::vector<Command>& commandSet) const;
TimeInterval getIntervalOnDataStrobe() const;
bool collidesOnDataStrobe(const ScheduledCommand& command) const;
private:
Command command;

View File

@@ -23,7 +23,7 @@ void PrechargeChecker::delayToSatisfyConstraints(ScheduledCommand& command) cons
if (lastCommand.getCommand() == Command::Read)
{
command.delayToMeetConstraint(lastCommand.getStart(),
lastCommand.getBurstLength() * config.Timings.clk);
max(config.Timings.tRTP , lastCommand.getIntervalOnDataStrobe().getLength()));
}
else if (lastCommand.getCommand() == Command::Write)
{

View File

@@ -23,7 +23,8 @@ void ReadChecker::delayToSatisfyConstraints(ScheduledCommand& command) const
{
command.delayToMeetConstraint(lastCommand.getEnd(), SC_ZERO_TIME);
}
else if (lastCommand.getCommand() == Command::Read || lastCommand.getCommand() == Command::Write)
else if (lastCommand.getCommand() == Command::Read
|| lastCommand.getCommand() == Command::Write)
{
}
else if (lastCommand.getCommand() == Command::PDNAX)
@@ -41,21 +42,6 @@ void ReadChecker::delayToSatisfyConstraints(ScheduledCommand& command) const
}
}
sc_time ReadChecker::getExecutionTime(const tlm::tlm_generic_payload& payload,
Command command) const
{
assert(command == Command::Read || command == Command::ReadA);
if (command == Command::Read)
{
return config.Timings.tRL + config.Timings.clk * payload.get_streaming_width();
}
else
{
return config.Timings.clk * payload.get_streaming_width() + max(config.Timings.tRP,config.Timings.tRL);
}
}
bool ReadChecker::collidesOnDataStrobe(ScheduledCommand& read) const
{
for (ScheduledCommand& strobeCommand : state.lastDataStrobeCommands)
@@ -67,18 +53,32 @@ bool ReadChecker::collidesOnDataStrobe(ScheduledCommand& read) const
return false;
}
sc_time ReadChecker::getExecutionTime(const tlm::tlm_generic_payload& payload,
Command command) const
{
if (command == Command::Read)
{
return config.Timings.tRL + getBurstLengthOnDataStrobe(payload.get_streaming_width());
}
else
{
return getBurstLengthOnDataStrobe(payload.get_streaming_width()) + max(config.Timings.tRP, config.Timings.tRL);
}
}
bool ReadChecker::collidesWithStrobeCommand(ScheduledCommand& read,
ScheduledCommand& strobeCommand) const
{
//read to read
if (strobeCommand.getCommand() == Command::Read || strobeCommand.getCommand() == Command::ReadA)
{
bool collision = getIntervalOnDataStrobe(read).intersects(getIntervalOnDataStrobe(strobeCommand));
bool collision = read.collidesOnDataStrobe(strobeCommand);
sc_time tCCD =
(getBankGroup(read.getBank()) == getBankGroup(strobeCommand.getBank())) ?
config.Timings.tCCD_L : config.Timings.tCCD_S;
bool casToCas = (getDistance(read.getStart(), strobeCommand.getStart()) < tCCD) ? true : false;
bool casToCas =
(getDistance(read.getStart(), strobeCommand.getStart()) < tCCD) ? true : false;
return collision || casToCas;
}
@@ -88,7 +88,7 @@ bool ReadChecker::collidesWithStrobeCommand(ScheduledCommand& read,
//read to write
if (strobeCommand.getStart() >= read.getStart())
{
return !(strobeCommand.getStart() >= getIntervalOnDataStrobe(read).end);
return strobeCommand.getStart() < read.getIntervalOnDataStrobe().end;
}
//write to read
else
@@ -97,7 +97,8 @@ bool ReadChecker::collidesWithStrobeCommand(ScheduledCommand& read,
(getBankGroup(read.getBank()) == getBankGroup(strobeCommand.getBank())) ?
config.Timings.tWTR_L : config.Timings.tWTR_S;
return !(read.getStart()>= getIntervalOnDataStrobe(strobeCommand).end + tWTR);
return read.getStart()
< clkAlign(strobeCommand.getIntervalOnDataStrobe().end, Alignment::DOWN) + tWTR;
}
}
else

View File

@@ -22,6 +22,7 @@ public:
virtual void delayToSatisfyConstraints(ScheduledCommand& command) const override;
virtual sc_time getExecutionTime(const tlm::tlm_generic_payload& payload, Command command) const override;
private:
const Configuration& config;
ControllerState& state;

View File

@@ -47,13 +47,19 @@ sc_time WriteChecker::getExecutionTime(const tlm::tlm_generic_payload& payload,
Command command) const
{
assert(command == Command::Write || command == Command::WriteA);
sc_time lengthOnDataStrobe = getBurstLengthOnDataStrobe(payload.get_streaming_width());
if(Configuration::getInstance().DataRate == 1)
lengthOnDataStrobe -= Configuration::getInstance().Timings.clk;
if (command == Command::Write)
{
return config.Timings.tWL + config.Timings.clk * (payload.get_streaming_width() - 1);
return config.Timings.tWL + lengthOnDataStrobe;
}
else
{
return config.Timings.tWL + config.Timings.clk * payload.get_streaming_width() + config.Timings.tWR;
return config.Timings.tWL + lengthOnDataStrobe + config.Timings.tWR;
}
}
@@ -75,7 +81,7 @@ bool WriteChecker::collidesWithStrobeCommand(ScheduledCommand& write,
if (strobeCommand.getCommand() == Command::Write
|| strobeCommand.getCommand() == Command::WriteA)
{
bool collision = getIntervalOnDataStrobe(write).intersects(getIntervalOnDataStrobe(strobeCommand));
bool collision = write.collidesOnDataStrobe(strobeCommand);
sc_time tCCD =
(getBankGroup(write.getBank()) == getBankGroup(strobeCommand.getBank())) ?
@@ -94,14 +100,13 @@ bool WriteChecker::collidesWithStrobeCommand(ScheduledCommand& write,
(getBankGroup(write.getBank()) == getBankGroup(strobeCommand.getBank())) ?
config.Timings.tWTR_L : config.Timings.tWTR_S;
return !(strobeCommand.getStart()
>= getIntervalOnDataStrobe(write).end + tWTR);
return strobeCommand.getStart()
< clkAlign(write.getIntervalOnDataStrobe().end, Alignment::DOWN) + tWTR;
}
//read to write
else
{
return !(write.getStart() >= getIntervalOnDataStrobe(strobeCommand).end);
return write.getStart() < strobeCommand.getIntervalOnDataStrobe().end;
}
}
else

View File

@@ -34,39 +34,15 @@ sc_time getDelayToMeetConstraint(sc_time previous, sc_time start, sc_time constr
return SC_ZERO_TIME;
}
const sc_time clkAlign(sc_time time, sc_time clk, Alignment alignment)
const sc_time clkAlign(sc_time time, Alignment alignment)
{
sc_time clk = Configuration::getInstance().Timings.clk;
if (alignment == UP)
return ceil(time / clk) * clk;
else
return floor(time / clk) * clk;
}
TimeInterval getIntervalOnDataStrobe(const ScheduledCommand& command)
{
sc_assert(
command.getCommand() == Command::Read || command.getCommand() == Command::ReadA
|| command.getCommand() == Command::Write
|| command.getCommand() == Command::WriteA);
TimingConfiguration& timings = Configuration::getInstance().Timings;
sc_assert((command.getBurstLength() / Configuration::getInstance().DataRate) > 0);
sc_time burstLength = timings.clk
* (command.getBurstLength() / Configuration::getInstance().DataRate);
if (command.getCommand() == Command::Read || command.getCommand() == Command::ReadA)
{
return TimeInterval(command.getStart() + timings.tRL,
command.getStart() + timings.tRL + burstLength);
}
else
{
return TimeInterval(command.getStart() + timings.tWL,
command.getStart() + timings.tWL + burstLength);
}
}
bool isClkAligned(sc_time time, sc_time clk)
{
return !((time / clk) - ceil(time / clk));
@@ -99,3 +75,11 @@ BankGroup getBankGroup(Bank bank)
}
}
sc_time core::getBurstLengthOnDataStrobe(unsigned int burstlength)
{
Configuration& config = Configuration::getInstance();
sc_assert((burstlength / config.DataRate) > 0);
return config.Timings.clk * (burstlength / config.DataRate);
}

View File

@@ -11,29 +11,30 @@
#include <systemc.h>
#include <tlm.h>
#include "../../common/dramExtension.h"
#include "../scheduling/ScheduledCommand.h"
namespace core
{
unsigned int getStartAddress(const Bank& bank);
sc_time getDistance(sc_time a, sc_time b);
struct TimeInterval
{
sc_time start,end;
TimeInterval() : start(SC_ZERO_TIME), end(SC_ZERO_TIME){}
TimeInterval(sc_time start,sc_time end) : start(start), end(end){}
sc_time getLength() {return getDistance(start,end);}
bool timeIsInInterval(sc_time time);
bool intersects(TimeInterval other);
};
sc_time getDistance(sc_time a, sc_time b);
sc_time getBurstLengthOnDataStrobe(unsigned int burstlength);
struct TimingConfiguration;
sc_time getDelayToMeetConstraint(sc_time previous, sc_time start, sc_time constraint);
TimeInterval getIntervalOnDataStrobe(const ScheduledCommand& command);
enum Alignment {UP, DOWN};
const sc_time clkAlign(sc_time time, sc_time clk, Alignment alignment = UP);
const sc_time clkAlign(sc_time time, Alignment alignment = UP);
bool isClkAligned(sc_time time, sc_time clk);
BankGroup getBankGroup(Bank bank);

View File

@@ -61,12 +61,14 @@ public:
void buildScheduler()
{
string selectedScheduler = Configuration::getInstance().Scheduler;
if(selectedScheduler == "FR_FCFS")
scheduler = new FR_FCFS(*controller,Configuration::getInstance().RefreshAwareScheduling,Configuration::getInstance().AdaptiveOpenPagePolicy);
else if(selectedScheduler == "FIFO")
if (selectedScheduler == "FR_FCFS")
scheduler = new FR_FCFS(*controller,
Configuration::getInstance().RefreshAwareScheduling,
Configuration::getInstance().AdaptiveOpenPagePolicy);
else if (selectedScheduler == "FIFO")
scheduler = new Fifo();
else
reportFatal(name(),"unsupporeted scheduler: " + selectedScheduler);
reportFatal(name(), "unsupported scheduler: " + selectedScheduler);
}
void terminateSimulation()
@@ -81,57 +83,98 @@ public:
{
assert(command.getStart() >= sc_time_stamp());
TimeInterval dataStrobe;
TlmRecorder& rec = TlmRecorder::getInstance();
switch (command.getCommand())
{
case Command::Read:
rec.recordPhase(payload, BEGIN_RD, command.getStart());
dataStrobe = command.getIntervalOnDataStrobe();
rec.updateDataStrobe(dataStrobe.start, dataStrobe.end, payload);
rec.recordPhase(payload, END_RD, command.getEnd());
dramPEQ.notify(payload, BEGIN_RD, command.getStart() - sc_time_stamp());
dramPEQ.notify(payload, END_RD, command.getEnd() - sc_time_stamp());
break;
case Command::ReadA:
rec.recordPhase(payload, BEGIN_RDA, command.getStart());
dataStrobe = command.getIntervalOnDataStrobe();
rec.updateDataStrobe(dataStrobe.start, dataStrobe.end, payload);
rec.recordPhase(payload, END_RDA, command.getEnd());
dramPEQ.notify(payload, BEGIN_RDA, command.getStart() - sc_time_stamp());
dramPEQ.notify(payload, END_RDA, command.getEnd() - sc_time_stamp());
break;
case Command::Write:
rec.recordPhase(payload, BEGIN_WR, command.getStart());
dataStrobe = command.getIntervalOnDataStrobe();
rec.updateDataStrobe(dataStrobe.start, dataStrobe.end, payload);
rec.recordPhase(payload, END_WR, command.getEnd());
dramPEQ.notify(payload, BEGIN_WR, command.getStart() - sc_time_stamp());
dramPEQ.notify(payload, END_WR, command.getEnd() - sc_time_stamp());
break;
case Command::WriteA:
rec.recordPhase(payload, BEGIN_WRA, command.getStart());
dataStrobe = command.getIntervalOnDataStrobe();
rec.updateDataStrobe(dataStrobe.start, dataStrobe.end, payload);
rec.recordPhase(payload, END_WRA, command.getEnd());
dramPEQ.notify(payload, BEGIN_WRA, command.getStart() - sc_time_stamp());
dramPEQ.notify(payload, END_WRA, command.getEnd() - sc_time_stamp());
break;
case Command::AutoRefresh:
rec.recordPhase(payload, BEGIN_AUTO_REFRESH, command.getStart());
rec.recordPhase(payload, END_AUTO_REFRESH, command.getEnd());
dramPEQ.notify(payload, BEGIN_AUTO_REFRESH, command.getStart() - sc_time_stamp());
dramPEQ.notify(payload, END_AUTO_REFRESH, command.getEnd() - sc_time_stamp());
break;
case Command::Activate:
rec.recordPhase(payload, BEGIN_ACT, command.getStart());
rec.recordPhase(payload, END_ACT, command.getEnd());
dramPEQ.notify(payload, BEGIN_ACT, command.getStart() - sc_time_stamp());
dramPEQ.notify(payload, END_ACT, command.getEnd() - sc_time_stamp());
break;
case Command::Precharge:
rec.recordPhase(payload, BEGIN_PRE, command.getStart());
rec.recordPhase(payload, END_PRE, command.getEnd());
dramPEQ.notify(payload, BEGIN_PRE, command.getStart() - sc_time_stamp());
dramPEQ.notify(payload, END_PRE, command.getEnd() - sc_time_stamp());
break;
case Command::PrechargeAll:
rec.recordPhase(payload, BEGIN_PRE_ALL, command.getStart());
rec.recordPhase(payload, END_PRE_ALL, command.getEnd());
dramPEQ.notify(payload, BEGIN_PRE_ALL, command.getStart() - sc_time_stamp());
dramPEQ.notify(payload, END_PRE_ALL, command.getEnd() - sc_time_stamp());
break;
case Command::PDNA:
dramPEQ.notify(payload, BEGIN_PDNA, command.getStart() - sc_time_stamp());
rec.recordPhase(payload, BEGIN_PDNA, command.getStart());
break;
case Command::PDNP:
dramPEQ.notify(payload, BEGIN_PDNP, command.getStart() - sc_time_stamp());
rec.recordPhase(payload, BEGIN_PDNP, command.getStart());
break;
case Command::SREF:
dramPEQ.notify(payload, BEGIN_SREF, command.getStart() - sc_time_stamp());
rec.recordPhase(payload, BEGIN_SREF, command.getStart());
break;
case Command::PDNAX:
dramPEQ.notify(payload, END_PDNA, command.getStart() - sc_time_stamp());
rec.recordPhase(payload, END_PDNA, command.getStart());
break;
case Command::PDNPX:
dramPEQ.notify(payload, END_PDNP, command.getStart() - sc_time_stamp());
rec.recordPhase(payload, END_PDNP, command.getStart());
break;
case Command::SREFX:
dramPEQ.notify(payload, END_SREF, command.getStart() - sc_time_stamp());
rec.recordPhase(payload, END_SREF, command.getStart());
break;
default:
SC_REPORT_FATAL(0, "unsupported command in controller");
@@ -195,7 +238,7 @@ private:
void scheduleNextPayload(Bank bank)
{
if(bank.ID() == 5)
if (bank.ID() == 5)
{
int i = 5;
++i;
@@ -282,8 +325,6 @@ private:
void dramPEQCallback(tlm_generic_payload& payload, const tlm_phase& phase)
{
TlmRecorder::getInstance().recordPhase(payload, phase, sc_time_stamp());
Bank bank = DramExtension::getExtension(payload).getBank();
if (phase == BEGIN_RD || phase == BEGIN_WR)
{
@@ -303,7 +344,7 @@ private:
payloadLeavesSystem(payload);
scheduleNextPayload(bank);
}
else if (isIn(phase, { BEGIN_ACT, BEGIN_PRE, BEGIN_PRE_ALL, BEGIN_RDA,BEGIN_WRA }))
else if (isIn(phase, { BEGIN_ACT, BEGIN_PRE, BEGIN_PRE_ALL, BEGIN_RDA, BEGIN_WRA }))
{
sendToDram(payload, phase, SC_ZERO_TIME);
}

View File

@@ -18,35 +18,38 @@ using namespace std;
namespace simulation {
SimulationManager::SimulationManager(sc_module_name name, string memconfig, string memspec,
string stl1, unsigned int burstlength1, string stl2,
unsigned int burstlenght2, string traceName, string pathToResources,
bool silent) :
dram("dram"), arbiter("arbiter"), controller("controller"), player1("player1",
pathToResources + string("traces/") + stl1,burstlength1, this), player2("player2",
pathToResources + string("traces/") + stl2,burstlenght2, this), traceName(traceName)
string stl1, unsigned int burstlength1, string stl2, unsigned int burstlenght2,
string traceName, string pathToResources, bool silent) :
traceName(traceName)
{
SC_THREAD(terminationThread);
cout << pathToResources + string("configs/memconfigs/") + memconfig << endl;
cout << pathToResources + string("configs/memspecs/") + memspec << endl;
xmlAddressDecoder::addressConfigURI = pathToResources + string("configs/addressConfig.xml");
TlmRecorder::dbName = traceName;
TlmRecorder::sqlScriptURI = pathToResources + string("scripts/createTraceDB.sql");
Configuration::memconfigUri = pathToResources + string("configs/memconfigs/") + memconfig;
Configuration::memspecUri = pathToResources + string("configs/memspecs/") + memspec;
player1.iSocket.bind(arbiter.tSockets[0]);
player2.iSocket.bind(arbiter.tSockets[1]);
arbiter.iSocket.bind(controller.tSocket);
controller.iSocket.bind(dram.tSocket);
dram = new Dram<>("dram");
arbiter = new Arbiter<numberOfTracePlayers,128>("arbiter");
controller = new Controller<>("controller");
player1 = new TracePlayer<>("player1", pathToResources + string("traces/") + stl1, burstlength1,
this);
player2 = new TracePlayer<>("player2", pathToResources + string("traces/") + stl2, burstlenght2,
this);
player1->iSocket.bind(arbiter->tSockets[0]);
player2->iSocket.bind(arbiter->tSockets[1]);
arbiter->iSocket.bind(controller->tSocket);
controller->iSocket.bind(dram->tSocket);
vector<string> whiteList;
if(!silent)
if (!silent)
{
whiteList.push_back(controller.name());
whiteList.push_back(player2.name());
whiteList.push_back(player1.name());
whiteList.push_back(controller->name());
whiteList.push_back(player2->name());
whiteList.push_back(player1->name());
whiteList.push_back(this->name());
whiteList.push_back(TlmRecorder::senderName);
whiteList.push_back(ControllerCore::senderName);
@@ -55,14 +58,24 @@ SimulationManager::SimulationManager(sc_module_name name, string memconfig, stri
DebugManager::getInstance().addToWhiteList(whiteList);
}
SimulationManager::~SimulationManager()
{
delete dram;
delete arbiter;
delete controller;
delete player1;
delete player2;
}
void SimulationManager::startSimulation()
{
clock_t begin = clock();
DebugManager::getInstance().printDebugMessage(name(), "Starting simulation");
player1.start();
player2.start();
player1->start();
player2->start();
sc_start();
clock_t end = clock();
@@ -87,13 +100,11 @@ void SimulationManager::terminationThread()
{
wait(terminateSimulation);
DebugManager::getInstance().printDebugMessage(this->name(), "Terminating simulation");
controller.terminateSimulation();
controller->terminateSimulation();
//waits for the termination of all pending powerdown phases in the dram system
wait(sc_time(50, SC_NS));
TlmRecorder::getInstance().closeConnection();
sc_stop();
}
} /* namespace simulation */

View File

@@ -26,6 +26,7 @@ public:
std::string stl1, unsigned int burstlength1, std::string stl2,
unsigned int burstlenght2, std::string traceName, std::string pathToResources,
bool silent = false);
~SimulationManager();
void startSimulation();
void tracePlayerFinishedCallback(string name) override;
@@ -34,11 +35,11 @@ private:
sc_event terminateSimulation;
constexpr static unsigned int numberOfTracePlayers = 2;
std::string traceName;
Dram<> dram;
Arbiter<numberOfTracePlayers, 128> arbiter;
Controller<> controller;
TracePlayer<> player1;
TracePlayer<> player2;
Dram<> *dram;
Arbiter<numberOfTracePlayers, 128> *arbiter;
Controller<> *controller;
TracePlayer<> *player1;
TracePlayer<> *player2;
};
} /* namespace simulation */

View File

@@ -10,6 +10,8 @@
#include "SimulationManager.h"
#include "../core/configuration/Configuration.h"
#include <systemc.h>
using namespace std;
using namespace simulation;
@@ -32,21 +34,15 @@ int sc_main(int argc, char **argv)
string resources = pathOfFile(argv[0]) + string("/../resources/");
string memconfig = "memconfig.xml";
string memspec = "MatzesWideIO.xml";
string memspec = "MICRON_4Gb_DDR4-1866_8bit_A.xml";
// string memspec = "MatzesWideIO.xml";
string stl1 = "chstone-sha_32.stl";
stl1 = "empty.stl";
unsigned int burstlength1 = 8;
unsigned int burstlength1 = 4;
string stl2 = "mediabench-h263decode_32.stl";
stl2 = "trace.stl";
unsigned int burstlength2 = 8;
string traceName = "unaware_long.tdb";
Configuration::memspecUri = "/home/jonny/git/dram/dram/resources/configs/memspecs/MatzesWideIO.xml";
Configuration::memspecUri = "/home/jonny/git/dram/dram/resources/configs/memspecs/MICRON_4Gb_DDR4-1866_8bit_A.xml";
Configuration::memconfigUri = "/home/jonny/git/dram/dram/resources/configs/memconfigs/memconfig.xml";
// Configuration::memconfigUri = resources + string("configs/memconfigs/") + memconfig;
// Configuration::memconfigUri = resources + string("configs/memspecs/") + memspec;
// stl2 = "trace.stl";
unsigned int burstlength2 = 4;
string traceName = "tpr.tdb";
SimulationManager simulationManager("sim",memconfig,memspec,stl1,burstlength1, stl2,burstlength2, traceName, resources,false);
simulationManager.startSimulation();