Resolving Merge Conflicts
This commit is contained in:
@@ -49,10 +49,11 @@ struct GeneralInfo
|
||||
QString description;
|
||||
QString unitOfTime;
|
||||
unsigned int clkPeriod;
|
||||
unsigned long long timeWindowSize;
|
||||
|
||||
public:
|
||||
GeneralInfo(unsigned int numberOfTransactions,unsigned int numberOfPhases, Timespan span,unsigned int numberOfBanks,const QString& description, QString unitOfTime,unsigned int clkPeriod) :
|
||||
numberOfTransactions(numberOfTransactions) , numberOfPhases(numberOfPhases), span(span), numberOfBanks(numberOfBanks), description(description), unitOfTime(unitOfTime),clkPeriod(clkPeriod)
|
||||
GeneralInfo(unsigned int numberOfTransactions,unsigned int numberOfPhases,Timespan span,unsigned int numberOfBanks,const QString& description, QString unitOfTime,unsigned int clkPeriod, unsigned long long timeWindowSize) :
|
||||
numberOfTransactions(numberOfTransactions) , numberOfPhases(numberOfPhases),span(span), numberOfBanks(numberOfBanks), description(description), unitOfTime(unitOfTime), clkPeriod(clkPeriod), timeWindowSize(timeWindowSize)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -199,7 +199,7 @@ ID TraceDB::getTransactionIDFromPhaseID(ID phaseID)
|
||||
GeneralInfo TraceDB::getGeneralInfoFromDB()
|
||||
{
|
||||
QSqlQuery query(database);
|
||||
query.prepare("SELECT NumberOfTransactions,TraceEnd,NumberOfBanks,Clk,UnitOfTime,Traces,Memspec,Memconfig FROM GeneralInfo");
|
||||
query.prepare("SELECT NumberOfTransactions,TraceEnd,NumberOfBanks,Clk,UnitOfTime,Traces,Memspec,Memconfig,TimeWindowSize FROM GeneralInfo");
|
||||
executeQuery(query);
|
||||
|
||||
if(query.next())
|
||||
@@ -214,15 +214,17 @@ GeneralInfo TraceDB::getGeneralInfoFromDB()
|
||||
QString traces = "Traces: " + query.value(5).toString();
|
||||
QString memspec = "Memspec: " + query.value(6).toString();
|
||||
QString memconfig = "Memconfig: " + query.value(7).toString();
|
||||
unsigned long long timeWindowSize = query.value(8).toLongLong();
|
||||
|
||||
QString description = (traces + "\n");
|
||||
description += memconfig + "\n";
|
||||
description += memspec + "\n";
|
||||
description += "Number of Transactions: " + QString::number(numberOfTransactions) + "\n";
|
||||
description += "Clock period: " + QString::number(clkPeriod) + " " + unitOfTime + "\n";
|
||||
description += "Length of trace: " + prettyFormatTime(traceEnd);
|
||||
description += "Length of trace: " + prettyFormatTime(traceEnd) + "\n";
|
||||
description += "Time windows size: " + prettyFormatTime(timeWindowSize);
|
||||
|
||||
return GeneralInfo(numberOfTransactions, numberOfPhases, Timespan(0,traceEnd),numberOfBanks,description,unitOfTime,clkPeriod);
|
||||
return GeneralInfo(numberOfTransactions, numberOfPhases, Timespan(0,traceEnd),numberOfBanks,description,unitOfTime,clkPeriod,timeWindowSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -22,25 +22,23 @@ def memory_utilisation_window(connection, tracePath):
|
||||
# Besides, extracting the data from the memory specs, it is feasible to calculate the maximum data rate of the memory and then determine the bandwidth in Gbit/s.
|
||||
# The bandwidth data are then plotted in two graphics.
|
||||
|
||||
steps = 1000
|
||||
cursor = connection.cursor()
|
||||
cursor.execute(""" SELECT max(DataStrobeEnd) FROM Transactions """)
|
||||
total = cursor.fetchone()
|
||||
windowSize = ceil(float(total[0])/float(steps))
|
||||
if (windowSize == 0):
|
||||
windowSize = 1
|
||||
# print(steps)
|
||||
cursor.execute("SELECT TimeWindowSize FROM generalInfo")
|
||||
windowSize = cursor.fetchone()[0]
|
||||
cursor.execute("SELECT TraceEnd FROM generalInfo")
|
||||
traceEnd = cursor.fetchone()[0]
|
||||
steps = ceil(float(traceEnd)/float(windowSize))
|
||||
# All possible cases of data transfers inside a time window
|
||||
queryFull = """ SELECT sum(DataStrobeEnd - DataStrobeBegin) FROM transactions Where DataStrobeBegin > ? and DataStrobeEnd < ?""" # The data transfer begins and ends inside the time window
|
||||
queryEnd = """ SELECT sum(DataStrobeEnd - ?) FROM transactions Where DataStrobeBegin < ? and DataStrobeEnd > ? and DataStrobeEnd <=?""" # Only the end of the data transfer is inside the time window
|
||||
queryBegin = """ SELECT sum(? - DataStrobeBegin) FROM transactions Where DataStrobeBegin >= ? and DataStrobeBegin < ? and DataStrobeEnd > ?""" # Only the beginning of the data transfer is inside the time window
|
||||
queryPart = """ SELECT DataStrobeBegin FROM transactions Where DataStrobeBegin <= ? and DataStrobeEnd >= ?""" # The data transfer occupies all the time window
|
||||
maxDataRate = maximum_data_rate(connection)
|
||||
# print(width)
|
||||
# print(clk)
|
||||
# print(rate)
|
||||
bandwidthPercentage = [0] * steps
|
||||
bandwidth = [0] * steps
|
||||
maximumPercentage = 0
|
||||
bandwidthPercentage = [0] * (steps+1)
|
||||
bandwidth = [0] * (steps+1)
|
||||
bandwidthPercentage[0] = 0
|
||||
bandwidth[0] = 0
|
||||
for i in range(steps):
|
||||
# print(i)
|
||||
bandwidthPercentage[i] = 0
|
||||
@@ -65,9 +63,11 @@ def memory_utilisation_window(connection, tracePath):
|
||||
else:
|
||||
bandwidthPercentage[i] = windowSize
|
||||
# print(bandwidthPercentage[i])
|
||||
bandwidthPercentage[i] = float(bandwidthPercentage[i]/windowSize)
|
||||
bandwidth[i] = float(bandwidthPercentage[i])*float(maxDataRate)/1024
|
||||
bandwidthPercentage[i] *= 100
|
||||
bandwidthPercentage[i+1] = float(bandwidthPercentage[i+1]/windowSize)
|
||||
bandwidth[i+1] = float(bandwidthPercentage[i+1])*float(maxDataRate)/1024
|
||||
bandwidthPercentage[i+1] *= 100
|
||||
if(maximumPercentage < 100 and maximumPercentage < bandwidthPercentage[i+1]):
|
||||
maximumPercentage = bandwidthPercentage[i+1]
|
||||
|
||||
name = ntpath.basename(tracePath)
|
||||
basename, extension = os.path.splitext(name)
|
||||
@@ -86,9 +86,9 @@ def memory_utilisation_window(connection, tracePath):
|
||||
subplotIndex = 211
|
||||
plt.subplot(subplotIndex)
|
||||
plt.plot(time/1000, bandwidthPercentage)
|
||||
plt.xlabel('Time (ns)')
|
||||
#plt.xlabel('Time (ns)')
|
||||
plt.ylabel('Bandwidth (%)')
|
||||
plt.ylim(0, 100)
|
||||
plt.ylim(0, maximumPercentage + (10 - maximumPercentage%10))
|
||||
plt.grid(True)
|
||||
|
||||
subplotIndex += 1
|
||||
@@ -108,37 +108,41 @@ def memory_utilisation_window(connection, tracePath):
|
||||
@plot
|
||||
def power_window(connection, tracePath):
|
||||
cursor = connection.cursor()
|
||||
cursor.execute(""" SELECT max(time) FROM Power """)
|
||||
maxTime = cursor.fetchone()
|
||||
cursor.execute(""" SELECT min(time) FROM Power WHERE time > 0""")
|
||||
windowSize = cursor.fetchone()
|
||||
steps = ceil(float(maxTime[0])/float(windowSize[0]))
|
||||
cursor.execute(""" SELECT * FROM Power """)
|
||||
time = [0] * steps
|
||||
power = [0] * steps
|
||||
for i in range(steps):
|
||||
result = cursor.fetchone()
|
||||
time[i] = float(result[0]) * 1000000000 # convertion of seconds to nanoseconds
|
||||
power[i] = float(result[1]) # values are stored in mW
|
||||
cursor.execute(""" SELECT time FROM Power """)
|
||||
|
||||
name = ntpath.basename(tracePath)
|
||||
basename, extension = os.path.splitext(name)
|
||||
if(cursor.fetchone() is not None):
|
||||
cursor.execute("SELECT TimeWindowSize FROM generalInfo")
|
||||
windowSize = cursor.fetchone()[0]
|
||||
cursor.execute("SELECT TraceEnd FROM generalInfo")
|
||||
traceEnd = cursor.fetchone()[0]
|
||||
steps = ceil(float(traceEnd)/float(windowSize))
|
||||
cursor.execute(""" SELECT * FROM Power """)
|
||||
time = [0] * (steps+1)
|
||||
power = [0] * (steps+1)
|
||||
time[0] = 0
|
||||
power[0] = 0
|
||||
for i in range((steps)):
|
||||
result = cursor.fetchone()
|
||||
time[i+1] = float(result[0])*1000000000
|
||||
power[i+1] = float(result[1])
|
||||
|
||||
OUTPUT_FILE = 'power_' + basename + '.pdf'
|
||||
print("Output file is {0}".format(OUTPUT_FILE))
|
||||
name = ntpath.basename(tracePath)
|
||||
basename, extension = os.path.splitext(name)
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib.backends.backend_pdf import PdfPages
|
||||
OUTPUT_FILE = 'power_' + basename + '.pdf'
|
||||
print("Output file is {0}".format(OUTPUT_FILE))
|
||||
|
||||
plt.plot(time, power)
|
||||
plt.xlabel('Time (ns)')
|
||||
plt.ylabel('Power (mW)')
|
||||
plt.gca().set_ylim(bottom=0)
|
||||
plt.grid(True)
|
||||
pdf = PdfPages(OUTPUT_FILE)
|
||||
pdf.savefig()
|
||||
pdf.close()
|
||||
plt.close()
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib.backends.backend_pdf import PdfPages
|
||||
|
||||
plt.plot(time, power)
|
||||
plt.xlabel('Time (ns)')
|
||||
plt.ylabel('Power (mW)')
|
||||
plt.grid(True)
|
||||
pdf = PdfPages(OUTPUT_FILE)
|
||||
pdf.savefig()
|
||||
pdf.close()
|
||||
plt.close()
|
||||
return
|
||||
|
||||
# @plot
|
||||
@@ -161,6 +165,7 @@ def generatePlots(pathToTrace):
|
||||
print("================================")
|
||||
print("Generating plots for {0}".format(pathToTrace))
|
||||
|
||||
|
||||
for p in plots:
|
||||
p(connection, pathToTrace)
|
||||
|
||||
|
||||
@@ -15,14 +15,15 @@ CREATE TABLE Phases(
|
||||
);
|
||||
|
||||
CREATE TABLE GeneralInfo(
|
||||
NumberOfTransactions INTEGER,
|
||||
NumberOfTransactions INTEGER,
|
||||
TraceEnd INTEGER,
|
||||
NumberOfBanks INTEGER,
|
||||
clk INTEGER,
|
||||
clk INTEGER,
|
||||
UnitOfTime TEXT,
|
||||
Memconfig TEXT,
|
||||
Memconfig TEXT,
|
||||
Memspec TEXT,
|
||||
Traces TEXT
|
||||
Traces TEXT,
|
||||
TimeWindowSize INTEGER
|
||||
);
|
||||
|
||||
CREATE TABLE Power(
|
||||
@@ -43,13 +44,13 @@ CREATE TABLE DebugMessages(
|
||||
|
||||
-- use SQLITE R* TREE Module to make queries on timespans effecient (see http://www.sqlite.org/rtree.html)
|
||||
CREATE VIRTUAL TABLE ranges USING rtree(
|
||||
id,
|
||||
begin, end
|
||||
id,
|
||||
begin, end
|
||||
);
|
||||
|
||||
CREATE TABLE Transactions(
|
||||
ID INTEGER,
|
||||
Range INTEGER,
|
||||
Range INTEGER,
|
||||
Address INTEGER,
|
||||
Burstlength INTEGER,
|
||||
TThread INTEGER,
|
||||
@@ -61,7 +62,7 @@ CREATE TABLE Transactions(
|
||||
DataStrobeBegin INTEGER,
|
||||
DataStrobeEnd INTEGER,
|
||||
TimeOfGeneration INTEGER,
|
||||
Command TEXT
|
||||
Command TEXT
|
||||
);
|
||||
|
||||
CREATE INDEX ranges_index ON Transactions(Range);
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
<Debug value="0" />
|
||||
<DatabaseRecording value="1" />
|
||||
<PowerAnalysis value="1" />
|
||||
<PowerWindowSize value="1000" />
|
||||
<PowerWindowUnit value="ns" />
|
||||
<NumberOfTimeWindows value="1000" />
|
||||
<NumberOfTracePlayers value="1"/>
|
||||
<NumberOfMemChannels value="1"/>
|
||||
<ControllerCoreDisableRefresh value="0"/>
|
||||
<ThermalSimulation value="0"/>
|
||||
<SimulationProgressBar value="1"/>
|
||||
</simconfig>
|
||||
|
||||
<!-- Temperature Simulator Configuration (used for all simulation setups) -->
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
<Debug value="0" />
|
||||
<DatabaseRecording value="1" />
|
||||
<PowerAnalysis value="1" />
|
||||
<PowerWindowSize value="1000" />
|
||||
<PowerWindowUnit value="ns" />
|
||||
<NumberOfTimeWindows value="1000" />
|
||||
<NumberOfTracePlayers value="1"/>
|
||||
<NumberOfMemChannels value="4"/>
|
||||
<ControllerCoreDisableRefresh value="0"/>
|
||||
<ThermalSimulation value="0"/>
|
||||
<SimulationProgressBar value="1"/>
|
||||
</simconfig>
|
||||
|
||||
<!-- Temperature Simulator Configuration (used for all simulation setups) -->
|
||||
|
||||
@@ -270,8 +270,8 @@ void TlmRecorder::prepareSqlStatements()
|
||||
updatePhaseString =
|
||||
"UPDATE Phases SET PhaseEnd = :end WHERE Transact = :trans AND PhaseName = :name";
|
||||
insertGeneralInfoString =
|
||||
"INSERT INTO GeneralInfo (NumberOfTransactions,TraceEnd,NumberOfBanks,clk,UnitOfTime,Memconfig,Memspec,Traces) Values "
|
||||
"(:numberOfTransactions,:end,:numberOfBanks,:clk,:unitOfTime,:memconfig,:memspec,:traces)";
|
||||
"INSERT INTO GeneralInfo (NumberOfTransactions,TraceEnd,NumberOfBanks,clk,UnitOfTime,Memconfig,Memspec,Traces,TimeWindowSize) VALUES"
|
||||
"(:numberOfTransactions,:end,:numberOfBanks,:clk,:unitOfTime,:memconfig,:memspec,:traces,:timeWindowSize)";
|
||||
insertDebugMessageString = "INSERT INTO DebugMessages (Time,Message) Values (:time,:message)";
|
||||
insertPowerString = "INSERT INTO Power VALUES (:time,:averagePower)";
|
||||
|
||||
@@ -304,6 +304,9 @@ void TlmRecorder::insertGeneralInfo()
|
||||
sqlite3_bind_text(insertGeneralInfoStatement, 6, memconfig.c_str(), memconfig.length(), NULL);
|
||||
sqlite3_bind_text(insertGeneralInfoStatement, 7, memspec.c_str(), memspec.length(), NULL);
|
||||
sqlite3_bind_text(insertGeneralInfoStatement, 8, traces.c_str(), traces.length(), NULL);
|
||||
sqlite3_bind_int64(insertGeneralInfoStatement, 9,
|
||||
Configuration::getInstance().TraceLength.value()/Configuration::getInstance().NumberOfTimeWindows);
|
||||
|
||||
executeSqlStatement(insertGeneralInfoStatement);
|
||||
}
|
||||
|
||||
|
||||
@@ -140,10 +140,12 @@ void ControllerCore::scheduleRequest(Command command, tlm::tlm_generic_payload &
|
||||
{
|
||||
sc_time start = clkAlign(sc_time_stamp());
|
||||
state->cleanUp(start);
|
||||
|
||||
ScheduledCommand scheduledCommand = schedule(command, start, payload);
|
||||
state->change(scheduledCommand);
|
||||
controller.send(scheduledCommand, payload);
|
||||
if(!(command == Command::Precharge && refreshManager->hasCollision(scheduledCommand)))
|
||||
{
|
||||
state->change(scheduledCommand);
|
||||
controller.send(scheduledCommand, payload);
|
||||
}
|
||||
}
|
||||
|
||||
ScheduledCommand ControllerCore::schedule(Command command, sc_time start,
|
||||
|
||||
@@ -136,30 +136,35 @@ void Configuration::setParameter(std::string name, std::string value)
|
||||
DatabaseRecording = string2bool(value);
|
||||
else if(name == "PowerAnalysis")
|
||||
PowerAnalysis = string2bool(value);
|
||||
else if (name == "PowerWindowSize")
|
||||
PowerWindowSize = std::stod(value.c_str());
|
||||
else if (name == "PowerWindowUnit")
|
||||
PowerWindowUnit = string2TimeUnit(value);
|
||||
else if (name == "NumberOfTimeWindows") {
|
||||
if(string2int(value) < 1) {
|
||||
SC_REPORT_FATAL("Configuration", ("Invalid value for parameter " + name + ". This parameter must be at least one.").c_str());
|
||||
throw;
|
||||
}
|
||||
NumberOfTimeWindows = string2int(value);
|
||||
}
|
||||
else if(name == "Debug")
|
||||
Debug = string2bool(value);
|
||||
else if (name == "NumberOfTracePlayers")
|
||||
NumberOfTracePlayers = string2int(value);
|
||||
else if (name == "NumberOfMemChannels") {
|
||||
NumberOfMemChannels = string2int(value);
|
||||
unsigned int maxNumberofMemChannels = xmlAddressDecoder::getInstance().amount["channel"];
|
||||
if (NumberOfMemChannels > maxNumberofMemChannels) {
|
||||
unsigned int maxNumberofMemChannels = xmlAddressDecoder::getInstance().amount["channel"];
|
||||
if (NumberOfMemChannels > maxNumberofMemChannels) {
|
||||
SC_REPORT_FATAL("Configuration", ("Invalid value for parameter "
|
||||
+ name
|
||||
+ ". Value is out of range. The maximum value according to "
|
||||
+ "the address mapping configuration file is "
|
||||
+ std::to_string(maxNumberofMemChannels) + ".").c_str());
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (name == "ControllerCoreDisableRefresh")
|
||||
ControllerCoreDisableRefresh = string2bool(value);
|
||||
else if (name == "ThermalSimulation")
|
||||
ThermalSimulation = string2bool(value);
|
||||
else if(name == "SimulationProgressBar")
|
||||
SimulationProgressBar = string2bool(value);
|
||||
// Specification for ErrorChipSeed, ErrorCSVFile path and ErrorStoreMode
|
||||
else if(name == "ErrorChipSeed")
|
||||
ErrorChipSeed = string2int(value);
|
||||
|
||||
@@ -75,13 +75,14 @@ struct Configuration
|
||||
//SimConfig
|
||||
bool DatabaseRecording = true;
|
||||
bool PowerAnalysis = false;
|
||||
double PowerWindowSize;
|
||||
enum sc_time_unit PowerWindowUnit;
|
||||
sc_time TraceLength;
|
||||
unsigned int NumberOfTimeWindows;
|
||||
bool Debug = false;
|
||||
unsigned int NumberOfTracePlayers = 1;
|
||||
unsigned int NumberOfMemChannels = 1;
|
||||
bool ControllerCoreDisableRefresh = false;
|
||||
bool ThermalSimulation = false;
|
||||
bool SimulationProgressBar;
|
||||
|
||||
//MemSpec(from DRAM-Power XML)
|
||||
MemSpec memSpec;
|
||||
|
||||
@@ -58,7 +58,7 @@ RefreshManager::~RefreshManager()
|
||||
|
||||
bool RefreshManager::hasCollision(const ScheduledCommand& command)
|
||||
{
|
||||
return command.getStart() < controllerCore.state->getLastCommand(Command::AutoRefresh).getEnd() || command.getEnd() > nextPlannedRefresh;
|
||||
return command.getStart() < controllerCore.state->getLastCommand(Command::AutoRefresh).getEnd() || command.getEnd() >= nextPlannedRefresh;
|
||||
}
|
||||
|
||||
void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload& payload __attribute__((unused)), sc_time time)
|
||||
|
||||
@@ -37,45 +37,87 @@
|
||||
#include "RefreshChecker.h"
|
||||
#include "../../TimingCalculation.h"
|
||||
|
||||
|
||||
|
||||
void RefreshChecker::delayToSatisfyConstraints(ScheduledCommand& command) const
|
||||
{
|
||||
sc_assert(command.getCommand() == Command::AutoRefresh);
|
||||
|
||||
ScheduledCommand lastCommandOnBank = state.getLastScheduledCommand(command.getBank());
|
||||
|
||||
if (lastCommandOnBank.isValidCommand())
|
||||
if(config.BankwiseLogic)
|
||||
{
|
||||
if (lastCommandOnBank.getCommand() == Command::Precharge || lastCommandOnBank.getCommand() == Command::PrechargeAll)
|
||||
ScheduledCommand lastCommandOnBank = state.getLastScheduledCommand(command.getBank());
|
||||
|
||||
if (lastCommandOnBank.isValidCommand())
|
||||
{
|
||||
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tRP);
|
||||
if (lastCommandOnBank.getCommand() == Command::Precharge || lastCommandOnBank.getCommand() == Command::PrechargeAll)
|
||||
{
|
||||
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tRP);
|
||||
}
|
||||
else if (lastCommandOnBank.getCommand() == Command::ReadA)
|
||||
{
|
||||
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tRTP + config.memSpec.tRP);
|
||||
}
|
||||
else if (lastCommandOnBank.getCommand() == Command::WriteA)
|
||||
{
|
||||
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(),
|
||||
config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR + config.memSpec.tRP);
|
||||
}
|
||||
else if (lastCommandOnBank.getCommand() == Command::PDNPX || lastCommandOnBank.getCommand() == Command::PDNAX)
|
||||
{
|
||||
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tXP);
|
||||
}
|
||||
else if (lastCommandOnBank.getCommand() == Command::SREFX)
|
||||
{
|
||||
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tXSR);
|
||||
}
|
||||
else if (lastCommandOnBank.getCommand() == Command::AutoRefresh)
|
||||
{
|
||||
}
|
||||
else
|
||||
reportFatal("Refresh Checker", "Refresh can not follow " + commandToString(lastCommandOnBank.getCommand()));
|
||||
}
|
||||
else if (lastCommandOnBank.getCommand() == Command::ReadA)
|
||||
}
|
||||
else
|
||||
{
|
||||
for (unsigned int bank = 0; bank < config.memSpec.NumberOfBanks; ++bank)
|
||||
{
|
||||
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tRTP + config.memSpec.tRP);
|
||||
}
|
||||
else if (lastCommandOnBank.getCommand() == Command::WriteA)
|
||||
{
|
||||
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(),
|
||||
config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR + config.memSpec.tRP);
|
||||
}
|
||||
else if (lastCommandOnBank.getCommand() == Command::PDNPX || lastCommandOnBank.getCommand() == Command::PDNAX)
|
||||
{
|
||||
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tXP);
|
||||
}
|
||||
else if (lastCommandOnBank.getCommand() == Command::SREFX)
|
||||
ScheduledCommand lastCommand = state.getLastScheduledCommand(Bank(bank));
|
||||
if (lastCommand.isValidCommand())
|
||||
{
|
||||
if(lastCommand.getCommand() == Command::Precharge || lastCommand.getCommand() == Command::PrechargeAll)
|
||||
{
|
||||
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tXSR);
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tRP);
|
||||
}
|
||||
else if (lastCommandOnBank.getCommand() == Command::AutoRefresh)
|
||||
{
|
||||
else if(lastCommand.getCommand() == Command::Activate)
|
||||
{
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tRCD);
|
||||
}
|
||||
else if (lastCommand.getCommand() == Command::ReadA)
|
||||
{
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tRTP + config.memSpec.tRP);
|
||||
}
|
||||
else if(lastCommand.getCommand() == Command::WriteA)
|
||||
{
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR + config.memSpec.tRP);
|
||||
}
|
||||
else if (lastCommand.getCommand() == Command::PDNAX || lastCommand.getCommand() == Command::PDNPX)
|
||||
{
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tXP);
|
||||
}
|
||||
else if (lastCommand.getCommand() == Command::SREFX)
|
||||
{
|
||||
command.establishMinDistanceFromStart(lastCommand.getEnd(), config.memSpec.tXSR);
|
||||
}
|
||||
else if (lastCommand.getCommand() == Command::AutoRefresh)
|
||||
{
|
||||
}
|
||||
else
|
||||
reportFatal("Refresh Checker", "Refresh can not follow " + commandToString(lastCommand.getCommand()));
|
||||
}
|
||||
}
|
||||
else
|
||||
reportFatal("Refresh Checker", "Refresh can not follow " + commandToString(lastCommandOnBank.getCommand()));
|
||||
}
|
||||
|
||||
state.bus.moveCommandToNextFreeSlot(command);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -68,9 +68,7 @@ struct Dram : sc_module
|
||||
|
||||
// Power Model related
|
||||
bool powerAnalysis = Configuration::getInstance().PowerAnalysis;
|
||||
double pWindowSize = Configuration::getInstance().PowerWindowSize;
|
||||
enum sc_time_unit pWindowUnit = Configuration::getInstance().PowerWindowUnit;
|
||||
sc_time powerWindowSize = sc_time(pWindowSize, pWindowUnit);
|
||||
sc_time powerWindowSize = Configuration::getInstance().TraceLength/Configuration::getInstance().NumberOfTimeWindows;
|
||||
libDRAMPower *DRAMPower;
|
||||
double sumOfEnergyWindows = 0.0;
|
||||
|
||||
@@ -278,6 +276,7 @@ struct Dram : sc_module
|
||||
// (log10(2^53)). The implementation sets the number of digits
|
||||
// (DBL_DIG) to 15, not 16, because it has to round down.
|
||||
//
|
||||
|
||||
sumOfEnergyWindows += currentTotalEnergy;
|
||||
|
||||
// Store the time (in seconds) and the current average power (in mW) into the database
|
||||
@@ -286,6 +285,7 @@ struct Dram : sc_module
|
||||
// Here considering that DRAMPower provides the energy in pJ and the power in mW
|
||||
printDebugMessage(string("\tCurrent Energy: \t") + to_string(currentTotalEnergy) + string("\t[pJ]"));
|
||||
printDebugMessage(string("\tAverage Power: \t") + to_string(currentAveragePower) + string("\t[mW]"));
|
||||
|
||||
} while(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -121,14 +121,23 @@ void Simulation::instantiateModules(const string &traceName, const string &pathT
|
||||
// or if you simply dont care about the data the normal StlPlayer is used.
|
||||
if(Configuration::getInstance().ErrorStoreMode == ErrorStorageMode::NoStorage)
|
||||
{
|
||||
player = new StlPlayer<>(playerStr.c_str(), pathToResources + string("traces/") + devices[i].trace, devices[i].clkMhz, this);
|
||||
StlPlayer<> *newPlayer = new StlPlayer<>(playerStr.c_str(), pathToResources + string("traces/") + devices[i].trace, devices[i].clkMhz, this);
|
||||
player = newPlayer;
|
||||
newPlayer->getTraceLength(pathToResources + string("traces/") + devices[i].trace);
|
||||
totalTransactions += newPlayer->getNumberOfLines(pathToResources + string("traces/") + devices[i].trace);
|
||||
}
|
||||
else
|
||||
{
|
||||
player = new StlDataPlayer<>(playerStr.c_str(), pathToResources + string("traces/") + devices[i].trace, devices[i].clkMhz, this);
|
||||
StlDataPlayer<> *newPlayer = new StlDataPlayer<>(playerStr.c_str(), pathToResources + string("traces/") + devices[i].trace, devices[i].clkMhz, this);
|
||||
player = newPlayer;
|
||||
newPlayer->getTraceLength(pathToResources + string("traces/") + devices[i].trace);
|
||||
totalTransactions += newPlayer->getNumberOfLines(pathToResources + string("traces/") + devices[i].trace);
|
||||
}
|
||||
players.push_back(player);
|
||||
}
|
||||
remainingTransactions = totalTransactions;
|
||||
|
||||
//player->remainingTransactions = player->totalTransactions;
|
||||
|
||||
// Create and properly initialize TLM recorders. They need to be ready before creating some modules.
|
||||
setupTlmRecorders(traceName, pathToResources, devices);
|
||||
@@ -177,7 +186,7 @@ Simulation::~Simulation()
|
||||
}
|
||||
|
||||
for (auto rec : tlmRecorders) {
|
||||
delete rec;
|
||||
delete rec;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,7 +198,7 @@ void Simulation::start()
|
||||
report(" -> memspec: \t\t" + Configuration::getInstance().memSpec.MemoryId);
|
||||
cout << endl;
|
||||
simulationStartTime = clock();
|
||||
|
||||
|
||||
for (auto player : players) {
|
||||
player->nextPayload();
|
||||
}
|
||||
@@ -224,6 +233,17 @@ void Simulation::stop()
|
||||
report("Simulation took " + to_string(elapsed_secs) + " seconds");
|
||||
}
|
||||
|
||||
|
||||
void inline Simulation::transactionFinished()
|
||||
{
|
||||
remainingTransactions--;
|
||||
loadbar(totalTransactions - remainingTransactions, totalTransactions);
|
||||
if (remainingTransactions == 0)
|
||||
{
|
||||
cout << endl;
|
||||
}
|
||||
}
|
||||
|
||||
void Simulation::report(string message)
|
||||
{
|
||||
DebugManager::getInstance().printDebugMessage(this->name(), message);
|
||||
|
||||
@@ -86,6 +86,7 @@ public:
|
||||
void stop();
|
||||
|
||||
virtual void tracePlayerTerminates() override;
|
||||
virtual void transactionFinished() override;
|
||||
|
||||
private:
|
||||
std::string traceName;
|
||||
@@ -107,6 +108,9 @@ private:
|
||||
// Transaction Recorders (one per channel). They generate the output databases.
|
||||
std::vector<TlmRecorder*> tlmRecorders;
|
||||
|
||||
unsigned int totalTransactions = 0;
|
||||
unsigned int remainingTransactions;
|
||||
|
||||
clock_t simulationStartTime;
|
||||
void report(std::string message);
|
||||
void setupTlmRecorders(const string &traceName, const string &pathToResources, const std::vector<Device> &devices);
|
||||
|
||||
@@ -134,6 +134,63 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void getTraceLength(string pathToTrace)
|
||||
{
|
||||
ifstream newFile;
|
||||
newFile.open(pathToTrace);
|
||||
if(newFile.is_open()) {
|
||||
newFile.seekg(-1,ios_base::end);// go to one spot before the EOF
|
||||
char ch;
|
||||
newFile.get(ch);
|
||||
|
||||
if(ch == file.eof())
|
||||
SC_REPORT_FATAL(0, (string("Empty Trace ") + pathToTrace).c_str());
|
||||
|
||||
if(ch == '\n')
|
||||
newFile.seekg(-2,ios_base::end);
|
||||
|
||||
bool keepLooping = true;
|
||||
while(keepLooping) {
|
||||
|
||||
newFile.get(ch); // Get current byte's data
|
||||
|
||||
if((int)newFile.tellg() <= 1) { // If the data was at or before the 0th byte
|
||||
newFile.seekg(0); // The first line is the last line
|
||||
keepLooping = false; // So stop there
|
||||
}
|
||||
else if(ch == '\n') { // If the data was a newline
|
||||
keepLooping = false; // Stop at the current position.
|
||||
}
|
||||
else { // If the data was neither a newline nor at the 0 byte
|
||||
newFile.seekg(-2,ios_base::cur); // Move to the front of that data, then to the front of the data before it
|
||||
}
|
||||
}
|
||||
|
||||
string lastLine;
|
||||
getline(newFile,lastLine); // Read the current line
|
||||
std::istringstream iss(lastLine);
|
||||
string time;
|
||||
iss >> time;
|
||||
Configuration::getInstance().TraceLength = std::stoull(time.c_str())*clk;
|
||||
newFile.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
unsigned int getNumberOfLines(string pathToTrace)
|
||||
{
|
||||
ifstream newFile;
|
||||
newFile.open(pathToTrace);
|
||||
newFile.unsetf(std::ios_base::skipws); // new lines will be skipped unless we stop it from happening:
|
||||
// count the newlines with an algorithm specialized for counting:
|
||||
unsigned int lineCount = std::count(std::istream_iterator<char>(newFile), std::istream_iterator<char>(), '\n');
|
||||
|
||||
newFile.close();
|
||||
return lineCount;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private:
|
||||
ifstream file;
|
||||
unsigned int burstlength;
|
||||
|
||||
@@ -120,6 +120,64 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void getTraceLength(string pathToTrace)
|
||||
{
|
||||
ifstream newFile;
|
||||
newFile.open(pathToTrace);
|
||||
if(newFile.is_open()) {
|
||||
newFile.seekg(-1,ios_base::end);// go to one spot before the EOF
|
||||
char ch;
|
||||
newFile.get(ch);
|
||||
|
||||
if(ch == file.eof())
|
||||
SC_REPORT_FATAL(0, (string("Empty Trace ") + pathToTrace).c_str());
|
||||
|
||||
if(ch == '\n')
|
||||
newFile.seekg(-2,ios_base::end);
|
||||
|
||||
bool keepLooping = true;
|
||||
while(keepLooping) {
|
||||
|
||||
newFile.get(ch); // Get current byte's data
|
||||
|
||||
if((int)newFile.tellg() <= 1) { // If the data was at or before the 0th byte
|
||||
newFile.seekg(0); // The first line is the last line
|
||||
keepLooping = false; // So stop there
|
||||
}
|
||||
else if(ch == '\n') { // If the data was a newline
|
||||
keepLooping = false; // Stop at the current position.
|
||||
}
|
||||
else { // If the data was neither a newline nor at the 0 byte
|
||||
newFile.seekg(-2,ios_base::cur); // Move to the front of that data, then to the front of the data before it
|
||||
}
|
||||
}
|
||||
|
||||
string lastLine;
|
||||
getline(newFile,lastLine); // Read the current line
|
||||
std::istringstream iss(lastLine);
|
||||
string time;
|
||||
iss >> time;
|
||||
Configuration::getInstance().TraceLength = std::stoull(time.c_str())*clk;
|
||||
newFile.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
unsigned int getNumberOfLines(string pathToTrace)
|
||||
{
|
||||
ifstream newFile;
|
||||
newFile.open(pathToTrace);
|
||||
newFile.unsetf(std::ios_base::skipws); // new lines will be skipped unless we stop it from happening:
|
||||
// count the newlines with an algorithm specialized for counting:
|
||||
unsigned int lineCount = std::count(std::istream_iterator<char>(newFile), std::istream_iterator<char>(), '\n');
|
||||
|
||||
newFile.close();
|
||||
return lineCount;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
ifstream file;
|
||||
unsigned int burstlength;
|
||||
|
||||
@@ -96,7 +96,7 @@ gp *TracePlayer<BUSWIDTH>::allocatePayload()
|
||||
template<unsigned int BUSWIDTH>
|
||||
void TracePlayer<BUSWIDTH>::terminate()
|
||||
{
|
||||
cout << sc_time_stamp() << " " << this->name() << " terminated" << std::endl;
|
||||
cout << sc_time_stamp() << " " << this->name() << " terminated " << std::endl;
|
||||
listener->tracePlayerTerminates();
|
||||
}
|
||||
|
||||
@@ -159,6 +159,9 @@ void TracePlayer<BUSWIDTH>::peqCallback(tlm_generic_payload &payload, const tlm_
|
||||
|
||||
sendToTarget(payload, END_RESP, SC_ZERO_TIME);
|
||||
payload.release();
|
||||
if(Configuration::getInstance().SimulationProgressBar)
|
||||
listener->transactionFinished();
|
||||
|
||||
}
|
||||
else if (phase == END_RESP)
|
||||
{
|
||||
|
||||
@@ -42,6 +42,7 @@ class TracePlayerListener
|
||||
{
|
||||
public:
|
||||
virtual void tracePlayerTerminates() = 0;
|
||||
virtual void transactionFinished() = 0;
|
||||
};
|
||||
|
||||
#endif // TRACEPLAYERLISTENER_H
|
||||
|
||||
22
README.md
22
README.md
@@ -319,12 +319,12 @@ The DRAMSys' main configuration file is presented below.
|
||||
<Debug value="1" />
|
||||
<DatabaseRecording value="1" />
|
||||
<PowerAnalysis value="1" />
|
||||
<PowerWindowSize value="1000" />
|
||||
<PowerWindowUnit value="ns" />
|
||||
<NumberOfTimeWindows value="1000" />
|
||||
<NumberOfTracePlayers value="1"/>
|
||||
<NumberOfMemChannels value="4"/>
|
||||
<ControllerCoreDisableRefresh value="0"/>
|
||||
<ThermalSimulation value="1"/>
|
||||
<SimulationProgressBar value="1"/>
|
||||
</simconfig>
|
||||
|
||||
<!-- Temperature Simulator Configuration (used for all simulation setups) -->
|
||||
@@ -419,12 +419,12 @@ The XML code below shows a typic configuration:
|
||||
<Debug value="1"/>
|
||||
<DatabaseRecording value="1"/>
|
||||
<PowerAnalysis value="1"/>
|
||||
<PowerWindowSize value="1000" />
|
||||
<PowerWindowUnit value="ns" />
|
||||
<NumberOfTimeWindows value="1000" />
|
||||
<NumberOfTracePlayers value="5"/>
|
||||
<NumberOfMemChannels value="1"/>
|
||||
<ControllerCoreDisableRefresh value="0"/>
|
||||
<ThermalSimulation value="0"/>
|
||||
<SimulationProgressBar value="1"/>
|
||||
</simconfig>
|
||||
|
||||
<!-- Temperature Simulator Configuration (used for all simulation setups) -->
|
||||
@@ -532,15 +532,8 @@ Below are listed the configuration sections and configuration fields.
|
||||
- *PowerAnalysis* (boolean)
|
||||
- "1": enables live power analysis with the DRAMPower tool
|
||||
- "0": disables power analysis
|
||||
- *PowerWindowSize* (double)
|
||||
- Size of the time window used to evaluate averate power consumption
|
||||
- *PowerWindowUnit* (string)
|
||||
- "s": seconds
|
||||
- "ms": millisecond
|
||||
- "us": microseconds
|
||||
- "ns": nanoseconds
|
||||
- "ps": picoseconds
|
||||
- "fs": femtoseconds
|
||||
- *NumberOfTimeWindows* (int)
|
||||
- number of time windows used to evaluate average bandwidth and average power consumption
|
||||
- *NumberOfTracePlayers* (unsigned int)
|
||||
- Number of trace players
|
||||
- *NumberOfMemChannels* (unsigned int)
|
||||
@@ -551,6 +544,9 @@ Below are listed the configuration sections and configuration fields.
|
||||
- *ThermalSimulation* (boolean)
|
||||
- "1": enables thermal simulation
|
||||
- "0": static temperature during simulation
|
||||
- *SimulationProgressBar* (boolean)
|
||||
- "1": enables the simulation progress bar
|
||||
- "0": disables the simulation progress bar
|
||||
|
||||
- **Temperature Simulator Configuration**
|
||||
- *TemperatureScale* (string)
|
||||
|
||||
Reference in New Issue
Block a user