corrected checkers for non-interleaving reads/writes. Added burst length to db. Added burst functionally to players

This commit is contained in:
robert
2014-04-07 20:07:44 +02:00
parent 79a7366d9b
commit c1841e4102
24 changed files with 232 additions and 126 deletions

View File

@@ -4,7 +4,7 @@
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-2055719358" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} -E -P -v -dD &quot;${INPUTS}&quot; -std=c++11">
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-64906255729110141" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} -E -P -v -dD &quot;${INPUTS}&quot; -std=c++11">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>

View File

@@ -43,6 +43,7 @@ CREATE TABLE Transactions(
ID INTEGER PRIMARY KEY,
Range INTEGER,
Address INTEGER,
Burstlength INTEGER,
TThread INTEGER,
TChannel INTEGER,
TBank INTEGER,

View File

@@ -26,6 +26,11 @@ def getNumberOfBanks(connection):
result = cursor.fetchone()
return result[0]
def getTraceLength(connection):
cursor = connection.cursor()
cursor.execute("SELECT TraceEnd FROM GeneralInfo")
result = cursor.fetchone()
return result[0]
@metric
def average_response_latency_in_ns(connection):
@@ -60,6 +65,46 @@ def number_of_precharges(connection):
result = cursor.fetchone()
return result[0]
def timeInPowerStates(connection):
totalTimeAllBanks = getTraceLength(connection)*getNumberOfBanks(connection)
cursor = connection.cursor()
result = []
cursor.execute("SELECT SUM(PhaseEnd-PhaseBegin) from Phases where PhaseName = 'PDNA'")
timeInPDNA = cursor.fetchone()
if(timeInPDNA != None):
totalTimeInPDNA = timeInPDNA[0]
else:
totalTimeInPDNA = 0
fractionInPDNA = totalTimeInPDNA*1.0/totalTimeAllBanks
result.append(("Time in PDNA (%)", fractionInPDNA*100))
print("{0} {1}".format(result[-1][0],result[-1][1]))
cursor.execute("SELECT SUM(PhaseEnd-PhaseBegin) from Phases where PhaseName = 'PDNP'")
timeInPDNP = cursor.fetchone()
if(timeInPDNP != None):
totalTimeInPDNP = timeInPDNP[0]
else:
totalTimeInPDNP = 0
fractionInPDNP = totalTimeInPDNP*1.0/totalTimeAllBanks
result.append(("Time in PDNP (%)", fractionInPDNP*100))
print("{0} {1}".format(result[-1][0],result[-1][1]))
cursor.execute("SELECT SUM(PhaseEnd-PhaseBegin) from Phases where PhaseName = 'SREF'")
timeInSREF = cursor.fetchone()
if(timeInSREF != None):
totalTimeInSREF = timeInSREF[0]
else:
totalTimeInSREF = 0
fractionInSREF = totalTimeInSREF*1.0/totalTimeAllBanks
result.append(("Time in SREF (%)", fractionInSREF*100))
print("{0} {1}".format(result[-1][0],result[-1][1]))
result.insert(0,("Active time (%)", 1-fractionInPDNA-fractionInPDNP-fractionInSREF))
print("{0} {1}".format(result[0][0],result[0][1]))
return result
def passRatio(connection):
numberOfPassWins = {}
@@ -95,9 +140,14 @@ def passRatio(connection):
result = []
for thread in getThreads(connection):
print("Thread {0} passed other threads {1} times and was passed {2} times. Ratio is {3}".format
(thread, numberOfPassWins[thread], numberOfPassLosses[thread], numberOfPassWins[thread]*1.0/(numberOfPassWins[thread]+numberOfPassLosses[thread])))
result.append(("Thread {0} pass ratio".format(thread), numberOfPassWins[thread]*1.0/(numberOfPassWins[thread]+numberOfPassLosses[thread])))
totalPassedInvolved = numberOfPassWins[thread]+numberOfPassLosses[thread]
if(totalPassedInvolved > 0):
passRatio = numberOfPassWins[thread]*1.0/(numberOfPassWins[thread]+numberOfPassLosses[thread])
else:
passRatio = 0.5
print("Thread {0} passed other threads {1} times and was passed {2} times. Pass ratio is {3}".format
(thread, numberOfPassWins[thread], numberOfPassLosses[thread],passRatio))
result.append(("Thread {0} pass ratio".format(thread), passRatio))
return result
@@ -122,7 +172,7 @@ def calculateMetrics(pathToTrace):
calculatedMetrics.append(res)
calculatedMetrics.extend(passRatio(connection))
calculatedMetrics.extend(timeInPowerStates(connection))
connection.close()
return calculatedMetrics

View File

@@ -7,10 +7,11 @@ class DramConfig(object):
unitOfTime = "ns"
nActivateWindow = 0
burstLengtht = 2
clk = numberOfBanks = 0
tRP = tRAS = tRC = tRRD = tRCD = tTAW = tRL = tWL = tWTR = tRFC = tWR = 0
tReadLength = tWriteLength = 0
bankwiseRefresh = False
bankwisePowerdown = False
def clkAlign(self, value):
return math.ceil(1.0*value/self.clk)*self.clk
@@ -32,15 +33,21 @@ class DramConfig(object):
self.tWR = 2*self.clk
self.tTAW = self.clkAlign(50)
self.tRFC = self.clkAlign(130)
self.tReadLength = self.tRL + self.burstLength * self.clk
self.tWriteLength = self.tWL + (self.burstLength - 1) *self.clk
self.tCKESR = self.clkAlign(max(3*self.clk, 15))
def __init__(self):
self.parseFromXml()
dramconfig = DramConfig()
def calculateReadLength(burstLength):
return dramconfig.tRL + burstLength * dramconfig.clk
def calculateWriteLength(burstLength):
return dramconfig.tWL + burstLength * dramconfig.clk
# ----------- test utils ---------------------------------------
@@ -88,11 +95,23 @@ def commands_are_clockaligned(connection):
def commandbus_slots_are_used_once(connection):
"""Checks that no two phases on the command bus start at the same time"""
cursor = connection.cursor()
cursor.execute("SELECT PhaseBegin,count FROM (SELECT phaseBegin,count(phasebegin) AS count FROM Phases WHERE PhaseName NOT IN ('RESP','REQ') GROUP BY phaseBegin) WHERE count>1")
result = cursor.fetchone()
if dramconfig.bankwisePowerdown and dramconfig.bankwiseRefresh:
excludedPhases = "('REQ','RESP','PRE_ALL')"
elif (not dramconfig.bankwisePowerdown and dramconfig.bankwiseRefresh):
excludedPhases = "('REQ','RESP','PRE_ALL','PDNA','PDNP','SREF')"
elif dramconfig.bankwisePowerdown and not dramconfig.bankwiseRefresh:
excludedPhases = "('REQ','RESP','PRE_ALL','AUTO_REFRESH')"
else:
excludedPhases = "('REQ','RESP','PRE_ALL','PDNA','PDNP','SREF','AUTO_REFRESH')"
query = """SELECT PhaseBegin,count FROM (SELECT phaseBegin,count(phasebegin) AS count
FROM Phases WHERE PhaseName NOT IN """ + excludedPhases + """ AND phasebegin>0 GROUP BY phaseBegin) WHERE count>1"""
cursor.execute(query)
result = cursor.fetchone()
if(result != None):
return TestFailed("Slot on commandbus at time {0} is used twice".format(formatTime(result[0])))
return TestFailed("Slot on commandbus at time {0} is used multiple times".format(formatTime(result[0])))
return TestSuceeded()
@@ -171,29 +190,23 @@ def phases_on_bank_are_sequential(connection):
@test
def phase_lengths_are_correct(connection):
query = """SELECT ID,PhaseEnd-PhaseBegin FROM Phases WHERE PhaseName = :command and (PhaseEnd-PhaseBegin)!= :length"""
commandLengths = [('RD', dramconfig.tReadLength),
('RDA', dramconfig.tReadLength + dramconfig.tRP),
('WR', dramconfig.tWriteLength),
('WRA', dramconfig.tWriteLength + dramconfig.tRP),
('PRE', dramconfig.tRP),
('ACT', dramconfig.tRCD),
('AUTO_REFRESH', dramconfig.tRFC)]
for commandLength in commandLengths:
command = commandLength[0]
length = commandLength[1]
cursor = connection.cursor()
cursor.execute(query, {"command":command, "length" : length})
result = cursor.fetchone()
if(result != None):
return TestFailed("Phase with ID {0}({1}) has invalid length {2}".format(result[0],command,formatTime(result[1])))
query = """SELECT phases.ID,PhaseName, PhaseEnd-PhaseBegin,Burstlength FROM Phases INNER JOIN transactions ON transactions.ID = phases.transact """
cursor = connection.cursor()
cursor.execute(query)
for currentRow in cursor:
command = currentRow[1]
commandLength = currentRow[2]
burstlength = currentRow[3]
if(command == "RD" and commandLength != calculateReadLength(burstlength) or
command == "WR" and commandLength != calculateWriteLength(burstLength) or
command == "RDA" and commandLength != calculateReadLength(burstlength)+dramconfig.tRP or
command == "WRA" and commandLength != calculateReadLength(burstlength)+dramconfig.tRP or
(command == "PRE" or command=="PRE_ALL") and commandLength != dramconfig.tRP or
command == "AUTO_REFRESH" and commandLength != dramconfig.tRFC):
return TestFailed("Phase with ID {0}({1}) has invalid length of {2}".format(currentRow[0],command,formatTime(commandLength)))
return TestSuceeded()
#----------- activate checks ---------------------------------------
@test
@@ -325,6 +338,16 @@ def write_or_read_to_precharge(connection):
lastRow = currentRow
return TestSuceeded()
@test
def sref_active_for_minimal_time(connection):
"""Checks if SREF is active for at least a minimal time (JEDEC 229, P. 41)"""
cursor = connection.cursor()
cursor.execute("SELECT ID, PhaseEnd-PhaseBegin FROM Phases WHERE PhaseName = 'SREF'")
for currentRow in cursor:
if(currentRow[1] < dramconfig.tCKESR):
return TestFailed("SREF with ID {0} is {1} long. Minimal time in SREF is {2}".format(currentRow[0], formatTime(currentRow[1]), dramconfig.tCKESR))
return TestSuceeded()
# -------------------------- interface methods --------------------
def runTests(pathToTrace):

View File

@@ -88,7 +88,7 @@ void TlmRecorder::setUpTransactionTerminatingPhases()
void TlmRecorder::prepareSqlStatements()
{
insertTransactionString =
"INSERT INTO Transactions VALUES (:id,:rangeID,:address,:thread,:channel,:bank,:row,:column,:command)";
"INSERT INTO Transactions VALUES (:id,:rangeID,:address,:burstlength,:thread,:channel,:bank,:row,:column,:command)";
insertRangeString = "INSERT INTO Ranges VALUES (:id,:begin,:end)";
updateRangeString = "UPDATE Ranges SET End = :end WHERE ID = :id";
insertPhaseString =
@@ -139,15 +139,16 @@ void TlmRecorder::insertTransactionInDB(unsigned int id, tlm::tlm_generic_payloa
sqlite3_bind_int(insertTransactionStatement, 1, id);
sqlite3_bind_int(insertTransactionStatement, 2, id);
sqlite3_bind_int(insertTransactionStatement, 3, trans.get_address());
sqlite3_bind_text(insertTransactionStatement, 9,
sqlite3_bind_int(insertTransactionStatement, 4, trans.get_streaming_width());
sqlite3_bind_text(insertTransactionStatement, 10,
trans.get_command() == tlm::TLM_READ_COMMAND ? "R" : "W", 1, 0);
const DramExtension& extension = DramExtension::getExtension(trans);
sqlite3_bind_int(insertTransactionStatement, 4, extension.getThread().ID());
sqlite3_bind_int(insertTransactionStatement, 5, extension.getChannel().ID());
sqlite3_bind_int(insertTransactionStatement, 6, extension.getBank().ID());
sqlite3_bind_int(insertTransactionStatement, 7, extension.getRow().ID());
sqlite3_bind_int(insertTransactionStatement, 8, extension.getColumn().ID());
sqlite3_bind_int(insertTransactionStatement, 5, extension.getThread().ID());
sqlite3_bind_int(insertTransactionStatement, 6, extension.getChannel().ID());
sqlite3_bind_int(insertTransactionStatement, 7, extension.getBank().ID());
sqlite3_bind_int(insertTransactionStatement, 8, extension.getRow().ID());
sqlite3_bind_int(insertTransactionStatement, 9, extension.getColumn().ID());
executeSqlStatement(insertTransactionStatement);
}
@@ -258,3 +259,4 @@ void TlmRecorder::closeConnection()
sqlite3_close(db);
db = NULL;
}

View File

@@ -103,20 +103,20 @@ private:
Bank bank;
Row row;
Column column;
unsigned int burstlength;
public:
DramExtension():thread(0),channel(0),bank(0),row(0),column(0){}
DramExtension(const Thread& thread, const Bank& bank, const Row& row, const Column& column) :
thread(thread),channel(0),bank(bank),row(row),column(column){}
DramExtension(const Thread& thread,const Channel& channel, const Bank& bank, const Row& row, const Column& column) :
thread(thread),channel(channel),bank(bank),row(row),column(column){}
DramExtension():thread(0),channel(0),bank(0),row(0),column(0),burstlength(0){}
DramExtension(const Thread& thread, const Bank& bank, const Row& row, const Column& column, unsigned int burstlength=0) :
thread(thread),channel(0),bank(bank),row(row),column(column), burstlength(burstlength){}
DramExtension(const Thread& thread,const Channel& channel, const Bank& bank, const Row& row, const Column& column, unsigned int burstlength=0) :
thread(thread),channel(channel),bank(bank),row(row),column(column), burstlength(burstlength){}
~DramExtension(){}
virtual tlm_extension_base* clone() const
{
return new DramExtension(thread, bank, row, column);
return new DramExtension(thread, bank, row, column, burstlength);
}
virtual void copy_from(const tlm_extension_base& ext)
{
@@ -125,6 +125,7 @@ public:
bank = cpyFrom.bank;
row = cpyFrom.row;
column = cpyFrom.column;
burstlength = cpyFrom.burstlength;
}
const Thread& getThread() const{return thread;}
@@ -132,6 +133,7 @@ public:
const Bank& getBank() const{return bank;}
const Row& getRow() const{return row;}
const Column& getColumn() const{return column;}
const unsigned int getBurstlength() const{return burstlength;}
static const DramExtension& getExtension(const tlm::tlm_generic_payload *payload);

View File

@@ -19,6 +19,7 @@ xmlAddressDecoder::xmlAddressDecoder(string addressConfigURI)
// get channel:
TiXmlElement* channel = addressmap->FirstChildElement("channel");
from = getAttribute<unsigned int>(channel, "from");
to = getAttribute<unsigned int>(channel, "to");

View File

@@ -6,6 +6,8 @@
*/
#include "BankStates.h"
#include "ControllerCore.h"
#include "../common/DebugManager.h"
using namespace std;
@@ -34,11 +36,13 @@ Row BankStates::getRowInRowBuffer(const Bank &bank) const
void BankStates::openRowInRowBuffer(const Bank &bank, const Row &row)
{
DebugManager::getInstance().printDebugMessage(ControllerCore::senderName, "Row buffer for bank " + to_string(bank.ID()) + " is now open");
rowsInRowBuffers.at(bank.ID()) = row;
}
void BankStates::closeRowBuffer(const Bank &bank)
{
DebugManager::getInstance().printDebugMessage(ControllerCore::senderName, "Row buffer for bank " + to_string(bank.ID()) + " is now closed");
rowsInRowBuffers.at(bank.ID()) = Row::NO_ROW;
}

View File

@@ -15,7 +15,7 @@ namespace core{
struct Configuration
{
Configuration(): NumberOfBanks(8), NumberOfBankGroups(4), Burstlength(2), Timings(NumberOfBanks), BankwiseRefresh(true),BankwisePowerDown(true),
Configuration(): NumberOfBanks(8), NumberOfBankGroups(4), Burstlength(2), Timings(NumberOfBanks), BankwiseRefresh(false),BankwisePowerDown(false),
nActivate(2)
{}
unsigned int NumberOfBanks;

View File

@@ -79,9 +79,15 @@ void ControllerCore::triggerRefresh(tlm::tlm_generic_payload& payload, sc_time t
if (!powerDownManager->isInSelfRefresh(bank))
{
if(config.BankwiseRefresh)
powerDownManager->wakeUpForRefresh(bank, time);//expect PDNA and PDNP to exit without delay
{
printDebugMessage("Waking up bank " + to_string(bank.ID()) + " for refresh");
powerDownManager->wakeUpForRefresh(bank, time);//expects PDNA and PDNP to exit without delay
}
else
{
printDebugMessage("Waking up all banks for refresh");
powerDownManager->wakeUpAllForRefresh(time);
}
refreshManager->scheduleRefresh(payload, time);
}
@@ -96,7 +102,6 @@ bool ControllerCore::scheduleRequest(sc_time start, tlm::tlm_generic_payload& pa
{
start = clkAlign(start, config.Timings.clk);
state.cleanUp(start);
payload.set_streaming_width(config.Burstlength);
saveState();

View File

@@ -45,10 +45,6 @@ void PowerDownManager::sleep(Bank bank, sc_time time)
sendPowerDownPayload(time, bank, getSleepCommand(getPowerDownState(bank)));
}
else
{
SC_REPORT_FATAL("Power Down Manager", "Sleep triggered even though already in sleep");
}
}
void PowerDownManager::wakeUp(Bank bank, sc_time time)
@@ -260,7 +256,6 @@ void PowerDownManager::init()
controller.state.change(pdn);
controller.wrapper.send(pdn, payload);
powerDownStates[bank] = PowerDownState::PDNPrecharge;
//setState(PowerDownState::PDNPrecharge, bank);
}
}

View File

@@ -25,9 +25,7 @@ PowerDownManagerGrouped::~PowerDownManagerGrouped()
void PowerDownManagerGrouped::sleep(Bank bank, sc_time time)
{
assert(!isInPowerDown());//cause nobody calls sleep if already sleeping on all banks
//all banks can sleep and no pending refresh
//all banks can sleep and no pending refresh in system
if (!canSleep() || (controller.state.getLastCommand(Command::AutoRefresh).getEnd() > time))
return;
@@ -43,19 +41,20 @@ void PowerDownManagerGrouped::sleep(Bank bank, sc_time time)
}
else if (state == PowerDownState::AwakeForRefresh)//coming from refresh interrupting power down
{
//last running refresh triggers sleep
if (controller.state.getLastCommand(Command::PDNA).getStart()
> controller.state.getLastCommand(Command::PDNP).getStart())
setState(PowerDownState::PDNPrecharge);
if(controller.state.bankStates.allRowBuffersAreClosed())
{
if (controller.state.getLastCommand(Command::PDNA).getStart()
> controller.state.getLastCommand(Command::PDNP).getStart())
setState(PowerDownState::PDNPrecharge);
else
setState(PowerDownState::PDNSelfRefresh);
}
else
setState(PowerDownState::PDNSelfRefresh);
{
setState(PowerDownState::PDNActive);
}
sendPowerDownPayload(time, getSleepCommand(getPowerDownState()));
}
else
{
SC_REPORT_FATAL("PowerDownManagerGrouped", "Sleep triggered even though already in sleep");
}
}
void PowerDownManagerGrouped::wakeUp(Bank bank, sc_time time)
@@ -105,10 +104,7 @@ void PowerDownManagerGrouped::wakeUpAllForRefresh(sc_time time)
{
if(isInPowerDown())
{
for (Bank bank : controller.getBanks())
{
sendPowerDownPayload(time, getWakeUpCommand(getPowerDownState()));
}
sendPowerDownPayload(time, getWakeUpCommand(getPowerDownState()));
setState(PowerDownState::AwakeForRefresh);
}

View File

@@ -18,7 +18,7 @@ class CommandSchedule
{
public:
CommandSchedule(tlm::tlm_generic_payload& transaction) :
extension(DramExtension::getExtension(&transaction)), burstLength(transaction.get_streaming_width())
extension(DramExtension::getExtension(&transaction))
{
}
@@ -28,7 +28,7 @@ public:
ScheduledCommand& add(Command command, sc_time start, sc_time executionTime)
{
scheduledCommands.push_back(ScheduledCommand(command, start, executionTime, extension, burstLength));
scheduledCommands.push_back(ScheduledCommand(command, start, executionTime, extension));
return scheduledCommands.back();
}
@@ -59,7 +59,6 @@ public:
private:
std::vector<ScheduledCommand> scheduledCommands;
unsigned int burstLength;
DramExtension extension;
};

View File

@@ -69,7 +69,7 @@ Row ScheduledCommand::getRow() const
unsigned int ScheduledCommand::getBurstLength()
{
return burstLength;
return extension.getBurstlength();
}
bool ScheduledCommand::operator ==(const ScheduledCommand& b) const

View File

@@ -20,15 +20,15 @@ class ScheduledCommand
{
public:
ScheduledCommand(Command command, sc_time start, sc_time executionTime, const DramExtension& extension, unsigned int burstLength = 0) :
command(command), start(start), executionTime(executionTime),end(start+executionTime), burstLength(burstLength),
ScheduledCommand(Command command, sc_time start, sc_time executionTime, const DramExtension& extension) :
command(command), start(start), executionTime(executionTime),end(start+executionTime),
extension(extension)
{
}
ScheduledCommand() :
command(Command::NOP), start(SC_ZERO_TIME), executionTime(SC_ZERO_TIME), end(SC_ZERO_TIME), burstLength(0), extension()
command(Command::NOP), start(SC_ZERO_TIME), executionTime(SC_ZERO_TIME), end(SC_ZERO_TIME), extension()
{
}
@@ -58,7 +58,6 @@ private:
sc_time start;
sc_time executionTime;
sc_time end;
unsigned int burstLength;
DramExtension extension;
};
} /* namespace controller */

View File

@@ -78,22 +78,13 @@ bool ReadChecker::collidesWithStrobeCommand(ScheduledCommand& read,
if (strobeCommand.getCommand() == Command::Read || strobeCommand.getCommand() == Command::ReadA)
{
//read to read
TimeInterval readOnStrobe = getIntervalOnDataStrobe(read, config.Timings);
TimeInterval otherReadOnStrobe = getIntervalOnDataStrobe(strobeCommand, config.Timings);
if (readOnStrobe.timeIsInInterval(otherReadOnStrobe.start))
if(read.getStart() < strobeCommand.getStart())
{
return !isClkAligned(otherReadOnStrobe.start - readOnStrobe.start,
2 * config.Timings.clk);
}
else if (otherReadOnStrobe.timeIsInInterval(readOnStrobe.start))
{
return !isClkAligned(readOnStrobe.start - otherReadOnStrobe.start,
2 * config.Timings.clk);
return (strobeCommand.getStart() - read.getStart() < read.getBurstLength()*config.Timings.clk);
}
else
{
return false;
return (read.getStart() - strobeCommand.getStart() < strobeCommand.getBurstLength()*config.Timings.clk);
}
}
else if (strobeCommand.getCommand() == Command::Write

View File

@@ -27,7 +27,8 @@ void WriteChecker::delayToSatisfyConstraints(ScheduledCommand& command) const
}
}
else if (lastCommand.getCommand() == Command::Read
|| lastCommand.getCommand() == Command::Write || lastCommand.getCommand() == Command::PDNAX)
|| lastCommand.getCommand() == Command::Write
|| lastCommand.getCommand() == Command::PDNAX)
{
}
else
@@ -73,8 +74,17 @@ bool WriteChecker::collidesWithStrobeCommand(ScheduledCommand& write,
if (strobeCommand.getCommand() == Command::Write
|| strobeCommand.getCommand() == Command::WriteA)
{
//write to write (implicitly checked by checking the command bus first)
return false;
//write to write
if (write.getStart() < strobeCommand.getStart())
{
return (strobeCommand.getStart() - write.getStart()
< write.getBurstLength() * config.Timings.clk);
}
else
{
return (write.getStart() - strobeCommand.getStart()
< strobeCommand.getBurstLength() * config.Timings.clk);
}
}
else if (strobeCommand.getCommand() == Command::Read
|| strobeCommand.getCommand() == Command::ReadA)

View File

@@ -132,9 +132,10 @@ private:
void appendDramExtension(int socketId, tlm_generic_payload& payload)
{
unsigned int burstlength = payload.get_streaming_width();
node n;
xmlAddressDecoder::getInstance().getNode(static_cast<unsigned int>(payload.get_address()), &n);
DramExtension* extension = new DramExtension(Thread(socketId+1), Channel(n.channel), Bank(n.bank), Row(n.row), Column(n.colum));
DramExtension* extension = new DramExtension(Thread(socketId+1), Channel(n.channel), Bank(n.bank), Row(n.row), Column(n.colum),burstlength);
payload.set_auto_extension(extension);
}
};

View File

@@ -177,7 +177,7 @@ private:
void scheduleNextPayload(Bank bank)
{
printDebugMessage("Try to schedule next payload on bank " + to_string(bank.ID()));
printDebugMessage("Triggering schedule next payload on bank " + to_string(bank.ID()));
if (scheduler->hasTransactionForBank(bank))
{
@@ -188,8 +188,8 @@ private:
}
if (controller->powerDownManager->isInPowerDown(bank))
{
printDebugMessage("\t-> break: wake up bank first");
controller->powerDownManager->wakeUp(bank, sc_time_stamp());
printDebugMessage("\t-> break: wake up power down");
return;
}
else if (controller->powerDownManager->isAwakeForRefresh(bank))
@@ -302,7 +302,10 @@ private:
{
printDebugMessage("Finished auto refresh on bank " + to_string(bank.ID()));
if (numberOfPayloadsInSystem[bank] == 0)
{
printDebugMessage("\t -> Triggering sleep on bank " + to_string(bank.ID()));
controller->powerDownManager->sleep(bank, sc_time_stamp());
}
scheduleNextPayload(DramExtension::getExtension(payload).getBank());
}
else if (isIn(phase, { END_PRE, END_PRE_ALL, END_ACT }))

View File

@@ -8,7 +8,7 @@ class ISimulationManager
{
public:
virtual ~ISimulationManager(){}
virtual void tracePlayerFinishedCallback() = 0;
virtual void tracePlayerFinishedCallback(string name) = 0;
};
} // namespace simulation

View File

@@ -17,13 +17,15 @@ using namespace std;
namespace simulation {
SimulationManager::SimulationManager(sc_module_name name, std::string stl1, std::string stl2,
SimulationManager::SimulationManager(sc_module_name name, std::string stl1,
unsigned int burstlength1, std::string stl2, unsigned int burstlenght2,
std::string traceName, std::string pathToResources) :
dram("dram"), arbiter("arbiter"), controller("controller"), player1("player1",
pathToResources + string("traces/") + stl1, this), player2("player2",
pathToResources + string("traces/") + stl2, this), traceName(traceName)
pathToResources + string("traces/") + stl1,burstlength1, this), player2("player2",
pathToResources + string("traces/") + stl2,burstlenght2, this), traceName(traceName)
{
SC_THREAD(terminationThread);
xmlAddressDecoder::addressConfigURI = pathToResources + string("configs/addressConfig.xml");
TlmRecorder::dbName = traceName;
@@ -38,6 +40,7 @@ SimulationManager::SimulationManager(sc_module_name name, std::string stl1, std:
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);
whiteList.push_back(PowerDownManager::senderName);
@@ -49,21 +52,21 @@ void SimulationManager::startSimulation()
clock_t begin = clock();
cout << "Toplevel: simulation start" << std::endl;
DebugManager::getInstance().printDebugMessage(name(), "Starting simulation");
player1.start();
player2.start();
sc_start();
clock_t end = clock();
double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
cout << "Simulation took " << elapsed_secs << " seconds." << endl;
cout << this->name();
string p = getenv("trace");
string run_tpr = p + " " + traceName;
system(run_tpr.c_str());
DebugManager::getInstance().printDebugMessage(name(),
"Simulation took " + to_string(elapsed_secs) + " seconds");
}
void SimulationManager::tracePlayerFinishedCallback()
void SimulationManager::tracePlayerFinishedCallback(string name)
{
DebugManager::getInstance().printDebugMessage(this->name(), "Traceplayer " + name + " finshed");
static int finishedPlayers = 0;
finishedPlayers++;
if (finishedPlayers == numberOfTracePlayers)
@@ -75,9 +78,10 @@ void SimulationManager::tracePlayerFinishedCallback()
void SimulationManager::terminationThread()
{
wait(terminateSimulation);
DebugManager::getInstance().printDebugMessage(this->name(), "Terminating simulation");
controller.terminateSimulation();
//waits for the termination of all pending powerdown phases in the dram system
wait(sc_time(50,SC_NS));
wait(sc_time(50, SC_NS));
TlmRecorder::getInstance().closeConnection();
sc_stop();
}

View File

@@ -22,10 +22,11 @@ class SimulationManager : public ISimulationManager, public sc_module
{
public:
SC_HAS_PROCESS(SimulationManager);
SimulationManager(sc_module_name name,std::string stl1, std::string stl2,
std::string traceName, std::string pathToResources);
SimulationManager(sc_module_name name, std::string stl1,
unsigned int burstlength1, std::string stl2, unsigned int burstlenght2,
std::string traceName, std::string pathToResources);
void startSimulation();
void tracePlayerFinishedCallback() override;
void tracePlayerFinishedCallback(string name) override;
private:
void terminationThread();

View File

@@ -28,28 +28,36 @@ struct TracePlayer: public sc_module
{
public:
tlm_utils::simple_initiator_socket<TracePlayer, BUSWIDTH, tlm::tlm_base_protocol_types> iSocket;
TracePlayer(sc_module_name name, string pathToTrace,
TracePlayer(sc_module_name name, string pathToTrace, unsigned int burstlength,
simulation::ISimulationManager* simulationManager) :
payloadEventQueue(this, &TracePlayer::peqCallback), file(pathToTrace), numberOfPendingTransactions(
payloadEventQueue(this, &TracePlayer::peqCallback), file(pathToTrace), burstlenght(burstlength), numberOfPendingTransactions(
0), transactionsSent(0), transactionsReceived(0), simulationManager(
simulationManager)
{
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");
}
iSocket.register_nb_transport_bw(this, &TracePlayer::nb_transport_bw);
scheduleNextPayload();
}
void start()
{
bool fileIsEmpty = file.peek() == std::ifstream::traits_type::eof();
if (fileIsEmpty)
{
simulationManager->tracePlayerFinishedCallback(name());
}
else
{
scheduleNextPayload();
}
}
private:
tlm_utils::peq_with_cb_and_phase<TracePlayer> payloadEventQueue;
MemoryManager memoryManager;
ifstream file;
unsigned int burstlenght;
unsigned int numberOfPendingTransactions;
unsigned int transactionsSent;
unsigned int transactionsReceived;
@@ -89,7 +97,7 @@ private:
payload->set_response_status(TLM_INCOMPLETE_RESPONSE);
payload->set_dmi_allowed(false);
payload->set_byte_enable_length(0);
payload->set_streaming_width(0);
payload->set_streaming_width(burstlenght);
sc_time sendingTime = sc_time(std::stoi(time.c_str()), SC_NS);
if (sendingTime <= sc_time_stamp())
@@ -137,7 +145,7 @@ private:
+ std::to_string(transactionsSent - transactionsReceived));
if (numberOfPendingTransactions == 0)
simulationManager->tracePlayerFinishedCallback();
simulationManager->tracePlayerFinishedCallback(name());
}
else if (phase == END_RESP)

View File

@@ -17,15 +17,26 @@ string pathOfFile(string file)
return file.substr(0, file.find_last_of('/'));
}
void startTraceAnalyzer(string traceName)
{
string p = getenv("trace");
string run_tpr = p + " " + traceName;
system(run_tpr.c_str());
}
int sc_main(int argc, char **argv)
{
sc_set_time_resolution(1, SC_NS);
string resources = pathOfFile(argv[0]) + string("/../resources/");
string stl1 = "chstone-mips_32.stl";
string stl2 = "chstone-motion_32.stl";
SimulationManager simulationManager("sim",stl1,stl2,"tpr.tdb", resources);
unsigned int burstlength1 = 4;
string stl2 = "empty.stl";
unsigned int burstlength2 = 2;
string traceName = "tpr.tdb";
SimulationManager simulationManager("sim", stl1,burstlength1, stl2,burstlength2, traceName, resources);
simulationManager.startSimulation();
startTraceAnalyzer(traceName);
return 0;
}