diff --git a/dram/resources/scripts/tests.py b/dram/resources/scripts/tests.py index bea32111..2c92bac5 100644 --- a/dram/resources/scripts/tests.py +++ b/dram/resources/scripts/tests.py @@ -139,13 +139,13 @@ class DramConfig(object): def clkAlign(self, value): return math.ceil(1.0*value/self.clk)*self.clk - def getWriteAcessTime(self): + def getWriteAccessTime(self): if(self.dataRate == 1): return self.clk*(self.burstLength - 1) elif (self.memoryType == "DDR4"): return self.clk*self.burstLength/self.dataRate - def getReadAcessTime(self): + def getReadAccessTime(self): return self.burstLength/self.dataRate * dramconfig.clk @@ -288,17 +288,17 @@ def timing_constraint(FirstPhase, SecondPhase): if(SecondPhaseName in ["PRE, PRE_ALL"]): return dramconfig.tRTP elif(SecondPhaseName in ["RD, RDA"]): - return max(dramconfig.tCCD_L, getReadAcessTime()) + return max(dramconfig.tCCD_L, getReadAccessTime()) elif(SecondPhase in ["WR","WRA"]): - return dramconfig.tRL + getReadAcessTime() - dramconfig.tWL + 2*dramconfig.clk + return dramconfig.tRL + getReadAccessTime() - dramconfig.tWL + 2*dramconfig.clk elif(SecondPhase == "PDNA" ): - return dramconfig.tRL + getReadAcessTime() + dramconfig.clk + return dramconfig.tRL + getReadAccessTime() + dramconfig.clk elif(FirstPhaseName == "WR"): if(SecondPhaseName in ["PRE, PRE_ALL", "PDNA"]): - return dramconfig.tWL + dramconfig.getWriteAcessTime() + dramconfig.tWR + return dramconfig.tWL + dramconfig.getWriteAccessTime() + dramconfig.tWR elif(SecondPhaseName in ["RD, RDA"]): - return dramconfig.tWL + dramconfig.getWriteAcessTime() + dramconfig.tWTR_L + return dramconfig.tWL + dramconfig.getWriteAccessTime() + dramconfig.tWTR_L elif(SecondPhaseName in ["WR, WRA"]): return max(dramconfig.tCCD_L, burstlength/dramconfig.dataRate) @@ -306,13 +306,13 @@ def timing_constraint(FirstPhase, SecondPhase): if(SecondPhaseName in ["ACT", "PRE_ALL", "AUTO_REFRESH"]): return dramconfig.tRTP + dramconfig.tRP elif(SecondPhaseName in ["PDNA","PDNP"]): - return dramconfig.tRL + getReadAcessTime() + dramconfig.clk + return dramconfig.tRL + getReadAccessTime() + dramconfig.clk elif(FirstPhaseName == "WRA"): if(SecondPhaseName in ["ACT", "PRE_ALL", "AUTO_REFRESH"]): - return dramconfig.tWL + getWriteAcessTime() + dramconfig.tWR + dramconfig.tRP + return dramconfig.tWL + getWriteAccessTime() + dramconfig.tWR + dramconfig.tRP elif(SecondPhaseName in ["PDNA","PDNP"]): - return dramconfig.tWL + dramconfig.getWriteAcessTime() + dramconfig.tWR + dramconfig.clk + return dramconfig.tWL + dramconfig.getWriteAccessTime() + dramconfig.tWR + dramconfig.clk elif(FirstPhaseName == "AUTO_REFRESH"): return dramconfig.tRFC @@ -438,49 +438,80 @@ def n_activate_window(connection): return TestSuceeded() -# # ----------- read/write checks --------------------------------------- + # ----------- read/write checks --------------------------------------- +@test +def read_to_read(connection): + cursor = connection.cursor() + cursor.execute("SELECT phases.ID,PhaseBegin,TBankGroup FROM Phases INNER JOIN transactions ON phases.transact=transactions.ID WHERE PhaseName IN ('RD','RDA') ORDER BY PhaseBegin") + lastRow = cursor.fetchone() -# @test -# def read_to_read(connection): -# """Checks minimal time between two reads(JEDEC 229, P. 29)""" -# cursor = connection.cursor() -# cursor.execute("SELECT Phases.ID, PhaseBegin, PhaseName from Phases WHERE PhaseName IN ('RD','RDA') ORDER BY PhaseBegin") -# lastRow = cursor.fetchone() + for currentRow in cursor: + timeBetweenReads = currentRow[1] - lastRow[1] + if (currentRow[2] == lastRow[2]): + minTime = max(dramconfig.tCCD_L,dramconfig.getReadAccessTime()) + else: + minTime = max(dramconfig.tCCD_S,dramconfig.getReadAccessTime()) + if(timeBetweenReads < minTime): + return TestFailed("Reads with PhaseIDs {0} and {1} are {2} apart. Minimum time between two reads is {3}".format(currentRow[0], lastRow[0],formatTime(timeBetweenReads), minTime)) + lastRow = currentRow + + return TestSuceeded() -# for currentRow in cursor: -# if(currentRow[1] < lastRow[1] + dramconfig.tReadLength): -# timeBetweenReads = currentRow[1] - lastRow[1]; -# clocksBetweenReads = round(timeBetweenReads/dramconfig.clk) -# if(clocksBetweenReads % 2 == 1): -# return TestFailed("{0} with PhaseID {1} interrupts data acess of {2} {3}. They are {4} clocks ({5}) apart. Numbers of clock between interrupting reads must be even.". -# format(currentRow[2], currentRow[0], lastRow[2], lastRow[0], clocksBetweenReads, formatTime(timeBetweenReads))) -# lastRow = currentRow -# return TestSuceeded() +@test +def write_to_write(connection): + cursor = connection.cursor() + cursor.execute("SELECT phases.ID,PhaseBegin,TBankGroup FROM Phases INNER JOIN transactions ON phases.transact=transactions.ID WHERE PhaseName IN ('WR','WRA') ORDER BY PhaseBegin") + lastRow = cursor.fetchone() -# @test -# def write_to_read_and_read_to_write(connection): -# """Checks minimal time between write and read/read and write (JEDEC 229, P. 33/34)""" -# cursor = connection.cursor() -# query = """SELECT Phases.ID,PhaseBegin,PhaseName from Phases INNER JOIN Transactions ON Phases.Transact = Transactions.ID -# WHERE PhaseName IN ('RD','WR','RDA','WRA') ORDER BY PhaseBegin""" + for currentRow in cursor: + timeBetweenWrites = currentRow[1] - lastRow[1] + if (currentRow[2] == lastRow[2]): + minTime = max(dramconfig.tCCD_L,dramconfig.getWriteAccessTime()) + else: + minTime = max(dramconfig.tCCD_S,dramconfig.getWriteAccessTime()) + if(timeBetweenWrites < minTime): + return TestFailed("Writes with PhaseIDs {0} and {1} are {2} apart. Minimum time between two writes is {3}".format(currentRow[0], lastRow[0],formatTime(timeBetweenWrites), minTime)) + lastRow = currentRow + return TestSuceeded() -# cursor.execute(query) -# lastRow = cursor.fetchone() +@test +def write_to_read_and_read_to_write(connection): + """Checks minimal time between write and read/read and write (JEDEC 229, P. 33/34)""" + cursor = connection.cursor() + query = """SELECT Phases.ID,PhaseBegin,PhaseName,TBankGroup from Phases INNER JOIN Transactions ON Phases.Transact = Transactions.ID + WHERE PhaseName IN ('RD','WR','RDA','WRA') ORDER BY PhaseBegin""" -# for currentRow in cursor: -# if(currentRow[2] in ["RD","RDA"] and lastRow[2] in ["WR","WRA"]): -# writeEndToReadBegin = currentRow[1] - (lastRow[1] + dramconfig.tWriteLength); -# if(writeEndToReadBegin < dramconfig.tWTR ): -# return TestFailed("Read with PhaseID {0} starts {1} after end of data access of write {2}. Minimum time between end of write and start of read is {3}". -# format(currentRow[0],formatTime(writeEndToReadBegin),lastRow[0], formatTime(dramconfig.tWTR ))) -# elif(currentRow[2] in ["WR","WRA"] and lastRow[2] in ["RD","RDA"]): -# if(currentRow[1] < (lastRow[1]+dramconfig.tReadLength)): -# return TestFailed("WR with PhaseID {0} starts before end of data acess of read {1}". -# format(currentRow[0], lastRow[0])) -# lastRow = currentRow + cursor.execute(query) + lastRow = cursor.fetchone() -# return TestSuceeded() + for currentRow in cursor: + + if(currentRow[2] in ["RD","RDA"] and lastRow[2] in ["WR","WRA"]): + #write to read + if (currentRow[3] == lastRow[3]): + tWTR = dramconfig.tWTR_L + else: + tWTR = dramconfig.tWTR_S + + minWriteToRead = dramconfig.tWL + dramconfig.getWriteAccessTime() + tWTR + writeToRead = currentRow[1] - lastRow[1] + + if(writeToRead < minWriteToRead ): + return TestFailed("Read {0} starts {1} after start of write {2}. Minimum time is {3}". + format(currentRow[0],formatTime(writeToRead),lastRow[0], formatTime(minWriteToRead))) + + elif(currentRow[2] in ["WR","WRA"] and lastRow[2] in ["RD","RDA"]): + #read to write + minReadToWrite = dramconfig.tRL + dramconfig.getReadAccessTime() - dramconfig.tWL + dramconfig.clk * 2 + readToWrite = currentRow[1] - lastRow[1] + if(readToWrite < minReadToWrite ): + return TestFailed("Write {0} starts {1} after start of read {2}. Minimum time is {3}". + format(currentRow[0],formatTime(readToWrite),lastRow[0], formatTime(minWriteToRead))) + + lastRow = currentRow + + return TestSuceeded() @test diff --git a/dram/src/core/TimingCalculation.cpp b/dram/src/core/TimingCalculation.cpp index d81f99a4..048353a8 100644 --- a/dram/src/core/TimingCalculation.cpp +++ b/dram/src/core/TimingCalculation.cpp @@ -53,7 +53,7 @@ sc_time getExecutionTime(Command command, tlm::tlm_generic_payload& payload) } else if (command == Command::Read) { - return config.tRL + getReadAcessTime(); + return config.tRL + getReadAccessTime(); } else if (command == Command::ReadA) { @@ -61,11 +61,11 @@ sc_time getExecutionTime(Command command, tlm::tlm_generic_payload& payload) } else if (command == Command::Write) { - return config.tWL + getWriteAcessTime(); + return config.tWL + getWriteAccessTime(); } else if (command == Command::WriteA) { - return config.tWL + getWriteAcessTime() + config.tWR + config.tRP; + return config.tWL + getWriteAccessTime() + config.tWR + config.tRP; } else if (command == Command::PrechargeAll) { @@ -120,13 +120,13 @@ bool TimeInterval::intersects(TimeInterval other) return other.timeIsInInterval(this->start) || this->timeIsInInterval(other.start); } -sc_time getReadAcessTime() +sc_time getReadAccessTime() { Configuration& config = Configuration::getInstance(); return config.BurstLength/config.DataRate*config.Timings.clk; } -sc_time getWriteAcessTime() +sc_time getWriteAccessTime() { Configuration& config = Configuration::getInstance(); diff --git a/dram/src/core/TimingCalculation.h b/dram/src/core/TimingCalculation.h index 996bc364..3080069b 100644 --- a/dram/src/core/TimingCalculation.h +++ b/dram/src/core/TimingCalculation.h @@ -31,8 +31,8 @@ struct TimeInterval sc_time getMinimalExecutionTime(Command command, tlm::tlm_generic_payload& payload); sc_time getExecutionTime(Command command, tlm::tlm_generic_payload& payload); -sc_time getReadAcessTime(); -sc_time getWriteAcessTime(); +sc_time getReadAccessTime(); +sc_time getWriteAccessTime(); sc_time getDelayToMeetConstraint(sc_time previous, sc_time start, sc_time constraint); enum Alignment {UP, DOWN}; diff --git a/dram/src/core/scheduling/ScheduledCommand.cpp b/dram/src/core/scheduling/ScheduledCommand.cpp index 99b76f89..4ef2a3b8 100644 --- a/dram/src/core/scheduling/ScheduledCommand.cpp +++ b/dram/src/core/scheduling/ScheduledCommand.cpp @@ -99,11 +99,11 @@ TimeInterval ScheduledCommand::getIntervalOnDataStrobe() const if (getCommand() == Command::Read || getCommand() == Command::ReadA) { - return TimeInterval(getStart() + timings.tRL,getStart() + timings.tRL + getReadAcessTime()); + return TimeInterval(getStart() + timings.tRL,getStart() + timings.tRL + getReadAccessTime()); } else { - return TimeInterval(getStart() + timings.tWL - timings.clk / 2, getStart() + timings.tWL + getWriteAcessTime() - timings.clk / 2); + return TimeInterval(getStart() + timings.tWL - timings.clk / 2, getStart() + timings.tWL + getWriteAccessTime() - timings.clk / 2); } } diff --git a/dram/src/core/scheduling/checker/ActivateChecker.cpp b/dram/src/core/scheduling/checker/ActivateChecker.cpp index b1729862..ef062ff2 100644 --- a/dram/src/core/scheduling/checker/ActivateChecker.cpp +++ b/dram/src/core/scheduling/checker/ActivateChecker.cpp @@ -34,7 +34,7 @@ void ActivateChecker::delayToSatisfyConstraints(ScheduledCommand& command) const else if (lastCommandOnBank.getCommand() == Command::WriteA) { command.delayToMeetConstraint(lastCommandOnBank.getStart(), - config.Timings.tWL + getWriteAcessTime() + config.Timings.tWR + config.Timings.tRP); + config.Timings.tWL + getWriteAccessTime() + config.Timings.tWR + config.Timings.tRP); } else if (lastCommandOnBank.getCommand() == Command::AutoRefresh) { diff --git a/dram/src/core/scheduling/checker/PowerDownChecker.cpp b/dram/src/core/scheduling/checker/PowerDownChecker.cpp index c1a19d75..ea851e39 100644 --- a/dram/src/core/scheduling/checker/PowerDownChecker.cpp +++ b/dram/src/core/scheduling/checker/PowerDownChecker.cpp @@ -24,17 +24,17 @@ void PowerDownChecker::delayToSatisfyConstraints(ScheduledCommand& command) cons if (lastCommandOnBank.getCommand() == Command::Read || lastCommandOnBank.getCommand() == Command::ReadA) { command.delayToMeetConstraint(lastCommandOnBank.getStart(), - config.Timings.tRL + getReadAcessTime() + config.Timings.clk); + config.Timings.tRL + getReadAccessTime() + config.Timings.clk); } else if (lastCommandOnBank.getCommand() == Command::Write) { command.delayToMeetConstraint(lastCommandOnBank.getStart(), - config.Timings.tWL + getWriteAcessTime() + config.Timings.tWR); + config.Timings.tWL + getWriteAccessTime() + config.Timings.tWR); } else if (lastCommandOnBank.getCommand() == Command::WriteA) { command.delayToMeetConstraint(lastCommandOnBank.getStart(), - config.Timings.tWL + getWriteAcessTime() + config.Timings.tWR + config.Timings.clk); + config.Timings.tWL + getWriteAccessTime() + config.Timings.tWR + config.Timings.clk); } else if (lastCommandOnBank.getCommand() == Command::AutoRefresh) { diff --git a/dram/src/core/scheduling/checker/PrechargeAllChecker.cpp b/dram/src/core/scheduling/checker/PrechargeAllChecker.cpp index 67033a71..682c96e4 100644 --- a/dram/src/core/scheduling/checker/PrechargeAllChecker.cpp +++ b/dram/src/core/scheduling/checker/PrechargeAllChecker.cpp @@ -29,11 +29,11 @@ void PrechargeAllChecker::delayToSatisfyConstraints(ScheduledCommand& command) c } else if (lastCommand.getCommand() == Command::Write) { - command.delayToMeetConstraint(lastCommand.getStart(), config.Timings.tWL + getWriteAcessTime() + config.Timings.tWR); + command.delayToMeetConstraint(lastCommand.getStart(), config.Timings.tWL + getWriteAccessTime() + config.Timings.tWR); } else if(lastCommand.getCommand() == Command::WriteA) { - command.delayToMeetConstraint(lastCommand.getStart(), config.Timings.tWL + getWriteAcessTime() + config.Timings.tWR + config.Timings.tRP); + command.delayToMeetConstraint(lastCommand.getStart(), config.Timings.tWL + getWriteAccessTime() + config.Timings.tWR + config.Timings.tRP); } else if (lastCommand.getCommand() == Command::AutoRefresh) { diff --git a/dram/src/core/scheduling/checker/PrechargeChecker.cpp b/dram/src/core/scheduling/checker/PrechargeChecker.cpp index c33df3b1..9f525200 100644 --- a/dram/src/core/scheduling/checker/PrechargeChecker.cpp +++ b/dram/src/core/scheduling/checker/PrechargeChecker.cpp @@ -24,7 +24,7 @@ void PrechargeChecker::delayToSatisfyConstraints(ScheduledCommand& command) cons } else if (lastCommand.getCommand() == Command::Write) { - command.delayToMeetConstraint(lastCommand.getStart(), config.Timings.tWL + getWriteAcessTime() + config.Timings.tWR); + command.delayToMeetConstraint(lastCommand.getStart(), config.Timings.tWL + getWriteAccessTime() + config.Timings.tWR); } else if (lastCommand.getCommand() == Command::PDNAX) { diff --git a/dram/src/core/scheduling/checker/ReadChecker.cpp b/dram/src/core/scheduling/checker/ReadChecker.cpp index a153ff31..b02a2de7 100644 --- a/dram/src/core/scheduling/checker/ReadChecker.cpp +++ b/dram/src/core/scheduling/checker/ReadChecker.cpp @@ -94,7 +94,7 @@ sc_time ReadChecker::readToRead(ScheduledCommand& firstRead, ScheduledCommand& s TimingConfiguration& config = Configuration::getInstance().Timings; sc_time tCCD = (firstRead.getBankGroup() == secondRead.getBankGroup()) ? config.tCCD_L : config.tCCD_S; - return max(tCCD, getReadAcessTime()); + return max(tCCD, getReadAccessTime()); } sc_time ReadChecker::writeToRead(ScheduledCommand& write, ScheduledCommand& read) @@ -104,7 +104,7 @@ sc_time ReadChecker::writeToRead(ScheduledCommand& write, ScheduledCommand& read TimingConfiguration& config = Configuration::getInstance().Timings; sc_time tWTR = (write.getBankGroup() == read.getBankGroup()) ? config.tWTR_L : config.tWTR_S; - return config.tWL + getWriteAcessTime() + tWTR; + return config.tWL + getWriteAccessTime() + tWTR; } } /* namespace controller */ diff --git a/dram/src/core/scheduling/checker/RefreshChecker.cpp b/dram/src/core/scheduling/checker/RefreshChecker.cpp index 6f4f2c5c..51e63392 100644 --- a/dram/src/core/scheduling/checker/RefreshChecker.cpp +++ b/dram/src/core/scheduling/checker/RefreshChecker.cpp @@ -29,7 +29,7 @@ void RefreshChecker::delayToSatisfyConstraints(ScheduledCommand& command) const else if (lastCommandOnBank.getCommand() == Command::WriteA) { command.delayToMeetConstraint(lastCommandOnBank.getStart(), - config.Timings.tWL + getWriteAcessTime() + config.Timings.tWR + config.Timings.tRP); + config.Timings.tWL + getWriteAccessTime() + config.Timings.tWR + config.Timings.tRP); } else if (lastCommandOnBank.getCommand() == Command::PDNPX || lastCommandOnBank.getCommand() == Command::PDNAX) { diff --git a/dram/src/core/scheduling/checker/WriteChecker.cpp b/dram/src/core/scheduling/checker/WriteChecker.cpp index e7c45541..7fec0fb8 100644 --- a/dram/src/core/scheduling/checker/WriteChecker.cpp +++ b/dram/src/core/scheduling/checker/WriteChecker.cpp @@ -85,7 +85,7 @@ sc_time WriteChecker::writeToWrite(ScheduledCommand& firstWrite, ScheduledComman TimingConfiguration& config = Configuration::getInstance().Timings; sc_time tCCD = (firstWrite.getBankGroup() == secondWrite.getBankGroup()) ? config.tCCD_L : config.tCCD_S; - return max(tCCD, getWriteAcessTime()); + return max(tCCD, getWriteAccessTime()); } sc_time WriteChecker::readToWrite(ScheduledCommand& read, ScheduledCommand& write) @@ -94,7 +94,7 @@ sc_time WriteChecker::readToWrite(ScheduledCommand& read, ScheduledCommand& writ sc_assert(write.getCommand() == Command::Write || write.getCommand() == Command::WriteA); TimingConfiguration& config = Configuration::getInstance().Timings; - return config.tRL + getReadAcessTime() - config.tWL + config.clk * 2; + return config.tRL + getReadAccessTime() - config.tWL + config.clk * 2; } } /* namespace controller */