Included timing checker for DDR4.

This commit is contained in:
Lukas Steiner (2)
2019-09-24 15:18:37 +02:00
parent 2690755024
commit cfbce483bd
9 changed files with 456 additions and 18 deletions

View File

@@ -135,7 +135,8 @@ SOURCES += \
src/controller/refresh/RefreshManagerDummy.cpp \
src/controller/refresh/RefreshManagerBankwise.cpp \
src/controller/checker/CheckerWideIO.cpp \
src/configuration/memspec/MemSpecLPDDR4.cpp
src/configuration/memspec/MemSpecLPDDR4.cpp \
src/controller/checker/CheckerDDR4.cpp
HEADERS += \
src/common/third_party/tinyxml2/tinyxml2.h \
@@ -207,7 +208,8 @@ HEADERS += \
src/configuration/memspec/MemSpecDDR3.h \
src/configuration/memspec/MemSpecWideIO.h \
src/configuration/memspec/MemSpecDDR4.h \
src/configuration/memspec/MemSpecLPDDR4.h
src/configuration/memspec/MemSpecLPDDR4.h \
src/controller/checker/CheckerDDR4.h
#src/common/third_party/json/include/nlohmann/json.hpp \
thermalsim = $$(THERMALSIM)

View File

@@ -42,6 +42,7 @@
#include "../common/dramExtensions.h"
#include "../common/protocol.h"
#include "checker/CheckerDDR3.h"
#include "checker/CheckerDDR4.h"
#include "checker/CheckerWideIO.h"
#include "refresh/RefreshManager.h"
#include "refresh/RefreshManagerDummy.h"
@@ -59,6 +60,8 @@ Controller::Controller(sc_module_name name) :
if (config.memSpec->MemoryType == "DDR3")
checker = new CheckerDDR3();
else if (config.memSpec->MemoryType == "DDR4")
checker = new CheckerDDR4();
else if (config.memSpec->MemoryType == "WIDEIO_SDR")
checker = new CheckerWideIO();
else
@@ -288,7 +291,7 @@ void Controller::sendToFrontend(tlm_generic_payload *payload, tlm_phase phase)
void Controller::sendToDram(Command command, tlm_generic_payload *payload)
{
DramExtension extension = DramExtension::getExtension(payload);
checker->insert(command, extension.getRank(), extension.getBank());
checker->insert(command, extension.getRank(), extension.getBankGroup(), extension.getBank());
sc_time delay = SC_ZERO_TIME;
tlm_phase phase;

View File

@@ -168,13 +168,12 @@ sc_time CheckerDDR3::delayToSatisfyConstraints(Command command, Rank rank, BankG
reportFatal("CheckerDDR3", "Unknown command!");
}
// Check if command bus is free
//if (lastScheduled.isValidCommand())
earliestTimeToStart = std::max(earliestTimeToStart, lastScheduled + memSpec->clk);
earliestTimeToStart = std::max(earliestTimeToStart, lastScheduled + memSpec->clk);
return (earliestTimeToStart - sc_time_stamp());
}
void CheckerDDR3::insert(Command command, Rank rank, Bank bank)
void CheckerDDR3::insert(Command command, Rank rank, BankGroup, Bank bank)
{
PRINTDEBUGMESSAGE("CheckerDDR3", "Changing state on bank " + bank.ID()
+ " command is " + commandToString(command));

View File

@@ -49,11 +49,16 @@ public:
CheckerDDR3();
~CheckerDDR3();
sc_time delayToSatisfyConstraints(Command, Rank, BankGroup, Bank) const;
void insert(Command, Rank, Bank);
void insert(Command, Rank, BankGroup, Bank);
private:
const MemSpecDDR3 *memSpec;
std::vector<std::vector<sc_time>> lastScheduledByCommandAndBank;
std::vector<std::vector<sc_time>> lastScheduledByCommandAndRank;
std::vector<sc_time> lastScheduledByCommand;
sc_time lastScheduled;
// Four activate window
std::vector<std::queue<sc_time>> lastActivates;

View File

@@ -0,0 +1,304 @@
/*
* Copyright (c) 2019, University of Kaiserslautern
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Author: Lukas Steiner
*/
#include "CheckerDDR4.h"
CheckerDDR4::CheckerDDR4()
{
Configuration config = Configuration::getInstance();
memSpec = dynamic_cast<MemSpecDDR4 *>(config.memSpec);
if (memSpec == nullptr)
SC_REPORT_FATAL("CheckerDDR4", "Wrong MemSpec chosen");
if (config.ControllerCoreRefDisable)
refreshChecker = new RefreshCheckerDDR4Dummy(memSpec);
else if (config.BankwiseLogic)
refreshChecker = new RefreshCheckerDDR4Bankwise(memSpec);
else
refreshChecker = new RefreshCheckerDDR4(memSpec);
lastScheduledByCommandAndBank = std::vector<std::vector<sc_time>>
(numberOfCommands(), std::vector<sc_time>(memSpec->NumberOfBanks));
lastScheduledByCommandAndBankGroup = std::vector<std::vector<sc_time>>
(numberOfCommands(), std::vector<sc_time>(memSpec->NumberOfBankGroups));
lastScheduledByCommandAndRank = std::vector<std::vector<sc_time>>
(numberOfCommands(), std::vector<sc_time>(memSpec->NumberOfRanks));
lastScheduledByCommand = std::vector<sc_time>(numberOfCommands());
lastActivates = std::vector<std::queue<sc_time>>(memSpec->NumberOfRanks);
burstClocks = (memSpec->BurstLength / 2) * memSpec->clk;
}
CheckerDDR4::~CheckerDDR4()
{
delete refreshChecker;
}
sc_time CheckerDDR4::delayToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
{
sc_time lastCommandStart;
sc_time earliestTimeToStart = sc_time_stamp();
if (command == Command::ACT)
{
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP);
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL
+ burstClocks + memSpec->tWR + memSpec->tRP);
lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankgroup.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_L);
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_S);
lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
lastCommandStart = lastScheduledByCommandAndBank[Command::REFB][bank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
if (lastActivates[rank.ID()].size() >= 4)
earliestTimeToStart = std::max(earliestTimeToStart, lastActivates[rank.ID()].front() + memSpec->tFAW);
refreshChecker->delayToSatisfyACT(bank, earliestTimeToStart);
}
else if (command == Command::RD || command == Command::RDA)
{
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD);
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankgroup.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L);
lastCommandStart = lastScheduledByCommand[Command::RD];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S);
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankgroup.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L);
lastCommandStart = lastScheduledByCommand[Command::RDA];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S);
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL
+ burstClocks + memSpec->tWTR_L);
lastCommandStart = lastScheduledByCommand[Command::WR];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL
+ burstClocks + memSpec->tWTR_S);
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL
+ burstClocks + memSpec->tWTR_L);
lastCommandStart = lastScheduledByCommand[Command::WRA];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL
+ burstClocks + memSpec->tWTR_S);
refreshChecker->delayToSatisfyRD(bank, earliestTimeToStart);
}
else if (command == Command::WR || command == Command::WRA)
{
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD);
lastCommandStart = lastScheduledByCommand[Command::RD];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRL
+ burstClocks + 2 * memSpec->clk - memSpec->tWL);
lastCommandStart = lastScheduledByCommand[Command::RDA];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRL
+ burstClocks + 2 * memSpec->clk - memSpec->tWL);
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L);
lastCommandStart = lastScheduledByCommand[Command::WR];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S);
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L);
lastCommandStart = lastScheduledByCommand[Command::WRA];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S);
refreshChecker->delayToSatisfyWR(bank, earliestTimeToStart);
}
else if (command == Command::PRE)
{
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL
+ burstClocks + memSpec->tWR);
refreshChecker->delayToSatisfyPRE(bank, earliestTimeToStart);
}
else
{
reportFatal("CheckerDDR4", "Unknown command!");
}
// Check if command bus is free
earliestTimeToStart = std::max(earliestTimeToStart, lastScheduled + memSpec->clk);
return (earliestTimeToStart - sc_time_stamp());
}
void CheckerDDR4::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank)
{
PRINTDEBUGMESSAGE("CheckerDDR4", "Changing state on bank " + bank.ID()
+ " command is " + commandToString(command));
lastScheduledByCommandAndBank[command][bank.ID()] = sc_time_stamp();
lastScheduledByCommandAndBankGroup[command][bankgroup.ID()] = sc_time_stamp();
lastScheduledByCommandAndRank[command][rank.ID()] = sc_time_stamp();
lastScheduledByCommand[command] = sc_time_stamp();
lastScheduled = sc_time_stamp();
if (command == Command::ACT)
{
if (lastActivates[rank.ID()].size() == 4)
lastActivates[rank.ID()].pop();
lastActivates[rank.ID()].push(sc_time_stamp());
}
else if (command == Command::REFA || command == Command::REFB)
refreshChecker->insert(bank);
}
// TODO: max(earliestTimeToStart, ...) needed?
void RefreshCheckerDDR4::delayToSatisfyACT(Bank, sc_time &earliestTimeToStart)
{
if (earliestTimeToStart >= (timeForNextPREA - memSpec->tRAS))
earliestTimeToStart = timeForNextREFA + memSpec->tRFC;
}
void RefreshCheckerDDR4::delayToSatisfyRD(Bank, sc_time &earliestTimeToStart)
{
if (earliestTimeToStart >= (timeForNextPREA - memSpec->tRTP))
earliestTimeToStart = timeForNextREFA + memSpec->tRFC;
}
void RefreshCheckerDDR4::delayToSatisfyWR(Bank, sc_time &earliestTimeToStart)
{
if (earliestTimeToStart >= (timeForNextPREA - memSpec->tWL - burstClocks - memSpec->tWR))
earliestTimeToStart = timeForNextREFA + memSpec->tRFC;
}
void RefreshCheckerDDR4::delayToSatisfyPRE(Bank, sc_time &earliestTimeToStart)
{
if (earliestTimeToStart >= timeForNextPREA)
earliestTimeToStart = timeForNextREFA + memSpec->tRFC;
}
void RefreshCheckerDDR4::insert(Bank)
{
timeForNextREFA += memSpec->tREFI;
timeForNextPREA += memSpec->tREFI;
}
RefreshCheckerDDR4Bankwise::RefreshCheckerDDR4Bankwise(const MemSpecDDR4 *memSpec)
: RefreshCheckerDDR4Dummy(memSpec)
{
sc_time currentREFB = memSpec->tREFI - memSpec->clk * (memSpec->NumberOfBanks - 1);
sc_time currentPRE = currentREFB - std::max(memSpec->clk * memSpec->NumberOfBanks, memSpec->tRP);
for (unsigned bankID = 0; bankID < memSpec->NumberOfBanks; bankID++)
{
timesForNextREFB.push_back(currentREFB);
timesForNextPRE.push_back(currentPRE);
currentREFB += memSpec->clk;
currentPRE += memSpec->clk;
}
}
void RefreshCheckerDDR4Bankwise::delayToSatisfyACT(Bank bank, sc_time &earliestTimeToStart)
{
if (earliestTimeToStart >= (timesForNextPRE[bank.ID()] - memSpec->tRAS))
earliestTimeToStart = timesForNextREFB[bank.ID()] + memSpec->tRFC;
}
void RefreshCheckerDDR4Bankwise::delayToSatisfyRD(Bank bank, sc_time &earliestTimeToStart)
{
if (earliestTimeToStart >= (timesForNextPRE[bank.ID()] - memSpec->tRTP))
earliestTimeToStart = timesForNextREFB[bank.ID()] + memSpec->tRFC;
}
void RefreshCheckerDDR4Bankwise::delayToSatisfyWR(Bank bank, sc_time &earliestTimeToStart)
{
if (earliestTimeToStart >= (timesForNextPRE[bank.ID()] - memSpec->tWL - burstClocks - memSpec->tWR))
earliestTimeToStart = timesForNextREFB[bank.ID()] + memSpec->tRFC;
}
void RefreshCheckerDDR4Bankwise::insert(Bank bank)
{
timesForNextREFB[bank.ID()] += memSpec->tREFI;
timesForNextPRE[bank.ID()] += memSpec->tREFI;
}

View File

@@ -0,0 +1,127 @@
/*
* Copyright (c) 2019, University of Kaiserslautern
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Author: Lukas Steiner
*/
#ifndef CHECKERDDR4_H
#define CHECKERDDR4_H
#include "CheckerIF.h"
#include <queue>
#include <vector>
#include "../../configuration/memspec/MemSpecDDR4.h"
#include "../../configuration/Configuration.h"
class RefreshCheckerDDR4Dummy;
class CheckerDDR4 final : public CheckerIF
{
public:
CheckerDDR4();
~CheckerDDR4();
sc_time delayToSatisfyConstraints(Command, Rank, BankGroup, Bank) const;
void insert(Command, Rank, BankGroup, Bank);
private:
const MemSpecDDR4 *memSpec;
std::vector<std::vector<sc_time>> lastScheduledByCommandAndBank;
std::vector<std::vector<sc_time>> lastScheduledByCommandAndBankGroup;
std::vector<std::vector<sc_time>> lastScheduledByCommandAndRank;
std::vector<sc_time> lastScheduledByCommand;
sc_time lastScheduled;
// Four activate window
std::vector<std::queue<sc_time>> lastActivates;
RefreshCheckerDDR4Dummy *refreshChecker;
sc_time burstClocks;
// PowerDown TODO: Implement this method?
//sc_time getTimeConstraintToEnterPowerDown(Command lastCmd, Command pdnCmd) const;
};
class RefreshCheckerDDR4Dummy
{
protected:
friend class CheckerDDR4;
RefreshCheckerDDR4Dummy(const MemSpecDDR4 *memSpec) : memSpec(memSpec)
{
burstClocks = (memSpec->BurstLength / 2) * memSpec->clk;
}
virtual ~RefreshCheckerDDR4Dummy() {}
virtual void delayToSatisfyACT(Bank, sc_time &) {}
virtual void delayToSatisfyRD(Bank, sc_time &) {}
virtual void delayToSatisfyWR(Bank, sc_time &) {}
virtual void delayToSatisfyPRE(Bank, sc_time &) {}
virtual void insert(Bank) {}
const MemSpecDDR4 *memSpec;
sc_time burstClocks;
};
class RefreshCheckerDDR4 final : public RefreshCheckerDDR4Dummy
{
private:
friend class CheckerDDR4;
RefreshCheckerDDR4(const MemSpecDDR4 *memSpec)
: RefreshCheckerDDR4Dummy(memSpec) {}
void delayToSatisfyACT(Bank, sc_time &);
void delayToSatisfyRD(Bank, sc_time &);
void delayToSatisfyWR(Bank, sc_time &);
void delayToSatisfyPRE(Bank, sc_time &);
void insert(Bank);
sc_time timeForNextREFA = memSpec->tREFI;
sc_time timeForNextPREA = timeForNextREFA - memSpec->tRP;
};
class RefreshCheckerDDR4Bankwise final : public RefreshCheckerDDR4Dummy
{
private:
friend class CheckerDDR4;
RefreshCheckerDDR4Bankwise(const MemSpecDDR4 *);
void delayToSatisfyACT(Bank, sc_time &);
void delayToSatisfyRD(Bank, sc_time &);
void delayToSatisfyWR(Bank, sc_time &);
void insert(Bank);
std::vector<sc_time> timesForNextREFB;
std::vector<sc_time> timesForNextPRE;
};
#endif // CHECKERDDR4_H

View File

@@ -47,13 +47,7 @@ public:
virtual ~CheckerIF() {}
virtual sc_time delayToSatisfyConstraints(Command, Rank, BankGroup, Bank) const = 0;
virtual void insert(Command, Rank, Bank) = 0;
protected:
std::vector<std::vector<sc_time>> lastScheduledByCommandAndBank;
std::vector<std::vector<sc_time>> lastScheduledByCommandAndRank;
std::vector<sc_time> lastScheduledByCommand;
sc_time lastScheduled;
virtual void insert(Command, Rank, BankGroup, Bank) = 0;
// PowerDown TODO: Implement this method?
//sc_time getTimeConstraintToEnterPowerDown(Command lastCmd, Command pdnCmd) const;

View File

@@ -152,13 +152,12 @@ sc_time CheckerWideIO::delayToSatisfyConstraints(Command command, Rank rank, Ban
reportFatal("CheckerWideIO", "Unknown command!");
}
// Check if command bus is free
//if (lastScheduled.isValidCommand())
earliestTimeToStart = std::max(earliestTimeToStart, lastScheduled + memSpec->clk);
earliestTimeToStart = std::max(earliestTimeToStart, lastScheduled + memSpec->clk);
return (earliestTimeToStart - sc_time_stamp());
}
void CheckerWideIO::insert(Command command, Rank rank, Bank bank)
void CheckerWideIO::insert(Command command, Rank rank, BankGroup, Bank bank)
{
PRINTDEBUGMESSAGE("CheckerWideIO", "Changing state on bank " + bank.ID()
+ " command is " + commandToString(command));

View File

@@ -49,11 +49,16 @@ public:
CheckerWideIO();
~CheckerWideIO();
sc_time delayToSatisfyConstraints(Command, Rank, BankGroup, Bank) const;
void insert(Command, Rank, Bank);
void insert(Command, Rank, BankGroup, Bank);
private:
const MemSpecWideIO *memSpec;
std::vector<std::vector<sc_time>> lastScheduledByCommandAndBank;
std::vector<std::vector<sc_time>> lastScheduledByCommandAndRank;
std::vector<sc_time> lastScheduledByCommand;
sc_time lastScheduled;
// Four activate window
std::vector<std::queue<sc_time>> lastActivates;