Merge remote-tracking branch 'origin/develop' into work/tracegenerator

This commit is contained in:
2021-05-19 11:53:11 +02:00
98 changed files with 1779 additions and 357 deletions

2
.gitignore vendored
View File

@@ -24,3 +24,5 @@ DRAMSys/analyzer/scripts/__pycache__/
DRAMSys/gem5/boot_linux/linux-aarch32-ael.img
DRAMSys/docs/doxygen
/.vscode
/cmake-build*
/.idea

View File

@@ -97,6 +97,7 @@ add_library(DRAMSysLibrary
src/configuration/memspec/MemSpecGDDR5X.cpp
src/configuration/memspec/MemSpecGDDR6.cpp
src/configuration/memspec/MemSpecHBM2.cpp
src/configuration/memspec/MemSpecSTTMRAM.cpp
src/controller/BankMachine.cpp
src/controller/Command.cpp
@@ -114,6 +115,7 @@ add_library(DRAMSysLibrary
src/controller/checker/CheckerGDDR5X.cpp
src/controller/checker/CheckerGDDR6.cpp
src/controller/checker/CheckerHBM2.cpp
src/controller/checker/CheckerSTTMRAM.cpp
src/controller/cmdmux/CmdMuxIF.h
src/controller/cmdmux/CmdMuxOldest.cpp
@@ -168,6 +170,7 @@ add_library(DRAMSysLibrary
src/simulation/dram/DramGDDR5X.cpp
src/simulation/dram/DramGDDR6.cpp
src/simulation/dram/DramHBM2.cpp
src/simulation/dram/DramSTTMRAM.cpp
${RECORDING_SOURCES}

View File

@@ -0,0 +1,43 @@
{
"CONGEN": {
"BANK_BIT": [
13,
14,
15
],
"BYTE_BIT": [
0,
1,
2
],
"COLUMN_BIT": [
3,
4,
5,
6,
7,
8,
9,
10,
11,
12
],
"ROW_BIT": [
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30
]
}
}

View File

@@ -0,0 +1,16 @@
{
"mcconfig": {
"PagePolicy": "Open",
"Scheduler": "FrFcfs",
"SchedulerBuffer": "Bankwise",
"RequestBufferSize": 8,
"CmdMux": "Oldest",
"RespQueue": "Fifo",
"RefreshPolicy": "NoRefresh",
"RefreshMaxPostponed": 0,
"RefreshMaxPulledin": 0,
"PowerDownPolicy": "NoPowerDown",
"Arbiter": "Simple",
"MaxActiveTransactions": 128
}
}

View File

@@ -34,7 +34,8 @@
"WPST": 0,
"WR": 48,
"CCD_L_slr": 8,
"CCD_L_WR_slr": 16,
"CCD_L_WR_slr": 32,
"CCD_L_WR2_slr": 16,
"CCD_S_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_dlr": 0,
@@ -70,4 +71,4 @@
"clkMhz": 1600
}
}
}
}

View File

@@ -34,7 +34,8 @@
"WPST": 0,
"WR": 54,
"CCD_L_slr": 9,
"CCD_L_WR_slr": 18,
"CCD_L_WR_slr": 36,
"CCD_L_WR2_slr": 18,
"CCD_S_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_dlr": 0,
@@ -70,4 +71,4 @@
"clkMhz": 1800
}
}
}
}

View File

@@ -34,7 +34,8 @@
"WPST": 0,
"WR": 60,
"CCD_L_slr": 10,
"CCD_L_WR_slr": 20,
"CCD_L_WR_slr": 40,
"CCD_L_WR2_slr": 20,
"CCD_S_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_dlr": 0,
@@ -70,4 +71,4 @@
"clkMhz": 2000
}
}
}
}

View File

@@ -34,7 +34,8 @@
"WPST": 0,
"WR": 66,
"CCD_L_slr": 11,
"CCD_L_WR_slr": 22,
"CCD_L_WR_slr": 44,
"CCD_L_WR2_slr": 22,
"CCD_S_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_dlr": 0,
@@ -70,4 +71,4 @@
"clkMhz": 2200
}
}
}
}

View File

@@ -34,7 +34,8 @@
"WPST": 0,
"WR": 72,
"CCD_L_slr": 12,
"CCD_L_WR_slr": 24,
"CCD_L_WR_slr": 48,
"CCD_L_WR2_slr": 24,
"CCD_S_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_dlr": 0,
@@ -70,4 +71,4 @@
"clkMhz": 2400
}
}
}
}

View File

@@ -34,7 +34,8 @@
"WPST": 0,
"WR": 78,
"CCD_L_slr": 13,
"CCD_L_WR_slr": 26,
"CCD_L_WR_slr": 52,
"CCD_L_WR2_slr": 26,
"CCD_S_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_dlr": 0,
@@ -70,4 +71,4 @@
"clkMhz": 2600
}
}
}
}

View File

@@ -34,7 +34,8 @@
"WPST": 0,
"WR": 84,
"CCD_L_slr": 14,
"CCD_L_WR_slr": 28,
"CCD_L_WR_slr": 56,
"CCD_L_WR2_slr": 28,
"CCD_S_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_dlr": 0,
@@ -70,4 +71,4 @@
"clkMhz": 2800
}
}
}
}

View File

@@ -34,7 +34,8 @@
"WPST": 0,
"WR": 90,
"CCD_L_slr": 15,
"CCD_L_WR_slr": 30,
"CCD_L_WR_slr": 60,
"CCD_L_WR2_slr": 30,
"CCD_S_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_dlr": 0,
@@ -70,4 +71,4 @@
"clkMhz": 3000
}
}
}
}

View File

@@ -34,7 +34,8 @@
"WPST": 0,
"WR": 96,
"CCD_L_slr": 16,
"CCD_L_WR_slr": 32,
"CCD_L_WR_slr": 64,
"CCD_L_WR2_slr": 32,
"CCD_S_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_dlr": 0,
@@ -70,4 +71,4 @@
"clkMhz": 3200
}
}
}
}

View File

@@ -35,6 +35,7 @@
"WR": 48,
"CCD_L_slr": 8,
"CCD_L_WR_slr": 32,
"CCD_L_WR2_slr": 16,
"CCD_S_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_dlr": 0,
@@ -70,4 +71,4 @@
"clkMhz": 1600
}
}
}
}

View File

@@ -35,6 +35,7 @@
"WR": 54,
"CCD_L_slr": 9,
"CCD_L_WR_slr": 36,
"CCD_L_WR2_slr": 18,
"CCD_S_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_dlr": 0,
@@ -70,4 +71,4 @@
"clkMhz": 1800
}
}
}
}

View File

@@ -35,6 +35,7 @@
"WR": 60,
"CCD_L_slr": 10,
"CCD_L_WR_slr": 40,
"CCD_L_WR2_slr": 20,
"CCD_S_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_dlr": 0,
@@ -70,4 +71,4 @@
"clkMhz": 2000
}
}
}
}

View File

@@ -35,6 +35,7 @@
"WR": 66,
"CCD_L_slr": 11,
"CCD_L_WR_slr": 44,
"CCD_L_WR2_slr": 22,
"CCD_S_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_dlr": 0,
@@ -70,4 +71,4 @@
"clkMhz": 2200
}
}
}
}

View File

@@ -35,6 +35,7 @@
"WR": 72,
"CCD_L_slr": 12,
"CCD_L_WR_slr": 48,
"CCD_L_WR2_slr": 24,
"CCD_S_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_dlr": 0,
@@ -70,4 +71,4 @@
"clkMhz": 2400
}
}
}
}

View File

@@ -35,6 +35,7 @@
"WR": 78,
"CCD_L_slr": 13,
"CCD_L_WR_slr": 52,
"CCD_L_WR2_slr": 26,
"CCD_S_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_dlr": 0,
@@ -70,4 +71,4 @@
"clkMhz": 2600
}
}
}
}

View File

@@ -35,6 +35,7 @@
"WR": 84,
"CCD_L_slr": 14,
"CCD_L_WR_slr": 56,
"CCD_L_WR2_slr": 28,
"CCD_S_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_dlr": 0,
@@ -70,4 +71,4 @@
"clkMhz": 2800
}
}
}
}

View File

@@ -35,6 +35,7 @@
"WR": 90,
"CCD_L_slr": 15,
"CCD_L_WR_slr": 60,
"CCD_L_WR2_slr": 30,
"CCD_S_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_dlr": 0,
@@ -70,4 +71,4 @@
"clkMhz": 3000
}
}
}
}

View File

@@ -35,6 +35,7 @@
"WR": 96,
"CCD_L_slr": 16,
"CCD_L_WR_slr": 64,
"CCD_L_WR2_slr": 32,
"CCD_S_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_dlr": 0,
@@ -70,4 +71,4 @@
"clkMhz": 3200
}
}
}
}

View File

@@ -35,6 +35,7 @@
"WR": 48,
"CCD_L_slr": 8,
"CCD_L_WR_slr": 32,
"CCD_L_WR2_slr": 16,
"CCD_S_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_dlr": 8,

View File

@@ -0,0 +1,16 @@
*The following copyright notice only applies to the files "STT-MRAM-1.2x.json", "STT-MRAM-1.5x.json" and "STT-MRAM-2.0x.json".*
(C) Copyright 2006-2018 Barcelona Supercomputing Center (BSC)
The copyright holder is BSC-CNS, and the authorship correspond to Kazi Asifuzzaman, Rommel Sanchez Verdejo, and Petar Radojkovic. The complete explanation of the derivation of the data can be found in the following study: Kazi Asifuzzaman, Rommel Sanchez Verdejo, and Petar Radojkovic. 2017. Enabling a reliable STT-MRAM main memory simulation. In Proceedings of the International Symposium on Memory Systems (MEMSYS '17). Washington DC, USA, 283-292. DOI: https://doi.org/10.1145/3132402.3132416
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.
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.”
The configuration files list detailed timing parameters for STT-MRAM main memory, specifying a 1.2x/1.5x/2.0x deviation from respective DRAM timing parameters.

View File

@@ -0,0 +1,44 @@
{
"memspec": {
"memarchitecturespec": {
"burstLength": 8,
"dataRate": 2,
"nbrOfBanks": 8,
"nbrOfColumns": 1024,
"nbrOfRanks": 1,
"nbrOfRows": 32768,
"width": 8,
"nbrOfDevicesOnDIMM": 8,
"nbrOfChannels": 1
},
"memoryId": "STT-MRAM-1.2x",
"memoryType": "STT-MRAM",
"memtimingspec": {
"AL": 0,
"CCD": 4,
"CKE": 4,
"CKESR": 7,
"CL": 11,
"DQSCK": 0,
"FAW": 29,
"RAS": 20,
"RC": 34,
"RCD": 14,
"RL": 11,
"RP": 14,
"RRD": 6,
"RTP": 6,
"WL": 11,
"WR": 12,
"WTR": 2,
"XP": 5,
"XPDLL": 325,
"XS": 324,
"XSDLL": 512,
"ACTPDEN": 2,
"PRPDEN": 2,
"RTRS": 1,
"clkMhz": 800
}
}
}

View File

@@ -0,0 +1,44 @@
{
"memspec": {
"memarchitecturespec": {
"burstLength": 8,
"dataRate": 2,
"nbrOfBanks": 8,
"nbrOfColumns": 1024,
"nbrOfRanks": 1,
"nbrOfRows": 32768,
"width": 8,
"nbrOfDevicesOnDIMM": 8,
"nbrOfChannels": 1
},
"memoryId": "STT-MRAM-1.5x",
"memoryType": "STT-MRAM",
"memtimingspec": {
"AL": 0,
"CCD": 4,
"CKE": 4,
"CKESR": 7,
"CL": 11,
"DQSCK": 0,
"FAW": 36,
"RAS": 23,
"RC": 40,
"RCD": 14,
"RL": 11,
"RP": 17,
"RRD": 8,
"RTP": 6,
"WL": 11,
"WR": 12,
"WTR": 6,
"XP": 5,
"XPDLL": 325,
"XS": 324,
"XSDLL": 512,
"ACTPDEN": 2,
"PRPDEN": 2,
"RTRS": 1,
"clkMhz": 800
}
}
}

View File

@@ -0,0 +1,44 @@
{
"memspec": {
"memarchitecturespec": {
"burstLength": 8,
"dataRate": 2,
"nbrOfBanks": 8,
"nbrOfColumns": 1024,
"nbrOfRanks": 1,
"nbrOfRows": 32768,
"width": 8,
"nbrOfDevicesOnDIMM": 8,
"nbrOfChannels": 1
},
"memoryId": "STT-MRAM-2.0x",
"memoryType": "STT-MRAM",
"memtimingspec": {
"AL": 0,
"CCD": 4,
"CKE": 4,
"CKESR": 7,
"CL": 11,
"DQSCK": 0,
"FAW": 36,
"RAS": 28,
"RC": 50,
"RCD": 14,
"RL": 11,
"RP": 22,
"RRD": 10,
"RTP": 6,
"WL": 11,
"WR": 48,
"WTR": 6,
"XP": 5,
"XPDLL": 325,
"XS": 324,
"XSDLL": 512,
"ACTPDEN": 2,
"PRPDEN": 2,
"RTRS": 1,
"clkMhz": 800
}
}
}

View File

@@ -0,0 +1,19 @@
{
"simconfig": {
"AddressOffset": 0,
"CheckTLM2Protocol": false,
"DatabaseRecording": true,
"Debug": false,
"ECCControllerMode": "Disabled",
"EnableWindowing": false,
"ErrorCSVFile": "",
"ErrorChipSeed": 42,
"PowerAnalysis": false,
"SimulationName": "stt-mram",
"SimulationProgressBar": true,
"StoreMode": "NoStorage",
"ThermalSimulation": false,
"UseMalloc": false,
"WindowSize": 1000
}
}

View File

@@ -0,0 +1,16 @@
{
"simulation": {
"addressmapping": "am_stt-mram_8x2Gbx8_dimm_p1KB_rbc.json",
"mcconfig": "fr_fcfs_noref.json",
"memspec": "STT-MRAM-1.2x.json",
"simconfig": "stt-mram.json",
"simulationid": "stt-mram-example",
"thermalconfig": "config.json",
"tracesetup": [
{
"clkMhz": 800,
"name": "ddr3_example.stl"
}
]
}
}

View File

@@ -162,7 +162,7 @@ void TlmRecorder::introduceTransactionSystem(tlm_generic_payload &trans)
currentTransactionsInSystem[&trans].cmd = trans.get_command() ==
tlm::TLM_READ_COMMAND ? "R" : "W";
currentTransactionsInSystem[&trans].address = trans.get_address();
currentTransactionsInSystem[&trans].burstlength = trans.get_streaming_width();
currentTransactionsInSystem[&trans].burstLength = DramExtension::getBurstLength(trans);
currentTransactionsInSystem[&trans].dramExtension = DramExtension::getExtension(trans);
currentTransactionsInSystem[&trans].timeOfGeneration = GenerationExtension::getTimeOfGeneration(trans);
@@ -406,7 +406,7 @@ void TlmRecorder::insertTransactionInDB(Transaction &recordingData)
sqlite3_bind_int(insertTransactionStatement, 1, static_cast<int>(recordingData.id));
sqlite3_bind_int(insertTransactionStatement, 2, static_cast<int>(recordingData.id));
sqlite3_bind_int64(insertTransactionStatement, 3, static_cast<int64_t>(recordingData.address));
sqlite3_bind_int(insertTransactionStatement, 4, static_cast<int>(recordingData.burstlength));
sqlite3_bind_int(insertTransactionStatement, 4, static_cast<int>(recordingData.burstLength));
sqlite3_bind_int(insertTransactionStatement, 5,
static_cast<int>(recordingData.dramExtension.getThread().ID()));
sqlite3_bind_int(insertTransactionStatement, 6,

View File

@@ -92,7 +92,7 @@ private:
uint64_t id;
uint64_t address;
unsigned int burstlength;
unsigned int burstLength;
std::string cmd;
DramExtension dramExtension;
sc_time timeOfGeneration;

View File

@@ -44,21 +44,21 @@ using namespace tlm;
DramExtension::DramExtension() :
thread(0), channel(0), rank(0), bankgroup(0), bank(0),
row(0), column(0), burstlength(0),
row(0), column(0), burstLength(0),
threadPayloadID(0), channelPayloadID(0) {}
DramExtension::DramExtension(Thread thread, Channel channel, Rank rank,
BankGroup bankgroup, Bank bank, Row row,
Column column, unsigned int burstlength,
Column column, unsigned int burstLength,
uint64_t threadPayloadID, uint64_t channelPayloadID) :
thread(thread), channel(channel), rank(rank), bankgroup(bankgroup), bank(bank),
row(row), column(column), burstlength(burstlength),
row(row), column(column), burstLength(burstLength),
threadPayloadID(threadPayloadID), channelPayloadID(channelPayloadID) {}
void DramExtension::setExtension(tlm::tlm_generic_payload *payload,
Thread thread, Channel channel, Rank rank,
BankGroup bankgroup, Bank bank, Row row,
Column column, unsigned int burstlength,
Column column, unsigned int burstLength,
uint64_t threadPayloadID, uint64_t channelPayloadID)
{
DramExtension *extension = nullptr;
@@ -73,14 +73,14 @@ void DramExtension::setExtension(tlm::tlm_generic_payload *payload,
extension->bank = bank;
extension->row = row;
extension->column = column;
extension->burstlength = burstlength;
extension->burstLength = burstLength;
extension->threadPayloadID = threadPayloadID;
extension->channelPayloadID = channelPayloadID;
}
else
{
extension = new DramExtension(thread, channel, rank, bankgroup,
bank, row, column, burstlength,
bank, row, column, burstLength,
threadPayloadID, channelPayloadID);
payload->set_auto_extension(extension);
}
@@ -89,11 +89,11 @@ void DramExtension::setExtension(tlm::tlm_generic_payload *payload,
void DramExtension::setExtension(tlm::tlm_generic_payload &payload,
Thread thread, Channel channel, Rank rank,
BankGroup bankgroup, Bank bank, Row row,
Column column, unsigned int burstlength,
Column column, unsigned int burstLength,
uint64_t threadPayloadID, uint64_t channelPayloadID)
{
setExtension(&payload, thread, channel, rank, bankgroup,
bank, row, column, burstlength,
bank, row, column, burstLength,
threadPayloadID, channelPayloadID);
}
@@ -194,6 +194,16 @@ Column DramExtension::getColumn(const tlm_generic_payload &payload)
return DramExtension::getColumn(&payload);
}
unsigned DramExtension::getBurstLength(const tlm_generic_payload *payload)
{
return DramExtension::getExtension(payload).getBurstLength();
}
unsigned DramExtension::getBurstLength(const tlm_generic_payload &payload)
{
return DramExtension::getBurstLength(&payload);
}
uint64_t DramExtension::getThreadPayloadID(const tlm_generic_payload *payload)
{
return DramExtension::getExtension(payload).getThreadPayloadID();
@@ -217,7 +227,7 @@ uint64_t DramExtension::getChannelPayloadID(const tlm_generic_payload &payload)
tlm_extension_base *DramExtension::clone() const
{
return new DramExtension(thread, channel, rank, bankgroup, bank, row, column,
burstlength, threadPayloadID, channelPayloadID);
burstLength, threadPayloadID, channelPayloadID);
}
void DramExtension::copy_from(const tlm_extension_base &ext)
@@ -230,7 +240,7 @@ void DramExtension::copy_from(const tlm_extension_base &ext)
bank = cpyFrom.bank;
row = cpyFrom.row;
column = cpyFrom.column;
burstlength = cpyFrom.burstlength;
burstLength = cpyFrom.burstLength;
}
Thread DramExtension::getThread() const
@@ -268,9 +278,9 @@ Column DramExtension::getColumn() const
return column;
}
unsigned int DramExtension::getBurstlength() const
unsigned int DramExtension::getBurstLength() const
{
return burstlength;
return burstLength;
}
uint64_t DramExtension::getThreadPayloadID() const

View File

@@ -165,7 +165,7 @@ public:
DramExtension();
DramExtension(Thread thread, Channel channel, Rank rank,
BankGroup bankgroup, Bank bank, Row row,
Column column, unsigned int burstlength,
Column column, unsigned int burstLength,
uint64_t threadPayloadID, uint64_t channelPayloadID);
virtual tlm::tlm_extension_base *clone() const;
@@ -174,12 +174,12 @@ public:
static void setExtension(tlm::tlm_generic_payload *payload,
Thread thread, Channel channel, Rank rank,
BankGroup bankgroup, Bank bank, Row row,
Column column, unsigned int burstlength,
Column column, unsigned int burstLength,
uint64_t threadPayloadID, uint64_t channelPayloadID);
static void setExtension(tlm::tlm_generic_payload &payload,
Thread thread, Channel channel, Rank rank,
BankGroup bankgroup, Bank bank, Row row,
Column column, unsigned int burstlength,
Column column, unsigned int burstLength,
uint64_t threadPayloadID, uint64_t channelPayloadID);
static DramExtension &getExtension(const tlm::tlm_generic_payload *payload);
@@ -205,6 +205,8 @@ public:
static Row getRow(const tlm::tlm_generic_payload &payload);
static Column getColumn(const tlm::tlm_generic_payload *payload);
static Column getColumn(const tlm::tlm_generic_payload &payload);
static unsigned getBurstLength(const tlm::tlm_generic_payload *payload);
static unsigned getBurstLength(const tlm::tlm_generic_payload &payload);
static uint64_t getThreadPayloadID(const tlm::tlm_generic_payload *payload);
static uint64_t getThreadPayloadID(const tlm::tlm_generic_payload &payload);
static uint64_t getChannelPayloadID(const tlm::tlm_generic_payload *payload);
@@ -218,7 +220,7 @@ public:
Row getRow() const;
Column getColumn() const;
unsigned int getBurstlength() const;
unsigned int getBurstLength() const;
uint64_t getThreadPayloadID() const;
uint64_t getChannelPayloadID() const;
void incrementRow();
@@ -231,7 +233,7 @@ private:
Bank bank;
Row row;
Column column;
unsigned int burstlength;
unsigned int burstLength;
uint64_t threadPayloadID;
uint64_t channelPayloadID;
};

View File

@@ -51,6 +51,7 @@
#include "memspec/MemSpecGDDR5.h"
#include "memspec/MemSpecGDDR5X.h"
#include "memspec/MemSpecGDDR6.h"
#include "memspec/MemSpecSTTMRAM.h"
using json = nlohmann::json;
@@ -357,6 +358,8 @@ void Configuration::loadMemSpec(Configuration &config, std::string memspecUri)
memSpec = new MemSpecGDDR5X(jMemSpec);
else if (memoryType == "GDDR6")
memSpec = new MemSpecGDDR6(jMemSpec);
else if (memoryType == "STT-MRAM")
memSpec = new MemSpecSTTMRAM(jMemSpec);
else
SC_REPORT_FATAL("Configuration", "Unsupported DRAM type");
}

View File

@@ -69,7 +69,8 @@ public:
const sc_time tCK;
const std::string memoryId;
const enum class MemoryType {DDR3, DDR4, DDR5, LPDDR4, WideIO, WideIO2, GDDR5, GDDR5X, GDDR6, HBM2} memoryType;
const enum class MemoryType {DDR3, DDR4, DDR5, LPDDR4, WideIO,
WideIO2, GDDR5, GDDR5X, GDDR6, HBM2, STTMRAM} memoryType;
virtual ~MemSpec() {}
@@ -79,8 +80,8 @@ public:
virtual bool hasRasAndCasBus() const;
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const = 0;
virtual TimeInterval getIntervalOnDataStrobe(Command) const = 0;
virtual sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const = 0;
virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const = 0;
sc_time getCommandLength(Command) const;
virtual uint64_t getSimMemSizeInBytes() const = 0;

View File

@@ -120,7 +120,7 @@ sc_time MemSpecDDR3::getExecutionTime(Command command, const tlm_generic_payload
}
}
TimeInterval MemSpecDDR3::getIntervalOnDataStrobe(Command command) const
TimeInterval MemSpecDDR3::getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &) const
{
if (command == Command::RD || command == Command::RDA)
return TimeInterval(tRL, tRL + burstDuration);

View File

@@ -89,8 +89,8 @@ public:
virtual sc_time getRefreshIntervalAB() const override;
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
virtual sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override;
virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override;
virtual uint64_t getSimMemSizeInBytes() const override;
};

View File

@@ -139,7 +139,7 @@ sc_time MemSpecDDR4::getExecutionTime(Command command, const tlm_generic_payload
}
}
TimeInterval MemSpecDDR4::getIntervalOnDataStrobe(Command command) const
TimeInterval MemSpecDDR4::getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &) const
{
if (command == Command::RD || command == Command::RDA)
return TimeInterval(tRL, tRL + burstDuration);

View File

@@ -97,8 +97,8 @@ public:
virtual sc_time getRefreshIntervalAB() const override;
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
virtual sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override;
virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override;
virtual uint64_t getSimMemSizeInBytes() const override;
};

View File

@@ -59,56 +59,59 @@ MemSpecDDR5::MemSpecDDR5(json &memspec)
numberOfLogicalRanks(logicalRanksPerPhysicalRank * numberOfPhysicalRanks),
cmdMode(parseUint(memspec["memarchitecturespec"]["cmdMode"], "cmdMode")),
refMode(parseUint(memspec["memarchitecturespec"]["refMode"], "refMode")),
tRCD (tCK * parseUint(memspec["memtimingspec"]["RCD"], "RCD")),
tPPD (tCK * parseUint(memspec["memtimingspec"]["PPD"], "PPD")),
tRP (tCK * parseUint(memspec["memtimingspec"]["RP"], "RP")),
tRAS (tCK * parseUint(memspec["memtimingspec"]["RAS"], "RAS")),
tRC (tRAS + tRP),
tRL (tCK * parseUint(memspec["memtimingspec"]["RL"], "RL")),
tRTP (tCK * parseUint(memspec["memtimingspec"]["RTP"], "RTP")),
tRPRE (tCK * parseUint(memspec["memtimingspec"]["RPRE"], "RPRE")),
tRPST (tCK * parseUint(memspec["memtimingspec"]["RPST"], "RPST")),
tRDDQS (tCK * parseUint(memspec["memtimingspec"]["RDDQS"], "RDDQS")),
tWL (tCK * parseUint(memspec["memtimingspec"]["WL"], "WL")),
tWPRE (tCK * parseUint(memspec["memtimingspec"]["WPRE"], "WPRE")),
tWPST (tCK * parseUint(memspec["memtimingspec"]["WPST"], "WPST")),
tWR (tCK * parseUint(memspec["memtimingspec"]["WR"], "WR")),
tCCD_L_slr (tCK * parseUint(memspec["memtimingspec"]["CCD_L_slr"], "CCD_L_slr")),
tCCD_L_WR_slr (tCK * parseUint(memspec["memtimingspec"]["CCD_L_WR_slr"], "CCD_L_WR_slr")),
tCCD_S_slr (tCK * parseUint(memspec["memtimingspec"]["CCD_S_slr"], "CCD_S_slr")),
tCCD_S_WR_slr (tCK * parseUint(memspec["memtimingspec"]["CCD_S_WR_slr"], "CCD_S_WR_slr")),
tCCD_dlr (tCK * parseUint(memspec["memtimingspec"]["CCD_dlr"], "CCD_dlr")),
tCCD_WR_dlr (tCK * parseUint(memspec["memtimingspec"]["CCD_WR_dlr"], "CCD_WR_dlr")),
tCCD_WR_dpr (tCK * parseUint(memspec["memtimingspec"]["CCD_WR_dpr"], "CCD_WR_dpr")),
tRRD_L_slr (tCK * parseUint(memspec["memtimingspec"]["RRD_L_slr"], "RRD_L_slr")),
tRRD_S_slr (tCK * parseUint(memspec["memtimingspec"]["RRD_S_slr"], "RRD_S_slr")),
tRRD_dlr (tCK * parseUint(memspec["memtimingspec"]["RRD_dlr"], "RRD_dlr")),
tFAW_slr (tCK * parseUint(memspec["memtimingspec"]["FAW_slr"], "FAW_slr")),
tFAW_dlr (tCK * parseUint(memspec["memtimingspec"]["FAW_dlr"], "FAW_dlr")),
tWTR_L (tCK * parseUint(memspec["memtimingspec"]["WTR_L"], "WTR_L")),
tWTR_S (tCK * parseUint(memspec["memtimingspec"]["WTR_S"], "WTR_S")),
tRFC_slr ((refMode == 1) ? tCK * parseUint(memspec["memtimingspec"]["RFC1_slr"], "RFC1_slr")
: tCK * parseUint(memspec["memtimingspec"]["RFC2_slr"], "RFC2_slr")),
tRFC_dlr ((refMode == 1) ? tCK * parseUint(memspec["memtimingspec"]["RFC1_dlr"], "RFC1_dlr")
: tCK * parseUint(memspec["memtimingspec"]["RFC2_dlr"], "RFC2_dlr")),
tRFC_dpr ((refMode == 1) ? tCK * parseUint(memspec["memtimingspec"]["RFC1_dpr"], "RFC1_dpr")
: tCK * parseUint(memspec["memtimingspec"]["RFC2_dpr"], "RFC2_dpr")),
tRFCsb_slr (tCK * parseUint(memspec["memtimingspec"]["RFCsb_slr"], "RFCsb_slr")),
tRFCsb_dlr (tCK * parseUint(memspec["memtimingspec"]["RFCsb_dlr"], "RFCsb_dlr")),
tREFI ((refMode == 1) ? tCK * parseUint(memspec["memtimingspec"]["REFI1"], "REFI1")
: tCK * parseUint(memspec["memtimingspec"]["REFI2"], "REFI2")),
tREFIsb (tCK * parseUint(memspec["memtimingspec"]["REFISB"], "REFISB")),
tREFSBRD_slr (tCK * parseUint(memspec["memtimingspec"]["REFSBRD_slr"], "REFSBRD_slr")),
tREFSBRD_dlr (tCK * parseUint(memspec["memtimingspec"]["REFSBRD_dlr"], "REFSBRD_dlr")),
tRTRS (tCK * parseUint(memspec["memtimingspec"]["RTRS"], "RTRS")),
tCPDED (tCK * parseUint(memspec["memtimingspec"]["CPDED"], "CPDED")),
tPD (tCK * parseUint(memspec["memtimingspec"]["PD"], "PD")),
tXP (tCK * parseUint(memspec["memtimingspec"]["XP"], "XP")),
tACTPDEN (tCK * parseUint(memspec["memtimingspec"]["ACTPDEN"], "ACTPDEN")),
tPRPDEN (tCK * parseUint(memspec["memtimingspec"]["PRPDEN"], "PRPDEN")),
tREFPDEN (tCK * parseUint(memspec["memtimingspec"]["REFPDEN"], "REFPDEN")),
cmdOffset_S (cmdMode == 2 ? 1 * tCK : 0 * tCK),
cmdOffset_L (cmdMode == 2 ? 3 * tCK : 1 * tCK)
tRCD (tCK * parseUint(memspec["memtimingspec"]["RCD"], "RCD")),
tPPD (tCK * parseUint(memspec["memtimingspec"]["PPD"], "PPD")),
tRP (tCK * parseUint(memspec["memtimingspec"]["RP"], "RP")),
tRAS (tCK * parseUint(memspec["memtimingspec"]["RAS"], "RAS")),
tRC (tRAS + tRP),
tRL (tCK * parseUint(memspec["memtimingspec"]["RL"], "RL")),
tRTP (tCK * parseUint(memspec["memtimingspec"]["RTP"], "RTP")),
tRPRE (tCK * parseUint(memspec["memtimingspec"]["RPRE"], "RPRE")),
tRPST (tCK * parseUint(memspec["memtimingspec"]["RPST"], "RPST")),
tRDDQS (tCK * parseUint(memspec["memtimingspec"]["RDDQS"], "RDDQS")),
tWL (tCK * parseUint(memspec["memtimingspec"]["WL"], "WL")),
tWPRE (tCK * parseUint(memspec["memtimingspec"]["WPRE"], "WPRE")),
tWPST (tCK * parseUint(memspec["memtimingspec"]["WPST"], "WPST")),
tWR (tCK * parseUint(memspec["memtimingspec"]["WR"], "WR")),
tCCD_L_slr (tCK * parseUint(memspec["memtimingspec"]["CCD_L_slr"], "CCD_L_slr")),
tCCD_L_WR_slr (tCK * parseUint(memspec["memtimingspec"]["CCD_L_WR_slr"], "CCD_L_WR_slr")),
tCCD_L_WR2_slr (tCK * parseUint(memspec["memtimingspec"]["CCD_L_WR2_slr"], "CCD_L_WR2_slr")),
tCCD_S_slr (tCK * parseUint(memspec["memtimingspec"]["CCD_S_slr"], "CCD_S_slr")),
tCCD_S_WR_slr (tCK * parseUint(memspec["memtimingspec"]["CCD_S_WR_slr"], "CCD_S_WR_slr")),
tCCD_dlr (tCK * parseUint(memspec["memtimingspec"]["CCD_dlr"], "CCD_dlr")),
tCCD_WR_dlr (tCK * parseUint(memspec["memtimingspec"]["CCD_WR_dlr"], "CCD_WR_dlr")),
tCCD_WR_dpr (tCK * parseUint(memspec["memtimingspec"]["CCD_WR_dpr"], "CCD_WR_dpr")),
tRRD_L_slr (tCK * parseUint(memspec["memtimingspec"]["RRD_L_slr"], "RRD_L_slr")),
tRRD_S_slr (tCK * parseUint(memspec["memtimingspec"]["RRD_S_slr"], "RRD_S_slr")),
tRRD_dlr (tCK * parseUint(memspec["memtimingspec"]["RRD_dlr"], "RRD_dlr")),
tFAW_slr (tCK * parseUint(memspec["memtimingspec"]["FAW_slr"], "FAW_slr")),
tFAW_dlr (tCK * parseUint(memspec["memtimingspec"]["FAW_dlr"], "FAW_dlr")),
tWTR_L (tCK * parseUint(memspec["memtimingspec"]["WTR_L"], "WTR_L")),
tWTR_S (tCK * parseUint(memspec["memtimingspec"]["WTR_S"], "WTR_S")),
tRFC_slr ((refMode == 1) ? tCK * parseUint(memspec["memtimingspec"]["RFC1_slr"], "RFC1_slr")
: tCK * parseUint(memspec["memtimingspec"]["RFC2_slr"], "RFC2_slr")),
tRFC_dlr ((refMode == 1) ? tCK * parseUint(memspec["memtimingspec"]["RFC1_dlr"], "RFC1_dlr")
: tCK * parseUint(memspec["memtimingspec"]["RFC2_dlr"], "RFC2_dlr")),
tRFC_dpr ((refMode == 1) ? tCK * parseUint(memspec["memtimingspec"]["RFC1_dpr"], "RFC1_dpr")
: tCK * parseUint(memspec["memtimingspec"]["RFC2_dpr"], "RFC2_dpr")),
tRFCsb_slr (tCK * parseUint(memspec["memtimingspec"]["RFCsb_slr"], "RFCsb_slr")),
tRFCsb_dlr (tCK * parseUint(memspec["memtimingspec"]["RFCsb_dlr"], "RFCsb_dlr")),
tREFI ((refMode == 1) ? tCK * parseUint(memspec["memtimingspec"]["REFI1"], "REFI1")
: tCK * parseUint(memspec["memtimingspec"]["REFI2"], "REFI2")),
tREFIsb (tCK * parseUint(memspec["memtimingspec"]["REFISB"], "REFISB")),
tREFSBRD_slr (tCK * parseUint(memspec["memtimingspec"]["REFSBRD_slr"], "REFSBRD_slr")),
tREFSBRD_dlr (tCK * parseUint(memspec["memtimingspec"]["REFSBRD_dlr"], "REFSBRD_dlr")),
tRTRS (tCK * parseUint(memspec["memtimingspec"]["RTRS"], "RTRS")),
tCPDED (tCK * parseUint(memspec["memtimingspec"]["CPDED"], "CPDED")),
tPD (tCK * parseUint(memspec["memtimingspec"]["PD"], "PD")),
tXP (tCK * parseUint(memspec["memtimingspec"]["XP"], "XP")),
tACTPDEN (tCK * parseUint(memspec["memtimingspec"]["ACTPDEN"], "ACTPDEN")),
tPRPDEN (tCK * parseUint(memspec["memtimingspec"]["PRPDEN"], "PRPDEN")),
tREFPDEN (tCK * parseUint(memspec["memtimingspec"]["REFPDEN"], "REFPDEN")),
shortCmdOffset (cmdMode == 2 ? 1 * tCK : 0 * tCK),
longCmdOffset (cmdMode == 2 ? 3 * tCK : 1 * tCK),
tBURST16(tCK * 8),
tBURST32(tCK * 16)
{
if (cmdMode == 1)
{
@@ -156,24 +159,39 @@ sc_time MemSpecDDR5::getRefreshIntervalSB() const
}
// Returns the execution time for commands that have a fixed execution time
sc_time MemSpecDDR5::getExecutionTime(Command command, const tlm_generic_payload &) const
sc_time MemSpecDDR5::getExecutionTime(Command command, const tlm_generic_payload &payload) const
{
if (command == Command::PRE || command == Command::PREA || command == Command::PRESB)
return tRP + cmdOffset_S;
return tRP + shortCmdOffset;
else if (command == Command::ACT)
return tRCD + cmdOffset_L;
return tRCD + longCmdOffset;
else if (command == Command::RD)
return tRL + burstDuration + cmdOffset_L;
{
if (DramExtension::getBurstLength(payload) == 32)
return tRL + tBURST32 + longCmdOffset;
else
return tRL + tBURST16 + longCmdOffset;
}
else if (command == Command::RDA)
return tRTP + tRP + cmdOffset_L;
return tRTP + tRP + longCmdOffset;
else if (command == Command::WR)
return tWL + burstDuration + cmdOffset_L;
{
if (DramExtension::getBurstLength(payload) == 32)
return tWL + tBURST32 + longCmdOffset;
else
return tWL + tBURST16 + longCmdOffset;
}
else if (command == Command::WRA)
return tWL + burstDuration + tWR + tRP + cmdOffset_L;
{
if (DramExtension::getBurstLength(payload) == 32)
return tWL + tBURST32 + tWR + tRP + longCmdOffset;
else
return tWL + tBURST16 + tWR + tRP + longCmdOffset;
}
else if (command == Command::REFA)
return tRFC_slr + cmdOffset_S;
return tRFC_slr + shortCmdOffset;
else if (command == Command::REFSB)
return tRFCsb_slr + cmdOffset_S;
return tRFCsb_slr + shortCmdOffset;
else
{
SC_REPORT_FATAL("getExecutionTime",
@@ -182,12 +200,22 @@ sc_time MemSpecDDR5::getExecutionTime(Command command, const tlm_generic_payload
}
}
TimeInterval MemSpecDDR5::getIntervalOnDataStrobe(Command command) const
TimeInterval MemSpecDDR5::getIntervalOnDataStrobe(Command command, const tlm_generic_payload &payload) const
{
if (command == Command::RD || command == Command::RDA)
return TimeInterval(tRL + cmdOffset_L, tRL + burstDuration + cmdOffset_L);
{
if (DramExtension::getBurstLength(payload) == 32)
return TimeInterval(tRL + longCmdOffset, tRL + tBURST32 + longCmdOffset);
else
return TimeInterval(tRL + longCmdOffset, tRL + tBURST16 + longCmdOffset);
}
else if (command == Command::WR || command == Command::WRA)
return TimeInterval(tWL + cmdOffset_L, tWL + burstDuration + cmdOffset_L);
{
if (DramExtension::getBurstLength(payload) == 32)
return TimeInterval(tWL + longCmdOffset, tWL + tBURST32 + longCmdOffset);
else
return TimeInterval(tWL + longCmdOffset, tWL + tBURST16 + longCmdOffset);
}
else
{
SC_REPORT_FATAL("MemSpec", "Method was called with invalid argument");

View File

@@ -69,6 +69,7 @@ public:
const sc_time tWR;
const sc_time tCCD_L_slr;
const sc_time tCCD_L_WR_slr;
const sc_time tCCD_L_WR2_slr;
const sc_time tCCD_S_slr;
const sc_time tCCD_S_WR_slr;
const sc_time tCCD_dlr;
@@ -99,8 +100,11 @@ public:
const sc_time tPRPDEN;
const sc_time tREFPDEN;
const sc_time cmdOffset_S;
const sc_time cmdOffset_L;
const sc_time shortCmdOffset;
const sc_time longCmdOffset;
const sc_time tBURST16;
const sc_time tBURST32;
// Currents and Voltages:
// TODO: to be completed
@@ -108,8 +112,8 @@ public:
virtual sc_time getRefreshIntervalAB() const override;
virtual sc_time getRefreshIntervalSB() const override;
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
virtual sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override;
virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override;
virtual uint64_t getSimMemSizeInBytes() const override;
};

View File

@@ -128,7 +128,7 @@ sc_time MemSpecGDDR5::getExecutionTime(Command command, const tlm_generic_payloa
}
}
TimeInterval MemSpecGDDR5::getIntervalOnDataStrobe(Command command) const
TimeInterval MemSpecGDDR5::getIntervalOnDataStrobe(Command command, const tlm_generic_payload &) const
{
if (command == Command::RD || command == Command::RDA)
return TimeInterval(tCL + tWCK2CKPIN + tWCK2CK + tWCK2DQO,

View File

@@ -88,8 +88,8 @@ public:
virtual sc_time getRefreshIntervalAB() const override;
virtual sc_time getRefreshIntervalPB() const override;
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
virtual sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override;
virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override;
virtual uint64_t getSimMemSizeInBytes() const override;
};

View File

@@ -128,7 +128,7 @@ sc_time MemSpecGDDR5X::getExecutionTime(Command command, const tlm_generic_paylo
}
}
TimeInterval MemSpecGDDR5X::getIntervalOnDataStrobe(Command command) const
TimeInterval MemSpecGDDR5X::getIntervalOnDataStrobe(Command command, const tlm_generic_payload &) const
{
if (command == Command::RD || command == Command::RDA)
return TimeInterval(tRL + tWCK2CKPIN + tWCK2CK + tWCK2DQO,

View File

@@ -88,8 +88,8 @@ public:
virtual sc_time getRefreshIntervalAB() const override;
virtual sc_time getRefreshIntervalPB() const override;
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
virtual sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override;
virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override;
virtual uint64_t getSimMemSizeInBytes() const override;
};

View File

@@ -130,7 +130,7 @@ sc_time MemSpecGDDR6::getExecutionTime(Command command, const tlm_generic_payloa
}
}
TimeInterval MemSpecGDDR6::getIntervalOnDataStrobe(Command command) const
TimeInterval MemSpecGDDR6::getIntervalOnDataStrobe(Command command, const tlm_generic_payload &) const
{
if (command == Command::RD || command == Command::RDA)
return TimeInterval(tRL + tWCK2CKPIN + tWCK2CK + tWCK2DQO,

View File

@@ -90,8 +90,8 @@ public:
virtual sc_time getRefreshIntervalAB() const override;
virtual sc_time getRefreshIntervalPB() const override;
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
virtual sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override;
virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override;
virtual uint64_t getSimMemSizeInBytes() const override;
};

View File

@@ -130,7 +130,7 @@ sc_time MemSpecHBM2::getExecutionTime(Command command, const tlm_generic_payload
}
}
TimeInterval MemSpecHBM2::getIntervalOnDataStrobe(Command command) const
TimeInterval MemSpecHBM2::getIntervalOnDataStrobe(Command command, const tlm_generic_payload &) const
{
if (command == Command::RD || command == Command::RDA)
return TimeInterval(tRL + tDQSCK, tRL + tDQSCK + burstDuration);

View File

@@ -85,8 +85,8 @@ public:
virtual bool hasRasAndCasBus() const override;
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
virtual sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override;
virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override;
virtual uint64_t getSimMemSizeInBytes() const override;
};

View File

@@ -132,7 +132,7 @@ sc_time MemSpecLPDDR4::getExecutionTime(Command command, const tlm_generic_paylo
}
}
TimeInterval MemSpecLPDDR4::getIntervalOnDataStrobe(Command command) const
TimeInterval MemSpecLPDDR4::getIntervalOnDataStrobe(Command command, const tlm_generic_payload &) const
{
if (command == Command::RD || command == Command::RDA)
return TimeInterval(tRL + tDQSCK + 3 * tCK,

View File

@@ -83,8 +83,8 @@ public:
virtual sc_time getRefreshIntervalAB() const override;
virtual sc_time getRefreshIntervalPB() const override;
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
virtual sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override;
virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override;
virtual uint64_t getSimMemSizeInBytes() const override;
};

View File

@@ -0,0 +1,136 @@
/*
* Copyright (c) 2021, Technische Universität 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.
*
* Authors:
* Lukas Steiner
*/
#include "MemSpecSTTMRAM.h"
using namespace tlm;
using json = nlohmann::json;
MemSpecSTTMRAM::MemSpecSTTMRAM(json &memspec)
: MemSpec(memspec, MemoryType::STTMRAM,
parseUint(memspec["memarchitecturespec"]["nbrOfChannels"],"nbrOfChannels"),
parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"),
parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"),
1,
parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"),
parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks")
* parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"),
parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"),
parseUint(memspec["memarchitecturespec"]["nbrOfDevicesOnDIMM"],"nbrOfDevicesOnDIMM")),
tCKE (tCK * parseUint(memspec["memtimingspec"]["CKE"], "CKE")),
tPD (tCKE),
tCKESR (tCK * parseUint(memspec["memtimingspec"]["CKESR"], "CKESR")),
tDQSCK (tCK * parseUint(memspec["memtimingspec"]["DQSCK"], "DQSCK")),
tRAS (tCK * parseUint(memspec["memtimingspec"]["RAS"], "RAS")),
tRC (tCK * parseUint(memspec["memtimingspec"]["RC"], "RC")),
tRCD (tCK * parseUint(memspec["memtimingspec"]["RCD"], "RCD")),
tRL (tCK * parseUint(memspec["memtimingspec"]["RL"], "RL")),
tRTP (tCK * parseUint(memspec["memtimingspec"]["RTP"], "RTP")),
tWL (tCK * parseUint(memspec["memtimingspec"]["WL"], "WL")),
tWR (tCK * parseUint(memspec["memtimingspec"]["WR"], "WR")),
tXP (tCK * parseUint(memspec["memtimingspec"]["XP"], "XP")),
tXS (tCK * parseUint(memspec["memtimingspec"]["XS"], "XS")),
tCCD (tCK * parseUint(memspec["memtimingspec"]["CCD"], "CCD")),
tFAW (tCK * parseUint(memspec["memtimingspec"]["FAW"], "FAW")),
tRP (tCK * parseUint(memspec["memtimingspec"]["RP"], "RP")),
tRRD (tCK * parseUint(memspec["memtimingspec"]["RRD"], "RRD")),
tWTR (tCK * parseUint(memspec["memtimingspec"]["WTR"], "WTR")),
tAL (tCK * parseUint(memspec["memtimingspec"]["AL"], "AL")),
tXPDLL (tCK * parseUint(memspec["memtimingspec"]["XPDLL"], "XPDLL")),
tXSDLL (tCK * parseUint(memspec["memtimingspec"]["XSDLL"], "XSDLL")),
tACTPDEN (tCK * parseUint(memspec["memtimingspec"]["ACTPDEN"], "ACTPDEN")),
tPRPDEN (tCK * parseUint(memspec["memtimingspec"]["PRPDEN"], "PRPDEN")),
tRTRS (tCK * parseUint(memspec["memtimingspec"]["RTRS"], "RTRS"))
{}
// Returns the execution time for commands that have a fixed execution time
sc_time MemSpecSTTMRAM::getExecutionTime(Command command, const tlm_generic_payload &) const
{
if (command == Command::PRE || command == Command::PREA)
return tRP;
else if (command == Command::ACT)
return tRCD;
else if (command == Command::RD)
return tRL + burstDuration;
else if (command == Command::RDA)
return tRTP + tRP;
else if (command == Command::WR)
return tWL + burstDuration;
else if (command == Command::WRA)
return tWL + burstDuration + tWR + tRP;
else
{
SC_REPORT_FATAL("getExecutionTime",
"command not known or command doesn't have a fixed execution time");
return SC_ZERO_TIME;
}
}
TimeInterval MemSpecSTTMRAM::getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &) const
{
if (command == Command::RD || command == Command::RDA)
return TimeInterval(tRL, tRL + burstDuration);
else if (command == Command::WR || command == Command::WRA)
return TimeInterval(tWL, tWL + burstDuration);
else
{
SC_REPORT_FATAL("MemSpec", "Method was called with invalid argument");
return TimeInterval();
}
}
uint64_t MemSpecSTTMRAM::getSimMemSizeInBytes() const
{
uint64_t deviceSizeBits = static_cast<uint64_t>(banksPerRank) * numberOfRows * numberOfColumns * bitWidth;
uint64_t deviceSizeBytes = deviceSizeBits / 8;
uint64_t memorySizeBytes = deviceSizeBytes * numberOfDevicesOnDIMM * numberOfRanks;
std::cout << headline << std::endl;
std::cout << "Per Channel Configuration:" << std::endl << std::endl;
std::cout << " Memory type: " << "STT-MRAM" << std::endl;
std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl;
std::cout << " Ranks: " << numberOfRanks << std::endl;
std::cout << " Banks per rank: " << banksPerRank << std::endl;
std::cout << " Rows per bank: " << numberOfRows << std::endl;
std::cout << " Columns per row: " << numberOfColumns << std::endl;
std::cout << " Device width in bits: " << bitWidth << std::endl;
std::cout << " Device size in bits: " << deviceSizeBits << std::endl;
std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl;
std::cout << " Devices on DIMM: " << numberOfDevicesOnDIMM << std::endl;
std::cout << std::endl;
assert(memorySizeBytes > 0);
return memorySizeBytes;
}

View File

@@ -0,0 +1,82 @@
/*
* Copyright (c) 2021, Technische Universität 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.
*
* Authors:
* Lukas Steiner
*/
#ifndef MEMSPECSTTMRAM_H
#define MEMSPECSTTMRAM_H
#include "MemSpec.h"
#include "../../common/third_party/nlohmann/single_include/nlohmann/json.hpp"
class MemSpecSTTMRAM final : public MemSpec
{
public:
MemSpecSTTMRAM(nlohmann::json &memspec);
// Memspec Variables:
const sc_time tCKE;
const sc_time tPD;
const sc_time tCKESR;
const sc_time tRAS;
const sc_time tRC;
const sc_time tRCD;
const sc_time tRL;
const sc_time tRTP;
const sc_time tWL;
const sc_time tWR;
const sc_time tXP;
const sc_time tXS;
const sc_time tRP;
const sc_time tDQSCK;
const sc_time tCCD;
const sc_time tFAW;
const sc_time tRRD;
const sc_time tWTR;
const sc_time tXPDLL;
const sc_time tXSDLL;
const sc_time tAL;
const sc_time tACTPDEN;
const sc_time tPRPDEN;
const sc_time tRTRS;
// Currents and Voltages:
// TODO: to be completed
virtual sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override;
virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override;
virtual uint64_t getSimMemSizeInBytes() const override;
};
#endif // MEMSPECSTTMRAM_H

View File

@@ -126,7 +126,7 @@ sc_time MemSpecWideIO::getExecutionTime(Command command, const tlm_generic_paylo
}
}
TimeInterval MemSpecWideIO::getIntervalOnDataStrobe(Command command) const
TimeInterval MemSpecWideIO::getIntervalOnDataStrobe(Command command, const tlm_generic_payload &) const
{
if (command == Command::RD || command == Command::RDA)
return TimeInterval(tRL + tAC, tRL + tAC + burstDuration);

View File

@@ -95,8 +95,8 @@ public:
virtual sc_time getRefreshIntervalAB() const override;
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
virtual sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override;
virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override;
virtual uint64_t getSimMemSizeInBytes() const override;
};

View File

@@ -117,7 +117,7 @@ sc_time MemSpecWideIO2::getExecutionTime(Command command, const tlm_generic_payl
}
}
TimeInterval MemSpecWideIO2::getIntervalOnDataStrobe(Command command) const
TimeInterval MemSpecWideIO2::getIntervalOnDataStrobe(Command command, const tlm_generic_payload &) const
{
if (command == Command::RD || command == Command::RDA)
return TimeInterval(tRL + tDQSCK, tRL + tDQSCK + burstDuration);

View File

@@ -77,8 +77,8 @@ public:
virtual sc_time getRefreshIntervalAB() const override;
virtual sc_time getRefreshIntervalPB() const override;
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
virtual sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override;
virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override;
virtual uint64_t getSimMemSizeInBytes() const override;
};

View File

@@ -148,7 +148,8 @@ sc_time BankMachineOpen::start()
else // row miss
nextCommand = Command::PRE;
}
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank);
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank,
bankgroup, bank, DramExtension::getBurstLength(currentPayload));
}
}
return timeToSchedule;
@@ -178,7 +179,8 @@ sc_time BankMachineClosed::start()
else
SC_REPORT_FATAL("BankMachine", "Wrong TLM command");
}
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank);
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank,
bankgroup, bank, DramExtension::getBurstLength(currentPayload));
}
}
return timeToSchedule;
@@ -225,7 +227,8 @@ sc_time BankMachineOpenAdaptive::start()
else // row miss
nextCommand = Command::PRE;
}
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank);
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank,
bankgroup, bank, DramExtension::getBurstLength(currentPayload));
}
}
return timeToSchedule;
@@ -272,7 +275,8 @@ sc_time BankMachineClosedAdaptive::start()
else // row miss, should never happen
SC_REPORT_FATAL("BankMachine", "Should never be reached for this policy");
}
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank);
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank,
bankgroup, bank, DramExtension::getBurstLength(currentPayload));
}
}
return timeToSchedule;

View File

@@ -47,6 +47,7 @@
#include "checker/CheckerGDDR5.h"
#include "checker/CheckerGDDR5X.h"
#include "checker/CheckerGDDR6.h"
#include "checker/CheckerSTTMRAM.h"
#include "scheduler/SchedulerFifo.h"
#include "scheduler/SchedulerFrFcfs.h"
#include "scheduler/SchedulerFrFcfsGrp.h"
@@ -102,6 +103,8 @@ Controller::Controller(sc_module_name name) :
checker = new CheckerGDDR5X();
else if (memSpec->memoryType == MemSpec::MemoryType::GDDR6)
checker = new CheckerGDDR6();
else if (memSpec->memoryType == MemSpec::MemoryType::STTMRAM)
checker = new CheckerSTTMRAM();
// instantiate scheduler and command mux
if (config.scheduler == Configuration::Scheduler::Fifo)
@@ -287,6 +290,7 @@ void Controller::controllerMethod()
Rank rank = DramExtension::getRank(payload);
BankGroup bankgroup = DramExtension::getBankGroup(payload);
Bank bank = DramExtension::getBank(payload);
unsigned burstLength = DramExtension::getBurstLength(payload);
if (isRankCommand(command))
{
@@ -304,7 +308,7 @@ void Controller::controllerMethod()
refreshManagers[rank.ID()]->updateState(command);
powerDownManagers[rank.ID()]->updateState(command);
checker->insert(command, rank, bankgroup, bank);
checker->insert(command, rank, bankgroup, bank, burstLength);
if (isCasCommand(command))
{
@@ -312,7 +316,7 @@ void Controller::controllerMethod()
manageRequests(thinkDelayFw);
respQueue->insertPayload(payload, sc_time_stamp()
+ thinkDelayFw + phyDelayFw
+ memSpec->getIntervalOnDataStrobe(command).end
+ memSpec->getIntervalOnDataStrobe(command, *payload).end
+ phyDelayBw + thinkDelayBw);
sc_time triggerTime = respQueue->getTriggerTime();
@@ -437,9 +441,9 @@ void Controller::manageResponses()
NDEBUG_UNUSED(uint64_t id) = DramExtension::getChannelPayloadID(transToRelease.payload);
PRINTDEBUGMESSAGE(name(), "Payload " + std::to_string(id) + " left system.");
numberOfBeatsServed += DramExtension::getBurstLength(transToRelease.payload);
transToRelease.payload->release();
transToRelease.payload = nullptr;
numberOfTransactionsServed++;
totalNumberOfPayloads--;
if (totalNumberOfPayloads == 0)

View File

@@ -55,8 +55,7 @@ public:
// Destructor
virtual ~ControllerIF()
{
sc_time activeTime = numberOfTransactionsServed
* Configuration::getInstance().memSpec->burstLength
sc_time activeTime = numberOfBeatsServed
/ Configuration::getInstance().memSpec->dataRate
* Configuration::getInstance().memSpec->tCK;
@@ -143,7 +142,7 @@ protected:
sc_time idleStart;
} idleTimeCollector;
uint64_t numberOfTransactionsServed = 0;
uint64_t numberOfBeatsServed = 0;
};

View File

@@ -75,7 +75,7 @@ void ControllerRecordable::sendToDram(Command command, tlm_generic_payload *payl
{
if (isCasCommand(command))
{
TimeInterval dataStrobe = Configuration::getInstance().memSpec->getIntervalOnDataStrobe(command);
TimeInterval dataStrobe = Configuration::getInstance().memSpec->getIntervalOnDataStrobe(command, *payload);
tlmRecorder->updateDataStrobe(sc_time_stamp() + delay + dataStrobe.start,
sc_time_stamp() + delay + dataStrobe.end, *payload);
}
@@ -130,9 +130,9 @@ void ControllerRecordable::controllerMethod()
Controller::controllerMethod();
uint64_t windowNumberOfTransactionsServed = numberOfTransactionsServed - lastNumberOfTransactionsServed;
lastNumberOfTransactionsServed = numberOfTransactionsServed;
sc_time windowActiveTime = windowNumberOfTransactionsServed * activeTimeMultiplier;
uint64_t windowNumberOfBeatsServed = numberOfBeatsServed - lastNumberOfBeatsServed;
lastNumberOfBeatsServed = numberOfBeatsServed;
sc_time windowActiveTime = windowNumberOfBeatsServed * activeTimeMultiplier;
double windowAverageBandwidth = windowActiveTime / windowSizeTime;
tlmRecorder->recordBandwidth(sc_time_stamp().to_seconds(), windowAverageBandwidth);
}

View File

@@ -66,10 +66,9 @@ private:
std::vector<double> windowAverageBufferDepth;
sc_time lastTimeCalled = SC_ZERO_TIME;
uint64_t lastNumberOfTransactionsServed = 0;
sc_time activeTimeMultiplier = Configuration::getInstance().memSpec->burstLength
/ Configuration::getInstance().memSpec->dataRate
* Configuration::getInstance().memSpec->tCK;
uint64_t lastNumberOfBeatsServed = 0;
sc_time activeTimeMultiplier = Configuration::getInstance().memSpec->tCK
/ Configuration::getInstance().memSpec->dataRate;
};
#endif // CONTROLLERRECORDABLE_H

View File

@@ -52,7 +52,7 @@ CheckerDDR3::CheckerDDR3()
tBURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK;
tRDWR = memSpec->tRL + tBURST + 2 * memSpec->tCK - memSpec->tWL;
tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL;
tWRRD = memSpec->tWL + tBURST + memSpec->tWTR;
tWRRD = memSpec->tWL + tBURST + memSpec->tWTR - memSpec->tAL;
tWRRD_R = memSpec->tWL + tBURST + memSpec->tRTRS - memSpec->tRL;
tWRPRE = memSpec->tWL + tBURST + memSpec->tWR;
tRDPDEN = memSpec->tRL + tBURST + memSpec->tCK;
@@ -60,7 +60,7 @@ CheckerDDR3::CheckerDDR3()
tWRAPDEN = memSpec->tWL + tBURST + memSpec->tWR + memSpec->tCK;
}
sc_time CheckerDDR3::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank) const
sc_time CheckerDDR3::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank, unsigned) const
{
sc_time lastCommandStart;
sc_time earliestTimeToStart = sc_time_stamp();
@@ -91,7 +91,7 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command, Rank rank, BankGr
{
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP - memSpec->tAL);
}
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
@@ -412,7 +412,7 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command, Rank rank, BankGr
return earliestTimeToStart;
}
void CheckerDDR3::insert(Command command, Rank rank, BankGroup, Bank bank)
void CheckerDDR3::insert(Command command, Rank rank, BankGroup, Bank bank, unsigned)
{
PRINTDEBUGMESSAGE("CheckerDDR3", "Changing state on bank " + std::to_string(bank.ID())
+ " command is " + commandToString(command));

View File

@@ -45,8 +45,9 @@ class CheckerDDR3 final : public CheckerIF
{
public:
CheckerDDR3();
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
virtual void insert(Command, Rank, BankGroup, Bank) override;
virtual sc_time timeToSatisfyConstraints(Command, Rank = Rank(0),
BankGroup = BankGroup(0), Bank = Bank(0), unsigned burstLength = 0) const override;
virtual void insert(Command, Rank, BankGroup, Bank, unsigned) override;
private:
const MemSpecDDR3 *memSpec;

View File

@@ -54,8 +54,8 @@ CheckerDDR4::CheckerDDR4()
tBURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK;
tRDWR = memSpec->tRL + tBURST + memSpec->tCK - memSpec->tWL + memSpec->tWPRE;
tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL + memSpec->tWPRE;
tWRRD_S = memSpec->tWL + tBURST + memSpec->tWTR_S;
tWRRD_L = memSpec->tWL + tBURST + memSpec->tWTR_L;
tWRRD_S = memSpec->tWL + tBURST + memSpec->tWTR_S - memSpec->tAL;
tWRRD_L = memSpec->tWL + tBURST + memSpec->tWTR_L - memSpec->tAL;
tWRRD_R = memSpec->tWL + tBURST + memSpec->tRTRS - memSpec->tRL + memSpec->tRPRE;
tWRPRE = memSpec->tWL + tBURST + memSpec->tWR;
tRDPDEN = memSpec->tRL + tBURST + memSpec->tCK;
@@ -63,7 +63,7 @@ CheckerDDR4::CheckerDDR4()
tWRAPDEN = memSpec->tWL + tBURST + memSpec->tCK + memSpec->tWR;
}
sc_time CheckerDDR4::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
sc_time CheckerDDR4::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank, unsigned) const
{
sc_time lastCommandStart;
sc_time earliestTimeToStart = sc_time_stamp();
@@ -102,7 +102,7 @@ sc_time CheckerDDR4::timeToSatisfyConstraints(Command command, Rank rank, BankGr
{
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP - memSpec->tAL);
}
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()];
@@ -443,7 +443,7 @@ sc_time CheckerDDR4::timeToSatisfyConstraints(Command command, Rank rank, BankGr
return earliestTimeToStart;
}
void CheckerDDR4::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank)
void CheckerDDR4::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank, unsigned)
{
PRINTDEBUGMESSAGE("CheckerDDR4", "Changing state on bank " + std::to_string(bank.ID())
+ " command is " + commandToString(command));

View File

@@ -45,8 +45,9 @@ class CheckerDDR4 final : public CheckerIF
{
public:
CheckerDDR4();
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
virtual void insert(Command, Rank, BankGroup, Bank) override;
virtual sc_time timeToSatisfyConstraints(Command, Rank = Rank(0),
BankGroup = BankGroup(0), Bank = Bank(0), unsigned burstLength = 0) const override;
virtual void insert(Command, Rank, BankGroup, Bank, unsigned) override;
private:
const MemSpecDDR4 *memSpec;

View File

@@ -41,7 +41,7 @@ CheckerDDR5::CheckerDDR5()
if (memSpec == nullptr)
SC_REPORT_FATAL("CheckerDDR5", "Wrong MemSpec chosen");
lastScheduledByCommandAndDIMMRank = std::vector<std::vector<sc_time>>
lastScheduledByCommandAndDimmRank = std::vector<std::vector<sc_time>>
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfDIMMRanks, sc_max_time()));
lastScheduledByCommandAndPhysicalRank = std::vector<std::vector<sc_time>>
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfPhysicalRanks, sc_max_time()));
@@ -56,40 +56,63 @@ CheckerDDR5::CheckerDDR5()
lastScheduledByCommandAndBankInGroup = std::vector<std::vector<sc_time>>(numberOfCommands(),
std::vector<sc_time>(memSpec->numberOfRanks * memSpec->banksPerGroup, sc_max_time()));
lastCommandOnBus = sc_max_time();
dummyCommandOnBus.start = sc_max_time();
dummyCommandOnBus.end = sc_max_time();
last4ActivatesLogical = std::vector<std::queue<sc_time>>(memSpec->numberOfLogicalRanks);
last4ActivatesPhysical = std::vector<std::queue<sc_time>>(memSpec->numberOfPhysicalRanks);
cmdOffset = memSpec->cmdMode * memSpec->tCK;
lastBurstLengthByCommandAndDimmRank = std::vector<std::vector<uint8_t>>
(4, std::vector<uint8_t>(memSpec->numberOfDIMMRanks));
lastBurstLengthByCommandAndPhysicalRank = std::vector<std::vector<uint8_t>>
(4, std::vector<uint8_t>(memSpec->numberOfPhysicalRanks));
lastBurstLengthByCommandAndLogicalRank = std::vector<std::vector<uint8_t>>
(4, std::vector<uint8_t>(memSpec->numberOfLogicalRanks));
lastBurstLengthByCommandAndBankGroup = std::vector<std::vector<uint8_t>>
(4, std::vector<uint8_t>(memSpec->numberOfBankGroups));
lastBurstLengthByCommandAndBank = std::vector<std::vector<uint8_t>>
(4, std::vector<uint8_t>(memSpec->numberOfBanks));
lastBurstLengthByCommand = std::vector<uint8_t>(4);
lastBurstLengthByCommandAndBankInGroup = std::vector<std::vector<uint8_t>>
(4, std::vector<uint8_t>(memSpec->numberOfRanks * memSpec->banksPerGroup));
tRD_BURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK;
tWR_BURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK;
cmdLengthDiff = memSpec->cmdMode * memSpec->tCK;
tBURST16 = 8 * memSpec->tCK;
tBURST32 = 16 * memSpec->tCK;
tWTRA = memSpec->tWR - memSpec->tRTP;
tWRRDA = memSpec->tWL + tWR_BURST + tWTRA;
tWRPRE = memSpec->tWL + tWR_BURST + memSpec->tWR;
tWRRDA = memSpec->tWL + tBURST16 + tWTRA; // tWTRA = tWR - tRTP
tWRPRE = memSpec->tWL + tBURST16 + memSpec->tWR;
tRDAACT = memSpec->tRTP + memSpec->tRP;
tWRAACT = tWRPRE + memSpec->tRP;
tCCD_L_RTW_slr = memSpec->tRL - memSpec->tWL + tRD_BURST + 2 * memSpec->tCK - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE;
tCCD_S_RTW_slr = memSpec->tRL - memSpec->tWL + tRD_BURST + 2 * memSpec->tCK - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE;
tCCD_RTW_dlr = memSpec->tRL - memSpec->tWL + tRD_BURST + 2 * memSpec->tCK - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE;
tRDRD_dpr = tRD_BURST + memSpec->tRTRS;
tRDRD_ddr = tRD_BURST + memSpec->tRTRS;
tRDWR_dpr = memSpec->tRL - memSpec->tWL + tRD_BURST + memSpec->tRTRS - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE;
tRDWR_ddr = memSpec->tRL - memSpec->tWL + tRD_BURST + memSpec->tRTRS - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE;
tCCD_L_WTR_slr = memSpec->tWL + tWR_BURST + memSpec->tWTR_L;
tCCD_S_WTR_slr = memSpec->tWL + tWR_BURST + memSpec->tWTR_S;
tCCD_WTR_dlr = memSpec->tWL + tWR_BURST + memSpec->tWTR_S;
tWRWR_dpr = std::max(memSpec->tCCD_WR_dpr, tWR_BURST + memSpec->tRTRS);
tWRWR_ddr = tWR_BURST + memSpec->tRTRS;
tWRRD_dpr = memSpec->tWL - memSpec->tRL + tWR_BURST + memSpec->tRTRS + memSpec->tRDDQS + memSpec->tWPST + memSpec->tRPRE;
tWRRD_ddr = memSpec->tWL - memSpec->tRL + tWR_BURST + memSpec->tRTRS + memSpec->tRDDQS + memSpec->tWPST + memSpec->tRPRE;
tRDPDEN = memSpec->tRL + tRD_BURST + cmdOffset;
tWRPDEN = memSpec->tWL + tWR_BURST + memSpec->tWR + cmdOffset;
tWRAPDEN = memSpec->tWL + tWR_BURST + memSpec->tWR + cmdOffset;
// TODO: tRTP BL 32 (similar to LPDDR4)
tCCD_L_RTW_slr = memSpec->tRL - memSpec->tWL + tBURST16 + 2 * memSpec->tCK
- memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE;
tCCD_S_RTW_slr = memSpec->tRL - memSpec->tWL + tBURST16 + 2 * memSpec->tCK
- memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE;
tCCD_RTW_dlr = memSpec->tRL - memSpec->tWL + tBURST16 + 2 * memSpec->tCK
- memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE;
tRDRD_dpr = tBURST16 + memSpec->tRTRS;
tRDRD_ddr = tBURST16 + memSpec->tRTRS;
tRDWR_dpr = memSpec->tRL - memSpec->tWL + tBURST16 + memSpec->tRTRS
- memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE;
tRDWR_ddr = memSpec->tRL - memSpec->tWL + tBURST16 + memSpec->tRTRS
- memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE;
tCCD_L_WTR_slr = memSpec->tWL + tBURST16 + memSpec->tWTR_L;
tCCD_S_WTR_slr = memSpec->tWL + tBURST16 + memSpec->tWTR_S;
tCCD_WTR_dlr = memSpec->tWL + tBURST16 + memSpec->tWTR_S;
tWRWR_dpr = std::max(memSpec->tCCD_WR_dpr, tBURST16 + memSpec->tRTRS);
tWRWR_ddr = tBURST16 + memSpec->tRTRS;
tWRRD_dpr = memSpec->tWL - memSpec->tRL + tBURST16 + memSpec->tRTRS
+ memSpec->tRDDQS + memSpec->tWPST + memSpec->tRPRE;
tWRRD_ddr = memSpec->tWL - memSpec->tRL + tBURST16 + memSpec->tRTRS
+ memSpec->tRDDQS + memSpec->tWPST + memSpec->tRPRE;
tRDPDEN = memSpec->tRL + tBURST16 + cmdLengthDiff;
tWRPDEN = memSpec->tWL + tBURST16 + memSpec->tWR + cmdLengthDiff;
tWRAPDEN = memSpec->tWL + tBURST16 + memSpec->tWR + cmdLengthDiff;
}
sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank,
unsigned burstLength) const
{
sc_time lastCommandStart;
sc_time earliestTimeToStart = sc_time_stamp();
@@ -116,15 +139,30 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()];
if (lastCommandStart != sc_max_time())
{
if (lastBurstLengthByCommandAndPhysicalRank[Command::RD][physicalrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST32);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_dlr);
}
lastCommandStart = lastScheduledByCommand[Command::RD];
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()])
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()]) // different physical rank
{
if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::RD][dimmrank.ID()])
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_ddr);
if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::RD][dimmrank.ID()]) // same DIMM
{
if (lastBurstLengthByCommandAndDimmRank[Command::RD][dimmrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr + tBURST16);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr);
}
else // different DIMM
{
if (lastBurstLengthByCommand[Command::RD] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_ddr + tBURST16);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_ddr);
}
}
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankgroup.ID()];
@@ -137,64 +175,134 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()];
if (lastCommandStart != sc_max_time())
{
if (lastBurstLengthByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST32);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_dlr);
}
lastCommandStart = lastScheduledByCommand[Command::RDA];
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()])
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()]) // different physical rank
{
if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::RDA][dimmrank.ID()])
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_ddr);
if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::RDA][dimmrank.ID()]) // same DIMM
{
if (lastBurstLengthByCommandAndDimmRank[Command::RDA][dimmrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr + tBURST16);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr);
}
else // different DIMM
{
if (lastBurstLengthByCommand[Command::RDA] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_ddr + tBURST16);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_ddr);
}
}
if (command == Command::RDA)
{
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRDA);
{
if (lastBurstLengthByCommandAndBank[Command::WR][bank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRDA + tBURST16);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRDA);
}
}
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr);
{
if (lastBurstLengthByCommandAndBankGroup[Command::WR][bankgroup.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr + tBURST16);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr);
}
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WR][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_WTR_slr);
{
if (lastBurstLengthByCommandAndLogicalRank[Command::WR][logicalrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_WTR_slr + tBURST16);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_WTR_slr);
}
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_WTR_dlr);
{
if (lastBurstLengthByCommandAndPhysicalRank[Command::WR][physicalrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_WTR_dlr + tBURST16);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_WTR_dlr);
}
lastCommandStart = lastScheduledByCommand[Command::WR];
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()])
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()]) // different physical rank
{
if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::WR][dimmrank.ID()])
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_ddr);
if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::WR][dimmrank.ID()]) // same DIMM
{
if (lastBurstLengthByCommandAndDimmRank[Command::WR][dimmrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr + tBURST16);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr);
}
else // different DIMM
{
if (lastBurstLengthByCommand[Command::WR] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_ddr + tBURST16);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_ddr);
}
}
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr);
{
if (lastBurstLengthByCommandAndBankGroup[Command::WRA][bankgroup.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr + tBURST16);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr);
}
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WRA][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_WTR_slr);
{
if (lastBurstLengthByCommandAndLogicalRank[Command::WRA][logicalrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_WTR_slr + tBURST16);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_WTR_slr);
}
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_WTR_dlr);
{
if (lastBurstLengthByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_WTR_dlr + tBURST16);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_WTR_dlr);
}
lastCommandStart = lastScheduledByCommand[Command::WRA];
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()])
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()]) // different physical rank
{
if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::WRA][dimmrank.ID()])
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_ddr);
if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::WRA][dimmrank.ID()]) // same DIMM
{
if (lastBurstLengthByCommandAndDimmRank[Command::WRA][dimmrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr + tBURST16);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr);
}
else // different DIMM
{
if (lastBurstLengthByCommand[Command::WRA] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_ddr + tBURST16);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_ddr);
}
}
}
else if (command == Command::WR || command == Command::WRA)
@@ -205,49 +313,114 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankgroup.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_RTW_slr);
{
if (lastBurstLengthByCommandAndBankGroup[Command::RD][bankgroup.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_RTW_slr + tBURST16);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_RTW_slr);
}
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RD][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_RTW_slr);
{
if (lastBurstLengthByCommandAndLogicalRank[Command::RD][logicalrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_RTW_slr + tBURST16);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_RTW_slr);
}
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_RTW_dlr);
{
if (lastBurstLengthByCommandAndPhysicalRank[Command::RD][physicalrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_RTW_dlr + tBURST16);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_RTW_dlr);
}
lastCommandStart = lastScheduledByCommand[Command::RD];
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()])
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()]) // different physical rank
{
if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::RD][dimmrank.ID()])
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_ddr);
if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::RD][dimmrank.ID()]) // same DIMM
{
if (lastBurstLengthByCommandAndDimmRank[Command::RD][dimmrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr + tBURST16);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr);
}
else // different DIMM
{
if (lastBurstLengthByCommand[Command::RD] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_ddr + tBURST16);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_ddr);
}
}
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankgroup.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_RTW_slr);
{
if (lastBurstLengthByCommandAndBankGroup[Command::RDA][bankgroup.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_RTW_slr + tBURST16);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_RTW_slr);
}
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RDA][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_RTW_slr);
{
if (lastBurstLengthByCommandAndLogicalRank[Command::RDA][logicalrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_RTW_slr + tBURST16);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_RTW_slr);
}
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_RTW_dlr);
{
if (lastBurstLengthByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_RTW_dlr + tBURST16);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_RTW_dlr);
}
lastCommandStart = lastScheduledByCommand[Command::RDA];
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()])
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()]) // different physical rank
{
if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::RDA][dimmrank.ID()])
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_ddr);
if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::RDA][dimmrank.ID()]) // same DIMM
{
if (lastBurstLengthByCommandAndDimmRank[Command::RDA][dimmrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr + tBURST16);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr);
}
else // different DIMM
{
if (lastBurstLengthByCommand[Command::RDA] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_ddr + tBURST16);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_ddr);
}
}
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_WR_slr);
{
if (lastBurstLengthByCommandAndBankGroup[Command::WR][bankgroup.ID()] == 32)
{
if (burstLength == 16 && memSpec->bitWidth == 4) // second WR requires RMW
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST16 + memSpec->tCCD_L_WR_slr);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST16 + memSpec->tCCD_L_WR2_slr);
}
else
{
if (burstLength == 16 && memSpec->bitWidth == 4) // second WR requires RMW
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_WR_slr);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_WR2_slr);
}
}
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WR][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
@@ -255,20 +428,50 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()];
if (lastCommandStart != sc_max_time())
{
if (lastBurstLengthByCommandAndPhysicalRank[Command::WR][physicalrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST32);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_WR_dlr);
}
lastCommandStart = lastScheduledByCommand[Command::WR];
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()])
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()]) // different physical rank
{
if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::WR][dimmrank.ID()])
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_ddr);
if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::WR][dimmrank.ID()]) // same DIMM
{
if (lastBurstLengthByCommandAndDimmRank[Command::WR][dimmrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr + tBURST16);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr);
}
else // different DIMM
{
if (lastBurstLengthByCommand[Command::WR] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_ddr + tBURST16);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_ddr);
}
}
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_WR_slr);
{
if (lastBurstLengthByCommandAndBankGroup[Command::WRA][bankgroup.ID()] == 32)
{
if (burstLength == 16 && memSpec->bitWidth == 4) // second WR requires RMW
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST16 + memSpec->tCCD_L_WR_slr);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST16 + memSpec->tCCD_L_WR2_slr);
}
else
{
if (burstLength == 16 && memSpec->bitWidth == 4) // second WR requires RMW
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_WR_slr);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_WR2_slr);
}
}
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WRA][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
@@ -276,15 +479,30 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()];
if (lastCommandStart != sc_max_time())
{
if (lastBurstLengthByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST32);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_WR_dlr);
}
lastCommandStart = lastScheduledByCommand[Command::WRA];
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()])
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()]) // different physical rank
{
if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::WRA][dimmrank.ID()])
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_ddr);
if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::WRA][dimmrank.ID()]) // same DIMM
{
if (lastBurstLengthByCommandAndDimmRank[Command::WRA][dimmrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr + tBURST16);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr);
}
else // different DIMM
{
if (lastBurstLengthByCommand[Command::WRA] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_ddr + tBURST16);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_ddr);
}
}
}
else if (command == Command::ACT)
@@ -311,61 +529,71 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAACT);
{
if (lastBurstLengthByCommandAndBank[Command::WRA][bank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAACT + tBURST16);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAACT);
}
lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - cmdOffset);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - cmdLengthDiff);
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::PREA][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - cmdOffset);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - cmdLengthDiff);
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::PRESB][bankInGroup.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - cmdOffset);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - cmdLengthDiff);
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::REFA][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_slr - cmdOffset);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_slr - cmdLengthDiff);
// TODO: No tRFC_dlr and tRFC_dpr between REFA and ACT?
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::REFSB][bankInGroup.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCsb_slr - cmdOffset);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCsb_slr - cmdLengthDiff);
// TODO: No tRFCsb_dlr between REFSB and ACT?
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::REFSB][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFSBRD_slr - cmdOffset);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFSBRD_slr - cmdLengthDiff);
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::REFSB][physicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFSBRD_dlr - cmdOffset);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFSBRD_dlr - cmdLengthDiff);
if (last4ActivatesLogical[logicalrank.ID()].size() >= 4)
earliestTimeToStart = std::max(earliestTimeToStart, last4ActivatesLogical[logicalrank.ID()].front()
+ memSpec->tFAW_slr - memSpec->cmdOffset_L);
+ memSpec->tFAW_slr - memSpec->longCmdOffset);
if (last4ActivatesPhysical[physicalrank.ID()].size() >= 4)
earliestTimeToStart = std::max(earliestTimeToStart, last4ActivatesPhysical[physicalrank.ID()].front()
+ memSpec->tFAW_dlr - memSpec->cmdOffset_L);
+ memSpec->tFAW_dlr - memSpec->longCmdOffset);
}
else if (command == Command::PRE)
{
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tCK);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + cmdLengthDiff);
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tCK);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + cmdLengthDiff);
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tCK);
{
if (lastBurstLengthByCommandAndBank[Command::WR][bank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + tBURST16 + cmdLengthDiff);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + cmdLengthDiff);
}
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PRE][physicalrank.ID()];
if (lastCommandStart != sc_max_time())
@@ -383,23 +611,33 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr
{
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::ACT][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tCK);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + cmdLengthDiff);
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RD][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tCK);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + cmdLengthDiff);
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RDA][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tCK);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + cmdLengthDiff);
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WR][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tCK);
{
if (lastBurstLengthByCommandAndLogicalRank[Command::WR][logicalrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + tBURST16 + cmdLengthDiff);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + cmdLengthDiff);
}
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WRA][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tCK);
{
if (lastBurstLengthByCommandAndLogicalRank[Command::WRA][logicalrank.ID()])
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + tBURST16 + cmdLengthDiff);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + cmdLengthDiff);
}
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PRE][physicalrank.ID()];
if (lastCommandStart != sc_max_time())
@@ -415,23 +653,33 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr
{
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::ACT][bankInGroup.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tCK);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + cmdLengthDiff);
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::RD][bankInGroup.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tCK);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + cmdLengthDiff);
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::RDA][bankInGroup.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tCK);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + cmdLengthDiff);
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::WR][bankInGroup.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tCK);
{
if (lastBurstLengthByCommandAndBankInGroup[Command::WR][bankInGroup.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + tBURST16 + cmdLengthDiff);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + cmdLengthDiff);
}
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::WRA][bankInGroup.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tCK);
{
if (lastBurstLengthByCommandAndBankInGroup[Command::WRA][bankInGroup.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + tBURST16 + cmdLengthDiff);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + cmdLengthDiff);
}
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PRE][physicalrank.ID()];
if (lastCommandStart != sc_max_time())
@@ -447,15 +695,20 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr
{
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::ACT][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + memSpec->tCK);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + cmdLengthDiff);
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDAACT + memSpec->tCK);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDAACT + cmdLengthDiff);
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WRA][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP + memSpec->tCK);
{
if (lastBurstLengthByCommandAndLogicalRank[Command::WRA][logicalrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + tBURST16 + memSpec->tRP + cmdLengthDiff);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP + cmdLengthDiff);
}
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::PRE][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
@@ -473,7 +726,7 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_dlr);
lastCommandStart = lastScheduledByCommandAndDIMMRank[Command::REFA][dimmrank.ID()];
lastCommandStart = lastScheduledByCommandAndDimmRank[Command::REFA][dimmrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_dpr);
@@ -484,19 +737,24 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr
{
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::ACT][bankInGroup.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + memSpec->tCK);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + cmdLengthDiff);
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::ACT][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_L_slr + memSpec->tCK);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_L_slr + cmdLengthDiff);
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::RDA][bankInGroup.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDAACT + memSpec->tCK);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDAACT + cmdLengthDiff);
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::WRA][bankInGroup.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAACT + memSpec->tCK);
{
if (lastBurstLengthByCommandAndBankInGroup[Command::WRA][bankInGroup.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAACT + tBURST16 + cmdLengthDiff);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAACT + cmdLengthDiff);
}
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::PRE][bankInGroup.ID()];
if (lastCommandStart != sc_max_time())
@@ -518,7 +776,7 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_dlr);
// TODO: check this
lastCommandStart = lastScheduledByCommandAndDIMMRank[Command::REFA][dimmrank.ID()];
lastCommandStart = lastScheduledByCommandAndDimmRank[Command::REFA][dimmrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_dpr);
@@ -532,11 +790,11 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr
if (last4ActivatesLogical[logicalrank.ID()].size() >= 4)
earliestTimeToStart = std::max(earliestTimeToStart, last4ActivatesLogical[logicalrank.ID()].front()
+ memSpec->tFAW_slr - memSpec->cmdOffset_S);
+ memSpec->tFAW_slr - memSpec->shortCmdOffset);
if (last4ActivatesPhysical[physicalrank.ID()].size() >= 4)
earliestTimeToStart = std::max(earliestTimeToStart, last4ActivatesPhysical[physicalrank.ID()].front()
+ memSpec->tFAW_dlr - memSpec->cmdOffset_S);
+ memSpec->tFAW_dlr - memSpec->shortCmdOffset);
}
else
SC_REPORT_FATAL("CheckerDDR5", "Unknown command!");
@@ -544,38 +802,62 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr
if (lastCommandOnBus != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->tCK);
if (dummyCommandOnBus.start != sc_max_time())
{
TimeInterval currentCommandOnBus(earliestTimeToStart,
earliestTimeToStart + memSpec->getCommandLength(command));
if (currentCommandOnBus.intersects(dummyCommandOnBus))
earliestTimeToStart = dummyCommandOnBus.end;
}
return earliestTimeToStart;
}
void CheckerDDR5::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank)
void CheckerDDR5::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank, unsigned burstLength)
{
PRINTDEBUGMESSAGE("CheckerDDR5", "Changing state on bank " + std::to_string(bank.ID())
+ " command is " + commandToString(command));
Rank logicalrank = rank;
Rank physicalrank = Rank(logicalrank.ID() / memSpec->logicalRanksPerPhysicalRank);
Rank dimmrank = Rank(physicalrank.ID() / memSpec->physicalRanksPerDIMMRank);
Rank logicalRank = rank;
Rank physicalRank = Rank(logicalRank.ID() / memSpec->logicalRanksPerPhysicalRank);
Rank dimmRank = Rank(physicalRank.ID() / memSpec->physicalRanksPerDIMMRank);
Bank bankInGroup = Bank(rank.ID() * memSpec->banksPerGroup + bank.ID() % memSpec->banksPerGroup);
lastScheduledByCommandAndDIMMRank[command][dimmrank.ID()] = sc_time_stamp();
lastScheduledByCommandAndPhysicalRank[command][physicalrank.ID()] = sc_time_stamp();
lastScheduledByCommandAndLogicalRank[command][logicalrank.ID()] = sc_time_stamp();
lastScheduledByCommandAndDimmRank[command][dimmRank.ID()] = sc_time_stamp();
lastScheduledByCommandAndPhysicalRank[command][physicalRank.ID()] = sc_time_stamp();
lastScheduledByCommandAndLogicalRank[command][logicalRank.ID()] = sc_time_stamp();
lastScheduledByCommandAndBankGroup[command][bankgroup.ID()] = sc_time_stamp();
lastScheduledByCommandAndBank[command][bank.ID()] = sc_time_stamp();
lastScheduledByCommand[command] = sc_time_stamp();
lastScheduledByCommandAndBankInGroup[command][bankInGroup.ID()] = sc_time_stamp();
if (isCasCommand(command))
{
lastBurstLengthByCommandAndDimmRank[command][dimmRank.ID()] = burstLength;
lastBurstLengthByCommandAndPhysicalRank[command][physicalRank.ID()] = burstLength;
lastBurstLengthByCommandAndLogicalRank[command][logicalRank.ID()] = burstLength;
lastBurstLengthByCommandAndBankGroup[command][bankgroup.ID()] = burstLength;
lastBurstLengthByCommandAndBank[command][bank.ID()] = burstLength;
lastBurstLengthByCommand[command] = burstLength;
lastBurstLengthByCommandAndBankInGroup[command][bankInGroup.ID()] = burstLength;
if (burstLength == 32)
{
dummyCommandOnBus.start = sc_time_stamp() + tBURST16;
dummyCommandOnBus.end = sc_time_stamp() + tBURST16 + memSpec->getCommandLength(command);
}
}
lastCommandOnBus = sc_time_stamp() + memSpec->getCommandLength(command) - memSpec->tCK;
lastScheduledByCommandAndBankInGroup[command][rank.ID() * memSpec->banksPerGroup
+ bank.ID() % memSpec->banksPerGroup] = sc_time_stamp();
if (command == Command::ACT || command == Command::REFSB)
{
if (last4ActivatesLogical[logicalrank.ID()].size() == 4)
last4ActivatesLogical[logicalrank.ID()].pop();
last4ActivatesLogical[logicalrank.ID()].push(lastCommandOnBus);
if (last4ActivatesLogical[logicalRank.ID()].size() == 4)
last4ActivatesLogical[logicalRank.ID()].pop();
last4ActivatesLogical[logicalRank.ID()].push(lastCommandOnBus);
if (last4ActivatesPhysical[physicalrank.ID()].size() == 4)
last4ActivatesPhysical[physicalrank.ID()].pop();
last4ActivatesPhysical[physicalrank.ID()].push(lastCommandOnBus);
if (last4ActivatesPhysical[physicalRank.ID()].size() == 4)
last4ActivatesPhysical[physicalRank.ID()].pop();
last4ActivatesPhysical[physicalRank.ID()].push(lastCommandOnBus);
}
}

View File

@@ -40,34 +40,48 @@
#include <vector>
#include "../../configuration/memspec/MemSpecDDR5.h"
#include "../../configuration/Configuration.h"
#include "../../common/utils.h"
class CheckerDDR5 final : public CheckerIF
{
public:
CheckerDDR5();
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
virtual void insert(Command, Rank, BankGroup, Bank) override;
virtual sc_time timeToSatisfyConstraints(Command, Rank = Rank(0),
BankGroup = BankGroup(0), Bank = Bank(0), unsigned burstLength = 0) const override;
virtual void insert(Command, Rank, BankGroup, Bank, unsigned) override;
private:
const MemSpecDDR5 *memSpec;
std::vector<std::vector<sc_time>> lastScheduledByCommandAndDIMMRank;
std::vector<std::vector<sc_time>> lastScheduledByCommandAndDimmRank;
std::vector<std::vector<sc_time>> lastScheduledByCommandAndPhysicalRank;
std::vector<std::vector<sc_time>> lastScheduledByCommandAndLogicalRank;
std::vector<std::vector<sc_time>> lastScheduledByCommandAndBankGroup;
std::vector<std::vector<sc_time>> lastScheduledByCommandAndBank;
std::vector<sc_time> lastScheduledByCommand;
sc_time lastCommandOnBus;
TimeInterval dummyCommandOnBus;
std::vector<std::vector<sc_time>> lastScheduledByCommandAndBankInGroup;
std::vector<std::queue<sc_time>> last4ActivatesPhysical;
std::vector<std::queue<sc_time>> last4ActivatesLogical;
sc_time cmdOffset;
std::vector<std::vector<uint8_t>> lastBurstLengthByCommandAndDimmRank;
std::vector<std::vector<uint8_t>> lastBurstLengthByCommandAndPhysicalRank;
std::vector<std::vector<uint8_t>> lastBurstLengthByCommandAndLogicalRank;
std::vector<std::vector<uint8_t>> lastBurstLengthByCommandAndBankGroup;
std::vector<std::vector<uint8_t>> lastBurstLengthByCommandAndBank;
std::vector<uint8_t> lastBurstLengthByCommand;
sc_time tRD_BURST;
sc_time tWR_BURST;
std::vector<std::vector<uint8_t>> lastBurstLengthByCommandAndBankInGroup;
// TODO: store BL of last RD and WR globally or for each hierarchy?
sc_time cmdLengthDiff;
sc_time tBURST16;
sc_time tBURST32;
sc_time tWTRA;
sc_time tWRRDA;
sc_time tWRPRE;

View File

@@ -64,7 +64,7 @@ CheckerGDDR5::CheckerGDDR5()
tWRPRE = memSpec->tWL + tBURST + memSpec->tWR;
}
sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank, unsigned) const
{
sc_time lastCommandStart;
sc_time earliestTimeToStart = sc_time_stamp();
@@ -525,7 +525,7 @@ sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankG
return earliestTimeToStart;
}
void CheckerGDDR5::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank)
void CheckerGDDR5::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank, unsigned)
{
PRINTDEBUGMESSAGE("CheckerGDDR5", "Changing state on bank " + std::to_string(bank.ID())
+ " command is " + commandToString(command));

View File

@@ -45,8 +45,9 @@ class CheckerGDDR5 final : public CheckerIF
{
public:
CheckerGDDR5();
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
virtual void insert(Command, Rank, BankGroup, Bank) override;
virtual sc_time timeToSatisfyConstraints(Command, Rank = Rank(0),
BankGroup = BankGroup(0), Bank = Bank(0), unsigned burstLength = 0) const override;
virtual void insert(Command, Rank, BankGroup, Bank, unsigned) override;
private:
const MemSpecGDDR5 *memSpec;

View File

@@ -64,7 +64,7 @@ CheckerGDDR5X::CheckerGDDR5X()
tWRPRE = memSpec->tWL + tBURST + memSpec->tWR;
}
sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank, unsigned) const
{
sc_time lastCommandStart;
sc_time earliestTimeToStart = sc_time_stamp();
@@ -525,7 +525,7 @@ sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command, Rank rank, Bank
return earliestTimeToStart;
}
void CheckerGDDR5X::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank)
void CheckerGDDR5X::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank, unsigned)
{
PRINTDEBUGMESSAGE("CheckerGDDR5X", "Changing state on bank " + std::to_string(bank.ID())
+ " command is " + commandToString(command));

View File

@@ -45,8 +45,9 @@ class CheckerGDDR5X final : public CheckerIF
{
public:
CheckerGDDR5X();
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
virtual void insert(Command, Rank, BankGroup, Bank) override;
virtual sc_time timeToSatisfyConstraints(Command, Rank = Rank(0),
BankGroup = BankGroup(0), Bank = Bank(0), unsigned burstLength = 0) const override;
virtual void insert(Command, Rank, BankGroup, Bank, unsigned) override;
private:
const MemSpecGDDR5X *memSpec;

View File

@@ -63,7 +63,7 @@ CheckerGDDR6::CheckerGDDR6()
tWRPRE = memSpec->tWL + tBURST + memSpec->tWR;
}
sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank, unsigned) const
{
sc_time lastCommandStart;
sc_time earliestTimeToStart = sc_time_stamp();
@@ -546,7 +546,7 @@ sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command, Rank rank, BankG
return earliestTimeToStart;
}
void CheckerGDDR6::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank)
void CheckerGDDR6::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank, unsigned)
{
PRINTDEBUGMESSAGE("CheckerGDDR6", "Changing state on bank " + std::to_string(bank.ID())
+ " command is " + commandToString(command));

View File

@@ -45,8 +45,9 @@ class CheckerGDDR6 final : public CheckerIF
{
public:
CheckerGDDR6();
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
virtual void insert(Command, Rank, BankGroup, Bank) override;
virtual sc_time timeToSatisfyConstraints(Command, Rank = Rank(0),
BankGroup = BankGroup(0), Bank = Bank(0), unsigned burstLength = 0) const override;
virtual void insert(Command, Rank, BankGroup, Bank, unsigned) override;
private:
const MemSpecGDDR6 *memSpec;

View File

@@ -64,7 +64,7 @@ CheckerHBM2::CheckerHBM2()
tWRRDL = memSpec->tWL + tBURST + memSpec->tWTRL;
}
sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank, unsigned) const
{
sc_time lastCommandStart;
sc_time earliestTimeToStart = sc_time_stamp();
@@ -500,7 +500,7 @@ sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, Rank rank, BankGr
return earliestTimeToStart;
}
void CheckerHBM2::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank)
void CheckerHBM2::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank, unsigned)
{
PRINTDEBUGMESSAGE("CheckerHBM2", "Changing state on bank " + std::to_string(bank.ID())
+ " command is " + commandToString(command));

View File

@@ -45,8 +45,9 @@ class CheckerHBM2 final : public CheckerIF
{
public:
CheckerHBM2();
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
virtual void insert(Command, Rank, BankGroup, Bank) override;
virtual sc_time timeToSatisfyConstraints(Command, Rank = Rank(0),
BankGroup = BankGroup(0), Bank = Bank(0), unsigned burstLength = 0) const override;
virtual void insert(Command, Rank, BankGroup, Bank, unsigned) override;
private:
const MemSpecHBM2 *memSpec;

View File

@@ -46,8 +46,9 @@ class CheckerIF
public:
virtual ~CheckerIF() {}
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const = 0;
virtual void insert(Command, Rank, BankGroup, Bank) = 0;
virtual sc_time timeToSatisfyConstraints(Command, Rank = Rank(0),
BankGroup = BankGroup(0), Bank = Bank(0), unsigned burstLength = 0) const = 0;
virtual void insert(Command, Rank, BankGroup, Bank, unsigned) = 0;
};
#endif // CHECKERIF_H

View File

@@ -66,7 +66,7 @@ CheckerLPDDR4::CheckerLPDDR4()
tREFPDEN = memSpec->tCK + memSpec->tCMDCKE;
}
sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank) const
sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank, unsigned) const
{
sc_time lastCommandStart;
sc_time earliestTimeToStart = sc_time_stamp();
@@ -496,7 +496,7 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, Rank rank, Bank
return earliestTimeToStart;
}
void CheckerLPDDR4::insert(Command command, Rank rank, BankGroup, Bank bank)
void CheckerLPDDR4::insert(Command command, Rank rank, BankGroup, Bank bank, unsigned)
{
PRINTDEBUGMESSAGE("CheckerLPDDR4", "Changing state on bank " + std::to_string(bank.ID())
+ " command is " + commandToString(command));

View File

@@ -45,8 +45,9 @@ class CheckerLPDDR4 final : public CheckerIF
{
public:
CheckerLPDDR4();
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
virtual void insert(Command, Rank, BankGroup, Bank) override;
virtual sc_time timeToSatisfyConstraints(Command, Rank = Rank(0),
BankGroup = BankGroup(0), Bank = Bank(0), unsigned burstLength = 0) const override;
virtual void insert(Command, Rank, BankGroup, Bank, unsigned) override;
private:
const MemSpecLPDDR4 *memSpec;

View File

@@ -0,0 +1,388 @@
/*
* Copyright (c) 2021, Technische Universität 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 "CheckerSTTMRAM.h"
CheckerSTTMRAM::CheckerSTTMRAM()
{
Configuration &config = Configuration::getInstance();
memSpec = dynamic_cast<const MemSpecSTTMRAM *>(config.memSpec);
if (memSpec == nullptr)
SC_REPORT_FATAL("CheckerSTTMRAM", "Wrong MemSpec chosen");
lastScheduledByCommandAndBank = std::vector<std::vector<sc_time>>
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfBanks, sc_max_time()));
lastScheduledByCommandAndRank = std::vector<std::vector<sc_time>>
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfRanks, sc_max_time()));
lastScheduledByCommand = std::vector<sc_time>(numberOfCommands(), sc_max_time());
lastCommandOnBus = sc_max_time();
last4Activates = std::vector<std::queue<sc_time>>(memSpec->numberOfRanks);
tBURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK;
tRDWR = memSpec->tRL + tBURST + 2 * memSpec->tCK - memSpec->tWL;
tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL;
tWRRD = memSpec->tWL + tBURST + memSpec->tWTR - memSpec->tAL;
tWRRD_R = memSpec->tWL + tBURST + memSpec->tRTRS - memSpec->tRL;
tWRPRE = memSpec->tWL + tBURST + memSpec->tWR;
tRDPDEN = memSpec->tRL + tBURST + memSpec->tCK;
tWRPDEN = memSpec->tWL + tBURST + memSpec->tWR;
tWRAPDEN = memSpec->tWL + tBURST + memSpec->tWR + memSpec->tCK;
}
sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank, unsigned) const
{
sc_time lastCommandStart;
sc_time earliestTimeToStart = sc_time_stamp();
if (command == Command::RD || command == Command::RDA)
{
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD - memSpec->tAL);
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD);
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ?
lastScheduledByCommand[Command::RD] : sc_max_time();
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD);
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ?
lastScheduledByCommand[Command::RDA] : sc_max_time();
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
if (command == Command::RDA)
{
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP - memSpec->tAL);
}
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD);
lastCommandStart = lastScheduledByCommand[Command::WR];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R);
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD);
lastCommandStart = lastScheduledByCommand[Command::WRA];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R);
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSDLL);
}
else if (command == Command::WR || command == Command::WRA)
{
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD - memSpec->tAL);
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR);
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : sc_max_time();
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R);
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR);
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : sc_max_time();
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R);
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD);
lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank.ID()] ? lastScheduledByCommand[Command::WR] : sc_max_time();
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD);
lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank.ID()] ? lastScheduledByCommand[Command::WRA] : sc_max_time();
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSDLL);
}
else if (command == Command::ACT)
{
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD);
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP + memSpec->tRP);
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
if (last4Activates[rank.ID()].size() >= 4)
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank.ID()].front() + memSpec->tFAW);
}
else if (command == Command::PRE)
{
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP);
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
}
else if (command == Command::PREA)
{
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP);
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP);
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
}
else if (command == Command::PDEA)
{
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tACTPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
}
else if (command == Command::PDXA)
{
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
}
else if (command == Command::PDEP)
{
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
}
else if (command == Command::PDXP)
{
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
}
else if (command == Command::SREFEN)
{
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tRDPDEN, memSpec->tAL + memSpec->tRTP + memSpec->tRP));
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tWRAPDEN, tWRPRE + memSpec->tRP));
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
}
else if (command == Command::SREFEX)
{
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKESR);
}
else
SC_REPORT_FATAL("CheckerSTTMRAM", "Unknown command!");
if (lastCommandOnBus != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->tCK);
return earliestTimeToStart;
}
void CheckerSTTMRAM::insert(Command command, Rank rank, BankGroup, Bank bank, unsigned)
{
PRINTDEBUGMESSAGE("CheckerSTTMRAM", "Changing state on bank " + std::to_string(bank.ID())
+ " command is " + commandToString(command));
lastScheduledByCommandAndRank[command][rank.ID()] = sc_time_stamp();
lastScheduledByCommandAndBank[command][bank.ID()] = sc_time_stamp();
lastScheduledByCommand[command] = sc_time_stamp();
lastCommandOnBus = sc_time_stamp();
if (command == Command::ACT)
{
if (last4Activates[rank.ID()].size() == 4)
last4Activates[rank.ID()].pop();
last4Activates[rank.ID()].push(sc_time_stamp());
}
}

View File

@@ -0,0 +1,74 @@
/*
* Copyright (c) 2021, Technische Universität 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 CHECKERSTTMRAM_H
#define CHECKERSTTMRAM_H
#include "CheckerIF.h"
#include <queue>
#include <vector>
#include "../../configuration/memspec/MemSpecSTTMRAM.h"
#include "../../configuration/Configuration.h"
class CheckerSTTMRAM final : public CheckerIF
{
public:
CheckerSTTMRAM();
virtual sc_time timeToSatisfyConstraints(Command, Rank = Rank(0),
BankGroup = BankGroup(0), Bank = Bank(0), unsigned burstLength = 0) const override;
virtual void insert(Command, Rank, BankGroup, Bank, unsigned) override;
private:
const MemSpecSTTMRAM *memSpec;
std::vector<std::vector<sc_time>> lastScheduledByCommandAndBank;
std::vector<std::vector<sc_time>> lastScheduledByCommandAndRank;
std::vector<sc_time> lastScheduledByCommand;
sc_time lastCommandOnBus;
// Four activate window
std::vector<std::queue<sc_time>> last4Activates;
sc_time tBURST;
sc_time tRDWR;
sc_time tRDWR_R;
sc_time tWRRD;
sc_time tWRPRE;
sc_time tWRRD_R;
sc_time tRDPDEN;
sc_time tWRPDEN;
sc_time tWRAPDEN;
};
#endif // CHECKERSTTMRAM_H

View File

@@ -60,7 +60,7 @@ CheckerWideIO::CheckerWideIO()
tWRAPDEN = memSpec->tWL + tBURST + memSpec->tWR; // + memSpec->tCK; ??
}
sc_time CheckerWideIO::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank) const
sc_time CheckerWideIO::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank, unsigned) const
{
sc_time lastCommandStart;
sc_time earliestTimeToStart = sc_time_stamp();
@@ -385,7 +385,7 @@ sc_time CheckerWideIO::timeToSatisfyConstraints(Command command, Rank rank, Bank
return earliestTimeToStart;
}
void CheckerWideIO::insert(Command command, Rank rank, BankGroup, Bank bank)
void CheckerWideIO::insert(Command command, Rank rank, BankGroup, Bank bank, unsigned)
{
PRINTDEBUGMESSAGE("CheckerWideIO", "Changing state on bank " + std::to_string(bank.ID())
+ " command is " + commandToString(command));

View File

@@ -45,8 +45,9 @@ class CheckerWideIO final : public CheckerIF
{
public:
CheckerWideIO();
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
virtual void insert(Command, Rank, BankGroup, Bank) override;
virtual sc_time timeToSatisfyConstraints(Command, Rank = Rank(0),
BankGroup = BankGroup(0), Bank = Bank(0), unsigned burstLength = 0) const override;
virtual void insert(Command, Rank, BankGroup, Bank, unsigned) override;
private:
const MemSpecWideIO *memSpec;

View File

@@ -61,7 +61,7 @@ CheckerWideIO2::CheckerWideIO2()
tWRRD_R = memSpec->tWL + memSpec->tCK + tBURST + memSpec->tRTRS - memSpec->tRL;
}
sc_time CheckerWideIO2::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank) const
sc_time CheckerWideIO2::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank, unsigned) const
{
sc_time lastCommandStart;
sc_time earliestTimeToStart = sc_time_stamp();
@@ -463,7 +463,7 @@ sc_time CheckerWideIO2::timeToSatisfyConstraints(Command command, Rank rank, Ban
return earliestTimeToStart;
}
void CheckerWideIO2::insert(Command command, Rank rank, BankGroup, Bank bank)
void CheckerWideIO2::insert(Command command, Rank rank, BankGroup, Bank bank, unsigned)
{
PRINTDEBUGMESSAGE("CheckerWideIO2", "Changing state on bank " + std::to_string(bank.ID())
+ " command is " + commandToString(command));

View File

@@ -45,8 +45,9 @@ class CheckerWideIO2 final : public CheckerIF
{
public:
CheckerWideIO2();
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
virtual void insert(Command, Rank, BankGroup, Bank) override;
virtual sc_time timeToSatisfyConstraints(Command, Rank = Rank(0),
BankGroup = BankGroup(0), Bank = Bank(0), unsigned burstLength = 0) const override;
virtual void insert(Command, Rank, BankGroup, Bank, unsigned) override;
private:
const MemSpecWideIO2 *memSpec;

View File

@@ -54,6 +54,8 @@ Arbiter::Arbiter(sc_module_name name, std::string pathToAddressMapping) :
addressDecoder = new AddressDecoder(pathToAddressMapping);
addressDecoder->print();
bytesPerBeat = Configuration::getInstance().memSpec->dataBusWidth / 8;
}
ArbiterSimple::ArbiterSimple(sc_module_name name, std::string pathToAddressMapping) :
@@ -126,7 +128,8 @@ void ArbiterReorder::end_of_elaboration()
tlm_sync_enum Arbiter::nb_transport_fw(int id, tlm_generic_payload &payload,
tlm_phase &phase, sc_time &fwDelay)
{
sc_time notDelay = std::ceil((sc_time_stamp() + fwDelay) / tCK) * tCK - sc_time_stamp();
sc_time clockOffset = (sc_time_stamp() + fwDelay) % tCK;
sc_time notDelay = (clockOffset == SC_ZERO_TIME) ? fwDelay : (fwDelay + tCK - clockOffset);
if (phase == BEGIN_REQ)
{
@@ -140,7 +143,7 @@ tlm_sync_enum Arbiter::nb_transport_fw(int id, tlm_generic_payload &payload,
Channel(decodedAddress.channel), Rank(decodedAddress.rank),
BankGroup(decodedAddress.bankgroup), Bank(decodedAddress.bank),
Row(decodedAddress.row), Column(decodedAddress.column),
payload.get_streaming_width(), 0, 0);
payload.get_data_length() / bytesPerBeat, 0, 0);
payload.acquire();
}

View File

@@ -87,6 +87,8 @@ protected:
sc_time tCK;
sc_time arbitrationDelayFw;
sc_time arbitrationDelayBw;
unsigned bytesPerBeat;
};
class ArbiterSimple final : public Arbiter

View File

@@ -59,6 +59,7 @@
#include "dram/DramGDDR5.h"
#include "dram/DramGDDR5X.h"
#include "dram/DramGDDR6.h"
#include "dram/DramSTTMRAM.h"
#include "../controller/Controller.h"
DRAMSys::DRAMSys(sc_module_name name,
@@ -231,6 +232,8 @@ void DRAMSys::instantiateModules(const std::string &pathToResources,
dram = new DramGDDR5X(str.c_str());
else if (memoryType == MemSpec::MemoryType::GDDR6)
dram = new DramGDDR6(str.c_str());
else if (memoryType == MemSpec::MemoryType::STTMRAM)
dram = new DramSTTMRAM(str.c_str());
drams.push_back(dram);

View File

@@ -46,6 +46,7 @@
#include "dram/DramGDDR5.h"
#include "dram/DramGDDR5X.h"
#include "dram/DramGDDR6.h"
#include "dram/DramSTTMRAM.h"
#include "../common/TlmRecorder.h"
#include "../simulation/TemperatureController.h"
#include "../error/ecchamming.h"
@@ -172,6 +173,8 @@ void DRAMSysRecordable::instantiateModules(const std::string &traceName,
dram = new DramRecordable<DramGDDR5X>(str.c_str(), tlmRecorders[i]);
else if (memoryType == MemSpec::MemoryType::GDDR6)
dram = new DramRecordable<DramGDDR6>(str.c_str(), tlmRecorders[i]);
else if (memoryType == MemSpec::MemoryType::STTMRAM)
dram = new DramRecordable<DramSTTMRAM>(str.c_str(), tlmRecorders[i]);
drams.push_back(dram);

View File

@@ -49,6 +49,7 @@
#include "DramGDDR5.h"
#include "DramGDDR5X.h"
#include "DramGDDR6.h"
#include "DramSTTMRAM.h"
using namespace tlm;
@@ -156,3 +157,4 @@ template class DramRecordable<DramGDDR5>;
template class DramRecordable<DramGDDR5X>;
template class DramRecordable<DramGDDR6>;
template class DramRecordable<DramHBM2>;
template class DramRecordable<DramSTTMRAM>;

View File

@@ -0,0 +1,52 @@
/*
* Copyright (c) 2021, Technische Universität 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.
*
* Authors:
* Lukas Steiner
*/
#include "DramSTTMRAM.h"
#include "Dram.h"
#include "../../configuration/Configuration.h"
#include "../../common/third_party/DRAMPower/src/libdrampower/LibDRAMPower.h"
#include "../../configuration/memspec/MemSpecSTTMRAM.h"
using namespace DRAMPower;
DramSTTMRAM::DramSTTMRAM(sc_module_name name) : Dram(name)
{
if (storeMode == Configuration::StoreMode::ErrorModel)
SC_REPORT_FATAL("DramSTTMRAM", "Error Model not supported for STT-MRAM");
if (Configuration::getInstance().powerAnalysis)
SC_REPORT_FATAL("DramSTTMRAM", "DRAMPower does not support STT-MRAM");
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright (c) 2021, Technische Universität 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.
*
* Authors:
* Lukas Steiner
*/
#ifndef DRAMSTTMRAM_H
#define DRAMSTTMRAM_H
#include <systemc.h>
#include "Dram.h"
class DramSTTMRAM : public Dram
{
public:
DramSTTMRAM(sc_module_name);
SC_HAS_PROCESS(DramSTTMRAM);
virtual ~DramSTTMRAM() {}
};
#endif // DRAMSTTMRAM_H

View File

@@ -42,6 +42,8 @@ project(DRAMSysSimulator)
set(CMAKE_CXX_STANDARD 11 CACHE STRING "C++ Version")
set(DCMAKE_SH="CMAKE_SH-NOTFOUND")
find_package(Threads REQUIRED)
add_executable(DRAMSys
main.cpp
ExampleInitiator.h
@@ -62,4 +64,5 @@ target_include_directories(DRAMSys
target_link_libraries(DRAMSys
PRIVATE DRAMSysLibrary
PRIVATE Threads::Threads
)

View File

@@ -61,7 +61,7 @@ StlPlayer::StlPlayer(const sc_module_name &name,
this->maxPendingWriteRequests = maxPendingWriteRequests;
this->playerClk = playerClk;
burstlength = Configuration::getInstance().memSpec->burstLength;
burstLength = Configuration::getInstance().memSpec->burstLength;
dataLength = Configuration::getInstance().memSpec->bytesPerBurst;
lineCnt = 0;
@@ -100,23 +100,23 @@ void StlPlayer::nextPayload()
payload->set_response_status(TLM_INCOMPLETE_RESPONSE);
payload->set_dmi_allowed(false);
payload->set_byte_enable_length(0);
payload->set_streaming_width(burstlength);
payload->set_streaming_width(burstLength);
payload->set_data_length(dataLength);
payload->set_command(lineIterator->cmd);
std::copy(lineIterator->data.begin(), lineIterator->data.end(), payload->get_data_ptr());
sc_time sendingOffset;
sc_time sendingTime;
sc_time sendingOffset;
if (lastEndReq == sc_time_stamp())
sendingOffset = playerClk;
else
if (transactionsSent == 0)
sendingOffset = SC_ZERO_TIME;
else
sendingOffset = playerClk - (sc_time_stamp() % playerClk);
if (!relative)
sendingTime = std::max(sc_time_stamp() + sendingOffset, lineIterator->sendingTime);
else
sendingTime = sc_time_stamp() + std::max(sendingOffset, lineIterator->sendingTime);
sendingTime = sc_time_stamp() + sendingOffset + lineIterator->sendingTime;
sendToTarget(*payload, BEGIN_REQ, sendingTime - sc_time_stamp());

View File

@@ -80,7 +80,7 @@ private:
std::ifstream file;
uint64_t lineCnt;
unsigned int burstlength;
unsigned int burstLength;
unsigned int dataLength;
sc_time playerClk; // May be different from the memory clock!

View File

@@ -92,10 +92,10 @@ void TrafficGenerator::nextPayload()
payload->set_command(command);
sc_time sendingOffset;
if (lastEndReq == sc_time_stamp())
sendingOffset = tCK;
else
if (transactionsSent == 0)
sendingOffset = SC_ZERO_TIME;
else
sendingOffset = tCK;
// TODO: do not send two requests in the same cycle
sendToTarget(*payload, tlm::BEGIN_REQ, sendingOffset);

View File

@@ -74,8 +74,6 @@ void TrafficInitiator::peqCallback(tlm_generic_payload &payload,
{
if (phase == END_REQ)
{
lastEndReq = sc_time_stamp();
if (nextPayloadSendable())
nextPayload();
else

View File

@@ -75,7 +75,7 @@ protected:
unsigned int maxPendingWriteRequests = 0;
bool payloadPostponed = false;
bool finished = false;
sc_time lastEndReq = sc_max_time();
sc_event transactionFinished;
private: