diff --git a/README.md b/README.md index 4eabcd46..59e654e9 100644 --- a/README.md +++ b/README.md @@ -3,21 +3,9 @@ de.uni-kl.ems.dram.vp.system Generic DRAM controller -#Setup with Eclipse +#Setup with QTCreator -1. Start Eclipse ($eclipse) -2. -> Import - -> Git - -> Projects from Git - -> Existing Local Repository - -> Add Path to $dram.vp.system - -> Import Existing Projects - -> Finish - -3. Configure Eclipse: - -> Run Configurations - -> Environment - -> Variable: LD_LIBRARY_PATH = /opt/systemc/lib-linux64/:/opt/gcc/lib64 +needs update! diff --git a/analyzer/analyzer/businessObjects/phases/phase.cpp b/analyzer/analyzer/businessObjects/phases/phase.cpp index a3e467f4..3a5827b7 100644 --- a/analyzer/analyzer/businessObjects/phases/phase.cpp +++ b/analyzer/analyzer/businessObjects/phases/phase.cpp @@ -28,7 +28,13 @@ void Phase::draw(QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap & painter->setPen(pen); } - drawPhaseSymbol(span.Begin(), span.End(), getYVal(drawingProperties), drawingProperties.drawText,getPhaseSymbol(), painter, xMap, yMap); + if(!isBankwise()) + { + for(unsigned int i=0; iisBankwise() || fabs(yVal-getYVal(drawingproperties))<=hexagonHeigth)) return true; if (spanOnDataBus && spanOnDataBus->contains(time) && fabs(yVal-drawingproperties.yValDataBus)<=hexagonHeigth) return true; diff --git a/analyzer/analyzer/businessObjects/phases/phase.h b/analyzer/analyzer/businessObjects/phases/phase.h index 5d827512..8c643849 100644 --- a/analyzer/analyzer/businessObjects/phases/phase.h +++ b/analyzer/analyzer/businessObjects/phases/phase.h @@ -25,6 +25,7 @@ public: const Timespan& Span() const {return span;} ID Id() const {return id;} virtual QString Name() const = 0; + virtual bool isBankwise() const {return true;} protected: ID id; @@ -136,6 +137,24 @@ protected: } }; +class REFA : public AUTO_REFRESH +{ +public: + using AUTO_REFRESH::AUTO_REFRESH; +protected: + virtual QString Name() const override {return "REFA";} + virtual bool isBankwise() const {return false;} +}; + +class REFB : public AUTO_REFRESH +{ +public: + using AUTO_REFRESH::AUTO_REFRESH; +protected: + virtual QString Name() const override {return "REFB";} +}; + + class PRECHARGE_ALL : public Phase { public: @@ -145,42 +164,71 @@ protected: virtual std::vector getTimesOnCommandBus() const {return {span.Begin()};} virtual QColor getColor(const TraceDrawingProperties &drawingProperties) const override {Q_UNUSED(drawingProperties) return getPhaseColor();} virtual QColor getPhaseColor() const override {return ColorGenerator::getColor(10);} + virtual bool isBankwise() const {return false;} }; -class PDNA : public Phase +class PDNAB : public Phase { public: using Phase::Phase; protected: - virtual QString Name() const override {return "PDNA";} + virtual QString Name() const override {return "PDNAB";} virtual Qt::BrushStyle getBrushStyle() const override {return Qt::Dense6Pattern;} virtual QColor getColor(const TraceDrawingProperties &drawingProperties) const override {Q_UNUSED(drawingProperties) return getPhaseColor();} virtual QColor getPhaseColor() const override {return QColor(Qt::black);} virtual Phase::PhaseSymbol getPhaseSymbol() const override {return PhaseSymbol::Rect;} }; -class PDNP : public Phase +class PDNA : public PDNAB +{ +public: + using PDNAB::PDNAB; +protected: + virtual QString Name() const override {return "PDNA";} + virtual bool isBankwise() const {return false;} +}; + +class PDNPB : public Phase { public: using Phase::Phase; protected: - virtual QString Name() const override {return "PDNP";} + virtual QString Name() const override {return "PDNPB";} virtual Qt::BrushStyle getBrushStyle() const override{return Qt::Dense4Pattern;} virtual QColor getColor(const TraceDrawingProperties &drawingProperties) const override {Q_UNUSED(drawingProperties) return getPhaseColor();} virtual QColor getPhaseColor() const override {return QColor(Qt::black);} virtual Phase::PhaseSymbol getPhaseSymbol() const override {return PhaseSymbol::Rect;} }; -class SREF : public Phase +class PDNP : public PDNPB +{ +public: + using PDNPB::PDNPB; +protected: + virtual QString Name() const override {return "PDNP";} + virtual bool isBankwise() const {return false;} +}; + +class SREFB : public Phase { public: using Phase::Phase; protected: - virtual QString Name() const final {return "SREF";} + virtual QString Name() const {return "SREFB";} virtual Qt::BrushStyle getBrushStyle() const {return Qt::Dense1Pattern;} virtual QColor getColor(const TraceDrawingProperties &drawingProperties) const override {Q_UNUSED(drawingProperties) return getPhaseColor();} virtual QColor getPhaseColor() const override {return QColor(Qt::black);} virtual Phase::PhaseSymbol getPhaseSymbol() const override {return PhaseSymbol::Rect;} }; +class SREF : public SREFB +{ +public: + using SREFB::SREFB; +protected: + virtual QString Name() const override {return "SREF";} + virtual bool isBankwise() const {return false;} +}; + + #endif // BANKPHASE_H diff --git a/analyzer/analyzer/businessObjects/phases/phasefactory.cpp b/analyzer/analyzer/businessObjects/phases/phasefactory.cpp index 37da7a93..efcf69da 100644 --- a/analyzer/analyzer/businessObjects/phases/phasefactory.cpp +++ b/analyzer/analyzer/businessObjects/phases/phasefactory.cpp @@ -22,8 +22,10 @@ shared_ptr PhaseFactory::CreatePhase(ID id, const QString& dbPhaseName,co return shared_ptr(new ACT(id, span,trans,{Timespan(span.Begin(),span.Begin()+clk)},std::shared_ptr())); else if(dbPhaseName == "PRE_ALL") return shared_ptr(new PRECHARGE_ALL(id,span,trans,{Timespan(span.Begin(),span.Begin()+clk)},std::shared_ptr())); - else if(dbPhaseName == "AUTO_REFRESH") - return shared_ptr(new AUTO_REFRESH(id, span,trans,{Timespan(span.Begin(),span.Begin()+clk)},std::shared_ptr())); + else if(dbPhaseName == "REFA") + return shared_ptr(new REFA(id, span,trans,{Timespan(span.Begin(),span.Begin()+clk)},std::shared_ptr())); + else if(dbPhaseName == "REFB") + return shared_ptr(new REFB(id, span,trans,{Timespan(span.Begin(),span.Begin()+clk)},std::shared_ptr())); else if(dbPhaseName == "RD") return shared_ptr(new RD(id, span,trans,{Timespan(span.Begin(),span.Begin()+clk)},std::shared_ptr(new Timespan(trans->SpanOnDataStrobe())))); @@ -33,13 +35,18 @@ shared_ptr PhaseFactory::CreatePhase(ID id, const QString& dbPhaseName,co return shared_ptr(new WR(id, span,trans,{Timespan(span.Begin(),span.Begin()+clk)},std::shared_ptr(new Timespan(trans->SpanOnDataStrobe())))); else if(dbPhaseName == "WRA") return shared_ptr(new WRA(id, span,trans,{Timespan(span.Begin(),span.Begin()+clk)},std::shared_ptr(new Timespan(trans->SpanOnDataStrobe())))); - - else if(dbPhaseName == "SREF") - return shared_ptr(new SREF(id, span, trans,{Timespan(span.Begin(),span.Begin()+clk),Timespan(span.End()-clk,span.End())},std::shared_ptr())); else if(dbPhaseName == "PDNA") return shared_ptr(new PDNA(id, span,trans, {Timespan(span.Begin(),span.Begin()+clk),Timespan(span.End()-clk,span.End())},std::shared_ptr())); + else if(dbPhaseName == "PDNAB") + return shared_ptr(new PDNAB(id, span,trans, {Timespan(span.Begin(),span.Begin()+clk),Timespan(span.End()-clk,span.End())},std::shared_ptr())); else if(dbPhaseName == "PDNP") return shared_ptr(new PDNP(id, span,trans, {Timespan(span.Begin(),span.Begin()+clk),Timespan(span.End()-clk,span.End())},std::shared_ptr())); + else if(dbPhaseName == "PDNPB") + return shared_ptr(new PDNPB(id, span,trans, {Timespan(span.Begin(),span.Begin()+clk),Timespan(span.End()-clk,span.End())},std::shared_ptr())); + else if(dbPhaseName == "SREF") + return shared_ptr(new SREF(id, span, trans,{Timespan(span.Begin(),span.Begin()+clk),Timespan(span.End()-clk,span.End())},std::shared_ptr())); + else if(dbPhaseName == "SREFB") + return shared_ptr(new SREFB(id, span, trans,{Timespan(span.Begin(),span.Begin()+clk),Timespan(span.End()-clk,span.End())},std::shared_ptr())); else throw std::runtime_error("DB phasename " + dbPhaseName.toStdString() + " unkown to phasefactory"); } diff --git a/dram/dramSys/dramSys.pro b/dram/dramSys/dramSys.pro index 9a679742..6ba44ef5 100644 --- a/dram/dramSys/dramSys.pro +++ b/dram/dramSys/dramSys.pro @@ -1,4 +1,4 @@ - TEMPLATE = app +TEMPLATE = app CONFIG += console CONFIG -= app_bundle CONFIG -= qt @@ -21,6 +21,7 @@ INCLUDEPATH += /opt/sqlite3/include DEFINES += TIXML_USE_STL DEFINES += SC_INCLUDE_DYNAMIC_PROCESSES DEFINES += USE_XERCES=1 +DEFINES += NDEBUG QMAKE_CXXFLAGS += -std=c++11 QMAKE_CXXFLAGS += -isystem /opt/systemc/include @@ -70,7 +71,6 @@ SOURCES += \ HEADERS += \ ../src/common/third_party/tinyxml2.h \ - ../src/common/xmlConfig.h \ ../src/common/xmlAddressdecoder.h \ ../src/common/Utils.h \ ../src/common/TlmRecorder.h \ diff --git a/dram/resources/configs/memconfigs/fifo.xml b/dram/resources/configs/memconfigs/fifo.xml index 2e23e330..603049f2 100644 --- a/dram/resources/configs/memconfigs/fifo.xml +++ b/dram/resources/configs/memconfigs/fifo.xml @@ -1,6 +1,6 @@ - + diff --git a/dram/resources/scripts/metrics.py b/dram/resources/scripts/metrics.py index 7f780cca..dfcf491a 100644 --- a/dram/resources/scripts/metrics.py +++ b/dram/resources/scripts/metrics.py @@ -38,17 +38,17 @@ def getClock(connection): result = cursor.fetchone() return result[0] -@metric -def latency_histogram(connection): - cursor = connection.cursor() - cursor.execute("SELECT ((p2.PhaseEnd - p1.PhaseEnd)/1000) FROM Transactions t, Phases p1, Phases p2 WHERE t.id = p1.Transact and t.id = p2.Transact and p1.PhaseName = \"REQ\" and p2.PhaseName = \"RESP\" ") - result = cursor.fetchall() - #result.sort() - #print(max(result)[0]) - import matplotlib.pyplot as plt - plt.hist(result, bins=max(result)[0], histtype='barstacked') - plt.savefig('hist.png') - return "Saved as hist.png" +#@metric +#def latency_histogram(connection): +# cursor = connection.cursor() +# cursor.execute("SELECT ((p2.PhaseEnd - p1.PhaseEnd)/1000) FROM Transactions t, Phases p1, Phases p2 WHERE t.id = p1.Transact and t.id = p2.Transact and p1.PhaseName = \"REQ\" and p2.PhaseName = \"RESP\" ") +# result = cursor.fetchall() +# #result.sort() +# #print(max(result)[0]) +# import matplotlib.pyplot as plt +# plt.hist(result, bins=max(result)[0], histtype='barstacked') +# plt.savefig('hist.png') +# return "Saved as hist.png" @metric def average_response_latency_in_ns(connection): @@ -59,6 +59,17 @@ def average_response_latency_in_ns(connection): result = cursor.fetchone() return round(result[0],1) +@metric +def memory_utilisation_percent(connection): + cursor = connection.cursor() + cursor.execute(""" SELECT sum(DataStrobeEnd - DataStrobeBegin) FROM transactions """) + active = cursor.fetchone() + cursor = connection.cursor() + cursor.execute(""" SELECT max(DataStrobeEnd) FROM Transactions """) + total = cursor.fetchone() + return (active[0]/total[0])*100 + + def refreshMissDecision(connection,calculatedMetrics): cursor = connection.cursor() cursor.execute("""SELECT phases.ID,PhaseBegin,PhaseEnd,TBank FROM Phases INNER JOIN transactions on transactions.id = phases.transact WHERE PhaseName='AUTO_REFRESH' """) diff --git a/dram/resources/simulations/sim-batch.xml b/dram/resources/simulations/sim-batch.xml index 21a24d7c..a9e88a0b 100644 --- a/dram/resources/simulations/sim-batch.xml +++ b/dram/resources/simulations/sim-batch.xml @@ -10,8 +10,7 @@ - test.stl + chstone-sha_32.stl diff --git a/dram/src/common/TlmRecorder.cpp b/dram/src/common/TlmRecorder.cpp index e6bad2d4..7e2d3821 100644 --- a/dram/src/common/TlmRecorder.cpp +++ b/dram/src/common/TlmRecorder.cpp @@ -191,10 +191,14 @@ void TlmRecorder::createTables(string pathToURI) void TlmRecorder::setUpTransactionTerminatingPhases() { transactionTerminatingPhases.push_back(tlm::END_RESP); - transactionTerminatingPhases.push_back(static_cast(END_AUTO_REFRESH)); + transactionTerminatingPhases.push_back(static_cast(END_REFA)); + transactionTerminatingPhases.push_back(static_cast(END_REFB)); transactionTerminatingPhases.push_back(static_cast(END_PDNP)); transactionTerminatingPhases.push_back(static_cast(END_PDNA)); transactionTerminatingPhases.push_back(static_cast(END_SREF)); + transactionTerminatingPhases.push_back(static_cast(END_PDNPB)); + transactionTerminatingPhases.push_back(static_cast(END_PDNAB)); + transactionTerminatingPhases.push_back(static_cast(END_SREFB)); } void TlmRecorder::prepareSqlStatements() diff --git a/dram/src/common/protocol.h b/dram/src/common/protocol.h index 41e5daeb..a9c1ae57 100755 --- a/dram/src/common/protocol.h +++ b/dram/src/common/protocol.h @@ -11,8 +11,11 @@ DECLARE_EXTENDED_PHASE(END_PRE_ALL); DECLARE_EXTENDED_PHASE(BEGIN_ACT); DECLARE_EXTENDED_PHASE(END_ACT); -DECLARE_EXTENDED_PHASE(BEGIN_AUTO_REFRESH); -DECLARE_EXTENDED_PHASE(END_AUTO_REFRESH); +DECLARE_EXTENDED_PHASE(BEGIN_REFA); +DECLARE_EXTENDED_PHASE(END_REFA); + +DECLARE_EXTENDED_PHASE(BEGIN_REFB); +DECLARE_EXTENDED_PHASE(END_REFB); // Phases for Read and Write @@ -38,6 +41,16 @@ DECLARE_EXTENDED_PHASE(END_PDNA); DECLARE_EXTENDED_PHASE(BEGIN_SREF); DECLARE_EXTENDED_PHASE(END_SREF); +// Phases for Power Down Bankwise +DECLARE_EXTENDED_PHASE(BEGIN_PDNPB); +DECLARE_EXTENDED_PHASE(END_PDNPB); + +DECLARE_EXTENDED_PHASE(BEGIN_PDNAB); +DECLARE_EXTENDED_PHASE(END_PDNAB); + +DECLARE_EXTENDED_PHASE(BEGIN_SREFB); +DECLARE_EXTENDED_PHASE(END_SREFB); + //Triggers DECLARE_EXTENDED_PHASE(REF_TRIGGER); diff --git a/dram/src/common/xmlConfig.h b/dram/src/common/xmlConfig.h deleted file mode 100755 index 110dd2aa..00000000 --- a/dram/src/common/xmlConfig.h +++ /dev/null @@ -1,97 +0,0 @@ -#ifndef CONFIH_H -#define CONFIH_H - -#include -#include - -using namespace std; - -class xmlConfig -{ - public: - - sc_time clk; - sc_time tRRD; - sc_time tRC; - sc_time tRCD; - sc_time tBL; - sc_time tRL; - sc_time tWL; - sc_time tWTR; - sc_time tRP; - sc_time tRAS; - sc_time tWR; - sc_time tREF; - sc_time tRFC; - sc_time tXP; - sc_time tCKE; - sc_time tXSR; - sc_time tCKESR; - sc_time tREFA; - sc_time tREFB; - sc_time tPDNTO; - - double IDD0; - double IDD2N; - double IDD3N; - double IDD4R; - double IDD4W; - double IDD5; - double IDD6; - double IDD5B1; - double IDD2P; - double IDD3P; - double VDD; - - sc_time ccPreprocessingTime; - - public: - xmlConfig() - { - //clk = sc_time(6.0, SC_NS); // 166MHz - clk = sc_time(6, SC_NS); // 166MHz - - // Timings: - // WC timings for 200MHz - // before thermal: - tRRD = 2 * clk; // 2 * clk; // 4 * clk;//1 * clk; //2 * clk; - tRCD = 3 * clk; // 2 * clk; // 10 * clk;//3 * clk; //4 * clk; - tRL = 3 * clk; // 3 * clk; // 10 * clk;//3 * clk; //3 * clk; - tBL = 1 * clk; // 1 * clk; // 1 * clk;//1 * clk; //1 * clk; - tWL = 1 * clk; // 1 * clk; // 9 * clk;//1 * clk; //1 * clk; - tWTR = 3 * clk; // 3 * clk; // 4 * clk;//3 * clk; //3 * clk; - tRP = 3 * clk; // 3 * clk; // 10 * clk;//3 * clk; //4 * clk; // sadri changed from 2 to 3 = 18ns/6ns - tRAS = 6 * clk; // 5 * clk; // 18 * clk;//8 * clk; //9 * clk; - tWR = 2 * clk; // 2 * clk; // 10 * clk;//2 * clk; //3 * clk; - tRFC = 18 * clk; // 22 * clk; // 15 * clk; // 110* clk;//18 * clk; // sadri changed from 15 to 22 = 130ns/6ns - tXP = 2 * clk; - tCKE = 3 * clk; - tXSR = tRFC + 2 * clk; - tCKESR = 3 * clk; - tPDNTO = 0 * clk; - tRC = tRP + tRAS; - tREF = sc_time(64, SC_MS); - tREFA = tRP + tRFC; - tREFB = tRP + tRC; // refresh for one bank - - // Power realted currents and voltages: - // 166MHz thermal non minimal timings (200MHz) - // 166MHz with minimal timing - IDD0 = 37.85 / 1000.0; // 47.3 / 1000.0; //64 / 1000.0; - IDD2N = 4.36 / 1000.0; // 4.36 / 1000.0; //4.4 / 1000.0; - IDD3N = 5.60 / 1000.0; // 6.07 / 1000.0; //5.9 / 1000.0; - IDD4R = 94.64 / 1000.0; // 94.65 / 1000.0; //94 / 1000.0; - IDD4W = 88.65 / 1000.0; // 88.66 / 1000.0; //88 / 1000.0; - IDD5 = 136.20 / 1000.0; // 162.56 / 1000.0; //163 / 1000.0; - IDD5B1 = 37.32 / 1000.0; // - IDD2P = 2.4 / 1000.0; // - IDD3P = 3.6 / 1000.0; // - IDD6 = 3.4 / 1000.0; // - - VDD = 1.2; - - ccPreprocessingTime = 1 * clk; - } -}; - -#endif diff --git a/dram/src/controller/Controller.h b/dram/src/controller/Controller.h index 814ffc56..4c0f5a7d 100644 --- a/dram/src/controller/Controller.h +++ b/dram/src/controller/Controller.h @@ -165,7 +165,13 @@ void Controller::send(const ScheduledCommand &command, tlm_generic_pay controllerCorePEQ.notify(payload, BEGIN_WRA, command.getStart() - sc_time_stamp()); break; case Command::AutoRefresh: - controllerCorePEQ.notify(payload, BEGIN_AUTO_REFRESH, command.getStart() - sc_time_stamp()); + if(!Configuration::getInstance().BankwiseLogic) + { + if(command.getBank() == Bank(0)) + controllerCorePEQ.notify(payload, BEGIN_REFA, command.getStart() - sc_time_stamp()); + } + else + controllerCorePEQ.notify(payload, BEGIN_REFB, command.getStart() - sc_time_stamp()); break; case Command::Activate: controllerCorePEQ.notify(payload, BEGIN_ACT, command.getStart() - sc_time_stamp()); @@ -174,27 +180,63 @@ void Controller::send(const ScheduledCommand &command, tlm_generic_pay controllerCorePEQ.notify(payload, BEGIN_PRE, command.getStart() - sc_time_stamp()); break; case Command::PrechargeAll: - controllerCorePEQ.notify(payload, BEGIN_PRE_ALL, command.getStart() - sc_time_stamp()); + if(command.getBank() == Bank(0)) + controllerCorePEQ.notify(payload, BEGIN_PRE_ALL, command.getStart() - sc_time_stamp()); break; case Command::PDNA: - controllerCorePEQ.notify(payload, BEGIN_PDNA, command.getStart() - sc_time_stamp()); - break; - case Command::PDNP: - controllerCorePEQ.notify(payload, BEGIN_PDNP, command.getStart() - sc_time_stamp()); - break; - case Command::SREF: - controllerCorePEQ.notify(payload, BEGIN_SREF, command.getStart() - sc_time_stamp()); + if(!Configuration::getInstance().BankwiseLogic) + { + if(command.getBank() == Bank(0)) + controllerCorePEQ.notify(payload, BEGIN_PDNA, command.getStart() - sc_time_stamp()); + } + else + controllerCorePEQ.notify(payload, BEGIN_PDNAB, command.getStart() - sc_time_stamp()); break; case Command::PDNAX: - controllerCorePEQ.notify(payload, END_PDNA, command.getEnd() - sc_time_stamp()); + if(!Configuration::getInstance().BankwiseLogic) + { + if(command.getBank() == Bank(0)) + controllerCorePEQ.notify(payload, END_PDNA, command.getStart() - sc_time_stamp()); + } + else + controllerCorePEQ.notify(payload, END_PDNAB, command.getStart() - sc_time_stamp()); + break; + case Command::PDNP: + if(!Configuration::getInstance().BankwiseLogic) + { + if(command.getBank() == Bank(0)) + controllerCorePEQ.notify(payload, BEGIN_PDNP, command.getStart() - sc_time_stamp()); + } + else + controllerCorePEQ.notify(payload, BEGIN_PDNPB, command.getStart() - sc_time_stamp()); break; case Command::PDNPX: - controllerCorePEQ.notify(payload, END_PDNP, command.getEnd() - sc_time_stamp()); + if(!Configuration::getInstance().BankwiseLogic) + { + if(command.getBank() == Bank(0)) + controllerCorePEQ.notify(payload, END_PDNP, command.getStart() - sc_time_stamp()); + } + else + controllerCorePEQ.notify(payload, END_PDNPB, command.getStart() - sc_time_stamp()); + break; + case Command::SREF: + if(!Configuration::getInstance().BankwiseLogic) + { + if(command.getBank() == Bank(0)) + controllerCorePEQ.notify(payload, BEGIN_SREF, command.getStart() - sc_time_stamp()); + } + else + controllerCorePEQ.notify(payload, BEGIN_SREFB, command.getStart() - sc_time_stamp()); break; case Command::SREFX: - controllerCorePEQ.notify(payload, END_SREF, command.getEnd() - sc_time_stamp()); + if(!Configuration::getInstance().BankwiseLogic) + { + if(command.getBank() == Bank(0)) + controllerCorePEQ.notify(payload, END_SREF, command.getStart() - sc_time_stamp()); + } + else + controllerCorePEQ.notify(payload, END_SREFB, command.getStart() - sc_time_stamp()); break; - default: SC_REPORT_FATAL(0, "unsupported command was sent by controller"); break; @@ -239,12 +281,18 @@ void Controller::controllerCorePEQCallback(tlm_generic_payload &payloa if (phase == BEGIN_RD || phase == BEGIN_WR) scheduleNextPayload(); - else if (phase == BEGIN_AUTO_REFRESH) - printDebugMessage("Entering auto refresh on bank " + to_string(bank.ID())); - else if (containsPhase(phase, { BEGIN_PDNA, BEGIN_PDNP, BEGIN_SREF })) + else if (phase == BEGIN_REFB) + printDebugMessage("Entering REFB on bank " + to_string(bank.ID())); + else if (phase == BEGIN_REFA) + printDebugMessage("Entering REFA"); + else if (containsPhase(phase, { BEGIN_PDNAB, BEGIN_PDNPB, BEGIN_SREFB })) printDebugMessage("Entering PowerDown " + phaseNameToString(phase) + " on bank " + to_string(bank.ID())); - else if (containsPhase(phase, { END_PDNA, END_PDNP, END_SREF })) + else if (containsPhase(phase, { END_PDNAB, END_PDNPB, END_SREFB })) printDebugMessage("Leaving PowerDown " + phaseNameToString(phase) + " on bank " + to_string(bank.ID())); + else if (containsPhase(phase, { BEGIN_PDNA, BEGIN_PDNP, BEGIN_SREF })) + printDebugMessage("Entering PowerDown " + phaseNameToString(phase) + " on all banks"); + else if (containsPhase(phase, { END_PDNA, END_PDNP, END_SREF })) + printDebugMessage("Leaving PowerDown " + phaseNameToString(phase) + " on all banks" ); else if (containsPhase(phase, { BEGIN_RD, BEGIN_WR, BEGIN_ACT, BEGIN_PRE, BEGIN_PRE_ALL, BEGIN_RDA, BEGIN_WRA })) { } @@ -397,7 +445,7 @@ void Controller::dramPEQCallback(tlm_generic_payload &payload, const t sendToFrontend(payload, BEGIN_RESP, SC_ZERO_TIME); scheduleNextPayload(); } - else if (phase == END_AUTO_REFRESH) + else if (phase == END_REFA || phase == END_REFB)//TODO send all to sleep for REFA cause we only send for bank 0 now??? { printDebugMessage("Finished auto refresh on bank " + to_string(bank.ID())); if(numberOfPayloadsInSystem[bank] == 0) diff --git a/dram/src/simulation/Dram.h b/dram/src/simulation/Dram.h index f28b1749..bdb70e99 100644 --- a/dram/src/simulation/Dram.h +++ b/dram/src/simulation/Dram.h @@ -19,38 +19,90 @@ #include "../common/protocol.h" #include "../common/Utils.h" #include "../common/TlmRecorder.h" -//#include "../common/third_party/DRAMPower/src/libdrampower/LibDRAMPower.h" -//#include "../common/third_party/DRAMPower/src/xmlparser/MemSpecParser.h" -//#include "../common/third_party/DRAMPower/src/MemorySpecification.h" -//#include "../common/third_party/DRAMPower/src/MemCommand.h" +#include "../common/third_party/DRAMPower/src/libdrampower/LibDRAMPower.h" +#include "../common/third_party/DRAMPower/src/xmlparser/MemSpecParser.h" +#include "../common/third_party/DRAMPower/src/MemorySpecification.h" +#include "../common/third_party/DRAMPower/src/MemCommand.h" using namespace std; using namespace tlm; using namespace core; -//using namespace Data; +using namespace Data; + + +#define POWER + +#ifdef POWER + #define IFPOW(x) x +#else + #define IFPOW(x) +#endif + + +class column +{ + private: + + unsigned char * data; + unsigned int bytes; + + public: + + column() + { + bytes = 0; + data = NULL; + } + + column(int bytes) + { + bytes = bytes; + data = new unsigned char[bytes]; + } + + ~column() + { + //delete data; + } + + void set(unsigned char * payloadDataPtr) + { + printf("Dest: %p Source: %p\n",data,payloadDataPtr); + cout << "mem" ; + memcpy(data, payloadDataPtr, bytes); // XXX hier knallts + cout << "copy" << endl; + } + + void get(unsigned char * payloadDataPtr) + { + memcpy(payloadDataPtr, data, bytes); + } +}; template struct Dram: sc_module { tlm_utils::simple_target_socket tSocket; - //libDRAMPower *DRAMPower; + IFPOW(libDRAMPower *DRAMPower); + + map< unsigned long int, column * > memory; SC_CTOR(Dram) : tSocket("socket") { tSocket.register_nb_transport_fw(this, &Dram::nb_transport_fw); -// MemorySpecification memSpec(MemSpecParser::getMemSpecFromXML(Configuration::getInstance().memspecUri)); -// //MemorySpecification::getMemSpecFromXML(Configuration::getInstance().memspecUri)); -// DRAMPower = new libDRAMPower( memSpec, 1,1,1,0,0 ); + IFPOW( MemorySpecification memSpec(MemSpecParser::getMemSpecFromXML(Configuration::getInstance().memspecUri)) ); + IFPOW( DRAMPower = new libDRAMPower( memSpec, 0 ) ); } ~Dram() { -// DRAMPower->updateCounters(true); -// DRAMPower->getEnergy(); -// cout << "Total Energy" << "\t" << DRAMPower->mpm.energy.total_energy << endl; -// cout << "Average Power" << "\t" << DRAMPower->mpm.power.average_power << endl; + IFPOW( DRAMPower->updateCounters(true)); + IFPOW( DRAMPower->getEnergy() ); + IFPOW( cout << "Total Energy" << "\t" << DRAMPower->mpm.energy.total_energy << endl); + IFPOW( cout << "Average Power" << "\t" << DRAMPower->mpm.power.average_power << endl ); + std::cout << "Simulated Memory Size: " << memory.size() << endl; } virtual tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload& payload, tlm::tlm_phase& phase, sc_time& delay) @@ -58,102 +110,124 @@ struct Dram: sc_module TlmRecorder::getInstance().recordPhase(payload, phase, sc_time_stamp() + delay); // This is only needed for power simulation: - //unsigned long long cycle = sc_time_stamp().value()/Configuration::getInstance().Timings.clk.value(); + unsigned long long cycle = sc_time_stamp().value()/Configuration::getInstance().Timings.clk.value(); unsigned int bank = DramExtension::getExtension(payload).getBank().ID(); if (phase == BEGIN_PRE) { - //DRAMPower->doCommand(MemCommand::PRE, bank, cycle); + IFPOW(DRAMPower->doCommand(MemCommand::PRE, bank, cycle)); sendToController(payload, END_PRE, delay + getExecutionTime(Command::Precharge, payload)); } else if (phase == BEGIN_PRE_ALL) { - //DRAMPower->doCommand(MemCommand::PREA, bank, cycle); + IFPOW(DRAMPower->doCommand(MemCommand::PREA, bank, cycle)); sendToController(payload, END_PRE_ALL,delay + getExecutionTime(Command::PrechargeAll, payload)); } else if (phase == BEGIN_ACT) { - //DRAMPower->doCommand(MemCommand::ACT, bank, cycle); + IFPOW(DRAMPower->doCommand(MemCommand::ACT, bank, cycle)); sendToController(payload, END_ACT, delay + getExecutionTime(Command::Activate, payload)); } else if (phase == BEGIN_WR) { - //DRAMPower->doCommand(MemCommand::WR, bank, cycle); + IFPOW(DRAMPower->doCommand(MemCommand::WR, bank, cycle)); sendToController(payload, END_WR, delay + getExecutionTime(Command::Write, payload)); + + // Save: + column * c = new column(16); + c->set(payload.get_data_ptr()); // <-- hier drin knallts + memory[payload.get_address()] = c; } else if (phase == BEGIN_RD) { - //DRAMPower->doCommand(MemCommand::RD, bank, cycle); + IFPOW(DRAMPower->doCommand(MemCommand::RD, bank, cycle)); sendToController(payload, END_RD, delay + getExecutionTime(Command::Read, payload)); + + // Load: + //if(memory.count(payload.get_address()) == 1) + //{ + // column * c = memory[payload.get_address()]; + // c->get(payload.get_data_ptr()); + //} + //else + //{ + // SC_REPORT_WARNING ("DRAM", "Reading from an empty memory location"); + //} } else if (phase == BEGIN_WRA) { - //DRAMPower->doCommand(MemCommand::WRA, bank, cycle); + IFPOW(DRAMPower->doCommand(MemCommand::WRA, bank, cycle)); sendToController(payload, END_WRA, delay + getExecutionTime(Command::WriteA, payload)); } else if (phase == BEGIN_RDA) { - //DRAMPower->doCommand(MemCommand::RDA, bank, cycle); + IFPOW(DRAMPower->doCommand(MemCommand::RDA, bank, cycle)); sendToController(payload, END_RDA, delay + getExecutionTime(Command::ReadA, payload)); } - else if (phase == BEGIN_AUTO_REFRESH) + else if (phase == BEGIN_REFA) { - //DRAMPower->doCommand(MemCommand::REF, bank, cycle); - sendToController(payload, END_AUTO_REFRESH, delay + getExecutionTime(Command::AutoRefresh, payload)); + IFPOW(DRAMPower->doCommand(MemCommand::REF, bank, cycle)); + sendToController(payload, END_REFA, delay + getExecutionTime(Command::AutoRefresh, payload)); + } + + else if (phase == BEGIN_REFB) + { + IFPOW( SC_REPORT_FATAL("DRAM", "Power calculation for bankwise logic not supported") ); + sendToController(payload, END_REFB, delay + getExecutionTime(Command::AutoRefresh, payload)); } //Powerdown phases have to be started and ended by the controller, because they do not have a fixed length - else if (phase == BEGIN_PDNP) - { - if(Configuration::getInstance().BankwiseLogic == false) - { - if(bank == 0) - { - //DRAMPower->doCommand(MemCommand::PDN_S_PRE, bank, cycle); - } - } - } - else if (phase == END_PDNP) - { - if(Configuration::getInstance().BankwiseLogic == false) - { - if(bank == 0) - { - //DRAMPower->doCommand(MemCommand::PUP_PRE, bank, cycle); - } - } - } else if (phase == BEGIN_PDNA) { - if(Configuration::getInstance().BankwiseLogic == false) - { - if(bank == 0) - { - //DRAMPower->doCommand(MemCommand::PDN_S_ACT, bank, cycle); - } - } + IFPOW(DRAMPower->doCommand(MemCommand::PDN_S_ACT, bank, cycle)); } else if (phase == END_PDNA) { - if(Configuration::getInstance().BankwiseLogic ==false) - { - if(bank == 0) - { - //DRAMPower->doCommand(MemCommand::PUP_ACT, bank, cycle); - } - } + IFPOW(DRAMPower->doCommand(MemCommand::PUP_ACT, bank, cycle)); + } + else if (phase == BEGIN_PDNAB) + { + IFPOW(SC_REPORT_FATAL("DRAM", "Power calculation for bankwise logic not supported")); + } + else if (phase == END_PDNAB) + { + IFPOW(SC_REPORT_FATAL("DRAM", "Power calculation for bankwise logic not supported")); + } + else if (phase == BEGIN_PDNP) + { + IFPOW(DRAMPower->doCommand(MemCommand::PDN_S_PRE, bank, cycle)); + } + else if (phase == END_PDNP) + { + IFPOW(DRAMPower->doCommand(MemCommand::PUP_PRE, bank, cycle)); + } + else if (phase == BEGIN_PDNPB) + { + IFPOW(SC_REPORT_FATAL("DRAM", "Power calculation for bankwise logic not supported")); + } + else if (phase == END_PDNPB) + { + IFPOW(SC_REPORT_FATAL("DRAM", "Power calculation for bankwise logic not supported")); } else if (phase == BEGIN_SREF) { - //DRAMPower->doCommand(MemCommand::SREN, bank, cycle); + IFPOW(DRAMPower->doCommand(MemCommand::SREN, bank, cycle)); } else if (phase == END_SREF) { - //DRAMPower->doCommand(MemCommand::SREX, bank, cycle); + IFPOW(DRAMPower->doCommand(MemCommand::SREX, bank, cycle)); + } + else if (phase == BEGIN_SREFB) + { + IFPOW(SC_REPORT_FATAL("DRAM", "Power calculation for bankwise logic not supported")); + } + else if (phase == END_SREFB) + { + IFPOW(SC_REPORT_FATAL("DRAM", "Power calculation for bankwise logic not supported")); } else { - SC_REPORT_FATAL("DRAM", "DRAM PEQ was called with unknown phase"); + IFPOW(SC_REPORT_FATAL("DRAM", "DRAM PEQ was called with unknown phase")); } return tlm::TLM_ACCEPTED; } @@ -172,4 +246,6 @@ struct Dram: sc_module }; + + #endif /* DRAM_H_ */ diff --git a/dram/src/simulation/TracePlayer.h b/dram/src/simulation/TracePlayer.h index 42b589da..5581ed6c 100644 --- a/dram/src/simulation/TracePlayer.h +++ b/dram/src/simulation/TracePlayer.h @@ -87,11 +87,11 @@ void TracePlayer::generateNextPayload() { if (file) { - string time, command, address; + string time, command, address, data; file >> time >> command >> address; //if there is a newline at the end of the .stl - if (time.empty() || command.empty() || address.empty()) + if (time.empty() || command.empty() || address.empty() ) return; long parsedAdress = std::stoi(address.c_str(), 0, 16); @@ -99,6 +99,13 @@ void TracePlayer::generateNextPayload() gp* payload = memoryManager.allocate(); payload->set_address(parsedAdress); + // Set data pointer + unsigned char * dataElement = new unsigned char[16]; // TODO: column / burst breite + payload->set_data_length(16); // TODO: column / burst breite + payload->set_data_ptr(dataElement); + for(int i = 0; i < 16; i++) // TODO: column / burst breite + dataElement[i] = 0; + if (command == "read") { payload->set_command(TLM_READ_COMMAND); @@ -106,6 +113,17 @@ void TracePlayer::generateNextPayload() else if (command == "write") { payload->set_command(TLM_WRITE_COMMAND); + + // Parse and set data + file >> data; + unsigned int counter = 0; + for(int i = 0; i < 16*2-2; i=i+2) // TODO column / burst breite + { + std::string byteString = "0x"; + byteString.append(data.substr(i+2, 2)); + //cout << byteString << " " << std::stoi(byteString.c_str(), 0, 16) << endl; + dataElement[counter++] = std::stoi(byteString.c_str(), 0, 16); + } } else { @@ -113,7 +131,6 @@ void TracePlayer::generateNextPayload() (string("Corrupted tracefile, command ") + command + string(" unknown")).c_str()); } - payload->set_data_length(BUSWIDTH / 8); payload->set_response_status(TLM_INCOMPLETE_RESPONSE); payload->set_dmi_allowed(false); payload->set_byte_enable_length(0);